Socket
Socket
Sign inDemoInstall

svelte

Package Overview
Dependencies
Maintainers
3
Versions
735
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

svelte - npm Package Compare versions

Comparing version 5.0.0-next.205 to 5.0.0-next.206

src/compiler/phases/3-transform/client/visitors/AnimateDirective.js

2

package.json

@@ -5,3 +5,3 @@ {

"license": "MIT",
"version": "5.0.0-next.205",
"version": "5.0.0-next.206",
"type": "module",

@@ -8,0 +8,0 @@ "types": "./types/index.d.ts",

@@ -6,3 +6,2 @@ /** @import { TemplateNode, Fragment, Root, SvelteOptionsRaw } from '#compiler' */

import { regex_whitespace } from '../patterns.js';
import { reserved } from '../../../constants.js';
import full_char_code_at from './utils/full_char_code_at.js';

@@ -12,2 +11,3 @@ import * as e from '../../errors.js';

import read_options from './read/options.js';
import { is_reserved } from '../../../utils.js';

@@ -224,3 +224,3 @@ const regex_position_indicator = / \(\d+:\d+\)$/;

if (!allow_reserved && reserved.includes(identifier)) {
if (!allow_reserved && is_reserved(identifier)) {
e.unexpected_reserved_word(start, identifier);

@@ -227,0 +227,0 @@ }

/** @import { ObjectExpression } from 'estree' */
/** @import { SvelteOptionsRaw, Root, SvelteOptions } from '#compiler' */
import { namespace_mathml, namespace_svg } from '../../../../constants.js';
import { NAMESPACE_MATHML, NAMESPACE_SVG } from '../../../../constants.js';
import * as e from '../../../errors.js';

@@ -158,5 +158,5 @@

if (value === namespace_svg) {
if (value === NAMESPACE_SVG) {
component_options.namespace = 'svg';
} else if (value === namespace_mathml) {
} else if (value === NAMESPACE_MATHML) {
component_options.namespace = 'mathml';

@@ -163,0 +163,0 @@ } else if (

/** @import { Expression } from 'estree' */
/** @import * as Compiler from '#compiler' */
/** @import { Parser } from '../index.js' */
import { is_void } from '../../../../constants.js';
import { is_void } from '../../../../utils.js';
import read_expression from '../read/expression.js';

@@ -6,0 +6,0 @@ import { read_script } from '../read/script.js';

@@ -10,3 +10,2 @@ /** @import { Node, Program } from 'estree' */

import * as b from '../../utils/builders.js';
import { ReservedKeywords, Runes } from '../constants.js';
import { Scope, ScopeRoot, create_scopes, get_rune } from '../scope.js';

@@ -17,3 +16,3 @@ import check_graph_for_cycles from './utils/check_graph_for_cycles.js';

import { prune } from './css/css-prune.js';
import { hash } from '../../../utils.js';
import { hash, is_rune } from '../../../utils.js';
import { warn_unused } from './css/css-warn.js';

@@ -208,2 +207,4 @@ import { extract_svelte_ignore } from '../../utils/extract_svelte_ignore.js';

const RESERVED = ['$$props', '$$restProps', '$$slots'];
/**

@@ -218,3 +219,3 @@ * @param {Program} ast

for (const [name, references] of scope.references) {
if (name[0] !== '$' || ReservedKeywords.includes(name)) continue;
if (name[0] !== '$' || RESERVED.includes(name)) continue;
if (name === '$' || name[1] === '$') {

@@ -264,3 +265,3 @@ e.global_reference_invalid(references[0].node, name);

for (const [name, references] of module.scope.references) {
if (name[0] !== '$' || ReservedKeywords.includes(name)) continue;
if (name[0] !== '$' || RESERVED.includes(name)) continue;
if (name === '$' || name[1] === '$') {

@@ -277,3 +278,3 @@ e.global_reference_invalid(references[0].node, name);

options.runes === false ||
!Runes.includes(/** @type {any} */ (name)) ||
!is_rune(name) ||
(declaration !== null &&

@@ -316,3 +317,3 @@ // const state = $state(0) is valid

e.global_reference_invalid(references[0].node, name);
} else if (declaration !== null && Runes.includes(/** @type {any} */ (name))) {
} else if (declaration !== null && is_rune(name)) {
for (const { node, path } of references) {

@@ -349,5 +350,3 @@ if (path.at(-1)?.type === 'CallExpression') {

const runes =
options.runes ??
Array.from(module.scope.references).some(([name]) => Runes.includes(/** @type {any} */ (name)));
const runes = options.runes ?? Array.from(module.scope.references.keys()).some(is_rune);

@@ -354,0 +353,0 @@ // TODO remove all the ?? stuff, we don't need it now that we're validating the config

/** @import { ArrowFunctionExpression, Expression, FunctionDeclaration, FunctionExpression } from 'estree' */
/** @import { Attribute, DelegatedEvent, RegularElement } from '#compiler' */
/** @import { Context } from '../types' */
import { DelegatedEvents, is_capture_event } from '../../../../constants.js';
import { is_capture_event, is_delegated } from '../../../../utils.js';
import {

@@ -62,3 +62,3 @@ get_attribute_chunks,

// Handle delegated event handlers. Bail-out if not a delegated event.
if (!handler || !DelegatedEvents.includes(event_name)) {
if (!handler || !is_delegated(event_name)) {
return null;

@@ -122,3 +122,3 @@ }

element.metadata.has_spread ||
!DelegatedEvents.includes(event_name)
!is_delegated(event_name)
) {

@@ -210,7 +210,7 @@ return non_hoistable;

function get_attribute_event_name(event_name) {
if (is_capture_event(event_name, 'include-on')) {
event_name = event_name.slice(2);
if (is_capture_event(event_name)) {
event_name = event_name.slice(0, -7);
}
event_name = event_name.slice(2);
return event_name;
}

@@ -12,4 +12,4 @@ /** @import { Attribute, BindDirective } from '#compiler' */

import { binding_properties } from '../../bindings.js';
import { ContentEditableBindings, SVGElements } from '../../constants.js';
import fuzzymatch from '../../1-parse/utils/fuzzymatch.js';
import { is_content_editable_binding, is_svg } from '../../../../utils.js';

@@ -201,3 +201,3 @@ /**

if (node.name === 'offsetWidth' && SVGElements.includes(parent.name)) {
if (node.name === 'offsetWidth' && is_svg(parent.name)) {
e.bind_invalid_target(

@@ -210,3 +210,3 @@ node,

if (ContentEditableBindings.includes(node.name)) {
if (is_content_editable_binding(node.name)) {
const contenteditable = /** @type {Attribute} */ (

@@ -213,0 +213,0 @@ parent.attributes.find((a) => a.type === 'Attribute' && a.name === 'contenteditable')

/** @import { Expression, Identifier } from 'estree' */
/** @import { SvelteNode } from '#compiler' */
/** @import { Context } from '../types' */
import is_reference from 'is-reference';
import { Runes } from '../../constants.js';
import { should_proxy_or_freeze } from '../../3-transform/client/utils.js';
import * as e from '../../../errors.js';
import * as w from '../../../warnings.js';
import { is_rune } from '../../../../utils.js';

@@ -37,3 +36,3 @@ /**

if (
Runes.includes(/** @type {Runes[number]} */ (node.name)) &&
is_rune(node.name) &&
context.state.scope.get(node.name) === null &&

@@ -53,3 +52,3 @@ context.state.scope.get(node.name.slice(1)) === null

if (!Runes.includes(/** @type {Runes[number]} */ (name))) {
if (!is_rune(name)) {
if (name === '$effect.active') {

@@ -56,0 +55,0 @@ e.rune_renamed(parent, '$effect.active', '$effect.tracking');

/** @import { RegularElement } from '#compiler' */
/** @import { Context } from '../types' */
import { is_mathml, is_svg, is_void } from '../../../../utils.js';
import {

@@ -9,3 +10,2 @@ is_tag_valid_with_ancestor,

import * as w from '../../../warnings.js';
import { MathMLElements, SVGElements, VoidElements } from '../../constants.js';
import { create_attribute } from '../../nodes.js';

@@ -95,4 +95,4 @@ import { regex_starts_with_newline } from '../../patterns.js';

if (context.state.options.namespace !== 'foreign') {
if (SVGElements.includes(node.name)) node.metadata.svg = true;
else if (MathMLElements.includes(node.name)) node.metadata.mathml = true;
node.metadata.svg = is_svg(node.name);
node.metadata.mathml = is_mathml(node.name);
}

@@ -103,2 +103,3 @@

let only_warn = false;
const ancestors = [context.state.parent_element];

@@ -135,3 +136,5 @@ for (let i = context.path.length - 1; i >= 0; i--) {

} else if (ancestor.type === 'RegularElement') {
if (!is_tag_valid_with_ancestor(node.name, ancestor.name)) {
ancestors.push(ancestor.name);
if (!is_tag_valid_with_ancestor(node.name, ancestors)) {
if (only_warn) {

@@ -161,4 +164,4 @@ w.node_invalid_placement_ssr(node, `\`<${node.name}>\``, ancestor.name);

context.state.options.namespace !== 'foreign' &&
!VoidElements.includes(node_name) &&
!SVGElements.includes(node_name)
!is_void(node_name) &&
!is_svg(node_name)
) {

@@ -165,0 +168,0 @@ w.element_invalid_self_closing_tag(node, node.name);

@@ -17,5 +17,5 @@ /** @import { Visitors } from 'zimmerframe' */

import { is_event_attribute, is_text_attribute } from '../../../../utils/ast.js';
import { ContentEditableBindings } from '../../../constants.js';
import { walk } from 'zimmerframe';
import { list } from '../../../../utils/string.js';
import { is_content_editable_binding } from '../../../../../utils.js';

@@ -724,6 +724,3 @@ const aria_roles = roles_map.keys();

}
} else if (
attribute.type === 'BindDirective' &&
ContentEditableBindings.includes(attribute.name)
) {
} else if (attribute.type === 'BindDirective' && is_content_editable_binding(attribute.name)) {
has_contenteditable_binding = true;

@@ -730,0 +727,0 @@ }

@@ -7,3 +7,2 @@ /** @import { Component, RegularElement, SvelteComponent, SvelteElement, SvelteSelf, TransitionDirective } from '#compiler' */

import * as w from '../../../../warnings.js';
import { EventModifiers } from '../../../constants.js';
import {

@@ -15,2 +14,14 @@ validate_attribute,

const EVENT_MODIFIERS = [
'preventDefault',
'stopPropagation',
'stopImmediatePropagation',
'capture',
'once',
'passive',
'nonpassive',
'self',
'trusted'
];
/**

@@ -127,4 +138,4 @@ * @param {import('#compiler').RegularElement | SvelteElement} node

for (const modifier of attribute.modifiers) {
if (!EventModifiers.includes(modifier)) {
const list = `${EventModifiers.slice(0, -1).join(', ')} or ${EventModifiers.at(-1)}`;
if (!EVENT_MODIFIERS.includes(modifier)) {
const list = `${EVENT_MODIFIERS.slice(0, -1).join(', ')} or ${EVENT_MODIFIERS.at(-1)}`;
e.event_handler_invalid_modifier(attribute, list);

@@ -131,0 +142,0 @@ }

/** @import { Attribute, SvelteElement, Text } from '#compiler' */
/** @import { Context } from '../types' */
import { namespace_mathml, namespace_svg } from '../../../../constants.js';
import { NAMESPACE_MATHML, NAMESPACE_SVG } from '../../../../constants.js';
import { is_text_attribute } from '../../../utils/ast.js';

@@ -26,4 +26,4 @@ import { check_element } from './shared/a11y.js';

if (xmlns) {
node.metadata.svg = xmlns.value[0].data === namespace_svg;
node.metadata.mathml = xmlns.value[0].data === namespace_mathml;
node.metadata.svg = xmlns.value[0].data === NAMESPACE_SVG;
node.metadata.mathml = xmlns.value[0].data === NAMESPACE_MATHML;
} else {

@@ -30,0 +30,0 @@ let i = context.path.length;

@@ -8,36 +8,106 @@ /** @import * as ESTree from 'estree' */

import { set_scope } from '../../scope.js';
import { template_visitors } from './visitors/template.js';
import { global_visitors } from './visitors/global.js';
import { javascript_visitors } from './visitors/javascript.js';
import { javascript_visitors_runes } from './visitors/javascript-runes.js';
import { javascript_visitors_legacy } from './visitors/javascript-legacy.js';
import { serialize_get_binding } from './utils.js';
import { build_getter } from './utils.js';
import { render_stylesheet } from '../css/index.js';
import { dev, filename } from '../../../state.js';
import { AnimateDirective } from './visitors/AnimateDirective.js';
import { ArrowFunctionExpression } from './visitors/ArrowFunctionExpression.js';
import { AssignmentExpression } from './visitors/AssignmentExpression.js';
import { Attribute } from './visitors/Attribute.js';
import { AwaitBlock } from './visitors/AwaitBlock.js';
import { BinaryExpression } from './visitors/BinaryExpression.js';
import { BindDirective } from './visitors/BindDirective.js';
import { BreakStatement } from './visitors/BreakStatement.js';
import { CallExpression } from './visitors/CallExpression.js';
import { ClassBody } from './visitors/ClassBody.js';
import { Comment } from './visitors/Comment.js';
import { Component } from './visitors/Component.js';
import { ConstTag } from './visitors/ConstTag.js';
import { DebugTag } from './visitors/DebugTag.js';
import { EachBlock } from './visitors/EachBlock.js';
import { ExportNamedDeclaration } from './visitors/ExportNamedDeclaration.js';
import { ExpressionStatement } from './visitors/ExpressionStatement.js';
import { Fragment } from './visitors/Fragment.js';
import { FunctionDeclaration } from './visitors/FunctionDeclaration.js';
import { FunctionExpression } from './visitors/FunctionExpression.js';
import { HtmlTag } from './visitors/HtmlTag.js';
import { Identifier } from './visitors/Identifier.js';
import { IfBlock } from './visitors/IfBlock.js';
import { ImportDeclaration } from './visitors/ImportDeclaration.js';
import { KeyBlock } from './visitors/KeyBlock.js';
import { LabeledStatement } from './visitors/LabeledStatement.js';
import { LetDirective } from './visitors/LetDirective.js';
import { MemberExpression } from './visitors/MemberExpression.js';
import { OnDirective } from './visitors/OnDirective.js';
import { RegularElement } from './visitors/RegularElement.js';
import { RenderTag } from './visitors/RenderTag.js';
import { SlotElement } from './visitors/SlotElement.js';
import { SnippetBlock } from './visitors/SnippetBlock.js';
import { SpreadAttribute } from './visitors/SpreadAttribute.js';
import { SvelteBody } from './visitors/SvelteBody.js';
import { SvelteComponent } from './visitors/SvelteComponent.js';
import { SvelteDocument } from './visitors/SvelteDocument.js';
import { SvelteElement } from './visitors/SvelteElement.js';
import { SvelteFragment } from './visitors/SvelteFragment.js';
import { SvelteHead } from './visitors/SvelteHead.js';
import { SvelteSelf } from './visitors/SvelteSelf.js';
import { SvelteWindow } from './visitors/SvelteWindow.js';
import { TitleElement } from './visitors/TitleElement.js';
import { TransitionDirective } from './visitors/TransitionDirective.js';
import { UpdateExpression } from './visitors/UpdateExpression.js';
import { UseDirective } from './visitors/UseDirective.js';
import { VariableDeclaration } from './visitors/VariableDeclaration.js';
/**
* This function ensures visitor sets don't accidentally clobber each other
* @param {...Visitors} array
* @returns {Visitors}
*/
function combine_visitors(...array) {
/** @type {Record<string, any>} */
const visitors = {};
/** @type {Visitors} */
const visitors = {
_: set_scope,
AnimateDirective,
ArrowFunctionExpression,
AssignmentExpression,
Attribute,
AwaitBlock,
BinaryExpression,
BindDirective,
BreakStatement,
CallExpression,
ClassBody,
Comment,
Component,
ConstTag,
DebugTag,
EachBlock,
ExportNamedDeclaration,
ExpressionStatement,
Fragment,
FunctionDeclaration,
FunctionExpression,
HtmlTag,
Identifier,
IfBlock,
ImportDeclaration,
KeyBlock,
LabeledStatement,
LetDirective,
MemberExpression,
OnDirective,
RegularElement,
RenderTag,
SlotElement,
SnippetBlock,
SpreadAttribute,
SvelteBody,
SvelteComponent,
SvelteDocument,
SvelteElement,
SvelteFragment,
SvelteHead,
SvelteSelf,
SvelteWindow,
TitleElement,
TransitionDirective,
UpdateExpression,
UseDirective,
VariableDeclaration
};
for (const member of array) {
for (const key in member) {
if (visitors[key]) {
throw new Error(`Duplicate visitor: ${key}`);
}
// @ts-ignore
visitors[key] = member[key];
}
}
return visitors;
}
/**
* @param {string} source
* @param {ComponentAnalysis} analysis

@@ -47,3 +117,3 @@ * @param {ValidatedCompileOptions} options

*/
export function client_component(source, analysis, options) {
export function client_component(analysis, options) {
/** @type {ComponentClientTransformState} */

@@ -54,3 +124,4 @@ const state = {

scope: analysis.module.scope,
scopes: analysis.template.scopes,
scopes: analysis.module.scopes,
is_instance: false,
hoisted: [b.import_all('$', 'svelte/internal/client')],

@@ -72,2 +143,3 @@ node: /** @type {any} */ (null), // populated by the root node

getters: {},
setters: {},
in_constructor: false,

@@ -85,41 +157,14 @@

const module = /** @type {ESTree.Program} */ (
walk(
/** @type {SvelteNode} */ (analysis.module.ast),
state,
combine_visitors(
set_scope(analysis.module.scopes),
global_visitors,
// @ts-expect-error TODO
javascript_visitors,
analysis.runes ? javascript_visitors_runes : javascript_visitors_legacy
)
)
walk(/** @type {SvelteNode} */ (analysis.module.ast), state, visitors)
);
const instance_state = { ...state, scope: analysis.instance.scope };
const instance_state = {
...state,
scope: analysis.instance.scope,
scopes: analysis.instance.scopes,
is_instance: true
};
const instance = /** @type {ESTree.Program} */ (
walk(
/** @type {SvelteNode} */ (analysis.instance.ast),
instance_state,
combine_visitors(
set_scope(analysis.instance.scopes),
global_visitors,
// @ts-expect-error TODO
javascript_visitors,
analysis.runes ? javascript_visitors_runes : javascript_visitors_legacy,
{
ImportDeclaration(node) {
state.hoisted.push(node);
return b.empty;
},
ExportNamedDeclaration(node, context) {
if (node.declaration) {
return context.visit(node.declaration);
}
return b.empty;
}
}
)
)
walk(/** @type {SvelteNode} */ (analysis.instance.ast), instance_state, visitors)
);

@@ -130,9 +175,4 @@

/** @type {SvelteNode} */ (analysis.template.ast),
{ ...state, scope: analysis.instance.scope },
combine_visitors(
set_scope(analysis.template.scopes),
global_visitors,
// @ts-expect-error TODO
template_visitors
)
{ ...state, scope: analysis.instance.scope, scopes: analysis.template.scopes },
visitors
)

@@ -168,3 +208,3 @@ );

// We're creating an arrow function that gets the store value which minifies better for two or more references
const store_reference = serialize_get_binding(b.id(name.slice(1)), instance_state);
const store_reference = build_getter(b.id(name.slice(1)), instance_state);
const store_get = b.call('$.store_get', store_reference, b.literal(name), b.id('$$stores'));

@@ -211,3 +251,3 @@ store_setup.push(

const binding = instance_state.scope.get(name);
const expression = serialize_get_binding(b.id(name), instance_state);
const expression = build_getter(b.id(name), instance_state);
const getter = b.get(alias ?? name, [b.return(expression)]);

@@ -337,3 +377,3 @@

b.literal(alias ?? name),
serialize_get_binding(b.id(name), instance_state)
build_getter(b.id(name), instance_state)
)

@@ -597,2 +637,3 @@ )

getters: {},
setters: {},
in_constructor: false

@@ -602,13 +643,3 @@ };

const module = /** @type {ESTree.Program} */ (
walk(
/** @type {SvelteNode} */ (analysis.module.ast),
state,
combine_visitors(
set_scope(analysis.module.scopes),
global_visitors,
// @ts-expect-error
javascript_visitors,
javascript_visitors_runes
)
)
walk(/** @type {SvelteNode} */ (analysis.module.ast), state, visitors)
);

@@ -615,0 +646,0 @@

@@ -7,3 +7,4 @@ import type {

PrivateIdentifier,
Expression
Expression,
AssignmentExpression
} from 'estree';

@@ -32,2 +33,9 @@ import type { Namespace, SvelteNode, ValidatedCompileOptions } from '#compiler';

readonly getters: Record<string, Expression | ((id: Identifier) => Expression)>;
/**
* Counterpart to `getters`
*/
readonly setters: Record<
string,
(assignment: AssignmentExpression, context: Context) => Expression
>;
}

@@ -40,2 +48,3 @@

readonly events: Set<string>;
readonly is_instance: boolean;

@@ -79,3 +88,3 @@ /** Stuff that happens before the render effect(s) */

export interface StateField {
kind: 'state' | 'frozen_state' | 'derived' | 'derived_call';
kind: 'state' | 'frozen_state' | 'derived' | 'derived_by';
id: PrivateIdentifier;

@@ -85,3 +94,3 @@ }

export type Context = import('zimmerframe').Context<SvelteNode, ClientTransformState>;
export type Visitors = import('zimmerframe').Visitors<SvelteNode, ClientTransformState>;
export type Visitors = import('zimmerframe').Visitors<SvelteNode, any>;

@@ -88,0 +97,0 @@ export type ComponentContext = import('zimmerframe').Context<

@@ -35,3 +35,3 @@ /** @import { ArrowFunctionExpression, AssignmentExpression, BinaryOperator, Expression, FunctionDeclaration, FunctionExpression, Identifier, MemberExpression, Node, Pattern, PrivateIdentifier, Statement } from 'estree' */

/** @type {BinaryOperator} */ (operator.slice(0, -1)),
serialize_get_binding(node.left, state),
build_getter(node.left, state),
/** @type {Expression} */ (visit(node.right))

@@ -76,3 +76,3 @@ );

*/
export function serialize_get_binding(node, state) {
export function build_getter(node, state) {
const binding = state.scope.get(node.name);

@@ -135,3 +135,3 @@

*/
export function serialize_set_binding(node, context, fallback, prefix, options) {
export function build_setter(node, context, fallback, prefix, options) {
const { state, visit } = context;

@@ -160,5 +160,3 @@

original_assignments.push(assignment);
assignments.push(
serialize_set_binding(assignment, context, () => assignment, prefix, options)
);
assignments.push(build_setter(assignment, context, () => assignment, prefix, options));
}

@@ -220,3 +218,3 @@

? b.call('$.freeze', value)
: serialize_proxy_reassignment(value, private_state.id);
: build_proxy_reassignment(value, private_state.id);
return assignment;

@@ -234,3 +232,3 @@ }

? b.call('$.freeze', value)
: serialize_proxy_reassignment(value, private_state.id)
: build_proxy_reassignment(value, private_state.id)
: value

@@ -259,3 +257,3 @@ );

? b.call('$.freeze', value)
: serialize_proxy_reassignment(value, public_state.id);
: build_proxy_reassignment(value, public_state.id);
return assignment;

@@ -277,4 +275,6 @@ }

if (binding.mutation !== null) {
return binding.mutation(node, context);
if (Object.hasOwn(state.setters, left.name)) {
const setter = state.setters[left.name];
// @ts-expect-error
return setter(node, context);
}

@@ -335,3 +335,3 @@

} else if (is_store) {
return b.call('$.store_set', serialize_get_binding(b.id(left_name), state), value);
return b.call('$.store_set', build_getter(b.id(left_name), state), value);
} else {

@@ -346,3 +346,3 @@ let call;

should_proxy_or_freeze(value, context.state.scope)
? serialize_proxy_reassignment(value, left_name)
? build_proxy_reassignment(value, left_name)
: value

@@ -370,3 +370,3 @@ );

binding.kind === 'bindable_prop'
? serialize_proxy_reassignment(value, left_name)
? build_proxy_reassignment(value, left_name)
: value

@@ -415,3 +415,3 @@ );

'$.store_mutate',
serialize_get_binding(b.id(left_name), state),
build_getter(b.id(left_name), state),
b.assignment(node.operator, /** @type {Pattern}} */ (visit_node(node.left)), value),

@@ -468,3 +468,3 @@ b.call('$.untrack', b.id('$' + left_name))

if (value.type === 'BinaryExpression' && /** @type {any} */ (value.operator) === '??') {
return b.logical('??', serialize_get_binding(b.id(left_name), state), serialize());
return b.logical('??', build_getter(b.id(left_name), state), serialize());
}

@@ -479,3 +479,3 @@

*/
export function serialize_proxy_reassignment(value, proxy_reference) {
export function build_proxy_reassignment(value, proxy_reference) {
return dev

@@ -494,33 +494,2 @@ ? b.call(

/**
* @param {ArrowFunctionExpression | FunctionExpression} node
* @param {ComponentContext} context
*/
export const function_visitor = (node, context) => {
const metadata = node.metadata;
let state = context.state;
if (node.type === 'FunctionExpression') {
const parent = /** @type {Node} */ (context.path.at(-1));
const in_constructor = parent.type === 'MethodDefinition' && parent.kind === 'constructor';
state = { ...context.state, in_constructor };
} else {
state = { ...context.state, in_constructor: false };
}
if (metadata?.hoistable === true) {
const params = serialize_hoistable_params(node, context);
return /** @type {FunctionExpression} */ ({
...node,
params,
body: context.visit(node.body, state)
});
}
context.next(state);
};
/**
* @param {FunctionDeclaration | FunctionExpression | ArrowFunctionExpression} node

@@ -598,3 +567,3 @@ * @param {ComponentContext} context

*/
export function serialize_hoistable_params(node, context) {
export function build_hoistable_params(node, context) {
const hoistable_params = get_hoistable_params(node, context);

@@ -601,0 +570,0 @@ node.metadata.hoistable_params = hoistable_params;

@@ -33,3 +33,3 @@ /** @import { ValidatedCompileOptions, CompileResult, ValidatedModuleCompileOptions } from '#compiler' */

? server_component(analysis, options)
: client_component(source, analysis, options);
: client_component(analysis, options);

@@ -36,0 +36,0 @@ const js_source_name = get_source_name(options.filename, options.outputFilename, 'input.svelte');

@@ -14,3 +14,3 @@ /** @import { Program, Property, Statement, VariableDeclarator } from 'estree' */

import { CallExpression } from './visitors/CallExpression.js';
import { ClassBodyRunes } from './visitors/ClassBody.js';
import { ClassBody } from './visitors/ClassBody.js';
import { Component } from './visitors/Component.js';

@@ -20,3 +20,3 @@ import { ConstTag } from './visitors/ConstTag.js';

import { EachBlock } from './visitors/EachBlock.js';
import { ExpressionStatementRunes } from './visitors/ExpressionStatement.js';
import { ExpressionStatement } from './visitors/ExpressionStatement.js';
import { Fragment } from './visitors/Fragment.js';

@@ -27,5 +27,5 @@ import { HtmlTag } from './visitors/HtmlTag.js';

import { KeyBlock } from './visitors/KeyBlock.js';
import { LabeledStatementLegacy } from './visitors/LabeledStatement.js';
import { MemberExpressionRunes } from './visitors/MemberExpression.js';
import { PropertyDefinitionRunes } from './visitors/PropertyDefinition.js';
import { LabeledStatement } from './visitors/LabeledStatement.js';
import { MemberExpression } from './visitors/MemberExpression.js';
import { PropertyDefinition } from './visitors/PropertyDefinition.js';
import { RegularElement } from './visitors/RegularElement.js';

@@ -43,32 +43,19 @@ import { RenderTag } from './visitors/RenderTag.js';

import { UpdateExpression } from './visitors/UpdateExpression.js';
import {
VariableDeclarationLegacy,
VariableDeclarationRunes
} from './visitors/VariableDeclaration.js';
import { VariableDeclaration } from './visitors/VariableDeclaration.js';
/** @type {Visitors} */
const global_visitors = {
_: set_scope,
AssignmentExpression,
CallExpression,
ClassBody,
ExpressionStatement,
Identifier,
UpdateExpression
LabeledStatement,
MemberExpression,
PropertyDefinition,
UpdateExpression,
VariableDeclaration
};
/** @type {Visitors} */
const javascript_visitors_runes = {
...global_visitors,
ClassBody: ClassBodyRunes,
ExpressionStatement: ExpressionStatementRunes,
MemberExpression: MemberExpressionRunes,
PropertyDefinition: PropertyDefinitionRunes,
VariableDeclaration: VariableDeclarationRunes
};
/** @type {Visitors} */
const javascript_visitors_legacy = {
...global_visitors,
LabeledStatement: LabeledStatementLegacy,
VariableDeclaration: VariableDeclarationLegacy
};
/** @type {ComponentVisitors} */

@@ -109,3 +96,3 @@ const template_visitors = {

scope: analysis.module.scope,
scopes: analysis.template.scopes,
scopes: analysis.module.scopes,
hoisted: [b.import_all('$', 'svelte/internal/server')],

@@ -123,11 +110,3 @@ legacy_reactive_statements: new Map(),

const module = /** @type {Program} */ (
walk(
/** @type {SvelteNode} */ (analysis.module.ast),
state,
// @ts-expect-error TODO: zimmerframe types
{
...set_scope(analysis.module.scopes),
...(analysis.runes ? javascript_visitors_runes : javascript_visitors_legacy)
}
)
walk(/** @type {SvelteNode} */ (analysis.module.ast), state, global_visitors)
);

@@ -138,7 +117,5 @@

/** @type {SvelteNode} */ (analysis.instance.ast),
state,
// @ts-expect-error TODO: zimmerframe types
{ ...state, scopes: analysis.instance.scopes },
{
...set_scope(analysis.instance.scopes),
...(analysis.runes ? javascript_visitors_runes : javascript_visitors_legacy),
...global_visitors,
ImportDeclaration(node) {

@@ -162,9 +139,5 @@ state.hoisted.push(node);

/** @type {SvelteNode} */ (analysis.template.ast),
state,
// @ts-expect-error TODO: zimmerframe types
{
...set_scope(analysis.template.scopes),
...global_visitors,
...template_visitors
}
{ ...state, scopes: analysis.template.scopes },
// @ts-expect-error don't know, don't care
{ ...global_visitors, ...template_visitors }
)

@@ -434,6 +407,3 @@ );

const module = /** @type {Program} */ (
walk(/** @type {SvelteNode} */ (analysis.module.ast), state, {
...set_scope(analysis.module.scopes),
...javascript_visitors_runes
})
walk(/** @type {SvelteNode} */ (analysis.module.ast), state, global_visitors)
);

@@ -440,0 +410,0 @@

@@ -6,3 +6,3 @@ /** @import { AssignmentExpression, AssignmentOperator, BinaryOperator, Expression, Node, Pattern } from 'estree' */

import { extract_paths } from '../../../../utils/ast.js';
import { serialize_get_binding } from './shared/utils.js';
import { build_getter } from './shared/utils.js';

@@ -31,3 +31,3 @@ /**

let assignment = serialize_assignment('=', path.node, value, context);
let assignment = build_assignment('=', path.node, value, context);
if (assignment !== null) changed = true;

@@ -58,3 +58,3 @@

return serialize_assignment(node.operator, node.left, node.right, context) || context.next();
return build_assignment(node.operator, node.left, node.right, context) || context.next();
}

@@ -70,3 +70,3 @@

*/
function serialize_assignment(operator, left, right, context) {
function build_assignment(operator, left, right, context) {
let object = left;

@@ -96,3 +96,3 @@

/** @type {BinaryOperator} */ (operator.slice(0, -1)),
serialize_get_binding(left, context.state),
build_getter(left, context.state),
value

@@ -99,0 +99,0 @@ );

@@ -12,3 +12,8 @@ /** @import { ClassBody, Expression, MethodDefinition, PropertyDefinition } from 'estree' */

*/
export function ClassBodyRunes(node, context) {
export function ClassBody(node, context) {
if (!context.state.analysis.runes) {
context.next();
return;
}
/** @type {Map<string, StateField>} */

@@ -38,3 +43,3 @@ const public_derived = new Map();

const field = {
kind: rune === '$derived.by' ? 'derived_call' : 'derived',
kind: rune === '$derived.by' ? 'derived_by' : 'derived',
// @ts-expect-error this is set in the next pass

@@ -86,3 +91,3 @@ id: is_private ? definition.key : null

const value =
field.kind === 'derived_call' ? b.call('$.once', init) : b.call('$.once', b.thunk(init));
field.kind === 'derived_by' ? b.call('$.once', init) : b.call('$.once', b.thunk(init));

@@ -99,3 +104,3 @@ if (is_private) {

if (dev && (field.kind === 'derived' || field.kind === 'derived_call')) {
if (dev && (field.kind === 'derived' || field.kind === 'derived_by')) {
body.push(

@@ -102,0 +107,0 @@ b.method(

/** @import { Component } from '#compiler' */
/** @import { ComponentContext } from '../types.js' */
import * as b from '../../../../utils/builders.js';
import { serialize_inline_component } from './shared/component.js';
import { build_inline_component } from './shared/component.js';

@@ -11,3 +11,3 @@ /**

export function Component(node, context) {
serialize_inline_component(node, b.id(node.name), context);
build_inline_component(node, b.id(node.name), context);
}
/** @import { ExpressionStatement } from 'estree' */
/** @import { Context } from '../types.js' */
import * as b from '../../../../utils/builders.js';
import { get_rune } from '../../../scope.js';

@@ -9,19 +10,7 @@ /**

*/
export function ExpressionStatementRunes(node, context) {
const expression = node.expression;
export function ExpressionStatement(node, context) {
const rune = get_rune(node.expression, context.state.scope);
if (expression.type === 'CallExpression') {
const callee = expression.callee;
if (callee.type === 'Identifier' && callee.name === '$effect') {
return b.empty;
}
if (
callee.type === 'MemberExpression' &&
callee.object.type === 'Identifier' &&
callee.object.name === '$effect'
) {
return b.empty;
}
if (rune === '$effect' || rune === '$effect.pre' || rune === '$effect.root') {
return b.empty;
}

@@ -28,0 +17,0 @@

@@ -5,3 +5,3 @@ /** @import { Fragment } from '#compiler' */

import * as b from '../../../../utils/builders.js';
import { empty_comment, process_children, serialize_template } from './shared/utils.js';
import { empty_comment, process_children, build_template } from './shared/utils.js';

@@ -46,3 +46,3 @@ /**

return b.block([...state.init, ...serialize_template(state.template)]);
return b.block([...state.init, ...build_template(state.template)]);
}

@@ -5,3 +5,3 @@ /** @import { Identifier, Node } from 'estree' */

import * as b from '../../../../utils/builders.js';
import { serialize_get_binding } from './shared/utils.js';
import { build_getter } from './shared/utils.js';

@@ -18,4 +18,4 @@ /**

return serialize_get_binding(node, context.state);
return build_getter(node, context.state);
}
}

@@ -9,5 +9,6 @@ /** @import { ExpressionStatement, LabeledStatement } from 'estree' */

*/
export function LabeledStatementLegacy(node, context) {
if (context.path.length > 1) return;
if (node.label.name !== '$') return;
export function LabeledStatement(node, context) {
if (context.state.analysis.runes || context.path.length > 1 || node.label.name !== '$') {
return;
}

@@ -14,0 +15,0 @@ // TODO bail out if we're in module context

@@ -9,4 +9,8 @@ /** @import { MemberExpression } from 'estree' */

*/
export function MemberExpressionRunes(node, context) {
if (node.object.type === 'ThisExpression' && node.property.type === 'PrivateIdentifier') {
export function MemberExpression(node, context) {
if (
context.state.analysis.runes &&
node.object.type === 'ThisExpression' &&
node.property.type === 'PrivateIdentifier'
) {
const field = context.state.private_derived.get(node.property.name);

@@ -13,0 +17,0 @@

@@ -10,4 +10,4 @@ /** @import { Expression, PropertyDefinition } from 'estree' */

*/
export function PropertyDefinitionRunes(node, context) {
if (node.value != null && node.value.type === 'CallExpression') {
export function PropertyDefinition(node, context) {
if (context.state.analysis.runes && node.value != null && node.value.type === 'CallExpression') {
const rune = get_rune(node.value, context.state.scope);

@@ -14,0 +14,0 @@

@@ -5,8 +5,8 @@ /** @import { Location } from 'locate-character' */

/** @import { Scope } from '../../../scope.js' */
import { is_void } from '../../../../../utils.js';
import { dev, locator } from '../../../../state.js';
import * as b from '../../../../utils/builders.js';
import { VoidElements } from '../../../constants.js';
import { clean_nodes, determine_namespace_for_children } from '../../utils.js';
import { serialize_element_attributes } from './shared/element.js';
import { process_children, serialize_template } from './shared/utils.js';
import { build_element_attributes } from './shared/element.js';
import { process_children, build_template } from './shared/utils.js';

@@ -30,3 +30,3 @@ /**

context.state.template.push(b.literal(`<${node.name}`));
const body = serialize_element_attributes(node, { ...context, state });
const body = build_element_attributes(node, { ...context, state });
context.state.template.push(b.literal('>'));

@@ -94,4 +94,4 @@

id,
b.block(serialize_template([id])),
b.block([...inner_state.init, ...serialize_template(inner_state.template)])
b.block(build_template([id])),
b.block([...inner_state.init, ...build_template(inner_state.template)])
)

@@ -101,3 +101,3 @@ );

if (!VoidElements.includes(node.name) || namespace === 'foreign') {
if (!is_void(node.name) || namespace === 'foreign') {
state.template.push(b.literal(`</${node.name}>`));

@@ -104,0 +104,0 @@ }

/** @import { BlockStatement, Expression, Pattern, Property, Statement } from 'estree' */
/** @import { Attribute, Component, LetDirective, SvelteComponent, SvelteSelf, TemplateNode, Text } from '#compiler' */
/** @import { ComponentContext } from '../../types.js' */
import { empty_comment, serialize_attribute_value } from './utils.js';
import { empty_comment, build_attribute_value } from './utils.js';
import * as b from '../../../../../utils/builders.js';

@@ -13,3 +13,3 @@ import { is_element_node } from '../../../../nodes.js';

*/
export function serialize_inline_component(node, expression, context) {
export function build_inline_component(node, expression, context) {
/** @type {Array<Property[] | Expression>} */

@@ -63,3 +63,3 @@ const props_and_spreads = [];

if (attribute.name.startsWith('--')) {
const value = serialize_attribute_value(attribute.value, context, false, true);
const value = build_attribute_value(attribute.value, context, false, true);
custom_css_props.push(b.init(attribute.name, value));

@@ -73,3 +73,3 @@ continue;

const value = serialize_attribute_value(attribute.value, context, false, true);
const value = build_attribute_value(attribute.value, context, false, true);
push_prop(b.prop('init', b.key(attribute.name), value));

@@ -76,0 +76,0 @@ } else if (attribute.type === 'BindDirective' && attribute.name !== 'this') {

@@ -11,7 +11,2 @@ /** @import { Expression, ExpressionStatement, Literal } from 'estree' */

import {
ContentEditableBindings,
LoadErrorElements,
WhitespaceInsensitiveAttributes
} from '../../../../constants.js';
import {
create_attribute,

@@ -24,8 +19,14 @@ create_expression_metadata,

import {
DOMBooleanAttributes,
ELEMENT_IS_NAMESPACED,
ELEMENT_PRESERVE_ATTRIBUTE_CASE
} from '../../../../../../constants.js';
import { serialize_attribute_value } from './utils.js';
import { build_attribute_value } from './utils.js';
import {
is_boolean_attribute,
is_content_editable_binding,
is_load_error_element
} from '../../../../../../utils.js';
const WHITESPACE_INSENSITIVE_ATTRIBUTES = ['class', 'style'];
/**

@@ -37,3 +38,3 @@ * Writes the output to the template output. Some elements may have attributes on them that require the

*/
export function serialize_element_attributes(node, context) {
export function build_element_attributes(node, context) {
/** @type {Array<Attribute | SpreadAttribute>} */

@@ -72,3 +73,3 @@ const attributes = [];

}
content = b.call('$.escape', serialize_attribute_value(attribute.value, context));
content = b.call('$.escape', build_attribute_value(attribute.value, context));
} else if (node.name !== 'select') {

@@ -84,3 +85,3 @@ // omit value attribute for select elements, it's irrelevant for the initially selected value and has no

(attribute.name === 'onload' || attribute.name === 'onerror') &&
LoadErrorElements.includes(node.name)
is_load_error_element(node.name)
) {

@@ -116,3 +117,3 @@ events_to_capture.add(attribute.name);

if (ContentEditableBindings.includes(attribute.name)) {
if (is_content_editable_binding(attribute.name)) {
content = /** @type {Expression} */ (context.visit(attribute.expression));

@@ -147,3 +148,3 @@ } else if (attribute.name === 'value' && node.name === 'textarea') {

b.member(attribute.expression, b.id('includes')),
serialize_attribute_value(value_attribute.value, context)
build_attribute_value(value_attribute.value, context)
)

@@ -153,3 +154,3 @@ : b.binary(

attribute.expression,
serialize_attribute_value(value_attribute.value, context)
build_attribute_value(value_attribute.value, context)
),

@@ -181,3 +182,3 @@ metadata: {

has_spread = true;
if (LoadErrorElements.includes(node.name)) {
if (is_load_error_element(node.name)) {
events_to_capture.add('onload');

@@ -187,3 +188,3 @@ events_to_capture.add('onerror');

} else if (attribute.type === 'UseDirective') {
if (LoadErrorElements.includes(node.name)) {
if (is_load_error_element(node.name)) {
events_to_capture.add('onload');

@@ -197,3 +198,3 @@ events_to_capture.add('onerror');

} else if (attribute.type === 'LetDirective') {
// do nothing, these are handled inside `serialize_inline_component`
// do nothing, these are handled inside `build_inline_component`
} else {

@@ -205,3 +206,3 @@ context.visit(attribute);

if (class_directives.length > 0 && !has_spread) {
const class_attribute = serialize_class_directives(
const class_attribute = build_class_directives(
class_directives,

@@ -216,3 +217,3 @@ /** @type {Attribute | null} */ (attributes[class_index] ?? null)

if (style_directives.length > 0 && !has_spread) {
serialize_style_directives(
build_style_directives(
style_directives,

@@ -228,9 +229,3 @@ /** @type {Attribute | null} */ (attributes[style_index] ?? null),

if (has_spread) {
serialize_element_spread_attributes(
node,
attributes,
style_directives,
class_directives,
context
);
build_element_spread_attributes(node, attributes, style_directives, class_directives, context);
} else {

@@ -241,6 +236,6 @@ for (const attribute of /** @type {Attribute[]} */ (attributes)) {

const literal_value = /** @type {Literal} */ (
serialize_attribute_value(
build_attribute_value(
attribute.value,
context,
WhitespaceInsensitiveAttributes.includes(name)
WHITESPACE_INSENSITIVE_ATTRIBUTES.includes(name)
)

@@ -252,3 +247,3 @@ ).value;

` ${attribute.name}${
DOMBooleanAttributes.includes(name) && literal_value === true
is_boolean_attribute(name) && literal_value === true
? ''

@@ -264,11 +259,10 @@ : `="${literal_value === true ? '' : String(literal_value)}"`

const name = get_attribute_name(node, attribute, context);
const is_boolean = DOMBooleanAttributes.includes(name);
const value = serialize_attribute_value(
const value = build_attribute_value(
attribute.value,
context,
WhitespaceInsensitiveAttributes.includes(name)
WHITESPACE_INSENSITIVE_ATTRIBUTES.includes(name)
);
context.state.template.push(
b.call('$.attr', b.literal(name), value, is_boolean && b.literal(is_boolean))
b.call('$.attr', b.literal(name), value, is_boolean_attribute(name) && b.true)
);

@@ -310,3 +304,3 @@ }

*/
function serialize_element_spread_attributes(
function build_element_spread_attributes(
element,

@@ -345,3 +339,3 @@ attributes,

? b.id(directive.name)
: serialize_attribute_value(directive.value, context, true)
: build_attribute_value(directive.value, context, true)
)

@@ -363,6 +357,6 @@ );

const name = get_attribute_name(element, attribute, context);
const value = serialize_attribute_value(
const value = build_attribute_value(
attribute.value,
context,
WhitespaceInsensitiveAttributes.includes(name)
WHITESPACE_INSENSITIVE_ATTRIBUTES.includes(name)
);

@@ -386,3 +380,3 @@ return b.prop('init', b.key(name), value);

*/
function serialize_class_directives(class_directives, class_attribute) {
function build_class_directives(class_directives, class_attribute) {
const expressions = class_directives.map((directive) =>

@@ -439,3 +433,3 @@ b.conditional(directive.expression, b.literal(directive.name), b.literal(''))

*/
function serialize_style_directives(style_directives, style_attribute, context) {
function build_style_directives(style_directives, style_attribute, context) {
const styles = style_directives.map((directive) => {

@@ -445,3 +439,3 @@ let value =

? b.id(directive.name)
: serialize_attribute_value(directive.value, context, true);
: build_attribute_value(directive.value, context, true);
if (directive.modifiers.includes('important')) {

@@ -458,3 +452,3 @@ value = b.binary('+', value, b.literal(' !important'));

'$.merge_styles',
serialize_attribute_value(style_attribute.value, context, true),
build_attribute_value(style_attribute.value, context, true),
b.object(styles)

@@ -461,0 +455,0 @@ );

@@ -97,3 +97,3 @@ /** @import { AssignmentOperator, Expression, Identifier, Node, Statement, TemplateElement } from 'estree' */

*/
export function serialize_template(template, out = b.id('$$payload.out'), operator = '+=') {
export function build_template(template, out = b.id('$$payload.out'), operator = '+=') {
/** @type {TemplateElement[]} */

@@ -156,3 +156,3 @@ let quasis = [];

*/
export function serialize_attribute_value(
export function build_attribute_value(
value,

@@ -212,3 +212,3 @@ context,

*/
export function serialize_get_binding(node, state) {
export function build_getter(node, state) {
const binding = state.scope.get(node.name);

@@ -227,3 +227,3 @@

b.literal(node.name),
serialize_get_binding(store_id, state)
build_getter(store_id, state)
);

@@ -230,0 +230,0 @@ }

@@ -5,3 +5,3 @@ /** @import { BlockStatement, Expression, ExpressionStatement, Property } from 'estree' */

import * as b from '../../../../utils/builders.js';
import { empty_comment, serialize_attribute_value } from './shared/utils.js';
import { empty_comment, build_attribute_value } from './shared/utils.js';

@@ -26,3 +26,3 @@ /**

} else if (attribute.type === 'Attribute') {
const value = serialize_attribute_value(attribute.value, context, false, true);
const value = build_attribute_value(attribute.value, context, false, true);

@@ -29,0 +29,0 @@ if (attribute.name === 'name') {

/** @import { Expression } from 'estree' */
/** @import { SvelteComponent } from '#compiler' */
/** @import { ComponentContext } from '../types.js' */
import { serialize_inline_component } from './shared/component.js';
import { build_inline_component } from './shared/component.js';

@@ -11,7 +11,3 @@ /**

export function SvelteComponent(node, context) {
serialize_inline_component(
node,
/** @type {Expression} */ (context.visit(node.expression)),
context
);
build_inline_component(node, /** @type {Expression} */ (context.visit(node.expression)), context);
}

@@ -7,4 +7,4 @@ /** @import { BlockStatement, Expression } from 'estree' */

import { determine_namespace_for_children } from '../../utils.js';
import { serialize_element_attributes } from './shared/element.js';
import { serialize_template } from './shared/utils.js';
import { build_element_attributes } from './shared/element.js';
import { build_template } from './shared/utils.js';

@@ -37,3 +37,3 @@ /**

serialize_element_attributes(node, { ...context, state });
build_element_attributes(node, { ...context, state });

@@ -44,3 +44,3 @@ if (dev) {

const attributes = b.block([...state.init, ...serialize_template(state.template)]);
const attributes = b.block([...state.init, ...build_template(state.template)]);
const children = /** @type {BlockStatement} */ (context.visit(node.fragment, state));

@@ -47,0 +47,0 @@

/** @import { SvelteSelf } from '#compiler' */
/** @import { ComponentContext } from '../types.js' */
import * as b from '../../../../utils/builders.js';
import { serialize_inline_component } from './shared/component.js';
import { build_inline_component } from './shared/component.js';

@@ -11,3 +11,3 @@ /**

export function SvelteSelf(node, context) {
serialize_inline_component(node, b.id(context.state.analysis.name), context);
build_inline_component(node, b.id(context.state.analysis.name), context);
}
/** @import { TitleElement } from '#compiler' */
/** @import { ComponentContext } from '../types.js' */
import * as b from '../../../../utils/builders.js';
import { process_children, serialize_template } from './shared/utils.js';
import { process_children, build_template } from './shared/utils.js';

@@ -16,3 +16,3 @@ /**

context.state.init.push(...serialize_template(template, b.id('$$payload.title'), '='));
context.state.init.push(...build_template(template, b.id('$$payload.title'), '='));
}

@@ -14,132 +14,123 @@ /** @import { VariableDeclaration, VariableDeclarator, Expression, CallExpression, Pattern, Identifier } from 'estree' */

*/
export function VariableDeclarationRunes(node, context) {
export function VariableDeclaration(node, context) {
/** @type {VariableDeclarator[]} */
const declarations = [];
for (const declarator of node.declarations) {
const init = declarator.init;
const rune = get_rune(init, context.state.scope);
if (!rune || rune === '$effect.tracking' || rune === '$inspect' || rune === '$effect.root') {
declarations.push(/** @type {VariableDeclarator} */ (context.visit(declarator)));
continue;
}
if (context.state.analysis.runes) {
for (const declarator of node.declarations) {
const init = declarator.init;
const rune = get_rune(init, context.state.scope);
if (!rune || rune === '$effect.tracking' || rune === '$inspect' || rune === '$effect.root') {
declarations.push(/** @type {VariableDeclarator} */ (context.visit(declarator)));
continue;
}
if (rune === '$props') {
// remove $bindable() from props declaration
const id = walk(declarator.id, null, {
AssignmentPattern(node) {
if (
node.right.type === 'CallExpression' &&
get_rune(node.right, context.state.scope) === '$bindable'
) {
const right = node.right.arguments.length
? /** @type {Expression} */ (context.visit(node.right.arguments[0]))
: b.id('undefined');
return b.assignment_pattern(node.left, right);
if (rune === '$props') {
// remove $bindable() from props declaration
const id = walk(declarator.id, null, {
AssignmentPattern(node) {
if (
node.right.type === 'CallExpression' &&
get_rune(node.right, context.state.scope) === '$bindable'
) {
const right = node.right.arguments.length
? /** @type {Expression} */ (context.visit(node.right.arguments[0]))
: b.id('undefined');
return b.assignment_pattern(node.left, right);
}
}
}
});
declarations.push(b.declarator(id, b.id('$$props')));
continue;
}
});
declarations.push(b.declarator(id, b.id('$$props')));
continue;
}
const args = /** @type {CallExpression} */ (init).arguments;
const value =
args.length === 0 ? b.id('undefined') : /** @type {Expression} */ (context.visit(args[0]));
const args = /** @type {CallExpression} */ (init).arguments;
const value =
args.length === 0 ? b.id('undefined') : /** @type {Expression} */ (context.visit(args[0]));
if (rune === '$derived.by') {
declarations.push(
b.declarator(/** @type {Pattern} */ (context.visit(declarator.id)), b.call(value))
);
continue;
}
if (rune === '$derived.by') {
declarations.push(
b.declarator(/** @type {Pattern} */ (context.visit(declarator.id)), b.call(value))
);
continue;
}
if (declarator.id.type === 'Identifier') {
declarations.push(b.declarator(declarator.id, value));
continue;
}
if (declarator.id.type === 'Identifier') {
declarations.push(b.declarator(declarator.id, value));
continue;
}
if (rune === '$derived') {
declarations.push(b.declarator(/** @type {Pattern} */ (context.visit(declarator.id)), value));
continue;
if (rune === '$derived') {
declarations.push(
b.declarator(/** @type {Pattern} */ (context.visit(declarator.id)), value)
);
continue;
}
declarations.push(...create_state_declarators(declarator, context.state.scope, value));
}
} else {
for (const declarator of node.declarations) {
const bindings = /** @type {Binding[]} */ (context.state.scope.get_bindings(declarator));
const has_state = bindings.some((binding) => binding.kind === 'state');
const has_props = bindings.some((binding) => binding.kind === 'bindable_prop');
declarations.push(...create_state_declarators(declarator, context.state.scope, value));
}
if (!has_state && !has_props) {
declarations.push(/** @type {VariableDeclarator} */ (context.visit(declarator)));
continue;
}
return {
...node,
declarations
};
}
if (has_props) {
if (declarator.id.type !== 'Identifier') {
// Turn export let into props. It's really really weird because export let { x: foo, z: [bar]} = ..
// means that foo and bar are the props (i.e. the leafs are the prop names), not x and z.
const tmp = context.state.scope.generate('tmp');
const paths = extract_paths(declarator.id);
declarations.push(
b.declarator(
b.id(tmp),
/** @type {Expression} */ (context.visit(/** @type {Expression} */ (declarator.init)))
)
);
for (const path of paths) {
const value = path.expression?.(b.id(tmp));
const name = /** @type {Identifier} */ (path.node).name;
const binding = /** @type {Binding} */ (context.state.scope.get(name));
const prop = b.member(b.id('$$props'), b.literal(binding.prop_alias ?? name), true);
declarations.push(
b.declarator(path.node, b.call('$.value_or_fallback', prop, b.thunk(value)))
);
}
continue;
}
/**
* @param {VariableDeclaration} node
* @param {Context} context
*/
export function VariableDeclarationLegacy(node, { state, visit }) {
/** @type {VariableDeclarator[]} */
const declarations = [];
const binding = /** @type {Binding} */ (context.state.scope.get(declarator.id.name));
const prop = b.member(
b.id('$$props'),
b.literal(binding.prop_alias ?? declarator.id.name),
true
);
for (const declarator of node.declarations) {
const bindings = /** @type {Binding[]} */ (state.scope.get_bindings(declarator));
const has_state = bindings.some((binding) => binding.kind === 'state');
const has_props = bindings.some((binding) => binding.kind === 'bindable_prop');
/** @type {Expression} */
let init = prop;
if (declarator.init) {
const default_value = /** @type {Expression} */ (context.visit(declarator.init));
init = is_expression_async(default_value)
? b.await(b.call('$.value_or_fallback_async', prop, b.thunk(default_value, true)))
: b.call('$.value_or_fallback', prop, b.thunk(default_value));
}
if (!has_state && !has_props) {
declarations.push(/** @type {VariableDeclarator} */ (visit(declarator)));
continue;
}
declarations.push(b.declarator(declarator.id, init));
if (has_props) {
if (declarator.id.type !== 'Identifier') {
// Turn export let into props. It's really really weird because export let { x: foo, z: [bar]} = ..
// means that foo and bar are the props (i.e. the leafs are the prop names), not x and z.
const tmp = state.scope.generate('tmp');
const paths = extract_paths(declarator.id);
declarations.push(
b.declarator(
b.id(tmp),
/** @type {Expression} */ (visit(/** @type {Expression} */ (declarator.init)))
)
);
for (const path of paths) {
const value = path.expression?.(b.id(tmp));
const name = /** @type {Identifier} */ (path.node).name;
const binding = /** @type {Binding} */ (state.scope.get(name));
const prop = b.member(b.id('$$props'), b.literal(binding.prop_alias ?? name), true);
declarations.push(
b.declarator(path.node, b.call('$.value_or_fallback', prop, b.thunk(value)))
);
}
continue;
}
const binding = /** @type {Binding} */ (state.scope.get(declarator.id.name));
const prop = b.member(
b.id('$$props'),
b.literal(binding.prop_alias ?? declarator.id.name),
true
declarations.push(
...create_state_declarators(
declarator,
context.state.scope,
/** @type {Expression} */ (declarator.init && context.visit(declarator.init))
)
);
/** @type {Expression} */
let init = prop;
if (declarator.init) {
const default_value = /** @type {Expression} */ (visit(declarator.init));
init = is_expression_async(default_value)
? b.await(b.call('$.value_or_fallback_async', prop, b.thunk(default_value, true)))
: b.call('$.value_or_fallback', prop, b.thunk(default_value));
}
declarations.push(b.declarator(declarator.id, init));
continue;
}
declarations.push(
...create_state_declarators(
declarator,
state.scope,
/** @type {Expression} */ (declarator.init && visit(declarator.init))
)
);
}

@@ -146,0 +137,0 @@

@@ -52,4 +52,2 @@ /** @import { Context } from 'zimmerframe' */

const { _ } = set_scope(state.scopes);
for (const node of nodes) {

@@ -67,3 +65,4 @@ if (node.type === 'ConstTag') {

walk(declaration.init, state, {
_,
// @ts-expect-error don't know, don't care
_: set_scope,
Identifier(node, context) {

@@ -70,0 +69,0 @@ const parent = /** @type {Expression} */ (context.path.at(-1));

/** @import { ClassDeclaration, Expression, FunctionDeclaration, Identifier, ImportDeclaration, MemberExpression, Node, Pattern, VariableDeclarator } from 'estree' */
/** @import { Context, Visitor, Visitors } from 'zimmerframe' */
/** @import { Context, Visitor } from 'zimmerframe' */
/** @import { AnimateDirective, Binding, DeclarationKind, EachBlock, ElementLike, LetDirective, SvelteNode, TransitionDirective, UseDirective } from '#compiler' */

@@ -15,3 +15,3 @@ import is_reference from 'is-reference';

} from '../utils/ast.js';
import { JsKeywords, Runes } from './constants.js';
import { is_reserved, is_rune } from '../../utils.js';

@@ -122,3 +122,2 @@ export class Scope {

prop_alias: null,
mutation: null,
reassigned: false,

@@ -153,3 +152,3 @@ metadata: null

this.root.conflicts.has(name) ||
JsKeywords.includes(name)
is_reserved(name)
) {

@@ -744,18 +743,9 @@ name = `${preferred_name}_${n++}`;

/**
* @template {{ scope: Scope }} State
* @param {Map<SvelteNode, Scope>} scopes
* @returns {Visitors<SvelteNode, State>}
* @template {{ scope: Scope, scopes: Map<SvelteNode, Scope> }} State
* @param {SvelteNode} node
* @param {Context<SvelteNode, State>} context
*/
export function set_scope(scopes) {
return {
/**
*
* @param {SvelteNode} node
* @param {Context<SvelteNode, State>} context
*/
_(node, { next, state }) {
const scope = scopes.get(node);
next(scope !== undefined && scope !== state.scope ? { ...state, scope } : state);
}
};
export function set_scope(node, { next, state }) {
const scope = state.scopes.get(node);
next(scope !== undefined && scope !== state.scope ? { ...state, scope } : state);
}

@@ -767,3 +757,2 @@

* @param {Scope} scope
* @returns {Runes[number] | null}
*/

@@ -794,3 +783,3 @@ export function get_rune(node, scope) {

if (!Runes.includes(/** @type {any} */ (joined))) return null;
if (!is_rune(joined)) return null;

@@ -800,3 +789,3 @@ const binding = scope.get(n.name);

return /** @type {typeof Runes[number] | null} */ (joined);
return joined;
}

@@ -310,4 +310,2 @@ import type {

prop_alias: string | null;
/** If this is set, all mutations should use this expression */
mutation: ((assignment: AssignmentExpression, context: Context<any, any>) => Expression) | null;
/** Additional metadata, varies per binding type */

@@ -314,0 +312,0 @@ metadata: {

@@ -37,167 +37,5 @@ export const EACH_ITEM_REACTIVE = 1;

/** List of elements that require raw contents and should not have SSR comments put in them */
export const RawTextElements = ['textarea', 'script', 'style', 'title'];
export const NAMESPACE_SVG = 'http://www.w3.org/2000/svg';
export const NAMESPACE_MATHML = 'http://www.w3.org/1998/Math/MathML';
/** List of Element events that will be delegated */
export const DelegatedEvents = [
'beforeinput',
'click',
'change',
'dblclick',
'contextmenu',
'focusin',
'focusout',
'input',
'keydown',
'keyup',
'mousedown',
'mousemove',
'mouseout',
'mouseover',
'mouseup',
'pointerdown',
'pointermove',
'pointerout',
'pointerover',
'pointerup',
'touchend',
'touchmove',
'touchstart'
];
/** List of Element events that will be delegated and are passive */
export const PassiveDelegatedEvents = ['touchstart', 'touchmove', 'touchend'];
/**
* @type {Record<string, string>}
* List of attribute names that should be aliased to their property names
* because they behave differently between setting them as an attribute and
* setting them as a property.
*/
export const AttributeAliases = {
// no `class: 'className'` because we handle that separately
formnovalidate: 'formNoValidate',
ismap: 'isMap',
nomodule: 'noModule',
playsinline: 'playsInline',
readonly: 'readOnly'
};
/**
* Attributes that are boolean, i.e. they are present or not present.
*/
export const DOMBooleanAttributes = [
'allowfullscreen',
'async',
'autofocus',
'autoplay',
'checked',
'controls',
'default',
'disabled',
'formnovalidate',
'hidden',
'indeterminate',
'ismap',
'loop',
'multiple',
'muted',
'nomodule',
'novalidate',
'open',
'playsinline',
'readonly',
'required',
'reversed',
'seamless',
'selected',
'webkitdirectory'
];
export const namespace_svg = 'http://www.w3.org/2000/svg';
export const namespace_mathml = 'http://www.w3.org/1998/Math/MathML';
/**
* @param {string} name
* @param {"include-on" | "exclude-on"} [mode] - wether if name starts with `on` or `on` is excluded at this point
*/
export function is_capture_event(name, mode = 'exclude-on') {
if (!name.endsWith('capture')) {
return false;
}
return mode == 'exclude-on'
? name !== 'gotpointercapture' && name !== 'lostpointercapture'
: name !== 'ongotpointercapture' && name !== 'onlostpointercapture';
}
export const reserved = [
'arguments',
'await',
'break',
'case',
'catch',
'class',
'const',
'continue',
'debugger',
'default',
'delete',
'do',
'else',
'enum',
'eval',
'export',
'extends',
'false',
'finally',
'for',
'function',
'if',
'implements',
'import',
'in',
'instanceof',
'interface',
'let',
'new',
'null',
'package',
'private',
'protected',
'public',
'return',
'static',
'super',
'switch',
'this',
'throw',
'true',
'try',
'typeof',
'var',
'void',
'while',
'with',
'yield'
];
const void_element_names = [
'area',
'base',
'br',
'col',
'command',
'embed',
'hr',
'img',
'input',
'keygen',
'link',
'meta',
'param',
'source',
'track',
'wbr'
];
// we use a list of ignorable runtime warnings because not every runtime warning

@@ -214,5 +52,8 @@ // can be ignored and we want to keep the validation for svelte-ignore in place

/** @param {string} name */
export function is_void(name) {
return void_element_names.includes(name) || name.toLowerCase() === '!doctype';
}
/**
* Whitespace inside one of these elements will not result in
* a whitespace node being created in any circumstances. (This
* list is almost certainly very incomplete)
* TODO this is currently unused
*/
export const ELEMENTS_WITHOUT_TEXT = ['audio', 'datalist', 'dl', 'optgroup', 'select', 'video'];

@@ -5,3 +5,3 @@ /**

* There are more elements that are invalid inside other elements, but they're not auto-closed and so don't break SSR and are therefore not listed here.
* @type {Record<string, { direct: string[]} | { descendant: string[] }>}
* @type {Record<string, { direct: string[]} | { descendant: string[]; reset_by?: string[] }>}
*/

@@ -11,4 +11,5 @@ const autoclosing_children = {

li: { direct: ['li'] },
dt: { descendant: ['dt', 'dd'] },
dd: { descendant: ['dt', 'dd'] },
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dt#technical_summary
dt: { descendant: ['dt', 'dd'], reset_by: ['dl'] },
dd: { descendant: ['dt', 'dd'], reset_by: ['dl'] },
p: {

@@ -80,3 +81,3 @@ descendant: [

* There are more elements that are invalid inside other elements, but they're not repaired and so don't break SSR and are therefore not listed here.
* @type {Record<string, { direct: string[]} | { descendant: string[]; only?: string[] } | { only: string[] }>}
* @type {Record<string, { direct: string[]} | { descendant: string[]; reset_by?: string[]; only?: string[] } | { only: string[] }>}
*/

@@ -143,8 +144,20 @@ const disallowed_children = {

* @param {string} tag
* @param {string} ancestor Must not be the parent, but higher up the tree
* @param {string[]} ancestors All nodes starting with the parent, up until the ancestor, which means two entries minimum
* @returns {boolean}
*/
export function is_tag_valid_with_ancestor(tag, ancestor) {
const disallowed = disallowed_children[ancestor];
return !disallowed || ('descendant' in disallowed ? !disallowed.descendant.includes(tag) : true);
export function is_tag_valid_with_ancestor(tag, ancestors) {
const target = ancestors[ancestors.length - 1];
const disallowed = disallowed_children[target];
if (!disallowed) return true;
if ('reset_by' in disallowed && disallowed.reset_by) {
for (let i = ancestors.length - 2; i >= 0; i--) {
// A reset means that forbidden descendants are allowed again
if (disallowed.reset_by.includes(ancestors[i])) {
return true;
}
}
}
return 'descendant' in disallowed ? !disallowed.descendant.includes(tag) : true;
}

@@ -151,0 +164,0 @@

/** @import { Effect, EffectNodes, TemplateNode } from '#client' */
import { FILENAME, namespace_svg } from '../../../../constants.js';
import { FILENAME, NAMESPACE_SVG } from '../../../../constants.js';
import {

@@ -71,3 +71,3 @@ hydrate_next,

const next_tag = get_tag() || null;
var ns = get_namespace ? get_namespace() : is_svg || next_tag === 'svg' ? namespace_svg : null;
var ns = get_namespace ? get_namespace() : is_svg || next_tag === 'svg' ? NAMESPACE_SVG : null;

@@ -74,0 +74,0 @@ // Assumption: Noone changes the namespace but not the tag (what would that even mean?)

import { DEV } from 'esm-env';
import { hydrating } from '../hydration.js';
import { get_descriptors, get_prototype_of } from '../../../shared/utils.js';
import {
AttributeAliases,
DelegatedEvents,
is_capture_event,
namespace_svg
} from '../../../../constants.js';
import { NAMESPACE_SVG } from '../../../../constants.js';
import { create_event, delegate } from './events.js';

@@ -15,2 +10,3 @@ import { add_form_reset_listener, autofocus } from './misc.js';

import { queue_idle_task, queue_micro_task } from '../task.js';
import { is_capture_event, is_delegated, normalize_attribute } from '../../../../utils.js';

@@ -220,3 +216,3 @@ /**

let event_name = key.slice(2);
var delegated = DelegatedEvents.includes(event_name);
var delegated = is_delegated(event_name);

@@ -277,4 +273,3 @@ if (is_capture_event(event_name)) {

if (lowercase_attributes) {
name = name.toLowerCase();
name = AttributeAliases[name] || name;
name = normalize_attribute(name);
}

@@ -341,3 +336,3 @@

next,
node.namespaceURI !== namespace_svg,
node.namespaceURI !== NAMESPACE_SVG,
css_hash

@@ -344,0 +339,0 @@ );

@@ -5,9 +5,4 @@ /** @import { ComponentContext, Effect, EffectNodes, TemplateNode } from '#client' */

import { clear_text_content, empty, init_operations } from './dom/operations.js';
import {
HYDRATION_END,
HYDRATION_ERROR,
HYDRATION_START,
PassiveDelegatedEvents
} from '../../constants.js';
import { flush_sync, push, pop, current_component_context, current_effect } from './runtime.js';
import { HYDRATION_END, HYDRATION_ERROR, HYDRATION_START } from '../../constants.js';
import { push, pop, current_component_context, current_effect } from './runtime.js';
import { effect_root, branch } from './reactivity/effects.js';

@@ -31,2 +26,3 @@ import {

import { assign_nodes } from './dom/template.js';
import { is_passive_event } from '../../utils.js';

@@ -200,3 +196,3 @@ /**

var passive = PassiveDelegatedEvents.includes(event_name);
var passive = is_passive_event(event_name);

@@ -203,0 +199,0 @@ // Add the event listener to both the container and the document.

@@ -62,13 +62,18 @@ /** @import { Component, Payload } from '#server' */

var child = { tag, parent, filename, line, column };
var ancestor = parent?.parent;
if (parent !== null && !is_tag_valid_with_parent(tag, parent.tag)) {
print_error(payload, parent, child);
}
if (parent !== null) {
var ancestor = parent.parent;
var ancestors = [parent.tag];
while (ancestor != null) {
if (!is_tag_valid_with_ancestor(tag, ancestor.tag)) {
print_error(payload, ancestor, child);
if (!is_tag_valid_with_parent(tag, parent.tag)) {
print_error(payload, parent, child);
}
ancestor = ancestor.parent;
while (ancestor != null) {
ancestors.push(ancestor.tag);
if (!is_tag_valid_with_ancestor(tag, ancestors)) {
print_error(payload, ancestor, child);
}
ancestor = ancestor.parent;
}
}

@@ -75,0 +80,0 @@

@@ -9,7 +9,6 @@ /** @import { ComponentType, SvelteComponent } from 'svelte' */

UNINITIALIZED,
DOMBooleanAttributes,
RawTextElements,
ELEMENT_PRESERVE_ATTRIBUTE_CASE,
ELEMENT_IS_NAMESPACED
} from '../../constants.js';
import { escape_html } from '../../escaping.js';

@@ -20,2 +19,3 @@ import { DEV } from 'esm-env';

import { validate_store } from '../shared/validate.js';
import { is_boolean_attribute, is_void } from '../../utils.js';

@@ -27,20 +27,4 @@ // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2

export const VoidElements = new Set([
'area',
'base',
'br',
'col',
'embed',
'hr',
'img',
'input',
'keygen',
'link',
'menuitem',
'meta',
'param',
'source',
'track',
'wbr'
]);
/** List of elements that require raw contents and should not have SSR comments put in them */
const RAW_TEXT_ELEMENTS = ['textarea', 'script', 'style', 'title'];

@@ -88,5 +72,5 @@ /**

if (!VoidElements.has(tag)) {
if (!is_void(tag)) {
children_fn();
if (!RawTextElements.includes(tag)) {
if (!RAW_TEXT_ELEMENTS.includes(tag)) {
payload.out += EMPTY_COMMENT;

@@ -249,4 +233,3 @@ }

const is_boolean = is_html && DOMBooleanAttributes.includes(name);
attr_str += attr(name, attrs[name], is_boolean);
attr_str += attr(name, attrs[name], is_html && is_boolean_attribute(name));
}

@@ -253,0 +236,0 @@

/** @import { TemplateNode } from '#client' */
/** @import { Getters } from '#shared' */
import { is_void } from '../../constants.js';
import { is_void } from '../../utils.js';
import * as w from './warnings.js';

@@ -5,0 +5,0 @@ import * as e from './errors.js';

@@ -15,1 +15,405 @@ const regex_return_characters = /\r/g;

}
const VOID_ELEMENT_NAMES = [
'area',
'base',
'br',
'col',
'command',
'embed',
'hr',
'img',
'input',
'keygen',
'link',
'meta',
'param',
'source',
'track',
'wbr'
];
/**
* Returns `true` if `name` is of a void element
* @param {string} name
*/
export function is_void(name) {
return VOID_ELEMENT_NAMES.includes(name) || name.toLowerCase() === '!doctype';
}
const RESERVED_WORDS = [
'arguments',
'await',
'break',
'case',
'catch',
'class',
'const',
'continue',
'debugger',
'default',
'delete',
'do',
'else',
'enum',
'eval',
'export',
'extends',
'false',
'finally',
'for',
'function',
'if',
'implements',
'import',
'in',
'instanceof',
'interface',
'let',
'new',
'null',
'package',
'private',
'protected',
'public',
'return',
'static',
'super',
'switch',
'this',
'throw',
'true',
'try',
'typeof',
'var',
'void',
'while',
'with',
'yield'
];
/**
* Returns `true` if `word` is a reserved JavaScript keyword
* @param {string} word
*/
export function is_reserved(word) {
return RESERVED_WORDS.includes(word);
}
/**
* @param {string} name
*/
export function is_capture_event(name) {
return name.endsWith('capture') && name !== 'gotpointercapture' && name !== 'lostpointercapture';
}
/** List of Element events that will be delegated */
export const DELEGATED_EVENTS = [
'beforeinput',
'click',
'change',
'dblclick',
'contextmenu',
'focusin',
'focusout',
'input',
'keydown',
'keyup',
'mousedown',
'mousemove',
'mouseout',
'mouseover',
'mouseup',
'pointerdown',
'pointermove',
'pointerout',
'pointerover',
'pointerup',
'touchend',
'touchmove',
'touchstart'
];
/**
* Returns `true` if `event_name` is a delegated event
* @param {string} event_name
*/
export function is_delegated(event_name) {
return DELEGATED_EVENTS.includes(event_name);
}
/**
* Attributes that are boolean, i.e. they are present or not present.
*/
export const DOM_BOOLEAN_ATTRIBUTES = [
'allowfullscreen',
'async',
'autofocus',
'autoplay',
'checked',
'controls',
'default',
'disabled',
'formnovalidate',
'hidden',
'indeterminate',
'ismap',
'loop',
'multiple',
'muted',
'nomodule',
'novalidate',
'open',
'playsinline',
'readonly',
'required',
'reversed',
'seamless',
'selected',
'webkitdirectory'
];
/**
* Returns `true` if `name` is a boolean attribute
* @param {string} name
*/
export function is_boolean_attribute(name) {
return DOM_BOOLEAN_ATTRIBUTES.includes(name);
}
/**
* @type {Record<string, string>}
* List of attribute names that should be aliased to their property names
* because they behave differently between setting them as an attribute and
* setting them as a property.
*/
const ATTRIBUTE_ALIASES = {
// no `class: 'className'` because we handle that separately
formnovalidate: 'formNoValidate',
ismap: 'isMap',
nomodule: 'noModule',
playsinline: 'playsInline',
readonly: 'readOnly'
};
/**
* @param {string} name
*/
export function normalize_attribute(name) {
name = name.toLowerCase();
return ATTRIBUTE_ALIASES[name] ?? name;
}
const DOM_PROPERTIES = [
...DOM_BOOLEAN_ATTRIBUTES,
'formNoValidate',
'isMap',
'noModule',
'playsInline',
'readOnly',
'value',
'inert',
'volume'
];
/**
* @param {string} name
*/
export function is_dom_property(name) {
return DOM_PROPERTIES.includes(name);
}
const PASSIVE_EVENTS = ['wheel', 'touchstart', 'touchmove', 'touchend', 'touchcancel'];
/**
* Returns `true` if `name` is a passive event
* @param {string} name
*/
export function is_passive_event(name) {
return PASSIVE_EVENTS.includes(name);
}
const CONTENT_EDITABLE_BINDINGS = ['textContent', 'innerHTML', 'innerText'];
/** @param {string} name */
export function is_content_editable_binding(name) {
return CONTENT_EDITABLE_BINDINGS.includes(name);
}
const LOAD_ERROR_ELEMENTS = [
'body',
'embed',
'iframe',
'img',
'link',
'object',
'script',
'style',
'track'
];
/**
* Returns `true` if the element emits `load` and `error` events
* @param {string} name
*/
export function is_load_error_element(name) {
return LOAD_ERROR_ELEMENTS.includes(name);
}
const SVG_ELEMENTS = [
'altGlyph',
'altGlyphDef',
'altGlyphItem',
'animate',
'animateColor',
'animateMotion',
'animateTransform',
'circle',
'clipPath',
'color-profile',
'cursor',
'defs',
'desc',
'discard',
'ellipse',
'feBlend',
'feColorMatrix',
'feComponentTransfer',
'feComposite',
'feConvolveMatrix',
'feDiffuseLighting',
'feDisplacementMap',
'feDistantLight',
'feDropShadow',
'feFlood',
'feFuncA',
'feFuncB',
'feFuncG',
'feFuncR',
'feGaussianBlur',
'feImage',
'feMerge',
'feMergeNode',
'feMorphology',
'feOffset',
'fePointLight',
'feSpecularLighting',
'feSpotLight',
'feTile',
'feTurbulence',
'filter',
'font',
'font-face',
'font-face-format',
'font-face-name',
'font-face-src',
'font-face-uri',
'foreignObject',
'g',
'glyph',
'glyphRef',
'hatch',
'hatchpath',
'hkern',
'image',
'line',
'linearGradient',
'marker',
'mask',
'mesh',
'meshgradient',
'meshpatch',
'meshrow',
'metadata',
'missing-glyph',
'mpath',
'path',
'pattern',
'polygon',
'polyline',
'radialGradient',
'rect',
'set',
'solidcolor',
'stop',
'svg',
'switch',
'symbol',
'text',
'textPath',
'tref',
'tspan',
'unknown',
'use',
'view',
'vkern'
];
/** @param {string} name */
export function is_svg(name) {
return SVG_ELEMENTS.includes(name);
}
const MATHML_ELEMENTS = [
'annotation',
'annotation-xml',
'maction',
'math',
'merror',
'mfrac',
'mi',
'mmultiscripts',
'mn',
'mo',
'mover',
'mpadded',
'mphantom',
'mprescripts',
'mroot',
'mrow',
'ms',
'mspace',
'msqrt',
'mstyle',
'msub',
'msubsup',
'msup',
'mtable',
'mtd',
'mtext',
'mtr',
'munder',
'munderover',
'semantics'
];
/** @param {string} name */
export function is_mathml(name) {
return MATHML_ELEMENTS.includes(name);
}
const RUNES = /** @type {const} */ ([
'$state',
'$state.frozen',
'$state.snapshot',
'$state.is',
'$props',
'$bindable',
'$derived',
'$derived.by',
'$effect',
'$effect.pre',
'$effect.tracking',
'$effect.root',
'$inspect',
'$inspect().with',
'$host'
]);
/**
* @param {string} name
* @returns {name is RUNES[number]}
*/
export function is_rune(name) {
return RUNES.includes(/** @type {RUNES[number]} */ (name));
}

@@ -9,3 +9,3 @@ // generated during release, do not modify

*/
export const VERSION = '5.0.0-next.205';
export const VERSION = '5.0.0-next.206';
export const PUBLIC_VERSION = '5';

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc