update names

pull/15538/head
Rich Harris 4 months ago
parent dfde4590b5
commit 4ba38535c1

@ -2,4 +2,4 @@
'svelte': minor 'svelte': minor
--- ---
feat: functional template generation feat: add `fragments: 'html' | 'tree'` option for wider CSP compliance

@ -36,7 +36,7 @@ function build_locations(nodes) {
* @param {number} [flags] * @param {number} [flags]
*/ */
export function transform_template(state, namespace, flags = 0) { export function transform_template(state, namespace, flags = 0) {
const tree = state.options.templatingMode === 'functional'; const tree = state.options.fragments === 'tree';
const expression = tree ? state.template.as_tree() : state.template.as_html(); const expression = tree ? state.template.as_tree() : state.template.as_html();

@ -123,11 +123,14 @@ export interface CompileOptions extends ModuleCompileOptions {
*/ */
preserveWhitespace?: boolean; preserveWhitespace?: boolean;
/** /**
* If `functional`, the template will get compiled to a series of `document.createElement` calls, if `string` it will render the template tp a string and use `template.innerHTML`. * Which strategy to use when cloning DOM fragments:
* *
* @default 'string' * - `html` populates a `<template>` with `innerHTML` and clones it. This is faster, but cannot be used if your app's [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) includes [`require-trusted-types-for 'script'`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/require-trusted-types-for)
* - `tree` creates the fragment one element at a time and _then_ clones it. This is slower, but works everywhere
*
* @default 'html'
*/ */
templatingMode?: 'string' | 'functional'; fragments?: 'html' | 'tree';
/** /**
* Set to `true` to force the compiler into runes mode, even if there are no indications of runes usage. * Set to `true` to force the compiler into runes mode, even if there are no indications of runes usage.
* Set to `false` to force the compiler into ignoring runes, even if there are indications of runes usage. * Set to `false` to force the compiler into ignoring runes, even if there are indications of runes usage.

@ -110,7 +110,7 @@ export const validate_component_options =
preserveComments: boolean(false), preserveComments: boolean(false),
templatingMode: list(['string', 'functional']), fragments: list(['html', 'tree']),
preserveWhitespace: boolean(false), preserveWhitespace: boolean(false),

@ -191,5 +191,4 @@ if (typeof window !== 'undefined') {
}); });
} }
export const templatingMode = export const fragments = /** @type {'html' | 'tree'} */ (process.env.FRAGMENTS) ?? 'html';
/** @type {'string' | 'functional'} */ (process.env.TEMPLATING_MODE) ?? 'string';

@ -4,7 +4,7 @@ import * as fs from 'node:fs';
import { assert } from 'vitest'; import { assert } from 'vitest';
import { compile_directory } from '../helpers.js'; import { compile_directory } from '../helpers.js';
import { assert_html_equal } from '../html_equal.js'; import { assert_html_equal } from '../html_equal.js';
import { templatingMode } from '../helpers.js'; import { fragments } from '../helpers.js';
import { assert_ok, suite, type BaseTest } from '../suite.js'; import { assert_ok, suite, type BaseTest } from '../suite.js';
import { createClassComponent } from 'svelte/legacy'; import { createClassComponent } from 'svelte/legacy';
import { render } from 'svelte/server'; import { render } from 'svelte/server';
@ -46,7 +46,7 @@ const { test, run } = suite<HydrationTest>(async (config, cwd) => {
if (!config.load_compiled) { if (!config.load_compiled) {
await compile_directory(cwd, 'client', { await compile_directory(cwd, 'client', {
accessors: true, accessors: true,
templatingMode, fragments,
...config.compileOptions ...config.compileOptions
}); });

@ -5,7 +5,7 @@ import * as path from 'node:path';
import { compile } from 'svelte/compiler'; import { compile } from 'svelte/compiler';
import { afterAll, assert, beforeAll, describe } from 'vitest'; import { afterAll, assert, beforeAll, describe } from 'vitest';
import { suite, suite_with_variants } from '../suite'; import { suite, suite_with_variants } from '../suite';
import { write, templatingMode } from '../helpers'; import { write, fragments } from '../helpers';
import type { Warning } from '#compiler'; import type { Warning } from '#compiler';
const assert_file = path.resolve(__dirname, 'assert.js'); const assert_file = path.resolve(__dirname, 'assert.js');
@ -87,7 +87,7 @@ async function run_test(
build.onLoad({ filter: /\.svelte$/ }, (args) => { build.onLoad({ filter: /\.svelte$/ }, (args) => {
const compiled = compile(fs.readFileSync(args.path, 'utf-8').replace(/\r/g, ''), { const compiled = compile(fs.readFileSync(args.path, 'utf-8').replace(/\r/g, ''), {
generate: 'client', generate: 'client',
templatingMode, fragments,
...config.compileOptions, ...config.compileOptions,
immutable: config.immutable, immutable: config.immutable,
customElement: test_dir.includes('custom-elements-samples'), customElement: test_dir.includes('custom-elements-samples'),

@ -6,7 +6,7 @@ import { proxy } from 'svelte/internal/client';
import { flushSync, hydrate, mount, unmount } from 'svelte'; import { flushSync, hydrate, mount, unmount } from 'svelte';
import { render } from 'svelte/server'; import { render } from 'svelte/server';
import { afterAll, assert, beforeAll } from 'vitest'; import { afterAll, assert, beforeAll } from 'vitest';
import { compile_directory, templatingMode } from '../helpers.js'; import { compile_directory, fragments } from '../helpers.js';
import { setup_html_equal } from '../html_equal.js'; import { setup_html_equal } from '../html_equal.js';
import { raf } from '../animation-helpers.js'; import { raf } from '../animation-helpers.js';
import type { CompileOptions } from '#compiler'; import type { CompileOptions } from '#compiler';
@ -158,7 +158,7 @@ async function common_setup(cwd: string, runes: boolean | undefined, config: Run
rootDir: cwd, rootDir: cwd,
dev: force_hmr ? true : undefined, dev: force_hmr ? true : undefined,
hmr: force_hmr ? true : undefined, hmr: force_hmr ? true : undefined,
templatingMode, fragments,
...config.compileOptions, ...config.compileOptions,
immutable: config.immutable, immutable: config.immutable,
accessors: 'accessors' in config ? config.accessors : true, accessors: 'accessors' in config ? config.accessors : true,

@ -2,7 +2,7 @@ import { test } from '../../test';
export default test({ export default test({
compileOptions: { compileOptions: {
templatingMode: 'functional' fragments: 'tree'
}, },
html: `<p>hello</p>` html: `<p>hello</p>`

@ -2,6 +2,6 @@ import { test } from '../../test';
export default test({ export default test({
compileOptions: { compileOptions: {
templatingMode: 'functional' fragments: 'tree'
} }
}); });

@ -986,11 +986,14 @@ declare module 'svelte/compiler' {
*/ */
preserveWhitespace?: boolean; preserveWhitespace?: boolean;
/** /**
* If `functional`, the template will get compiled to a series of `document.createElement` calls, if `string` it will render the template tp a string and use `template.innerHTML`. * Which strategy to use when cloning DOM fragments:
* *
* @default 'string' * - `html` populates a `<template>` with `innerHTML` and clones it. This is faster, but cannot be used if your app's [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) includes [`require-trusted-types-for 'script'`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/require-trusted-types-for)
* - `tree` creates the fragment one element at a time and _then_ clones it. This is slower, but works everywhere
*
* @default 'html'
*/ */
templatingMode?: 'string' | 'functional'; fragments?: 'html' | 'tree';
/** /**
* Set to `true` to force the compiler into runes mode, even if there are no indications of runes usage. * Set to `true` to force the compiler into runes mode, even if there are no indications of runes usage.
* Set to `false` to force the compiler into ignoring runes, even if there are indications of runes usage. * Set to `false` to force the compiler into ignoring runes, even if there are indications of runes usage.
@ -2879,11 +2882,14 @@ declare module 'svelte/types/compiler/interfaces' {
*/ */
preserveWhitespace?: boolean; preserveWhitespace?: boolean;
/** /**
* If `functional`, the template will get compiled to a series of `document.createElement` calls, if `string` it will render the template tp a string and use `template.innerHTML`. * Which strategy to use when cloning DOM fragments:
* *
* @default 'string' * - `html` populates a `<template>` with `innerHTML` and clones it. This is faster, but cannot be used if your app's [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) includes [`require-trusted-types-for 'script'`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/require-trusted-types-for)
* - `tree` creates the fragment one element at a time and _then_ clones it. This is slower, but works everywhere
*
* @default 'html'
*/ */
templatingMode?: 'string' | 'functional'; fragments?: 'html' | 'tree';
/** /**
* Set to `true` to force the compiler into runes mode, even if there are no indications of runes usage. * Set to `true` to force the compiler into runes mode, even if there are no indications of runes usage.
* Set to `false` to force the compiler into ignoring runes, even if there are indications of runes usage. * Set to `false` to force the compiler into ignoring runes, even if there are indications of runes usage.

Loading…
Cancel
Save