move stuff off `state.metadata.context` and onto `state.template`

pull/15538/head
Rich Harris 4 months ago
parent 9106533053
commit 310f82d4f7

@ -154,10 +154,6 @@ export function client_component(analysis, options) {
legacy_reactive_imports: [], legacy_reactive_imports: [],
legacy_reactive_statements: new Map(), legacy_reactive_statements: new Map(),
metadata: { metadata: {
context: {
template_needs_import_node: false,
template_contains_script_tag: false
},
namespace: options.namespace, namespace: options.namespace,
bound_contenteditable: false bound_contenteditable: false
}, },

@ -14,7 +14,7 @@ import { template_to_string } from './to-string.js';
* @returns * @returns
*/ */
function get_template_function(namespace, state) { function get_template_function(namespace, state) {
const contains_script_tag = state.metadata.context.template_contains_script_tag; const contains_script_tag = state.template.contains_script_tag;
return ( return (
namespace === 'svg' namespace === 'svg'
? contains_script_tag ? contains_script_tag

@ -2,6 +2,15 @@
/** @import { Node, Element } from './types'; */ /** @import { Node, Element } from './types'; */
export class Template { export class Template {
/**
* `true` if HTML template contains a `<script>` tag. In this case we need to invoke a special
* template instantiation function (see `create_fragment_with_script_from_html` for more info)
*/
contains_script_tag = false;
/** `true` if the HTML template needs to be instantiated with `importNode` */
needs_import_node = false;
/** @type {Node[]} */ /** @type {Node[]} */
nodes = []; nodes = [];

@ -59,21 +59,6 @@ export interface ComponentClientTransformState extends ClientTransformState {
readonly metadata: { readonly metadata: {
namespace: Namespace; namespace: Namespace;
bound_contenteditable: boolean; bound_contenteditable: boolean;
/**
* Stuff that is set within the children of one `Fragment` visitor that is relevant
* to said fragment. Shouldn't be destructured or otherwise spread unless inside the
* `Fragment` visitor to keep the object reference intact (it's also nested
* within `metadata` for this reason).
*/
context: {
/** `true` if the HTML template needs to be instantiated with `importNode` */
template_needs_import_node: boolean;
/**
* `true` if HTML template contains a `<script>` tag. In this case we need to invoke a special
* template instantiation function (see `create_fragment_with_script_from_html` for more info)
*/
template_contains_script_tag: boolean;
};
}; };
readonly preserve_whitespace: boolean; readonly preserve_whitespace: boolean;

@ -70,10 +70,6 @@ export function Fragment(node, context) {
locations: [], locations: [],
transform: { ...context.state.transform }, transform: { ...context.state.transform },
metadata: { metadata: {
context: {
template_needs_import_node: false,
template_contains_script_tag: false
},
namespace, namespace,
bound_contenteditable: context.state.metadata.bound_contenteditable bound_contenteditable: context.state.metadata.bound_contenteditable
} }
@ -98,11 +94,7 @@ export function Fragment(node, context) {
node: id node: id
}); });
let flags = undefined; let flags = state.template.needs_import_node ? TEMPLATE_USE_IMPORT_NODE : undefined;
if (state.metadata.context.template_needs_import_node) {
flags = TEMPLATE_USE_IMPORT_NODE;
}
transform_template(state, context, namespace, template_name, flags); transform_template(state, context, namespace, template_name, flags);
@ -144,7 +136,7 @@ export function Fragment(node, context) {
let flags = TEMPLATE_FRAGMENT; let flags = TEMPLATE_FRAGMENT;
if (state.metadata.context.template_needs_import_node) { if (state.template.needs_import_node) {
flags |= TEMPLATE_USE_IMPORT_NODE; flags |= TEMPLATE_USE_IMPORT_NODE;
} }

@ -58,19 +58,15 @@ export function RegularElement(node, context) {
const is_custom_element = is_custom_element_node(node); const is_custom_element = is_custom_element_node(node);
if (node.name === 'video' || is_custom_element) { // cloneNode is faster, but it does not instantiate the underlying class of the
// cloneNode is faster, but it does not instantiate the underlying class of the // custom element until the template is connected to the dom, which would
// custom element until the template is connected to the dom, which would // cause problems when setting properties on the custom element.
// cause problems when setting properties on the custom element. // Therefore we need to use importNode instead, which doesn't have this caveat.
// Therefore we need to use importNode instead, which doesn't have this caveat. // Additionally, Webkit browsers need importNode for video elements for autoplay
// Additionally, Webkit browsers need importNode for video elements for autoplay // to work correctly.
// to work correctly. context.state.template.needs_import_node ||= node.name === 'video' || is_custom_element;
context.state.metadata.context.template_needs_import_node = true;
} context.state.template.contains_script_tag ||= node.name === 'script';
if (node.name === 'script') {
context.state.metadata.context.template_contains_script_tag = true;
}
context.state.template.create_element(node.name); context.state.template.create_element(node.name);

Loading…
Cancel
Save