first commit
This commit is contained in:
36
frontend/node_modules/svelte/src/compiler/compile/nodes/Action.js
generated
vendored
Normal file
36
frontend/node_modules/svelte/src/compiler/compile/nodes/Action.js
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
import Node from './shared/Node.js';
|
||||
import Expression from './shared/Expression.js';
|
||||
|
||||
/** @extends Node<'Action'> */
|
||||
export default class Action extends Node {
|
||||
/** @type {string} */
|
||||
name;
|
||||
|
||||
/** @type {import('./shared/Expression.js').default} */
|
||||
expression;
|
||||
|
||||
/** @type {boolean} */
|
||||
uses_context;
|
||||
|
||||
/** @type {import('./shared/TemplateScope.js').default} */
|
||||
template_scope;
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component *
|
||||
* @param {import('./shared/Node.js').default} parent *
|
||||
* @param {import('./shared/TemplateScope.js').default} scope *
|
||||
* @param {import('../../interfaces.js').Directive} info undefined
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
const object = info.name.split('.')[0];
|
||||
component.warn_if_undefined(object, info, scope);
|
||||
this.name = info.name;
|
||||
component.add_reference(/** @type {any} */ (this), object);
|
||||
this.expression = info.expression
|
||||
? new Expression(component, this, scope, info.expression)
|
||||
: null;
|
||||
this.template_scope = scope;
|
||||
this.uses_context = this.expression && this.expression.uses_context;
|
||||
}
|
||||
}
|
||||
43
frontend/node_modules/svelte/src/compiler/compile/nodes/Animation.js
generated
vendored
Normal file
43
frontend/node_modules/svelte/src/compiler/compile/nodes/Animation.js
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
import Node from './shared/Node.js';
|
||||
import Expression from './shared/Expression.js';
|
||||
import compiler_errors from '../compiler_errors.js';
|
||||
|
||||
/** @extends Node<'Animation'> */
|
||||
export default class Animation extends Node {
|
||||
/** @type {string} */
|
||||
name;
|
||||
|
||||
/** @type {import('./shared/Expression.js').default} */
|
||||
expression;
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component *
|
||||
* @param {import('./Element.js').default} parent *
|
||||
* @param {import('./shared/TemplateScope.js').default} scope *
|
||||
* @param {import('../../interfaces.js').TemplateNode} info undefined
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
component.warn_if_undefined(info.name, info, scope);
|
||||
this.name = info.name;
|
||||
component.add_reference(/** @type {any} */ (this), info.name.split('.')[0]);
|
||||
if (parent.animation) {
|
||||
component.error(this, compiler_errors.duplicate_animation);
|
||||
return;
|
||||
}
|
||||
const block = parent.parent;
|
||||
if (!block || block.type !== 'EachBlock') {
|
||||
// TODO can we relax the 'immediate child' rule?
|
||||
component.error(this, compiler_errors.invalid_animation_immediate);
|
||||
return;
|
||||
}
|
||||
if (!block.key) {
|
||||
component.error(this, compiler_errors.invalid_animation_key);
|
||||
return;
|
||||
}
|
||||
/** @type {import('./EachBlock.js').default} */ (block).has_animation = true;
|
||||
this.expression = info.expression
|
||||
? new Expression(component, this, scope, info.expression, true)
|
||||
: null;
|
||||
}
|
||||
}
|
||||
136
frontend/node_modules/svelte/src/compiler/compile/nodes/Attribute.js
generated
vendored
Normal file
136
frontend/node_modules/svelte/src/compiler/compile/nodes/Attribute.js
generated
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
import { string_literal } from '../utils/stringify.js';
|
||||
import add_to_set from '../utils/add_to_set.js';
|
||||
import Node from './shared/Node.js';
|
||||
import Expression from './shared/Expression.js';
|
||||
import { x } from 'code-red';
|
||||
import compiler_warnings from '../compiler_warnings.js';
|
||||
|
||||
/** @extends Node<'Attribute' | 'Spread', import('./Element.js').default> */
|
||||
export default class Attribute extends Node {
|
||||
/** @type {import('./shared/TemplateScope.js').default} */
|
||||
scope;
|
||||
|
||||
/** @type {string} */
|
||||
name;
|
||||
|
||||
/** @type {boolean} */
|
||||
is_spread;
|
||||
|
||||
/** @type {boolean} */
|
||||
is_true;
|
||||
|
||||
/** @type {boolean} */
|
||||
is_static;
|
||||
|
||||
/** @type {import('./shared/Expression.js').default} */
|
||||
expression;
|
||||
|
||||
/** @type {Array<import('./Text.js').default | import('./shared/Expression.js').default>} */
|
||||
chunks;
|
||||
|
||||
/** @type {Set<string>} */
|
||||
dependencies;
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./shared/Node.js').default} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
this.scope = scope;
|
||||
|
||||
if (info.type === 'Spread') {
|
||||
this.name = null;
|
||||
this.is_spread = true;
|
||||
this.is_true = false;
|
||||
this.expression = new Expression(component, this, scope, info.expression);
|
||||
this.dependencies = this.expression.dependencies;
|
||||
this.chunks = null;
|
||||
this.is_static = false;
|
||||
} else {
|
||||
this.name = info.name;
|
||||
this.is_true = info.value === true;
|
||||
this.is_static = true;
|
||||
this.dependencies = new Set();
|
||||
this.chunks = this.is_true
|
||||
? []
|
||||
: info.value.map((node) => {
|
||||
if (node.type === 'Text') return node;
|
||||
this.is_static = false;
|
||||
const expression = new Expression(component, this, scope, node.expression);
|
||||
add_to_set(this.dependencies, expression.dependencies);
|
||||
return expression;
|
||||
});
|
||||
}
|
||||
|
||||
if (this.dependencies.size > 0) {
|
||||
parent.cannot_use_innerhtml();
|
||||
parent.not_static_content();
|
||||
}
|
||||
|
||||
// TODO Svelte 5: Think about moving this into the parser and make it an error
|
||||
if (
|
||||
this.name &&
|
||||
this.name.includes(':') &&
|
||||
!this.name.startsWith('xmlns:') &&
|
||||
!this.name.startsWith('xlink:') &&
|
||||
!this.name.startsWith('xml:')
|
||||
) {
|
||||
component.warn(this, compiler_warnings.illegal_attribute_character);
|
||||
}
|
||||
}
|
||||
get_dependencies() {
|
||||
if (this.is_spread) return this.expression.dynamic_dependencies();
|
||||
|
||||
/** @type {Set<string>} */
|
||||
const dependencies = new Set();
|
||||
this.chunks.forEach((chunk) => {
|
||||
if (chunk.type === 'Expression') {
|
||||
add_to_set(dependencies, chunk.dynamic_dependencies());
|
||||
}
|
||||
});
|
||||
return Array.from(dependencies);
|
||||
}
|
||||
|
||||
/** @param {any} block */
|
||||
get_value(block) {
|
||||
if (this.is_true) return x`true`;
|
||||
if (this.chunks.length === 0) return x`""`;
|
||||
if (this.chunks.length === 1) {
|
||||
return this.chunks[0].type === 'Text'
|
||||
? string_literal(/** @type {import('./Text.js').default} */ (this.chunks[0]).data)
|
||||
: /** @type {import('./shared/Expression.js').default} */ (this.chunks[0]).manipulate(
|
||||
block
|
||||
);
|
||||
}
|
||||
let expression = this.chunks
|
||||
.map(
|
||||
/** @param {any} chunk */ (chunk) =>
|
||||
chunk.type === 'Text' ? string_literal(chunk.data) : chunk.manipulate(block)
|
||||
)
|
||||
.reduce((lhs, rhs) => x`${lhs} + ${rhs}`);
|
||||
if (this.chunks[0].type !== 'Text') {
|
||||
expression = x`"" + ${expression}`;
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
get_static_value() {
|
||||
if (!this.is_static) return null;
|
||||
return this.is_true
|
||||
? true
|
||||
: this.chunks[0]
|
||||
? // method should be called only when `is_static = true`
|
||||
/** @type {import('./Text.js').default} */ (this.chunks[0]).data
|
||||
: '';
|
||||
}
|
||||
should_cache() {
|
||||
return this.is_static
|
||||
? false
|
||||
: this.chunks.length === 1
|
||||
? // @ts-ignore todo: probably error
|
||||
this.chunks[0].node.type !== 'Identifier' || this.scope.names.has(this.chunks[0].node.name)
|
||||
: true;
|
||||
}
|
||||
}
|
||||
74
frontend/node_modules/svelte/src/compiler/compile/nodes/AwaitBlock.js
generated
vendored
Normal file
74
frontend/node_modules/svelte/src/compiler/compile/nodes/AwaitBlock.js
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
import Node from './shared/Node.js';
|
||||
import PendingBlock from './PendingBlock.js';
|
||||
import ThenBlock from './ThenBlock.js';
|
||||
import CatchBlock from './CatchBlock.js';
|
||||
import Expression from './shared/Expression.js';
|
||||
import { unpack_destructuring } from './shared/Context.js';
|
||||
|
||||
/** @extends Node<'AwaitBlock'> */
|
||||
export default class AwaitBlock extends Node {
|
||||
/** @type {import('./shared/Expression.js').default} */
|
||||
expression;
|
||||
|
||||
/** @type {import('./shared/Context.js').Context[]} */
|
||||
then_contexts;
|
||||
|
||||
/** @type {import('./shared/Context.js').Context[]} */
|
||||
catch_contexts;
|
||||
|
||||
/** @type {import('estree').Node | null} */
|
||||
then_node;
|
||||
|
||||
/** @type {import('estree').Node | null} */
|
||||
catch_node;
|
||||
|
||||
/** @type {import('./PendingBlock.js').default} */
|
||||
pending;
|
||||
|
||||
/** @type {import('./ThenBlock.js').default} */
|
||||
then;
|
||||
|
||||
/** @type {import('./CatchBlock.js').default} */
|
||||
catch;
|
||||
|
||||
/** @type {Map<string, import('estree').Node>} */
|
||||
context_rest_properties = new Map();
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./shared/Node.js').default} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
this.cannot_use_innerhtml();
|
||||
this.not_static_content();
|
||||
this.expression = new Expression(component, this, scope, info.expression);
|
||||
this.then_node = info.value;
|
||||
this.catch_node = info.error;
|
||||
if (this.then_node) {
|
||||
this.then_contexts = [];
|
||||
unpack_destructuring({
|
||||
contexts: this.then_contexts,
|
||||
node: info.value,
|
||||
scope,
|
||||
component,
|
||||
context_rest_properties: this.context_rest_properties
|
||||
});
|
||||
}
|
||||
if (this.catch_node) {
|
||||
this.catch_contexts = [];
|
||||
unpack_destructuring({
|
||||
contexts: this.catch_contexts,
|
||||
node: info.error,
|
||||
scope,
|
||||
component,
|
||||
context_rest_properties: this.context_rest_properties
|
||||
});
|
||||
}
|
||||
this.pending = new PendingBlock(component, this, scope, info.pending);
|
||||
this.then = new ThenBlock(component, this, scope, info.then);
|
||||
this.catch = new CatchBlock(component, this, scope, info.catch);
|
||||
}
|
||||
}
|
||||
132
frontend/node_modules/svelte/src/compiler/compile/nodes/Binding.js
generated
vendored
Normal file
132
frontend/node_modules/svelte/src/compiler/compile/nodes/Binding.js
generated
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
import Node from './shared/Node.js';
|
||||
import get_object from '../utils/get_object.js';
|
||||
import Expression from './shared/Expression.js';
|
||||
import { regex_dimensions, regex_box_size } from '../../utils/patterns.js';
|
||||
import { clone } from '../../utils/clone.js';
|
||||
import compiler_errors from '../compiler_errors.js';
|
||||
import compiler_warnings from '../compiler_warnings.js';
|
||||
|
||||
// TODO this should live in a specific binding
|
||||
const read_only_media_attributes = new Set([
|
||||
'duration',
|
||||
'buffered',
|
||||
'seekable',
|
||||
'played',
|
||||
'seeking',
|
||||
'ended',
|
||||
'videoHeight',
|
||||
'videoWidth',
|
||||
'naturalWidth',
|
||||
'naturalHeight',
|
||||
'readyState'
|
||||
]);
|
||||
|
||||
/** @extends Node<'Binding'> */
|
||||
export default class Binding extends Node {
|
||||
/** @type {string} */
|
||||
name;
|
||||
|
||||
/** @type {import('./shared/Expression.js').default} */
|
||||
expression;
|
||||
|
||||
/** @type {import('estree').Node} */
|
||||
raw_expression; // TODO exists only for bind:this — is there a more elegant solution?
|
||||
|
||||
/** @type {boolean} */
|
||||
is_contextual;
|
||||
|
||||
/** @type {boolean} */
|
||||
is_readonly;
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./Element.js').default | import('./InlineComponent.js').default | import('./Window.js').default | import('./Document.js').default} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
if (info.expression.type !== 'Identifier' && info.expression.type !== 'MemberExpression') {
|
||||
component.error(info, compiler_errors.invalid_directive_value);
|
||||
return;
|
||||
}
|
||||
this.name = info.name;
|
||||
this.expression = new Expression(component, this, scope, info.expression);
|
||||
this.raw_expression = clone(info.expression);
|
||||
const { name } = get_object(this.expression.node);
|
||||
this.is_contextual = Array.from(this.expression.references).some((name) =>
|
||||
scope.names.has(name)
|
||||
);
|
||||
if (this.is_contextual) this.validate_binding_rest_properties(scope);
|
||||
// make sure we track this as a mutable ref
|
||||
if (scope.is_let(name)) {
|
||||
component.error(this, compiler_errors.invalid_binding_let);
|
||||
return;
|
||||
} else if (scope.names.has(name)) {
|
||||
if (scope.is_await(name)) {
|
||||
component.error(this, compiler_errors.invalid_binding_await);
|
||||
return;
|
||||
}
|
||||
if (scope.is_const(name)) {
|
||||
component.error(this, compiler_errors.invalid_binding_const);
|
||||
}
|
||||
scope.dependencies_for_name.get(name).forEach((name) => {
|
||||
const variable = component.var_lookup.get(name);
|
||||
if (variable) {
|
||||
variable.mutated = true;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
const variable = component.var_lookup.get(name);
|
||||
if (!variable || variable.global) {
|
||||
component.error(
|
||||
/** @type {any} */ (this.expression.node),
|
||||
compiler_errors.binding_undeclared(name)
|
||||
);
|
||||
return;
|
||||
}
|
||||
variable[this.expression.node.type === 'MemberExpression' ? 'mutated' : 'reassigned'] = true;
|
||||
if (info.expression.type === 'Identifier' && !variable.writable) {
|
||||
component.error(
|
||||
/** @type {any} */ (this.expression.node),
|
||||
compiler_errors.invalid_binding_writable
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
const type = parent.get_static_attribute_value('type');
|
||||
this.is_readonly =
|
||||
regex_dimensions.test(this.name) ||
|
||||
regex_box_size.test(this.name) ||
|
||||
(is_element(parent) &&
|
||||
((parent.is_media_node() && read_only_media_attributes.has(this.name)) ||
|
||||
(parent.name === 'input' && type === 'file'))) /* TODO others? */;
|
||||
}
|
||||
is_readonly_media_attribute() {
|
||||
return read_only_media_attributes.has(this.name);
|
||||
}
|
||||
|
||||
/** @param {import('./shared/TemplateScope.js').default} scope */
|
||||
validate_binding_rest_properties(scope) {
|
||||
this.expression.references.forEach((name) => {
|
||||
const each_block = scope.get_owner(name);
|
||||
if (each_block && each_block.type === 'EachBlock') {
|
||||
const rest_node = each_block.context_rest_properties.get(name);
|
||||
if (rest_node) {
|
||||
this.component.warn(
|
||||
/** @type {any} */ (rest_node),
|
||||
compiler_warnings.invalid_rest_eachblock_binding(name)
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('./shared/Node.js').default} node
|
||||
* @returns {node is import('./Element.js').default}
|
||||
*/
|
||||
function is_element(node) {
|
||||
return !!(/** @type {any} */ (node).is_media_node);
|
||||
}
|
||||
31
frontend/node_modules/svelte/src/compiler/compile/nodes/Body.js
generated
vendored
Normal file
31
frontend/node_modules/svelte/src/compiler/compile/nodes/Body.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
import Node from './shared/Node.js';
|
||||
import EventHandler from './EventHandler.js';
|
||||
import Action from './Action.js';
|
||||
|
||||
/** @extends Node<'Body'> */
|
||||
export default class Body extends Node {
|
||||
/** @type {import('./EventHandler.js').default[]} */
|
||||
handlers = [];
|
||||
|
||||
/** @type {import('./Action.js').default[]} */
|
||||
actions = [];
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./shared/Node.js').default} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').Element} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
info.attributes.forEach((node) => {
|
||||
if (node.type === 'EventHandler') {
|
||||
this.handlers.push(new EventHandler(component, this, scope, node));
|
||||
} else if (node.type === 'Action') {
|
||||
this.actions.push(new Action(component, this, scope, node));
|
||||
} else {
|
||||
// TODO there shouldn't be anything else here...
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
32
frontend/node_modules/svelte/src/compiler/compile/nodes/CatchBlock.js
generated
vendored
Normal file
32
frontend/node_modules/svelte/src/compiler/compile/nodes/CatchBlock.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
import AbstractBlock from './shared/AbstractBlock.js';
|
||||
import get_const_tags from './shared/get_const_tags.js';
|
||||
|
||||
/** @extends AbstractBlock<'CatchBlock'> */
|
||||
export default class CatchBlock extends AbstractBlock {
|
||||
/** @type {import('./shared/TemplateScope.js').default} */
|
||||
scope;
|
||||
|
||||
/** @type {import('./ConstTag.js').default[]} */
|
||||
const_tags;
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./AwaitBlock.js').default} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
this.scope = scope.child();
|
||||
if (parent.catch_node) {
|
||||
parent.catch_contexts.forEach((context) => {
|
||||
if (context.type !== 'DestructuredVariable') return;
|
||||
this.scope.add(context.key.name, parent.expression.dependencies, this);
|
||||
});
|
||||
}
|
||||
[this.const_tags, this.children] = get_const_tags(info.children, component, this, parent);
|
||||
if (!info.skip) {
|
||||
this.warn_if_empty_block();
|
||||
}
|
||||
}
|
||||
}
|
||||
25
frontend/node_modules/svelte/src/compiler/compile/nodes/Class.js
generated
vendored
Normal file
25
frontend/node_modules/svelte/src/compiler/compile/nodes/Class.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
import Node from './shared/Node.js';
|
||||
import Expression from './shared/Expression.js';
|
||||
|
||||
/** @extends Node<'Class'> */
|
||||
export default class Class extends Node {
|
||||
/** @type {string} */
|
||||
name;
|
||||
|
||||
/** @type {import('./shared/Expression.js').default} */
|
||||
expression;
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./shared/Node.js').default} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
this.name = info.name;
|
||||
this.expression = info.expression
|
||||
? new Expression(component, this, scope, info.expression)
|
||||
: null;
|
||||
}
|
||||
}
|
||||
22
frontend/node_modules/svelte/src/compiler/compile/nodes/Comment.js
generated
vendored
Normal file
22
frontend/node_modules/svelte/src/compiler/compile/nodes/Comment.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
import Node from './shared/Node.js';
|
||||
|
||||
/** @extends Node<'Comment'> */
|
||||
export default class Comment extends Node {
|
||||
/** @type {string} */
|
||||
data;
|
||||
|
||||
/** @type {string[]} */
|
||||
ignores;
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./shared/Node.js').default} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
this.data = info.data;
|
||||
this.ignores = info.ignores;
|
||||
}
|
||||
}
|
||||
104
frontend/node_modules/svelte/src/compiler/compile/nodes/ConstTag.js
generated
vendored
Normal file
104
frontend/node_modules/svelte/src/compiler/compile/nodes/ConstTag.js
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
import Node from './shared/Node.js';
|
||||
import Expression from './shared/Expression.js';
|
||||
import { unpack_destructuring } from './shared/Context.js';
|
||||
import { walk } from 'estree-walker';
|
||||
import { extract_identifiers } from 'periscopic';
|
||||
import is_reference from 'is-reference';
|
||||
import get_object from '../utils/get_object.js';
|
||||
import compiler_errors from '../compiler_errors.js';
|
||||
|
||||
const allowed_parents = new Set([
|
||||
'EachBlock',
|
||||
'CatchBlock',
|
||||
'ThenBlock',
|
||||
'InlineComponent',
|
||||
'SlotTemplate',
|
||||
'IfBlock',
|
||||
'ElseBlock'
|
||||
]);
|
||||
|
||||
/** @extends Node<'ConstTag'> */
|
||||
export default class ConstTag extends Node {
|
||||
/** @type {import('./shared/Expression.js').default} */
|
||||
expression;
|
||||
|
||||
/** @type {import('./shared/Context.js').Context[]} */
|
||||
contexts = [];
|
||||
|
||||
/** @type {import('../../interfaces.js').ConstTag} */
|
||||
node;
|
||||
|
||||
/** @type {import('./shared/TemplateScope.js').default} */
|
||||
scope;
|
||||
|
||||
/** @type {Map<string, import('estree').Node>} */
|
||||
context_rest_properties = new Map();
|
||||
|
||||
/** @type {Set<string>} */
|
||||
assignees = new Set();
|
||||
|
||||
/** @type {Set<string>} */
|
||||
dependencies = new Set();
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./interfaces.js').INodeAllowConstTag} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').ConstTag} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
if (!allowed_parents.has(parent.type)) {
|
||||
component.error(info, compiler_errors.invalid_const_placement);
|
||||
}
|
||||
this.node = info;
|
||||
this.scope = scope;
|
||||
const { assignees, dependencies } = this;
|
||||
extract_identifiers(info.expression.left).forEach(({ name }) => {
|
||||
assignees.add(name);
|
||||
const owner = this.scope.get_owner(name);
|
||||
if (owner === parent) {
|
||||
component.error(info, compiler_errors.invalid_const_declaration(name));
|
||||
}
|
||||
});
|
||||
walk(info.expression.right, {
|
||||
/**
|
||||
* @type {import('estree-walker').SyncHandler}
|
||||
*/
|
||||
enter(node, parent) {
|
||||
if (
|
||||
is_reference(
|
||||
/** @type {import('is-reference').NodeWithPropertyDefinition} */ (node),
|
||||
/** @type {import('is-reference').NodeWithPropertyDefinition} */ (parent)
|
||||
)
|
||||
) {
|
||||
const identifier = get_object(node);
|
||||
const { name } = identifier;
|
||||
dependencies.add(name);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
parse_expression() {
|
||||
unpack_destructuring({
|
||||
contexts: this.contexts,
|
||||
node: this.node.expression.left,
|
||||
scope: this.scope,
|
||||
component: this.component,
|
||||
context_rest_properties: this.context_rest_properties
|
||||
});
|
||||
this.expression = new Expression(this.component, this, this.scope, this.node.expression.right);
|
||||
this.contexts.forEach((context) => {
|
||||
if (context.type !== 'DestructuredVariable') return;
|
||||
const owner = this.scope.get_owner(context.key.name);
|
||||
if (owner && owner.type === 'ConstTag' && owner.parent === this.parent) {
|
||||
this.component.error(
|
||||
this.node,
|
||||
compiler_errors.invalid_const_declaration(context.key.name)
|
||||
);
|
||||
}
|
||||
this.scope.add(context.key.name, this.expression.dependencies, this);
|
||||
});
|
||||
}
|
||||
}
|
||||
23
frontend/node_modules/svelte/src/compiler/compile/nodes/DebugTag.js
generated
vendored
Normal file
23
frontend/node_modules/svelte/src/compiler/compile/nodes/DebugTag.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
import Node from './shared/Node.js';
|
||||
import Expression from './shared/Expression.js';
|
||||
|
||||
/** @extends Node<'DebugTag'> */
|
||||
export default class DebugTag extends Node {
|
||||
/** @type {import('./shared/Expression.js').default[]} */
|
||||
expressions;
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./interfaces.js').INode} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
this.expressions = info.identifiers.map(
|
||||
/** @param {import('estree').Node} node */ (node) => {
|
||||
return new Expression(component, parent, scope, node);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
75
frontend/node_modules/svelte/src/compiler/compile/nodes/Document.js
generated
vendored
Normal file
75
frontend/node_modules/svelte/src/compiler/compile/nodes/Document.js
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
import Node from './shared/Node.js';
|
||||
import Binding from './Binding.js';
|
||||
import EventHandler from './EventHandler.js';
|
||||
import fuzzymatch from '../../utils/fuzzymatch.js';
|
||||
import Action from './Action.js';
|
||||
import list from '../../utils/list.js';
|
||||
import compiler_warnings from '../compiler_warnings.js';
|
||||
import compiler_errors from '../compiler_errors.js';
|
||||
|
||||
const valid_bindings = ['fullscreenElement', 'visibilityState'];
|
||||
|
||||
/** @extends Node<'Document'> */
|
||||
export default class Document extends Node {
|
||||
/** @type {import('./EventHandler.js').default[]} */
|
||||
handlers = [];
|
||||
|
||||
/** @type {import('./Binding.js').default[]} */
|
||||
bindings = [];
|
||||
|
||||
/** @type {import('./Action.js').default[]} */
|
||||
actions = [];
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./shared/Node.js').default} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').Element} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
info.attributes.forEach((node) => {
|
||||
if (node.type === 'EventHandler') {
|
||||
this.handlers.push(new EventHandler(component, this, scope, node));
|
||||
} else if (node.type === 'Binding') {
|
||||
if (!~valid_bindings.indexOf(node.name)) {
|
||||
const match = fuzzymatch(node.name, valid_bindings);
|
||||
if (match) {
|
||||
return component.error(
|
||||
node,
|
||||
compiler_errors.invalid_binding_on(
|
||||
node.name,
|
||||
'<svelte:document>',
|
||||
` (did you mean '${match}'?)`
|
||||
)
|
||||
);
|
||||
} else {
|
||||
return component.error(
|
||||
node,
|
||||
compiler_errors.invalid_binding_on(
|
||||
node.name,
|
||||
'<svelte:document>',
|
||||
` — valid bindings are ${list(valid_bindings)}`
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
this.bindings.push(new Binding(component, this, scope, node));
|
||||
} else if (node.type === 'Action') {
|
||||
this.actions.push(new Action(component, this, scope, node));
|
||||
} else {
|
||||
// TODO there shouldn't be anything else here...
|
||||
}
|
||||
});
|
||||
this.validate();
|
||||
}
|
||||
|
||||
/** @private */
|
||||
validate() {
|
||||
const handlers_map = new Set();
|
||||
this.handlers.forEach((handler) => handlers_map.add(handler.name));
|
||||
if (handlers_map.has('mouseenter') || handlers_map.has('mouseleave')) {
|
||||
this.component.warn(this, compiler_warnings.avoid_mouse_events_on_document);
|
||||
}
|
||||
}
|
||||
}
|
||||
114
frontend/node_modules/svelte/src/compiler/compile/nodes/EachBlock.js
generated
vendored
Normal file
114
frontend/node_modules/svelte/src/compiler/compile/nodes/EachBlock.js
generated
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
import ElseBlock from './ElseBlock.js';
|
||||
import Expression from './shared/Expression.js';
|
||||
import AbstractBlock from './shared/AbstractBlock.js';
|
||||
import { unpack_destructuring } from './shared/Context.js';
|
||||
import compiler_errors from '../compiler_errors.js';
|
||||
import get_const_tags from './shared/get_const_tags.js';
|
||||
|
||||
/** @extends AbstractBlock<'EachBlock'> */
|
||||
export default class EachBlock extends AbstractBlock {
|
||||
/** @type {import('./shared/Expression.js').default} */
|
||||
expression;
|
||||
|
||||
/** @type {import('estree').Node} */
|
||||
context_node;
|
||||
|
||||
/** @type {string} */
|
||||
iterations;
|
||||
|
||||
/** @type {string} */
|
||||
index;
|
||||
|
||||
/** @type {string} */
|
||||
context;
|
||||
|
||||
/** @type {import('./shared/Expression.js').default} */
|
||||
key;
|
||||
|
||||
/** @type {import('./shared/TemplateScope.js').default} */
|
||||
scope;
|
||||
|
||||
/** @type {import('./shared/Context.js').Context[]} */
|
||||
contexts;
|
||||
|
||||
/** @type {import('./ConstTag.js').default[]} */
|
||||
const_tags;
|
||||
|
||||
/** @type {boolean} */
|
||||
has_animation;
|
||||
/** */
|
||||
has_binding = false;
|
||||
/** */
|
||||
has_index_binding = false;
|
||||
|
||||
/** @type {Map<string, import('estree').Node>} */
|
||||
context_rest_properties;
|
||||
|
||||
/** @type {import('./ElseBlock.js').default} */
|
||||
else;
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('estree').Node} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
this.cannot_use_innerhtml();
|
||||
this.not_static_content();
|
||||
this.expression = new Expression(component, this, scope, info.expression);
|
||||
this.context = info.context.name || 'each'; // TODO this is used to facilitate binding; currently fails with destructuring
|
||||
this.context_node = info.context;
|
||||
this.index = info.index;
|
||||
this.scope = scope.child();
|
||||
this.context_rest_properties = new Map();
|
||||
this.contexts = [];
|
||||
unpack_destructuring({
|
||||
contexts: this.contexts,
|
||||
node: info.context,
|
||||
scope,
|
||||
component,
|
||||
context_rest_properties: this.context_rest_properties
|
||||
});
|
||||
this.contexts.forEach((context) => {
|
||||
if (context.type !== 'DestructuredVariable') return;
|
||||
this.scope.add(context.key.name, this.expression.dependencies, this);
|
||||
});
|
||||
if (this.index) {
|
||||
// index can only change if this is a keyed each block
|
||||
const dependencies = info.key ? this.expression.dependencies : new Set([]);
|
||||
this.scope.add(this.index, dependencies, this);
|
||||
}
|
||||
this.key = info.key ? new Expression(component, this, this.scope, info.key) : null;
|
||||
this.has_animation = false;
|
||||
[this.const_tags, this.children] = get_const_tags(info.children, component, this, this);
|
||||
if (this.has_animation) {
|
||||
this.children = this.children.filter(
|
||||
(child) => !is_empty_node(child) && !is_comment_node(child)
|
||||
);
|
||||
if (this.children.length !== 1) {
|
||||
const child = this.children.find(
|
||||
(child) => !!(/** @type {import('./Element.js').default} */ (child).animation)
|
||||
);
|
||||
component.error(
|
||||
/** @type {import('./Element.js').default} */ (child).animation,
|
||||
compiler_errors.invalid_animation_sole
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.warn_if_empty_block();
|
||||
this.else = info.else ? new ElseBlock(component, this, this.scope, info.else) : null;
|
||||
}
|
||||
}
|
||||
|
||||
/** @param {import('./interfaces.js').INode} node */
|
||||
function is_empty_node(node) {
|
||||
return node.type === 'Text' && node.data.trim() === '';
|
||||
}
|
||||
|
||||
/** @param {import('./interfaces.js').INode} node */
|
||||
function is_comment_node(node) {
|
||||
return node.type === 'Comment';
|
||||
}
|
||||
1450
frontend/node_modules/svelte/src/compiler/compile/nodes/Element.js
generated
vendored
Normal file
1450
frontend/node_modules/svelte/src/compiler/compile/nodes/Element.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
24
frontend/node_modules/svelte/src/compiler/compile/nodes/ElseBlock.js
generated
vendored
Normal file
24
frontend/node_modules/svelte/src/compiler/compile/nodes/ElseBlock.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
import AbstractBlock from './shared/AbstractBlock.js';
|
||||
import get_const_tags from './shared/get_const_tags.js';
|
||||
|
||||
/** @extends AbstractBlock<'ElseBlock'> */
|
||||
export default class ElseBlock extends AbstractBlock {
|
||||
/** @type {import('./shared/TemplateScope.js').default} */
|
||||
scope;
|
||||
|
||||
/** @type {import('./ConstTag.js').default[]} */
|
||||
const_tags;
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./shared/Node.js').default} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
this.scope = scope.child();
|
||||
[this.const_tags, this.children] = get_const_tags(info.children, component, this, this);
|
||||
this.warn_if_empty_block();
|
||||
}
|
||||
}
|
||||
82
frontend/node_modules/svelte/src/compiler/compile/nodes/EventHandler.js
generated
vendored
Normal file
82
frontend/node_modules/svelte/src/compiler/compile/nodes/EventHandler.js
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
import Node from './shared/Node.js';
|
||||
import Expression from './shared/Expression.js';
|
||||
import { sanitize } from '../../utils/names.js';
|
||||
|
||||
const regex_contains_term_function_expression = /FunctionExpression/;
|
||||
|
||||
/** @extends Node<'EventHandler'> */
|
||||
export default class EventHandler extends Node {
|
||||
/** @type {string} */
|
||||
name;
|
||||
|
||||
/** @type {Set<string>} */
|
||||
modifiers;
|
||||
|
||||
/** @type {import('./shared/Expression.js').default} */
|
||||
expression;
|
||||
|
||||
/** @type {import('estree').Identifier} */
|
||||
handler_name;
|
||||
/** */
|
||||
uses_context = false;
|
||||
/** */
|
||||
can_make_passive = false;
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./shared/Node.js').default} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} template_scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, template_scope, info) {
|
||||
super(component, parent, template_scope, info);
|
||||
this.name = info.name;
|
||||
this.modifiers = new Set(info.modifiers);
|
||||
if (info.expression) {
|
||||
this.expression = new Expression(component, this, template_scope, info.expression);
|
||||
this.uses_context = this.expression.uses_context;
|
||||
if (
|
||||
regex_contains_term_function_expression.test(info.expression.type) &&
|
||||
info.expression.params.length === 0
|
||||
) {
|
||||
// TODO make this detection more accurate — if `event.preventDefault` isn't called, and
|
||||
// `event` is passed to another function, we can make it passive
|
||||
this.can_make_passive = true;
|
||||
} else if (info.expression.type === 'Identifier') {
|
||||
let node = component.node_for_declaration.get(info.expression.name);
|
||||
if (node) {
|
||||
if (node.type === 'VariableDeclaration') {
|
||||
// for `const handleClick = () => {...}`, we want the [arrow] function expression node
|
||||
const declarator = node.declarations.find(
|
||||
(d) => /** @type {import('estree').Identifier} */ (d.id).name === info.expression.name
|
||||
);
|
||||
node = declarator && declarator.init;
|
||||
}
|
||||
if (
|
||||
node &&
|
||||
(node.type === 'FunctionExpression' ||
|
||||
node.type === 'FunctionDeclaration' ||
|
||||
node.type === 'ArrowFunctionExpression') &&
|
||||
node.params.length === 0
|
||||
) {
|
||||
this.can_make_passive = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.handler_name = component.get_unique_name(`${sanitize(this.name)}_handler`);
|
||||
}
|
||||
}
|
||||
|
||||
/** @returns {boolean} */
|
||||
get reassigned() {
|
||||
if (!this.expression) {
|
||||
return false;
|
||||
}
|
||||
const node = this.expression.node;
|
||||
if (regex_contains_term_function_expression.test(node.type)) {
|
||||
return false;
|
||||
}
|
||||
return this.expression.dynamic_dependencies().length > 0;
|
||||
}
|
||||
}
|
||||
26
frontend/node_modules/svelte/src/compiler/compile/nodes/Fragment.js
generated
vendored
Normal file
26
frontend/node_modules/svelte/src/compiler/compile/nodes/Fragment.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
import Node from './shared/Node.js';
|
||||
import map_children from './shared/map_children.js';
|
||||
import TemplateScope from './shared/TemplateScope.js';
|
||||
|
||||
/** @extends Node<'Fragment'> */
|
||||
export default class Fragment extends Node {
|
||||
/** @type {import('../render_dom/Block.js').default} */
|
||||
block;
|
||||
|
||||
/** @type {import('./interfaces.js').INode[]} */
|
||||
children;
|
||||
|
||||
/** @type {import('./shared/TemplateScope.js').default} */
|
||||
scope;
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, info) {
|
||||
const scope = new TemplateScope();
|
||||
super(component, null, scope, info);
|
||||
this.scope = scope;
|
||||
this.children = map_children(component, this, scope, info.children);
|
||||
}
|
||||
}
|
||||
40
frontend/node_modules/svelte/src/compiler/compile/nodes/Head.js
generated
vendored
Normal file
40
frontend/node_modules/svelte/src/compiler/compile/nodes/Head.js
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
import Node from './shared/Node.js';
|
||||
import map_children from './shared/map_children.js';
|
||||
import hash from '../utils/hash.js';
|
||||
import compiler_errors from '../compiler_errors.js';
|
||||
import { regex_non_whitespace_character } from '../../utils/patterns.js';
|
||||
|
||||
/** @extends Node<'Head'> */
|
||||
export default class Head extends Node {
|
||||
/** @type {any[]} */
|
||||
children; // TODO
|
||||
|
||||
/** @type {string} */
|
||||
id;
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./shared/Node.js').default} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
this.cannot_use_innerhtml();
|
||||
if (info.attributes.length) {
|
||||
component.error(info.attributes[0], compiler_errors.invalid_attribute_head);
|
||||
return;
|
||||
}
|
||||
this.children = map_children(
|
||||
component,
|
||||
parent,
|
||||
scope,
|
||||
info.children.filter((child) => {
|
||||
return child.type !== 'Text' || regex_non_whitespace_character.test(child.data);
|
||||
})
|
||||
);
|
||||
if (this.children.length > 0) {
|
||||
this.id = `svelte-${hash(this.component.source.slice(this.start, this.end))}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
36
frontend/node_modules/svelte/src/compiler/compile/nodes/IfBlock.js
generated
vendored
Normal file
36
frontend/node_modules/svelte/src/compiler/compile/nodes/IfBlock.js
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
import ElseBlock from './ElseBlock.js';
|
||||
import Expression from './shared/Expression.js';
|
||||
import AbstractBlock from './shared/AbstractBlock.js';
|
||||
import get_const_tags from './shared/get_const_tags.js';
|
||||
|
||||
/** @extends AbstractBlock<'IfBlock'> */
|
||||
export default class IfBlock extends AbstractBlock {
|
||||
/** @type {import('./shared/Expression.js').default} */
|
||||
expression;
|
||||
|
||||
/** @type {import('./ElseBlock.js').default} */
|
||||
else;
|
||||
|
||||
/** @type {import('./shared/TemplateScope.js').default} */
|
||||
scope;
|
||||
|
||||
/** @type {import('./ConstTag.js').default[]} */
|
||||
const_tags;
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./shared/Node.js').default} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
this.scope = scope.child();
|
||||
this.cannot_use_innerhtml();
|
||||
this.not_static_content();
|
||||
this.expression = new Expression(component, this, this.scope, info.expression);
|
||||
[this.const_tags, this.children] = get_const_tags(info.children, component, this, this);
|
||||
this.else = info.else ? new ElseBlock(component, this, scope, info.else) : null;
|
||||
this.warn_if_empty_block();
|
||||
}
|
||||
}
|
||||
199
frontend/node_modules/svelte/src/compiler/compile/nodes/InlineComponent.js
generated
vendored
Normal file
199
frontend/node_modules/svelte/src/compiler/compile/nodes/InlineComponent.js
generated
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
import Node from './shared/Node.js';
|
||||
import Attribute from './Attribute.js';
|
||||
import map_children from './shared/map_children.js';
|
||||
import Binding from './Binding.js';
|
||||
import EventHandler from './EventHandler.js';
|
||||
import Expression from './shared/Expression.js';
|
||||
import compiler_errors from '../compiler_errors.js';
|
||||
import { regex_only_whitespaces } from '../../utils/patterns.js';
|
||||
|
||||
/** @extends Node<'InlineComponent'> */
|
||||
export default class InlineComponent extends Node {
|
||||
/** @type {string} */
|
||||
name;
|
||||
|
||||
/** @type {import('./shared/Expression.js').default} */
|
||||
expression;
|
||||
|
||||
/** @type {import('./Binding.js').default[]} */
|
||||
bindings = [];
|
||||
|
||||
/** @type {import('./EventHandler.js').default[]} */
|
||||
handlers = [];
|
||||
|
||||
/** @type {import('./Attribute.js').default[]} */
|
||||
css_custom_properties = [];
|
||||
|
||||
/** @type {import('./interfaces.js').INode[]} */
|
||||
children;
|
||||
|
||||
/** @type {import('./shared/TemplateScope.js').default} */
|
||||
scope;
|
||||
|
||||
/** @type {string} */
|
||||
namespace;
|
||||
|
||||
/** @type {Attribute[]} */
|
||||
let_attributes;
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./shared/Node.js').default} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
this.cannot_use_innerhtml();
|
||||
this.not_static_content();
|
||||
if (info.name !== 'svelte:component' && info.name !== 'svelte:self') {
|
||||
const name = info.name.split('.')[0]; // accommodate namespaces
|
||||
component.warn_if_undefined(name, info, scope);
|
||||
component.add_reference(/** @type {any} */ (this), name);
|
||||
}
|
||||
this.name = info.name;
|
||||
this.namespace = get_namespace(parent, component.namespace);
|
||||
this.expression =
|
||||
this.name === 'svelte:component'
|
||||
? new Expression(component, this, scope, info.expression)
|
||||
: null;
|
||||
|
||||
const let_attributes = (this.let_attributes = []);
|
||||
info.attributes.forEach(
|
||||
/** @param {import('../../interfaces.js').BaseDirective | import('../../interfaces.js').Attribute | import('../../interfaces.js').SpreadAttribute} node */ (
|
||||
node
|
||||
) => {
|
||||
/* eslint-disable no-fallthrough */
|
||||
switch (node.type) {
|
||||
case 'Action':
|
||||
return component.error(node, compiler_errors.invalid_action);
|
||||
case 'Attribute':
|
||||
if (node.name.startsWith('--')) {
|
||||
this.css_custom_properties.push(new Attribute(component, this, scope, node));
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
case 'Spread':
|
||||
this.attributes.push(new Attribute(component, this, scope, node));
|
||||
break;
|
||||
case 'Binding':
|
||||
this.bindings.push(new Binding(component, this, scope, node));
|
||||
break;
|
||||
case 'Class':
|
||||
return component.error(node, compiler_errors.invalid_class);
|
||||
case 'EventHandler':
|
||||
this.handlers.push(new EventHandler(component, this, scope, node));
|
||||
break;
|
||||
case 'Let':
|
||||
let_attributes.push(node);
|
||||
break;
|
||||
case 'Transition':
|
||||
return component.error(node, compiler_errors.invalid_transition);
|
||||
case 'StyleDirective':
|
||||
return component.error(node, compiler_errors.invalid_component_style_directive);
|
||||
case 'Animation':
|
||||
return component.error(node, compiler_errors.invalid_animation);
|
||||
default:
|
||||
throw new Error(`Not implemented: ${node.type}`);
|
||||
}
|
||||
/* eslint-enable no-fallthrough */
|
||||
}
|
||||
);
|
||||
|
||||
this.scope = scope;
|
||||
|
||||
this.handlers.forEach((handler) => {
|
||||
handler.modifiers.forEach((modifier) => {
|
||||
if (modifier !== 'once') {
|
||||
return component.error(handler, compiler_errors.invalid_event_modifier_component);
|
||||
}
|
||||
});
|
||||
});
|
||||
const children = [];
|
||||
for (let i = info.children.length - 1; i >= 0; i--) {
|
||||
const child = info.children[i];
|
||||
if (child.type === 'SlotTemplate') {
|
||||
children.push(child);
|
||||
info.children.splice(i, 1);
|
||||
} else if (
|
||||
(child.type === 'Element' || child.type === 'InlineComponent' || child.type === 'Slot') &&
|
||||
child.attributes.find((attribute) => attribute.name === 'slot')
|
||||
) {
|
||||
const slot_template = {
|
||||
start: child.start,
|
||||
end: child.end,
|
||||
type: 'SlotTemplate',
|
||||
name: 'svelte:fragment',
|
||||
attributes: [],
|
||||
children: [child]
|
||||
};
|
||||
// transfer attributes
|
||||
for (let i = child.attributes.length - 1; i >= 0; i--) {
|
||||
const attribute = child.attributes[i];
|
||||
if (attribute.type === 'Let') {
|
||||
slot_template.attributes.push(attribute);
|
||||
child.attributes.splice(i, 1);
|
||||
} else if (attribute.type === 'Attribute' && attribute.name === 'slot') {
|
||||
slot_template.attributes.push(attribute);
|
||||
}
|
||||
}
|
||||
// transfer const
|
||||
for (let i = child.children.length - 1; i >= 0; i--) {
|
||||
const child_child = child.children[i];
|
||||
if (child_child.type === 'ConstTag') {
|
||||
slot_template.children.push(child_child);
|
||||
child.children.splice(i, 1);
|
||||
}
|
||||
}
|
||||
children.push(slot_template);
|
||||
info.children.splice(i, 1);
|
||||
} else if (child.type === 'Comment' && children.length > 0) {
|
||||
children[children.length - 1].children.unshift(child);
|
||||
}
|
||||
}
|
||||
if (info.children.some((node) => not_whitespace_text(node))) {
|
||||
children.push({
|
||||
start: info.start,
|
||||
end: info.end,
|
||||
type: 'SlotTemplate',
|
||||
name: 'svelte:fragment',
|
||||
attributes: [],
|
||||
children: info.children
|
||||
});
|
||||
}
|
||||
|
||||
if (let_attributes.length) {
|
||||
// copy let: attribute from <Component /> to <svelte:fragment slot="default" />
|
||||
// as they are for `slot="default"` only
|
||||
children.forEach((child) => {
|
||||
const slot = child.attributes.find((attribute) => attribute.name === 'slot');
|
||||
if (!slot || slot.value[0].data === 'default') {
|
||||
child.attributes.push(...let_attributes);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.children = map_children(component, this, this.scope, children);
|
||||
}
|
||||
get slot_template_name() {
|
||||
return /** @type {string} */ (
|
||||
this.attributes.find((attribute) => attribute.name === 'slot').get_static_value()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/** @param {any} node */
|
||||
function not_whitespace_text(node) {
|
||||
return !(node.type === 'Text' && regex_only_whitespaces.test(node.data));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('./shared/Node.js').default} parent
|
||||
* @param {string} explicit_namespace
|
||||
*/
|
||||
function get_namespace(parent, explicit_namespace) {
|
||||
const parent_element = parent.find_nearest(/^Element/);
|
||||
if (!parent_element) {
|
||||
return explicit_namespace;
|
||||
}
|
||||
return parent_element.namespace;
|
||||
}
|
||||
24
frontend/node_modules/svelte/src/compiler/compile/nodes/KeyBlock.js
generated
vendored
Normal file
24
frontend/node_modules/svelte/src/compiler/compile/nodes/KeyBlock.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
import Expression from './shared/Expression.js';
|
||||
import map_children from './shared/map_children.js';
|
||||
import AbstractBlock from './shared/AbstractBlock.js';
|
||||
|
||||
/** @extends AbstractBlock<'KeyBlock'> */
|
||||
export default class KeyBlock extends AbstractBlock {
|
||||
/** @type {import('./shared/Expression.js').default} */
|
||||
expression;
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./shared/Node.js').default} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
this.cannot_use_innerhtml();
|
||||
this.not_static_content();
|
||||
this.expression = new Expression(component, this, scope, info.expression);
|
||||
this.children = map_children(component, this, scope, info.children);
|
||||
this.warn_if_empty_block();
|
||||
}
|
||||
}
|
||||
52
frontend/node_modules/svelte/src/compiler/compile/nodes/Let.js
generated
vendored
Normal file
52
frontend/node_modules/svelte/src/compiler/compile/nodes/Let.js
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
import Node from './shared/Node.js';
|
||||
import { walk } from 'estree-walker';
|
||||
import compiler_errors from '../compiler_errors.js';
|
||||
|
||||
const applicable = new Set(['Identifier', 'ObjectExpression', 'ArrayExpression', 'Property']);
|
||||
|
||||
/** @extends Node<'Let'> */
|
||||
export default class Let extends Node {
|
||||
/** @type {import('estree').Identifier} */
|
||||
name;
|
||||
|
||||
/** @type {import('estree').Identifier} */
|
||||
value;
|
||||
|
||||
/** @type {string[]} */
|
||||
names = [];
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./shared/Node.js').default} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
this.name = { type: 'Identifier', name: info.name };
|
||||
const { names } = this;
|
||||
if (info.expression) {
|
||||
this.value = info.expression;
|
||||
walk(info.expression, {
|
||||
/** @param {import('estree').Identifier | import('estree').BasePattern} node */
|
||||
enter(node) {
|
||||
if (!applicable.has(node.type)) {
|
||||
return component.error(/** @type {any} */ (node), compiler_errors.invalid_let);
|
||||
}
|
||||
if (node.type === 'Identifier') {
|
||||
names.push(/** @type {import('estree').Identifier} */ (node).name);
|
||||
}
|
||||
// slightly unfortunate hack
|
||||
if (node.type === 'ArrayExpression') {
|
||||
node.type = 'ArrayPattern';
|
||||
}
|
||||
if (node.type === 'ObjectExpression') {
|
||||
node.type = 'ObjectPattern';
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
names.push(this.name.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
4
frontend/node_modules/svelte/src/compiler/compile/nodes/MustacheTag.js
generated
vendored
Normal file
4
frontend/node_modules/svelte/src/compiler/compile/nodes/MustacheTag.js
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import Tag from './shared/Tag.js';
|
||||
|
||||
/** @extends Tag<'MustacheTag'> */
|
||||
export default class MustacheTag extends Tag {}
|
||||
4
frontend/node_modules/svelte/src/compiler/compile/nodes/Options.js
generated
vendored
Normal file
4
frontend/node_modules/svelte/src/compiler/compile/nodes/Options.js
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import Node from './shared/Node.js';
|
||||
|
||||
/** @extends Node<'Options'> */
|
||||
export default class Options extends Node {}
|
||||
19
frontend/node_modules/svelte/src/compiler/compile/nodes/PendingBlock.js
generated
vendored
Normal file
19
frontend/node_modules/svelte/src/compiler/compile/nodes/PendingBlock.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
import map_children from './shared/map_children.js';
|
||||
import AbstractBlock from './shared/AbstractBlock.js';
|
||||
|
||||
/** @extends AbstractBlock<'PendingBlock'> */
|
||||
export default class PendingBlock extends AbstractBlock {
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./shared/Node.js').default} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
this.children = map_children(component, parent, scope, info.children);
|
||||
if (!info.skip) {
|
||||
this.warn_if_empty_block();
|
||||
}
|
||||
}
|
||||
}
|
||||
16
frontend/node_modules/svelte/src/compiler/compile/nodes/RawMustacheTag.js
generated
vendored
Normal file
16
frontend/node_modules/svelte/src/compiler/compile/nodes/RawMustacheTag.js
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
import Tag from './shared/Tag.js';
|
||||
|
||||
/** @extends Tag<'RawMustacheTag'> */
|
||||
export default class RawMustacheTag extends Tag {
|
||||
/**
|
||||
* @param {any} component
|
||||
* @param {any} parent
|
||||
* @param {any} scope
|
||||
* @param {any} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
this.cannot_use_innerhtml();
|
||||
this.not_static_content();
|
||||
}
|
||||
}
|
||||
46
frontend/node_modules/svelte/src/compiler/compile/nodes/Slot.js
generated
vendored
Normal file
46
frontend/node_modules/svelte/src/compiler/compile/nodes/Slot.js
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
import Element from './Element.js';
|
||||
import Attribute from './Attribute.js';
|
||||
import compiler_errors from '../compiler_errors.js';
|
||||
|
||||
/** @extends Element */
|
||||
export default class Slot extends Element {
|
||||
/** @type {'Slot'} */
|
||||
// @ts-ignore Slot elements have the 'Slot' type, but TypeScript doesn't allow us to have 'Slot' when it extends Element
|
||||
type = 'Slot';
|
||||
|
||||
/** @type {string} */
|
||||
slot_name;
|
||||
|
||||
/** @type {Map<string, import('./Attribute.js').default>} */
|
||||
values = new Map();
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./interfaces.js').INode} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
info.attributes.forEach((attr) => {
|
||||
if (attr.type !== 'Attribute' && attr.type !== 'Spread') {
|
||||
return component.error(attr, compiler_errors.invalid_slot_directive);
|
||||
}
|
||||
if (attr.name === 'name') {
|
||||
if (attr.value.length !== 1 || attr.value[0].type !== 'Text') {
|
||||
return component.error(attr, compiler_errors.dynamic_slot_name);
|
||||
}
|
||||
this.slot_name = attr.value[0].data;
|
||||
if (this.slot_name === 'default') {
|
||||
return component.error(attr, compiler_errors.invalid_slot_name);
|
||||
}
|
||||
}
|
||||
this.values.set(attr.name, new Attribute(component, this, scope, attr));
|
||||
});
|
||||
if (!this.slot_name) this.slot_name = 'default';
|
||||
|
||||
component.slots.set(this.slot_name, this);
|
||||
this.cannot_use_innerhtml();
|
||||
this.not_static_content();
|
||||
}
|
||||
}
|
||||
75
frontend/node_modules/svelte/src/compiler/compile/nodes/SlotTemplate.js
generated
vendored
Normal file
75
frontend/node_modules/svelte/src/compiler/compile/nodes/SlotTemplate.js
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
import Node from './shared/Node.js';
|
||||
import Let from './Let.js';
|
||||
import Attribute from './Attribute.js';
|
||||
import compiler_errors from '../compiler_errors.js';
|
||||
import get_const_tags from './shared/get_const_tags.js';
|
||||
|
||||
/** @extends Node<'SlotTemplate'> */
|
||||
export default class SlotTemplate extends Node {
|
||||
/** @type {import('./shared/TemplateScope.js').default} */
|
||||
scope;
|
||||
|
||||
/** @type {import('./interfaces.js').INode[]} */
|
||||
children;
|
||||
|
||||
/** @type {import('./Let.js').default[]} */
|
||||
lets = [];
|
||||
|
||||
/** @type {import('./ConstTag.js').default[]} */
|
||||
const_tags;
|
||||
|
||||
/** @type {import('./Attribute.js').default} */
|
||||
slot_attribute;
|
||||
|
||||
/** @type {string} */
|
||||
slot_template_name = 'default';
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./interfaces.js').INode} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {any} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
this.validate_slot_template_placement();
|
||||
scope = scope.child();
|
||||
info.attributes.forEach((node) => {
|
||||
switch (node.type) {
|
||||
case 'Let': {
|
||||
const l = new Let(component, this, scope, node);
|
||||
this.lets.push(l);
|
||||
const dependencies = new Set([l.name.name]);
|
||||
l.names.forEach((name) => {
|
||||
scope.add(name, dependencies, this);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'Attribute': {
|
||||
if (node.name === 'slot') {
|
||||
this.slot_attribute = new Attribute(component, this, scope, node);
|
||||
if (!this.slot_attribute.is_static) {
|
||||
return component.error(node, compiler_errors.invalid_slot_attribute);
|
||||
}
|
||||
const value = this.slot_attribute.get_static_value();
|
||||
if (typeof value === 'boolean') {
|
||||
return component.error(node, compiler_errors.invalid_slot_attribute_value_missing);
|
||||
}
|
||||
this.slot_template_name = /** @type {string} */ (value);
|
||||
break;
|
||||
}
|
||||
throw new Error(`Invalid attribute '${node.name}' in <svelte:fragment>`);
|
||||
}
|
||||
default:
|
||||
throw new Error(`Not implemented: ${node.type}`);
|
||||
}
|
||||
});
|
||||
this.scope = scope;
|
||||
[this.const_tags, this.children] = get_const_tags(info.children, component, this, this);
|
||||
}
|
||||
validate_slot_template_placement() {
|
||||
if (this.parent.type !== 'InlineComponent') {
|
||||
return this.component.error(this, compiler_errors.invalid_slotted_content_fragment);
|
||||
}
|
||||
}
|
||||
}
|
||||
64
frontend/node_modules/svelte/src/compiler/compile/nodes/StyleDirective.js
generated
vendored
Normal file
64
frontend/node_modules/svelte/src/compiler/compile/nodes/StyleDirective.js
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
import list from '../../utils/list.js';
|
||||
import compiler_errors from '../compiler_errors.js';
|
||||
import { nodes_to_template_literal } from '../utils/nodes_to_template_literal.js';
|
||||
import Expression from './shared/Expression.js';
|
||||
import Node from './shared/Node.js';
|
||||
|
||||
const valid_modifiers = new Set(['important']);
|
||||
|
||||
/** @extends Node<'StyleDirective'> */
|
||||
export default class StyleDirective extends Node {
|
||||
/** @type {string} */
|
||||
name;
|
||||
|
||||
/** @type {Set<string>} */
|
||||
modifiers;
|
||||
|
||||
/** @type {import('./shared/Expression.js').default} */
|
||||
expression;
|
||||
|
||||
/** @type {boolean} */
|
||||
should_cache;
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./shared/Node.js').default} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
this.name = info.name;
|
||||
this.modifiers = new Set(info.modifiers);
|
||||
for (const modifier of this.modifiers) {
|
||||
if (!valid_modifiers.has(modifier)) {
|
||||
component.error(
|
||||
this,
|
||||
compiler_errors.invalid_style_directive_modifier(list([...valid_modifiers]))
|
||||
);
|
||||
}
|
||||
}
|
||||
// Convert the value array to an expression so it's easier to handle
|
||||
// the StyleDirective going forward.
|
||||
if (info.value === true || (info.value.length === 1 && info.value[0].type === 'MustacheTag')) {
|
||||
const identifier =
|
||||
info.value === true
|
||||
? {
|
||||
type: 'Identifier',
|
||||
start: info.end - info.name.length,
|
||||
end: info.end,
|
||||
name: info.name
|
||||
}
|
||||
: info.value[0].expression;
|
||||
this.expression = new Expression(component, this, scope, identifier);
|
||||
this.should_cache = false;
|
||||
} else {
|
||||
const raw_expression = nodes_to_template_literal(info.value);
|
||||
this.expression = new Expression(component, this, scope, raw_expression);
|
||||
this.should_cache = raw_expression.expressions.length > 0;
|
||||
}
|
||||
}
|
||||
get important() {
|
||||
return this.modifiers.has('important');
|
||||
}
|
||||
}
|
||||
68
frontend/node_modules/svelte/src/compiler/compile/nodes/Text.js
generated
vendored
Normal file
68
frontend/node_modules/svelte/src/compiler/compile/nodes/Text.js
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
import Node from './shared/Node.js';
|
||||
import { regex_non_whitespace_character } from '../../utils/patterns.js';
|
||||
|
||||
// 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)
|
||||
const elements_without_text = new Set(['audio', 'datalist', 'dl', 'optgroup', 'select', 'video']);
|
||||
const regex_ends_with_svg = /svg$/;
|
||||
const regex_non_whitespace_characters = /[\S\u00A0]/;
|
||||
|
||||
/** @extends Node<'Text'> */
|
||||
export default class Text extends Node {
|
||||
/** @type {string} */
|
||||
data;
|
||||
|
||||
/** @type {boolean} */
|
||||
synthetic;
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./interfaces.js').INode} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
this.data = info.data;
|
||||
this.synthetic = info.synthetic || false;
|
||||
}
|
||||
should_skip() {
|
||||
if (regex_non_whitespace_character.test(this.data)) return false;
|
||||
const parent_element = this.find_nearest(/(?:Element|InlineComponent|SlotTemplate|Head)/);
|
||||
if (!parent_element) return false;
|
||||
if (parent_element.type === 'Head') return true;
|
||||
if (parent_element.type === 'InlineComponent')
|
||||
return parent_element.children.length === 1 && this === parent_element.children[0];
|
||||
// svg namespace exclusions
|
||||
if (regex_ends_with_svg.test(parent_element.namespace)) {
|
||||
if (this.prev && this.prev.type === 'Element' && this.prev.name === 'tspan') return false;
|
||||
}
|
||||
return parent_element.namespace || elements_without_text.has(parent_element.name);
|
||||
}
|
||||
|
||||
/** @returns {boolean} */
|
||||
keep_space() {
|
||||
if (this.component.component_options.preserveWhitespace) return true;
|
||||
return this.within_pre();
|
||||
}
|
||||
|
||||
/** @returns {boolean} */
|
||||
within_pre() {
|
||||
let node = this.parent;
|
||||
while (node) {
|
||||
if (node.type === 'Element' && node.name === 'pre') {
|
||||
return true;
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @returns {boolean} */
|
||||
use_space() {
|
||||
if (this.component.compile_options.preserveWhitespace) return false;
|
||||
if (regex_non_whitespace_characters.test(this.data)) return false;
|
||||
return !this.within_pre();
|
||||
}
|
||||
}
|
||||
32
frontend/node_modules/svelte/src/compiler/compile/nodes/ThenBlock.js
generated
vendored
Normal file
32
frontend/node_modules/svelte/src/compiler/compile/nodes/ThenBlock.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
import AbstractBlock from './shared/AbstractBlock.js';
|
||||
import get_const_tags from './shared/get_const_tags.js';
|
||||
|
||||
/** @extends AbstractBlock<'ThenBlock'> */
|
||||
export default class ThenBlock extends AbstractBlock {
|
||||
/** @type {import('./shared/TemplateScope.js').default} */
|
||||
scope;
|
||||
|
||||
/** @type {import('./ConstTag.js').default[]} */
|
||||
const_tags;
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./AwaitBlock.js').default} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
this.scope = scope.child();
|
||||
if (parent.then_node) {
|
||||
parent.then_contexts.forEach((context) => {
|
||||
if (context.type !== 'DestructuredVariable') return;
|
||||
this.scope.add(context.key.name, parent.expression.dependencies, this);
|
||||
});
|
||||
}
|
||||
[this.const_tags, this.children] = get_const_tags(info.children, component, this, parent);
|
||||
if (!info.skip) {
|
||||
this.warn_if_empty_block();
|
||||
}
|
||||
}
|
||||
}
|
||||
36
frontend/node_modules/svelte/src/compiler/compile/nodes/Title.js
generated
vendored
Normal file
36
frontend/node_modules/svelte/src/compiler/compile/nodes/Title.js
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
import Node from './shared/Node.js';
|
||||
import map_children from './shared/map_children.js';
|
||||
import compiler_errors from '../compiler_errors.js';
|
||||
|
||||
/** @extends Node<'Title'> */
|
||||
export default class Title extends Node {
|
||||
/** @type {import('./shared/map_children.js').Children} */
|
||||
children;
|
||||
|
||||
/** @type {boolean} */
|
||||
should_cache;
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./shared/Node.js').default} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
this.children = map_children(component, parent, scope, info.children);
|
||||
if (info.attributes.length > 0) {
|
||||
component.error(info.attributes[0], compiler_errors.illegal_attribute_title);
|
||||
return;
|
||||
}
|
||||
info.children.forEach((child) => {
|
||||
if (child.type !== 'Text' && child.type !== 'MustacheTag') {
|
||||
return component.error(child, compiler_errors.illegal_structure_title);
|
||||
}
|
||||
});
|
||||
this.should_cache =
|
||||
info.children.length === 1
|
||||
? info.children[0].type !== 'Identifier' || scope.names.has(info.children[0].name)
|
||||
: true;
|
||||
}
|
||||
}
|
||||
44
frontend/node_modules/svelte/src/compiler/compile/nodes/Transition.js
generated
vendored
Normal file
44
frontend/node_modules/svelte/src/compiler/compile/nodes/Transition.js
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
import Node from './shared/Node.js';
|
||||
import Expression from './shared/Expression.js';
|
||||
import compiler_errors from '../compiler_errors.js';
|
||||
|
||||
/** @extends Node<'Transition'> */
|
||||
export default class Transition extends Node {
|
||||
/** @type {string} */
|
||||
name;
|
||||
|
||||
/** @type {string} */
|
||||
directive;
|
||||
|
||||
/** @type {import('./shared/Expression.js').default} */
|
||||
expression;
|
||||
|
||||
/** @type {boolean} */
|
||||
is_local;
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./Element.js').default} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
component.warn_if_undefined(info.name, info, scope);
|
||||
this.name = info.name;
|
||||
component.add_reference(/** @type {any} */ (this), info.name.split('.')[0]);
|
||||
this.directive = info.intro && info.outro ? 'transition' : info.intro ? 'in' : 'out';
|
||||
this.is_local = !info.modifiers.includes('global');
|
||||
if ((info.intro && parent.intro) || (info.outro && parent.outro)) {
|
||||
const parent_transition = parent.intro || parent.outro;
|
||||
component.error(
|
||||
info,
|
||||
compiler_errors.duplicate_transition(this.directive, parent_transition.directive)
|
||||
);
|
||||
return;
|
||||
}
|
||||
this.expression = info.expression
|
||||
? new Expression(component, this, scope, info.expression)
|
||||
: null;
|
||||
}
|
||||
}
|
||||
84
frontend/node_modules/svelte/src/compiler/compile/nodes/Window.js
generated
vendored
Normal file
84
frontend/node_modules/svelte/src/compiler/compile/nodes/Window.js
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
import Node from './shared/Node.js';
|
||||
import Binding from './Binding.js';
|
||||
import EventHandler from './EventHandler.js';
|
||||
import flatten_reference from '../utils/flatten_reference.js';
|
||||
import fuzzymatch from '../../utils/fuzzymatch.js';
|
||||
import list from '../../utils/list.js';
|
||||
import Action from './Action.js';
|
||||
import compiler_errors from '../compiler_errors.js';
|
||||
|
||||
const valid_bindings = [
|
||||
'innerWidth',
|
||||
'innerHeight',
|
||||
'outerWidth',
|
||||
'outerHeight',
|
||||
'scrollX',
|
||||
'scrollY',
|
||||
'devicePixelRatio',
|
||||
'online'
|
||||
];
|
||||
|
||||
/** @extends Node<'Window'> */
|
||||
export default class Window extends Node {
|
||||
/** @type {import('./EventHandler.js').default[]} */
|
||||
handlers = [];
|
||||
|
||||
/** @type {import('./Binding.js').default[]} */
|
||||
bindings = [];
|
||||
|
||||
/** @type {import('./Action.js').default[]} */
|
||||
actions = [];
|
||||
|
||||
/**
|
||||
* @param {import('../Component.js').default} component
|
||||
* @param {import('./shared/Node.js').default} parent
|
||||
* @param {import('./shared/TemplateScope.js').default} scope
|
||||
* @param {import('../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
info.attributes.forEach((node) => {
|
||||
if (node.type === 'EventHandler') {
|
||||
this.handlers.push(new EventHandler(component, this, scope, node));
|
||||
} else if (node.type === 'Binding') {
|
||||
if (node.expression.type !== 'Identifier') {
|
||||
const { parts } = flatten_reference(node.expression);
|
||||
// TODO is this constraint necessary?
|
||||
return component.error(node.expression, compiler_errors.invalid_binding_window(parts));
|
||||
}
|
||||
if (!~valid_bindings.indexOf(node.name)) {
|
||||
const match =
|
||||
node.name === 'width'
|
||||
? 'innerWidth'
|
||||
: node.name === 'height'
|
||||
? 'innerHeight'
|
||||
: fuzzymatch(node.name, valid_bindings);
|
||||
if (match) {
|
||||
return component.error(
|
||||
node,
|
||||
compiler_errors.invalid_binding_on(
|
||||
node.name,
|
||||
'<svelte:window>',
|
||||
` (did you mean '${match}'?)`
|
||||
)
|
||||
);
|
||||
} else {
|
||||
return component.error(
|
||||
node,
|
||||
compiler_errors.invalid_binding_on(
|
||||
node.name,
|
||||
'<svelte:window>',
|
||||
` — valid bindings are ${list(valid_bindings)}`
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
this.bindings.push(new Binding(component, this, scope, node));
|
||||
} else if (node.type === 'Action') {
|
||||
this.actions.push(new Action(component, this, scope, node));
|
||||
} else {
|
||||
// TODO there shouldn't be anything else here...
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
83
frontend/node_modules/svelte/src/compiler/compile/nodes/interfaces.d.ts
generated
vendored
Normal file
83
frontend/node_modules/svelte/src/compiler/compile/nodes/interfaces.d.ts
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
import Tag from './shared/Tag';
|
||||
import Action from './Action';
|
||||
import Animation from './Animation';
|
||||
import Attribute from './Attribute';
|
||||
import AwaitBlock from './AwaitBlock';
|
||||
import Binding from './Binding';
|
||||
import Body from './Body';
|
||||
import CatchBlock from './CatchBlock';
|
||||
import Class from './Class';
|
||||
import StyleDirective from './StyleDirective';
|
||||
import Comment from './Comment';
|
||||
import ConstTag from './ConstTag';
|
||||
import DebugTag from './DebugTag';
|
||||
import Document from './Document';
|
||||
import EachBlock from './EachBlock';
|
||||
import Element from './Element';
|
||||
import ElseBlock from './ElseBlock';
|
||||
import EventHandler from './EventHandler';
|
||||
import Fragment from './Fragment';
|
||||
import Head from './Head';
|
||||
import IfBlock from './IfBlock';
|
||||
import InlineComponent from './InlineComponent';
|
||||
import KeyBlock from './KeyBlock';
|
||||
import Let from './Let';
|
||||
import MustacheTag from './MustacheTag';
|
||||
import Options from './Options';
|
||||
import PendingBlock from './PendingBlock';
|
||||
import RawMustacheTag from './RawMustacheTag';
|
||||
import Slot from './Slot';
|
||||
import SlotTemplate from './SlotTemplate';
|
||||
import Text from './Text';
|
||||
import ThenBlock from './ThenBlock';
|
||||
import Title from './Title';
|
||||
import Transition from './Transition';
|
||||
import Window from './Window';
|
||||
|
||||
// note: to write less types each of types in union below should have type defined as literal
|
||||
// https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html#discriminating-unions
|
||||
export type INode =
|
||||
| Action
|
||||
| Animation
|
||||
| Attribute
|
||||
| AwaitBlock
|
||||
| Binding
|
||||
| Body
|
||||
| CatchBlock
|
||||
| Class
|
||||
| Comment
|
||||
| ConstTag
|
||||
| DebugTag
|
||||
| Document
|
||||
| EachBlock
|
||||
| Element
|
||||
| ElseBlock
|
||||
| EventHandler
|
||||
| Fragment
|
||||
| Head
|
||||
| IfBlock
|
||||
| InlineComponent
|
||||
| KeyBlock
|
||||
| Let
|
||||
| MustacheTag
|
||||
| Options
|
||||
| PendingBlock
|
||||
| RawMustacheTag
|
||||
| Slot
|
||||
| SlotTemplate
|
||||
| StyleDirective
|
||||
| Tag
|
||||
| Text
|
||||
| ThenBlock
|
||||
| Title
|
||||
| Transition
|
||||
| Window;
|
||||
|
||||
export type INodeAllowConstTag =
|
||||
| IfBlock
|
||||
| ElseBlock
|
||||
| EachBlock
|
||||
| CatchBlock
|
||||
| ThenBlock
|
||||
| InlineComponent
|
||||
| SlotTemplate;
|
||||
33
frontend/node_modules/svelte/src/compiler/compile/nodes/shared/AbstractBlock.js
generated
vendored
Normal file
33
frontend/node_modules/svelte/src/compiler/compile/nodes/shared/AbstractBlock.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
import Node from './Node.js';
|
||||
import compiler_warnings from '../../compiler_warnings.js';
|
||||
|
||||
const regex_non_whitespace_characters = /[^ \r\n\f\v\t]/;
|
||||
|
||||
/**
|
||||
* @template {string} Type
|
||||
* @extends Node<Type>
|
||||
*/
|
||||
export default class AbstractBlock extends Node {
|
||||
/** @type {import('../../render_dom/Block.js').default} */
|
||||
block;
|
||||
|
||||
/** @type {import('../interfaces.js').INode[]} */
|
||||
children;
|
||||
|
||||
/**
|
||||
* @param {import('../../Component.js').default} component
|
||||
* @param {any} parent
|
||||
* @param {any} scope
|
||||
* @param {any} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
}
|
||||
warn_if_empty_block() {
|
||||
if (!this.children || this.children.length > 1) return;
|
||||
const child = this.children[0];
|
||||
if (!child || (child.type === 'Text' && !regex_non_whitespace_characters.test(child.data))) {
|
||||
this.component.warn(this, compiler_warnings.empty_block);
|
||||
}
|
||||
}
|
||||
}
|
||||
249
frontend/node_modules/svelte/src/compiler/compile/nodes/shared/Context.js
generated
vendored
Normal file
249
frontend/node_modules/svelte/src/compiler/compile/nodes/shared/Context.js
generated
vendored
Normal file
@@ -0,0 +1,249 @@
|
||||
import { x } from 'code-red';
|
||||
import { walk } from 'estree-walker';
|
||||
import is_reference from 'is-reference';
|
||||
import { clone } from '../../../utils/clone.js';
|
||||
import flatten_reference from '../../utils/flatten_reference.js';
|
||||
/**
|
||||
* @param {{
|
||||
* contexts: Context[];
|
||||
* node: import('estree').Pattern;
|
||||
* modifier?: DestructuredVariable['modifier'];
|
||||
* default_modifier?: DestructuredVariable['default_modifier'];
|
||||
* scope: import('./TemplateScope.js').default;
|
||||
* component: import('../../Component.js').default;
|
||||
* context_rest_properties: Map<string, import('estree').Node>;
|
||||
* in_rest_element?: boolean;
|
||||
* }} params
|
||||
*/
|
||||
export function unpack_destructuring({
|
||||
contexts,
|
||||
node,
|
||||
modifier = (node) => node,
|
||||
default_modifier = (node) => node,
|
||||
scope,
|
||||
component,
|
||||
context_rest_properties,
|
||||
in_rest_element = false
|
||||
}) {
|
||||
if (!node) return;
|
||||
if (node.type === 'Identifier') {
|
||||
contexts.push({
|
||||
type: 'DestructuredVariable',
|
||||
key: /** @type {import('estree').Identifier} */ (node),
|
||||
modifier,
|
||||
default_modifier
|
||||
});
|
||||
if (in_rest_element) {
|
||||
context_rest_properties.set(node.name, node);
|
||||
}
|
||||
component.used_names.add(node.name);
|
||||
} else if (node.type === 'ArrayPattern') {
|
||||
node.elements.forEach((element, i) => {
|
||||
if (!element) {
|
||||
return;
|
||||
} else if (element.type === 'RestElement') {
|
||||
unpack_destructuring({
|
||||
contexts,
|
||||
node: element.argument,
|
||||
modifier: (node) =>
|
||||
/** @type {import('estree').Node} */ (x`${modifier(node)}.slice(${i})`),
|
||||
default_modifier,
|
||||
scope,
|
||||
component,
|
||||
context_rest_properties,
|
||||
in_rest_element: true
|
||||
});
|
||||
} else if (element.type === 'AssignmentPattern') {
|
||||
const n = contexts.length;
|
||||
mark_referenced(element.right, scope, component);
|
||||
unpack_destructuring({
|
||||
contexts,
|
||||
node: element.left,
|
||||
modifier: (node) => x`${modifier(node)}[${i}]`,
|
||||
default_modifier: (node, to_ctx) =>
|
||||
/** @type {import('estree').Node} */ (
|
||||
x`${node} !== undefined ? ${node} : ${update_reference(
|
||||
contexts,
|
||||
n,
|
||||
element.right,
|
||||
to_ctx
|
||||
)}`
|
||||
),
|
||||
scope,
|
||||
component,
|
||||
context_rest_properties,
|
||||
in_rest_element
|
||||
});
|
||||
} else {
|
||||
unpack_destructuring({
|
||||
contexts,
|
||||
node: element,
|
||||
modifier: (node) => /** @type {import('estree').Node} */ (x`${modifier(node)}[${i}]`),
|
||||
default_modifier,
|
||||
scope,
|
||||
component,
|
||||
context_rest_properties,
|
||||
in_rest_element
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (node.type === 'ObjectPattern') {
|
||||
const used_properties = [];
|
||||
node.properties.forEach((property) => {
|
||||
if (property.type === 'RestElement') {
|
||||
unpack_destructuring({
|
||||
contexts,
|
||||
node: property.argument,
|
||||
modifier: (node) =>
|
||||
/** @type {import('estree').Node} */ (
|
||||
x`@object_without_properties(${modifier(node)}, [${used_properties}])`
|
||||
),
|
||||
default_modifier,
|
||||
scope,
|
||||
component,
|
||||
context_rest_properties,
|
||||
in_rest_element: true
|
||||
});
|
||||
} else if (property.type === 'Property') {
|
||||
const key = property.key;
|
||||
const value = property.value;
|
||||
|
||||
/** @type {(node: import('estree').Node) => import('estree').Node} */
|
||||
let new_modifier;
|
||||
if (property.computed) {
|
||||
// e.g { [computedProperty]: ... }
|
||||
const property_name = component.get_unique_name('computed_property');
|
||||
contexts.push({
|
||||
type: 'ComputedProperty',
|
||||
property_name,
|
||||
key
|
||||
});
|
||||
new_modifier = (node) => x`${modifier(node)}[${property_name}]`;
|
||||
used_properties.push(x`${property_name}`);
|
||||
} else if (key.type === 'Identifier') {
|
||||
// e.g. { someProperty: ... }
|
||||
const property_name = key.name;
|
||||
new_modifier = (node) => x`${modifier(node)}.${property_name}`;
|
||||
used_properties.push(x`"${property_name}"`);
|
||||
} else if (key.type === 'Literal') {
|
||||
// e.g. { "property-in-quotes": ... } or { 14: ... }
|
||||
const property_name = key.value;
|
||||
new_modifier = (node) => x`${modifier(node)}["${property_name}"]`;
|
||||
used_properties.push(x`"${property_name}"`);
|
||||
}
|
||||
if (value.type === 'AssignmentPattern') {
|
||||
// e.g. { property = default } or { property: newName = default }
|
||||
const n = contexts.length;
|
||||
mark_referenced(value.right, scope, component);
|
||||
unpack_destructuring({
|
||||
contexts,
|
||||
node: value.left,
|
||||
modifier: new_modifier,
|
||||
default_modifier: (node, to_ctx) =>
|
||||
/** @type {import('estree').Node} */ (
|
||||
x`${node} !== undefined ? ${node} : ${update_reference(
|
||||
contexts,
|
||||
n,
|
||||
value.right,
|
||||
to_ctx
|
||||
)}`
|
||||
),
|
||||
scope,
|
||||
component,
|
||||
context_rest_properties,
|
||||
in_rest_element
|
||||
});
|
||||
} else {
|
||||
// e.g. { property } or { property: newName }
|
||||
unpack_destructuring({
|
||||
contexts,
|
||||
node: value,
|
||||
modifier: new_modifier,
|
||||
default_modifier,
|
||||
scope,
|
||||
component,
|
||||
context_rest_properties,
|
||||
in_rest_element
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Context[]} contexts
|
||||
* @param {number} n
|
||||
* @param {import('estree').Expression} expression
|
||||
* @param {(name: string) => import('estree').Node} to_ctx
|
||||
* @returns {import('estree').Node}
|
||||
*/
|
||||
function update_reference(contexts, n, expression, to_ctx) {
|
||||
/** @param {import('estree').Identifier} node */
|
||||
const find_from_context = (node) => {
|
||||
for (let i = n; i < contexts.length; i++) {
|
||||
const cur_context = contexts[i];
|
||||
if (cur_context.type !== 'DestructuredVariable') continue;
|
||||
const { key } = cur_context;
|
||||
if (node.name === key.name) {
|
||||
throw new Error(`Cannot access '${node.name}' before initialization`);
|
||||
}
|
||||
}
|
||||
return to_ctx(node.name);
|
||||
};
|
||||
if (expression.type === 'Identifier') {
|
||||
return find_from_context(expression);
|
||||
}
|
||||
// NOTE: avoid unnecessary deep clone?
|
||||
expression = /** @type {import('estree').Expression} */ (clone(expression));
|
||||
walk(expression, {
|
||||
enter(node, parent) {
|
||||
if (
|
||||
is_reference(
|
||||
/** @type {import('is-reference').NodeWithPropertyDefinition} */ (node),
|
||||
/** @type {import('is-reference').NodeWithPropertyDefinition} */ (parent)
|
||||
)
|
||||
) {
|
||||
this.replace(find_from_context(/** @type {import('estree').Identifier} */ (node)));
|
||||
this.skip();
|
||||
}
|
||||
}
|
||||
});
|
||||
return expression;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('estree').Node} node
|
||||
* @param {import('./TemplateScope.js').default} scope
|
||||
* @param {import('../../Component.js').default} component
|
||||
*/
|
||||
function mark_referenced(node, scope, component) {
|
||||
walk(node, {
|
||||
enter(node, parent) {
|
||||
if (is_reference(node, parent)) {
|
||||
const { name } = flatten_reference(node);
|
||||
if (!scope.is_let(name) && !scope.names.has(name)) {
|
||||
component.add_reference(node, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** @typedef {DestructuredVariable | ComputedProperty} Context */
|
||||
|
||||
/**
|
||||
* @typedef {Object} ComputedProperty
|
||||
* @property {'ComputedProperty'} type
|
||||
* @property {import('estree').Identifier} property_name
|
||||
* @property {import('estree').Expression|import('estree').PrivateIdentifier} key
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} DestructuredVariable
|
||||
* @property {'DestructuredVariable'} type
|
||||
* @property {import('estree').Identifier} key
|
||||
* @property {string} [name]
|
||||
* @property {(node:import('estree').Node)=>import('estree').Node} modifier
|
||||
* @property {(node:import('estree').Node,to_ctx:(name:string)=>import('estree').Node)=>import('estree').Node} default_modifier
|
||||
*/
|
||||
474
frontend/node_modules/svelte/src/compiler/compile/nodes/shared/Expression.js
generated
vendored
Normal file
474
frontend/node_modules/svelte/src/compiler/compile/nodes/shared/Expression.js
generated
vendored
Normal file
@@ -0,0 +1,474 @@
|
||||
import { walk } from 'estree-walker';
|
||||
import is_reference from 'is-reference';
|
||||
import flatten_reference from '../../utils/flatten_reference.js';
|
||||
import { create_scopes, extract_names } from '../../utils/scope.js';
|
||||
import { sanitize } from '../../../utils/names.js';
|
||||
import get_object from '../../utils/get_object.js';
|
||||
import is_dynamic from '../../render_dom/wrappers/shared/is_dynamic.js';
|
||||
import { b } from 'code-red';
|
||||
import { invalidate } from '../../render_dom/invalidate.js';
|
||||
import { is_reserved_keyword } from '../../utils/reserved_keywords.js';
|
||||
import replace_object from '../../utils/replace_object.js';
|
||||
import is_contextual from './is_contextual.js';
|
||||
import { clone } from '../../../utils/clone.js';
|
||||
import compiler_errors from '../../compiler_errors.js';
|
||||
|
||||
const regex_contains_term_function_expression = /FunctionExpression/;
|
||||
|
||||
export default class Expression {
|
||||
/** @type {'Expression'} */
|
||||
type = 'Expression';
|
||||
|
||||
/** @type {import('../../Component.js').default} */
|
||||
component;
|
||||
|
||||
/** @type {import('../interfaces.js').INode} */
|
||||
owner;
|
||||
|
||||
/** @type {import('estree').Node} */
|
||||
node;
|
||||
|
||||
/** @type {Set<string>} */
|
||||
references = new Set();
|
||||
|
||||
/**
|
||||
* Dependencies declared in the script block
|
||||
* @type {Set<string>}
|
||||
*/
|
||||
dependencies = new Set();
|
||||
|
||||
/**
|
||||
* Dependencies declared in the HTML-like template section
|
||||
* @type {Set<string>}
|
||||
*/
|
||||
contextual_dependencies = new Set();
|
||||
|
||||
/** @type {import('./TemplateScope.js').default} */
|
||||
template_scope;
|
||||
|
||||
/** @type {import('../../utils/scope.js').Scope} */
|
||||
scope;
|
||||
|
||||
/** @type {WeakMap<import('estree').Node, import('../../utils/scope.js').Scope>} */
|
||||
scope_map;
|
||||
|
||||
/** @type {Array<import('estree').Node | import('estree').Node[]>} */
|
||||
declarations = [];
|
||||
|
||||
/** @type {boolean} */
|
||||
uses_context = false;
|
||||
|
||||
/** @type {import('estree').Node} */
|
||||
manipulated;
|
||||
|
||||
/**
|
||||
* @param {import('../../Component.js').default} component *
|
||||
* @param {import('../interfaces.js').INode} owner *
|
||||
* @param {import('./TemplateScope.js').default} template_scope *
|
||||
* @param {import('estree').Node} info *
|
||||
* @param {boolean} [lazy] undefined
|
||||
*/
|
||||
constructor(component, owner, template_scope, info, lazy) {
|
||||
// TODO revert to direct property access in prod?
|
||||
Object.defineProperties(this, {
|
||||
component: {
|
||||
value: component
|
||||
}
|
||||
});
|
||||
this.node = info;
|
||||
this.template_scope = template_scope;
|
||||
this.owner = owner;
|
||||
const { dependencies, contextual_dependencies, references } = this;
|
||||
let { map, scope } = create_scopes(info);
|
||||
this.scope = scope;
|
||||
this.scope_map = map;
|
||||
const expression = this;
|
||||
let function_expression;
|
||||
|
||||
// discover dependencies, but don't change the code yet
|
||||
walk(info, {
|
||||
/**
|
||||
* @param {any} node
|
||||
* @param {import('estree').Node} parent
|
||||
* @param {string} key
|
||||
*/
|
||||
enter(node, parent, key) {
|
||||
// don't manipulate shorthand props twice
|
||||
if (key === 'key' && /** @type {import('estree').Property} */ (parent).shorthand) return;
|
||||
// don't manipulate `import.meta`, `new.target`
|
||||
if (node.type === 'MetaProperty') return this.skip();
|
||||
if (map.has(node)) {
|
||||
scope = map.get(node);
|
||||
}
|
||||
if (!function_expression && regex_contains_term_function_expression.test(node.type)) {
|
||||
function_expression = node;
|
||||
}
|
||||
if (is_reference(node, parent)) {
|
||||
const { name, nodes } = flatten_reference(node);
|
||||
references.add(name);
|
||||
if (scope.has(name)) return;
|
||||
if (name[0] === '$') {
|
||||
const store_name = name.slice(1);
|
||||
if (template_scope.names.has(store_name) || scope.has(store_name)) {
|
||||
return component.error(node, compiler_errors.contextual_store);
|
||||
}
|
||||
}
|
||||
if (template_scope.is_let(name)) {
|
||||
if (!lazy) {
|
||||
contextual_dependencies.add(name);
|
||||
dependencies.add(name);
|
||||
}
|
||||
} else if (template_scope.names.has(name)) {
|
||||
expression.uses_context = true;
|
||||
contextual_dependencies.add(name);
|
||||
const owner = template_scope.get_owner(name);
|
||||
const is_index = owner.type === 'EachBlock' && owner.key && name === owner.index;
|
||||
if (!lazy || is_index) {
|
||||
template_scope.dependencies_for_name
|
||||
.get(name)
|
||||
.forEach((name) => dependencies.add(name));
|
||||
}
|
||||
} else {
|
||||
if (!lazy) {
|
||||
const variable = component.var_lookup.get(name);
|
||||
if (!variable || !variable.imported || variable.mutated || variable.reassigned) {
|
||||
dependencies.add(name);
|
||||
}
|
||||
}
|
||||
component.add_reference(node, name);
|
||||
component.warn_if_undefined(name, nodes[0], template_scope, owner);
|
||||
}
|
||||
this.skip();
|
||||
}
|
||||
// track any assignments from template expressions as mutable
|
||||
let names;
|
||||
let deep = false;
|
||||
if (function_expression) {
|
||||
if (node.type === 'AssignmentExpression') {
|
||||
deep = node.left.type === 'MemberExpression';
|
||||
names = extract_names(deep ? get_object(node.left) : node.left);
|
||||
} else if (node.type === 'UpdateExpression') {
|
||||
deep = node.argument.type === 'MemberExpression';
|
||||
names = extract_names(get_object(node.argument));
|
||||
}
|
||||
}
|
||||
if (names) {
|
||||
names.forEach((name) => {
|
||||
if (template_scope.names.has(name)) {
|
||||
if (template_scope.is_const(name)) {
|
||||
component.error(node, compiler_errors.invalid_const_update(name));
|
||||
}
|
||||
template_scope.dependencies_for_name.get(name).forEach((name) => {
|
||||
const variable = component.var_lookup.get(name);
|
||||
if (variable) variable[deep ? 'mutated' : 'reassigned'] = true;
|
||||
});
|
||||
const each_block = template_scope.get_owner(name);
|
||||
/** @type {import('../EachBlock.js').default} */ (each_block).has_binding = true;
|
||||
} else {
|
||||
component.add_reference(node, name);
|
||||
const variable = component.var_lookup.get(name);
|
||||
if (variable) {
|
||||
variable[deep ? 'mutated' : 'reassigned'] = true;
|
||||
}
|
||||
|
||||
const declaration = scope.find_owner(name)?.declarations.get(name);
|
||||
if (declaration) {
|
||||
if (
|
||||
/** @type {import('estree').VariableDeclaration} */ (declaration).kind ===
|
||||
'const' &&
|
||||
!deep
|
||||
) {
|
||||
component.error(node, {
|
||||
code: 'assignment-to-const',
|
||||
message: 'You are assigning to a const'
|
||||
});
|
||||
}
|
||||
} else if (variable && variable.writable === false && !deep) {
|
||||
component.error(node, {
|
||||
code: 'assignment-to-const',
|
||||
message: 'You are assigning to a const'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/** @type {import('estree-walker').SyncHandler} */
|
||||
leave(node) {
|
||||
if (map.has(node)) {
|
||||
scope = scope.parent;
|
||||
}
|
||||
if (node === function_expression) {
|
||||
function_expression = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
dynamic_dependencies() {
|
||||
return Array.from(this.dependencies).filter((name) => {
|
||||
if (this.template_scope.is_let(name)) return true;
|
||||
if (is_reserved_keyword(name)) return true;
|
||||
const variable = this.component.var_lookup.get(name);
|
||||
return is_dynamic(variable);
|
||||
});
|
||||
}
|
||||
dynamic_contextual_dependencies() {
|
||||
return Array.from(this.contextual_dependencies).filter((name) => {
|
||||
return Array.from(this.template_scope.dependencies_for_name.get(name)).some(
|
||||
(variable_name) => {
|
||||
const variable = this.component.var_lookup.get(variable_name);
|
||||
return is_dynamic(variable);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
// TODO move this into a render-dom wrapper?
|
||||
|
||||
/**
|
||||
* @param {import('../../render_dom/Block.js').default} [block]
|
||||
* @param {string | void} [ctx]
|
||||
*/
|
||||
manipulate(block, ctx) {
|
||||
// TODO ideally we wouldn't end up calling this method
|
||||
// multiple times
|
||||
if (this.manipulated) return this.manipulated;
|
||||
const { component, declarations, scope_map: map, template_scope, owner } = this;
|
||||
let scope = this.scope;
|
||||
|
||||
/** @type {import('estree').FunctionExpression | import('estree').ArrowFunctionExpression | null} */
|
||||
let function_expression;
|
||||
|
||||
/** @type {Set<string>} */
|
||||
let dependencies;
|
||||
|
||||
/** @type {Set<string>} */
|
||||
let contextual_dependencies;
|
||||
const node = walk(this.node, {
|
||||
/** @type {import('estree-walker').SyncHandler} */
|
||||
enter(node, parent) {
|
||||
if (node.type === 'Property' && node.shorthand) {
|
||||
node.value = clone(node.value);
|
||||
node.shorthand = false;
|
||||
}
|
||||
if (map.has(node)) {
|
||||
scope = map.get(node);
|
||||
}
|
||||
if (node.type === 'Identifier' && is_reference(node, parent)) {
|
||||
const { name } = flatten_reference(node);
|
||||
if (scope.has(name)) return;
|
||||
if (function_expression) {
|
||||
if (template_scope.names.has(name)) {
|
||||
contextual_dependencies.add(name);
|
||||
template_scope.dependencies_for_name.get(name).forEach((dependency) => {
|
||||
dependencies.add(dependency);
|
||||
});
|
||||
} else {
|
||||
dependencies.add(name);
|
||||
component.add_reference(node, name); // TODO is this redundant/misplaced?
|
||||
}
|
||||
} else if (is_contextual(component, template_scope, name)) {
|
||||
const reference = block.renderer.reference(node, ctx);
|
||||
this.replace(reference);
|
||||
}
|
||||
this.skip();
|
||||
}
|
||||
if (!function_expression) {
|
||||
if (node.type === 'AssignmentExpression') {
|
||||
// TODO should this be a warning/error? `<p>{foo = 1}</p>`
|
||||
}
|
||||
if (node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') {
|
||||
function_expression = node;
|
||||
dependencies = new Set();
|
||||
contextual_dependencies = new Set();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/** @type {import('estree-walker').SyncHandler} */
|
||||
leave(node, parent) {
|
||||
if (map.has(node)) scope = scope.parent;
|
||||
if (node === function_expression) {
|
||||
const id = component.get_unique_name(sanitize(get_function_name(node, owner)));
|
||||
const declaration = b`const ${id} = ${node}`;
|
||||
const extract_functions = () => {
|
||||
const deps = Array.from(contextual_dependencies);
|
||||
const function_expression = /** @type {import('estree').FunctionExpression} */ (node);
|
||||
const has_args = function_expression.params.length > 0;
|
||||
function_expression.params = [
|
||||
...deps.map(
|
||||
(name) => /** @type {import('estree').Identifier} */ ({ type: 'Identifier', name })
|
||||
),
|
||||
...function_expression.params
|
||||
];
|
||||
const context_args = deps.map((name) => block.renderer.reference(name, ctx));
|
||||
component.partly_hoisted.push(declaration);
|
||||
block.renderer.add_to_context(id.name);
|
||||
const callee = block.renderer.reference(id);
|
||||
this.replace(id);
|
||||
const func_declaration = has_args
|
||||
? b`function ${id}(...args) {
|
||||
return ${callee}(${context_args}, ...args);
|
||||
}`
|
||||
: b`function ${id}() {
|
||||
return ${callee}(${context_args});
|
||||
}`;
|
||||
return { deps, func_declaration };
|
||||
};
|
||||
if (owner.type === 'ConstTag') {
|
||||
// we need a combo block/init recipe
|
||||
if (contextual_dependencies.size === 0) {
|
||||
let child_scope = scope;
|
||||
walk(node, {
|
||||
/** @type {import('estree-walker').SyncHandler} */
|
||||
enter(node, parent) {
|
||||
if (map.has(node)) child_scope = map.get(node);
|
||||
if (node.type === 'Identifier' && is_reference(node, parent)) {
|
||||
if (child_scope.has(node.name)) return;
|
||||
this.replace(block.renderer.reference(node, ctx));
|
||||
}
|
||||
},
|
||||
|
||||
/** @param {import('estree').Node} node */
|
||||
leave(node) {
|
||||
if (map.has(node)) child_scope = child_scope.parent;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
const { func_declaration } = extract_functions();
|
||||
this.replace(func_declaration[0]);
|
||||
}
|
||||
} else if (dependencies.size === 0 && contextual_dependencies.size === 0) {
|
||||
// we can hoist this out of the component completely
|
||||
component.fully_hoisted.push(declaration);
|
||||
this.replace(id);
|
||||
component.add_var(node, {
|
||||
name: id.name,
|
||||
internal: true,
|
||||
hoistable: true,
|
||||
referenced: true
|
||||
});
|
||||
} else if (contextual_dependencies.size === 0) {
|
||||
// function can be hoisted inside the component init
|
||||
component.partly_hoisted.push(declaration);
|
||||
block.renderer.add_to_context(id.name);
|
||||
this.replace(block.renderer.reference(id));
|
||||
} else {
|
||||
// we need a combo block/init recipe
|
||||
const { deps, func_declaration } = extract_functions();
|
||||
if (owner.type === 'Attribute' && owner.parent.name === 'slot') {
|
||||
/** @type {Set<import('../interfaces.js').INode>} */
|
||||
const dep_scopes = new Set(deps.map((name) => template_scope.get_owner(name)));
|
||||
// find the nearest scopes
|
||||
|
||||
/** @type {import('../interfaces.js').INode} */
|
||||
let node = owner.parent;
|
||||
while (node && !dep_scopes.has(node)) {
|
||||
node = node.parent;
|
||||
}
|
||||
const func_expression = func_declaration[0];
|
||||
|
||||
if (node.type === 'SlotTemplate') {
|
||||
// <svelte:fragment let:data />
|
||||
this.replace(func_expression);
|
||||
} else {
|
||||
// {#each}, {#await}
|
||||
const func_id = component.get_unique_name(id.name + '_func');
|
||||
block.renderer.add_to_context(func_id.name, true);
|
||||
// rename #ctx -> child_ctx;
|
||||
walk(func_expression, {
|
||||
/** @param {import('estree').Node} node */
|
||||
enter(node) {
|
||||
if (node.type === 'Identifier' && node.name === '#ctx') {
|
||||
node.name = 'child_ctx';
|
||||
}
|
||||
}
|
||||
});
|
||||
// add to get_xxx_context
|
||||
// child_ctx[x] = function () { ... }
|
||||
/** @type {import('../EachBlock.js').default} */ (
|
||||
template_scope.get_owner(deps[0])
|
||||
).contexts.push({
|
||||
type: 'DestructuredVariable',
|
||||
key: func_id,
|
||||
modifier: () => func_expression,
|
||||
default_modifier: (node) => node
|
||||
});
|
||||
this.replace(block.renderer.reference(func_id));
|
||||
}
|
||||
} else {
|
||||
declarations.push(func_declaration);
|
||||
}
|
||||
}
|
||||
function_expression = null;
|
||||
dependencies = null;
|
||||
contextual_dependencies = null;
|
||||
if (parent && parent.type === 'Property') {
|
||||
parent.method = false;
|
||||
}
|
||||
}
|
||||
if (node.type === 'AssignmentExpression' || node.type === 'UpdateExpression') {
|
||||
const assignee = node.type === 'AssignmentExpression' ? node.left : node.argument;
|
||||
const object_name = get_object(assignee).name;
|
||||
if (scope.has(object_name)) return;
|
||||
// normally (`a = 1`, `b.c = 2`), there'll be a single name
|
||||
// (a or b). In destructuring cases (`[d, e] = [e, d]`) there
|
||||
// may be more, in which case we need to tack the extra ones
|
||||
// onto the initial function call
|
||||
const names = new Set(extract_names(/** @type {import('estree').Node} */ (assignee)));
|
||||
|
||||
/** @type {Set<string>} */
|
||||
const traced = new Set();
|
||||
names.forEach((name) => {
|
||||
const dependencies = template_scope.dependencies_for_name.get(name);
|
||||
if (dependencies) {
|
||||
dependencies.forEach((name) => traced.add(name));
|
||||
} else {
|
||||
traced.add(name);
|
||||
}
|
||||
});
|
||||
const context = block.bindings.get(object_name);
|
||||
if (context) {
|
||||
// for `{#each array as item}`
|
||||
// replace `item = 1` to `each_array[each_index] = 1`, this allow us to mutate the array
|
||||
// rather than mutating the local `item` variable
|
||||
const { snippet, object, property } = context;
|
||||
|
||||
/** @type {any} */
|
||||
const replaced = replace_object(assignee, snippet);
|
||||
if (node.type === 'AssignmentExpression') {
|
||||
node.left = replaced;
|
||||
} else {
|
||||
node.argument = replaced;
|
||||
}
|
||||
contextual_dependencies.add(object.name);
|
||||
contextual_dependencies.add(property.name);
|
||||
}
|
||||
this.replace(invalidate(block.renderer, scope, node, traced));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (declarations.length > 0) {
|
||||
block.maintain_context = true;
|
||||
declarations.forEach((declaration) => {
|
||||
block.chunks.init.push(declaration);
|
||||
});
|
||||
}
|
||||
return (this.manipulated = /** @type {import('estree').Node} */ (node));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('estree').Node} _node
|
||||
* @param {import('../interfaces.js').INode} parent
|
||||
*/
|
||||
function get_function_name(_node, parent) {
|
||||
if (parent.type === 'EventHandler') {
|
||||
return `${parent.name}_handler`;
|
||||
}
|
||||
if (parent.type === 'Action') {
|
||||
return `${parent.name}_function`;
|
||||
}
|
||||
return 'func';
|
||||
}
|
||||
113
frontend/node_modules/svelte/src/compiler/compile/nodes/shared/Node.js
generated
vendored
Normal file
113
frontend/node_modules/svelte/src/compiler/compile/nodes/shared/Node.js
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* @template {string} Type
|
||||
* @template {import('../interfaces.js').INode} [Parent=import('../interfaces.js').INode]
|
||||
*/
|
||||
export default class Node {
|
||||
/**
|
||||
* @readonly
|
||||
* @type {number}
|
||||
*/
|
||||
start;
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @type {number}
|
||||
*/
|
||||
end;
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @type {import('../../Component.js').default}
|
||||
*/
|
||||
component;
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @type {Parent}
|
||||
*/
|
||||
parent;
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @type {Type}
|
||||
*/
|
||||
type;
|
||||
|
||||
/** @type {import('../interfaces.js').INode} */
|
||||
prev;
|
||||
|
||||
/** @type {import('../interfaces.js').INode} */
|
||||
next;
|
||||
|
||||
/** @type {boolean} */
|
||||
can_use_innerhtml;
|
||||
|
||||
/** @type {boolean} */
|
||||
is_static_content;
|
||||
|
||||
/** @type {string} */
|
||||
var;
|
||||
|
||||
/** @type {import('../Attribute.js').default[]} */
|
||||
attributes = [];
|
||||
|
||||
/**
|
||||
* @param {import('../../Component.js').default} component
|
||||
* @param {Node} parent
|
||||
* @param {any} _scope
|
||||
* @param {import('../../../interfaces.js').TemplateNode} info
|
||||
*/
|
||||
constructor(component, parent, _scope, info) {
|
||||
this.start = info.start;
|
||||
this.end = info.end;
|
||||
this.type = /** @type {Type} */ (info.type);
|
||||
// this makes properties non-enumerable, which makes logging
|
||||
// bearable. might have a performance cost. TODO remove in prod?
|
||||
Object.defineProperties(this, {
|
||||
component: {
|
||||
value: component
|
||||
},
|
||||
parent: {
|
||||
value: parent
|
||||
}
|
||||
});
|
||||
this.can_use_innerhtml = true;
|
||||
this.is_static_content = true;
|
||||
}
|
||||
cannot_use_innerhtml() {
|
||||
if (this.can_use_innerhtml !== false) {
|
||||
this.can_use_innerhtml = false;
|
||||
if (this.parent) this.parent.cannot_use_innerhtml();
|
||||
}
|
||||
}
|
||||
not_static_content() {
|
||||
this.is_static_content = false;
|
||||
if (this.parent) this.parent.not_static_content();
|
||||
}
|
||||
|
||||
/** @param {RegExp} selector */
|
||||
find_nearest(selector) {
|
||||
if (selector.test(this.type)) return this;
|
||||
if (this.parent) return this.parent.find_nearest(selector);
|
||||
}
|
||||
|
||||
/** @param {string} name */
|
||||
get_static_attribute_value(name) {
|
||||
const attribute = this.attributes.find(
|
||||
/** @param {import('../Attribute.js').default} attr */
|
||||
(attr) => attr.type === 'Attribute' && attr.name.toLowerCase() === name
|
||||
);
|
||||
if (!attribute) return null;
|
||||
if (attribute.is_true) return true;
|
||||
if (attribute.chunks.length === 0) return '';
|
||||
if (attribute.chunks.length === 1 && attribute.chunks[0].type === 'Text') {
|
||||
return /** @type {import('../Text.js').default} */ (attribute.chunks[0]).data;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @param {string} type */
|
||||
has_ancestor(type) {
|
||||
return this.parent ? this.parent.type === type || this.parent.has_ancestor(type) : false;
|
||||
}
|
||||
}
|
||||
41
frontend/node_modules/svelte/src/compiler/compile/nodes/shared/Tag.js
generated
vendored
Normal file
41
frontend/node_modules/svelte/src/compiler/compile/nodes/shared/Tag.js
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
import Node from './Node.js';
|
||||
import Expression from './Expression.js';
|
||||
|
||||
/**
|
||||
* @template {'MustacheTag' | 'RawMustacheTag'} [Type='MustacheTag' | 'RawMustacheTag']
|
||||
* @extends Node<Type>
|
||||
*/
|
||||
export default class Tag extends Node {
|
||||
/** @type {import('./Expression.js').default} */
|
||||
expression;
|
||||
|
||||
/** @type {boolean} */
|
||||
should_cache;
|
||||
|
||||
/**
|
||||
* @param {any} component
|
||||
* @param {any} parent
|
||||
* @param {any} scope
|
||||
* @param {any} info
|
||||
*/
|
||||
constructor(component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
component.tags.push(this);
|
||||
this.cannot_use_innerhtml();
|
||||
this.expression = new Expression(component, this, scope, info.expression);
|
||||
this.should_cache =
|
||||
info.expression.type !== 'Identifier' ||
|
||||
(this.expression.dependencies.size && scope.names.has(info.expression.name));
|
||||
}
|
||||
is_dependencies_static() {
|
||||
return (
|
||||
this.expression.dynamic_contextual_dependencies().length === 0 &&
|
||||
this.expression.dynamic_dependencies().length === 0
|
||||
);
|
||||
}
|
||||
check_if_content_dynamic() {
|
||||
if (!this.is_dependencies_static()) {
|
||||
this.not_static_content();
|
||||
}
|
||||
}
|
||||
}
|
||||
83
frontend/node_modules/svelte/src/compiler/compile/nodes/shared/TemplateScope.js
generated
vendored
Normal file
83
frontend/node_modules/svelte/src/compiler/compile/nodes/shared/TemplateScope.js
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
/** The scope of constructs within the Svelte template */
|
||||
export default class TemplateScope {
|
||||
/**
|
||||
* @typedef {import('../EachBlock').default
|
||||
* | import('../ThenBlock').default
|
||||
* | import('../CatchBlock').default
|
||||
* | import('../InlineComponent').default
|
||||
* | import('../Element').default
|
||||
* | import('../SlotTemplate').default
|
||||
* | import('../ConstTag').default} NodeWithScope
|
||||
*/
|
||||
|
||||
/** @type {Set<string>} */
|
||||
names;
|
||||
|
||||
/** @type {Map<string, Set<string>>} */
|
||||
dependencies_for_name;
|
||||
|
||||
/** @type {Map<string, NodeWithScope>} */
|
||||
owners = new Map();
|
||||
|
||||
/** @type {TemplateScope} */
|
||||
parent;
|
||||
|
||||
/** @param {TemplateScope} [parent] undefined */
|
||||
constructor(parent) {
|
||||
this.parent = parent;
|
||||
this.names = new Set(parent ? parent.names : []);
|
||||
this.dependencies_for_name = new Map(parent ? parent.dependencies_for_name : []);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} name
|
||||
* @param {Set<string>} dependencies
|
||||
* @param {any} owner
|
||||
*/
|
||||
add(name, dependencies, owner) {
|
||||
this.names.add(name);
|
||||
this.dependencies_for_name.set(name, dependencies);
|
||||
this.owners.set(name, owner);
|
||||
return this;
|
||||
}
|
||||
child() {
|
||||
const child = new TemplateScope(this);
|
||||
return child;
|
||||
}
|
||||
|
||||
/** @param {string} name */
|
||||
is_top_level(name) {
|
||||
return !this.parent || (!this.names.has(name) && this.parent.is_top_level(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @returns {NodeWithScope}
|
||||
*/
|
||||
get_owner(name) {
|
||||
return this.owners.get(name) || (this.parent && this.parent.get_owner(name));
|
||||
}
|
||||
|
||||
/** @param {string} name */
|
||||
is_let(name) {
|
||||
const owner = this.get_owner(name);
|
||||
return (
|
||||
owner &&
|
||||
(owner.type === 'Element' ||
|
||||
owner.type === 'InlineComponent' ||
|
||||
owner.type === 'SlotTemplate')
|
||||
);
|
||||
}
|
||||
|
||||
/** @param {string} name */
|
||||
is_await(name) {
|
||||
const owner = this.get_owner(name);
|
||||
return owner && (owner.type === 'ThenBlock' || owner.type === 'CatchBlock');
|
||||
}
|
||||
|
||||
/** @param {string} name */
|
||||
is_const(name) {
|
||||
const owner = this.get_owner(name);
|
||||
return owner && owner.type === 'ConstTag';
|
||||
}
|
||||
}
|
||||
95
frontend/node_modules/svelte/src/compiler/compile/nodes/shared/get_const_tags.js
generated
vendored
Normal file
95
frontend/node_modules/svelte/src/compiler/compile/nodes/shared/get_const_tags.js
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
import ConstTag from '../ConstTag.js';
|
||||
import map_children from './map_children.js';
|
||||
import check_graph_for_cycles from '../../utils/check_graph_for_cycles.js';
|
||||
import compiler_errors from '../../compiler_errors.js';
|
||||
|
||||
/**
|
||||
* @param {import('../../../interfaces.js').TemplateNode[]} children
|
||||
* @param {import('../../Component.js').default} component
|
||||
* @param {import('../interfaces.js').INodeAllowConstTag} node
|
||||
* @param {import('../interfaces.js').INode} parent
|
||||
* @returns {[ConstTag[], Array<Exclude<import('../interfaces.js').INode, ConstTag>>]}
|
||||
*/
|
||||
export default function get_const_tags(children, component, node, parent) {
|
||||
/** @type {import('../../../interfaces.js').ConstTag[]} */
|
||||
const const_tags = [];
|
||||
|
||||
/** @type {Array<Exclude<import('../../../interfaces.js').TemplateNode, import('../../../interfaces.js').ConstTag>>} */
|
||||
const others = [];
|
||||
for (const child of children) {
|
||||
if (child.type === 'ConstTag') {
|
||||
const_tags.push(/** @type {import('../../../interfaces.js').ConstTag} */ (child));
|
||||
} else {
|
||||
others.push(child);
|
||||
}
|
||||
}
|
||||
const consts_nodes = const_tags.map((tag) => new ConstTag(component, node, node.scope, tag));
|
||||
const sorted_consts_nodes = sort_consts_nodes(consts_nodes, component);
|
||||
sorted_consts_nodes.forEach((node) => node.parse_expression());
|
||||
const children_nodes = map_children(component, parent, node.scope, others);
|
||||
return [
|
||||
sorted_consts_nodes,
|
||||
/** @type {Array<Exclude<import('../interfaces.js').INode, ConstTag>>} */ (children_nodes)
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ConstTag[]} consts_nodes
|
||||
* @param {import('../../Component.js').default} component
|
||||
*/
|
||||
function sort_consts_nodes(consts_nodes, component) {
|
||||
/** @typedef {{ assignees: Set<string>; dependencies: Set<string>; node: ConstTag; }} ConstNode */
|
||||
|
||||
/** @type {ConstNode[]} */
|
||||
const sorted_consts_nodes = [];
|
||||
|
||||
/** @type {ConstNode[]} */
|
||||
const unsorted_consts_nodes = consts_nodes.map((node) => {
|
||||
return {
|
||||
assignees: node.assignees,
|
||||
dependencies: node.dependencies,
|
||||
node
|
||||
};
|
||||
});
|
||||
const lookup = new Map();
|
||||
unsorted_consts_nodes.forEach((node) => {
|
||||
node.assignees.forEach((name) => {
|
||||
if (!lookup.has(name)) {
|
||||
lookup.set(name, []);
|
||||
}
|
||||
lookup.get(name).push(node);
|
||||
});
|
||||
});
|
||||
const cycle = check_graph_for_cycles(
|
||||
unsorted_consts_nodes.reduce((acc, node) => {
|
||||
node.assignees.forEach((v) => {
|
||||
node.dependencies.forEach((w) => {
|
||||
if (!node.assignees.has(w)) {
|
||||
acc.push([v, w]);
|
||||
}
|
||||
});
|
||||
});
|
||||
return acc;
|
||||
}, [])
|
||||
);
|
||||
if (cycle && cycle.length) {
|
||||
const node_list = lookup.get(cycle[0]);
|
||||
const node = node_list[0];
|
||||
component.error(node.node, compiler_errors.cyclical_const_tags(cycle));
|
||||
}
|
||||
|
||||
/** @param {ConstNode} node */
|
||||
const add_node = (node) => {
|
||||
if (sorted_consts_nodes.includes(node)) return;
|
||||
node.dependencies.forEach((name) => {
|
||||
if (node.assignees.has(name)) return;
|
||||
const earlier_nodes = lookup.get(name);
|
||||
if (earlier_nodes) {
|
||||
earlier_nodes.forEach(add_node);
|
||||
}
|
||||
});
|
||||
sorted_consts_nodes.push(node);
|
||||
};
|
||||
unsorted_consts_nodes.forEach(add_node);
|
||||
return sorted_consts_nodes.map((node) => node.node);
|
||||
}
|
||||
17
frontend/node_modules/svelte/src/compiler/compile/nodes/shared/is_contextual.js
generated
vendored
Normal file
17
frontend/node_modules/svelte/src/compiler/compile/nodes/shared/is_contextual.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import { is_reserved_keyword } from '../../utils/reserved_keywords.js';
|
||||
|
||||
/**
|
||||
* @param {import('../../Component.js').default} component
|
||||
* @param {import('./TemplateScope.js').default} scope
|
||||
* @param {string} name
|
||||
*/
|
||||
export default function is_contextual(component, scope, name) {
|
||||
if (is_reserved_keyword(name)) return true;
|
||||
// if it's a name below root scope, it's contextual
|
||||
if (!scope.is_top_level(name)) return true;
|
||||
const variable = component.var_lookup.get(name);
|
||||
// hoistables, module declarations, and imports are non-contextual
|
||||
if (!variable || variable.hoistable) return false;
|
||||
// assume contextual
|
||||
return true;
|
||||
}
|
||||
96
frontend/node_modules/svelte/src/compiler/compile/nodes/shared/map_children.js
generated
vendored
Normal file
96
frontend/node_modules/svelte/src/compiler/compile/nodes/shared/map_children.js
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
import AwaitBlock from '../AwaitBlock.js';
|
||||
import Body from '../Body.js';
|
||||
import ConstTag from '../ConstTag.js';
|
||||
import Comment from '../Comment.js';
|
||||
import EachBlock from '../EachBlock.js';
|
||||
import Document from '../Document.js';
|
||||
import Element from '../Element.js';
|
||||
import Head from '../Head.js';
|
||||
import IfBlock from '../IfBlock.js';
|
||||
import InlineComponent from '../InlineComponent.js';
|
||||
import KeyBlock from '../KeyBlock.js';
|
||||
import MustacheTag from '../MustacheTag.js';
|
||||
import Options from '../Options.js';
|
||||
import RawMustacheTag from '../RawMustacheTag.js';
|
||||
import DebugTag from '../DebugTag.js';
|
||||
import Slot from '../Slot.js';
|
||||
import SlotTemplate from '../SlotTemplate.js';
|
||||
import Text from '../Text.js';
|
||||
import Title from '../Title.js';
|
||||
import Window from '../Window.js';
|
||||
import { push_array } from '../../../utils/push_array.js';
|
||||
|
||||
/** @typedef {ReturnType<typeof map_children>} Children */
|
||||
|
||||
/** @param {any} type */
|
||||
function get_constructor(type) {
|
||||
switch (type) {
|
||||
case 'AwaitBlock':
|
||||
return AwaitBlock;
|
||||
case 'Body':
|
||||
return Body;
|
||||
case 'Comment':
|
||||
return Comment;
|
||||
case 'ConstTag':
|
||||
return ConstTag;
|
||||
case 'Document':
|
||||
return Document;
|
||||
case 'EachBlock':
|
||||
return EachBlock;
|
||||
case 'Element':
|
||||
return Element;
|
||||
case 'Head':
|
||||
return Head;
|
||||
case 'IfBlock':
|
||||
return IfBlock;
|
||||
case 'InlineComponent':
|
||||
return InlineComponent;
|
||||
case 'KeyBlock':
|
||||
return KeyBlock;
|
||||
case 'MustacheTag':
|
||||
return MustacheTag;
|
||||
case 'Options':
|
||||
return Options;
|
||||
case 'RawMustacheTag':
|
||||
return RawMustacheTag;
|
||||
case 'DebugTag':
|
||||
return DebugTag;
|
||||
case 'Slot':
|
||||
return Slot;
|
||||
case 'SlotTemplate':
|
||||
return SlotTemplate;
|
||||
case 'Text':
|
||||
return Text;
|
||||
case 'Title':
|
||||
return Title;
|
||||
case 'Window':
|
||||
return Window;
|
||||
default:
|
||||
throw new Error(`Not implemented: ${type}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} component
|
||||
* @param {any} parent
|
||||
* @param {any} scope
|
||||
* @param {import('../../../interfaces.js').TemplateNode[]} children
|
||||
*/
|
||||
export default function map_children(component, parent, scope, children) {
|
||||
let last = null;
|
||||
let ignores = [];
|
||||
return children.map((child) => {
|
||||
const constructor = get_constructor(child.type);
|
||||
const use_ignores = child.type !== 'Text' && child.type !== 'Comment' && ignores.length;
|
||||
if (use_ignores) component.push_ignores(ignores);
|
||||
const node = new constructor(component, parent, scope, child);
|
||||
if (use_ignores) component.pop_ignores(), (ignores = []);
|
||||
if (node.type === 'Comment' && node.ignores.length) {
|
||||
push_array(ignores, node.ignores);
|
||||
}
|
||||
if (last) last.next = node;
|
||||
node.prev = last;
|
||||
last = node;
|
||||
return node;
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user