diff options
author | 2021-03-16 12:37:45 -0600 | |
---|---|---|
committer | 2021-03-16 12:37:45 -0600 | |
commit | 8c45c4a8567e31a10ae954fa11a0f3f1f94fd89c (patch) | |
tree | e526f67e93ed5a7fcf9237c2d30ec536a4a96d7b /src | |
parent | 1f5c7c791fe3595f4c775192ffc6b6a15efb71a1 (diff) | |
download | astro-8c45c4a8567e31a10ae954fa11a0f3f1f94fd89c.tar.gz astro-8c45c4a8567e31a10ae954fa11a0f3f1f94fd89c.tar.zst astro-8c45c4a8567e31a10ae954fa11a0f3f1f94fd89c.zip |
Annoying Lint PR™ (#3)
* Add Prettier + ESLint
* Format files
Diffstat (limited to 'src')
109 files changed, 20408 insertions, 21126 deletions
diff --git a/src/@types/astro.ts b/src/@types/astro.ts index 493d7d22a..710067599 100644 --- a/src/@types/astro.ts +++ b/src/@types/astro.ts @@ -1,4 +1,3 @@ - export interface AstroConfigRaw { dist: string; projectRoot: string; @@ -9,4 +8,4 @@ export interface AstroConfig { dist: string; projectRoot: URL; hmxRoot: URL; -}
\ No newline at end of file +} diff --git a/src/@types/compiler/Stats.d.ts b/src/@types/compiler/Stats.d.ts index 0e01e61f9..3ada0dab2 100644 --- a/src/@types/compiler/Stats.d.ts +++ b/src/@types/compiler/Stats.d.ts @@ -1,22 +1,22 @@ interface Timing { - label: string; - start: number; - end: number; - children: Timing[]; + label: string; + start: number; + end: number; + children: Timing[]; } export default class Stats { - start_time: number; - current_timing: Timing; - current_children: Timing[]; - timings: Timing[]; - stack: Timing[]; - constructor(); - start(label: any): void; - stop(label: any): void; - render(): { - timings: { - total: number; - }; + start_time: number; + current_timing: Timing; + current_children: Timing[]; + timings: Timing[]; + stack: Timing[]; + constructor(); + start(label: any): void; + stop(label: any): void; + render(): { + timings: { + total: number; }; + }; } export {}; diff --git a/src/@types/compiler/compile/Component.d.ts b/src/@types/compiler/compile/Component.d.ts index 483c5f83d..0cfb1b8be 100644 --- a/src/@types/compiler/compile/Component.d.ts +++ b/src/@types/compiler/compile/Component.d.ts @@ -8,123 +8,131 @@ import Slot from './nodes/Slot'; import { Node, ImportDeclaration, Identifier } from 'estree'; import Element from './nodes/Element'; interface ComponentOptions { - namespace?: string; - tag?: string; - immutable?: boolean; - accessors?: boolean; - preserveWhitespace?: boolean; + namespace?: string; + tag?: string; + immutable?: boolean; + accessors?: boolean; + preserveWhitespace?: boolean; } export default class Component { - stats: Stats; - warnings: Warning[]; - ignores: Set<string>; - ignore_stack: Array<Set<string>>; + stats: Stats; + warnings: Warning[]; + ignores: Set<string>; + ignore_stack: Array<Set<string>>; + ast: Ast; + original_ast: Ast; + source: string; + name: Identifier; + compile_options: CompileOptions; + fragment: Fragment; + module_scope: Scope; + instance_scope: Scope; + instance_scope_map: WeakMap<Node, Scope>; + component_options: ComponentOptions; + namespace: string; + tag: string; + accessors: boolean; + vars: Var[]; + var_lookup: Map<string, Var>; + imports: ImportDeclaration[]; + hoistable_nodes: Set<Node>; + node_for_declaration: Map<string, Node>; + partly_hoisted: Array<Node | Node[]>; + fully_hoisted: Array<Node | Node[]>; + reactive_declarations: Array<{ + assignees: Set<string>; + dependencies: Set<string>; + node: Node; + declaration: Node; + }>; + reactive_declaration_nodes: Set<Node>; + has_reactive_assignments: boolean; + injected_reactive_declaration_vars: Set<string>; + helpers: Map<string, Identifier>; + globals: Map<string, Identifier>; + indirect_dependencies: Map<string, Set<string>>; + file: string; + locate: ( + c: number + ) => { + line: number; + column: number; + }; + elements: Element[]; + stylesheet: Stylesheet; + aliases: Map<string, Identifier>; + used_names: Set<string>; + globally_used_names: Set<string>; + slots: Map<string, Slot>; + slot_outlets: Set<string>; + constructor(ast: Ast, source: string, name: string, compile_options: CompileOptions, stats: Stats, warnings: Warning[]); + add_var(variable: Var): void; + add_reference(name: string): void; + alias(name: string): Identifier; + apply_stylesheet(element: Element): void; + global(name: string): Identifier; + generate(result?: { + js: Node[]; + css: CssResult; + }): { + js: any; + css: any; ast: Ast; - original_ast: Ast; - source: string; - name: Identifier; - compile_options: CompileOptions; - fragment: Fragment; - module_scope: Scope; - instance_scope: Scope; - instance_scope_map: WeakMap<Node, Scope>; - component_options: ComponentOptions; - namespace: string; - tag: string; - accessors: boolean; - vars: Var[]; - var_lookup: Map<string, Var>; - imports: ImportDeclaration[]; - hoistable_nodes: Set<Node>; - node_for_declaration: Map<string, Node>; - partly_hoisted: Array<(Node | Node[])>; - fully_hoisted: Array<(Node | Node[])>; - reactive_declarations: Array<{ - assignees: Set<string>; - dependencies: Set<string>; - node: Node; - declaration: Node; - }>; - reactive_declaration_nodes: Set<Node>; - has_reactive_assignments: boolean; - injected_reactive_declaration_vars: Set<string>; - helpers: Map<string, Identifier>; - globals: Map<string, Identifier>; - indirect_dependencies: Map<string, Set<string>>; - file: string; - locate: (c: number) => { - line: number; - column: number; - }; - elements: Element[]; - stylesheet: Stylesheet; - aliases: Map<string, Identifier>; - used_names: Set<string>; - globally_used_names: Set<string>; - slots: Map<string, Slot>; - slot_outlets: Set<string>; - constructor(ast: Ast, source: string, name: string, compile_options: CompileOptions, stats: Stats, warnings: Warning[]); - add_var(variable: Var): void; - add_reference(name: string): void; - alias(name: string): Identifier; - apply_stylesheet(element: Element): void; - global(name: string): Identifier; - generate(result?: { - js: Node[]; - css: CssResult; - }): { - js: any; - css: any; - ast: Ast; - warnings: Warning[]; - vars: { - name: string; - export_name: string; - injected: boolean; - module: boolean; - mutated: boolean; - reassigned: boolean; - referenced: boolean; - writable: boolean; - referenced_from_script: boolean; - }[]; - stats: { - timings: { - total: number; - }; - }; + warnings: Warning[]; + vars: { + name: string; + export_name: string; + injected: boolean; + module: boolean; + mutated: boolean; + reassigned: boolean; + referenced: boolean; + writable: boolean; + referenced_from_script: boolean; + }[]; + stats: { + timings: { + total: number; + }; }; - get_unique_name(name: string, scope?: Scope): Identifier; - get_unique_name_maker(): (name: string) => Identifier; - error(pos: { - start: number; - end: number; - }, e: { - code: string; - message: string; - }): void; - warn(pos: { - start: number; - end: number; - }, warning: { - code: string; - message: string; - }): void; - extract_imports(node: any): void; - extract_exports(node: any): any; - extract_javascript(script: any): any; - walk_module_js(): void; - walk_instance_js_pre_template(): void; - walk_instance_js_post_template(): void; - post_template_walk(): void; - track_references_and_mutations(): void; - warn_on_undefined_store_value_references(node: Node, parent: Node, prop: string, scope: Scope): void; - loop_protect(node: any, scope: Scope, timeout: number): Node | null; - rewrite_props(get_insert: (variable: Var) => Node[]): void; - hoist_instance_declarations(): void; - extract_reactive_declarations(): void; - warn_if_undefined(name: string, node: any, template_scope: TemplateScope): void; - push_ignores(ignores: any): void; - pop_ignores(): void; + }; + get_unique_name(name: string, scope?: Scope): Identifier; + get_unique_name_maker(): (name: string) => Identifier; + error( + pos: { + start: number; + end: number; + }, + e: { + code: string; + message: string; + } + ): void; + warn( + pos: { + start: number; + end: number; + }, + warning: { + code: string; + message: string; + } + ): void; + extract_imports(node: any): void; + extract_exports(node: any): any; + extract_javascript(script: any): any; + walk_module_js(): void; + walk_instance_js_pre_template(): void; + walk_instance_js_post_template(): void; + post_template_walk(): void; + track_references_and_mutations(): void; + warn_on_undefined_store_value_references(node: Node, parent: Node, prop: string, scope: Scope): void; + loop_protect(node: any, scope: Scope, timeout: number): Node | null; + rewrite_props(get_insert: (variable: Var) => Node[]): void; + hoist_instance_declarations(): void; + extract_reactive_declarations(): void; + warn_if_undefined(name: string, node: any, template_scope: TemplateScope): void; + push_ignores(ignores: any): void; + pop_ignores(): void; } export {}; diff --git a/src/@types/compiler/compile/create_module.d.ts b/src/@types/compiler/compile/create_module.d.ts index e6a18226c..075ccc5af 100644 --- a/src/@types/compiler/compile/create_module.d.ts +++ b/src/@types/compiler/compile/create_module.d.ts @@ -1,14 +1,24 @@ import { ModuleFormat } from '../interfaces'; import { Identifier, ImportDeclaration } from 'estree'; interface Export { - name: string; - as: string; + name: string; + as: string; } -export default function create_module(program: any, format: ModuleFormat, name: Identifier, banner: string, sveltePath: string, helpers: Array<{ +export default function create_module( + program: any, + format: ModuleFormat, + name: Identifier, + banner: string, + sveltePath: string, + helpers: Array<{ name: string; alias: Identifier; -}>, globals: Array<{ + }>, + globals: Array<{ name: string; alias: Identifier; -}>, imports: ImportDeclaration[], module_exports: Export[]): void; + }>, + imports: ImportDeclaration[], + module_exports: Export[] +): void; export {}; diff --git a/src/@types/compiler/compile/css/Selector.d.ts b/src/@types/compiler/compile/css/Selector.d.ts index 2ab73c3b6..f49f69234 100644 --- a/src/@types/compiler/compile/css/Selector.d.ts +++ b/src/@types/compiler/compile/css/Selector.d.ts @@ -4,27 +4,27 @@ import { CssNode } from './interfaces'; import Component from '../Component'; import Element from '../nodes/Element'; export default class Selector { - node: CssNode; - stylesheet: Stylesheet; - blocks: Block[]; - local_blocks: Block[]; - used: boolean; - constructor(node: CssNode, stylesheet: Stylesheet); - apply(node: Element): void; - minify(code: MagicString): void; - transform(code: MagicString, attr: string, max_amount_class_specificity_increased: number): void; - validate(component: Component): void; - get_amount_class_specificity_increased(): number; + node: CssNode; + stylesheet: Stylesheet; + blocks: Block[]; + local_blocks: Block[]; + used: boolean; + constructor(node: CssNode, stylesheet: Stylesheet); + apply(node: Element): void; + minify(code: MagicString): void; + transform(code: MagicString, attr: string, max_amount_class_specificity_increased: number): void; + validate(component: Component): void; + get_amount_class_specificity_increased(): number; } declare class Block { - global: boolean; - host: boolean; - combinator: CssNode; - selectors: CssNode[]; - start: number; - end: number; - should_encapsulate: boolean; - constructor(combinator: CssNode); - add(selector: CssNode): void; + global: boolean; + host: boolean; + combinator: CssNode; + selectors: CssNode[]; + start: number; + end: number; + should_encapsulate: boolean; + constructor(combinator: CssNode); + add(selector: CssNode): void; } export {}; diff --git a/src/@types/compiler/compile/css/Stylesheet.d.ts b/src/@types/compiler/compile/css/Stylesheet.d.ts index 5f80d2a27..71a1a24ca 100644 --- a/src/@types/compiler/compile/css/Stylesheet.d.ts +++ b/src/@types/compiler/compile/css/Stylesheet.d.ts @@ -5,63 +5,73 @@ import { Ast, CssHashGetter } from '../../interfaces'; import Component from '../Component'; import { CssNode } from './interfaces'; declare class Rule { - selectors: Selector[]; - declarations: Declaration[]; - node: CssNode; - parent: Atrule; - constructor(node: CssNode, stylesheet: any, parent?: Atrule); - apply(node: Element): void; - is_used(dev: boolean): boolean; - minify(code: MagicString, _dev: boolean): void; - transform(code: MagicString, id: string, keyframes: Map<string, string>, max_amount_class_specificity_increased: number): boolean; - validate(component: Component): void; - warn_on_unused_selector(handler: (selector: Selector) => void): void; - get_max_amount_class_specificity_increased(): number; + selectors: Selector[]; + declarations: Declaration[]; + node: CssNode; + parent: Atrule; + constructor(node: CssNode, stylesheet: any, parent?: Atrule); + apply(node: Element): void; + is_used(dev: boolean): boolean; + minify(code: MagicString, _dev: boolean): void; + transform(code: MagicString, id: string, keyframes: Map<string, string>, max_amount_class_specificity_increased: number): boolean; + validate(component: Component): void; + warn_on_unused_selector(handler: (selector: Selector) => void): void; + get_max_amount_class_specificity_increased(): number; } declare class Declaration { - node: CssNode; - constructor(node: CssNode); - transform(code: MagicString, keyframes: Map<string, string>): void; - minify(code: MagicString): void; + node: CssNode; + constructor(node: CssNode); + transform(code: MagicString, keyframes: Map<string, string>): void; + minify(code: MagicString): void; } declare class Atrule { - node: CssNode; - children: Array<Atrule | Rule>; - declarations: Declaration[]; - constructor(node: CssNode); - apply(node: Element): void; - is_used(_dev: boolean): boolean; - minify(code: MagicString, dev: boolean): void; - transform(code: MagicString, id: string, keyframes: Map<string, string>, max_amount_class_specificity_increased: number): void; - validate(component: Component): void; - warn_on_unused_selector(handler: (selector: Selector) => void): void; - get_max_amount_class_specificity_increased(): any; + node: CssNode; + children: Array<Atrule | Rule>; + declarations: Declaration[]; + constructor(node: CssNode); + apply(node: Element): void; + is_used(_dev: boolean): boolean; + minify(code: MagicString, dev: boolean): void; + transform(code: MagicString, id: string, keyframes: Map<string, string>, max_amount_class_specificity_increased: number): void; + validate(component: Component): void; + warn_on_unused_selector(handler: (selector: Selector) => void): void; + get_max_amount_class_specificity_increased(): any; } export default class Stylesheet { + source: string; + ast: Ast; + filename: string; + dev: boolean; + has_styles: boolean; + id: string; + children: Array<Rule | Atrule>; + keyframes: Map<string, string>; + nodes_with_css_class: Set<CssNode>; + constructor({ + source, + ast, + component_name, + filename, + dev, + get_css_hash, + }: { source: string; ast: Ast; - filename: string; + filename: string | undefined; + component_name: string | undefined; dev: boolean; - has_styles: boolean; - id: string; - children: Array<Rule | Atrule>; - keyframes: Map<string, string>; - nodes_with_css_class: Set<CssNode>; - constructor({ source, ast, component_name, filename, dev, get_css_hash }: { - source: string; - ast: Ast; - filename: string | undefined; - component_name: string | undefined; - dev: boolean; - get_css_hash: CssHashGetter; - }); - apply(node: Element): void; - reify(): void; - render(file: string, should_transform_selectors: boolean): { - code: string; - map: import("magic-string").SourceMap; - }; - validate(component: Component): void; - warn_on_unused_selectors(component: Component): void; + get_css_hash: CssHashGetter; + }); + apply(node: Element): void; + reify(): void; + render( + file: string, + should_transform_selectors: boolean + ): { + code: string; + map: import('magic-string').SourceMap; + }; + validate(component: Component): void; + warn_on_unused_selectors(component: Component): void; } export {}; diff --git a/src/@types/compiler/compile/css/interfaces.d.ts b/src/@types/compiler/compile/css/interfaces.d.ts index 6bbee6416..c7530a6dd 100644 --- a/src/@types/compiler/compile/css/interfaces.d.ts +++ b/src/@types/compiler/compile/css/interfaces.d.ts @@ -1,6 +1,6 @@ export interface CssNode { - type: string; - start: number; - end: number; - [prop_name: string]: any; + type: string; + start: number; + end: number; + [prop_name: string]: any; } diff --git a/src/@types/compiler/compile/index.d.ts b/src/@types/compiler/compile/index.d.ts index 8394b3a59..23d1e9830 100644 --- a/src/@types/compiler/compile/index.d.ts +++ b/src/@types/compiler/compile/index.d.ts @@ -1,23 +1,26 @@ import { CompileOptions, Warning } from '../interfaces'; -export default function compile(source: string, options?: CompileOptions): { - js: any; - css: any; - ast: import("../interfaces").Ast; - warnings: Warning[]; - vars: { - name: string; - export_name: string; - injected: boolean; - module: boolean; - mutated: boolean; - reassigned: boolean; - referenced: boolean; - writable: boolean; - referenced_from_script: boolean; - }[]; - stats: { - timings: { - total: number; - }; +export default function compile( + source: string, + options?: CompileOptions +): { + js: any; + css: any; + ast: import('../interfaces').Ast; + warnings: Warning[]; + vars: { + name: string; + export_name: string; + injected: boolean; + module: boolean; + mutated: boolean; + reassigned: boolean; + referenced: boolean; + writable: boolean; + referenced_from_script: boolean; + }[]; + stats: { + timings: { + total: number; }; + }; }; diff --git a/src/@types/compiler/compile/nodes/Action.d.ts b/src/@types/compiler/compile/nodes/Action.d.ts index cfbf7e774..571682935 100644 --- a/src/@types/compiler/compile/nodes/Action.d.ts +++ b/src/@types/compiler/compile/nodes/Action.d.ts @@ -4,10 +4,10 @@ import Component from '../Component'; import TemplateScope from './shared/TemplateScope'; import { Directive } from '../../interfaces'; export default class Action extends Node { - type: 'Action'; - name: string; - expression: Expression; - uses_context: boolean; - template_scope: TemplateScope; - constructor(component: Component, parent: Node, scope: TemplateScope, info: Directive); + type: 'Action'; + name: string; + expression: Expression; + uses_context: boolean; + template_scope: TemplateScope; + constructor(component: Component, parent: Node, scope: TemplateScope, info: Directive); } diff --git a/src/@types/compiler/compile/nodes/Animation.d.ts b/src/@types/compiler/compile/nodes/Animation.d.ts index 2bc43379c..5b4b75d83 100644 --- a/src/@types/compiler/compile/nodes/Animation.d.ts +++ b/src/@types/compiler/compile/nodes/Animation.d.ts @@ -5,8 +5,8 @@ import TemplateScope from './shared/TemplateScope'; import { TemplateNode } from '../../interfaces'; import Element from './Element'; export default class Animation extends Node { - type: 'Animation'; - name: string; - expression: Expression; - constructor(component: Component, parent: Element, scope: TemplateScope, info: TemplateNode); + type: 'Animation'; + name: string; + expression: Expression; + constructor(component: Component, parent: Element, scope: TemplateScope, info: TemplateNode); } diff --git a/src/@types/compiler/compile/nodes/Attribute.d.ts b/src/@types/compiler/compile/nodes/Attribute.d.ts index aaa589ad3..12e78962c 100644 --- a/src/@types/compiler/compile/nodes/Attribute.d.ts +++ b/src/@types/compiler/compile/nodes/Attribute.d.ts @@ -6,25 +6,97 @@ import Expression from './shared/Expression'; import TemplateScope from './shared/TemplateScope'; import { TemplateNode } from '../../interfaces'; export default class Attribute extends Node { - type: 'Attribute' | 'Spread'; - start: number; - end: number; - scope: TemplateScope; - component: Component; - parent: Element; - name: string; - is_spread: boolean; - is_true: boolean; - is_static: boolean; - expression?: Expression; - chunks: Array<Text | Expression>; - dependencies: Set<string>; - constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); - get_dependencies(): string[]; - get_value(block: any): import("estree").Identifier | import("estree").SimpleLiteral | import("estree").RegExpLiteral | import("estree").Program | import("estree").FunctionDeclaration | import("estree").FunctionExpression | import("estree").ArrowFunctionExpression | import("estree").SwitchCase | import("estree").CatchClause | import("estree").VariableDeclarator | import("estree").ExpressionStatement | import("estree").BlockStatement | import("estree").EmptyStatement | import("estree").DebuggerStatement | import("estree").WithStatement | import("estree").ReturnStatement | import("estree").LabeledStatement | import("estree").BreakStatement | import("estree").ContinueStatement | import("estree").IfStatement | import("estree").SwitchStatement | import("estree").ThrowStatement | import("estree").TryStatement | import("estree").WhileStatement | import("estree").DoWhileStatement | import("estree").ForStatement | import("estree").ForInStatement | import("estree").ForOfStatement | import("estree").VariableDeclaration | import("estree").ClassDeclaration | import("estree").ThisExpression | import("estree").ArrayExpression | import("estree").ObjectExpression | import("estree").YieldExpression | import("estree").UnaryExpression | import("estree").UpdateExpression | import("estree").BinaryExpression | import("estree").AssignmentExpression | import("estree").LogicalExpression | import("estree").MemberExpression | import("estree").ConditionalExpression | import("estree").SimpleCallExpression | import("estree").NewExpression | import("estree").SequenceExpression | import("estree").TemplateLiteral | import("estree").TaggedTemplateExpression | import("estree").ClassExpression | import("estree").MetaProperty | import("estree").AwaitExpression | import("estree").ImportExpression | import("estree").ChainExpression | import("estree").Property | import("estree").Super | import("estree").TemplateElement | import("estree").SpreadElement | import("estree").ObjectPattern | import("estree").ArrayPattern | import("estree").RestElement | import("estree").AssignmentPattern | import("estree").ClassBody | import("estree").MethodDefinition | import("estree").ImportDeclaration | import("estree").ExportNamedDeclaration | import("estree").ExportDefaultDeclaration | import("estree").ExportAllDeclaration | import("estree").ImportSpecifier | import("estree").ImportDefaultSpecifier | import("estree").ImportNamespaceSpecifier | import("estree").ExportSpecifier | { + type: 'Attribute' | 'Spread'; + start: number; + end: number; + scope: TemplateScope; + component: Component; + parent: Element; + name: string; + is_spread: boolean; + is_true: boolean; + is_static: boolean; + expression?: Expression; + chunks: Array<Text | Expression>; + dependencies: Set<string>; + constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); + get_dependencies(): string[]; + get_value( + block: any + ): + | import('estree').Identifier + | import('estree').SimpleLiteral + | import('estree').RegExpLiteral + | import('estree').Program + | import('estree').FunctionDeclaration + | import('estree').FunctionExpression + | import('estree').ArrowFunctionExpression + | import('estree').SwitchCase + | import('estree').CatchClause + | import('estree').VariableDeclarator + | import('estree').ExpressionStatement + | import('estree').BlockStatement + | import('estree').EmptyStatement + | import('estree').DebuggerStatement + | import('estree').WithStatement + | import('estree').ReturnStatement + | import('estree').LabeledStatement + | import('estree').BreakStatement + | import('estree').ContinueStatement + | import('estree').IfStatement + | import('estree').SwitchStatement + | import('estree').ThrowStatement + | import('estree').TryStatement + | import('estree').WhileStatement + | import('estree').DoWhileStatement + | import('estree').ForStatement + | import('estree').ForInStatement + | import('estree').ForOfStatement + | import('estree').VariableDeclaration + | import('estree').ClassDeclaration + | import('estree').ThisExpression + | import('estree').ArrayExpression + | import('estree').ObjectExpression + | import('estree').YieldExpression + | import('estree').UnaryExpression + | import('estree').UpdateExpression + | import('estree').BinaryExpression + | import('estree').AssignmentExpression + | import('estree').LogicalExpression + | import('estree').MemberExpression + | import('estree').ConditionalExpression + | import('estree').SimpleCallExpression + | import('estree').NewExpression + | import('estree').SequenceExpression + | import('estree').TemplateLiteral + | import('estree').TaggedTemplateExpression + | import('estree').ClassExpression + | import('estree').MetaProperty + | import('estree').AwaitExpression + | import('estree').ImportExpression + | import('estree').ChainExpression + | import('estree').Property + | import('estree').Super + | import('estree').TemplateElement + | import('estree').SpreadElement + | import('estree').ObjectPattern + | import('estree').ArrayPattern + | import('estree').RestElement + | import('estree').AssignmentPattern + | import('estree').ClassBody + | import('estree').MethodDefinition + | import('estree').ImportDeclaration + | import('estree').ExportNamedDeclaration + | import('estree').ExportDefaultDeclaration + | import('estree').ExportAllDeclaration + | import('estree').ImportSpecifier + | import('estree').ImportDefaultSpecifier + | import('estree').ImportNamespaceSpecifier + | import('estree').ExportSpecifier + | { type: string; value: string; - }; - get_static_value(): string | true; - should_cache(): boolean; + }; + get_static_value(): string | true; + should_cache(): boolean; } diff --git a/src/@types/compiler/compile/nodes/AwaitBlock.d.ts b/src/@types/compiler/compile/nodes/AwaitBlock.d.ts index 0a5130787..4ebf8f073 100644 --- a/src/@types/compiler/compile/nodes/AwaitBlock.d.ts +++ b/src/@types/compiler/compile/nodes/AwaitBlock.d.ts @@ -9,14 +9,14 @@ import { TemplateNode } from '../../interfaces'; import { Context } from './shared/Context'; import { Node as ESTreeNode } from 'estree'; export default class AwaitBlock extends Node { - type: 'AwaitBlock'; - expression: Expression; - then_contexts: Context[]; - catch_contexts: Context[]; - then_node: ESTreeNode | null; - catch_node: ESTreeNode | null; - pending: PendingBlock; - then: ThenBlock; - catch: CatchBlock; - constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); + type: 'AwaitBlock'; + expression: Expression; + then_contexts: Context[]; + catch_contexts: Context[]; + then_node: ESTreeNode | null; + catch_node: ESTreeNode | null; + pending: PendingBlock; + then: ThenBlock; + catch: CatchBlock; + constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); } diff --git a/src/@types/compiler/compile/nodes/Binding.d.ts b/src/@types/compiler/compile/nodes/Binding.d.ts index 43769b2ac..a8f7ab3b0 100644 --- a/src/@types/compiler/compile/nodes/Binding.d.ts +++ b/src/@types/compiler/compile/nodes/Binding.d.ts @@ -8,12 +8,12 @@ import Element from './Element'; import InlineComponent from './InlineComponent'; import Window from './Window'; export default class Binding extends Node { - type: 'Binding'; - name: string; - expression: Expression; - raw_expression: ESTreeNode; - is_contextual: boolean; - is_readonly: boolean; - constructor(component: Component, parent: Element | InlineComponent | Window, scope: TemplateScope, info: TemplateNode); - is_readonly_media_attribute(): boolean; + type: 'Binding'; + name: string; + expression: Expression; + raw_expression: ESTreeNode; + is_contextual: boolean; + is_readonly: boolean; + constructor(component: Component, parent: Element | InlineComponent | Window, scope: TemplateScope, info: TemplateNode); + is_readonly_media_attribute(): boolean; } diff --git a/src/@types/compiler/compile/nodes/Body.d.ts b/src/@types/compiler/compile/nodes/Body.d.ts index 8c024c13a..19c61e65a 100644 --- a/src/@types/compiler/compile/nodes/Body.d.ts +++ b/src/@types/compiler/compile/nodes/Body.d.ts @@ -4,7 +4,7 @@ import Component from '../Component'; import TemplateScope from './shared/TemplateScope'; import { TemplateNode } from '../../interfaces'; export default class Body extends Node { - type: 'Body'; - handlers: EventHandler[]; - constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); + type: 'Body'; + handlers: EventHandler[]; + constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); } diff --git a/src/@types/compiler/compile/nodes/CatchBlock.d.ts b/src/@types/compiler/compile/nodes/CatchBlock.d.ts index ec1e952ad..cf7abad64 100644 --- a/src/@types/compiler/compile/nodes/CatchBlock.d.ts +++ b/src/@types/compiler/compile/nodes/CatchBlock.d.ts @@ -4,7 +4,7 @@ import AwaitBlock from './AwaitBlock'; import Component from '../Component'; import { TemplateNode } from '../../interfaces'; export default class CatchBlock extends AbstractBlock { - type: 'CatchBlock'; - scope: TemplateScope; - constructor(component: Component, parent: AwaitBlock, scope: TemplateScope, info: TemplateNode); + type: 'CatchBlock'; + scope: TemplateScope; + constructor(component: Component, parent: AwaitBlock, scope: TemplateScope, info: TemplateNode); } diff --git a/src/@types/compiler/compile/nodes/Class.d.ts b/src/@types/compiler/compile/nodes/Class.d.ts index d3365c738..d2bd8f018 100644 --- a/src/@types/compiler/compile/nodes/Class.d.ts +++ b/src/@types/compiler/compile/nodes/Class.d.ts @@ -4,8 +4,8 @@ import { TemplateNode } from '../../interfaces'; import TemplateScope from './shared/TemplateScope'; import Component from '../Component'; export default class Class extends Node { - type: 'Class'; - name: string; - expression: Expression; - constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); + type: 'Class'; + name: string; + expression: Expression; + constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); } diff --git a/src/@types/compiler/compile/nodes/Comment.d.ts b/src/@types/compiler/compile/nodes/Comment.d.ts index 6fb0cea27..89e399e2e 100644 --- a/src/@types/compiler/compile/nodes/Comment.d.ts +++ b/src/@types/compiler/compile/nodes/Comment.d.ts @@ -3,8 +3,8 @@ import Component from '../Component'; import Node from './shared/Node'; import TemplateScope from './shared/TemplateScope'; export default class Comment extends Node { - type: 'Comment'; - data: string; - ignores: string[]; - constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); + type: 'Comment'; + data: string; + ignores: string[]; + constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); } diff --git a/src/@types/compiler/compile/nodes/DebugTag.d.ts b/src/@types/compiler/compile/nodes/DebugTag.d.ts index 2241e7ace..95355425f 100644 --- a/src/@types/compiler/compile/nodes/DebugTag.d.ts +++ b/src/@types/compiler/compile/nodes/DebugTag.d.ts @@ -5,7 +5,7 @@ import TemplateScope from './shared/TemplateScope'; import { TemplateNode } from '../../interfaces'; import { INode } from './interfaces'; export default class DebugTag extends Node { - type: 'DebugTag'; - expressions: Expression[]; - constructor(component: Component, parent: INode, scope: TemplateScope, info: TemplateNode); + type: 'DebugTag'; + expressions: Expression[]; + constructor(component: Component, parent: INode, scope: TemplateScope, info: TemplateNode); } diff --git a/src/@types/compiler/compile/nodes/DefaultSlotTemplate.d.ts b/src/@types/compiler/compile/nodes/DefaultSlotTemplate.d.ts index 77729362b..2f99064c6 100644 --- a/src/@types/compiler/compile/nodes/DefaultSlotTemplate.d.ts +++ b/src/@types/compiler/compile/nodes/DefaultSlotTemplate.d.ts @@ -4,10 +4,10 @@ import Node from './shared/Node'; import Let from './Let'; import { INode } from './interfaces'; export default class DefaultSlotTemplate extends Node { - type: 'SlotTemplate'; - scope: TemplateScope; - children: INode[]; - lets: Let[]; - slot_template_name: string; - constructor(component: Component, parent: INode, scope: TemplateScope, info: any, lets: Let[], children: INode[]); + type: 'SlotTemplate'; + scope: TemplateScope; + children: INode[]; + lets: Let[]; + slot_template_name: string; + constructor(component: Component, parent: INode, scope: TemplateScope, info: any, lets: Let[], children: INode[]); } diff --git a/src/@types/compiler/compile/nodes/EachBlock.d.ts b/src/@types/compiler/compile/nodes/EachBlock.d.ts index 81be9c074..23480c839 100644 --- a/src/@types/compiler/compile/nodes/EachBlock.d.ts +++ b/src/@types/compiler/compile/nodes/EachBlock.d.ts @@ -7,18 +7,18 @@ import { Node } from 'estree'; import Component from '../Component'; import { TemplateNode } from '../../interfaces'; export default class EachBlock extends AbstractBlock { - type: 'EachBlock'; - expression: Expression; - context_node: Node; - iterations: string; - index: string; - context: string; - key: Expression; - scope: TemplateScope; - contexts: Context[]; - has_animation: boolean; - has_binding: boolean; - has_index_binding: boolean; - else?: ElseBlock; - constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); + type: 'EachBlock'; + expression: Expression; + context_node: Node; + iterations: string; + index: string; + context: string; + key: Expression; + scope: TemplateScope; + contexts: Context[]; + has_animation: boolean; + has_binding: boolean; + has_index_binding: boolean; + else?: ElseBlock; + constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); } diff --git a/src/@types/compiler/compile/nodes/Element.d.ts b/src/@types/compiler/compile/nodes/Element.d.ts index 016ebe2c1..0b519af70 100644 --- a/src/@types/compiler/compile/nodes/Element.d.ts +++ b/src/@types/compiler/compile/nodes/Element.d.ts @@ -11,31 +11,31 @@ import TemplateScope from './shared/TemplateScope'; import { INode } from './interfaces'; import Component from '../Component'; export default class Element extends Node { - type: 'Element'; - name: string; - scope: TemplateScope; - attributes: Attribute[]; - actions: Action[]; - bindings: Binding[]; - classes: Class[]; - handlers: EventHandler[]; - lets: Let[]; - intro?: Transition; - outro?: Transition; - animation?: Animation; - children: INode[]; - namespace: string; - needs_manual_style_scoping: boolean; - constructor(component: Component, parent: Node, scope: TemplateScope, info: any); - validate(): void; - validate_attributes(): void; - validate_attributes_a11y(): void; - validate_special_cases(): void; - validate_bindings_foreign(): void; - validate_bindings(): void; - validate_content(): void; - validate_event_handlers(): void; - is_media_node(): boolean; - add_css_class(): void; - get slot_template_name(): string; + type: 'Element'; + name: string; + scope: TemplateScope; + attributes: Attribute[]; + actions: Action[]; + bindings: Binding[]; + classes: Class[]; + handlers: EventHandler[]; + lets: Let[]; + intro?: Transition; + outro?: Transition; + animation?: Animation; + children: INode[]; + namespace: string; + needs_manual_style_scoping: boolean; + constructor(component: Component, parent: Node, scope: TemplateScope, info: any); + validate(): void; + validate_attributes(): void; + validate_attributes_a11y(): void; + validate_special_cases(): void; + validate_bindings_foreign(): void; + validate_bindings(): void; + validate_content(): void; + validate_event_handlers(): void; + is_media_node(): boolean; + add_css_class(): void; + get slot_template_name(): string; } diff --git a/src/@types/compiler/compile/nodes/ElseBlock.d.ts b/src/@types/compiler/compile/nodes/ElseBlock.d.ts index bc371e0e9..1c1cc1406 100644 --- a/src/@types/compiler/compile/nodes/ElseBlock.d.ts +++ b/src/@types/compiler/compile/nodes/ElseBlock.d.ts @@ -4,6 +4,6 @@ import TemplateScope from './shared/TemplateScope'; import { TemplateNode } from '../../interfaces'; import Node from './shared/Node'; export default class ElseBlock extends AbstractBlock { - type: 'ElseBlock'; - constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); + type: 'ElseBlock'; + constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); } diff --git a/src/@types/compiler/compile/nodes/EventHandler.d.ts b/src/@types/compiler/compile/nodes/EventHandler.d.ts index d7c58de00..03d1575bf 100644 --- a/src/@types/compiler/compile/nodes/EventHandler.d.ts +++ b/src/@types/compiler/compile/nodes/EventHandler.d.ts @@ -5,13 +5,13 @@ import { Identifier } from 'estree'; import TemplateScope from './shared/TemplateScope'; import { TemplateNode } from '../../interfaces'; export default class EventHandler extends Node { - type: 'EventHandler'; - name: string; - modifiers: Set<string>; - expression: Expression; - handler_name: Identifier; - uses_context: boolean; - can_make_passive: boolean; - constructor(component: Component, parent: Node, template_scope: TemplateScope, info: TemplateNode); - get reassigned(): boolean; + type: 'EventHandler'; + name: string; + modifiers: Set<string>; + expression: Expression; + handler_name: Identifier; + uses_context: boolean; + can_make_passive: boolean; + constructor(component: Component, parent: Node, template_scope: TemplateScope, info: TemplateNode); + get reassigned(): boolean; } diff --git a/src/@types/compiler/compile/nodes/Fragment.d.ts b/src/@types/compiler/compile/nodes/Fragment.d.ts index a382218d8..a491da6a2 100644 --- a/src/@types/compiler/compile/nodes/Fragment.d.ts +++ b/src/@types/compiler/compile/nodes/Fragment.d.ts @@ -5,9 +5,9 @@ import TemplateScope from './shared/TemplateScope'; import { INode } from './interfaces'; import { TemplateNode } from '../../interfaces'; export default class Fragment extends Node { - type: 'Fragment'; - block: Block; - children: INode[]; - scope: TemplateScope; - constructor(component: Component, info: TemplateNode); + type: 'Fragment'; + block: Block; + children: INode[]; + scope: TemplateScope; + constructor(component: Component, info: TemplateNode); } diff --git a/src/@types/compiler/compile/nodes/Head.d.ts b/src/@types/compiler/compile/nodes/Head.d.ts index 736bbc4a9..ab2322087 100644 --- a/src/@types/compiler/compile/nodes/Head.d.ts +++ b/src/@types/compiler/compile/nodes/Head.d.ts @@ -3,8 +3,8 @@ import Component from '../Component'; import TemplateScope from './shared/TemplateScope'; import { TemplateNode } from '../../interfaces'; export default class Head extends Node { - type: 'Head'; - children: any[]; - id: string; - constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); + type: 'Head'; + children: any[]; + id: string; + constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); } diff --git a/src/@types/compiler/compile/nodes/IfBlock.d.ts b/src/@types/compiler/compile/nodes/IfBlock.d.ts index 14418cb07..02049ee87 100644 --- a/src/@types/compiler/compile/nodes/IfBlock.d.ts +++ b/src/@types/compiler/compile/nodes/IfBlock.d.ts @@ -6,8 +6,8 @@ import TemplateScope from './shared/TemplateScope'; import { TemplateNode } from '../../interfaces'; import Node from './shared/Node'; export default class IfBlock extends AbstractBlock { - type: 'IfBlock'; - expression: Expression; - else: ElseBlock; - constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); + type: 'IfBlock'; + expression: Expression; + else: ElseBlock; + constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); } diff --git a/src/@types/compiler/compile/nodes/InlineComponent.d.ts b/src/@types/compiler/compile/nodes/InlineComponent.d.ts index c555ed124..7b01a7a7f 100644 --- a/src/@types/compiler/compile/nodes/InlineComponent.d.ts +++ b/src/@types/compiler/compile/nodes/InlineComponent.d.ts @@ -9,15 +9,15 @@ import TemplateScope from './shared/TemplateScope'; import { INode } from './interfaces'; import { TemplateNode } from '../../interfaces'; export default class InlineComponent extends Node { - type: 'InlineComponent'; - name: string; - expression: Expression; - attributes: Attribute[]; - bindings: Binding[]; - handlers: EventHandler[]; - lets: Let[]; - children: INode[]; - scope: TemplateScope; - constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); - get slot_template_name(): string; + type: 'InlineComponent'; + name: string; + expression: Expression; + attributes: Attribute[]; + bindings: Binding[]; + handlers: EventHandler[]; + lets: Let[]; + children: INode[]; + scope: TemplateScope; + constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); + get slot_template_name(): string; } diff --git a/src/@types/compiler/compile/nodes/KeyBlock.d.ts b/src/@types/compiler/compile/nodes/KeyBlock.d.ts index 38c62be80..9c6df46b8 100644 --- a/src/@types/compiler/compile/nodes/KeyBlock.d.ts +++ b/src/@types/compiler/compile/nodes/KeyBlock.d.ts @@ -5,7 +5,7 @@ import TemplateScope from './shared/TemplateScope'; import { TemplateNode } from '../../interfaces'; import Node from './shared/Node'; export default class KeyBlock extends AbstractBlock { - type: 'KeyBlock'; - expression: Expression; - constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); + type: 'KeyBlock'; + expression: Expression; + constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); } diff --git a/src/@types/compiler/compile/nodes/Let.d.ts b/src/@types/compiler/compile/nodes/Let.d.ts index 6fb24b118..43065e0c6 100644 --- a/src/@types/compiler/compile/nodes/Let.d.ts +++ b/src/@types/compiler/compile/nodes/Let.d.ts @@ -4,9 +4,9 @@ import { Identifier } from 'estree'; import TemplateScope from './shared/TemplateScope'; import { TemplateNode } from '../../interfaces'; export default class Let extends Node { - type: 'Let'; - name: Identifier; - value: Identifier; - names: string[]; - constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); + type: 'Let'; + name: Identifier; + value: Identifier; + names: string[]; + constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); } diff --git a/src/@types/compiler/compile/nodes/MustacheTag.d.ts b/src/@types/compiler/compile/nodes/MustacheTag.d.ts index f659e3d44..e1a5dc964 100644 --- a/src/@types/compiler/compile/nodes/MustacheTag.d.ts +++ b/src/@types/compiler/compile/nodes/MustacheTag.d.ts @@ -1,4 +1,4 @@ import Tag from './shared/Tag'; export default class MustacheTag extends Tag { - type: 'MustacheTag'; + type: 'MustacheTag'; } diff --git a/src/@types/compiler/compile/nodes/Options.d.ts b/src/@types/compiler/compile/nodes/Options.d.ts index d114122fb..a61fac82c 100644 --- a/src/@types/compiler/compile/nodes/Options.d.ts +++ b/src/@types/compiler/compile/nodes/Options.d.ts @@ -1,4 +1,4 @@ import Node from './shared/Node'; export default class Options extends Node { - type: 'Options'; + type: 'Options'; } diff --git a/src/@types/compiler/compile/nodes/PendingBlock.d.ts b/src/@types/compiler/compile/nodes/PendingBlock.d.ts index 3b3ffa36d..b2cd09490 100644 --- a/src/@types/compiler/compile/nodes/PendingBlock.d.ts +++ b/src/@types/compiler/compile/nodes/PendingBlock.d.ts @@ -4,6 +4,6 @@ import TemplateScope from './shared/TemplateScope'; import { TemplateNode } from '../../interfaces'; import Node from './shared/Node'; export default class PendingBlock extends AbstractBlock { - type: 'PendingBlock'; - constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); + type: 'PendingBlock'; + constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); } diff --git a/src/@types/compiler/compile/nodes/RawMustacheTag.d.ts b/src/@types/compiler/compile/nodes/RawMustacheTag.d.ts index 98b279d86..a3c624b50 100644 --- a/src/@types/compiler/compile/nodes/RawMustacheTag.d.ts +++ b/src/@types/compiler/compile/nodes/RawMustacheTag.d.ts @@ -1,4 +1,4 @@ import Tag from './shared/Tag'; export default class RawMustacheTag extends Tag { - type: 'RawMustacheTag'; + type: 'RawMustacheTag'; } diff --git a/src/@types/compiler/compile/nodes/Slot.d.ts b/src/@types/compiler/compile/nodes/Slot.d.ts index b27476b3c..fb69f91de 100644 --- a/src/@types/compiler/compile/nodes/Slot.d.ts +++ b/src/@types/compiler/compile/nodes/Slot.d.ts @@ -5,10 +5,10 @@ import TemplateScope from './shared/TemplateScope'; import { INode } from './interfaces'; import { TemplateNode } from '../../interfaces'; export default class Slot extends Element { - type: 'Element'; - name: string; - children: INode[]; - slot_name: string; - values: Map<string, Attribute>; - constructor(component: Component, parent: INode, scope: TemplateScope, info: TemplateNode); + type: 'Element'; + name: string; + children: INode[]; + slot_name: string; + values: Map<string, Attribute>; + constructor(component: Component, parent: INode, scope: TemplateScope, info: TemplateNode); } diff --git a/src/@types/compiler/compile/nodes/SlotTemplate.d.ts b/src/@types/compiler/compile/nodes/SlotTemplate.d.ts index 4722632d2..65f649a44 100644 --- a/src/@types/compiler/compile/nodes/SlotTemplate.d.ts +++ b/src/@types/compiler/compile/nodes/SlotTemplate.d.ts @@ -5,12 +5,12 @@ import Let from './Let'; import Attribute from './Attribute'; import { INode } from './interfaces'; export default class SlotTemplate extends Node { - type: 'SlotTemplate'; - scope: TemplateScope; - children: INode[]; - lets: Let[]; - slot_attribute: Attribute; - slot_template_name: string; - constructor(component: Component, parent: INode, scope: TemplateScope, info: any); - validate_slot_template_placement(): void; + type: 'SlotTemplate'; + scope: TemplateScope; + children: INode[]; + lets: Let[]; + slot_attribute: Attribute; + slot_template_name: string; + constructor(component: Component, parent: INode, scope: TemplateScope, info: any); + validate_slot_template_placement(): void; } diff --git a/src/@types/compiler/compile/nodes/Text.d.ts b/src/@types/compiler/compile/nodes/Text.d.ts index e0f4570d0..ab1d940c5 100644 --- a/src/@types/compiler/compile/nodes/Text.d.ts +++ b/src/@types/compiler/compile/nodes/Text.d.ts @@ -4,9 +4,9 @@ import TemplateScope from './shared/TemplateScope'; import { INode } from './interfaces'; import { TemplateNode } from '../../interfaces'; export default class Text extends Node { - type: 'Text'; - data: string; - synthetic: boolean; - constructor(component: Component, parent: INode, scope: TemplateScope, info: TemplateNode); - should_skip(): any; + type: 'Text'; + data: string; + synthetic: boolean; + constructor(component: Component, parent: INode, scope: TemplateScope, info: TemplateNode); + should_skip(): any; } diff --git a/src/@types/compiler/compile/nodes/ThenBlock.d.ts b/src/@types/compiler/compile/nodes/ThenBlock.d.ts index 2a0a4c379..d6be4438f 100644 --- a/src/@types/compiler/compile/nodes/ThenBlock.d.ts +++ b/src/@types/compiler/compile/nodes/ThenBlock.d.ts @@ -4,7 +4,7 @@ import AwaitBlock from './AwaitBlock'; import Component from '../Component'; import { TemplateNode } from '../../interfaces'; export default class ThenBlock extends AbstractBlock { - type: 'ThenBlock'; - scope: TemplateScope; - constructor(component: Component, parent: AwaitBlock, scope: TemplateScope, info: TemplateNode); + type: 'ThenBlock'; + scope: TemplateScope; + constructor(component: Component, parent: AwaitBlock, scope: TemplateScope, info: TemplateNode); } diff --git a/src/@types/compiler/compile/nodes/Title.d.ts b/src/@types/compiler/compile/nodes/Title.d.ts index 8288a0583..092629f15 100644 --- a/src/@types/compiler/compile/nodes/Title.d.ts +++ b/src/@types/compiler/compile/nodes/Title.d.ts @@ -4,8 +4,8 @@ import Component from '../Component'; import TemplateScope from './shared/TemplateScope'; import { TemplateNode } from '../../interfaces'; export default class Title extends Node { - type: 'Title'; - children: Children; - should_cache: boolean; - constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); + type: 'Title'; + children: Children; + should_cache: boolean; + constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); } diff --git a/src/@types/compiler/compile/nodes/Transition.d.ts b/src/@types/compiler/compile/nodes/Transition.d.ts index 7ce9dc7b0..9415609dd 100644 --- a/src/@types/compiler/compile/nodes/Transition.d.ts +++ b/src/@types/compiler/compile/nodes/Transition.d.ts @@ -5,10 +5,10 @@ import TemplateScope from './shared/TemplateScope'; import { TemplateNode } from '../../interfaces'; import Element from './Element'; export default class Transition extends Node { - type: 'Transition'; - name: string; - directive: string; - expression: Expression; - is_local: boolean; - constructor(component: Component, parent: Element, scope: TemplateScope, info: TemplateNode); + type: 'Transition'; + name: string; + directive: string; + expression: Expression; + is_local: boolean; + constructor(component: Component, parent: Element, scope: TemplateScope, info: TemplateNode); } diff --git a/src/@types/compiler/compile/nodes/Window.d.ts b/src/@types/compiler/compile/nodes/Window.d.ts index 183a8cc13..dfe573cac 100644 --- a/src/@types/compiler/compile/nodes/Window.d.ts +++ b/src/@types/compiler/compile/nodes/Window.d.ts @@ -6,9 +6,9 @@ import Component from '../Component'; import TemplateScope from './shared/TemplateScope'; import { TemplateNode } from '../../interfaces'; export default class Window extends Node { - type: 'Window'; - handlers: EventHandler[]; - bindings: Binding[]; - actions: Action[]; - constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); + type: 'Window'; + handlers: EventHandler[]; + bindings: Binding[]; + actions: Action[]; + constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode); } diff --git a/src/@types/compiler/compile/nodes/interfaces.d.ts b/src/@types/compiler/compile/nodes/interfaces.d.ts index 0995951a3..51d8145e7 100644 --- a/src/@types/compiler/compile/nodes/interfaces.d.ts +++ b/src/@types/compiler/compile/nodes/interfaces.d.ts @@ -31,4 +31,37 @@ import ThenBlock from './ThenBlock'; import Title from './Title'; import Transition from './Transition'; import Window from './Window'; -export declare type INode = Action | Animation | Attribute | AwaitBlock | Binding | Body | CatchBlock | Class | Comment | DebugTag | EachBlock | Element | ElseBlock | EventHandler | Fragment | Head | IfBlock | InlineComponent | KeyBlock | Let | MustacheTag | Options | PendingBlock | RawMustacheTag | Slot | SlotTemplate | DefaultSlotTemplate | Tag | Text | ThenBlock | Title | Transition | Window; +export declare type INode = + | Action + | Animation + | Attribute + | AwaitBlock + | Binding + | Body + | CatchBlock + | Class + | Comment + | DebugTag + | EachBlock + | Element + | ElseBlock + | EventHandler + | Fragment + | Head + | IfBlock + | InlineComponent + | KeyBlock + | Let + | MustacheTag + | Options + | PendingBlock + | RawMustacheTag + | Slot + | SlotTemplate + | DefaultSlotTemplate + | Tag + | Text + | ThenBlock + | Title + | Transition + | Window; diff --git a/src/@types/compiler/compile/nodes/shared/AbstractBlock.d.ts b/src/@types/compiler/compile/nodes/shared/AbstractBlock.d.ts index 9dea594b8..6379acaf3 100644 --- a/src/@types/compiler/compile/nodes/shared/AbstractBlock.d.ts +++ b/src/@types/compiler/compile/nodes/shared/AbstractBlock.d.ts @@ -3,8 +3,8 @@ import Component from '../../Component'; import Node from './Node'; import { INode } from '../interfaces'; export default class AbstractBlock extends Node { - block: Block; - children: INode[]; - constructor(component: Component, parent: any, scope: any, info: any); - warn_if_empty_block(): void; + block: Block; + children: INode[]; + constructor(component: Component, parent: any, scope: any, info: any); + warn_if_empty_block(): void; } diff --git a/src/@types/compiler/compile/nodes/shared/Context.d.ts b/src/@types/compiler/compile/nodes/shared/Context.d.ts index 5c401a7f4..aca6133a9 100644 --- a/src/@types/compiler/compile/nodes/shared/Context.d.ts +++ b/src/@types/compiler/compile/nodes/shared/Context.d.ts @@ -1,8 +1,8 @@ import { Node, Identifier } from 'estree'; export interface Context { - key: Identifier; - name?: string; - modifier: (node: Node) => Node; - default_modifier: (node: Node, to_ctx: (name: string) => Node) => Node; + key: Identifier; + name?: string; + modifier: (node: Node) => Node; + default_modifier: (node: Node, to_ctx: (name: string) => Node) => Node; } export declare function unpack_destructuring(contexts: Context[], node: Node, modifier?: Context['modifier'], default_modifier?: Context['default_modifier']): void; diff --git a/src/@types/compiler/compile/nodes/shared/Expression.d.ts b/src/@types/compiler/compile/nodes/shared/Expression.d.ts index 6764bfc2c..b9b24f6eb 100644 --- a/src/@types/compiler/compile/nodes/shared/Expression.d.ts +++ b/src/@types/compiler/compile/nodes/shared/Expression.d.ts @@ -6,21 +6,21 @@ import { Node } from 'estree'; import { INode } from '../interfaces'; declare type Owner = INode; export default class Expression { - type: 'Expression'; - component: Component; - owner: Owner; - node: Node; - references: Set<string>; - dependencies: Set<string>; - contextual_dependencies: Set<string>; - template_scope: TemplateScope; - scope: Scope; - scope_map: WeakMap<Node, Scope>; - declarations: Array<(Node | Node[])>; - uses_context: boolean; - manipulated: Node; - constructor(component: Component, owner: Owner, template_scope: TemplateScope, info: Node, lazy?: boolean); - dynamic_dependencies(): string[]; - manipulate(block?: Block): Node; + type: 'Expression'; + component: Component; + owner: Owner; + node: Node; + references: Set<string>; + dependencies: Set<string>; + contextual_dependencies: Set<string>; + template_scope: TemplateScope; + scope: Scope; + scope_map: WeakMap<Node, Scope>; + declarations: Array<Node | Node[]>; + uses_context: boolean; + manipulated: Node; + constructor(component: Component, owner: Owner, template_scope: TemplateScope, info: Node, lazy?: boolean); + dynamic_dependencies(): string[]; + manipulate(block?: Block): Node; } export {}; diff --git a/src/@types/compiler/compile/nodes/shared/Node.d.ts b/src/@types/compiler/compile/nodes/shared/Node.d.ts index 783009441..0c2b945ff 100644 --- a/src/@types/compiler/compile/nodes/shared/Node.d.ts +++ b/src/@types/compiler/compile/nodes/shared/Node.d.ts @@ -3,19 +3,19 @@ import Component from '../../Component'; import { INode } from '../interfaces'; import { TemplateNode } from '../../../interfaces'; export default class Node { - readonly start: number; - readonly end: number; - readonly component: Component; - readonly parent: INode; - readonly type: string; - prev?: INode; - next?: INode; - can_use_innerhtml: boolean; - var: string; - attributes: Attribute[]; - constructor(component: Component, parent: Node, _scope: any, info: TemplateNode); - cannot_use_innerhtml(): void; - find_nearest(selector: RegExp): any; - get_static_attribute_value(name: string): string | true; - has_ancestor(type: string): any; + readonly start: number; + readonly end: number; + readonly component: Component; + readonly parent: INode; + readonly type: string; + prev?: INode; + next?: INode; + can_use_innerhtml: boolean; + var: string; + attributes: Attribute[]; + constructor(component: Component, parent: Node, _scope: any, info: TemplateNode); + cannot_use_innerhtml(): void; + find_nearest(selector: RegExp): any; + get_static_attribute_value(name: string): string | true; + has_ancestor(type: string): any; } diff --git a/src/@types/compiler/compile/nodes/shared/Tag.d.ts b/src/@types/compiler/compile/nodes/shared/Tag.d.ts index 8c5db1895..5dd9ecf2d 100644 --- a/src/@types/compiler/compile/nodes/shared/Tag.d.ts +++ b/src/@types/compiler/compile/nodes/shared/Tag.d.ts @@ -1,8 +1,8 @@ import Node from './Node'; import Expression from './Expression'; export default class Tag extends Node { - type: 'MustacheTag' | 'RawMustacheTag'; - expression: Expression; - should_cache: boolean; - constructor(component: any, parent: any, scope: any, info: any); + type: 'MustacheTag' | 'RawMustacheTag'; + expression: Expression; + should_cache: boolean; + constructor(component: any, parent: any, scope: any, info: any); } diff --git a/src/@types/compiler/compile/nodes/shared/TemplateScope.d.ts b/src/@types/compiler/compile/nodes/shared/TemplateScope.d.ts index 3cfd39821..e1bb8df4c 100644 --- a/src/@types/compiler/compile/nodes/shared/TemplateScope.d.ts +++ b/src/@types/compiler/compile/nodes/shared/TemplateScope.d.ts @@ -6,16 +6,16 @@ import Element from '../Element'; import SlotTemplate from '../SlotTemplate'; declare type NodeWithScope = EachBlock | ThenBlock | CatchBlock | InlineComponent | Element | SlotTemplate; export default class TemplateScope { - names: Set<string>; - dependencies_for_name: Map<string, Set<string>>; - owners: Map<string, NodeWithScope>; - parent?: TemplateScope; - constructor(parent?: TemplateScope); - add(name: any, dependencies: Set<string>, owner: any): this; - child(): TemplateScope; - is_top_level(name: string): any; - get_owner(name: string): NodeWithScope; - is_let(name: string): boolean; - is_await(name: string): boolean; + names: Set<string>; + dependencies_for_name: Map<string, Set<string>>; + owners: Map<string, NodeWithScope>; + parent?: TemplateScope; + constructor(parent?: TemplateScope); + add(name: any, dependencies: Set<string>, owner: any): this; + child(): TemplateScope; + is_top_level(name: string): any; + get_owner(name: string): NodeWithScope; + is_let(name: string): boolean; + is_await(name: string): boolean; } export {}; diff --git a/src/@types/compiler/compile/nodes/shared/map_children.d.ts b/src/@types/compiler/compile/nodes/shared/map_children.d.ts index 8c4dfb949..ef3274a48 100644 --- a/src/@types/compiler/compile/nodes/shared/map_children.d.ts +++ b/src/@types/compiler/compile/nodes/shared/map_children.d.ts @@ -17,4 +17,27 @@ import Title from '../Title'; import Window from '../Window'; import { TemplateNode } from '../../../interfaces'; export declare type Children = ReturnType<typeof map_children>; -export default function map_children(component: any, parent: any, scope: any, children: TemplateNode[]): (AwaitBlock | Body | Comment | DebugTag | EachBlock | Element | Head | IfBlock | InlineComponent | KeyBlock | MustacheTag | Options | RawMustacheTag | SlotTemplate | Text | Title | Window)[]; +export default function map_children( + component: any, + parent: any, + scope: any, + children: TemplateNode[] +): ( + | AwaitBlock + | Body + | Comment + | DebugTag + | EachBlock + | Element + | Head + | IfBlock + | InlineComponent + | KeyBlock + | MustacheTag + | Options + | RawMustacheTag + | SlotTemplate + | Text + | Title + | Window +)[]; diff --git a/src/@types/compiler/compile/render_dom/Block.d.ts b/src/@types/compiler/compile/render_dom/Block.d.ts index 9a272f90c..8cbd2f1e1 100644 --- a/src/@types/compiler/compile/render_dom/Block.d.ts +++ b/src/@types/compiler/compile/render_dom/Block.d.ts @@ -2,77 +2,80 @@ import Renderer from './Renderer'; import Wrapper from './wrappers/shared/Wrapper'; import { Node, Identifier } from 'estree'; export interface Bindings { - object: Identifier; - property: Identifier; - snippet: Node; - store: string; - modifier: (node: Node) => Node; + object: Identifier; + property: Identifier; + snippet: Node; + store: string; + modifier: (node: Node) => Node; } export interface BlockOptions { - parent?: Block; - name: Identifier; - type: string; - renderer?: Renderer; - comment?: string; - key?: Identifier; - bindings?: Map<string, Bindings>; - dependencies?: Set<string>; + parent?: Block; + name: Identifier; + type: string; + renderer?: Renderer; + comment?: string; + key?: Identifier; + bindings?: Map<string, Bindings>; + dependencies?: Set<string>; } export default class Block { - parent?: Block; - renderer: Renderer; - name: Identifier; - type: string; - comment?: string; - wrappers: Wrapper[]; - key: Identifier; - first: Identifier; - dependencies: Set<string>; - bindings: Map<string, Bindings>; - binding_group_initialised: Set<string>; - chunks: { - declarations: Array<Node | Node[]>; - init: Array<Node | Node[]>; - create: Array<Node | Node[]>; - claim: Array<Node | Node[]>; - hydrate: Array<Node | Node[]>; - mount: Array<Node | Node[]>; - measure: Array<Node | Node[]>; - fix: Array<Node | Node[]>; - animate: Array<Node | Node[]>; - intro: Array<Node | Node[]>; - update: Array<Node | Node[]>; - outro: Array<Node | Node[]>; - destroy: Array<Node | Node[]>; - }; - event_listeners: Node[]; - maintain_context: boolean; - has_animation: boolean; - has_intros: boolean; - has_outros: boolean; - has_intro_method: boolean; - has_outro_method: boolean; - outros: number; - aliases: Map<string, Identifier>; - variables: Map<string, { - id: Identifier; - init?: Node; - }>; - get_unique_name: (name: string) => Identifier; - has_update_method: boolean; - autofocus: string; - constructor(options: BlockOptions); - assign_variable_names(): void; - add_dependencies(dependencies: Set<string>): void; - add_element(id: Identifier, render_statement: Node, claim_statement: Node, parent_node: Node, no_detach?: boolean): void; - add_intro(local?: boolean): void; - add_outro(local?: boolean): void; - add_animation(): void; - add_variable(id: Identifier, init?: Node): void; - alias(name: string): Identifier; - child(options: BlockOptions): Block; - get_contents(key?: any): Node[]; - has_content(): boolean; - render(): Node[]; - render_listeners(chunk?: string): void; + parent?: Block; + renderer: Renderer; + name: Identifier; + type: string; + comment?: string; + wrappers: Wrapper[]; + key: Identifier; + first: Identifier; + dependencies: Set<string>; + bindings: Map<string, Bindings>; + binding_group_initialised: Set<string>; + chunks: { + declarations: Array<Node | Node[]>; + init: Array<Node | Node[]>; + create: Array<Node | Node[]>; + claim: Array<Node | Node[]>; + hydrate: Array<Node | Node[]>; + mount: Array<Node | Node[]>; + measure: Array<Node | Node[]>; + fix: Array<Node | Node[]>; + animate: Array<Node | Node[]>; + intro: Array<Node | Node[]>; + update: Array<Node | Node[]>; + outro: Array<Node | Node[]>; + destroy: Array<Node | Node[]>; + }; + event_listeners: Node[]; + maintain_context: boolean; + has_animation: boolean; + has_intros: boolean; + has_outros: boolean; + has_intro_method: boolean; + has_outro_method: boolean; + outros: number; + aliases: Map<string, Identifier>; + variables: Map< + string, + { + id: Identifier; + init?: Node; + } + >; + get_unique_name: (name: string) => Identifier; + has_update_method: boolean; + autofocus: string; + constructor(options: BlockOptions); + assign_variable_names(): void; + add_dependencies(dependencies: Set<string>): void; + add_element(id: Identifier, render_statement: Node, claim_statement: Node, parent_node: Node, no_detach?: boolean): void; + add_intro(local?: boolean): void; + add_outro(local?: boolean): void; + add_animation(): void; + add_variable(id: Identifier, init?: Node): void; + alias(name: string): Identifier; + child(options: BlockOptions): Block; + get_contents(key?: any): Node[]; + has_content(): boolean; + render(): Node[]; + render_listeners(chunk?: string): void; } diff --git a/src/@types/compiler/compile/render_dom/Renderer.d.ts b/src/@types/compiler/compile/render_dom/Renderer.d.ts index ece1e715f..e56f32342 100644 --- a/src/@types/compiler/compile/render_dom/Renderer.d.ts +++ b/src/@types/compiler/compile/render_dom/Renderer.d.ts @@ -4,42 +4,47 @@ import Component from '../Component'; import FragmentWrapper from './wrappers/Fragment'; import { Node, Identifier, MemberExpression, Literal, Expression } from 'estree'; interface ContextMember { - name: string; - index: Literal; - is_contextual: boolean; - is_non_contextual: boolean; - variable: Var; - priority: number; + name: string; + index: Literal; + is_contextual: boolean; + is_non_contextual: boolean; + variable: Var; + priority: number; } export default class Renderer { - component: Component; - options: CompileOptions; - context: ContextMember[]; - initial_context: ContextMember[]; - context_lookup: Map<string, ContextMember>; - context_overflow: boolean; - blocks: Array<Block | Node | Node[]>; - readonly: Set<string>; - meta_bindings: Array<Node | Node[]>; - binding_groups: Map<string, { - binding_group: (to_reference?: boolean) => Node; - is_context: boolean; - contexts: string[]; - index: number; - keypath: string; - }>; - block: Block; - fragment: FragmentWrapper; - file_var: Identifier; - locate: (c: number) => { - line: number; - column: number; - }; - constructor(component: Component, options: CompileOptions); - add_to_context(name: string, contextual?: boolean): ContextMember; - invalidate(name: string, value?: any, main_execution_context?: boolean): any; - dirty(names: string[], is_reactive_declaration?: boolean): Expression; - reference(node: string | Identifier | MemberExpression): any; - remove_block(block: Block | Node | Node[]): void; + component: Component; + options: CompileOptions; + context: ContextMember[]; + initial_context: ContextMember[]; + context_lookup: Map<string, ContextMember>; + context_overflow: boolean; + blocks: Array<Block | Node | Node[]>; + readonly: Set<string>; + meta_bindings: Array<Node | Node[]>; + binding_groups: Map< + string, + { + binding_group: (to_reference?: boolean) => Node; + is_context: boolean; + contexts: string[]; + index: number; + keypath: string; + } + >; + block: Block; + fragment: FragmentWrapper; + file_var: Identifier; + locate: ( + c: number + ) => { + line: number; + column: number; + }; + constructor(component: Component, options: CompileOptions); + add_to_context(name: string, contextual?: boolean): ContextMember; + invalidate(name: string, value?: any, main_execution_context?: boolean): any; + dirty(names: string[], is_reactive_declaration?: boolean): Expression; + reference(node: string | Identifier | MemberExpression): any; + remove_block(block: Block | Node | Node[]): void; } export {}; diff --git a/src/@types/compiler/compile/render_dom/index.d.ts b/src/@types/compiler/compile/render_dom/index.d.ts index 406561f4b..6fd9ab63e 100644 --- a/src/@types/compiler/compile/render_dom/index.d.ts +++ b/src/@types/compiler/compile/render_dom/index.d.ts @@ -1,7 +1,10 @@ import Component from '../Component'; import { CompileOptions, CssResult } from '../../interfaces'; import { Node } from 'estree'; -export default function dom(component: Component, options: CompileOptions): { - js: Node[]; - css: CssResult; +export default function dom( + component: Component, + options: CompileOptions +): { + js: Node[]; + css: CssResult; }; diff --git a/src/@types/compiler/compile/render_dom/wrappers/AwaitBlock.d.ts b/src/@types/compiler/compile/render_dom/wrappers/AwaitBlock.d.ts index 28ffd28d0..55e41bbc9 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/AwaitBlock.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/AwaitBlock.d.ts @@ -10,29 +10,37 @@ import { Context } from '../../nodes/shared/Context'; import { Identifier, Literal, Node } from 'estree'; declare type Status = 'pending' | 'then' | 'catch'; declare class AwaitBlockBranch extends Wrapper { - parent: AwaitBlockWrapper; - node: PendingBlock | ThenBlock | CatchBlock; - block: Block; - fragment: FragmentWrapper; - is_dynamic: boolean; - var: any; - status: Status; - value: string; - value_index: Literal; - value_contexts: Context[]; - is_destructured: boolean; - constructor(status: Status, renderer: Renderer, block: Block, parent: AwaitBlockWrapper, node: PendingBlock | ThenBlock | CatchBlock, strip_whitespace: boolean, next_sibling: Wrapper); - add_context(node: Node | null, contexts: Context[]): void; - render(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; - render_destructure(): void; + parent: AwaitBlockWrapper; + node: PendingBlock | ThenBlock | CatchBlock; + block: Block; + fragment: FragmentWrapper; + is_dynamic: boolean; + var: any; + status: Status; + value: string; + value_index: Literal; + value_contexts: Context[]; + is_destructured: boolean; + constructor( + status: Status, + renderer: Renderer, + block: Block, + parent: AwaitBlockWrapper, + node: PendingBlock | ThenBlock | CatchBlock, + strip_whitespace: boolean, + next_sibling: Wrapper + ); + add_context(node: Node | null, contexts: Context[]): void; + render(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; + render_destructure(): void; } export default class AwaitBlockWrapper extends Wrapper { - node: AwaitBlock; - pending: AwaitBlockBranch; - then: AwaitBlockBranch; - catch: AwaitBlockBranch; - var: Identifier; - constructor(renderer: Renderer, block: Block, parent: Wrapper, node: AwaitBlock, strip_whitespace: boolean, next_sibling: Wrapper); - render(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; + node: AwaitBlock; + pending: AwaitBlockBranch; + then: AwaitBlockBranch; + catch: AwaitBlockBranch; + var: Identifier; + constructor(renderer: Renderer, block: Block, parent: Wrapper, node: AwaitBlock, strip_whitespace: boolean, next_sibling: Wrapper); + render(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; } export {}; diff --git a/src/@types/compiler/compile/render_dom/wrappers/Body.d.ts b/src/@types/compiler/compile/render_dom/wrappers/Body.d.ts index e00cfdf07..2846fc10e 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/Body.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/Body.d.ts @@ -6,8 +6,8 @@ import EventHandler from './Element/EventHandler'; import { TemplateNode } from '../../../interfaces'; import Renderer from '../Renderer'; export default class BodyWrapper extends Wrapper { - node: Body; - handlers: EventHandler[]; - constructor(renderer: Renderer, block: Block, parent: Wrapper, node: TemplateNode); - render(block: Block, _parent_node: Identifier, _parent_nodes: Identifier): void; + node: Body; + handlers: EventHandler[]; + constructor(renderer: Renderer, block: Block, parent: Wrapper, node: TemplateNode); + render(block: Block, _parent_node: Identifier, _parent_nodes: Identifier): void; } diff --git a/src/@types/compiler/compile/render_dom/wrappers/DebugTag.d.ts b/src/@types/compiler/compile/render_dom/wrappers/DebugTag.d.ts index bf68ea962..24a672f79 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/DebugTag.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/DebugTag.d.ts @@ -4,7 +4,7 @@ import Block from '../Block'; import DebugTag from '../../nodes/DebugTag'; import { Identifier } from 'estree'; export default class DebugTagWrapper extends Wrapper { - node: DebugTag; - constructor(renderer: Renderer, block: Block, parent: Wrapper, node: DebugTag, _strip_whitespace: boolean, _next_sibling: Wrapper); - render(block: Block, _parent_node: Identifier, _parent_nodes: Identifier): void; + node: DebugTag; + constructor(renderer: Renderer, block: Block, parent: Wrapper, node: DebugTag, _strip_whitespace: boolean, _next_sibling: Wrapper); + render(block: Block, _parent_node: Identifier, _parent_nodes: Identifier): void; } diff --git a/src/@types/compiler/compile/render_dom/wrappers/EachBlock.d.ts b/src/@types/compiler/compile/render_dom/wrappers/EachBlock.d.ts index 573b7c1a5..275b9b443 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/EachBlock.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/EachBlock.d.ts @@ -6,51 +6,68 @@ import FragmentWrapper from './Fragment'; import ElseBlock from '../../nodes/ElseBlock'; import { Identifier, Node } from 'estree'; export declare class ElseBlockWrapper extends Wrapper { - node: ElseBlock; - block: Block; - fragment: FragmentWrapper; - is_dynamic: boolean; - var: any; - constructor(renderer: Renderer, block: Block, parent: Wrapper, node: ElseBlock, strip_whitespace: boolean, next_sibling: Wrapper); + node: ElseBlock; + block: Block; + fragment: FragmentWrapper; + is_dynamic: boolean; + var: any; + constructor(renderer: Renderer, block: Block, parent: Wrapper, node: ElseBlock, strip_whitespace: boolean, next_sibling: Wrapper); } export default class EachBlockWrapper extends Wrapper { + block: Block; + node: EachBlock; + fragment: FragmentWrapper; + else?: ElseBlockWrapper; + vars: { + create_each_block: Identifier; + each_block_value: Identifier; + get_each_context: Identifier; + iterations: Identifier; + fixed_length: number; + data_length: Node | number; + view_length: Node | number; + }; + context_props: Array<Node | Node[]>; + index_name: Identifier; + updates: Array<Node | Node[]>; + dependencies: Set<string>; + var: Identifier; + constructor(renderer: Renderer, block: Block, parent: Wrapper, node: EachBlock, strip_whitespace: boolean, next_sibling: Wrapper); + render(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; + render_keyed({ + block, + parent_node, + parent_nodes, + snippet, + initial_anchor_node, + initial_mount_node, + update_anchor_node, + update_mount_node, + }: { + block: Block; + parent_node: Identifier; + parent_nodes: Identifier; + snippet: Node; + initial_anchor_node: Identifier; + initial_mount_node: Identifier; + update_anchor_node: Identifier; + update_mount_node: Identifier; + }): void; + render_unkeyed({ + block, + parent_nodes, + snippet, + initial_anchor_node, + initial_mount_node, + update_anchor_node, + update_mount_node, + }: { block: Block; - node: EachBlock; - fragment: FragmentWrapper; - else?: ElseBlockWrapper; - vars: { - create_each_block: Identifier; - each_block_value: Identifier; - get_each_context: Identifier; - iterations: Identifier; - fixed_length: number; - data_length: Node | number; - view_length: Node | number; - }; - context_props: Array<Node | Node[]>; - index_name: Identifier; - updates: Array<Node | Node[]>; - dependencies: Set<string>; - var: Identifier; - constructor(renderer: Renderer, block: Block, parent: Wrapper, node: EachBlock, strip_whitespace: boolean, next_sibling: Wrapper); - render(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; - render_keyed({ block, parent_node, parent_nodes, snippet, initial_anchor_node, initial_mount_node, update_anchor_node, update_mount_node }: { - block: Block; - parent_node: Identifier; - parent_nodes: Identifier; - snippet: Node; - initial_anchor_node: Identifier; - initial_mount_node: Identifier; - update_anchor_node: Identifier; - update_mount_node: Identifier; - }): void; - render_unkeyed({ block, parent_nodes, snippet, initial_anchor_node, initial_mount_node, update_anchor_node, update_mount_node }: { - block: Block; - parent_nodes: Identifier; - snippet: Node; - initial_anchor_node: Identifier; - initial_mount_node: Identifier; - update_anchor_node: Identifier; - update_mount_node: Identifier; - }): void; + parent_nodes: Identifier; + snippet: Node; + initial_anchor_node: Identifier; + initial_mount_node: Identifier; + update_anchor_node: Identifier; + update_mount_node: Identifier; + }): void; } diff --git a/src/@types/compiler/compile/render_dom/wrappers/Element/Attribute.d.ts b/src/@types/compiler/compile/render_dom/wrappers/Element/Attribute.d.ts index 6edb5630e..a97d28e94 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/Element/Attribute.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/Element/Attribute.d.ts @@ -3,40 +3,257 @@ import Block from '../../Block'; import ElementWrapper from './index'; import { Identifier, Node } from 'estree'; export declare class BaseAttributeWrapper { - node: Attribute; - parent: ElementWrapper; - constructor(parent: ElementWrapper, block: Block, node: Attribute); - render(_block: Block): void; + node: Attribute; + parent: ElementWrapper; + constructor(parent: ElementWrapper, block: Block, node: Attribute); + render(_block: Block): void; } export default class AttributeWrapper extends BaseAttributeWrapper { - node: Attribute; - parent: ElementWrapper; - metadata: any; - name: string; - property_name: string; - is_indirectly_bound_value: boolean; - is_src: boolean; - is_select_value_attribute: boolean; - is_input_value: boolean; - should_cache: boolean; - last: Identifier; - constructor(parent: ElementWrapper, block: Block, node: Attribute); - render(block: Block): void; - get_init(block: Block, value: any): any; - get_dom_update_conditions(block: Block, dependency_condition: Node): Node; - get_dependencies(): string[]; - get_metadata(): any; - get_value(block: any): Identifier | import("estree").SimpleLiteral | import("estree").RegExpLiteral | import("estree").Program | import("estree").FunctionDeclaration | import("estree").FunctionExpression | import("estree").ArrowFunctionExpression | import("estree").SwitchCase | import("estree").CatchClause | import("estree").VariableDeclarator | import("estree").ExpressionStatement | import("estree").BlockStatement | import("estree").EmptyStatement | import("estree").DebuggerStatement | import("estree").WithStatement | import("estree").ReturnStatement | import("estree").LabeledStatement | import("estree").BreakStatement | import("estree").ContinueStatement | import("estree").IfStatement | import("estree").SwitchStatement | import("estree").ThrowStatement | import("estree").TryStatement | import("estree").WhileStatement | import("estree").DoWhileStatement | import("estree").ForStatement | import("estree").ForInStatement | import("estree").ForOfStatement | import("estree").VariableDeclaration | import("estree").ClassDeclaration | import("estree").ThisExpression | import("estree").ArrayExpression | import("estree").ObjectExpression | import("estree").YieldExpression | import("estree").UnaryExpression | import("estree").UpdateExpression | import("estree").BinaryExpression | import("estree").AssignmentExpression | import("estree").LogicalExpression | import("estree").MemberExpression | import("estree").ConditionalExpression | import("estree").SimpleCallExpression | import("estree").NewExpression | import("estree").SequenceExpression | import("estree").TemplateLiteral | import("estree").TaggedTemplateExpression | import("estree").ClassExpression | import("estree").MetaProperty | import("estree").AwaitExpression | import("estree").ImportExpression | import("estree").ChainExpression | import("estree").Property | import("estree").Super | import("estree").TemplateElement | import("estree").SpreadElement | import("estree").ObjectPattern | import("estree").ArrayPattern | import("estree").RestElement | import("estree").AssignmentPattern | import("estree").ClassBody | import("estree").MethodDefinition | import("estree").ImportDeclaration | import("estree").ExportNamedDeclaration | import("estree").ExportDefaultDeclaration | import("estree").ExportAllDeclaration | import("estree").ImportSpecifier | import("estree").ImportDefaultSpecifier | import("estree").ImportNamespaceSpecifier | import("estree").ExportSpecifier | { + node: Attribute; + parent: ElementWrapper; + metadata: any; + name: string; + property_name: string; + is_indirectly_bound_value: boolean; + is_src: boolean; + is_select_value_attribute: boolean; + is_input_value: boolean; + should_cache: boolean; + last: Identifier; + constructor(parent: ElementWrapper, block: Block, node: Attribute); + render(block: Block): void; + get_init(block: Block, value: any): any; + get_dom_update_conditions(block: Block, dependency_condition: Node): Node; + get_dependencies(): string[]; + get_metadata(): any; + get_value( + block: any + ): + | Identifier + | import('estree').SimpleLiteral + | import('estree').RegExpLiteral + | import('estree').Program + | import('estree').FunctionDeclaration + | import('estree').FunctionExpression + | import('estree').ArrowFunctionExpression + | import('estree').SwitchCase + | import('estree').CatchClause + | import('estree').VariableDeclarator + | import('estree').ExpressionStatement + | import('estree').BlockStatement + | import('estree').EmptyStatement + | import('estree').DebuggerStatement + | import('estree').WithStatement + | import('estree').ReturnStatement + | import('estree').LabeledStatement + | import('estree').BreakStatement + | import('estree').ContinueStatement + | import('estree').IfStatement + | import('estree').SwitchStatement + | import('estree').ThrowStatement + | import('estree').TryStatement + | import('estree').WhileStatement + | import('estree').DoWhileStatement + | import('estree').ForStatement + | import('estree').ForInStatement + | import('estree').ForOfStatement + | import('estree').VariableDeclaration + | import('estree').ClassDeclaration + | import('estree').ThisExpression + | import('estree').ArrayExpression + | import('estree').ObjectExpression + | import('estree').YieldExpression + | import('estree').UnaryExpression + | import('estree').UpdateExpression + | import('estree').BinaryExpression + | import('estree').AssignmentExpression + | import('estree').LogicalExpression + | import('estree').MemberExpression + | import('estree').ConditionalExpression + | import('estree').SimpleCallExpression + | import('estree').NewExpression + | import('estree').SequenceExpression + | import('estree').TemplateLiteral + | import('estree').TaggedTemplateExpression + | import('estree').ClassExpression + | import('estree').MetaProperty + | import('estree').AwaitExpression + | import('estree').ImportExpression + | import('estree').ChainExpression + | import('estree').Property + | import('estree').Super + | import('estree').TemplateElement + | import('estree').SpreadElement + | import('estree').ObjectPattern + | import('estree').ArrayPattern + | import('estree').RestElement + | import('estree').AssignmentPattern + | import('estree').ClassBody + | import('estree').MethodDefinition + | import('estree').ImportDeclaration + | import('estree').ExportNamedDeclaration + | import('estree').ExportDefaultDeclaration + | import('estree').ExportAllDeclaration + | import('estree').ImportSpecifier + | import('estree').ImportDefaultSpecifier + | import('estree').ImportNamespaceSpecifier + | import('estree').ExportSpecifier + | { type: string; value: string; - }; - get_class_name_text(block: any): Identifier | import("estree").SimpleLiteral | import("estree").RegExpLiteral | import("estree").Program | import("estree").FunctionDeclaration | import("estree").FunctionExpression | import("estree").ArrowFunctionExpression | import("estree").SwitchCase | import("estree").CatchClause | import("estree").VariableDeclarator | import("estree").ExpressionStatement | import("estree").BlockStatement | import("estree").EmptyStatement | import("estree").DebuggerStatement | import("estree").WithStatement | import("estree").ReturnStatement | import("estree").LabeledStatement | import("estree").BreakStatement | import("estree").ContinueStatement | import("estree").IfStatement | import("estree").SwitchStatement | import("estree").ThrowStatement | import("estree").TryStatement | import("estree").WhileStatement | import("estree").DoWhileStatement | import("estree").ForStatement | import("estree").ForInStatement | import("estree").ForOfStatement | import("estree").VariableDeclaration | import("estree").ClassDeclaration | import("estree").ThisExpression | import("estree").ArrayExpression | import("estree").ObjectExpression | import("estree").YieldExpression | import("estree").UnaryExpression | import("estree").UpdateExpression | import("estree").BinaryExpression | import("estree").AssignmentExpression | import("estree").LogicalExpression | import("estree").MemberExpression | import("estree").ConditionalExpression | import("estree").SimpleCallExpression | import("estree").NewExpression | import("estree").SequenceExpression | import("estree").TemplateLiteral | import("estree").TaggedTemplateExpression | import("estree").ClassExpression | import("estree").MetaProperty | import("estree").AwaitExpression | import("estree").ImportExpression | import("estree").ChainExpression | import("estree").Property | import("estree").Super | import("estree").TemplateElement | import("estree").SpreadElement | import("estree").ObjectPattern | import("estree").ArrayPattern | import("estree").RestElement | import("estree").AssignmentPattern | import("estree").ClassBody | import("estree").MethodDefinition | import("estree").ImportDeclaration | import("estree").ExportNamedDeclaration | import("estree").ExportDefaultDeclaration | import("estree").ExportAllDeclaration | import("estree").ImportSpecifier | import("estree").ImportDefaultSpecifier | import("estree").ImportNamespaceSpecifier | import("estree").ExportSpecifier | { + }; + get_class_name_text( + block: any + ): + | Identifier + | import('estree').SimpleLiteral + | import('estree').RegExpLiteral + | import('estree').Program + | import('estree').FunctionDeclaration + | import('estree').FunctionExpression + | import('estree').ArrowFunctionExpression + | import('estree').SwitchCase + | import('estree').CatchClause + | import('estree').VariableDeclarator + | import('estree').ExpressionStatement + | import('estree').BlockStatement + | import('estree').EmptyStatement + | import('estree').DebuggerStatement + | import('estree').WithStatement + | import('estree').ReturnStatement + | import('estree').LabeledStatement + | import('estree').BreakStatement + | import('estree').ContinueStatement + | import('estree').IfStatement + | import('estree').SwitchStatement + | import('estree').ThrowStatement + | import('estree').TryStatement + | import('estree').WhileStatement + | import('estree').DoWhileStatement + | import('estree').ForStatement + | import('estree').ForInStatement + | import('estree').ForOfStatement + | import('estree').VariableDeclaration + | import('estree').ClassDeclaration + | import('estree').ThisExpression + | import('estree').ArrayExpression + | import('estree').ObjectExpression + | import('estree').YieldExpression + | import('estree').UnaryExpression + | import('estree').UpdateExpression + | import('estree').BinaryExpression + | import('estree').AssignmentExpression + | import('estree').LogicalExpression + | import('estree').MemberExpression + | import('estree').ConditionalExpression + | import('estree').SimpleCallExpression + | import('estree').NewExpression + | import('estree').SequenceExpression + | import('estree').TemplateLiteral + | import('estree').TaggedTemplateExpression + | import('estree').ClassExpression + | import('estree').MetaProperty + | import('estree').AwaitExpression + | import('estree').ImportExpression + | import('estree').ChainExpression + | import('estree').Property + | import('estree').Super + | import('estree').TemplateElement + | import('estree').SpreadElement + | import('estree').ObjectPattern + | import('estree').ArrayPattern + | import('estree').RestElement + | import('estree').AssignmentPattern + | import('estree').ClassBody + | import('estree').MethodDefinition + | import('estree').ImportDeclaration + | import('estree').ExportNamedDeclaration + | import('estree').ExportDefaultDeclaration + | import('estree').ExportAllDeclaration + | import('estree').ImportSpecifier + | import('estree').ImportDefaultSpecifier + | import('estree').ImportNamespaceSpecifier + | import('estree').ExportSpecifier + | { type: string; value: string; - }; - render_chunks(block: Block): (Identifier | import("estree").SimpleLiteral | import("estree").RegExpLiteral | import("estree").Program | import("estree").FunctionDeclaration | import("estree").FunctionExpression | import("estree").ArrowFunctionExpression | import("estree").SwitchCase | import("estree").CatchClause | import("estree").VariableDeclarator | import("estree").ExpressionStatement | import("estree").BlockStatement | import("estree").EmptyStatement | import("estree").DebuggerStatement | import("estree").WithStatement | import("estree").ReturnStatement | import("estree").LabeledStatement | import("estree").BreakStatement | import("estree").ContinueStatement | import("estree").IfStatement | import("estree").SwitchStatement | import("estree").ThrowStatement | import("estree").TryStatement | import("estree").WhileStatement | import("estree").DoWhileStatement | import("estree").ForStatement | import("estree").ForInStatement | import("estree").ForOfStatement | import("estree").VariableDeclaration | import("estree").ClassDeclaration | import("estree").ThisExpression | import("estree").ArrayExpression | import("estree").ObjectExpression | import("estree").YieldExpression | import("estree").UnaryExpression | import("estree").UpdateExpression | import("estree").BinaryExpression | import("estree").AssignmentExpression | import("estree").LogicalExpression | import("estree").MemberExpression | import("estree").ConditionalExpression | import("estree").SimpleCallExpression | import("estree").NewExpression | import("estree").SequenceExpression | import("estree").TemplateLiteral | import("estree").TaggedTemplateExpression | import("estree").ClassExpression | import("estree").MetaProperty | import("estree").AwaitExpression | import("estree").ImportExpression | import("estree").ChainExpression | import("estree").Property | import("estree").Super | import("estree").TemplateElement | import("estree").SpreadElement | import("estree").ObjectPattern | import("estree").ArrayPattern | import("estree").RestElement | import("estree").AssignmentPattern | import("estree").ClassBody | import("estree").MethodDefinition | import("estree").ImportDeclaration | import("estree").ExportNamedDeclaration | import("estree").ExportDefaultDeclaration | import("estree").ExportAllDeclaration | import("estree").ImportSpecifier | import("estree").ImportDefaultSpecifier | import("estree").ImportNamespaceSpecifier | import("estree").ExportSpecifier | { + }; + render_chunks( + block: Block + ): ( + | Identifier + | import('estree').SimpleLiteral + | import('estree').RegExpLiteral + | import('estree').Program + | import('estree').FunctionDeclaration + | import('estree').FunctionExpression + | import('estree').ArrowFunctionExpression + | import('estree').SwitchCase + | import('estree').CatchClause + | import('estree').VariableDeclarator + | import('estree').ExpressionStatement + | import('estree').BlockStatement + | import('estree').EmptyStatement + | import('estree').DebuggerStatement + | import('estree').WithStatement + | import('estree').ReturnStatement + | import('estree').LabeledStatement + | import('estree').BreakStatement + | import('estree').ContinueStatement + | import('estree').IfStatement + | import('estree').SwitchStatement + | import('estree').ThrowStatement + | import('estree').TryStatement + | import('estree').WhileStatement + | import('estree').DoWhileStatement + | import('estree').ForStatement + | import('estree').ForInStatement + | import('estree').ForOfStatement + | import('estree').VariableDeclaration + | import('estree').ClassDeclaration + | import('estree').ThisExpression + | import('estree').ArrayExpression + | import('estree').ObjectExpression + | import('estree').YieldExpression + | import('estree').UnaryExpression + | import('estree').UpdateExpression + | import('estree').BinaryExpression + | import('estree').AssignmentExpression + | import('estree').LogicalExpression + | import('estree').MemberExpression + | import('estree').ConditionalExpression + | import('estree').SimpleCallExpression + | import('estree').NewExpression + | import('estree').SequenceExpression + | import('estree').TemplateLiteral + | import('estree').TaggedTemplateExpression + | import('estree').ClassExpression + | import('estree').MetaProperty + | import('estree').AwaitExpression + | import('estree').ImportExpression + | import('estree').ChainExpression + | import('estree').Property + | import('estree').Super + | import('estree').TemplateElement + | import('estree').SpreadElement + | import('estree').ObjectPattern + | import('estree').ArrayPattern + | import('estree').RestElement + | import('estree').AssignmentPattern + | import('estree').ClassBody + | import('estree').MethodDefinition + | import('estree').ImportDeclaration + | import('estree').ExportNamedDeclaration + | import('estree').ExportDefaultDeclaration + | import('estree').ExportAllDeclaration + | import('estree').ImportSpecifier + | import('estree').ImportDefaultSpecifier + | import('estree').ImportNamespaceSpecifier + | import('estree').ExportSpecifier + | { type: string; value: string; - })[]; - stringify(): string; + } + )[]; + stringify(): string; } diff --git a/src/@types/compiler/compile/render_dom/wrappers/Element/Binding.d.ts b/src/@types/compiler/compile/render_dom/wrappers/Element/Binding.d.ts index 78286feff..c15384f06 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/Element/Binding.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/Element/Binding.d.ts @@ -4,20 +4,20 @@ import InlineComponentWrapper from '../InlineComponent'; import Block from '../../Block'; import { Node, Identifier } from 'estree'; export default class BindingWrapper { - node: Binding; - parent: ElementWrapper | InlineComponentWrapper; - object: string; - handler: { - uses_context: boolean; - mutation: (Node | Node[]); - contextual_dependencies: Set<string>; - lhs?: Node; - }; - snippet: Node; - is_readonly: boolean; - needs_lock: boolean; - constructor(block: Block, node: Binding, parent: ElementWrapper | InlineComponentWrapper); - get_dependencies(): Set<string>; - is_readonly_media_attribute(): boolean; - render(block: Block, lock: Identifier): void; + node: Binding; + parent: ElementWrapper | InlineComponentWrapper; + object: string; + handler: { + uses_context: boolean; + mutation: Node | Node[]; + contextual_dependencies: Set<string>; + lhs?: Node; + }; + snippet: Node; + is_readonly: boolean; + needs_lock: boolean; + constructor(block: Block, node: Binding, parent: ElementWrapper | InlineComponentWrapper); + get_dependencies(): Set<string>; + is_readonly_media_attribute(): boolean; + render(block: Block, lock: Identifier): void; } diff --git a/src/@types/compiler/compile/render_dom/wrappers/Element/EventHandler.d.ts b/src/@types/compiler/compile/render_dom/wrappers/Element/EventHandler.d.ts index 2ee41296e..7e5ce439c 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/Element/EventHandler.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/Element/EventHandler.d.ts @@ -3,9 +3,9 @@ import Wrapper from '../shared/Wrapper'; import Block from '../../Block'; import { Expression } from 'estree'; export default class EventHandlerWrapper { - node: EventHandler; - parent: Wrapper; - constructor(node: EventHandler, parent: Wrapper); - get_snippet(block: any): any; - render(block: Block, target: string | Expression): void; + node: EventHandler; + parent: Wrapper; + constructor(node: EventHandler, parent: Wrapper); + get_snippet(block: any): any; + render(block: Block, target: string | Expression): void; } diff --git a/src/@types/compiler/compile/render_dom/wrappers/Element/SpreadAttribute.d.ts b/src/@types/compiler/compile/render_dom/wrappers/Element/SpreadAttribute.d.ts index be5f05691..7ceafc0da 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/Element/SpreadAttribute.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/Element/SpreadAttribute.d.ts @@ -1,3 +1,2 @@ import { BaseAttributeWrapper } from './Attribute'; -export default class SpreadAttributeWrapper extends BaseAttributeWrapper { -} +export default class SpreadAttributeWrapper extends BaseAttributeWrapper {} diff --git a/src/@types/compiler/compile/render_dom/wrappers/Element/StyleAttribute.d.ts b/src/@types/compiler/compile/render_dom/wrappers/Element/StyleAttribute.d.ts index 8d87aa16f..a93605717 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/Element/StyleAttribute.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/Element/StyleAttribute.d.ts @@ -5,12 +5,12 @@ import ElementWrapper from '../Element'; import Expression from '../../../nodes/shared/Expression'; import Text from '../../../nodes/Text'; export interface StyleProp { - key: string; - value: Array<Text | Expression>; - important: boolean; + key: string; + value: Array<Text | Expression>; + important: boolean; } export default class StyleAttributeWrapper extends AttributeWrapper { - node: Attribute; - parent: ElementWrapper; - render(block: Block): void; + node: Attribute; + parent: ElementWrapper; + render(block: Block): void; } diff --git a/src/@types/compiler/compile/render_dom/wrappers/Element/index.d.ts b/src/@types/compiler/compile/render_dom/wrappers/Element/index.d.ts index 543d462c5..54b98c695 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/Element/index.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/Element/index.d.ts @@ -10,32 +10,32 @@ import Binding from './Binding'; import { Identifier } from 'estree'; import EventHandler from './EventHandler'; interface BindingGroup { - events: string[]; - bindings: Binding[]; + events: string[]; + bindings: Binding[]; } export default class ElementWrapper extends Wrapper { - node: Element; - fragment: FragmentWrapper; - attributes: Array<AttributeWrapper | StyleAttributeWrapper | SpreadAttributeWrapper>; - bindings: Binding[]; - event_handlers: EventHandler[]; - class_dependencies: string[]; - select_binding_dependencies?: Set<string>; - var: any; - void: boolean; - constructor(renderer: Renderer, block: Block, parent: Wrapper, node: Element, strip_whitespace: boolean, next_sibling: Wrapper); - render(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; - can_use_textcontent(): boolean; - get_render_statement(block: Block): import("estree").Expression; - get_claim_statement(nodes: Identifier): import("estree").Expression; - add_directives_in_order(block: Block): void; - add_bindings(block: Block, binding_group: BindingGroup): void; - add_this_binding(block: Block, this_binding: Binding): void; - add_attributes(block: Block): void; - add_spread_attributes(block: Block): void; - add_transitions(block: Block): void; - add_animation(block: Block): void; - add_classes(block: Block): void; - add_manual_style_scoping(block: any): void; + node: Element; + fragment: FragmentWrapper; + attributes: Array<AttributeWrapper | StyleAttributeWrapper | SpreadAttributeWrapper>; + bindings: Binding[]; + event_handlers: EventHandler[]; + class_dependencies: string[]; + select_binding_dependencies?: Set<string>; + var: any; + void: boolean; + constructor(renderer: Renderer, block: Block, parent: Wrapper, node: Element, strip_whitespace: boolean, next_sibling: Wrapper); + render(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; + can_use_textcontent(): boolean; + get_render_statement(block: Block): import('estree').Expression; + get_claim_statement(nodes: Identifier): import('estree').Expression; + add_directives_in_order(block: Block): void; + add_bindings(block: Block, binding_group: BindingGroup): void; + add_this_binding(block: Block, this_binding: Binding): void; + add_attributes(block: Block): void; + add_spread_attributes(block: Block): void; + add_transitions(block: Block): void; + add_animation(block: Block): void; + add_classes(block: Block): void; + add_manual_style_scoping(block: any): void; } export {}; diff --git a/src/@types/compiler/compile/render_dom/wrappers/Fragment.d.ts b/src/@types/compiler/compile/render_dom/wrappers/Fragment.d.ts index d320e7c7a..e426dab40 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/Fragment.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/Fragment.d.ts @@ -4,7 +4,7 @@ import Renderer from '../Renderer'; import Block from '../Block'; import { Identifier } from 'estree'; export default class FragmentWrapper { - nodes: Wrapper[]; - constructor(renderer: Renderer, block: Block, nodes: INode[], parent: Wrapper, strip_whitespace: boolean, next_sibling: Wrapper); - render(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; + nodes: Wrapper[]; + constructor(renderer: Renderer, block: Block, nodes: INode[], parent: Wrapper, strip_whitespace: boolean, next_sibling: Wrapper); + render(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; } diff --git a/src/@types/compiler/compile/render_dom/wrappers/Head.d.ts b/src/@types/compiler/compile/render_dom/wrappers/Head.d.ts index e21de0349..f620a75cf 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/Head.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/Head.d.ts @@ -5,8 +5,8 @@ import Head from '../../nodes/Head'; import FragmentWrapper from './Fragment'; import { Identifier } from 'estree'; export default class HeadWrapper extends Wrapper { - fragment: FragmentWrapper; - node: Head; - constructor(renderer: Renderer, block: Block, parent: Wrapper, node: Head, strip_whitespace: boolean, next_sibling: Wrapper); - render(block: Block, _parent_node: Identifier, _parent_nodes: Identifier): void; + fragment: FragmentWrapper; + node: Head; + constructor(renderer: Renderer, block: Block, parent: Wrapper, node: Head, strip_whitespace: boolean, next_sibling: Wrapper); + render(block: Block, _parent_node: Identifier, _parent_nodes: Identifier): void; } diff --git a/src/@types/compiler/compile/render_dom/wrappers/IfBlock.d.ts b/src/@types/compiler/compile/render_dom/wrappers/IfBlock.d.ts index 2bbaf3250..827ec0f7a 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/IfBlock.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/IfBlock.d.ts @@ -7,48 +7,86 @@ import ElseBlock from '../../nodes/ElseBlock'; import FragmentWrapper from './Fragment'; import { Identifier, Node, UnaryExpression } from 'estree'; declare class IfBlockBranch extends Wrapper { - block: Block; - fragment: FragmentWrapper; - dependencies?: string[]; - condition?: any; - snippet?: Node; - is_dynamic: boolean; - var: any; - constructor(renderer: Renderer, block: Block, parent: IfBlockWrapper, node: IfBlock | ElseBlock, strip_whitespace: boolean, next_sibling: Wrapper); + block: Block; + fragment: FragmentWrapper; + dependencies?: string[]; + condition?: any; + snippet?: Node; + is_dynamic: boolean; + var: any; + constructor(renderer: Renderer, block: Block, parent: IfBlockWrapper, node: IfBlock | ElseBlock, strip_whitespace: boolean, next_sibling: Wrapper); } export default class IfBlockWrapper extends Wrapper { - node: IfBlock; - branches: IfBlockBranch[]; - needs_update: boolean; - var: Identifier; - constructor(renderer: Renderer, block: Block, parent: Wrapper, node: EachBlock, strip_whitespace: boolean, next_sibling: Wrapper); - render(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; - render_compound(block: Block, parent_node: Identifier, _parent_nodes: Identifier, dynamic: any, { name, anchor, has_else, if_exists_condition, has_transitions }: { - name: any; - anchor: any; - has_else: any; - if_exists_condition: any; - has_transitions: any; - }, detaching: any): void; - render_compound_with_outros(block: Block, parent_node: Identifier, _parent_nodes: Identifier, dynamic: any, { name, anchor, has_else, has_transitions, if_exists_condition }: { - name: any; - anchor: any; - has_else: any; - has_transitions: any; - if_exists_condition: any; - }, detaching: any): void; - render_simple(block: Block, parent_node: Identifier, _parent_nodes: Identifier, dynamic: any, { name, anchor, if_exists_condition, has_transitions }: { - name: any; - anchor: any; - if_exists_condition: any; - has_transitions: any; - }, detaching: any): void; - get_initial_dirty_bit(): { - readonly type: "ArrayExpression" | "UnaryExpression"; - elements: UnaryExpression[]; - operator: import("estree").UnaryOperator; - prefix: true; - argument: import("estree").Expression; - }; + node: IfBlock; + branches: IfBlockBranch[]; + needs_update: boolean; + var: Identifier; + constructor(renderer: Renderer, block: Block, parent: Wrapper, node: EachBlock, strip_whitespace: boolean, next_sibling: Wrapper); + render(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; + render_compound( + block: Block, + parent_node: Identifier, + _parent_nodes: Identifier, + dynamic: any, + { + name, + anchor, + has_else, + if_exists_condition, + has_transitions, + }: { + name: any; + anchor: any; + has_else: any; + if_exists_condition: any; + has_transitions: any; + }, + detaching: any + ): void; + render_compound_with_outros( + block: Block, + parent_node: Identifier, + _parent_nodes: Identifier, + dynamic: any, + { + name, + anchor, + has_else, + has_transitions, + if_exists_condition, + }: { + name: any; + anchor: any; + has_else: any; + has_transitions: any; + if_exists_condition: any; + }, + detaching: any + ): void; + render_simple( + block: Block, + parent_node: Identifier, + _parent_nodes: Identifier, + dynamic: any, + { + name, + anchor, + if_exists_condition, + has_transitions, + }: { + name: any; + anchor: any; + if_exists_condition: any; + has_transitions: any; + }, + detaching: any + ): void; + get_initial_dirty_bit(): { + readonly type: 'ArrayExpression' | 'UnaryExpression'; + elements: UnaryExpression[]; + operator: import('estree').UnaryOperator; + prefix: true; + argument: import('estree').Expression; + }; } export {}; diff --git a/src/@types/compiler/compile/render_dom/wrappers/InlineComponent/index.d.ts b/src/@types/compiler/compile/render_dom/wrappers/InlineComponent/index.d.ts index 6d7993bb3..34ff301b1 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/InlineComponent/index.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/InlineComponent/index.d.ts @@ -6,20 +6,20 @@ import FragmentWrapper from '../Fragment'; import TemplateScope from '../../../nodes/shared/TemplateScope'; import { Node, Identifier } from 'estree'; declare type SlotDefinition = { - block: Block; - scope: TemplateScope; - get_context?: Node; - get_changes?: Node; + block: Block; + scope: TemplateScope; + get_context?: Node; + get_changes?: Node; }; export default class InlineComponentWrapper extends Wrapper { - var: Identifier; - slots: Map<string, SlotDefinition>; - node: InlineComponent; - fragment: FragmentWrapper; - children: Array<Wrapper | FragmentWrapper>; - constructor(renderer: Renderer, block: Block, parent: Wrapper, node: InlineComponent, strip_whitespace: boolean, next_sibling: Wrapper); - set_slot(name: string, slot_definition: SlotDefinition): void; - warn_if_reactive(): void; - render(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; + var: Identifier; + slots: Map<string, SlotDefinition>; + node: InlineComponent; + fragment: FragmentWrapper; + children: Array<Wrapper | FragmentWrapper>; + constructor(renderer: Renderer, block: Block, parent: Wrapper, node: InlineComponent, strip_whitespace: boolean, next_sibling: Wrapper); + set_slot(name: string, slot_definition: SlotDefinition): void; + warn_if_reactive(): void; + render(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; } export {}; diff --git a/src/@types/compiler/compile/render_dom/wrappers/KeyBlock.d.ts b/src/@types/compiler/compile/render_dom/wrappers/KeyBlock.d.ts index 0dda974e0..f599be8aa 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/KeyBlock.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/KeyBlock.d.ts @@ -6,13 +6,13 @@ import KeyBlock from '../../nodes/KeyBlock'; import FragmentWrapper from './Fragment'; import { Identifier } from 'estree'; export default class KeyBlockWrapper extends Wrapper { - node: KeyBlock; - fragment: FragmentWrapper; - block: Block; - dependencies: string[]; - var: Identifier; - constructor(renderer: Renderer, block: Block, parent: Wrapper, node: EachBlock, strip_whitespace: boolean, next_sibling: Wrapper); - render(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; - render_static_key(_block: Block, parent_node: Identifier, parent_nodes: Identifier): void; - render_dynamic_key(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; + node: KeyBlock; + fragment: FragmentWrapper; + block: Block; + dependencies: string[]; + var: Identifier; + constructor(renderer: Renderer, block: Block, parent: Wrapper, node: EachBlock, strip_whitespace: boolean, next_sibling: Wrapper); + render(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; + render_static_key(_block: Block, parent_node: Identifier, parent_nodes: Identifier): void; + render_dynamic_key(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; } diff --git a/src/@types/compiler/compile/render_dom/wrappers/MustacheTag.d.ts b/src/@types/compiler/compile/render_dom/wrappers/MustacheTag.d.ts index 32decd6ee..3f221d5ea 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/MustacheTag.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/MustacheTag.d.ts @@ -6,7 +6,7 @@ import MustacheTag from '../../nodes/MustacheTag'; import RawMustacheTag from '../../nodes/RawMustacheTag'; import { Identifier } from 'estree'; export default class MustacheTagWrapper extends Tag { - var: Identifier; - constructor(renderer: Renderer, block: Block, parent: Wrapper, node: MustacheTag | RawMustacheTag); - render(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; + var: Identifier; + constructor(renderer: Renderer, block: Block, parent: Wrapper, node: MustacheTag | RawMustacheTag); + render(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; } diff --git a/src/@types/compiler/compile/render_dom/wrappers/RawMustacheTag.d.ts b/src/@types/compiler/compile/render_dom/wrappers/RawMustacheTag.d.ts index e1b0842ea..69cf65c37 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/RawMustacheTag.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/RawMustacheTag.d.ts @@ -6,7 +6,7 @@ import MustacheTag from '../../nodes/MustacheTag'; import RawMustacheTag from '../../nodes/RawMustacheTag'; import { Identifier } from 'estree'; export default class RawMustacheTagWrapper extends Tag { - var: Identifier; - constructor(renderer: Renderer, block: Block, parent: Wrapper, node: MustacheTag | RawMustacheTag); - render(block: Block, parent_node: Identifier, _parent_nodes: Identifier): void; + var: Identifier; + constructor(renderer: Renderer, block: Block, parent: Wrapper, node: MustacheTag | RawMustacheTag); + render(block: Block, parent_node: Identifier, _parent_nodes: Identifier): void; } diff --git a/src/@types/compiler/compile/render_dom/wrappers/Slot.d.ts b/src/@types/compiler/compile/render_dom/wrappers/Slot.d.ts index dbfb324da..3d12ba3c0 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/Slot.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/Slot.d.ts @@ -5,13 +5,13 @@ import Slot from '../../nodes/Slot'; import FragmentWrapper from './Fragment'; import { Identifier } from 'estree'; export default class SlotWrapper extends Wrapper { - node: Slot; - fragment: FragmentWrapper; - fallback: Block | null; - slot_block: Block; - var: Identifier; - dependencies: Set<string>; - constructor(renderer: Renderer, block: Block, parent: Wrapper, node: Slot, strip_whitespace: boolean, next_sibling: Wrapper); - render(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; - is_dependency_dynamic(name: string): boolean; + node: Slot; + fragment: FragmentWrapper; + fallback: Block | null; + slot_block: Block; + var: Identifier; + dependencies: Set<string>; + constructor(renderer: Renderer, block: Block, parent: Wrapper, node: Slot, strip_whitespace: boolean, next_sibling: Wrapper); + render(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; + is_dependency_dynamic(name: string): boolean; } diff --git a/src/@types/compiler/compile/render_dom/wrappers/SlotTemplate.d.ts b/src/@types/compiler/compile/render_dom/wrappers/SlotTemplate.d.ts index ee35c2de3..ad772633a 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/SlotTemplate.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/SlotTemplate.d.ts @@ -7,16 +7,16 @@ import { INode } from '../../nodes/interfaces'; import Let from '../../nodes/Let'; import TemplateScope from '../../nodes/shared/TemplateScope'; declare type NodeWithLets = INode & { - scope: TemplateScope; - lets: Let[]; - slot_template_name: string; + scope: TemplateScope; + lets: Let[]; + slot_template_name: string; }; export default class SlotTemplateWrapper extends Wrapper { - node: NodeWithLets; - fragment: FragmentWrapper; - block: Block; - parent: InlineComponentWrapper; - constructor(renderer: Renderer, block: Block, parent: Wrapper, node: NodeWithLets, strip_whitespace: boolean, next_sibling: Wrapper); - render(): void; + node: NodeWithLets; + fragment: FragmentWrapper; + block: Block; + parent: InlineComponentWrapper; + constructor(renderer: Renderer, block: Block, parent: Wrapper, node: NodeWithLets, strip_whitespace: boolean, next_sibling: Wrapper); + render(): void; } export {}; diff --git a/src/@types/compiler/compile/render_dom/wrappers/Text.d.ts b/src/@types/compiler/compile/render_dom/wrappers/Text.d.ts index be0981fff..a6b84b232 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/Text.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/Text.d.ts @@ -4,11 +4,11 @@ import Text from '../../nodes/Text'; import Wrapper from './shared/Wrapper'; import { Identifier } from 'estree'; export default class TextWrapper extends Wrapper { - node: Text; - data: string; - skip: boolean; - var: Identifier; - constructor(renderer: Renderer, block: Block, parent: Wrapper, node: Text, data: string); - use_space(): boolean; - render(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; + node: Text; + data: string; + skip: boolean; + var: Identifier; + constructor(renderer: Renderer, block: Block, parent: Wrapper, node: Text, data: string); + use_space(): boolean; + render(block: Block, parent_node: Identifier, parent_nodes: Identifier): void; } diff --git a/src/@types/compiler/compile/render_dom/wrappers/Title.d.ts b/src/@types/compiler/compile/render_dom/wrappers/Title.d.ts index f4a6880b0..5c12353cf 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/Title.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/Title.d.ts @@ -4,7 +4,7 @@ import Block from '../Block'; import Title from '../../nodes/Title'; import { Identifier } from 'estree'; export default class TitleWrapper extends Wrapper { - node: Title; - constructor(renderer: Renderer, block: Block, parent: Wrapper, node: Title, _strip_whitespace: boolean, _next_sibling: Wrapper); - render(block: Block, _parent_node: Identifier, _parent_nodes: Identifier): void; + node: Title; + constructor(renderer: Renderer, block: Block, parent: Wrapper, node: Title, _strip_whitespace: boolean, _next_sibling: Wrapper); + render(block: Block, _parent_node: Identifier, _parent_nodes: Identifier): void; } diff --git a/src/@types/compiler/compile/render_dom/wrappers/Window.d.ts b/src/@types/compiler/compile/render_dom/wrappers/Window.d.ts index 14cc85988..daa748991 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/Window.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/Window.d.ts @@ -6,8 +6,8 @@ import { Identifier } from 'estree'; import { TemplateNode } from '../../../interfaces'; import EventHandler from './Element/EventHandler'; export default class WindowWrapper extends Wrapper { - node: Window; - handlers: EventHandler[]; - constructor(renderer: Renderer, block: Block, parent: Wrapper, node: TemplateNode); - render(block: Block, _parent_node: Identifier, _parent_nodes: Identifier): void; + node: Window; + handlers: EventHandler[]; + constructor(renderer: Renderer, block: Block, parent: Wrapper, node: TemplateNode); + render(block: Block, _parent_node: Identifier, _parent_nodes: Identifier): void; } diff --git a/src/@types/compiler/compile/render_dom/wrappers/shared/Tag.d.ts b/src/@types/compiler/compile/render_dom/wrappers/shared/Tag.d.ts index 3c510f1be..7cae664d4 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/shared/Tag.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/shared/Tag.d.ts @@ -5,10 +5,82 @@ import MustacheTag from '../../../nodes/MustacheTag'; import RawMustacheTag from '../../../nodes/RawMustacheTag'; import { Node } from 'estree'; export default class Tag extends Wrapper { - node: MustacheTag | RawMustacheTag; - constructor(renderer: Renderer, block: Block, parent: Wrapper, node: MustacheTag | RawMustacheTag); - is_dependencies_static(): boolean; - rename_this_method(block: Block, update: ((value: Node) => (Node | Node[]))): { - init: import("estree").Identifier | import("estree").SimpleLiteral | import("estree").RegExpLiteral | import("estree").Program | import("estree").FunctionDeclaration | import("estree").FunctionExpression | import("estree").ArrowFunctionExpression | import("estree").SwitchCase | import("estree").CatchClause | import("estree").VariableDeclarator | import("estree").ExpressionStatement | import("estree").BlockStatement | import("estree").EmptyStatement | import("estree").DebuggerStatement | import("estree").WithStatement | import("estree").ReturnStatement | import("estree").LabeledStatement | import("estree").BreakStatement | import("estree").ContinueStatement | import("estree").IfStatement | import("estree").SwitchStatement | import("estree").ThrowStatement | import("estree").TryStatement | import("estree").WhileStatement | import("estree").DoWhileStatement | import("estree").ForStatement | import("estree").ForInStatement | import("estree").ForOfStatement | import("estree").VariableDeclaration | import("estree").ClassDeclaration | import("estree").ThisExpression | import("estree").ArrayExpression | import("estree").ObjectExpression | import("estree").YieldExpression | import("estree").UnaryExpression | import("estree").UpdateExpression | import("estree").BinaryExpression | import("estree").AssignmentExpression | import("estree").LogicalExpression | import("estree").MemberExpression | import("estree").ConditionalExpression | import("estree").SimpleCallExpression | import("estree").NewExpression | import("estree").SequenceExpression | import("estree").TemplateLiteral | import("estree").TaggedTemplateExpression | import("estree").ClassExpression | import("estree").MetaProperty | import("estree").AwaitExpression | import("estree").ImportExpression | import("estree").ChainExpression | import("estree").Property | import("estree").Super | import("estree").TemplateElement | import("estree").SpreadElement | import("estree").ObjectPattern | import("estree").ArrayPattern | import("estree").RestElement | import("estree").AssignmentPattern | import("estree").ClassBody | import("estree").MethodDefinition | import("estree").ImportDeclaration | import("estree").ExportNamedDeclaration | import("estree").ExportDefaultDeclaration | import("estree").ExportAllDeclaration | import("estree").ImportSpecifier | import("estree").ImportDefaultSpecifier | import("estree").ImportNamespaceSpecifier | import("estree").ExportSpecifier; - }; + node: MustacheTag | RawMustacheTag; + constructor(renderer: Renderer, block: Block, parent: Wrapper, node: MustacheTag | RawMustacheTag); + is_dependencies_static(): boolean; + rename_this_method( + block: Block, + update: (value: Node) => Node | Node[] + ): { + init: + | import('estree').Identifier + | import('estree').SimpleLiteral + | import('estree').RegExpLiteral + | import('estree').Program + | import('estree').FunctionDeclaration + | import('estree').FunctionExpression + | import('estree').ArrowFunctionExpression + | import('estree').SwitchCase + | import('estree').CatchClause + | import('estree').VariableDeclarator + | import('estree').ExpressionStatement + | import('estree').BlockStatement + | import('estree').EmptyStatement + | import('estree').DebuggerStatement + | import('estree').WithStatement + | import('estree').ReturnStatement + | import('estree').LabeledStatement + | import('estree').BreakStatement + | import('estree').ContinueStatement + | import('estree').IfStatement + | import('estree').SwitchStatement + | import('estree').ThrowStatement + | import('estree').TryStatement + | import('estree').WhileStatement + | import('estree').DoWhileStatement + | import('estree').ForStatement + | import('estree').ForInStatement + | import('estree').ForOfStatement + | import('estree').VariableDeclaration + | import('estree').ClassDeclaration + | import('estree').ThisExpression + | import('estree').ArrayExpression + | import('estree').ObjectExpression + | import('estree').YieldExpression + | import('estree').UnaryExpression + | import('estree').UpdateExpression + | import('estree').BinaryExpression + | import('estree').AssignmentExpression + | import('estree').LogicalExpression + | import('estree').MemberExpression + | import('estree').ConditionalExpression + | import('estree').SimpleCallExpression + | import('estree').NewExpression + | import('estree').SequenceExpression + | import('estree').TemplateLiteral + | import('estree').TaggedTemplateExpression + | import('estree').ClassExpression + | import('estree').MetaProperty + | import('estree').AwaitExpression + | import('estree').ImportExpression + | import('estree').ChainExpression + | import('estree').Property + | import('estree').Super + | import('estree').TemplateElement + | import('estree').SpreadElement + | import('estree').ObjectPattern + | import('estree').ArrayPattern + | import('estree').RestElement + | import('estree').AssignmentPattern + | import('estree').ClassBody + | import('estree').MethodDefinition + | import('estree').ImportDeclaration + | import('estree').ExportNamedDeclaration + | import('estree').ExportDefaultDeclaration + | import('estree').ExportAllDeclaration + | import('estree').ImportSpecifier + | import('estree').ImportDefaultSpecifier + | import('estree').ImportNamespaceSpecifier + | import('estree').ExportSpecifier; + }; } diff --git a/src/@types/compiler/compile/render_dom/wrappers/shared/Wrapper.d.ts b/src/@types/compiler/compile/render_dom/wrappers/shared/Wrapper.d.ts index 411bf0f60..da34232da 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/shared/Wrapper.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/shared/Wrapper.d.ts @@ -3,19 +3,19 @@ import Block from '../../Block'; import { TemplateNode } from '../../../../interfaces'; import { Identifier } from 'estree'; export default class Wrapper { - renderer: Renderer; - parent: Wrapper; - node: TemplateNode; - prev: Wrapper | null; - next: Wrapper | null; - var: Identifier; - can_use_innerhtml: boolean; - is_static_content: boolean; - constructor(renderer: Renderer, block: Block, parent: Wrapper, node: TemplateNode); - cannot_use_innerhtml(): void; - not_static_content(): void; - get_or_create_anchor(block: Block, parent_node: Identifier, parent_nodes: Identifier): Identifier; - get_update_mount_node(anchor: Identifier): Identifier; - is_dom_node(): boolean; - render(_block: Block, _parent_node: Identifier, _parent_nodes: Identifier): void; + renderer: Renderer; + parent: Wrapper; + node: TemplateNode; + prev: Wrapper | null; + next: Wrapper | null; + var: Identifier; + can_use_innerhtml: boolean; + is_static_content: boolean; + constructor(renderer: Renderer, block: Block, parent: Wrapper, node: TemplateNode); + cannot_use_innerhtml(): void; + not_static_content(): void; + get_or_create_anchor(block: Block, parent_node: Identifier, parent_nodes: Identifier): Identifier; + get_update_mount_node(anchor: Identifier): Identifier; + is_dom_node(): boolean; + render(_block: Block, _parent_node: Identifier, _parent_nodes: Identifier): void; } diff --git a/src/@types/compiler/compile/render_dom/wrappers/shared/bind_this.d.ts b/src/@types/compiler/compile/render_dom/wrappers/shared/bind_this.d.ts index ebe317859..1a46d6509 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/shared/bind_this.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/shared/bind_this.d.ts @@ -2,4 +2,4 @@ import Component from '../../../Component'; import Block from '../../Block'; import BindingWrapper from '../Element/Binding'; import { Identifier } from 'estree'; -export default function bind_this(component: Component, block: Block, binding: BindingWrapper, variable: Identifier): import("estree").Node[]; +export default function bind_this(component: Component, block: Block, binding: BindingWrapper, variable: Identifier): import('estree').Node[]; diff --git a/src/@types/compiler/compile/render_dom/wrappers/shared/get_slot_definition.d.ts b/src/@types/compiler/compile/render_dom/wrappers/shared/get_slot_definition.d.ts index 5a96c33bf..9e4cd8a70 100644 --- a/src/@types/compiler/compile/render_dom/wrappers/shared/get_slot_definition.d.ts +++ b/src/@types/compiler/compile/render_dom/wrappers/shared/get_slot_definition.d.ts @@ -1,14 +1,20 @@ import Let from '../../../nodes/Let'; import Block from '../../Block'; import TemplateScope from '../../../nodes/shared/TemplateScope'; -export declare function get_slot_definition(block: Block, scope: TemplateScope, lets: Let[]): { - block: Block; - scope: TemplateScope; - get_context?: undefined; - get_changes?: undefined; -} | { - block: Block; - scope: TemplateScope; - get_context: import("estree").Expression; - get_changes: import("estree").Expression; -}; +export declare function get_slot_definition( + block: Block, + scope: TemplateScope, + lets: Let[] +): + | { + block: Block; + scope: TemplateScope; + get_context?: undefined; + get_changes?: undefined; + } + | { + block: Block; + scope: TemplateScope; + get_context: import('estree').Expression; + get_changes: import('estree').Expression; + }; diff --git a/src/@types/compiler/compile/render_ssr/Renderer.d.ts b/src/@types/compiler/compile/render_ssr/Renderer.d.ts index 2a7f29551..aa2de457c 100644 --- a/src/@types/compiler/compile/render_ssr/Renderer.d.ts +++ b/src/@types/compiler/compile/render_ssr/Renderer.d.ts @@ -2,32 +2,32 @@ import { AppendTarget, CompileOptions } from '../../interfaces'; import { INode } from '../nodes/interfaces'; import { Expression, TemplateLiteral, Identifier } from 'estree'; export interface RenderOptions extends CompileOptions { - locate: (c: number) => { - line: number; - column: number; - }; - head_id?: string; + locate: ( + c: number + ) => { + line: number; + column: number; + }; + head_id?: string; } export default class Renderer { - has_bindings: boolean; - name: Identifier; - stack: Array<{ - current: { - value: string; - }; - literal: TemplateLiteral; - }>; + has_bindings: boolean; + name: Identifier; + stack: Array<{ current: { - value: string; + value: string; }; literal: TemplateLiteral; - targets: AppendTarget[]; - constructor({ name }: { - name: any; - }); - add_string(str: string): void; - add_expression(node: Expression): void; - push(): void; - pop(): TemplateLiteral; - render(nodes: INode[], options: RenderOptions): void; + }>; + current: { + value: string; + }; + literal: TemplateLiteral; + targets: AppendTarget[]; + constructor({ name }: { name: any }); + add_string(str: string): void; + add_expression(node: Expression): void; + push(): void; + pop(): TemplateLiteral; + render(nodes: INode[], options: RenderOptions): void; } diff --git a/src/@types/compiler/compile/render_ssr/handlers/Slot.d.ts b/src/@types/compiler/compile/render_ssr/handlers/Slot.d.ts index b07dd1374..3a17a1ade 100644 --- a/src/@types/compiler/compile/render_ssr/handlers/Slot.d.ts +++ b/src/@types/compiler/compile/render_ssr/handlers/Slot.d.ts @@ -1,5 +1,9 @@ import Renderer, { RenderOptions } from '../Renderer'; import Slot from '../../nodes/Slot'; -export default function (node: Slot, renderer: Renderer, options: RenderOptions & { +export default function ( + node: Slot, + renderer: Renderer, + options: RenderOptions & { slot_scopes: Map<any, any>; -}): void; + } +): void; diff --git a/src/@types/compiler/compile/render_ssr/handlers/SlotTemplate.d.ts b/src/@types/compiler/compile/render_ssr/handlers/SlotTemplate.d.ts index defd084a7..27985cc0f 100644 --- a/src/@types/compiler/compile/render_ssr/handlers/SlotTemplate.d.ts +++ b/src/@types/compiler/compile/render_ssr/handlers/SlotTemplate.d.ts @@ -2,6 +2,10 @@ import Renderer, { RenderOptions } from '../Renderer'; import SlotTemplate from '../../nodes/SlotTemplate'; import InlineComponent from '../../nodes/InlineComponent'; import Element from '../../nodes/Element'; -export default function (node: SlotTemplate | Element | InlineComponent, renderer: Renderer, options: RenderOptions & { +export default function ( + node: SlotTemplate | Element | InlineComponent, + renderer: Renderer, + options: RenderOptions & { slot_scopes: Map<any, any>; -}): void; + } +): void; diff --git a/src/@types/compiler/compile/render_ssr/index.d.ts b/src/@types/compiler/compile/render_ssr/index.d.ts index 011307736..212293400 100644 --- a/src/@types/compiler/compile/render_ssr/index.d.ts +++ b/src/@types/compiler/compile/render_ssr/index.d.ts @@ -1,7 +1,10 @@ import Component from '../Component'; import { CompileOptions, CssResult } from '../../interfaces'; import { Node } from 'estree'; -export default function ssr(component: Component, options: CompileOptions): { - js: Node[]; - css: CssResult; +export default function ssr( + component: Component, + options: CompileOptions +): { + js: Node[]; + css: CssResult; }; diff --git a/src/@types/compiler/compile/utils/flatten_reference.d.ts b/src/@types/compiler/compile/utils/flatten_reference.d.ts index e07492982..d50cc454d 100644 --- a/src/@types/compiler/compile/utils/flatten_reference.d.ts +++ b/src/@types/compiler/compile/utils/flatten_reference.d.ts @@ -1,6 +1,8 @@ import { Node } from 'estree'; -export default function flatten_reference(node: Node): { - name: string; - nodes: any[]; - parts: any[]; +export default function flatten_reference( + node: Node +): { + name: string; + nodes: any[]; + parts: any[]; }; diff --git a/src/@types/compiler/compile/utils/get_slot_data.d.ts b/src/@types/compiler/compile/utils/get_slot_data.d.ts index 45796e4d4..6c8a9807b 100644 --- a/src/@types/compiler/compile/utils/get_slot_data.d.ts +++ b/src/@types/compiler/compile/utils/get_slot_data.d.ts @@ -1,9 +1,85 @@ import Attribute from '../nodes/Attribute'; import Block from '../render_dom/Block'; -export default function get_slot_data(values: Map<string, Attribute>, block?: Block): { - type: string; - properties: (import("estree").Property | import("estree").SpreadElement | { +export default function get_slot_data( + values: Map<string, Attribute>, + block?: Block +): { + type: string; + properties: ( + | import('estree').Property + | import('estree').SpreadElement + | { type: string; - argument: import("estree").Identifier | import("estree").SimpleLiteral | import("estree").RegExpLiteral | import("estree").Program | import("estree").FunctionDeclaration | import("estree").FunctionExpression | import("estree").ArrowFunctionExpression | import("estree").SwitchCase | import("estree").CatchClause | import("estree").VariableDeclarator | import("estree").ExpressionStatement | import("estree").BlockStatement | import("estree").EmptyStatement | import("estree").DebuggerStatement | import("estree").WithStatement | import("estree").ReturnStatement | import("estree").LabeledStatement | import("estree").BreakStatement | import("estree").ContinueStatement | import("estree").IfStatement | import("estree").SwitchStatement | import("estree").ThrowStatement | import("estree").TryStatement | import("estree").WhileStatement | import("estree").DoWhileStatement | import("estree").ForStatement | import("estree").ForInStatement | import("estree").ForOfStatement | import("estree").VariableDeclaration | import("estree").ClassDeclaration | import("estree").ThisExpression | import("estree").ArrayExpression | import("estree").ObjectExpression | import("estree").YieldExpression | import("estree").UnaryExpression | import("estree").UpdateExpression | import("estree").BinaryExpression | import("estree").AssignmentExpression | import("estree").LogicalExpression | import("estree").MemberExpression | import("estree").ConditionalExpression | import("estree").SimpleCallExpression | import("estree").NewExpression | import("estree").SequenceExpression | import("estree").TemplateLiteral | import("estree").TaggedTemplateExpression | import("estree").ClassExpression | import("estree").MetaProperty | import("estree").AwaitExpression | import("estree").ImportExpression | import("estree").ChainExpression | import("estree").Property | import("estree").Super | import("estree").TemplateElement | import("estree").SpreadElement | import("estree").ObjectPattern | import("estree").ArrayPattern | import("estree").RestElement | import("estree").AssignmentPattern | import("estree").ClassBody | import("estree").MethodDefinition | import("estree").ImportDeclaration | import("estree").ExportNamedDeclaration | import("estree").ExportDefaultDeclaration | import("estree").ExportAllDeclaration | import("estree").ImportSpecifier | import("estree").ImportDefaultSpecifier | import("estree").ImportNamespaceSpecifier | import("estree").ExportSpecifier; - })[]; + argument: + | import('estree').Identifier + | import('estree').SimpleLiteral + | import('estree').RegExpLiteral + | import('estree').Program + | import('estree').FunctionDeclaration + | import('estree').FunctionExpression + | import('estree').ArrowFunctionExpression + | import('estree').SwitchCase + | import('estree').CatchClause + | import('estree').VariableDeclarator + | import('estree').ExpressionStatement + | import('estree').BlockStatement + | import('estree').EmptyStatement + | import('estree').DebuggerStatement + | import('estree').WithStatement + | import('estree').ReturnStatement + | import('estree').LabeledStatement + | import('estree').BreakStatement + | import('estree').ContinueStatement + | import('estree').IfStatement + | import('estree').SwitchStatement + | import('estree').ThrowStatement + | import('estree').TryStatement + | import('estree').WhileStatement + | import('estree').DoWhileStatement + | import('estree').ForStatement + | import('estree').ForInStatement + | import('estree').ForOfStatement + | import('estree').VariableDeclaration + | import('estree').ClassDeclaration + | import('estree').ThisExpression + | import('estree').ArrayExpression + | import('estree').ObjectExpression + | import('estree').YieldExpression + | import('estree').UnaryExpression + | import('estree').UpdateExpression + | import('estree').BinaryExpression + | import('estree').AssignmentExpression + | import('estree').LogicalExpression + | import('estree').MemberExpression + | import('estree').ConditionalExpression + | import('estree').SimpleCallExpression + | import('estree').NewExpression + | import('estree').SequenceExpression + | import('estree').TemplateLiteral + | import('estree').TaggedTemplateExpression + | import('estree').ClassExpression + | import('estree').MetaProperty + | import('estree').AwaitExpression + | import('estree').ImportExpression + | import('estree').ChainExpression + | import('estree').Property + | import('estree').Super + | import('estree').TemplateElement + | import('estree').SpreadElement + | import('estree').ObjectPattern + | import('estree').ArrayPattern + | import('estree').RestElement + | import('estree').AssignmentPattern + | import('estree').ClassBody + | import('estree').MethodDefinition + | import('estree').ImportDeclaration + | import('estree').ExportNamedDeclaration + | import('estree').ExportDefaultDeclaration + | import('estree').ExportAllDeclaration + | import('estree').ImportSpecifier + | import('estree').ImportDefaultSpecifier + | import('estree').ImportNamespaceSpecifier + | import('estree').ExportSpecifier; + } + )[]; }; diff --git a/src/@types/compiler/compile/utils/replace_object.d.ts b/src/@types/compiler/compile/utils/replace_object.d.ts index bd4ded862..e1f3491d9 100644 --- a/src/@types/compiler/compile/utils/replace_object.d.ts +++ b/src/@types/compiler/compile/utils/replace_object.d.ts @@ -1,2 +1,74 @@ import { Node } from 'estree'; -export default function replace_object(node: Node, replacement: Node): import("estree").Identifier | import("estree").SimpleLiteral | import("estree").RegExpLiteral | import("estree").Program | import("estree").FunctionDeclaration | import("estree").FunctionExpression | import("estree").ArrowFunctionExpression | import("estree").SwitchCase | import("estree").CatchClause | import("estree").VariableDeclarator | import("estree").ExpressionStatement | import("estree").BlockStatement | import("estree").EmptyStatement | import("estree").DebuggerStatement | import("estree").WithStatement | import("estree").ReturnStatement | import("estree").LabeledStatement | import("estree").BreakStatement | import("estree").ContinueStatement | import("estree").IfStatement | import("estree").SwitchStatement | import("estree").ThrowStatement | import("estree").TryStatement | import("estree").WhileStatement | import("estree").DoWhileStatement | import("estree").ForStatement | import("estree").ForInStatement | import("estree").ForOfStatement | import("estree").VariableDeclaration | import("estree").ClassDeclaration | import("estree").ThisExpression | import("estree").ArrayExpression | import("estree").ObjectExpression | import("estree").YieldExpression | import("estree").UnaryExpression | import("estree").UpdateExpression | import("estree").BinaryExpression | import("estree").AssignmentExpression | import("estree").LogicalExpression | import("estree").MemberExpression | import("estree").ConditionalExpression | import("estree").SimpleCallExpression | import("estree").NewExpression | import("estree").SequenceExpression | import("estree").TemplateLiteral | import("estree").TaggedTemplateExpression | import("estree").ClassExpression | import("estree").MetaProperty | import("estree").AwaitExpression | import("estree").ImportExpression | import("estree").ChainExpression | import("estree").Property | import("estree").Super | import("estree").TemplateElement | import("estree").SpreadElement | import("estree").ObjectPattern | import("estree").ArrayPattern | import("estree").RestElement | import("estree").AssignmentPattern | import("estree").ClassBody | import("estree").MethodDefinition | import("estree").ImportDeclaration | import("estree").ExportNamedDeclaration | import("estree").ExportDefaultDeclaration | import("estree").ExportAllDeclaration | import("estree").ImportSpecifier | import("estree").ImportDefaultSpecifier | import("estree").ImportNamespaceSpecifier | import("estree").ExportSpecifier; +export default function replace_object( + node: Node, + replacement: Node +): + | import('estree').Identifier + | import('estree').SimpleLiteral + | import('estree').RegExpLiteral + | import('estree').Program + | import('estree').FunctionDeclaration + | import('estree').FunctionExpression + | import('estree').ArrowFunctionExpression + | import('estree').SwitchCase + | import('estree').CatchClause + | import('estree').VariableDeclarator + | import('estree').ExpressionStatement + | import('estree').BlockStatement + | import('estree').EmptyStatement + | import('estree').DebuggerStatement + | import('estree').WithStatement + | import('estree').ReturnStatement + | import('estree').LabeledStatement + | import('estree').BreakStatement + | import('estree').ContinueStatement + | import('estree').IfStatement + | import('estree').SwitchStatement + | import('estree').ThrowStatement + | import('estree').TryStatement + | import('estree').WhileStatement + | import('estree').DoWhileStatement + | import('estree').ForStatement + | import('estree').ForInStatement + | import('estree').ForOfStatement + | import('estree').VariableDeclaration + | import('estree').ClassDeclaration + | import('estree').ThisExpression + | import('estree').ArrayExpression + | import('estree').ObjectExpression + | import('estree').YieldExpression + | import('estree').UnaryExpression + | import('estree').UpdateExpression + | import('estree').BinaryExpression + | import('estree').AssignmentExpression + | import('estree').LogicalExpression + | import('estree').MemberExpression + | import('estree').ConditionalExpression + | import('estree').SimpleCallExpression + | import('estree').NewExpression + | import('estree').SequenceExpression + | import('estree').TemplateLiteral + | import('estree').TaggedTemplateExpression + | import('estree').ClassExpression + | import('estree').MetaProperty + | import('estree').AwaitExpression + | import('estree').ImportExpression + | import('estree').ChainExpression + | import('estree').Property + | import('estree').Super + | import('estree').TemplateElement + | import('estree').SpreadElement + | import('estree').ObjectPattern + | import('estree').ArrayPattern + | import('estree').RestElement + | import('estree').AssignmentPattern + | import('estree').ClassBody + | import('estree').MethodDefinition + | import('estree').ImportDeclaration + | import('estree').ExportNamedDeclaration + | import('estree').ExportDefaultDeclaration + | import('estree').ExportAllDeclaration + | import('estree').ImportSpecifier + | import('estree').ImportDefaultSpecifier + | import('estree').ImportNamespaceSpecifier + | import('estree').ExportSpecifier; diff --git a/src/@types/compiler/compile/utils/scope.d.ts b/src/@types/compiler/compile/utils/scope.d.ts index e5b08f9d5..ae2fc773f 100644 --- a/src/@types/compiler/compile/utils/scope.d.ts +++ b/src/@types/compiler/compile/utils/scope.d.ts @@ -1,8 +1,10 @@ import { Node } from 'estree'; import { Scope, extract_names, extract_identifiers } from 'periscopic'; -export declare function create_scopes(expression: Node): { - map: WeakMap<Node, Scope>; - scope: Scope; - globals: Map<string, Node>; +export declare function create_scopes( + expression: Node +): { + map: WeakMap<Node, Scope>; + scope: Scope; + globals: Map<string, Node>; }; export { Scope, extract_names, extract_identifiers }; diff --git a/src/@types/compiler/compile/utils/stringify.d.ts b/src/@types/compiler/compile/utils/stringify.d.ts index 471194a1b..17808aeeb 100644 --- a/src/@types/compiler/compile/utils/stringify.d.ts +++ b/src/@types/compiler/compile/utils/stringify.d.ts @@ -1,9 +1,16 @@ -export declare function string_literal(data: string): { - type: string; - value: string; +export declare function string_literal( + data: string +): { + type: string; + value: string; }; -export declare function escape(data: string, { only_escape_at_symbol }?: { +export declare function escape( + data: string, + { + only_escape_at_symbol, + }?: { only_escape_at_symbol?: boolean; -}): string; + } +): string; export declare function escape_html(html: any): string; export declare function escape_template(str: any): any; diff --git a/src/@types/compiler/index.d.ts b/src/@types/compiler/index.d.ts index 99fe8e027..1b04db06a 100644 --- a/src/@types/compiler/index.d.ts +++ b/src/@types/compiler/index.d.ts @@ -2,4 +2,4 @@ export { default as compile } from './compile/index'; export { default as parse } from './parse/index'; export { default as preprocess } from './preprocess/index'; export { walk } from 'estree-walker'; -export declare const VERSION = "__VERSION__"; +export declare const VERSION = '__VERSION__'; diff --git a/src/@types/compiler/interfaces.d.ts b/src/@types/compiler/interfaces.d.ts index 2fc2db544..6f1bffe9f 100644 --- a/src/@types/compiler/interfaces.d.ts +++ b/src/@types/compiler/interfaces.d.ts @@ -1,148 +1,143 @@ import { Node, Program } from 'estree'; import { SourceMap } from 'magic-string'; interface BaseNode { - start: number; - end: number; - type: string; - children?: TemplateNode[]; - [prop_name: string]: any; + start: number; + end: number; + type: string; + children?: TemplateNode[]; + [prop_name: string]: any; } export interface Fragment extends BaseNode { - type: 'Fragment'; - children: TemplateNode[]; + type: 'Fragment'; + children: TemplateNode[]; } export interface Text extends BaseNode { - type: 'Text'; - data: string; + type: 'Text'; + data: string; } export interface MustacheTag extends BaseNode { - type: 'MustacheTag'; - expression: string; + type: 'MustacheTag'; + expression: string; } export declare type DirectiveType = 'Action' | 'Animation' | 'Binding' | 'Class' | 'EventHandler' | 'Let' | 'Ref' | 'Transition'; interface BaseDirective extends BaseNode { - type: DirectiveType; - expression: null | Node; - name: string; - modifiers: string[]; + type: DirectiveType; + expression: null | Node; + name: string; + modifiers: string[]; } export interface Transition extends BaseDirective { - type: 'Transition'; - intro: boolean; - outro: boolean; + type: 'Transition'; + intro: boolean; + outro: boolean; } export declare type Directive = BaseDirective | Transition; export declare type TemplateNode = Text | MustacheTag | BaseNode | Directive | Transition; export interface Parser { - readonly template: string; - readonly filename?: string; - index: number; - stack: Node[]; - html: Node; - css: Node; - js: Node; - meta_tags: {}; + readonly template: string; + readonly filename?: string; + index: number; + stack: Node[]; + html: Node; + css: Node; + js: Node; + meta_tags: {}; } export interface Script extends BaseNode { - type: 'Script'; - context: string; - content: Program; + type: 'Script'; + context: string; + content: Program; } export interface Style extends BaseNode { - type: 'Style'; - attributes: any[]; - children: any[]; - content: { - start: number; - end: number; - styles: string; - }; + type: 'Style'; + attributes: any[]; + children: any[]; + content: { + start: number; + end: number; + styles: string; + }; } export interface Ast { - html: TemplateNode; - css: Style; - instance: Script; - module: Script; + html: TemplateNode; + css: Style; + instance: Script; + module: Script; } export interface Warning { - start?: { - line: number; - column: number; - pos?: number; - }; - end?: { - line: number; - column: number; - }; + start?: { + line: number; + column: number; pos?: number; - code: string; - message: string; - filename?: string; - frame?: string; - toString: () => string; + }; + end?: { + line: number; + column: number; + }; + pos?: number; + code: string; + message: string; + filename?: string; + frame?: string; + toString: () => string; } export declare type ModuleFormat = 'esm' | 'cjs'; -export declare type CssHashGetter = (args: { - name: string; - filename: string | undefined; - css: string; - hash: (input: string) => string; -}) => string; +export declare type CssHashGetter = (args: { name: string; filename: string | undefined; css: string; hash: (input: string) => string }) => string; export interface CompileOptions { - format?: ModuleFormat; - name?: string; - filename?: string; - generate?: 'dom' | 'ssr' | false; - sourcemap?: object | string; - outputFilename?: string; - cssOutputFilename?: string; - sveltePath?: string; - dev?: boolean; - accessors?: boolean; - immutable?: boolean; - hydratable?: boolean; - legacy?: boolean; - customElement?: boolean; - tag?: string; - css?: boolean; - loopGuardTimeout?: number; - namespace?: string; - cssHash?: CssHashGetter; - preserveComments?: boolean; - preserveWhitespace?: boolean; + format?: ModuleFormat; + name?: string; + filename?: string; + generate?: 'dom' | 'ssr' | false; + sourcemap?: object | string; + outputFilename?: string; + cssOutputFilename?: string; + sveltePath?: string; + dev?: boolean; + accessors?: boolean; + immutable?: boolean; + hydratable?: boolean; + legacy?: boolean; + customElement?: boolean; + tag?: string; + css?: boolean; + loopGuardTimeout?: number; + namespace?: string; + cssHash?: CssHashGetter; + preserveComments?: boolean; + preserveWhitespace?: boolean; } export interface ParserOptions { - filename?: string; - customElement?: boolean; + filename?: string; + customElement?: boolean; } export interface Visitor { - enter: (node: Node) => void; - leave?: (node: Node) => void; + enter: (node: Node) => void; + leave?: (node: Node) => void; } export interface AppendTarget { - slots: Record<string, string>; - slot_stack: string[]; + slots: Record<string, string>; + slot_stack: string[]; } export interface Var { - name: string; - export_name?: string; - injected?: boolean; - module?: boolean; - mutated?: boolean; - reassigned?: boolean; - referenced?: boolean; - referenced_from_script?: boolean; - writable?: boolean; - global?: boolean; - internal?: boolean; - initialised?: boolean; - hoistable?: boolean; - subscribable?: boolean; - is_reactive_dependency?: boolean; - imported?: boolean; + name: string; + export_name?: string; + injected?: boolean; + module?: boolean; + mutated?: boolean; + reassigned?: boolean; + referenced?: boolean; + referenced_from_script?: boolean; + writable?: boolean; + global?: boolean; + internal?: boolean; + initialised?: boolean; + hoistable?: boolean; + subscribable?: boolean; + is_reactive_dependency?: boolean; + imported?: boolean; } export interface CssResult { - code: string; - map: SourceMap; + code: string; + map: SourceMap; } export {}; diff --git a/src/@types/compiler/parse/index.d.ts b/src/@types/compiler/parse/index.d.ts index 1d2f6ec00..7b5af3de3 100644 --- a/src/@types/compiler/parse/index.d.ts +++ b/src/@types/compiler/parse/index.d.ts @@ -1,35 +1,41 @@ import { TemplateNode, Ast, ParserOptions, Fragment, Style, Script } from '../interfaces'; interface LastAutoClosedTag { - tag: string; - reason: string; - depth: number; + tag: string; + reason: string; + depth: number; } export declare class Parser { - readonly template: string; - readonly filename?: string; - readonly customElement: boolean; - index: number; - stack: TemplateNode[]; - html: Fragment; - css: Style[]; - js: Script[]; - meta_tags: {}; - last_auto_closed_tag?: LastAutoClosedTag; - constructor(template: string, options: ParserOptions); - current(): TemplateNode; - acorn_error(err: any): void; - error({ code, message }: { - code: string; - message: string; - }, index?: number): void; - eat(str: string, required?: boolean, message?: string): boolean; - match(str: string): boolean; - match_regex(pattern: RegExp): string; - allow_whitespace(): void; - read(pattern: RegExp): string; - read_identifier(allow_reserved?: boolean): string; - read_until(pattern: RegExp): string; - require_whitespace(): void; + readonly template: string; + readonly filename?: string; + readonly customElement: boolean; + index: number; + stack: TemplateNode[]; + html: Fragment; + css: Style[]; + js: Script[]; + meta_tags: {}; + last_auto_closed_tag?: LastAutoClosedTag; + constructor(template: string, options: ParserOptions); + current(): TemplateNode; + acorn_error(err: any): void; + error( + { + code, + message, + }: { + code: string; + message: string; + }, + index?: number + ): void; + eat(str: string, required?: boolean, message?: string): boolean; + match(str: string): boolean; + match_regex(pattern: RegExp): string; + allow_whitespace(): void; + read(pattern: RegExp): string; + read_identifier(allow_reserved?: boolean): string; + read_until(pattern: RegExp): string; + require_whitespace(): void; } export default function parse(template: string, options?: ParserOptions): Ast; export {}; diff --git a/src/@types/compiler/parse/read/context.d.ts b/src/@types/compiler/parse/read/context.d.ts index e6d53f41d..259ab0276 100644 --- a/src/@types/compiler/parse/read/context.d.ts +++ b/src/@types/compiler/parse/read/context.d.ts @@ -1,6 +1,8 @@ import { Parser } from '../index'; import { Pattern } from 'estree'; -export default function read_context(parser: Parser): Pattern & { - start: number; - end: number; +export default function read_context( + parser: Parser +): Pattern & { + start: number; + end: number; }; diff --git a/src/@types/compiler/parse/utils/entities.d.ts b/src/@types/compiler/parse/utils/entities.d.ts index 41902a659..12ce08bdf 100644 --- a/src/@types/compiler/parse/utils/entities.d.ts +++ b/src/@types/compiler/parse/utils/entities.d.ts @@ -1,2034 +1,2034 @@ declare const _default: { - CounterClockwiseContourIntegral: number; - ClockwiseContourIntegral: number; - DoubleLongLeftRightArrow: number; - DiacriticalDoubleAcute: number; - NotSquareSupersetEqual: number; - CloseCurlyDoubleQuote: number; - DoubleContourIntegral: number; - FilledVerySmallSquare: number; - NegativeVeryThinSpace: number; - NotPrecedesSlantEqual: number; - NotRightTriangleEqual: number; - NotSucceedsSlantEqual: number; - CapitalDifferentialD: number; - DoubleLeftRightArrow: number; - DoubleLongRightArrow: number; - EmptyVerySmallSquare: number; - NestedGreaterGreater: number; - NotDoubleVerticalBar: number; - NotLeftTriangleEqual: number; - NotSquareSubsetEqual: number; - OpenCurlyDoubleQuote: number; - ReverseUpEquilibrium: number; - DoubleLongLeftArrow: number; - DownLeftRightVector: number; - LeftArrowRightArrow: number; - NegativeMediumSpace: number; - RightArrowLeftArrow: number; - SquareSupersetEqual: number; - leftrightsquigarrow: number; - DownRightTeeVector: number; - DownRightVectorBar: number; - LongLeftRightArrow: number; - Longleftrightarrow: number; - NegativeThickSpace: number; - PrecedesSlantEqual: number; - ReverseEquilibrium: number; - RightDoubleBracket: number; - RightDownTeeVector: number; - RightDownVectorBar: number; - RightTriangleEqual: number; - SquareIntersection: number; - SucceedsSlantEqual: number; - blacktriangleright: number; - longleftrightarrow: number; - DoubleUpDownArrow: number; - DoubleVerticalBar: number; - DownLeftTeeVector: number; - DownLeftVectorBar: number; - FilledSmallSquare: number; - GreaterSlantEqual: number; - LeftDoubleBracket: number; - LeftDownTeeVector: number; - LeftDownVectorBar: number; - LeftTriangleEqual: number; - NegativeThinSpace: number; - NotReverseElement: number; - NotTildeFullEqual: number; - RightAngleBracket: number; - RightUpDownVector: number; - SquareSubsetEqual: number; - VerticalSeparator: number; - blacktriangledown: number; - blacktriangleleft: number; - leftrightharpoons: number; - rightleftharpoons: number; - twoheadrightarrow: number; - DiacriticalAcute: number; - DiacriticalGrave: number; - DiacriticalTilde: number; - DoubleRightArrow: number; - DownArrowUpArrow: number; - EmptySmallSquare: number; - GreaterEqualLess: number; - GreaterFullEqual: number; - LeftAngleBracket: number; - LeftUpDownVector: number; - LessEqualGreater: number; - NonBreakingSpace: number; - NotRightTriangle: number; - NotSupersetEqual: number; - RightTriangleBar: number; - RightUpTeeVector: number; - RightUpVectorBar: number; - UnderParenthesis: number; - UpArrowDownArrow: number; - circlearrowright: number; - downharpoonright: number; - ntrianglerighteq: number; - rightharpoondown: number; - rightrightarrows: number; - twoheadleftarrow: number; - vartriangleright: number; - CloseCurlyQuote: number; - ContourIntegral: number; - DoubleDownArrow: number; - DoubleLeftArrow: number; - DownRightVector: number; - LeftRightVector: number; - LeftTriangleBar: number; - LeftUpTeeVector: number; - LeftUpVectorBar: number; - LowerRightArrow: number; - NotGreaterEqual: number; - NotGreaterTilde: number; - NotLeftTriangle: number; - OverParenthesis: number; - RightDownVector: number; - ShortRightArrow: number; - UpperRightArrow: number; - bigtriangledown: number; - circlearrowleft: number; - curvearrowright: number; - downharpoonleft: number; - leftharpoondown: number; - leftrightarrows: number; - nLeftrightarrow: number; - nleftrightarrow: number; - ntrianglelefteq: number; - rightleftarrows: number; - rightsquigarrow: number; - rightthreetimes: number; - straightepsilon: number; - trianglerighteq: number; - vartriangleleft: number; - DiacriticalDot: number; - DoubleRightTee: number; - DownLeftVector: number; - GreaterGreater: number; - HorizontalLine: number; - InvisibleComma: number; - InvisibleTimes: number; - LeftDownVector: number; - LeftRightArrow: number; - Leftrightarrow: number; - LessSlantEqual: number; - LongRightArrow: number; - Longrightarrow: number; - LowerLeftArrow: number; - NestedLessLess: number; - NotGreaterLess: number; - NotLessGreater: number; - NotSubsetEqual: number; - NotVerticalBar: number; - OpenCurlyQuote: number; - ReverseElement: number; - RightTeeVector: number; - RightVectorBar: number; - ShortDownArrow: number; - ShortLeftArrow: number; - SquareSuperset: number; - TildeFullEqual: number; - UpperLeftArrow: number; - ZeroWidthSpace: number; - curvearrowleft: number; - doublebarwedge: number; - downdownarrows: number; - hookrightarrow: number; - leftleftarrows: number; - leftrightarrow: number; - leftthreetimes: number; - longrightarrow: number; - looparrowright: number; - nshortparallel: number; - ntriangleright: number; - rightarrowtail: number; - rightharpoonup: number; - trianglelefteq: number; - upharpoonright: number; - ApplyFunction: number; - DifferentialD: number; - DoubleLeftTee: number; - DoubleUpArrow: number; - LeftTeeVector: number; - LeftVectorBar: number; - LessFullEqual: number; - LongLeftArrow: number; - Longleftarrow: number; - NotTildeEqual: number; - NotTildeTilde: number; - Poincareplane: number; - PrecedesEqual: number; - PrecedesTilde: number; - RightArrowBar: number; - RightTeeArrow: number; - RightTriangle: number; - RightUpVector: number; - SucceedsEqual: number; - SucceedsTilde: number; - SupersetEqual: number; - UpEquilibrium: number; - VerticalTilde: number; - VeryThinSpace: number; - bigtriangleup: number; - blacktriangle: number; - divideontimes: number; - fallingdotseq: number; - hookleftarrow: number; - leftarrowtail: number; - leftharpoonup: number; - longleftarrow: number; - looparrowleft: number; - measuredangle: number; - ntriangleleft: number; - shortparallel: number; - smallsetminus: number; - triangleright: number; - upharpoonleft: number; - DownArrowBar: number; - DownTeeArrow: number; - ExponentialE: number; - GreaterEqual: number; - GreaterTilde: number; - HilbertSpace: number; - HumpDownHump: number; - Intersection: number; - LeftArrowBar: number; - LeftTeeArrow: number; - LeftTriangle: number; - LeftUpVector: number; - NotCongruent: number; - NotLessEqual: number; - NotLessTilde: number; - Proportional: number; - RightCeiling: number; - RoundImplies: number; - ShortUpArrow: number; - SquareSubset: number; - UnderBracket: number; - VerticalLine: number; - blacklozenge: number; - exponentiale: number; - risingdotseq: number; - triangledown: number; - triangleleft: number; - CircleMinus: number; - CircleTimes: number; - Equilibrium: number; - GreaterLess: number; - LeftCeiling: number; - LessGreater: number; - MediumSpace: number; - NotPrecedes: number; - NotSucceeds: number; - OverBracket: number; - RightVector: number; - Rrightarrow: number; - RuleDelayed: number; - SmallCircle: number; - SquareUnion: number; - SubsetEqual: number; - UpDownArrow: number; - Updownarrow: number; - VerticalBar: number; - backepsilon: number; - blacksquare: number; - circledcirc: number; - circleddash: number; - curlyeqprec: number; - curlyeqsucc: number; - diamondsuit: number; - eqslantless: number; - expectation: number; - nRightarrow: number; - nrightarrow: number; - preccurlyeq: number; - precnapprox: number; - quaternions: number; - straightphi: number; - succcurlyeq: number; - succnapprox: number; - thickapprox: number; - updownarrow: number; - Bernoullis: number; - CirclePlus: number; - EqualTilde: number; - Fouriertrf: number; - ImaginaryI: number; - Laplacetrf: number; - LeftVector: number; - Lleftarrow: number; - NotElement: number; - NotGreater: number; - Proportion: number; - RightArrow: number; - RightFloor: number; - Rightarrow: number; - TildeEqual: number; - TildeTilde: number; - UnderBrace: number; - UpArrowBar: number; - UpTeeArrow: number; - circledast: number; - complement: number; - curlywedge: number; - eqslantgtr: number; - gtreqqless: number; - lessapprox: number; - lesseqqgtr: number; - lmoustache: number; - longmapsto: number; - mapstodown: number; - mapstoleft: number; - nLeftarrow: number; - nleftarrow: number; - precapprox: number; - rightarrow: number; - rmoustache: number; - sqsubseteq: number; - sqsupseteq: number; - subsetneqq: number; - succapprox: number; - supsetneqq: number; - upuparrows: number; - varepsilon: number; - varnothing: number; - Backslash: number; - CenterDot: number; - CircleDot: number; - Congruent: number; - Coproduct: number; - DoubleDot: number; - DownArrow: number; - DownBreve: number; - Downarrow: number; - HumpEqual: number; - LeftArrow: number; - LeftFloor: number; - Leftarrow: number; - LessTilde: number; - Mellintrf: number; - MinusPlus: number; - NotCupCap: number; - NotExists: number; - OverBrace: number; - PlusMinus: number; - Therefore: number; - ThinSpace: number; - TripleDot: number; - UnionPlus: number; - backprime: number; - backsimeq: number; - bigotimes: number; - centerdot: number; - checkmark: number; - complexes: number; - dotsquare: number; - downarrow: number; - gtrapprox: number; - gtreqless: number; - heartsuit: number; - leftarrow: number; - lesseqgtr: number; - nparallel: number; - nshortmid: number; - nsubseteq: number; - nsupseteq: number; - pitchfork: number; - rationals: number; - spadesuit: number; - subseteqq: number; - subsetneq: number; - supseteqq: number; - supsetneq: number; - therefore: number; - triangleq: number; - varpropto: number; - DDotrahd: number; - DotEqual: number; - Integral: number; - LessLess: number; - NotEqual: number; - NotTilde: number; - PartialD: number; - Precedes: number; - RightTee: number; - Succeeds: number; - SuchThat: number; - Superset: number; - Uarrocir: number; - UnderBar: number; - andslope: number; - angmsdaa: number; - angmsdab: number; - angmsdac: number; - angmsdad: number; - angmsdae: number; - angmsdaf: number; - angmsdag: number; - angmsdah: number; - angrtvbd: number; - approxeq: number; - awconint: number; - backcong: number; - barwedge: number; - bbrktbrk: number; - bigoplus: number; - bigsqcup: number; - biguplus: number; - bigwedge: number; - boxminus: number; - boxtimes: number; - capbrcup: number; - circledR: number; - circledS: number; - cirfnint: number; - clubsuit: number; - cupbrcap: number; - curlyvee: number; - cwconint: number; - doteqdot: number; - dotminus: number; - drbkarow: number; - dzigrarr: number; - elinters: number; - emptyset: number; - eqvparsl: number; - fpartint: number; - geqslant: number; - gesdotol: number; - gnapprox: number; - hksearow: number; - hkswarow: number; - imagline: number; - imagpart: number; - infintie: number; - integers: number; - intercal: number; - intlarhk: number; - laemptyv: number; - ldrushar: number; - leqslant: number; - lesdotor: number; - llcorner: number; - lnapprox: number; - lrcorner: number; - lurdshar: number; - mapstoup: number; - multimap: number; - naturals: number; - otimesas: number; - parallel: number; - plusacir: number; - pointint: number; - precneqq: number; - precnsim: number; - profalar: number; - profline: number; - profsurf: number; - raemptyv: number; - realpart: number; - rppolint: number; - rtriltri: number; - scpolint: number; - setminus: number; - shortmid: number; - smeparsl: number; - sqsubset: number; - sqsupset: number; - subseteq: number; - succneqq: number; - succnsim: number; - supseteq: number; - thetasym: number; - thicksim: number; - timesbar: number; - triangle: number; - triminus: number; - trpezium: number; - ulcorner: number; - urcorner: number; - varkappa: number; - varsigma: number; - vartheta: number; - Because: number; - Cayleys: number; - Cconint: number; - Cedilla: number; - Diamond: number; - DownTee: number; - Element: number; - Epsilon: number; - Implies: number; - LeftTee: number; - NewLine: number; - NoBreak: number; - NotLess: number; - Omicron: number; - OverBar: number; - Product: number; - UpArrow: number; - Uparrow: number; - Upsilon: number; - alefsym: number; - angrtvb: number; - angzarr: number; - asympeq: number; - backsim: number; - because: number; - bemptyv: number; - between: number; - bigcirc: number; - bigodot: number; - bigstar: number; - boxplus: number; - ccupssm: number; - cemptyv: number; - cirscir: number; - coloneq: number; - congdot: number; - cudarrl: number; - cudarrr: number; - cularrp: number; - curarrm: number; - dbkarow: number; - ddagger: number; - ddotseq: number; - demptyv: number; - diamond: number; - digamma: number; - dotplus: number; - dwangle: number; - epsilon: number; - eqcolon: number; - equivDD: number; - gesdoto: number; - gtquest: number; - gtrless: number; - harrcir: number; - intprod: number; - isindot: number; - larrbfs: number; - larrsim: number; - lbrksld: number; - lbrkslu: number; - ldrdhar: number; - lesdoto: number; - lessdot: number; - lessgtr: number; - lesssim: number; - lotimes: number; - lozenge: number; - ltquest: number; - luruhar: number; - maltese: number; - minusdu: number; - napprox: number; - natural: number; - nearrow: number; - nexists: number; - notinva: number; - notinvb: number; - notinvc: number; - notniva: number; - notnivb: number; - notnivc: number; - npolint: number; - nsqsube: number; - nsqsupe: number; - nvinfin: number; - nwarrow: number; - olcross: number; - omicron: number; - orderof: number; - orslope: number; - pertenk: number; - planckh: number; - pluscir: number; - plussim: number; - plustwo: number; - precsim: number; - quatint: number; - questeq: number; - rarrbfs: number; - rarrsim: number; - rbrksld: number; - rbrkslu: number; - rdldhar: number; - realine: number; - rotimes: number; - ruluhar: number; - searrow: number; - simplus: number; - simrarr: number; - subedot: number; - submult: number; - subplus: number; - subrarr: number; - succsim: number; - supdsub: number; - supedot: number; - suphsub: number; - suplarr: number; - supmult: number; - supplus: number; - swarrow: number; - topfork: number; - triplus: number; - tritime: number; - uparrow: number; - upsilon: number; - uwangle: number; - vzigzag: number; - zigrarr: number; - Aacute: number; - Abreve: number; - Agrave: number; - Assign: number; - Atilde: number; - Barwed: number; - Bumpeq: number; - Cacute: number; - Ccaron: number; - Ccedil: number; - Colone: number; - Conint: number; - CupCap: number; - Dagger: number; - Dcaron: number; - DotDot: number; - Dstrok: number; - Eacute: number; - Ecaron: number; - Egrave: number; - Exists: number; - ForAll: number; - Gammad: number; - Gbreve: number; - Gcedil: number; - HARDcy: number; - Hstrok: number; - Iacute: number; - Igrave: number; - Itilde: number; - Jsercy: number; - Kcedil: number; - Lacute: number; - Lambda: number; - Lcaron: number; - Lcedil: number; - Lmidot: number; - Lstrok: number; - Nacute: number; - Ncaron: number; - Ncedil: number; - Ntilde: number; - Oacute: number; - Odblac: number; - Ograve: number; - Oslash: number; - Otilde: number; - Otimes: number; - Racute: number; - Rarrtl: number; - Rcaron: number; - Rcedil: number; - SHCHcy: number; - SOFTcy: number; - Sacute: number; - Scaron: number; - Scedil: number; - Square: number; - Subset: number; - Supset: number; - Tcaron: number; - Tcedil: number; - Tstrok: number; - Uacute: number; - Ubreve: number; - Udblac: number; - Ugrave: number; - Utilde: number; - Vdashl: number; - Verbar: number; - Vvdash: number; - Yacute: number; - Zacute: number; - Zcaron: number; - aacute: number; - abreve: number; - agrave: number; - andand: number; - angmsd: number; - angsph: number; - apacir: number; - approx: number; - atilde: number; - barvee: number; - barwed: number; - becaus: number; - bernou: number; - bigcap: number; - bigcup: number; - bigvee: number; - bkarow: number; - bottom: number; - bowtie: number; - boxbox: number; - bprime: number; - brvbar: number; - bullet: number; - bumpeq: number; - cacute: number; - capand: number; - capcap: number; - capcup: number; - capdot: number; - ccaron: number; - ccedil: number; - circeq: number; - cirmid: number; - colone: number; - commat: number; - compfn: number; - conint: number; - coprod: number; - copysr: number; - cularr: number; - cupcap: number; - cupcup: number; - cupdot: number; - curarr: number; - curren: number; - cylcty: number; - dagger: number; - daleth: number; - dcaron: number; - dfisht: number; - divide: number; - divonx: number; - dlcorn: number; - dlcrop: number; - dollar: number; - drcorn: number; - drcrop: number; - dstrok: number; - eacute: number; - easter: number; - ecaron: number; - ecolon: number; - egrave: number; - egsdot: number; - elsdot: number; - emptyv: number; - emsp13: number; - emsp14: number; - eparsl: number; - eqcirc: number; - equals: number; - equest: number; - female: number; - ffilig: number; - ffllig: number; - forall: number; - frac12: number; - frac13: number; - frac14: number; - frac15: number; - frac16: number; - frac18: number; - frac23: number; - frac25: number; - frac34: number; - frac35: number; - frac38: number; - frac45: number; - frac56: number; - frac58: number; - frac78: number; - gacute: number; - gammad: number; - gbreve: number; - gesdot: number; - gesles: number; - gtlPar: number; - gtrarr: number; - gtrdot: number; - gtrsim: number; - hairsp: number; - hamilt: number; - hardcy: number; - hearts: number; - hellip: number; - hercon: number; - homtht: number; - horbar: number; - hslash: number; - hstrok: number; - hybull: number; - hyphen: number; - iacute: number; - igrave: number; - iiiint: number; - iinfin: number; - incare: number; - inodot: number; - intcal: number; - iquest: number; - isinsv: number; - itilde: number; - jsercy: number; - kappav: number; - kcedil: number; - kgreen: number; - lAtail: number; - lacute: number; - lagran: number; - lambda: number; - langle: number; - larrfs: number; - larrhk: number; - larrlp: number; - larrpl: number; - larrtl: number; - latail: number; - lbrace: number; - lbrack: number; - lcaron: number; - lcedil: number; - ldquor: number; - lesdot: number; - lesges: number; - lfisht: number; - lfloor: number; - lharul: number; - llhard: number; - lmidot: number; - lmoust: number; - loplus: number; - lowast: number; - lowbar: number; - lparlt: number; - lrhard: number; - lsaquo: number; - lsquor: number; - lstrok: number; - lthree: number; - ltimes: number; - ltlarr: number; - ltrPar: number; - mapsto: number; - marker: number; - mcomma: number; - midast: number; - midcir: number; - middot: number; - minusb: number; - minusd: number; - mnplus: number; - models: number; - mstpos: number; - nVDash: number; - nVdash: number; - nacute: number; - ncaron: number; - ncedil: number; - nearhk: number; - nequiv: number; - nesear: number; - nexist: number; - nltrie: number; - nprcue: number; - nrtrie: number; - nsccue: number; - nsimeq: number; - ntilde: number; - numero: number; - nvDash: number; - nvHarr: number; - nvdash: number; - nvlArr: number; - nvrArr: number; - nwarhk: number; - nwnear: number; - oacute: number; - odblac: number; - odsold: number; - ograve: number; - ominus: number; - origof: number; - oslash: number; - otilde: number; - otimes: number; - parsim: number; - percnt: number; - period: number; - permil: number; - phmmat: number; - planck: number; - plankv: number; - plusdo: number; - plusdu: number; - plusmn: number; - preceq: number; - primes: number; - prnsim: number; - propto: number; - prurel: number; - puncsp: number; - qprime: number; - rAtail: number; - racute: number; - rangle: number; - rarrap: number; - rarrfs: number; - rarrhk: number; - rarrlp: number; - rarrpl: number; - rarrtl: number; - ratail: number; - rbrace: number; - rbrack: number; - rcaron: number; - rcedil: number; - rdquor: number; - rfisht: number; - rfloor: number; - rharul: number; - rmoust: number; - roplus: number; - rpargt: number; - rsaquo: number; - rsquor: number; - rthree: number; - rtimes: number; - sacute: number; - scaron: number; - scedil: number; - scnsim: number; - searhk: number; - seswar: number; - sfrown: number; - shchcy: number; - sigmaf: number; - sigmav: number; - simdot: number; - smashp: number; - softcy: number; - solbar: number; - spades: number; - sqsube: number; - sqsupe: number; - square: number; - squarf: number; - ssetmn: number; - ssmile: number; - sstarf: number; - subdot: number; - subset: number; - subsim: number; - subsub: number; - subsup: number; - succeq: number; - supdot: number; - supset: number; - supsim: number; - supsub: number; - supsup: number; - swarhk: number; - swnwar: number; - target: number; - tcaron: number; - tcedil: number; - telrec: number; - there4: number; - thetav: number; - thinsp: number; - thksim: number; - timesb: number; - timesd: number; - topbot: number; - topcir: number; - tprime: number; - tridot: number; - tstrok: number; - uacute: number; - ubreve: number; - udblac: number; - ufisht: number; - ugrave: number; - ulcorn: number; - ulcrop: number; - urcorn: number; - urcrop: number; - utilde: number; - vangrt: number; - varphi: number; - varrho: number; - veebar: number; - vellip: number; - verbar: number; - wedbar: number; - wedgeq: number; - weierp: number; - wreath: number; - xoplus: number; - xotime: number; - xsqcup: number; - xuplus: number; - xwedge: number; - yacute: number; - zacute: number; - zcaron: number; - zeetrf: number; - AElig: number; - Acirc: number; - Alpha: number; - Amacr: number; - Aogon: number; - Aring: number; - Breve: number; - Ccirc: number; - Colon: number; - Cross: number; - Dashv: number; - Delta: number; - Ecirc: number; - Emacr: number; - Eogon: number; - Equal: number; - Gamma: number; - Gcirc: number; - Hacek: number; - Hcirc: number; - IJlig: number; - Icirc: number; - Imacr: number; - Iogon: number; - Iukcy: number; - Jcirc: number; - Jukcy: number; - Kappa: number; - OElig: number; - Ocirc: number; - Omacr: number; - Omega: number; - Prime: number; - RBarr: number; - Scirc: number; - Sigma: number; - THORN: number; - TRADE: number; - TSHcy: number; - Theta: number; - Tilde: number; - Ubrcy: number; - Ucirc: number; - Umacr: number; - Union: number; - Uogon: number; - UpTee: number; - Uring: number; - VDash: number; - Vdash: number; - Wcirc: number; - Wedge: number; - Ycirc: number; - acirc: number; - acute: number; - aelig: number; - aleph: number; - alpha: number; - amacr: number; - amalg: number; - angle: number; - angrt: number; - angst: number; - aogon: number; - aring: number; - asymp: number; - awint: number; - bcong: number; - bdquo: number; - bepsi: number; - blank: number; - blk12: number; - blk14: number; - blk34: number; - block: number; - boxDL: number; - boxDR: number; - boxDl: number; - boxDr: number; - boxHD: number; - boxHU: number; - boxHd: number; - boxHu: number; - boxUL: number; - boxUR: number; - boxUl: number; - boxUr: number; - boxVH: number; - boxVL: number; - boxVR: number; - boxVh: number; - boxVl: number; - boxVr: number; - boxdL: number; - boxdR: number; - boxdl: number; - boxdr: number; - boxhD: number; - boxhU: number; - boxhd: number; - boxhu: number; - boxuL: number; - boxuR: number; - boxul: number; - boxur: number; - boxvH: number; - boxvL: number; - boxvR: number; - boxvh: number; - boxvl: number; - boxvr: number; - breve: number; - bsemi: number; - bsime: number; - bsolb: number; - bumpE: number; - bumpe: number; - caret: number; - caron: number; - ccaps: number; - ccirc: number; - ccups: number; - cedil: number; - check: number; - clubs: number; - colon: number; - comma: number; - crarr: number; - cross: number; - csube: number; - csupe: number; - ctdot: number; - cuepr: number; - cuesc: number; - cupor: number; - cuvee: number; - cuwed: number; - cwint: number; - dashv: number; - dblac: number; - ddarr: number; - delta: number; - dharl: number; - dharr: number; - diams: number; - disin: number; - doteq: number; - dtdot: number; - dtrif: number; - duarr: number; - duhar: number; - eDDot: number; - ecirc: number; - efDot: number; - emacr: number; - empty: number; - eogon: number; - eplus: number; - epsiv: number; - eqsim: number; - equiv: number; - erDot: number; - erarr: number; - esdot: number; - exist: number; - fflig: number; - filig: number; - fllig: number; - fltns: number; - forkv: number; - frasl: number; - frown: number; - gamma: number; - gcirc: number; - gescc: number; - gimel: number; - gneqq: number; - gnsim: number; - grave: number; - gsime: number; - gsiml: number; - gtcir: number; - gtdot: number; - harrw: number; - hcirc: number; - hoarr: number; - icirc: number; - iexcl: number; - iiint: number; - iiota: number; - ijlig: number; - imacr: number; - image: number; - imath: number; - imped: number; - infin: number; - iogon: number; - iprod: number; - isinE: number; - isins: number; - isinv: number; - iukcy: number; - jcirc: number; - jmath: number; - jukcy: number; - kappa: number; - lAarr: number; - lBarr: number; - langd: number; - laquo: number; - larrb: number; - lbarr: number; - lbbrk: number; - lbrke: number; - lceil: number; - ldquo: number; - lescc: number; - lhard: number; - lharu: number; - lhblk: number; - llarr: number; - lltri: number; - lneqq: number; - lnsim: number; - loang: number; - loarr: number; - lobrk: number; - lopar: number; - lrarr: number; - lrhar: number; - lrtri: number; - lsime: number; - lsimg: number; - lsquo: number; - ltcir: number; - ltdot: number; - ltrie: number; - ltrif: number; - mDDot: number; - mdash: number; - micro: number; - minus: number; - mumap: number; - nabla: number; - napos: number; - natur: number; - ncong: number; - ndash: number; - neArr: number; - nearr: number; - ngsim: number; - nhArr: number; - nharr: number; - nhpar: number; - nlArr: number; - nlarr: number; - nless: number; - nlsim: number; - nltri: number; - notin: number; - notni: number; - nprec: number; - nrArr: number; - nrarr: number; - nrtri: number; - nsime: number; - nsmid: number; - nspar: number; - nsube: number; - nsucc: number; - nsupe: number; - numsp: number; - nwArr: number; - nwarr: number; - ocirc: number; - odash: number; - oelig: number; - ofcir: number; - ohbar: number; - olarr: number; - olcir: number; - oline: number; - omacr: number; - omega: number; - operp: number; - oplus: number; - orarr: number; - order: number; - ovbar: number; - parsl: number; - phone: number; - plusb: number; - pluse: number; - pound: number; - prcue: number; - prime: number; - prnap: number; - prsim: number; - quest: number; - rAarr: number; - rBarr: number; - radic: number; - rangd: number; - range: number; - raquo: number; - rarrb: number; - rarrc: number; - rarrw: number; - ratio: number; - rbarr: number; - rbbrk: number; - rbrke: number; - rceil: number; - rdquo: number; - reals: number; - rhard: number; - rharu: number; - rlarr: number; - rlhar: number; - rnmid: number; - roang: number; - roarr: number; - robrk: number; - ropar: number; - rrarr: number; - rsquo: number; - rtrie: number; - rtrif: number; - sbquo: number; - sccue: number; - scirc: number; - scnap: number; - scsim: number; - sdotb: number; - sdote: number; - seArr: number; - searr: number; - setmn: number; - sharp: number; - sigma: number; - simeq: number; - simgE: number; - simlE: number; - simne: number; - slarr: number; - smile: number; - sqcap: number; - sqcup: number; - sqsub: number; - sqsup: number; - srarr: number; - starf: number; - strns: number; - subnE: number; - subne: number; - supnE: number; - supne: number; - swArr: number; - swarr: number; - szlig: number; - theta: number; - thkap: number; - thorn: number; - tilde: number; - times: number; - trade: number; - trisb: number; - tshcy: number; - twixt: number; - ubrcy: number; - ucirc: number; - udarr: number; - udhar: number; - uharl: number; - uharr: number; - uhblk: number; - ultri: number; - umacr: number; - uogon: number; - uplus: number; - upsih: number; - uring: number; - urtri: number; - utdot: number; - utrif: number; - uuarr: number; - vBarv: number; - vDash: number; - varpi: number; - vdash: number; - veeeq: number; - vltri: number; - vprop: number; - vrtri: number; - wcirc: number; - wedge: number; - xcirc: number; - xdtri: number; - xhArr: number; - xharr: number; - xlArr: number; - xlarr: number; - xodot: number; - xrArr: number; - xrarr: number; - xutri: number; - ycirc: number; - Aopf: number; - Ascr: number; - Auml: number; - Barv: number; - Beta: number; - Bopf: number; - Bscr: number; - CHcy: number; - COPY: number; - Cdot: number; - Copf: number; - Cscr: number; - DJcy: number; - DScy: number; - DZcy: number; - Darr: number; - Dopf: number; - Dscr: number; - Edot: number; - Eopf: number; - Escr: number; - Esim: number; - Euml: number; - Fopf: number; - Fscr: number; - GJcy: number; - Gdot: number; - Gopf: number; - Gscr: number; - Hopf: number; - Hscr: number; - IEcy: number; - IOcy: number; - Idot: number; - Iopf: number; - Iota: number; - Iscr: number; - Iuml: number; - Jopf: number; - Jscr: number; - KHcy: number; - KJcy: number; - Kopf: number; - Kscr: number; - LJcy: number; - Lang: number; - Larr: number; - Lopf: number; - Lscr: number; - Mopf: number; - Mscr: number; - NJcy: number; - Nopf: number; - Nscr: number; - Oopf: number; - Oscr: number; - Ouml: number; - Popf: number; - Pscr: number; - QUOT: number; - Qopf: number; - Qscr: number; - Rang: number; - Rarr: number; - Ropf: number; - Rscr: number; - SHcy: number; - Sopf: number; - Sqrt: number; - Sscr: number; - Star: number; - TScy: number; - Topf: number; - Tscr: number; - Uarr: number; - Uopf: number; - Upsi: number; - Uscr: number; - Uuml: number; - Vbar: number; - Vert: number; - Vopf: number; - Vscr: number; - Wopf: number; - Wscr: number; - Xopf: number; - Xscr: number; - YAcy: number; - YIcy: number; - YUcy: number; - Yopf: number; - Yscr: number; - Yuml: number; - ZHcy: number; - Zdot: number; - Zeta: number; - Zopf: number; - Zscr: number; - andd: number; - andv: number; - ange: number; - aopf: number; - apid: number; - apos: number; - ascr: number; - auml: number; - bNot: number; - bbrk: number; - beta: number; - beth: number; - bnot: number; - bopf: number; - boxH: number; - boxV: number; - boxh: number; - boxv: number; - bscr: number; - bsim: number; - bsol: number; - bull: number; - bump: number; - cdot: number; - cent: number; - chcy: number; - cirE: number; - circ: number; - cire: number; - comp: number; - cong: number; - copf: number; - copy: number; - cscr: number; - csub: number; - csup: number; - dArr: number; - dHar: number; - darr: number; - dash: number; - diam: number; - djcy: number; - dopf: number; - dscr: number; - dscy: number; - dsol: number; - dtri: number; - dzcy: number; - eDot: number; - ecir: number; - edot: number; - emsp: number; - ensp: number; - eopf: number; - epar: number; - epsi: number; - escr: number; - esim: number; - euml: number; - euro: number; - excl: number; - flat: number; - fnof: number; - fopf: number; - fork: number; - fscr: number; - gdot: number; - geqq: number; - gjcy: number; - gnap: number; - gneq: number; - gopf: number; - gscr: number; - gsim: number; - gtcc: number; - hArr: number; - half: number; - harr: number; - hbar: number; - hopf: number; - hscr: number; - iecy: number; - imof: number; - iocy: number; - iopf: number; - iota: number; - iscr: number; - isin: number; - iuml: number; - jopf: number; - jscr: number; - khcy: number; - kjcy: number; - kopf: number; - kscr: number; - lArr: number; - lHar: number; - lang: number; - larr: number; - late: number; - lcub: number; - ldca: number; - ldsh: number; - leqq: number; - ljcy: number; - lnap: number; - lneq: number; - lopf: number; - lozf: number; - lpar: number; - lscr: number; - lsim: number; - lsqb: number; - ltcc: number; - ltri: number; - macr: number; - male: number; - malt: number; - mlcp: number; - mldr: number; - mopf: number; - mscr: number; - nbsp: number; - ncap: number; - ncup: number; - ngeq: number; - ngtr: number; - nisd: number; - njcy: number; - nldr: number; - nleq: number; - nmid: number; - nopf: number; - npar: number; - nscr: number; - nsim: number; - nsub: number; - nsup: number; - ntgl: number; - ntlg: number; - oast: number; - ocir: number; - odiv: number; - odot: number; - ogon: number; - oint: number; - omid: number; - oopf: number; - opar: number; - ordf: number; - ordm: number; - oror: number; - oscr: number; - osol: number; - ouml: number; - para: number; - part: number; - perp: number; - phiv: number; - plus: number; - popf: number; - prap: number; - prec: number; - prnE: number; - prod: number; - prop: number; - pscr: number; - qint: number; - qopf: number; - qscr: number; - quot: number; - rArr: number; - rHar: number; - race: number; - rang: number; - rarr: number; - rcub: number; - rdca: number; - rdsh: number; - real: number; - rect: number; - rhov: number; - ring: number; - ropf: number; - rpar: number; - rscr: number; - rsqb: number; - rtri: number; - scap: number; - scnE: number; - sdot: number; - sect: number; - semi: number; - sext: number; - shcy: number; - sime: number; - simg: number; - siml: number; - smid: number; - smte: number; - solb: number; - sopf: number; - spar: number; - squf: number; - sscr: number; - star: number; - subE: number; - sube: number; - succ: number; - sung: number; - sup1: number; - sup2: number; - sup3: number; - supE: number; - supe: number; - tbrk: number; - tdot: number; - tint: number; - toea: number; - topf: number; - tosa: number; - trie: number; - tscr: number; - tscy: number; - uArr: number; - uHar: number; - uarr: number; - uopf: number; - upsi: number; - uscr: number; - utri: number; - uuml: number; - vArr: number; - vBar: number; - varr: number; - vert: number; - vopf: number; - vscr: number; - wopf: number; - wscr: number; - xcap: number; - xcup: number; - xmap: number; - xnis: number; - xopf: number; - xscr: number; - xvee: number; - yacy: number; - yicy: number; - yopf: number; - yscr: number; - yucy: number; - yuml: number; - zdot: number; - zeta: number; - zhcy: number; - zopf: number; - zscr: number; - zwnj: number; - AMP: number; - Acy: number; - Afr: number; - And: number; - Bcy: number; - Bfr: number; - Cap: number; - Cfr: number; - Chi: number; - Cup: number; - Dcy: number; - Del: number; - Dfr: number; - Dot: number; - ENG: number; - ETH: number; - Ecy: number; - Efr: number; - Eta: number; - Fcy: number; - Ffr: number; - Gcy: number; - Gfr: number; - Hat: number; - Hfr: number; - Icy: number; - Ifr: number; - Int: number; - Jcy: number; - Jfr: number; - Kcy: number; - Kfr: number; - Lcy: number; - Lfr: number; - Lsh: number; - Map: number; - Mcy: number; - Mfr: number; - Ncy: number; - Nfr: number; - Not: number; - Ocy: number; - Ofr: number; - Pcy: number; - Pfr: number; - Phi: number; - Psi: number; - Qfr: number; - REG: number; - Rcy: number; - Rfr: number; - Rho: number; - Rsh: number; - Scy: number; - Sfr: number; - Sub: number; - Sum: number; - Sup: number; - Tab: number; - Tau: number; - Tcy: number; - Tfr: number; - Ucy: number; - Ufr: number; - Vcy: number; - Vee: number; - Vfr: number; - Wfr: number; - Xfr: number; - Ycy: number; - Yfr: number; - Zcy: number; - Zfr: number; - acd: number; - acy: number; - afr: number; - amp: number; - and: number; - ang: number; - apE: number; - ape: number; - ast: number; - bcy: number; - bfr: number; - bot: number; - cap: number; - cfr: number; - chi: number; - cir: number; - cup: number; - dcy: number; - deg: number; - dfr: number; - die: number; - div: number; - dot: number; - ecy: number; - efr: number; - egs: number; - ell: number; - els: number; - eng: number; - eta: number; - eth: number; - fcy: number; - ffr: number; - gEl: number; - gap: number; - gcy: number; - gel: number; - geq: number; - ges: number; - gfr: number; - ggg: number; - glE: number; - gla: number; - glj: number; - gnE: number; - gne: number; - hfr: number; - icy: number; - iff: number; - ifr: number; - int: number; - jcy: number; - jfr: number; - kcy: number; - kfr: number; - lEg: number; - lap: number; - lat: number; - lcy: number; - leg: number; - leq: number; - les: number; - lfr: number; - lgE: number; - lnE: number; - lne: number; - loz: number; - lrm: number; - lsh: number; - map: number; - mcy: number; - mfr: number; - mho: number; - mid: number; - nap: number; - ncy: number; - nfr: number; - nge: number; - ngt: number; - nis: number; - niv: number; - nle: number; - nlt: number; - not: number; - npr: number; - nsc: number; - num: number; - ocy: number; - ofr: number; - ogt: number; - ohm: number; - olt: number; - ord: number; - orv: number; - par: number; - pcy: number; - pfr: number; - phi: number; - piv: number; - prE: number; - pre: number; - psi: number; - qfr: number; - rcy: number; - reg: number; - rfr: number; - rho: number; - rlm: number; - rsh: number; - scE: number; - sce: number; - scy: number; - sfr: number; - shy: number; - sim: number; - smt: number; - sol: number; - squ: number; - sub: number; - sum: number; - sup: number; - tau: number; - tcy: number; - tfr: number; - top: number; - ucy: number; - ufr: number; - uml: number; - vcy: number; - vee: number; - vfr: number; - wfr: number; - xfr: number; - ycy: number; - yen: number; - yfr: number; - zcy: number; - zfr: number; - zwj: number; - DD: number; - GT: number; - Gg: number; - Gt: number; - Im: number; - LT: number; - Ll: number; - Lt: number; - Mu: number; - Nu: number; - Or: number; - Pi: number; - Pr: number; - Re: number; - Sc: number; - Xi: number; - ac: number; - af: number; - ap: number; - dd: number; - ee: number; - eg: number; - el: number; - gE: number; - ge: number; - gg: number; - gl: number; - gt: number; - ic: number; - ii: number; - in: number; - it: number; - lE: number; - le: number; - lg: number; - ll: number; - lt: number; - mp: number; - mu: number; - ne: number; - ni: number; - nu: number; - oS: number; - or: number; - pi: number; - pm: number; - pr: number; - rx: number; - sc: number; - wp: number; - wr: number; - xi: number; + CounterClockwiseContourIntegral: number; + ClockwiseContourIntegral: number; + DoubleLongLeftRightArrow: number; + DiacriticalDoubleAcute: number; + NotSquareSupersetEqual: number; + CloseCurlyDoubleQuote: number; + DoubleContourIntegral: number; + FilledVerySmallSquare: number; + NegativeVeryThinSpace: number; + NotPrecedesSlantEqual: number; + NotRightTriangleEqual: number; + NotSucceedsSlantEqual: number; + CapitalDifferentialD: number; + DoubleLeftRightArrow: number; + DoubleLongRightArrow: number; + EmptyVerySmallSquare: number; + NestedGreaterGreater: number; + NotDoubleVerticalBar: number; + NotLeftTriangleEqual: number; + NotSquareSubsetEqual: number; + OpenCurlyDoubleQuote: number; + ReverseUpEquilibrium: number; + DoubleLongLeftArrow: number; + DownLeftRightVector: number; + LeftArrowRightArrow: number; + NegativeMediumSpace: number; + RightArrowLeftArrow: number; + SquareSupersetEqual: number; + leftrightsquigarrow: number; + DownRightTeeVector: number; + DownRightVectorBar: number; + LongLeftRightArrow: number; + Longleftrightarrow: number; + NegativeThickSpace: number; + PrecedesSlantEqual: number; + ReverseEquilibrium: number; + RightDoubleBracket: number; + RightDownTeeVector: number; + RightDownVectorBar: number; + RightTriangleEqual: number; + SquareIntersection: number; + SucceedsSlantEqual: number; + blacktriangleright: number; + longleftrightarrow: number; + DoubleUpDownArrow: number; + DoubleVerticalBar: number; + DownLeftTeeVector: number; + DownLeftVectorBar: number; + FilledSmallSquare: number; + GreaterSlantEqual: number; + LeftDoubleBracket: number; + LeftDownTeeVector: number; + LeftDownVectorBar: number; + LeftTriangleEqual: number; + NegativeThinSpace: number; + NotReverseElement: number; + NotTildeFullEqual: number; + RightAngleBracket: number; + RightUpDownVector: number; + SquareSubsetEqual: number; + VerticalSeparator: number; + blacktriangledown: number; + blacktriangleleft: number; + leftrightharpoons: number; + rightleftharpoons: number; + twoheadrightarrow: number; + DiacriticalAcute: number; + DiacriticalGrave: number; + DiacriticalTilde: number; + DoubleRightArrow: number; + DownArrowUpArrow: number; + EmptySmallSquare: number; + GreaterEqualLess: number; + GreaterFullEqual: number; + LeftAngleBracket: number; + LeftUpDownVector: number; + LessEqualGreater: number; + NonBreakingSpace: number; + NotRightTriangle: number; + NotSupersetEqual: number; + RightTriangleBar: number; + RightUpTeeVector: number; + RightUpVectorBar: number; + UnderParenthesis: number; + UpArrowDownArrow: number; + circlearrowright: number; + downharpoonright: number; + ntrianglerighteq: number; + rightharpoondown: number; + rightrightarrows: number; + twoheadleftarrow: number; + vartriangleright: number; + CloseCurlyQuote: number; + ContourIntegral: number; + DoubleDownArrow: number; + DoubleLeftArrow: number; + DownRightVector: number; + LeftRightVector: number; + LeftTriangleBar: number; + LeftUpTeeVector: number; + LeftUpVectorBar: number; + LowerRightArrow: number; + NotGreaterEqual: number; + NotGreaterTilde: number; + NotLeftTriangle: number; + OverParenthesis: number; + RightDownVector: number; + ShortRightArrow: number; + UpperRightArrow: number; + bigtriangledown: number; + circlearrowleft: number; + curvearrowright: number; + downharpoonleft: number; + leftharpoondown: number; + leftrightarrows: number; + nLeftrightarrow: number; + nleftrightarrow: number; + ntrianglelefteq: number; + rightleftarrows: number; + rightsquigarrow: number; + rightthreetimes: number; + straightepsilon: number; + trianglerighteq: number; + vartriangleleft: number; + DiacriticalDot: number; + DoubleRightTee: number; + DownLeftVector: number; + GreaterGreater: number; + HorizontalLine: number; + InvisibleComma: number; + InvisibleTimes: number; + LeftDownVector: number; + LeftRightArrow: number; + Leftrightarrow: number; + LessSlantEqual: number; + LongRightArrow: number; + Longrightarrow: number; + LowerLeftArrow: number; + NestedLessLess: number; + NotGreaterLess: number; + NotLessGreater: number; + NotSubsetEqual: number; + NotVerticalBar: number; + OpenCurlyQuote: number; + ReverseElement: number; + RightTeeVector: number; + RightVectorBar: number; + ShortDownArrow: number; + ShortLeftArrow: number; + SquareSuperset: number; + TildeFullEqual: number; + UpperLeftArrow: number; + ZeroWidthSpace: number; + curvearrowleft: number; + doublebarwedge: number; + downdownarrows: number; + hookrightarrow: number; + leftleftarrows: number; + leftrightarrow: number; + leftthreetimes: number; + longrightarrow: number; + looparrowright: number; + nshortparallel: number; + ntriangleright: number; + rightarrowtail: number; + rightharpoonup: number; + trianglelefteq: number; + upharpoonright: number; + ApplyFunction: number; + DifferentialD: number; + DoubleLeftTee: number; + DoubleUpArrow: number; + LeftTeeVector: number; + LeftVectorBar: number; + LessFullEqual: number; + LongLeftArrow: number; + Longleftarrow: number; + NotTildeEqual: number; + NotTildeTilde: number; + Poincareplane: number; + PrecedesEqual: number; + PrecedesTilde: number; + RightArrowBar: number; + RightTeeArrow: number; + RightTriangle: number; + RightUpVector: number; + SucceedsEqual: number; + SucceedsTilde: number; + SupersetEqual: number; + UpEquilibrium: number; + VerticalTilde: number; + VeryThinSpace: number; + bigtriangleup: number; + blacktriangle: number; + divideontimes: number; + fallingdotseq: number; + hookleftarrow: number; + leftarrowtail: number; + leftharpoonup: number; + longleftarrow: number; + looparrowleft: number; + measuredangle: number; + ntriangleleft: number; + shortparallel: number; + smallsetminus: number; + triangleright: number; + upharpoonleft: number; + DownArrowBar: number; + DownTeeArrow: number; + ExponentialE: number; + GreaterEqual: number; + GreaterTilde: number; + HilbertSpace: number; + HumpDownHump: number; + Intersection: number; + LeftArrowBar: number; + LeftTeeArrow: number; + LeftTriangle: number; + LeftUpVector: number; + NotCongruent: number; + NotLessEqual: number; + NotLessTilde: number; + Proportional: number; + RightCeiling: number; + RoundImplies: number; + ShortUpArrow: number; + SquareSubset: number; + UnderBracket: number; + VerticalLine: number; + blacklozenge: number; + exponentiale: number; + risingdotseq: number; + triangledown: number; + triangleleft: number; + CircleMinus: number; + CircleTimes: number; + Equilibrium: number; + GreaterLess: number; + LeftCeiling: number; + LessGreater: number; + MediumSpace: number; + NotPrecedes: number; + NotSucceeds: number; + OverBracket: number; + RightVector: number; + Rrightarrow: number; + RuleDelayed: number; + SmallCircle: number; + SquareUnion: number; + SubsetEqual: number; + UpDownArrow: number; + Updownarrow: number; + VerticalBar: number; + backepsilon: number; + blacksquare: number; + circledcirc: number; + circleddash: number; + curlyeqprec: number; + curlyeqsucc: number; + diamondsuit: number; + eqslantless: number; + expectation: number; + nRightarrow: number; + nrightarrow: number; + preccurlyeq: number; + precnapprox: number; + quaternions: number; + straightphi: number; + succcurlyeq: number; + succnapprox: number; + thickapprox: number; + updownarrow: number; + Bernoullis: number; + CirclePlus: number; + EqualTilde: number; + Fouriertrf: number; + ImaginaryI: number; + Laplacetrf: number; + LeftVector: number; + Lleftarrow: number; + NotElement: number; + NotGreater: number; + Proportion: number; + RightArrow: number; + RightFloor: number; + Rightarrow: number; + TildeEqual: number; + TildeTilde: number; + UnderBrace: number; + UpArrowBar: number; + UpTeeArrow: number; + circledast: number; + complement: number; + curlywedge: number; + eqslantgtr: number; + gtreqqless: number; + lessapprox: number; + lesseqqgtr: number; + lmoustache: number; + longmapsto: number; + mapstodown: number; + mapstoleft: number; + nLeftarrow: number; + nleftarrow: number; + precapprox: number; + rightarrow: number; + rmoustache: number; + sqsubseteq: number; + sqsupseteq: number; + subsetneqq: number; + succapprox: number; + supsetneqq: number; + upuparrows: number; + varepsilon: number; + varnothing: number; + Backslash: number; + CenterDot: number; + CircleDot: number; + Congruent: number; + Coproduct: number; + DoubleDot: number; + DownArrow: number; + DownBreve: number; + Downarrow: number; + HumpEqual: number; + LeftArrow: number; + LeftFloor: number; + Leftarrow: number; + LessTilde: number; + Mellintrf: number; + MinusPlus: number; + NotCupCap: number; + NotExists: number; + OverBrace: number; + PlusMinus: number; + Therefore: number; + ThinSpace: number; + TripleDot: number; + UnionPlus: number; + backprime: number; + backsimeq: number; + bigotimes: number; + centerdot: number; + checkmark: number; + complexes: number; + dotsquare: number; + downarrow: number; + gtrapprox: number; + gtreqless: number; + heartsuit: number; + leftarrow: number; + lesseqgtr: number; + nparallel: number; + nshortmid: number; + nsubseteq: number; + nsupseteq: number; + pitchfork: number; + rationals: number; + spadesuit: number; + subseteqq: number; + subsetneq: number; + supseteqq: number; + supsetneq: number; + therefore: number; + triangleq: number; + varpropto: number; + DDotrahd: number; + DotEqual: number; + Integral: number; + LessLess: number; + NotEqual: number; + NotTilde: number; + PartialD: number; + Precedes: number; + RightTee: number; + Succeeds: number; + SuchThat: number; + Superset: number; + Uarrocir: number; + UnderBar: number; + andslope: number; + angmsdaa: number; + angmsdab: number; + angmsdac: number; + angmsdad: number; + angmsdae: number; + angmsdaf: number; + angmsdag: number; + angmsdah: number; + angrtvbd: number; + approxeq: number; + awconint: number; + backcong: number; + barwedge: number; + bbrktbrk: number; + bigoplus: number; + bigsqcup: number; + biguplus: number; + bigwedge: number; + boxminus: number; + boxtimes: number; + capbrcup: number; + circledR: number; + circledS: number; + cirfnint: number; + clubsuit: number; + cupbrcap: number; + curlyvee: number; + cwconint: number; + doteqdot: number; + dotminus: number; + drbkarow: number; + dzigrarr: number; + elinters: number; + emptyset: number; + eqvparsl: number; + fpartint: number; + geqslant: number; + gesdotol: number; + gnapprox: number; + hksearow: number; + hkswarow: number; + imagline: number; + imagpart: number; + infintie: number; + integers: number; + intercal: number; + intlarhk: number; + laemptyv: number; + ldrushar: number; + leqslant: number; + lesdotor: number; + llcorner: number; + lnapprox: number; + lrcorner: number; + lurdshar: number; + mapstoup: number; + multimap: number; + naturals: number; + otimesas: number; + parallel: number; + plusacir: number; + pointint: number; + precneqq: number; + precnsim: number; + profalar: number; + profline: number; + profsurf: number; + raemptyv: number; + realpart: number; + rppolint: number; + rtriltri: number; + scpolint: number; + setminus: number; + shortmid: number; + smeparsl: number; + sqsubset: number; + sqsupset: number; + subseteq: number; + succneqq: number; + succnsim: number; + supseteq: number; + thetasym: number; + thicksim: number; + timesbar: number; + triangle: number; + triminus: number; + trpezium: number; + ulcorner: number; + urcorner: number; + varkappa: number; + varsigma: number; + vartheta: number; + Because: number; + Cayleys: number; + Cconint: number; + Cedilla: number; + Diamond: number; + DownTee: number; + Element: number; + Epsilon: number; + Implies: number; + LeftTee: number; + NewLine: number; + NoBreak: number; + NotLess: number; + Omicron: number; + OverBar: number; + Product: number; + UpArrow: number; + Uparrow: number; + Upsilon: number; + alefsym: number; + angrtvb: number; + angzarr: number; + asympeq: number; + backsim: number; + because: number; + bemptyv: number; + between: number; + bigcirc: number; + bigodot: number; + bigstar: number; + boxplus: number; + ccupssm: number; + cemptyv: number; + cirscir: number; + coloneq: number; + congdot: number; + cudarrl: number; + cudarrr: number; + cularrp: number; + curarrm: number; + dbkarow: number; + ddagger: number; + ddotseq: number; + demptyv: number; + diamond: number; + digamma: number; + dotplus: number; + dwangle: number; + epsilon: number; + eqcolon: number; + equivDD: number; + gesdoto: number; + gtquest: number; + gtrless: number; + harrcir: number; + intprod: number; + isindot: number; + larrbfs: number; + larrsim: number; + lbrksld: number; + lbrkslu: number; + ldrdhar: number; + lesdoto: number; + lessdot: number; + lessgtr: number; + lesssim: number; + lotimes: number; + lozenge: number; + ltquest: number; + luruhar: number; + maltese: number; + minusdu: number; + napprox: number; + natural: number; + nearrow: number; + nexists: number; + notinva: number; + notinvb: number; + notinvc: number; + notniva: number; + notnivb: number; + notnivc: number; + npolint: number; + nsqsube: number; + nsqsupe: number; + nvinfin: number; + nwarrow: number; + olcross: number; + omicron: number; + orderof: number; + orslope: number; + pertenk: number; + planckh: number; + pluscir: number; + plussim: number; + plustwo: number; + precsim: number; + quatint: number; + questeq: number; + rarrbfs: number; + rarrsim: number; + rbrksld: number; + rbrkslu: number; + rdldhar: number; + realine: number; + rotimes: number; + ruluhar: number; + searrow: number; + simplus: number; + simrarr: number; + subedot: number; + submult: number; + subplus: number; + subrarr: number; + succsim: number; + supdsub: number; + supedot: number; + suphsub: number; + suplarr: number; + supmult: number; + supplus: number; + swarrow: number; + topfork: number; + triplus: number; + tritime: number; + uparrow: number; + upsilon: number; + uwangle: number; + vzigzag: number; + zigrarr: number; + Aacute: number; + Abreve: number; + Agrave: number; + Assign: number; + Atilde: number; + Barwed: number; + Bumpeq: number; + Cacute: number; + Ccaron: number; + Ccedil: number; + Colone: number; + Conint: number; + CupCap: number; + Dagger: number; + Dcaron: number; + DotDot: number; + Dstrok: number; + Eacute: number; + Ecaron: number; + Egrave: number; + Exists: number; + ForAll: number; + Gammad: number; + Gbreve: number; + Gcedil: number; + HARDcy: number; + Hstrok: number; + Iacute: number; + Igrave: number; + Itilde: number; + Jsercy: number; + Kcedil: number; + Lacute: number; + Lambda: number; + Lcaron: number; + Lcedil: number; + Lmidot: number; + Lstrok: number; + Nacute: number; + Ncaron: number; + Ncedil: number; + Ntilde: number; + Oacute: number; + Odblac: number; + Ograve: number; + Oslash: number; + Otilde: number; + Otimes: number; + Racute: number; + Rarrtl: number; + Rcaron: number; + Rcedil: number; + SHCHcy: number; + SOFTcy: number; + Sacute: number; + Scaron: number; + Scedil: number; + Square: number; + Subset: number; + Supset: number; + Tcaron: number; + Tcedil: number; + Tstrok: number; + Uacute: number; + Ubreve: number; + Udblac: number; + Ugrave: number; + Utilde: number; + Vdashl: number; + Verbar: number; + Vvdash: number; + Yacute: number; + Zacute: number; + Zcaron: number; + aacute: number; + abreve: number; + agrave: number; + andand: number; + angmsd: number; + angsph: number; + apacir: number; + approx: number; + atilde: number; + barvee: number; + barwed: number; + becaus: number; + bernou: number; + bigcap: number; + bigcup: number; + bigvee: number; + bkarow: number; + bottom: number; + bowtie: number; + boxbox: number; + bprime: number; + brvbar: number; + bullet: number; + bumpeq: number; + cacute: number; + capand: number; + capcap: number; + capcup: number; + capdot: number; + ccaron: number; + ccedil: number; + circeq: number; + cirmid: number; + colone: number; + commat: number; + compfn: number; + conint: number; + coprod: number; + copysr: number; + cularr: number; + cupcap: number; + cupcup: number; + cupdot: number; + curarr: number; + curren: number; + cylcty: number; + dagger: number; + daleth: number; + dcaron: number; + dfisht: number; + divide: number; + divonx: number; + dlcorn: number; + dlcrop: number; + dollar: number; + drcorn: number; + drcrop: number; + dstrok: number; + eacute: number; + easter: number; + ecaron: number; + ecolon: number; + egrave: number; + egsdot: number; + elsdot: number; + emptyv: number; + emsp13: number; + emsp14: number; + eparsl: number; + eqcirc: number; + equals: number; + equest: number; + female: number; + ffilig: number; + ffllig: number; + forall: number; + frac12: number; + frac13: number; + frac14: number; + frac15: number; + frac16: number; + frac18: number; + frac23: number; + frac25: number; + frac34: number; + frac35: number; + frac38: number; + frac45: number; + frac56: number; + frac58: number; + frac78: number; + gacute: number; + gammad: number; + gbreve: number; + gesdot: number; + gesles: number; + gtlPar: number; + gtrarr: number; + gtrdot: number; + gtrsim: number; + hairsp: number; + hamilt: number; + hardcy: number; + hearts: number; + hellip: number; + hercon: number; + homtht: number; + horbar: number; + hslash: number; + hstrok: number; + hybull: number; + hyphen: number; + iacute: number; + igrave: number; + iiiint: number; + iinfin: number; + incare: number; + inodot: number; + intcal: number; + iquest: number; + isinsv: number; + itilde: number; + jsercy: number; + kappav: number; + kcedil: number; + kgreen: number; + lAtail: number; + lacute: number; + lagran: number; + lambda: number; + langle: number; + larrfs: number; + larrhk: number; + larrlp: number; + larrpl: number; + larrtl: number; + latail: number; + lbrace: number; + lbrack: number; + lcaron: number; + lcedil: number; + ldquor: number; + lesdot: number; + lesges: number; + lfisht: number; + lfloor: number; + lharul: number; + llhard: number; + lmidot: number; + lmoust: number; + loplus: number; + lowast: number; + lowbar: number; + lparlt: number; + lrhard: number; + lsaquo: number; + lsquor: number; + lstrok: number; + lthree: number; + ltimes: number; + ltlarr: number; + ltrPar: number; + mapsto: number; + marker: number; + mcomma: number; + midast: number; + midcir: number; + middot: number; + minusb: number; + minusd: number; + mnplus: number; + models: number; + mstpos: number; + nVDash: number; + nVdash: number; + nacute: number; + ncaron: number; + ncedil: number; + nearhk: number; + nequiv: number; + nesear: number; + nexist: number; + nltrie: number; + nprcue: number; + nrtrie: number; + nsccue: number; + nsimeq: number; + ntilde: number; + numero: number; + nvDash: number; + nvHarr: number; + nvdash: number; + nvlArr: number; + nvrArr: number; + nwarhk: number; + nwnear: number; + oacute: number; + odblac: number; + odsold: number; + ograve: number; + ominus: number; + origof: number; + oslash: number; + otilde: number; + otimes: number; + parsim: number; + percnt: number; + period: number; + permil: number; + phmmat: number; + planck: number; + plankv: number; + plusdo: number; + plusdu: number; + plusmn: number; + preceq: number; + primes: number; + prnsim: number; + propto: number; + prurel: number; + puncsp: number; + qprime: number; + rAtail: number; + racute: number; + rangle: number; + rarrap: number; + rarrfs: number; + rarrhk: number; + rarrlp: number; + rarrpl: number; + rarrtl: number; + ratail: number; + rbrace: number; + rbrack: number; + rcaron: number; + rcedil: number; + rdquor: number; + rfisht: number; + rfloor: number; + rharul: number; + rmoust: number; + roplus: number; + rpargt: number; + rsaquo: number; + rsquor: number; + rthree: number; + rtimes: number; + sacute: number; + scaron: number; + scedil: number; + scnsim: number; + searhk: number; + seswar: number; + sfrown: number; + shchcy: number; + sigmaf: number; + sigmav: number; + simdot: number; + smashp: number; + softcy: number; + solbar: number; + spades: number; + sqsube: number; + sqsupe: number; + square: number; + squarf: number; + ssetmn: number; + ssmile: number; + sstarf: number; + subdot: number; + subset: number; + subsim: number; + subsub: number; + subsup: number; + succeq: number; + supdot: number; + supset: number; + supsim: number; + supsub: number; + supsup: number; + swarhk: number; + swnwar: number; + target: number; + tcaron: number; + tcedil: number; + telrec: number; + there4: number; + thetav: number; + thinsp: number; + thksim: number; + timesb: number; + timesd: number; + topbot: number; + topcir: number; + tprime: number; + tridot: number; + tstrok: number; + uacute: number; + ubreve: number; + udblac: number; + ufisht: number; + ugrave: number; + ulcorn: number; + ulcrop: number; + urcorn: number; + urcrop: number; + utilde: number; + vangrt: number; + varphi: number; + varrho: number; + veebar: number; + vellip: number; + verbar: number; + wedbar: number; + wedgeq: number; + weierp: number; + wreath: number; + xoplus: number; + xotime: number; + xsqcup: number; + xuplus: number; + xwedge: number; + yacute: number; + zacute: number; + zcaron: number; + zeetrf: number; + AElig: number; + Acirc: number; + Alpha: number; + Amacr: number; + Aogon: number; + Aring: number; + Breve: number; + Ccirc: number; + Colon: number; + Cross: number; + Dashv: number; + Delta: number; + Ecirc: number; + Emacr: number; + Eogon: number; + Equal: number; + Gamma: number; + Gcirc: number; + Hacek: number; + Hcirc: number; + IJlig: number; + Icirc: number; + Imacr: number; + Iogon: number; + Iukcy: number; + Jcirc: number; + Jukcy: number; + Kappa: number; + OElig: number; + Ocirc: number; + Omacr: number; + Omega: number; + Prime: number; + RBarr: number; + Scirc: number; + Sigma: number; + THORN: number; + TRADE: number; + TSHcy: number; + Theta: number; + Tilde: number; + Ubrcy: number; + Ucirc: number; + Umacr: number; + Union: number; + Uogon: number; + UpTee: number; + Uring: number; + VDash: number; + Vdash: number; + Wcirc: number; + Wedge: number; + Ycirc: number; + acirc: number; + acute: number; + aelig: number; + aleph: number; + alpha: number; + amacr: number; + amalg: number; + angle: number; + angrt: number; + angst: number; + aogon: number; + aring: number; + asymp: number; + awint: number; + bcong: number; + bdquo: number; + bepsi: number; + blank: number; + blk12: number; + blk14: number; + blk34: number; + block: number; + boxDL: number; + boxDR: number; + boxDl: number; + boxDr: number; + boxHD: number; + boxHU: number; + boxHd: number; + boxHu: number; + boxUL: number; + boxUR: number; + boxUl: number; + boxUr: number; + boxVH: number; + boxVL: number; + boxVR: number; + boxVh: number; + boxVl: number; + boxVr: number; + boxdL: number; + boxdR: number; + boxdl: number; + boxdr: number; + boxhD: number; + boxhU: number; + boxhd: number; + boxhu: number; + boxuL: number; + boxuR: number; + boxul: number; + boxur: number; + boxvH: number; + boxvL: number; + boxvR: number; + boxvh: number; + boxvl: number; + boxvr: number; + breve: number; + bsemi: number; + bsime: number; + bsolb: number; + bumpE: number; + bumpe: number; + caret: number; + caron: number; + ccaps: number; + ccirc: number; + ccups: number; + cedil: number; + check: number; + clubs: number; + colon: number; + comma: number; + crarr: number; + cross: number; + csube: number; + csupe: number; + ctdot: number; + cuepr: number; + cuesc: number; + cupor: number; + cuvee: number; + cuwed: number; + cwint: number; + dashv: number; + dblac: number; + ddarr: number; + delta: number; + dharl: number; + dharr: number; + diams: number; + disin: number; + doteq: number; + dtdot: number; + dtrif: number; + duarr: number; + duhar: number; + eDDot: number; + ecirc: number; + efDot: number; + emacr: number; + empty: number; + eogon: number; + eplus: number; + epsiv: number; + eqsim: number; + equiv: number; + erDot: number; + erarr: number; + esdot: number; + exist: number; + fflig: number; + filig: number; + fllig: number; + fltns: number; + forkv: number; + frasl: number; + frown: number; + gamma: number; + gcirc: number; + gescc: number; + gimel: number; + gneqq: number; + gnsim: number; + grave: number; + gsime: number; + gsiml: number; + gtcir: number; + gtdot: number; + harrw: number; + hcirc: number; + hoarr: number; + icirc: number; + iexcl: number; + iiint: number; + iiota: number; + ijlig: number; + imacr: number; + image: number; + imath: number; + imped: number; + infin: number; + iogon: number; + iprod: number; + isinE: number; + isins: number; + isinv: number; + iukcy: number; + jcirc: number; + jmath: number; + jukcy: number; + kappa: number; + lAarr: number; + lBarr: number; + langd: number; + laquo: number; + larrb: number; + lbarr: number; + lbbrk: number; + lbrke: number; + lceil: number; + ldquo: number; + lescc: number; + lhard: number; + lharu: number; + lhblk: number; + llarr: number; + lltri: number; + lneqq: number; + lnsim: number; + loang: number; + loarr: number; + lobrk: number; + lopar: number; + lrarr: number; + lrhar: number; + lrtri: number; + lsime: number; + lsimg: number; + lsquo: number; + ltcir: number; + ltdot: number; + ltrie: number; + ltrif: number; + mDDot: number; + mdash: number; + micro: number; + minus: number; + mumap: number; + nabla: number; + napos: number; + natur: number; + ncong: number; + ndash: number; + neArr: number; + nearr: number; + ngsim: number; + nhArr: number; + nharr: number; + nhpar: number; + nlArr: number; + nlarr: number; + nless: number; + nlsim: number; + nltri: number; + notin: number; + notni: number; + nprec: number; + nrArr: number; + nrarr: number; + nrtri: number; + nsime: number; + nsmid: number; + nspar: number; + nsube: number; + nsucc: number; + nsupe: number; + numsp: number; + nwArr: number; + nwarr: number; + ocirc: number; + odash: number; + oelig: number; + ofcir: number; + ohbar: number; + olarr: number; + olcir: number; + oline: number; + omacr: number; + omega: number; + operp: number; + oplus: number; + orarr: number; + order: number; + ovbar: number; + parsl: number; + phone: number; + plusb: number; + pluse: number; + pound: number; + prcue: number; + prime: number; + prnap: number; + prsim: number; + quest: number; + rAarr: number; + rBarr: number; + radic: number; + rangd: number; + range: number; + raquo: number; + rarrb: number; + rarrc: number; + rarrw: number; + ratio: number; + rbarr: number; + rbbrk: number; + rbrke: number; + rceil: number; + rdquo: number; + reals: number; + rhard: number; + rharu: number; + rlarr: number; + rlhar: number; + rnmid: number; + roang: number; + roarr: number; + robrk: number; + ropar: number; + rrarr: number; + rsquo: number; + rtrie: number; + rtrif: number; + sbquo: number; + sccue: number; + scirc: number; + scnap: number; + scsim: number; + sdotb: number; + sdote: number; + seArr: number; + searr: number; + setmn: number; + sharp: number; + sigma: number; + simeq: number; + simgE: number; + simlE: number; + simne: number; + slarr: number; + smile: number; + sqcap: number; + sqcup: number; + sqsub: number; + sqsup: number; + srarr: number; + starf: number; + strns: number; + subnE: number; + subne: number; + supnE: number; + supne: number; + swArr: number; + swarr: number; + szlig: number; + theta: number; + thkap: number; + thorn: number; + tilde: number; + times: number; + trade: number; + trisb: number; + tshcy: number; + twixt: number; + ubrcy: number; + ucirc: number; + udarr: number; + udhar: number; + uharl: number; + uharr: number; + uhblk: number; + ultri: number; + umacr: number; + uogon: number; + uplus: number; + upsih: number; + uring: number; + urtri: number; + utdot: number; + utrif: number; + uuarr: number; + vBarv: number; + vDash: number; + varpi: number; + vdash: number; + veeeq: number; + vltri: number; + vprop: number; + vrtri: number; + wcirc: number; + wedge: number; + xcirc: number; + xdtri: number; + xhArr: number; + xharr: number; + xlArr: number; + xlarr: number; + xodot: number; + xrArr: number; + xrarr: number; + xutri: number; + ycirc: number; + Aopf: number; + Ascr: number; + Auml: number; + Barv: number; + Beta: number; + Bopf: number; + Bscr: number; + CHcy: number; + COPY: number; + Cdot: number; + Copf: number; + Cscr: number; + DJcy: number; + DScy: number; + DZcy: number; + Darr: number; + Dopf: number; + Dscr: number; + Edot: number; + Eopf: number; + Escr: number; + Esim: number; + Euml: number; + Fopf: number; + Fscr: number; + GJcy: number; + Gdot: number; + Gopf: number; + Gscr: number; + Hopf: number; + Hscr: number; + IEcy: number; + IOcy: number; + Idot: number; + Iopf: number; + Iota: number; + Iscr: number; + Iuml: number; + Jopf: number; + Jscr: number; + KHcy: number; + KJcy: number; + Kopf: number; + Kscr: number; + LJcy: number; + Lang: number; + Larr: number; + Lopf: number; + Lscr: number; + Mopf: number; + Mscr: number; + NJcy: number; + Nopf: number; + Nscr: number; + Oopf: number; + Oscr: number; + Ouml: number; + Popf: number; + Pscr: number; + QUOT: number; + Qopf: number; + Qscr: number; + Rang: number; + Rarr: number; + Ropf: number; + Rscr: number; + SHcy: number; + Sopf: number; + Sqrt: number; + Sscr: number; + Star: number; + TScy: number; + Topf: number; + Tscr: number; + Uarr: number; + Uopf: number; + Upsi: number; + Uscr: number; + Uuml: number; + Vbar: number; + Vert: number; + Vopf: number; + Vscr: number; + Wopf: number; + Wscr: number; + Xopf: number; + Xscr: number; + YAcy: number; + YIcy: number; + YUcy: number; + Yopf: number; + Yscr: number; + Yuml: number; + ZHcy: number; + Zdot: number; + Zeta: number; + Zopf: number; + Zscr: number; + andd: number; + andv: number; + ange: number; + aopf: number; + apid: number; + apos: number; + ascr: number; + auml: number; + bNot: number; + bbrk: number; + beta: number; + beth: number; + bnot: number; + bopf: number; + boxH: number; + boxV: number; + boxh: number; + boxv: number; + bscr: number; + bsim: number; + bsol: number; + bull: number; + bump: number; + cdot: number; + cent: number; + chcy: number; + cirE: number; + circ: number; + cire: number; + comp: number; + cong: number; + copf: number; + copy: number; + cscr: number; + csub: number; + csup: number; + dArr: number; + dHar: number; + darr: number; + dash: number; + diam: number; + djcy: number; + dopf: number; + dscr: number; + dscy: number; + dsol: number; + dtri: number; + dzcy: number; + eDot: number; + ecir: number; + edot: number; + emsp: number; + ensp: number; + eopf: number; + epar: number; + epsi: number; + escr: number; + esim: number; + euml: number; + euro: number; + excl: number; + flat: number; + fnof: number; + fopf: number; + fork: number; + fscr: number; + gdot: number; + geqq: number; + gjcy: number; + gnap: number; + gneq: number; + gopf: number; + gscr: number; + gsim: number; + gtcc: number; + hArr: number; + half: number; + harr: number; + hbar: number; + hopf: number; + hscr: number; + iecy: number; + imof: number; + iocy: number; + iopf: number; + iota: number; + iscr: number; + isin: number; + iuml: number; + jopf: number; + jscr: number; + khcy: number; + kjcy: number; + kopf: number; + kscr: number; + lArr: number; + lHar: number; + lang: number; + larr: number; + late: number; + lcub: number; + ldca: number; + ldsh: number; + leqq: number; + ljcy: number; + lnap: number; + lneq: number; + lopf: number; + lozf: number; + lpar: number; + lscr: number; + lsim: number; + lsqb: number; + ltcc: number; + ltri: number; + macr: number; + male: number; + malt: number; + mlcp: number; + mldr: number; + mopf: number; + mscr: number; + nbsp: number; + ncap: number; + ncup: number; + ngeq: number; + ngtr: number; + nisd: number; + njcy: number; + nldr: number; + nleq: number; + nmid: number; + nopf: number; + npar: number; + nscr: number; + nsim: number; + nsub: number; + nsup: number; + ntgl: number; + ntlg: number; + oast: number; + ocir: number; + odiv: number; + odot: number; + ogon: number; + oint: number; + omid: number; + oopf: number; + opar: number; + ordf: number; + ordm: number; + oror: number; + oscr: number; + osol: number; + ouml: number; + para: number; + part: number; + perp: number; + phiv: number; + plus: number; + popf: number; + prap: number; + prec: number; + prnE: number; + prod: number; + prop: number; + pscr: number; + qint: number; + qopf: number; + qscr: number; + quot: number; + rArr: number; + rHar: number; + race: number; + rang: number; + rarr: number; + rcub: number; + rdca: number; + rdsh: number; + real: number; + rect: number; + rhov: number; + ring: number; + ropf: number; + rpar: number; + rscr: number; + rsqb: number; + rtri: number; + scap: number; + scnE: number; + sdot: number; + sect: number; + semi: number; + sext: number; + shcy: number; + sime: number; + simg: number; + siml: number; + smid: number; + smte: number; + solb: number; + sopf: number; + spar: number; + squf: number; + sscr: number; + star: number; + subE: number; + sube: number; + succ: number; + sung: number; + sup1: number; + sup2: number; + sup3: number; + supE: number; + supe: number; + tbrk: number; + tdot: number; + tint: number; + toea: number; + topf: number; + tosa: number; + trie: number; + tscr: number; + tscy: number; + uArr: number; + uHar: number; + uarr: number; + uopf: number; + upsi: number; + uscr: number; + utri: number; + uuml: number; + vArr: number; + vBar: number; + varr: number; + vert: number; + vopf: number; + vscr: number; + wopf: number; + wscr: number; + xcap: number; + xcup: number; + xmap: number; + xnis: number; + xopf: number; + xscr: number; + xvee: number; + yacy: number; + yicy: number; + yopf: number; + yscr: number; + yucy: number; + yuml: number; + zdot: number; + zeta: number; + zhcy: number; + zopf: number; + zscr: number; + zwnj: number; + AMP: number; + Acy: number; + Afr: number; + And: number; + Bcy: number; + Bfr: number; + Cap: number; + Cfr: number; + Chi: number; + Cup: number; + Dcy: number; + Del: number; + Dfr: number; + Dot: number; + ENG: number; + ETH: number; + Ecy: number; + Efr: number; + Eta: number; + Fcy: number; + Ffr: number; + Gcy: number; + Gfr: number; + Hat: number; + Hfr: number; + Icy: number; + Ifr: number; + Int: number; + Jcy: number; + Jfr: number; + Kcy: number; + Kfr: number; + Lcy: number; + Lfr: number; + Lsh: number; + Map: number; + Mcy: number; + Mfr: number; + Ncy: number; + Nfr: number; + Not: number; + Ocy: number; + Ofr: number; + Pcy: number; + Pfr: number; + Phi: number; + Psi: number; + Qfr: number; + REG: number; + Rcy: number; + Rfr: number; + Rho: number; + Rsh: number; + Scy: number; + Sfr: number; + Sub: number; + Sum: number; + Sup: number; + Tab: number; + Tau: number; + Tcy: number; + Tfr: number; + Ucy: number; + Ufr: number; + Vcy: number; + Vee: number; + Vfr: number; + Wfr: number; + Xfr: number; + Ycy: number; + Yfr: number; + Zcy: number; + Zfr: number; + acd: number; + acy: number; + afr: number; + amp: number; + and: number; + ang: number; + apE: number; + ape: number; + ast: number; + bcy: number; + bfr: number; + bot: number; + cap: number; + cfr: number; + chi: number; + cir: number; + cup: number; + dcy: number; + deg: number; + dfr: number; + die: number; + div: number; + dot: number; + ecy: number; + efr: number; + egs: number; + ell: number; + els: number; + eng: number; + eta: number; + eth: number; + fcy: number; + ffr: number; + gEl: number; + gap: number; + gcy: number; + gel: number; + geq: number; + ges: number; + gfr: number; + ggg: number; + glE: number; + gla: number; + glj: number; + gnE: number; + gne: number; + hfr: number; + icy: number; + iff: number; + ifr: number; + int: number; + jcy: number; + jfr: number; + kcy: number; + kfr: number; + lEg: number; + lap: number; + lat: number; + lcy: number; + leg: number; + leq: number; + les: number; + lfr: number; + lgE: number; + lnE: number; + lne: number; + loz: number; + lrm: number; + lsh: number; + map: number; + mcy: number; + mfr: number; + mho: number; + mid: number; + nap: number; + ncy: number; + nfr: number; + nge: number; + ngt: number; + nis: number; + niv: number; + nle: number; + nlt: number; + not: number; + npr: number; + nsc: number; + num: number; + ocy: number; + ofr: number; + ogt: number; + ohm: number; + olt: number; + ord: number; + orv: number; + par: number; + pcy: number; + pfr: number; + phi: number; + piv: number; + prE: number; + pre: number; + psi: number; + qfr: number; + rcy: number; + reg: number; + rfr: number; + rho: number; + rlm: number; + rsh: number; + scE: number; + sce: number; + scy: number; + sfr: number; + shy: number; + sim: number; + smt: number; + sol: number; + squ: number; + sub: number; + sum: number; + sup: number; + tau: number; + tcy: number; + tfr: number; + top: number; + ucy: number; + ufr: number; + uml: number; + vcy: number; + vee: number; + vfr: number; + wfr: number; + xfr: number; + ycy: number; + yen: number; + yfr: number; + zcy: number; + zfr: number; + zwj: number; + DD: number; + GT: number; + Gg: number; + Gt: number; + Im: number; + LT: number; + Ll: number; + Lt: number; + Mu: number; + Nu: number; + Or: number; + Pi: number; + Pr: number; + Re: number; + Sc: number; + Xi: number; + ac: number; + af: number; + ap: number; + dd: number; + ee: number; + eg: number; + el: number; + gE: number; + ge: number; + gg: number; + gl: number; + gt: number; + ic: number; + ii: number; + in: number; + it: number; + lE: number; + le: number; + lg: number; + ll: number; + lt: number; + mp: number; + mu: number; + ne: number; + ni: number; + nu: number; + oS: number; + or: number; + pi: number; + pm: number; + pr: number; + rx: number; + sc: number; + wp: number; + wr: number; + xi: number; }; export default _default; diff --git a/src/@types/compiler/preprocess/index.d.ts b/src/@types/compiler/preprocess/index.d.ts index f56362a7f..627cee97e 100644 --- a/src/@types/compiler/preprocess/index.d.ts +++ b/src/@types/compiler/preprocess/index.d.ts @@ -1,4 +1,8 @@ import { PreprocessorGroup, Processed } from './types'; -export default function preprocess(source: string, preprocessor: PreprocessorGroup | PreprocessorGroup[], options?: { +export default function preprocess( + source: string, + preprocessor: PreprocessorGroup | PreprocessorGroup[], + options?: { filename?: string; -}): Promise<Processed>; + } +): Promise<Processed>; diff --git a/src/@types/compiler/preprocess/types.d.ts b/src/@types/compiler/preprocess/types.d.ts index c4a043c41..7f8a3dbcf 100644 --- a/src/@types/compiler/preprocess/types.d.ts +++ b/src/@types/compiler/preprocess/types.d.ts @@ -1,27 +1,20 @@ import { Location } from 'locate-character'; export interface Source { - source: string; - get_location: (search: number) => Location; - file_basename: string; - filename: string; + source: string; + get_location: (search: number) => Location; + file_basename: string; + filename: string; } export interface Processed { - code: string; - map?: string | object; - dependencies?: string[]; - toString?: () => string; + code: string; + map?: string | object; + dependencies?: string[]; + toString?: () => string; } -export declare type MarkupPreprocessor = (options: { - content: string; - filename: string; -}) => Processed | Promise<Processed>; -export declare type Preprocessor = (options: { - content: string; - attributes: Record<string, string | boolean>; - filename?: string; -}) => Processed | Promise<Processed>; +export declare type MarkupPreprocessor = (options: { content: string; filename: string }) => Processed | Promise<Processed>; +export declare type Preprocessor = (options: { content: string; attributes: Record<string, string | boolean>; filename?: string }) => Processed | Promise<Processed>; export interface PreprocessorGroup { - markup?: MarkupPreprocessor; - style?: Preprocessor; - script?: Preprocessor; + markup?: MarkupPreprocessor; + style?: Preprocessor; + script?: Preprocessor; } diff --git a/src/@types/compiler/utils/error.d.ts b/src/@types/compiler/utils/error.d.ts index babd2bbdb..a59c146c9 100644 --- a/src/@types/compiler/utils/error.d.ts +++ b/src/@types/compiler/utils/error.d.ts @@ -1,8 +1,11 @@ -export default function error(message: string, props: { +export default function error( + message: string, + props: { name: string; code: string; source: string; filename: string; start: number; end?: number; -}): never; + } +): never; diff --git a/src/@types/compiler/utils/link.d.ts b/src/@types/compiler/utils/link.d.ts index e73ccbce1..8cb0c0bb3 100644 --- a/src/@types/compiler/utils/link.d.ts +++ b/src/@types/compiler/utils/link.d.ts @@ -1,4 +1,6 @@ -export declare function link<T extends { +export declare function link< + T extends { next?: T; prev?: T; -}>(next: T, prev: T): void; + } +>(next: T, prev: T): void; diff --git a/src/@types/compiler/utils/mapped_code.d.ts b/src/@types/compiler/utils/mapped_code.d.ts index b6aa28971..a6b194c8b 100644 --- a/src/@types/compiler/utils/mapped_code.d.ts +++ b/src/@types/compiler/utils/mapped_code.d.ts @@ -2,21 +2,21 @@ import { DecodedSourceMap, RawSourceMap } from '@ampproject/remapping/dist/types import { SourceMap } from 'magic-string'; import { Source, Processed } from '../preprocess/types'; export declare type SourceLocation = { - line: number; - column: number; + line: number; + column: number; }; export declare function sourcemap_add_offset(map: DecodedSourceMap, offset: SourceLocation, source_index: number): void; export declare class MappedCode { - string: string; - map: DecodedSourceMap; - constructor(string?: string, map?: DecodedSourceMap); - /** - * concat in-place (mutable), return this (chainable) - * will also mutate the `other` object - */ - concat(other: MappedCode): MappedCode; - static from_processed(string: string, map?: DecodedSourceMap): MappedCode; - static from_source({ source, file_basename, get_location }: Source): MappedCode; + string: string; + map: DecodedSourceMap; + constructor(string?: string, map?: DecodedSourceMap); + /** + * concat in-place (mutable), return this (chainable) + * will also mutate the `other` object + */ + concat(other: MappedCode): MappedCode; + static from_processed(string: string, map?: DecodedSourceMap): MappedCode; + static from_source({ source, file_basename, get_location }: Source): MappedCode; } export declare function combine_sourcemaps(filename: string, sourcemap_list: Array<DecodedSourceMap | RawSourceMap>): RawSourceMap; export declare function apply_preprocessor_sourcemap(filename: string, svelte_map: SourceMap, preprocessor_map_input: string | DecodedSourceMap | RawSourceMap): SourceMap; diff --git a/src/@types/compiler/utils/namespaces.d.ts b/src/@types/compiler/utils/namespaces.d.ts index 373776ef3..aaad38860 100644 --- a/src/@types/compiler/utils/namespaces.d.ts +++ b/src/@types/compiler/utils/namespaces.d.ts @@ -1,9 +1,9 @@ -export declare const foreign = "https://svelte.dev/docs#svelte_options"; -export declare const html = "http://www.w3.org/1999/xhtml"; -export declare const mathml = "http://www.w3.org/1998/Math/MathML"; -export declare const svg = "http://www.w3.org/2000/svg"; -export declare const xlink = "http://www.w3.org/1999/xlink"; -export declare const xml = "http://www.w3.org/XML/1998/namespace"; -export declare const xmlns = "http://www.w3.org/2000/xmlns"; +export declare const foreign = 'https://svelte.dev/docs#svelte_options'; +export declare const html = 'http://www.w3.org/1999/xhtml'; +export declare const mathml = 'http://www.w3.org/1998/Math/MathML'; +export declare const svg = 'http://www.w3.org/2000/svg'; +export declare const xlink = 'http://www.w3.org/1999/xlink'; +export declare const xml = 'http://www.w3.org/XML/1998/namespace'; +export declare const xmlns = 'http://www.w3.org/2000/xmlns'; export declare const valid_namespaces: string[]; export declare const namespaces: Record<string, string>; diff --git a/src/cli.ts b/src/cli.ts index e2ff727bd..62e50f3eb 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -14,17 +14,20 @@ type Arguments = yargs.Arguments; type cliState = 'help' | 'version' | 'dev' | 'build'; function resolveArgs(flags: Arguments): cliState { - if(flags.version) { + if (flags.version) { return 'version'; - } else if(flags.help) { + } else if (flags.help) { return 'help'; } const cmd = flags._[2]; - switch(cmd) { - case 'dev': return 'dev'; - case 'build': return 'build'; - default: return 'help'; + switch (cmd) { + case 'dev': + return 'dev'; + case 'build': + return 'build'; + default: + return 'help'; } } @@ -47,7 +50,7 @@ async function printVersion() { } async function loadConfig(rawRoot: string | undefined): Promise<AstroConfig | undefined> { - if(typeof rawRoot === 'undefined') { + if (typeof rawRoot === 'undefined') { rawRoot = process.cwd(); } @@ -55,7 +58,7 @@ async function loadConfig(rawRoot: string | undefined): Promise<AstroConfig | un const fileProtocolRoot = `file://${root}/`; const astroConfigPath = pathJoin(root, 'astro.config.mjs'); - if(!existsSync(astroConfigPath)) { + if (!existsSync(astroConfigPath)) { return undefined; } @@ -67,7 +70,7 @@ async function loadConfig(rawRoot: string | undefined): Promise<AstroConfig | un async function runCommand(rawRoot: string, cmd: (a: AstroConfig) => Promise<void>) { const astroConfig = await loadConfig(rawRoot); - if(typeof astroConfig === 'undefined') { + if (typeof astroConfig === 'undefined') { console.error(colors.red(' An astro.config.mjs file is required.\n')); printHelp(); process.exit(1); @@ -78,14 +81,14 @@ async function runCommand(rawRoot: string, cmd: (a: AstroConfig) => Promise<void const cmdMap = new Map([ ['build', generate], - ['dev', devServer] + ['dev', devServer], ]); export async function cli(args: string[]) { const flags = yargs(args); const state = resolveArgs(flags); - switch(state) { + switch (state) { case 'help': { printHelp(); process.exit(1); @@ -102,4 +105,4 @@ export async function cli(args: string[]) { runCommand(flags._[3], cmd); } } -}
\ No newline at end of file +} diff --git a/src/compiler.d.ts b/src/compiler.d.ts index 0b37f1f8c..ee22628f9 100644 --- a/src/compiler.d.ts +++ b/src/compiler.d.ts @@ -1 +1 @@ -export { compile, parse, preprocess, walk, VERSION } from './@types/compiler/index';
\ No newline at end of file +export { compile, parse, preprocess, walk, VERSION } from './@types/compiler/index'; diff --git a/src/compiler.js b/src/compiler.js index 4f9567b9f..92c6959f4 100644 --- a/src/compiler.js +++ b/src/compiler.js @@ -1,84 +1,77 @@ - import acorn, { isIdentifierStart, isIdentifierChar, parse as parse$3, parseExpressionAt } from 'acorn'; import parse$2 from 'css-tree/lib/parser/index.js'; import MagicString from 'magic-string'; -const now = (typeof process !== 'undefined' && process.hrtime) - ? () => { - const t = process.hrtime(); - return t[0] * 1e3 + t[1] / 1e6; - } - : () => self.performance.now(); - - - +const now = + typeof process !== 'undefined' && process.hrtime + ? () => { + const t = process.hrtime(); + return t[0] * 1e3 + t[1] / 1e6; + } + : () => self.performance.now(); +function collapse_timings(timings) { + const result = {}; + timings.forEach((timing) => { + result[timing.label] = Object.assign( + { + total: timing.end - timing.start, + }, + timing.children && collapse_timings(timing.children) + ); + }); + return result; +} +class Stats { + constructor() { + this.start_time = now(); + this.stack = []; + this.current_children = this.timings = []; + } + start(label) { + const timing = { + label, + start: now(), + end: null, + children: [], + }; + this.current_children.push(timing); + this.stack.push(timing); -function collapse_timings(timings) { - const result = {}; - timings.forEach(timing => { - result[timing.label] = Object.assign({ - total: timing.end - timing.start - }, timing.children && collapse_timings(timing.children)); - }); - return result; -} + this.current_timing = timing; + this.current_children = timing.children; + } -class Stats { - - - - - - - constructor() { - this.start_time = now(); - this.stack = []; - this.current_children = this.timings = []; - } - - start(label) { - const timing = { - label, - start: now(), - end: null, - children: [] - }; - - this.current_children.push(timing); - this.stack.push(timing); - - this.current_timing = timing; - this.current_children = timing.children; - } - - stop(label) { - if (label !== this.current_timing.label) { - throw new Error(`Mismatched timing labels (expected ${this.current_timing.label}, got ${label})`); - } + stop(label) { + if (label !== this.current_timing.label) { + throw new Error(`Mismatched timing labels (expected ${this.current_timing.label}, got ${label})`); + } - this.current_timing.end = now(); - this.stack.pop(); - this.current_timing = this.stack[this.stack.length - 1]; - this.current_children = this.current_timing ? this.current_timing.children : this.timings; - } + this.current_timing.end = now(); + this.stack.pop(); + this.current_timing = this.stack[this.stack.length - 1]; + this.current_children = this.current_timing ? this.current_timing.children : this.timings; + } - render() { - const timings = Object.assign({ - total: now() - this.start_time - }, collapse_timings(this.timings)); + render() { + const timings = Object.assign( + { + total: now() - this.start_time, + }, + collapse_timings(this.timings) + ); - return { - timings - }; - } + return { + timings, + }; + } } function createCommonjsModule(fn, module) { - return module = { exports: {} }, fn(module, module.exports), module.exports; + return (module = { exports: {} }), fn(module, module.exports), module.exports; } var xhtml = { @@ -306,7 +299,7 @@ var xhtml = { or: '\u2228', cap: '\u2229', cup: '\u222A', - 'int': '\u222B', + int: '\u222B', there4: '\u2234', sim: '\u223C', cong: '\u2245', @@ -334,512 +327,500 @@ var xhtml = { spades: '\u2660', clubs: '\u2663', hearts: '\u2665', - diams: '\u2666' + diams: '\u2666', }; var acornJsx = createCommonjsModule(function (module) { + const hexNumber = /^[\da-fA-F]+$/; + const decimalNumber = /^\d+$/; + + // The map to `acorn-jsx` tokens from `acorn` namespace objects. + const acornJsxMap = new WeakMap(); + + // Get the original tokens for the given `acorn` namespace object. + function getJsxTokens(acorn) { + acorn = acorn.Parser.acorn || acorn; + let acornJsx = acornJsxMap.get(acorn); + if (!acornJsx) { + const tt = acorn.tokTypes; + const TokContext = acorn.TokContext; + const TokenType = acorn.TokenType; + const tc_oTag = new TokContext('<tag', false); + const tc_cTag = new TokContext('</tag', false); + const tc_expr = new TokContext('<tag>...</tag>', true, true); + const tokContexts = { + tc_oTag: tc_oTag, + tc_cTag: tc_cTag, + tc_expr: tc_expr, + }; + const tokTypes = { + jsxName: new TokenType('jsxName'), + jsxText: new TokenType('jsxText', { beforeExpr: true }), + jsxTagStart: new TokenType('jsxTagStart', { startsExpr: true }), + jsxTagEnd: new TokenType('jsxTagEnd'), + }; + + tokTypes.jsxTagStart.updateContext = function () { + this.context.push(tc_expr); // treat as beginning of JSX expression + this.context.push(tc_oTag); // start opening tag context + this.exprAllowed = false; + }; + tokTypes.jsxTagEnd.updateContext = function (prevType) { + let out = this.context.pop(); + if ((out === tc_oTag && prevType === tt.slash) || out === tc_cTag) { + this.context.pop(); + this.exprAllowed = this.curContext() === tc_expr; + } else { + this.exprAllowed = true; + } + }; + acornJsx = { tokContexts: tokContexts, tokTypes: tokTypes }; + acornJsxMap.set(acorn, acornJsx); + } - -const hexNumber = /^[\da-fA-F]+$/; -const decimalNumber = /^\d+$/; - -// The map to `acorn-jsx` tokens from `acorn` namespace objects. -const acornJsxMap = new WeakMap(); - -// Get the original tokens for the given `acorn` namespace object. -function getJsxTokens(acorn) { - acorn = acorn.Parser.acorn || acorn; - let acornJsx = acornJsxMap.get(acorn); - if (!acornJsx) { - const tt = acorn.tokTypes; - const TokContext = acorn.TokContext; - const TokenType = acorn.TokenType; - const tc_oTag = new TokContext('<tag', false); - const tc_cTag = new TokContext('</tag', false); - const tc_expr = new TokContext('<tag>...</tag>', true, true); - const tokContexts = { - tc_oTag: tc_oTag, - tc_cTag: tc_cTag, - tc_expr: tc_expr - }; - const tokTypes = { - jsxName: new TokenType('jsxName'), - jsxText: new TokenType('jsxText', {beforeExpr: true}), - jsxTagStart: new TokenType('jsxTagStart', {startsExpr: true}), - jsxTagEnd: new TokenType('jsxTagEnd') - }; - - tokTypes.jsxTagStart.updateContext = function() { - this.context.push(tc_expr); // treat as beginning of JSX expression - this.context.push(tc_oTag); // start opening tag context - this.exprAllowed = false; - }; - tokTypes.jsxTagEnd.updateContext = function(prevType) { - let out = this.context.pop(); - if (out === tc_oTag && prevType === tt.slash || out === tc_cTag) { - this.context.pop(); - this.exprAllowed = this.curContext() === tc_expr; - } else { - this.exprAllowed = true; - } - }; - - acornJsx = { tokContexts: tokContexts, tokTypes: tokTypes }; - acornJsxMap.set(acorn, acornJsx); + return acornJsx; } - return acornJsx; -} - -// Transforms JSX element name to string. + // Transforms JSX element name to string. -function getQualifiedJSXName(object) { - if (!object) - return object; + function getQualifiedJSXName(object) { + if (!object) return object; - if (object.type === 'JSXIdentifier') - return object.name; + if (object.type === 'JSXIdentifier') return object.name; - if (object.type === 'JSXNamespacedName') - return object.namespace.name + ':' + object.name.name; + if (object.type === 'JSXNamespacedName') return object.namespace.name + ':' + object.name.name; - if (object.type === 'JSXMemberExpression') - return getQualifiedJSXName(object.object) + '.' + - getQualifiedJSXName(object.property); -} + if (object.type === 'JSXMemberExpression') return getQualifiedJSXName(object.object) + '.' + getQualifiedJSXName(object.property); + } -module.exports = function(options) { - options = options || {}; - return function(Parser) { - return plugin({ - allowNamespaces: options.allowNamespaces !== false, - allowNamespacedObjects: !!options.allowNamespacedObjects - }, Parser); + module.exports = function (options) { + options = options || {}; + return function (Parser) { + return plugin( + { + allowNamespaces: options.allowNamespaces !== false, + allowNamespacedObjects: !!options.allowNamespacedObjects, + }, + Parser + ); + }; }; -}; -// This is `tokTypes` of the peer dep. -// This can be different instances from the actual `tokTypes` this plugin uses. -Object.defineProperty(module.exports, "tokTypes", { - get: function get_tokTypes() { - return getJsxTokens(acorn).tokTypes; - }, - configurable: true, - enumerable: true -}); - -function plugin(options, Parser) { - const acorn$1 = Parser.acorn || acorn; - const acornJsx = getJsxTokens(acorn$1); - const tt = acorn$1.tokTypes; - const tok = acornJsx.tokTypes; - const tokContexts = acorn$1.tokContexts; - const tc_oTag = acornJsx.tokContexts.tc_oTag; - const tc_cTag = acornJsx.tokContexts.tc_cTag; - const tc_expr = acornJsx.tokContexts.tc_expr; - const isNewLine = acorn$1.isNewLine; - const isIdentifierStart = acorn$1.isIdentifierStart; - const isIdentifierChar = acorn$1.isIdentifierChar; - - return class extends Parser { - // Expose actual `tokTypes` and `tokContexts` to other plugins. - static get acornJsx() { - return acornJsx; - } - - // Reads inline JSX contents token. - jsx_readToken() { - let out = '', chunkStart = this.pos; - for (;;) { - if (this.pos >= this.input.length) - this.raise(this.start, 'Unterminated JSX contents'); - let ch = this.input.charCodeAt(this.pos); + // This is `tokTypes` of the peer dep. + // This can be different instances from the actual `tokTypes` this plugin uses. + Object.defineProperty(module.exports, 'tokTypes', { + get: function get_tokTypes() { + return getJsxTokens(acorn).tokTypes; + }, + configurable: true, + enumerable: true, + }); + + function plugin(options, Parser) { + const acorn$1 = Parser.acorn || acorn; + const acornJsx = getJsxTokens(acorn$1); + const tt = acorn$1.tokTypes; + const tok = acornJsx.tokTypes; + const tokContexts = acorn$1.tokContexts; + const tc_oTag = acornJsx.tokContexts.tc_oTag; + const tc_cTag = acornJsx.tokContexts.tc_cTag; + const tc_expr = acornJsx.tokContexts.tc_expr; + const isNewLine = acorn$1.isNewLine; + const isIdentifierStart = acorn$1.isIdentifierStart; + const isIdentifierChar = acorn$1.isIdentifierChar; + + return class extends Parser { + // Expose actual `tokTypes` and `tokContexts` to other plugins. + static get acornJsx() { + return acornJsx; + } - switch (ch) { - case 60: // '<' - case 123: // '{' - if (this.pos === this.start) { - if (ch === 60 && this.exprAllowed) { - ++this.pos; - return this.finishToken(tok.jsxTagStart); - } - return this.getTokenFromCode(ch); + // Reads inline JSX contents token. + jsx_readToken() { + let out = '', + chunkStart = this.pos; + for (;;) { + if (this.pos >= this.input.length) this.raise(this.start, 'Unterminated JSX contents'); + let ch = this.input.charCodeAt(this.pos); + + switch (ch) { + case 60: // '<' + case 123: // '{' + if (this.pos === this.start) { + if (ch === 60 && this.exprAllowed) { + ++this.pos; + return this.finishToken(tok.jsxTagStart); + } + return this.getTokenFromCode(ch); + } + out += this.input.slice(chunkStart, this.pos); + return this.finishToken(tok.jsxText, out); + + case 38: // '&' + out += this.input.slice(chunkStart, this.pos); + out += this.jsx_readEntity(); + chunkStart = this.pos; + break; + + case 62: // '>' + case 125: // '}' + this.raise( + this.pos, + 'Unexpected token `' + this.input[this.pos] + '`. Did you mean `' + (ch === 62 ? '>' : '}') + '` or ' + '`{"' + this.input[this.pos] + '"}' + '`?' + ); + + default: + if (isNewLine(ch)) { + out += this.input.slice(chunkStart, this.pos); + out += this.jsx_readNewLine(true); + chunkStart = this.pos; + } else { + ++this.pos; + } } - out += this.input.slice(chunkStart, this.pos); - return this.finishToken(tok.jsxText, out); + } + } - case 38: // '&' - out += this.input.slice(chunkStart, this.pos); - out += this.jsx_readEntity(); - chunkStart = this.pos; - break; + jsx_readNewLine(normalizeCRLF) { + let ch = this.input.charCodeAt(this.pos); + let out; + ++this.pos; + if (ch === 13 && this.input.charCodeAt(this.pos) === 10) { + ++this.pos; + out = normalizeCRLF ? '\n' : '\r\n'; + } else { + out = String.fromCharCode(ch); + } + if (this.options.locations) { + ++this.curLine; + this.lineStart = this.pos; + } - case 62: // '>' - case 125: // '}' - this.raise( - this.pos, - "Unexpected token `" + this.input[this.pos] + "`. Did you mean `" + - (ch === 62 ? ">" : "}") + "` or " + "`{\"" + this.input[this.pos] + "\"}" + "`?" - ); + return out; + } - default: - if (isNewLine(ch)) { + jsx_readString(quote) { + let out = '', + chunkStart = ++this.pos; + for (;;) { + if (this.pos >= this.input.length) this.raise(this.start, 'Unterminated string constant'); + let ch = this.input.charCodeAt(this.pos); + if (ch === quote) break; + if (ch === 38) { + // '&' out += this.input.slice(chunkStart, this.pos); - out += this.jsx_readNewLine(true); + out += this.jsx_readEntity(); + chunkStart = this.pos; + } else if (isNewLine(ch)) { + out += this.input.slice(chunkStart, this.pos); + out += this.jsx_readNewLine(false); chunkStart = this.pos; } else { ++this.pos; } } - } - } - - jsx_readNewLine(normalizeCRLF) { - let ch = this.input.charCodeAt(this.pos); - let out; - ++this.pos; - if (ch === 13 && this.input.charCodeAt(this.pos) === 10) { - ++this.pos; - out = normalizeCRLF ? '\n' : '\r\n'; - } else { - out = String.fromCharCode(ch); - } - if (this.options.locations) { - ++this.curLine; - this.lineStart = this.pos; + out += this.input.slice(chunkStart, this.pos++); + return this.finishToken(tt.string, out); } - return out; - } - - jsx_readString(quote) { - let out = '', chunkStart = ++this.pos; - for (;;) { - if (this.pos >= this.input.length) - this.raise(this.start, 'Unterminated string constant'); - let ch = this.input.charCodeAt(this.pos); - if (ch === quote) break; - if (ch === 38) { // '&' - out += this.input.slice(chunkStart, this.pos); - out += this.jsx_readEntity(); - chunkStart = this.pos; - } else if (isNewLine(ch)) { - out += this.input.slice(chunkStart, this.pos); - out += this.jsx_readNewLine(false); - chunkStart = this.pos; - } else { - ++this.pos; - } - } - out += this.input.slice(chunkStart, this.pos++); - return this.finishToken(tt.string, out); - } - - jsx_readEntity() { - let str = '', count = 0, entity; - let ch = this.input[this.pos]; - if (ch !== '&') - this.raise(this.pos, 'Entity must start with an ampersand'); - let startPos = ++this.pos; - while (this.pos < this.input.length && count++ < 10) { - ch = this.input[this.pos++]; - if (ch === ';') { - if (str[0] === '#') { - if (str[1] === 'x') { - str = str.substr(2); - if (hexNumber.test(str)) - entity = String.fromCharCode(parseInt(str, 16)); + jsx_readEntity() { + let str = '', + count = 0, + entity; + let ch = this.input[this.pos]; + if (ch !== '&') this.raise(this.pos, 'Entity must start with an ampersand'); + let startPos = ++this.pos; + while (this.pos < this.input.length && count++ < 10) { + ch = this.input[this.pos++]; + if (ch === ';') { + if (str[0] === '#') { + if (str[1] === 'x') { + str = str.substr(2); + if (hexNumber.test(str)) entity = String.fromCharCode(parseInt(str, 16)); + } else { + str = str.substr(1); + if (decimalNumber.test(str)) entity = String.fromCharCode(parseInt(str, 10)); + } } else { - str = str.substr(1); - if (decimalNumber.test(str)) - entity = String.fromCharCode(parseInt(str, 10)); + entity = xhtml[str]; } - } else { - entity = xhtml[str]; + break; } - break; + str += ch; } - str += ch; - } - if (!entity) { - this.pos = startPos; - return '&'; + if (!entity) { + this.pos = startPos; + return '&'; + } + return entity; } - return entity; - } - - // Read a JSX identifier (valid tag or attribute name). - // - // Optimized version since JSX identifiers can't contain - // escape characters and so can be read as single slice. - // Also assumes that first character was already checked - // by isIdentifierStart in readToken. - - jsx_readWord() { - let ch, start = this.pos; - do { - ch = this.input.charCodeAt(++this.pos); - } while (isIdentifierChar(ch) || ch === 45); // '-' - return this.finishToken(tok.jsxName, this.input.slice(start, this.pos)); - } - - // Parse next token as JSX identifier - jsx_parseIdentifier() { - let node = this.startNode(); - if (this.type === tok.jsxName) - node.name = this.value; - else if (this.type.keyword) - node.name = this.type.keyword; - else - this.unexpected(); - this.next(); - return this.finishNode(node, 'JSXIdentifier'); - } - - // Parse namespaced identifier. - - jsx_parseNamespacedName() { - let startPos = this.start, startLoc = this.startLoc; - let name = this.jsx_parseIdentifier(); - if (!options.allowNamespaces || !this.eat(tt.colon)) return name; - var node = this.startNodeAt(startPos, startLoc); - node.namespace = name; - node.name = this.jsx_parseIdentifier(); - return this.finishNode(node, 'JSXNamespacedName'); - } + // Read a JSX identifier (valid tag or attribute name). + // + // Optimized version since JSX identifiers can't contain + // escape characters and so can be read as single slice. + // Also assumes that first character was already checked + // by isIdentifierStart in readToken. + + jsx_readWord() { + let ch, + start = this.pos; + do { + ch = this.input.charCodeAt(++this.pos); + } while (isIdentifierChar(ch) || ch === 45); // '-' + return this.finishToken(tok.jsxName, this.input.slice(start, this.pos)); + } - // Parses element name in any form - namespaced, member - // or single identifier. + // Parse next token as JSX identifier - jsx_parseElementName() { - if (this.type === tok.jsxTagEnd) return ''; - let startPos = this.start, startLoc = this.startLoc; - let node = this.jsx_parseNamespacedName(); - if (this.type === tt.dot && node.type === 'JSXNamespacedName' && !options.allowNamespacedObjects) { - this.unexpected(); + jsx_parseIdentifier() { + let node = this.startNode(); + if (this.type === tok.jsxName) node.name = this.value; + else if (this.type.keyword) node.name = this.type.keyword; + else this.unexpected(); + this.next(); + return this.finishNode(node, 'JSXIdentifier'); } - while (this.eat(tt.dot)) { - let newNode = this.startNodeAt(startPos, startLoc); - newNode.object = node; - newNode.property = this.jsx_parseIdentifier(); - node = this.finishNode(newNode, 'JSXMemberExpression'); + + // Parse namespaced identifier. + + jsx_parseNamespacedName() { + let startPos = this.start, + startLoc = this.startLoc; + let name = this.jsx_parseIdentifier(); + if (!options.allowNamespaces || !this.eat(tt.colon)) return name; + var node = this.startNodeAt(startPos, startLoc); + node.namespace = name; + node.name = this.jsx_parseIdentifier(); + return this.finishNode(node, 'JSXNamespacedName'); } - return node; - } - // Parses any type of JSX attribute value. + // Parses element name in any form - namespaced, member + // or single identifier. - jsx_parseAttributeValue() { - switch (this.type) { - case tt.braceL: - let node = this.jsx_parseExpressionContainer(); - if (node.expression.type === 'JSXEmptyExpression') - this.raise(node.start, 'JSX attributes must only be assigned a non-empty expression'); + jsx_parseElementName() { + if (this.type === tok.jsxTagEnd) return ''; + let startPos = this.start, + startLoc = this.startLoc; + let node = this.jsx_parseNamespacedName(); + if (this.type === tt.dot && node.type === 'JSXNamespacedName' && !options.allowNamespacedObjects) { + this.unexpected(); + } + while (this.eat(tt.dot)) { + let newNode = this.startNodeAt(startPos, startLoc); + newNode.object = node; + newNode.property = this.jsx_parseIdentifier(); + node = this.finishNode(newNode, 'JSXMemberExpression'); + } return node; + } - case tok.jsxTagStart: - case tt.string: - return this.parseExprAtom(); + // Parses any type of JSX attribute value. - default: - this.raise(this.start, 'JSX value should be either an expression or a quoted JSX text'); - } - } + jsx_parseAttributeValue() { + switch (this.type) { + case tt.braceL: + let node = this.jsx_parseExpressionContainer(); + if (node.expression.type === 'JSXEmptyExpression') this.raise(node.start, 'JSX attributes must only be assigned a non-empty expression'); + return node; - // JSXEmptyExpression is unique type since it doesn't actually parse anything, - // and so it should start at the end of last read token (left brace) and finish - // at the beginning of the next one (right brace). + case tok.jsxTagStart: + case tt.string: + return this.parseExprAtom(); - jsx_parseEmptyExpression() { - let node = this.startNodeAt(this.lastTokEnd, this.lastTokEndLoc); - return this.finishNodeAt(node, 'JSXEmptyExpression', this.start, this.startLoc); - } + default: + this.raise(this.start, 'JSX value should be either an expression or a quoted JSX text'); + } + } - // Parses JSX expression enclosed into curly brackets. + // JSXEmptyExpression is unique type since it doesn't actually parse anything, + // and so it should start at the end of last read token (left brace) and finish + // at the beginning of the next one (right brace). - jsx_parseExpressionContainer() { - let node = this.startNode(); - this.next(); - node.expression = this.type === tt.braceR - ? this.jsx_parseEmptyExpression() - : this.parseExpression(); - this.expect(tt.braceR); - return this.finishNode(node, 'JSXExpressionContainer'); - } + jsx_parseEmptyExpression() { + let node = this.startNodeAt(this.lastTokEnd, this.lastTokEndLoc); + return this.finishNodeAt(node, 'JSXEmptyExpression', this.start, this.startLoc); + } - // Parses following JSX attribute name-value pair. + // Parses JSX expression enclosed into curly brackets. - jsx_parseAttribute() { - let node = this.startNode(); - if (this.eat(tt.braceL)) { - this.expect(tt.ellipsis); - node.argument = this.parseMaybeAssign(); + jsx_parseExpressionContainer() { + let node = this.startNode(); + this.next(); + node.expression = this.type === tt.braceR ? this.jsx_parseEmptyExpression() : this.parseExpression(); this.expect(tt.braceR); - return this.finishNode(node, 'JSXSpreadAttribute'); + return this.finishNode(node, 'JSXExpressionContainer'); } - node.name = this.jsx_parseNamespacedName(); - node.value = this.eat(tt.eq) ? this.jsx_parseAttributeValue() : null; - return this.finishNode(node, 'JSXAttribute'); - } - - // Parses JSX opening tag starting after '<'. - jsx_parseOpeningElementAt(startPos, startLoc) { - let node = this.startNodeAt(startPos, startLoc); - node.attributes = []; - let nodeName = this.jsx_parseElementName(); - if (nodeName) node.name = nodeName; - while (this.type !== tt.slash && this.type !== tok.jsxTagEnd) - node.attributes.push(this.jsx_parseAttribute()); - node.selfClosing = this.eat(tt.slash); - this.expect(tok.jsxTagEnd); - return this.finishNode(node, nodeName ? 'JSXOpeningElement' : 'JSXOpeningFragment'); - } + // Parses following JSX attribute name-value pair. - // Parses JSX closing tag starting after '</'. + jsx_parseAttribute() { + let node = this.startNode(); + if (this.eat(tt.braceL)) { + this.expect(tt.ellipsis); + node.argument = this.parseMaybeAssign(); + this.expect(tt.braceR); + return this.finishNode(node, 'JSXSpreadAttribute'); + } + node.name = this.jsx_parseNamespacedName(); + node.value = this.eat(tt.eq) ? this.jsx_parseAttributeValue() : null; + return this.finishNode(node, 'JSXAttribute'); + } - jsx_parseClosingElementAt(startPos, startLoc) { - let node = this.startNodeAt(startPos, startLoc); - let nodeName = this.jsx_parseElementName(); - if (nodeName) node.name = nodeName; - this.expect(tok.jsxTagEnd); - return this.finishNode(node, nodeName ? 'JSXClosingElement' : 'JSXClosingFragment'); - } + // Parses JSX opening tag starting after '<'. + + jsx_parseOpeningElementAt(startPos, startLoc) { + let node = this.startNodeAt(startPos, startLoc); + node.attributes = []; + let nodeName = this.jsx_parseElementName(); + if (nodeName) node.name = nodeName; + while (this.type !== tt.slash && this.type !== tok.jsxTagEnd) node.attributes.push(this.jsx_parseAttribute()); + node.selfClosing = this.eat(tt.slash); + this.expect(tok.jsxTagEnd); + return this.finishNode(node, nodeName ? 'JSXOpeningElement' : 'JSXOpeningFragment'); + } - // Parses entire JSX element, including it's opening tag - // (starting after '<'), attributes, contents and closing tag. + // Parses JSX closing tag starting after '</'. - jsx_parseElementAt(startPos, startLoc) { - let node = this.startNodeAt(startPos, startLoc); - let children = []; - let openingElement = this.jsx_parseOpeningElementAt(startPos, startLoc); - let closingElement = null; + jsx_parseClosingElementAt(startPos, startLoc) { + let node = this.startNodeAt(startPos, startLoc); + let nodeName = this.jsx_parseElementName(); + if (nodeName) node.name = nodeName; + this.expect(tok.jsxTagEnd); + return this.finishNode(node, nodeName ? 'JSXClosingElement' : 'JSXClosingFragment'); + } - if (!openingElement.selfClosing) { - contents: for (;;) { - switch (this.type) { - case tok.jsxTagStart: - startPos = this.start; startLoc = this.startLoc; - this.next(); - if (this.eat(tt.slash)) { - closingElement = this.jsx_parseClosingElementAt(startPos, startLoc); - break contents; - } - children.push(this.jsx_parseElementAt(startPos, startLoc)); - break; + // Parses entire JSX element, including it's opening tag + // (starting after '<'), attributes, contents and closing tag. + + jsx_parseElementAt(startPos, startLoc) { + let node = this.startNodeAt(startPos, startLoc); + let children = []; + let openingElement = this.jsx_parseOpeningElementAt(startPos, startLoc); + let closingElement = null; + + if (!openingElement.selfClosing) { + contents: for (;;) { + switch (this.type) { + case tok.jsxTagStart: + startPos = this.start; + startLoc = this.startLoc; + this.next(); + if (this.eat(tt.slash)) { + closingElement = this.jsx_parseClosingElementAt(startPos, startLoc); + break contents; + } + children.push(this.jsx_parseElementAt(startPos, startLoc)); + break; - case tok.jsxText: - children.push(this.parseExprAtom()); - break; + case tok.jsxText: + children.push(this.parseExprAtom()); + break; - case tt.braceL: - children.push(this.jsx_parseExpressionContainer()); - break; + case tt.braceL: + children.push(this.jsx_parseExpressionContainer()); + break; - default: - this.unexpected(); + default: + this.unexpected(); + } + } + if (getQualifiedJSXName(closingElement.name) !== getQualifiedJSXName(openingElement.name)) { + this.raise(closingElement.start, 'Expected corresponding JSX closing tag for <' + getQualifiedJSXName(openingElement.name) + '>'); } } - if (getQualifiedJSXName(closingElement.name) !== getQualifiedJSXName(openingElement.name)) { - this.raise( - closingElement.start, - 'Expected corresponding JSX closing tag for <' + getQualifiedJSXName(openingElement.name) + '>'); + let fragmentOrElement = openingElement.name ? 'Element' : 'Fragment'; + + node['opening' + fragmentOrElement] = openingElement; + node['closing' + fragmentOrElement] = closingElement; + node.children = children; + if (this.type === tt.relational && this.value === '<') { + this.raise(this.start, 'Adjacent JSX elements must be wrapped in an enclosing tag'); } + return this.finishNode(node, 'JSX' + fragmentOrElement); } - let fragmentOrElement = openingElement.name ? 'Element' : 'Fragment'; - node['opening' + fragmentOrElement] = openingElement; - node['closing' + fragmentOrElement] = closingElement; - node.children = children; - if (this.type === tt.relational && this.value === "<") { - this.raise(this.start, "Adjacent JSX elements must be wrapped in an enclosing tag"); + // Parse JSX text + + jsx_parseText() { + let node = this.parseLiteral(this.value); + node.type = 'JSXText'; + return node; } - return this.finishNode(node, 'JSX' + fragmentOrElement); - } - // Parse JSX text + // Parses entire JSX element from current position. - jsx_parseText() { - let node = this.parseLiteral(this.value); - node.type = "JSXText"; - return node; - } + jsx_parseElement() { + let startPos = this.start, + startLoc = this.startLoc; + this.next(); + return this.jsx_parseElementAt(startPos, startLoc); + } - // Parses entire JSX element from current position. + parseExprAtom(refShortHandDefaultPos) { + if (this.type === tok.jsxText) return this.jsx_parseText(); + else if (this.type === tok.jsxTagStart) return this.jsx_parseElement(); + else return super.parseExprAtom(refShortHandDefaultPos); + } - jsx_parseElement() { - let startPos = this.start, startLoc = this.startLoc; - this.next(); - return this.jsx_parseElementAt(startPos, startLoc); - } + readToken(code) { + let context = this.curContext(); - parseExprAtom(refShortHandDefaultPos) { - if (this.type === tok.jsxText) - return this.jsx_parseText(); - else if (this.type === tok.jsxTagStart) - return this.jsx_parseElement(); - else - return super.parseExprAtom(refShortHandDefaultPos); - } + if (context === tc_expr) return this.jsx_readToken(); - readToken(code) { - let context = this.curContext(); + if (context === tc_oTag || context === tc_cTag) { + if (isIdentifierStart(code)) return this.jsx_readWord(); - if (context === tc_expr) return this.jsx_readToken(); + if (code == 62) { + ++this.pos; + return this.finishToken(tok.jsxTagEnd); + } - if (context === tc_oTag || context === tc_cTag) { - if (isIdentifierStart(code)) return this.jsx_readWord(); + if ((code === 34 || code === 39) && context == tc_oTag) return this.jsx_readString(code); + } - if (code == 62) { + if (code === 60 && this.exprAllowed && this.input.charCodeAt(this.pos + 1) !== 33) { ++this.pos; - return this.finishToken(tok.jsxTagEnd); + return this.finishToken(tok.jsxTagStart); } - - if ((code === 34 || code === 39) && context == tc_oTag) - return this.jsx_readString(code); + return super.readToken(code); } - if (code === 60 && this.exprAllowed && this.input.charCodeAt(this.pos + 1) !== 33) { - ++this.pos; - return this.finishToken(tok.jsxTagStart); - } - return super.readToken(code); - } - - updateContext(prevType) { - if (this.type == tt.braceL) { - var curContext = this.curContext(); - if (curContext == tc_oTag) this.context.push(tokContexts.b_expr); - else if (curContext == tc_expr) this.context.push(tokContexts.b_tmpl); - else super.updateContext(prevType); - this.exprAllowed = true; - } else if (this.type === tt.slash && prevType === tok.jsxTagStart) { - this.context.length -= 2; // do not consider JSX expr -> JSX open tag -> ... anymore - this.context.push(tc_cTag); // reconsider as closing tag context - this.exprAllowed = false; - } else { - return super.updateContext(prevType); + updateContext(prevType) { + if (this.type == tt.braceL) { + var curContext = this.curContext(); + if (curContext == tc_oTag) this.context.push(tokContexts.b_expr); + else if (curContext == tc_expr) this.context.push(tokContexts.b_tmpl); + else super.updateContext(prevType); + this.exprAllowed = true; + } else if (this.type === tt.slash && prevType === tok.jsxTagStart) { + this.context.length -= 2; // do not consider JSX expr -> JSX open tag -> ... anymore + this.context.push(tc_cTag); // reconsider as closing tag context + this.exprAllowed = false; + } else { + return super.updateContext(prevType); + } } - } - }; -} + }; + } }); const acornJsx$1 = acorn.Parser.extend(acornJsx()); -const parse = (source) => acorn.parse(source, { - sourceType: 'module', - ecmaVersion: 2020, - locations: true -}); +const parse = (source) => + acorn.parse(source, { + sourceType: 'module', + ecmaVersion: 2020, + locations: true, + }); -const parse_expression_at = (source, index) => acornJsx$1.parseExpressionAt(source, index, { - sourceType: 'module', - ecmaVersion: 2020, - locations: true -}); +const parse_expression_at = (source, index) => + acornJsx$1.parseExpressionAt(source, index, { + sourceType: 'module', + ecmaVersion: 2020, + locations: true, + }); const whitespace = /[ \t\r\n]/; @@ -848,2413 +829,2417 @@ const dimensions = /^(?:offset|client)(?:Width|Height)$/; // import { Node } from 'estree'; function read_expression(parser) { - try { - const node = parse_expression_at(parser.template, parser.index); + try { + const node = parse_expression_at(parser.template, parser.index); - let num_parens = 0; + let num_parens = 0; - for (let i = parser.index; i < node.start; i += 1) { - if (parser.template[i] === '(') num_parens += 1; - } + for (let i = parser.index; i < node.start; i += 1) { + if (parser.template[i] === '(') num_parens += 1; + } - let index = node.end; - while (num_parens > 0) { - const char = parser.template[index]; - - if (char === ')') { - num_parens -= 1; - } else if (!whitespace.test(char)) { - parser.error({ - code: 'unexpected-token', - message: 'Expected )' - }, index); - } + let index = node.end; + while (num_parens > 0) { + const char = parser.template[index]; + + if (char === ')') { + num_parens -= 1; + } else if (!whitespace.test(char)) { + parser.error( + { + code: 'unexpected-token', + message: 'Expected )', + }, + index + ); + } - index += 1; - } + index += 1; + } + + parser.index = index; - parser.index = index; - - return parser.template.substring(node.start, node.end); - // return node as Node; - } catch (err) { - parser.acorn_error(err); - } + return parser.template.substring(node.start, node.end); + // return node as Node; + } catch (err) { + parser.acorn_error(err); + } } const script_closing_tag = '</script>'; function get_context(parser, attributes, start) { - const context = attributes.find(attribute => attribute.name === 'context'); - if (!context) return 'default'; - - if (context.value.length !== 1 || context.value[0].type !== 'Text') { - parser.error({ - code: 'invalid-script', - message: 'context attribute must be static' - }, start); - } + const context = attributes.find((attribute) => attribute.name === 'context'); + if (!context) return 'default'; + + if (context.value.length !== 1 || context.value[0].type !== 'Text') { + parser.error( + { + code: 'invalid-script', + message: 'context attribute must be static', + }, + start + ); + } - const value = context.value[0].data; + const value = context.value[0].data; - if (value !== 'module') { - parser.error({ - code: 'invalid-script', - message: 'If the context attribute is supplied, its value must be "module"' - }, context.start); - } + if (value !== 'module') { + parser.error( + { + code: 'invalid-script', + message: 'If the context attribute is supplied, its value must be "module"', + }, + context.start + ); + } - return value; + return value; } function read_script(parser, start, attributes) { - const script_start = parser.index; - const script_end = parser.template.indexOf(script_closing_tag, script_start); + const script_start = parser.index; + const script_end = parser.template.indexOf(script_closing_tag, script_start); - if (script_end === -1) { - parser.error({ - code: 'unclosed-script', - message: '<script> must have a closing tag' - }); - } + if (script_end === -1) { + parser.error({ + code: 'unclosed-script', + message: '<script> must have a closing tag', + }); + } - const source = parser.template.slice(0, script_start).replace(/[^\n]/g, ' ') + - parser.template.slice(script_start, script_end); - parser.index = script_end + script_closing_tag.length; + const source = parser.template.slice(0, script_start).replace(/[^\n]/g, ' ') + parser.template.slice(script_start, script_end); + parser.index = script_end + script_closing_tag.length; - let ast; + let ast; - try { - ast = parse(source) ; - } catch (err) { - parser.acorn_error(err); - } + try { + ast = parse(source); + } catch (err) { + parser.acorn_error(err); + } - // TODO is this necessary? - (ast ).start = script_start; + // TODO is this necessary? + ast.start = script_start; - return { - type: 'Script', - start, - end: parser.index, - context: get_context(parser, attributes, start), - content: ast - }; + return { + type: 'Script', + start, + end: parser.index, + context: get_context(parser, attributes, start), + content: ast, + }; } function walk(ast, { enter, leave }) { - return visit(ast, null, enter, leave); + return visit(ast, null, enter, leave); } let should_skip = false; let should_remove = false; let replacement = null; const context = { - skip: () => should_skip = true, - remove: () => should_remove = true, - replace: (node) => replacement = node + skip: () => (should_skip = true), + remove: () => (should_remove = true), + replace: (node) => (replacement = node), }; function replace(parent, prop, index, node) { - if (parent) { - if (index !== null) { - parent[prop][index] = node; - } else { - parent[prop] = node; - } - } + if (parent) { + if (index !== null) { + parent[prop][index] = node; + } else { + parent[prop] = node; + } + } } function remove(parent, prop, index) { - if (parent) { - if (index !== null) { - parent[prop].splice(index, 1); - } else { - delete parent[prop]; - } - } -} - -function visit( - node, - parent, - enter, - leave, - prop, - index -) { - if (node) { - if (enter) { - const _should_skip = should_skip; - const _should_remove = should_remove; - const _replacement = replacement; - should_skip = false; - should_remove = false; - replacement = null; - - enter.call(context, node, parent, prop, index); - - if (replacement) { - node = replacement; - replace(parent, prop, index, node); - } + if (parent) { + if (index !== null) { + parent[prop].splice(index, 1); + } else { + delete parent[prop]; + } + } +} - if (should_remove) { - remove(parent, prop, index); - } +function visit(node, parent, enter, leave, prop, index) { + if (node) { + if (enter) { + const _should_skip = should_skip; + const _should_remove = should_remove; + const _replacement = replacement; + should_skip = false; + should_remove = false; + replacement = null; - const skipped = should_skip; - const removed = should_remove; + enter.call(context, node, parent, prop, index); - should_skip = _should_skip; - should_remove = _should_remove; - replacement = _replacement; + if (replacement) { + node = replacement; + replace(parent, prop, index, node); + } - if (skipped) return node; - if (removed) return null; - } + if (should_remove) { + remove(parent, prop, index); + } - for (const key in node) { - const value = (node )[key]; + const skipped = should_skip; + const removed = should_remove; - if (typeof value !== 'object') { - continue; - } + should_skip = _should_skip; + should_remove = _should_remove; + replacement = _replacement; - else if (Array.isArray(value)) { - for (let j = 0, k = 0; j < value.length; j += 1, k += 1) { - if (value[j] !== null && typeof value[j].type === 'string') { - if (!visit(value[j], node, enter, leave, key, k)) { - // removed - j--; - } - } - } - } + if (skipped) return node; + if (removed) return null; + } - else if (value !== null && typeof value.type === 'string') { - visit(value, node, enter, leave, key, null); - } - } + for (const key in node) { + const value = node[key]; + + if (typeof value !== 'object') { + continue; + } else if (Array.isArray(value)) { + for (let j = 0, k = 0; j < value.length; j += 1, k += 1) { + if (value[j] !== null && typeof value[j].type === 'string') { + if (!visit(value[j], node, enter, leave, key, k)) { + // removed + j--; + } + } + } + } else if (value !== null && typeof value.type === 'string') { + visit(value, node, enter, leave, key, null); + } + } - if (leave) { - const _replacement = replacement; - const _should_remove = should_remove; - replacement = null; - should_remove = false; + if (leave) { + const _replacement = replacement; + const _should_remove = should_remove; + replacement = null; + should_remove = false; - leave.call(context, node, parent, prop, index); + leave.call(context, node, parent, prop, index); - if (replacement) { - node = replacement; - replace(parent, prop, index, node); - } + if (replacement) { + node = replacement; + replace(parent, prop, index, node); + } - if (should_remove) { - remove(parent, prop, index); - } + if (should_remove) { + remove(parent, prop, index); + } - const removed = should_remove; + const removed = should_remove; - replacement = _replacement; - should_remove = _should_remove; + replacement = _replacement; + should_remove = _should_remove; - if (removed) return null; - } - } + if (removed) return null; + } + } - return node; + return node; } function read_style(parser, start, attributes) { - const content_start = parser.index; - const styles = parser.read_until(/<\/style>/); - const content_end = parser.index; - - let ast; - - try { - ast = parse$2(styles, { - positions: true, - offset: content_start, - onParseError(error) { - throw error; - } - }); - } catch (err) { - if (err.name === 'SyntaxError') { - parser.error({ - code: 'css-syntax-error', - message: err.message - }, err.offset); - } else { - throw err; - } - } - - ast = JSON.parse(JSON.stringify(ast)); - - // tidy up AST - walk(ast, { - enter: (node) => { // `any` because this isn't an ESTree node - // replace `ref:a` nodes - if (node.type === 'Selector') { - for (let i = 0; i < node.children.length; i += 1) { - const a = node.children[i]; - const b = node.children[i + 1]; - - if (is_ref_selector(a, b)) { - parser.error({ - code: 'invalid-ref-selector', - message: 'ref selectors are no longer supported' - }, a.loc.start.offset); - } - } - } + const content_start = parser.index; + const styles = parser.read_until(/<\/style>/); + const content_end = parser.index; + + let ast; + + try { + ast = parse$2(styles, { + positions: true, + offset: content_start, + onParseError(error) { + throw error; + }, + }); + } catch (err) { + if (err.name === 'SyntaxError') { + parser.error( + { + code: 'css-syntax-error', + message: err.message, + }, + err.offset + ); + } else { + throw err; + } + } - if (node.type === 'Declaration' && node.value.type === 'Value' && node.value.children.length === 0) { - parser.error({ - code: 'invalid-declaration', - message: 'Declaration cannot be empty' - }, node.start); - } + ast = JSON.parse(JSON.stringify(ast)); + + // tidy up AST + walk(ast, { + enter: (node) => { + // `any` because this isn't an ESTree node + // replace `ref:a` nodes + if (node.type === 'Selector') { + for (let i = 0; i < node.children.length; i += 1) { + const a = node.children[i]; + const b = node.children[i + 1]; + + if (is_ref_selector(a, b)) { + parser.error( + { + code: 'invalid-ref-selector', + message: 'ref selectors are no longer supported', + }, + a.loc.start.offset + ); + } + } + } - if (node.type === 'PseudoClassSelector' && node.name === 'global' && node.children === null) { - parser.error({ - code: 'css-syntax-error', - message: ':global() must contain a selector' - }, node.loc.start.offset); - } + if (node.type === 'Declaration' && node.value.type === 'Value' && node.value.children.length === 0) { + parser.error( + { + code: 'invalid-declaration', + message: 'Declaration cannot be empty', + }, + node.start + ); + } - if (node.loc) { - node.start = node.loc.start.offset; - node.end = node.loc.end.offset; - delete node.loc; - } - } - }); - - parser.eat('</style>', true); - const end = parser.index; - - return { - type: 'Style', - start, - end, - attributes, - children: ast.children, - content: { - start: content_start, - end: content_end, - styles - } - }; + if (node.type === 'PseudoClassSelector' && node.name === 'global' && node.children === null) { + parser.error( + { + code: 'css-syntax-error', + message: ':global() must contain a selector', + }, + node.loc.start.offset + ); + } + + if (node.loc) { + node.start = node.loc.start.offset; + node.end = node.loc.end.offset; + delete node.loc; + } + }, + }); + + parser.eat('</style>', true); + const end = parser.index; + + return { + type: 'Style', + start, + end, + attributes, + children: ast.children, + content: { + start: content_start, + end: content_end, + styles, + }, + }; } -function is_ref_selector(a, b) { // TODO add CSS node types - if (!b) return false; +function is_ref_selector(a, b) { + // TODO add CSS node types + if (!b) return false; - return ( - a.type === 'TypeSelector' && - a.name === 'ref' && - b.type === 'PseudoClassSelector' - ); + return a.type === 'TypeSelector' && a.name === 'ref' && b.type === 'PseudoClassSelector'; } // https://dev.w3.org/html5/html-author/charref var entities = { - CounterClockwiseContourIntegral: 8755, - ClockwiseContourIntegral: 8754, - DoubleLongLeftRightArrow: 10234, - DiacriticalDoubleAcute: 733, - NotSquareSupersetEqual: 8931, - CloseCurlyDoubleQuote: 8221, - DoubleContourIntegral: 8751, - FilledVerySmallSquare: 9642, - NegativeVeryThinSpace: 8203, - NotPrecedesSlantEqual: 8928, - NotRightTriangleEqual: 8941, - NotSucceedsSlantEqual: 8929, - CapitalDifferentialD: 8517, - DoubleLeftRightArrow: 8660, - DoubleLongRightArrow: 10233, - EmptyVerySmallSquare: 9643, - NestedGreaterGreater: 8811, - NotDoubleVerticalBar: 8742, - NotLeftTriangleEqual: 8940, - NotSquareSubsetEqual: 8930, - OpenCurlyDoubleQuote: 8220, - ReverseUpEquilibrium: 10607, - DoubleLongLeftArrow: 10232, - DownLeftRightVector: 10576, - LeftArrowRightArrow: 8646, - NegativeMediumSpace: 8203, - RightArrowLeftArrow: 8644, - SquareSupersetEqual: 8850, - leftrightsquigarrow: 8621, - DownRightTeeVector: 10591, - DownRightVectorBar: 10583, - LongLeftRightArrow: 10231, - Longleftrightarrow: 10234, - NegativeThickSpace: 8203, - PrecedesSlantEqual: 8828, - ReverseEquilibrium: 8651, - RightDoubleBracket: 10215, - RightDownTeeVector: 10589, - RightDownVectorBar: 10581, - RightTriangleEqual: 8885, - SquareIntersection: 8851, - SucceedsSlantEqual: 8829, - blacktriangleright: 9656, - longleftrightarrow: 10231, - DoubleUpDownArrow: 8661, - DoubleVerticalBar: 8741, - DownLeftTeeVector: 10590, - DownLeftVectorBar: 10582, - FilledSmallSquare: 9724, - GreaterSlantEqual: 10878, - LeftDoubleBracket: 10214, - LeftDownTeeVector: 10593, - LeftDownVectorBar: 10585, - LeftTriangleEqual: 8884, - NegativeThinSpace: 8203, - NotReverseElement: 8716, - NotTildeFullEqual: 8775, - RightAngleBracket: 10217, - RightUpDownVector: 10575, - SquareSubsetEqual: 8849, - VerticalSeparator: 10072, - blacktriangledown: 9662, - blacktriangleleft: 9666, - leftrightharpoons: 8651, - rightleftharpoons: 8652, - twoheadrightarrow: 8608, - DiacriticalAcute: 180, - DiacriticalGrave: 96, - DiacriticalTilde: 732, - DoubleRightArrow: 8658, - DownArrowUpArrow: 8693, - EmptySmallSquare: 9723, - GreaterEqualLess: 8923, - GreaterFullEqual: 8807, - LeftAngleBracket: 10216, - LeftUpDownVector: 10577, - LessEqualGreater: 8922, - NonBreakingSpace: 160, - NotRightTriangle: 8939, - NotSupersetEqual: 8841, - RightTriangleBar: 10704, - RightUpTeeVector: 10588, - RightUpVectorBar: 10580, - UnderParenthesis: 9181, - UpArrowDownArrow: 8645, - circlearrowright: 8635, - downharpoonright: 8642, - ntrianglerighteq: 8941, - rightharpoondown: 8641, - rightrightarrows: 8649, - twoheadleftarrow: 8606, - vartriangleright: 8883, - CloseCurlyQuote: 8217, - ContourIntegral: 8750, - DoubleDownArrow: 8659, - DoubleLeftArrow: 8656, - DownRightVector: 8641, - LeftRightVector: 10574, - LeftTriangleBar: 10703, - LeftUpTeeVector: 10592, - LeftUpVectorBar: 10584, - LowerRightArrow: 8600, - NotGreaterEqual: 8817, - NotGreaterTilde: 8821, - NotLeftTriangle: 8938, - OverParenthesis: 9180, - RightDownVector: 8642, - ShortRightArrow: 8594, - UpperRightArrow: 8599, - bigtriangledown: 9661, - circlearrowleft: 8634, - curvearrowright: 8631, - downharpoonleft: 8643, - leftharpoondown: 8637, - leftrightarrows: 8646, - nLeftrightarrow: 8654, - nleftrightarrow: 8622, - ntrianglelefteq: 8940, - rightleftarrows: 8644, - rightsquigarrow: 8605, - rightthreetimes: 8908, - straightepsilon: 1013, - trianglerighteq: 8885, - vartriangleleft: 8882, - DiacriticalDot: 729, - DoubleRightTee: 8872, - DownLeftVector: 8637, - GreaterGreater: 10914, - HorizontalLine: 9472, - InvisibleComma: 8291, - InvisibleTimes: 8290, - LeftDownVector: 8643, - LeftRightArrow: 8596, - Leftrightarrow: 8660, - LessSlantEqual: 10877, - LongRightArrow: 10230, - Longrightarrow: 10233, - LowerLeftArrow: 8601, - NestedLessLess: 8810, - NotGreaterLess: 8825, - NotLessGreater: 8824, - NotSubsetEqual: 8840, - NotVerticalBar: 8740, - OpenCurlyQuote: 8216, - ReverseElement: 8715, - RightTeeVector: 10587, - RightVectorBar: 10579, - ShortDownArrow: 8595, - ShortLeftArrow: 8592, - SquareSuperset: 8848, - TildeFullEqual: 8773, - UpperLeftArrow: 8598, - ZeroWidthSpace: 8203, - curvearrowleft: 8630, - doublebarwedge: 8966, - downdownarrows: 8650, - hookrightarrow: 8618, - leftleftarrows: 8647, - leftrightarrow: 8596, - leftthreetimes: 8907, - longrightarrow: 10230, - looparrowright: 8620, - nshortparallel: 8742, - ntriangleright: 8939, - rightarrowtail: 8611, - rightharpoonup: 8640, - trianglelefteq: 8884, - upharpoonright: 8638, - ApplyFunction: 8289, - DifferentialD: 8518, - DoubleLeftTee: 10980, - DoubleUpArrow: 8657, - LeftTeeVector: 10586, - LeftVectorBar: 10578, - LessFullEqual: 8806, - LongLeftArrow: 10229, - Longleftarrow: 10232, - NotTildeEqual: 8772, - NotTildeTilde: 8777, - Poincareplane: 8460, - PrecedesEqual: 10927, - PrecedesTilde: 8830, - RightArrowBar: 8677, - RightTeeArrow: 8614, - RightTriangle: 8883, - RightUpVector: 8638, - SucceedsEqual: 10928, - SucceedsTilde: 8831, - SupersetEqual: 8839, - UpEquilibrium: 10606, - VerticalTilde: 8768, - VeryThinSpace: 8202, - bigtriangleup: 9651, - blacktriangle: 9652, - divideontimes: 8903, - fallingdotseq: 8786, - hookleftarrow: 8617, - leftarrowtail: 8610, - leftharpoonup: 8636, - longleftarrow: 10229, - looparrowleft: 8619, - measuredangle: 8737, - ntriangleleft: 8938, - shortparallel: 8741, - smallsetminus: 8726, - triangleright: 9657, - upharpoonleft: 8639, - DownArrowBar: 10515, - DownTeeArrow: 8615, - ExponentialE: 8519, - GreaterEqual: 8805, - GreaterTilde: 8819, - HilbertSpace: 8459, - HumpDownHump: 8782, - Intersection: 8898, - LeftArrowBar: 8676, - LeftTeeArrow: 8612, - LeftTriangle: 8882, - LeftUpVector: 8639, - NotCongruent: 8802, - NotLessEqual: 8816, - NotLessTilde: 8820, - Proportional: 8733, - RightCeiling: 8969, - RoundImplies: 10608, - ShortUpArrow: 8593, - SquareSubset: 8847, - UnderBracket: 9141, - VerticalLine: 124, - blacklozenge: 10731, - exponentiale: 8519, - risingdotseq: 8787, - triangledown: 9663, - triangleleft: 9667, - CircleMinus: 8854, - CircleTimes: 8855, - Equilibrium: 8652, - GreaterLess: 8823, - LeftCeiling: 8968, - LessGreater: 8822, - MediumSpace: 8287, - NotPrecedes: 8832, - NotSucceeds: 8833, - OverBracket: 9140, - RightVector: 8640, - Rrightarrow: 8667, - RuleDelayed: 10740, - SmallCircle: 8728, - SquareUnion: 8852, - SubsetEqual: 8838, - UpDownArrow: 8597, - Updownarrow: 8661, - VerticalBar: 8739, - backepsilon: 1014, - blacksquare: 9642, - circledcirc: 8858, - circleddash: 8861, - curlyeqprec: 8926, - curlyeqsucc: 8927, - diamondsuit: 9830, - eqslantless: 10901, - expectation: 8496, - nRightarrow: 8655, - nrightarrow: 8603, - preccurlyeq: 8828, - precnapprox: 10937, - quaternions: 8461, - straightphi: 981, - succcurlyeq: 8829, - succnapprox: 10938, - thickapprox: 8776, - updownarrow: 8597, - Bernoullis: 8492, - CirclePlus: 8853, - EqualTilde: 8770, - Fouriertrf: 8497, - ImaginaryI: 8520, - Laplacetrf: 8466, - LeftVector: 8636, - Lleftarrow: 8666, - NotElement: 8713, - NotGreater: 8815, - Proportion: 8759, - RightArrow: 8594, - RightFloor: 8971, - Rightarrow: 8658, - TildeEqual: 8771, - TildeTilde: 8776, - UnderBrace: 9183, - UpArrowBar: 10514, - UpTeeArrow: 8613, - circledast: 8859, - complement: 8705, - curlywedge: 8911, - eqslantgtr: 10902, - gtreqqless: 10892, - lessapprox: 10885, - lesseqqgtr: 10891, - lmoustache: 9136, - longmapsto: 10236, - mapstodown: 8615, - mapstoleft: 8612, - nLeftarrow: 8653, - nleftarrow: 8602, - precapprox: 10935, - rightarrow: 8594, - rmoustache: 9137, - sqsubseteq: 8849, - sqsupseteq: 8850, - subsetneqq: 10955, - succapprox: 10936, - supsetneqq: 10956, - upuparrows: 8648, - varepsilon: 949, - varnothing: 8709, - Backslash: 8726, - CenterDot: 183, - CircleDot: 8857, - Congruent: 8801, - Coproduct: 8720, - DoubleDot: 168, - DownArrow: 8595, - DownBreve: 785, - Downarrow: 8659, - HumpEqual: 8783, - LeftArrow: 8592, - LeftFloor: 8970, - Leftarrow: 8656, - LessTilde: 8818, - Mellintrf: 8499, - MinusPlus: 8723, - NotCupCap: 8813, - NotExists: 8708, - OverBrace: 9182, - PlusMinus: 177, - Therefore: 8756, - ThinSpace: 8201, - TripleDot: 8411, - UnionPlus: 8846, - backprime: 8245, - backsimeq: 8909, - bigotimes: 10754, - centerdot: 183, - checkmark: 10003, - complexes: 8450, - dotsquare: 8865, - downarrow: 8595, - gtrapprox: 10886, - gtreqless: 8923, - heartsuit: 9829, - leftarrow: 8592, - lesseqgtr: 8922, - nparallel: 8742, - nshortmid: 8740, - nsubseteq: 8840, - nsupseteq: 8841, - pitchfork: 8916, - rationals: 8474, - spadesuit: 9824, - subseteqq: 10949, - subsetneq: 8842, - supseteqq: 10950, - supsetneq: 8843, - therefore: 8756, - triangleq: 8796, - varpropto: 8733, - DDotrahd: 10513, - DotEqual: 8784, - Integral: 8747, - LessLess: 10913, - NotEqual: 8800, - NotTilde: 8769, - PartialD: 8706, - Precedes: 8826, - RightTee: 8866, - Succeeds: 8827, - SuchThat: 8715, - Superset: 8835, - Uarrocir: 10569, - UnderBar: 818, - andslope: 10840, - angmsdaa: 10664, - angmsdab: 10665, - angmsdac: 10666, - angmsdad: 10667, - angmsdae: 10668, - angmsdaf: 10669, - angmsdag: 10670, - angmsdah: 10671, - angrtvbd: 10653, - approxeq: 8778, - awconint: 8755, - backcong: 8780, - barwedge: 8965, - bbrktbrk: 9142, - bigoplus: 10753, - bigsqcup: 10758, - biguplus: 10756, - bigwedge: 8896, - boxminus: 8863, - boxtimes: 8864, - capbrcup: 10825, - circledR: 174, - circledS: 9416, - cirfnint: 10768, - clubsuit: 9827, - cupbrcap: 10824, - curlyvee: 8910, - cwconint: 8754, - doteqdot: 8785, - dotminus: 8760, - drbkarow: 10512, - dzigrarr: 10239, - elinters: 9191, - emptyset: 8709, - eqvparsl: 10725, - fpartint: 10765, - geqslant: 10878, - gesdotol: 10884, - gnapprox: 10890, - hksearow: 10533, - hkswarow: 10534, - imagline: 8464, - imagpart: 8465, - infintie: 10717, - integers: 8484, - intercal: 8890, - intlarhk: 10775, - laemptyv: 10676, - ldrushar: 10571, - leqslant: 10877, - lesdotor: 10883, - llcorner: 8990, - lnapprox: 10889, - lrcorner: 8991, - lurdshar: 10570, - mapstoup: 8613, - multimap: 8888, - naturals: 8469, - otimesas: 10806, - parallel: 8741, - plusacir: 10787, - pointint: 10773, - precneqq: 10933, - precnsim: 8936, - profalar: 9006, - profline: 8978, - profsurf: 8979, - raemptyv: 10675, - realpart: 8476, - rppolint: 10770, - rtriltri: 10702, - scpolint: 10771, - setminus: 8726, - shortmid: 8739, - smeparsl: 10724, - sqsubset: 8847, - sqsupset: 8848, - subseteq: 8838, - succneqq: 10934, - succnsim: 8937, - supseteq: 8839, - thetasym: 977, - thicksim: 8764, - timesbar: 10801, - triangle: 9653, - triminus: 10810, - trpezium: 9186, - ulcorner: 8988, - urcorner: 8989, - varkappa: 1008, - varsigma: 962, - vartheta: 977, - Because: 8757, - Cayleys: 8493, - Cconint: 8752, - Cedilla: 184, - Diamond: 8900, - DownTee: 8868, - Element: 8712, - Epsilon: 917, - Implies: 8658, - LeftTee: 8867, - NewLine: 10, - NoBreak: 8288, - NotLess: 8814, - Omicron: 927, - OverBar: 175, - Product: 8719, - UpArrow: 8593, - Uparrow: 8657, - Upsilon: 933, - alefsym: 8501, - angrtvb: 8894, - angzarr: 9084, - asympeq: 8781, - backsim: 8765, - because: 8757, - bemptyv: 10672, - between: 8812, - bigcirc: 9711, - bigodot: 10752, - bigstar: 9733, - boxplus: 8862, - ccupssm: 10832, - cemptyv: 10674, - cirscir: 10690, - coloneq: 8788, - congdot: 10861, - cudarrl: 10552, - cudarrr: 10549, - cularrp: 10557, - curarrm: 10556, - dbkarow: 10511, - ddagger: 8225, - ddotseq: 10871, - demptyv: 10673, - diamond: 8900, - digamma: 989, - dotplus: 8724, - dwangle: 10662, - epsilon: 949, - eqcolon: 8789, - equivDD: 10872, - gesdoto: 10882, - gtquest: 10876, - gtrless: 8823, - harrcir: 10568, - intprod: 10812, - isindot: 8949, - larrbfs: 10527, - larrsim: 10611, - lbrksld: 10639, - lbrkslu: 10637, - ldrdhar: 10599, - lesdoto: 10881, - lessdot: 8918, - lessgtr: 8822, - lesssim: 8818, - lotimes: 10804, - lozenge: 9674, - ltquest: 10875, - luruhar: 10598, - maltese: 10016, - minusdu: 10794, - napprox: 8777, - natural: 9838, - nearrow: 8599, - nexists: 8708, - notinva: 8713, - notinvb: 8951, - notinvc: 8950, - notniva: 8716, - notnivb: 8958, - notnivc: 8957, - npolint: 10772, - nsqsube: 8930, - nsqsupe: 8931, - nvinfin: 10718, - nwarrow: 8598, - olcross: 10683, - omicron: 959, - orderof: 8500, - orslope: 10839, - pertenk: 8241, - planckh: 8462, - pluscir: 10786, - plussim: 10790, - plustwo: 10791, - precsim: 8830, - quatint: 10774, - questeq: 8799, - rarrbfs: 10528, - rarrsim: 10612, - rbrksld: 10638, - rbrkslu: 10640, - rdldhar: 10601, - realine: 8475, - rotimes: 10805, - ruluhar: 10600, - searrow: 8600, - simplus: 10788, - simrarr: 10610, - subedot: 10947, - submult: 10945, - subplus: 10943, - subrarr: 10617, - succsim: 8831, - supdsub: 10968, - supedot: 10948, - suphsub: 10967, - suplarr: 10619, - supmult: 10946, - supplus: 10944, - swarrow: 8601, - topfork: 10970, - triplus: 10809, - tritime: 10811, - uparrow: 8593, - upsilon: 965, - uwangle: 10663, - vzigzag: 10650, - zigrarr: 8669, - Aacute: 193, - Abreve: 258, - Agrave: 192, - Assign: 8788, - Atilde: 195, - Barwed: 8966, - Bumpeq: 8782, - Cacute: 262, - Ccaron: 268, - Ccedil: 199, - Colone: 10868, - Conint: 8751, - CupCap: 8781, - Dagger: 8225, - Dcaron: 270, - DotDot: 8412, - Dstrok: 272, - Eacute: 201, - Ecaron: 282, - Egrave: 200, - Exists: 8707, - ForAll: 8704, - Gammad: 988, - Gbreve: 286, - Gcedil: 290, - HARDcy: 1066, - Hstrok: 294, - Iacute: 205, - Igrave: 204, - Itilde: 296, - Jsercy: 1032, - Kcedil: 310, - Lacute: 313, - Lambda: 923, - Lcaron: 317, - Lcedil: 315, - Lmidot: 319, - Lstrok: 321, - Nacute: 323, - Ncaron: 327, - Ncedil: 325, - Ntilde: 209, - Oacute: 211, - Odblac: 336, - Ograve: 210, - Oslash: 216, - Otilde: 213, - Otimes: 10807, - Racute: 340, - Rarrtl: 10518, - Rcaron: 344, - Rcedil: 342, - SHCHcy: 1065, - SOFTcy: 1068, - Sacute: 346, - Scaron: 352, - Scedil: 350, - Square: 9633, - Subset: 8912, - Supset: 8913, - Tcaron: 356, - Tcedil: 354, - Tstrok: 358, - Uacute: 218, - Ubreve: 364, - Udblac: 368, - Ugrave: 217, - Utilde: 360, - Vdashl: 10982, - Verbar: 8214, - Vvdash: 8874, - Yacute: 221, - Zacute: 377, - Zcaron: 381, - aacute: 225, - abreve: 259, - agrave: 224, - andand: 10837, - angmsd: 8737, - angsph: 8738, - apacir: 10863, - approx: 8776, - atilde: 227, - barvee: 8893, - barwed: 8965, - becaus: 8757, - bernou: 8492, - bigcap: 8898, - bigcup: 8899, - bigvee: 8897, - bkarow: 10509, - bottom: 8869, - bowtie: 8904, - boxbox: 10697, - bprime: 8245, - brvbar: 166, - bullet: 8226, - bumpeq: 8783, - cacute: 263, - capand: 10820, - capcap: 10827, - capcup: 10823, - capdot: 10816, - ccaron: 269, - ccedil: 231, - circeq: 8791, - cirmid: 10991, - colone: 8788, - commat: 64, - compfn: 8728, - conint: 8750, - coprod: 8720, - copysr: 8471, - cularr: 8630, - cupcap: 10822, - cupcup: 10826, - cupdot: 8845, - curarr: 8631, - curren: 164, - cylcty: 9005, - dagger: 8224, - daleth: 8504, - dcaron: 271, - dfisht: 10623, - divide: 247, - divonx: 8903, - dlcorn: 8990, - dlcrop: 8973, - dollar: 36, - drcorn: 8991, - drcrop: 8972, - dstrok: 273, - eacute: 233, - easter: 10862, - ecaron: 283, - ecolon: 8789, - egrave: 232, - egsdot: 10904, - elsdot: 10903, - emptyv: 8709, - emsp13: 8196, - emsp14: 8197, - eparsl: 10723, - eqcirc: 8790, - equals: 61, - equest: 8799, - female: 9792, - ffilig: 64259, - ffllig: 64260, - forall: 8704, - frac12: 189, - frac13: 8531, - frac14: 188, - frac15: 8533, - frac16: 8537, - frac18: 8539, - frac23: 8532, - frac25: 8534, - frac34: 190, - frac35: 8535, - frac38: 8540, - frac45: 8536, - frac56: 8538, - frac58: 8541, - frac78: 8542, - gacute: 501, - gammad: 989, - gbreve: 287, - gesdot: 10880, - gesles: 10900, - gtlPar: 10645, - gtrarr: 10616, - gtrdot: 8919, - gtrsim: 8819, - hairsp: 8202, - hamilt: 8459, - hardcy: 1098, - hearts: 9829, - hellip: 8230, - hercon: 8889, - homtht: 8763, - horbar: 8213, - hslash: 8463, - hstrok: 295, - hybull: 8259, - hyphen: 8208, - iacute: 237, - igrave: 236, - iiiint: 10764, - iinfin: 10716, - incare: 8453, - inodot: 305, - intcal: 8890, - iquest: 191, - isinsv: 8947, - itilde: 297, - jsercy: 1112, - kappav: 1008, - kcedil: 311, - kgreen: 312, - lAtail: 10523, - lacute: 314, - lagran: 8466, - lambda: 955, - langle: 10216, - larrfs: 10525, - larrhk: 8617, - larrlp: 8619, - larrpl: 10553, - larrtl: 8610, - latail: 10521, - lbrace: 123, - lbrack: 91, - lcaron: 318, - lcedil: 316, - ldquor: 8222, - lesdot: 10879, - lesges: 10899, - lfisht: 10620, - lfloor: 8970, - lharul: 10602, - llhard: 10603, - lmidot: 320, - lmoust: 9136, - loplus: 10797, - lowast: 8727, - lowbar: 95, - lparlt: 10643, - lrhard: 10605, - lsaquo: 8249, - lsquor: 8218, - lstrok: 322, - lthree: 8907, - ltimes: 8905, - ltlarr: 10614, - ltrPar: 10646, - mapsto: 8614, - marker: 9646, - mcomma: 10793, - midast: 42, - midcir: 10992, - middot: 183, - minusb: 8863, - minusd: 8760, - mnplus: 8723, - models: 8871, - mstpos: 8766, - nVDash: 8879, - nVdash: 8878, - nacute: 324, - ncaron: 328, - ncedil: 326, - nearhk: 10532, - nequiv: 8802, - nesear: 10536, - nexist: 8708, - nltrie: 8940, - nprcue: 8928, - nrtrie: 8941, - nsccue: 8929, - nsimeq: 8772, - ntilde: 241, - numero: 8470, - nvDash: 8877, - nvHarr: 10500, - nvdash: 8876, - nvlArr: 10498, - nvrArr: 10499, - nwarhk: 10531, - nwnear: 10535, - oacute: 243, - odblac: 337, - odsold: 10684, - ograve: 242, - ominus: 8854, - origof: 8886, - oslash: 248, - otilde: 245, - otimes: 8855, - parsim: 10995, - percnt: 37, - period: 46, - permil: 8240, - phmmat: 8499, - planck: 8463, - plankv: 8463, - plusdo: 8724, - plusdu: 10789, - plusmn: 177, - preceq: 10927, - primes: 8473, - prnsim: 8936, - propto: 8733, - prurel: 8880, - puncsp: 8200, - qprime: 8279, - rAtail: 10524, - racute: 341, - rangle: 10217, - rarrap: 10613, - rarrfs: 10526, - rarrhk: 8618, - rarrlp: 8620, - rarrpl: 10565, - rarrtl: 8611, - ratail: 10522, - rbrace: 125, - rbrack: 93, - rcaron: 345, - rcedil: 343, - rdquor: 8221, - rfisht: 10621, - rfloor: 8971, - rharul: 10604, - rmoust: 9137, - roplus: 10798, - rpargt: 10644, - rsaquo: 8250, - rsquor: 8217, - rthree: 8908, - rtimes: 8906, - sacute: 347, - scaron: 353, - scedil: 351, - scnsim: 8937, - searhk: 10533, - seswar: 10537, - sfrown: 8994, - shchcy: 1097, - sigmaf: 962, - sigmav: 962, - simdot: 10858, - smashp: 10803, - softcy: 1100, - solbar: 9023, - spades: 9824, - sqsube: 8849, - sqsupe: 8850, - square: 9633, - squarf: 9642, - ssetmn: 8726, - ssmile: 8995, - sstarf: 8902, - subdot: 10941, - subset: 8834, - subsim: 10951, - subsub: 10965, - subsup: 10963, - succeq: 10928, - supdot: 10942, - supset: 8835, - supsim: 10952, - supsub: 10964, - supsup: 10966, - swarhk: 10534, - swnwar: 10538, - target: 8982, - tcaron: 357, - tcedil: 355, - telrec: 8981, - there4: 8756, - thetav: 977, - thinsp: 8201, - thksim: 8764, - timesb: 8864, - timesd: 10800, - topbot: 9014, - topcir: 10993, - tprime: 8244, - tridot: 9708, - tstrok: 359, - uacute: 250, - ubreve: 365, - udblac: 369, - ufisht: 10622, - ugrave: 249, - ulcorn: 8988, - ulcrop: 8975, - urcorn: 8989, - urcrop: 8974, - utilde: 361, - vangrt: 10652, - varphi: 966, - varrho: 1009, - veebar: 8891, - vellip: 8942, - verbar: 124, - wedbar: 10847, - wedgeq: 8793, - weierp: 8472, - wreath: 8768, - xoplus: 10753, - xotime: 10754, - xsqcup: 10758, - xuplus: 10756, - xwedge: 8896, - yacute: 253, - zacute: 378, - zcaron: 382, - zeetrf: 8488, - AElig: 198, - Acirc: 194, - Alpha: 913, - Amacr: 256, - Aogon: 260, - Aring: 197, - Breve: 728, - Ccirc: 264, - Colon: 8759, - Cross: 10799, - Dashv: 10980, - Delta: 916, - Ecirc: 202, - Emacr: 274, - Eogon: 280, - Equal: 10869, - Gamma: 915, - Gcirc: 284, - Hacek: 711, - Hcirc: 292, - IJlig: 306, - Icirc: 206, - Imacr: 298, - Iogon: 302, - Iukcy: 1030, - Jcirc: 308, - Jukcy: 1028, - Kappa: 922, - OElig: 338, - Ocirc: 212, - Omacr: 332, - Omega: 937, - Prime: 8243, - RBarr: 10512, - Scirc: 348, - Sigma: 931, - THORN: 222, - TRADE: 8482, - TSHcy: 1035, - Theta: 920, - Tilde: 8764, - Ubrcy: 1038, - Ucirc: 219, - Umacr: 362, - Union: 8899, - Uogon: 370, - UpTee: 8869, - Uring: 366, - VDash: 8875, - Vdash: 8873, - Wcirc: 372, - Wedge: 8896, - Ycirc: 374, - acirc: 226, - acute: 180, - aelig: 230, - aleph: 8501, - alpha: 945, - amacr: 257, - amalg: 10815, - angle: 8736, - angrt: 8735, - angst: 8491, - aogon: 261, - aring: 229, - asymp: 8776, - awint: 10769, - bcong: 8780, - bdquo: 8222, - bepsi: 1014, - blank: 9251, - blk12: 9618, - blk14: 9617, - blk34: 9619, - block: 9608, - boxDL: 9559, - boxDR: 9556, - boxDl: 9558, - boxDr: 9555, - boxHD: 9574, - boxHU: 9577, - boxHd: 9572, - boxHu: 9575, - boxUL: 9565, - boxUR: 9562, - boxUl: 9564, - boxUr: 9561, - boxVH: 9580, - boxVL: 9571, - boxVR: 9568, - boxVh: 9579, - boxVl: 9570, - boxVr: 9567, - boxdL: 9557, - boxdR: 9554, - boxdl: 9488, - boxdr: 9484, - boxhD: 9573, - boxhU: 9576, - boxhd: 9516, - boxhu: 9524, - boxuL: 9563, - boxuR: 9560, - boxul: 9496, - boxur: 9492, - boxvH: 9578, - boxvL: 9569, - boxvR: 9566, - boxvh: 9532, - boxvl: 9508, - boxvr: 9500, - breve: 728, - bsemi: 8271, - bsime: 8909, - bsolb: 10693, - bumpE: 10926, - bumpe: 8783, - caret: 8257, - caron: 711, - ccaps: 10829, - ccirc: 265, - ccups: 10828, - cedil: 184, - check: 10003, - clubs: 9827, - colon: 58, - comma: 44, - crarr: 8629, - cross: 10007, - csube: 10961, - csupe: 10962, - ctdot: 8943, - cuepr: 8926, - cuesc: 8927, - cupor: 10821, - cuvee: 8910, - cuwed: 8911, - cwint: 8753, - dashv: 8867, - dblac: 733, - ddarr: 8650, - delta: 948, - dharl: 8643, - dharr: 8642, - diams: 9830, - disin: 8946, - doteq: 8784, - dtdot: 8945, - dtrif: 9662, - duarr: 8693, - duhar: 10607, - eDDot: 10871, - ecirc: 234, - efDot: 8786, - emacr: 275, - empty: 8709, - eogon: 281, - eplus: 10865, - epsiv: 949, - eqsim: 8770, - equiv: 8801, - erDot: 8787, - erarr: 10609, - esdot: 8784, - exist: 8707, - fflig: 64256, - filig: 64257, - fllig: 64258, - fltns: 9649, - forkv: 10969, - frasl: 8260, - frown: 8994, - gamma: 947, - gcirc: 285, - gescc: 10921, - gimel: 8503, - gneqq: 8809, - gnsim: 8935, - grave: 96, - gsime: 10894, - gsiml: 10896, - gtcir: 10874, - gtdot: 8919, - harrw: 8621, - hcirc: 293, - hoarr: 8703, - icirc: 238, - iexcl: 161, - iiint: 8749, - iiota: 8489, - ijlig: 307, - imacr: 299, - image: 8465, - imath: 305, - imped: 437, - infin: 8734, - iogon: 303, - iprod: 10812, - isinE: 8953, - isins: 8948, - isinv: 8712, - iukcy: 1110, - jcirc: 309, - jmath: 567, - jukcy: 1108, - kappa: 954, - lAarr: 8666, - lBarr: 10510, - langd: 10641, - laquo: 171, - larrb: 8676, - lbarr: 10508, - lbbrk: 10098, - lbrke: 10635, - lceil: 8968, - ldquo: 8220, - lescc: 10920, - lhard: 8637, - lharu: 8636, - lhblk: 9604, - llarr: 8647, - lltri: 9722, - lneqq: 8808, - lnsim: 8934, - loang: 10220, - loarr: 8701, - lobrk: 10214, - lopar: 10629, - lrarr: 8646, - lrhar: 8651, - lrtri: 8895, - lsime: 10893, - lsimg: 10895, - lsquo: 8216, - ltcir: 10873, - ltdot: 8918, - ltrie: 8884, - ltrif: 9666, - mDDot: 8762, - mdash: 8212, - micro: 181, - minus: 8722, - mumap: 8888, - nabla: 8711, - napos: 329, - natur: 9838, - ncong: 8775, - ndash: 8211, - neArr: 8663, - nearr: 8599, - ngsim: 8821, - nhArr: 8654, - nharr: 8622, - nhpar: 10994, - nlArr: 8653, - nlarr: 8602, - nless: 8814, - nlsim: 8820, - nltri: 8938, - notin: 8713, - notni: 8716, - nprec: 8832, - nrArr: 8655, - nrarr: 8603, - nrtri: 8939, - nsime: 8772, - nsmid: 8740, - nspar: 8742, - nsube: 8840, - nsucc: 8833, - nsupe: 8841, - numsp: 8199, - nwArr: 8662, - nwarr: 8598, - ocirc: 244, - odash: 8861, - oelig: 339, - ofcir: 10687, - ohbar: 10677, - olarr: 8634, - olcir: 10686, - oline: 8254, - omacr: 333, - omega: 969, - operp: 10681, - oplus: 8853, - orarr: 8635, - order: 8500, - ovbar: 9021, - parsl: 11005, - phone: 9742, - plusb: 8862, - pluse: 10866, - pound: 163, - prcue: 8828, - prime: 8242, - prnap: 10937, - prsim: 8830, - quest: 63, - rAarr: 8667, - rBarr: 10511, - radic: 8730, - rangd: 10642, - range: 10661, - raquo: 187, - rarrb: 8677, - rarrc: 10547, - rarrw: 8605, - ratio: 8758, - rbarr: 10509, - rbbrk: 10099, - rbrke: 10636, - rceil: 8969, - rdquo: 8221, - reals: 8477, - rhard: 8641, - rharu: 8640, - rlarr: 8644, - rlhar: 8652, - rnmid: 10990, - roang: 10221, - roarr: 8702, - robrk: 10215, - ropar: 10630, - rrarr: 8649, - rsquo: 8217, - rtrie: 8885, - rtrif: 9656, - sbquo: 8218, - sccue: 8829, - scirc: 349, - scnap: 10938, - scsim: 8831, - sdotb: 8865, - sdote: 10854, - seArr: 8664, - searr: 8600, - setmn: 8726, - sharp: 9839, - sigma: 963, - simeq: 8771, - simgE: 10912, - simlE: 10911, - simne: 8774, - slarr: 8592, - smile: 8995, - sqcap: 8851, - sqcup: 8852, - sqsub: 8847, - sqsup: 8848, - srarr: 8594, - starf: 9733, - strns: 175, - subnE: 10955, - subne: 8842, - supnE: 10956, - supne: 8843, - swArr: 8665, - swarr: 8601, - szlig: 223, - theta: 952, - thkap: 8776, - thorn: 254, - tilde: 732, - times: 215, - trade: 8482, - trisb: 10701, - tshcy: 1115, - twixt: 8812, - ubrcy: 1118, - ucirc: 251, - udarr: 8645, - udhar: 10606, - uharl: 8639, - uharr: 8638, - uhblk: 9600, - ultri: 9720, - umacr: 363, - uogon: 371, - uplus: 8846, - upsih: 978, - uring: 367, - urtri: 9721, - utdot: 8944, - utrif: 9652, - uuarr: 8648, - vBarv: 10985, - vDash: 8872, - varpi: 982, - vdash: 8866, - veeeq: 8794, - vltri: 8882, - vprop: 8733, - vrtri: 8883, - wcirc: 373, - wedge: 8743, - xcirc: 9711, - xdtri: 9661, - xhArr: 10234, - xharr: 10231, - xlArr: 10232, - xlarr: 10229, - xodot: 10752, - xrArr: 10233, - xrarr: 10230, - xutri: 9651, - ycirc: 375, - Aopf: 120120, - Ascr: 119964, - Auml: 196, - Barv: 10983, - Beta: 914, - Bopf: 120121, - Bscr: 8492, - CHcy: 1063, - COPY: 169, - Cdot: 266, - Copf: 8450, - Cscr: 119966, - DJcy: 1026, - DScy: 1029, - DZcy: 1039, - Darr: 8609, - Dopf: 120123, - Dscr: 119967, - Edot: 278, - Eopf: 120124, - Escr: 8496, - Esim: 10867, - Euml: 203, - Fopf: 120125, - Fscr: 8497, - GJcy: 1027, - Gdot: 288, - Gopf: 120126, - Gscr: 119970, - Hopf: 8461, - Hscr: 8459, - IEcy: 1045, - IOcy: 1025, - Idot: 304, - Iopf: 120128, - Iota: 921, - Iscr: 8464, - Iuml: 207, - Jopf: 120129, - Jscr: 119973, - KHcy: 1061, - KJcy: 1036, - Kopf: 120130, - Kscr: 119974, - LJcy: 1033, - Lang: 10218, - Larr: 8606, - Lopf: 120131, - Lscr: 8466, - Mopf: 120132, - Mscr: 8499, - NJcy: 1034, - Nopf: 8469, - Nscr: 119977, - Oopf: 120134, - Oscr: 119978, - Ouml: 214, - Popf: 8473, - Pscr: 119979, - QUOT: 34, - Qopf: 8474, - Qscr: 119980, - Rang: 10219, - Rarr: 8608, - Ropf: 8477, - Rscr: 8475, - SHcy: 1064, - Sopf: 120138, - Sqrt: 8730, - Sscr: 119982, - Star: 8902, - TScy: 1062, - Topf: 120139, - Tscr: 119983, - Uarr: 8607, - Uopf: 120140, - Upsi: 978, - Uscr: 119984, - Uuml: 220, - Vbar: 10987, - Vert: 8214, - Vopf: 120141, - Vscr: 119985, - Wopf: 120142, - Wscr: 119986, - Xopf: 120143, - Xscr: 119987, - YAcy: 1071, - YIcy: 1031, - YUcy: 1070, - Yopf: 120144, - Yscr: 119988, - Yuml: 376, - ZHcy: 1046, - Zdot: 379, - Zeta: 918, - Zopf: 8484, - Zscr: 119989, - andd: 10844, - andv: 10842, - ange: 10660, - aopf: 120146, - apid: 8779, - apos: 39, - ascr: 119990, - auml: 228, - bNot: 10989, - bbrk: 9141, - beta: 946, - beth: 8502, - bnot: 8976, - bopf: 120147, - boxH: 9552, - boxV: 9553, - boxh: 9472, - boxv: 9474, - bscr: 119991, - bsim: 8765, - bsol: 92, - bull: 8226, - bump: 8782, - cdot: 267, - cent: 162, - chcy: 1095, - cirE: 10691, - circ: 710, - cire: 8791, - comp: 8705, - cong: 8773, - copf: 120148, - copy: 169, - cscr: 119992, - csub: 10959, - csup: 10960, - dArr: 8659, - dHar: 10597, - darr: 8595, - dash: 8208, - diam: 8900, - djcy: 1106, - dopf: 120149, - dscr: 119993, - dscy: 1109, - dsol: 10742, - dtri: 9663, - dzcy: 1119, - eDot: 8785, - ecir: 8790, - edot: 279, - emsp: 8195, - ensp: 8194, - eopf: 120150, - epar: 8917, - epsi: 1013, - escr: 8495, - esim: 8770, - euml: 235, - euro: 8364, - excl: 33, - flat: 9837, - fnof: 402, - fopf: 120151, - fork: 8916, - fscr: 119995, - gdot: 289, - geqq: 8807, - gjcy: 1107, - gnap: 10890, - gneq: 10888, - gopf: 120152, - gscr: 8458, - gsim: 8819, - gtcc: 10919, - hArr: 8660, - half: 189, - harr: 8596, - hbar: 8463, - hopf: 120153, - hscr: 119997, - iecy: 1077, - imof: 8887, - iocy: 1105, - iopf: 120154, - iota: 953, - iscr: 119998, - isin: 8712, - iuml: 239, - jopf: 120155, - jscr: 119999, - khcy: 1093, - kjcy: 1116, - kopf: 120156, - kscr: 120000, - lArr: 8656, - lHar: 10594, - lang: 10216, - larr: 8592, - late: 10925, - lcub: 123, - ldca: 10550, - ldsh: 8626, - leqq: 8806, - ljcy: 1113, - lnap: 10889, - lneq: 10887, - lopf: 120157, - lozf: 10731, - lpar: 40, - lscr: 120001, - lsim: 8818, - lsqb: 91, - ltcc: 10918, - ltri: 9667, - macr: 175, - male: 9794, - malt: 10016, - mlcp: 10971, - mldr: 8230, - mopf: 120158, - mscr: 120002, - nbsp: 160, - ncap: 10819, - ncup: 10818, - ngeq: 8817, - ngtr: 8815, - nisd: 8954, - njcy: 1114, - nldr: 8229, - nleq: 8816, - nmid: 8740, - nopf: 120159, - npar: 8742, - nscr: 120003, - nsim: 8769, - nsub: 8836, - nsup: 8837, - ntgl: 8825, - ntlg: 8824, - oast: 8859, - ocir: 8858, - odiv: 10808, - odot: 8857, - ogon: 731, - oint: 8750, - omid: 10678, - oopf: 120160, - opar: 10679, - ordf: 170, - ordm: 186, - oror: 10838, - oscr: 8500, - osol: 8856, - ouml: 246, - para: 182, - part: 8706, - perp: 8869, - phiv: 966, - plus: 43, - popf: 120161, - prap: 10935, - prec: 8826, - prnE: 10933, - prod: 8719, - prop: 8733, - pscr: 120005, - qint: 10764, - qopf: 120162, - qscr: 120006, - quot: 34, - rArr: 8658, - rHar: 10596, - race: 10714, - rang: 10217, - rarr: 8594, - rcub: 125, - rdca: 10551, - rdsh: 8627, - real: 8476, - rect: 9645, - rhov: 1009, - ring: 730, - ropf: 120163, - rpar: 41, - rscr: 120007, - rsqb: 93, - rtri: 9657, - scap: 10936, - scnE: 10934, - sdot: 8901, - sect: 167, - semi: 59, - sext: 10038, - shcy: 1096, - sime: 8771, - simg: 10910, - siml: 10909, - smid: 8739, - smte: 10924, - solb: 10692, - sopf: 120164, - spar: 8741, - squf: 9642, - sscr: 120008, - star: 9734, - subE: 10949, - sube: 8838, - succ: 8827, - sung: 9834, - sup1: 185, - sup2: 178, - sup3: 179, - supE: 10950, - supe: 8839, - tbrk: 9140, - tdot: 8411, - tint: 8749, - toea: 10536, - topf: 120165, - tosa: 10537, - trie: 8796, - tscr: 120009, - tscy: 1094, - uArr: 8657, - uHar: 10595, - uarr: 8593, - uopf: 120166, - upsi: 965, - uscr: 120010, - utri: 9653, - uuml: 252, - vArr: 8661, - vBar: 10984, - varr: 8597, - vert: 124, - vopf: 120167, - vscr: 120011, - wopf: 120168, - wscr: 120012, - xcap: 8898, - xcup: 8899, - xmap: 10236, - xnis: 8955, - xopf: 120169, - xscr: 120013, - xvee: 8897, - yacy: 1103, - yicy: 1111, - yopf: 120170, - yscr: 120014, - yucy: 1102, - yuml: 255, - zdot: 380, - zeta: 950, - zhcy: 1078, - zopf: 120171, - zscr: 120015, - zwnj: 8204, - AMP: 38, - Acy: 1040, - Afr: 120068, - And: 10835, - Bcy: 1041, - Bfr: 120069, - Cap: 8914, - Cfr: 8493, - Chi: 935, - Cup: 8915, - Dcy: 1044, - Del: 8711, - Dfr: 120071, - Dot: 168, - ENG: 330, - ETH: 208, - Ecy: 1069, - Efr: 120072, - Eta: 919, - Fcy: 1060, - Ffr: 120073, - Gcy: 1043, - Gfr: 120074, - Hat: 94, - Hfr: 8460, - Icy: 1048, - Ifr: 8465, - Int: 8748, - Jcy: 1049, - Jfr: 120077, - Kcy: 1050, - Kfr: 120078, - Lcy: 1051, - Lfr: 120079, - Lsh: 8624, - Map: 10501, - Mcy: 1052, - Mfr: 120080, - Ncy: 1053, - Nfr: 120081, - Not: 10988, - Ocy: 1054, - Ofr: 120082, - Pcy: 1055, - Pfr: 120083, - Phi: 934, - Psi: 936, - Qfr: 120084, - REG: 174, - Rcy: 1056, - Rfr: 8476, - Rho: 929, - Rsh: 8625, - Scy: 1057, - Sfr: 120086, - Sub: 8912, - Sum: 8721, - Sup: 8913, - Tab: 9, - Tau: 932, - Tcy: 1058, - Tfr: 120087, - Ucy: 1059, - Ufr: 120088, - Vcy: 1042, - Vee: 8897, - Vfr: 120089, - Wfr: 120090, - Xfr: 120091, - Ycy: 1067, - Yfr: 120092, - Zcy: 1047, - Zfr: 8488, - acd: 8767, - acy: 1072, - afr: 120094, - amp: 38, - and: 8743, - ang: 8736, - apE: 10864, - ape: 8778, - ast: 42, - bcy: 1073, - bfr: 120095, - bot: 8869, - cap: 8745, - cfr: 120096, - chi: 967, - cir: 9675, - cup: 8746, - dcy: 1076, - deg: 176, - dfr: 120097, - die: 168, - div: 247, - dot: 729, - ecy: 1101, - efr: 120098, - egs: 10902, - ell: 8467, - els: 10901, - eng: 331, - eta: 951, - eth: 240, - fcy: 1092, - ffr: 120099, - gEl: 10892, - gap: 10886, - gcy: 1075, - gel: 8923, - geq: 8805, - ges: 10878, - gfr: 120100, - ggg: 8921, - glE: 10898, - gla: 10917, - glj: 10916, - gnE: 8809, - gne: 10888, - hfr: 120101, - icy: 1080, - iff: 8660, - ifr: 120102, - int: 8747, - jcy: 1081, - jfr: 120103, - kcy: 1082, - kfr: 120104, - lEg: 10891, - lap: 10885, - lat: 10923, - lcy: 1083, - leg: 8922, - leq: 8804, - les: 10877, - lfr: 120105, - lgE: 10897, - lnE: 8808, - lne: 10887, - loz: 9674, - lrm: 8206, - lsh: 8624, - map: 8614, - mcy: 1084, - mfr: 120106, - mho: 8487, - mid: 8739, - nap: 8777, - ncy: 1085, - nfr: 120107, - nge: 8817, - ngt: 8815, - nis: 8956, - niv: 8715, - nle: 8816, - nlt: 8814, - not: 172, - npr: 8832, - nsc: 8833, - num: 35, - ocy: 1086, - ofr: 120108, - ogt: 10689, - ohm: 8486, - olt: 10688, - ord: 10845, - orv: 10843, - par: 8741, - pcy: 1087, - pfr: 120109, - phi: 966, - piv: 982, - prE: 10931, - pre: 10927, - psi: 968, - qfr: 120110, - rcy: 1088, - reg: 174, - rfr: 120111, - rho: 961, - rlm: 8207, - rsh: 8625, - scE: 10932, - sce: 10928, - scy: 1089, - sfr: 120112, - shy: 173, - sim: 8764, - smt: 10922, - sol: 47, - squ: 9633, - sub: 8834, - sum: 8721, - sup: 8835, - tau: 964, - tcy: 1090, - tfr: 120113, - top: 8868, - ucy: 1091, - ufr: 120114, - uml: 168, - vcy: 1074, - vee: 8744, - vfr: 120115, - wfr: 120116, - xfr: 120117, - ycy: 1099, - yen: 165, - yfr: 120118, - zcy: 1079, - zfr: 120119, - zwj: 8205, - DD: 8517, - GT: 62, - Gg: 8921, - Gt: 8811, - Im: 8465, - LT: 60, - Ll: 8920, - Lt: 8810, - Mu: 924, - Nu: 925, - Or: 10836, - Pi: 928, - Pr: 10939, - Re: 8476, - Sc: 10940, - Xi: 926, - ac: 8766, - af: 8289, - ap: 8776, - dd: 8518, - ee: 8519, - eg: 10906, - el: 10905, - gE: 8807, - ge: 8805, - gg: 8811, - gl: 8823, - gt: 62, - ic: 8291, - ii: 8520, - in: 8712, - it: 8290, - lE: 8806, - le: 8804, - lg: 8822, - ll: 8810, - lt: 60, - mp: 8723, - mu: 956, - ne: 8800, - ni: 8715, - nu: 957, - oS: 9416, - or: 8744, - pi: 960, - pm: 177, - pr: 8826, - rx: 8478, - sc: 8827, - wp: 8472, - wr: 8768, - xi: 958 + CounterClockwiseContourIntegral: 8755, + ClockwiseContourIntegral: 8754, + DoubleLongLeftRightArrow: 10234, + DiacriticalDoubleAcute: 733, + NotSquareSupersetEqual: 8931, + CloseCurlyDoubleQuote: 8221, + DoubleContourIntegral: 8751, + FilledVerySmallSquare: 9642, + NegativeVeryThinSpace: 8203, + NotPrecedesSlantEqual: 8928, + NotRightTriangleEqual: 8941, + NotSucceedsSlantEqual: 8929, + CapitalDifferentialD: 8517, + DoubleLeftRightArrow: 8660, + DoubleLongRightArrow: 10233, + EmptyVerySmallSquare: 9643, + NestedGreaterGreater: 8811, + NotDoubleVerticalBar: 8742, + NotLeftTriangleEqual: 8940, + NotSquareSubsetEqual: 8930, + OpenCurlyDoubleQuote: 8220, + ReverseUpEquilibrium: 10607, + DoubleLongLeftArrow: 10232, + DownLeftRightVector: 10576, + LeftArrowRightArrow: 8646, + NegativeMediumSpace: 8203, + RightArrowLeftArrow: 8644, + SquareSupersetEqual: 8850, + leftrightsquigarrow: 8621, + DownRightTeeVector: 10591, + DownRightVectorBar: 10583, + LongLeftRightArrow: 10231, + Longleftrightarrow: 10234, + NegativeThickSpace: 8203, + PrecedesSlantEqual: 8828, + ReverseEquilibrium: 8651, + RightDoubleBracket: 10215, + RightDownTeeVector: 10589, + RightDownVectorBar: 10581, + RightTriangleEqual: 8885, + SquareIntersection: 8851, + SucceedsSlantEqual: 8829, + blacktriangleright: 9656, + longleftrightarrow: 10231, + DoubleUpDownArrow: 8661, + DoubleVerticalBar: 8741, + DownLeftTeeVector: 10590, + DownLeftVectorBar: 10582, + FilledSmallSquare: 9724, + GreaterSlantEqual: 10878, + LeftDoubleBracket: 10214, + LeftDownTeeVector: 10593, + LeftDownVectorBar: 10585, + LeftTriangleEqual: 8884, + NegativeThinSpace: 8203, + NotReverseElement: 8716, + NotTildeFullEqual: 8775, + RightAngleBracket: 10217, + RightUpDownVector: 10575, + SquareSubsetEqual: 8849, + VerticalSeparator: 10072, + blacktriangledown: 9662, + blacktriangleleft: 9666, + leftrightharpoons: 8651, + rightleftharpoons: 8652, + twoheadrightarrow: 8608, + DiacriticalAcute: 180, + DiacriticalGrave: 96, + DiacriticalTilde: 732, + DoubleRightArrow: 8658, + DownArrowUpArrow: 8693, + EmptySmallSquare: 9723, + GreaterEqualLess: 8923, + GreaterFullEqual: 8807, + LeftAngleBracket: 10216, + LeftUpDownVector: 10577, + LessEqualGreater: 8922, + NonBreakingSpace: 160, + NotRightTriangle: 8939, + NotSupersetEqual: 8841, + RightTriangleBar: 10704, + RightUpTeeVector: 10588, + RightUpVectorBar: 10580, + UnderParenthesis: 9181, + UpArrowDownArrow: 8645, + circlearrowright: 8635, + downharpoonright: 8642, + ntrianglerighteq: 8941, + rightharpoondown: 8641, + rightrightarrows: 8649, + twoheadleftarrow: 8606, + vartriangleright: 8883, + CloseCurlyQuote: 8217, + ContourIntegral: 8750, + DoubleDownArrow: 8659, + DoubleLeftArrow: 8656, + DownRightVector: 8641, + LeftRightVector: 10574, + LeftTriangleBar: 10703, + LeftUpTeeVector: 10592, + LeftUpVectorBar: 10584, + LowerRightArrow: 8600, + NotGreaterEqual: 8817, + NotGreaterTilde: 8821, + NotLeftTriangle: 8938, + OverParenthesis: 9180, + RightDownVector: 8642, + ShortRightArrow: 8594, + UpperRightArrow: 8599, + bigtriangledown: 9661, + circlearrowleft: 8634, + curvearrowright: 8631, + downharpoonleft: 8643, + leftharpoondown: 8637, + leftrightarrows: 8646, + nLeftrightarrow: 8654, + nleftrightarrow: 8622, + ntrianglelefteq: 8940, + rightleftarrows: 8644, + rightsquigarrow: 8605, + rightthreetimes: 8908, + straightepsilon: 1013, + trianglerighteq: 8885, + vartriangleleft: 8882, + DiacriticalDot: 729, + DoubleRightTee: 8872, + DownLeftVector: 8637, + GreaterGreater: 10914, + HorizontalLine: 9472, + InvisibleComma: 8291, + InvisibleTimes: 8290, + LeftDownVector: 8643, + LeftRightArrow: 8596, + Leftrightarrow: 8660, + LessSlantEqual: 10877, + LongRightArrow: 10230, + Longrightarrow: 10233, + LowerLeftArrow: 8601, + NestedLessLess: 8810, + NotGreaterLess: 8825, + NotLessGreater: 8824, + NotSubsetEqual: 8840, + NotVerticalBar: 8740, + OpenCurlyQuote: 8216, + ReverseElement: 8715, + RightTeeVector: 10587, + RightVectorBar: 10579, + ShortDownArrow: 8595, + ShortLeftArrow: 8592, + SquareSuperset: 8848, + TildeFullEqual: 8773, + UpperLeftArrow: 8598, + ZeroWidthSpace: 8203, + curvearrowleft: 8630, + doublebarwedge: 8966, + downdownarrows: 8650, + hookrightarrow: 8618, + leftleftarrows: 8647, + leftrightarrow: 8596, + leftthreetimes: 8907, + longrightarrow: 10230, + looparrowright: 8620, + nshortparallel: 8742, + ntriangleright: 8939, + rightarrowtail: 8611, + rightharpoonup: 8640, + trianglelefteq: 8884, + upharpoonright: 8638, + ApplyFunction: 8289, + DifferentialD: 8518, + DoubleLeftTee: 10980, + DoubleUpArrow: 8657, + LeftTeeVector: 10586, + LeftVectorBar: 10578, + LessFullEqual: 8806, + LongLeftArrow: 10229, + Longleftarrow: 10232, + NotTildeEqual: 8772, + NotTildeTilde: 8777, + Poincareplane: 8460, + PrecedesEqual: 10927, + PrecedesTilde: 8830, + RightArrowBar: 8677, + RightTeeArrow: 8614, + RightTriangle: 8883, + RightUpVector: 8638, + SucceedsEqual: 10928, + SucceedsTilde: 8831, + SupersetEqual: 8839, + UpEquilibrium: 10606, + VerticalTilde: 8768, + VeryThinSpace: 8202, + bigtriangleup: 9651, + blacktriangle: 9652, + divideontimes: 8903, + fallingdotseq: 8786, + hookleftarrow: 8617, + leftarrowtail: 8610, + leftharpoonup: 8636, + longleftarrow: 10229, + looparrowleft: 8619, + measuredangle: 8737, + ntriangleleft: 8938, + shortparallel: 8741, + smallsetminus: 8726, + triangleright: 9657, + upharpoonleft: 8639, + DownArrowBar: 10515, + DownTeeArrow: 8615, + ExponentialE: 8519, + GreaterEqual: 8805, + GreaterTilde: 8819, + HilbertSpace: 8459, + HumpDownHump: 8782, + Intersection: 8898, + LeftArrowBar: 8676, + LeftTeeArrow: 8612, + LeftTriangle: 8882, + LeftUpVector: 8639, + NotCongruent: 8802, + NotLessEqual: 8816, + NotLessTilde: 8820, + Proportional: 8733, + RightCeiling: 8969, + RoundImplies: 10608, + ShortUpArrow: 8593, + SquareSubset: 8847, + UnderBracket: 9141, + VerticalLine: 124, + blacklozenge: 10731, + exponentiale: 8519, + risingdotseq: 8787, + triangledown: 9663, + triangleleft: 9667, + CircleMinus: 8854, + CircleTimes: 8855, + Equilibrium: 8652, + GreaterLess: 8823, + LeftCeiling: 8968, + LessGreater: 8822, + MediumSpace: 8287, + NotPrecedes: 8832, + NotSucceeds: 8833, + OverBracket: 9140, + RightVector: 8640, + Rrightarrow: 8667, + RuleDelayed: 10740, + SmallCircle: 8728, + SquareUnion: 8852, + SubsetEqual: 8838, + UpDownArrow: 8597, + Updownarrow: 8661, + VerticalBar: 8739, + backepsilon: 1014, + blacksquare: 9642, + circledcirc: 8858, + circleddash: 8861, + curlyeqprec: 8926, + curlyeqsucc: 8927, + diamondsuit: 9830, + eqslantless: 10901, + expectation: 8496, + nRightarrow: 8655, + nrightarrow: 8603, + preccurlyeq: 8828, + precnapprox: 10937, + quaternions: 8461, + straightphi: 981, + succcurlyeq: 8829, + succnapprox: 10938, + thickapprox: 8776, + updownarrow: 8597, + Bernoullis: 8492, + CirclePlus: 8853, + EqualTilde: 8770, + Fouriertrf: 8497, + ImaginaryI: 8520, + Laplacetrf: 8466, + LeftVector: 8636, + Lleftarrow: 8666, + NotElement: 8713, + NotGreater: 8815, + Proportion: 8759, + RightArrow: 8594, + RightFloor: 8971, + Rightarrow: 8658, + TildeEqual: 8771, + TildeTilde: 8776, + UnderBrace: 9183, + UpArrowBar: 10514, + UpTeeArrow: 8613, + circledast: 8859, + complement: 8705, + curlywedge: 8911, + eqslantgtr: 10902, + gtreqqless: 10892, + lessapprox: 10885, + lesseqqgtr: 10891, + lmoustache: 9136, + longmapsto: 10236, + mapstodown: 8615, + mapstoleft: 8612, + nLeftarrow: 8653, + nleftarrow: 8602, + precapprox: 10935, + rightarrow: 8594, + rmoustache: 9137, + sqsubseteq: 8849, + sqsupseteq: 8850, + subsetneqq: 10955, + succapprox: 10936, + supsetneqq: 10956, + upuparrows: 8648, + varepsilon: 949, + varnothing: 8709, + Backslash: 8726, + CenterDot: 183, + CircleDot: 8857, + Congruent: 8801, + Coproduct: 8720, + DoubleDot: 168, + DownArrow: 8595, + DownBreve: 785, + Downarrow: 8659, + HumpEqual: 8783, + LeftArrow: 8592, + LeftFloor: 8970, + Leftarrow: 8656, + LessTilde: 8818, + Mellintrf: 8499, + MinusPlus: 8723, + NotCupCap: 8813, + NotExists: 8708, + OverBrace: 9182, + PlusMinus: 177, + Therefore: 8756, + ThinSpace: 8201, + TripleDot: 8411, + UnionPlus: 8846, + backprime: 8245, + backsimeq: 8909, + bigotimes: 10754, + centerdot: 183, + checkmark: 10003, + complexes: 8450, + dotsquare: 8865, + downarrow: 8595, + gtrapprox: 10886, + gtreqless: 8923, + heartsuit: 9829, + leftarrow: 8592, + lesseqgtr: 8922, + nparallel: 8742, + nshortmid: 8740, + nsubseteq: 8840, + nsupseteq: 8841, + pitchfork: 8916, + rationals: 8474, + spadesuit: 9824, + subseteqq: 10949, + subsetneq: 8842, + supseteqq: 10950, + supsetneq: 8843, + therefore: 8756, + triangleq: 8796, + varpropto: 8733, + DDotrahd: 10513, + DotEqual: 8784, + Integral: 8747, + LessLess: 10913, + NotEqual: 8800, + NotTilde: 8769, + PartialD: 8706, + Precedes: 8826, + RightTee: 8866, + Succeeds: 8827, + SuchThat: 8715, + Superset: 8835, + Uarrocir: 10569, + UnderBar: 818, + andslope: 10840, + angmsdaa: 10664, + angmsdab: 10665, + angmsdac: 10666, + angmsdad: 10667, + angmsdae: 10668, + angmsdaf: 10669, + angmsdag: 10670, + angmsdah: 10671, + angrtvbd: 10653, + approxeq: 8778, + awconint: 8755, + backcong: 8780, + barwedge: 8965, + bbrktbrk: 9142, + bigoplus: 10753, + bigsqcup: 10758, + biguplus: 10756, + bigwedge: 8896, + boxminus: 8863, + boxtimes: 8864, + capbrcup: 10825, + circledR: 174, + circledS: 9416, + cirfnint: 10768, + clubsuit: 9827, + cupbrcap: 10824, + curlyvee: 8910, + cwconint: 8754, + doteqdot: 8785, + dotminus: 8760, + drbkarow: 10512, + dzigrarr: 10239, + elinters: 9191, + emptyset: 8709, + eqvparsl: 10725, + fpartint: 10765, + geqslant: 10878, + gesdotol: 10884, + gnapprox: 10890, + hksearow: 10533, + hkswarow: 10534, + imagline: 8464, + imagpart: 8465, + infintie: 10717, + integers: 8484, + intercal: 8890, + intlarhk: 10775, + laemptyv: 10676, + ldrushar: 10571, + leqslant: 10877, + lesdotor: 10883, + llcorner: 8990, + lnapprox: 10889, + lrcorner: 8991, + lurdshar: 10570, + mapstoup: 8613, + multimap: 8888, + naturals: 8469, + otimesas: 10806, + parallel: 8741, + plusacir: 10787, + pointint: 10773, + precneqq: 10933, + precnsim: 8936, + profalar: 9006, + profline: 8978, + profsurf: 8979, + raemptyv: 10675, + realpart: 8476, + rppolint: 10770, + rtriltri: 10702, + scpolint: 10771, + setminus: 8726, + shortmid: 8739, + smeparsl: 10724, + sqsubset: 8847, + sqsupset: 8848, + subseteq: 8838, + succneqq: 10934, + succnsim: 8937, + supseteq: 8839, + thetasym: 977, + thicksim: 8764, + timesbar: 10801, + triangle: 9653, + triminus: 10810, + trpezium: 9186, + ulcorner: 8988, + urcorner: 8989, + varkappa: 1008, + varsigma: 962, + vartheta: 977, + Because: 8757, + Cayleys: 8493, + Cconint: 8752, + Cedilla: 184, + Diamond: 8900, + DownTee: 8868, + Element: 8712, + Epsilon: 917, + Implies: 8658, + LeftTee: 8867, + NewLine: 10, + NoBreak: 8288, + NotLess: 8814, + Omicron: 927, + OverBar: 175, + Product: 8719, + UpArrow: 8593, + Uparrow: 8657, + Upsilon: 933, + alefsym: 8501, + angrtvb: 8894, + angzarr: 9084, + asympeq: 8781, + backsim: 8765, + because: 8757, + bemptyv: 10672, + between: 8812, + bigcirc: 9711, + bigodot: 10752, + bigstar: 9733, + boxplus: 8862, + ccupssm: 10832, + cemptyv: 10674, + cirscir: 10690, + coloneq: 8788, + congdot: 10861, + cudarrl: 10552, + cudarrr: 10549, + cularrp: 10557, + curarrm: 10556, + dbkarow: 10511, + ddagger: 8225, + ddotseq: 10871, + demptyv: 10673, + diamond: 8900, + digamma: 989, + dotplus: 8724, + dwangle: 10662, + epsilon: 949, + eqcolon: 8789, + equivDD: 10872, + gesdoto: 10882, + gtquest: 10876, + gtrless: 8823, + harrcir: 10568, + intprod: 10812, + isindot: 8949, + larrbfs: 10527, + larrsim: 10611, + lbrksld: 10639, + lbrkslu: 10637, + ldrdhar: 10599, + lesdoto: 10881, + lessdot: 8918, + lessgtr: 8822, + lesssim: 8818, + lotimes: 10804, + lozenge: 9674, + ltquest: 10875, + luruhar: 10598, + maltese: 10016, + minusdu: 10794, + napprox: 8777, + natural: 9838, + nearrow: 8599, + nexists: 8708, + notinva: 8713, + notinvb: 8951, + notinvc: 8950, + notniva: 8716, + notnivb: 8958, + notnivc: 8957, + npolint: 10772, + nsqsube: 8930, + nsqsupe: 8931, + nvinfin: 10718, + nwarrow: 8598, + olcross: 10683, + omicron: 959, + orderof: 8500, + orslope: 10839, + pertenk: 8241, + planckh: 8462, + pluscir: 10786, + plussim: 10790, + plustwo: 10791, + precsim: 8830, + quatint: 10774, + questeq: 8799, + rarrbfs: 10528, + rarrsim: 10612, + rbrksld: 10638, + rbrkslu: 10640, + rdldhar: 10601, + realine: 8475, + rotimes: 10805, + ruluhar: 10600, + searrow: 8600, + simplus: 10788, + simrarr: 10610, + subedot: 10947, + submult: 10945, + subplus: 10943, + subrarr: 10617, + succsim: 8831, + supdsub: 10968, + supedot: 10948, + suphsub: 10967, + suplarr: 10619, + supmult: 10946, + supplus: 10944, + swarrow: 8601, + topfork: 10970, + triplus: 10809, + tritime: 10811, + uparrow: 8593, + upsilon: 965, + uwangle: 10663, + vzigzag: 10650, + zigrarr: 8669, + Aacute: 193, + Abreve: 258, + Agrave: 192, + Assign: 8788, + Atilde: 195, + Barwed: 8966, + Bumpeq: 8782, + Cacute: 262, + Ccaron: 268, + Ccedil: 199, + Colone: 10868, + Conint: 8751, + CupCap: 8781, + Dagger: 8225, + Dcaron: 270, + DotDot: 8412, + Dstrok: 272, + Eacute: 201, + Ecaron: 282, + Egrave: 200, + Exists: 8707, + ForAll: 8704, + Gammad: 988, + Gbreve: 286, + Gcedil: 290, + HARDcy: 1066, + Hstrok: 294, + Iacute: 205, + Igrave: 204, + Itilde: 296, + Jsercy: 1032, + Kcedil: 310, + Lacute: 313, + Lambda: 923, + Lcaron: 317, + Lcedil: 315, + Lmidot: 319, + Lstrok: 321, + Nacute: 323, + Ncaron: 327, + Ncedil: 325, + Ntilde: 209, + Oacute: 211, + Odblac: 336, + Ograve: 210, + Oslash: 216, + Otilde: 213, + Otimes: 10807, + Racute: 340, + Rarrtl: 10518, + Rcaron: 344, + Rcedil: 342, + SHCHcy: 1065, + SOFTcy: 1068, + Sacute: 346, + Scaron: 352, + Scedil: 350, + Square: 9633, + Subset: 8912, + Supset: 8913, + Tcaron: 356, + Tcedil: 354, + Tstrok: 358, + Uacute: 218, + Ubreve: 364, + Udblac: 368, + Ugrave: 217, + Utilde: 360, + Vdashl: 10982, + Verbar: 8214, + Vvdash: 8874, + Yacute: 221, + Zacute: 377, + Zcaron: 381, + aacute: 225, + abreve: 259, + agrave: 224, + andand: 10837, + angmsd: 8737, + angsph: 8738, + apacir: 10863, + approx: 8776, + atilde: 227, + barvee: 8893, + barwed: 8965, + becaus: 8757, + bernou: 8492, + bigcap: 8898, + bigcup: 8899, + bigvee: 8897, + bkarow: 10509, + bottom: 8869, + bowtie: 8904, + boxbox: 10697, + bprime: 8245, + brvbar: 166, + bullet: 8226, + bumpeq: 8783, + cacute: 263, + capand: 10820, + capcap: 10827, + capcup: 10823, + capdot: 10816, + ccaron: 269, + ccedil: 231, + circeq: 8791, + cirmid: 10991, + colone: 8788, + commat: 64, + compfn: 8728, + conint: 8750, + coprod: 8720, + copysr: 8471, + cularr: 8630, + cupcap: 10822, + cupcup: 10826, + cupdot: 8845, + curarr: 8631, + curren: 164, + cylcty: 9005, + dagger: 8224, + daleth: 8504, + dcaron: 271, + dfisht: 10623, + divide: 247, + divonx: 8903, + dlcorn: 8990, + dlcrop: 8973, + dollar: 36, + drcorn: 8991, + drcrop: 8972, + dstrok: 273, + eacute: 233, + easter: 10862, + ecaron: 283, + ecolon: 8789, + egrave: 232, + egsdot: 10904, + elsdot: 10903, + emptyv: 8709, + emsp13: 8196, + emsp14: 8197, + eparsl: 10723, + eqcirc: 8790, + equals: 61, + equest: 8799, + female: 9792, + ffilig: 64259, + ffllig: 64260, + forall: 8704, + frac12: 189, + frac13: 8531, + frac14: 188, + frac15: 8533, + frac16: 8537, + frac18: 8539, + frac23: 8532, + frac25: 8534, + frac34: 190, + frac35: 8535, + frac38: 8540, + frac45: 8536, + frac56: 8538, + frac58: 8541, + frac78: 8542, + gacute: 501, + gammad: 989, + gbreve: 287, + gesdot: 10880, + gesles: 10900, + gtlPar: 10645, + gtrarr: 10616, + gtrdot: 8919, + gtrsim: 8819, + hairsp: 8202, + hamilt: 8459, + hardcy: 1098, + hearts: 9829, + hellip: 8230, + hercon: 8889, + homtht: 8763, + horbar: 8213, + hslash: 8463, + hstrok: 295, + hybull: 8259, + hyphen: 8208, + iacute: 237, + igrave: 236, + iiiint: 10764, + iinfin: 10716, + incare: 8453, + inodot: 305, + intcal: 8890, + iquest: 191, + isinsv: 8947, + itilde: 297, + jsercy: 1112, + kappav: 1008, + kcedil: 311, + kgreen: 312, + lAtail: 10523, + lacute: 314, + lagran: 8466, + lambda: 955, + langle: 10216, + larrfs: 10525, + larrhk: 8617, + larrlp: 8619, + larrpl: 10553, + larrtl: 8610, + latail: 10521, + lbrace: 123, + lbrack: 91, + lcaron: 318, + lcedil: 316, + ldquor: 8222, + lesdot: 10879, + lesges: 10899, + lfisht: 10620, + lfloor: 8970, + lharul: 10602, + llhard: 10603, + lmidot: 320, + lmoust: 9136, + loplus: 10797, + lowast: 8727, + lowbar: 95, + lparlt: 10643, + lrhard: 10605, + lsaquo: 8249, + lsquor: 8218, + lstrok: 322, + lthree: 8907, + ltimes: 8905, + ltlarr: 10614, + ltrPar: 10646, + mapsto: 8614, + marker: 9646, + mcomma: 10793, + midast: 42, + midcir: 10992, + middot: 183, + minusb: 8863, + minusd: 8760, + mnplus: 8723, + models: 8871, + mstpos: 8766, + nVDash: 8879, + nVdash: 8878, + nacute: 324, + ncaron: 328, + ncedil: 326, + nearhk: 10532, + nequiv: 8802, + nesear: 10536, + nexist: 8708, + nltrie: 8940, + nprcue: 8928, + nrtrie: 8941, + nsccue: 8929, + nsimeq: 8772, + ntilde: 241, + numero: 8470, + nvDash: 8877, + nvHarr: 10500, + nvdash: 8876, + nvlArr: 10498, + nvrArr: 10499, + nwarhk: 10531, + nwnear: 10535, + oacute: 243, + odblac: 337, + odsold: 10684, + ograve: 242, + ominus: 8854, + origof: 8886, + oslash: 248, + otilde: 245, + otimes: 8855, + parsim: 10995, + percnt: 37, + period: 46, + permil: 8240, + phmmat: 8499, + planck: 8463, + plankv: 8463, + plusdo: 8724, + plusdu: 10789, + plusmn: 177, + preceq: 10927, + primes: 8473, + prnsim: 8936, + propto: 8733, + prurel: 8880, + puncsp: 8200, + qprime: 8279, + rAtail: 10524, + racute: 341, + rangle: 10217, + rarrap: 10613, + rarrfs: 10526, + rarrhk: 8618, + rarrlp: 8620, + rarrpl: 10565, + rarrtl: 8611, + ratail: 10522, + rbrace: 125, + rbrack: 93, + rcaron: 345, + rcedil: 343, + rdquor: 8221, + rfisht: 10621, + rfloor: 8971, + rharul: 10604, + rmoust: 9137, + roplus: 10798, + rpargt: 10644, + rsaquo: 8250, + rsquor: 8217, + rthree: 8908, + rtimes: 8906, + sacute: 347, + scaron: 353, + scedil: 351, + scnsim: 8937, + searhk: 10533, + seswar: 10537, + sfrown: 8994, + shchcy: 1097, + sigmaf: 962, + sigmav: 962, + simdot: 10858, + smashp: 10803, + softcy: 1100, + solbar: 9023, + spades: 9824, + sqsube: 8849, + sqsupe: 8850, + square: 9633, + squarf: 9642, + ssetmn: 8726, + ssmile: 8995, + sstarf: 8902, + subdot: 10941, + subset: 8834, + subsim: 10951, + subsub: 10965, + subsup: 10963, + succeq: 10928, + supdot: 10942, + supset: 8835, + supsim: 10952, + supsub: 10964, + supsup: 10966, + swarhk: 10534, + swnwar: 10538, + target: 8982, + tcaron: 357, + tcedil: 355, + telrec: 8981, + there4: 8756, + thetav: 977, + thinsp: 8201, + thksim: 8764, + timesb: 8864, + timesd: 10800, + topbot: 9014, + topcir: 10993, + tprime: 8244, + tridot: 9708, + tstrok: 359, + uacute: 250, + ubreve: 365, + udblac: 369, + ufisht: 10622, + ugrave: 249, + ulcorn: 8988, + ulcrop: 8975, + urcorn: 8989, + urcrop: 8974, + utilde: 361, + vangrt: 10652, + varphi: 966, + varrho: 1009, + veebar: 8891, + vellip: 8942, + verbar: 124, + wedbar: 10847, + wedgeq: 8793, + weierp: 8472, + wreath: 8768, + xoplus: 10753, + xotime: 10754, + xsqcup: 10758, + xuplus: 10756, + xwedge: 8896, + yacute: 253, + zacute: 378, + zcaron: 382, + zeetrf: 8488, + AElig: 198, + Acirc: 194, + Alpha: 913, + Amacr: 256, + Aogon: 260, + Aring: 197, + Breve: 728, + Ccirc: 264, + Colon: 8759, + Cross: 10799, + Dashv: 10980, + Delta: 916, + Ecirc: 202, + Emacr: 274, + Eogon: 280, + Equal: 10869, + Gamma: 915, + Gcirc: 284, + Hacek: 711, + Hcirc: 292, + IJlig: 306, + Icirc: 206, + Imacr: 298, + Iogon: 302, + Iukcy: 1030, + Jcirc: 308, + Jukcy: 1028, + Kappa: 922, + OElig: 338, + Ocirc: 212, + Omacr: 332, + Omega: 937, + Prime: 8243, + RBarr: 10512, + Scirc: 348, + Sigma: 931, + THORN: 222, + TRADE: 8482, + TSHcy: 1035, + Theta: 920, + Tilde: 8764, + Ubrcy: 1038, + Ucirc: 219, + Umacr: 362, + Union: 8899, + Uogon: 370, + UpTee: 8869, + Uring: 366, + VDash: 8875, + Vdash: 8873, + Wcirc: 372, + Wedge: 8896, + Ycirc: 374, + acirc: 226, + acute: 180, + aelig: 230, + aleph: 8501, + alpha: 945, + amacr: 257, + amalg: 10815, + angle: 8736, + angrt: 8735, + angst: 8491, + aogon: 261, + aring: 229, + asymp: 8776, + awint: 10769, + bcong: 8780, + bdquo: 8222, + bepsi: 1014, + blank: 9251, + blk12: 9618, + blk14: 9617, + blk34: 9619, + block: 9608, + boxDL: 9559, + boxDR: 9556, + boxDl: 9558, + boxDr: 9555, + boxHD: 9574, + boxHU: 9577, + boxHd: 9572, + boxHu: 9575, + boxUL: 9565, + boxUR: 9562, + boxUl: 9564, + boxUr: 9561, + boxVH: 9580, + boxVL: 9571, + boxVR: 9568, + boxVh: 9579, + boxVl: 9570, + boxVr: 9567, + boxdL: 9557, + boxdR: 9554, + boxdl: 9488, + boxdr: 9484, + boxhD: 9573, + boxhU: 9576, + boxhd: 9516, + boxhu: 9524, + boxuL: 9563, + boxuR: 9560, + boxul: 9496, + boxur: 9492, + boxvH: 9578, + boxvL: 9569, + boxvR: 9566, + boxvh: 9532, + boxvl: 9508, + boxvr: 9500, + breve: 728, + bsemi: 8271, + bsime: 8909, + bsolb: 10693, + bumpE: 10926, + bumpe: 8783, + caret: 8257, + caron: 711, + ccaps: 10829, + ccirc: 265, + ccups: 10828, + cedil: 184, + check: 10003, + clubs: 9827, + colon: 58, + comma: 44, + crarr: 8629, + cross: 10007, + csube: 10961, + csupe: 10962, + ctdot: 8943, + cuepr: 8926, + cuesc: 8927, + cupor: 10821, + cuvee: 8910, + cuwed: 8911, + cwint: 8753, + dashv: 8867, + dblac: 733, + ddarr: 8650, + delta: 948, + dharl: 8643, + dharr: 8642, + diams: 9830, + disin: 8946, + doteq: 8784, + dtdot: 8945, + dtrif: 9662, + duarr: 8693, + duhar: 10607, + eDDot: 10871, + ecirc: 234, + efDot: 8786, + emacr: 275, + empty: 8709, + eogon: 281, + eplus: 10865, + epsiv: 949, + eqsim: 8770, + equiv: 8801, + erDot: 8787, + erarr: 10609, + esdot: 8784, + exist: 8707, + fflig: 64256, + filig: 64257, + fllig: 64258, + fltns: 9649, + forkv: 10969, + frasl: 8260, + frown: 8994, + gamma: 947, + gcirc: 285, + gescc: 10921, + gimel: 8503, + gneqq: 8809, + gnsim: 8935, + grave: 96, + gsime: 10894, + gsiml: 10896, + gtcir: 10874, + gtdot: 8919, + harrw: 8621, + hcirc: 293, + hoarr: 8703, + icirc: 238, + iexcl: 161, + iiint: 8749, + iiota: 8489, + ijlig: 307, + imacr: 299, + image: 8465, + imath: 305, + imped: 437, + infin: 8734, + iogon: 303, + iprod: 10812, + isinE: 8953, + isins: 8948, + isinv: 8712, + iukcy: 1110, + jcirc: 309, + jmath: 567, + jukcy: 1108, + kappa: 954, + lAarr: 8666, + lBarr: 10510, + langd: 10641, + laquo: 171, + larrb: 8676, + lbarr: 10508, + lbbrk: 10098, + lbrke: 10635, + lceil: 8968, + ldquo: 8220, + lescc: 10920, + lhard: 8637, + lharu: 8636, + lhblk: 9604, + llarr: 8647, + lltri: 9722, + lneqq: 8808, + lnsim: 8934, + loang: 10220, + loarr: 8701, + lobrk: 10214, + lopar: 10629, + lrarr: 8646, + lrhar: 8651, + lrtri: 8895, + lsime: 10893, + lsimg: 10895, + lsquo: 8216, + ltcir: 10873, + ltdot: 8918, + ltrie: 8884, + ltrif: 9666, + mDDot: 8762, + mdash: 8212, + micro: 181, + minus: 8722, + mumap: 8888, + nabla: 8711, + napos: 329, + natur: 9838, + ncong: 8775, + ndash: 8211, + neArr: 8663, + nearr: 8599, + ngsim: 8821, + nhArr: 8654, + nharr: 8622, + nhpar: 10994, + nlArr: 8653, + nlarr: 8602, + nless: 8814, + nlsim: 8820, + nltri: 8938, + notin: 8713, + notni: 8716, + nprec: 8832, + nrArr: 8655, + nrarr: 8603, + nrtri: 8939, + nsime: 8772, + nsmid: 8740, + nspar: 8742, + nsube: 8840, + nsucc: 8833, + nsupe: 8841, + numsp: 8199, + nwArr: 8662, + nwarr: 8598, + ocirc: 244, + odash: 8861, + oelig: 339, + ofcir: 10687, + ohbar: 10677, + olarr: 8634, + olcir: 10686, + oline: 8254, + omacr: 333, + omega: 969, + operp: 10681, + oplus: 8853, + orarr: 8635, + order: 8500, + ovbar: 9021, + parsl: 11005, + phone: 9742, + plusb: 8862, + pluse: 10866, + pound: 163, + prcue: 8828, + prime: 8242, + prnap: 10937, + prsim: 8830, + quest: 63, + rAarr: 8667, + rBarr: 10511, + radic: 8730, + rangd: 10642, + range: 10661, + raquo: 187, + rarrb: 8677, + rarrc: 10547, + rarrw: 8605, + ratio: 8758, + rbarr: 10509, + rbbrk: 10099, + rbrke: 10636, + rceil: 8969, + rdquo: 8221, + reals: 8477, + rhard: 8641, + rharu: 8640, + rlarr: 8644, + rlhar: 8652, + rnmid: 10990, + roang: 10221, + roarr: 8702, + robrk: 10215, + ropar: 10630, + rrarr: 8649, + rsquo: 8217, + rtrie: 8885, + rtrif: 9656, + sbquo: 8218, + sccue: 8829, + scirc: 349, + scnap: 10938, + scsim: 8831, + sdotb: 8865, + sdote: 10854, + seArr: 8664, + searr: 8600, + setmn: 8726, + sharp: 9839, + sigma: 963, + simeq: 8771, + simgE: 10912, + simlE: 10911, + simne: 8774, + slarr: 8592, + smile: 8995, + sqcap: 8851, + sqcup: 8852, + sqsub: 8847, + sqsup: 8848, + srarr: 8594, + starf: 9733, + strns: 175, + subnE: 10955, + subne: 8842, + supnE: 10956, + supne: 8843, + swArr: 8665, + swarr: 8601, + szlig: 223, + theta: 952, + thkap: 8776, + thorn: 254, + tilde: 732, + times: 215, + trade: 8482, + trisb: 10701, + tshcy: 1115, + twixt: 8812, + ubrcy: 1118, + ucirc: 251, + udarr: 8645, + udhar: 10606, + uharl: 8639, + uharr: 8638, + uhblk: 9600, + ultri: 9720, + umacr: 363, + uogon: 371, + uplus: 8846, + upsih: 978, + uring: 367, + urtri: 9721, + utdot: 8944, + utrif: 9652, + uuarr: 8648, + vBarv: 10985, + vDash: 8872, + varpi: 982, + vdash: 8866, + veeeq: 8794, + vltri: 8882, + vprop: 8733, + vrtri: 8883, + wcirc: 373, + wedge: 8743, + xcirc: 9711, + xdtri: 9661, + xhArr: 10234, + xharr: 10231, + xlArr: 10232, + xlarr: 10229, + xodot: 10752, + xrArr: 10233, + xrarr: 10230, + xutri: 9651, + ycirc: 375, + Aopf: 120120, + Ascr: 119964, + Auml: 196, + Barv: 10983, + Beta: 914, + Bopf: 120121, + Bscr: 8492, + CHcy: 1063, + COPY: 169, + Cdot: 266, + Copf: 8450, + Cscr: 119966, + DJcy: 1026, + DScy: 1029, + DZcy: 1039, + Darr: 8609, + Dopf: 120123, + Dscr: 119967, + Edot: 278, + Eopf: 120124, + Escr: 8496, + Esim: 10867, + Euml: 203, + Fopf: 120125, + Fscr: 8497, + GJcy: 1027, + Gdot: 288, + Gopf: 120126, + Gscr: 119970, + Hopf: 8461, + Hscr: 8459, + IEcy: 1045, + IOcy: 1025, + Idot: 304, + Iopf: 120128, + Iota: 921, + Iscr: 8464, + Iuml: 207, + Jopf: 120129, + Jscr: 119973, + KHcy: 1061, + KJcy: 1036, + Kopf: 120130, + Kscr: 119974, + LJcy: 1033, + Lang: 10218, + Larr: 8606, + Lopf: 120131, + Lscr: 8466, + Mopf: 120132, + Mscr: 8499, + NJcy: 1034, + Nopf: 8469, + Nscr: 119977, + Oopf: 120134, + Oscr: 119978, + Ouml: 214, + Popf: 8473, + Pscr: 119979, + QUOT: 34, + Qopf: 8474, + Qscr: 119980, + Rang: 10219, + Rarr: 8608, + Ropf: 8477, + Rscr: 8475, + SHcy: 1064, + Sopf: 120138, + Sqrt: 8730, + Sscr: 119982, + Star: 8902, + TScy: 1062, + Topf: 120139, + Tscr: 119983, + Uarr: 8607, + Uopf: 120140, + Upsi: 978, + Uscr: 119984, + Uuml: 220, + Vbar: 10987, + Vert: 8214, + Vopf: 120141, + Vscr: 119985, + Wopf: 120142, + Wscr: 119986, + Xopf: 120143, + Xscr: 119987, + YAcy: 1071, + YIcy: 1031, + YUcy: 1070, + Yopf: 120144, + Yscr: 119988, + Yuml: 376, + ZHcy: 1046, + Zdot: 379, + Zeta: 918, + Zopf: 8484, + Zscr: 119989, + andd: 10844, + andv: 10842, + ange: 10660, + aopf: 120146, + apid: 8779, + apos: 39, + ascr: 119990, + auml: 228, + bNot: 10989, + bbrk: 9141, + beta: 946, + beth: 8502, + bnot: 8976, + bopf: 120147, + boxH: 9552, + boxV: 9553, + boxh: 9472, + boxv: 9474, + bscr: 119991, + bsim: 8765, + bsol: 92, + bull: 8226, + bump: 8782, + cdot: 267, + cent: 162, + chcy: 1095, + cirE: 10691, + circ: 710, + cire: 8791, + comp: 8705, + cong: 8773, + copf: 120148, + copy: 169, + cscr: 119992, + csub: 10959, + csup: 10960, + dArr: 8659, + dHar: 10597, + darr: 8595, + dash: 8208, + diam: 8900, + djcy: 1106, + dopf: 120149, + dscr: 119993, + dscy: 1109, + dsol: 10742, + dtri: 9663, + dzcy: 1119, + eDot: 8785, + ecir: 8790, + edot: 279, + emsp: 8195, + ensp: 8194, + eopf: 120150, + epar: 8917, + epsi: 1013, + escr: 8495, + esim: 8770, + euml: 235, + euro: 8364, + excl: 33, + flat: 9837, + fnof: 402, + fopf: 120151, + fork: 8916, + fscr: 119995, + gdot: 289, + geqq: 8807, + gjcy: 1107, + gnap: 10890, + gneq: 10888, + gopf: 120152, + gscr: 8458, + gsim: 8819, + gtcc: 10919, + hArr: 8660, + half: 189, + harr: 8596, + hbar: 8463, + hopf: 120153, + hscr: 119997, + iecy: 1077, + imof: 8887, + iocy: 1105, + iopf: 120154, + iota: 953, + iscr: 119998, + isin: 8712, + iuml: 239, + jopf: 120155, + jscr: 119999, + khcy: 1093, + kjcy: 1116, + kopf: 120156, + kscr: 120000, + lArr: 8656, + lHar: 10594, + lang: 10216, + larr: 8592, + late: 10925, + lcub: 123, + ldca: 10550, + ldsh: 8626, + leqq: 8806, + ljcy: 1113, + lnap: 10889, + lneq: 10887, + lopf: 120157, + lozf: 10731, + lpar: 40, + lscr: 120001, + lsim: 8818, + lsqb: 91, + ltcc: 10918, + ltri: 9667, + macr: 175, + male: 9794, + malt: 10016, + mlcp: 10971, + mldr: 8230, + mopf: 120158, + mscr: 120002, + nbsp: 160, + ncap: 10819, + ncup: 10818, + ngeq: 8817, + ngtr: 8815, + nisd: 8954, + njcy: 1114, + nldr: 8229, + nleq: 8816, + nmid: 8740, + nopf: 120159, + npar: 8742, + nscr: 120003, + nsim: 8769, + nsub: 8836, + nsup: 8837, + ntgl: 8825, + ntlg: 8824, + oast: 8859, + ocir: 8858, + odiv: 10808, + odot: 8857, + ogon: 731, + oint: 8750, + omid: 10678, + oopf: 120160, + opar: 10679, + ordf: 170, + ordm: 186, + oror: 10838, + oscr: 8500, + osol: 8856, + ouml: 246, + para: 182, + part: 8706, + perp: 8869, + phiv: 966, + plus: 43, + popf: 120161, + prap: 10935, + prec: 8826, + prnE: 10933, + prod: 8719, + prop: 8733, + pscr: 120005, + qint: 10764, + qopf: 120162, + qscr: 120006, + quot: 34, + rArr: 8658, + rHar: 10596, + race: 10714, + rang: 10217, + rarr: 8594, + rcub: 125, + rdca: 10551, + rdsh: 8627, + real: 8476, + rect: 9645, + rhov: 1009, + ring: 730, + ropf: 120163, + rpar: 41, + rscr: 120007, + rsqb: 93, + rtri: 9657, + scap: 10936, + scnE: 10934, + sdot: 8901, + sect: 167, + semi: 59, + sext: 10038, + shcy: 1096, + sime: 8771, + simg: 10910, + siml: 10909, + smid: 8739, + smte: 10924, + solb: 10692, + sopf: 120164, + spar: 8741, + squf: 9642, + sscr: 120008, + star: 9734, + subE: 10949, + sube: 8838, + succ: 8827, + sung: 9834, + sup1: 185, + sup2: 178, + sup3: 179, + supE: 10950, + supe: 8839, + tbrk: 9140, + tdot: 8411, + tint: 8749, + toea: 10536, + topf: 120165, + tosa: 10537, + trie: 8796, + tscr: 120009, + tscy: 1094, + uArr: 8657, + uHar: 10595, + uarr: 8593, + uopf: 120166, + upsi: 965, + uscr: 120010, + utri: 9653, + uuml: 252, + vArr: 8661, + vBar: 10984, + varr: 8597, + vert: 124, + vopf: 120167, + vscr: 120011, + wopf: 120168, + wscr: 120012, + xcap: 8898, + xcup: 8899, + xmap: 10236, + xnis: 8955, + xopf: 120169, + xscr: 120013, + xvee: 8897, + yacy: 1103, + yicy: 1111, + yopf: 120170, + yscr: 120014, + yucy: 1102, + yuml: 255, + zdot: 380, + zeta: 950, + zhcy: 1078, + zopf: 120171, + zscr: 120015, + zwnj: 8204, + AMP: 38, + Acy: 1040, + Afr: 120068, + And: 10835, + Bcy: 1041, + Bfr: 120069, + Cap: 8914, + Cfr: 8493, + Chi: 935, + Cup: 8915, + Dcy: 1044, + Del: 8711, + Dfr: 120071, + Dot: 168, + ENG: 330, + ETH: 208, + Ecy: 1069, + Efr: 120072, + Eta: 919, + Fcy: 1060, + Ffr: 120073, + Gcy: 1043, + Gfr: 120074, + Hat: 94, + Hfr: 8460, + Icy: 1048, + Ifr: 8465, + Int: 8748, + Jcy: 1049, + Jfr: 120077, + Kcy: 1050, + Kfr: 120078, + Lcy: 1051, + Lfr: 120079, + Lsh: 8624, + Map: 10501, + Mcy: 1052, + Mfr: 120080, + Ncy: 1053, + Nfr: 120081, + Not: 10988, + Ocy: 1054, + Ofr: 120082, + Pcy: 1055, + Pfr: 120083, + Phi: 934, + Psi: 936, + Qfr: 120084, + REG: 174, + Rcy: 1056, + Rfr: 8476, + Rho: 929, + Rsh: 8625, + Scy: 1057, + Sfr: 120086, + Sub: 8912, + Sum: 8721, + Sup: 8913, + Tab: 9, + Tau: 932, + Tcy: 1058, + Tfr: 120087, + Ucy: 1059, + Ufr: 120088, + Vcy: 1042, + Vee: 8897, + Vfr: 120089, + Wfr: 120090, + Xfr: 120091, + Ycy: 1067, + Yfr: 120092, + Zcy: 1047, + Zfr: 8488, + acd: 8767, + acy: 1072, + afr: 120094, + amp: 38, + and: 8743, + ang: 8736, + apE: 10864, + ape: 8778, + ast: 42, + bcy: 1073, + bfr: 120095, + bot: 8869, + cap: 8745, + cfr: 120096, + chi: 967, + cir: 9675, + cup: 8746, + dcy: 1076, + deg: 176, + dfr: 120097, + die: 168, + div: 247, + dot: 729, + ecy: 1101, + efr: 120098, + egs: 10902, + ell: 8467, + els: 10901, + eng: 331, + eta: 951, + eth: 240, + fcy: 1092, + ffr: 120099, + gEl: 10892, + gap: 10886, + gcy: 1075, + gel: 8923, + geq: 8805, + ges: 10878, + gfr: 120100, + ggg: 8921, + glE: 10898, + gla: 10917, + glj: 10916, + gnE: 8809, + gne: 10888, + hfr: 120101, + icy: 1080, + iff: 8660, + ifr: 120102, + int: 8747, + jcy: 1081, + jfr: 120103, + kcy: 1082, + kfr: 120104, + lEg: 10891, + lap: 10885, + lat: 10923, + lcy: 1083, + leg: 8922, + leq: 8804, + les: 10877, + lfr: 120105, + lgE: 10897, + lnE: 8808, + lne: 10887, + loz: 9674, + lrm: 8206, + lsh: 8624, + map: 8614, + mcy: 1084, + mfr: 120106, + mho: 8487, + mid: 8739, + nap: 8777, + ncy: 1085, + nfr: 120107, + nge: 8817, + ngt: 8815, + nis: 8956, + niv: 8715, + nle: 8816, + nlt: 8814, + not: 172, + npr: 8832, + nsc: 8833, + num: 35, + ocy: 1086, + ofr: 120108, + ogt: 10689, + ohm: 8486, + olt: 10688, + ord: 10845, + orv: 10843, + par: 8741, + pcy: 1087, + pfr: 120109, + phi: 966, + piv: 982, + prE: 10931, + pre: 10927, + psi: 968, + qfr: 120110, + rcy: 1088, + reg: 174, + rfr: 120111, + rho: 961, + rlm: 8207, + rsh: 8625, + scE: 10932, + sce: 10928, + scy: 1089, + sfr: 120112, + shy: 173, + sim: 8764, + smt: 10922, + sol: 47, + squ: 9633, + sub: 8834, + sum: 8721, + sup: 8835, + tau: 964, + tcy: 1090, + tfr: 120113, + top: 8868, + ucy: 1091, + ufr: 120114, + uml: 168, + vcy: 1074, + vee: 8744, + vfr: 120115, + wfr: 120116, + xfr: 120117, + ycy: 1099, + yen: 165, + yfr: 120118, + zcy: 1079, + zfr: 120119, + zwj: 8205, + DD: 8517, + GT: 62, + Gg: 8921, + Gt: 8811, + Im: 8465, + LT: 60, + Ll: 8920, + Lt: 8810, + Mu: 924, + Nu: 925, + Or: 10836, + Pi: 928, + Pr: 10939, + Re: 8476, + Sc: 10940, + Xi: 926, + ac: 8766, + af: 8289, + ap: 8776, + dd: 8518, + ee: 8519, + eg: 10906, + el: 10905, + gE: 8807, + ge: 8805, + gg: 8811, + gl: 8823, + gt: 62, + ic: 8291, + ii: 8520, + in: 8712, + it: 8290, + lE: 8806, + le: 8804, + lg: 8822, + ll: 8810, + lt: 60, + mp: 8723, + mu: 956, + ne: 8800, + ni: 8715, + nu: 957, + oS: 9416, + or: 8744, + pi: 960, + pm: 177, + pr: 8826, + rx: 8478, + sc: 8827, + wp: 8472, + wr: 8768, + xi: 958, }; const windows_1252 = [ - 8364, - 129, - 8218, - 402, - 8222, - 8230, - 8224, - 8225, - 710, - 8240, - 352, - 8249, - 338, - 141, - 381, - 143, - 144, - 8216, - 8217, - 8220, - 8221, - 8226, - 8211, - 8212, - 732, - 8482, - 353, - 8250, - 339, - 157, - 382, - 376 + 8364, + 129, + 8218, + 402, + 8222, + 8230, + 8224, + 8225, + 710, + 8240, + 352, + 8249, + 338, + 141, + 381, + 143, + 144, + 8216, + 8217, + 8220, + 8221, + 8226, + 8211, + 8212, + 732, + 8482, + 353, + 8250, + 339, + 157, + 382, + 376, ]; -const entity_pattern = new RegExp( - `&(#?(?:x[\\w\\d]+|\\d+|${Object.keys(entities).join('|')}))(?:;|\\b)`, - 'g' -); +const entity_pattern = new RegExp(`&(#?(?:x[\\w\\d]+|\\d+|${Object.keys(entities).join('|')}))(?:;|\\b)`, 'g'); function decode_character_references(html) { - return html.replace(entity_pattern, (match, entity) => { - let code; - - // Handle named entities - if (entity[0] !== '#') { - code = entities[entity]; - } else if (entity[1] === 'x') { - code = parseInt(entity.substring(2), 16); - } else { - code = parseInt(entity.substring(1), 10); - } + return html.replace(entity_pattern, (match, entity) => { + let code; + + // Handle named entities + if (entity[0] !== '#') { + code = entities[entity]; + } else if (entity[1] === 'x') { + code = parseInt(entity.substring(2), 16); + } else { + code = parseInt(entity.substring(1), 10); + } - if (!code) { - return match; - } + if (!code) { + return match; + } - return String.fromCodePoint(validate_code(code)); - }); + return String.fromCodePoint(validate_code(code)); + }); } const NUL = 0; @@ -3265,240 +3250,233 @@ const NUL = 0; // // Source: http://en.wikipedia.org/wiki/Character_encodings_in_HTML#Illegal_characters function validate_code(code) { - // line feed becomes generic whitespace - if (code === 10) { - return 32; - } - - // ASCII range. (Why someone would use HTML entities for ASCII characters I don't know, but...) - if (code < 128) { - return code; - } - - // code points 128-159 are dealt with leniently by browsers, but they're incorrect. We need - // to correct the mistake or we'll end up with missing € signs and so on - if (code <= 159) { - return windows_1252[code - 128]; - } - - // basic multilingual plane - if (code < 55296) { - return code; - } - - // UTF-16 surrogate halves - if (code <= 57343) { - return NUL; - } - - // rest of the basic multilingual plane - if (code <= 65535) { - return code; - } - - // supplementary multilingual plane 0x10000 - 0x1ffff - if (code >= 65536 && code <= 131071) { - return code; - } - - // supplementary ideographic plane 0x20000 - 0x2ffff - if (code >= 131072 && code <= 196607) { - return code; - } - - return NUL; + // line feed becomes generic whitespace + if (code === 10) { + return 32; + } + + // ASCII range. (Why someone would use HTML entities for ASCII characters I don't know, but...) + if (code < 128) { + return code; + } + + // code points 128-159 are dealt with leniently by browsers, but they're incorrect. We need + // to correct the mistake or we'll end up with missing € signs and so on + if (code <= 159) { + return windows_1252[code - 128]; + } + + // basic multilingual plane + if (code < 55296) { + return code; + } + + // UTF-16 surrogate halves + if (code <= 57343) { + return NUL; + } + + // rest of the basic multilingual plane + if (code <= 65535) { + return code; + } + + // supplementary multilingual plane 0x10000 - 0x1ffff + if (code >= 65536 && code <= 131071) { + return code; + } + + // supplementary ideographic plane 0x20000 - 0x2ffff + if (code >= 131072 && code <= 196607) { + return code; + } + + return NUL; } // based on http://developers.whatwg.org/syntax.html#syntax-tag-omission const disallowed_contents = new Map([ - ['li', new Set(['li'])], - ['dt', new Set(['dt', 'dd'])], - ['dd', new Set(['dt', 'dd'])], - [ - 'p', - new Set( - 'address article aside blockquote div dl fieldset footer form h1 h2 h3 h4 h5 h6 header hgroup hr main menu nav ol p pre section table ul'.split( - ' ' - ) - ) - ], - ['rt', new Set(['rt', 'rp'])], - ['rp', new Set(['rt', 'rp'])], - ['optgroup', new Set(['optgroup'])], - ['option', new Set(['option', 'optgroup'])], - ['thead', new Set(['tbody', 'tfoot'])], - ['tbody', new Set(['tbody', 'tfoot'])], - ['tfoot', new Set(['tbody'])], - ['tr', new Set(['tr', 'tbody'])], - ['td', new Set(['td', 'th', 'tr'])], - ['th', new Set(['td', 'th', 'tr'])] + ['li', new Set(['li'])], + ['dt', new Set(['dt', 'dd'])], + ['dd', new Set(['dt', 'dd'])], + ['p', new Set('address article aside blockquote div dl fieldset footer form h1 h2 h3 h4 h5 h6 header hgroup hr main menu nav ol p pre section table ul'.split(' '))], + ['rt', new Set(['rt', 'rp'])], + ['rp', new Set(['rt', 'rp'])], + ['optgroup', new Set(['optgroup'])], + ['option', new Set(['option', 'optgroup'])], + ['thead', new Set(['tbody', 'tfoot'])], + ['tbody', new Set(['tbody', 'tfoot'])], + ['tfoot', new Set(['tbody'])], + ['tr', new Set(['tr', 'tbody'])], + ['td', new Set(['td', 'th', 'tr'])], + ['th', new Set(['td', 'th', 'tr'])], ]); // can this be a child of the parent element, or does it implicitly // close it, like `<li>one<li>two`? function closing_tag_omitted(current, next) { - if (disallowed_contents.has(current)) { - if (!next || disallowed_contents.get(current).has(next)) { - return true; - } - } + if (disallowed_contents.has(current)) { + if (!next || disallowed_contents.get(current).has(next)) { + return true; + } + } - return false; + return false; } // Adapted from https://github.com/acornjs/acorn/blob/6584815dca7440e00de841d1dad152302fdd7ca5/src/tokenize.js // Reproduced under MIT License https://github.com/acornjs/acorn/blob/master/LICENSE function full_char_code_at(str, i) { - const code = str.charCodeAt(i); - if (code <= 0xd7ff || code >= 0xe000) return code; + const code = str.charCodeAt(i); + if (code <= 0xd7ff || code >= 0xe000) return code; - const next = str.charCodeAt(i + 1); - return (code << 10) + next - 0x35fdc00; + const next = str.charCodeAt(i + 1); + return (code << 10) + next - 0x35fdc00; } const globals = new Set([ - 'alert', - 'Array', - 'Boolean', - 'clearInterval', - 'clearTimeout', - 'confirm', - 'console', - 'Date', - 'decodeURI', - 'decodeURIComponent', - 'document', - 'Element', - 'encodeURI', - 'encodeURIComponent', - 'Error', - 'EvalError', - 'Event', - 'EventSource', - 'fetch', - 'global', - 'globalThis', - 'history', - 'Infinity', - 'InternalError', - 'Intl', - 'isFinite', - 'isNaN', - 'JSON', - 'localStorage', - 'location', - 'Map', - 'Math', - 'NaN', - 'navigator', - 'Number', - 'Node', - 'Object', - 'parseFloat', - 'parseInt', - 'process', - 'Promise', - 'prompt', - 'RangeError', - 'ReferenceError', - 'RegExp', - 'sessionStorage', - 'Set', - 'setInterval', - 'setTimeout', - 'String', - 'SyntaxError', - 'TypeError', - 'undefined', - 'URIError', - 'URL', - 'window' + 'alert', + 'Array', + 'Boolean', + 'clearInterval', + 'clearTimeout', + 'confirm', + 'console', + 'Date', + 'decodeURI', + 'decodeURIComponent', + 'document', + 'Element', + 'encodeURI', + 'encodeURIComponent', + 'Error', + 'EvalError', + 'Event', + 'EventSource', + 'fetch', + 'global', + 'globalThis', + 'history', + 'Infinity', + 'InternalError', + 'Intl', + 'isFinite', + 'isNaN', + 'JSON', + 'localStorage', + 'location', + 'Map', + 'Math', + 'NaN', + 'navigator', + 'Number', + 'Node', + 'Object', + 'parseFloat', + 'parseInt', + 'process', + 'Promise', + 'prompt', + 'RangeError', + 'ReferenceError', + 'RegExp', + 'sessionStorage', + 'Set', + 'setInterval', + 'setTimeout', + 'String', + 'SyntaxError', + 'TypeError', + 'undefined', + 'URIError', + 'URL', + 'window', ]); const reserved = new Set([ - 'arguments', - 'await', - 'break', - 'case', - 'catch', - 'class', - 'const', - 'continue', - 'debugger', - 'default', - 'delete', - 'do', - 'else', - 'enum', - 'eval', - 'export', - 'extends', - 'false', - 'finally', - 'for', - 'function', - 'if', - 'implements', - 'import', - 'in', - 'instanceof', - 'interface', - 'let', - 'new', - 'null', - 'package', - 'private', - 'protected', - 'public', - 'return', - 'static', - 'super', - 'switch', - 'this', - 'throw', - 'true', - 'try', - 'typeof', - 'var', - 'void', - 'while', - 'with', - 'yield' + 'arguments', + 'await', + 'break', + 'case', + 'catch', + 'class', + 'const', + 'continue', + 'debugger', + 'default', + 'delete', + 'do', + 'else', + 'enum', + 'eval', + 'export', + 'extends', + 'false', + 'finally', + 'for', + 'function', + 'if', + 'implements', + 'import', + 'in', + 'instanceof', + 'interface', + 'let', + 'new', + 'null', + 'package', + 'private', + 'protected', + 'public', + 'return', + 'static', + 'super', + 'switch', + 'this', + 'throw', + 'true', + 'try', + 'typeof', + 'var', + 'void', + 'while', + 'with', + 'yield', ]); const void_element_names = /^(?:area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/; function is_void(name) { - return void_element_names.test(name) || name.toLowerCase() === '!doctype'; + return void_element_names.test(name) || name.toLowerCase() === '!doctype'; } function is_valid(str) { - let i = 0; + let i = 0; - while (i < str.length) { - const code = full_char_code_at(str, i); - if (!(i === 0 ? isIdentifierStart : isIdentifierChar)(code, true)) return false; + while (i < str.length) { + const code = full_char_code_at(str, i); + if (!(i === 0 ? isIdentifierStart : isIdentifierChar)(code, true)) return false; - i += code <= 0xffff ? 1 : 2; - } + i += code <= 0xffff ? 1 : 2; + } - return true; + return true; } function sanitize(name) { - return name - .replace(/[^a-zA-Z0-9_]+/g, '_') - .replace(/^_/, '') - .replace(/_$/, '') - .replace(/^[0-9]/, '_$&'); + return name + .replace(/[^a-zA-Z0-9_]+/g, '_') + .replace(/^_/, '') + .replace(/_$/, '') + .replace(/^[0-9]/, '_$&'); } function fuzzymatch(name, names) { - const set = new FuzzySet(names); - const matches = set.get(name); + const set = new FuzzySet(names); + const matches = set.get(name); - return matches && matches[0] && matches[0][0] > 0.7 ? matches[0][1] : null; + return matches && matches[0] && matches[0][0] > 0.7 ? matches[0][1] : null; } // adapted from https://github.com/Glench/fuzzyset.js/blob/master/lib/fuzzyset.js @@ -3509,263 +3487,260 @@ const GRAM_SIZE_UPPER = 3; // return an edit distance from 0 to 1 function _distance(str1, str2) { - if (str1 === null && str2 === null) { - throw 'Trying to compare two null values'; - } - if (str1 === null || str2 === null) return 0; - str1 = String(str1); - str2 = String(str2); - - const distance = levenshtein(str1, str2); - if (str1.length > str2.length) { - return 1 - distance / str1.length; - } else { - return 1 - distance / str2.length; - } + if (str1 === null && str2 === null) { + throw 'Trying to compare two null values'; + } + if (str1 === null || str2 === null) return 0; + str1 = String(str1); + str2 = String(str2); + + const distance = levenshtein(str1, str2); + if (str1.length > str2.length) { + return 1 - distance / str1.length; + } else { + return 1 - distance / str2.length; + } } // helper functions function levenshtein(str1, str2) { - const current = []; - let prev; - let value; - - for (let i = 0; i <= str2.length; i++) { - for (let j = 0; j <= str1.length; j++) { - if (i && j) { - if (str1.charAt(j - 1) === str2.charAt(i - 1)) { - value = prev; - } else { - value = Math.min(current[j], current[j - 1], prev) + 1; - } - } else { - value = i + j; - } + const current = []; + let prev; + let value; + + for (let i = 0; i <= str2.length; i++) { + for (let j = 0; j <= str1.length; j++) { + if (i && j) { + if (str1.charAt(j - 1) === str2.charAt(i - 1)) { + value = prev; + } else { + value = Math.min(current[j], current[j - 1], prev) + 1; + } + } else { + value = i + j; + } - prev = current[j]; - current[j] = value; - } - } + prev = current[j]; + current[j] = value; + } + } - return current.pop(); + return current.pop(); } const non_word_regex = /[^\w, ]+/; function iterate_grams(value, gram_size = 2) { - const simplified = '-' + value.toLowerCase().replace(non_word_regex, '') + '-'; - const len_diff = gram_size - simplified.length; - const results = []; + const simplified = '-' + value.toLowerCase().replace(non_word_regex, '') + '-'; + const len_diff = gram_size - simplified.length; + const results = []; - if (len_diff > 0) { - for (let i = 0; i < len_diff; ++i) { - value += '-'; - } - } - for (let i = 0; i < simplified.length - gram_size + 1; ++i) { - results.push(simplified.slice(i, i + gram_size)); - } - return results; + if (len_diff > 0) { + for (let i = 0; i < len_diff; ++i) { + value += '-'; + } + } + for (let i = 0; i < simplified.length - gram_size + 1; ++i) { + results.push(simplified.slice(i, i + gram_size)); + } + return results; } function gram_counter(value, gram_size = 2) { - // return an object where key=gram, value=number of occurrences - const result = {}; - const grams = iterate_grams(value, gram_size); - let i = 0; - - for (i; i < grams.length; ++i) { - if (grams[i] in result) { - result[grams[i]] += 1; - } else { - result[grams[i]] = 1; - } - } - return result; + // return an object where key=gram, value=number of occurrences + const result = {}; + const grams = iterate_grams(value, gram_size); + let i = 0; + + for (i; i < grams.length; ++i) { + if (grams[i] in result) { + result[grams[i]] += 1; + } else { + result[grams[i]] = 1; + } + } + return result; } function sort_descending(a, b) { - return b[0] - a[0]; + return b[0] - a[0]; } class FuzzySet { - __init() {this.exact_set = {};} - __init2() {this.match_dict = {};} - __init3() {this.items = {};} - - constructor(arr) {FuzzySet.prototype.__init.call(this);FuzzySet.prototype.__init2.call(this);FuzzySet.prototype.__init3.call(this); - // initialization - for (let i = GRAM_SIZE_LOWER; i < GRAM_SIZE_UPPER + 1; ++i) { - this.items[i] = []; - } + __init() { + this.exact_set = {}; + } + __init2() { + this.match_dict = {}; + } + __init3() { + this.items = {}; + } - // add all the items to the set - for (let i = 0; i < arr.length; ++i) { - this.add(arr[i]); - } - } + constructor(arr) { + FuzzySet.prototype.__init.call(this); + FuzzySet.prototype.__init2.call(this); + FuzzySet.prototype.__init3.call(this); + // initialization + for (let i = GRAM_SIZE_LOWER; i < GRAM_SIZE_UPPER + 1; ++i) { + this.items[i] = []; + } - add(value) { - const normalized_value = value.toLowerCase(); - if (normalized_value in this.exact_set) { - return false; - } + // add all the items to the set + for (let i = 0; i < arr.length; ++i) { + this.add(arr[i]); + } + } - let i = GRAM_SIZE_LOWER; - for (i; i < GRAM_SIZE_UPPER + 1; ++i) { - this._add(value, i); - } - } - - _add(value, gram_size) { - const normalized_value = value.toLowerCase(); - const items = this.items[gram_size] || []; - const index = items.length; - - items.push(0); - const gram_counts = gram_counter(normalized_value, gram_size); - let sum_of_square_gram_counts = 0; - let gram; - let gram_count; - - for (gram in gram_counts) { - gram_count = gram_counts[gram]; - sum_of_square_gram_counts += Math.pow(gram_count, 2); - if (gram in this.match_dict) { - this.match_dict[gram].push([index, gram_count]); - } else { - this.match_dict[gram] = [[index, gram_count]]; - } - } - const vector_normal = Math.sqrt(sum_of_square_gram_counts); - items[index] = [vector_normal, normalized_value]; - this.items[gram_size] = items; - this.exact_set[normalized_value] = value; - } - - get(value) { - const normalized_value = value.toLowerCase(); - const result = this.exact_set[normalized_value]; - - if (result) { - return [[1, result]]; - } + add(value) { + const normalized_value = value.toLowerCase(); + if (normalized_value in this.exact_set) { + return false; + } - let results = []; - // start with high gram size and if there are no results, go to lower gram sizes - for ( - let gram_size = GRAM_SIZE_UPPER; - gram_size >= GRAM_SIZE_LOWER; - --gram_size - ) { - results = this.__get(value, gram_size); - if (results) { - return results; - } - } - return null; - } - - __get(value, gram_size) { - const normalized_value = value.toLowerCase(); - const matches = {}; - const gram_counts = gram_counter(normalized_value, gram_size); - const items = this.items[gram_size]; - let sum_of_square_gram_counts = 0; - let gram; - let gram_count; - let i; - let index; - let other_gram_count; - - for (gram in gram_counts) { - gram_count = gram_counts[gram]; - sum_of_square_gram_counts += Math.pow(gram_count, 2); - if (gram in this.match_dict) { - for (i = 0; i < this.match_dict[gram].length; ++i) { - index = this.match_dict[gram][i][0]; - other_gram_count = this.match_dict[gram][i][1]; - if (index in matches) { - matches[index] += gram_count * other_gram_count; - } else { - matches[index] = gram_count * other_gram_count; - } - } - } - } + let i = GRAM_SIZE_LOWER; + for (i; i < GRAM_SIZE_UPPER + 1; ++i) { + this._add(value, i); + } + } - const vector_normal = Math.sqrt(sum_of_square_gram_counts); - let results = []; - let match_score; - - // build a results list of [score, str] - for (const match_index in matches) { - match_score = matches[match_index]; - results.push([ - match_score / (vector_normal * items[match_index][0]), - items[match_index][1] - ]); - } + _add(value, gram_size) { + const normalized_value = value.toLowerCase(); + const items = this.items[gram_size] || []; + const index = items.length; + + items.push(0); + const gram_counts = gram_counter(normalized_value, gram_size); + let sum_of_square_gram_counts = 0; + let gram; + let gram_count; + + for (gram in gram_counts) { + gram_count = gram_counts[gram]; + sum_of_square_gram_counts += Math.pow(gram_count, 2); + if (gram in this.match_dict) { + this.match_dict[gram].push([index, gram_count]); + } else { + this.match_dict[gram] = [[index, gram_count]]; + } + } + const vector_normal = Math.sqrt(sum_of_square_gram_counts); + items[index] = [vector_normal, normalized_value]; + this.items[gram_size] = items; + this.exact_set[normalized_value] = value; + } - results.sort(sort_descending); + get(value) { + const normalized_value = value.toLowerCase(); + const result = this.exact_set[normalized_value]; - let new_results = []; - const end_index = Math.min(50, results.length); - // truncate somewhat arbitrarily to 50 - for (let i = 0; i < end_index; ++i) { - new_results.push([ - _distance(results[i][1], normalized_value), - results[i][1] - ]); - } - results = new_results; - results.sort(sort_descending); + if (result) { + return [[1, result]]; + } - new_results = []; - for (let i = 0; i < results.length; ++i) { - if (results[i][0] == results[0][0]) { - new_results.push([results[i][0], this.exact_set[results[i][1]]]); - } - } + let results = []; + // start with high gram size and if there are no results, go to lower gram sizes + for (let gram_size = GRAM_SIZE_UPPER; gram_size >= GRAM_SIZE_LOWER; --gram_size) { + results = this.__get(value, gram_size); + if (results) { + return results; + } + } + return null; + } + + __get(value, gram_size) { + const normalized_value = value.toLowerCase(); + const matches = {}; + const gram_counts = gram_counter(normalized_value, gram_size); + const items = this.items[gram_size]; + let sum_of_square_gram_counts = 0; + let gram; + let gram_count; + let i; + let index; + let other_gram_count; + + for (gram in gram_counts) { + gram_count = gram_counts[gram]; + sum_of_square_gram_counts += Math.pow(gram_count, 2); + if (gram in this.match_dict) { + for (i = 0; i < this.match_dict[gram].length; ++i) { + index = this.match_dict[gram][i][0]; + other_gram_count = this.match_dict[gram][i][1]; + if (index in matches) { + matches[index] += gram_count * other_gram_count; + } else { + matches[index] = gram_count * other_gram_count; + } + } + } + } + + const vector_normal = Math.sqrt(sum_of_square_gram_counts); + let results = []; + let match_score; + + // build a results list of [score, str] + for (const match_index in matches) { + match_score = matches[match_index]; + results.push([match_score / (vector_normal * items[match_index][0]), items[match_index][1]]); + } + + results.sort(sort_descending); + + let new_results = []; + const end_index = Math.min(50, results.length); + // truncate somewhat arbitrarily to 50 + for (let i = 0; i < end_index; ++i) { + new_results.push([_distance(results[i][1], normalized_value), results[i][1]]); + } + results = new_results; + results.sort(sort_descending); + + new_results = []; + for (let i = 0; i < results.length; ++i) { + if (results[i][0] == results[0][0]) { + new_results.push([results[i][0], this.exact_set[results[i][1]]]); + } + } - return new_results; - } + return new_results; + } } function list(items, conjunction = 'or') { - if (items.length === 1) return items[0]; - return `${items.slice(0, -1).join(', ')} ${conjunction} ${items[ - items.length - 1 - ]}`; + if (items.length === 1) return items[0]; + return `${items.slice(0, -1).join(', ')} ${conjunction} ${items[items.length - 1]}`; } // eslint-disable-next-line no-useless-escape const valid_tag_name = /^\!?[a-zA-Z]{1,}:?[a-zA-Z0-9\-]*/; const meta_tags = new Map([ - ['svelte:head', 'Head'], - ['svelte:options', 'Options'], - ['svelte:window', 'Window'], - ['svelte:body', 'Body'] + ['svelte:head', 'Head'], + ['svelte:options', 'Options'], + ['svelte:window', 'Window'], + ['svelte:body', 'Body'], ]); const valid_meta_tags = Array.from(meta_tags.keys()).concat('svelte:self', 'svelte:component', 'svelte:fragment'); const specials = new Map([ - [ - 'script', - { - read: read_script, - property: 'js' - } - ], - [ - 'style', - { - read: read_style, - property: 'css' - } - ] + [ + 'script', + { + read: read_script, + property: 'js', + }, + ], + [ + 'style', + { + read: read_style, + property: 'css', + }, + ], ]); const SELF = /^svelte:self(?=[\s/>])/; @@ -3773,491 +3748,533 @@ const COMPONENT = /^svelte:component(?=[\s/>])/; const SLOT = /^svelte:fragment(?=[\s/>])/; function parent_is_head(stack) { - let i = stack.length; - while (i--) { - const { type } = stack[i]; - if (type === 'Head') return true; - if (type === 'Element' || type === 'InlineComponent') return false; - } - return false; + let i = stack.length; + while (i--) { + const { type } = stack[i]; + if (type === 'Head') return true; + if (type === 'Element' || type === 'InlineComponent') return false; + } + return false; } function tag(parser) { - const start = parser.index++; + const start = parser.index++; - let parent = parser.current(); + let parent = parser.current(); - if (parser.eat('!--')) { - const data = parser.read_until(/-->/); - parser.eat('-->', true, 'comment was left open, expected -->'); + if (parser.eat('!--')) { + const data = parser.read_until(/-->/); + parser.eat('-->', true, 'comment was left open, expected -->'); - parser.current().children.push({ - start, - end: parser.index, - type: 'Comment', - data - }); + parser.current().children.push({ + start, + end: parser.index, + type: 'Comment', + data, + }); - return; - } + return; + } - const is_closing_tag = parser.eat('/'); + const is_closing_tag = parser.eat('/'); + + const name = read_tag_name(parser); + + if (meta_tags.has(name)) { + const slug = meta_tags.get(name).toLowerCase(); + if (is_closing_tag) { + if ((name === 'svelte:window' || name === 'svelte:body') && parser.current().children.length) { + parser.error( + { + code: `invalid-${slug}-content`, + message: `<${name}> cannot have children`, + }, + parser.current().children[0].start + ); + } + } else { + if (name in parser.meta_tags) { + parser.error( + { + code: `duplicate-${slug}`, + message: `A component can only have one <${name}> tag`, + }, + start + ); + } - const name = read_tag_name(parser); + if (parser.stack.length > 1) { + parser.error( + { + code: `invalid-${slug}-placement`, + message: `<${name}> tags cannot be inside elements or blocks`, + }, + start + ); + } - if (meta_tags.has(name)) { - const slug = meta_tags.get(name).toLowerCase(); - if (is_closing_tag) { - if ( - (name === 'svelte:window' || name === 'svelte:body') && - parser.current().children.length - ) { - parser.error({ - code: `invalid-${slug}-content`, - message: `<${name}> cannot have children` - }, parser.current().children[0].start); - } - } else { - if (name in parser.meta_tags) { - parser.error({ - code: `duplicate-${slug}`, - message: `A component can only have one <${name}> tag` - }, start); - } + parser.meta_tags[name] = true; + } + } - if (parser.stack.length > 1) { - parser.error({ - code: `invalid-${slug}-placement`, - message: `<${name}> tags cannot be inside elements or blocks` - }, start); - } + const type = meta_tags.has(name) + ? meta_tags.get(name) + : /[A-Z]/.test(name[0]) || name === 'svelte:self' || name === 'svelte:component' + ? 'InlineComponent' + : name === 'svelte:fragment' + ? 'SlotTemplate' + : name === 'title' && parent_is_head(parser.stack) + ? 'Title' + : name === 'slot' && !parser.customElement + ? 'Slot' + : 'Element'; + + const element = { + start, + end: null, // filled in later + type, + name, + attributes: [], + children: [], + }; - parser.meta_tags[name] = true; - } - } - - const type = meta_tags.has(name) - ? meta_tags.get(name) - : (/[A-Z]/.test(name[0]) || name === 'svelte:self' || name === 'svelte:component') ? 'InlineComponent' - : name === 'svelte:fragment' ? 'SlotTemplate' - : name === 'title' && parent_is_head(parser.stack) ? 'Title' - : name === 'slot' && !parser.customElement ? 'Slot' : 'Element'; - - const element = { - start, - end: null, // filled in later - type, - name, - attributes: [], - children: [] - }; - - parser.allow_whitespace(); - - if (is_closing_tag) { - if (is_void(name)) { - parser.error({ - code: 'invalid-void-content', - message: `<${name}> is a void element and cannot have children, or a closing tag` - }, start); - } + parser.allow_whitespace(); + + if (is_closing_tag) { + if (is_void(name)) { + parser.error( + { + code: 'invalid-void-content', + message: `<${name}> is a void element and cannot have children, or a closing tag`, + }, + start + ); + } - parser.eat('>', true); - - // close any elements that don't have their own closing tags, e.g. <div><p></div> - while (parent.name !== name) { - if (parent.type !== 'Element') { - const message = parser.last_auto_closed_tag && parser.last_auto_closed_tag.tag === name - ? `</${name}> attempted to close <${name}> that was already automatically closed by <${parser.last_auto_closed_tag.reason}>` - : `</${name}> attempted to close an element that was not open`; - parser.error({ - code: 'invalid-closing-tag', - message - }, start); - } + parser.eat('>', true); + + // close any elements that don't have their own closing tags, e.g. <div><p></div> + while (parent.name !== name) { + if (parent.type !== 'Element') { + const message = + parser.last_auto_closed_tag && parser.last_auto_closed_tag.tag === name + ? `</${name}> attempted to close <${name}> that was already automatically closed by <${parser.last_auto_closed_tag.reason}>` + : `</${name}> attempted to close an element that was not open`; + parser.error( + { + code: 'invalid-closing-tag', + message, + }, + start + ); + } - parent.end = start; - parser.stack.pop(); + parent.end = start; + parser.stack.pop(); - parent = parser.current(); - } + parent = parser.current(); + } - parent.end = parser.index; - parser.stack.pop(); + parent.end = parser.index; + parser.stack.pop(); - if (parser.last_auto_closed_tag && parser.stack.length < parser.last_auto_closed_tag.depth) { - parser.last_auto_closed_tag = null; - } + if (parser.last_auto_closed_tag && parser.stack.length < parser.last_auto_closed_tag.depth) { + parser.last_auto_closed_tag = null; + } - return; - } else if (closing_tag_omitted(parent.name, name)) { - parent.end = start; - parser.stack.pop(); - parser.last_auto_closed_tag = { - tag: parent.name, - reason: name, - depth: parser.stack.length - }; - } - - const unique_names = new Set(); - - let attribute; - while ((attribute = read_attribute(parser, unique_names))) { - element.attributes.push(attribute); - parser.allow_whitespace(); - } - - if (name === 'svelte:component') { - const index = element.attributes.findIndex(attr => attr.type === 'Attribute' && attr.name === 'this'); - if (!~index) { - parser.error({ - code: 'missing-component-definition', - message: "<svelte:component> must have a 'this' attribute" - }, start); - } + return; + } else if (closing_tag_omitted(parent.name, name)) { + parent.end = start; + parser.stack.pop(); + parser.last_auto_closed_tag = { + tag: parent.name, + reason: name, + depth: parser.stack.length, + }; + } - const definition = element.attributes.splice(index, 1)[0]; - if (definition.value === true || definition.value.length !== 1 || definition.value[0].type === 'Text') { - parser.error({ - code: 'invalid-component-definition', - message: 'invalid component definition' - }, definition.start); - } + const unique_names = new Set(); + + let attribute; + while ((attribute = read_attribute(parser, unique_names))) { + element.attributes.push(attribute); + parser.allow_whitespace(); + } + + if (name === 'svelte:component') { + const index = element.attributes.findIndex((attr) => attr.type === 'Attribute' && attr.name === 'this'); + if (!~index) { + parser.error( + { + code: 'missing-component-definition', + message: "<svelte:component> must have a 'this' attribute", + }, + start + ); + } - element.expression = definition.value[0].expression; - } - - // special cases – top-level <script> and <style> - if (specials.has(name) && parser.stack.length === 1) { - const special = specials.get(name); - - parser.eat('>', true); - const content = special.read(parser, start, element.attributes); - if (content) parser[special.property].push(content); - return; - } - - parser.current().children.push(element); - - const self_closing = parser.eat('/') || is_void(name); - - parser.eat('>', true); - - if (self_closing) { - // don't push self-closing elements onto the stack - element.end = parser.index; - } else if (name === 'textarea') { - // special case - element.children = read_sequence( - parser, - () => - parser.template.slice(parser.index, parser.index + 11) === '</textarea>' - ); - parser.read(/<\/textarea>/); - element.end = parser.index; - } else if (name === 'script' || name === 'style') { - // special case - const start = parser.index; - const data = parser.read_until(new RegExp(`</${name}>`)); - const end = parser.index; - element.children.push({ start, end, type: 'Text', data }); - parser.eat(`</${name}>`, true); - element.end = parser.index; - } else { - parser.stack.push(element); - } + const definition = element.attributes.splice(index, 1)[0]; + if (definition.value === true || definition.value.length !== 1 || definition.value[0].type === 'Text') { + parser.error( + { + code: 'invalid-component-definition', + message: 'invalid component definition', + }, + definition.start + ); + } + + element.expression = definition.value[0].expression; + } + + // special cases – top-level <script> and <style> + if (specials.has(name) && parser.stack.length === 1) { + const special = specials.get(name); + + parser.eat('>', true); + const content = special.read(parser, start, element.attributes); + if (content) parser[special.property].push(content); + return; + } + + parser.current().children.push(element); + + const self_closing = parser.eat('/') || is_void(name); + + parser.eat('>', true); + + if (self_closing) { + // don't push self-closing elements onto the stack + element.end = parser.index; + } else if (name === 'textarea') { + // special case + element.children = read_sequence(parser, () => parser.template.slice(parser.index, parser.index + 11) === '</textarea>'); + parser.read(/<\/textarea>/); + element.end = parser.index; + } else if (name === 'script' || name === 'style') { + // special case + const start = parser.index; + const data = parser.read_until(new RegExp(`</${name}>`)); + const end = parser.index; + element.children.push({ start, end, type: 'Text', data }); + parser.eat(`</${name}>`, true); + element.end = parser.index; + } else { + parser.stack.push(element); + } } function read_tag_name(parser) { - const start = parser.index; - - if (parser.read(SELF)) { - // check we're inside a block, otherwise this - // will cause infinite recursion - let i = parser.stack.length; - let legal = false; - - while (i--) { - const fragment = parser.stack[i]; - if (fragment.type === 'IfBlock' || fragment.type === 'EachBlock' || fragment.type === 'InlineComponent') { - legal = true; - break; - } - } + const start = parser.index; + + if (parser.read(SELF)) { + // check we're inside a block, otherwise this + // will cause infinite recursion + let i = parser.stack.length; + let legal = false; + + while (i--) { + const fragment = parser.stack[i]; + if (fragment.type === 'IfBlock' || fragment.type === 'EachBlock' || fragment.type === 'InlineComponent') { + legal = true; + break; + } + } - if (!legal) { - parser.error({ - code: 'invalid-self-placement', - message: '<svelte:self> components can only exist inside {#if} blocks, {#each} blocks, or slots passed to components' - }, start); - } + if (!legal) { + parser.error( + { + code: 'invalid-self-placement', + message: '<svelte:self> components can only exist inside {#if} blocks, {#each} blocks, or slots passed to components', + }, + start + ); + } - return 'svelte:self'; - } + return 'svelte:self'; + } - if (parser.read(COMPONENT)) return 'svelte:component'; + if (parser.read(COMPONENT)) return 'svelte:component'; - if (parser.read(SLOT)) return 'svelte:fragment'; + if (parser.read(SLOT)) return 'svelte:fragment'; - const name = parser.read_until(/(\s|\/|>)/); + const name = parser.read_until(/(\s|\/|>)/); - if (meta_tags.has(name)) return name; + if (meta_tags.has(name)) return name; - if (name.startsWith('svelte:')) { - const match = fuzzymatch(name.slice(7), valid_meta_tags); + if (name.startsWith('svelte:')) { + const match = fuzzymatch(name.slice(7), valid_meta_tags); - let message = `Valid <svelte:...> tag names are ${list(valid_meta_tags)}`; - if (match) message += ` (did you mean '${match}'?)`; + let message = `Valid <svelte:...> tag names are ${list(valid_meta_tags)}`; + if (match) message += ` (did you mean '${match}'?)`; - parser.error({ - code: 'invalid-tag-name', - message - }, start); - } + parser.error( + { + code: 'invalid-tag-name', + message, + }, + start + ); + } - if (!valid_tag_name.test(name)) { - parser.error({ - code: 'invalid-tag-name', - message: 'Expected valid tag name' - }, start); - } + if (!valid_tag_name.test(name)) { + parser.error( + { + code: 'invalid-tag-name', + message: 'Expected valid tag name', + }, + start + ); + } - return name; + return name; } function read_attribute(parser, unique_names) { - const start = parser.index; - - function check_unique(name) { - if (unique_names.has(name)) { - parser.error({ - code: 'duplicate-attribute', - message: 'Attributes need to be unique' - }, start); - } - unique_names.add(name); - } - - if (parser.eat('{')) { - parser.allow_whitespace(); - - if (parser.eat('...')) { - const expression = read_expression(parser); - - parser.allow_whitespace(); - parser.eat('}', true); - - return { - start, - end: parser.index, - type: 'Spread', - expression - }; - } else { - const value_start = parser.index; - - const name = parser.read_identifier(); - parser.allow_whitespace(); - parser.eat('}', true); - - check_unique(name); - - return { - start, - end: parser.index, - type: 'Attribute', - name, - value: [{ - start: value_start, - end: value_start + name.length, - type: 'AttributeShorthand', - expression: { - start: value_start, - end: value_start + name.length, - type: 'Identifier', - name - } - }] - }; - } - } - - // eslint-disable-next-line no-useless-escape - const name = parser.read_until(/[\s=\/>"']/); - if (!name) return null; - - let end = parser.index; - - parser.allow_whitespace(); - - const colon_index = name.indexOf(':'); - const type = colon_index !== -1 && get_directive_type(name.slice(0, colon_index)); - - let value = true; - if (parser.eat('=')) { - parser.allow_whitespace(); - value = read_attribute_value(parser); - end = parser.index; - } else if (parser.match_regex(/["']/)) { - parser.error({ - code: 'unexpected-token', - message: 'Expected =' - }, parser.index); - } - - if (type) { - const [directive_name, ...modifiers] = name.slice(colon_index + 1).split('|'); - - if (type === 'Binding' && directive_name !== 'this') { - check_unique(directive_name); - } else if (type !== 'EventHandler' && type !== 'Action') { - check_unique(name); - } + const start = parser.index; + + function check_unique(name) { + if (unique_names.has(name)) { + parser.error( + { + code: 'duplicate-attribute', + message: 'Attributes need to be unique', + }, + start + ); + } + unique_names.add(name); + } - if (type === 'Ref') { - parser.error({ - code: 'invalid-ref-directive', - message: `The ref directive is no longer supported — use \`bind:this={${directive_name}}\` instead` - }, start); - } + if (parser.eat('{')) { + parser.allow_whitespace(); + + if (parser.eat('...')) { + const expression = read_expression(parser); + + parser.allow_whitespace(); + parser.eat('}', true); + + return { + start, + end: parser.index, + type: 'Spread', + expression, + }; + } else { + const value_start = parser.index; + + const name = parser.read_identifier(); + parser.allow_whitespace(); + parser.eat('}', true); + + check_unique(name); + + return { + start, + end: parser.index, + type: 'Attribute', + name, + value: [ + { + start: value_start, + end: value_start + name.length, + type: 'AttributeShorthand', + expression: { + start: value_start, + end: value_start + name.length, + type: 'Identifier', + name, + }, + }, + ], + }; + } + } - if (type === 'Class' && directive_name === '') { - parser.error({ - code: 'invalid-class-directive', - message: 'Class binding name cannot be empty' - }, start + colon_index + 1); - } + // eslint-disable-next-line no-useless-escape + const name = parser.read_until(/[\s=\/>"']/); + if (!name) return null; + + let end = parser.index; + + parser.allow_whitespace(); + + const colon_index = name.indexOf(':'); + const type = colon_index !== -1 && get_directive_type(name.slice(0, colon_index)); + + let value = true; + if (parser.eat('=')) { + parser.allow_whitespace(); + value = read_attribute_value(parser); + end = parser.index; + } else if (parser.match_regex(/["']/)) { + parser.error( + { + code: 'unexpected-token', + message: 'Expected =', + }, + parser.index + ); + } - if (value[0]) { - if ((value ).length > 1 || value[0].type === 'Text') { - parser.error({ - code: 'invalid-directive-value', - message: 'Directive value must be a JavaScript expression enclosed in curly braces' - }, value[0].start); - } - } + if (type) { + const [directive_name, ...modifiers] = name.slice(colon_index + 1).split('|'); - const directive = { - start, - end, - type, - name: directive_name, - modifiers, - expression: (value[0] && value[0].expression) || null - }; - - if (type === 'Transition') { - const direction = name.slice(0, colon_index); - directive.intro = direction === 'in' || direction === 'transition'; - directive.outro = direction === 'out' || direction === 'transition'; - } + if (type === 'Binding' && directive_name !== 'this') { + check_unique(directive_name); + } else if (type !== 'EventHandler' && type !== 'Action') { + check_unique(name); + } - if (!directive.expression && (type === 'Binding' || type === 'Class')) { - directive.expression = { - start: directive.start + colon_index + 1, - end: directive.end, - type: 'Identifier', - name: directive.name - } ; - } + if (type === 'Ref') { + parser.error( + { + code: 'invalid-ref-directive', + message: `The ref directive is no longer supported — use \`bind:this={${directive_name}}\` instead`, + }, + start + ); + } + + if (type === 'Class' && directive_name === '') { + parser.error( + { + code: 'invalid-class-directive', + message: 'Class binding name cannot be empty', + }, + start + colon_index + 1 + ); + } + + if (value[0]) { + if (value.length > 1 || value[0].type === 'Text') { + parser.error( + { + code: 'invalid-directive-value', + message: 'Directive value must be a JavaScript expression enclosed in curly braces', + }, + value[0].start + ); + } + } + + const directive = { + start, + end, + type, + name: directive_name, + modifiers, + expression: (value[0] && value[0].expression) || null, + }; - return directive; - } + if (type === 'Transition') { + const direction = name.slice(0, colon_index); + directive.intro = direction === 'in' || direction === 'transition'; + directive.outro = direction === 'out' || direction === 'transition'; + } - check_unique(name); + if (!directive.expression && (type === 'Binding' || type === 'Class')) { + directive.expression = { + start: directive.start + colon_index + 1, + end: directive.end, + type: 'Identifier', + name: directive.name, + }; + } + + return directive; + } - return { - start, - end, - type: 'Attribute', - name, - value - }; + check_unique(name); + + return { + start, + end, + type: 'Attribute', + name, + value, + }; } function get_directive_type(name) { - if (name === 'use') return 'Action'; - if (name === 'animate') return 'Animation'; - if (name === 'bind') return 'Binding'; - if (name === 'class') return 'Class'; - if (name === 'on') return 'EventHandler'; - if (name === 'let') return 'Let'; - if (name === 'ref') return 'Ref'; - if (name === 'in' || name === 'out' || name === 'transition') return 'Transition'; + if (name === 'use') return 'Action'; + if (name === 'animate') return 'Animation'; + if (name === 'bind') return 'Binding'; + if (name === 'class') return 'Class'; + if (name === 'on') return 'EventHandler'; + if (name === 'let') return 'Let'; + if (name === 'ref') return 'Ref'; + if (name === 'in' || name === 'out' || name === 'transition') return 'Transition'; } function read_attribute_value(parser) { - const quote_mark = parser.eat("'") ? "'" : parser.eat('"') ? '"' : null; + const quote_mark = parser.eat("'") ? "'" : parser.eat('"') ? '"' : null; - const regex = ( - quote_mark === "'" ? /'/ : - quote_mark === '"' ? /"/ : - /(\/>|[\s"'=<>`])/ - ); + const regex = quote_mark === "'" ? /'/ : quote_mark === '"' ? /"/ : /(\/>|[\s"'=<>`])/; - const value = read_sequence(parser, () => !!parser.match_regex(regex)); + const value = read_sequence(parser, () => !!parser.match_regex(regex)); - if (quote_mark) parser.index += 1; - return value; + if (quote_mark) parser.index += 1; + return value; } function read_sequence(parser, done) { - let current_chunk = { - start: parser.index, - end: null, - type: 'Text', - raw: '', - data: null - }; - - function flush() { - if (current_chunk.raw) { - current_chunk.data = decode_character_references(current_chunk.raw); - current_chunk.end = parser.index; - chunks.push(current_chunk); - } - } - - const chunks = []; - - while (parser.index < parser.template.length) { - const index = parser.index; - - if (done()) { - flush(); - return chunks; - } else if (parser.eat('{')) { - flush(); - - parser.allow_whitespace(); - const expression = read_expression(parser); - parser.allow_whitespace(); - parser.eat('}', true); + let current_chunk = { + start: parser.index, + end: null, + type: 'Text', + raw: '', + data: null, + }; - chunks.push({ - start: index, - end: parser.index, - type: 'MustacheTag', - expression - }); + function flush() { + if (current_chunk.raw) { + current_chunk.data = decode_character_references(current_chunk.raw); + current_chunk.end = parser.index; + chunks.push(current_chunk); + } + } - current_chunk = { - start: parser.index, - end: null, - type: 'Text', - raw: '', - data: null - }; - } else { - current_chunk.raw += parser.template[parser.index++]; - } - } + const chunks = []; + + while (parser.index < parser.template.length) { + const index = parser.index; + + if (done()) { + flush(); + return chunks; + } else if (parser.eat('{')) { + flush(); + + parser.allow_whitespace(); + const expression = read_expression(parser); + parser.allow_whitespace(); + parser.eat('}', true); + + chunks.push({ + start: index, + end: parser.index, + type: 'MustacheTag', + expression, + }); + + current_chunk = { + start: parser.index, + end: null, + type: 'Text', + raw: '', + data: null, + }; + } else { + current_chunk.raw += parser.template[parser.index++]; + } + } - parser.error({ - code: 'unexpected-eof', - message: 'Unexpected end of input' - }); + parser.error({ + code: 'unexpected-eof', + message: 'Unexpected end of input', + }); } const SQUARE_BRACKET_OPEN = '['.charCodeAt(0); @@ -4266,2625 +4283,2341 @@ const CURLY_BRACKET_OPEN = '{'.charCodeAt(0); const CURLY_BRACKET_CLOSE = '}'.charCodeAt(0); function is_bracket_open(code) { - return code === SQUARE_BRACKET_OPEN || code === CURLY_BRACKET_OPEN; + return code === SQUARE_BRACKET_OPEN || code === CURLY_BRACKET_OPEN; } function is_bracket_close(code) { - return code === SQUARE_BRACKET_CLOSE || code === CURLY_BRACKET_CLOSE; + return code === SQUARE_BRACKET_CLOSE || code === CURLY_BRACKET_CLOSE; } function is_bracket_pair(open, close) { - return ( - (open === SQUARE_BRACKET_OPEN && close === SQUARE_BRACKET_CLOSE) || - (open === CURLY_BRACKET_OPEN && close === CURLY_BRACKET_CLOSE) - ); + return (open === SQUARE_BRACKET_OPEN && close === SQUARE_BRACKET_CLOSE) || (open === CURLY_BRACKET_OPEN && close === CURLY_BRACKET_CLOSE); } function get_bracket_close(open) { - if (open === SQUARE_BRACKET_OPEN) { - return SQUARE_BRACKET_CLOSE; - } - if (open === CURLY_BRACKET_OPEN) { - return CURLY_BRACKET_CLOSE; - } -} - -function read_context( - parser -) { - const start = parser.index; - let i = parser.index; - - const code = full_char_code_at(parser.template, i); - if (isIdentifierStart(code, true)) { - return { - type: 'Identifier', - name: parser.read_identifier(), - start, - end: parser.index - }; - } - - if (!is_bracket_open(code)) { - parser.error({ - code: 'unexpected-token', - message: 'Expected identifier or destructure pattern' - }); - } - - const bracket_stack = [code]; - i += code <= 0xffff ? 1 : 2; - - while (i < parser.template.length) { - const code = full_char_code_at(parser.template, i); - if (is_bracket_open(code)) { - bracket_stack.push(code); - } else if (is_bracket_close(code)) { - if (!is_bracket_pair(bracket_stack[bracket_stack.length - 1], code)) { - parser.error({ - code: 'unexpected-token', - message: `Expected ${String.fromCharCode( - get_bracket_close(bracket_stack[bracket_stack.length - 1]) - )}` - }); - } - bracket_stack.pop(); - if (bracket_stack.length === 0) { - i += code <= 0xffff ? 1 : 2; - break; - } - } - i += code <= 0xffff ? 1 : 2; - } - - parser.index = i; - - const pattern_string = parser.template.slice(start, i); - try { - // the length of the `space_with_newline` has to be start - 1 - // because we added a `(` in front of the pattern_string, - // which shifted the entire string to right by 1 - // so we offset it by removing 1 character in the `space_with_newline` - // to achieve that, we remove the 1st space encountered, - // so it will not affect the `column` of the node - let space_with_newline = parser.template.slice(0, start).replace(/[^\n]/g, ' '); - const first_space = space_with_newline.indexOf(' '); - space_with_newline = space_with_newline.slice(0, first_space) + space_with_newline.slice(first_space + 1); - - return (parse_expression_at( - `${space_with_newline}(${pattern_string} = 1)`, - start - 1 - ) ).left; - } catch (error) { - parser.acorn_error(error); - } + if (open === SQUARE_BRACKET_OPEN) { + return SQUARE_BRACKET_CLOSE; + } + if (open === CURLY_BRACKET_OPEN) { + return CURLY_BRACKET_CLOSE; + } +} + +function read_context(parser) { + const start = parser.index; + let i = parser.index; + + const code = full_char_code_at(parser.template, i); + if (isIdentifierStart(code, true)) { + return { + type: 'Identifier', + name: parser.read_identifier(), + start, + end: parser.index, + }; + } + + if (!is_bracket_open(code)) { + parser.error({ + code: 'unexpected-token', + message: 'Expected identifier or destructure pattern', + }); + } + + const bracket_stack = [code]; + i += code <= 0xffff ? 1 : 2; + + while (i < parser.template.length) { + const code = full_char_code_at(parser.template, i); + if (is_bracket_open(code)) { + bracket_stack.push(code); + } else if (is_bracket_close(code)) { + if (!is_bracket_pair(bracket_stack[bracket_stack.length - 1], code)) { + parser.error({ + code: 'unexpected-token', + message: `Expected ${String.fromCharCode(get_bracket_close(bracket_stack[bracket_stack.length - 1]))}`, + }); + } + bracket_stack.pop(); + if (bracket_stack.length === 0) { + i += code <= 0xffff ? 1 : 2; + break; + } + } + i += code <= 0xffff ? 1 : 2; + } + + parser.index = i; + + const pattern_string = parser.template.slice(start, i); + try { + // the length of the `space_with_newline` has to be start - 1 + // because we added a `(` in front of the pattern_string, + // which shifted the entire string to right by 1 + // so we offset it by removing 1 character in the `space_with_newline` + // to achieve that, we remove the 1st space encountered, + // so it will not affect the `column` of the node + let space_with_newline = parser.template.slice(0, start).replace(/[^\n]/g, ' '); + const first_space = space_with_newline.indexOf(' '); + space_with_newline = space_with_newline.slice(0, first_space) + space_with_newline.slice(first_space + 1); + + return parse_expression_at(`${space_with_newline}(${pattern_string} = 1)`, start - 1).left; + } catch (error) { + parser.acorn_error(error); + } } function trim_start(str) { - let i = 0; - while (whitespace.test(str[i])) i += 1; + let i = 0; + while (whitespace.test(str[i])) i += 1; - return str.slice(i); + return str.slice(i); } function trim_end(str) { - let i = str.length; - while (whitespace.test(str[i - 1])) i -= 1; + let i = str.length; + while (whitespace.test(str[i - 1])) i -= 1; - return str.slice(0, i); + return str.slice(0, i); } function to_string(node) { - switch (node.type) { - case 'IfBlock': - return '{#if} block'; - case 'ThenBlock': - return '{:then} block'; - case 'ElseBlock': - return '{:else} block'; - case 'PendingBlock': - case 'AwaitBlock': - return '{#await} block'; - case 'CatchBlock': - return '{:catch} block'; - case 'EachBlock': - return '{#each} block'; - case 'RawMustacheTag': - return '{@html} block'; - case 'DebugTag': - return '{@debug} block'; - case 'Element': - case 'InlineComponent': - case 'Slot': - case 'Title': - return `<${node.name}> tag`; - default: - return node.type; - } + switch (node.type) { + case 'IfBlock': + return '{#if} block'; + case 'ThenBlock': + return '{:then} block'; + case 'ElseBlock': + return '{:else} block'; + case 'PendingBlock': + case 'AwaitBlock': + return '{#await} block'; + case 'CatchBlock': + return '{:catch} block'; + case 'EachBlock': + return '{#each} block'; + case 'RawMustacheTag': + return '{@html} block'; + case 'DebugTag': + return '{@debug} block'; + case 'Element': + case 'InlineComponent': + case 'Slot': + case 'Title': + return `<${node.name}> tag`; + default: + return node.type; + } } function trim_whitespace(block, trim_before, trim_after) { - if (!block.children || block.children.length === 0) return; // AwaitBlock + if (!block.children || block.children.length === 0) return; // AwaitBlock - const first_child = block.children[0]; - const last_child = block.children[block.children.length - 1]; + const first_child = block.children[0]; + const last_child = block.children[block.children.length - 1]; - if (first_child.type === 'Text' && trim_before) { - first_child.data = trim_start(first_child.data); - if (!first_child.data) block.children.shift(); - } + if (first_child.type === 'Text' && trim_before) { + first_child.data = trim_start(first_child.data); + if (!first_child.data) block.children.shift(); + } - if (last_child.type === 'Text' && trim_after) { - last_child.data = trim_end(last_child.data); - if (!last_child.data) block.children.pop(); - } + if (last_child.type === 'Text' && trim_after) { + last_child.data = trim_end(last_child.data); + if (!last_child.data) block.children.pop(); + } - if (block.else) { - trim_whitespace(block.else, trim_before, trim_after); - } + if (block.else) { + trim_whitespace(block.else, trim_before, trim_after); + } - if (first_child.elseif) { - trim_whitespace(first_child, trim_before, trim_after); - } + if (first_child.elseif) { + trim_whitespace(first_child, trim_before, trim_after); + } } function mustache(parser) { - const start = parser.index; - parser.index += 1; + const start = parser.index; + parser.index += 1; - parser.allow_whitespace(); + parser.allow_whitespace(); - // {/if}, {/each}, {/await} or {/key} - if (parser.eat('/')) { - let block = parser.current(); - let expected; + // {/if}, {/each}, {/await} or {/key} + if (parser.eat('/')) { + let block = parser.current(); + let expected; - if (closing_tag_omitted(block.name)) { - block.end = start; - parser.stack.pop(); - block = parser.current(); - } + if (closing_tag_omitted(block.name)) { + block.end = start; + parser.stack.pop(); + block = parser.current(); + } - if (block.type === 'ElseBlock' || block.type === 'PendingBlock' || block.type === 'ThenBlock' || block.type === 'CatchBlock') { - block.end = start; - parser.stack.pop(); - block = parser.current(); + if (block.type === 'ElseBlock' || block.type === 'PendingBlock' || block.type === 'ThenBlock' || block.type === 'CatchBlock') { + block.end = start; + parser.stack.pop(); + block = parser.current(); - expected = 'await'; - } + expected = 'await'; + } - if (block.type === 'IfBlock') { - expected = 'if'; - } else if (block.type === 'EachBlock') { - expected = 'each'; - } else if (block.type === 'AwaitBlock') { - expected = 'await'; - } else if (block.type === 'KeyBlock') { - expected = 'key'; - } else { - parser.error({ - code: 'unexpected-block-close', - message: 'Unexpected block closing tag' - }); - } + if (block.type === 'IfBlock') { + expected = 'if'; + } else if (block.type === 'EachBlock') { + expected = 'each'; + } else if (block.type === 'AwaitBlock') { + expected = 'await'; + } else if (block.type === 'KeyBlock') { + expected = 'key'; + } else { + parser.error({ + code: 'unexpected-block-close', + message: 'Unexpected block closing tag', + }); + } - parser.eat(expected, true); - parser.allow_whitespace(); - parser.eat('}', true); + parser.eat(expected, true); + parser.allow_whitespace(); + parser.eat('}', true); - while (block.elseif) { - block.end = parser.index; - parser.stack.pop(); - block = parser.current(); + while (block.elseif) { + block.end = parser.index; + parser.stack.pop(); + block = parser.current(); - if (block.else) { - block.else.end = start; - } - } + if (block.else) { + block.else.end = start; + } + } - // strip leading/trailing whitespace as necessary - const char_before = parser.template[block.start - 1]; - const char_after = parser.template[parser.index]; - const trim_before = !char_before || whitespace.test(char_before); - const trim_after = !char_after || whitespace.test(char_after); - - trim_whitespace(block, trim_before, trim_after); - - block.end = parser.index; - parser.stack.pop(); - } else if (parser.eat(':else')) { - if (parser.eat('if')) { - parser.error({ - code: 'invalid-elseif', - message: "'elseif' should be 'else if'" - }); - } + // strip leading/trailing whitespace as necessary + const char_before = parser.template[block.start - 1]; + const char_after = parser.template[parser.index]; + const trim_before = !char_before || whitespace.test(char_before); + const trim_after = !char_after || whitespace.test(char_after); + + trim_whitespace(block, trim_before, trim_after); + + block.end = parser.index; + parser.stack.pop(); + } else if (parser.eat(':else')) { + if (parser.eat('if')) { + parser.error({ + code: 'invalid-elseif', + message: "'elseif' should be 'else if'", + }); + } - parser.allow_whitespace(); - - // :else if - if (parser.eat('if')) { - const block = parser.current(); - if (block.type !== 'IfBlock') { - parser.error({ - code: 'invalid-elseif-placement', - message: parser.stack.some(block => block.type === 'IfBlock') - ? `Expected to close ${to_string(block)} before seeing {:else if ...} block` - : 'Cannot have an {:else if ...} block outside an {#if ...} block' - }); - } + parser.allow_whitespace(); + + // :else if + if (parser.eat('if')) { + const block = parser.current(); + if (block.type !== 'IfBlock') { + parser.error({ + code: 'invalid-elseif-placement', + message: parser.stack.some((block) => block.type === 'IfBlock') + ? `Expected to close ${to_string(block)} before seeing {:else if ...} block` + : 'Cannot have an {:else if ...} block outside an {#if ...} block', + }); + } - parser.require_whitespace(); + parser.require_whitespace(); + + const expression = read_expression(parser); + + parser.allow_whitespace(); + parser.eat('}', true); + + block.else = { + start: parser.index, + end: null, + type: 'ElseBlock', + children: [ + { + start: parser.index, + end: null, + type: 'IfBlock', + elseif: true, + expression, + children: [], + }, + ], + }; + + parser.stack.push(block.else.children[0]); + } else { + // :else + const block = parser.current(); + if (block.type !== 'IfBlock' && block.type !== 'EachBlock') { + parser.error({ + code: 'invalid-else-placement', + message: parser.stack.some((block) => block.type === 'IfBlock' || block.type === 'EachBlock') + ? `Expected to close ${to_string(block)} before seeing {:else} block` + : 'Cannot have an {:else} block outside an {#if ...} or {#each ...} block', + }); + } - const expression = read_expression(parser); + parser.allow_whitespace(); + parser.eat('}', true); - parser.allow_whitespace(); - parser.eat('}', true); + block.else = { + start: parser.index, + end: null, + type: 'ElseBlock', + children: [], + }; - block.else = { - start: parser.index, - end: null, - type: 'ElseBlock', - children: [ - { - start: parser.index, - end: null, - type: 'IfBlock', - elseif: true, - expression, - children: [] - } - ] - }; - - parser.stack.push(block.else.children[0]); - } else { - // :else - const block = parser.current(); - if (block.type !== 'IfBlock' && block.type !== 'EachBlock') { - parser.error({ - code: 'invalid-else-placement', - message: parser.stack.some(block => block.type === 'IfBlock' || block.type === 'EachBlock') - ? `Expected to close ${to_string(block)} before seeing {:else} block` - : 'Cannot have an {:else} block outside an {#if ...} or {#each ...} block' - }); - } + parser.stack.push(block.else); + } + } else if (parser.match(':then') || parser.match(':catch')) { + const block = parser.current(); + const is_then = parser.eat(':then') || !parser.eat(':catch'); + + if (is_then) { + if (block.type !== 'PendingBlock') { + parser.error({ + code: 'invalid-then-placement', + message: parser.stack.some((block) => block.type === 'PendingBlock') + ? `Expected to close ${to_string(block)} before seeing {:then} block` + : 'Cannot have an {:then} block outside an {#await ...} block', + }); + } + } else { + if (block.type !== 'ThenBlock' && block.type !== 'PendingBlock') { + parser.error({ + code: 'invalid-catch-placement', + message: parser.stack.some((block) => block.type === 'ThenBlock' || block.type === 'PendingBlock') + ? `Expected to close ${to_string(block)} before seeing {:catch} block` + : 'Cannot have an {:catch} block outside an {#await ...} block', + }); + } + } - parser.allow_whitespace(); - parser.eat('}', true); + block.end = start; + parser.stack.pop(); + const await_block = parser.current(); - block.else = { - start: parser.index, - end: null, - type: 'ElseBlock', - children: [] - }; + if (!parser.eat('}')) { + parser.require_whitespace(); + await_block[is_then ? 'value' : 'error'] = read_context(parser); + parser.allow_whitespace(); + parser.eat('}', true); + } - parser.stack.push(block.else); - } - } else if (parser.match(':then') || parser.match(':catch')) { - const block = parser.current(); - const is_then = parser.eat(':then') || !parser.eat(':catch'); - - if (is_then) { - if (block.type !== 'PendingBlock') { - parser.error({ - code: 'invalid-then-placement', - message: parser.stack.some(block => block.type === 'PendingBlock') - ? `Expected to close ${to_string(block)} before seeing {:then} block` - : 'Cannot have an {:then} block outside an {#await ...} block' - }); - } - } else { - if (block.type !== 'ThenBlock' && block.type !== 'PendingBlock') { - parser.error({ - code: 'invalid-catch-placement', - message: parser.stack.some(block => block.type === 'ThenBlock' || block.type === 'PendingBlock') - ? `Expected to close ${to_string(block)} before seeing {:catch} block` - : 'Cannot have an {:catch} block outside an {#await ...} block' - }); - } - } + const new_block = { + start, + end: null, + type: is_then ? 'ThenBlock' : 'CatchBlock', + children: [], + skip: false, + }; - block.end = start; - parser.stack.pop(); - const await_block = parser.current(); + await_block[is_then ? 'then' : 'catch'] = new_block; + parser.stack.push(new_block); + } else if (parser.eat('#')) { + // {#if foo}, {#each foo} or {#await foo} + let type; + + if (parser.eat('if')) { + type = 'IfBlock'; + } else if (parser.eat('each')) { + type = 'EachBlock'; + } else if (parser.eat('await')) { + type = 'AwaitBlock'; + } else if (parser.eat('key')) { + type = 'KeyBlock'; + } else { + parser.error({ + code: 'expected-block-type', + message: 'Expected if, each, await or key', + }); + } - if (!parser.eat('}')) { - parser.require_whitespace(); - await_block[is_then ? 'value' : 'error'] = read_context(parser); - parser.allow_whitespace(); - parser.eat('}', true); - } + parser.require_whitespace(); + + const expression = read_expression(parser); + + const block = + type === 'AwaitBlock' + ? { + start, + end: null, + type, + expression, + value: null, + error: null, + pending: { + start: null, + end: null, + type: 'PendingBlock', + children: [], + skip: true, + }, + then: { + start: null, + end: null, + type: 'ThenBlock', + children: [], + skip: true, + }, + catch: { + start: null, + end: null, + type: 'CatchBlock', + children: [], + skip: true, + }, + } + : { + start, + end: null, + type, + expression, + children: [], + }; + + parser.allow_whitespace(); + + // {#each} blocks must declare a context – {#each list as item} + if (type === 'EachBlock') { + parser.eat('as', true); + parser.require_whitespace(); + + block.context = read_context(parser); + + parser.allow_whitespace(); + + if (parser.eat(',')) { + parser.allow_whitespace(); + block.index = parser.read_identifier(); + if (!block.index) { + parser.error({ + code: 'expected-name', + message: 'Expected name', + }); + } - const new_block = { - start, - end: null, - type: is_then ? 'ThenBlock' : 'CatchBlock', - children: [], - skip: false - }; - - await_block[is_then ? 'then' : 'catch'] = new_block; - parser.stack.push(new_block); - } else if (parser.eat('#')) { - // {#if foo}, {#each foo} or {#await foo} - let type; - - if (parser.eat('if')) { - type = 'IfBlock'; - } else if (parser.eat('each')) { - type = 'EachBlock'; - } else if (parser.eat('await')) { - type = 'AwaitBlock'; - } else if (parser.eat('key')) { - type = 'KeyBlock'; - } else { - parser.error({ - code: 'expected-block-type', - message: 'Expected if, each, await or key' - }); - } + parser.allow_whitespace(); + } - parser.require_whitespace(); - - const expression = read_expression(parser); - - const block = type === 'AwaitBlock' ? - { - start, - end: null, - type, - expression, - value: null, - error: null, - pending: { - start: null, - end: null, - type: 'PendingBlock', - children: [], - skip: true - }, - then: { - start: null, - end: null, - type: 'ThenBlock', - children: [], - skip: true - }, - catch: { - start: null, - end: null, - type: 'CatchBlock', - children: [], - skip: true - } - } : - { - start, - end: null, - type, - expression, - children: [] - }; - - parser.allow_whitespace(); - - // {#each} blocks must declare a context – {#each list as item} - if (type === 'EachBlock') { - parser.eat('as', true); - parser.require_whitespace(); - - block.context = read_context(parser); - - parser.allow_whitespace(); - - if (parser.eat(',')) { - parser.allow_whitespace(); - block.index = parser.read_identifier(); - if (!block.index) { - parser.error({ - code: 'expected-name', - message: 'Expected name' - }); - } + if (parser.eat('(')) { + parser.allow_whitespace(); - parser.allow_whitespace(); - } + block.key = read_expression(parser); + parser.allow_whitespace(); + parser.eat(')', true); + parser.allow_whitespace(); + } + } - if (parser.eat('(')) { - parser.allow_whitespace(); + const await_block_shorthand = type === 'AwaitBlock' && parser.eat('then'); + if (await_block_shorthand) { + parser.require_whitespace(); + block.value = read_context(parser); + parser.allow_whitespace(); + } - block.key = read_expression(parser); - parser.allow_whitespace(); - parser.eat(')', true); - parser.allow_whitespace(); - } - } + const await_block_catch_shorthand = !await_block_shorthand && type === 'AwaitBlock' && parser.eat('catch'); + if (await_block_catch_shorthand) { + parser.require_whitespace(); + block.error = read_context(parser); + parser.allow_whitespace(); + } - const await_block_shorthand = type === 'AwaitBlock' && parser.eat('then'); - if (await_block_shorthand) { - parser.require_whitespace(); - block.value = read_context(parser); - parser.allow_whitespace(); - } + parser.eat('}', true); - const await_block_catch_shorthand = !await_block_shorthand && type === 'AwaitBlock' && parser.eat('catch'); - if (await_block_catch_shorthand) { - parser.require_whitespace(); - block.error = read_context(parser); - parser.allow_whitespace(); - } + parser.current().children.push(block); + parser.stack.push(block); - parser.eat('}', true); - - parser.current().children.push(block); - parser.stack.push(block); - - if (type === 'AwaitBlock') { - let child_block; - if (await_block_shorthand) { - block.then.skip = false; - child_block = block.then; - } else if (await_block_catch_shorthand) { - block.catch.skip = false; - child_block = block.catch; - } else { - block.pending.skip = false; - child_block = block.pending; - } + if (type === 'AwaitBlock') { + let child_block; + if (await_block_shorthand) { + block.then.skip = false; + child_block = block.then; + } else if (await_block_catch_shorthand) { + block.catch.skip = false; + child_block = block.catch; + } else { + block.pending.skip = false; + child_block = block.pending; + } - child_block.start = parser.index; - parser.stack.push(child_block); - } - } else if (parser.eat('@html')) { - // {@html content} tag - parser.require_whitespace(); + child_block.start = parser.index; + parser.stack.push(child_block); + } + } else if (parser.eat('@html')) { + // {@html content} tag + parser.require_whitespace(); - const expression = read_expression(parser); + const expression = read_expression(parser); - parser.allow_whitespace(); - parser.eat('}', true); + parser.allow_whitespace(); + parser.eat('}', true); - parser.current().children.push({ - start, - end: parser.index, - type: 'RawMustacheTag', - expression - }); - } else if (parser.eat('@debug')) { - // let identifiers; - - // // Implies {@debug} which indicates "debug all" - // if (parser.read(/\s*}/)) { - // identifiers = []; - // } else { - // const expression = read_expression(parser); - - // identifiers = expression.type === 'SequenceExpression' - // ? expression.expressions - // : [expression]; - - // identifiers.forEach(node => { - // if (node.type !== 'Identifier') { - // parser.error({ - // code: 'invalid-debug-args', - // message: '{@debug ...} arguments must be identifiers, not arbitrary expressions' - // }, node.start); - // } - // }); - - // parser.allow_whitespace(); - // parser.eat('}', true); - // } - - // parser.current().children.push({ - // start, - // end: parser.index, - // type: 'DebugTag', - // identifiers - // }); - throw new Error('@debug not yet supported'); - } else { - const expression = read_expression(parser); - - parser.allow_whitespace(); - parser.eat('}', true); - - parser.current().children.push({ - start, - end: parser.index, - type: 'MustacheTag', - expression - }); - } + parser.current().children.push({ + start, + end: parser.index, + type: 'RawMustacheTag', + expression, + }); + } else if (parser.eat('@debug')) { + // let identifiers; + + // // Implies {@debug} which indicates "debug all" + // if (parser.read(/\s*}/)) { + // identifiers = []; + // } else { + // const expression = read_expression(parser); + + // identifiers = expression.type === 'SequenceExpression' + // ? expression.expressions + // : [expression]; + + // identifiers.forEach(node => { + // if (node.type !== 'Identifier') { + // parser.error({ + // code: 'invalid-debug-args', + // message: '{@debug ...} arguments must be identifiers, not arbitrary expressions' + // }, node.start); + // } + // }); + + // parser.allow_whitespace(); + // parser.eat('}', true); + // } + + // parser.current().children.push({ + // start, + // end: parser.index, + // type: 'DebugTag', + // identifiers + // }); + throw new Error('@debug not yet supported'); + } else { + const expression = read_expression(parser); + + parser.allow_whitespace(); + parser.eat('}', true); + + parser.current().children.push({ + start, + end: parser.index, + type: 'MustacheTag', + expression, + }); + } } function text(parser) { - const start = parser.index; + const start = parser.index; - let data = ''; + let data = ''; - while ( - parser.index < parser.template.length && - !parser.match('<') && - !parser.match('{') - ) { - data += parser.template[parser.index++]; - } + while (parser.index < parser.template.length && !parser.match('<') && !parser.match('{')) { + data += parser.template[parser.index++]; + } - const node = { - start, - end: parser.index, - type: 'Text', - raw: data, - data: decode_character_references(data) - }; + const node = { + start, + end: parser.index, + type: 'Text', + raw: data, + data: decode_character_references(data), + }; - parser.current().children.push(node); + parser.current().children.push(node); } function fragment(parser) { - if (parser.match('<')) { - return tag; - } + if (parser.match('<')) { + return tag; + } - if (parser.match('{')) { - return mustache; - } + if (parser.match('{')) { + return mustache; + } - return text; + return text; } function getLocator(source, options) { - if (options === void 0) { options = {}; } - var offsetLine = options.offsetLine || 0; - var offsetColumn = options.offsetColumn || 0; - var originalLines = source.split('\n'); - var start = 0; - var lineRanges = originalLines.map(function (line, i) { - var end = start + line.length + 1; - var range = { start: start, end: end, line: i }; - start = end; - return range; - }); - var i = 0; - function rangeContains(range, index) { - return range.start <= index && index < range.end; - } - function getLocation(range, index) { - return { line: offsetLine + range.line, column: offsetColumn + index - range.start, character: index }; + if (options === void 0) { + options = {}; + } + var offsetLine = options.offsetLine || 0; + var offsetColumn = options.offsetColumn || 0; + var originalLines = source.split('\n'); + var start = 0; + var lineRanges = originalLines.map(function (line, i) { + var end = start + line.length + 1; + var range = { start: start, end: end, line: i }; + start = end; + return range; + }); + var i = 0; + function rangeContains(range, index) { + return range.start <= index && index < range.end; + } + function getLocation(range, index) { + return { line: offsetLine + range.line, column: offsetColumn + index - range.start, character: index }; + } + function locate(search, startIndex) { + if (typeof search === 'string') { + search = source.indexOf(search, startIndex || 0); } - function locate(search, startIndex) { - if (typeof search === 'string') { - search = source.indexOf(search, startIndex || 0); - } - var range = lineRanges[i]; - var d = search >= range.end ? 1 : -1; - while (range) { - if (rangeContains(range, search)) - return getLocation(range, search); - i += d; - range = lineRanges[i]; - } + var range = lineRanges[i]; + var d = search >= range.end ? 1 : -1; + while (range) { + if (rangeContains(range, search)) return getLocation(range, search); + i += d; + range = lineRanges[i]; } - return locate; + } + return locate; } function locate(source, search, options) { - if (typeof options === 'number') { - throw new Error('locate takes a { startIndex, offsetLine, offsetColumn } object as the third argument'); - } - return getLocator(source, options)(search, options && options.startIndex); + if (typeof options === 'number') { + throw new Error('locate takes a { startIndex, offsetLine, offsetColumn } object as the third argument'); + } + return getLocator(source, options)(search, options && options.startIndex); } function tabs_to_spaces(str) { - return str.replace(/^\t+/, match => match.split('\t').join(' ')); + return str.replace(/^\t+/, (match) => match.split('\t').join(' ')); } -function get_code_frame( - source, - line, - column -) { - const lines = source.split('\n'); +function get_code_frame(source, line, column) { + const lines = source.split('\n'); - const frame_start = Math.max(0, line - 2); - const frame_end = Math.min(line + 3, lines.length); + const frame_start = Math.max(0, line - 2); + const frame_end = Math.min(line + 3, lines.length); - const digits = String(frame_end + 1).length; + const digits = String(frame_end + 1).length; - return lines - .slice(frame_start, frame_end) - .map((str, i) => { - const isErrorLine = frame_start + i === line; - const line_num = String(i + frame_start + 1).padStart(digits, ' '); + return lines + .slice(frame_start, frame_end) + .map((str, i) => { + const isErrorLine = frame_start + i === line; + const line_num = String(i + frame_start + 1).padStart(digits, ' '); - if (isErrorLine) { - const indicator = ' '.repeat(digits + 2 + tabs_to_spaces(str.slice(0, column)).length) + '^'; - return `${line_num}: ${tabs_to_spaces(str)}\n${indicator}`; - } + if (isErrorLine) { + const indicator = ' '.repeat(digits + 2 + tabs_to_spaces(str.slice(0, column)).length) + '^'; + return `${line_num}: ${tabs_to_spaces(str)}\n${indicator}`; + } - return `${line_num}: ${tabs_to_spaces(str)}`; - }) - .join('\n'); + return `${line_num}: ${tabs_to_spaces(str)}`; + }) + .join('\n'); } class CompileError extends Error { - - - - - - + toString() { + return `${this.message} (${this.start.line}:${this.start.column})\n${this.frame}`; + } +} + +function error(message, props) { + const error = new CompileError(message); + error.name = props.name; + + const start = locate(props.source, props.start, { offsetLine: 1 }); + const end = locate(props.source, props.end || props.start, { offsetLine: 1 }); + + error.code = props.code; + error.start = start; + error.end = end; + error.pos = props.start; + error.filename = props.filename; - toString() { - return `${this.message} (${this.start.line}:${this.start.column})\n${this.frame}`; - } + error.frame = get_code_frame(props.source, start.line - 1, start.column); + + throw error; } -function error(message, props +class Parser { + __init() { + this.index = 0; + } + __init2() { + this.stack = []; + } + __init3() { + this.css = []; + } + __init4() { + this.js = []; + } + __init5() { + this.meta_tags = {}; + } + constructor(template, options) { + Parser.prototype.__init.call(this); + Parser.prototype.__init2.call(this); + Parser.prototype.__init3.call(this); + Parser.prototype.__init4.call(this); + Parser.prototype.__init5.call(this); + if (typeof template !== 'string') { + throw new TypeError('Template must be a string'); + } + this.template = template.replace(/\s+$/, ''); + this.filename = options.filename; + this.customElement = options.customElement; + this.html = { + start: null, + end: null, + type: 'Fragment', + children: [], + }; + this.stack.push(this.html); -) { - const error = new CompileError(message); - error.name = props.name; + let state = fragment; - const start = locate(props.source, props.start, { offsetLine: 1 }); - const end = locate(props.source, props.end || props.start, { offsetLine: 1 }); + while (this.index < this.template.length) { + state = state(this) || fragment; + } - error.code = props.code; - error.start = start; - error.end = end; - error.pos = props.start; - error.filename = props.filename; + if (this.stack.length > 1) { + const current = this.current(); - error.frame = get_code_frame(props.source, start.line - 1, start.column); + const type = current.type === 'Element' ? `<${current.name}>` : 'Block'; + const slug = current.type === 'Element' ? 'element' : 'block'; - throw error; -} + this.error( + { + code: `unclosed-${slug}`, + message: `${type} was left open`, + }, + current.start + ); + } -class Parser { - - - - - __init() {this.index = 0;} - __init2() {this.stack = [];} - - - __init3() {this.css = [];} - __init4() {this.js = [];} - __init5() {this.meta_tags = {};} - - - constructor(template, options) {Parser.prototype.__init.call(this);Parser.prototype.__init2.call(this);Parser.prototype.__init3.call(this);Parser.prototype.__init4.call(this);Parser.prototype.__init5.call(this); - if (typeof template !== 'string') { - throw new TypeError('Template must be a string'); - } + if (state !== fragment) { + this.error({ + code: 'unexpected-eof', + message: 'Unexpected end of input', + }); + } - this.template = template.replace(/\s+$/, ''); - this.filename = options.filename; - this.customElement = options.customElement; + if (this.html.children.length) { + let start = this.html.children[0].start; + while (whitespace.test(template[start])) start += 1; - this.html = { - start: null, - end: null, - type: 'Fragment', - children: [] - }; + let end = this.html.children[this.html.children.length - 1].end; + while (whitespace.test(template[end - 1])) end -= 1; - this.stack.push(this.html); + this.html.start = start; + this.html.end = end; + } else { + this.html.start = this.html.end = null; + } + } - let state = fragment; + current() { + return this.stack[this.stack.length - 1]; + } - while (this.index < this.template.length) { - state = state(this) || fragment; - } + acorn_error(err) { + this.error( + { + code: 'parse-error', + message: err.message.replace(/ \(\d+:\d+\)$/, ''), + }, + err.pos + ); + } - if (this.stack.length > 1) { - const current = this.current(); + error({ code, message }, index = this.index) { + error(message, { + name: 'ParseError', + code, + source: this.template, + start: index, + filename: this.filename, + }); + } - const type = current.type === 'Element' ? `<${current.name}>` : 'Block'; - const slug = current.type === 'Element' ? 'element' : 'block'; + eat(str, required, message) { + if (this.match(str)) { + this.index += str.length; + return true; + } - this.error({ - code: `unclosed-${slug}`, - message: `${type} was left open` - }, current.start); - } + if (required) { + this.error({ + code: `unexpected-${this.index === this.template.length ? 'eof' : 'token'}`, + message: message || `Expected ${str}`, + }); + } - if (state !== fragment) { - this.error({ - code: 'unexpected-eof', - message: 'Unexpected end of input' - }); - } + return false; + } - if (this.html.children.length) { - let start = this.html.children[0].start; - while (whitespace.test(template[start])) start += 1; + match(str) { + return this.template.slice(this.index, this.index + str.length) === str; + } - let end = this.html.children[this.html.children.length - 1].end; - while (whitespace.test(template[end - 1])) end -= 1; + match_regex(pattern) { + const match = pattern.exec(this.template.slice(this.index)); + if (!match || match.index !== 0) return null; - this.html.start = start; - this.html.end = end; - } else { - this.html.start = this.html.end = null; - } - } - - current() { - return this.stack[this.stack.length - 1]; - } - - acorn_error(err) { - this.error({ - code: 'parse-error', - message: err.message.replace(/ \(\d+:\d+\)$/, '') - }, err.pos); - } - - error({ code, message }, index = this.index) { - error(message, { - name: 'ParseError', - code, - source: this.template, - start: index, - filename: this.filename - }); - } + return match[0]; + } - eat(str, required, message) { - if (this.match(str)) { - this.index += str.length; - return true; - } + allow_whitespace() { + while (this.index < this.template.length && whitespace.test(this.template[this.index])) { + this.index++; + } + } - if (required) { - this.error({ - code: `unexpected-${this.index === this.template.length ? 'eof' : 'token'}`, - message: message || `Expected ${str}` - }); - } + read(pattern) { + const result = this.match_regex(pattern); + if (result) this.index += result.length; + return result; + } - return false; - } + read_identifier(allow_reserved = false) { + const start = this.index; - match(str) { - return this.template.slice(this.index, this.index + str.length) === str; - } + let i = this.index; - match_regex(pattern) { - const match = pattern.exec(this.template.slice(this.index)); - if (!match || match.index !== 0) return null; + const code = full_char_code_at(this.template, i); + if (!isIdentifierStart(code, true)) return null; - return match[0]; - } + i += code <= 0xffff ? 1 : 2; - allow_whitespace() { - while ( - this.index < this.template.length && - whitespace.test(this.template[this.index]) - ) { - this.index++; - } - } + while (i < this.template.length) { + const code = full_char_code_at(this.template, i); - read(pattern) { - const result = this.match_regex(pattern); - if (result) this.index += result.length; - return result; - } + if (!isIdentifierChar(code, true)) break; + i += code <= 0xffff ? 1 : 2; + } - read_identifier(allow_reserved = false) { - const start = this.index; + const identifier = this.template.slice(this.index, (this.index = i)); - let i = this.index; + if (!allow_reserved && reserved.has(identifier)) { + this.error( + { + code: 'unexpected-reserved-word', + message: `'${identifier}' is a reserved word in JavaScript and cannot be used here`, + }, + start + ); + } - const code = full_char_code_at(this.template, i); - if (!isIdentifierStart(code, true)) return null; + return identifier; + } - i += code <= 0xffff ? 1 : 2; + read_until(pattern) { + if (this.index >= this.template.length) { + this.error({ + code: 'unexpected-eof', + message: 'Unexpected end of input', + }); + } - while (i < this.template.length) { - const code = full_char_code_at(this.template, i); + const start = this.index; + const match = pattern.exec(this.template.slice(start)); - if (!isIdentifierChar(code, true)) break; - i += code <= 0xffff ? 1 : 2; - } + if (match) { + this.index = start + match.index; + return this.template.slice(start, this.index); + } - const identifier = this.template.slice(this.index, this.index = i); + this.index = this.template.length; + return this.template.slice(start); + } - if (!allow_reserved && reserved.has(identifier)) { - this.error({ - code: 'unexpected-reserved-word', - message: `'${identifier}' is a reserved word in JavaScript and cannot be used here` - }, start); - } + require_whitespace() { + if (!whitespace.test(this.template[this.index])) { + this.error({ + code: 'missing-whitespace', + message: 'Expected whitespace', + }); + } - return identifier; - } + this.allow_whitespace(); + } +} - read_until(pattern) { - if (this.index >= this.template.length) { - this.error({ - code: 'unexpected-eof', - message: 'Unexpected end of input' - }); - } +function parse$1(template, options = {}) { + const parser = new Parser(template, options); - const start = this.index; - const match = pattern.exec(this.template.slice(start)); + // TODO we may want to allow multiple <style> tags — + // one scoped, one global. for now, only allow one + if (parser.css.length > 1) { + parser.error( + { + code: 'duplicate-style', + message: 'You can only have one top-level <style> tag per component', + }, + parser.css[1].start + ); + } - if (match) { - this.index = start + match.index; - return this.template.slice(start, this.index); - } + const instance_scripts = parser.js.filter((script) => script.context === 'default'); + const module_scripts = parser.js.filter((script) => script.context === 'module'); - this.index = this.template.length; - return this.template.slice(start); - } + if (instance_scripts.length > 1) { + parser.error( + { + code: 'invalid-script', + message: 'A component can only have one instance-level <script> element', + }, + instance_scripts[1].start + ); + } - require_whitespace() { - if (!whitespace.test(this.template[this.index])) { - this.error({ - code: 'missing-whitespace', - message: 'Expected whitespace' - }); - } + if (module_scripts.length > 1) { + parser.error( + { + code: 'invalid-script', + message: 'A component can only have one <script context="module"> element', + }, + module_scripts[1].start + ); + } - this.allow_whitespace(); - } -} - -function parse$1( - template, - options = {} -) { - const parser = new Parser(template, options); - - // TODO we may want to allow multiple <style> tags — - // one scoped, one global. for now, only allow one - if (parser.css.length > 1) { - parser.error({ - code: 'duplicate-style', - message: 'You can only have one top-level <style> tag per component' - }, parser.css[1].start); - } - - const instance_scripts = parser.js.filter(script => script.context === 'default'); - const module_scripts = parser.js.filter(script => script.context === 'module'); - - if (instance_scripts.length > 1) { - parser.error({ - code: 'invalid-script', - message: 'A component can only have one instance-level <script> element' - }, instance_scripts[1].start); - } - - if (module_scripts.length > 1) { - parser.error({ - code: 'invalid-script', - message: 'A component can only have one <script context="module"> element' - }, module_scripts[1].start); - } - - return { - html: parser.html, - css: parser.css[0], - instance: instance_scripts[0], - module: module_scripts[0] - }; + return { + html: parser.html, + css: parser.css[0], + instance: instance_scripts[0], + module: module_scripts[0], + }; } function isReference(node, parent) { - if (node.type === 'MemberExpression') { - return !node.computed && isReference(node.object, node); - } - if (node.type === 'Identifier') { - if (!parent) - return true; - switch (parent.type) { - // disregard `bar` in `foo.bar` - case 'MemberExpression': return parent.computed || node === parent.object; - // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}` - case 'MethodDefinition': return parent.computed; - // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}` - case 'FieldDefinition': return parent.computed || node === parent.value; - // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }` - case 'Property': return parent.computed || node === parent.value; - // disregard the `bar` in `export { foo as bar }` or - // the foo in `import { foo as bar }` - case 'ExportSpecifier': - case 'ImportSpecifier': return node === parent.local; - // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}` - case 'LabeledStatement': - case 'BreakStatement': - case 'ContinueStatement': return false; - default: return true; - } + if (node.type === 'MemberExpression') { + return !node.computed && isReference(node.object, node); + } + if (node.type === 'Identifier') { + if (!parent) return true; + switch (parent.type) { + // disregard `bar` in `foo.bar` + case 'MemberExpression': + return parent.computed || node === parent.object; + // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}` + case 'MethodDefinition': + return parent.computed; + // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}` + case 'FieldDefinition': + return parent.computed || node === parent.value; + // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }` + case 'Property': + return parent.computed || node === parent.value; + // disregard the `bar` in `export { foo as bar }` or + // the foo in `import { foo as bar }` + case 'ExportSpecifier': + case 'ImportSpecifier': + return node === parent.local; + // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}` + case 'LabeledStatement': + case 'BreakStatement': + case 'ContinueStatement': + return false; + default: + return true; } - return false; + } + return false; } function analyze(expression) { - const map = new WeakMap(); - - let scope = new Scope(null, false); - - walk(expression, { - enter(node, parent) { - if (node.type === 'ImportDeclaration') { - node.specifiers.forEach((specifier) => { - scope.declarations.set(specifier.local.name, specifier); - }); - } else if (/(Function(Declaration|Expression)|ArrowFunctionExpression)/.test(node.type)) { - if (node.type === 'FunctionDeclaration') { - scope.declarations.set(node.id.name, node); - map.set(node, scope = new Scope(scope, false)); - } else { - map.set(node, scope = new Scope(scope, false)); - if (node.type === 'FunctionExpression' && node.id) scope.declarations.set(node.id.name, node); - } + const map = new WeakMap(); + + let scope = new Scope(null, false); + + walk(expression, { + enter(node, parent) { + if (node.type === 'ImportDeclaration') { + node.specifiers.forEach((specifier) => { + scope.declarations.set(specifier.local.name, specifier); + }); + } else if (/(Function(Declaration|Expression)|ArrowFunctionExpression)/.test(node.type)) { + if (node.type === 'FunctionDeclaration') { + scope.declarations.set(node.id.name, node); + map.set(node, (scope = new Scope(scope, false))); + } else { + map.set(node, (scope = new Scope(scope, false))); + if (node.type === 'FunctionExpression' && node.id) scope.declarations.set(node.id.name, node); + } - node.params.forEach((param) => { - extract_names(param).forEach(name => { - scope.declarations.set(name, node); - }); - }); - } else if (/For(?:In|Of)?Statement/.test(node.type)) { - map.set(node, scope = new Scope(scope, true)); - } else if (node.type === 'BlockStatement') { - map.set(node, scope = new Scope(scope, true)); - } else if (/(Class|Variable)Declaration/.test(node.type)) { - scope.add_declaration(node); - } else if (node.type === 'CatchClause') { - map.set(node, scope = new Scope(scope, true)); - - if (node.param) { - extract_names(node.param).forEach(name => { - scope.declarations.set(name, node.param); - }); - } - } - }, + node.params.forEach((param) => { + extract_names(param).forEach((name) => { + scope.declarations.set(name, node); + }); + }); + } else if (/For(?:In|Of)?Statement/.test(node.type)) { + map.set(node, (scope = new Scope(scope, true))); + } else if (node.type === 'BlockStatement') { + map.set(node, (scope = new Scope(scope, true))); + } else if (/(Class|Variable)Declaration/.test(node.type)) { + scope.add_declaration(node); + } else if (node.type === 'CatchClause') { + map.set(node, (scope = new Scope(scope, true))); + + if (node.param) { + extract_names(node.param).forEach((name) => { + scope.declarations.set(name, node.param); + }); + } + } + }, - leave(node) { - if (map.has(node)) { - scope = scope.parent; - } - } - }); + leave(node) { + if (map.has(node)) { + scope = scope.parent; + } + }, + }); - const globals = new Map(); + const globals = new Map(); - walk(expression, { - enter(node, parent) { - if (map.has(node)) scope = map.get(node); + walk(expression, { + enter(node, parent) { + if (map.has(node)) scope = map.get(node); - if (node.type === 'Identifier' && isReference(node, parent)) { - const owner = scope.find_owner(node.name); - if (!owner) globals.set(node.name, node); + if (node.type === 'Identifier' && isReference(node, parent)) { + const owner = scope.find_owner(node.name); + if (!owner) globals.set(node.name, node); - add_reference(scope, node.name); - } - }, - leave(node) { - if (map.has(node)) { - scope = scope.parent; - } - } - }); + add_reference(scope, node.name); + } + }, + leave(node) { + if (map.has(node)) { + scope = scope.parent; + } + }, + }); - return { map, scope, globals }; + return { map, scope, globals }; } function add_reference(scope, name) { - scope.references.add(name); - if (scope.parent) add_reference(scope.parent, name); + scope.references.add(name); + if (scope.parent) add_reference(scope.parent, name); } class Scope { - - - __init() {this.declarations = new Map();} - __init2() {this.initialised_declarations = new Set();} - __init3() {this.references = new Set();} - - constructor(parent, block) {Scope.prototype.__init.call(this);Scope.prototype.__init2.call(this);Scope.prototype.__init3.call(this); - this.parent = parent; - this.block = block; - } - - - add_declaration(node) { - if (node.type === 'VariableDeclaration') { - if (node.kind === 'var' && this.block && this.parent) { - this.parent.add_declaration(node); - } else if (node.type === 'VariableDeclaration') { - node.declarations.forEach((declarator) => { - extract_names(declarator.id).forEach(name => { - this.declarations.set(name, node); - if (declarator.init) this.initialised_declarations.add(name); - }); - }); - } - } else { - this.declarations.set(node.id.name, node); - } - } + __init() { + this.declarations = new Map(); + } + __init2() { + this.initialised_declarations = new Set(); + } + __init3() { + this.references = new Set(); + } + + constructor(parent, block) { + Scope.prototype.__init.call(this); + Scope.prototype.__init2.call(this); + Scope.prototype.__init3.call(this); + this.parent = parent; + this.block = block; + } - find_owner(name) { - if (this.declarations.has(name)) return this; - return this.parent && this.parent.find_owner(name); - } + add_declaration(node) { + if (node.type === 'VariableDeclaration') { + if (node.kind === 'var' && this.block && this.parent) { + this.parent.add_declaration(node); + } else if (node.type === 'VariableDeclaration') { + node.declarations.forEach((declarator) => { + extract_names(declarator.id).forEach((name) => { + this.declarations.set(name, node); + if (declarator.init) this.initialised_declarations.add(name); + }); + }); + } + } else { + this.declarations.set(node.id.name, node); + } + } + + find_owner(name) { + if (this.declarations.has(name)) return this; + return this.parent && this.parent.find_owner(name); + } - has(name) { - return ( - this.declarations.has(name) || (this.parent && this.parent.has(name)) - ); - } + has(name) { + return this.declarations.has(name) || (this.parent && this.parent.has(name)); + } } function extract_names(param) { - return extract_identifiers(param).map(node => node.name); + return extract_identifiers(param).map((node) => node.name); } function extract_identifiers(param) { - const nodes = []; - extractors[param.type] && extractors[param.type](nodes, param); - return nodes; + const nodes = []; + extractors[param.type] && extractors[param.type](nodes, param); + return nodes; } const extractors = { - Identifier(nodes, param) { - nodes.push(param); - }, - - MemberExpression(nodes, param) { - let object = param; - while (object.type === 'MemberExpression') object = object.object; - nodes.push(object); - }, - - ObjectPattern(nodes, param) { - param.properties.forEach((prop) => { - if (prop.type === 'RestElement') { - nodes.push(prop.argument); - } else { - extractors[prop.value.type](nodes, prop.value); - } - }); - }, + Identifier(nodes, param) { + nodes.push(param); + }, - ArrayPattern(nodes, param) { - param.elements.forEach((element) => { - if (element) extractors[element.type](nodes, element); - }); - }, + MemberExpression(nodes, param) { + let object = param; + while (object.type === 'MemberExpression') object = object.object; + nodes.push(object); + }, - RestElement(nodes, param) { - extractors[param.argument.type](nodes, param.argument); - }, + ObjectPattern(nodes, param) { + param.properties.forEach((prop) => { + if (prop.type === 'RestElement') { + nodes.push(prop.argument); + } else { + extractors[prop.value.type](nodes, prop.value); + } + }); + }, + + ArrayPattern(nodes, param) { + param.elements.forEach((element) => { + if (element) extractors[element.type](nodes, element); + }); + }, - AssignmentPattern(nodes, param) { - extractors[param.left.type](nodes, param.left); - } + RestElement(nodes, param) { + extractors[param.argument.type](nodes, param.argument); + }, + + AssignmentPattern(nodes, param) { + extractors[param.left.type](nodes, param.left); + }, }; var charToInteger = {}; var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; for (var i = 0; i < chars.length; i++) { - charToInteger[chars.charCodeAt(i)] = i; + charToInteger[chars.charCodeAt(i)] = i; } function decode(mappings) { - var decoded = []; - var line = []; - var segment = [ - 0, - 0, - 0, - 0, - 0, - ]; - var j = 0; - for (var i = 0, shift = 0, value = 0; i < mappings.length; i++) { - var c = mappings.charCodeAt(i); - if (c === 44) { // "," - segmentify(line, segment, j); - j = 0; - } - else if (c === 59) { // ";" - segmentify(line, segment, j); - j = 0; - decoded.push(line); - line = []; - segment[0] = 0; - } - else { - var integer = charToInteger[c]; - if (integer === undefined) { - throw new Error('Invalid character (' + String.fromCharCode(c) + ')'); - } - var hasContinuationBit = integer & 32; - integer &= 31; - value += integer << shift; - if (hasContinuationBit) { - shift += 5; - } - else { - var shouldNegate = value & 1; - value >>>= 1; - if (shouldNegate) { - value = value === 0 ? -0x80000000 : -value; - } - segment[j] += value; - j++; - value = shift = 0; // reset - } + var decoded = []; + var line = []; + var segment = [0, 0, 0, 0, 0]; + var j = 0; + for (var i = 0, shift = 0, value = 0; i < mappings.length; i++) { + var c = mappings.charCodeAt(i); + if (c === 44) { + // "," + segmentify(line, segment, j); + j = 0; + } else if (c === 59) { + // ";" + segmentify(line, segment, j); + j = 0; + decoded.push(line); + line = []; + segment[0] = 0; + } else { + var integer = charToInteger[c]; + if (integer === undefined) { + throw new Error('Invalid character (' + String.fromCharCode(c) + ')'); + } + var hasContinuationBit = integer & 32; + integer &= 31; + value += integer << shift; + if (hasContinuationBit) { + shift += 5; + } else { + var shouldNegate = value & 1; + value >>>= 1; + if (shouldNegate) { + value = value === 0 ? -0x80000000 : -value; } + segment[j] += value; + j++; + value = shift = 0; // reset + } } - segmentify(line, segment, j); - decoded.push(line); - return decoded; + } + segmentify(line, segment, j); + decoded.push(line); + return decoded; } function segmentify(line, segment, j) { - // This looks ugly, but we're creating specialized arrays with a specific - // length. This is much faster than creating a new array (which v8 expands to - // a capacity of 17 after pushing the first item), or slicing out a subarray - // (which is slow). Length 4 is assumed to be the most frequent, followed by - // length 5 (since not everything will have an associated name), followed by - // length 1 (it's probably rare for a source substring to not have an - // associated segment data). - if (j === 4) - line.push([segment[0], segment[1], segment[2], segment[3]]); - else if (j === 5) - line.push([segment[0], segment[1], segment[2], segment[3], segment[4]]); - else if (j === 1) - line.push([segment[0]]); + // This looks ugly, but we're creating specialized arrays with a specific + // length. This is much faster than creating a new array (which v8 expands to + // a capacity of 17 after pushing the first item), or slicing out a subarray + // (which is slow). Length 4 is assumed to be the most frequent, followed by + // length 5 (since not everything will have an associated name), followed by + // length 1 (it's probably rare for a source substring to not have an + // associated segment data). + if (j === 4) line.push([segment[0], segment[1], segment[2], segment[3]]); + else if (j === 5) line.push([segment[0], segment[1], segment[2], segment[3], segment[4]]); + else if (j === 1) line.push([segment[0]]); } function encode(decoded) { - var sourceFileIndex = 0; // second field - var sourceCodeLine = 0; // third field - var sourceCodeColumn = 0; // fourth field - var nameIndex = 0; // fifth field - var mappings = ''; - for (var i = 0; i < decoded.length; i++) { - var line = decoded[i]; - if (i > 0) - mappings += ';'; - if (line.length === 0) - continue; - var generatedCodeColumn = 0; // first field - var lineMappings = []; - for (var _i = 0, line_1 = line; _i < line_1.length; _i++) { - var segment = line_1[_i]; - var segmentMappings = encodeInteger(segment[0] - generatedCodeColumn); - generatedCodeColumn = segment[0]; - if (segment.length > 1) { - segmentMappings += - encodeInteger(segment[1] - sourceFileIndex) + - encodeInteger(segment[2] - sourceCodeLine) + - encodeInteger(segment[3] - sourceCodeColumn); - sourceFileIndex = segment[1]; - sourceCodeLine = segment[2]; - sourceCodeColumn = segment[3]; - } - if (segment.length === 5) { - segmentMappings += encodeInteger(segment[4] - nameIndex); - nameIndex = segment[4]; - } - lineMappings.push(segmentMappings); - } - mappings += lineMappings.join(','); + var sourceFileIndex = 0; // second field + var sourceCodeLine = 0; // third field + var sourceCodeColumn = 0; // fourth field + var nameIndex = 0; // fifth field + var mappings = ''; + for (var i = 0; i < decoded.length; i++) { + var line = decoded[i]; + if (i > 0) mappings += ';'; + if (line.length === 0) continue; + var generatedCodeColumn = 0; // first field + var lineMappings = []; + for (var _i = 0, line_1 = line; _i < line_1.length; _i++) { + var segment = line_1[_i]; + var segmentMappings = encodeInteger(segment[0] - generatedCodeColumn); + generatedCodeColumn = segment[0]; + if (segment.length > 1) { + segmentMappings += encodeInteger(segment[1] - sourceFileIndex) + encodeInteger(segment[2] - sourceCodeLine) + encodeInteger(segment[3] - sourceCodeColumn); + sourceFileIndex = segment[1]; + sourceCodeLine = segment[2]; + sourceCodeColumn = segment[3]; + } + if (segment.length === 5) { + segmentMappings += encodeInteger(segment[4] - nameIndex); + nameIndex = segment[4]; + } + lineMappings.push(segmentMappings); } - return mappings; + mappings += lineMappings.join(','); + } + return mappings; } function encodeInteger(num) { - var result = ''; - num = num < 0 ? (-num << 1) | 1 : num << 1; - do { - var clamped = num & 31; - num >>>= 5; - if (num > 0) { - clamped |= 32; - } - result += chars[clamped]; - } while (num > 0); - return result; + var result = ''; + num = num < 0 ? (-num << 1) | 1 : num << 1; + do { + var clamped = num & 31; + num >>>= 5; + if (num > 0) { + clamped |= 32; + } + result += chars[clamped]; + } while (num > 0); + return result; } // generate an ID that is, to all intents and purposes, unique -const id = (Math.round(Math.random() * 1e20)).toString(36); +const id = Math.round(Math.random() * 1e20).toString(36); const re = new RegExp(`_${id}_(?:(\\d+)|(AT)|(HASH))_(\\w+)?`, 'g'); const get_comment_handlers = (comments, raw) => ({ + // pass to acorn options + onComment: (block, value, start, end) => { + if (block && /\n/.test(value)) { + let a = start; + while (a > 0 && raw[a - 1] !== '\n') a -= 1; - // pass to acorn options - onComment: (block, value, start, end) => { - if (block && /\n/.test(value)) { - let a = start; - while (a > 0 && raw[a - 1] !== '\n') a -= 1; - - let b = a; - while (/[ \t]/.test(raw[b])) b += 1; - - const indentation = raw.slice(a, b); - value = value.replace(new RegExp(`^${indentation}`, 'gm'), ''); - } + let b = a; + while (/[ \t]/.test(raw[b])) b += 1; - comments.push({ type: block ? 'Block' : 'Line', value, start, end }); - }, + const indentation = raw.slice(a, b); + value = value.replace(new RegExp(`^${indentation}`, 'gm'), ''); + } - // pass to estree-walker options - enter(node) { - let comment; + comments.push({ type: block ? 'Block' : 'Line', value, start, end }); + }, - while (comments[0] && comments[0].start < (node ).start) { - comment = comments.shift(); + // pass to estree-walker options + enter(node) { + let comment; - comment.value = comment.value.replace(re, (match, id, at, hash, value) => { - if (hash) return `#${value}`; - if (at) return `@${value}`; + while (comments[0] && comments[0].start < node.start) { + comment = comments.shift(); - return match; - }); + comment.value = comment.value.replace(re, (match, id, at, hash, value) => { + if (hash) return `#${value}`; + if (at) return `@${value}`; - const next = comments[0] || node; - (comment ).has_trailing_newline = ( - comment.type === 'Line' || - /\n/.test(raw.slice(comment.end, (next ).start)) - ); + return match; + }); - (node.leadingComments || (node.leadingComments = [])).push(comment); - } - }, - leave(node) { - if (comments[0]) { - const slice = raw.slice((node ).end, comments[0].start); + const next = comments[0] || node; + comment.has_trailing_newline = comment.type === 'Line' || /\n/.test(raw.slice(comment.end, next.start)); - if (/^[,) \t]*$/.test(slice)) { - node.trailingComments = [comments.shift()]; - } - } - } + (node.leadingComments || (node.leadingComments = [])).push(comment); + } + }, + leave(node) { + if (comments[0]) { + const slice = raw.slice(node.end, comments[0].start); + if (/^[,) \t]*$/.test(slice)) { + node.trailingComments = [comments.shift()]; + } + } + }, }); function handle(node, state) { - const handler = handlers[node.type]; + const handler = handlers[node.type]; - if (!handler) { - throw new Error(`Not implemented ${node.type}`); - } - - const result = handler(node, state); + if (!handler) { + throw new Error(`Not implemented ${node.type}`); + } - if (node.leadingComments) { - result.unshift(c(node.leadingComments.map(comment => comment.type === 'Block' - ? `/*${comment.value}*/${(comment ).has_trailing_newline ? `\n${state.indent}` : ` `}` - : `//${comment.value}${(comment ).has_trailing_newline ? `\n${state.indent}` : ` `}`).join(``))); - } + const result = handler(node, state); + + if (node.leadingComments) { + result.unshift( + c( + node.leadingComments + .map((comment) => + comment.type === 'Block' + ? `/*${comment.value}*/${comment.has_trailing_newline ? `\n${state.indent}` : ` `}` + : `//${comment.value}${comment.has_trailing_newline ? `\n${state.indent}` : ` `}` + ) + .join(``) + ) + ); + } - if (node.trailingComments) { - state.comments.push(node.trailingComments[0]); // there is only ever one - } + if (node.trailingComments) { + state.comments.push(node.trailingComments[0]); // there is only ever one + } - return result; + return result; } function c(content, node) { - return { - content, - loc: node && node.loc, - has_newline: /\n/.test(content) - }; + return { + content, + loc: node && node.loc, + has_newline: /\n/.test(content), + }; } const OPERATOR_PRECEDENCE = { - '||': 2, - '&&': 3, - '??': 4, - '|': 5, - '^': 6, - '&': 7, - '==': 8, - '!=': 8, - '===': 8, - '!==': 8, - '<': 9, - '>': 9, - '<=': 9, - '>=': 9, - in: 9, - instanceof: 9, - '<<': 10, - '>>': 10, - '>>>': 10, - '+': 11, - '-': 11, - '*': 12, - '%': 12, - '/': 12, - '**': 13, + '||': 2, + '&&': 3, + '??': 4, + '|': 5, + '^': 6, + '&': 7, + '==': 8, + '!=': 8, + '===': 8, + '!==': 8, + '<': 9, + '>': 9, + '<=': 9, + '>=': 9, + in: 9, + instanceof: 9, + '<<': 10, + '>>': 10, + '>>>': 10, + '+': 11, + '-': 11, + '*': 12, + '%': 12, + '/': 12, + '**': 13, }; const EXPRESSIONS_PRECEDENCE = { - ArrayExpression: 20, - TaggedTemplateExpression: 20, - ThisExpression: 20, - Identifier: 20, - Literal: 18, - TemplateLiteral: 20, - Super: 20, - SequenceExpression: 20, - MemberExpression: 19, - CallExpression: 19, - NewExpression: 19, - AwaitExpression: 17, - ClassExpression: 17, - FunctionExpression: 17, - ObjectExpression: 17, - UpdateExpression: 16, - UnaryExpression: 15, - BinaryExpression: 14, - LogicalExpression: 13, - ConditionalExpression: 4, - ArrowFunctionExpression: 3, - AssignmentExpression: 3, - YieldExpression: 2, - RestElement: 1 + ArrayExpression: 20, + TaggedTemplateExpression: 20, + ThisExpression: 20, + Identifier: 20, + Literal: 18, + TemplateLiteral: 20, + Super: 20, + SequenceExpression: 20, + MemberExpression: 19, + CallExpression: 19, + NewExpression: 19, + AwaitExpression: 17, + ClassExpression: 17, + FunctionExpression: 17, + ObjectExpression: 17, + UpdateExpression: 16, + UnaryExpression: 15, + BinaryExpression: 14, + LogicalExpression: 13, + ConditionalExpression: 4, + ArrowFunctionExpression: 3, + AssignmentExpression: 3, + YieldExpression: 2, + RestElement: 1, }; function needs_parens(node, parent, is_right) { - // special case where logical expressions and coalesce expressions cannot be mixed, - // either of them need to be wrapped with parentheses - if ( - node.type === 'LogicalExpression' && - parent.type === 'LogicalExpression' && - ((parent.operator === '??' && node.operator !== '??') || - (parent.operator !== '??' && node.operator === '??')) - ) { - return true; - } - - const precedence = EXPRESSIONS_PRECEDENCE[node.type]; - const parent_precedence = EXPRESSIONS_PRECEDENCE[parent.type]; - - if (precedence !== parent_precedence) { - // Different node types - return ( - (!is_right && - precedence === 15 && - parent_precedence === 14 && - parent.operator === '**') || - precedence < parent_precedence - ); - } - - if (precedence !== 13 && precedence !== 14) { - // Not a `LogicalExpression` or `BinaryExpression` - return false; - } - - if ((node ).operator === '**' && parent.operator === '**') { - // Exponentiation operator has right-to-left associativity - return !is_right; - } - - if (is_right) { - // Parenthesis are used if both operators have the same precedence - return ( - OPERATOR_PRECEDENCE[(node ).operator] <= - OPERATOR_PRECEDENCE[parent.operator] - ); - } - - return ( - OPERATOR_PRECEDENCE[(node ).operator] < - OPERATOR_PRECEDENCE[parent.operator] - ); + // special case where logical expressions and coalesce expressions cannot be mixed, + // either of them need to be wrapped with parentheses + if ( + node.type === 'LogicalExpression' && + parent.type === 'LogicalExpression' && + ((parent.operator === '??' && node.operator !== '??') || (parent.operator !== '??' && node.operator === '??')) + ) { + return true; + } + + const precedence = EXPRESSIONS_PRECEDENCE[node.type]; + const parent_precedence = EXPRESSIONS_PRECEDENCE[parent.type]; + + if (precedence !== parent_precedence) { + // Different node types + return (!is_right && precedence === 15 && parent_precedence === 14 && parent.operator === '**') || precedence < parent_precedence; + } + + if (precedence !== 13 && precedence !== 14) { + // Not a `LogicalExpression` or `BinaryExpression` + return false; + } + + if (node.operator === '**' && parent.operator === '**') { + // Exponentiation operator has right-to-left associativity + return !is_right; + } + + if (is_right) { + // Parenthesis are used if both operators have the same precedence + return OPERATOR_PRECEDENCE[node.operator] <= OPERATOR_PRECEDENCE[parent.operator]; + } + + return OPERATOR_PRECEDENCE[node.operator] < OPERATOR_PRECEDENCE[parent.operator]; } function has_call_expression(node) { - while (node) { - if (node.type[0] === 'CallExpression') { - return true; - } else if (node.type === 'MemberExpression') { - node = node.object; - } else { - return false; - } - } + while (node) { + if (node.type[0] === 'CallExpression') { + return true; + } else if (node.type === 'MemberExpression') { + node = node.object; + } else { + return false; + } + } } const has_newline = (chunks) => { - for (let i = 0; i < chunks.length; i += 1) { - if (chunks[i].has_newline) return true; - } - return false; + for (let i = 0; i < chunks.length; i += 1) { + if (chunks[i].has_newline) return true; + } + return false; }; const get_length = (chunks) => { - let total = 0; - for (let i = 0; i < chunks.length; i += 1) { - total += chunks[i].content.length; - } - return total; + let total = 0; + for (let i = 0; i < chunks.length; i += 1) { + total += chunks[i].content.length; + } + return total; }; const sum = (a, b) => a + b; const join = (nodes, separator) => { - if (nodes.length === 0) return []; - const joined = [...nodes[0]]; - for (let i = 1; i < nodes.length; i += 1) { - joined.push(separator, ...nodes[i] ); - } - return joined; + if (nodes.length === 0) return []; + const joined = [...nodes[0]]; + for (let i = 1; i < nodes.length; i += 1) { + joined.push(separator, ...nodes[i]); + } + return joined; }; const scoped = (fn) => { - return (node, state) => { - return fn(node, { - ...state, - scope: state.scope_map.get(node) - }); - }; + return (node, state) => { + return fn(node, { + ...state, + scope: state.scope_map.get(node), + }); + }; }; const deconflict = (name, names) => { - const original = name; - let i = 1; + const original = name; + let i = 1; - while (names.has(name)) { - name = `${original}$${i++}`; - } + while (names.has(name)) { + name = `${original}$${i++}`; + } - return name; + return name; }; const handle_body = (nodes, state) => { - const chunks = []; + const chunks = []; - const body = nodes.map(statement => { - const chunks = handle(statement, { - ...state, - indent: state.indent - }); + const body = nodes.map((statement) => { + const chunks = handle(statement, { + ...state, + indent: state.indent, + }); - let add_newline = false; + let add_newline = false; - while (state.comments.length) { - const comment = state.comments.shift(); - const prefix = add_newline ? `\n${state.indent}` : ` `; + while (state.comments.length) { + const comment = state.comments.shift(); + const prefix = add_newline ? `\n${state.indent}` : ` `; - chunks.push(c(comment.type === 'Block' - ? `${prefix}/*${comment.value}*/` - : `${prefix}//${comment.value}`)); + chunks.push(c(comment.type === 'Block' ? `${prefix}/*${comment.value}*/` : `${prefix}//${comment.value}`)); - add_newline = (comment.type === 'Line'); - } + add_newline = comment.type === 'Line'; + } - return chunks; - }); + return chunks; + }); - let needed_padding = false; + let needed_padding = false; - for (let i = 0; i < body.length; i += 1) { - const needs_padding = has_newline(body[i]); + for (let i = 0; i < body.length; i += 1) { + const needs_padding = has_newline(body[i]); - if (i > 0) { - chunks.push( - c(needs_padding || needed_padding ? `\n\n${state.indent}` : `\n${state.indent}`) - ); - } + if (i > 0) { + chunks.push(c(needs_padding || needed_padding ? `\n\n${state.indent}` : `\n${state.indent}`)); + } - chunks.push( - ...body[i] - ); + chunks.push(...body[i]); - needed_padding = needs_padding; - } + needed_padding = needs_padding; + } - return chunks; + return chunks; }; const handle_var_declaration = (node, state) => { - const chunks = [c(`${node.kind} `)]; + const chunks = [c(`${node.kind} `)]; - const declarators = node.declarations.map(d => handle(d, { - ...state, - indent: state.indent + (node.declarations.length === 1 ? '' : '\t') - })); + const declarators = node.declarations.map((d) => + handle(d, { + ...state, + indent: state.indent + (node.declarations.length === 1 ? '' : '\t'), + }) + ); - const multiple_lines = ( - declarators.some(has_newline) || - (declarators.map(get_length).reduce(sum, 0) + (state.indent.length + declarators.length - 1) * 2) > 80 - ); + const multiple_lines = declarators.some(has_newline) || declarators.map(get_length).reduce(sum, 0) + (state.indent.length + declarators.length - 1) * 2 > 80; - const separator = c(multiple_lines ? `,\n${state.indent}\t` : ', '); + const separator = c(multiple_lines ? `,\n${state.indent}\t` : ', '); - if (multiple_lines) { - chunks.push(...join(declarators, separator)); - } else { - chunks.push( - ...join(declarators, separator) - ); - } + if (multiple_lines) { + chunks.push(...join(declarators, separator)); + } else { + chunks.push(...join(declarators, separator)); + } - return chunks; + return chunks; }; const handlers = { - Program(node, state) { - return handle_body(node.body, state); - }, - - BlockStatement: scoped((node, state) => { - return [ - c(`{\n${state.indent}\t`), - ...handle_body(node.body, { ...state, indent: state.indent + '\t' }), - c(`\n${state.indent}}`) - ]; - }), - - EmptyStatement(node, state) { - return []; - }, - - ParenthesizedExpression(node, state) { - return handle(node.expression, state); - }, - - ExpressionStatement(node, state) { - if ( - node.expression.type === 'AssignmentExpression' && - node.expression.left.type === 'ObjectPattern' - ) { - // is an AssignmentExpression to an ObjectPattern - return [ - c('('), - ...handle(node.expression, state), - c(');') - ]; - } + Program(node, state) { + return handle_body(node.body, state); + }, - return [ - ...handle(node.expression, state), - c(';') - ]; - }, - - IfStatement(node, state) { - const chunks = [ - c('if ('), - ...handle(node.test, state), - c(') '), - ...handle(node.consequent, state) - ]; - - if (node.alternate) { - chunks.push( - c(' else '), - ...handle(node.alternate, state) - ); - } + BlockStatement: scoped((node, state) => { + return [c(`{\n${state.indent}\t`), ...handle_body(node.body, { ...state, indent: state.indent + '\t' }), c(`\n${state.indent}}`)]; + }), - return chunks; - }, - - LabeledStatement(node, state) { - return [ - ...handle(node.label, state), - c(': '), - ...handle(node.body, state) - ]; - }, - - BreakStatement(node, state) { - return node.label - ? [c('break '), ...handle(node.label, state), c(';')] - : [c('break;')]; - }, - - ContinueStatement(node, state) { - return node.label - ? [c('continue '), ...handle(node.label, state), c(';')] - : [c('continue;')]; - }, - - WithStatement(node, state) { - return [ - c('with ('), - ...handle(node.object, state), - c(') '), - ...handle(node.body, state) - ]; - }, - - SwitchStatement(node, state) { - const chunks = [ - c('switch ('), - ...handle(node.discriminant, state), - c(') {') - ]; - - node.cases.forEach(block => { - if (block.test) { - chunks.push( - c(`\n${state.indent}\tcase `), - ...handle(block.test, { ...state, indent: `${state.indent}\t` }), - c(':') - ); - } else { - chunks.push(c(`\n${state.indent}\tdefault:`)); - } + EmptyStatement(node, state) { + return []; + }, - block.consequent.forEach(statement => { - chunks.push( - c(`\n${state.indent}\t\t`), - ...handle(statement, { ...state, indent: `${state.indent}\t\t` }) - ); - }); - }); + ParenthesizedExpression(node, state) { + return handle(node.expression, state); + }, - chunks.push(c(`\n${state.indent}}`)); + ExpressionStatement(node, state) { + if (node.expression.type === 'AssignmentExpression' && node.expression.left.type === 'ObjectPattern') { + // is an AssignmentExpression to an ObjectPattern + return [c('('), ...handle(node.expression, state), c(');')]; + } - return chunks; - }, + return [...handle(node.expression, state), c(';')]; + }, - ReturnStatement(node, state) { - if (node.argument) { - return [ - c('return '), - ...handle(node.argument, state), - c(';') - ]; - } else { - return [c('return;')]; - } - }, - - ThrowStatement(node, state) { - return [ - c('throw '), - ...handle(node.argument, state), - c(';') - ]; - }, - - TryStatement(node, state) { - const chunks = [ - c('try '), - ...handle(node.block, state) - ]; - - if (node.handler) { - if (node.handler.param) { - chunks.push( - c(' catch('), - ...handle(node.handler.param, state), - c(') ') - ); - } else { - chunks.push(c(' catch ')); - } + IfStatement(node, state) { + const chunks = [c('if ('), ...handle(node.test, state), c(') '), ...handle(node.consequent, state)]; - chunks.push(...handle(node.handler.body, state)); - } + if (node.alternate) { + chunks.push(c(' else '), ...handle(node.alternate, state)); + } - if (node.finalizer) { - chunks.push(c(' finally '), ...handle(node.finalizer, state)); - } + return chunks; + }, - return chunks; - }, - - WhileStatement(node, state) { - return [ - c('while ('), - ...handle(node.test, state), - c(') '), - ...handle(node.body, state) - ]; - }, - - DoWhileStatement(node, state) { - return [ - c('do '), - ...handle(node.body, state), - c(' while ('), - ...handle(node.test, state), - c(');') - ]; - }, - - ForStatement: scoped((node, state) => { - const chunks = [c('for (')]; - - if (node.init) { - if ((node.init ).type === 'VariableDeclaration') { - chunks.push(...handle_var_declaration(node.init , state)); - } else { - chunks.push(...handle(node.init, state)); - } - } + LabeledStatement(node, state) { + return [...handle(node.label, state), c(': '), ...handle(node.body, state)]; + }, - chunks.push(c('; ')); - if (node.test) chunks.push(...handle(node.test, state)); - chunks.push(c('; ')); - if (node.update) chunks.push(...handle(node.update, state)); + BreakStatement(node, state) { + return node.label ? [c('break '), ...handle(node.label, state), c(';')] : [c('break;')]; + }, - chunks.push( - c(') '), - ...handle(node.body, state) - ); + ContinueStatement(node, state) { + return node.label ? [c('continue '), ...handle(node.label, state), c(';')] : [c('continue;')]; + }, - return chunks; - }), + WithStatement(node, state) { + return [c('with ('), ...handle(node.object, state), c(') '), ...handle(node.body, state)]; + }, - ForInStatement: scoped((node, state) => { - const chunks = [ - c(`for ${(node ).await ? 'await ' : ''}(`) - ]; + SwitchStatement(node, state) { + const chunks = [c('switch ('), ...handle(node.discriminant, state), c(') {')]; - if ((node.left ).type === 'VariableDeclaration') { - chunks.push(...handle_var_declaration(node.left , state)); - } else { - chunks.push(...handle(node.left, state)); - } + node.cases.forEach((block) => { + if (block.test) { + chunks.push(c(`\n${state.indent}\tcase `), ...handle(block.test, { ...state, indent: `${state.indent}\t` }), c(':')); + } else { + chunks.push(c(`\n${state.indent}\tdefault:`)); + } - chunks.push( - c(node.type === 'ForInStatement' ? ` in ` : ` of `), - ...handle(node.right, state), - c(') '), - ...handle(node.body, state) - ); - - return chunks; - }), - - DebuggerStatement(node, state) { - return [c('debugger', node), c(';')]; - }, - - FunctionDeclaration: scoped((node, state) => { - const chunks = []; - - if (node.async) chunks.push(c('async ')); - chunks.push(c(node.generator ? 'function* ' : 'function ')); - if (node.id) chunks.push(...handle(node.id, state)); - chunks.push(c('(')); - - const params = node.params.map(p => handle(p, { - ...state, - indent: state.indent + '\t' - })); - - const multiple_lines = ( - params.some(has_newline) || - (params.map(get_length).reduce(sum, 0) + (state.indent.length + params.length - 1) * 2) > 80 - ); - - const separator = c(multiple_lines ? `,\n${state.indent}` : ', '); - - if (multiple_lines) { - chunks.push( - c(`\n${state.indent}\t`), - ...join(params, separator), - c(`\n${state.indent}`) - ); - } else { - chunks.push( - ...join(params, separator) - ); - } + block.consequent.forEach((statement) => { + chunks.push(c(`\n${state.indent}\t\t`), ...handle(statement, { ...state, indent: `${state.indent}\t\t` })); + }); + }); - chunks.push( - c(') '), - ...handle(node.body, state) - ); + chunks.push(c(`\n${state.indent}}`)); - return chunks; - }), + return chunks; + }, - VariableDeclaration(node, state) { - return handle_var_declaration(node, state).concat(c(';')); - }, + ReturnStatement(node, state) { + if (node.argument) { + return [c('return '), ...handle(node.argument, state), c(';')]; + } else { + return [c('return;')]; + } + }, - VariableDeclarator(node, state) { - if (node.init) { - return [ - ...handle(node.id, state), - c(' = '), - ...handle(node.init, state) - ]; - } else { - return handle(node.id, state); - } - }, + ThrowStatement(node, state) { + return [c('throw '), ...handle(node.argument, state), c(';')]; + }, - ClassDeclaration(node, state) { - const chunks = [c('class ')]; + TryStatement(node, state) { + const chunks = [c('try '), ...handle(node.block, state)]; - if (node.id) chunks.push(...handle(node.id, state), c(' ')); + if (node.handler) { + if (node.handler.param) { + chunks.push(c(' catch('), ...handle(node.handler.param, state), c(') ')); + } else { + chunks.push(c(' catch ')); + } - if (node.superClass) { - chunks.push( - c('extends '), - ...handle(node.superClass, state), - c(' ') - ); - } + chunks.push(...handle(node.handler.body, state)); + } - chunks.push(...handle(node.body, state)); + if (node.finalizer) { + chunks.push(c(' finally '), ...handle(node.finalizer, state)); + } - return chunks; - }, + return chunks; + }, - ImportDeclaration(node, state) { - const chunks = [c('import ')]; + WhileStatement(node, state) { + return [c('while ('), ...handle(node.test, state), c(') '), ...handle(node.body, state)]; + }, - const { length } = node.specifiers; - const source = handle(node.source, state); + DoWhileStatement(node, state) { + return [c('do '), ...handle(node.body, state), c(' while ('), ...handle(node.test, state), c(');')]; + }, - if (length > 0) { - let i = 0; + ForStatement: scoped((node, state) => { + const chunks = [c('for (')]; - while (i < length) { - if (i > 0) { - chunks.push(c(', ')); - } + if (node.init) { + if (node.init.type === 'VariableDeclaration') { + chunks.push(...handle_var_declaration(node.init, state)); + } else { + chunks.push(...handle(node.init, state)); + } + } - const specifier = node.specifiers[i]; + chunks.push(c('; ')); + if (node.test) chunks.push(...handle(node.test, state)); + chunks.push(c('; ')); + if (node.update) chunks.push(...handle(node.update, state)); - if (specifier.type === 'ImportDefaultSpecifier') { - chunks.push(c(specifier.local.name, specifier)); - i += 1; - } else if (specifier.type === 'ImportNamespaceSpecifier') { - chunks.push(c('* as ' + specifier.local.name, specifier)); - i += 1; - } else { - break; - } - } + chunks.push(c(') '), ...handle(node.body, state)); - if (i < length) { - // we have named specifiers - const specifiers = node.specifiers.slice(i).map((specifier) => { - const name = handle(specifier.imported, state)[0]; - const as = handle(specifier.local, state)[0]; + return chunks; + }), - if (name.content === as.content) { - return [as]; - } + ForInStatement: scoped((node, state) => { + const chunks = [c(`for ${node.await ? 'await ' : ''}(`)]; - return [name, c(' as '), as]; - }); + if (node.left.type === 'VariableDeclaration') { + chunks.push(...handle_var_declaration(node.left, state)); + } else { + chunks.push(...handle(node.left, state)); + } - const width = get_length(chunks) + specifiers.map(get_length).reduce(sum, 0) + (2 * specifiers.length) + 6 + get_length(source); + chunks.push(c(node.type === 'ForInStatement' ? ` in ` : ` of `), ...handle(node.right, state), c(') '), ...handle(node.body, state)); - if (width > 80) { - chunks.push( - c(`{\n\t`), - ...join(specifiers, c(',\n\t')), - c('\n}') - ); - } else { - chunks.push( - c(`{ `), - ...join(specifiers, c(', ')), - c(' }') - ); - } - } + return chunks; + }), - chunks.push(c(' from ')); - } + DebuggerStatement(node, state) { + return [c('debugger', node), c(';')]; + }, - chunks.push( - ...source, - c(';') - ); + FunctionDeclaration: scoped((node, state) => { + const chunks = []; - return chunks; - }, + if (node.async) chunks.push(c('async ')); + chunks.push(c(node.generator ? 'function* ' : 'function ')); + if (node.id) chunks.push(...handle(node.id, state)); + chunks.push(c('(')); - ImportExpression(node, state) { - return [c('import('), ...handle(node.source, state), c(')')]; - }, + const params = node.params.map((p) => + handle(p, { + ...state, + indent: state.indent + '\t', + }) + ); - ExportDefaultDeclaration(node, state) { - const chunks = [ - c(`export default `), - ...handle(node.declaration, state) - ]; + const multiple_lines = params.some(has_newline) || params.map(get_length).reduce(sum, 0) + (state.indent.length + params.length - 1) * 2 > 80; - if (node.declaration.type !== 'FunctionDeclaration') { - chunks.push(c(';')); - } + const separator = c(multiple_lines ? `,\n${state.indent}` : ', '); - return chunks; - }, + if (multiple_lines) { + chunks.push(c(`\n${state.indent}\t`), ...join(params, separator), c(`\n${state.indent}`)); + } else { + chunks.push(...join(params, separator)); + } - ExportNamedDeclaration(node, state) { - const chunks = [c('export ')]; + chunks.push(c(') '), ...handle(node.body, state)); - if (node.declaration) { - chunks.push(...handle(node.declaration, state)); - } else { - const specifiers = node.specifiers.map(specifier => { - const name = handle(specifier.local, state)[0]; - const as = handle(specifier.exported, state)[0]; + return chunks; + }), - if (name.content === as.content) { - return [name]; - } + VariableDeclaration(node, state) { + return handle_var_declaration(node, state).concat(c(';')); + }, - return [name, c(' as '), as]; - }); + VariableDeclarator(node, state) { + if (node.init) { + return [...handle(node.id, state), c(' = '), ...handle(node.init, state)]; + } else { + return handle(node.id, state); + } + }, - const width = 7 + specifiers.map(get_length).reduce(sum, 0) + 2 * specifiers.length; - - if (width > 80) { - chunks.push( - c('{\n\t'), - ...join(specifiers, c(',\n\t')), - c('\n}') - ); - } else { - chunks.push( - c('{ '), - ...join(specifiers, c(', ')), - c(' }') - ); - } + ClassDeclaration(node, state) { + const chunks = [c('class ')]; - if (node.source) { - chunks.push( - c(' from '), - ...handle(node.source, state) - ); - } - } + if (node.id) chunks.push(...handle(node.id, state), c(' ')); - chunks.push(c(';')); + if (node.superClass) { + chunks.push(c('extends '), ...handle(node.superClass, state), c(' ')); + } - return chunks; - }, + chunks.push(...handle(node.body, state)); - ExportAllDeclaration(node, state) { - return [ - c(`export * from `), - ...handle(node.source, state), - c(`;`) - ]; - }, + return chunks; + }, - MethodDefinition(node, state) { - const chunks = []; + ImportDeclaration(node, state) { + const chunks = [c('import ')]; - if (node.static) { - chunks.push(c('static ')); - } + const { length } = node.specifiers; + const source = handle(node.source, state); - if (node.kind === 'get' || node.kind === 'set') { - // Getter or setter - chunks.push(c(node.kind + ' ')); - } + if (length > 0) { + let i = 0; - if (node.value.async) { - chunks.push(c('async ')); - } + while (i < length) { + if (i > 0) { + chunks.push(c(', ')); + } - if (node.value.generator) { - chunks.push(c('*')); - } + const specifier = node.specifiers[i]; - if (node.computed) { - chunks.push( - c('['), - ...handle(node.key, state), - c(']') - ); - } else { - chunks.push(...handle(node.key, state)); - } + if (specifier.type === 'ImportDefaultSpecifier') { + chunks.push(c(specifier.local.name, specifier)); + i += 1; + } else if (specifier.type === 'ImportNamespaceSpecifier') { + chunks.push(c('* as ' + specifier.local.name, specifier)); + i += 1; + } else { + break; + } + } - chunks.push(c('(')); + if (i < length) { + // we have named specifiers + const specifiers = node.specifiers.slice(i).map((specifier) => { + const name = handle(specifier.imported, state)[0]; + const as = handle(specifier.local, state)[0]; - const { params } = node.value; - for (let i = 0; i < params.length; i += 1) { - chunks.push(...handle(params[i], state)); - if (i < params.length - 1) chunks.push(c(', ')); - } + if (name.content === as.content) { + return [as]; + } - chunks.push( - c(') '), - ...handle(node.value.body, state) - ); + return [name, c(' as '), as]; + }); - return chunks; - }, + const width = get_length(chunks) + specifiers.map(get_length).reduce(sum, 0) + 2 * specifiers.length + 6 + get_length(source); - ArrowFunctionExpression: scoped((node, state) => { - const chunks = []; + if (width > 80) { + chunks.push(c(`{\n\t`), ...join(specifiers, c(',\n\t')), c('\n}')); + } else { + chunks.push(c(`{ `), ...join(specifiers, c(', ')), c(' }')); + } + } - if (node.async) chunks.push(c('async ')); + chunks.push(c(' from ')); + } - if (node.params.length === 1 && node.params[0].type === 'Identifier') { - chunks.push(...handle(node.params[0], state)); - } else { - const params = node.params.map(param => handle(param, { - ...state, - indent: state.indent + '\t' - })); + chunks.push(...source, c(';')); - chunks.push( - c('('), - ...join(params, c(', ')), - c(')') - ); - } + return chunks; + }, - chunks.push(c(' => ')); + ImportExpression(node, state) { + return [c('import('), ...handle(node.source, state), c(')')]; + }, - if (node.body.type === 'ObjectExpression') { - chunks.push( - c('('), - ...handle(node.body, state), - c(')') - ); - } else { - chunks.push(...handle(node.body, state)); - } + ExportDefaultDeclaration(node, state) { + const chunks = [c(`export default `), ...handle(node.declaration, state)]; - return chunks; - }), + if (node.declaration.type !== 'FunctionDeclaration') { + chunks.push(c(';')); + } - ThisExpression(node, state) { - return [c('this', node)]; - }, + return chunks; + }, - Super(node, state) { - return [c('super', node)]; - }, + ExportNamedDeclaration(node, state) { + const chunks = [c('export ')]; - RestElement(node, state) { - return [c('...'), ...handle(node.argument, state)]; - }, + if (node.declaration) { + chunks.push(...handle(node.declaration, state)); + } else { + const specifiers = node.specifiers.map((specifier) => { + const name = handle(specifier.local, state)[0]; + const as = handle(specifier.exported, state)[0]; - YieldExpression(node, state) { - if (node.argument) { - return [c(node.delegate ? `yield* ` : `yield `), ...handle(node.argument, state)]; - } + if (name.content === as.content) { + return [name]; + } - return [c(node.delegate ? `yield*` : `yield`)]; - }, + return [name, c(' as '), as]; + }); - AwaitExpression(node, state) { - if (node.argument) { - const precedence = EXPRESSIONS_PRECEDENCE[node.argument.type]; + const width = 7 + specifiers.map(get_length).reduce(sum, 0) + 2 * specifiers.length; - if (precedence && (precedence < EXPRESSIONS_PRECEDENCE.AwaitExpression)) { - return [c('await ('), ...handle(node.argument, state), c(')')]; - } else { - return [c('await '), ...handle(node.argument, state)]; - } - } + if (width > 80) { + chunks.push(c('{\n\t'), ...join(specifiers, c(',\n\t')), c('\n}')); + } else { + chunks.push(c('{ '), ...join(specifiers, c(', ')), c(' }')); + } - return [c('await')]; - }, + if (node.source) { + chunks.push(c(' from '), ...handle(node.source, state)); + } + } - TemplateLiteral(node, state) { - const chunks = [c('`')]; + chunks.push(c(';')); - const { quasis, expressions } = node; + return chunks; + }, - for (let i = 0; i < expressions.length; i++) { - chunks.push( - c(quasis[i].value.raw), - c('${'), - ...handle(expressions[i], state), - c('}') - ); - } + ExportAllDeclaration(node, state) { + return [c(`export * from `), ...handle(node.source, state), c(`;`)]; + }, - chunks.push( - c(quasis[quasis.length - 1].value.raw), - c('`') - ); - - return chunks; - }, - - TaggedTemplateExpression(node, state) { - return handle(node.tag, state).concat(handle(node.quasi, state)); - }, - - ArrayExpression(node, state) { - const chunks = [c('[')]; - - const elements = []; - let sparse_commas = []; - - for (let i = 0; i < node.elements.length; i += 1) { - // can't use map/forEach because of sparse arrays - const element = node.elements[i]; - if (element) { - elements.push([...sparse_commas, ...handle(element, { - ...state, - indent: state.indent + '\t' - })]); - sparse_commas = []; - } else { - sparse_commas.push(c(',')); - } - } + MethodDefinition(node, state) { + const chunks = []; - const multiple_lines = ( - elements.some(has_newline) || - (elements.map(get_length).reduce(sum, 0) + (state.indent.length + elements.length - 1) * 2) > 80 - ); - - if (multiple_lines) { - chunks.push( - c(`\n${state.indent}\t`), - ...join(elements, c(`,\n${state.indent}\t`)), - c(`\n${state.indent}`), - ...sparse_commas - ); - } else { - chunks.push(...join(elements, c(', ')), ...sparse_commas); - } + if (node.static) { + chunks.push(c('static ')); + } - chunks.push(c(']')); + if (node.kind === 'get' || node.kind === 'set') { + // Getter or setter + chunks.push(c(node.kind + ' ')); + } - return chunks; - }, + if (node.value.async) { + chunks.push(c('async ')); + } - ObjectExpression(node, state) { - if (node.properties.length === 0) { - return [c('{}')]; - } + if (node.value.generator) { + chunks.push(c('*')); + } - let has_inline_comment = false; + if (node.computed) { + chunks.push(c('['), ...handle(node.key, state), c(']')); + } else { + chunks.push(...handle(node.key, state)); + } - const chunks = []; - const separator = c(', '); + chunks.push(c('(')); - node.properties.forEach((p, i) => { - chunks.push(...handle(p, { - ...state, - indent: state.indent + '\t' - })); + const { params } = node.value; + for (let i = 0; i < params.length; i += 1) { + chunks.push(...handle(params[i], state)); + if (i < params.length - 1) chunks.push(c(', ')); + } - if (state.comments.length) { - // TODO generalise this, so it works with ArrayExpressions and other things. - // At present, stuff will just get appended to the closest statement/declaration - chunks.push(c(', ')); + chunks.push(c(') '), ...handle(node.value.body, state)); - while (state.comments.length) { - const comment = state.comments.shift(); + return chunks; + }, - chunks.push(c(comment.type === 'Block' - ? `/*${comment.value}*/\n${state.indent}\t` - : `//${comment.value}\n${state.indent}\t`)); + ArrowFunctionExpression: scoped((node, state) => { + const chunks = []; - if (comment.type === 'Line') { - has_inline_comment = true; - } - } - } else { - if (i < node.properties.length - 1) { - chunks.push(separator); - } - } - }); + if (node.async) chunks.push(c('async ')); - const multiple_lines = ( - has_inline_comment || - has_newline(chunks) || - get_length(chunks) > 40 - ); + if (node.params.length === 1 && node.params[0].type === 'Identifier') { + chunks.push(...handle(node.params[0], state)); + } else { + const params = node.params.map((param) => + handle(param, { + ...state, + indent: state.indent + '\t', + }) + ); - if (multiple_lines) { - separator.content = `,\n${state.indent}\t`; - } + chunks.push(c('('), ...join(params, c(', ')), c(')')); + } - return [ - c(multiple_lines ? `{\n${state.indent}\t` : `{ `), - ...chunks, - c(multiple_lines ? `\n${state.indent}}` : ` }`) - ]; - }, + chunks.push(c(' => ')); - Property(node, state) { - const value = handle(node.value, state); + if (node.body.type === 'ObjectExpression') { + chunks.push(c('('), ...handle(node.body, state), c(')')); + } else { + chunks.push(...handle(node.body, state)); + } - if (node.key === node.value) { - return value; - } + return chunks; + }), - // special case - if ( - !node.computed && - node.value.type === 'AssignmentPattern' && - node.value.left.type === 'Identifier' && - node.value.left.name === (node.key ).name - ) { - return value; - } + ThisExpression(node, state) { + return [c('this', node)]; + }, - if (node.value.type === 'Identifier' && ( - (node.key.type === 'Identifier' && node.key.name === value[0].content) || - (node.key.type === 'Literal' && node.key.value === value[0].content) - )) { - return value; - } + Super(node, state) { + return [c('super', node)]; + }, - const key = handle(node.key, state); + RestElement(node, state) { + return [c('...'), ...handle(node.argument, state)]; + }, - if (node.value.type === 'FunctionExpression' && !node.value.id) { - state = { - ...state, - scope: state.scope_map.get(node.value) - }; + YieldExpression(node, state) { + if (node.argument) { + return [c(node.delegate ? `yield* ` : `yield `), ...handle(node.argument, state)]; + } - const chunks = node.kind !== 'init' - ? [c(`${node.kind} `)] - : []; + return [c(node.delegate ? `yield*` : `yield`)]; + }, - if (node.value.async) { - chunks.push(c('async ')); - } - if (node.value.generator) { - chunks.push(c('*')); - } + AwaitExpression(node, state) { + if (node.argument) { + const precedence = EXPRESSIONS_PRECEDENCE[node.argument.type]; - chunks.push( - ...(node.computed ? [c('['), ...key, c(']')] : key), - c('('), - ...join((node.value ).params.map(param => handle(param, state)), c(', ')), - c(') '), - ...handle((node.value ).body, state) - ); + if (precedence && precedence < EXPRESSIONS_PRECEDENCE.AwaitExpression) { + return [c('await ('), ...handle(node.argument, state), c(')')]; + } else { + return [c('await '), ...handle(node.argument, state)]; + } + } - return chunks; - } + return [c('await')]; + }, - if (node.computed) { - return [ - c('['), - ...key, - c(']: '), - ...value - ]; - } + TemplateLiteral(node, state) { + const chunks = [c('`')]; - return [ - ...key, - c(': '), - ...value - ]; - }, + const { quasis, expressions } = node; - ObjectPattern(node, state) { - const chunks = [c('{ ')]; + for (let i = 0; i < expressions.length; i++) { + chunks.push(c(quasis[i].value.raw), c('${'), ...handle(expressions[i], state), c('}')); + } - for (let i = 0; i < node.properties.length; i += 1) { - chunks.push(...handle(node.properties[i], state)); - if (i < node.properties.length - 1) chunks.push(c(', ')); - } + chunks.push(c(quasis[quasis.length - 1].value.raw), c('`')); - chunks.push(c(' }')); + return chunks; + }, - return chunks; - }, + TaggedTemplateExpression(node, state) { + return handle(node.tag, state).concat(handle(node.quasi, state)); + }, - SequenceExpression(node, state) { - const expressions = node.expressions.map(e => handle(e, state)); + ArrayExpression(node, state) { + const chunks = [c('[')]; + + const elements = []; + let sparse_commas = []; + + for (let i = 0; i < node.elements.length; i += 1) { + // can't use map/forEach because of sparse arrays + const element = node.elements[i]; + if (element) { + elements.push([ + ...sparse_commas, + ...handle(element, { + ...state, + indent: state.indent + '\t', + }), + ]); + sparse_commas = []; + } else { + sparse_commas.push(c(',')); + } + } - return [ - c('('), - ...join(expressions, c(', ')), - c(')') - ]; - }, + const multiple_lines = elements.some(has_newline) || elements.map(get_length).reduce(sum, 0) + (state.indent.length + elements.length - 1) * 2 > 80; - UnaryExpression(node, state) { - const chunks = [c(node.operator)]; + if (multiple_lines) { + chunks.push(c(`\n${state.indent}\t`), ...join(elements, c(`,\n${state.indent}\t`)), c(`\n${state.indent}`), ...sparse_commas); + } else { + chunks.push(...join(elements, c(', ')), ...sparse_commas); + } - if (node.operator.length > 1) { - chunks.push(c(' ')); - } + chunks.push(c(']')); - if ( - EXPRESSIONS_PRECEDENCE[node.argument.type] < - EXPRESSIONS_PRECEDENCE.UnaryExpression - ) { - chunks.push( - c('('), - ...handle(node.argument, state), - c(')') - ); - } else { - chunks.push(...handle(node.argument, state)); - } + return chunks; + }, - return chunks; - }, - - UpdateExpression(node, state) { - return node.prefix - ? [c(node.operator), ...handle(node.argument, state)] - : [...handle(node.argument, state), c(node.operator)]; - }, - - AssignmentExpression(node, state) { - return [ - ...handle(node.left, state), - c(` ${node.operator || '='} `), - ...handle(node.right, state) - ]; - }, - - BinaryExpression(node, state) { - const chunks = []; - - // TODO - // const is_in = node.operator === 'in'; - // if (is_in) { - // // Avoids confusion in `for` loops initializers - // chunks.push(c('(')); - // } - - if (needs_parens(node.left, node, false)) { - chunks.push( - c('('), - ...handle(node.left, state), - c(')') - ); - } else { - chunks.push(...handle(node.left, state)); - } + ObjectExpression(node, state) { + if (node.properties.length === 0) { + return [c('{}')]; + } - chunks.push(c(` ${node.operator} `)); + let has_inline_comment = false; - if (needs_parens(node.right, node, true)) { - chunks.push( - c('('), - ...handle(node.right, state), - c(')') - ); - } else { - chunks.push(...handle(node.right, state)); - } + const chunks = []; + const separator = c(', '); - return chunks; - }, - - ConditionalExpression(node, state) { - const chunks = []; - - if ( - EXPRESSIONS_PRECEDENCE[node.test.type] > - EXPRESSIONS_PRECEDENCE.ConditionalExpression - ) { - chunks.push(...handle(node.test, state)); - } else { - chunks.push( - c('('), - ...handle(node.test, state), - c(')') - ); - } + node.properties.forEach((p, i) => { + chunks.push( + ...handle(p, { + ...state, + indent: state.indent + '\t', + }) + ); - const child_state = { ...state, indent: state.indent + '\t' }; - - const consequent = handle(node.consequent, child_state); - const alternate = handle(node.alternate, child_state); - - const multiple_lines = ( - has_newline(consequent) || has_newline(alternate) || - get_length(chunks) + get_length(consequent) + get_length(alternate) > 50 - ); - - if (multiple_lines) { - chunks.push( - c(`\n${state.indent}? `), - ...consequent, - c(`\n${state.indent}: `), - ...alternate - ); - } else { - chunks.push( - c(` ? `), - ...consequent, - c(` : `), - ...alternate - ); - } + if (state.comments.length) { + // TODO generalise this, so it works with ArrayExpressions and other things. + // At present, stuff will just get appended to the closest statement/declaration + chunks.push(c(', ')); - return chunks; - }, - - NewExpression(node, state) { - const chunks = [c('new ')]; - - if ( - EXPRESSIONS_PRECEDENCE[node.callee.type] < - EXPRESSIONS_PRECEDENCE.CallExpression || has_call_expression(node.callee) - ) { - chunks.push( - c('('), - ...handle(node.callee, state), - c(')') - ); - } else { - chunks.push(...handle(node.callee, state)); - } + while (state.comments.length) { + const comment = state.comments.shift(); - // TODO this is copied from CallExpression — DRY it out - const args = node.arguments.map(arg => handle(arg, { - ...state, - indent: state.indent + '\t' - })); - - const separator = args.some(has_newline) // TODO or length exceeds 80 - ? c(',\n' + state.indent) - : c(', '); - - chunks.push( - c('('), - ...join(args, separator) , - c(')') - ); - - return chunks; - }, - - ChainExpression(node, state) { - return handle(node.expression, state); - }, - - CallExpression(node, state) { - const chunks = []; - - if ( - EXPRESSIONS_PRECEDENCE[node.callee.type] < - EXPRESSIONS_PRECEDENCE.CallExpression - ) { - chunks.push( - c('('), - ...handle(node.callee, state), - c(')') - ); - } else { - chunks.push(...handle(node.callee, state)); - } + chunks.push(c(comment.type === 'Block' ? `/*${comment.value}*/\n${state.indent}\t` : `//${comment.value}\n${state.indent}\t`)); - if ((node ).optional) { - chunks.push(c('?.')); - } + if (comment.type === 'Line') { + has_inline_comment = true; + } + } + } else { + if (i < node.properties.length - 1) { + chunks.push(separator); + } + } + }); - const args = node.arguments.map(arg => handle(arg, state)); - - const multiple_lines = args.slice(0, -1).some(has_newline); // TODO or length exceeds 80 - - if (multiple_lines) { - // need to handle args again. TODO find alternative approach? - const args = node.arguments.map(arg => handle(arg, { - ...state, - indent: `${state.indent}\t` - })); - - chunks.push( - c(`(\n${state.indent}\t`), - ...join(args, c(`,\n${state.indent}\t`)), - c(`\n${state.indent})`) - ); - } else { - chunks.push( - c('('), - ...join(args, c(', ')), - c(')') - ); - } + const multiple_lines = has_inline_comment || has_newline(chunks) || get_length(chunks) > 40; - return chunks; - }, + if (multiple_lines) { + separator.content = `,\n${state.indent}\t`; + } - MemberExpression(node, state) { - const chunks = []; + return [c(multiple_lines ? `{\n${state.indent}\t` : `{ `), ...chunks, c(multiple_lines ? `\n${state.indent}}` : ` }`)]; + }, - if (EXPRESSIONS_PRECEDENCE[node.object.type] < EXPRESSIONS_PRECEDENCE.MemberExpression) { - chunks.push( - c('('), - ...handle(node.object, state), - c(')') - ); - } else { - chunks.push(...handle(node.object, state)); - } + Property(node, state) { + const value = handle(node.value, state); - if (node.computed) { - if (node.optional) { - chunks.push(c('?.')); - } - chunks.push( - c('['), - ...handle(node.property, state), - c(']') - ); - } else { - chunks.push( - c(node.optional ? '?.' : '.'), - ...handle(node.property, state) - ); - } + if (node.key === node.value) { + return value; + } - return chunks; - }, + // special case + if (!node.computed && node.value.type === 'AssignmentPattern' && node.value.left.type === 'Identifier' && node.value.left.name === node.key.name) { + return value; + } - MetaProperty(node, state) { - return [...handle(node.meta, state), c('.'), ...handle(node.property, state)]; - }, + if ( + node.value.type === 'Identifier' && + ((node.key.type === 'Identifier' && node.key.name === value[0].content) || (node.key.type === 'Literal' && node.key.value === value[0].content)) + ) { + return value; + } - Identifier(node, state) { - let name = node.name; + const key = handle(node.key, state); - if (name[0] === '@') { - name = state.getName(name.slice(1)); - } else if (node.name[0] === '#') { - const owner = state.scope.find_owner(node.name); + if (node.value.type === 'FunctionExpression' && !node.value.id) { + state = { + ...state, + scope: state.scope_map.get(node.value), + }; - if (!owner) { - throw new Error(`Could not find owner for node`); - } + const chunks = node.kind !== 'init' ? [c(`${node.kind} `)] : []; - if (!state.deconflicted.has(owner)) { - state.deconflicted.set(owner, new Map()); - } + if (node.value.async) { + chunks.push(c('async ')); + } + if (node.value.generator) { + chunks.push(c('*')); + } - const deconflict_map = state.deconflicted.get(owner); + chunks.push( + ...(node.computed ? [c('['), ...key, c(']')] : key), + c('('), + ...join( + node.value.params.map((param) => handle(param, state)), + c(', ') + ), + c(') '), + ...handle(node.value.body, state) + ); + + return chunks; + } - if (!deconflict_map.has(node.name)) { - deconflict_map.set(node.name, deconflict(node.name.slice(1), owner.references)); - } + if (node.computed) { + return [c('['), ...key, c(']: '), ...value]; + } - name = deconflict_map.get(node.name); - } + return [...key, c(': '), ...value]; + }, - return [c(name, node)]; - }, - - Literal(node, state) { - if (typeof node.value === 'string') { - return [ - // TODO do we need to handle weird unicode characters somehow? - // str.replace(/\\u(\d{4})/g, (m, n) => String.fromCharCode(+n)) - c(JSON.stringify(node.value).replace(re, (_m, _i, at, hash, name) => { - if (at) return '@' + name; - if (hash) return '#' + name; - throw new Error(`this shouldn't happen`); - }), node) - ]; - } + ObjectPattern(node, state) { + const chunks = [c('{ ')]; - const { regex } = node ; // TODO is this right? - if (regex) { - return [c(`/${regex.pattern}/${regex.flags}`, node)]; - } + for (let i = 0; i < node.properties.length; i += 1) { + chunks.push(...handle(node.properties[i], state)); + if (i < node.properties.length - 1) chunks.push(c(', ')); + } + + chunks.push(c(' }')); + + return chunks; + }, + + SequenceExpression(node, state) { + const expressions = node.expressions.map((e) => handle(e, state)); + + return [c('('), ...join(expressions, c(', ')), c(')')]; + }, + + UnaryExpression(node, state) { + const chunks = [c(node.operator)]; + + if (node.operator.length > 1) { + chunks.push(c(' ')); + } + + if (EXPRESSIONS_PRECEDENCE[node.argument.type] < EXPRESSIONS_PRECEDENCE.UnaryExpression) { + chunks.push(c('('), ...handle(node.argument, state), c(')')); + } else { + chunks.push(...handle(node.argument, state)); + } + + return chunks; + }, + + UpdateExpression(node, state) { + return node.prefix ? [c(node.operator), ...handle(node.argument, state)] : [...handle(node.argument, state), c(node.operator)]; + }, + + AssignmentExpression(node, state) { + return [...handle(node.left, state), c(` ${node.operator || '='} `), ...handle(node.right, state)]; + }, + + BinaryExpression(node, state) { + const chunks = []; + + // TODO + // const is_in = node.operator === 'in'; + // if (is_in) { + // // Avoids confusion in `for` loops initializers + // chunks.push(c('(')); + // } + + if (needs_parens(node.left, node, false)) { + chunks.push(c('('), ...handle(node.left, state), c(')')); + } else { + chunks.push(...handle(node.left, state)); + } + + chunks.push(c(` ${node.operator} `)); + + if (needs_parens(node.right, node, true)) { + chunks.push(c('('), ...handle(node.right, state), c(')')); + } else { + chunks.push(...handle(node.right, state)); + } + + return chunks; + }, + + ConditionalExpression(node, state) { + const chunks = []; + + if (EXPRESSIONS_PRECEDENCE[node.test.type] > EXPRESSIONS_PRECEDENCE.ConditionalExpression) { + chunks.push(...handle(node.test, state)); + } else { + chunks.push(c('('), ...handle(node.test, state), c(')')); + } + + const child_state = { ...state, indent: state.indent + '\t' }; + + const consequent = handle(node.consequent, child_state); + const alternate = handle(node.alternate, child_state); + + const multiple_lines = has_newline(consequent) || has_newline(alternate) || get_length(chunks) + get_length(consequent) + get_length(alternate) > 50; + + if (multiple_lines) { + chunks.push(c(`\n${state.indent}? `), ...consequent, c(`\n${state.indent}: `), ...alternate); + } else { + chunks.push(c(` ? `), ...consequent, c(` : `), ...alternate); + } + + return chunks; + }, + + NewExpression(node, state) { + const chunks = [c('new ')]; + + if (EXPRESSIONS_PRECEDENCE[node.callee.type] < EXPRESSIONS_PRECEDENCE.CallExpression || has_call_expression(node.callee)) { + chunks.push(c('('), ...handle(node.callee, state), c(')')); + } else { + chunks.push(...handle(node.callee, state)); + } + + // TODO this is copied from CallExpression — DRY it out + const args = node.arguments.map((arg) => + handle(arg, { + ...state, + indent: state.indent + '\t', + }) + ); + + const separator = args.some(has_newline) // TODO or length exceeds 80 + ? c(',\n' + state.indent) + : c(', '); + + chunks.push(c('('), ...join(args, separator), c(')')); + + return chunks; + }, + + ChainExpression(node, state) { + return handle(node.expression, state); + }, + + CallExpression(node, state) { + const chunks = []; + + if (EXPRESSIONS_PRECEDENCE[node.callee.type] < EXPRESSIONS_PRECEDENCE.CallExpression) { + chunks.push(c('('), ...handle(node.callee, state), c(')')); + } else { + chunks.push(...handle(node.callee, state)); + } + + if (node.optional) { + chunks.push(c('?.')); + } + + const args = node.arguments.map((arg) => handle(arg, state)); + + const multiple_lines = args.slice(0, -1).some(has_newline); // TODO or length exceeds 80 + + if (multiple_lines) { + // need to handle args again. TODO find alternative approach? + const args = node.arguments.map((arg) => + handle(arg, { + ...state, + indent: `${state.indent}\t`, + }) + ); + + chunks.push(c(`(\n${state.indent}\t`), ...join(args, c(`,\n${state.indent}\t`)), c(`\n${state.indent})`)); + } else { + chunks.push(c('('), ...join(args, c(', ')), c(')')); + } + + return chunks; + }, + + MemberExpression(node, state) { + const chunks = []; - return [c(String(node.value), node)]; - } + if (EXPRESSIONS_PRECEDENCE[node.object.type] < EXPRESSIONS_PRECEDENCE.MemberExpression) { + chunks.push(c('('), ...handle(node.object, state), c(')')); + } else { + chunks.push(...handle(node.object, state)); + } + + if (node.computed) { + if (node.optional) { + chunks.push(c('?.')); + } + chunks.push(c('['), ...handle(node.property, state), c(']')); + } else { + chunks.push(c(node.optional ? '?.' : '.'), ...handle(node.property, state)); + } + + return chunks; + }, + + MetaProperty(node, state) { + return [...handle(node.meta, state), c('.'), ...handle(node.property, state)]; + }, + + Identifier(node, state) { + let name = node.name; + + if (name[0] === '@') { + name = state.getName(name.slice(1)); + } else if (node.name[0] === '#') { + const owner = state.scope.find_owner(node.name); + + if (!owner) { + throw new Error(`Could not find owner for node`); + } + + if (!state.deconflicted.has(owner)) { + state.deconflicted.set(owner, new Map()); + } + + const deconflict_map = state.deconflicted.get(owner); + + if (!deconflict_map.has(node.name)) { + deconflict_map.set(node.name, deconflict(node.name.slice(1), owner.references)); + } + + name = deconflict_map.get(node.name); + } + + return [c(name, node)]; + }, + + Literal(node, state) { + if (typeof node.value === 'string') { + return [ + // TODO do we need to handle weird unicode characters somehow? + // str.replace(/\\u(\d{4})/g, (m, n) => String.fromCharCode(+n)) + c( + JSON.stringify(node.value).replace(re, (_m, _i, at, hash, name) => { + if (at) return '@' + name; + if (hash) return '#' + name; + throw new Error(`this shouldn't happen`); + }), + node + ), + ]; + } + + const { regex } = node; // TODO is this right? + if (regex) { + return [c(`/${regex.pattern}/${regex.flags}`, node)]; + } + + return [c(String(node.value), node)]; + }, }; handlers.ForOfStatement = handlers.ForInStatement; @@ -6897,713 +6630,673 @@ handlers.LogicalExpression = handlers.BinaryExpression; handlers.AssignmentPattern = handlers.AssignmentExpression; let btoa$1 = () => { - throw new Error('Unsupported environment: `window.btoa` or `Buffer` should be supported.'); + throw new Error('Unsupported environment: `window.btoa` or `Buffer` should be supported.'); }; if (typeof window !== 'undefined' && typeof window.btoa === 'function') { - btoa$1 = (str) => window.btoa(unescape(encodeURIComponent(str))); + btoa$1 = (str) => window.btoa(unescape(encodeURIComponent(str))); } else if (typeof Buffer === 'function') { - btoa$1 = (str) => Buffer.from(str, 'utf-8').toString('base64'); + btoa$1 = (str) => Buffer.from(str, 'utf-8').toString('base64'); } +function print(node, opts = {}) { + if (Array.isArray(node)) { + return print( + { + type: 'Program', + body: node, + }, + opts + ); + } + const { + getName = (x) => { + throw new Error(`Unhandled sigil @${x}`); + }, + } = opts; + + let { map: scope_map, scope } = analyze(node); + const deconflicted = new WeakMap(); + + const chunks = handle(node, { + indent: '', + getName, + scope, + scope_map, + deconflicted, + comments: [], + }); + + let code = ''; + let mappings = []; + let current_line = []; + let current_column = 0; + + for (let i = 0; i < chunks.length; i += 1) { + const chunk = chunks[i]; + + code += chunk.content; + + if (chunk.loc) { + current_line.push([ + current_column, + 0, // source index is always zero + chunk.loc.start.line - 1, + chunk.loc.start.column, + ]); + } + for (let i = 0; i < chunk.content.length; i += 1) { + if (chunk.content[i] === '\n') { + mappings.push(current_line); + current_line = []; + current_column = 0; + } else { + current_column += 1; + } + } + if (chunk.loc) { + current_line.push([ + current_column, + 0, // source index is always zero + chunk.loc.end.line - 1, + chunk.loc.end.column, + ]); + } + } + mappings.push(current_line); + const map = { + version: 3, + names: [], + sources: [opts.sourceMapSource || null], + sourcesContent: [opts.sourceMapContent || null], + mappings: encode(mappings), + }; - -function print(node, opts = {}) { - if (Array.isArray(node)) { - return print({ - type: 'Program', - body: node - } , opts); - } - - const { - getName = (x) => { - throw new Error(`Unhandled sigil @${x}`); - } - } = opts; - - let { map: scope_map, scope } = analyze(node); - const deconflicted = new WeakMap(); - - const chunks = handle(node, { - indent: '', - getName, - scope, - scope_map, - deconflicted, - comments: [] - }); - - - - let code = ''; - let mappings = []; - let current_line = []; - let current_column = 0; - - for (let i = 0; i < chunks.length; i += 1) { - const chunk = chunks[i]; - - code += chunk.content; - - if (chunk.loc) { - current_line.push([ - current_column, - 0, // source index is always zero - chunk.loc.start.line - 1, - chunk.loc.start.column, - ]); - } - - for (let i = 0; i < chunk.content.length; i += 1) { - if (chunk.content[i] === '\n') { - mappings.push(current_line); - current_line = []; - current_column = 0; - } else { - current_column += 1; - } - } - - if (chunk.loc) { - current_line.push([ - current_column, - 0, // source index is always zero - chunk.loc.end.line - 1, - chunk.loc.end.column, - ]); - } - } - - mappings.push(current_line); - - const map = { - version: 3, - names: [] , - sources: [opts.sourceMapSource || null], - sourcesContent: [opts.sourceMapContent || null], - mappings: encode(mappings) - }; - - Object.defineProperties(map, { - toString: { - enumerable: false, - value: function toString() { - return JSON.stringify(this); - } - }, - toUrl: { - enumerable: false, - value: function toUrl() { - return 'data:application/json;charset=utf-8;base64,' + btoa$1(this.toString()); - } - } - }); - - return { - code, - map - }; + Object.defineProperties(map, { + toString: { + enumerable: false, + value: function toString() { + return JSON.stringify(this); + }, + }, + toUrl: { + enumerable: false, + value: function toUrl() { + return 'data:application/json;charset=utf-8;base64,' + btoa$1(this.toString()); + }, + }, + }); + + return { + code, + map, + }; } const sigils = { - '@': 'AT', - '#': 'HASH' + '@': 'AT', + '#': 'HASH', }; const join$1 = (strings) => { - let str = strings[0]; - for (let i = 1; i < strings.length; i += 1) { - str += `_${id}_${i - 1}_${strings[i]}`; - } - return str.replace(/([@#])(\w+)/g, (_m, sigil, name) => `_${id}_${sigils[sigil]}_${name}`); + let str = strings[0]; + for (let i = 1; i < strings.length; i += 1) { + str += `_${id}_${i - 1}_${strings[i]}`; + } + return str.replace(/([@#])(\w+)/g, (_m, sigil, name) => `_${id}_${sigils[sigil]}_${name}`); }; const flatten_body = (array, target) => { - for (let i = 0; i < array.length; i += 1) { - const statement = array[i]; - if (Array.isArray(statement)) { - flatten_body(statement, target); - continue; - } + for (let i = 0; i < array.length; i += 1) { + const statement = array[i]; + if (Array.isArray(statement)) { + flatten_body(statement, target); + continue; + } - if (statement.type === 'ExpressionStatement') { - if (statement.expression === EMPTY) continue; + if (statement.type === 'ExpressionStatement') { + if (statement.expression === EMPTY) continue; - if (Array.isArray(statement.expression)) { - // TODO this is hacktacular - let node = statement.expression[0]; - while (Array.isArray(node)) node = node[0]; - if (node) node.leadingComments = statement.leadingComments; + if (Array.isArray(statement.expression)) { + // TODO this is hacktacular + let node = statement.expression[0]; + while (Array.isArray(node)) node = node[0]; + if (node) node.leadingComments = statement.leadingComments; - flatten_body(statement.expression, target); - continue; - } + flatten_body(statement.expression, target); + continue; + } - if (/(Expression|Literal)$/.test(statement.expression.type)) { - target.push(statement); - continue; - } + if (/(Expression|Literal)$/.test(statement.expression.type)) { + target.push(statement); + continue; + } - if (statement.leadingComments) statement.expression.leadingComments = statement.leadingComments; - if (statement.trailingComments) statement.expression.trailingComments = statement.trailingComments; + if (statement.leadingComments) statement.expression.leadingComments = statement.leadingComments; + if (statement.trailingComments) statement.expression.trailingComments = statement.trailingComments; - target.push(statement.expression); - continue; - } + target.push(statement.expression); + continue; + } - target.push(statement); - } + target.push(statement); + } - return target; + return target; }; const flatten_properties = (array, target) => { - for (let i = 0; i < array.length; i += 1) { - const property = array[i]; + for (let i = 0; i < array.length; i += 1) { + const property = array[i]; - if (property.value === EMPTY) continue; + if (property.value === EMPTY) continue; - if (property.key === property.value && Array.isArray(property.key)) { - flatten_properties(property.key, target); - continue; - } + if (property.key === property.value && Array.isArray(property.key)) { + flatten_properties(property.key, target); + continue; + } - target.push(property); - } + target.push(property); + } - return target; + return target; }; const flatten = (nodes, target) => { - for (let i = 0; i < nodes.length; i += 1) { - const node = nodes[i]; + for (let i = 0; i < nodes.length; i += 1) { + const node = nodes[i]; - if (node === EMPTY) continue; + if (node === EMPTY) continue; - if (Array.isArray(node)) { - flatten(node, target); - continue; - } + if (Array.isArray(node)) { + flatten(node, target); + continue; + } - target.push(node); - } + target.push(node); + } - return target; + return target; }; const EMPTY = { type: 'Empty' }; const acorn_opts = (comments, raw) => { - const { onComment } = get_comment_handlers(comments, raw); - return { - ecmaVersion: 2020, - sourceType: 'module', - allowAwaitOutsideFunction: true, - allowImportExportEverywhere: true, - allowReturnOutsideFunction: true, - onComment - } ; + const { onComment } = get_comment_handlers(comments, raw); + return { + ecmaVersion: 2020, + sourceType: 'module', + allowAwaitOutsideFunction: true, + allowImportExportEverywhere: true, + allowReturnOutsideFunction: true, + onComment, + }; }; const inject = (raw, node, values, comments) => { - comments.forEach(comment => { - comment.value = comment.value.replace(re, (m, i) => +i in values ? values[+i] : m); - }); + comments.forEach((comment) => { + comment.value = comment.value.replace(re, (m, i) => (+i in values ? values[+i] : m)); + }); - const { enter, leave } = get_comment_handlers(comments, raw); + const { enter, leave } = get_comment_handlers(comments, raw); - walk(node, { - enter, + walk(node, { + enter, - leave(node, parent, key, index) { - if (node.type === 'Identifier') { - re.lastIndex = 0; - const match = re.exec(node.name); + leave(node, parent, key, index) { + if (node.type === 'Identifier') { + re.lastIndex = 0; + const match = re.exec(node.name); - if (match) { - if (match[1]) { - if (+match[1] in values) { - let value = values[+match[1]]; + if (match) { + if (match[1]) { + if (+match[1] in values) { + let value = values[+match[1]]; - if (typeof value === 'string') { - value = { type: 'Identifier', name: value, leadingComments: node.leadingComments, trailingComments: node.trailingComments }; - } else if (typeof value === 'number') { - value = { type: 'Literal', value, leadingComments: node.leadingComments, trailingComments: node.trailingComments }; - } + if (typeof value === 'string') { + value = { type: 'Identifier', name: value, leadingComments: node.leadingComments, trailingComments: node.trailingComments }; + } else if (typeof value === 'number') { + value = { type: 'Literal', value, leadingComments: node.leadingComments, trailingComments: node.trailingComments }; + } - this.replace(value || EMPTY); - } - } else { - node.name = `${match[2] ? `@` : `#`}${match[4]}`; - } - } - } + this.replace(value || EMPTY); + } + } else { + node.name = `${match[2] ? `@` : `#`}${match[4]}`; + } + } + } - if (node.type === 'Literal') { - if (typeof node.value === 'string') { - re.lastIndex = 0; - node.value = node.value.replace(re, (m, i) => +i in values ? values[+i] : m); - } - } + if (node.type === 'Literal') { + if (typeof node.value === 'string') { + re.lastIndex = 0; + node.value = node.value.replace(re, (m, i) => (+i in values ? values[+i] : m)); + } + } - if (node.type === 'TemplateElement') { - re.lastIndex = 0; - node.value.raw = (node.value.raw ).replace(re, (m, i) => +i in values ? values[+i] : m); - } + if (node.type === 'TemplateElement') { + re.lastIndex = 0; + node.value.raw = node.value.raw.replace(re, (m, i) => (+i in values ? values[+i] : m)); + } - if (node.type === 'Program' || node.type === 'BlockStatement') { - node.body = flatten_body(node.body, []); - } + if (node.type === 'Program' || node.type === 'BlockStatement') { + node.body = flatten_body(node.body, []); + } - if (node.type === 'ObjectExpression' || node.type === 'ObjectPattern') { - node.properties = flatten_properties(node.properties, []); - } + if (node.type === 'ObjectExpression' || node.type === 'ObjectPattern') { + node.properties = flatten_properties(node.properties, []); + } - if (node.type === 'ArrayExpression' || node.type === 'ArrayPattern') { - node.elements = flatten(node.elements, []); - } + if (node.type === 'ArrayExpression' || node.type === 'ArrayPattern') { + node.elements = flatten(node.elements, []); + } - if (node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration' || node.type === 'ArrowFunctionExpression') { - node.params = flatten(node.params, []); - } + if (node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration' || node.type === 'ArrowFunctionExpression') { + node.params = flatten(node.params, []); + } - if (node.type === 'CallExpression' || node.type === 'NewExpression') { - node.arguments = flatten(node.arguments, []); - } + if (node.type === 'CallExpression' || node.type === 'NewExpression') { + node.arguments = flatten(node.arguments, []); + } - if (node.type === 'ImportDeclaration' || node.type === 'ExportNamedDeclaration') { - node.specifiers = flatten(node.specifiers, []); - } + if (node.type === 'ImportDeclaration' || node.type === 'ExportNamedDeclaration') { + node.specifiers = flatten(node.specifiers, []); + } - if (node.type === 'ForStatement') { - node.init = node.init === EMPTY ? null : node.init; - node.test = node.test === EMPTY ? null : node.test; - node.update = node.update === EMPTY ? null : node.update; - } + if (node.type === 'ForStatement') { + node.init = node.init === EMPTY ? null : node.init; + node.test = node.test === EMPTY ? null : node.test; + node.update = node.update === EMPTY ? null : node.update; + } - leave(node); - } - }); + leave(node); + }, + }); }; function b(strings, ...values) { - const str = join$1(strings); - const comments = []; + const str = join$1(strings); + const comments = []; - try { - const ast = parse$3(str, acorn_opts(comments, str)); + try { + const ast = parse$3(str, acorn_opts(comments, str)); - inject(str, ast, values, comments); + inject(str, ast, values, comments); - return ast.body; - } catch (err) { - handle_error(str, err); - } + return ast.body; + } catch (err) { + handle_error(str, err); + } } function x(strings, ...values) { - const str = join$1(strings); - const comments = []; - - try { - const expression = parseExpressionAt(str, 0, acorn_opts(comments, str)) ; - const match = /\S+/.exec(str.slice((expression ).end)); - if (match) { - throw new Error(`Unexpected token '${match[0]}'`); - } + const str = join$1(strings); + const comments = []; + + try { + const expression = parseExpressionAt(str, 0, acorn_opts(comments, str)); + const match = /\S+/.exec(str.slice(expression.end)); + if (match) { + throw new Error(`Unexpected token '${match[0]}'`); + } - inject(str, expression, values, comments); + inject(str, expression, values, comments); - return expression; - } catch (err) { - handle_error(str, err); - } + return expression; + } catch (err) { + handle_error(str, err); + } } function p(strings, ...values) { - const str = `{${join$1(strings)}}`; - const comments = []; + const str = `{${join$1(strings)}}`; + const comments = []; - try { - const expression = parseExpressionAt(str, 0, acorn_opts(comments, str)) ; + try { + const expression = parseExpressionAt(str, 0, acorn_opts(comments, str)); - inject(str, expression, values, comments); + inject(str, expression, values, comments); - return expression.properties[0]; - } catch (err) { - handle_error(str, err); - } + return expression.properties[0]; + } catch (err) { + handle_error(str, err); + } } function handle_error(str, err) { - // TODO location/code frame + // TODO location/code frame - re.lastIndex = 0; + re.lastIndex = 0; - str = str.replace(re, (m, i, at, hash, name) => { - if (at) return `@${name}`; - if (hash) return `#${name}`; + str = str.replace(re, (m, i, at, hash, name) => { + if (at) return `@${name}`; + if (hash) return `#${name}`; - return '${...}'; - }); + return '${...}'; + }); - console.log(`failed to parse:\n${str}`); - throw err; + console.log(`failed to parse:\n${str}`); + throw err; } function is_head(node) { - return node && node.type === 'MemberExpression' && node.object.name === '@_document' && node.property.name === 'head'; + return node && node.type === 'MemberExpression' && node.object.name === '@_document' && node.property.name === 'head'; } class Block { - - - - - - - - - - - - __init() {this.dependencies = new Set();} - - - __init2() {this.binding_group_initialised = new Set();} - - - - - - - - - - - - - + __init() { + this.dependencies = new Set(); + } + __init2() { + this.binding_group_initialised = new Set(); + } + __init3() { + this.event_listeners = []; + } + // could have the method without the transition, due to siblings - __init3() {this.event_listeners = [];} + __init4() { + this.variables = new Map(); + } - - - - - // could have the method without the transition, due to siblings - - + __init5() { + this.has_update_method = false; + } - - __init4() {this.variables = new Map();} - + constructor(options) { + Block.prototype.__init.call(this); + Block.prototype.__init2.call(this); + Block.prototype.__init3.call(this); + Block.prototype.__init4.call(this); + Block.prototype.__init5.call(this); + this.parent = options.parent; + this.renderer = options.renderer; + this.name = options.name; + this.type = options.type; + this.comment = options.comment; + + this.wrappers = []; + + // for keyed each blocks + this.key = options.key; + this.first = null; + + this.bindings = options.bindings; + + this.chunks = { + declarations: [], + init: [], + create: [], + claim: [], + hydrate: [], + mount: [], + measure: [], + fix: [], + animate: [], + intro: [], + update: [], + outro: [], + destroy: [], + }; - __init5() {this.has_update_method = false;} - + this.has_animation = false; + this.has_intro_method = false; // a block could have an intro method but not intro transitions, e.g. if a sibling block has intros + this.has_outro_method = false; + this.outros = 0; - constructor(options) {Block.prototype.__init.call(this);Block.prototype.__init2.call(this);Block.prototype.__init3.call(this);Block.prototype.__init4.call(this);Block.prototype.__init5.call(this); - this.parent = options.parent; - this.renderer = options.renderer; - this.name = options.name; - this.type = options.type; - this.comment = options.comment; + this.get_unique_name = this.renderer.component.get_unique_name_maker(); - this.wrappers = []; + this.aliases = new Map(); + if (this.key) this.aliases.set('key', this.get_unique_name('key')); + } - // for keyed each blocks - this.key = options.key; - this.first = null; + assign_variable_names() { + const seen = new Set(); + const dupes = new Set(); - this.bindings = options.bindings; + let i = this.wrappers.length; - this.chunks = { - declarations: [], - init: [], - create: [], - claim: [], - hydrate: [], - mount: [], - measure: [], - fix: [], - animate: [], - intro: [], - update: [], - outro: [], - destroy: [] - }; + while (i--) { + const wrapper = this.wrappers[i]; - this.has_animation = false; - this.has_intro_method = false; // a block could have an intro method but not intro transitions, e.g. if a sibling block has intros - this.has_outro_method = false; - this.outros = 0; + if (!wrapper.var) continue; - this.get_unique_name = this.renderer.component.get_unique_name_maker(); + if (seen.has(wrapper.var.name)) { + dupes.add(wrapper.var.name); + } - this.aliases = new Map(); - if (this.key) this.aliases.set('key', this.get_unique_name('key')); - } + seen.add(wrapper.var.name); + } - assign_variable_names() { - const seen = new Set(); - const dupes = new Set(); + const counts = new Map(); + i = this.wrappers.length; - let i = this.wrappers.length; + while (i--) { + const wrapper = this.wrappers[i]; - while (i--) { - const wrapper = this.wrappers[i]; + if (!wrapper.var) continue; - if (!wrapper.var) continue; + let suffix = ''; + if (dupes.has(wrapper.var.name)) { + const i = counts.get(wrapper.var.name) || 0; + counts.set(wrapper.var.name, i + 1); + suffix = i; + } + wrapper.var.name = this.get_unique_name(wrapper.var.name + suffix).name; + } + } - if (seen.has(wrapper.var.name)) { - dupes.add(wrapper.var.name); - } + add_dependencies(dependencies) { + dependencies.forEach((dependency) => { + this.dependencies.add(dependency); + }); - seen.add(wrapper.var.name); - } + this.has_update_method = true; + if (this.parent) { + this.parent.add_dependencies(dependencies); + } + } - const counts = new Map(); - i = this.wrappers.length; + add_element(id, render_statement, claim_statement, parent_node, no_detach) { + this.add_variable(id); + this.chunks.create.push(b`${id} = ${render_statement};`); - while (i--) { - const wrapper = this.wrappers[i]; + if (this.renderer.options.hydratable) { + this.chunks.claim.push(b`${id} = ${claim_statement || render_statement};`); + } - if (!wrapper.var) continue; + if (parent_node) { + this.chunks.mount.push(b`@append(${parent_node}, ${id});`); + if (is_head(parent_node) && !no_detach) this.chunks.destroy.push(b`@detach(${id});`); + } else { + this.chunks.mount.push(b`@insert(#target, ${id}, #anchor);`); + if (!no_detach) this.chunks.destroy.push(b`if (detaching) @detach(${id});`); + } + } - let suffix = ''; - if (dupes.has(wrapper.var.name)) { - const i = counts.get(wrapper.var.name) || 0; - counts.set(wrapper.var.name, i + 1); - suffix = i; - } - wrapper.var.name = this.get_unique_name(wrapper.var.name + suffix).name; - } - } + add_intro(local) { + this.has_intros = this.has_intro_method = true; + if (!local && this.parent) this.parent.add_intro(); + } - add_dependencies(dependencies) { - dependencies.forEach(dependency => { - this.dependencies.add(dependency); - }); + add_outro(local) { + this.has_outros = this.has_outro_method = true; + this.outros += 1; + if (!local && this.parent) this.parent.add_outro(); + } - this.has_update_method = true; - if (this.parent) { - this.parent.add_dependencies(dependencies); - } - } - - add_element( - id, - render_statement, - claim_statement, - parent_node, - no_detach - ) { - this.add_variable(id); - this.chunks.create.push(b`${id} = ${render_statement};`); - - if (this.renderer.options.hydratable) { - this.chunks.claim.push(b`${id} = ${claim_statement || render_statement};`); - } + add_animation() { + this.has_animation = true; + } - if (parent_node) { - this.chunks.mount.push(b`@append(${parent_node}, ${id});`); - if (is_head(parent_node) && !no_detach) this.chunks.destroy.push(b`@detach(${id});`); - } else { - this.chunks.mount.push(b`@insert(#target, ${id}, #anchor);`); - if (!no_detach) this.chunks.destroy.push(b`if (detaching) @detach(${id});`); - } - } - - add_intro(local) { - this.has_intros = this.has_intro_method = true; - if (!local && this.parent) this.parent.add_intro(); - } - - add_outro(local) { - this.has_outros = this.has_outro_method = true; - this.outros += 1; - if (!local && this.parent) this.parent.add_outro(); - } - - add_animation() { - this.has_animation = true; - } - - add_variable(id, init) { - if (this.variables.has(id.name)) { - throw new Error( - `Variable '${id.name}' already initialised with a different value` - ); - } + add_variable(id, init) { + if (this.variables.has(id.name)) { + throw new Error(`Variable '${id.name}' already initialised with a different value`); + } - this.variables.set(id.name, { id, init }); - } + this.variables.set(id.name, { id, init }); + } - alias(name) { - if (!this.aliases.has(name)) { - this.aliases.set(name, this.get_unique_name(name)); - } + alias(name) { + if (!this.aliases.has(name)) { + this.aliases.set(name, this.get_unique_name(name)); + } - return this.aliases.get(name); - } + return this.aliases.get(name); + } - child(options) { - return new Block(Object.assign({}, this, { key: null }, options, { parent: this })); - } + child(options) { + return new Block(Object.assign({}, this, { key: null }, options, { parent: this })); + } - get_contents(key) { - const { dev } = this.renderer.options; + get_contents(key) { + const { dev } = this.renderer.options; - if (this.has_outros) { - this.add_variable({ type: 'Identifier', name: '#current' }); + if (this.has_outros) { + this.add_variable({ type: 'Identifier', name: '#current' }); - if (this.chunks.intro.length > 0) { - this.chunks.intro.push(b`#current = true;`); - this.chunks.mount.push(b`#current = true;`); - } + if (this.chunks.intro.length > 0) { + this.chunks.intro.push(b`#current = true;`); + this.chunks.mount.push(b`#current = true;`); + } - if (this.chunks.outro.length > 0) { - this.chunks.outro.push(b`#current = false;`); - } - } + if (this.chunks.outro.length > 0) { + this.chunks.outro.push(b`#current = false;`); + } + } - if (this.autofocus) { - this.chunks.mount.push(b`${this.autofocus}.focus();`); - } + if (this.autofocus) { + this.chunks.mount.push(b`${this.autofocus}.focus();`); + } - this.render_listeners(); + this.render_listeners(); - const properties = {}; + const properties = {}; - const noop = x`@noop`; + const noop = x`@noop`; - properties.key = key; + properties.key = key; - if (this.first) { - properties.first = x`null`; - this.chunks.hydrate.push(b`this.first = ${this.first};`); - } + if (this.first) { + properties.first = x`null`; + this.chunks.hydrate.push(b`this.first = ${this.first};`); + } - if (this.chunks.create.length === 0 && this.chunks.hydrate.length === 0) { - properties.create = noop; - } else { - const hydrate = this.chunks.hydrate.length > 0 && ( - this.renderer.options.hydratable - ? b`this.h();` - : this.chunks.hydrate - ); + if (this.chunks.create.length === 0 && this.chunks.hydrate.length === 0) { + properties.create = noop; + } else { + const hydrate = this.chunks.hydrate.length > 0 && (this.renderer.options.hydratable ? b`this.h();` : this.chunks.hydrate); - properties.create = x`function #create() { + properties.create = x`function #create() { ${this.chunks.create} ${hydrate} }`; - } + } - if (this.renderer.options.hydratable || this.chunks.claim.length > 0) { - if (this.chunks.claim.length === 0 && this.chunks.hydrate.length === 0) { - properties.claim = noop; - } else { - properties.claim = x`function #claim(#nodes) { + if (this.renderer.options.hydratable || this.chunks.claim.length > 0) { + if (this.chunks.claim.length === 0 && this.chunks.hydrate.length === 0) { + properties.claim = noop; + } else { + properties.claim = x`function #claim(#nodes) { ${this.chunks.claim} ${this.renderer.options.hydratable && this.chunks.hydrate.length > 0 && b`this.h();`} }`; - } - } + } + } - if (this.renderer.options.hydratable && this.chunks.hydrate.length > 0) { - properties.hydrate = x`function #hydrate() { + if (this.renderer.options.hydratable && this.chunks.hydrate.length > 0) { + properties.hydrate = x`function #hydrate() { ${this.chunks.hydrate} }`; - } + } - if (this.chunks.mount.length === 0) { - properties.mount = noop; - } else if (this.event_listeners.length === 0) { - properties.mount = x`function #mount(#target, #anchor) { + if (this.chunks.mount.length === 0) { + properties.mount = noop; + } else if (this.event_listeners.length === 0) { + properties.mount = x`function #mount(#target, #anchor) { ${this.chunks.mount} }`; - } else { - properties.mount = x`function #mount(#target, #anchor) { + } else { + properties.mount = x`function #mount(#target, #anchor) { ${this.chunks.mount} }`; - } + } - if (this.has_update_method || this.maintain_context) { - if (this.chunks.update.length === 0 && !this.maintain_context) { - properties.update = noop; - } else { - const ctx = this.maintain_context ? x`#new_ctx` : x`#ctx`; + if (this.has_update_method || this.maintain_context) { + if (this.chunks.update.length === 0 && !this.maintain_context) { + properties.update = noop; + } else { + const ctx = this.maintain_context ? x`#new_ctx` : x`#ctx`; - let dirty = { type: 'Identifier', name: '#dirty' }; - if (!this.renderer.context_overflow && !this.parent) { - dirty = { type: 'ArrayPattern', elements: [dirty] }; - } + let dirty = { type: 'Identifier', name: '#dirty' }; + if (!this.renderer.context_overflow && !this.parent) { + dirty = { type: 'ArrayPattern', elements: [dirty] }; + } - properties.update = x`function #update(${ctx}, ${dirty}) { + properties.update = x`function #update(${ctx}, ${dirty}) { ${this.maintain_context && b`#ctx = ${ctx};`} ${this.chunks.update} }`; - } - } + } + } - if (this.has_animation) { - properties.measure = x`function #measure() { + if (this.has_animation) { + properties.measure = x`function #measure() { ${this.chunks.measure} }`; - properties.fix = x`function #fix() { + properties.fix = x`function #fix() { ${this.chunks.fix} }`; - properties.animate = x`function #animate() { + properties.animate = x`function #animate() { ${this.chunks.animate} }`; - } + } - if (this.has_intro_method || this.has_outro_method) { - if (this.chunks.intro.length === 0) { - properties.intro = noop; - } else { - properties.intro = x`function #intro(#local) { + if (this.has_intro_method || this.has_outro_method) { + if (this.chunks.intro.length === 0) { + properties.intro = noop; + } else { + properties.intro = x`function #intro(#local) { ${this.has_outros && b`if (#current) return;`} ${this.chunks.intro} }`; - } + } - if (this.chunks.outro.length === 0) { - properties.outro = noop; - } else { - properties.outro = x`function #outro(#local) { + if (this.chunks.outro.length === 0) { + properties.outro = noop; + } else { + properties.outro = x`function #outro(#local) { ${this.chunks.outro} }`; - } - } + } + } - if (this.chunks.destroy.length === 0) { - properties.destroy = noop; - } else { - properties.destroy = x`function #destroy(detaching) { + if (this.chunks.destroy.length === 0) { + properties.destroy = noop; + } else { + properties.destroy = x`function #destroy(detaching) { ${this.chunks.destroy} }`; - } + } - if (!this.renderer.component.compile_options.dev) { - // allow shorthand names - for (const name in properties) { - const property = properties[name]; - if (property) property.id = null; - } - } + if (!this.renderer.component.compile_options.dev) { + // allow shorthand names + for (const name in properties) { + const property = properties[name]; + if (property) property.id = null; + } + } - const return_value = x`{ + const return_value = x`{ key: ${properties.key}, first: ${properties.first}, c: ${properties.create}, @@ -7619,21 +7312,20 @@ class Block { d: ${properties.destroy} }`; - const block = dev && this.get_unique_name('block'); + const block = dev && this.get_unique_name('block'); - const body = b` + const body = b` ${this.chunks.declarations} ${Array.from(this.variables.values()).map(({ id, init }) => { - return init - ? b`let ${id} = ${init}` - : b`let ${id}`; - })} + return init ? b`let ${id} = ${init}` : b`let ${id}`; + })} ${this.chunks.init} - ${dev - ? b` + ${ + dev + ? b` const ${block} = ${return_value}; @dispatch_dev("SvelteRegisterBlock", { block: ${block}, @@ -7643,72 +7335,72 @@ class Block { ctx: #ctx }); return ${block};` - : b` + : b` return ${return_value};` - } + } `; - return body; - } - - has_content() { - return !!this.first || - this.event_listeners.length > 0 || - this.chunks.intro.length > 0 || - this.chunks.outro.length > 0 || - this.chunks.create.length > 0 || - this.chunks.hydrate.length > 0 || - this.chunks.claim.length > 0 || - this.chunks.mount.length > 0 || - this.chunks.update.length > 0 || - this.chunks.destroy.length > 0 || - this.has_animation; - } - - render() { - const key = this.key && this.get_unique_name('key'); - - const args = [x`#ctx`]; - if (key) args.unshift(key); - - const fn = b`function ${this.name}(${args}) { + return body; + } + + has_content() { + return ( + !!this.first || + this.event_listeners.length > 0 || + this.chunks.intro.length > 0 || + this.chunks.outro.length > 0 || + this.chunks.create.length > 0 || + this.chunks.hydrate.length > 0 || + this.chunks.claim.length > 0 || + this.chunks.mount.length > 0 || + this.chunks.update.length > 0 || + this.chunks.destroy.length > 0 || + this.has_animation + ); + } + + render() { + const key = this.key && this.get_unique_name('key'); + + const args = [x`#ctx`]; + if (key) args.unshift(key); + + const fn = b`function ${this.name}(${args}) { ${this.get_contents(key)} }`; - return this.comment - ? b` + return this.comment + ? b` // ${this.comment} ${fn}` - : fn; - } + : fn; + } - render_listeners(chunk = '') { - if (this.event_listeners.length > 0) { - this.add_variable({ type: 'Identifier', name: '#mounted' }); - this.chunks.destroy.push(b`#mounted = false`); + render_listeners(chunk = '') { + if (this.event_listeners.length > 0) { + this.add_variable({ type: 'Identifier', name: '#mounted' }); + this.chunks.destroy.push(b`#mounted = false`); - const dispose = { - type: 'Identifier', - name: `#dispose${chunk}` - }; + const dispose = { + type: 'Identifier', + name: `#dispose${chunk}`, + }; - this.add_variable(dispose); + this.add_variable(dispose); - if (this.event_listeners.length === 1) { - this.chunks.mount.push( - b` + if (this.event_listeners.length === 1) { + this.chunks.mount.push( + b` if (!#mounted) { ${dispose} = ${this.event_listeners[0]}; #mounted = true; } ` - ); + ); - this.chunks.destroy.push( - b`${dispose}();` - ); - } else { - this.chunks.mount.push(b` + this.chunks.destroy.push(b`${dispose}();`); + } else { + this.chunks.mount.push(b` if (!#mounted) { ${dispose} = [ ${this.event_listeners} @@ -7717,308 +7409,234 @@ class Block { } `); - this.chunks.destroy.push( - b`@run_all(${dispose});` - ); - } - } - } + this.chunks.destroy.push(b`@run_all(${dispose});`); + } + } + } } class Wrapper { - - - - - - - - - - - - constructor( - renderer, - block, - parent, - node - ) { - this.node = node; - - // make these non-enumerable so that they can be logged sensibly - // (TODO in dev only?) - Object.defineProperties(this, { - renderer: { - value: renderer - }, - parent: { - value: parent - } - }); + constructor(renderer, block, parent, node) { + this.node = node; + + // make these non-enumerable so that they can be logged sensibly + // (TODO in dev only?) + Object.defineProperties(this, { + renderer: { + value: renderer, + }, + parent: { + value: parent, + }, + }); - this.can_use_innerhtml = !renderer.options.hydratable; - this.is_static_content = !renderer.options.hydratable; - - block.wrappers.push(this); - } - - cannot_use_innerhtml() { - 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(); - } - - get_or_create_anchor(block, parent_node, parent_nodes) { - // TODO use this in EachBlock and IfBlock — tricky because - // children need to be created first - const needs_anchor = this.next ? !this.next.is_dom_node() : !parent_node || !this.parent.is_dom_node(); - const anchor = needs_anchor - ? block.get_unique_name(`${this.var.name}_anchor`) - : (this.next && this.next.var) || { type: 'Identifier', name: 'null' }; - - if (needs_anchor) { - block.add_element( - anchor, - x`@empty()`, - parent_nodes && x`@empty()`, - parent_node - ); - } + this.can_use_innerhtml = !renderer.options.hydratable; + this.is_static_content = !renderer.options.hydratable; - return anchor; - } - - get_update_mount_node(anchor) { - return ((this.parent && this.parent.is_dom_node()) - ? this.parent.var - : x`${anchor}.parentNode`) ; - } - - is_dom_node() { - return ( - this.node.type === 'Element' || - this.node.type === 'Text' || - this.node.type === 'MustacheTag' - ); - } - - render(_block, _parent_node, _parent_nodes) { - throw Error('Wrapper class is not renderable'); - } -} - -function create_debugging_comment( - node, - component -) { - const { locate, source } = component; - - let c = node.start; - if (node.type === 'ElseBlock') { - while (source[c - 1] !== '{') c -= 1; - while (source[c - 1] === '{') c -= 1; - } - - let d; - - if (node.type === 'InlineComponent' || node.type === 'Element' || node.type === 'SlotTemplate') { - if (node.children.length) { - d = node.children[0].start; - while (source[d - 1] !== '>') d -= 1; - } else { - d = node.start; - while (source[d] !== '>') d += 1; - d += 1; - } - } else if (node.type === 'Text' || node.type === 'Comment') { - d = node.end; - } else { - // @ts-ignore - d = node.expression ? node.expression.node.end : c; - while (source[d] !== '}' && d <= source.length) d += 1; - while (source[d] === '}') d += 1; - } + block.wrappers.push(this); + } - const start = locate(c); - const loc = `(${start.line}:${start.column})`; + cannot_use_innerhtml() { + this.can_use_innerhtml = false; + if (this.parent) this.parent.cannot_use_innerhtml(); + } - return `${loc} ${source.slice(c, d)}`.replace(/\s/g, ' '); + not_static_content() { + this.is_static_content = false; + if (this.parent) this.parent.not_static_content(); + } + + get_or_create_anchor(block, parent_node, parent_nodes) { + // TODO use this in EachBlock and IfBlock — tricky because + // children need to be created first + const needs_anchor = this.next ? !this.next.is_dom_node() : !parent_node || !this.parent.is_dom_node(); + const anchor = needs_anchor ? block.get_unique_name(`${this.var.name}_anchor`) : (this.next && this.next.var) || { type: 'Identifier', name: 'null' }; + + if (needs_anchor) { + block.add_element(anchor, x`@empty()`, parent_nodes && x`@empty()`, parent_node); + } + + return anchor; + } + + get_update_mount_node(anchor) { + return this.parent && this.parent.is_dom_node() ? this.parent.var : x`${anchor}.parentNode`; + } + + is_dom_node() { + return this.node.type === 'Element' || this.node.type === 'Text' || this.node.type === 'MustacheTag'; + } + + render(_block, _parent_node, _parent_nodes) { + throw Error('Wrapper class is not renderable'); + } +} + +function create_debugging_comment(node, component) { + const { locate, source } = component; + + let c = node.start; + if (node.type === 'ElseBlock') { + while (source[c - 1] !== '{') c -= 1; + while (source[c - 1] === '{') c -= 1; + } + + let d; + + if (node.type === 'InlineComponent' || node.type === 'Element' || node.type === 'SlotTemplate') { + if (node.children.length) { + d = node.children[0].start; + while (source[d - 1] !== '>') d -= 1; + } else { + d = node.start; + while (source[d] !== '>') d += 1; + d += 1; + } + } else if (node.type === 'Text' || node.type === 'Comment') { + d = node.end; + } else { + // @ts-ignore + d = node.expression ? node.expression.node.end : c; + while (source[d] !== '}' && d <= source.length) d += 1; + while (source[d] === '}') d += 1; + } + + const start = locate(c); + const loc = `(${start.line}:${start.column})`; + + return `${loc} ${source.slice(c, d)}`.replace(/\s/g, ' '); } class AwaitBlockBranch extends Wrapper { - - - - - - - __init() {this.var = null;} - - - - - - - - constructor( - status, - renderer, - block, - parent, - node, - strip_whitespace, - next_sibling - ) { - super(renderer, block, parent, node);AwaitBlockBranch.prototype.__init.call(this); this.status = status; - - this.block = block.child({ - comment: create_debugging_comment(node, this.renderer.component), - name: this.renderer.component.get_unique_name(`create_${status}_block`), - type: status - }); + __init() { + this.var = null; + } - this.add_context(parent.node[status + '_node'], parent.node[status + '_contexts']); - - this.fragment = new FragmentWrapper( - renderer, - this.block, - this.node.children, - parent, - strip_whitespace, - next_sibling - ); - - this.is_dynamic = this.block.dependencies.size > 0; - } - - add_context(node, contexts) { - if (!node) return; - - if (node.type === 'Identifier') { - this.value = node.name; - this.renderer.add_to_context(this.value, true); - } else { - contexts.forEach(context => { - this.renderer.add_to_context(context.key.name, true); - }); - this.value = this.block.parent.get_unique_name('value').name; - this.value_contexts = contexts; - this.renderer.add_to_context(this.value, true); - this.is_destructured = true; - } - this.value_index = this.renderer.context_lookup.get(this.value).index; - } + constructor(status, renderer, block, parent, node, strip_whitespace, next_sibling) { + super(renderer, block, parent, node); + AwaitBlockBranch.prototype.__init.call(this); + this.status = status; - render(block, parent_node, parent_nodes) { - this.fragment.render(block, parent_node, parent_nodes); + this.block = block.child({ + comment: create_debugging_comment(node, this.renderer.component), + name: this.renderer.component.get_unique_name(`create_${status}_block`), + type: status, + }); - if (this.is_destructured) { - this.render_destructure(); - } - } + this.add_context(parent.node[status + '_node'], parent.node[status + '_contexts']); + + this.fragment = new FragmentWrapper(renderer, this.block, this.node.children, parent, strip_whitespace, next_sibling); + + this.is_dynamic = this.block.dependencies.size > 0; + } + + add_context(node, contexts) { + if (!node) return; + + if (node.type === 'Identifier') { + this.value = node.name; + this.renderer.add_to_context(this.value, true); + } else { + contexts.forEach((context) => { + this.renderer.add_to_context(context.key.name, true); + }); + this.value = this.block.parent.get_unique_name('value').name; + this.value_contexts = contexts; + this.renderer.add_to_context(this.value, true); + this.is_destructured = true; + } + this.value_index = this.renderer.context_lookup.get(this.value).index; + } + + render(block, parent_node, parent_nodes) { + this.fragment.render(block, parent_node, parent_nodes); + + if (this.is_destructured) { + this.render_destructure(); + } + } - render_destructure() { - const props = this.value_contexts.map(prop => b`#ctx[${this.block.renderer.context_lookup.get(prop.key.name).index}] = ${prop.default_modifier(prop.modifier(x`#ctx[${this.value_index}]`), name => this.renderer.reference(name))};`); - const get_context = this.block.renderer.component.get_unique_name(`get_${this.status}_context`); - this.block.renderer.blocks.push(b` + render_destructure() { + const props = this.value_contexts.map( + (prop) => + b`#ctx[${this.block.renderer.context_lookup.get(prop.key.name).index}] = ${prop.default_modifier(prop.modifier(x`#ctx[${this.value_index}]`), (name) => + this.renderer.reference(name) + )};` + ); + const get_context = this.block.renderer.component.get_unique_name(`get_${this.status}_context`); + this.block.renderer.blocks.push(b` function ${get_context}(#ctx) { ${props} } `); - this.block.chunks.declarations.push(b`${get_context}(#ctx)`); - if (this.block.has_update_method) { - this.block.chunks.update.unshift(b`${get_context}(#ctx)`); - } - } + this.block.chunks.declarations.push(b`${get_context}(#ctx)`); + if (this.block.has_update_method) { + this.block.chunks.update.unshift(b`${get_context}(#ctx)`); + } + } } class AwaitBlockWrapper extends Wrapper { - - - - - - - __init2() {this.var = { type: 'Identifier', name: 'await_block' };} - - constructor( - renderer, - block, - parent, - node, - strip_whitespace, - next_sibling - ) { - super(renderer, block, parent, node);AwaitBlockWrapper.prototype.__init2.call(this); - this.cannot_use_innerhtml(); - this.not_static_content(); - - block.add_dependencies(this.node.expression.dependencies); - - let is_dynamic = false; - let has_intros = false; - let has_outros = false; - - ['pending', 'then', 'catch'].forEach((status) => { - const child = this.node[status]; - - const branch = new AwaitBlockBranch( - status, - renderer, - block, - this, - child, - strip_whitespace, - next_sibling - ); - - renderer.blocks.push(branch.block); - - if (branch.is_dynamic) { - is_dynamic = true; - // TODO should blocks update their own parents? - block.add_dependencies(branch.block.dependencies); - } + __init2() { + this.var = { type: 'Identifier', name: 'await_block' }; + } - if (branch.block.has_intros) has_intros = true; - if (branch.block.has_outros) has_outros = true; + constructor(renderer, block, parent, node, strip_whitespace, next_sibling) { + super(renderer, block, parent, node); + AwaitBlockWrapper.prototype.__init2.call(this); + this.cannot_use_innerhtml(); + this.not_static_content(); - this[status] = branch; - }); + block.add_dependencies(this.node.expression.dependencies); - ['pending', 'then', 'catch'].forEach(status => { - this[status].block.has_update_method = is_dynamic; - this[status].block.has_intro_method = has_intros; - this[status].block.has_outro_method = has_outros; - }); + let is_dynamic = false; + let has_intros = false; + let has_outros = false; - if (has_outros) { - block.add_outro(); - } - } + ['pending', 'then', 'catch'].forEach((status) => { + const child = this.node[status]; - render( - block, - parent_node, - parent_nodes - ) { - const anchor = this.get_or_create_anchor(block, parent_node, parent_nodes); - const update_mount_node = this.get_update_mount_node(anchor); + const branch = new AwaitBlockBranch(status, renderer, block, this, child, strip_whitespace, next_sibling); - const snippet = this.node.expression.manipulate(block); + renderer.blocks.push(branch.block); - const info = block.get_unique_name('info'); - const promise = block.get_unique_name('promise'); + if (branch.is_dynamic) { + is_dynamic = true; + // TODO should blocks update their own parents? + block.add_dependencies(branch.block.dependencies); + } - block.add_variable(promise); + if (branch.block.has_intros) has_intros = true; + if (branch.block.has_outros) has_outros = true; - block.maintain_context = true; + this[status] = branch; + }); - const info_props = x`{ + ['pending', 'then', 'catch'].forEach((status) => { + this[status].block.has_update_method = is_dynamic; + this[status].block.has_intro_method = has_intros; + this[status].block.has_outro_method = has_outros; + }); + + if (has_outros) { + block.add_outro(); + } + } + + render(block, parent_node, parent_nodes) { + const anchor = this.get_or_create_anchor(block, parent_node, parent_nodes); + const update_mount_node = this.get_update_mount_node(anchor); + + const snippet = this.node.expression.manipulate(block); + + const info = block.get_unique_name('info'); + const promise = block.get_unique_name('promise'); + + block.add_variable(promise); + + block.maintain_context = true; + + const info_props = x`{ ctx: #ctx, current: null, token: null, @@ -8031,62 +7649,60 @@ class AwaitBlockWrapper extends Wrapper { blocks: ${this.pending.block.has_outro_method && x`[,,,]`} }`; - block.chunks.init.push(b` + block.chunks.init.push(b` let ${info} = ${info_props}; `); - block.chunks.init.push(b` + block.chunks.init.push(b` @handle_promise(${promise} = ${snippet}, ${info}); `); - block.chunks.create.push(b` + block.chunks.create.push(b` ${info}.block.c(); `); - if (parent_nodes && this.renderer.options.hydratable) { - block.chunks.claim.push(b` + if (parent_nodes && this.renderer.options.hydratable) { + block.chunks.claim.push(b` ${info}.block.l(${parent_nodes}); `); - } + } - const initial_mount_node = parent_node || '#target'; - const anchor_node = parent_node ? 'null' : '#anchor'; + const initial_mount_node = parent_node || '#target'; + const anchor_node = parent_node ? 'null' : '#anchor'; - const has_transitions = this.pending.block.has_intro_method || this.pending.block.has_outro_method; + const has_transitions = this.pending.block.has_intro_method || this.pending.block.has_outro_method; - block.chunks.mount.push(b` + block.chunks.mount.push(b` ${info}.block.m(${initial_mount_node}, ${info}.anchor = ${anchor_node}); ${info}.mount = () => ${update_mount_node}; ${info}.anchor = ${anchor}; `); - if (has_transitions) { - block.chunks.intro.push(b`@transition_in(${info}.block);`); - } + if (has_transitions) { + block.chunks.intro.push(b`@transition_in(${info}.block);`); + } - const dependencies = this.node.expression.dynamic_dependencies(); + const dependencies = this.node.expression.dynamic_dependencies(); - let update_child_context; - if (this.then.value && this.catch.value) { - update_child_context = b`#child_ctx[${this.then.value_index}] = #child_ctx[${this.catch.value_index}] = ${info}.resolved;`; - } else if (this.then.value) { - update_child_context = b`#child_ctx[${this.then.value_index}] = ${info}.resolved;`; - } else if (this.catch.value) { - update_child_context = b`#child_ctx[${this.catch.value_index}] = ${info}.resolved;`; - } + let update_child_context; + if (this.then.value && this.catch.value) { + update_child_context = b`#child_ctx[${this.then.value_index}] = #child_ctx[${this.catch.value_index}] = ${info}.resolved;`; + } else if (this.then.value) { + update_child_context = b`#child_ctx[${this.then.value_index}] = ${info}.resolved;`; + } else if (this.catch.value) { + update_child_context = b`#child_ctx[${this.catch.value_index}] = ${info}.resolved;`; + } - if (dependencies.length > 0) { - const condition = x` + if (dependencies.length > 0) { + const condition = x` ${block.renderer.dirty(dependencies)} && ${promise} !== (${promise} = ${snippet}) && @handle_promise(${promise}, ${info})`; - block.chunks.update.push( - b`${info}.ctx = #ctx;` - ); + block.chunks.update.push(b`${info}.ctx = #ctx;`); - if (this.pending.block.has_update_method) { - block.chunks.update.push(b` + if (this.pending.block.has_update_method) { + block.chunks.update.push(b` if (${condition}) { } else { @@ -8095,522 +7711,441 @@ class AwaitBlockWrapper extends Wrapper { ${info}.block.p(#child_ctx, #dirty); } `); - } else { - block.chunks.update.push(b` + } else { + block.chunks.update.push(b` ${condition} `); - } - } else { - if (this.pending.block.has_update_method) { - block.chunks.update.push(b` + } + } else { + if (this.pending.block.has_update_method) { + block.chunks.update.push(b` { const #child_ctx = #ctx.slice(); ${update_child_context} ${info}.block.p(#child_ctx, #dirty); } `); - } - } + } + } - if (this.pending.block.has_outro_method) { - block.chunks.outro.push(b` + if (this.pending.block.has_outro_method) { + block.chunks.outro.push(b` for (let #i = 0; #i < 3; #i += 1) { const block = ${info}.blocks[#i]; @transition_out(block); } `); - } + } - block.chunks.destroy.push(b` + block.chunks.destroy.push(b` ${info}.block.d(${parent_node ? null : 'detaching'}); ${info}.token = null; ${info} = null; `); - [this.pending, this.then, this.catch].forEach(branch => { - branch.render(branch.block, null, x`#nodes` ); - }); - } + [this.pending, this.then, this.catch].forEach((branch) => { + branch.render(branch.block, null, x`#nodes`); + }); + } } const TRUE = x`true`; const FALSE = x`false`; class EventHandlerWrapper { - - + constructor(node, parent) { + this.node = node; + this.parent = parent; - constructor(node, parent) { - this.node = node; - this.parent = parent; + if (!node.expression) { + this.parent.renderer.add_to_context(node.handler_name.name); - if (!node.expression) { - this.parent.renderer.add_to_context(node.handler_name.name); - - this.parent.renderer.component.partly_hoisted.push(b` + this.parent.renderer.component.partly_hoisted.push(b` function ${node.handler_name.name}(event) { @bubble($$self, event); } `); - } - } + } + } - get_snippet(block) { - const snippet = this.node.expression ? this.node.expression.manipulate(block) : block.renderer.reference(this.node.handler_name); + get_snippet(block) { + const snippet = this.node.expression ? this.node.expression.manipulate(block) : block.renderer.reference(this.node.handler_name); - if (this.node.reassigned) { - block.maintain_context = true; - return x`function () { if (@is_function(${snippet})) ${snippet}.apply(this, arguments); }`; - } - return snippet; - } - - render(block, target) { - let snippet = this.get_snippet(block); - - if (this.node.modifiers.has('preventDefault')) snippet = x`@prevent_default(${snippet})`; - if (this.node.modifiers.has('stopPropagation')) snippet = x`@stop_propagation(${snippet})`; - if (this.node.modifiers.has('self')) snippet = x`@self(${snippet})`; - - const args = []; - - const opts = ['nonpassive', 'passive', 'once', 'capture'].filter(mod => this.node.modifiers.has(mod)); - if (opts.length) { - if (opts.length === 1 && opts[0] === 'capture') { - args.push(TRUE); - } else { - args.push(x`{ ${ opts.map(opt => - opt === 'nonpassive' - ? p`passive: false` - : p`${opt}: true` - ) } }`); - } - } else if (block.renderer.options.dev) { - args.push(FALSE); - } + if (this.node.reassigned) { + block.maintain_context = true; + return x`function () { if (@is_function(${snippet})) ${snippet}.apply(this, arguments); }`; + } + return snippet; + } - if (block.renderer.options.dev) { - args.push(this.node.modifiers.has('preventDefault') ? TRUE : FALSE); - args.push(this.node.modifiers.has('stopPropagation') ? TRUE : FALSE); - } + render(block, target) { + let snippet = this.get_snippet(block); + + if (this.node.modifiers.has('preventDefault')) snippet = x`@prevent_default(${snippet})`; + if (this.node.modifiers.has('stopPropagation')) snippet = x`@stop_propagation(${snippet})`; + if (this.node.modifiers.has('self')) snippet = x`@self(${snippet})`; - block.event_listeners.push( - x`@listen(${target}, "${this.node.name}", ${snippet}, ${args})` - ); - } + const args = []; + + const opts = ['nonpassive', 'passive', 'once', 'capture'].filter((mod) => this.node.modifiers.has(mod)); + if (opts.length) { + if (opts.length === 1 && opts[0] === 'capture') { + args.push(TRUE); + } else { + args.push(x`{ ${opts.map((opt) => (opt === 'nonpassive' ? p`passive: false` : p`${opt}: true`))} }`); + } + } else if (block.renderer.options.dev) { + args.push(FALSE); + } + + if (block.renderer.options.dev) { + args.push(this.node.modifiers.has('preventDefault') ? TRUE : FALSE); + args.push(this.node.modifiers.has('stopPropagation') ? TRUE : FALSE); + } + + block.event_listeners.push(x`@listen(${target}, "${this.node.name}", ${snippet}, ${args})`); + } } -function add_event_handlers( - block, - target, - handlers -) { - handlers.forEach(handler => add_event_handler(block, target, handler)); +function add_event_handlers(block, target, handlers) { + handlers.forEach((handler) => add_event_handler(block, target, handler)); } -function add_event_handler( - block, - target, - handler -) { - handler.render(block, target); +function add_event_handler(block, target, handler) { + handler.render(block, target); } class BodyWrapper extends Wrapper { - - - - constructor(renderer, block, parent, node) { - super(renderer, block, parent, node); - this.handlers = this.node.handlers.map(handler => new EventHandlerWrapper(handler, this)); - } + constructor(renderer, block, parent, node) { + super(renderer, block, parent, node); + this.handlers = this.node.handlers.map((handler) => new EventHandlerWrapper(handler, this)); + } - render(block, _parent_node, _parent_nodes) { - add_event_handlers(block, x`@_document.body`, this.handlers); - } + render(block, _parent_node, _parent_nodes) { + add_event_handlers(block, x`@_document.body`, this.handlers); + } } function add_to_set(a, b) { - // @ts-ignore - b.forEach(item => { - a.add(item); - }); + // @ts-ignore + b.forEach((item) => { + a.add(item); + }); } class DebugTagWrapper extends Wrapper { - - - constructor( - renderer, - block, - parent, - node, - _strip_whitespace, - _next_sibling - ) { - super(renderer, block, parent, node); - } - - render(block, _parent_node, _parent_nodes) { - const { renderer } = this; - const { component } = renderer; - - if (!renderer.options.dev) return; - - const { var_lookup } = component; - - const start = component.locate(this.node.start + 1); - const end = { line: start.line, column: start.column + 6 }; - - const loc = { start, end }; - - const debug = { - type: 'DebuggerStatement', - loc - }; - - if (this.node.expressions.length === 0) { - // Debug all - block.chunks.create.push(debug); - block.chunks.update.push(debug); - } else { - const log = { - type: 'Identifier', - name: 'log', - loc - }; - - const dependencies = new Set(); - this.node.expressions.forEach(expression => { - add_to_set(dependencies, expression.dependencies); - }); + constructor(renderer, block, parent, node, _strip_whitespace, _next_sibling) { + super(renderer, block, parent, node); + } + + render(block, _parent_node, _parent_nodes) { + const { renderer } = this; + const { component } = renderer; - const contextual_identifiers = this.node.expressions - .filter(e => { - const variable = var_lookup.get((e.node ).name); - return !(variable && variable.hoistable); - }) - .map(e => (e.node ).name); + if (!renderer.options.dev) return; - const logged_identifiers = this.node.expressions.map(e => p`${(e.node ).name}`); + const { var_lookup } = component; - const debug_statements = b` - ${contextual_identifiers.map(name => b`const ${name} = ${renderer.reference(name)};`)} + const start = component.locate(this.node.start + 1); + const end = { line: start.line, column: start.column + 6 }; + + const loc = { start, end }; + + const debug = { + type: 'DebuggerStatement', + loc, + }; + + if (this.node.expressions.length === 0) { + // Debug all + block.chunks.create.push(debug); + block.chunks.update.push(debug); + } else { + const log = { + type: 'Identifier', + name: 'log', + loc, + }; + + const dependencies = new Set(); + this.node.expressions.forEach((expression) => { + add_to_set(dependencies, expression.dependencies); + }); + + const contextual_identifiers = this.node.expressions + .filter((e) => { + const variable = var_lookup.get(e.node.name); + return !(variable && variable.hoistable); + }) + .map((e) => e.node.name); + + const logged_identifiers = this.node.expressions.map((e) => p`${e.node.name}`); + + const debug_statements = b` + ${contextual_identifiers.map((name) => b`const ${name} = ${renderer.reference(name)};`)} @_console.${log}({ ${logged_identifiers} }); debugger;`; - if (dependencies.size) { - const condition = renderer.dirty(Array.from(dependencies)); + if (dependencies.size) { + const condition = renderer.dirty(Array.from(dependencies)); - block.chunks.update.push(b` + block.chunks.update.push(b` if (${condition}) { ${debug_statements} } `); - } + } - block.chunks.create.push(b`{ + block.chunks.create.push(b`{ ${debug_statements} }`); - } - } + } + } } function get_object(node) { - while (node.type === 'MemberExpression') node = node.object; - return node ; + while (node.type === 'MemberExpression') node = node.object; + return node; } class ElseBlockWrapper extends Wrapper { - - - - - - __init() {this.var = null;} - - constructor( - renderer, - block, - parent, - node, - strip_whitespace, - next_sibling - ) { - super(renderer, block, parent, node);ElseBlockWrapper.prototype.__init.call(this); - this.block = block.child({ - comment: create_debugging_comment(node, this.renderer.component), - name: this.renderer.component.get_unique_name('create_else_block'), - type: 'else' - }); + __init() { + this.var = null; + } + + constructor(renderer, block, parent, node, strip_whitespace, next_sibling) { + super(renderer, block, parent, node); + ElseBlockWrapper.prototype.__init.call(this); + this.block = block.child({ + comment: create_debugging_comment(node, this.renderer.component), + name: this.renderer.component.get_unique_name('create_else_block'), + type: 'else', + }); - this.fragment = new FragmentWrapper( - renderer, - this.block, - this.node.children, - parent, - strip_whitespace, - next_sibling - ); + this.fragment = new FragmentWrapper(renderer, this.block, this.node.children, parent, strip_whitespace, next_sibling); - this.is_dynamic = this.block.dependencies.size > 0; - } + this.is_dynamic = this.block.dependencies.size > 0; + } } class EachBlockWrapper extends Wrapper { - - - - - - - - + __init2() { + this.updates = []; + } + __init3() { + this.var = { type: 'Identifier', name: 'each' }; + } + constructor(renderer, block, parent, node, strip_whitespace, next_sibling) { + super(renderer, block, parent, node); + EachBlockWrapper.prototype.__init2.call(this); + EachBlockWrapper.prototype.__init3.call(this); + this.cannot_use_innerhtml(); + this.not_static_content(); + const { dependencies } = node.expression; + block.add_dependencies(dependencies); + this.node.contexts.forEach((context) => { + renderer.add_to_context(context.key.name, true); + }); + this.block = block.child({ + comment: create_debugging_comment(this.node, this.renderer.component), + name: renderer.component.get_unique_name('create_each_block'), + type: 'each', + // @ts-ignore todo: probably error + key: node.key, - - - __init2() {this.updates = [];} - + bindings: new Map(block.bindings), + }); - __init3() {this.var = { type: 'Identifier', name: 'each' };} + // TODO this seems messy + this.block.has_animation = this.node.has_animation; + + this.index_name = this.node.index ? { type: 'Identifier', name: this.node.index } : renderer.component.get_unique_name(`${this.node.context}_index`); + + const fixed_length = + node.expression.node.type === 'ArrayExpression' && node.expression.node.elements.every((element) => element.type !== 'SpreadElement') + ? node.expression.node.elements.length + : null; + + // hack the sourcemap, so that if data is missing the bug + // is easy to find + let c = this.node.start + 2; + while (renderer.component.source[c] !== 'e') c += 1; + const start = renderer.component.locate(c); + const end = { line: start.line, column: start.column + 4 }; + const length = { + type: 'Identifier', + name: 'length', + loc: { start, end }, + }; - constructor( - renderer, - block, - parent, - node, - strip_whitespace, - next_sibling - ) { - super(renderer, block, parent, node);EachBlockWrapper.prototype.__init2.call(this);EachBlockWrapper.prototype.__init3.call(this); this.cannot_use_innerhtml(); - this.not_static_content(); + const each_block_value = renderer.component.get_unique_name(`${this.var.name}_value`); + const iterations = block.get_unique_name(`${this.var.name}_blocks`); - const { dependencies } = node.expression; - block.add_dependencies(dependencies); + renderer.add_to_context(each_block_value.name, true); + renderer.add_to_context(this.index_name.name, true); - this.node.contexts.forEach(context => { - renderer.add_to_context(context.key.name, true); - }); + this.vars = { + create_each_block: this.block.name, + each_block_value, + get_each_context: renderer.component.get_unique_name(`get_${this.var.name}_context`), + iterations, - this.block = block.child({ - comment: create_debugging_comment(this.node, this.renderer.component), - name: renderer.component.get_unique_name('create_each_block'), - type: 'each', - // @ts-ignore todo: probably error - key: node.key , + // optimisation for array literal + fixed_length, + data_length: fixed_length === null ? x`${each_block_value}.${length}` : fixed_length, + view_length: fixed_length === null ? x`${iterations}.length` : fixed_length, + }; - bindings: new Map(block.bindings) - }); + const object = get_object(node.expression.node); + const store = object.type === 'Identifier' && object.name[0] === '$' ? object.name.slice(1) : null; + + node.contexts.forEach((prop) => { + this.block.bindings.set(prop.key.name, { + object: this.vars.each_block_value, + property: this.index_name, + modifier: prop.modifier, + snippet: prop.modifier(x`${this.vars.each_block_value}[${this.index_name}]`), + store, + }); + }); - // TODO this seems messy - this.block.has_animation = this.node.has_animation; - - this.index_name = this.node.index - ? { type: 'Identifier', name: this.node.index } - : renderer.component.get_unique_name(`${this.node.context}_index`); - - const fixed_length = - node.expression.node.type === 'ArrayExpression' && - node.expression.node.elements.every(element => element.type !== 'SpreadElement') - ? node.expression.node.elements.length - : null; - - // hack the sourcemap, so that if data is missing the bug - // is easy to find - let c = this.node.start + 2; - while (renderer.component.source[c] !== 'e') c += 1; - const start = renderer.component.locate(c); - const end = { line: start.line, column: start.column + 4 }; - const length = { - type: 'Identifier', - name: 'length', - loc: { start, end } - }; - - const each_block_value = renderer.component.get_unique_name(`${this.var.name}_value`); - const iterations = block.get_unique_name(`${this.var.name}_blocks`); - - renderer.add_to_context(each_block_value.name, true); - renderer.add_to_context(this.index_name.name, true); - - this.vars = { - create_each_block: this.block.name, - each_block_value, - get_each_context: renderer.component.get_unique_name(`get_${this.var.name}_context`), - iterations, - - // optimisation for array literal - fixed_length, - data_length: fixed_length === null ? x`${each_block_value}.${length}` : fixed_length, - view_length: fixed_length === null ? x`${iterations}.length` : fixed_length - }; - - const object = get_object(node.expression.node); - const store = object.type === 'Identifier' && object.name[0] === '$' ? object.name.slice(1) : null; - - node.contexts.forEach(prop => { - this.block.bindings.set(prop.key.name, { - object: this.vars.each_block_value, - property: this.index_name, - modifier: prop.modifier, - snippet: prop.modifier(x`${this.vars.each_block_value}[${this.index_name}]` ), - store - }); - }); + if (this.node.index) { + this.block.get_unique_name(this.node.index); // this prevents name collisions (#1254) + } - if (this.node.index) { - this.block.get_unique_name(this.node.index); // this prevents name collisions (#1254) - } + renderer.blocks.push(this.block); - renderer.blocks.push(this.block); + this.fragment = new FragmentWrapper(renderer, this.block, node.children, this, strip_whitespace, next_sibling); - this.fragment = new FragmentWrapper(renderer, this.block, node.children, this, strip_whitespace, next_sibling); + if (this.node.else) { + this.else = new ElseBlockWrapper(renderer, block, this, this.node.else, strip_whitespace, next_sibling); - if (this.node.else) { - this.else = new ElseBlockWrapper( - renderer, - block, - this, - this.node.else, - strip_whitespace, - next_sibling - ); + renderer.blocks.push(this.else.block); - renderer.blocks.push(this.else.block); + if (this.else.is_dynamic) { + this.block.add_dependencies(this.else.block.dependencies); + } + } - if (this.else.is_dynamic) { - this.block.add_dependencies(this.else.block.dependencies); - } - } + block.add_dependencies(this.block.dependencies); - block.add_dependencies(this.block.dependencies); + if (this.block.has_outros || (this.else && this.else.block.has_outros)) { + block.add_outro(); + } + } - if (this.block.has_outros || (this.else && this.else.block.has_outros)) { - block.add_outro(); - } - } + render(block, parent_node, parent_nodes) { + if (this.fragment.nodes.length === 0) return; - render(block, parent_node, parent_nodes) { - if (this.fragment.nodes.length === 0) return; + const { renderer } = this; + const { component } = renderer; - const { renderer } = this; - const { component } = renderer; + const needs_anchor = this.next ? !this.next.is_dom_node() : !parent_node || !this.parent.is_dom_node(); - const needs_anchor = this.next - ? !this.next.is_dom_node() : - !parent_node || !this.parent.is_dom_node(); + const snippet = this.node.expression.manipulate(block); - const snippet = this.node.expression.manipulate(block); + block.chunks.init.push(b`let ${this.vars.each_block_value} = ${snippet};`); + if (this.renderer.options.dev) { + block.chunks.init.push(b`@validate_each_argument(${this.vars.each_block_value});`); + } - block.chunks.init.push(b`let ${this.vars.each_block_value} = ${snippet};`); - if (this.renderer.options.dev) { - block.chunks.init.push(b`@validate_each_argument(${this.vars.each_block_value});`); - } + const initial_anchor_node = { type: 'Identifier', name: parent_node ? 'null' : '#anchor' }; + const initial_mount_node = parent_node || { type: 'Identifier', name: '#target' }; + const update_anchor_node = needs_anchor ? block.get_unique_name(`${this.var.name}_anchor`) : (this.next && this.next.var) || { type: 'Identifier', name: 'null' }; + const update_mount_node = this.get_update_mount_node(update_anchor_node); + + const args = { + block, + parent_node, + parent_nodes, + snippet, + initial_anchor_node, + initial_mount_node, + update_anchor_node, + update_mount_node, + }; - const initial_anchor_node = { type: 'Identifier', name: parent_node ? 'null' : '#anchor' }; - const initial_mount_node = parent_node || { type: 'Identifier', name: '#target' }; - const update_anchor_node = needs_anchor - ? block.get_unique_name(`${this.var.name}_anchor`) - : (this.next && this.next.var) || { type: 'Identifier', name: 'null' }; - const update_mount_node = this.get_update_mount_node((update_anchor_node )); - - const args = { - block, - parent_node, - parent_nodes, - snippet, - initial_anchor_node, - initial_mount_node, - update_anchor_node, - update_mount_node - }; - - const all_dependencies = new Set(this.block.dependencies); // TODO should be dynamic deps only - this.node.expression.dynamic_dependencies().forEach((dependency) => { - all_dependencies.add(dependency); - }); - if (this.node.key) { - this.node.key.dynamic_dependencies().forEach((dependency) => { - all_dependencies.add(dependency); - }); - } - this.dependencies = all_dependencies; + const all_dependencies = new Set(this.block.dependencies); // TODO should be dynamic deps only + this.node.expression.dynamic_dependencies().forEach((dependency) => { + all_dependencies.add(dependency); + }); + if (this.node.key) { + this.node.key.dynamic_dependencies().forEach((dependency) => { + all_dependencies.add(dependency); + }); + } + this.dependencies = all_dependencies; - if (this.node.key) { - this.render_keyed(args); - } else { - this.render_unkeyed(args); - } + if (this.node.key) { + this.render_keyed(args); + } else { + this.render_unkeyed(args); + } - if (this.block.has_intro_method || this.block.has_outro_method) { - block.chunks.intro.push(b` + if (this.block.has_intro_method || this.block.has_outro_method) { + block.chunks.intro.push(b` for (let #i = 0; #i < ${this.vars.data_length}; #i += 1) { @transition_in(${this.vars.iterations}[#i]); } `); - } + } - if (needs_anchor) { - block.add_element( - update_anchor_node , - x`@empty()`, - parent_nodes && x`@empty()`, - parent_node - ); - } + if (needs_anchor) { + block.add_element(update_anchor_node, x`@empty()`, parent_nodes && x`@empty()`, parent_node); + } - if (this.else) { - const each_block_else = component.get_unique_name(`${this.var.name}_else`); + if (this.else) { + const each_block_else = component.get_unique_name(`${this.var.name}_else`); - block.chunks.init.push(b`let ${each_block_else} = null;`); + block.chunks.init.push(b`let ${each_block_else} = null;`); - // TODO neaten this up... will end up with an empty line in the block - block.chunks.init.push(b` + // TODO neaten this up... will end up with an empty line in the block + block.chunks.init.push(b` if (!${this.vars.data_length}) { ${each_block_else} = ${this.else.block.name}(#ctx); } `); - block.chunks.create.push(b` + block.chunks.create.push(b` if (${each_block_else}) { ${each_block_else}.c(); } `); - if (this.renderer.options.hydratable) { - block.chunks.claim.push(b` + if (this.renderer.options.hydratable) { + block.chunks.claim.push(b` if (${each_block_else}) { ${each_block_else}.l(${parent_nodes}); } `); - } + } - block.chunks.mount.push(b` + block.chunks.mount.push(b` if (${each_block_else}) { ${each_block_else}.m(${initial_mount_node}, ${initial_anchor_node}); } `); - const has_transitions = !!(this.else.block.has_intro_method || this.else.block.has_outro_method); + const has_transitions = !!(this.else.block.has_intro_method || this.else.block.has_outro_method); - const destroy_block_else = this.else.block.has_outro_method - ? b` + const destroy_block_else = this.else.block.has_outro_method + ? b` @group_outros(); @transition_out(${each_block_else}, 1, 1, () => { ${each_block_else} = null; }); @check_outros();` - : b` + : b` ${each_block_else}.d(1); ${each_block_else} = null;`; - if (this.else.block.has_update_method) { - this.updates.push(b` + if (this.else.block.has_update_method) { + this.updates.push(b` if (!${this.vars.data_length} && ${each_block_else}) { ${each_block_else}.p(#ctx, #dirty); } else if (!${this.vars.data_length}) { @@ -8622,8 +8157,8 @@ class EachBlockWrapper extends Wrapper { ${destroy_block_else}; } `); - } else { - this.updates.push(b` + } else { + this.updates.push(b` if (${this.vars.data_length}) { if (${each_block_else}) { ${destroy_block_else}; @@ -8635,86 +8170,64 @@ class EachBlockWrapper extends Wrapper { ${each_block_else}.m(${update_mount_node}, ${update_anchor_node}); } `); - } + } - block.chunks.destroy.push(b` + block.chunks.destroy.push(b` if (${each_block_else}) ${each_block_else}.d(${parent_node ? '' : 'detaching'}); `); - } + } - if (this.updates.length) { - block.chunks.update.push(b` + if (this.updates.length) { + block.chunks.update.push(b` if (${block.renderer.dirty(Array.from(all_dependencies))}) { ${this.updates} } `); - } + } - this.fragment.render(this.block, null, x`#nodes` ); + this.fragment.render(this.block, null, x`#nodes`); - if (this.else) { - this.else.fragment.render(this.else.block, null, x`#nodes` ); - } + if (this.else) { + this.else.fragment.render(this.else.block, null, x`#nodes`); + } - this.context_props = this.node.contexts.map(prop => b`child_ctx[${renderer.context_lookup.get(prop.key.name).index}] = ${prop.default_modifier(prop.modifier(x`list[i]`), name => renderer.context_lookup.has(name) ? x`child_ctx[${renderer.context_lookup.get(name).index}]`: { type: 'Identifier', name })};`); + this.context_props = this.node.contexts.map( + (prop) => + b`child_ctx[${renderer.context_lookup.get(prop.key.name).index}] = ${prop.default_modifier(prop.modifier(x`list[i]`), (name) => + renderer.context_lookup.has(name) ? x`child_ctx[${renderer.context_lookup.get(name).index}]` : { type: 'Identifier', name } + )};` + ); - if (this.node.has_binding) this.context_props.push(b`child_ctx[${renderer.context_lookup.get(this.vars.each_block_value.name).index}] = list;`); - if (this.node.has_binding || this.node.has_index_binding || this.node.index) this.context_props.push(b`child_ctx[${renderer.context_lookup.get(this.index_name.name).index}] = i;`); - // TODO which is better — Object.create(array) or array.slice()? - renderer.blocks.push(b` + if (this.node.has_binding) this.context_props.push(b`child_ctx[${renderer.context_lookup.get(this.vars.each_block_value.name).index}] = list;`); + if (this.node.has_binding || this.node.has_index_binding || this.node.index) + this.context_props.push(b`child_ctx[${renderer.context_lookup.get(this.index_name.name).index}] = i;`); + // TODO which is better — Object.create(array) or array.slice()? + renderer.blocks.push(b` function ${this.vars.get_each_context}(#ctx, list, i) { const child_ctx = #ctx.slice(); ${this.context_props} return child_ctx; } `); - } - - render_keyed({ - block, - parent_node, - parent_nodes, - snippet, - initial_anchor_node, - initial_mount_node, - update_anchor_node, - update_mount_node - } - - - - - - - + } -) { - const { - create_each_block, - iterations, - data_length, - view_length - } = this.vars; + render_keyed({ block, parent_node, parent_nodes, snippet, initial_anchor_node, initial_mount_node, update_anchor_node, update_mount_node }) { + const { create_each_block, iterations, data_length, view_length } = this.vars; - const get_key = block.get_unique_name('get_key'); - const lookup = block.get_unique_name(`${this.var.name}_lookup`); + const get_key = block.get_unique_name('get_key'); + const lookup = block.get_unique_name(`${this.var.name}_lookup`); - block.add_variable(iterations, x`[]`); - block.add_variable(lookup, x`new @_Map()`); + block.add_variable(iterations, x`[]`); + block.add_variable(lookup, x`new @_Map()`); - if (this.fragment.nodes[0].is_dom_node()) { - this.block.first = this.fragment.nodes[0].var; - } else { - this.block.first = this.block.get_unique_name('first'); - this.block.add_element( - this.block.first, - x`@empty()`, - parent_nodes && x`@empty()`, - null - ); - } + if (this.fragment.nodes[0].is_dom_node()) { + this.block.first = this.fragment.nodes[0].var; + } else { + this.block.first = this.block.get_unique_name('first'); + this.block.add_element(this.block.first, x`@empty()`, parent_nodes && x`@empty()`, null); + } - block.chunks.init.push(b` + block.chunks.init.push(b` const ${get_key} = #ctx => ${this.node.key.manipulate(block)}; ${this.renderer.options.dev && b`@validate_each_keys(#ctx, ${this.vars.each_block_value}, ${this.vars.get_each_context}, ${get_key});`} @@ -8725,93 +8238,73 @@ class EachBlockWrapper extends Wrapper { } `); - block.chunks.create.push(b` + block.chunks.create.push(b` for (let #i = 0; #i < ${view_length}; #i += 1) { ${iterations}[#i].c(); } `); - if (parent_nodes && this.renderer.options.hydratable) { - block.chunks.claim.push(b` + if (parent_nodes && this.renderer.options.hydratable) { + block.chunks.claim.push(b` for (let #i = 0; #i < ${view_length}; #i += 1) { ${iterations}[#i].l(${parent_nodes}); } `); - } + } - block.chunks.mount.push(b` + block.chunks.mount.push(b` for (let #i = 0; #i < ${view_length}; #i += 1) { ${iterations}[#i].m(${initial_mount_node}, ${initial_anchor_node}); } `); - const dynamic = this.block.has_update_method; + const dynamic = this.block.has_update_method; - const destroy = this.node.has_animation - ? (this.block.has_outros - ? '@fix_and_outro_and_destroy_block' - : '@fix_and_destroy_block') - : this.block.has_outros - ? '@outro_and_destroy_block' - : '@destroy_block'; + const destroy = this.node.has_animation + ? this.block.has_outros + ? '@fix_and_outro_and_destroy_block' + : '@fix_and_destroy_block' + : this.block.has_outros + ? '@outro_and_destroy_block' + : '@destroy_block'; - if (this.dependencies.size) { - this.block.maintain_context = true; + if (this.dependencies.size) { + this.block.maintain_context = true; - this.updates.push(b` + this.updates.push(b` ${this.vars.each_block_value} = ${snippet}; ${this.renderer.options.dev && b`@validate_each_argument(${this.vars.each_block_value});`} ${this.block.has_outros && b`@group_outros();`} ${this.node.has_animation && b`for (let #i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].r();`} ${this.renderer.options.dev && b`@validate_each_keys(#ctx, ${this.vars.each_block_value}, ${this.vars.get_each_context}, ${get_key});`} - ${iterations} = @update_keyed_each(${iterations}, #dirty, ${get_key}, ${dynamic ? 1 : 0}, #ctx, ${this.vars.each_block_value}, ${lookup}, ${update_mount_node}, ${destroy}, ${create_each_block}, ${update_anchor_node}, ${this.vars.get_each_context}); + ${iterations} = @update_keyed_each(${iterations}, #dirty, ${get_key}, ${dynamic ? 1 : 0}, #ctx, ${ + this.vars.each_block_value + }, ${lookup}, ${update_mount_node}, ${destroy}, ${create_each_block}, ${update_anchor_node}, ${this.vars.get_each_context}); ${this.node.has_animation && b`for (let #i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].a();`} ${this.block.has_outros && b`@check_outros();`} `); - } + } - if (this.block.has_outros) { - block.chunks.outro.push(b` + if (this.block.has_outros) { + block.chunks.outro.push(b` for (let #i = 0; #i < ${view_length}; #i += 1) { @transition_out(${iterations}[#i]); } `); - } + } - block.chunks.destroy.push(b` + block.chunks.destroy.push(b` for (let #i = 0; #i < ${view_length}; #i += 1) { ${iterations}[#i].d(${parent_node ? null : 'detaching'}); } `); - } - - render_unkeyed({ - block, - parent_nodes, - snippet, - initial_anchor_node, - initial_mount_node, - update_anchor_node, - update_mount_node - } - - - - - - + } -) { - const { - create_each_block, - iterations, - fixed_length, - data_length, - view_length - } = this.vars; + render_unkeyed({ block, parent_nodes, snippet, initial_anchor_node, initial_mount_node, update_anchor_node, update_mount_node }) { + const { create_each_block, iterations, fixed_length, data_length, view_length } = this.vars; - block.chunks.init.push(b` + block.chunks.init.push(b` let ${iterations} = []; for (let #i = 0; #i < ${data_length}; #i += 1) { @@ -8819,31 +8312,31 @@ class EachBlockWrapper extends Wrapper { } `); - block.chunks.create.push(b` + block.chunks.create.push(b` for (let #i = 0; #i < ${view_length}; #i += 1) { ${iterations}[#i].c(); } `); - if (parent_nodes && this.renderer.options.hydratable) { - block.chunks.claim.push(b` + if (parent_nodes && this.renderer.options.hydratable) { + block.chunks.claim.push(b` for (let #i = 0; #i < ${view_length}; #i += 1) { ${iterations}[#i].l(${parent_nodes}); } `); - } + } - block.chunks.mount.push(b` + block.chunks.mount.push(b` for (let #i = 0; #i < ${view_length}; #i += 1) { ${iterations}[#i].m(${initial_mount_node}, ${initial_anchor_node}); } `); - if (this.dependencies.size) { - const has_transitions = !!(this.block.has_intro_method || this.block.has_outro_method); + if (this.dependencies.size) { + const has_transitions = !!(this.block.has_intro_method || this.block.has_outro_method); - const for_loop_body = this.block.has_update_method - ? b` + const for_loop_body = this.block.has_update_method + ? b` if (${iterations}[#i]) { ${iterations}[#i].p(child_ctx, #dirty); ${has_transitions && b`@transition_in(${this.vars.iterations}[#i], 1);`} @@ -8854,8 +8347,8 @@ class EachBlockWrapper extends Wrapper { ${iterations}[#i].m(${update_mount_node}, ${update_anchor_node}); } ` - : has_transitions - ? b` + : has_transitions + ? b` if (${iterations}[#i]) { @transition_in(${this.vars.iterations}[#i], 1); } else { @@ -8865,7 +8358,7 @@ class EachBlockWrapper extends Wrapper { ${iterations}[#i].m(${update_mount_node}, ${update_anchor_node}); } ` - : b` + : b` if (!${iterations}[#i]) { ${iterations}[#i] = ${create_each_block}(child_ctx); ${iterations}[#i].c(); @@ -8873,37 +8366,37 @@ class EachBlockWrapper extends Wrapper { } `; - const start = this.block.has_update_method ? 0 : '#old_length'; + const start = this.block.has_update_method ? 0 : '#old_length'; - let remove_old_blocks; + let remove_old_blocks; - if (this.block.has_outros) { - const out = block.get_unique_name('out'); + if (this.block.has_outros) { + const out = block.get_unique_name('out'); - block.chunks.init.push(b` + block.chunks.init.push(b` const ${out} = i => @transition_out(${iterations}[i], 1, 1, () => { ${iterations}[i] = null; }); `); - remove_old_blocks = b` + remove_old_blocks = b` @group_outros(); for (#i = ${data_length}; #i < ${view_length}; #i += 1) { ${out}(#i); } @check_outros(); `; - } else { - remove_old_blocks = b` + } else { + remove_old_blocks = b` for (${this.block.has_update_method ? null : x`#i = ${data_length}`}; #i < ${this.block.has_update_method ? view_length : '#old_length'}; #i += 1) { ${iterations}[#i].d(1); } ${!fixed_length && b`${view_length} = ${data_length};`} `; - } + } - // We declare `i` as block scoped here, as the `remove_old_blocks` code - // may rely on continuing where this iteration stopped. - const update = b` + // We declare `i` as block scoped here, as the `remove_old_blocks` code + // may rely on continuing where this iteration stopped. + const update = b` ${!this.block.has_update_method && b`const #old_length = ${this.vars.each_block_value}.length;`} ${this.vars.each_block_value} = ${snippet}; ${this.renderer.options.dev && b`@validate_each_argument(${this.vars.each_block_value});`} @@ -8918,104 +8411,95 @@ class EachBlockWrapper extends Wrapper { ${remove_old_blocks} `; - this.updates.push(update); - } + this.updates.push(update); + } - if (this.block.has_outros) { - block.chunks.outro.push(b` + if (this.block.has_outros) { + block.chunks.outro.push(b` ${iterations} = ${iterations}.filter(@_Boolean); for (let #i = 0; #i < ${view_length}; #i += 1) { @transition_out(${iterations}[#i]); } `); - } + } - block.chunks.destroy.push(b`@destroy_each(${iterations}, detaching);`); - } + block.chunks.destroy.push(b`@destroy_each(${iterations}, detaching);`); + } } function string_literal(data) { - return { - type: 'Literal', - value: data - }; + return { + type: 'Literal', + value: data, + }; } const escaped = { - '"': '"', - "'": ''', - '&': '&', - '<': '<', - '>': '>' + '"': '"', + "'": ''', + '&': '&', + '<': '<', + '>': '>', }; function escape_html(html) { - return String(html).replace(/["'&<>]/g, match => escaped[match]); + return String(html).replace(/["'&<>]/g, (match) => escaped[match]); } function escape_template(str) { - return str.replace(/(\${|`|\\)/g, '\\$1'); + return str.replace(/(\${|`|\\)/g, '\\$1'); } class TextWrapper extends Wrapper { - - - - - - constructor( - renderer, - block, - parent, - node, - data - ) { - super(renderer, block, parent, node); - - this.skip = this.node.should_skip(); - this.data = data; - this.var = (this.skip ? null : x`t`) ; - } - - use_space() { - if (this.renderer.component.component_options.preserveWhitespace) return false; - if (/[\S\u00A0]/.test(this.data)) return false; - - let node = this.parent && this.parent.node; - while (node) { - if (node.type === 'Element' && node.name === 'pre') { - return false; - } - node = node.parent; - } + constructor(renderer, block, parent, node, data) { + super(renderer, block, parent, node); - return true; - } + this.skip = this.node.should_skip(); + this.data = data; + this.var = this.skip ? null : x`t`; + } - render(block, parent_node, parent_nodes) { - if (this.skip) return; - const use_space = this.use_space(); + use_space() { + if (this.renderer.component.component_options.preserveWhitespace) return false; + if (/[\S\u00A0]/.test(this.data)) return false; - block.add_element( - this.var, - use_space ? x`@space()` : x`@text("${this.data}")`, - parent_nodes && (use_space ? x`@claim_space(${parent_nodes})` : x`@claim_text(${parent_nodes}, "${this.data}")`), - parent_node - ); - } + let node = this.parent && this.parent.node; + while (node) { + if (node.type === 'Element' && node.name === 'pre') { + return false; + } + node = node.parent; + } + + return true; + } + + render(block, parent_node, parent_nodes) { + if (this.skip) return; + const use_space = this.use_space(); + + block.add_element( + this.var, + use_space ? x`@space()` : x`@text("${this.data}")`, + parent_nodes && (use_space ? x`@claim_space(${parent_nodes})` : x`@claim_text(${parent_nodes}, "${this.data}")`), + parent_node + ); + } } -const svg_attributes = 'accent-height accumulate additive alignment-baseline allowReorder alphabetic amplitude arabic-form ascent attributeName attributeType autoReverse azimuth baseFrequency baseline-shift baseProfile bbox begin bias by calcMode cap-height class clip clipPathUnits clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering contentScriptType contentStyleType cursor cx cy d decelerate descent diffuseConstant direction display divisor dominant-baseline dur dx dy edgeMode elevation enable-background end exponent externalResourcesRequired fill fill-opacity fill-rule filter filterRes filterUnits flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight format from fr fx fy g1 g2 glyph-name glyph-orientation-horizontal glyph-orientation-vertical glyphRef gradientTransform gradientUnits hanging height href horiz-adv-x horiz-origin-x id ideographic image-rendering in in2 intercept k k1 k2 k3 k4 kernelMatrix kernelUnitLength kerning keyPoints keySplines keyTimes lang lengthAdjust letter-spacing lighting-color limitingConeAngle local marker-end marker-mid marker-start markerHeight markerUnits markerWidth mask maskContentUnits maskUnits mathematical max media method min mode name numOctaves offset onabort onactivate onbegin onclick onend onerror onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup onrepeat onresize onscroll onunload opacity operator order orient orientation origin overflow overline-position overline-thickness panose-1 paint-order pathLength patternContentUnits patternTransform patternUnits pointer-events points pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits r radius refX refY rendering-intent repeatCount repeatDur requiredExtensions requiredFeatures restart result rotate rx ry scale seed shape-rendering slope spacing specularConstant specularExponent speed spreadMethod startOffset stdDeviation stemh stemv stitchTiles stop-color stop-opacity strikethrough-position strikethrough-thickness string stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style surfaceScale systemLanguage tabindex tableValues target targetX targetY text-anchor text-decoration text-rendering textLength to transform type u1 u2 underline-position underline-thickness unicode unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical values version vert-adv-y vert-origin-x vert-origin-y viewBox viewTarget visibility width widths word-spacing writing-mode x x-height x1 x2 xChannelSelector xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y y1 y2 yChannelSelector z zoomAndPan'.split(' '); +const svg_attributes = 'accent-height accumulate additive alignment-baseline allowReorder alphabetic amplitude arabic-form ascent attributeName attributeType autoReverse azimuth baseFrequency baseline-shift baseProfile bbox begin bias by calcMode cap-height class clip clipPathUnits clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering contentScriptType contentStyleType cursor cx cy d decelerate descent diffuseConstant direction display divisor dominant-baseline dur dx dy edgeMode elevation enable-background end exponent externalResourcesRequired fill fill-opacity fill-rule filter filterRes filterUnits flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight format from fr fx fy g1 g2 glyph-name glyph-orientation-horizontal glyph-orientation-vertical glyphRef gradientTransform gradientUnits hanging height href horiz-adv-x horiz-origin-x id ideographic image-rendering in in2 intercept k k1 k2 k3 k4 kernelMatrix kernelUnitLength kerning keyPoints keySplines keyTimes lang lengthAdjust letter-spacing lighting-color limitingConeAngle local marker-end marker-mid marker-start markerHeight markerUnits markerWidth mask maskContentUnits maskUnits mathematical max media method min mode name numOctaves offset onabort onactivate onbegin onclick onend onerror onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup onrepeat onresize onscroll onunload opacity operator order orient orientation origin overflow overline-position overline-thickness panose-1 paint-order pathLength patternContentUnits patternTransform patternUnits pointer-events points pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits r radius refX refY rendering-intent repeatCount repeatDur requiredExtensions requiredFeatures restart result rotate rx ry scale seed shape-rendering slope spacing specularConstant specularExponent speed spreadMethod startOffset stdDeviation stemh stemv stitchTiles stop-color stop-opacity strikethrough-position strikethrough-thickness string stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style surfaceScale systemLanguage tabindex tableValues target targetX targetY text-anchor text-decoration text-rendering textLength to transform type u1 u2 underline-position underline-thickness unicode unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical values version vert-adv-y vert-origin-x vert-origin-y viewBox viewTarget visibility width widths word-spacing writing-mode x x-height x1 x2 xChannelSelector xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y y1 y2 yChannelSelector z zoomAndPan'.split( + ' ' +); const svg_attribute_lookup = new Map(); -svg_attributes.forEach(name => { - svg_attribute_lookup.set(name.toLowerCase(), name); +svg_attributes.forEach((name) => { + svg_attribute_lookup.set(name.toLowerCase(), name); }); function fix_attribute_casing(name) { - name = name.toLowerCase(); - return svg_attribute_lookup.get(name) || name; + name = name.toLowerCase(); + return svg_attribute_lookup.get(name) || name; } // The `foreign` namespace covers all DOM implementations that aren't HTML5. @@ -9028,1214 +8512,1050 @@ const xlink = 'http://www.w3.org/1999/xlink'; const xml = 'http://www.w3.org/XML/1998/namespace'; const xmlns = 'http://www.w3.org/2000/xmlns'; -const valid_namespaces = [ - 'foreign', - 'html', - 'mathml', - 'svg', - 'xlink', - 'xml', - 'xmlns', - foreign, - html, - mathml, - svg, - xlink, - xml, - xmlns -]; +const valid_namespaces = ['foreign', 'html', 'mathml', 'svg', 'xlink', 'xml', 'xmlns', foreign, html, mathml, svg, xlink, xml, xmlns]; const namespaces = { foreign, html, mathml, svg, xlink, xml, xmlns }; -function handle_select_value_binding( - attr, - dependencies -) { - const { parent } = attr; - if (parent.node.name === 'select') { - (parent ).select_binding_dependencies = dependencies; - dependencies.forEach((prop) => { - parent.renderer.component.indirect_dependencies.set(prop, new Set()); - }); - } +function handle_select_value_binding(attr, dependencies) { + const { parent } = attr; + if (parent.node.name === 'select') { + parent.select_binding_dependencies = dependencies; + dependencies.forEach((prop) => { + parent.renderer.component.indirect_dependencies.set(prop, new Set()); + }); + } } class BaseAttributeWrapper { - - - - constructor(parent, block, node) { - this.node = node; - this.parent = parent; + constructor(parent, block, node) { + this.node = node; + this.parent = parent; - if (node.dependencies.size > 0) { - parent.cannot_use_innerhtml(); - parent.not_static_content(); + if (node.dependencies.size > 0) { + parent.cannot_use_innerhtml(); + parent.not_static_content(); - block.add_dependencies(node.dependencies); - } - } + block.add_dependencies(node.dependencies); + } + } - render(_block) {} + render(_block) {} } class AttributeWrapper extends BaseAttributeWrapper { - - - - - - - - - - - - - constructor(parent, block, node) { - super(parent, block, node); - - if (node.dependencies.size > 0) { - // special case — <option value={foo}> — see below - if (this.parent.node.name === 'option' && node.name === 'value') { - let select = this.parent; - while (select && (select.node.type !== 'Element' || select.node.name !== 'select')) { - // @ts-ignore todo: doublecheck this, but looks to be correct - select = select.parent; - } + constructor(parent, block, node) { + super(parent, block, node); + + if (node.dependencies.size > 0) { + // special case — <option value={foo}> — see below + if (this.parent.node.name === 'option' && node.name === 'value') { + let select = this.parent; + while (select && (select.node.type !== 'Element' || select.node.name !== 'select')) { + // @ts-ignore todo: doublecheck this, but looks to be correct + select = select.parent; + } - if (select && select.select_binding_dependencies) { - select.select_binding_dependencies.forEach(prop => { - this.node.dependencies.forEach((dependency) => { - this.parent.renderer.component.indirect_dependencies.get(prop).add(dependency); - }); - }); - } - } + if (select && select.select_binding_dependencies) { + select.select_binding_dependencies.forEach((prop) => { + this.node.dependencies.forEach((dependency) => { + this.parent.renderer.component.indirect_dependencies.get(prop).add(dependency); + }); + }); + } + } - if (node.name === 'value') { - handle_select_value_binding(this, node.dependencies); - } - } + if (node.name === 'value') { + handle_select_value_binding(this, node.dependencies); + } + } - if (this.parent.node.namespace == namespaces.foreign) { - // leave attribute case alone for elements in the "foreign" namespace - this.name = this.node.name; - this.metadata = this.get_metadata(); - this.is_indirectly_bound_value = false; - this.property_name = null; - this.is_select_value_attribute = false; - this.is_input_value = false; - } else { - this.name = fix_attribute_casing(this.node.name); - this.metadata = this.get_metadata(); - this.is_indirectly_bound_value = is_indirectly_bound_value(this); - this.property_name = this.is_indirectly_bound_value - ? '__value' - : this.metadata && this.metadata.property_name; - this.is_select_value_attribute = this.name === 'value' && this.parent.node.name === 'select'; - this.is_input_value = this.name === 'value' && this.parent.node.name === 'input'; - } - - this.is_src = this.name === 'src'; // TODO retire this exception in favour of https://github.com/sveltejs/svelte/issues/3750 - this.should_cache = should_cache(this); - } - - render(block) { - const element = this.parent; - const { name, property_name, should_cache, is_indirectly_bound_value } = this; - - // xlink is a special case... we could maybe extend this to generic - // namespaced attributes but I'm not sure that's applicable in - // HTML5? - const method = /-/.test(element.node.name) - ? '@set_custom_element_data' - : name.slice(0, 6) === 'xlink:' - ? '@xlink_attr' - : '@attr'; - - const is_legacy_input_type = element.renderer.component.compile_options.legacy && name === 'type' && this.parent.node.name === 'input'; - - const dependencies = this.get_dependencies(); - const value = this.get_value(block); - - let updater; - const init = this.get_init(block, value); - - if (is_legacy_input_type) { - block.chunks.hydrate.push( - b`@set_input_type(${element.var}, ${init});` - ); - updater = b`@set_input_type(${element.var}, ${should_cache ? this.last : value});`; - } else if (this.is_select_value_attribute) { - // annoying special case - const is_multiple_select = element.node.get_static_attribute_value('multiple'); - - if (is_multiple_select) { - updater = b`@select_options(${element.var}, ${value});`; - } else { - updater = b`@select_option(${element.var}, ${value});`; - } + if (this.parent.node.namespace == namespaces.foreign) { + // leave attribute case alone for elements in the "foreign" namespace + this.name = this.node.name; + this.metadata = this.get_metadata(); + this.is_indirectly_bound_value = false; + this.property_name = null; + this.is_select_value_attribute = false; + this.is_input_value = false; + } else { + this.name = fix_attribute_casing(this.node.name); + this.metadata = this.get_metadata(); + this.is_indirectly_bound_value = is_indirectly_bound_value(this); + this.property_name = this.is_indirectly_bound_value ? '__value' : this.metadata && this.metadata.property_name; + this.is_select_value_attribute = this.name === 'value' && this.parent.node.name === 'select'; + this.is_input_value = this.name === 'value' && this.parent.node.name === 'input'; + } + + this.is_src = this.name === 'src'; // TODO retire this exception in favour of https://github.com/sveltejs/svelte/issues/3750 + this.should_cache = should_cache(this); + } + + render(block) { + const element = this.parent; + const { name, property_name, should_cache, is_indirectly_bound_value } = this; + + // xlink is a special case... we could maybe extend this to generic + // namespaced attributes but I'm not sure that's applicable in + // HTML5? + const method = /-/.test(element.node.name) ? '@set_custom_element_data' : name.slice(0, 6) === 'xlink:' ? '@xlink_attr' : '@attr'; - block.chunks.mount.push(b` + const is_legacy_input_type = element.renderer.component.compile_options.legacy && name === 'type' && this.parent.node.name === 'input'; + + const dependencies = this.get_dependencies(); + const value = this.get_value(block); + + let updater; + const init = this.get_init(block, value); + + if (is_legacy_input_type) { + block.chunks.hydrate.push(b`@set_input_type(${element.var}, ${init});`); + updater = b`@set_input_type(${element.var}, ${should_cache ? this.last : value});`; + } else if (this.is_select_value_attribute) { + // annoying special case + const is_multiple_select = element.node.get_static_attribute_value('multiple'); + + if (is_multiple_select) { + updater = b`@select_options(${element.var}, ${value});`; + } else { + updater = b`@select_option(${element.var}, ${value});`; + } + + block.chunks.mount.push(b` ${updater} `); - } else if (this.is_src) { - block.chunks.hydrate.push( - b`if (${element.var}.src !== ${init}) ${method}(${element.var}, "${name}", ${this.last});` - ); - updater = b`${method}(${element.var}, "${name}", ${should_cache ? this.last : value});`; - } else if (property_name) { - block.chunks.hydrate.push( - b`${element.var}.${property_name} = ${init};` - ); - updater = block.renderer.options.dev - ? b`@prop_dev(${element.var}, "${property_name}", ${should_cache ? this.last : value});` - : b`${element.var}.${property_name} = ${should_cache ? this.last : value};`; - } else { - block.chunks.hydrate.push( - b`${method}(${element.var}, "${name}", ${init});` - ); - updater = b`${method}(${element.var}, "${name}", ${should_cache ? this.last : value});`; - } + } else if (this.is_src) { + block.chunks.hydrate.push(b`if (${element.var}.src !== ${init}) ${method}(${element.var}, "${name}", ${this.last});`); + updater = b`${method}(${element.var}, "${name}", ${should_cache ? this.last : value});`; + } else if (property_name) { + block.chunks.hydrate.push(b`${element.var}.${property_name} = ${init};`); + updater = block.renderer.options.dev + ? b`@prop_dev(${element.var}, "${property_name}", ${should_cache ? this.last : value});` + : b`${element.var}.${property_name} = ${should_cache ? this.last : value};`; + } else { + block.chunks.hydrate.push(b`${method}(${element.var}, "${name}", ${init});`); + updater = b`${method}(${element.var}, "${name}", ${should_cache ? this.last : value});`; + } - if (is_indirectly_bound_value) { - const update_value = b`${element.var}.value = ${element.var}.__value;`; - block.chunks.hydrate.push(update_value); + if (is_indirectly_bound_value) { + const update_value = b`${element.var}.value = ${element.var}.__value;`; + block.chunks.hydrate.push(update_value); - updater = b` + updater = b` ${updater} ${update_value}; `; - } + } - if (dependencies.length > 0) { - const condition = this.get_dom_update_conditions(block, block.renderer.dirty(dependencies)); + if (dependencies.length > 0) { + const condition = this.get_dom_update_conditions(block, block.renderer.dirty(dependencies)); - block.chunks.update.push(b` + block.chunks.update.push(b` if (${condition}) { ${updater} }`); - } + } - // special case – autofocus. has to be handled in a bit of a weird way - if (this.node.is_true && name === 'autofocus') { - block.autofocus = element.var; - } - } + // special case – autofocus. has to be handled in a bit of a weird way + if (this.node.is_true && name === 'autofocus') { + block.autofocus = element.var; + } + } - get_init(block, value) { - this.last = this.should_cache && block.get_unique_name( - `${this.parent.var.name}_${this.name.replace(/[^a-zA-Z_$]/g, '_')}_value` - ); + get_init(block, value) { + this.last = this.should_cache && block.get_unique_name(`${this.parent.var.name}_${this.name.replace(/[^a-zA-Z_$]/g, '_')}_value`); - if (this.should_cache) block.add_variable(this.last); + if (this.should_cache) block.add_variable(this.last); - return this.should_cache ? x`${this.last} = ${value}` : value; - } + return this.should_cache ? x`${this.last} = ${value}` : value; + } - get_dom_update_conditions(block, dependency_condition) { - const { property_name, should_cache, last } = this; - const element = this.parent; - const value = this.get_value(block); + get_dom_update_conditions(block, dependency_condition) { + const { property_name, should_cache, last } = this; + const element = this.parent; + const value = this.get_value(block); - let condition = dependency_condition; + let condition = dependency_condition; - if (should_cache) { - condition = this.is_src - ? x`${condition} && (${element.var}.src !== (${last} = ${value}))` - : x`${condition} && (${last} !== (${last} = ${value}))`; - } + if (should_cache) { + condition = this.is_src ? x`${condition} && (${element.var}.src !== (${last} = ${value}))` : x`${condition} && (${last} !== (${last} = ${value}))`; + } - if (this.is_input_value) { - const type = element.node.get_static_attribute_value('type'); + if (this.is_input_value) { + const type = element.node.get_static_attribute_value('type'); - if (type === null || type === '' || type === 'text' || type === 'email' || type === 'password') { - condition = x`${condition} && ${element.var}.${property_name} !== ${should_cache ? last : value}`; - } - } + if (type === null || type === '' || type === 'text' || type === 'email' || type === 'password') { + condition = x`${condition} && ${element.var}.${property_name} !== ${should_cache ? last : value}`; + } + } - if (block.has_outros) { - condition = x`!#current || ${condition}`; - } + if (block.has_outros) { + condition = x`!#current || ${condition}`; + } - return condition; - } + return condition; + } - get_dependencies() { - const node_dependencies = this.node.get_dependencies(); - const dependencies = new Set(node_dependencies); + get_dependencies() { + const node_dependencies = this.node.get_dependencies(); + const dependencies = new Set(node_dependencies); - node_dependencies.forEach((prop) => { - const indirect_dependencies = this.parent.renderer.component.indirect_dependencies.get(prop); - if (indirect_dependencies) { - indirect_dependencies.forEach(indirect_dependency => { - dependencies.add(indirect_dependency); - }); - } - }); + node_dependencies.forEach((prop) => { + const indirect_dependencies = this.parent.renderer.component.indirect_dependencies.get(prop); + if (indirect_dependencies) { + indirect_dependencies.forEach((indirect_dependency) => { + dependencies.add(indirect_dependency); + }); + } + }); - return Array.from(dependencies); - } + return Array.from(dependencies); + } - get_metadata() { - if (this.parent.node.namespace) return null; - const metadata = attribute_lookup[this.name]; - if (metadata && metadata.applies_to && !metadata.applies_to.includes(this.parent.node.name)) return null; - return metadata; - } + get_metadata() { + if (this.parent.node.namespace) return null; + const metadata = attribute_lookup[this.name]; + if (metadata && metadata.applies_to && !metadata.applies_to.includes(this.parent.node.name)) return null; + return metadata; + } - get_value(block) { - if (this.node.is_true) { - if (this.metadata && boolean_attribute.has(this.metadata.property_name.toLowerCase())) { - return x`true`; - } - return x`""`; - } - if (this.node.chunks.length === 0) return x`""`; - - // TODO some of this code is repeated in Tag.ts — would be good to - // DRY it out if that's possible without introducing crazy indirection - if (this.node.chunks.length === 1) { - return this.node.chunks[0].type === 'Text' - ? string_literal((this.node.chunks[0] ).data) - : (this.node.chunks[0] ).manipulate(block); - } + get_value(block) { + if (this.node.is_true) { + if (this.metadata && boolean_attribute.has(this.metadata.property_name.toLowerCase())) { + return x`true`; + } + return x`""`; + } + if (this.node.chunks.length === 0) return x`""`; - let value = this.node.name === 'class' - ? this.get_class_name_text(block) - : this.render_chunks(block).reduce((lhs, rhs) => x`${lhs} + ${rhs}`); + // TODO some of this code is repeated in Tag.ts — would be good to + // DRY it out if that's possible without introducing crazy indirection + if (this.node.chunks.length === 1) { + return this.node.chunks[0].type === 'Text' ? string_literal(this.node.chunks[0].data) : this.node.chunks[0].manipulate(block); + } - // '{foo} {bar}' — treat as string concatenation - if (this.node.chunks[0].type !== 'Text') { - value = x`"" + ${value}`; - } + let value = this.node.name === 'class' ? this.get_class_name_text(block) : this.render_chunks(block).reduce((lhs, rhs) => x`${lhs} + ${rhs}`); - return value; - } + // '{foo} {bar}' — treat as string concatenation + if (this.node.chunks[0].type !== 'Text') { + value = x`"" + ${value}`; + } - get_class_name_text(block) { - const scoped_css = this.node.chunks.some((chunk) => chunk.synthetic); - const rendered = this.render_chunks(block); + return value; + } - if (scoped_css && rendered.length === 2) { - // we have a situation like class={possiblyUndefined} - rendered[0] = x`@null_to_empty(${rendered[0]})`; - } + get_class_name_text(block) { + const scoped_css = this.node.chunks.some((chunk) => chunk.synthetic); + const rendered = this.render_chunks(block); - return rendered.reduce((lhs, rhs) => x`${lhs} + ${rhs}`); - } + if (scoped_css && rendered.length === 2) { + // we have a situation like class={possiblyUndefined} + rendered[0] = x`@null_to_empty(${rendered[0]})`; + } - render_chunks(block) { - return this.node.chunks.map((chunk) => { - if (chunk.type === 'Text') { - return string_literal(chunk.data); - } + return rendered.reduce((lhs, rhs) => x`${lhs} + ${rhs}`); + } - return chunk.manipulate(block); - }); - } + render_chunks(block) { + return this.node.chunks.map((chunk) => { + if (chunk.type === 'Text') { + return string_literal(chunk.data); + } - stringify() { - if (this.node.is_true) return ''; + return chunk.manipulate(block); + }); + } - const value = this.node.chunks; - if (value.length === 0) return '=""'; + stringify() { + if (this.node.is_true) return ''; - return `="${value.map(chunk => { - return chunk.type === 'Text' - ? chunk.data.replace(/"/g, '\\"') - : `\${${chunk.manipulate()}}`; - }).join('')}"`; - } + const value = this.node.chunks; + if (value.length === 0) return '=""'; + + return `="${value + .map((chunk) => { + return chunk.type === 'Text' ? chunk.data.replace(/"/g, '\\"') : `\${${chunk.manipulate()}}`; + }) + .join('')}"`; + } } // source: https://html.spec.whatwg.org/multipage/indices.html const attribute_lookup = { - allowfullscreen: { property_name: 'allowFullscreen', applies_to: ['iframe'] }, - allowpaymentrequest: { property_name: 'allowPaymentRequest', applies_to: ['iframe'] }, - async: { applies_to: ['script'] }, - autofocus: { applies_to: ['button', 'input', 'keygen', 'select', 'textarea'] }, - autoplay: { applies_to: ['audio', 'video'] }, - checked: { applies_to: ['input'] }, - controls: { applies_to: ['audio', 'video'] }, - default: { applies_to: ['track'] }, - defer: { applies_to: ['script'] }, - disabled: { - applies_to: [ - 'button', - 'fieldset', - 'input', - 'keygen', - 'optgroup', - 'option', - 'select', - 'textarea' - ] - }, - formnovalidate: { property_name: 'formNoValidate', applies_to: ['button', 'input'] }, - hidden: {}, - indeterminate: { applies_to: ['input'] }, - ismap: { property_name: 'isMap', applies_to: ['img'] }, - loop: { applies_to: ['audio', 'bgsound', 'video'] }, - multiple: { applies_to: ['input', 'select'] }, - muted: { applies_to: ['audio', 'video'] }, - nomodule: { property_name: 'noModule', applies_to: ['script'] }, - novalidate: { property_name: 'noValidate', applies_to: ['form'] }, - open: { applies_to: ['details', 'dialog'] }, - playsinline: { property_name: 'playsInline', applies_to: ['video'] }, - readonly: { property_name: 'readOnly', applies_to: ['input', 'textarea'] }, - required: { applies_to: ['input', 'select', 'textarea'] }, - reversed: { applies_to: ['ol'] }, - selected: { applies_to: ['option'] }, - value: { - applies_to: [ - 'button', - 'option', - 'input', - 'li', - 'meter', - 'progress', - 'param', - 'select', - 'textarea' - ] - } + allowfullscreen: { property_name: 'allowFullscreen', applies_to: ['iframe'] }, + allowpaymentrequest: { property_name: 'allowPaymentRequest', applies_to: ['iframe'] }, + async: { applies_to: ['script'] }, + autofocus: { applies_to: ['button', 'input', 'keygen', 'select', 'textarea'] }, + autoplay: { applies_to: ['audio', 'video'] }, + checked: { applies_to: ['input'] }, + controls: { applies_to: ['audio', 'video'] }, + default: { applies_to: ['track'] }, + defer: { applies_to: ['script'] }, + disabled: { + applies_to: ['button', 'fieldset', 'input', 'keygen', 'optgroup', 'option', 'select', 'textarea'], + }, + formnovalidate: { property_name: 'formNoValidate', applies_to: ['button', 'input'] }, + hidden: {}, + indeterminate: { applies_to: ['input'] }, + ismap: { property_name: 'isMap', applies_to: ['img'] }, + loop: { applies_to: ['audio', 'bgsound', 'video'] }, + multiple: { applies_to: ['input', 'select'] }, + muted: { applies_to: ['audio', 'video'] }, + nomodule: { property_name: 'noModule', applies_to: ['script'] }, + novalidate: { property_name: 'noValidate', applies_to: ['form'] }, + open: { applies_to: ['details', 'dialog'] }, + playsinline: { property_name: 'playsInline', applies_to: ['video'] }, + readonly: { property_name: 'readOnly', applies_to: ['input', 'textarea'] }, + required: { applies_to: ['input', 'select', 'textarea'] }, + reversed: { applies_to: ['ol'] }, + selected: { applies_to: ['option'] }, + value: { + applies_to: ['button', 'option', 'input', 'li', 'meter', 'progress', 'param', 'select', 'textarea'], + }, }; -Object.keys(attribute_lookup).forEach(name => { - const metadata = attribute_lookup[name]; - if (!metadata.property_name) metadata.property_name = name; +Object.keys(attribute_lookup).forEach((name) => { + const metadata = attribute_lookup[name]; + if (!metadata.property_name) metadata.property_name = name; }); // source: https://html.spec.whatwg.org/multipage/indices.html const boolean_attribute = new Set([ - 'allowfullscreen', - 'allowpaymentrequest', - 'async', - 'autofocus', - 'autoplay', - 'checked', - 'controls', - 'default', - 'defer', - 'disabled', - 'formnovalidate', - 'hidden', - 'ismap', - 'itemscope', - 'loop', - 'multiple', - 'muted', - 'nomodule', - 'novalidate', - 'open', - 'playsinline', - 'readonly', - 'required', - 'reversed', - 'selected' + 'allowfullscreen', + 'allowpaymentrequest', + 'async', + 'autofocus', + 'autoplay', + 'checked', + 'controls', + 'default', + 'defer', + 'disabled', + 'formnovalidate', + 'hidden', + 'ismap', + 'itemscope', + 'loop', + 'multiple', + 'muted', + 'nomodule', + 'novalidate', + 'open', + 'playsinline', + 'readonly', + 'required', + 'reversed', + 'selected', ]); function should_cache(attribute) { - return attribute.is_src || attribute.node.should_cache(); + return attribute.is_src || attribute.node.should_cache(); } function is_indirectly_bound_value(attribute) { - const element = attribute.parent; - return attribute.name === 'value' && - (element.node.name === 'option' || // TODO check it's actually bound - (element.node.name === 'input' && - element.node.bindings.some( - (binding) => - /checked|group/.test(binding.name) - ))); + const element = attribute.parent; + return ( + attribute.name === 'value' && + (element.node.name === 'option' || // TODO check it's actually bound + (element.node.name === 'input' && element.node.bindings.some((binding) => /checked|group/.test(binding.name)))) + ); } class StyleAttributeWrapper extends AttributeWrapper { - - - - render(block) { - const style_props = optimize_style(this.node.chunks); - if (!style_props) return super.render(block); + render(block) { + const style_props = optimize_style(this.node.chunks); + if (!style_props) return super.render(block); - style_props.forEach((prop) => { - let value; + style_props.forEach((prop) => { + let value; - if (is_dynamic(prop.value)) { - const prop_dependencies = new Set(); + if (is_dynamic(prop.value)) { + const prop_dependencies = new Set(); - value = prop.value - .map(chunk => { - if (chunk.type === 'Text') { - return string_literal(chunk.data); - } else { - add_to_set(prop_dependencies, chunk.dynamic_dependencies()); - return chunk.manipulate(block); - } - }) - .reduce((lhs, rhs) => x`${lhs} + ${rhs}`); + value = prop.value + .map((chunk) => { + if (chunk.type === 'Text') { + return string_literal(chunk.data); + } else { + add_to_set(prop_dependencies, chunk.dynamic_dependencies()); + return chunk.manipulate(block); + } + }) + .reduce((lhs, rhs) => x`${lhs} + ${rhs}`); - // TODO is this necessary? style.setProperty always treats value as string, no? - // if (prop.value.length === 1 || prop.value[0].type !== 'Text') { - // value = x`"" + ${value}`; - // } + // TODO is this necessary? style.setProperty always treats value as string, no? + // if (prop.value.length === 1 || prop.value[0].type !== 'Text') { + // value = x`"" + ${value}`; + // } - if (prop_dependencies.size) { - let condition = block.renderer.dirty(Array.from(prop_dependencies)); + if (prop_dependencies.size) { + let condition = block.renderer.dirty(Array.from(prop_dependencies)); - if (block.has_outros) { - condition = x`!#current || ${condition}`; - } + if (block.has_outros) { + condition = x`!#current || ${condition}`; + } - const update = b` + const update = b` if (${condition}) { @set_style(${this.parent.var}, "${prop.key}", ${value}, ${prop.important ? 1 : null}); }`; - block.chunks.update.push(update); - } - } else { - value = string_literal((prop.value[0] ).data); - } + block.chunks.update.push(update); + } + } else { + value = string_literal(prop.value[0].data); + } - block.chunks.hydrate.push( - b`@set_style(${this.parent.var}, "${prop.key}", ${value}, ${prop.important ? 1 : null});` - ); - }); - } + block.chunks.hydrate.push(b`@set_style(${this.parent.var}, "${prop.key}", ${value}, ${prop.important ? 1 : null});`); + }); + } } function optimize_style(value) { - const props = []; - let chunks = value.slice(); + const props = []; + let chunks = value.slice(); - while (chunks.length) { - const chunk = chunks[0]; + while (chunks.length) { + const chunk = chunks[0]; - if (chunk.type !== 'Text') return null; + if (chunk.type !== 'Text') return null; - const key_match = /^\s*([\w-]+):\s*/.exec(chunk.data); - if (!key_match) return null; + const key_match = /^\s*([\w-]+):\s*/.exec(chunk.data); + if (!key_match) return null; - const key = key_match[1]; + const key = key_match[1]; - const offset = key_match.index + key_match[0].length; - const remaining_data = chunk.data.slice(offset); + const offset = key_match.index + key_match[0].length; + const remaining_data = chunk.data.slice(offset); - if (remaining_data) { - chunks[0] = { - start: chunk.start + offset, - end: chunk.end, - type: 'Text', - data: remaining_data - } ; - } else { - chunks.shift(); - } + if (remaining_data) { + chunks[0] = { + start: chunk.start + offset, + end: chunk.end, + type: 'Text', + data: remaining_data, + }; + } else { + chunks.shift(); + } - const result = get_style_value(chunks); + const result = get_style_value(chunks); - props.push({ key, value: result.value, important: result.important }); - chunks = result.chunks; - } + props.push({ key, value: result.value, important: result.important }); + chunks = result.chunks; + } - return props; + return props; } function get_style_value(chunks) { - const value = []; - - let in_url = false; - let quote_mark = null; - let escaped = false; - let closed = false; - - while (chunks.length && !closed) { - const chunk = chunks.shift(); - - if (chunk.type === 'Text') { - let c = 0; - while (c < chunk.data.length) { - const char = chunk.data[c]; - - if (escaped) { - escaped = false; - } else if (char === '\\') { - escaped = true; - } else if (char === quote_mark) { - quote_mark = null; - } else if (char === '"' || char === "'") { - quote_mark = char; - } else if (char === ')' && in_url) { - in_url = false; - } else if (char === 'u' && chunk.data.slice(c, c + 4) === 'url(') { - in_url = true; - } else if (char === ';' && !in_url && !quote_mark) { - closed = true; - break; - } + const value = []; + + let in_url = false; + let quote_mark = null; + let escaped = false; + let closed = false; + + while (chunks.length && !closed) { + const chunk = chunks.shift(); + + if (chunk.type === 'Text') { + let c = 0; + while (c < chunk.data.length) { + const char = chunk.data[c]; + + if (escaped) { + escaped = false; + } else if (char === '\\') { + escaped = true; + } else if (char === quote_mark) { + quote_mark = null; + } else if (char === '"' || char === "'") { + quote_mark = char; + } else if (char === ')' && in_url) { + in_url = false; + } else if (char === 'u' && chunk.data.slice(c, c + 4) === 'url(') { + in_url = true; + } else if (char === ';' && !in_url && !quote_mark) { + closed = true; + break; + } - c += 1; - } + c += 1; + } - if (c > 0) { - value.push({ - type: 'Text', - start: chunk.start, - end: chunk.start + c, - data: chunk.data.slice(0, c) - } ); - } + if (c > 0) { + value.push({ + type: 'Text', + start: chunk.start, + end: chunk.start + c, + data: chunk.data.slice(0, c), + }); + } - while (/[;\s]/.test(chunk.data[c])) c += 1; - const remaining_data = chunk.data.slice(c); + while (/[;\s]/.test(chunk.data[c])) c += 1; + const remaining_data = chunk.data.slice(c); - if (remaining_data) { - chunks.unshift({ - start: chunk.start + c, - end: chunk.end, - type: 'Text', - data: remaining_data - } ); + if (remaining_data) { + chunks.unshift({ + start: chunk.start + c, + end: chunk.end, + type: 'Text', + data: remaining_data, + }); - break; - } - } else { - value.push(chunk); - } - } + break; + } + } else { + value.push(chunk); + } + } - let important = false; + let important = false; - const last_chunk = value[value.length - 1]; - if (last_chunk && last_chunk.type === 'Text' && /\s*!important\s*$/.test(last_chunk.data)) { - important = true; - last_chunk.data = last_chunk.data.replace(/\s*!important\s*$/, ''); - if (!last_chunk.data) value.pop(); - } + const last_chunk = value[value.length - 1]; + if (last_chunk && last_chunk.type === 'Text' && /\s*!important\s*$/.test(last_chunk.data)) { + important = true; + last_chunk.data = last_chunk.data.replace(/\s*!important\s*$/, ''); + if (!last_chunk.data) value.pop(); + } - return { - chunks, - value, - important - }; + return { + chunks, + value, + important, + }; } function is_dynamic(value) { - return value.length > 1 || value[0].type !== 'Text'; + return value.length > 1 || value[0].type !== 'Text'; } class SpreadAttributeWrapper extends BaseAttributeWrapper {} function replace_object(node, replacement) { - if (node.type === 'Identifier') return replacement; + if (node.type === 'Identifier') return replacement; - const ancestor = node; - let parent; - while (node.type === 'MemberExpression') { - parent = node; - node = node.object; - } - parent.object = replacement; - return ancestor; + const ancestor = node; + let parent; + while (node.type === 'MemberExpression') { + parent = node; + node = node.object; + } + parent.object = replacement; + return ancestor; } function flatten_reference(node) { - const nodes = []; - const parts = []; - - while (node.type === 'MemberExpression') { - nodes.unshift(node.property); - - if (!node.computed) { - parts.unshift((node.property ).name); - } else { - const computed_property = to_string$1(node.property); - if (computed_property) { - parts.unshift(`[${computed_property}]`); - } - } - node = node.object; - } + const nodes = []; + const parts = []; + + while (node.type === 'MemberExpression') { + nodes.unshift(node.property); + + if (!node.computed) { + parts.unshift(node.property.name); + } else { + const computed_property = to_string$1(node.property); + if (computed_property) { + parts.unshift(`[${computed_property}]`); + } + } + node = node.object; + } - const name = node.type === 'Identifier' - ? node.name - : node.type === 'ThisExpression' ? 'this' : null; + const name = node.type === 'Identifier' ? node.name : node.type === 'ThisExpression' ? 'this' : null; - nodes.unshift(node); + nodes.unshift(node); - parts.unshift(name); + parts.unshift(name); - return { name, nodes, parts }; + return { name, nodes, parts }; } function to_string$1(node) { - switch (node.type) { - case 'Literal': - return String(node.value); - case 'Identifier': - return node.name; - } -} - -function mark_each_block_bindings( - parent, - binding -) { - // we need to ensure that the each block creates a context including - // the list and the index, if they're not otherwise referenced - binding.expression.references.forEach(name => { - const each_block = parent.node.scope.get_owner(name); - if (each_block) { - (each_block ).has_binding = true; - } - }); - - if (binding.name === 'group') { - const add_index_binding = (name) => { - const each_block = parent.node.scope.get_owner(name); - if (each_block.type === 'EachBlock') { - each_block.has_index_binding = true; - for (const dep of each_block.expression.contextual_dependencies) { - add_index_binding(dep); - } - } - }; - // for `<input bind:group={} >`, we make sure that all the each blocks creates context with `index` - for (const name of binding.expression.contextual_dependencies) { - add_index_binding(name); - } - } + switch (node.type) { + case 'Literal': + return String(node.value); + case 'Identifier': + return node.name; + } } -class BindingWrapper { - - - - - - +function mark_each_block_bindings(parent, binding) { + // we need to ensure that the each block creates a context including + // the list and the index, if they're not otherwise referenced + binding.expression.references.forEach((name) => { + const each_block = parent.node.scope.get_owner(name); + if (each_block) { + each_block.has_binding = true; + } + }); + + if (binding.name === 'group') { + const add_index_binding = (name) => { + const each_block = parent.node.scope.get_owner(name); + if (each_block.type === 'EachBlock') { + each_block.has_index_binding = true; + for (const dep of each_block.expression.contextual_dependencies) { + add_index_binding(dep); + } + } + }; + // for `<input bind:group={} >`, we make sure that all the each blocks creates context with `index` + for (const name of binding.expression.contextual_dependencies) { + add_index_binding(name); + } + } +} +class BindingWrapper { + constructor(block, node, parent) { + this.node = node; + this.parent = parent; + const { dependencies } = this.node.expression; + block.add_dependencies(dependencies); - - - + // TODO does this also apply to e.g. `<input type='checkbox' bind:group='foo'>`? - constructor(block, node, parent) { - this.node = node; - this.parent = parent; + handle_select_value_binding(this, dependencies); - const { dependencies } = this.node.expression; + if (node.is_contextual) { + mark_each_block_bindings(this.parent, this.node); + } - block.add_dependencies(dependencies); + this.object = get_object(this.node.expression.node).name; - // TODO does this also apply to e.g. `<input type='checkbox' bind:group='foo'>`? + // view to model + this.handler = get_event_handler(this, parent.renderer, block, this.object, this.node.raw_expression); - handle_select_value_binding(this, dependencies); + this.snippet = this.node.expression.manipulate(block); - if (node.is_contextual) { - mark_each_block_bindings(this.parent, this.node); - } + this.is_readonly = this.node.is_readonly; - this.object = get_object(this.node.expression.node).name; + this.needs_lock = this.node.name === 'currentTime'; // TODO others? + } - // view to model - this.handler = get_event_handler(this, parent.renderer, block, this.object, this.node.raw_expression); + get_dependencies() { + const dependencies = new Set(this.node.expression.dependencies); - this.snippet = this.node.expression.manipulate(block); + this.node.expression.dependencies.forEach((prop) => { + const indirect_dependencies = this.parent.renderer.component.indirect_dependencies.get(prop); + if (indirect_dependencies) { + indirect_dependencies.forEach((indirect_dependency) => { + dependencies.add(indirect_dependency); + }); + } + }); - this.is_readonly = this.node.is_readonly; + return dependencies; + } - this.needs_lock = this.node.name === 'currentTime'; // TODO others? - } + is_readonly_media_attribute() { + return this.node.is_readonly_media_attribute(); + } - get_dependencies() { - const dependencies = new Set(this.node.expression.dependencies); + render(block, lock) { + if (this.is_readonly) return; - this.node.expression.dependencies.forEach((prop) => { - const indirect_dependencies = this.parent.renderer.component.indirect_dependencies.get(prop); - if (indirect_dependencies) { - indirect_dependencies.forEach(indirect_dependency => { - dependencies.add(indirect_dependency); - }); - } - }); + const { parent } = this; - return dependencies; - } + const update_conditions = this.needs_lock ? [x`!${lock}`] : []; + const mount_conditions = []; - is_readonly_media_attribute() { - return this.node.is_readonly_media_attribute(); - } + const dependency_array = Array.from(this.get_dependencies()); - render(block, lock) { - if (this.is_readonly) return; + if (dependency_array.length > 0) { + update_conditions.push(block.renderer.dirty(dependency_array)); + } - const { parent } = this; + if (parent.node.name === 'input') { + const type = parent.node.get_static_attribute_value('type'); - const update_conditions = this.needs_lock ? [x`!${lock}`] : []; - const mount_conditions = []; + if (type === null || type === '' || type === 'text' || type === 'email' || type === 'password') { + update_conditions.push(x`${parent.var}.${this.node.name} !== ${this.snippet}`); + } else if (type === 'number') { + update_conditions.push(x`@to_number(${parent.var}.${this.node.name}) !== ${this.snippet}`); + } + } - const dependency_array = Array.from(this.get_dependencies()); + // model to view + let update_dom = get_dom_updater(parent, this); + let mount_dom = update_dom; - if (dependency_array.length > 0) { - update_conditions.push(block.renderer.dirty(dependency_array)); - } + // special cases + switch (this.node.name) { + case 'group': { + const { binding_group, is_context, contexts, index, keypath } = get_binding_group(parent.renderer, this.node, block); - if (parent.node.name === 'input') { - const type = parent.node.get_static_attribute_value('type'); - - if ( - type === null || - type === '' || - type === 'text' || - type === 'email' || - type === 'password' - ) { - update_conditions.push( - x`${parent.var}.${this.node.name} !== ${this.snippet}` - ); - } else if (type === 'number') { - update_conditions.push( - x`@to_number(${parent.var}.${this.node.name}) !== ${this.snippet}` - ); - } - } + block.renderer.add_to_context('$$binding_groups'); - // model to view - let update_dom = get_dom_updater(parent, this); - let mount_dom = update_dom; - - // special cases - switch (this.node.name) { - case 'group': - { - const { binding_group, is_context, contexts, index, keypath } = get_binding_group(parent.renderer, this.node, block); - - block.renderer.add_to_context('$$binding_groups'); - - if (is_context && !block.binding_group_initialised.has(keypath)) { - if (contexts.length > 1) { - let binding_group = x`${block.renderer.reference('$$binding_groups')}[${index}]`; - for (const name of contexts.slice(0, -1)) { - binding_group = x`${binding_group}[${block.renderer.reference(name)}]`; - block.chunks.init.push( - b`${binding_group} = ${binding_group} || [];` - ); - } - } - block.chunks.init.push( - b`${binding_group(true)} = [];` - ); - block.binding_group_initialised.add(keypath); - } + if (is_context && !block.binding_group_initialised.has(keypath)) { + if (contexts.length > 1) { + let binding_group = x`${block.renderer.reference('$$binding_groups')}[${index}]`; + for (const name of contexts.slice(0, -1)) { + binding_group = x`${binding_group}[${block.renderer.reference(name)}]`; + block.chunks.init.push(b`${binding_group} = ${binding_group} || [];`); + } + } + block.chunks.init.push(b`${binding_group(true)} = [];`); + block.binding_group_initialised.add(keypath); + } - block.chunks.hydrate.push( - b`${binding_group(true)}.push(${parent.var});` - ); + block.chunks.hydrate.push(b`${binding_group(true)}.push(${parent.var});`); - block.chunks.destroy.push( - b`${binding_group(true)}.splice(${binding_group(true)}.indexOf(${parent.var}), 1);` - ); - break; - } + block.chunks.destroy.push(b`${binding_group(true)}.splice(${binding_group(true)}.indexOf(${parent.var}), 1);`); + break; + } - case 'textContent': - update_conditions.push(x`${this.snippet} !== ${parent.var}.textContent`); - mount_conditions.push(x`${this.snippet} !== void 0`); - break; - - case 'innerHTML': - update_conditions.push(x`${this.snippet} !== ${parent.var}.innerHTML`); - mount_conditions.push(x`${this.snippet} !== void 0`); - break; - - case 'currentTime': - update_conditions.push(x`!@_isNaN(${this.snippet})`); - mount_dom = null; - break; - - case 'playbackRate': - case 'volume': - update_conditions.push(x`!@_isNaN(${this.snippet})`); - mount_conditions.push(x`!@_isNaN(${this.snippet})`); - break; - - case 'paused': - { - // this is necessary to prevent audio restarting by itself - const last = block.get_unique_name(`${parent.var.name}_is_paused`); - block.add_variable(last, x`true`); - - update_conditions.push(x`${last} !== (${last} = ${this.snippet})`); - update_dom = b`${parent.var}[${last} ? "pause" : "play"]();`; - mount_dom = null; - break; - } + case 'textContent': + update_conditions.push(x`${this.snippet} !== ${parent.var}.textContent`); + mount_conditions.push(x`${this.snippet} !== void 0`); + break; + + case 'innerHTML': + update_conditions.push(x`${this.snippet} !== ${parent.var}.innerHTML`); + mount_conditions.push(x`${this.snippet} !== void 0`); + break; + + case 'currentTime': + update_conditions.push(x`!@_isNaN(${this.snippet})`); + mount_dom = null; + break; + + case 'playbackRate': + case 'volume': + update_conditions.push(x`!@_isNaN(${this.snippet})`); + mount_conditions.push(x`!@_isNaN(${this.snippet})`); + break; + + case 'paused': { + // this is necessary to prevent audio restarting by itself + const last = block.get_unique_name(`${parent.var.name}_is_paused`); + block.add_variable(last, x`true`); + + update_conditions.push(x`${last} !== (${last} = ${this.snippet})`); + update_dom = b`${parent.var}[${last} ? "pause" : "play"]();`; + mount_dom = null; + break; + } - case 'value': - if (parent.node.get_static_attribute_value('type') === 'file') { - update_dom = null; - mount_dom = null; - } - } + case 'value': + if (parent.node.get_static_attribute_value('type') === 'file') { + update_dom = null; + mount_dom = null; + } + } - if (update_dom) { - if (update_conditions.length > 0) { - const condition = update_conditions.reduce((lhs, rhs) => x`${lhs} && ${rhs}`); + if (update_dom) { + if (update_conditions.length > 0) { + const condition = update_conditions.reduce((lhs, rhs) => x`${lhs} && ${rhs}`); - block.chunks.update.push(b` + block.chunks.update.push(b` if (${condition}) { ${update_dom} } `); - } else { - block.chunks.update.push(update_dom); - } - } + } else { + block.chunks.update.push(update_dom); + } + } - if (mount_dom) { - if (mount_conditions.length > 0) { - const condition = mount_conditions.reduce((lhs, rhs) => x`${lhs} && ${rhs}`); + if (mount_dom) { + if (mount_conditions.length > 0) { + const condition = mount_conditions.reduce((lhs, rhs) => x`${lhs} && ${rhs}`); - block.chunks.mount.push(b` + block.chunks.mount.push(b` if (${condition}) { ${mount_dom} } `); - } else { - block.chunks.mount.push(mount_dom); - } - } - } + } else { + block.chunks.mount.push(mount_dom); + } + } + } } -function get_dom_updater( - element, - binding -) { - const { node } = element; +function get_dom_updater(element, binding) { + const { node } = element; - if (binding.is_readonly_media_attribute()) { - return null; - } + if (binding.is_readonly_media_attribute()) { + return null; + } - if (binding.node.name === 'this') { - return null; - } + if (binding.node.name === 'this') { + return null; + } - if (node.name === 'select') { - return node.get_static_attribute_value('multiple') === true ? - b`@select_options(${element.var}, ${binding.snippet})` : - b`@select_option(${element.var}, ${binding.snippet})`; - } + if (node.name === 'select') { + return node.get_static_attribute_value('multiple') === true ? b`@select_options(${element.var}, ${binding.snippet})` : b`@select_option(${element.var}, ${binding.snippet})`; + } - if (binding.node.name === 'group') { - const type = node.get_static_attribute_value('type'); + if (binding.node.name === 'group') { + const type = node.get_static_attribute_value('type'); - const condition = type === 'checkbox' - ? x`~${binding.snippet}.indexOf(${element.var}.__value)` - : x`${element.var}.__value === ${binding.snippet}`; + const condition = type === 'checkbox' ? x`~${binding.snippet}.indexOf(${element.var}.__value)` : x`${element.var}.__value === ${binding.snippet}`; - return b`${element.var}.checked = ${condition};`; - } + return b`${element.var}.checked = ${condition};`; + } - if (binding.node.name === 'value') { - return b`@set_input_value(${element.var}, ${binding.snippet});`; - } + if (binding.node.name === 'value') { + return b`@set_input_value(${element.var}, ${binding.snippet});`; + } - return b`${element.var}.${binding.node.name} = ${binding.snippet};`; + return b`${element.var}.${binding.node.name} = ${binding.snippet};`; } function get_binding_group(renderer, value, block) { - const { parts } = flatten_reference(value.raw_expression); - let keypath = parts.join('.'); - - const contexts = []; - const contextual_dependencies = new Set(); - const { template_scope } = value.expression; - const add_contextual_dependency = (dep) => { - contextual_dependencies.add(dep); - const owner = template_scope.get_owner(dep); - if (owner.type === 'EachBlock') { - for (const dep of owner.expression.contextual_dependencies) { - add_contextual_dependency(dep); - } - } - }; - for (const dep of value.expression.contextual_dependencies) { - add_contextual_dependency(dep); - } - - for (const dep of contextual_dependencies) { - const context = block.bindings.get(dep); - let key; - let name; - if (context) { - key = context.object.name; - name = context.property.name; - } else { - key = dep; - name = dep; - } - keypath = `${key}@${keypath}`; - contexts.push(name); - } + const { parts } = flatten_reference(value.raw_expression); + let keypath = parts.join('.'); + + const contexts = []; + const contextual_dependencies = new Set(); + const { template_scope } = value.expression; + const add_contextual_dependency = (dep) => { + contextual_dependencies.add(dep); + const owner = template_scope.get_owner(dep); + if (owner.type === 'EachBlock') { + for (const dep of owner.expression.contextual_dependencies) { + add_contextual_dependency(dep); + } + } + }; + for (const dep of value.expression.contextual_dependencies) { + add_contextual_dependency(dep); + } - if (!renderer.binding_groups.has(keypath)) { - const index = renderer.binding_groups.size; + for (const dep of contextual_dependencies) { + const context = block.bindings.get(dep); + let key; + let name; + if (context) { + key = context.object.name; + name = context.property.name; + } else { + key = dep; + name = dep; + } + keypath = `${key}@${keypath}`; + contexts.push(name); + } - contexts.forEach(context => { - renderer.add_to_context(context, true); - }); + if (!renderer.binding_groups.has(keypath)) { + const index = renderer.binding_groups.size; - renderer.binding_groups.set(keypath, { - binding_group: (to_reference = false) => { - let binding_group = '$$binding_groups'; - let _secondary_indexes = contexts; + contexts.forEach((context) => { + renderer.add_to_context(context, true); + }); - if (to_reference) { - binding_group = block.renderer.reference(binding_group); - _secondary_indexes = _secondary_indexes.map(name => block.renderer.reference(name)); - } + renderer.binding_groups.set(keypath, { + binding_group: (to_reference = false) => { + let binding_group = '$$binding_groups'; + let _secondary_indexes = contexts; - if (_secondary_indexes.length > 0) { - let obj = x`${binding_group}[${index}]`; - _secondary_indexes.forEach(secondary_index => { - obj = x`${obj}[${secondary_index}]`; - }); - return obj; - } else { - return x`${binding_group}[${index}]`; - } - }, - is_context: contexts.length > 0, - contexts, - index, - keypath - }); - } + if (to_reference) { + binding_group = block.renderer.reference(binding_group); + _secondary_indexes = _secondary_indexes.map((name) => block.renderer.reference(name)); + } - return renderer.binding_groups.get(keypath); + if (_secondary_indexes.length > 0) { + let obj = x`${binding_group}[${index}]`; + _secondary_indexes.forEach((secondary_index) => { + obj = x`${obj}[${secondary_index}]`; + }); + return obj; + } else { + return x`${binding_group}[${index}]`; + } + }, + is_context: contexts.length > 0, + contexts, + index, + keypath, + }); + } + + return renderer.binding_groups.get(keypath); } -function get_event_handler( - binding, - renderer, - block, - name, - lhs -) +function get_event_handler(binding, renderer, block, name, lhs) { + const contextual_dependencies = new Set(binding.node.expression.contextual_dependencies); + const context = block.bindings.get(name); + let set_store; + if (context) { + const { object, property, store, snippet } = context; + lhs = replace_object(lhs, snippet); + contextual_dependencies.add(object.name); + contextual_dependencies.add(property.name); + contextual_dependencies.delete(name); + if (store) { + set_store = b`${store}.set(${`$${store}`});`; + } + } else { + const object = get_object(lhs); + if (object.name[0] === '$') { + const store = object.name.slice(1); + set_store = b`${store}.set(${object.name});`; + } + } - { - const contextual_dependencies = new Set(binding.node.expression.contextual_dependencies); + const value = get_value_from_dom(renderer, binding.parent, binding, block, contextual_dependencies); - const context = block.bindings.get(name); - let set_store; + const mutation = b` + ${lhs} = ${value}; + ${set_store} + `; - if (context) { - const { object, property, store, snippet } = context; - lhs = replace_object(lhs, snippet); - contextual_dependencies.add(object.name); - contextual_dependencies.add(property.name); - contextual_dependencies.delete(name); + return { + uses_context: binding.node.is_contextual || binding.node.expression.uses_context, // TODO this is messy + mutation, + contextual_dependencies, + lhs, + }; +} - if (store) { - set_store = b`${store}.set(${`$${store}`});`; - } - } else { - const object = get_object(lhs); - if (object.name[0] === '$') { - const store = object.name.slice(1); - set_store = b`${store}.set(${object.name});`; - } - } +function get_value_from_dom(renderer, element, binding, block, contextual_dependencies) { + const { node } = element; + const { name } = binding.node; - const value = get_value_from_dom(renderer, binding.parent, binding, block, contextual_dependencies); + if (name === 'this') { + return x`$$value`; + } - const mutation = b` - ${lhs} = ${value}; - ${set_store} - `; + // <select bind:value='selected> + if (node.name === 'select') { + return node.get_static_attribute_value('multiple') === true ? x`@select_multiple_value(this)` : x`@select_value(this)`; + } - return { - uses_context: binding.node.is_contextual || binding.node.expression.uses_context, // TODO this is messy - mutation, - contextual_dependencies, - lhs - }; -} - -function get_value_from_dom( - renderer, - element, - binding, - block, - contextual_dependencies -) { - const { node } = element; - const { name } = binding.node; - - if (name === 'this') { - return x`$$value`; - } - - // <select bind:value='selected> - if (node.name === 'select') { - return node.get_static_attribute_value('multiple') === true ? - x`@select_multiple_value(this)` : - x`@select_value(this)`; - } - - const type = node.get_static_attribute_value('type'); - - // <input type='checkbox' bind:group='foo'> - if (name === 'group') { - if (type === 'checkbox') { - const { binding_group, contexts } = get_binding_group(renderer, binding.node, block); - add_to_set(contextual_dependencies, contexts); - return x`@get_binding_group_value(${binding_group()}, this.__value, this.checked)`; - } + const type = node.get_static_attribute_value('type'); - return x`this.__value`; - } + // <input type='checkbox' bind:group='foo'> + if (name === 'group') { + if (type === 'checkbox') { + const { binding_group, contexts } = get_binding_group(renderer, binding.node, block); + add_to_set(contextual_dependencies, contexts); + return x`@get_binding_group_value(${binding_group()}, this.__value, this.checked)`; + } - // <input type='range|number' bind:value> - if (type === 'range' || type === 'number') { - return x`@to_number(this.${name})`; - } + return x`this.__value`; + } - if ((name === 'buffered' || name === 'seekable' || name === 'played')) { - return x`@time_ranges_to_array(this.${name})`; - } + // <input type='range|number' bind:value> + if (type === 'range' || type === 'number') { + return x`@to_number(this.${name})`; + } + + if (name === 'buffered' || name === 'seekable' || name === 'played') { + return x`@time_ranges_to_array(this.${name})`; + } - // everything else - return x`this.${name}`; + // everything else + return x`this.${name}`; } const reserved_keywords = new Set(['$$props', '$$restProps', '$$slots']); function is_reserved_keyword(name) { - return reserved_keywords.has(name); + return reserved_keywords.has(name); } function is_contextual(component, scope, name) { - if (is_reserved_keyword(name)) return true; + 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; + // 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); + const variable = component.var_lookup.get(name); - // hoistables, module declarations, and imports are non-contextual - if (!variable || variable.hoistable) return false; + // hoistables, module declarations, and imports are non-contextual + if (!variable || variable.hoistable) return false; - // assume contextual - return true; + // assume contextual + return true; } -function add_actions( - block, - target, - actions -) { - actions.forEach(action => add_action(block, target, action)); +function add_actions(block, target, actions) { + actions.forEach((action) => add_action(block, target, action)); } function add_action(block, target, action) { - const { expression, template_scope } = action; - let snippet; - let dependencies; - - if (expression) { - snippet = expression.manipulate(block); - dependencies = expression.dynamic_dependencies(); - } - - const id = block.get_unique_name( - `${action.name.replace(/[^a-zA-Z0-9_$]/g, '_')}_action` - ); - - block.add_variable(id); - - const [obj, ...properties] = action.name.split('.'); - - const fn = is_contextual(action.component, template_scope, obj) - ? block.renderer.reference(obj) - : obj; - - if (properties.length) { - const member_expression = properties.reduce((lhs, rhs) => x`${lhs}.${rhs}`, fn); - block.event_listeners.push( - x`@action_destroyer(${id} = ${member_expression}(${target}, ${snippet}))` - ); - } else { - block.event_listeners.push( - x`@action_destroyer(${id} = ${fn}.call(null, ${target}, ${snippet}))` - ); - } - - if (dependencies && dependencies.length > 0) { - let condition = x`${id} && @is_function(${id}.update)`; - - if (dependencies.length > 0) { - condition = x`${condition} && ${block.renderer.dirty(dependencies)}`; - } + const { expression, template_scope } = action; + let snippet; + let dependencies; + + if (expression) { + snippet = expression.manipulate(block); + dependencies = expression.dynamic_dependencies(); + } + + const id = block.get_unique_name(`${action.name.replace(/[^a-zA-Z0-9_$]/g, '_')}_action`); + + block.add_variable(id); + + const [obj, ...properties] = action.name.split('.'); + + const fn = is_contextual(action.component, template_scope, obj) ? block.renderer.reference(obj) : obj; + + if (properties.length) { + const member_expression = properties.reduce((lhs, rhs) => x`${lhs}.${rhs}`, fn); + block.event_listeners.push(x`@action_destroyer(${id} = ${member_expression}(${target}, ${snippet}))`); + } else { + block.event_listeners.push(x`@action_destroyer(${id} = ${fn}.call(null, ${target}, ${snippet}))`); + } - block.chunks.update.push( - b`if (${condition}) ${id}.update.call(null, ${snippet});` - ); - } + if (dependencies && dependencies.length > 0) { + let condition = x`${id} && @is_function(${id}.update)`; + + if (dependencies.length > 0) { + condition = x`${condition} && ${block.renderer.dirty(dependencies)}`; + } + + block.chunks.update.push(b`if (${condition}) ${id}.update.call(null, ${snippet});`); + } } function compare_node(a, b) { - if (a === b) return true; - if (!a || !b) return false; - if (a.type !== b.type) return false; - switch (a.type) { - case 'Identifier': - return a.name === (b ).name; - case 'MemberExpression': - return ( - compare_node(a.object, (b ).object) && - compare_node(a.property, (b ).property) && - a.computed === (b ).computed - ); - case 'Literal': - return a.value === (b ).value; - } + if (a === b) return true; + if (!a || !b) return false; + if (a.type !== b.type) return false; + switch (a.type) { + case 'Identifier': + return a.name === b.name; + case 'MemberExpression': + return compare_node(a.object, b.object) && compare_node(a.property, b.property) && a.computed === b.computed; + case 'Literal': + return a.value === b.value; + } } function bind_this(component, block, binding, variable) { - const fn = component.get_unique_name(`${variable.name}_binding`); + const fn = component.get_unique_name(`${variable.name}_binding`); - block.renderer.add_to_context(fn.name); - const callee = block.renderer.reference(fn.name); + block.renderer.add_to_context(fn.name); + const callee = block.renderer.reference(fn.name); - const { contextual_dependencies, mutation } = binding.handler; - const dependencies = binding.get_dependencies(); + const { contextual_dependencies, mutation } = binding.handler; + const dependencies = binding.get_dependencies(); - const body = b` + const body = b` ${mutation} ${Array.from(dependencies) - .filter(dep => dep[0] !== '$') - .filter(dep => !contextual_dependencies.has(dep)) - .map(dep => b`${block.renderer.invalidate(dep)};`)} + .filter((dep) => dep[0] !== '$') + .filter((dep) => !contextual_dependencies.has(dep)) + .map((dep) => b`${block.renderer.invalidate(dep)};`)} `; - if (contextual_dependencies.size) { - const params = Array.from(contextual_dependencies).map(name => ({ - type: 'Identifier', - name - })); - component.partly_hoisted.push(b` + if (contextual_dependencies.size) { + const params = Array.from(contextual_dependencies).map((name) => ({ + type: 'Identifier', + name, + })); + component.partly_hoisted.push(b` function ${fn}($$value, ${params}) { @binding_callbacks[$$value ? 'unshift' : 'push'](() => { ${body} @@ -10243,56 +9563,51 @@ function bind_this(component, block, binding, variable) { } `); - const alias_map = new Map(); - const args = []; - for (let id of params) { - const value = block.renderer.reference(id.name); - let found = false; - if (block.variables.has(id.name)) { - let alias = id.name; - for ( - let i = 1; - block.variables.has(alias) && !compare_node(block.variables.get(alias).init, value); - alias = `${id.name}_${i++}` - ); - alias_map.set(alias, id.name); - id = { type: 'Identifier', name: alias }; - found = block.variables.has(alias); - } - args.push(id); - if (!found) { - block.add_variable(id, value); - } - } + const alias_map = new Map(); + const args = []; + for (let id of params) { + const value = block.renderer.reference(id.name); + let found = false; + if (block.variables.has(id.name)) { + let alias = id.name; + for (let i = 1; block.variables.has(alias) && !compare_node(block.variables.get(alias).init, value); alias = `${id.name}_${i++}`); + alias_map.set(alias, id.name); + id = { type: 'Identifier', name: alias }; + found = block.variables.has(alias); + } + args.push(id); + if (!found) { + block.add_variable(id, value); + } + } - const assign = block.get_unique_name(`assign_${variable.name}`); - const unassign = block.get_unique_name(`unassign_${variable.name}`); + const assign = block.get_unique_name(`assign_${variable.name}`); + const unassign = block.get_unique_name(`unassign_${variable.name}`); - block.chunks.init.push(b` + block.chunks.init.push(b` const ${assign} = () => ${callee}(${variable}, ${args}); const ${unassign} = () => ${callee}(null, ${args}); `); - const condition = Array.from(args) - .map(name => x`${name} !== ${block.renderer.reference(alias_map.get(name.name) || name.name)}`) - .reduce((lhs, rhs) => x`${lhs} || ${rhs}`); + const condition = Array.from(args) + .map((name) => x`${name} !== ${block.renderer.reference(alias_map.get(name.name) || name.name)}`) + .reduce((lhs, rhs) => x`${lhs} || ${rhs}`); - // we push unassign and unshift assign so that references are - // nulled out before they're created, to avoid glitches - // with shifting indices - block.chunks.update.push(b` + // we push unassign and unshift assign so that references are + // nulled out before they're created, to avoid glitches + // with shifting indices + block.chunks.update.push(b` if (${condition}) { ${unassign}(); - ${args.map(a => b`${a} = ${block.renderer.reference(alias_map.get(a.name) || a.name)}`)}; + ${args.map((a) => b`${a} = ${block.renderer.reference(alias_map.get(a.name) || a.name)}`)}; ${assign}(); - }` - ); + }`); - block.chunks.destroy.push(b`${unassign}();`); - return b`${assign}();`; - } + block.chunks.destroy.push(b`${unassign}();`); + return b`${assign}();`; + } - component.partly_hoisted.push(b` + component.partly_hoisted.push(b` function ${fn}($$value) { @binding_callbacks[$$value ? 'unshift' : 'push'](() => { ${body} @@ -10300,1258 +9615,1118 @@ function bind_this(component, block, binding, variable) { } `); - block.chunks.destroy.push(b`${callee}(null);`); - return b`${callee}(${variable});`; + block.chunks.destroy.push(b`${callee}(null);`); + return b`${callee}(${variable});`; } class Node { - - - - - - - - - - - - - - constructor(component, parent, _scope, info) { - this.start = info.start; - this.end = info.end; - this.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 - } - }); - } + constructor(component, parent, _scope, info) { + this.start = info.start; + this.end = info.end; + this.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, + }, + }); + } - cannot_use_innerhtml() { - if (this.can_use_innerhtml !== false) { - this.can_use_innerhtml = false; - if (this.parent) this.parent.cannot_use_innerhtml(); - } - } + cannot_use_innerhtml() { + if (this.can_use_innerhtml !== false) { + this.can_use_innerhtml = false; + if (this.parent) this.parent.cannot_use_innerhtml(); + } + } - find_nearest(selector) { - if (selector.test(this.type)) return this; - if (this.parent) return this.parent.find_nearest(selector); - } + find_nearest(selector) { + if (selector.test(this.type)) return this; + if (this.parent) return this.parent.find_nearest(selector); + } - get_static_attribute_value(name) { - const attribute = this.attributes && this.attributes.find( - (attr) => attr.type === 'Attribute' && attr.name.toLowerCase() === name - ); + get_static_attribute_value(name) { + const attribute = this.attributes && this.attributes.find((attr) => attr.type === 'Attribute' && attr.name.toLowerCase() === name); - if (!attribute) return null; + if (!attribute) return null; - if (attribute.is_true) return true; - if (attribute.chunks.length === 0) return ''; + if (attribute.is_true) return true; + if (attribute.chunks.length === 0) return ''; - if (attribute.chunks.length === 1 && attribute.chunks[0].type === 'Text') { - return (attribute.chunks[0] ).data; - } + if (attribute.chunks.length === 1 && attribute.chunks[0].type === 'Text') { + return attribute.chunks[0].data; + } - return null; - } + return null; + } - has_ancestor(type) { - return this.parent ? - this.parent.type === type || this.parent.has_ancestor(type) : - false; - } + has_ancestor(type) { + return this.parent ? this.parent.type === type || this.parent.has_ancestor(type) : false; + } } function create_scopes(expression) { - return analyze(expression); + return analyze(expression); } function is_dynamic$1(variable) { - if (variable) { - if (variable.mutated || variable.reassigned) return true; // dynamic internal state - if (!variable.module && variable.writable && variable.export_name) return true; // writable props - if (is_reserved_keyword(variable.name)) return true; - } + if (variable) { + if (variable.mutated || variable.reassigned) return true; // dynamic internal state + if (!variable.module && variable.writable && variable.export_name) return true; // writable props + if (is_reserved_keyword(variable.name)) return true; + } - return false; + return false; } function nodes_match(a, b) { - if (!!a !== !!b) return false; - if (Array.isArray(a) !== Array.isArray(b)) return false; + if (!!a !== !!b) return false; + if (Array.isArray(a) !== Array.isArray(b)) return false; - if (a && typeof a === 'object') { - if (Array.isArray(a)) { - if (a.length !== b.length) return false; - return a.every((child, i) => nodes_match(child, b[i])); - } + if (a && typeof a === 'object') { + if (Array.isArray(a)) { + if (a.length !== b.length) return false; + return a.every((child, i) => nodes_match(child, b[i])); + } - const a_keys = Object.keys(a).sort(); - const b_keys = Object.keys(b).sort(); + const a_keys = Object.keys(a).sort(); + const b_keys = Object.keys(b).sort(); - if (a_keys.length !== b_keys.length) return false; + if (a_keys.length !== b_keys.length) return false; - let i = a_keys.length; - while (i--) { - const key = a_keys[i]; - if (b_keys[i] !== key) return false; + let i = a_keys.length; + while (i--) { + const key = a_keys[i]; + if (b_keys[i] !== key) return false; - if (key === 'start' || key === 'end') continue; + if (key === 'start' || key === 'end') continue; - if (!nodes_match(a[key], b[key])) { - return false; - } - } + if (!nodes_match(a[key], b[key])) { + return false; + } + } - return true; - } + return true; + } - return a === b; + return a === b; } function invalidate(renderer, scope, node, names, main_execution_context = false) { - const { component } = renderer; - - const [head, ...tail] = Array.from(names) - .filter(name => { - const owner = scope.find_owner(name); - return !owner || owner === component.instance_scope; - }) - .map(name => component.var_lookup.get(name)) - .filter(variable => { - return variable && ( - !variable.hoistable && - !variable.global && - !variable.module && - ( - variable.referenced || - variable.subscribable || - variable.is_reactive_dependency || - variable.export_name || - variable.name[0] === '$' - ) - ); - }) ; - - function get_invalidated(variable, node) { - if (main_execution_context && !variable.subscribable && variable.name[0] !== '$') { - return node; - } - return renderer_invalidate(renderer, variable.name, undefined, main_execution_context); - } - - if (!head) { - return node; - } - - component.has_reactive_assignments = true; - - if (node.type === 'AssignmentExpression' && node.operator === '=' && nodes_match(node.left, node.right) && tail.length === 0) { - return get_invalidated(head, node); - } - - const is_store_value = head.name[0] === '$' && head.name[1] !== '$'; - const extra_args = tail.map(variable => get_invalidated(variable)).filter(Boolean); - - if (is_store_value) { - return x`@set_store_value(${head.name.slice(1)}, ${node}, ${head.name}, ${extra_args})`; - } - - let invalidate; - if (!main_execution_context) { - const pass_value = ( - extra_args.length > 0 || - (node.type === 'AssignmentExpression' && node.left.type !== 'Identifier') || - (node.type === 'UpdateExpression' && (!node.prefix || node.argument.type !== 'Identifier')) - ); - if (pass_value) { - extra_args.unshift({ - type: 'Identifier', - name: head.name - }); - } - invalidate = x`$$invalidate(${renderer.context_lookup.get(head.name).index}, ${node}, ${extra_args})`; - } else { - // skip `$$invalidate` if it is in the main execution context - invalidate = extra_args.length ? [node, ...extra_args] : node; - } + const { component } = renderer; + + const [head, ...tail] = Array.from(names) + .filter((name) => { + const owner = scope.find_owner(name); + return !owner || owner === component.instance_scope; + }) + .map((name) => component.var_lookup.get(name)) + .filter((variable) => { + return ( + variable && + !variable.hoistable && + !variable.global && + !variable.module && + (variable.referenced || variable.subscribable || variable.is_reactive_dependency || variable.export_name || variable.name[0] === '$') + ); + }); + + function get_invalidated(variable, node) { + if (main_execution_context && !variable.subscribable && variable.name[0] !== '$') { + return node; + } + return renderer_invalidate(renderer, variable.name, undefined, main_execution_context); + } + + if (!head) { + return node; + } + + component.has_reactive_assignments = true; + + if (node.type === 'AssignmentExpression' && node.operator === '=' && nodes_match(node.left, node.right) && tail.length === 0) { + return get_invalidated(head, node); + } + + const is_store_value = head.name[0] === '$' && head.name[1] !== '$'; + const extra_args = tail.map((variable) => get_invalidated(variable)).filter(Boolean); + + if (is_store_value) { + return x`@set_store_value(${head.name.slice(1)}, ${node}, ${head.name}, ${extra_args})`; + } + + let invalidate; + if (!main_execution_context) { + const pass_value = + extra_args.length > 0 || + (node.type === 'AssignmentExpression' && node.left.type !== 'Identifier') || + (node.type === 'UpdateExpression' && (!node.prefix || node.argument.type !== 'Identifier')); + if (pass_value) { + extra_args.unshift({ + type: 'Identifier', + name: head.name, + }); + } + invalidate = x`$$invalidate(${renderer.context_lookup.get(head.name).index}, ${node}, ${extra_args})`; + } else { + // skip `$$invalidate` if it is in the main execution context + invalidate = extra_args.length ? [node, ...extra_args] : node; + } - if (head.subscribable && head.reassigned) { - const subscribe = `$$subscribe_${head.name}`; - invalidate = x`${subscribe}(${invalidate})`; - } + if (head.subscribable && head.reassigned) { + const subscribe = `$$subscribe_${head.name}`; + invalidate = x`${subscribe}(${invalidate})`; + } - return invalidate; + return invalidate; } function renderer_invalidate(renderer, name, value, main_execution_context = false) { - const variable = renderer.component.var_lookup.get(name); - - if (variable && (variable.subscribable && (variable.reassigned || variable.export_name))) { - if (main_execution_context) { - return x`${`$$subscribe_${name}`}(${value || name})`; - } else { - const member = renderer.context_lookup.get(name); - return x`${`$$subscribe_${name}`}($$invalidate(${member.index}, ${value || name}))`; - } - } - - if (name[0] === '$' && name[1] !== '$') { - return x`${name.slice(1)}.set(${value || name})`; - } - - if ( - variable && ( - variable.module || ( - !variable.referenced && - !variable.is_reactive_dependency && - !variable.export_name && - !name.startsWith('$$') - ) - ) - ) { - return value || name; - } - - if (value) { - if (main_execution_context) { - return x`${value}`; - } else { - const member = renderer.context_lookup.get(name); - return x`$$invalidate(${member.index}, ${value})`; - } - } + const variable = renderer.component.var_lookup.get(name); + + if (variable && variable.subscribable && (variable.reassigned || variable.export_name)) { + if (main_execution_context) { + return x`${`$$subscribe_${name}`}(${value || name})`; + } else { + const member = renderer.context_lookup.get(name); + return x`${`$$subscribe_${name}`}($$invalidate(${member.index}, ${value || name}))`; + } + } - if (main_execution_context) return; + if (name[0] === '$' && name[1] !== '$') { + return x`${name.slice(1)}.set(${value || name})`; + } - // if this is a reactive declaration, invalidate dependencies recursively - const deps = new Set([name]); + if (variable && (variable.module || (!variable.referenced && !variable.is_reactive_dependency && !variable.export_name && !name.startsWith('$$')))) { + return value || name; + } - deps.forEach(name => { - const reactive_declarations = renderer.component.reactive_declarations.filter(x => - x.assignees.has(name) - ); - reactive_declarations.forEach(declaration => { - declaration.dependencies.forEach(name => { - deps.add(name); - }); - }); - }); + if (value) { + if (main_execution_context) { + return x`${value}`; + } else { + const member = renderer.context_lookup.get(name); + return x`$$invalidate(${member.index}, ${value})`; + } + } - // TODO ideally globals etc wouldn't be here in the first place - const filtered = Array.from(deps).filter(n => renderer.context_lookup.has(n)); - if (!filtered.length) return null; + if (main_execution_context) return; - return filtered - .map(n => x`$$invalidate(${renderer.context_lookup.get(n).index}, ${n})`) - .reduce((lhs, rhs) => x`${lhs}, ${rhs}`); + // if this is a reactive declaration, invalidate dependencies recursively + const deps = new Set([name]); + + deps.forEach((name) => { + const reactive_declarations = renderer.component.reactive_declarations.filter((x) => x.assignees.has(name)); + reactive_declarations.forEach((declaration) => { + declaration.dependencies.forEach((name) => { + deps.add(name); + }); + }); + }); + + // TODO ideally globals etc wouldn't be here in the first place + const filtered = Array.from(deps).filter((n) => renderer.context_lookup.has(n)); + if (!filtered.length) return null; + + return filtered.map((n) => x`$$invalidate(${renderer.context_lookup.get(n).index}, ${n})`).reduce((lhs, rhs) => x`${lhs}, ${rhs}`); } class Expression { - __init() {this.type = 'Expression';} - - - - __init2() {this.references = new Set();} - __init3() {this.dependencies = new Set();} - __init4() {this.contextual_dependencies = new Set();} - - - - - - __init5() {this.declarations = [];} - __init6() {this.uses_context = false;} - - - - constructor(component, owner, template_scope, info, lazy) {Expression.prototype.__init.call(this);Expression.prototype.__init2.call(this);Expression.prototype.__init3.call(this);Expression.prototype.__init4.call(this);Expression.prototype.__init5.call(this);Expression.prototype.__init6.call(this); - // TODO revert to direct property access in prod? - Object.defineProperties(this, { - component: { - value: component - } - }); + __init() { + this.type = 'Expression'; + } - this.node = info; - this.template_scope = template_scope; - this.owner = owner; + __init2() { + this.references = new Set(); + } + __init3() { + this.dependencies = new Set(); + } + __init4() { + this.contextual_dependencies = new Set(); + } - const { dependencies, contextual_dependencies, references } = this; + __init5() { + this.declarations = []; + } + __init6() { + this.uses_context = false; + } - let { map, scope } = create_scopes(info); - this.scope = scope; - this.scope_map = map; + constructor(component, owner, template_scope, info, lazy) { + Expression.prototype.__init.call(this); + Expression.prototype.__init2.call(this); + Expression.prototype.__init3.call(this); + Expression.prototype.__init4.call(this); + Expression.prototype.__init5.call(this); + Expression.prototype.__init6.call(this); + // TODO revert to direct property access in prod? + Object.defineProperties(this, { + component: { + value: component, + }, + }); - const expression = this; - let function_expression; + this.node = info; + this.template_scope = template_scope; + this.owner = owner; - // discover dependencies, but don't change the code yet - walk(info, { - enter(node, parent, key) { - // don't manipulate shorthand props twice - if (key === 'value' && parent.shorthand) return; - // don't manipulate `import.meta`, `new.target` - if (node.type === 'MetaProperty') return this.skip(); + const { dependencies, contextual_dependencies, references } = this; - if (map.has(node)) { - scope = map.get(node); - } + let { map, scope } = create_scopes(info); + this.scope = scope; + this.scope_map = map; - if (!function_expression && /FunctionExpression/.test(node.type)) { - function_expression = node; - } + const expression = this; + let function_expression; - if (isReference(node, parent)) { - const { name, nodes } = flatten_reference(node); - references.add(name); + // discover dependencies, but don't change the code yet + walk(info, { + enter(node, parent, key) { + // don't manipulate shorthand props twice + if (key === 'value' && parent.shorthand) return; + // don't manipulate `import.meta`, `new.target` + if (node.type === 'MetaProperty') return this.skip(); - if (scope.has(name)) return; + if (map.has(node)) { + scope = map.get(node); + } - if (name[0] === '$') { - const store_name = name.slice(1); - if (template_scope.names.has(store_name) || scope.has(store_name)) { - component.error(node, { - code: 'contextual-store', - message: 'Stores must be declared at the top level of the component (this may change in a future version of Svelte)' - }); - } - } + if (!function_expression && /FunctionExpression/.test(node.type)) { + function_expression = node; + } - if (template_scope.is_let(name)) { - if (!function_expression) { // TODO should this be `!lazy` ? - contextual_dependencies.add(name); - dependencies.add(name); - } - } else if (template_scope.names.has(name)) { - expression.uses_context = true; + if (isReference(node, parent)) { + const { name, nodes } = flatten_reference(node); + references.add(name); - contextual_dependencies.add(name); + if (scope.has(name)) return; - const owner = template_scope.get_owner(name); - const is_index = owner.type === 'EachBlock' && owner.key && name === owner.index; + if (name[0] === '$') { + const store_name = name.slice(1); + if (template_scope.names.has(store_name) || scope.has(store_name)) { + component.error(node, { + code: 'contextual-store', + message: 'Stores must be declared at the top level of the component (this may change in a future version of Svelte)', + }); + } + } - if (!lazy || is_index) { - template_scope.dependencies_for_name.get(name).forEach(name => dependencies.add(name)); - } - } else { - if (!lazy) { - dependencies.add(name); - } + if (template_scope.is_let(name)) { + if (!function_expression) { + // TODO should this be `!lazy` ? + contextual_dependencies.add(name); + dependencies.add(name); + } + } else if (template_scope.names.has(name)) { + expression.uses_context = true; - component.add_reference(name); - component.warn_if_undefined(name, nodes[0], template_scope); - } + contextual_dependencies.add(name); - this.skip(); - } + const owner = template_scope.get_owner(name); + const is_index = owner.type === 'EachBlock' && owner.key && name === owner.index; - // track any assignments from template expressions as mutable - let names; - let deep = false; + if (!lazy || is_index) { + template_scope.dependencies_for_name.get(name).forEach((name) => dependencies.add(name)); + } + } else { + if (!lazy) { + dependencies.add(name); + } - 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') { - names = extract_names(get_object(node.argument)); - } - } + component.add_reference(name); + component.warn_if_undefined(name, nodes[0], template_scope); + } - if (names) { - names.forEach(name => { - if (template_scope.names.has(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); - (each_block ).has_binding = true; - } else { - component.add_reference(name); + this.skip(); + } - const variable = component.var_lookup.get(name); - if (variable) variable[deep ? 'mutated' : 'reassigned'] = true; - } - }); - } - }, + // track any assignments from template expressions as mutable + let names; + let deep = false; - leave(node) { - if (map.has(node)) { - scope = scope.parent; - } + 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') { + names = extract_names(get_object(node.argument)); + } + } - if (node === function_expression) { - function_expression = null; - } - } - }); - } + if (names) { + names.forEach((name) => { + if (template_scope.names.has(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); + each_block.has_binding = true; + } else { + component.add_reference(name); - 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 = component.var_lookup.get(name); + if (variable) variable[deep ? 'mutated' : 'reassigned'] = true; + } + }); + } + }, - const variable = this.component.var_lookup.get(name); - return is_dynamic$1(variable); - }); - } - - // TODO move this into a render-dom wrapper? - manipulate(block) { - // 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; - - let function_expression; - - let dependencies; - let contextual_dependencies; - - const node = walk(this.node, { - enter(node, parent) { - if (node.type === 'Property' && node.shorthand) { - node.value = JSON.parse(JSON.stringify(node.value)); - node.shorthand = false; - } + leave(node) { + if (map.has(node)) { + scope = scope.parent; + } - if (map.has(node)) { - scope = map.get(node); - } + if (node === function_expression) { + function_expression = null; + } + }, + }); + } - if (node.type === 'Identifier' && isReference(node, parent)) { - const { name } = flatten_reference(node); + 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; - if (scope.has(name)) return; + const variable = this.component.var_lookup.get(name); + return is_dynamic$1(variable); + }); + } - if (function_expression) { - if (template_scope.names.has(name)) { - contextual_dependencies.add(name); + // TODO move this into a render-dom wrapper? + manipulate(block) { + // TODO ideally we wouldn't end up calling this method + // multiple times + if (this.manipulated) return this.manipulated; - template_scope.dependencies_for_name.get(name).forEach(dependency => { - dependencies.add(dependency); - }); - } else { - dependencies.add(name); - component.add_reference(name); // TODO is this redundant/misplaced? - } - } else if (is_contextual(component, template_scope, name)) { - const reference = block.renderer.reference(node); - this.replace(reference); - } + const { component, declarations, scope_map: map, template_scope, owner } = this; + let scope = this.scope; - this.skip(); - } + let function_expression; - if (!function_expression) { - if (node.type === 'AssignmentExpression') ; + let dependencies; + let contextual_dependencies; - if (node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') { - function_expression = node; - dependencies = new Set(); - contextual_dependencies = new Set(); - } - } - }, + const node = walk(this.node, { + enter(node, parent) { + if (node.type === 'Property' && node.shorthand) { + node.value = JSON.parse(JSON.stringify(node.value)); + node.shorthand = false; + } - leave(node, parent) { - if (map.has(node)) scope = scope.parent; + if (map.has(node)) { + scope = map.get(node); + } - if (node === function_expression) { - const id = component.get_unique_name( - sanitize(get_function_name(node, owner)) - ); + if (node.type === 'Identifier' && isReference(node, parent)) { + const { name } = flatten_reference(node); - const declaration = b`const ${id} = ${node}`; + if (scope.has(name)) return; - if (dependencies.size === 0 && contextual_dependencies.size === 0) { - // we can hoist this out of the component completely - component.fully_hoisted.push(declaration); + if (function_expression) { + if (template_scope.names.has(name)) { + contextual_dependencies.add(name); - this.replace(id ); + template_scope.dependencies_for_name.get(name).forEach((dependency) => { + dependencies.add(dependency); + }); + } else { + dependencies.add(name); + component.add_reference(name); // TODO is this redundant/misplaced? + } + } else if (is_contextual(component, template_scope, name)) { + const reference = block.renderer.reference(node); + this.replace(reference); + } - component.add_var({ - 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); + this.skip(); + } - block.renderer.add_to_context(id.name); - this.replace(block.renderer.reference(id)); - } else { - // we need a combo block/init recipe - const deps = Array.from(contextual_dependencies); - const function_expression = node ; - - const has_args = function_expression.params.length > 0; - function_expression.params = [ - ...deps.map(name => ({ type: 'Identifier', name } )), - ...function_expression.params - ]; + if (!function_expression) { + if (node.type === 'AssignmentExpression'); - const context_args = deps.map(name => block.renderer.reference(name)); + if (node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') { + function_expression = node; + dependencies = new Set(); + contextual_dependencies = new Set(); + } + } + }, + + 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}`; - component.partly_hoisted.push(declaration); + 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({ + 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 = Array.from(contextual_dependencies); + const function_expression = node; - block.renderer.add_to_context(id.name); - const callee = block.renderer.reference(id); + const has_args = function_expression.params.length > 0; + function_expression.params = [...deps.map((name) => ({ type: 'Identifier', name })), ...function_expression.params]; - this.replace(id ); + const context_args = deps.map((name) => block.renderer.reference(name)); - const func_declaration = has_args - ? b`function ${id}(...args) { + 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}() { + : b`function ${id}() { return ${callee}(${context_args}); }`; - if (owner.type === 'Attribute' && owner.parent.name === 'slot') { - const dep_scopes = new Set(deps.map(name => template_scope.get_owner(name))); - // find the nearest scopes - let node = owner.parent; - while (node && !dep_scopes.has(node)) { - node = node.parent; - } - - const func_expression = func_declaration[0]; - - if (node.type === 'InlineComponent') { - // <Comp 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, { - enter(node) { - if (node.type === 'Identifier' && node.name === '#ctx') { - node.name = 'child_ctx'; - } - } - }); - // add to get_xxx_context - // child_ctx[x] = function () { ... } - (template_scope.get_owner(deps[0]) ).contexts.push({ - 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 (owner.type === 'Attribute' && owner.parent.name === 'slot') { + const dep_scopes = new Set(deps.map((name) => template_scope.get_owner(name))); + // find the nearest scopes + let node = owner.parent; + while (node && !dep_scopes.has(node)) { + node = node.parent; + } + + const func_expression = func_declaration[0]; + + if (node.type === 'InlineComponent') { + // <Comp 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, { + enter(node) { + if (node.type === 'Identifier' && node.name === '#ctx') { + node.name = 'child_ctx'; + } + }, + }); + // add to get_xxx_context + // child_ctx[x] = function () { ... } + template_scope.get_owner(deps[0]).contexts.push({ + key: func_id, + modifier: () => func_expression, + default_modifier: (node) => node, + }); + this.replace(block.renderer.reference(func_id)); + } + } else { + declarations.push(func_declaration); + } + } - if (node.type === 'AssignmentExpression' || node.type === 'UpdateExpression') { - const assignee = node.type === 'AssignmentExpression' ? node.left : node.argument; + function_expression = null; + dependencies = null; + contextual_dependencies = null; - const object_name = get_object(assignee).name; + if (parent && parent.type === 'Property') { + parent.method = false; + } + } - if (scope.has(object_name)) return; + if (node.type === 'AssignmentExpression' || node.type === 'UpdateExpression') { + const assignee = node.type === 'AssignmentExpression' ? node.left : node.argument; - // 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(assignee)); + const object_name = get_object(assignee).name; - 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); - } - }); + if (scope.has(object_name)) return; - const context = block.bindings.get(object_name); + // 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(assignee)); - 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; - 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); - } + 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; + 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)); - } - } - }); + this.replace(invalidate(block.renderer, scope, node, traced)); + } + }, + }); - if (declarations.length > 0) { - block.maintain_context = true; - declarations.forEach(declaration => { - block.chunks.init.push(declaration); - }); - } + if (declarations.length > 0) { + block.maintain_context = true; + declarations.forEach((declaration) => { + block.chunks.init.push(declaration); + }); + } - return (this.manipulated = node ); - } + return (this.manipulated = node); + } } function get_function_name(_node, parent) { - if (parent.type === 'EventHandler') { - return `${parent.name}_handler`; - } + if (parent.type === 'EventHandler') { + return `${parent.name}_handler`; + } - if (parent.type === 'Action') { - return `${parent.name}_function`; - } + if (parent.type === 'Action') { + return `${parent.name}_function`; + } - return 'func'; + return 'func'; } class Action extends Node { - - - - - + constructor(component, parent, scope, info) { + super(component, parent, scope, info); - constructor(component, parent, scope, info) { - super(component, parent, scope, info); + const object = info.name.split('.')[0]; + component.warn_if_undefined(object, info, scope); - const object = info.name.split('.')[0]; - component.warn_if_undefined(object, info, scope); + this.name = info.name; + component.add_reference(object); - this.name = info.name; - component.add_reference(object); + this.expression = info.expression ? new Expression(component, this, scope, info.expression) : null; - this.expression = info.expression - ? new Expression(component, this, scope, info.expression) - : null; + this.template_scope = scope; - this.template_scope = scope; - - this.uses_context = this.expression && this.expression.uses_context; - } + this.uses_context = this.expression && this.expression.uses_context; + } } class Tag extends Wrapper { - + constructor(renderer, block, parent, node) { + super(renderer, block, parent, node); - constructor(renderer, block, parent, node) { - super(renderer, block, parent, node); - - this.cannot_use_innerhtml(); - if (!this.is_dependencies_static()) { - this.not_static_content(); - } + this.cannot_use_innerhtml(); + if (!this.is_dependencies_static()) { + this.not_static_content(); + } - block.add_dependencies(node.expression.dependencies); - } + block.add_dependencies(node.expression.dependencies); + } - is_dependencies_static() { - return this.node.expression.contextual_dependencies.size === 0 && this.node.expression.dynamic_dependencies().length === 0; - } + is_dependencies_static() { + return this.node.expression.contextual_dependencies.size === 0 && this.node.expression.dynamic_dependencies().length === 0; + } - rename_this_method( - block, - update - ) { - const dependencies = this.node.expression.dynamic_dependencies(); - let snippet = this.node.expression.manipulate(block); + rename_this_method(block, update) { + const dependencies = this.node.expression.dynamic_dependencies(); + let snippet = this.node.expression.manipulate(block); - const value = this.node.should_cache && block.get_unique_name(`${this.var.name}_value`); - const content = this.node.should_cache ? value : snippet; + const value = this.node.should_cache && block.get_unique_name(`${this.var.name}_value`); + const content = this.node.should_cache ? value : snippet; - snippet = x`${snippet} + ""`; + snippet = x`${snippet} + ""`; - if (this.node.should_cache) block.add_variable(value, snippet); // TODO may need to coerce snippet to string + if (this.node.should_cache) block.add_variable(value, snippet); // TODO may need to coerce snippet to string - if (dependencies.length > 0) { - let condition = block.renderer.dirty(dependencies); + if (dependencies.length > 0) { + let condition = block.renderer.dirty(dependencies); - if (block.has_outros) { - condition = x`!#current || ${condition}`; - } + if (block.has_outros) { + condition = x`!#current || ${condition}`; + } - const update_cached_value = x`${value} !== (${value} = ${snippet})`; + const update_cached_value = x`${value} !== (${value} = ${snippet})`; - if (this.node.should_cache) { - condition = x`${condition} && ${update_cached_value}`; - } + if (this.node.should_cache) { + condition = x`${condition} && ${update_cached_value}`; + } - block.chunks.update.push(b`if (${condition}) ${update(content )}`); - } + block.chunks.update.push(b`if (${condition}) ${update(content)}`); + } - return { init: content }; - } + return { init: content }; + } } class MustacheTagWrapper extends Tag { - __init() {this.var = { type: 'Identifier', name: 't' };} + __init() { + this.var = { type: 'Identifier', name: 't' }; + } - constructor(renderer, block, parent, node) { - super(renderer, block, parent, node);MustacheTagWrapper.prototype.__init.call(this); } + constructor(renderer, block, parent, node) { + super(renderer, block, parent, node); + MustacheTagWrapper.prototype.__init.call(this); + } - render(block, parent_node, parent_nodes) { - const { init } = this.rename_this_method( - block, - value => x`@set_data(${this.var}, ${value})` - ); + render(block, parent_node, parent_nodes) { + const { init } = this.rename_this_method(block, (value) => x`@set_data(${this.var}, ${value})`); - block.add_element( - this.var, - x`@text(${init})`, - parent_nodes && x`@claim_text(${parent_nodes}, ${init})`, - parent_node - ); - } + block.add_element(this.var, x`@text(${init})`, parent_nodes && x`@claim_text(${parent_nodes}, ${init})`, parent_node); + } } class RawMustacheTagWrapper extends Tag { - __init() {this.var = { type: 'Identifier', name: 'raw' };} + __init() { + this.var = { type: 'Identifier', name: 'raw' }; + } - constructor( - renderer, - block, - parent, - node - ) { - super(renderer, block, parent, node);RawMustacheTagWrapper.prototype.__init.call(this); this.cannot_use_innerhtml(); - this.not_static_content(); - } + constructor(renderer, block, parent, node) { + super(renderer, block, parent, node); + RawMustacheTagWrapper.prototype.__init.call(this); + this.cannot_use_innerhtml(); + this.not_static_content(); + } - render(block, parent_node, _parent_nodes) { - const in_head = is_head(parent_node); + render(block, parent_node, _parent_nodes) { + const in_head = is_head(parent_node); - const can_use_innerhtml = !in_head && parent_node && !this.prev && !this.next; + const can_use_innerhtml = !in_head && parent_node && !this.prev && !this.next; - if (can_use_innerhtml) { - const insert = content => b`${parent_node}.innerHTML = ${content};`[0]; + if (can_use_innerhtml) { + const insert = (content) => b`${parent_node}.innerHTML = ${content};`[0]; - const { init } = this.rename_this_method( - block, - content => insert(content) - ); + const { init } = this.rename_this_method(block, (content) => insert(content)); - block.chunks.mount.push(insert(init)); - } else { - const needs_anchor = in_head || (this.next ? !this.next.is_dom_node() : (!this.parent || !this.parent.is_dom_node())); + block.chunks.mount.push(insert(init)); + } else { + const needs_anchor = in_head || (this.next ? !this.next.is_dom_node() : !this.parent || !this.parent.is_dom_node()); - const html_tag = block.get_unique_name('html_tag'); - const html_anchor = needs_anchor && block.get_unique_name('html_anchor'); + const html_tag = block.get_unique_name('html_tag'); + const html_anchor = needs_anchor && block.get_unique_name('html_anchor'); - block.add_variable(html_tag); + block.add_variable(html_tag); - const { init } = this.rename_this_method( - block, - content => x`${html_tag}.p(${content})` - ); + const { init } = this.rename_this_method(block, (content) => x`${html_tag}.p(${content})`); - const update_anchor = needs_anchor ? html_anchor : this.next ? this.next.var : 'null'; + const update_anchor = needs_anchor ? html_anchor : this.next ? this.next.var : 'null'; - block.chunks.hydrate.push(b`${html_tag} = new @HtmlTag(${update_anchor});`); - block.chunks.mount.push(b`${html_tag}.m(${init}, ${parent_node || '#target'}, ${parent_node ? null : '#anchor'});`); + block.chunks.hydrate.push(b`${html_tag} = new @HtmlTag(${update_anchor});`); + block.chunks.mount.push(b`${html_tag}.m(${init}, ${parent_node || '#target'}, ${parent_node ? null : '#anchor'});`); - if (needs_anchor) { - block.add_element(html_anchor, x`@empty()`, x`@empty()`, parent_node); - } + if (needs_anchor) { + block.add_element(html_anchor, x`@empty()`, x`@empty()`, parent_node); + } - if (!parent_node || in_head) { - block.chunks.destroy.push(b`if (detaching) ${html_tag}.d();`); - } - } - } + if (!parent_node || in_head) { + block.chunks.destroy.push(b`if (detaching) ${html_tag}.d();`); + } + } + } } const events = [ - { - event_names: ['input'], - filter: (node, _name) => - node.name === 'textarea' || - node.name === 'input' && !/radio|checkbox|range|file/.test(node.get_static_attribute_value('type') ) - }, - { - event_names: ['input'], - filter: (node, name) => - (name === 'textContent' || name === 'innerHTML') && - node.attributes.some(attribute => attribute.name === 'contenteditable') - }, - { - event_names: ['change'], - filter: (node, _name) => - node.name === 'select' || - node.name === 'input' && /radio|checkbox|file/.test(node.get_static_attribute_value('type') ) - }, - { - event_names: ['change', 'input'], - filter: (node, _name) => - node.name === 'input' && node.get_static_attribute_value('type') === 'range' - }, - - { - event_names: ['elementresize'], - filter: (_node, name) => - dimensions.test(name) - }, - - // media events - { - event_names: ['timeupdate'], - filter: (node, name) => - node.is_media_node() && - (name === 'currentTime' || name === 'played' || name === 'ended') - }, - { - event_names: ['durationchange'], - filter: (node, name) => - node.is_media_node() && - name === 'duration' - }, - { - event_names: ['play', 'pause'], - filter: (node, name) => - node.is_media_node() && - name === 'paused' - }, - { - event_names: ['progress'], - filter: (node, name) => - node.is_media_node() && - name === 'buffered' - }, - { - event_names: ['loadedmetadata'], - filter: (node, name) => - node.is_media_node() && - (name === 'buffered' || name === 'seekable') - }, - { - event_names: ['volumechange'], - filter: (node, name) => - node.is_media_node() && - (name === 'volume' || name === 'muted') - }, - { - event_names: ['ratechange'], - filter: (node, name) => - node.is_media_node() && - name === 'playbackRate' - }, - { - event_names: ['seeking', 'seeked'], - filter: (node, name) => - node.is_media_node() && - (name === 'seeking') - }, - { - event_names: ['ended'], - filter: (node, name) => - node.is_media_node() && - name === 'ended' - }, - { - event_names: ['resize'], - filter: (node, name) => - node.is_media_node() && - (name === 'videoHeight' || name === 'videoWidth') - }, - - // details event - { - event_names: ['toggle'], - filter: (node, _name) => - node.name === 'details' - } + { + event_names: ['input'], + filter: (node, _name) => node.name === 'textarea' || (node.name === 'input' && !/radio|checkbox|range|file/.test(node.get_static_attribute_value('type'))), + }, + { + event_names: ['input'], + filter: (node, name) => (name === 'textContent' || name === 'innerHTML') && node.attributes.some((attribute) => attribute.name === 'contenteditable'), + }, + { + event_names: ['change'], + filter: (node, _name) => node.name === 'select' || (node.name === 'input' && /radio|checkbox|file/.test(node.get_static_attribute_value('type'))), + }, + { + event_names: ['change', 'input'], + filter: (node, _name) => node.name === 'input' && node.get_static_attribute_value('type') === 'range', + }, + + { + event_names: ['elementresize'], + filter: (_node, name) => dimensions.test(name), + }, + + // media events + { + event_names: ['timeupdate'], + filter: (node, name) => node.is_media_node() && (name === 'currentTime' || name === 'played' || name === 'ended'), + }, + { + event_names: ['durationchange'], + filter: (node, name) => node.is_media_node() && name === 'duration', + }, + { + event_names: ['play', 'pause'], + filter: (node, name) => node.is_media_node() && name === 'paused', + }, + { + event_names: ['progress'], + filter: (node, name) => node.is_media_node() && name === 'buffered', + }, + { + event_names: ['loadedmetadata'], + filter: (node, name) => node.is_media_node() && (name === 'buffered' || name === 'seekable'), + }, + { + event_names: ['volumechange'], + filter: (node, name) => node.is_media_node() && (name === 'volume' || name === 'muted'), + }, + { + event_names: ['ratechange'], + filter: (node, name) => node.is_media_node() && name === 'playbackRate', + }, + { + event_names: ['seeking', 'seeked'], + filter: (node, name) => node.is_media_node() && name === 'seeking', + }, + { + event_names: ['ended'], + filter: (node, name) => node.is_media_node() && name === 'ended', + }, + { + event_names: ['resize'], + filter: (node, name) => node.is_media_node() && (name === 'videoHeight' || name === 'videoWidth'), + }, + + // details event + { + event_names: ['toggle'], + filter: (node, _name) => node.name === 'details', + }, ]; class ElementWrapper extends Wrapper { - - - - - - - - - - - - - constructor( - renderer, - block, - parent, - node, - strip_whitespace, - next_sibling - ) { - super(renderer, block, parent, node); - this.var = { - type: 'Identifier', - name: node.name.replace(/[^a-zA-Z0-9_$]/g, '_') - }; - - this.void = is_void(node.name); - - this.class_dependencies = []; - - if (this.node.children.length) { - this.node.lets.forEach(l => { - extract_names(l.value || l.name).forEach(name => { - renderer.add_to_context(name, true); - }); - }); - } + constructor(renderer, block, parent, node, strip_whitespace, next_sibling) { + super(renderer, block, parent, node); + this.var = { + type: 'Identifier', + name: node.name.replace(/[^a-zA-Z0-9_$]/g, '_'), + }; - this.attributes = this.node.attributes.map(attribute => { - if (attribute.name === 'style') { - return new StyleAttributeWrapper(this, block, attribute); - } - if (attribute.type === 'Spread') { - return new SpreadAttributeWrapper(this, block, attribute); - } - return new AttributeWrapper(this, block, attribute); - }); + this.void = is_void(node.name); - // ordinarily, there'll only be one... but we need to handle - // the rare case where an element can have multiple bindings, - // e.g. <audio bind:paused bind:currentTime> - this.bindings = this.node.bindings.map(binding => new BindingWrapper(block, binding, this)); + this.class_dependencies = []; - this.event_handlers = this.node.handlers.map(event_handler => new EventHandlerWrapper(event_handler, this)); + if (this.node.children.length) { + this.node.lets.forEach((l) => { + extract_names(l.value || l.name).forEach((name) => { + renderer.add_to_context(name, true); + }); + }); + } - if (node.intro || node.outro) { - if (node.intro) block.add_intro(node.intro.is_local); - if (node.outro) block.add_outro(node.outro.is_local); - } + this.attributes = this.node.attributes.map((attribute) => { + if (attribute.name === 'style') { + return new StyleAttributeWrapper(this, block, attribute); + } + if (attribute.type === 'Spread') { + return new SpreadAttributeWrapper(this, block, attribute); + } + return new AttributeWrapper(this, block, attribute); + }); - if (node.animation) { - block.add_animation(); - } + // ordinarily, there'll only be one... but we need to handle + // the rare case where an element can have multiple bindings, + // e.g. <audio bind:paused bind:currentTime> + this.bindings = this.node.bindings.map((binding) => new BindingWrapper(block, binding, this)); - // add directive and handler dependencies - [node.animation, node.outro, ...node.actions, ...node.classes].forEach(directive => { - if (directive && directive.expression) { - block.add_dependencies(directive.expression.dependencies); - } - }); + this.event_handlers = this.node.handlers.map((event_handler) => new EventHandlerWrapper(event_handler, this)); - node.handlers.forEach(handler => { - if (handler.expression) { - block.add_dependencies(handler.expression.dependencies); - } - }); + if (node.intro || node.outro) { + if (node.intro) block.add_intro(node.intro.is_local); + if (node.outro) block.add_outro(node.outro.is_local); + } - if (this.parent) { - if (node.actions.length > 0 || - node.animation || - node.bindings.length > 0 || - node.classes.length > 0 || - node.intro || node.outro || - node.handlers.length > 0 || - this.node.name === 'option' || - renderer.options.dev - ) { - this.parent.cannot_use_innerhtml(); // need to use add_location - this.parent.not_static_content(); - } - } + if (node.animation) { + block.add_animation(); + } - this.fragment = new FragmentWrapper(renderer, block, node.children, this, strip_whitespace, next_sibling); - } + // add directive and handler dependencies + [node.animation, node.outro, ...node.actions, ...node.classes].forEach((directive) => { + if (directive && directive.expression) { + block.add_dependencies(directive.expression.dependencies); + } + }); + + node.handlers.forEach((handler) => { + if (handler.expression) { + block.add_dependencies(handler.expression.dependencies); + } + }); - render(block, parent_node, parent_nodes) { - const { renderer } = this; + if (this.parent) { + if ( + node.actions.length > 0 || + node.animation || + node.bindings.length > 0 || + node.classes.length > 0 || + node.intro || + node.outro || + node.handlers.length > 0 || + this.node.name === 'option' || + renderer.options.dev + ) { + this.parent.cannot_use_innerhtml(); // need to use add_location + this.parent.not_static_content(); + } + } + + this.fragment = new FragmentWrapper(renderer, block, node.children, this, strip_whitespace, next_sibling); + } - if (this.node.name === 'noscript') return; + render(block, parent_node, parent_nodes) { + const { renderer } = this; - const node = this.var; - const nodes = parent_nodes && block.get_unique_name(`${this.var.name}_nodes`); // if we're in unclaimable territory, i.e. <head>, parent_nodes is null - const children = x`@children(${this.node.name === 'template' ? x`${node}.content` : node})`; + if (this.node.name === 'noscript') return; - block.add_variable(node); - const render_statement = this.get_render_statement(block); - block.chunks.create.push( - b`${node} = ${render_statement};` - ); + const node = this.var; + const nodes = parent_nodes && block.get_unique_name(`${this.var.name}_nodes`); // if we're in unclaimable territory, i.e. <head>, parent_nodes is null + const children = x`@children(${this.node.name === 'template' ? x`${node}.content` : node})`; - if (renderer.options.hydratable) { - if (parent_nodes) { - block.chunks.claim.push(b` + block.add_variable(node); + const render_statement = this.get_render_statement(block); + block.chunks.create.push(b`${node} = ${render_statement};`); + + if (renderer.options.hydratable) { + if (parent_nodes) { + block.chunks.claim.push(b` ${node} = ${this.get_claim_statement(parent_nodes)}; `); - if (!this.void && this.node.children.length > 0) { - block.chunks.claim.push(b` + if (!this.void && this.node.children.length > 0) { + block.chunks.claim.push(b` var ${nodes} = ${children}; `); - } - } else { - block.chunks.claim.push( - b`${node} = ${render_statement};` - ); - } - } + } + } else { + block.chunks.claim.push(b`${node} = ${render_statement};`); + } + } - if (parent_node) { - block.chunks.mount.push( - b`@append(${parent_node}, ${node});` - ); + if (parent_node) { + block.chunks.mount.push(b`@append(${parent_node}, ${node});`); - if (is_head(parent_node)) { - block.chunks.destroy.push(b`@detach(${node});`); - } - } else { - block.chunks.mount.push(b`@insert(#target, ${node}, #anchor);`); + if (is_head(parent_node)) { + block.chunks.destroy.push(b`@detach(${node});`); + } + } else { + block.chunks.mount.push(b`@insert(#target, ${node}, #anchor);`); - // TODO we eventually need to consider what happens to elements - // that belong to the same outgroup as an outroing element... - block.chunks.destroy.push(b`if (detaching) @detach(${node});`); - } + // TODO we eventually need to consider what happens to elements + // that belong to the same outgroup as an outroing element... + block.chunks.destroy.push(b`if (detaching) @detach(${node});`); + } - // insert static children with textContent or innerHTML - const can_use_textcontent = this.can_use_textcontent(); - if (!this.node.namespace && (this.can_use_innerhtml || can_use_textcontent) && this.fragment.nodes.length > 0) { - if (this.fragment.nodes.length === 1 && this.fragment.nodes[0].node.type === 'Text') { - block.chunks.create.push( - b`${node}.textContent = ${string_literal((this.fragment.nodes[0] ).data)};` - ); - } else { - const state = { - quasi: { - type: 'TemplateElement', - value: { raw: '' } - } - }; + // insert static children with textContent or innerHTML + const can_use_textcontent = this.can_use_textcontent(); + if (!this.node.namespace && (this.can_use_innerhtml || can_use_textcontent) && this.fragment.nodes.length > 0) { + if (this.fragment.nodes.length === 1 && this.fragment.nodes[0].node.type === 'Text') { + block.chunks.create.push(b`${node}.textContent = ${string_literal(this.fragment.nodes[0].data)};`); + } else { + const state = { + quasi: { + type: 'TemplateElement', + value: { raw: '' }, + }, + }; + + const literal = { + type: 'TemplateLiteral', + expressions: [], + quasis: [], + }; + + const can_use_raw_text = !this.can_use_innerhtml && can_use_textcontent; + to_html(this.fragment.nodes, block, literal, state, can_use_raw_text); + literal.quasis.push(state.quasi); + + block.chunks.create.push(b`${node}.${this.can_use_innerhtml ? 'innerHTML' : 'textContent'} = ${literal};`); + } + } else { + this.fragment.nodes.forEach((child) => { + child.render(block, this.node.name === 'template' ? x`${node}.content` : node, nodes); + }); + } - const literal = { - type: 'TemplateLiteral', - expressions: [], - quasis: [] - }; + const event_handler_or_binding_uses_context = + this.bindings.some((binding) => binding.handler.uses_context) || + this.node.handlers.some((handler) => handler.uses_context) || + this.node.actions.some((action) => action.uses_context); - const can_use_raw_text = !this.can_use_innerhtml && can_use_textcontent; - to_html((this.fragment.nodes ), block, literal, state, can_use_raw_text); - literal.quasis.push(state.quasi); + if (event_handler_or_binding_uses_context) { + block.maintain_context = true; + } - block.chunks.create.push( - b`${node}.${this.can_use_innerhtml ? 'innerHTML' : 'textContent'} = ${literal};` - ); - } - } else { - this.fragment.nodes.forEach((child) => { - child.render( - block, - this.node.name === 'template' ? x`${node}.content` : node, - nodes - ); - }); - } + this.add_attributes(block); + this.add_directives_in_order(block); + this.add_transitions(block); + this.add_animation(block); + this.add_classes(block); + this.add_manual_style_scoping(block); - const event_handler_or_binding_uses_context = ( - this.bindings.some(binding => binding.handler.uses_context) || - this.node.handlers.some(handler => handler.uses_context) || - this.node.actions.some(action => action.uses_context) - ); + if (nodes && this.renderer.options.hydratable && !this.void) { + block.chunks.claim.push(b`${this.node.children.length > 0 ? nodes : children}.forEach(@detach);`); + } - if (event_handler_or_binding_uses_context) { - block.maintain_context = true; - } + if (renderer.options.dev) { + const loc = renderer.locate(this.node.start); + block.chunks.hydrate.push(b`@add_location(${this.var}, ${renderer.file_var}, ${loc.line - 1}, ${loc.column}, ${this.node.start});`); + } + } - this.add_attributes(block); - this.add_directives_in_order(block); - this.add_transitions(block); - this.add_animation(block); - this.add_classes(block); - this.add_manual_style_scoping(block); - - if (nodes && this.renderer.options.hydratable && !this.void) { - block.chunks.claim.push( - b`${this.node.children.length > 0 ? nodes : children}.forEach(@detach);` - ); - } + can_use_textcontent() { + return this.is_static_content && this.fragment.nodes.every((node) => node.node.type === 'Text' || node.node.type === 'MustacheTag'); + } - if (renderer.options.dev) { - const loc = renderer.locate(this.node.start); - block.chunks.hydrate.push( - b`@add_location(${this.var}, ${renderer.file_var}, ${loc.line - 1}, ${loc.column}, ${this.node.start});` - ); - } - } + get_render_statement(block) { + const { name, namespace } = this.node; - can_use_textcontent() { - return this.is_static_content && this.fragment.nodes.every(node => node.node.type === 'Text' || node.node.type === 'MustacheTag'); - } + if (namespace === namespaces.svg) { + return x`@svg_element("${name}")`; + } - get_render_statement(block) { - const { name, namespace } = this.node; + if (namespace) { + return x`@_document.createElementNS("${namespace}", "${name}")`; + } - if (namespace === namespaces.svg) { - return x`@svg_element("${name}")`; - } + const is = this.attributes.find((attr) => attr.node.name === 'is'); + if (is) { + return x`@element_is("${name}", ${is.render_chunks(block).reduce((lhs, rhs) => x`${lhs} + ${rhs}`)})`; + } - if (namespace) { - return x`@_document.createElementNS("${namespace}", "${name}")`; - } + return x`@element("${name}")`; + } - const is = this.attributes.find(attr => attr.node.name === 'is') ; - if (is) { - return x`@element_is("${name}", ${is.render_chunks(block).reduce((lhs, rhs) => x`${lhs} + ${rhs}`)})`; - } + get_claim_statement(nodes) { + const attributes = this.node.attributes.filter((attr) => attr.type === 'Attribute').map((attr) => p`${attr.name}: true`); - return x`@element("${name}")`; - } - - get_claim_statement(nodes) { - const attributes = this.node.attributes - .filter((attr) => attr.type === 'Attribute') - .map((attr) => p`${attr.name}: true`); - - const name = this.node.namespace - ? this.node.name - : this.node.name.toUpperCase(); - - const svg = this.node.namespace === namespaces.svg ? 1 : null; - - return x`@claim_element(${nodes}, "${name}", { ${attributes} }, ${svg})`; - } - - add_directives_in_order (block) { - - - const binding_groups = events - .map(event => ({ - events: event.event_names, - bindings: this.bindings - .filter(binding => binding.node.name !== 'this') - .filter(binding => event.filter(this.node, binding.node.name)) - })) - .filter(group => group.bindings.length); - - const this_binding = this.bindings.find(b => b.node.name === 'this'); - - function getOrder (item) { - if (item instanceof EventHandlerWrapper) { - return item.node.start; - } else if (item instanceof BindingWrapper) { - return item.node.start; - } else if (item instanceof Action) { - return item.start; - } else { - return item.bindings[0].node.start; - } - } + const name = this.node.namespace ? this.node.name : this.node.name.toUpperCase(); - ([ - ...binding_groups, - ...this.event_handlers, - this_binding, - ...this.node.actions - ] ) - .filter(Boolean) - .sort((a, b) => getOrder(a) - getOrder(b)) - .forEach(item => { - if (item instanceof EventHandlerWrapper) { - add_event_handler(block, this.var, item); - } else if (item instanceof BindingWrapper) { - this.add_this_binding(block, item); - } else if (item instanceof Action) { - add_action(block, this.var, item); - } else { - this.add_bindings(block, item); - } - }); - } + const svg = this.node.namespace === namespaces.svg ? 1 : null; - add_bindings(block, binding_group) { - const { renderer } = this; + return x`@claim_element(${nodes}, "${name}", { ${attributes} }, ${svg})`; + } - if (binding_group.bindings.length === 0) return; + add_directives_in_order(block) { + const binding_groups = events + .map((event) => ({ + events: event.event_names, + bindings: this.bindings.filter((binding) => binding.node.name !== 'this').filter((binding) => event.filter(this.node, binding.node.name)), + })) + .filter((group) => group.bindings.length); + + const this_binding = this.bindings.find((b) => b.node.name === 'this'); + + function getOrder(item) { + if (item instanceof EventHandlerWrapper) { + return item.node.start; + } else if (item instanceof BindingWrapper) { + return item.node.start; + } else if (item instanceof Action) { + return item.start; + } else { + return item.bindings[0].node.start; + } + } - renderer.component.has_reactive_assignments = true; + [...binding_groups, ...this.event_handlers, this_binding, ...this.node.actions] + .filter(Boolean) + .sort((a, b) => getOrder(a) - getOrder(b)) + .forEach((item) => { + if (item instanceof EventHandlerWrapper) { + add_event_handler(block, this.var, item); + } else if (item instanceof BindingWrapper) { + this.add_this_binding(block, item); + } else if (item instanceof Action) { + add_action(block, this.var, item); + } else { + this.add_bindings(block, item); + } + }); + } - const lock = binding_group.bindings.some(binding => binding.needs_lock) ? - block.get_unique_name(`${this.var.name}_updating`) : - null; + add_bindings(block, binding_group) { + const { renderer } = this; - if (lock) block.add_variable(lock, x`false`); + if (binding_group.bindings.length === 0) return; - const handler = renderer.component.get_unique_name(`${this.var.name}_${binding_group.events.join('_')}_handler`); - renderer.add_to_context(handler.name); + renderer.component.has_reactive_assignments = true; - // TODO figure out how to handle locks - const needs_lock = binding_group.bindings.some(binding => binding.needs_lock); + const lock = binding_group.bindings.some((binding) => binding.needs_lock) ? block.get_unique_name(`${this.var.name}_updating`) : null; - const dependencies = new Set(); - const contextual_dependencies = new Set(); + if (lock) block.add_variable(lock, x`false`); - binding_group.bindings.forEach(binding => { - // TODO this is a mess - add_to_set(dependencies, binding.get_dependencies()); - add_to_set(contextual_dependencies, binding.handler.contextual_dependencies); + const handler = renderer.component.get_unique_name(`${this.var.name}_${binding_group.events.join('_')}_handler`); + renderer.add_to_context(handler.name); - binding.render(block, lock); - }); + // TODO figure out how to handle locks + const needs_lock = binding_group.bindings.some((binding) => binding.needs_lock); - // media bindings — awkward special case. The native timeupdate events - // fire too infrequently, so we need to take matters into our - // own hands - let animation_frame; - if (binding_group.events[0] === 'timeupdate') { - animation_frame = block.get_unique_name(`${this.var.name}_animationframe`); - block.add_variable(animation_frame); - } + const dependencies = new Set(); + const contextual_dependencies = new Set(); - const has_local_function = contextual_dependencies.size > 0 || needs_lock || animation_frame; + binding_group.bindings.forEach((binding) => { + // TODO this is a mess + add_to_set(dependencies, binding.get_dependencies()); + add_to_set(contextual_dependencies, binding.handler.contextual_dependencies); - let callee = renderer.reference(handler); + binding.render(block, lock); + }); - // TODO dry this out — similar code for event handlers and component bindings - if (has_local_function) { - const args = Array.from(contextual_dependencies).map(name => renderer.reference(name)); + // media bindings — awkward special case. The native timeupdate events + // fire too infrequently, so we need to take matters into our + // own hands + let animation_frame; + if (binding_group.events[0] === 'timeupdate') { + animation_frame = block.get_unique_name(`${this.var.name}_animationframe`); + block.add_variable(animation_frame); + } - // need to create a block-local function that calls an instance-level function - if (animation_frame) { - block.chunks.init.push(b` + const has_local_function = contextual_dependencies.size > 0 || needs_lock || animation_frame; + + let callee = renderer.reference(handler); + + // TODO dry this out — similar code for event handlers and component bindings + if (has_local_function) { + const args = Array.from(contextual_dependencies).map((name) => renderer.reference(name)); + + // need to create a block-local function that calls an instance-level function + if (animation_frame) { + block.chunks.init.push(b` function ${handler}() { @_cancelAnimationFrame(${animation_frame}); if (!${this.var}.paused) { @@ -11561,146 +10736,125 @@ class ElementWrapper extends Wrapper { ${callee}.call(${this.var}, ${args}); } `); - } else { - block.chunks.init.push(b` + } else { + block.chunks.init.push(b` function ${handler}() { ${needs_lock && b`${lock} = true;`} ${callee}.call(${this.var}, ${args}); } `); - } + } - callee = handler; - } + callee = handler; + } - const params = Array.from(contextual_dependencies).map(name => ({ - type: 'Identifier', - name - })); + const params = Array.from(contextual_dependencies).map((name) => ({ + type: 'Identifier', + name, + })); - this.renderer.component.partly_hoisted.push(b` + this.renderer.component.partly_hoisted.push(b` function ${handler}(${params}) { - ${binding_group.bindings.map(b => b.handler.mutation)} + ${binding_group.bindings.map((b) => b.handler.mutation)} ${Array.from(dependencies) - .filter(dep => dep[0] !== '$') - .filter(dep => !contextual_dependencies.has(dep)) - .map(dep => b`${this.renderer.invalidate(dep)};`)} + .filter((dep) => dep[0] !== '$') + .filter((dep) => !contextual_dependencies.has(dep)) + .map((dep) => b`${this.renderer.invalidate(dep)};`)} } `); - binding_group.events.forEach(name => { - if (name === 'elementresize') { - // special case - const resize_listener = block.get_unique_name(`${this.var.name}_resize_listener`); - block.add_variable(resize_listener); - - block.chunks.mount.push( - b`${resize_listener} = @add_resize_listener(${this.var}, ${callee}.bind(${this.var}));` - ); - - block.chunks.destroy.push( - b`${resize_listener}();` - ); - } else { - block.event_listeners.push( - x`@listen(${this.var}, "${name}", ${callee})` - ); - } - }); + binding_group.events.forEach((name) => { + if (name === 'elementresize') { + // special case + const resize_listener = block.get_unique_name(`${this.var.name}_resize_listener`); + block.add_variable(resize_listener); - const some_initial_state_is_undefined = binding_group.bindings - .map(binding => x`${binding.snippet} === void 0`) - .reduce((lhs, rhs) => x`${lhs} || ${rhs}`); - - const should_initialise = ( - this.node.name === 'select' || - binding_group.bindings.find(binding => { - return ( - binding.node.name === 'indeterminate' || - binding.node.name === 'textContent' || - binding.node.name === 'innerHTML' || - binding.is_readonly_media_attribute() - ); - }) - ); - - if (should_initialise) { - const callback = has_local_function ? handler : x`() => ${callee}.call(${this.var})`; - block.chunks.hydrate.push( - b`if (${some_initial_state_is_undefined}) @add_render_callback(${callback});` - ); - } + block.chunks.mount.push(b`${resize_listener} = @add_resize_listener(${this.var}, ${callee}.bind(${this.var}));`); - if (binding_group.events[0] === 'elementresize') { - block.chunks.hydrate.push( - b`@add_render_callback(() => ${callee}.call(${this.var}));` - ); - } + block.chunks.destroy.push(b`${resize_listener}();`); + } else { + block.event_listeners.push(x`@listen(${this.var}, "${name}", ${callee})`); + } + }); - if (lock) { - block.chunks.update.push(b`${lock} = false;`); - } - } + const some_initial_state_is_undefined = binding_group.bindings.map((binding) => x`${binding.snippet} === void 0`).reduce((lhs, rhs) => x`${lhs} || ${rhs}`); + + const should_initialise = + this.node.name === 'select' || + binding_group.bindings.find((binding) => { + return binding.node.name === 'indeterminate' || binding.node.name === 'textContent' || binding.node.name === 'innerHTML' || binding.is_readonly_media_attribute(); + }); - add_this_binding(block, this_binding) { - const { renderer } = this; + if (should_initialise) { + const callback = has_local_function ? handler : x`() => ${callee}.call(${this.var})`; + block.chunks.hydrate.push(b`if (${some_initial_state_is_undefined}) @add_render_callback(${callback});`); + } - renderer.component.has_reactive_assignments = true; + if (binding_group.events[0] === 'elementresize') { + block.chunks.hydrate.push(b`@add_render_callback(() => ${callee}.call(${this.var}));`); + } - const binding_callback = bind_this(renderer.component, block, this_binding, this.var); - block.chunks.mount.push(binding_callback); - } + if (lock) { + block.chunks.update.push(b`${lock} = false;`); + } + } - add_attributes(block) { - // Get all the class dependencies first - this.attributes.forEach((attribute) => { - if (attribute.node.name === 'class') { - const dependencies = attribute.node.get_dependencies(); - this.class_dependencies.push(...dependencies); - } - }); + add_this_binding(block, this_binding) { + const { renderer } = this; - if (this.node.attributes.some(attr => attr.is_spread)) { - this.add_spread_attributes(block); - return; - } + renderer.component.has_reactive_assignments = true; - this.attributes.forEach((attribute) => { - attribute.render(block); - }); - } + const binding_callback = bind_this(renderer.component, block, this_binding, this.var); + block.chunks.mount.push(binding_callback); + } - add_spread_attributes(block) { - const levels = block.get_unique_name(`${this.var.name}_levels`); - const data = block.get_unique_name(`${this.var.name}_data`); + add_attributes(block) { + // Get all the class dependencies first + this.attributes.forEach((attribute) => { + if (attribute.node.name === 'class') { + const dependencies = attribute.node.get_dependencies(); + this.class_dependencies.push(...dependencies); + } + }); - const initial_props = []; - const updates = []; + if (this.node.attributes.some((attr) => attr.is_spread)) { + this.add_spread_attributes(block); + return; + } - this.attributes - .forEach(attr => { - const dependencies = attr.node.get_dependencies(); + this.attributes.forEach((attribute) => { + attribute.render(block); + }); + } - const condition = dependencies.length > 0 - ? block.renderer.dirty(dependencies) - : null; + add_spread_attributes(block) { + const levels = block.get_unique_name(`${this.var.name}_levels`); + const data = block.get_unique_name(`${this.var.name}_data`); - if (attr instanceof SpreadAttributeWrapper) { - const snippet = attr.node.expression.manipulate(block); + const initial_props = []; + const updates = []; - initial_props.push(snippet); + this.attributes.forEach((attr) => { + const dependencies = attr.node.get_dependencies(); - updates.push(condition ? x`${condition} && ${snippet}` : snippet); - } else { - const name = attr.property_name || attr.name; - initial_props.push(x`{ ${name}: ${attr.get_init(block, attr.get_value(block))} }`); - const snippet = x`{ ${name}: ${attr.should_cache ? attr.last : attr.get_value(block)} }`; + const condition = dependencies.length > 0 ? block.renderer.dirty(dependencies) : null; - updates.push(condition ? x`${attr.get_dom_update_conditions(block, condition)} && ${snippet}` : snippet); - } - }); + if (attr instanceof SpreadAttributeWrapper) { + const snippet = attr.node.expression.manipulate(block); + + initial_props.push(snippet); - block.chunks.init.push(b` + updates.push(condition ? x`${condition} && ${snippet}` : snippet); + } else { + const name = attr.property_name || attr.name; + initial_props.push(x`{ ${name}: ${attr.get_init(block, attr.get_value(block))} }`); + const snippet = x`{ ${name}: ${attr.should_cache ? attr.last : attr.get_value(block)} }`; + + updates.push(condition ? x`${attr.get_dom_update_conditions(block, condition)} && ${snippet}` : snippet); + } + }); + + block.chunks.init.push(b` let ${levels} = [${initial_props}]; let ${data} = {}; @@ -11709,111 +10863,103 @@ class ElementWrapper extends Wrapper { } `); - const fn = this.node.namespace === namespaces.svg ? x`@set_svg_attributes` : x`@set_attributes`; + const fn = this.node.namespace === namespaces.svg ? x`@set_svg_attributes` : x`@set_attributes`; - block.chunks.hydrate.push( - b`${fn}(${this.var}, ${data});` - ); + block.chunks.hydrate.push(b`${fn}(${this.var}, ${data});`); - block.chunks.update.push(b` + block.chunks.update.push(b` ${fn}(${this.var}, ${data} = @get_spread_update(${levels}, [ ${updates} ])); `); - // handle edge cases for elements - if (this.node.name === 'select') { - const dependencies = new Set(); - for (const attr of this.attributes) { - for (const dep of attr.node.dependencies) { - dependencies.add(dep); - } - } + // handle edge cases for elements + if (this.node.name === 'select') { + const dependencies = new Set(); + for (const attr of this.attributes) { + for (const dep of attr.node.dependencies) { + dependencies.add(dep); + } + } - block.chunks.mount.push(b` + block.chunks.mount.push(b` if (${data}.multiple) @select_options(${this.var}, ${data}.value); `); - block.chunks.update.push(b` + block.chunks.update.push(b` if (${block.renderer.dirty(Array.from(dependencies))} && ${data}.multiple) @select_options(${this.var}, ${data}.value); `); - } else if (this.node.name === 'input' && this.attributes.find(attr => attr.node.name === 'value')) { - const type = this.node.get_static_attribute_value('type'); - if (type === null || type === '' || type === 'text' || type === 'email' || type === 'password') { - block.chunks.mount.push(b` + } else if (this.node.name === 'input' && this.attributes.find((attr) => attr.node.name === 'value')) { + const type = this.node.get_static_attribute_value('type'); + if (type === null || type === '' || type === 'text' || type === 'email' || type === 'password') { + block.chunks.mount.push(b` ${this.var}.value = ${data}.value; `); - block.chunks.update.push(b` + block.chunks.update.push(b` if ('value' in ${data}) { ${this.var}.value = ${data}.value; } `); - } - } - } + } + } + } - add_transitions( - block - ) { - const { intro, outro } = this.node; - if (!intro && !outro) return; + add_transitions(block) { + const { intro, outro } = this.node; + if (!intro && !outro) return; - if (intro === outro) { - // bidirectional transition - const name = block.get_unique_name(`${this.var.name}_transition`); - const snippet = intro.expression - ? intro.expression.manipulate(block) - : x`{}`; + if (intro === outro) { + // bidirectional transition + const name = block.get_unique_name(`${this.var.name}_transition`); + const snippet = intro.expression ? intro.expression.manipulate(block) : x`{}`; - block.add_variable(name); + block.add_variable(name); - const fn = this.renderer.reference(intro.name); + const fn = this.renderer.reference(intro.name); - const intro_block = b` + const intro_block = b` @add_render_callback(() => { if (!${name}) ${name} = @create_bidirectional_transition(${this.var}, ${fn}, ${snippet}, true); ${name}.run(1); }); `; - const outro_block = b` + const outro_block = b` if (!${name}) ${name} = @create_bidirectional_transition(${this.var}, ${fn}, ${snippet}, false); ${name}.run(0); `; - if (intro.is_local) { - block.chunks.intro.push(b` + if (intro.is_local) { + block.chunks.intro.push(b` if (#local) { ${intro_block} } `); - block.chunks.outro.push(b` + block.chunks.outro.push(b` if (#local) { ${outro_block} } `); - } else { - block.chunks.intro.push(intro_block); - block.chunks.outro.push(outro_block); - } + } else { + block.chunks.intro.push(intro_block); + block.chunks.outro.push(outro_block); + } - block.chunks.destroy.push(b`if (detaching && ${name}) ${name}.end();`); - } else { - const intro_name = intro && block.get_unique_name(`${this.var.name}_intro`); - const outro_name = outro && block.get_unique_name(`${this.var.name}_outro`); + block.chunks.destroy.push(b`if (detaching && ${name}) ${name}.end();`); + } else { + const intro_name = intro && block.get_unique_name(`${this.var.name}_intro`); + const outro_name = outro && block.get_unique_name(`${this.var.name}_outro`); - if (intro) { - block.add_variable(intro_name); - const snippet = intro.expression - ? intro.expression.manipulate(block) - : x`{}`; + if (intro) { + block.add_variable(intro_name); + const snippet = intro.expression ? intro.expression.manipulate(block) : x`{}`; - const fn = this.renderer.reference(intro.name); + const fn = this.renderer.reference(intro.name); - let intro_block; + let intro_block; - if (outro) { - intro_block = b` + if (outro) { + intro_block = b` @add_render_callback(() => { if (${outro_name}) ${outro_name}.end(1); if (!${intro_name}) ${intro_name} = @create_in_transition(${this.var}, ${fn}, ${snippet}); @@ -11821,9 +10967,9 @@ class ElementWrapper extends Wrapper { }); `; - block.chunks.outro.push(b`if (${intro_name}) ${intro_name}.invalidate();`); - } else { - intro_block = b` + block.chunks.outro.push(b`if (${intro_name}) ${intro_name}.invalidate();`); + } else { + intro_block = b` if (!${intro_name}) { @add_render_callback(() => { ${intro_name} = @create_in_transition(${this.var}, ${fn}, ${snippet}); @@ -11831,552 +10977,466 @@ class ElementWrapper extends Wrapper { }); } `; - } + } - if (intro.is_local) { - intro_block = b` + if (intro.is_local) { + intro_block = b` if (#local) { ${intro_block} } `; - } + } - block.chunks.intro.push(intro_block); - } + block.chunks.intro.push(intro_block); + } - if (outro) { - block.add_variable(outro_name); - const snippet = outro.expression - ? outro.expression.manipulate(block) - : x`{}`; + if (outro) { + block.add_variable(outro_name); + const snippet = outro.expression ? outro.expression.manipulate(block) : x`{}`; - const fn = this.renderer.reference(outro.name); + const fn = this.renderer.reference(outro.name); - if (!intro) { - block.chunks.intro.push(b` + if (!intro) { + block.chunks.intro.push(b` if (${outro_name}) ${outro_name}.end(1); `); - } + } - // TODO hide elements that have outro'd (unless they belong to a still-outroing - // group) prior to their removal from the DOM - let outro_block = b` + // TODO hide elements that have outro'd (unless they belong to a still-outroing + // group) prior to their removal from the DOM + let outro_block = b` ${outro_name} = @create_out_transition(${this.var}, ${fn}, ${snippet}); `; - if (outro.is_local) { - outro_block = b` + if (outro.is_local) { + outro_block = b` if (#local) { ${outro_block} } `; - } + } - block.chunks.outro.push(outro_block); + block.chunks.outro.push(outro_block); - block.chunks.destroy.push(b`if (detaching && ${outro_name}) ${outro_name}.end();`); - } - } + block.chunks.destroy.push(b`if (detaching && ${outro_name}) ${outro_name}.end();`); + } + } - if ((intro && intro.expression && intro.expression.dependencies.size) || (outro && outro.expression && outro.expression.dependencies.size)) { - block.maintain_context = true; - } - } + if ((intro && intro.expression && intro.expression.dependencies.size) || (outro && outro.expression && outro.expression.dependencies.size)) { + block.maintain_context = true; + } + } - add_animation(block) { - if (!this.node.animation) return; + add_animation(block) { + if (!this.node.animation) return; - const { outro } = this.node; + const { outro } = this.node; - const rect = block.get_unique_name('rect'); - const stop_animation = block.get_unique_name('stop_animation'); + const rect = block.get_unique_name('rect'); + const stop_animation = block.get_unique_name('stop_animation'); - block.add_variable(rect); - block.add_variable(stop_animation, x`@noop`); + block.add_variable(rect); + block.add_variable(stop_animation, x`@noop`); - block.chunks.measure.push(b` + block.chunks.measure.push(b` ${rect} = ${this.var}.getBoundingClientRect(); `); - block.chunks.fix.push(b` + block.chunks.fix.push(b` @fix_position(${this.var}); ${stop_animation}(); ${outro && b`@add_transform(${this.var}, ${rect});`} `); - let params; - if (this.node.animation.expression) { - params = this.node.animation.expression.manipulate(block); + let params; + if (this.node.animation.expression) { + params = this.node.animation.expression.manipulate(block); - if (this.node.animation.expression.dynamic_dependencies().length) { - // if `params` is dynamic, calculate params ahead of time in the `.r()` method - const params_var = block.get_unique_name('params'); - block.add_variable(params_var); + if (this.node.animation.expression.dynamic_dependencies().length) { + // if `params` is dynamic, calculate params ahead of time in the `.r()` method + const params_var = block.get_unique_name('params'); + block.add_variable(params_var); - block.chunks.measure.push(b`${params_var} = ${params};`); - params = params_var; - } - } else { - params = x`{}`; - } + block.chunks.measure.push(b`${params_var} = ${params};`); + params = params_var; + } + } else { + params = x`{}`; + } - const name = this.renderer.reference(this.node.animation.name); + const name = this.renderer.reference(this.node.animation.name); - block.chunks.animate.push(b` + block.chunks.animate.push(b` ${stop_animation}(); ${stop_animation} = @create_animation(${this.var}, ${rect}, ${name}, ${params}); `); - } - - add_classes(block) { - const has_spread = this.node.attributes.some(attr => attr.is_spread); - this.node.classes.forEach(class_directive => { - const { expression, name } = class_directive; - let snippet; - let dependencies; - if (expression) { - snippet = expression.manipulate(block); - dependencies = expression.dependencies; - } else { - snippet = name; - dependencies = new Set([name]); - } - const updater = b`@toggle_class(${this.var}, "${name}", ${snippet});`; - - block.chunks.hydrate.push(updater); - - if (has_spread) { - block.chunks.update.push(updater); - } else if ((dependencies && dependencies.size > 0) || this.class_dependencies.length) { - const all_dependencies = this.class_dependencies.concat(...dependencies); - const condition = block.renderer.dirty(all_dependencies); + } - // If all of the dependencies are non-dynamic (don't get updated) then there is no reason - // to add an updater for this. - const any_dynamic_dependencies = all_dependencies.some((dep) => { - const variable = this.renderer.component.var_lookup.get(dep); - return !variable || is_dynamic$1(variable); - }); - if (any_dynamic_dependencies) { - block.chunks.update.push(b` + add_classes(block) { + const has_spread = this.node.attributes.some((attr) => attr.is_spread); + this.node.classes.forEach((class_directive) => { + const { expression, name } = class_directive; + let snippet; + let dependencies; + if (expression) { + snippet = expression.manipulate(block); + dependencies = expression.dependencies; + } else { + snippet = name; + dependencies = new Set([name]); + } + const updater = b`@toggle_class(${this.var}, "${name}", ${snippet});`; + + block.chunks.hydrate.push(updater); + + if (has_spread) { + block.chunks.update.push(updater); + } else if ((dependencies && dependencies.size > 0) || this.class_dependencies.length) { + const all_dependencies = this.class_dependencies.concat(...dependencies); + const condition = block.renderer.dirty(all_dependencies); + + // If all of the dependencies are non-dynamic (don't get updated) then there is no reason + // to add an updater for this. + const any_dynamic_dependencies = all_dependencies.some((dep) => { + const variable = this.renderer.component.var_lookup.get(dep); + return !variable || is_dynamic$1(variable); + }); + if (any_dynamic_dependencies) { + block.chunks.update.push(b` if (${condition}) { ${updater} } `); - } - } - }); - } + } + } + }); + } - add_manual_style_scoping(block) { - if (this.node.needs_manual_style_scoping) { - const updater = b`@toggle_class(${this.var}, "${this.node.component.stylesheet.id}", true);`; - block.chunks.hydrate.push(updater); - block.chunks.update.push(updater); - } - } + add_manual_style_scoping(block) { + if (this.node.needs_manual_style_scoping) { + const updater = b`@toggle_class(${this.var}, "${this.node.component.stylesheet.id}", true);`; + block.chunks.hydrate.push(updater); + block.chunks.update.push(updater); + } + } } function to_html(wrappers, block, literal, state, can_use_raw_text) { - wrappers.forEach(wrapper => { - if (wrapper instanceof TextWrapper) { - if ((wrapper ).use_space()) state.quasi.value.raw += ' '; - - const parent = wrapper.node.parent ; - - const raw = parent && ( - parent.name === 'script' || - parent.name === 'style' || - can_use_raw_text - ); - - state.quasi.value.raw += (raw ? wrapper.data : escape_html(wrapper.data)) - .replace(/\\/g, '\\\\') - .replace(/`/g, '\\`') - .replace(/\$/g, '\\$'); - } else if (wrapper instanceof MustacheTagWrapper || wrapper instanceof RawMustacheTagWrapper) { - literal.quasis.push(state.quasi); - literal.expressions.push(wrapper.node.expression.manipulate(block)); - state.quasi = { - type: 'TemplateElement', - value: { raw: '' } - }; - } else if (wrapper.node.name === 'noscript') ; else { - // element - state.quasi.value.raw += `<${wrapper.node.name}`; - - (wrapper ).attributes.forEach((attr) => { - state.quasi.value.raw += ` ${fix_attribute_casing(attr.node.name)}="`; - - attr.node.chunks.forEach(chunk => { - if (chunk.type === 'Text') { - state.quasi.value.raw += escape_html(chunk.data); - } else { - literal.quasis.push(state.quasi); - literal.expressions.push(chunk.manipulate(block)); + wrappers.forEach((wrapper) => { + if (wrapper instanceof TextWrapper) { + if (wrapper.use_space()) state.quasi.value.raw += ' '; + + const parent = wrapper.node.parent; + + const raw = parent && (parent.name === 'script' || parent.name === 'style' || can_use_raw_text); + + state.quasi.value.raw += (raw ? wrapper.data : escape_html(wrapper.data)).replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$/g, '\\$'); + } else if (wrapper instanceof MustacheTagWrapper || wrapper instanceof RawMustacheTagWrapper) { + literal.quasis.push(state.quasi); + literal.expressions.push(wrapper.node.expression.manipulate(block)); + state.quasi = { + type: 'TemplateElement', + value: { raw: '' }, + }; + } else if (wrapper.node.name === 'noscript'); + else { + // element + state.quasi.value.raw += `<${wrapper.node.name}`; - state.quasi = { - type: 'TemplateElement', - value: { raw: '' } - }; - } - }); + wrapper.attributes.forEach((attr) => { + state.quasi.value.raw += ` ${fix_attribute_casing(attr.node.name)}="`; - state.quasi.value.raw += '"'; - }); + attr.node.chunks.forEach((chunk) => { + if (chunk.type === 'Text') { + state.quasi.value.raw += escape_html(chunk.data); + } else { + literal.quasis.push(state.quasi); + literal.expressions.push(chunk.manipulate(block)); - if (!wrapper.void) { - state.quasi.value.raw += '>'; + state.quasi = { + type: 'TemplateElement', + value: { raw: '' }, + }; + } + }); - to_html(wrapper.fragment.nodes , block, literal, state); + state.quasi.value.raw += '"'; + }); - state.quasi.value.raw += `</${wrapper.node.name}>`; - } else { - state.quasi.value.raw += '/>'; - } - } - }); + if (!wrapper.void) { + state.quasi.value.raw += '>'; + + to_html(wrapper.fragment.nodes, block, literal, state); + + state.quasi.value.raw += `</${wrapper.node.name}>`; + } else { + state.quasi.value.raw += '/>'; + } + } + }); } class HeadWrapper extends Wrapper { - - - - constructor( - renderer, - block, - parent, - node, - strip_whitespace, - next_sibling - ) { - super(renderer, block, parent, node); - - this.can_use_innerhtml = false; - - this.fragment = new FragmentWrapper( - renderer, - block, - node.children, - this, - strip_whitespace, - next_sibling - ); - } - - render(block, _parent_node, _parent_nodes) { - let nodes; - if (this.renderer.options.hydratable && this.fragment.nodes.length) { - nodes = block.get_unique_name('head_nodes'); - block.chunks.claim.push(b`const ${nodes} = @query_selector_all('[data-svelte="${this.node.id}"]', @_document.head);`); - } + constructor(renderer, block, parent, node, strip_whitespace, next_sibling) { + super(renderer, block, parent, node); - this.fragment.render(block, x`@_document.head` , nodes); + this.can_use_innerhtml = false; - if (nodes && this.renderer.options.hydratable) { - block.chunks.claim.push( - b`${nodes}.forEach(@detach);` - ); - } - } + this.fragment = new FragmentWrapper(renderer, block, node.children, this, strip_whitespace, next_sibling); + } + + render(block, _parent_node, _parent_nodes) { + let nodes; + if (this.renderer.options.hydratable && this.fragment.nodes.length) { + nodes = block.get_unique_name('head_nodes'); + block.chunks.claim.push(b`const ${nodes} = @query_selector_all('[data-svelte="${this.node.id}"]', @_document.head);`); + } + + this.fragment.render(block, x`@_document.head`, nodes); + + if (nodes && this.renderer.options.hydratable) { + block.chunks.claim.push(b`${nodes}.forEach(@detach);`); + } + } } function is_else_if(node) { - return ( - node && node.children.length === 1 && node.children[0].type === 'IfBlock' - ); + return node && node.children.length === 1 && node.children[0].type === 'IfBlock'; } class IfBlockBranch extends Wrapper { - - - - - - - - __init() {this.var = null;} - - constructor( - renderer, - block, - parent, - node, - strip_whitespace, - next_sibling - ) { - super(renderer, block, parent, node);IfBlockBranch.prototype.__init.call(this); - const { expression } = (node ); - const is_else = !expression; - - if (expression) { - this.dependencies = expression.dynamic_dependencies(); - - // TODO is this the right rule? or should any non-reference count? - // const should_cache = !is_reference(expression.node, null) && dependencies.length > 0; - let should_cache = false; - walk(expression.node, { - enter(node) { - if (node.type === 'CallExpression' || node.type === 'NewExpression') { - should_cache = true; - } - } - }); + __init() { + this.var = null; + } - if (should_cache) { - this.condition = block.get_unique_name('show_if'); - this.snippet = (expression.manipulate(block) ); - } else { - this.condition = expression.manipulate(block); - } - } + constructor(renderer, block, parent, node, strip_whitespace, next_sibling) { + super(renderer, block, parent, node); + IfBlockBranch.prototype.__init.call(this); + const { expression } = node; + const is_else = !expression; + + if (expression) { + this.dependencies = expression.dynamic_dependencies(); + + // TODO is this the right rule? or should any non-reference count? + // const should_cache = !is_reference(expression.node, null) && dependencies.length > 0; + let should_cache = false; + walk(expression.node, { + enter(node) { + if (node.type === 'CallExpression' || node.type === 'NewExpression') { + should_cache = true; + } + }, + }); - this.block = block.child({ - comment: create_debugging_comment(node, parent.renderer.component), - name: parent.renderer.component.get_unique_name( - is_else ? 'create_else_block' : 'create_if_block' - ), - type: (node ).expression ? 'if' : 'else' - }); + if (should_cache) { + this.condition = block.get_unique_name('show_if'); + this.snippet = expression.manipulate(block); + } else { + this.condition = expression.manipulate(block); + } + } - this.fragment = new FragmentWrapper(renderer, this.block, node.children, parent, strip_whitespace, next_sibling); + this.block = block.child({ + comment: create_debugging_comment(node, parent.renderer.component), + name: parent.renderer.component.get_unique_name(is_else ? 'create_else_block' : 'create_if_block'), + type: node.expression ? 'if' : 'else', + }); + + this.fragment = new FragmentWrapper(renderer, this.block, node.children, parent, strip_whitespace, next_sibling); - this.is_dynamic = this.block.dependencies.size > 0; - } + this.is_dynamic = this.block.dependencies.size > 0; + } } class IfBlockWrapper extends Wrapper { - - - __init2() {this.needs_update = false;} - - __init3() {this.var = { type: 'Identifier', name: 'if_block' };} - - constructor( - renderer, - block, - parent, - node, - strip_whitespace, - next_sibling - ) { - super(renderer, block, parent, node);IfBlockWrapper.prototype.__init2.call(this);IfBlockWrapper.prototype.__init3.call(this); - this.cannot_use_innerhtml(); - this.not_static_content(); - - this.branches = []; - - const blocks = []; - let is_dynamic = false; - let has_intros = false; - let has_outros = false; - - const create_branches = (node) => { - const branch = new IfBlockBranch( - renderer, - block, - this, - node, - strip_whitespace, - next_sibling - ); - - this.branches.push(branch); - - blocks.push(branch.block); - block.add_dependencies(node.expression.dependencies); - - if (branch.block.dependencies.size > 0) { - // the condition, or its contents, is dynamic - is_dynamic = true; - block.add_dependencies(branch.block.dependencies); - } + __init2() { + this.needs_update = false; + } - if (branch.dependencies && branch.dependencies.length > 0) { - // the condition itself is dynamic - this.needs_update = true; - } + __init3() { + this.var = { type: 'Identifier', name: 'if_block' }; + } - if (branch.block.has_intros) has_intros = true; - if (branch.block.has_outros) has_outros = true; + constructor(renderer, block, parent, node, strip_whitespace, next_sibling) { + super(renderer, block, parent, node); + IfBlockWrapper.prototype.__init2.call(this); + IfBlockWrapper.prototype.__init3.call(this); + this.cannot_use_innerhtml(); + this.not_static_content(); - if (is_else_if(node.else)) { - create_branches(node.else.children[0] ); - } else if (node.else) { - const branch = new IfBlockBranch( - renderer, - block, - this, - node.else, - strip_whitespace, - next_sibling - ); + this.branches = []; - this.branches.push(branch); + const blocks = []; + let is_dynamic = false; + let has_intros = false; + let has_outros = false; - blocks.push(branch.block); + const create_branches = (node) => { + const branch = new IfBlockBranch(renderer, block, this, node, strip_whitespace, next_sibling); - if (branch.block.dependencies.size > 0) { - is_dynamic = true; - block.add_dependencies(branch.block.dependencies); - } + this.branches.push(branch); - if (branch.block.has_intros) has_intros = true; - if (branch.block.has_outros) has_outros = true; - } - }; + blocks.push(branch.block); + block.add_dependencies(node.expression.dependencies); - create_branches(this.node); + if (branch.block.dependencies.size > 0) { + // the condition, or its contents, is dynamic + is_dynamic = true; + block.add_dependencies(branch.block.dependencies); + } - blocks.forEach(block => { - block.has_update_method = is_dynamic; - block.has_intro_method = has_intros; - block.has_outro_method = has_outros; - }); + if (branch.dependencies && branch.dependencies.length > 0) { + // the condition itself is dynamic + this.needs_update = true; + } - renderer.blocks.push(...blocks); - } + if (branch.block.has_intros) has_intros = true; + if (branch.block.has_outros) has_outros = true; - render( - block, - parent_node, - parent_nodes - ) { - const name = this.var; + if (is_else_if(node.else)) { + create_branches(node.else.children[0]); + } else if (node.else) { + const branch = new IfBlockBranch(renderer, block, this, node.else, strip_whitespace, next_sibling); - const needs_anchor = this.next ? !this.next.is_dom_node() : !parent_node || !this.parent.is_dom_node(); - const anchor = needs_anchor - ? block.get_unique_name(`${this.var.name}_anchor`) - : (this.next && this.next.var) || 'null'; + this.branches.push(branch); - const has_else = !(this.branches[this.branches.length - 1].condition); - const if_exists_condition = has_else ? null : name; + blocks.push(branch.block); - const dynamic = this.branches[0].block.has_update_method; // can use [0] as proxy for all, since they necessarily have the same value - const has_intros = this.branches[0].block.has_intro_method; - const has_outros = this.branches[0].block.has_outro_method; - const has_transitions = has_intros || has_outros; + if (branch.block.dependencies.size > 0) { + is_dynamic = true; + block.add_dependencies(branch.block.dependencies); + } - const vars = { name, anchor, if_exists_condition, has_else, has_transitions }; + if (branch.block.has_intros) has_intros = true; + if (branch.block.has_outros) has_outros = true; + } + }; - const detaching = parent_node && !is_head(parent_node) ? null : 'detaching'; + create_branches(this.node); - if (this.node.else) { - this.branches.forEach(branch => { - if (branch.snippet) block.add_variable(branch.condition); - }); + blocks.forEach((block) => { + block.has_update_method = is_dynamic; + block.has_intro_method = has_intros; + block.has_outro_method = has_outros; + }); - if (has_outros) { - this.render_compound_with_outros(block, parent_node, parent_nodes, dynamic, vars, detaching); + renderer.blocks.push(...blocks); + } - block.chunks.outro.push(b`@transition_out(${name});`); - } else { - this.render_compound(block, parent_node, parent_nodes, dynamic, vars, detaching); - } - } else { - this.render_simple(block, parent_node, parent_nodes, dynamic, vars, detaching); + render(block, parent_node, parent_nodes) { + const name = this.var; - if (has_outros) { - block.chunks.outro.push(b`@transition_out(${name});`); - } - } + const needs_anchor = this.next ? !this.next.is_dom_node() : !parent_node || !this.parent.is_dom_node(); + const anchor = needs_anchor ? block.get_unique_name(`${this.var.name}_anchor`) : (this.next && this.next.var) || 'null'; - if (if_exists_condition) { - block.chunks.create.push(b`if (${if_exists_condition}) ${name}.c();`); - } else { - block.chunks.create.push(b`${name}.c();`); - } + const has_else = !this.branches[this.branches.length - 1].condition; + const if_exists_condition = has_else ? null : name; - if (parent_nodes && this.renderer.options.hydratable) { - if (if_exists_condition) { - block.chunks.claim.push( - b`if (${if_exists_condition}) ${name}.l(${parent_nodes});` - ); - } else { - block.chunks.claim.push( - b`${name}.l(${parent_nodes});` - ); - } - } + const dynamic = this.branches[0].block.has_update_method; // can use [0] as proxy for all, since they necessarily have the same value + const has_intros = this.branches[0].block.has_intro_method; + const has_outros = this.branches[0].block.has_outro_method; + const has_transitions = has_intros || has_outros; - if (has_intros || has_outros) { - block.chunks.intro.push(b`@transition_in(${name});`); - } + const vars = { name, anchor, if_exists_condition, has_else, has_transitions }; - if (needs_anchor) { - block.add_element( - anchor , - x`@empty()`, - parent_nodes && x`@empty()`, - parent_node - ); - } + const detaching = parent_node && !is_head(parent_node) ? null : 'detaching'; - this.branches.forEach(branch => { - branch.fragment.render(branch.block, null, x`#nodes` ); - }); - } - - render_compound( - block, - parent_node, - _parent_nodes, - dynamic, - { name, anchor, has_else, if_exists_condition, has_transitions }, - detaching - ) { - const select_block_type = this.renderer.component.get_unique_name('select_block_type'); - const current_block_type = block.get_unique_name('current_block_type'); - const get_block = has_else - ? x`${current_block_type}(#ctx)` - : x`${current_block_type} && ${current_block_type}(#ctx)`; - - if (this.needs_update) { - block.chunks.init.push(b` + if (this.node.else) { + this.branches.forEach((branch) => { + if (branch.snippet) block.add_variable(branch.condition); + }); + + if (has_outros) { + this.render_compound_with_outros(block, parent_node, parent_nodes, dynamic, vars, detaching); + + block.chunks.outro.push(b`@transition_out(${name});`); + } else { + this.render_compound(block, parent_node, parent_nodes, dynamic, vars, detaching); + } + } else { + this.render_simple(block, parent_node, parent_nodes, dynamic, vars, detaching); + + if (has_outros) { + block.chunks.outro.push(b`@transition_out(${name});`); + } + } + + if (if_exists_condition) { + block.chunks.create.push(b`if (${if_exists_condition}) ${name}.c();`); + } else { + block.chunks.create.push(b`${name}.c();`); + } + + if (parent_nodes && this.renderer.options.hydratable) { + if (if_exists_condition) { + block.chunks.claim.push(b`if (${if_exists_condition}) ${name}.l(${parent_nodes});`); + } else { + block.chunks.claim.push(b`${name}.l(${parent_nodes});`); + } + } + + if (has_intros || has_outros) { + block.chunks.intro.push(b`@transition_in(${name});`); + } + + if (needs_anchor) { + block.add_element(anchor, x`@empty()`, parent_nodes && x`@empty()`, parent_node); + } + + this.branches.forEach((branch) => { + branch.fragment.render(branch.block, null, x`#nodes`); + }); + } + + render_compound(block, parent_node, _parent_nodes, dynamic, { name, anchor, has_else, if_exists_condition, has_transitions }, detaching) { + const select_block_type = this.renderer.component.get_unique_name('select_block_type'); + const current_block_type = block.get_unique_name('current_block_type'); + const get_block = has_else ? x`${current_block_type}(#ctx)` : x`${current_block_type} && ${current_block_type}(#ctx)`; + + if (this.needs_update) { + block.chunks.init.push(b` function ${select_block_type}(#ctx, #dirty) { - ${this.branches.map(({ dependencies, condition, snippet, block }) => condition - ? b` - ${snippet && ( - dependencies.length > 0 - ? b`if (${condition} == null || ${block.renderer.dirty(dependencies)}) ${condition} = !!${snippet}` - : b`if (${condition} == null) ${condition} = !!${snippet}` - )} + ${this.branches.map(({ dependencies, condition, snippet, block }) => + condition + ? b` + ${ + snippet && + (dependencies.length > 0 + ? b`if (${condition} == null || ${block.renderer.dirty(dependencies)}) ${condition} = !!${snippet}` + : b`if (${condition} == null) ${condition} = !!${snippet}`) + } if (${condition}) return ${block.name};` - : b`return ${block.name};`)} + : b`return ${block.name};` + )} } `); - } else { - block.chunks.init.push(b` + } else { + block.chunks.init.push(b` function ${select_block_type}(#ctx, #dirty) { - ${this.branches.map(({ condition, snippet, block }) => condition - ? b`if (${snippet || condition}) return ${block.name};` - : b`return ${block.name};`)} + ${this.branches.map(({ condition, snippet, block }) => (condition ? b`if (${snippet || condition}) return ${block.name};` : b`return ${block.name};`))} } `); - } + } - block.chunks.init.push(b` + block.chunks.init.push(b` let ${current_block_type} = ${select_block_type}(#ctx, ${this.get_initial_dirty_bit()}); let ${name} = ${get_block}; `); - const initial_mount_node = parent_node || '#target'; - const anchor_node = parent_node ? 'null' : '#anchor'; - - if (if_exists_condition) { - block.chunks.mount.push( - b`if (${if_exists_condition}) ${name}.m(${initial_mount_node}, ${anchor_node});` - ); - } else { - block.chunks.mount.push( - b`${name}.m(${initial_mount_node}, ${anchor_node});` - ); - } + const initial_mount_node = parent_node || '#target'; + const anchor_node = parent_node ? 'null' : '#anchor'; + + if (if_exists_condition) { + block.chunks.mount.push(b`if (${if_exists_condition}) ${name}.m(${initial_mount_node}, ${anchor_node});`); + } else { + block.chunks.mount.push(b`${name}.m(${initial_mount_node}, ${anchor_node});`); + } - if (this.needs_update) { - const update_mount_node = this.get_update_mount_node(anchor); + if (this.needs_update) { + const update_mount_node = this.get_update_mount_node(anchor); - const change_block = b` + const change_block = b` ${if_exists_condition ? b`if (${if_exists_condition}) ${name}.d(1)` : b`${name}.d(1)`}; ${name} = ${get_block}; if (${name}) { @@ -12386,123 +11446,108 @@ class IfBlockWrapper extends Wrapper { } `; - if (dynamic) { - block.chunks.update.push(b` + if (dynamic) { + block.chunks.update.push(b` if (${current_block_type} === (${current_block_type} = ${select_block_type}(#ctx, #dirty)) && ${name}) { ${name}.p(#ctx, #dirty); } else { ${change_block} } `); - } else { - block.chunks.update.push(b` + } else { + block.chunks.update.push(b` if (${current_block_type} !== (${current_block_type} = ${select_block_type}(#ctx, #dirty))) { ${change_block} } `); - } - } else if (dynamic) { - if (if_exists_condition) { - block.chunks.update.push(b`if (${if_exists_condition}) ${name}.p(#ctx, #dirty);`); - } else { - block.chunks.update.push(b`${name}.p(#ctx, #dirty);`); - } - } + } + } else if (dynamic) { + if (if_exists_condition) { + block.chunks.update.push(b`if (${if_exists_condition}) ${name}.p(#ctx, #dirty);`); + } else { + block.chunks.update.push(b`${name}.p(#ctx, #dirty);`); + } + } - if (if_exists_condition) { - block.chunks.destroy.push(b` + if (if_exists_condition) { + block.chunks.destroy.push(b` if (${if_exists_condition}) { ${name}.d(${detaching}); } `); - } else { - block.chunks.destroy.push(b` + } else { + block.chunks.destroy.push(b` ${name}.d(${detaching}); `); - } - } - - // if any of the siblings have outros, we need to keep references to the blocks - // (TODO does this only apply to bidi transitions?) - render_compound_with_outros( - block, - parent_node, - _parent_nodes, - dynamic, - { name, anchor, has_else, has_transitions, if_exists_condition }, - detaching - ) { - const select_block_type = this.renderer.component.get_unique_name('select_block_type'); - const current_block_type_index = block.get_unique_name('current_block_type_index'); - const previous_block_index = block.get_unique_name('previous_block_index'); - const if_block_creators = block.get_unique_name('if_block_creators'); - const if_blocks = block.get_unique_name('if_blocks'); - - const if_current_block_type_index = has_else - ? nodes => nodes - : nodes => b`if (~${current_block_type_index}) { ${nodes} }`; - - block.add_variable(current_block_type_index); - block.add_variable(name); - - block.chunks.init.push(b` + } + } + + // if any of the siblings have outros, we need to keep references to the blocks + // (TODO does this only apply to bidi transitions?) + render_compound_with_outros(block, parent_node, _parent_nodes, dynamic, { name, anchor, has_else, has_transitions, if_exists_condition }, detaching) { + const select_block_type = this.renderer.component.get_unique_name('select_block_type'); + const current_block_type_index = block.get_unique_name('current_block_type_index'); + const previous_block_index = block.get_unique_name('previous_block_index'); + const if_block_creators = block.get_unique_name('if_block_creators'); + const if_blocks = block.get_unique_name('if_blocks'); + + const if_current_block_type_index = has_else ? (nodes) => nodes : (nodes) => b`if (~${current_block_type_index}) { ${nodes} }`; + + block.add_variable(current_block_type_index); + block.add_variable(name); + + block.chunks.init.push(b` const ${if_block_creators} = [ - ${this.branches.map(branch => branch.block.name)} + ${this.branches.map((branch) => branch.block.name)} ]; const ${if_blocks} = []; - ${this.needs_update - ? b` + ${ + this.needs_update + ? b` function ${select_block_type}(#ctx, #dirty) { - ${this.branches.map(({ dependencies, condition, snippet }, i) => condition - ? b` - ${snippet && ( - dependencies.length > 0 - ? b`if (${block.renderer.dirty(dependencies)}) ${condition} = !!${snippet}` - : b`if (${condition} == null) ${condition} = !!${snippet}` - )} + ${this.branches.map(({ dependencies, condition, snippet }, i) => + condition + ? b` + ${snippet && (dependencies.length > 0 ? b`if (${block.renderer.dirty(dependencies)}) ${condition} = !!${snippet}` : b`if (${condition} == null) ${condition} = !!${snippet}`)} if (${condition}) return ${i};` - : b`return ${i};`)} + : b`return ${i};` + )} ${!has_else && b`return -1;`} } ` - : b` + : b` function ${select_block_type}(#ctx, #dirty) { - ${this.branches.map(({ condition, snippet }, i) => condition - ? b`if (${snippet || condition}) return ${i};` - : b`return ${i};`)} + ${this.branches.map(({ condition, snippet }, i) => (condition ? b`if (${snippet || condition}) return ${i};` : b`return ${i};`))} ${!has_else && b`return -1;`} } - `} + ` + } `); - if (has_else) { - block.chunks.init.push(b` + if (has_else) { + block.chunks.init.push(b` ${current_block_type_index} = ${select_block_type}(#ctx, ${this.get_initial_dirty_bit()}); ${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](#ctx); `); - } else { - block.chunks.init.push(b` + } else { + block.chunks.init.push(b` if (~(${current_block_type_index} = ${select_block_type}(#ctx, ${this.get_initial_dirty_bit()}))) { ${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](#ctx); } `); - } + } - const initial_mount_node = parent_node || '#target'; - const anchor_node = parent_node ? 'null' : '#anchor'; + const initial_mount_node = parent_node || '#target'; + const anchor_node = parent_node ? 'null' : '#anchor'; - block.chunks.mount.push( - if_current_block_type_index( - b`${if_blocks}[${current_block_type_index}].m(${initial_mount_node}, ${anchor_node});` - ) - ); + block.chunks.mount.push(if_current_block_type_index(b`${if_blocks}[${current_block_type_index}].m(${initial_mount_node}, ${anchor_node});`)); - if (this.needs_update) { - const update_mount_node = this.get_update_mount_node(anchor); + if (this.needs_update) { + const update_mount_node = this.get_update_mount_node(anchor); - const destroy_old_block = b` + const destroy_old_block = b` @group_outros(); @transition_out(${if_blocks}[${previous_block_index}], 1, 1, () => { ${if_blocks}[${previous_block_index}] = null; @@ -12510,7 +11555,7 @@ class IfBlockWrapper extends Wrapper { @check_outros(); `; - const create_new_block = b` + const create_new_block = b` ${name} = ${if_blocks}[${current_block_type_index}]; if (!${name}) { ${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](#ctx); @@ -12522,13 +11567,13 @@ class IfBlockWrapper extends Wrapper { ${name}.m(${update_mount_node}, ${anchor}); `; - const change_block = has_else - ? b` + const change_block = has_else + ? b` ${destroy_old_block} ${create_new_block} ` - : b` + : b` if (${name}) { ${destroy_old_block} } @@ -12540,74 +11585,63 @@ class IfBlockWrapper extends Wrapper { } `; - block.chunks.update.push(b` + block.chunks.update.push(b` let ${previous_block_index} = ${current_block_type_index}; ${current_block_type_index} = ${select_block_type}(#ctx, #dirty); `); - if (dynamic) { - block.chunks.update.push(b` + if (dynamic) { + block.chunks.update.push(b` if (${current_block_type_index} === ${previous_block_index}) { ${if_current_block_type_index(b`${if_blocks}[${current_block_type_index}].p(#ctx, #dirty);`)} } else { ${change_block} } `); - } else { - block.chunks.update.push(b` + } else { + block.chunks.update.push(b` if (${current_block_type_index} !== ${previous_block_index}) { ${change_block} } `); - } - } else if (dynamic) { - if (if_exists_condition) { - block.chunks.update.push(b`if (${if_exists_condition}) ${name}.p(#ctx, #dirty);`); - } else { - block.chunks.update.push(b`${name}.p(#ctx, #dirty);`); - } - } + } + } else if (dynamic) { + if (if_exists_condition) { + block.chunks.update.push(b`if (${if_exists_condition}) ${name}.p(#ctx, #dirty);`); + } else { + block.chunks.update.push(b`${name}.p(#ctx, #dirty);`); + } + } - block.chunks.destroy.push( - if_current_block_type_index(b`${if_blocks}[${current_block_type_index}].d(${detaching});`) - ); - } + block.chunks.destroy.push(if_current_block_type_index(b`${if_blocks}[${current_block_type_index}].d(${detaching});`)); + } - render_simple( - block, - parent_node, - _parent_nodes, - dynamic, - { name, anchor, if_exists_condition, has_transitions }, - detaching - ) { - const branch = this.branches[0]; + render_simple(block, parent_node, _parent_nodes, dynamic, { name, anchor, if_exists_condition, has_transitions }, detaching) { + const branch = this.branches[0]; - if (branch.snippet) block.add_variable(branch.condition, branch.snippet); + if (branch.snippet) block.add_variable(branch.condition, branch.snippet); - block.chunks.init.push(b` + block.chunks.init.push(b` let ${name} = ${branch.condition} && ${branch.block.name}(#ctx); `); - const initial_mount_node = parent_node || '#target'; - const anchor_node = parent_node ? 'null' : '#anchor'; + const initial_mount_node = parent_node || '#target'; + const anchor_node = parent_node ? 'null' : '#anchor'; - block.chunks.mount.push( - b`if (${name}) ${name}.m(${initial_mount_node}, ${anchor_node});` - ); + block.chunks.mount.push(b`if (${name}) ${name}.m(${initial_mount_node}, ${anchor_node});`); - if (branch.dependencies.length > 0) { - const update_mount_node = this.get_update_mount_node(anchor); + if (branch.dependencies.length > 0) { + const update_mount_node = this.get_update_mount_node(anchor); - const enter = b` + const enter = b` if (${name}) { ${dynamic && b`${name}.p(#ctx, #dirty);`} ${ - has_transitions && - b`if (${block.renderer.dirty(branch.dependencies)}) { + has_transitions && + b`if (${block.renderer.dirty(branch.dependencies)}) { @transition_in(${name}, 1); }` - } + } } else { ${name} = ${branch.block.name}(#ctx); ${name}.c(); @@ -12616,14 +11650,14 @@ class IfBlockWrapper extends Wrapper { } `; - if (branch.snippet) { - block.chunks.update.push(b`if (${block.renderer.dirty(branch.dependencies)}) ${branch.condition} = ${branch.snippet}`); - } + if (branch.snippet) { + block.chunks.update.push(b`if (${block.renderer.dirty(branch.dependencies)}) ${branch.condition} = ${branch.snippet}`); + } - // no `p()` here — we don't want to update outroing nodes, - // as that will typically result in glitching - if (branch.block.has_outro_method) { - block.chunks.update.push(b` + // no `p()` here — we don't want to update outroing nodes, + // as that will typically result in glitching + if (branch.block.has_outro_method) { + block.chunks.update.push(b` if (${branch.condition}) { ${enter} } else if (${name}) { @@ -12634,8 +11668,8 @@ class IfBlockWrapper extends Wrapper { @check_outros(); } `); - } else { - block.chunks.update.push(b` + } else { + block.chunks.update.push(b` if (${branch.condition}) { ${enter} } else if (${name}) { @@ -12643,646 +11677,574 @@ class IfBlockWrapper extends Wrapper { ${name} = null; } `); - } - } else if (dynamic) { - block.chunks.update.push(b` + } + } else if (dynamic) { + block.chunks.update.push(b` if (${branch.condition}) ${name}.p(#ctx, #dirty); `); - } + } - if (if_exists_condition) { - block.chunks.destroy.push(b` + if (if_exists_condition) { + block.chunks.destroy.push(b` if (${if_exists_condition}) ${name}.d(${detaching}); `); - } else { - block.chunks.destroy.push(b` + } else { + block.chunks.destroy.push(b` ${name}.d(${detaching}); `); - } - } - - get_initial_dirty_bit() { - const _this = this; - // TODO: context-overflow make it less gross - const val = x`-1` ; - return { - get type() { - return _this.renderer.context_overflow ? 'ArrayExpression' : 'UnaryExpression'; - }, - // as [-1] - elements: [val], - // as -1 - operator: val.operator, - prefix: val.prefix, - argument: val.argument - }; - } + } + } + + get_initial_dirty_bit() { + const _this = this; + // TODO: context-overflow make it less gross + const val = x`-1`; + return { + get type() { + return _this.renderer.context_overflow ? 'ArrayExpression' : 'UnaryExpression'; + }, + // as [-1] + elements: [val], + // as -1 + operator: val.operator, + prefix: val.prefix, + argument: val.argument, + }; + } } class KeyBlockWrapper extends Wrapper { - - - - - __init() {this.var = { type: 'Identifier', name: 'key_block' };} - - constructor( - renderer, - block, - parent, - node, - strip_whitespace, - next_sibling - ) { - super(renderer, block, parent, node);KeyBlockWrapper.prototype.__init.call(this); - this.cannot_use_innerhtml(); - this.not_static_content(); - - this.dependencies = node.expression.dynamic_dependencies(); - - if (this.dependencies.length) { - block = block.child({ - comment: create_debugging_comment(node, renderer.component), - name: renderer.component.get_unique_name('create_key_block'), - type: 'key' - }); - renderer.blocks.push(block); - } + __init() { + this.var = { type: 'Identifier', name: 'key_block' }; + } - this.block = block; - this.fragment = new FragmentWrapper( - renderer, - this.block, - node.children, - this, - strip_whitespace, - next_sibling - ); - } - - render(block, parent_node, parent_nodes) { - if (this.dependencies.length === 0) { - this.render_static_key(block, parent_node, parent_nodes); - } else { - this.render_dynamic_key(block, parent_node, parent_nodes); - } - } + constructor(renderer, block, parent, node, strip_whitespace, next_sibling) { + super(renderer, block, parent, node); + KeyBlockWrapper.prototype.__init.call(this); + this.cannot_use_innerhtml(); + this.not_static_content(); + + this.dependencies = node.expression.dynamic_dependencies(); + + if (this.dependencies.length) { + block = block.child({ + comment: create_debugging_comment(node, renderer.component), + name: renderer.component.get_unique_name('create_key_block'), + type: 'key', + }); + renderer.blocks.push(block); + } - render_static_key(_block, parent_node, parent_nodes) { - this.fragment.render(this.block, parent_node, parent_nodes); - } + this.block = block; + this.fragment = new FragmentWrapper(renderer, this.block, node.children, this, strip_whitespace, next_sibling); + } - render_dynamic_key(block, parent_node, parent_nodes) { - this.fragment.render( - this.block, - null, - (x`#nodes` ) - ); + render(block, parent_node, parent_nodes) { + if (this.dependencies.length === 0) { + this.render_static_key(block, parent_node, parent_nodes); + } else { + this.render_dynamic_key(block, parent_node, parent_nodes); + } + } - const has_transitions = !!( - this.block.has_intro_method || this.block.has_outro_method - ); - const dynamic = this.block.has_update_method; + render_static_key(_block, parent_node, parent_nodes) { + this.fragment.render(this.block, parent_node, parent_nodes); + } + + render_dynamic_key(block, parent_node, parent_nodes) { + this.fragment.render(this.block, null, x`#nodes`); - const previous_key = block.get_unique_name('previous_key'); - const snippet = this.node.expression.manipulate(block); - block.add_variable(previous_key, snippet); + const has_transitions = !!(this.block.has_intro_method || this.block.has_outro_method); + const dynamic = this.block.has_update_method; - const not_equal = this.renderer.component.component_options.immutable ? x`@not_equal` : x`@safe_not_equal`; - const condition = x`${this.renderer.dirty(this.dependencies)} && ${not_equal}(${previous_key}, ${previous_key} = ${snippet})`; + const previous_key = block.get_unique_name('previous_key'); + const snippet = this.node.expression.manipulate(block); + block.add_variable(previous_key, snippet); - block.chunks.init.push(b` + const not_equal = this.renderer.component.component_options.immutable ? x`@not_equal` : x`@safe_not_equal`; + const condition = x`${this.renderer.dirty(this.dependencies)} && ${not_equal}(${previous_key}, ${previous_key} = ${snippet})`; + + block.chunks.init.push(b` let ${this.var} = ${this.block.name}(#ctx); `); - block.chunks.create.push(b`${this.var}.c();`); - if (this.renderer.options.hydratable) { - block.chunks.claim.push(b`${this.var}.l(${parent_nodes});`); - } - block.chunks.mount.push( - b`${this.var}.m(${parent_node || '#target'}, ${ - parent_node ? 'null' : '#anchor' - });` - ); - const anchor = this.get_or_create_anchor(block, parent_node, parent_nodes); - const body = b` + block.chunks.create.push(b`${this.var}.c();`); + if (this.renderer.options.hydratable) { + block.chunks.claim.push(b`${this.var}.l(${parent_nodes});`); + } + block.chunks.mount.push(b`${this.var}.m(${parent_node || '#target'}, ${parent_node ? 'null' : '#anchor'});`); + const anchor = this.get_or_create_anchor(block, parent_node, parent_nodes); + const body = b` ${ - has_transitions - ? b` + has_transitions + ? b` @group_outros(); @transition_out(${this.var}, 1, 1, @noop); @check_outros(); ` - : b`${this.var}.d(1);` - } + : b`${this.var}.d(1);` + } ${this.var} = ${this.block.name}(#ctx); ${this.var}.c(); ${has_transitions && b`@transition_in(${this.var})`} ${this.var}.m(${this.get_update_mount_node(anchor)}, ${anchor}); `; - if (dynamic) { - block.chunks.update.push(b` + if (dynamic) { + block.chunks.update.push(b` if (${condition}) { ${body} } else { ${this.var}.p(#ctx, #dirty); } `); - } else { - block.chunks.update.push(b` + } else { + block.chunks.update.push(b` if (${condition}) { ${body} } `); - } + } - if (has_transitions) { - block.chunks.intro.push(b`@transition_in(${this.var})`); - block.chunks.outro.push(b`@transition_out(${this.var})`); - } + if (has_transitions) { + block.chunks.intro.push(b`@transition_in(${this.var})`); + block.chunks.outro.push(b`@transition_out(${this.var})`); + } - block.chunks.destroy.push(b`${this.var}.d(detaching)`); - } + block.chunks.destroy.push(b`${this.var}.d(detaching)`); + } } function get_slot_definition(block, scope, lets) { - if (lets.length === 0) return { block, scope }; - - const context_input = { - type: 'ObjectPattern', - properties: lets.map(l => ({ - type: 'Property', - kind: 'init', - key: l.name, - value: l.value || l.name - })) - }; - - const properties = []; - const value_map = new Map(); - - lets.forEach(l => { - let value; - if (l.names.length > 1) { - // more than one, probably destructuring - const unique_name = block.get_unique_name(l.names.join('_')).name; - value_map.set(l.value, unique_name); - value = { type: 'Identifier', name: unique_name }; - } else { - value = l.value || l.name; - } - properties.push({ - type: 'Property', - kind: 'init', - key: l.name, - value - }); - }); + if (lets.length === 0) return { block, scope }; + + const context_input = { + type: 'ObjectPattern', + properties: lets.map((l) => ({ + type: 'Property', + kind: 'init', + key: l.name, + value: l.value || l.name, + })), + }; - const changes_input = { - type: 'ObjectPattern', - properties - }; + const properties = []; + const value_map = new Map(); + + lets.forEach((l) => { + let value; + if (l.names.length > 1) { + // more than one, probably destructuring + const unique_name = block.get_unique_name(l.names.join('_')).name; + value_map.set(l.value, unique_name); + value = { type: 'Identifier', name: unique_name }; + } else { + value = l.value || l.name; + } + properties.push({ + type: 'Property', + kind: 'init', + key: l.name, + value, + }); + }); - const names = new Set(); - const names_lookup = new Map(); + const changes_input = { + type: 'ObjectPattern', + properties, + }; - lets.forEach(l => { - l.names.forEach(name => { - names.add(name); - if (value_map.has(l.value)) { - names_lookup.set(name, value_map.get(l.value)); - } - }); - }); + const names = new Set(); + const names_lookup = new Map(); - const context = { - type: 'ObjectExpression', - properties: Array.from(names).map(name => p`${block.renderer.context_lookup.get(name).index}: ${name}`) - }; + lets.forEach((l) => { + l.names.forEach((name) => { + names.add(name); + if (value_map.has(l.value)) { + names_lookup.set(name, value_map.get(l.value)); + } + }); + }); - const { context_lookup } = block.renderer; + const context = { + type: 'ObjectExpression', + properties: Array.from(names).map((name) => p`${block.renderer.context_lookup.get(name).index}: ${name}`), + }; - // i am well aware that this code is gross - // TODO: context-overflow make it less gross - const changes = { - type: 'ParenthesizedExpression', - get expression() { - if (block.renderer.context_overflow) { - const grouped = []; + const { context_lookup } = block.renderer; - Array.from(names).forEach(name => { - const i = context_lookup.get(name).index.value ; - const g = Math.floor(i / 31); + // i am well aware that this code is gross + // TODO: context-overflow make it less gross + const changes = { + type: 'ParenthesizedExpression', + get expression() { + if (block.renderer.context_overflow) { + const grouped = []; - const lookup_name = names_lookup.has(name) ? names_lookup.get(name) : name; + Array.from(names).forEach((name) => { + const i = context_lookup.get(name).index.value; + const g = Math.floor(i / 31); - if (!grouped[g]) grouped[g] = []; - grouped[g].push({ name: lookup_name, n: i % 31 }); - }); + const lookup_name = names_lookup.has(name) ? names_lookup.get(name) : name; - const elements = []; + if (!grouped[g]) grouped[g] = []; + grouped[g].push({ name: lookup_name, n: i % 31 }); + }); - for (let g = 0; g < grouped.length; g += 1) { - elements[g] = grouped[g] - ? grouped[g] - .map(({ name, n }) => x`${name} ? ${1 << n} : 0`) - .reduce((lhs, rhs) => x`${lhs} | ${rhs}`) - : x`0`; - } + const elements = []; - return { - type: 'ArrayExpression', - elements - }; - } + for (let g = 0; g < grouped.length; g += 1) { + elements[g] = grouped[g] ? grouped[g].map(({ name, n }) => x`${name} ? ${1 << n} : 0`).reduce((lhs, rhs) => x`${lhs} | ${rhs}`) : x`0`; + } - return Array.from(names) - .map(name => { - const lookup_name = names_lookup.has(name) ? names_lookup.get(name) : name; - const i = context_lookup.get(name).index.value ; - return x`${lookup_name} ? ${1 << i} : 0`; - }) - .reduce((lhs, rhs) => x`${lhs} | ${rhs}`) ; - } - }; + return { + type: 'ArrayExpression', + elements, + }; + } - return { - block, - scope, - get_context: x`${context_input} => ${context}`, - get_changes: x`${changes_input} => ${changes}` - }; + return Array.from(names) + .map((name) => { + const lookup_name = names_lookup.has(name) ? names_lookup.get(name) : name; + const i = context_lookup.get(name).index.value; + return x`${lookup_name} ? ${1 << i} : 0`; + }) + .reduce((lhs, rhs) => x`${lhs} | ${rhs}`); + }, + }; + + return { + block, + scope, + get_context: x`${context_input} => ${context}`, + get_changes: x`${changes_input} => ${changes}`, + }; } class SlotTemplateWrapper extends Wrapper { - - - - - - constructor( - renderer, - block, - parent, - node, - strip_whitespace, - next_sibling - ) { - super(renderer, block, parent, node); - - const { scope, lets, slot_template_name } = this.node; - - lets.forEach(l => { - extract_names(l.value || l.name).forEach(name => { - renderer.add_to_context(name, true); - }); - }); + constructor(renderer, block, parent, node, strip_whitespace, next_sibling) { + super(renderer, block, parent, node); - this.block = block.child({ - comment: create_debugging_comment(this.node, this.renderer.component), - name: this.renderer.component.get_unique_name( - `create_${sanitize(slot_template_name)}_slot` - ), - type: 'slot' - }); - this.renderer.blocks.push(this.block); + const { scope, lets, slot_template_name } = this.node; - const seen = new Set(lets.map(l => l.name.name)); - this.parent.node.lets.forEach(l => { - if (!seen.has(l.name.name)) lets.push(l); - }); + lets.forEach((l) => { + extract_names(l.value || l.name).forEach((name) => { + renderer.add_to_context(name, true); + }); + }); - this.parent.set_slot( - slot_template_name, - get_slot_definition(this.block, scope, lets) - ); + this.block = block.child({ + comment: create_debugging_comment(this.node, this.renderer.component), + name: this.renderer.component.get_unique_name(`create_${sanitize(slot_template_name)}_slot`), + type: 'slot', + }); + this.renderer.blocks.push(this.block); - this.fragment = new FragmentWrapper( - renderer, - this.block, - node.type === 'SlotTemplate' ? node.children : [node], - this, - strip_whitespace, - next_sibling - ); + const seen = new Set(lets.map((l) => l.name.name)); + this.parent.node.lets.forEach((l) => { + if (!seen.has(l.name.name)) lets.push(l); + }); + + this.parent.set_slot(slot_template_name, get_slot_definition(this.block, scope, lets)); - this.block.parent.add_dependencies(this.block.dependencies); - } + this.fragment = new FragmentWrapper(renderer, this.block, node.type === 'SlotTemplate' ? node.children : [node], this, strip_whitespace, next_sibling); + + this.block.parent.add_dependencies(this.block.dependencies); + } - render() { - this.fragment.render(this.block, null, x`#nodes` ); - } + render() { + this.fragment.render(this.block, null, x`#nodes`); + } } function string_to_member_expression(name) { - const parts = name.split('.'); - let node = { - type: 'Identifier', - name: parts[0] - }; - for (let i = 1; i < parts.length; i++) { - node = { - type: 'MemberExpression', - object: node, - property: { type: 'Identifier', name: parts[i] } - } ; - } - return node; + const parts = name.split('.'); + let node = { + type: 'Identifier', + name: parts[0], + }; + for (let i = 1; i < parts.length; i++) { + node = { + type: 'MemberExpression', + object: node, + property: { type: 'Identifier', name: parts[i] }, + }; + } + return node; } class InlineComponentWrapper extends Wrapper { - - __init() {this.slots = new Map();} - - - __init2() {this.children = [];} - - constructor( - renderer, - block, - parent, - node, - strip_whitespace, - next_sibling - ) { - super(renderer, block, parent, node);InlineComponentWrapper.prototype.__init.call(this);InlineComponentWrapper.prototype.__init2.call(this); - this.cannot_use_innerhtml(); - this.not_static_content(); - - if (this.node.expression) { - block.add_dependencies(this.node.expression.dependencies); - } + __init() { + this.slots = new Map(); + } - this.node.attributes.forEach(attr => { - block.add_dependencies(attr.dependencies); - }); + __init2() { + this.children = []; + } - this.node.bindings.forEach(binding => { - if (binding.is_contextual) { - mark_each_block_bindings(this, binding); - } + constructor(renderer, block, parent, node, strip_whitespace, next_sibling) { + super(renderer, block, parent, node); + InlineComponentWrapper.prototype.__init.call(this); + InlineComponentWrapper.prototype.__init2.call(this); + this.cannot_use_innerhtml(); + this.not_static_content(); - block.add_dependencies(binding.expression.dependencies); - }); + if (this.node.expression) { + block.add_dependencies(this.node.expression.dependencies); + } - this.node.handlers.forEach(handler => { - if (handler.expression) { - block.add_dependencies(handler.expression.dependencies); - } - }); + this.node.attributes.forEach((attr) => { + block.add_dependencies(attr.dependencies); + }); - this.var = { - type: 'Identifier', - name: ( - this.node.name === 'svelte:self' ? renderer.component.name.name : - this.node.name === 'svelte:component' ? 'switch_instance' : - sanitize(this.node.name) - ).toLowerCase() - }; - - if (this.node.children.length) { - this.node.lets.forEach(l => { - extract_names(l.value || l.name).forEach(name => { - renderer.add_to_context(name, true); - }); - }); + this.node.bindings.forEach((binding) => { + if (binding.is_contextual) { + mark_each_block_bindings(this, binding); + } - this.children = this.node.children.map(child => new SlotTemplateWrapper(renderer, block, this, child , strip_whitespace, next_sibling)); - } + block.add_dependencies(binding.expression.dependencies); + }); - block.add_outro(); - } + this.node.handlers.forEach((handler) => { + if (handler.expression) { + block.add_dependencies(handler.expression.dependencies); + } + }); - set_slot(name, slot_definition) { - if (this.slots.has(name)) { - if (name === 'default') { - throw new Error('Found elements without slot attribute when using slot="default"'); - } - throw new Error(`Duplicate slot name "${name}" in <${this.node.name}>`); - } - this.slots.set(name, slot_definition); - } - - warn_if_reactive() { - const { name } = this.node; - const variable = this.renderer.component.var_lookup.get(name); - if (!variable) { - return; - } + this.var = { + type: 'Identifier', + name: (this.node.name === 'svelte:self' ? renderer.component.name.name : this.node.name === 'svelte:component' ? 'switch_instance' : sanitize(this.node.name)).toLowerCase(), + }; - if (variable.reassigned || variable.export_name || variable.is_reactive_dependency) { - this.renderer.component.warn(this.node, { - code: 'reactive-component', - message: `<${name}/> will not be reactive if ${name} changes. Use <svelte:component this={${name}}/> if you want this reactivity.` - }); - } - } + if (this.node.children.length) { + this.node.lets.forEach((l) => { + extract_names(l.value || l.name).forEach((name) => { + renderer.add_to_context(name, true); + }); + }); - render( - block, - parent_node, - parent_nodes - ) { - this.warn_if_reactive(); + this.children = this.node.children.map((child) => new SlotTemplateWrapper(renderer, block, this, child, strip_whitespace, next_sibling)); + } - const { renderer } = this; - const { component } = renderer; + block.add_outro(); + } - const name = this.var; - block.add_variable(name); + set_slot(name, slot_definition) { + if (this.slots.has(name)) { + if (name === 'default') { + throw new Error('Found elements without slot attribute when using slot="default"'); + } + throw new Error(`Duplicate slot name "${name}" in <${this.node.name}>`); + } + this.slots.set(name, slot_definition); + } - const component_opts = x`{}` ; + warn_if_reactive() { + const { name } = this.node; + const variable = this.renderer.component.var_lookup.get(name); + if (!variable) { + return; + } - const statements = []; - const updates = []; + if (variable.reassigned || variable.export_name || variable.is_reactive_dependency) { + this.renderer.component.warn(this.node, { + code: 'reactive-component', + message: `<${name}/> will not be reactive if ${name} changes. Use <svelte:component this={${name}}/> if you want this reactivity.`, + }); + } + } - this.children.forEach((child) => { - this.renderer.add_to_context('$$scope', true); - child.render(block, null, x`#nodes` ); - }); + render(block, parent_node, parent_nodes) { + this.warn_if_reactive(); - let props; - const name_changes = block.get_unique_name(`${name.name}_changes`); + const { renderer } = this; + const { component } = renderer; - const uses_spread = !!this.node.attributes.find(a => a.is_spread); + const name = this.var; + block.add_variable(name); - // removing empty slot - for (const slot of this.slots.keys()) { - if (!this.slots.get(slot).block.has_content()) { - this.renderer.remove_block(this.slots.get(slot).block); - this.slots.delete(slot); - } - } + const component_opts = x`{}`; - const initial_props = this.slots.size > 0 - ? [ - p`$$slots: { + const statements = []; + const updates = []; + + this.children.forEach((child) => { + this.renderer.add_to_context('$$scope', true); + child.render(block, null, x`#nodes`); + }); + + let props; + const name_changes = block.get_unique_name(`${name.name}_changes`); + + const uses_spread = !!this.node.attributes.find((a) => a.is_spread); + + // removing empty slot + for (const slot of this.slots.keys()) { + if (!this.slots.get(slot).block.has_content()) { + this.renderer.remove_block(this.slots.get(slot).block); + this.slots.delete(slot); + } + } + + const initial_props = + this.slots.size > 0 + ? [ + p`$$slots: { ${Array.from(this.slots).map(([name, slot]) => { - return p`${name}: [${slot.block.name}, ${slot.get_context || null}, ${slot.get_changes || null}]`; - })} + return p`${name}: [${slot.block.name}, ${slot.get_context || null}, ${slot.get_changes || null}]`; + })} }`, - p`$$scope: { + p`$$scope: { ctx: #ctx - }` - ] - : []; + }`, + ] + : []; - const attribute_object = uses_spread - ? x`{ ${initial_props} }` - : x`{ - ${this.node.attributes.map(attr => p`${attr.name}: ${attr.get_value(block)}`)}, + const attribute_object = uses_spread + ? x`{ ${initial_props} }` + : x`{ + ${this.node.attributes.map((attr) => p`${attr.name}: ${attr.get_value(block)}`)}, ${initial_props} }`; - if (this.node.attributes.length || this.node.bindings.length || initial_props.length) { - if (!uses_spread && this.node.bindings.length === 0) { - component_opts.properties.push(p`props: ${attribute_object}`); - } else { - props = block.get_unique_name(`${name.name}_props`); - component_opts.properties.push(p`props: ${props}`); - } - } + if (this.node.attributes.length || this.node.bindings.length || initial_props.length) { + if (!uses_spread && this.node.bindings.length === 0) { + component_opts.properties.push(p`props: ${attribute_object}`); + } else { + props = block.get_unique_name(`${name.name}_props`); + component_opts.properties.push(p`props: ${props}`); + } + } - if (component.compile_options.dev) { - // TODO this is a terrible hack, but without it the component - // will complain that options.target is missing. This would - // work better if components had separate public and private - // APIs - component_opts.properties.push(p`$$inline: true`); - } + if (component.compile_options.dev) { + // TODO this is a terrible hack, but without it the component + // will complain that options.target is missing. This would + // work better if components had separate public and private + // APIs + component_opts.properties.push(p`$$inline: true`); + } - const fragment_dependencies = new Set(this.slots.size ? ['$$scope'] : []); - this.slots.forEach(slot => { - slot.block.dependencies.forEach(name => { - const is_let = slot.scope.is_let(name); - const variable = renderer.component.var_lookup.get(name); + const fragment_dependencies = new Set(this.slots.size ? ['$$scope'] : []); + this.slots.forEach((slot) => { + slot.block.dependencies.forEach((name) => { + const is_let = slot.scope.is_let(name); + const variable = renderer.component.var_lookup.get(name); - if (is_let || is_dynamic$1(variable)) fragment_dependencies.add(name); - }); - }); + if (is_let || is_dynamic$1(variable)) fragment_dependencies.add(name); + }); + }); - const dynamic_attributes = this.node.attributes.filter(a => a.get_dependencies().length > 0); + const dynamic_attributes = this.node.attributes.filter((a) => a.get_dependencies().length > 0); - if (!uses_spread && (dynamic_attributes.length > 0 || this.node.bindings.length > 0 || fragment_dependencies.size > 0)) { - updates.push(b`const ${name_changes} = {};`); - } + if (!uses_spread && (dynamic_attributes.length > 0 || this.node.bindings.length > 0 || fragment_dependencies.size > 0)) { + updates.push(b`const ${name_changes} = {};`); + } - if (this.node.attributes.length) { - if (uses_spread) { - const levels = block.get_unique_name(`${this.var.name}_spread_levels`); + if (this.node.attributes.length) { + if (uses_spread) { + const levels = block.get_unique_name(`${this.var.name}_spread_levels`); - const initial_props = []; - const changes = []; + const initial_props = []; + const changes = []; - const all_dependencies = new Set(); + const all_dependencies = new Set(); - this.node.attributes.forEach(attr => { - add_to_set(all_dependencies, attr.dependencies); - }); + this.node.attributes.forEach((attr) => { + add_to_set(all_dependencies, attr.dependencies); + }); - this.node.attributes.forEach((attr, i) => { - const { name, dependencies } = attr; + this.node.attributes.forEach((attr, i) => { + const { name, dependencies } = attr; - const condition = dependencies.size > 0 && (dependencies.size !== all_dependencies.size) - ? renderer.dirty(Array.from(dependencies)) - : null; - const unchanged = dependencies.size === 0; + const condition = dependencies.size > 0 && dependencies.size !== all_dependencies.size ? renderer.dirty(Array.from(dependencies)) : null; + const unchanged = dependencies.size === 0; - let change_object; - if (attr.is_spread) { - const value = attr.expression.manipulate(block); - initial_props.push(value); + let change_object; + if (attr.is_spread) { + const value = attr.expression.manipulate(block); + initial_props.push(value); - let value_object = value; - if (attr.expression.node.type !== 'ObjectExpression') { - value_object = x`@get_spread_object(${value})`; - } - change_object = value_object; - } else { - const obj = x`{ ${name}: ${attr.get_value(block)} }`; - initial_props.push(obj); - change_object = obj; - } + let value_object = value; + if (attr.expression.node.type !== 'ObjectExpression') { + value_object = x`@get_spread_object(${value})`; + } + change_object = value_object; + } else { + const obj = x`{ ${name}: ${attr.get_value(block)} }`; + initial_props.push(obj); + change_object = obj; + } - changes.push( - unchanged - ? x`${levels}[${i}]` - : condition - ? x`${condition} && ${change_object}` - : change_object - ); - }); + changes.push(unchanged ? x`${levels}[${i}]` : condition ? x`${condition} && ${change_object}` : change_object); + }); - block.chunks.init.push(b` + block.chunks.init.push(b` const ${levels} = [ ${initial_props} ]; `); - statements.push(b` + statements.push(b` for (let #i = 0; #i < ${levels}.length; #i += 1) { ${props} = @assign(${props}, ${levels}[#i]); } `); - if (all_dependencies.size) { - const condition = renderer.dirty(Array.from(all_dependencies)); + if (all_dependencies.size) { + const condition = renderer.dirty(Array.from(all_dependencies)); - updates.push(b` + updates.push(b` const ${name_changes} = ${condition} ? @get_spread_update(${levels}, [ ${changes} ]) : {} `); - } else { - updates.push(b` + } else { + updates.push(b` const ${name_changes} = {}; `); - } - } else { - dynamic_attributes.forEach((attribute) => { - const dependencies = attribute.get_dependencies(); - if (dependencies.length > 0) { - const condition = renderer.dirty(dependencies); + } + } else { + dynamic_attributes.forEach((attribute) => { + const dependencies = attribute.get_dependencies(); + if (dependencies.length > 0) { + const condition = renderer.dirty(dependencies); - updates.push(b` + updates.push(b` if (${condition}) ${name_changes}.${attribute.name} = ${attribute.get_value(block)}; `); - } - }); - } - } + } + }); + } + } - if (fragment_dependencies.size > 0) { - updates.push(b` + if (fragment_dependencies.size > 0) { + updates.push(b` if (${renderer.dirty(Array.from(fragment_dependencies))}) { ${name_changes}.$$scope = { dirty: #dirty, ctx: #ctx }; }`); - } + } - const munged_bindings = this.node.bindings.map(binding => { - component.has_reactive_assignments = true; + const munged_bindings = this.node.bindings.map((binding) => { + component.has_reactive_assignments = true; - if (binding.name === 'this') { - return bind_this(component, block, new BindingWrapper(block, binding, this), this.var); - } + if (binding.name === 'this') { + return bind_this(component, block, new BindingWrapper(block, binding, this), this.var); + } - const id = component.get_unique_name(`${this.var.name}_${binding.name}_binding`); - renderer.add_to_context(id.name); - const callee = renderer.reference(id); + const id = component.get_unique_name(`${this.var.name}_${binding.name}_binding`); + renderer.add_to_context(id.name); + const callee = renderer.reference(id); - const updating = block.get_unique_name(`updating_${binding.name}`); - block.add_variable(updating); + const updating = block.get_unique_name(`updating_${binding.name}`); + block.add_variable(updating); - const snippet = binding.expression.manipulate(block); + const snippet = binding.expression.manipulate(block); - statements.push(b` + statements.push(b` if (${snippet} !== void 0) { ${props}.${binding.name} = ${snippet}; - }` - ); + }`); - updates.push(b` + updates.push(b` if (!${updating} && ${renderer.dirty(Array.from(binding.expression.dependencies))}) { ${updating} = true; ${name_changes}.${binding.name} = ${snippet}; @@ -13290,87 +12252,88 @@ class InlineComponentWrapper extends Wrapper { } `); - const contextual_dependencies = Array.from(binding.expression.contextual_dependencies); - const dependencies = Array.from(binding.expression.dependencies); + const contextual_dependencies = Array.from(binding.expression.contextual_dependencies); + const dependencies = Array.from(binding.expression.dependencies); - let lhs = binding.raw_expression; + let lhs = binding.raw_expression; - if (binding.is_contextual && binding.expression.node.type === 'Identifier') { - // bind:x={y} — we can't just do `y = x`, we need to - // to `array[index] = x; - const { name } = binding.expression.node; - const { object, property, snippet } = block.bindings.get(name); - lhs = snippet; - contextual_dependencies.push(object.name, property.name); - } - - const params = [x`#value`]; - const args = [x`#value`]; - if (contextual_dependencies.length > 0) { - - contextual_dependencies.forEach(name => { - params.push({ - type: 'Identifier', - name - }); + if (binding.is_contextual && binding.expression.node.type === 'Identifier') { + // bind:x={y} — we can't just do `y = x`, we need to + // to `array[index] = x; + const { name } = binding.expression.node; + const { object, property, snippet } = block.bindings.get(name); + lhs = snippet; + contextual_dependencies.push(object.name, property.name); + } - renderer.add_to_context(name, true); - args.push(renderer.reference(name)); - }); + const params = [x`#value`]; + const args = [x`#value`]; + if (contextual_dependencies.length > 0) { + contextual_dependencies.forEach((name) => { + params.push({ + type: 'Identifier', + name, + }); + renderer.add_to_context(name, true); + args.push(renderer.reference(name)); + }); - block.maintain_context = true; // TODO put this somewhere more logical - } + block.maintain_context = true; // TODO put this somewhere more logical + } - block.chunks.init.push(b` + block.chunks.init.push(b` function ${id}(#value) { ${callee}(${args}); } `); - let invalidate_binding = b` + let invalidate_binding = b` ${lhs} = #value; ${renderer.invalidate(dependencies[0])}; `; - if (binding.expression.node.type === 'MemberExpression') { - invalidate_binding = b` + if (binding.expression.node.type === 'MemberExpression') { + invalidate_binding = b` if ($$self.$$.not_equal(${lhs}, #value)) { ${invalidate_binding} } `; - } + } - const body = b` + const body = b` function ${id}(${params}) { ${invalidate_binding} } `; - component.partly_hoisted.push(body); + component.partly_hoisted.push(body); - return b`@binding_callbacks.push(() => @bind(${this.var}, '${binding.name}', ${id}));`; - }); + return b`@binding_callbacks.push(() => @bind(${this.var}, '${binding.name}', ${id}));`; + }); - const munged_handlers = this.node.handlers.map(handler => { - const event_handler = new EventHandlerWrapper(handler, this); - let snippet = event_handler.get_snippet(block); - if (handler.modifiers.has('once')) snippet = x`@once(${snippet})`; + const munged_handlers = this.node.handlers.map((handler) => { + const event_handler = new EventHandlerWrapper(handler, this); + let snippet = event_handler.get_snippet(block); + if (handler.modifiers.has('once')) snippet = x`@once(${snippet})`; - return b`${name}.$on("${handler.name}", ${snippet});`; - }); + return b`${name}.$on("${handler.name}", ${snippet});`; + }); - if (this.node.name === 'svelte:component') { - const switch_value = block.get_unique_name('switch_value'); - const switch_props = block.get_unique_name('switch_props'); + if (this.node.name === 'svelte:component') { + const switch_value = block.get_unique_name('switch_value'); + const switch_props = block.get_unique_name('switch_props'); - const snippet = this.node.expression.manipulate(block); + const snippet = this.node.expression.manipulate(block); - block.chunks.init.push(b` + block.chunks.init.push(b` var ${switch_value} = ${snippet}; function ${switch_props}(#ctx) { - ${(this.node.attributes.length > 0 || this.node.bindings.length > 0) && b` - ${props && b`let ${props} = ${attribute_object};`}`} + ${ + (this.node.attributes.length > 0 || this.node.bindings.length > 0) && + b` + ${props && b`let ${props} = ${attribute_object};`}` + } ${statements} return ${component_opts}; } @@ -13383,32 +12346,28 @@ class InlineComponentWrapper extends Wrapper { } `); - block.chunks.create.push( - b`if (${name}) @create_component(${name}.$$.fragment);` - ); + block.chunks.create.push(b`if (${name}) @create_component(${name}.$$.fragment);`); - if (parent_nodes && this.renderer.options.hydratable) { - block.chunks.claim.push( - b`if (${name}) @claim_component(${name}.$$.fragment, ${parent_nodes});` - ); - } + if (parent_nodes && this.renderer.options.hydratable) { + block.chunks.claim.push(b`if (${name}) @claim_component(${name}.$$.fragment, ${parent_nodes});`); + } - block.chunks.mount.push(b` + block.chunks.mount.push(b` if (${name}) { @mount_component(${name}, ${parent_node || '#target'}, ${parent_node ? 'null' : '#anchor'}); } `); - const anchor = this.get_or_create_anchor(block, parent_node, parent_nodes); - const update_mount_node = this.get_update_mount_node(anchor); + const anchor = this.get_or_create_anchor(block, parent_node, parent_nodes); + const update_mount_node = this.get_update_mount_node(anchor); - if (updates.length) { - block.chunks.update.push(b` + if (updates.length) { + block.chunks.update.push(b` ${updates} `); - } + } - block.chunks.update.push(b` + block.chunks.update.push(b` if (${switch_value} !== (${switch_value} = ${snippet})) { if (${name}) { @group_outros(); @@ -13436,23 +12395,22 @@ class InlineComponentWrapper extends Wrapper { } `); - block.chunks.intro.push(b` + block.chunks.intro.push(b` if (${name}) @transition_in(${name}.$$.fragment, #local); `); - block.chunks.outro.push( - b`if (${name}) @transition_out(${name}.$$.fragment, #local);` - ); + block.chunks.outro.push(b`if (${name}) @transition_out(${name}.$$.fragment, #local);`); - block.chunks.destroy.push(b`if (${name}) @destroy_component(${name}, ${parent_node ? null : 'detaching'});`); - } else { - const expression = this.node.name === 'svelte:self' - ? component.name - : this.renderer.reference(string_to_member_expression(this.node.name)); + block.chunks.destroy.push(b`if (${name}) @destroy_component(${name}, ${parent_node ? null : 'detaching'});`); + } else { + const expression = this.node.name === 'svelte:self' ? component.name : this.renderer.reference(string_to_member_expression(this.node.name)); - block.chunks.init.push(b` - ${(this.node.attributes.length > 0 || this.node.bindings.length > 0) && b` - ${props && b`let ${props} = ${attribute_object};`}`} + block.chunks.init.push(b` + ${ + (this.node.attributes.length > 0 || this.node.bindings.length > 0) && + b` + ${props && b`let ${props} = ${attribute_object};`}` + } ${statements} ${name} = new ${expression}(${component_opts}); @@ -13460,457 +12418,413 @@ class InlineComponentWrapper extends Wrapper { ${munged_handlers} `); - block.chunks.create.push(b`@create_component(${name}.$$.fragment);`); + block.chunks.create.push(b`@create_component(${name}.$$.fragment);`); - if (parent_nodes && this.renderer.options.hydratable) { - block.chunks.claim.push( - b`@claim_component(${name}.$$.fragment, ${parent_nodes});` - ); - } + if (parent_nodes && this.renderer.options.hydratable) { + block.chunks.claim.push(b`@claim_component(${name}.$$.fragment, ${parent_nodes});`); + } - block.chunks.mount.push( - b`@mount_component(${name}, ${parent_node || '#target'}, ${parent_node ? 'null' : '#anchor'});` - ); + block.chunks.mount.push(b`@mount_component(${name}, ${parent_node || '#target'}, ${parent_node ? 'null' : '#anchor'});`); - block.chunks.intro.push(b` + block.chunks.intro.push(b` @transition_in(${name}.$$.fragment, #local); `); - if (updates.length) { - block.chunks.update.push(b` + if (updates.length) { + block.chunks.update.push(b` ${updates} ${name}.$set(${name_changes}); `); - } + } - block.chunks.destroy.push(b` + block.chunks.destroy.push(b` @destroy_component(${name}, ${parent_node ? null : 'detaching'}); `); - block.chunks.outro.push( - b`@transition_out(${name}.$$.fragment, #local);` - ); - } - } + block.chunks.outro.push(b`@transition_out(${name}.$$.fragment, #local);`); + } + } } function get_slot_data(values, block = null) { - return { - type: 'ObjectExpression', - properties: Array.from(values.values()) - .filter(attribute => attribute.name !== 'name') - .map(attribute => { - if (attribute.is_spread) { - const argument = get_spread_value(block, attribute); - return { - type: 'SpreadElement', - argument - }; - } + return { + type: 'ObjectExpression', + properties: Array.from(values.values()) + .filter((attribute) => attribute.name !== 'name') + .map((attribute) => { + if (attribute.is_spread) { + const argument = get_spread_value(block, attribute); + return { + type: 'SpreadElement', + argument, + }; + } - const value = get_value(block, attribute); - return p`${attribute.name}: ${value}`; - }) - }; + const value = get_value(block, attribute); + return p`${attribute.name}: ${value}`; + }), + }; } function get_value(block, attribute) { - if (attribute.is_true) return x`true`; - if (attribute.chunks.length === 0) return x`""`; + if (attribute.is_true) return x`true`; + if (attribute.chunks.length === 0) return x`""`; - let value = attribute.chunks - .map(chunk => chunk.type === 'Text' ? string_literal(chunk.data) : (block ? chunk.manipulate(block) : chunk.node)) - .reduce((lhs, rhs) => x`${lhs} + ${rhs}`); + let value = attribute.chunks + .map((chunk) => (chunk.type === 'Text' ? string_literal(chunk.data) : block ? chunk.manipulate(block) : chunk.node)) + .reduce((lhs, rhs) => x`${lhs} + ${rhs}`); - if (attribute.chunks.length > 1 && attribute.chunks[0].type !== 'Text') { - value = x`"" + ${value}`; - } + if (attribute.chunks.length > 1 && attribute.chunks[0].type !== 'Text') { + value = x`"" + ${value}`; + } - return value; + return value; } function get_spread_value(block, attribute) { - return block ? attribute.expression.manipulate(block) : attribute.expression.node; + return block ? attribute.expression.manipulate(block) : attribute.expression.node; } class SlotWrapper extends Wrapper { - - - __init() {this.fallback = null;} - - - __init2() {this.var = { type: 'Identifier', name: 'slot' };} - __init3() {this.dependencies = new Set(['$$scope']);} - - constructor( - renderer, - block, - parent, - node, - strip_whitespace, - next_sibling - ) { - super(renderer, block, parent, node);SlotWrapper.prototype.__init.call(this);SlotWrapper.prototype.__init2.call(this);SlotWrapper.prototype.__init3.call(this); this.cannot_use_innerhtml(); - this.not_static_content(); - - if (this.node.children.length) { - this.fallback = block.child({ - comment: create_debugging_comment(this.node.children[0], this.renderer.component), - name: this.renderer.component.get_unique_name('fallback_block'), - type: 'fallback' - }); - renderer.blocks.push(this.fallback); - } + __init() { + this.fallback = null; + } - this.fragment = new FragmentWrapper( - renderer, - this.fallback, - node.children, - this, - strip_whitespace, - next_sibling - ); - - this.node.values.forEach(attribute => { - add_to_set(this.dependencies, attribute.dependencies); - }); + __init2() { + this.var = { type: 'Identifier', name: 'slot' }; + } + __init3() { + this.dependencies = new Set(['$$scope']); + } - block.add_dependencies(this.dependencies); + constructor(renderer, block, parent, node, strip_whitespace, next_sibling) { + super(renderer, block, parent, node); + SlotWrapper.prototype.__init.call(this); + SlotWrapper.prototype.__init2.call(this); + SlotWrapper.prototype.__init3.call(this); + this.cannot_use_innerhtml(); + this.not_static_content(); + + if (this.node.children.length) { + this.fallback = block.child({ + comment: create_debugging_comment(this.node.children[0], this.renderer.component), + name: this.renderer.component.get_unique_name('fallback_block'), + type: 'fallback', + }); + renderer.blocks.push(this.fallback); + } - // we have to do this, just in case - block.add_intro(); - block.add_outro(); - } + this.fragment = new FragmentWrapper(renderer, this.fallback, node.children, this, strip_whitespace, next_sibling); - render( - block, - parent_node, - parent_nodes - ) { - const { renderer } = this; + this.node.values.forEach((attribute) => { + add_to_set(this.dependencies, attribute.dependencies); + }); - const { slot_name } = this.node; + block.add_dependencies(this.dependencies); - if (this.slot_block) { - block = this.slot_block; - } + // we have to do this, just in case + block.add_intro(); + block.add_outro(); + } - let get_slot_changes_fn; - let get_slot_spread_changes_fn; - let get_slot_context_fn; + render(block, parent_node, parent_nodes) { + const { renderer } = this; - if (this.node.values.size > 0) { - get_slot_changes_fn = renderer.component.get_unique_name(`get_${sanitize(slot_name)}_slot_changes`); - get_slot_context_fn = renderer.component.get_unique_name(`get_${sanitize(slot_name)}_slot_context`); + const { slot_name } = this.node; - const changes = x`{}` ; + if (this.slot_block) { + block = this.slot_block; + } - const spread_dynamic_dependencies = new Set(); + let get_slot_changes_fn; + let get_slot_spread_changes_fn; + let get_slot_context_fn; - this.node.values.forEach(attribute => { - if (attribute.type === 'Spread') { - add_to_set(spread_dynamic_dependencies, Array.from(attribute.dependencies).filter((name) => this.is_dependency_dynamic(name))); - } else { - const dynamic_dependencies = Array.from(attribute.dependencies).filter((name) => this.is_dependency_dynamic(name)); - - if (dynamic_dependencies.length > 0) { - changes.properties.push(p`${attribute.name}: ${renderer.dirty(dynamic_dependencies)}`); - } - } - }); + if (this.node.values.size > 0) { + get_slot_changes_fn = renderer.component.get_unique_name(`get_${sanitize(slot_name)}_slot_changes`); + get_slot_context_fn = renderer.component.get_unique_name(`get_${sanitize(slot_name)}_slot_context`); + + const changes = x`{}`; + + const spread_dynamic_dependencies = new Set(); - renderer.blocks.push(b` + this.node.values.forEach((attribute) => { + if (attribute.type === 'Spread') { + add_to_set( + spread_dynamic_dependencies, + Array.from(attribute.dependencies).filter((name) => this.is_dependency_dynamic(name)) + ); + } else { + const dynamic_dependencies = Array.from(attribute.dependencies).filter((name) => this.is_dependency_dynamic(name)); + + if (dynamic_dependencies.length > 0) { + changes.properties.push(p`${attribute.name}: ${renderer.dirty(dynamic_dependencies)}`); + } + } + }); + + renderer.blocks.push(b` const ${get_slot_changes_fn} = #dirty => ${changes}; const ${get_slot_context_fn} = #ctx => ${get_slot_data(this.node.values, block)}; `); - if (spread_dynamic_dependencies.size) { - get_slot_spread_changes_fn = renderer.component.get_unique_name(`get_${sanitize(slot_name)}_slot_spread_changes`); - renderer.blocks.push(b` + if (spread_dynamic_dependencies.size) { + get_slot_spread_changes_fn = renderer.component.get_unique_name(`get_${sanitize(slot_name)}_slot_spread_changes`); + renderer.blocks.push(b` const ${get_slot_spread_changes_fn} = #dirty => ${renderer.dirty(Array.from(spread_dynamic_dependencies))} > 0 ? -1 : 0; `); - } - } else { - get_slot_changes_fn = 'null'; - get_slot_context_fn = 'null'; - } + } + } else { + get_slot_changes_fn = 'null'; + get_slot_context_fn = 'null'; + } - let has_fallback = !!this.fallback; - if (this.fallback) { - this.fragment.render(this.fallback, null, x`#nodes` ); - has_fallback = this.fallback.has_content(); - if (!has_fallback) { - renderer.remove_block(this.fallback); - } - } + let has_fallback = !!this.fallback; + if (this.fallback) { + this.fragment.render(this.fallback, null, x`#nodes`); + has_fallback = this.fallback.has_content(); + if (!has_fallback) { + renderer.remove_block(this.fallback); + } + } - const slot = block.get_unique_name(`${sanitize(slot_name)}_slot`); - const slot_definition = block.get_unique_name(`${sanitize(slot_name)}_slot_template`); - const slot_or_fallback = has_fallback ? block.get_unique_name(`${sanitize(slot_name)}_slot_or_fallback`) : slot; + const slot = block.get_unique_name(`${sanitize(slot_name)}_slot`); + const slot_definition = block.get_unique_name(`${sanitize(slot_name)}_slot_template`); + const slot_or_fallback = has_fallback ? block.get_unique_name(`${sanitize(slot_name)}_slot_or_fallback`) : slot; - block.chunks.init.push(b` + block.chunks.init.push(b` const ${slot_definition} = ${renderer.reference('#slots')}.${slot_name}; const ${slot} = @create_slot(${slot_definition}, #ctx, ${renderer.reference('$$scope')}, ${get_slot_context_fn}); ${has_fallback ? b`const ${slot_or_fallback} = ${slot} || ${this.fallback.name}(#ctx);` : null} `); - block.chunks.create.push( - b`if (${slot_or_fallback}) ${slot_or_fallback}.c();` - ); + block.chunks.create.push(b`if (${slot_or_fallback}) ${slot_or_fallback}.c();`); - if (renderer.options.hydratable) { - block.chunks.claim.push( - b`if (${slot_or_fallback}) ${slot_or_fallback}.l(${parent_nodes});` - ); - } + if (renderer.options.hydratable) { + block.chunks.claim.push(b`if (${slot_or_fallback}) ${slot_or_fallback}.l(${parent_nodes});`); + } - block.chunks.mount.push(b` + block.chunks.mount.push(b` if (${slot_or_fallback}) { ${slot_or_fallback}.m(${parent_node || '#target'}, ${parent_node ? 'null' : '#anchor'}); } `); - block.chunks.intro.push( - b`@transition_in(${slot_or_fallback}, #local);` - ); + block.chunks.intro.push(b`@transition_in(${slot_or_fallback}, #local);`); - block.chunks.outro.push( - b`@transition_out(${slot_or_fallback}, #local);` - ); + block.chunks.outro.push(b`@transition_out(${slot_or_fallback}, #local);`); - const dynamic_dependencies = Array.from(this.dependencies).filter((name) => this.is_dependency_dynamic(name)); + const dynamic_dependencies = Array.from(this.dependencies).filter((name) => this.is_dependency_dynamic(name)); - const fallback_dynamic_dependencies = has_fallback - ? Array.from(this.fallback.dependencies).filter((name) => this.is_dependency_dynamic(name)) - : []; + const fallback_dynamic_dependencies = has_fallback ? Array.from(this.fallback.dependencies).filter((name) => this.is_dependency_dynamic(name)) : []; - const slot_update = get_slot_spread_changes_fn ? b` + const slot_update = get_slot_spread_changes_fn + ? b` if (${slot}.p && ${renderer.dirty(dynamic_dependencies)}) { @update_slot_spread(${slot}, ${slot_definition}, #ctx, ${renderer.reference('$$scope')}, #dirty, ${get_slot_changes_fn}, ${get_slot_spread_changes_fn}, ${get_slot_context_fn}); } - ` : b` + ` + : b` if (${slot}.p && ${renderer.dirty(dynamic_dependencies)}) { @update_slot(${slot}, ${slot_definition}, #ctx, ${renderer.reference('$$scope')}, #dirty, ${get_slot_changes_fn}, ${get_slot_context_fn}); } `; - const fallback_update = has_fallback && fallback_dynamic_dependencies.length > 0 && b` + const fallback_update = + has_fallback && + fallback_dynamic_dependencies.length > 0 && + b` if (${slot_or_fallback} && ${slot_or_fallback}.p && ${renderer.dirty(fallback_dynamic_dependencies)}) { ${slot_or_fallback}.p(#ctx, #dirty); } `; - if (fallback_update) { - block.chunks.update.push(b` + if (fallback_update) { + block.chunks.update.push(b` if (${slot}) { ${slot_update} } else { ${fallback_update} } `); - } else { - block.chunks.update.push(b` + } else { + block.chunks.update.push(b` if (${slot}) { ${slot_update} } `); - } + } - block.chunks.destroy.push( - b`if (${slot_or_fallback}) ${slot_or_fallback}.d(detaching);` - ); - } + block.chunks.destroy.push(b`if (${slot_or_fallback}) ${slot_or_fallback}.d(detaching);`); + } - is_dependency_dynamic(name) { - if (name === '$$scope') return true; - if (this.node.scope.is_let(name)) return true; - if (is_reserved_keyword(name)) return true; - const variable = this.renderer.component.var_lookup.get(name); - return is_dynamic$1(variable); - } + is_dependency_dynamic(name) { + if (name === '$$scope') return true; + if (this.node.scope.is_let(name)) return true; + if (is_reserved_keyword(name)) return true; + const variable = this.renderer.component.var_lookup.get(name); + return is_dynamic$1(variable); + } } class TitleWrapper extends Wrapper { - - - constructor( - renderer, - block, - parent, - node, - _strip_whitespace, - _next_sibling - ) { - super(renderer, block, parent, node); - } - - render(block, _parent_node, _parent_nodes) { - const is_dynamic = !!this.node.children.find(node => node.type !== 'Text'); - - if (is_dynamic) { - let value; - - const all_dependencies = new Set(); - - // TODO some of this code is repeated in Tag.ts — would be good to - // DRY it out if that's possible without introducing crazy indirection - if (this.node.children.length === 1) { - // single {tag} — may be a non-string - // @ts-ignore todo: check this - const { expression } = this.node.children[0]; - value = expression.manipulate(block); - add_to_set(all_dependencies, expression.dependencies); - } else { - // '{foo} {bar}' — treat as string concatenation - value = this.node.children - .map(chunk => { - if (chunk.type === 'Text') return string_literal(chunk.data); - - (chunk ).expression.dependencies.forEach(d => { - all_dependencies.add(d); - }); + constructor(renderer, block, parent, node, _strip_whitespace, _next_sibling) { + super(renderer, block, parent, node); + } - return (chunk ).expression.manipulate(block); - }) - .reduce((lhs, rhs) => x`${lhs} + ${rhs}`); + render(block, _parent_node, _parent_nodes) { + const is_dynamic = !!this.node.children.find((node) => node.type !== 'Text'); - if (this.node.children[0].type !== 'Text') { - value = x`"" + ${value}`; - } - } + if (is_dynamic) { + let value; - const last = this.node.should_cache && block.get_unique_name( - 'title_value' - ); + const all_dependencies = new Set(); - if (this.node.should_cache) block.add_variable(last); + // TODO some of this code is repeated in Tag.ts — would be good to + // DRY it out if that's possible without introducing crazy indirection + if (this.node.children.length === 1) { + // single {tag} — may be a non-string + // @ts-ignore todo: check this + const { expression } = this.node.children[0]; + value = expression.manipulate(block); + add_to_set(all_dependencies, expression.dependencies); + } else { + // '{foo} {bar}' — treat as string concatenation + value = this.node.children + .map((chunk) => { + if (chunk.type === 'Text') return string_literal(chunk.data); - const init = this.node.should_cache ? x`${last} = ${value}` : value; + chunk.expression.dependencies.forEach((d) => { + all_dependencies.add(d); + }); - block.chunks.init.push( - b`@_document.title = ${init};` - ); + return chunk.expression.manipulate(block); + }) + .reduce((lhs, rhs) => x`${lhs} + ${rhs}`); - const updater = b`@_document.title = ${this.node.should_cache ? last : value};`; + if (this.node.children[0].type !== 'Text') { + value = x`"" + ${value}`; + } + } - if (all_dependencies.size) { - const dependencies = Array.from(all_dependencies); + const last = this.node.should_cache && block.get_unique_name('title_value'); - let condition = block.renderer.dirty(dependencies); + if (this.node.should_cache) block.add_variable(last); - if (block.has_outros) { - condition = x`!#current || ${condition}`; - } + const init = this.node.should_cache ? x`${last} = ${value}` : value; - if (this.node.should_cache) { - condition = x`${condition} && (${last} !== (${last} = ${value}))`; - } + block.chunks.init.push(b`@_document.title = ${init};`); + + const updater = b`@_document.title = ${this.node.should_cache ? last : value};`; + + if (all_dependencies.size) { + const dependencies = Array.from(all_dependencies); + + let condition = block.renderer.dirty(dependencies); + + if (block.has_outros) { + condition = x`!#current || ${condition}`; + } + + if (this.node.should_cache) { + condition = x`${condition} && (${last} !== (${last} = ${value}))`; + } - block.chunks.update.push(b` + block.chunks.update.push(b` if (${condition}) { ${updater} }`); - } - } else { - const value = this.node.children.length > 0 - ? string_literal((this.node.children[0] ).data) - : x`""`; + } + } else { + const value = this.node.children.length > 0 ? string_literal(this.node.children[0].data) : x`""`; - block.chunks.hydrate.push(b`@_document.title = ${value};`); - } - } + block.chunks.hydrate.push(b`@_document.title = ${value};`); + } + } } const associated_events = { - innerWidth: 'resize', - innerHeight: 'resize', - outerWidth: 'resize', - outerHeight: 'resize', + innerWidth: 'resize', + innerHeight: 'resize', + outerWidth: 'resize', + outerHeight: 'resize', - scrollX: 'scroll', - scrollY: 'scroll' + scrollX: 'scroll', + scrollY: 'scroll', }; const properties = { - scrollX: 'pageXOffset', - scrollY: 'pageYOffset' + scrollX: 'pageXOffset', + scrollY: 'pageYOffset', }; -const readonly = new Set([ - 'innerWidth', - 'innerHeight', - 'outerWidth', - 'outerHeight', - 'online' -]); +const readonly = new Set(['innerWidth', 'innerHeight', 'outerWidth', 'outerHeight', 'online']); class WindowWrapper extends Wrapper { - - - - constructor(renderer, block, parent, node) { - super(renderer, block, parent, node); - this.handlers = this.node.handlers.map(handler => new EventHandlerWrapper(handler, this)); - } + constructor(renderer, block, parent, node) { + super(renderer, block, parent, node); + this.handlers = this.node.handlers.map((handler) => new EventHandlerWrapper(handler, this)); + } - render(block, _parent_node, _parent_nodes) { - const { renderer } = this; - const { component } = renderer; + render(block, _parent_node, _parent_nodes) { + const { renderer } = this; + const { component } = renderer; - const events = {}; - const bindings = {}; + const events = {}; + const bindings = {}; - add_actions(block, '@_window', this.node.actions); - add_event_handlers(block, '@_window', this.handlers); + add_actions(block, '@_window', this.node.actions); + add_event_handlers(block, '@_window', this.handlers); - this.node.bindings.forEach(binding => { - // TODO: what if it's a MemberExpression? - const binding_name = (binding.expression.node ).name; + this.node.bindings.forEach((binding) => { + // TODO: what if it's a MemberExpression? + const binding_name = binding.expression.node.name; - // in dev mode, throw if read-only values are written to - if (readonly.has(binding.name)) { - renderer.readonly.add(binding_name); - } + // in dev mode, throw if read-only values are written to + if (readonly.has(binding.name)) { + renderer.readonly.add(binding_name); + } - bindings[binding.name] = binding_name; + bindings[binding.name] = binding_name; - // bind:online is a special case, we need to listen for two separate events - if (binding.name === 'online') return; + // bind:online is a special case, we need to listen for two separate events + if (binding.name === 'online') return; - const associated_event = associated_events[binding.name]; - const property = properties[binding.name] || binding.name; + const associated_event = associated_events[binding.name]; + const property = properties[binding.name] || binding.name; - if (!events[associated_event]) events[associated_event] = []; - events[associated_event].push({ - name: binding_name, - value: property - }); - }); + if (!events[associated_event]) events[associated_event] = []; + events[associated_event].push({ + name: binding_name, + value: property, + }); + }); - const scrolling = block.get_unique_name('scrolling'); - const clear_scrolling = block.get_unique_name('clear_scrolling'); - const scrolling_timeout = block.get_unique_name('scrolling_timeout'); + const scrolling = block.get_unique_name('scrolling'); + const clear_scrolling = block.get_unique_name('clear_scrolling'); + const scrolling_timeout = block.get_unique_name('scrolling_timeout'); - Object.keys(events).forEach(event => { - const id = block.get_unique_name(`onwindow${event}`); - const props = events[event]; + Object.keys(events).forEach((event) => { + const id = block.get_unique_name(`onwindow${event}`); + const props = events[event]; - renderer.add_to_context(id.name); - const fn = renderer.reference(id.name); + renderer.add_to_context(id.name); + const fn = renderer.reference(id.name); - if (event === 'scroll') { - // TODO other bidirectional bindings... - block.add_variable(scrolling, x`false`); - block.add_variable(clear_scrolling, x`() => { ${scrolling} = false }`); - block.add_variable(scrolling_timeout); + if (event === 'scroll') { + // TODO other bidirectional bindings... + block.add_variable(scrolling, x`false`); + block.add_variable(clear_scrolling, x`() => { ${scrolling} = false }`); + block.add_variable(scrolling_timeout); - const condition = bindings.scrollX && bindings.scrollY - ? x`"${bindings.scrollX}" in this._state || "${bindings.scrollY}" in this._state` - : x`"${bindings.scrollX || bindings.scrollY}" in this._state`; + const condition = + bindings.scrollX && bindings.scrollY + ? x`"${bindings.scrollX}" in this._state || "${bindings.scrollY}" in this._state` + : x`"${bindings.scrollX || bindings.scrollY}" in this._state`; - const scrollX = bindings.scrollX && x`this._state.${bindings.scrollX}`; - const scrollY = bindings.scrollY && x`this._state.${bindings.scrollY}`; + const scrollX = bindings.scrollX && x`this._state.${bindings.scrollX}`; + const scrollY = bindings.scrollY && x`this._state.${bindings.scrollY}`; - renderer.meta_bindings.push(b` + renderer.meta_bindings.push(b` if (${condition}) { @_scrollTo(${scrollX || '@_window.pageXOffset'}, ${scrollY || '@_window.pageYOffset'}); } @@ -13918,7 +12832,7 @@ class WindowWrapper extends Wrapper { ${scrollY && `${scrollY} = @_window.pageYOffset;`} `); - block.event_listeners.push(x` + block.event_listeners.push(x` @listen(@_window, "${event}", () => { ${scrolling} = true; @_clearTimeout(${scrolling_timeout}); @@ -13926,39 +12840,37 @@ class WindowWrapper extends Wrapper { ${fn}(); }) `); - } else { - props.forEach(prop => { - renderer.meta_bindings.push( - b`this._state.${prop.name} = @_window.${prop.value};` - ); - }); + } else { + props.forEach((prop) => { + renderer.meta_bindings.push(b`this._state.${prop.name} = @_window.${prop.value};`); + }); - block.event_listeners.push(x` + block.event_listeners.push(x` @listen(@_window, "${event}", ${fn}) `); - } + } - component.partly_hoisted.push(b` + component.partly_hoisted.push(b` function ${id}() { - ${props.map(prop => renderer.invalidate(prop.name, x`${prop.name} = @_window.${prop.value}`))} + ${props.map((prop) => renderer.invalidate(prop.name, x`${prop.name} = @_window.${prop.value}`))} } `); - block.chunks.init.push(b` + block.chunks.init.push(b` @add_render_callback(${fn}); `); - component.has_reactive_assignments = true; - }); + component.has_reactive_assignments = true; + }); - // special case... might need to abstract this out if we add more special cases - if (bindings.scrollX || bindings.scrollY) { - const condition = renderer.dirty([bindings.scrollX, bindings.scrollY].filter(Boolean)); + // special case... might need to abstract this out if we add more special cases + if (bindings.scrollX || bindings.scrollY) { + const condition = renderer.dirty([bindings.scrollX, bindings.scrollY].filter(Boolean)); - const scrollX = bindings.scrollX ? renderer.reference(bindings.scrollX) : x`@_window.pageXOffset`; - const scrollY = bindings.scrollY ? renderer.reference(bindings.scrollY) : x`@_window.pageYOffset`; + const scrollX = bindings.scrollX ? renderer.reference(bindings.scrollX) : x`@_window.pageXOffset`; + const scrollY = bindings.scrollY ? renderer.reference(bindings.scrollY) : x`@_window.pageYOffset`; - block.chunks.update.push(b` + block.chunks.update.push(b` if (${condition} && !${scrolling}) { ${scrolling} = true; @_clearTimeout(${scrolling_timeout}); @@ -13966,529 +12878,507 @@ class WindowWrapper extends Wrapper { ${scrolling_timeout} = @_setTimeout(${clear_scrolling}, 100); } `); - } + } - // another special case. (I'm starting to think these are all special cases.) - if (bindings.online) { - const id = block.get_unique_name('onlinestatuschanged'); - const name = bindings.online; + // another special case. (I'm starting to think these are all special cases.) + if (bindings.online) { + const id = block.get_unique_name('onlinestatuschanged'); + const name = bindings.online; - renderer.add_to_context(id.name); - const reference = renderer.reference(id.name); + renderer.add_to_context(id.name); + const reference = renderer.reference(id.name); - component.partly_hoisted.push(b` + component.partly_hoisted.push(b` function ${id}() { ${renderer.invalidate(name, x`${name} = @_navigator.onLine`)} } `); - block.chunks.init.push(b` + block.chunks.init.push(b` @add_render_callback(${reference}); `); - block.event_listeners.push( - x`@listen(@_window, "online", ${reference})`, - x`@listen(@_window, "offline", ${reference})` - ); + block.event_listeners.push(x`@listen(@_window, "online", ${reference})`, x`@listen(@_window, "offline", ${reference})`); - component.has_reactive_assignments = true; - } - } + component.has_reactive_assignments = true; + } + } } function link(next, prev) { - prev.next = next; - if (next) next.prev = prev; + prev.next = next; + if (next) next.prev = prev; } const wrappers = { - AwaitBlock: AwaitBlockWrapper, - Body: BodyWrapper, - Comment: null, - DebugTag: DebugTagWrapper, - EachBlock: EachBlockWrapper, - Element: ElementWrapper, - Head: HeadWrapper, - IfBlock: IfBlockWrapper, - InlineComponent: InlineComponentWrapper, - KeyBlock: KeyBlockWrapper, - MustacheTag: MustacheTagWrapper, - Options: null, - RawMustacheTag: RawMustacheTagWrapper, - Slot: SlotWrapper, - SlotTemplate: SlotTemplateWrapper, - Text: TextWrapper, - Title: TitleWrapper, - Window: WindowWrapper + AwaitBlock: AwaitBlockWrapper, + Body: BodyWrapper, + Comment: null, + DebugTag: DebugTagWrapper, + EachBlock: EachBlockWrapper, + Element: ElementWrapper, + Head: HeadWrapper, + IfBlock: IfBlockWrapper, + InlineComponent: InlineComponentWrapper, + KeyBlock: KeyBlockWrapper, + MustacheTag: MustacheTagWrapper, + Options: null, + RawMustacheTag: RawMustacheTagWrapper, + Slot: SlotWrapper, + SlotTemplate: SlotTemplateWrapper, + Text: TextWrapper, + Title: TitleWrapper, + Window: WindowWrapper, }; function trimmable_at(child, next_sibling) { - // Whitespace is trimmable if one of the following is true: - // The child and its sibling share a common nearest each block (not at an each block boundary) - // The next sibling's previous node is an each block - return (next_sibling.node.find_nearest(/EachBlock/) === child.find_nearest(/EachBlock/)) || next_sibling.node.prev.type === 'EachBlock'; + // Whitespace is trimmable if one of the following is true: + // The child and its sibling share a common nearest each block (not at an each block boundary) + // The next sibling's previous node is an each block + return next_sibling.node.find_nearest(/EachBlock/) === child.find_nearest(/EachBlock/) || next_sibling.node.prev.type === 'EachBlock'; } class FragmentWrapper { - - - constructor( - renderer, - block, - nodes, - parent, - strip_whitespace, - next_sibling - ) { - this.nodes = []; - - let last_child; - let window_wrapper; - - let i = nodes.length; - while (i--) { - const child = nodes[i]; - - if (!child.type) { - throw new Error('missing type'); - } + constructor(renderer, block, nodes, parent, strip_whitespace, next_sibling) { + this.nodes = []; - if (!(child.type in wrappers)) { - throw new Error(`TODO implement ${child.type}`); - } + let last_child; + let window_wrapper; - // special case — this is an easy way to remove whitespace surrounding - // <svelte:window/>. lil hacky but it works - if (child.type === 'Window') { - window_wrapper = new WindowWrapper(renderer, block, parent, child); - continue; - } + let i = nodes.length; + while (i--) { + const child = nodes[i]; - if (child.type === 'Text') { - let { data } = child; + if (!child.type) { + throw new Error('missing type'); + } - // We want to remove trailing whitespace inside an element/component/block, - // *unless* there is no whitespace between this node and its next sibling - if (this.nodes.length === 0) { - const should_trim = ( - next_sibling ? (next_sibling.node.type === 'Text' && /^\s/.test(next_sibling.node.data) && trimmable_at(child, next_sibling)) : !child.has_ancestor('EachBlock') - ); + if (!(child.type in wrappers)) { + throw new Error(`TODO implement ${child.type}`); + } - if (should_trim) { - data = trim_end(data); - if (!data) continue; - } - } + // special case — this is an easy way to remove whitespace surrounding + // <svelte:window/>. lil hacky but it works + if (child.type === 'Window') { + window_wrapper = new WindowWrapper(renderer, block, parent, child); + continue; + } - // glue text nodes (which could e.g. be separated by comments) together - if (last_child && last_child.node.type === 'Text') { - (last_child ).data = data + (last_child ).data; - continue; - } + if (child.type === 'Text') { + let { data } = child; - const wrapper = new TextWrapper(renderer, block, parent, child, data); - if (wrapper.skip) continue; + // We want to remove trailing whitespace inside an element/component/block, + // *unless* there is no whitespace between this node and its next sibling + if (this.nodes.length === 0) { + const should_trim = next_sibling + ? next_sibling.node.type === 'Text' && /^\s/.test(next_sibling.node.data) && trimmable_at(child, next_sibling) + : !child.has_ancestor('EachBlock'); - this.nodes.unshift(wrapper); + if (should_trim) { + data = trim_end(data); + if (!data) continue; + } + } - link(last_child, last_child = wrapper); - } else { - const Wrapper = wrappers[child.type]; - if (!Wrapper) continue; + // glue text nodes (which could e.g. be separated by comments) together + if (last_child && last_child.node.type === 'Text') { + last_child.data = data + last_child.data; + continue; + } - const wrapper = new Wrapper(renderer, block, parent, child, strip_whitespace, last_child || next_sibling); - this.nodes.unshift(wrapper); + const wrapper = new TextWrapper(renderer, block, parent, child, data); + if (wrapper.skip) continue; - link(last_child, last_child = wrapper); - } - } + this.nodes.unshift(wrapper); - if (strip_whitespace) { - const first = this.nodes[0] ; + link(last_child, (last_child = wrapper)); + } else { + const Wrapper = wrappers[child.type]; + if (!Wrapper) continue; - if (first && first.node.type === 'Text') { - first.data = trim_start(first.data); - if (!first.data) { - first.var = null; - this.nodes.shift(); + const wrapper = new Wrapper(renderer, block, parent, child, strip_whitespace, last_child || next_sibling); + this.nodes.unshift(wrapper); - if (this.nodes[0]) { - this.nodes[0].prev = null; - } - } - } - } + link(last_child, (last_child = wrapper)); + } + } - if (window_wrapper) { - this.nodes.unshift(window_wrapper); - link(last_child, window_wrapper); - } - } + if (strip_whitespace) { + const first = this.nodes[0]; - render(block, parent_node, parent_nodes) { - for (let i = 0; i < this.nodes.length; i += 1) { - this.nodes[i].render(block, parent_node, parent_nodes); - } - } + if (first && first.node.type === 'Text') { + first.data = trim_start(first.data); + if (!first.data) { + first.var = null; + this.nodes.shift(); + + if (this.nodes[0]) { + this.nodes[0].prev = null; + } + } + } + } + + if (window_wrapper) { + this.nodes.unshift(window_wrapper); + link(last_child, window_wrapper); + } + } + + render(block, parent_node, parent_nodes) { + for (let i = 0; i < this.nodes.length; i += 1) { + this.nodes[i].render(block, parent_node, parent_nodes); + } + } } class Renderer { - // TODO Maybe Renderer shouldn't know about Component? - + // TODO Maybe Renderer shouldn't know about Component? - __init() {this.context = [];} - __init2() {this.initial_context = [];} - __init3() {this.context_lookup = new Map();} - - __init4() {this.blocks = [];} - __init5() {this.readonly = new Set();} - __init6() {this.meta_bindings = [];} // initial values for e.g. window.innerWidth, if there's a <svelte:window> meta tag - __init7() {this.binding_groups = new Map();} + __init() { + this.context = []; + } + __init2() { + this.initial_context = []; + } + __init3() { + this.context_lookup = new Map(); + } - - + __init4() { + this.blocks = []; + } + __init5() { + this.readonly = new Set(); + } + __init6() { + this.meta_bindings = []; + } // initial values for e.g. window.innerWidth, if there's a <svelte:window> meta tag + __init7() { + this.binding_groups = new Map(); + } - - + constructor(component, options) { + Renderer.prototype.__init.call(this); + Renderer.prototype.__init2.call(this); + Renderer.prototype.__init3.call(this); + Renderer.prototype.__init4.call(this); + Renderer.prototype.__init5.call(this); + Renderer.prototype.__init6.call(this); + Renderer.prototype.__init7.call(this); + this.component = component; + this.options = options; + this.locate = component.locate; // TODO messy - constructor(component, options) {Renderer.prototype.__init.call(this);Renderer.prototype.__init2.call(this);Renderer.prototype.__init3.call(this);Renderer.prototype.__init4.call(this);Renderer.prototype.__init5.call(this);Renderer.prototype.__init6.call(this);Renderer.prototype.__init7.call(this); - this.component = component; - this.options = options; - this.locate = component.locate; // TODO messy + this.file_var = options.dev && this.component.get_unique_name('file'); - this.file_var = options.dev && this.component.get_unique_name('file'); + component.vars.filter((v) => !v.hoistable || (v.export_name && !v.module)).forEach((v) => this.add_to_context(v.name)); - component.vars.filter(v => !v.hoistable || (v.export_name && !v.module)).forEach(v => this.add_to_context(v.name)); + // ensure store values are included in context + component.vars.filter((v) => v.subscribable).forEach((v) => this.add_to_context(`$${v.name}`)); - // ensure store values are included in context - component.vars.filter(v => v.subscribable).forEach(v => this.add_to_context(`$${v.name}`)); + reserved_keywords.forEach((keyword) => { + if (component.var_lookup.has(keyword)) { + this.add_to_context(keyword); + } + }); - reserved_keywords.forEach(keyword => { - if (component.var_lookup.has(keyword)) { - this.add_to_context(keyword); - } - }); + if (component.slots.size > 0) { + this.add_to_context('$$scope'); + this.add_to_context('#slots'); + } - if (component.slots.size > 0) { - this.add_to_context('$$scope'); - this.add_to_context('#slots'); - } + if (this.binding_groups.size > 0) { + this.add_to_context('$$binding_groups'); + } - if (this.binding_groups.size > 0) { - this.add_to_context('$$binding_groups'); - } + // main block + this.block = new Block({ + renderer: this, + name: null, + type: 'component', + key: null, - // main block - this.block = new Block({ - renderer: this, - name: null, - type: 'component', - key: null, + bindings: new Map(), - bindings: new Map(), + dependencies: new Set(), + }); - dependencies: new Set() - }); + this.block.has_update_method = true; - this.block.has_update_method = true; - - this.fragment = new FragmentWrapper( - this, - this.block, - component.fragment.children, - null, - true, - null - ); - - // TODO messy - this.blocks.forEach(block => { - if (block instanceof Block) { - block.assign_variable_names(); - } - }); + this.fragment = new FragmentWrapper(this, this.block, component.fragment.children, null, true, null); - this.block.assign_variable_names(); + // TODO messy + this.blocks.forEach((block) => { + if (block instanceof Block) { + block.assign_variable_names(); + } + }); - this.fragment.render(this.block, null, x`#nodes` ); + this.block.assign_variable_names(); - this.context_overflow = this.context.length > 31; + this.fragment.render(this.block, null, x`#nodes`); - this.context.forEach(member => { - const { variable } = member; - if (variable) { - member.priority += 2; - if (variable.mutated || variable.reassigned) member.priority += 4; + this.context_overflow = this.context.length > 31; - // these determine whether variable is included in initial context - // array, so must have the highest priority - if (variable.is_reactive_dependency && (variable.mutated || variable.reassigned)) member.priority += 16; - if (variable.export_name) member.priority += 32; - if (variable.referenced) member.priority += 64; - } else if (member.is_non_contextual) { - // determine whether variable is included in initial context - // array, so must have the highest priority - member.priority += 8; - } + this.context.forEach((member) => { + const { variable } = member; + if (variable) { + member.priority += 2; + if (variable.mutated || variable.reassigned) member.priority += 4; - if (!member.is_contextual) { - member.priority += 1; - } - }); + // these determine whether variable is included in initial context + // array, so must have the highest priority + if (variable.is_reactive_dependency && (variable.mutated || variable.reassigned)) member.priority += 16; + if (variable.export_name) member.priority += 32; + if (variable.referenced) member.priority += 64; + } else if (member.is_non_contextual) { + // determine whether variable is included in initial context + // array, so must have the highest priority + member.priority += 8; + } - this.context.sort((a, b) => (b.priority - a.priority) || ((a.index.value ) - (b.index.value ))); - this.context.forEach((member, i) => member.index.value = i); + if (!member.is_contextual) { + member.priority += 1; + } + }); - let i = this.context.length; - while (i--) { - const member = this.context[i]; - if (member.variable) { - if (member.variable.referenced || member.variable.export_name || (member.variable.is_reactive_dependency && (member.variable.mutated || member.variable.reassigned))) break; - } else if (member.is_non_contextual) { - break; - } - } - this.initial_context = this.context.slice(0, i + 1); - } - - add_to_context(name, contextual = false) { - if (!this.context_lookup.has(name)) { - const member = { - name, - index: { type: 'Literal', value: this.context.length }, // index is updated later, but set here to preserve order within groups - is_contextual: false, - is_non_contextual: false, // shadowed vars could be contextual and non-contextual - variable: null, - priority: 0 - }; - - this.context_lookup.set(name, member); - this.context.push(member); - } + this.context.sort((a, b) => b.priority - a.priority || a.index.value - b.index.value); + this.context.forEach((member, i) => (member.index.value = i)); - const member = this.context_lookup.get(name); + let i = this.context.length; + while (i--) { + const member = this.context[i]; + if (member.variable) { + if (member.variable.referenced || member.variable.export_name || (member.variable.is_reactive_dependency && (member.variable.mutated || member.variable.reassigned))) break; + } else if (member.is_non_contextual) { + break; + } + } + this.initial_context = this.context.slice(0, i + 1); + } - if (contextual) { - member.is_contextual = true; - } else { - member.is_non_contextual = true; - member.variable = this.component.var_lookup.get(name); - } + add_to_context(name, contextual = false) { + if (!this.context_lookup.has(name)) { + const member = { + name, + index: { type: 'Literal', value: this.context.length }, // index is updated later, but set here to preserve order within groups + is_contextual: false, + is_non_contextual: false, // shadowed vars could be contextual and non-contextual + variable: null, + priority: 0, + }; + + this.context_lookup.set(name, member); + this.context.push(member); + } - return member; - } + const member = this.context_lookup.get(name); - invalidate(name, value, main_execution_context = false) { - return renderer_invalidate(this, name, value, main_execution_context); - } + if (contextual) { + member.is_contextual = true; + } else { + member.is_non_contextual = true; + member.variable = this.component.var_lookup.get(name); + } - dirty(names, is_reactive_declaration = false) { - const renderer = this; + return member; + } - const dirty = (is_reactive_declaration - ? x`$$self.$$.dirty` - : x`#dirty`) ; + invalidate(name, value, main_execution_context = false) { + return renderer_invalidate(this, name, value, main_execution_context); + } - const get_bitmask = () => { - const bitmask = []; - names.forEach((name) => { - const member = renderer.context_lookup.get(name); + dirty(names, is_reactive_declaration = false) { + const renderer = this; - if (!member) return; + const dirty = is_reactive_declaration ? x`$$self.$$.dirty` : x`#dirty`; - if (member.index.value === -1) { - throw new Error('unset index'); - } + const get_bitmask = () => { + const bitmask = []; + names.forEach((name) => { + const member = renderer.context_lookup.get(name); - const value = member.index.value ; - const i = (value / 31) | 0; - const n = 1 << (value % 31); + if (!member) return; - if (!bitmask[i]) bitmask[i] = { n: 0, names: [] }; + if (member.index.value === -1) { + throw new Error('unset index'); + } - bitmask[i].n |= n; - bitmask[i].names.push(name); - }); - return bitmask; - }; - - // TODO: context-overflow make it less gross - return { - // Using a ParenthesizedExpression allows us to create - // the expression lazily. TODO would be better if - // context was determined before rendering, so that - // this indirection was unnecessary - type: 'ParenthesizedExpression', - get expression() { - const bitmask = get_bitmask(); - - if (!bitmask.length) { - return x`${dirty} & /*${names.join(', ')}*/ 0` ; - } + const value = member.index.value; + const i = (value / 31) | 0; + const n = 1 << value % 31; - if (renderer.context_overflow) { - return bitmask - .map((b, i) => ({ b, i })) - .filter(({ b }) => b) - .map(({ b, i }) => x`${dirty}[${i}] & /*${b.names.join(', ')}*/ ${b.n}`) - .reduce((lhs, rhs) => x`${lhs} | ${rhs}`); - } + if (!bitmask[i]) bitmask[i] = { n: 0, names: [] }; - return x`${dirty} & /*${names.join(', ')}*/ ${bitmask[0].n}` ; - } - } ; - } + bitmask[i].n |= n; + bitmask[i].names.push(name); + }); + return bitmask; + }; - reference(node) { - if (typeof node === 'string') { - node = { type: 'Identifier', name: node }; - } + // TODO: context-overflow make it less gross + return { + // Using a ParenthesizedExpression allows us to create + // the expression lazily. TODO would be better if + // context was determined before rendering, so that + // this indirection was unnecessary + type: 'ParenthesizedExpression', + get expression() { + const bitmask = get_bitmask(); + + if (!bitmask.length) { + return x`${dirty} & /*${names.join(', ')}*/ 0`; + } - const { name, nodes } = flatten_reference(node); - const member = this.context_lookup.get(name); + if (renderer.context_overflow) { + return bitmask + .map((b, i) => ({ b, i })) + .filter(({ b }) => b) + .map(({ b, i }) => x`${dirty}[${i}] & /*${b.names.join(', ')}*/ ${b.n}`) + .reduce((lhs, rhs) => x`${lhs} | ${rhs}`); + } - // TODO is this correct? - if (this.component.var_lookup.get(name)) { - this.component.add_reference(name); - } + return x`${dirty} & /*${names.join(', ')}*/ ${bitmask[0].n}`; + }, + }; + } - if (member !== undefined) { - const replacement = x`/*${member.name}*/ #ctx[${member.index}]` ; + reference(node) { + if (typeof node === 'string') { + node = { type: 'Identifier', name: node }; + } - if (nodes[0].loc) replacement.object.loc = nodes[0].loc; - nodes[0] = replacement; + const { name, nodes } = flatten_reference(node); + const member = this.context_lookup.get(name); - return nodes.reduce((lhs, rhs) => x`${lhs}.${rhs}`); - } + // TODO is this correct? + if (this.component.var_lookup.get(name)) { + this.component.add_reference(name); + } - return node; - } + if (member !== undefined) { + const replacement = x`/*${member.name}*/ #ctx[${member.index}]`; - remove_block(block) { - this.blocks.splice(this.blocks.indexOf(block), 1); - } + if (nodes[0].loc) replacement.object.loc = nodes[0].loc; + nodes[0] = replacement; + + return nodes.reduce((lhs, rhs) => x`${lhs}.${rhs}`); + } + + return node; + } + + remove_block(block) { + this.blocks.splice(this.blocks.indexOf(block), 1); + } } var charToInteger$1 = {}; var chars$1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; for (var i$1 = 0; i$1 < chars$1.length; i$1++) { - charToInteger$1[chars$1.charCodeAt(i$1)] = i$1; + charToInteger$1[chars$1.charCodeAt(i$1)] = i$1; } function decode$1(mappings) { - var decoded = []; - var line = []; - var segment = [ - 0, - 0, - 0, - 0, - 0, - ]; - var j = 0; - for (var i = 0, shift = 0, value = 0; i < mappings.length; i++) { - var c = mappings.charCodeAt(i); - if (c === 44) { // "," - segmentify$1(line, segment, j); - j = 0; - } - else if (c === 59) { // ";" - segmentify$1(line, segment, j); - j = 0; - decoded.push(line); - line = []; - segment[0] = 0; - } - else { - var integer = charToInteger$1[c]; - if (integer === undefined) { - throw new Error('Invalid character (' + String.fromCharCode(c) + ')'); - } - var hasContinuationBit = integer & 32; - integer &= 31; - value += integer << shift; - if (hasContinuationBit) { - shift += 5; - } - else { - var shouldNegate = value & 1; - value >>>= 1; - if (shouldNegate) { - value = value === 0 ? -0x80000000 : -value; - } - segment[j] += value; - j++; - value = shift = 0; // reset - } + var decoded = []; + var line = []; + var segment = [0, 0, 0, 0, 0]; + var j = 0; + for (var i = 0, shift = 0, value = 0; i < mappings.length; i++) { + var c = mappings.charCodeAt(i); + if (c === 44) { + // "," + segmentify$1(line, segment, j); + j = 0; + } else if (c === 59) { + // ";" + segmentify$1(line, segment, j); + j = 0; + decoded.push(line); + line = []; + segment[0] = 0; + } else { + var integer = charToInteger$1[c]; + if (integer === undefined) { + throw new Error('Invalid character (' + String.fromCharCode(c) + ')'); + } + var hasContinuationBit = integer & 32; + integer &= 31; + value += integer << shift; + if (hasContinuationBit) { + shift += 5; + } else { + var shouldNegate = value & 1; + value >>>= 1; + if (shouldNegate) { + value = value === 0 ? -0x80000000 : -value; } + segment[j] += value; + j++; + value = shift = 0; // reset + } } - segmentify$1(line, segment, j); - decoded.push(line); - return decoded; + } + segmentify$1(line, segment, j); + decoded.push(line); + return decoded; } function segmentify$1(line, segment, j) { - // This looks ugly, but we're creating specialized arrays with a specific - // length. This is much faster than creating a new array (which v8 expands to - // a capacity of 17 after pushing the first item), or slicing out a subarray - // (which is slow). Length 4 is assumed to be the most frequent, followed by - // length 5 (since not everything will have an associated name), followed by - // length 1 (it's probably rare for a source substring to not have an - // associated segment data). - if (j === 4) - line.push([segment[0], segment[1], segment[2], segment[3]]); - else if (j === 5) - line.push([segment[0], segment[1], segment[2], segment[3], segment[4]]); - else if (j === 1) - line.push([segment[0]]); + // This looks ugly, but we're creating specialized arrays with a specific + // length. This is much faster than creating a new array (which v8 expands to + // a capacity of 17 after pushing the first item), or slicing out a subarray + // (which is slow). Length 4 is assumed to be the most frequent, followed by + // length 5 (since not everything will have an associated name), followed by + // length 1 (it's probably rare for a source substring to not have an + // associated segment data). + if (j === 4) line.push([segment[0], segment[1], segment[2], segment[3]]); + else if (j === 5) line.push([segment[0], segment[1], segment[2], segment[3], segment[4]]); + else if (j === 1) line.push([segment[0]]); } function encode$1(decoded) { - var sourceFileIndex = 0; // second field - var sourceCodeLine = 0; // third field - var sourceCodeColumn = 0; // fourth field - var nameIndex = 0; // fifth field - var mappings = ''; - for (var i = 0; i < decoded.length; i++) { - var line = decoded[i]; - if (i > 0) - mappings += ';'; - if (line.length === 0) - continue; - var generatedCodeColumn = 0; // first field - var lineMappings = []; - for (var _i = 0, line_1 = line; _i < line_1.length; _i++) { - var segment = line_1[_i]; - var segmentMappings = encodeInteger$1(segment[0] - generatedCodeColumn); - generatedCodeColumn = segment[0]; - if (segment.length > 1) { - segmentMappings += - encodeInteger$1(segment[1] - sourceFileIndex) + - encodeInteger$1(segment[2] - sourceCodeLine) + - encodeInteger$1(segment[3] - sourceCodeColumn); - sourceFileIndex = segment[1]; - sourceCodeLine = segment[2]; - sourceCodeColumn = segment[3]; - } - if (segment.length === 5) { - segmentMappings += encodeInteger$1(segment[4] - nameIndex); - nameIndex = segment[4]; - } - lineMappings.push(segmentMappings); - } - mappings += lineMappings.join(','); + var sourceFileIndex = 0; // second field + var sourceCodeLine = 0; // third field + var sourceCodeColumn = 0; // fourth field + var nameIndex = 0; // fifth field + var mappings = ''; + for (var i = 0; i < decoded.length; i++) { + var line = decoded[i]; + if (i > 0) mappings += ';'; + if (line.length === 0) continue; + var generatedCodeColumn = 0; // first field + var lineMappings = []; + for (var _i = 0, line_1 = line; _i < line_1.length; _i++) { + var segment = line_1[_i]; + var segmentMappings = encodeInteger$1(segment[0] - generatedCodeColumn); + generatedCodeColumn = segment[0]; + if (segment.length > 1) { + segmentMappings += encodeInteger$1(segment[1] - sourceFileIndex) + encodeInteger$1(segment[2] - sourceCodeLine) + encodeInteger$1(segment[3] - sourceCodeColumn); + sourceFileIndex = segment[1]; + sourceCodeLine = segment[2]; + sourceCodeColumn = segment[3]; + } + if (segment.length === 5) { + segmentMappings += encodeInteger$1(segment[4] - nameIndex); + nameIndex = segment[4]; + } + lineMappings.push(segmentMappings); } - return mappings; + mappings += lineMappings.join(','); + } + return mappings; } function encodeInteger$1(num) { - var result = ''; - num = num < 0 ? (-num << 1) | 1 : num << 1; - do { - var clamped = num & 31; - num >>>= 5; - if (num > 0) { - clamped |= 32; - } - result += chars$1[clamped]; - } while (num > 0); - return result; + var result = ''; + num = num < 0 ? (-num << 1) | 1 : num << 1; + do { + var clamped = num & 31; + num >>>= 5; + if (num > 0) { + clamped |= 32; + } + result += chars$1[clamped]; + } while (num > 0); + return result; } /** @@ -14512,7 +13402,7 @@ function encodeInteger$1(num) { * are not present on `target` will be copied as well. */ function defaults(target, source) { - return Object.assign(Object.create(null), source, target); + return Object.assign(Object.create(null), source, target); } /** @@ -14537,32 +13427,31 @@ function defaults(target, source) { * representations of either type. */ function decodeSourceMap(map) { - if (typeof map === 'string') { - map = JSON.parse(map); - } - let { mappings } = map; - if (typeof mappings === 'string') { - mappings = decode$1(mappings); - } - else { - // Clone the Line so that we can sort it. We don't want to mutate an array - // that we don't own directly. - mappings = mappings.map(cloneSegmentLine); - } - // Sort each Line's segments. There's no guarantee that segments are sorted for us, - // and even Chrome's implementation sorts: - // https://cs.chromium.org/chromium/src/third_party/devtools-frontend/src/front_end/sdk/SourceMap.js?l=507-508&rcl=109232bcf479c8f4ef8ead3cf56c49eb25f8c2f0 - mappings.forEach(sortSegments); - return defaults({ mappings }, map); + if (typeof map === 'string') { + map = JSON.parse(map); + } + let { mappings } = map; + if (typeof mappings === 'string') { + mappings = decode$1(mappings); + } else { + // Clone the Line so that we can sort it. We don't want to mutate an array + // that we don't own directly. + mappings = mappings.map(cloneSegmentLine); + } + // Sort each Line's segments. There's no guarantee that segments are sorted for us, + // and even Chrome's implementation sorts: + // https://cs.chromium.org/chromium/src/third_party/devtools-frontend/src/front_end/sdk/SourceMap.js?l=507-508&rcl=109232bcf479c8f4ef8ead3cf56c49eb25f8c2f0 + mappings.forEach(sortSegments); + return defaults({ mappings }, map); } function cloneSegmentLine(segments) { - return segments.slice(); + return segments.slice(); } function sortSegments(segments) { - segments.sort(segmentComparator); + segments.sort(segmentComparator); } function segmentComparator(a, b) { - return a[0] - b[0]; + return a[0] - b[0]; } /** @@ -14585,43 +13474,42 @@ function segmentComparator(a, b) { * source file. Recursive segment tracing ends at the `OriginalSource`. */ class OriginalSource { - constructor(filename, content) { - this.filename = filename; - this.content = content; - } - /** - * Tracing a `SourceMapSegment` ends when we get to an `OriginalSource`, - * meaning this line/column location originated from this source file. - */ - traceSegment(line, column, name) { - return { column, line, name, source: this }; - } + constructor(filename, content) { + this.filename = filename; + this.content = content; + } + /** + * Tracing a `SourceMapSegment` ends when we get to an `OriginalSource`, + * meaning this line/column location originated from this source file. + */ + traceSegment(line, column, name) { + return { column, line, name, source: this }; + } } /* istanbul ignore next */ -const Url = (typeof URL !== 'undefined' ? URL : require('url').URL); +const Url = typeof URL !== 'undefined' ? URL : require('url').URL; // Matches "..", which must be preceeded by "/" or the start of the string, and // must be followed by a "/". We do not eat the following "/", so that the next // iteration can match on it. const parentRegex = /(^|\/)\.\.(?=\/|$)/g; function isAbsoluteUrl(url) { - try { - return !!new Url(url); - } - catch (e) { - return false; - } + try { + return !!new Url(url); + } catch (e) { + return false; + } } /** * Creates a directory name that is guaranteed to not be in `str`. */ function uniqInStr(str) { - let uniq = String(Math.random()).slice(2); - while (str.indexOf(uniq) > -1) { - /* istanbul ignore next */ - uniq += uniq; - } - return uniq; + let uniq = String(Math.random()).slice(2); + while (str.indexOf(uniq) > -1) { + /* istanbul ignore next */ + uniq += uniq; + } + return uniq; } /** * Removes the filename from the path (everything trailing the last "/"). This @@ -14629,25 +13517,25 @@ function uniqInStr(str) { * relative URL. */ function stripPathFilename(path) { - path = normalizePath(path); - const index = path.lastIndexOf('/'); - return path.slice(0, index + 1); + path = normalizePath(path); + const index = path.lastIndexOf('/'); + return path.slice(0, index + 1); } /** * Normalizes a protocol-relative URL, but keeps it protocol relative by * stripping out the protocl before returning it. */ function normalizeProtocolRelative(input, absoluteBase) { - const { href, protocol } = new Url(input, absoluteBase); - return href.slice(protocol.length); + const { href, protocol } = new Url(input, absoluteBase); + return href.slice(protocol.length); } /** * Normalizes a simple path (one that has no ".."s, or is absolute so ".."s can * be normalized absolutely). */ function normalizeSimplePath(input) { - const { href } = new Url(input, 'https://foo.com/'); - return href.slice('https://foo.com/'.length); + const { href } = new Url(input, 'https://foo.com/'); + return href.slice('https://foo.com/'.length); } /** * Normalizes a path, ensuring that excess ".."s are preserved for relative @@ -14662,84 +13550,75 @@ function normalizeSimplePath(input) { * unless there are too many ".."s, in which case there will be a leading "..". */ function normalizePath(input) { - // If there are no ".."s, we can treat this as if it were an absolute path. - // The return won't be an absolute path, so it's easy. - if (!parentRegex.test(input)) - return normalizeSimplePath(input); - // We already found one "..". Let's see how many there are. - let total = 1; - while (parentRegex.test(input)) - total++; - // If there are ".."s, we need to prefix the the path with the same number of - // unique directories. This is to ensure that we "remember" how many parent - // directories we are accessing. Eg, "../../.." must keep 3, and "foo/../.." - // must keep 1. - const uniqDirectory = `z${uniqInStr(input)}/`; - // uniqDirectory is just a "z", followed by numbers, followed by a "/". So - // generating a runtime regex from it is safe. We'll use this search regex to - // strip out our uniq directory names and insert any needed ".."s. - const search = new RegExp(`^(?:${uniqDirectory})*`); - // Now we can resolve the total path. If there are excess ".."s, they will - // eliminate one or more of the unique directories we prefix with. - const relative = normalizeSimplePath(uniqDirectory.repeat(total) + input); - // We can now count the number of unique directories that were eliminated. If - // there were 3, and 1 was eliminated, we know we only need to add 1 "..". If - // 2 were eliminated, we need to insert 2 ".."s. If all 3 were eliminated, - // then we need 3, etc. This replace is guranteed to match (it may match 0 or - // more times), and we can count the total match to see how many were eliminated. - return relative.replace(search, (all) => { - const leftover = all.length / uniqDirectory.length; - return '../'.repeat(total - leftover); - }); + // If there are no ".."s, we can treat this as if it were an absolute path. + // The return won't be an absolute path, so it's easy. + if (!parentRegex.test(input)) return normalizeSimplePath(input); + // We already found one "..". Let's see how many there are. + let total = 1; + while (parentRegex.test(input)) total++; + // If there are ".."s, we need to prefix the the path with the same number of + // unique directories. This is to ensure that we "remember" how many parent + // directories we are accessing. Eg, "../../.." must keep 3, and "foo/../.." + // must keep 1. + const uniqDirectory = `z${uniqInStr(input)}/`; + // uniqDirectory is just a "z", followed by numbers, followed by a "/". So + // generating a runtime regex from it is safe. We'll use this search regex to + // strip out our uniq directory names and insert any needed ".."s. + const search = new RegExp(`^(?:${uniqDirectory})*`); + // Now we can resolve the total path. If there are excess ".."s, they will + // eliminate one or more of the unique directories we prefix with. + const relative = normalizeSimplePath(uniqDirectory.repeat(total) + input); + // We can now count the number of unique directories that were eliminated. If + // there were 3, and 1 was eliminated, we know we only need to add 1 "..". If + // 2 were eliminated, we need to insert 2 ".."s. If all 3 were eliminated, + // then we need 3, etc. This replace is guranteed to match (it may match 0 or + // more times), and we can count the total match to see how many were eliminated. + return relative.replace(search, (all) => { + const leftover = all.length / uniqDirectory.length; + return '../'.repeat(total - leftover); + }); } /** * Attempts to resolve `input` URL relative to `base`. */ function resolve(input, base) { - if (!base) - base = ''; - // Absolute URLs are very easy to resolve right. - if (isAbsoluteUrl(input)) - return new Url(input).href; - if (base) { - // Absolute URLs are easy... - if (isAbsoluteUrl(base)) - return new Url(input, base).href; - // If base is protocol relative, we'll resolve with it but keep the result - // protocol relative. - if (base.startsWith('//')) - return normalizeProtocolRelative(input, `https:${base}`); - } - // Normalize input, but keep it protocol relative. We know base doesn't supply - // a protocol, because that would have been handled above. - if (input.startsWith('//')) - return normalizeProtocolRelative(input, 'https://foo.com/'); - // We now know that base (if there is one) and input are paths. We've handled - // both absolute and protocol-relative variations above. - // Absolute paths don't need any special handling, because they cannot have - // extra "." or ".."s. That'll all be stripped away. Input takes priority here, - // because if input is an absolute path, base path won't affect it in any way. - if (input.startsWith('/')) - return '/' + normalizeSimplePath(input); - // Since input and base are paths, we need to join them to do any further - // processing. Paths are joined at the directory level, so we need to remove - // the base's filename before joining. We also know that input does not have a - // leading slash, and that the stripped base will have a trailing slash if - // there are any directories (or it'll be empty). - const joined = stripPathFilename(base) + input; - // If base is an absolute path, then input will be relative to it. - if (base.startsWith('/')) - return '/' + normalizeSimplePath(joined); - // We now know both base (if there is one) and input are relative paths. - const relative = normalizePath(joined); - // If base started with a leading ".", or there is no base and input started - // with a ".", then we need to ensure that the relative path starts with a - // ".". We don't know if relative starts with a "..", though, so check before - // prepending. - if ((base || input).startsWith('.') && !relative.startsWith('.')) { - return './' + relative; - } - return relative; + if (!base) base = ''; + // Absolute URLs are very easy to resolve right. + if (isAbsoluteUrl(input)) return new Url(input).href; + if (base) { + // Absolute URLs are easy... + if (isAbsoluteUrl(base)) return new Url(input, base).href; + // If base is protocol relative, we'll resolve with it but keep the result + // protocol relative. + if (base.startsWith('//')) return normalizeProtocolRelative(input, `https:${base}`); + } + // Normalize input, but keep it protocol relative. We know base doesn't supply + // a protocol, because that would have been handled above. + if (input.startsWith('//')) return normalizeProtocolRelative(input, 'https://foo.com/'); + // We now know that base (if there is one) and input are paths. We've handled + // both absolute and protocol-relative variations above. + // Absolute paths don't need any special handling, because they cannot have + // extra "." or ".."s. That'll all be stripped away. Input takes priority here, + // because if input is an absolute path, base path won't affect it in any way. + if (input.startsWith('/')) return '/' + normalizeSimplePath(input); + // Since input and base are paths, we need to join them to do any further + // processing. Paths are joined at the directory level, so we need to remove + // the base's filename before joining. We also know that input does not have a + // leading slash, and that the stripped base will have a trailing slash if + // there are any directories (or it'll be empty). + const joined = stripPathFilename(base) + input; + // If base is an absolute path, then input will be relative to it. + if (base.startsWith('/')) return '/' + normalizeSimplePath(joined); + // We now know both base (if there is one) and input are relative paths. + const relative = normalizePath(joined); + // If base started with a leading ".", or there is no base and input started + // with a ".", then we need to ensure that the relative path starts with a + // ".". We don't know if relative starts with a "..", though, so check before + // prepending. + if ((base || input).startsWith('.') && !relative.startsWith('.')) { + return './' + relative; + } + return relative; } /** @@ -14758,12 +13637,11 @@ function resolve(input, base) { * limitations under the License. */ function resolve$1(input, base) { - // The base is always treated as a directory, if it's not empty. - // https://github.com/mozilla/source-map/blob/8cb3ee57/lib/util.js#L327 - // https://github.com/chromium/chromium/blob/da4adbb3/third_party/blink/renderer/devtools/front_end/sdk/SourceMap.js#L400-L401 - if (base && !base.endsWith('/')) - base += '/'; - return resolve(input, base); + // The base is always treated as a directory, if it's not empty. + // https://github.com/mozilla/source-map/blob/8cb3ee57/lib/util.js#L327 + // https://github.com/chromium/chromium/blob/da4adbb3/third_party/blink/renderer/devtools/front_end/sdk/SourceMap.js#L400-L401 + if (base && !base.endsWith('/')) base += '/'; + return resolve(input, base); } /** @@ -14807,22 +13685,21 @@ function resolve$1(input, base) { * ``` */ function binarySearch(haystack, needle, comparator) { - let low = 0; - let high = haystack.length - 1; - while (low <= high) { - const mid = low + ((high - low) >> 1); - const cmp = comparator(haystack[mid], needle); - if (cmp === 0) { - return mid; - } - if (cmp < 0) { - low = mid + 1; - } - else { - high = mid - 1; - } + let low = 0; + let high = haystack.length - 1; + while (low <= high) { + const mid = low + ((high - low) >> 1); + const cmp = comparator(haystack[mid], needle); + if (cmp === 0) { + return mid; } - return ~low; + if (cmp < 0) { + low = mid + 1; + } else { + high = mid - 1; + } + } + return ~low; } /** @@ -14849,26 +13726,26 @@ function binarySearch(haystack, needle, comparator) { * associated with `source[i]`, and there are never duplicates. */ class FastStringArray { - constructor() { - this.indexes = Object.create(null); - this.array = []; - } - /** - * Puts `key` into the backing array, if it is not already present. Returns - * the index of the `key` in the backing array. - */ - put(key) { - const { array, indexes } = this; - // The key may or may not be present. If it is present, it's a number. - let index = indexes[key]; - // If it's not yet present, we need to insert it and track the index in the - // indexes. - if (index === undefined) { - index = indexes[key] = array.length; - array.push(key); - } - return index; + constructor() { + this.indexes = Object.create(null); + this.array = []; + } + /** + * Puts `key` into the backing array, if it is not already present. Returns + * the index of the `key` in the backing array. + */ + put(key) { + const { array, indexes } = this; + // The key may or may not be present. If it is present, it's a number. + let index = indexes[key]; + // If it's not yet present, we need to insert it and track the index in the + // indexes. + if (index === undefined) { + index = indexes[key] = array.length; + array.push(key); } + return index; + } } /** @@ -14891,99 +13768,98 @@ class FastStringArray { * mappings into its child nodes (which may themselves be SourceMapTrees). */ class SourceMapTree { - constructor(map, sources) { - this.map = map; - this.sources = sources; - } - /** - * traceMappings is only called on the root level SourceMapTree, and begins - * the process of resolving each mapping in terms of the original source - * files. - */ - traceMappings() { - const mappings = []; - const names = new FastStringArray(); - const sources = new FastStringArray(); - const sourcesContent = []; - const { mappings: rootMappings, names: rootNames } = this.map; - for (let i = 0; i < rootMappings.length; i++) { - const segments = rootMappings[i]; - const tracedSegments = []; - for (let j = 0; j < segments.length; j++) { - const segment = segments[j]; - // 1-length segments only move the current generated column, there's no - // source information to gather from it. - if (segment.length === 1) - continue; - const source = this.sources[segment[1]]; - const traced = source.traceSegment(segment[2], segment[3], segment.length === 5 ? rootNames[segment[4]] : ''); - if (!traced) - continue; - // So we traced a segment down into its original source file. Now push a - // new segment pointing to this location. - const { column, line, name } = traced; - const { content, filename } = traced.source; - // Store the source location, and ensure we keep sourcesContent up to - // date with the sources array. - const sourceIndex = sources.put(filename); - sourcesContent[sourceIndex] = content; - // This looks like unnecessary duplication, but it noticeably increases - // performance. If we were to push the nameIndex onto length-4 array, v8 - // would internally allocate 22 slots! That's 68 wasted bytes! Array - // literals have the same capacity as their length, saving memory. - if (name) { - tracedSegments.push([segment[0], sourceIndex, line, column, names.put(name)]); - } - else { - tracedSegments.push([segment[0], sourceIndex, line, column]); - } - } - mappings.push(tracedSegments); - } - // TODO: Make all sources relative to the sourceRoot. - return defaults({ - mappings, - names: names.array, - sources: sources.array, - sourcesContent, - }, this.map); - } - /** - * traceSegment is only called on children SourceMapTrees. It recurses down - * into its own child SourceMapTrees, until we find the original source map. - */ - traceSegment(line, column, name) { - const { mappings, names } = this.map; - // It's common for parent sourcemaps to have pointers to lines that have no - // mapping (like a "//# sourceMappingURL=") at the end of the child file. - if (line >= mappings.length) - return null; - const segments = mappings[line]; - if (segments.length === 0) - return null; - let index = binarySearch(segments, column, segmentComparator$1); - if (index === -1) - return null; // we come before any mapped segment - // If we can't find a segment that lines up to this column, we use the - // segment before. - if (index < 0) { - index = ~index - 1; - } - const segment = segments[index]; + constructor(map, sources) { + this.map = map; + this.sources = sources; + } + /** + * traceMappings is only called on the root level SourceMapTree, and begins + * the process of resolving each mapping in terms of the original source + * files. + */ + traceMappings() { + const mappings = []; + const names = new FastStringArray(); + const sources = new FastStringArray(); + const sourcesContent = []; + const { mappings: rootMappings, names: rootNames } = this.map; + for (let i = 0; i < rootMappings.length; i++) { + const segments = rootMappings[i]; + const tracedSegments = []; + for (let j = 0; j < segments.length; j++) { + const segment = segments[j]; // 1-length segments only move the current generated column, there's no // source information to gather from it. - if (segment.length === 1) - return null; + if (segment.length === 1) continue; const source = this.sources[segment[1]]; - // So now we can recurse down, until we hit the original source file. - return source.traceSegment(segment[2], segment[3], - // A child map's recorded name for this segment takes precedence over the - // parent's mapped name. Imagine a mangler changing the name over, etc. - segment.length === 5 ? names[segment[4]] : name); + const traced = source.traceSegment(segment[2], segment[3], segment.length === 5 ? rootNames[segment[4]] : ''); + if (!traced) continue; + // So we traced a segment down into its original source file. Now push a + // new segment pointing to this location. + const { column, line, name } = traced; + const { content, filename } = traced.source; + // Store the source location, and ensure we keep sourcesContent up to + // date with the sources array. + const sourceIndex = sources.put(filename); + sourcesContent[sourceIndex] = content; + // This looks like unnecessary duplication, but it noticeably increases + // performance. If we were to push the nameIndex onto length-4 array, v8 + // would internally allocate 22 slots! That's 68 wasted bytes! Array + // literals have the same capacity as their length, saving memory. + if (name) { + tracedSegments.push([segment[0], sourceIndex, line, column, names.put(name)]); + } else { + tracedSegments.push([segment[0], sourceIndex, line, column]); + } + } + mappings.push(tracedSegments); } + // TODO: Make all sources relative to the sourceRoot. + return defaults( + { + mappings, + names: names.array, + sources: sources.array, + sourcesContent, + }, + this.map + ); + } + /** + * traceSegment is only called on children SourceMapTrees. It recurses down + * into its own child SourceMapTrees, until we find the original source map. + */ + traceSegment(line, column, name) { + const { mappings, names } = this.map; + // It's common for parent sourcemaps to have pointers to lines that have no + // mapping (like a "//# sourceMappingURL=") at the end of the child file. + if (line >= mappings.length) return null; + const segments = mappings[line]; + if (segments.length === 0) return null; + let index = binarySearch(segments, column, segmentComparator$1); + if (index === -1) return null; // we come before any mapped segment + // If we can't find a segment that lines up to this column, we use the + // segment before. + if (index < 0) { + index = ~index - 1; + } + const segment = segments[index]; + // 1-length segments only move the current generated column, there's no + // source information to gather from it. + if (segment.length === 1) return null; + const source = this.sources[segment[1]]; + // So now we can recurse down, until we hit the original source file. + return source.traceSegment( + segment[2], + segment[3], + // A child map's recorded name for this segment takes precedence over the + // parent's mapped name. Imagine a mangler changing the name over, etc. + segment.length === 5 ? names[segment[4]] : name + ); + } } function segmentComparator$1(segment, column) { - return segment[0] - column; + return segment[0] - column; } /** @@ -15005,10 +13881,9 @@ function segmentComparator$1(segment, column) { * Removes the filename from a path. */ function stripFilename(path) { - if (!path) - return ''; - const index = path.lastIndexOf('/'); - return path.slice(0, index + 1); + if (!path) return ''; + const index = path.lastIndexOf('/'); + return path.slice(0, index + 1); } /** @@ -15027,9 +13902,8 @@ function stripFilename(path) { * limitations under the License. */ function asArray(value) { - if (Array.isArray(value)) - return value; - return [value]; + if (Array.isArray(value)) return value; + return [value]; } /** * Recursively builds a tree structure out of sourcemap files, with each node @@ -15043,39 +13917,38 @@ function asArray(value) { * unmodified source file. */ function buildSourceMapTree(input, loader, relativeRoot) { - const maps = asArray(input).map(decodeSourceMap); - const map = maps.pop(); - for (let i = 0; i < maps.length; i++) { - if (maps[i].sources.length !== 1) { - throw new Error(`Transformation map ${i} must have exactly one source file.\n` + - 'Did you specify these with the most recent transformation maps first?'); - } + const maps = asArray(input).map(decodeSourceMap); + const map = maps.pop(); + for (let i = 0; i < maps.length; i++) { + if (maps[i].sources.length !== 1) { + throw new Error(`Transformation map ${i} must have exactly one source file.\n` + 'Did you specify these with the most recent transformation maps first?'); } - const { sourceRoot, sources, sourcesContent } = map; - const children = sources.map((sourceFile, i) => { - // Each source file is loaded relative to the sourcemap's own sourceRoot, - // which is itself relative to the sourcemap's parent. - const uri = resolve$1(sourceFile || '', resolve$1(sourceRoot || '', stripFilename(relativeRoot))); - // Use the provided loader callback to retrieve the file's sourcemap. - // TODO: We should eventually support async loading of sourcemap files. - const sourceMap = loader(uri); - // If there is no sourcemap, then it is an unmodified source file. - if (!sourceMap) { - // The source file's actual contents must be included in the sourcemap - // (done when generating the sourcemap) for it to be included as a - // sourceContent in the output sourcemap. - const sourceContent = sourcesContent ? sourcesContent[i] : null; - return new OriginalSource(uri, sourceContent); - } - // Else, it's a real sourcemap, and we need to recurse into it to load its - // source files. - return buildSourceMapTree(decodeSourceMap(sourceMap), loader, uri); - }); - let tree = new SourceMapTree(map, children); - for (let i = maps.length - 1; i >= 0; i--) { - tree = new SourceMapTree(maps[i], [tree]); + } + const { sourceRoot, sources, sourcesContent } = map; + const children = sources.map((sourceFile, i) => { + // Each source file is loaded relative to the sourcemap's own sourceRoot, + // which is itself relative to the sourcemap's parent. + const uri = resolve$1(sourceFile || '', resolve$1(sourceRoot || '', stripFilename(relativeRoot))); + // Use the provided loader callback to retrieve the file's sourcemap. + // TODO: We should eventually support async loading of sourcemap files. + const sourceMap = loader(uri); + // If there is no sourcemap, then it is an unmodified source file. + if (!sourceMap) { + // The source file's actual contents must be included in the sourcemap + // (done when generating the sourcemap) for it to be included as a + // sourceContent in the output sourcemap. + const sourceContent = sourcesContent ? sourcesContent[i] : null; + return new OriginalSource(uri, sourceContent); } - return tree; + // Else, it's a real sourcemap, and we need to recurse into it to load its + // source files. + return buildSourceMapTree(decodeSourceMap(sourceMap), loader, uri); + }); + let tree = new SourceMapTree(map, children); + for (let i = maps.length - 1; i >= 0; i--) { + tree = new SourceMapTree(maps[i], [tree]); + } + return tree; } /** @@ -15098,22 +13971,20 @@ function buildSourceMapTree(input, loader, relativeRoot) { * provided to it. */ class SourceMap { - constructor(map, excludeContent) { - this.version = 3; // SourceMap spec says this should be first. - if ('file' in map) - this.file = map.file; - this.mappings = encode$1(map.mappings); - this.names = map.names; - // TODO: We first need to make all source URIs relative to the sourceRoot - // before we can support a sourceRoot. - // if ('sourceRoot' in map) this.sourceRoot = map.sourceRoot; - this.sources = map.sources; - if (!excludeContent && 'sourcesContent' in map) - this.sourcesContent = map.sourcesContent; - } - toString() { - return JSON.stringify(this); - } + constructor(map, excludeContent) { + this.version = 3; // SourceMap spec says this should be first. + if ('file' in map) this.file = map.file; + this.mappings = encode$1(map.mappings); + this.names = map.names; + // TODO: We first need to make all source URIs relative to the sourceRoot + // before we can support a sourceRoot. + // if ('sourceRoot' in map) this.sourceRoot = map.sourceRoot; + this.sources = map.sources; + if (!excludeContent && 'sourcesContent' in map) this.sourcesContent = map.sourcesContent; + } + toString() { + return JSON.stringify(this); + } } /** @@ -15144,368 +14015,342 @@ class SourceMap { * content from the output sourcemap. */ function remapping(input, loader, excludeContent) { - const graph = buildSourceMapTree(input, loader); - return new SourceMap(graph.traceMappings(), !!excludeContent); + const graph = buildSourceMapTree(input, loader); + return new SourceMap(graph.traceMappings(), !!excludeContent); } function last_line_length(s) { - return s.length - s.lastIndexOf('\n') - 1; + return s.length - s.lastIndexOf('\n') - 1; } // mutate map in-place -function sourcemap_add_offset( - map, offset, source_index -) { - if (map.mappings.length == 0) return; - for (let line = 0; line < map.mappings.length; line++) { - const segment_list = map.mappings[line]; - for (let segment = 0; segment < segment_list.length; segment++) { - const seg = segment_list[segment]; - // shift only segments that belong to component source file - if (seg[1] === source_index) { // also ensures that seg.length >= 4 - // shift column if it points at the first line - if (seg[2] === 0) { - seg[3] += offset.column; - } - // shift line - seg[2] += offset.line; - } - } - } +function sourcemap_add_offset(map, offset, source_index) { + if (map.mappings.length == 0) return; + for (let line = 0; line < map.mappings.length; line++) { + const segment_list = map.mappings[line]; + for (let segment = 0; segment < segment_list.length; segment++) { + const seg = segment_list[segment]; + // shift only segments that belong to component source file + if (seg[1] === source_index) { + // also ensures that seg.length >= 4 + // shift column if it points at the first line + if (seg[2] === 0) { + seg[3] += offset.column; + } + // shift line + seg[2] += offset.line; + } + } + } } function merge_tables(this_table, other_table) { - const new_table = this_table.slice(); - const idx_map = []; - other_table = other_table || []; - let val_changed = false; - for (const [other_idx, other_val] of other_table.entries()) { - const this_idx = this_table.indexOf(other_val); - if (this_idx >= 0) { - idx_map[other_idx] = this_idx; - } else { - const new_idx = new_table.length; - new_table[new_idx] = other_val; - idx_map[other_idx] = new_idx; - val_changed = true; - } - } - let idx_changed = val_changed; - if (val_changed) { - if (idx_map.find((val, idx) => val != idx) === undefined) { - // idx_map is identity map [0, 1, 2, 3, 4, ....] - idx_changed = false; - } - } - return [new_table, idx_map, val_changed, idx_changed]; + const new_table = this_table.slice(); + const idx_map = []; + other_table = other_table || []; + let val_changed = false; + for (const [other_idx, other_val] of other_table.entries()) { + const this_idx = this_table.indexOf(other_val); + if (this_idx >= 0) { + idx_map[other_idx] = this_idx; + } else { + const new_idx = new_table.length; + new_table[new_idx] = other_val; + idx_map[other_idx] = new_idx; + val_changed = true; + } + } + let idx_changed = val_changed; + if (val_changed) { + if (idx_map.find((val, idx) => val != idx) === undefined) { + // idx_map is identity map [0, 1, 2, 3, 4, ....] + idx_changed = false; + } + } + return [new_table, idx_map, val_changed, idx_changed]; } function pushArray(_this, other) { - // We use push to mutate in place for memory and perf reasons - // We use the for loop instead of _this.push(...other) to avoid the JS engine's function argument limit (65,535 in JavascriptCore) - for (let i = 0; i < other.length; i++) { - _this.push(other[i]); - } + // We use push to mutate in place for memory and perf reasons + // We use the for loop instead of _this.push(...other) to avoid the JS engine's function argument limit (65,535 in JavascriptCore) + for (let i = 0; i < other.length; i++) { + _this.push(other[i]); + } } class MappedCode { - - - - constructor(string = '', map = null) { - this.string = string; - if (map) { - this.map = map ; - } else { - this.map = { - version: 3, - mappings: [], - sources: [], - names: [] - }; - } - } - - /** - * concat in-place (mutable), return this (chainable) - * will also mutate the `other` object - */ - concat(other) { - // noop: if one is empty, return the other - if (other.string == '') return this; - if (this.string == '') { - this.string = other.string; - this.map = other.map; - return this; - } + constructor(string = '', map = null) { + this.string = string; + if (map) { + this.map = map; + } else { + this.map = { + version: 3, + mappings: [], + sources: [], + names: [], + }; + } + } - // compute last line length before mutating - const column_offset = last_line_length(this.string); + /** + * concat in-place (mutable), return this (chainable) + * will also mutate the `other` object + */ + concat(other) { + // noop: if one is empty, return the other + if (other.string == '') return this; + if (this.string == '') { + this.string = other.string; + this.map = other.map; + return this; + } - this.string += other.string; + // compute last line length before mutating + const column_offset = last_line_length(this.string); - const m1 = this.map; - const m2 = other.map; + this.string += other.string; - if (m2.mappings.length == 0) return this; + const m1 = this.map; + const m2 = other.map; - // combine sources and names - const [sources, new_source_idx, sources_changed, sources_idx_changed] = merge_tables(m1.sources, m2.sources); - const [names, new_name_idx, names_changed, names_idx_changed] = merge_tables(m1.names, m2.names); + if (m2.mappings.length == 0) return this; - if (sources_changed) m1.sources = sources; - if (names_changed) m1.names = names; + // combine sources and names + const [sources, new_source_idx, sources_changed, sources_idx_changed] = merge_tables(m1.sources, m2.sources); + const [names, new_name_idx, names_changed, names_idx_changed] = merge_tables(m1.names, m2.names); - // unswitched loops are faster - if (sources_idx_changed && names_idx_changed) { - for (let line = 0; line < m2.mappings.length; line++) { - const segment_list = m2.mappings[line]; - for (let segment = 0; segment < segment_list.length; segment++) { - const seg = segment_list[segment]; - if (seg[1] >= 0) seg[1] = new_source_idx[seg[1]]; - if (seg[4] >= 0) seg[4] = new_name_idx[seg[4]]; - } - } - } else if (sources_idx_changed) { - for (let line = 0; line < m2.mappings.length; line++) { - const segment_list = m2.mappings[line]; - for (let segment = 0; segment < segment_list.length; segment++) { - const seg = segment_list[segment]; - if (seg[1] >= 0) seg[1] = new_source_idx[seg[1]]; - } - } - } else if (names_idx_changed) { - for (let line = 0; line < m2.mappings.length; line++) { - const segment_list = m2.mappings[line]; - for (let segment = 0; segment < segment_list.length; segment++) { - const seg = segment_list[segment]; - if (seg[4] >= 0) seg[4] = new_name_idx[seg[4]]; - } - } - } + if (sources_changed) m1.sources = sources; + if (names_changed) m1.names = names; - // combine the mappings + // unswitched loops are faster + if (sources_idx_changed && names_idx_changed) { + for (let line = 0; line < m2.mappings.length; line++) { + const segment_list = m2.mappings[line]; + for (let segment = 0; segment < segment_list.length; segment++) { + const seg = segment_list[segment]; + if (seg[1] >= 0) seg[1] = new_source_idx[seg[1]]; + if (seg[4] >= 0) seg[4] = new_name_idx[seg[4]]; + } + } + } else if (sources_idx_changed) { + for (let line = 0; line < m2.mappings.length; line++) { + const segment_list = m2.mappings[line]; + for (let segment = 0; segment < segment_list.length; segment++) { + const seg = segment_list[segment]; + if (seg[1] >= 0) seg[1] = new_source_idx[seg[1]]; + } + } + } else if (names_idx_changed) { + for (let line = 0; line < m2.mappings.length; line++) { + const segment_list = m2.mappings[line]; + for (let segment = 0; segment < segment_list.length; segment++) { + const seg = segment_list[segment]; + if (seg[4] >= 0) seg[4] = new_name_idx[seg[4]]; + } + } + } - // combine - // 1. last line of first map - // 2. first line of second map - // columns of 2 must be shifted + // combine the mappings - if (m2.mappings.length > 0 && column_offset > 0) { - const first_line = m2.mappings[0]; - for (let i = 0; i < first_line.length; i++) { - first_line[i][0] += column_offset; - } - } + // combine + // 1. last line of first map + // 2. first line of second map + // columns of 2 must be shifted - // combine last line + first line - pushArray(m1.mappings[m1.mappings.length - 1], m2.mappings.shift()); + if (m2.mappings.length > 0 && column_offset > 0) { + const first_line = m2.mappings[0]; + for (let i = 0; i < first_line.length; i++) { + first_line[i][0] += column_offset; + } + } - // append other lines - pushArray(m1.mappings, m2.mappings); + // combine last line + first line + pushArray(m1.mappings[m1.mappings.length - 1], m2.mappings.shift()); - return this; - } + // append other lines + pushArray(m1.mappings, m2.mappings); - static from_processed(string, map) { - const line_count = string.split('\n').length; + return this; + } - if (map) { - // ensure that count of source map mappings lines - // is equal to count of generated code lines - // (some tools may produce less) - const missing_lines = line_count - map.mappings.length; - for (let i = 0; i < missing_lines; i++) { - map.mappings.push([]); - } - return new MappedCode(string, map); - } + static from_processed(string, map) { + const line_count = string.split('\n').length; - if (string == '') return new MappedCode(); - map = { version: 3, names: [], sources: [], mappings: [] }; - - // add empty SourceMapSegment[] for every line - for (let i = 0; i < line_count; i++) map.mappings.push([]); - return new MappedCode(string, map); - } - - static from_source({ source, file_basename, get_location }) { - let offset = get_location(0); - - if (!offset) offset = { line: 0, column: 0 }; - const map = { version: 3, names: [], sources: [file_basename], mappings: [] }; - if (source == '') return new MappedCode(source, map); - - // we create a high resolution identity map here, - // we know that it will eventually be merged with svelte's map, - // at which stage the resolution will decrease. - const line_list = source.split('\n'); - for (let line = 0; line < line_list.length; line++) { - map.mappings.push([]); - const token_list = line_list[line].split(/([^\d\w\s]|\s+)/g); - for (let token = 0, column = 0; token < token_list.length; token++) { - if (token_list[token] == '') continue; - map.mappings[line].push([column, 0, offset.line + line, column]); - column += token_list[token].length; - } - } - // shift columns in first line - const segment_list = map.mappings[0]; - for (let segment = 0; segment < segment_list.length; segment++) { - segment_list[segment][3] += offset.column; - } - return new MappedCode(source, map); - } -} - -function combine_sourcemaps( - filename, - sourcemap_list -) { - if (sourcemap_list.length == 0) return null; - - let map_idx = 1; - const map = - sourcemap_list.slice(0, -1) - .find(m => m.sources.length !== 1) === undefined - - ? remapping( // use array interface - // only the oldest sourcemap can have multiple sources - sourcemap_list, - () => null, - true // skip optional field `sourcesContent` - ) - - : remapping( // use loader interface - sourcemap_list[0], // last map - function loader(sourcefile) { - if (sourcefile === filename && sourcemap_list[map_idx]) { - return sourcemap_list[map_idx++]; // idx 1, 2, ... - // bundle file = branch node - } else { - return null; // source file = leaf node - } - } , - true - ); + if (map) { + // ensure that count of source map mappings lines + // is equal to count of generated code lines + // (some tools may produce less) + const missing_lines = line_count - map.mappings.length; + for (let i = 0; i < missing_lines; i++) { + map.mappings.push([]); + } + return new MappedCode(string, map); + } + + if (string == '') return new MappedCode(); + map = { version: 3, names: [], sources: [], mappings: [] }; - if (!map.file) delete map.file; // skip optional field `file` + // add empty SourceMapSegment[] for every line + for (let i = 0; i < line_count; i++) map.mappings.push([]); + return new MappedCode(string, map); + } - return map; + static from_source({ source, file_basename, get_location }) { + let offset = get_location(0); + + if (!offset) offset = { line: 0, column: 0 }; + const map = { version: 3, names: [], sources: [file_basename], mappings: [] }; + if (source == '') return new MappedCode(source, map); + + // we create a high resolution identity map here, + // we know that it will eventually be merged with svelte's map, + // at which stage the resolution will decrease. + const line_list = source.split('\n'); + for (let line = 0; line < line_list.length; line++) { + map.mappings.push([]); + const token_list = line_list[line].split(/([^\d\w\s]|\s+)/g); + for (let token = 0, column = 0; token < token_list.length; token++) { + if (token_list[token] == '') continue; + map.mappings[line].push([column, 0, offset.line + line, column]); + column += token_list[token].length; + } + } + // shift columns in first line + const segment_list = map.mappings[0]; + for (let segment = 0; segment < segment_list.length; segment++) { + segment_list[segment][3] += offset.column; + } + return new MappedCode(source, map); + } +} + +function combine_sourcemaps(filename, sourcemap_list) { + if (sourcemap_list.length == 0) return null; + + let map_idx = 1; + const map = + sourcemap_list.slice(0, -1).find((m) => m.sources.length !== 1) === undefined + ? remapping( + // use array interface + // only the oldest sourcemap can have multiple sources + sourcemap_list, + () => null, + true // skip optional field `sourcesContent` + ) + : remapping( + // use loader interface + sourcemap_list[0], // last map + function loader(sourcefile) { + if (sourcefile === filename && sourcemap_list[map_idx]) { + return sourcemap_list[map_idx++]; // idx 1, 2, ... + // bundle file = branch node + } else { + return null; // source file = leaf node + } + }, + true + ); + + if (!map.file) delete map.file; // skip optional field `file` + + return map; } // browser vs node.js -const b64enc = typeof btoa == 'function' ? btoa : b => Buffer.from(b).toString('base64'); -const b64dec = typeof atob == 'function' ? atob : a => Buffer.from(a, 'base64').toString(); +const b64enc = typeof btoa == 'function' ? btoa : (b) => Buffer.from(b).toString('base64'); +const b64dec = typeof atob == 'function' ? atob : (a) => Buffer.from(a, 'base64').toString(); function apply_preprocessor_sourcemap(filename, svelte_map, preprocessor_map_input) { - if (!svelte_map || !preprocessor_map_input) return svelte_map; - - const preprocessor_map = typeof preprocessor_map_input === 'string' ? JSON.parse(preprocessor_map_input) : preprocessor_map_input; - - const result_map = combine_sourcemaps( - filename, - [ - svelte_map , - preprocessor_map - ] - ) ; - - // Svelte expects a SourceMap which includes toUrl and toString. Instead of wrapping our output in a class, - // we just tack on the extra properties. - Object.defineProperties(result_map, { - toString: { - enumerable: false, - value: function toString() { - return JSON.stringify(this); - } - }, - toUrl: { - enumerable: false, - value: function toUrl() { - return 'data:application/json;charset=utf-8;base64,' + b64enc(this.toString()); - } - } - }); + if (!svelte_map || !preprocessor_map_input) return svelte_map; + + const preprocessor_map = typeof preprocessor_map_input === 'string' ? JSON.parse(preprocessor_map_input) : preprocessor_map_input; + + const result_map = combine_sourcemaps(filename, [svelte_map, preprocessor_map]); - return result_map ; + // Svelte expects a SourceMap which includes toUrl and toString. Instead of wrapping our output in a class, + // we just tack on the extra properties. + Object.defineProperties(result_map, { + toString: { + enumerable: false, + value: function toString() { + return JSON.stringify(this); + }, + }, + toUrl: { + enumerable: false, + value: function toUrl() { + return 'data:application/json;charset=utf-8;base64,' + b64enc(this.toString()); + }, + }, + }); + + return result_map; } // parse attached sourcemap in processed.code function parse_attached_sourcemap(processed, tag_name) { - const r_in = '[#@]\\s*sourceMappingURL\\s*=\\s*(\\S*)'; - const regex = (tag_name == 'script') - ? new RegExp('(?://'+r_in+')|(?:/\\*'+r_in+'\\s*\\*/)$') - : new RegExp('/\\*'+r_in+'\\s*\\*/$'); - function log_warning(message) { - // code_start: help to find preprocessor - const code_start = processed.code.length < 100 ? processed.code : (processed.code.slice(0, 100) + ' [...]'); - console.warn(`warning: ${message}. processed.code = ${JSON.stringify(code_start)}`); - } - processed.code = processed.code.replace(regex, (_, match1, match2) => { - const map_url = (tag_name == 'script') ? (match1 || match2) : match1; - const map_data = (map_url.match(/data:(?:application|text)\/json;(?:charset[:=]\S+?;)?base64,(\S*)/) || [])[1]; - if (map_data) { - // sourceMappingURL is data URL - if (processed.map) { - log_warning('Not implemented. ' + - 'Found sourcemap in both processed.code and processed.map. ' + - 'Please update your preprocessor to return only one sourcemap.'); - // ignore attached sourcemap - return ''; - } - processed.map = b64dec(map_data); // use attached sourcemap - return ''; // remove from processed.code - } - // sourceMappingURL is path or URL - if (!processed.map) { - log_warning(`Found sourcemap path ${JSON.stringify(map_url)} in processed.code, but no sourcemap data. ` + - 'Please update your preprocessor to return sourcemap data directly.'); - } - // ignore sourcemap path - return ''; // remove from processed.code - }); + const r_in = '[#@]\\s*sourceMappingURL\\s*=\\s*(\\S*)'; + const regex = tag_name == 'script' ? new RegExp('(?://' + r_in + ')|(?:/\\*' + r_in + '\\s*\\*/)$') : new RegExp('/\\*' + r_in + '\\s*\\*/$'); + function log_warning(message) { + // code_start: help to find preprocessor + const code_start = processed.code.length < 100 ? processed.code : processed.code.slice(0, 100) + ' [...]'; + console.warn(`warning: ${message}. processed.code = ${JSON.stringify(code_start)}`); + } + processed.code = processed.code.replace(regex, (_, match1, match2) => { + const map_url = tag_name == 'script' ? match1 || match2 : match1; + const map_data = (map_url.match(/data:(?:application|text)\/json;(?:charset[:=]\S+?;)?base64,(\S*)/) || [])[1]; + if (map_data) { + // sourceMappingURL is data URL + if (processed.map) { + log_warning('Not implemented. ' + 'Found sourcemap in both processed.code and processed.map. ' + 'Please update your preprocessor to return only one sourcemap.'); + // ignore attached sourcemap + return ''; + } + processed.map = b64dec(map_data); // use attached sourcemap + return ''; // remove from processed.code + } + // sourceMappingURL is path or URL + if (!processed.map) { + log_warning( + `Found sourcemap path ${JSON.stringify(map_url)} in processed.code, but no sourcemap data. ` + 'Please update your preprocessor to return sourcemap data directly.' + ); + } + // ignore sourcemap path + return ''; // remove from processed.code + }); } -function dom( - component, - options -) { - const { name } = component; +function dom(component, options) { + const { name } = component; - const renderer = new Renderer(component, options); - const { block } = renderer; + const renderer = new Renderer(component, options); + const { block } = renderer; - block.has_outro_method = true; + block.has_outro_method = true; - // prevent fragment being created twice (#1063) - if (options.customElement) block.chunks.create.push(b`this.c = @noop;`); + // prevent fragment being created twice (#1063) + if (options.customElement) block.chunks.create.push(b`this.c = @noop;`); - const body = []; + const body = []; - if (renderer.file_var) { - const file = component.file ? x`"${component.file}"` : x`undefined`; - body.push(b`const ${renderer.file_var} = ${file};`); - } + if (renderer.file_var) { + const file = component.file ? x`"${component.file}"` : x`undefined`; + body.push(b`const ${renderer.file_var} = ${file};`); + } - const css = component.stylesheet.render(options.filename, !options.customElement); + const css = component.stylesheet.render(options.filename, !options.customElement); - css.map = apply_preprocessor_sourcemap(options.filename, css.map, options.sourcemap ); + css.map = apply_preprocessor_sourcemap(options.filename, css.map, options.sourcemap); - const styles = component.stylesheet.has_styles && options.dev - ? `${css.code}\n/*# sourceMappingURL=${css.map.toUrl()} */` - : css.code; + const styles = component.stylesheet.has_styles && options.dev ? `${css.code}\n/*# sourceMappingURL=${css.map.toUrl()} */` : css.code; - const add_css = component.get_unique_name('add_css'); + const add_css = component.get_unique_name('add_css'); - const should_add_css = ( - !options.customElement && - !!styles && - options.css !== false - ); + const should_add_css = !options.customElement && !!styles && options.css !== false; - if (should_add_css) { - body.push(b` + if (should_add_css) { + body.push(b` function ${add_css}() { var style = @element("style"); style.id = "${component.stylesheet.id}-style"; @@ -15513,365 +14358,357 @@ function dom( @append(@_document.head, style); } `); - } - - // fix order - // TODO the deconflicted names of blocks are reversed... should set them here - const blocks = renderer.blocks.slice().reverse(); - - body.push(...blocks.map(block => { - // TODO this is a horrible mess — renderer.blocks - // contains a mixture of Blocks and Nodes - if ((block ).render) return (block ).render(); - return block; - })); - - if (options.dev && !options.hydratable) { - block.chunks.claim.push( - b`throw new @_Error("options.hydrate only works if the component was compiled with the \`hydratable: true\` option");` - ); - } - - const uses_slots = component.var_lookup.has('$$slots'); - let compute_slots; - if (uses_slots) { - compute_slots = b` - const $$slots = @compute_slots(#slots); - `; - } + } + // fix order + // TODO the deconflicted names of blocks are reversed... should set them here + const blocks = renderer.blocks.slice().reverse(); + + body.push( + ...blocks.map((block) => { + // TODO this is a horrible mess — renderer.blocks + // contains a mixture of Blocks and Nodes + if (block.render) return block.render(); + return block; + }) + ); + + if (options.dev && !options.hydratable) { + block.chunks.claim.push(b`throw new @_Error("options.hydrate only works if the component was compiled with the \`hydratable: true\` option");`); + } - const uses_props = component.var_lookup.has('$$props'); - const uses_rest = component.var_lookup.has('$$restProps'); - const $$props = uses_props || uses_rest ? '$$new_props' : '$$props'; - const props = component.vars.filter(variable => !variable.module && variable.export_name); - const writable_props = props.filter(variable => variable.writable); + const uses_slots = component.var_lookup.has('$$slots'); + let compute_slots; + if (uses_slots) { + compute_slots = b` + const $$slots = @compute_slots(#slots); + `; + } - const omit_props_names = component.get_unique_name('omit_props_names'); - const compute_rest = x`@compute_rest_props($$props, ${omit_props_names.name})`; - const rest = uses_rest ? b` - const ${omit_props_names.name} = [${props.map(prop => `"${prop.export_name}"`).join(',')}]; + const uses_props = component.var_lookup.has('$$props'); + const uses_rest = component.var_lookup.has('$$restProps'); + const $$props = uses_props || uses_rest ? '$$new_props' : '$$props'; + const props = component.vars.filter((variable) => !variable.module && variable.export_name); + const writable_props = props.filter((variable) => variable.writable); + + const omit_props_names = component.get_unique_name('omit_props_names'); + const compute_rest = x`@compute_rest_props($$props, ${omit_props_names.name})`; + const rest = uses_rest + ? b` + const ${omit_props_names.name} = [${props.map((prop) => `"${prop.export_name}"`).join(',')}]; let $$restProps = ${compute_rest}; - ` : null; + ` + : null; - const set = (uses_props || uses_rest || writable_props.length > 0 || component.slots.size > 0) - ? x` + const set = + uses_props || uses_rest || writable_props.length > 0 || component.slots.size > 0 + ? x` ${$$props} => { ${uses_props && renderer.invalidate('$$props', x`$$props = @assign(@assign({}, $$props), @exclude_internal_props($$new_props))`)} ${uses_rest && !uses_props && x`$$props = @assign(@assign({}, $$props), @exclude_internal_props($$new_props))`} ${uses_rest && renderer.invalidate('$$restProps', x`$$restProps = ${compute_rest}`)} - ${writable_props.map(prop => - b`if ('${prop.export_name}' in ${$$props}) ${renderer.invalidate(prop.name, x`${prop.name} = ${$$props}.${prop.export_name}`)};` - )} - ${component.slots.size > 0 && - b`if ('$$scope' in ${$$props}) ${renderer.invalidate('$$scope', x`$$scope = ${$$props}.$$scope`)};`} + ${writable_props.map((prop) => b`if ('${prop.export_name}' in ${$$props}) ${renderer.invalidate(prop.name, x`${prop.name} = ${$$props}.${prop.export_name}`)};`)} + ${component.slots.size > 0 && b`if ('$$scope' in ${$$props}) ${renderer.invalidate('$$scope', x`$$scope = ${$$props}.$$scope`)};`} } ` - : null; + : null; - const accessors = []; + const accessors = []; - const not_equal = component.component_options.immutable ? x`@not_equal` : x`@safe_not_equal`; - let dev_props_check; - let inject_state; - let capture_state; - let props_inject; + const not_equal = component.component_options.immutable ? x`@not_equal` : x`@safe_not_equal`; + let dev_props_check; + let inject_state; + let capture_state; + let props_inject; - props.forEach(prop => { - const variable = component.var_lookup.get(prop.name); + props.forEach((prop) => { + const variable = component.var_lookup.get(prop.name); - if (!variable.writable || component.component_options.accessors) { - accessors.push({ - type: 'MethodDefinition', - kind: 'get', - key: { type: 'Identifier', name: prop.export_name }, - value: x`function() { + if (!variable.writable || component.component_options.accessors) { + accessors.push({ + type: 'MethodDefinition', + kind: 'get', + key: { type: 'Identifier', name: prop.export_name }, + value: x`function() { return ${prop.hoistable ? prop.name : x`this.$$.ctx[${renderer.context_lookup.get(prop.name).index}]`} - }` - }); - } else if (component.compile_options.dev) { - accessors.push({ - type: 'MethodDefinition', - kind: 'get', - key: { type: 'Identifier', name: prop.export_name }, - value: x`function() { + }`, + }); + } else if (component.compile_options.dev) { + accessors.push({ + type: 'MethodDefinition', + kind: 'get', + key: { type: 'Identifier', name: prop.export_name }, + value: x`function() { throw new @_Error("<${component.tag}>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"); - }` - }); - } + }`, + }); + } - if (component.component_options.accessors) { - if (variable.writable && !renderer.readonly.has(prop.name)) { - accessors.push({ - type: 'MethodDefinition', - kind: 'set', - key: { type: 'Identifier', name: prop.export_name }, - value: x`function(${prop.name}) { + if (component.component_options.accessors) { + if (variable.writable && !renderer.readonly.has(prop.name)) { + accessors.push({ + type: 'MethodDefinition', + kind: 'set', + key: { type: 'Identifier', name: prop.export_name }, + value: x`function(${prop.name}) { this.$set({ ${prop.export_name}: ${prop.name} }); @flush(); - }` - }); - } else if (component.compile_options.dev) { - accessors.push({ - type: 'MethodDefinition', - kind: 'set', - key: { type: 'Identifier', name: prop.export_name }, - value: x`function(value) { + }`, + }); + } else if (component.compile_options.dev) { + accessors.push({ + type: 'MethodDefinition', + kind: 'set', + key: { type: 'Identifier', name: prop.export_name }, + value: x`function(value) { throw new @_Error("<${component.tag}>: Cannot set read-only property '${prop.export_name}'"); - }` - }); - } - } else if (component.compile_options.dev) { - accessors.push({ - type: 'MethodDefinition', - kind: 'set', - key: { type: 'Identifier', name: prop.export_name }, - value: x`function(value) { + }`, + }); + } + } else if (component.compile_options.dev) { + accessors.push({ + type: 'MethodDefinition', + kind: 'set', + key: { type: 'Identifier', name: prop.export_name }, + value: x`function(value) { throw new @_Error("<${component.tag}>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"); - }` - }); - } - }); + }`, + }); + } + }); - if (component.compile_options.dev) { - // checking that expected ones were passed - const expected = props.filter(prop => prop.writable && !prop.initialised); + if (component.compile_options.dev) { + // checking that expected ones were passed + const expected = props.filter((prop) => prop.writable && !prop.initialised); - if (expected.length) { - dev_props_check = b` + if (expected.length) { + dev_props_check = b` const { ctx: #ctx } = this.$$; const props = ${options.customElement ? x`this.attributes` : x`options.props || {}`}; - ${expected.map(prop => b` + ${expected.map( + (prop) => b` if (${renderer.reference(prop.name)} === undefined && !('${prop.export_name}' in props)) { @_console.warn("<${component.tag}> was created without expected prop '${prop.export_name}'"); - }`)} + }` + )} `; - } + } - const capturable_vars = component.vars.filter(v => !v.internal && !v.global && !v.name.startsWith('$$')); + const capturable_vars = component.vars.filter((v) => !v.internal && !v.global && !v.name.startsWith('$$')); - if (capturable_vars.length > 0) { - capture_state = x`() => ({ ${capturable_vars.map(prop => p`${prop.name}`)} })`; - } + if (capturable_vars.length > 0) { + capture_state = x`() => ({ ${capturable_vars.map((prop) => p`${prop.name}`)} })`; + } - const injectable_vars = capturable_vars.filter(v => !v.module && v.writable && v.name[0] !== '$'); + const injectable_vars = capturable_vars.filter((v) => !v.module && v.writable && v.name[0] !== '$'); - if (uses_props || injectable_vars.length > 0) { - inject_state = x` + if (uses_props || injectable_vars.length > 0) { + inject_state = x` ${$$props} => { ${uses_props && renderer.invalidate('$$props', x`$$props = @assign(@assign({}, $$props), $$new_props)`)} - ${injectable_vars.map( - v => b`if ('${v.name}' in $$props) ${renderer.invalidate(v.name, x`${v.name} = ${$$props}.${v.name}`)};` - )} + ${injectable_vars.map((v) => b`if ('${v.name}' in $$props) ${renderer.invalidate(v.name, x`${v.name} = ${$$props}.${v.name}`)};`)} } `; - props_inject = b` + props_inject = b` if ($$props && "$$inject" in $$props) { $$self.$inject_state($$props.$$inject); } `; - } - } + } + } - // instrument assignments - if (component.ast.instance) { - let scope = component.instance_scope; - const map = component.instance_scope_map; - let execution_context = null; + // instrument assignments + if (component.ast.instance) { + let scope = component.instance_scope; + const map = component.instance_scope_map; + let execution_context = null; - walk(component.ast.instance.content, { - enter(node) { - if (map.has(node)) { - scope = map.get(node) ; + walk(component.ast.instance.content, { + enter(node) { + if (map.has(node)) { + scope = map.get(node); - if (!execution_context && !scope.block) { - execution_context = node; - } - } else if (!execution_context && node.type === 'LabeledStatement' && node.label.name === '$') { - execution_context = node; - } - }, + if (!execution_context && !scope.block) { + execution_context = node; + } + } else if (!execution_context && node.type === 'LabeledStatement' && node.label.name === '$') { + execution_context = node; + } + }, - leave(node) { - if (map.has(node)) { - scope = scope.parent; - } + leave(node) { + if (map.has(node)) { + scope = scope.parent; + } - if (execution_context === node) { - execution_context = null; - } + if (execution_context === node) { + execution_context = null; + } - if (node.type === 'AssignmentExpression' || node.type === 'UpdateExpression') { - const assignee = node.type === 'AssignmentExpression' ? node.left : node.argument; + if (node.type === 'AssignmentExpression' || node.type === 'UpdateExpression') { + const assignee = node.type === 'AssignmentExpression' ? node.left : node.argument; - // 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(assignee)); + // 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(assignee)); - this.replace(invalidate(renderer, scope, node, names, execution_context === null)); - } - } - }); + this.replace(invalidate(renderer, scope, node, names, execution_context === null)); + } + }, + }); - component.rewrite_props(({ name, reassigned, export_name }) => { - const value = `$${name}`; - const i = renderer.context_lookup.get(`$${name}`).index; + component.rewrite_props(({ name, reassigned, export_name }) => { + const value = `$${name}`; + const i = renderer.context_lookup.get(`$${name}`).index; - const insert = (reassigned || export_name) - ? b`${`$$subscribe_${name}`}()` - : b`@component_subscribe($$self, ${name}, #value => $$invalidate(${i}, ${value} = #value))`; + const insert = reassigned || export_name ? b`${`$$subscribe_${name}`}()` : b`@component_subscribe($$self, ${name}, #value => $$invalidate(${i}, ${value} = #value))`; - if (component.compile_options.dev) { - return b`@validate_store(${name}, '${name}'); ${insert}`; - } + if (component.compile_options.dev) { + return b`@validate_store(${name}, '${name}'); ${insert}`; + } - return insert; - }); - } - - const args = [x`$$self`]; - const has_invalidate = props.length > 0 || - component.has_reactive_assignments || - component.slots.size > 0 || - capture_state || - inject_state; - if (has_invalidate) { - args.push(x`$$props`, x`$$invalidate`); - } else if (component.compile_options.dev) { - // $$props arg is still needed for unknown prop check - args.push(x`$$props`); - } - - const has_create_fragment = component.compile_options.dev || block.has_content(); - if (has_create_fragment) { - body.push(b` + return insert; + }); + } + + const args = [x`$$self`]; + const has_invalidate = props.length > 0 || component.has_reactive_assignments || component.slots.size > 0 || capture_state || inject_state; + if (has_invalidate) { + args.push(x`$$props`, x`$$invalidate`); + } else if (component.compile_options.dev) { + // $$props arg is still needed for unknown prop check + args.push(x`$$props`); + } + + const has_create_fragment = component.compile_options.dev || block.has_content(); + if (has_create_fragment) { + body.push(b` function create_fragment(#ctx) { ${block.get_contents()} } `); - } + } - body.push(b` + body.push(b` ${component.extract_javascript(component.ast.module)} ${component.fully_hoisted} `); - const filtered_props = props.filter(prop => { - const variable = component.var_lookup.get(prop.name); - - if (variable.hoistable) return false; - return prop.name[0] !== '$'; - }); - - const reactive_stores = component.vars.filter(variable => variable.name[0] === '$' && variable.name[1] !== '$'); - - const instance_javascript = component.extract_javascript(component.ast.instance); - - const has_definition = ( - component.compile_options.dev || - (instance_javascript && instance_javascript.length > 0) || - filtered_props.length > 0 || - uses_props || - component.partly_hoisted.length > 0 || - renderer.initial_context.length > 0 || - component.reactive_declarations.length > 0 || - capture_state || - inject_state - ); - - const definition = has_definition - ? component.alias('instance') - : { type: 'Literal', value: null }; - - const reactive_store_subscriptions = reactive_stores - .filter(store => { - const variable = component.var_lookup.get(store.name.slice(1)); - return !variable || variable.hoistable; - }) - .map(({ name }) => b` + const filtered_props = props.filter((prop) => { + const variable = component.var_lookup.get(prop.name); + + if (variable.hoistable) return false; + return prop.name[0] !== '$'; + }); + + const reactive_stores = component.vars.filter((variable) => variable.name[0] === '$' && variable.name[1] !== '$'); + + const instance_javascript = component.extract_javascript(component.ast.instance); + + const has_definition = + component.compile_options.dev || + (instance_javascript && instance_javascript.length > 0) || + filtered_props.length > 0 || + uses_props || + component.partly_hoisted.length > 0 || + renderer.initial_context.length > 0 || + component.reactive_declarations.length > 0 || + capture_state || + inject_state; + + const definition = has_definition ? component.alias('instance') : { type: 'Literal', value: null }; + + const reactive_store_subscriptions = reactive_stores + .filter((store) => { + const variable = component.var_lookup.get(store.name.slice(1)); + return !variable || variable.hoistable; + }) + .map( + ({ name }) => b` ${component.compile_options.dev && b`@validate_store(${name.slice(1)}, '${name.slice(1)}');`} @component_subscribe($$self, ${name.slice(1)}, $$value => $$invalidate(${renderer.context_lookup.get(name).index}, ${name} = $$value)); - `); + ` + ); - const resubscribable_reactive_store_unsubscribers = reactive_stores - .filter(store => { - const variable = component.var_lookup.get(store.name.slice(1)); - return variable && (variable.reassigned || variable.export_name); - }) - .map(({ name }) => b`$$self.$$.on_destroy.push(() => ${`$$unsubscribe_${name.slice(1)}`}());`); + const resubscribable_reactive_store_unsubscribers = reactive_stores + .filter((store) => { + const variable = component.var_lookup.get(store.name.slice(1)); + return variable && (variable.reassigned || variable.export_name); + }) + .map(({ name }) => b`$$self.$$.on_destroy.push(() => ${`$$unsubscribe_${name.slice(1)}`}());`); - if (has_definition) { - const reactive_declarations = []; - const fixed_reactive_declarations = []; // not really 'reactive' but whatever + if (has_definition) { + const reactive_declarations = []; + const fixed_reactive_declarations = []; // not really 'reactive' but whatever - component.reactive_declarations.forEach(d => { - const dependencies = Array.from(d.dependencies); - const uses_rest_or_props = !!dependencies.find(n => n === '$$props' || n === '$$restProps'); + component.reactive_declarations.forEach((d) => { + const dependencies = Array.from(d.dependencies); + const uses_rest_or_props = !!dependencies.find((n) => n === '$$props' || n === '$$restProps'); - const writable = dependencies.filter(n => { - const variable = component.var_lookup.get(n); - return variable && (variable.export_name || variable.mutated || variable.reassigned); - }); + const writable = dependencies.filter((n) => { + const variable = component.var_lookup.get(n); + return variable && (variable.export_name || variable.mutated || variable.reassigned); + }); - const condition = !uses_rest_or_props && writable.length > 0 && renderer.dirty(writable, true); + const condition = !uses_rest_or_props && writable.length > 0 && renderer.dirty(writable, true); - let statement = d.node; // TODO remove label (use d.node.body) if it's not referenced + let statement = d.node; // TODO remove label (use d.node.body) if it's not referenced - if (condition) statement = b`if (${condition}) { ${statement} }`[0] ; + if (condition) statement = b`if (${condition}) { ${statement} }`[0]; - if (condition || uses_rest_or_props) { - reactive_declarations.push(statement); - } else { - fixed_reactive_declarations.push(statement); - } - }); + if (condition || uses_rest_or_props) { + reactive_declarations.push(statement); + } else { + fixed_reactive_declarations.push(statement); + } + }); - const injected = Array.from(component.injected_reactive_declaration_vars).filter(name => { - const variable = component.var_lookup.get(name); - return variable.injected && variable.name[0] !== '$'; - }); + const injected = Array.from(component.injected_reactive_declaration_vars).filter((name) => { + const variable = component.var_lookup.get(name); + return variable.injected && variable.name[0] !== '$'; + }); - const reactive_store_declarations = reactive_stores.map(variable => { - const $name = variable.name; - const name = $name.slice(1); + const reactive_store_declarations = reactive_stores.map((variable) => { + const $name = variable.name; + const name = $name.slice(1); - const store = component.var_lookup.get(name); - if (store && (store.reassigned || store.export_name)) { - const unsubscribe = `$$unsubscribe_${name}`; - const subscribe = `$$subscribe_${name}`; - const i = renderer.context_lookup.get($name).index; + const store = component.var_lookup.get(name); + if (store && (store.reassigned || store.export_name)) { + const unsubscribe = `$$unsubscribe_${name}`; + const subscribe = `$$subscribe_${name}`; + const i = renderer.context_lookup.get($name).index; - return b`let ${$name}, ${unsubscribe} = @noop, ${subscribe} = () => (${unsubscribe}(), ${unsubscribe} = @subscribe(${name}, $$value => $$invalidate(${i}, ${$name} = $$value)), ${name})`; - } + return b`let ${$name}, ${unsubscribe} = @noop, ${subscribe} = () => (${unsubscribe}(), ${unsubscribe} = @subscribe(${name}, $$value => $$invalidate(${i}, ${$name} = $$value)), ${name})`; + } - return b`let ${$name};`; - }); + return b`let ${$name};`; + }); - let unknown_props_check; - if (component.compile_options.dev && !(uses_props || uses_rest)) { - unknown_props_check = b` - const writable_props = [${writable_props.map(prop => x`'${prop.export_name}'`)}]; + let unknown_props_check; + if (component.compile_options.dev && !(uses_props || uses_rest)) { + unknown_props_check = b` + const writable_props = [${writable_props.map((prop) => x`'${prop.export_name}'`)}]; @_Object.keys($$props).forEach(key => { if (!~writable_props.indexOf(key) && key.slice(0, 2) !== '$$') @_console.warn(\`<${component.tag}> was created with unknown prop '\${key}'\`); }); `; - } + } - const return_value = { - type: 'ArrayExpression', - elements: renderer.initial_context.map(member => ({ - type: 'Identifier', - name: member.name - }) ) - }; + const return_value = { + type: 'ArrayExpression', + elements: renderer.initial_context.map((member) => ({ + type: 'Identifier', + name: member.name, + })), + }; - body.push(b` + body.push(b` function ${definition}(${args}) { - ${injected.map(name => b`let ${name};`)} + ${injected.map((name) => b`let ${name};`)} ${rest} @@ -15882,14 +14719,14 @@ function dom( ${resubscribable_reactive_store_unsubscribers} ${component.slots.size || component.compile_options.dev || uses_slots ? b`let { $$slots: #slots = {}, $$scope } = $$props;` : null} - ${component.compile_options.dev && b`@validate_slots('${component.tag}', #slots, [${[...component.slots.keys()].map(key => `'${key}'`).join(',')}]);`} + ${component.compile_options.dev && b`@validate_slots('${component.tag}', #slots, [${[...component.slots.keys()].map((key) => `'${key}'`).join(',')}]);`} ${compute_slots} ${instance_javascript} ${unknown_props_check} - ${renderer.binding_groups.size > 0 && b`const $$binding_groups = [${[...renderer.binding_groups.keys()].map(_ => x`[]`)}];`} + ${renderer.binding_groups.size > 0 && b`const $$binding_groups = [${[...renderer.binding_groups.keys()].map((_) => x`[]`)}];`} ${component.partly_hoisted} @@ -15901,11 +14738,14 @@ function dom( ${/* before reactive declarations */ props_inject} - ${reactive_declarations.length > 0 && b` + ${ + reactive_declarations.length > 0 && + b` $$self.$$.update = () => { ${reactive_declarations} }; - `} + ` + } ${fixed_reactive_declarations} @@ -15914,35 +14754,36 @@ function dom( return ${return_value}; } `); - } - - const prop_indexes = x`{ - ${props.filter(v => v.export_name && !v.module).map(v => p`${v.export_name}: ${renderer.context_lookup.get(v.name).index}`)} - }` ; + } - let dirty; - if (renderer.context_overflow) { - dirty = x`[]`; - for (let i = 0; i < renderer.context.length; i += 31) { - dirty.elements.push(x`-1`); - } - } + const prop_indexes = x`{ + ${props.filter((v) => v.export_name && !v.module).map((v) => p`${v.export_name}: ${renderer.context_lookup.get(v.name).index}`)} + }`; - if (options.customElement) { + let dirty; + if (renderer.context_overflow) { + dirty = x`[]`; + for (let i = 0; i < renderer.context.length; i += 31) { + dirty.elements.push(x`-1`); + } + } - let init_props = x`@attribute_to_object(this.attributes)`; - if (uses_slots) { - init_props = x`{ ...${init_props}, $$slots: @get_custom_elements_slots(this) }`; - } + if (options.customElement) { + let init_props = x`@attribute_to_object(this.attributes)`; + if (uses_slots) { + init_props = x`{ ...${init_props}, $$slots: @get_custom_elements_slots(this) }`; + } - const declaration = b` + const declaration = b` class ${name} extends @SvelteElement { constructor(options) { super(); ${css.code && b`this.shadowRoot.innerHTML = \`<style>${css.code.replace(/\\/g, '\\\\')}${options.dev ? `\n/*# sourceMappingURL=${css.map.toUrl()} */` : ''}</style>\`;`} - @init(this, { target: this.shadowRoot, props: ${init_props}, customElement: true }, ${definition}, ${has_create_fragment ? 'create_fragment' : 'null'}, ${not_equal}, ${prop_indexes}, ${dirty}); + @init(this, { target: this.shadowRoot, props: ${init_props}, customElement: true }, ${definition}, ${ + has_create_fragment ? 'create_fragment' : 'null' + }, ${not_equal}, ${prop_indexes}, ${dirty}); ${dev_props_check} @@ -15951,45 +14792,48 @@ function dom( @insert(options.target, this, options.anchor); } - ${(props.length > 0 || uses_props || uses_rest) && b` + ${ + (props.length > 0 || uses_props || uses_rest) && + b` if (options.props) { this.$set(options.props); @flush(); - }`} + }` + } } } } - `[0] ; - - if (props.length > 0) { - declaration.body.body.push({ - type: 'MethodDefinition', - kind: 'get', - static: true, - computed: false, - key: { type: 'Identifier', name: 'observedAttributes' }, - value: x`function() { - return [${props.map(prop => x`"${prop.export_name}"`)}]; - }` - }); - } + `[0]; + + if (props.length > 0) { + declaration.body.body.push({ + type: 'MethodDefinition', + kind: 'get', + static: true, + computed: false, + key: { type: 'Identifier', name: 'observedAttributes' }, + value: x`function() { + return [${props.map((prop) => x`"${prop.export_name}"`)}]; + }`, + }); + } - declaration.body.body.push(...accessors); + declaration.body.body.push(...accessors); - body.push(declaration); + body.push(declaration); - if (component.tag != null) { - body.push(b` + if (component.tag != null) { + body.push(b` @_customElements.define("${component.tag}", ${name}); `); - } - } else { - const superclass = { - type: 'Identifier', - name: options.dev ? '@SvelteComponentDev' : '@SvelteComponent' - }; + } + } else { + const superclass = { + type: 'Identifier', + name: options.dev ? '@SvelteComponentDev' : '@SvelteComponent', + }; - const declaration = b` + const declaration = b` class ${name} extends ${superclass} { constructor(options) { super(${options.dev && 'options'}); @@ -16000,39 +14844,39 @@ function dom( ${dev_props_check} } } - `[0] ; + `[0]; - declaration.body.body.push(...accessors); + declaration.body.body.push(...accessors); - body.push(declaration); - } + body.push(declaration); + } - return { js: flatten$1(body, []), css }; + return { js: flatten$1(body, []), css }; } function flatten$1(nodes, target) { - for (let i = 0; i < nodes.length; i += 1) { - const node = nodes[i]; - if (Array.isArray(node)) { - flatten$1(node, target); - } else { - target.push(node); - } - } + for (let i = 0; i < nodes.length; i += 1) { + const node = nodes[i]; + if (Array.isArray(node)) { + flatten$1(node, target); + } else { + target.push(node); + } + } - return target; + return target; } function AwaitBlock(node, renderer, options) { - renderer.push(); - renderer.render(node.pending.children, options); - const pending = renderer.pop(); + renderer.push(); + renderer.render(node.pending.children, options); + const pending = renderer.pop(); - renderer.push(); - renderer.render(node.then.children, options); - const then = renderer.pop(); + renderer.push(); + renderer.render(node.then.children, options); + const then = renderer.pop(); - renderer.add_expression(x` + renderer.add_expression(x` function(__value) { if (@is_promise(__value)) return ${pending}; return (function(${node.then_node ? node.then_node : ''}) { return ${then}; }(__value)); @@ -16041,3028 +14885,2815 @@ function AwaitBlock(node, renderer, options) { } function Comment(_node, _renderer, _options) { - // TODO preserve comments - - // if (options.preserveComments) { - // renderer.append(`<!--${node.data}-->`); - // } + // TODO preserve comments + // if (options.preserveComments) { + // renderer.append(`<!--${node.data}-->`); + // } } function DebugTag(node, renderer, options) { - if (!options.dev) return; + if (!options.dev) return; - const filename = options.filename || null; - const { line, column } = options.locate(node.start + 1); + const filename = options.filename || null; + const { line, column } = options.locate(node.start + 1); - const obj = x`{ - ${node.expressions.map(e => p`${(e.node ).name}`)} + const obj = x`{ + ${node.expressions.map((e) => p`${e.node.name}`)} }`; - renderer.add_expression(x`@debug(${filename ? x`"${filename}"` : x`null`}, ${line - 1}, ${column}, ${obj})`); + renderer.add_expression(x`@debug(${filename ? x`"${filename}"` : x`null`}, ${line - 1}, ${column}, ${obj})`); } function EachBlock(node, renderer, options) { - const args = [node.context_node]; - if (node.index) args.push({ type: 'Identifier', name: node.index }); + const args = [node.context_node]; + if (node.index) args.push({ type: 'Identifier', name: node.index }); - renderer.push(); - renderer.render(node.children, options); - const result = renderer.pop(); + renderer.push(); + renderer.render(node.children, options); + const result = renderer.pop(); - const consequent = x`@each(${node.expression.node}, (${args}) => ${result})`; + const consequent = x`@each(${node.expression.node}, (${args}) => ${result})`; - if (node.else) { - renderer.push(); - renderer.render(node.else.children, options); - const alternate = renderer.pop(); + if (node.else) { + renderer.push(); + renderer.render(node.else.children, options); + const alternate = renderer.pop(); - renderer.add_expression(x`${node.expression.node}.length ? ${consequent} : ${alternate}`); - } else { - renderer.add_expression(consequent); - } + renderer.add_expression(x`${node.expression.node}.length ? ${consequent} : ${alternate}`); + } else { + renderer.add_expression(consequent); + } } function get_class_attribute_value(attribute) { - // handle special case — `class={possiblyUndefined}` with scoped CSS - if (attribute.chunks.length === 2 && (attribute.chunks[1] ).synthetic) { - const value = (attribute.chunks[0] ).node; - return x`@escape(@null_to_empty(${value})) + "${(attribute.chunks[1] ).data}"`; - } + // handle special case — `class={possiblyUndefined}` with scoped CSS + if (attribute.chunks.length === 2 && attribute.chunks[1].synthetic) { + const value = attribute.chunks[0].node; + return x`@escape(@null_to_empty(${value})) + "${attribute.chunks[1].data}"`; + } - return get_attribute_value(attribute); + return get_attribute_value(attribute); } function get_attribute_value(attribute) { - if (attribute.chunks.length === 0) return x`""`; + if (attribute.chunks.length === 0) return x`""`; - return attribute.chunks - .map((chunk) => { - return chunk.type === 'Text' - ? string_literal(chunk.data.replace(/"/g, '"')) - : x`@escape(${chunk.node})`; - }) - .reduce((lhs, rhs) => x`${lhs} + ${rhs}`); + return attribute.chunks + .map((chunk) => { + return chunk.type === 'Text' ? string_literal(chunk.data.replace(/"/g, '"')) : x`@escape(${chunk.node})`; + }) + .reduce((lhs, rhs) => x`${lhs} + ${rhs}`); } // source: https://html.spec.whatwg.org/multipage/indices.html const boolean_attributes = new Set([ - 'allowfullscreen', - 'allowpaymentrequest', - 'async', - 'autofocus', - 'autoplay', - 'checked', - 'controls', - 'default', - 'defer', - 'disabled', - 'formnovalidate', - 'hidden', - 'ismap', - 'loop', - 'multiple', - 'muted', - 'nomodule', - 'novalidate', - 'open', - 'playsinline', - 'readonly', - 'required', - 'reversed', - 'selected' + 'allowfullscreen', + 'allowpaymentrequest', + 'async', + 'autofocus', + 'autoplay', + 'checked', + 'controls', + 'default', + 'defer', + 'disabled', + 'formnovalidate', + 'hidden', + 'ismap', + 'loop', + 'multiple', + 'muted', + 'nomodule', + 'novalidate', + 'open', + 'playsinline', + 'readonly', + 'required', + 'reversed', + 'selected', ]); // similar logic from `compile/render_dom/wrappers/Fragment` // We want to remove trailing whitespace inside an element/component/block, // *unless* there is no whitespace between this node and its next sibling function remove_whitespace_children(children, next) { - const nodes = []; - let last_child; - let i = children.length; - while (i--) { - const child = children[i]; - - if (child.type === 'Text') { - if (child.should_skip()) { - continue; - } + const nodes = []; + let last_child; + let i = children.length; + while (i--) { + const child = children[i]; + + if (child.type === 'Text') { + if (child.should_skip()) { + continue; + } - let { data } = child; + let { data } = child; - if (nodes.length === 0) { - const should_trim = next - ? next.type === 'Text' && - /^\s/.test(next.data) && - trimmable_at$1(child, next) - : !child.has_ancestor('EachBlock'); + if (nodes.length === 0) { + const should_trim = next ? next.type === 'Text' && /^\s/.test(next.data) && trimmable_at$1(child, next) : !child.has_ancestor('EachBlock'); - if (should_trim) { - data = trim_end(data); - if (!data) continue; - } - } + if (should_trim) { + data = trim_end(data); + if (!data) continue; + } + } - // glue text nodes (which could e.g. be separated by comments) together - if (last_child && last_child.type === 'Text') { - last_child.data = data + last_child.data; - continue; - } + // glue text nodes (which could e.g. be separated by comments) together + if (last_child && last_child.type === 'Text') { + last_child.data = data + last_child.data; + continue; + } - nodes.unshift(child); - link(last_child, last_child = child); - } else { - nodes.unshift(child); - link(last_child, last_child = child); - } - } + nodes.unshift(child); + link(last_child, (last_child = child)); + } else { + nodes.unshift(child); + link(last_child, (last_child = child)); + } + } - const first = nodes[0]; - if (first && first.type === 'Text') { - first.data = trim_start(first.data); - if (!first.data) { - first.var = null; - nodes.shift(); + const first = nodes[0]; + if (first && first.type === 'Text') { + first.data = trim_start(first.data); + if (!first.data) { + first.var = null; + nodes.shift(); - if (nodes[0]) { - nodes[0].prev = null; - } - } - } + if (nodes[0]) { + nodes[0].prev = null; + } + } + } - return nodes; + return nodes; } function trimmable_at$1(child, next_sibling) { - // Whitespace is trimmable if one of the following is true: - // The child and its sibling share a common nearest each block (not at an each block boundary) - // The next sibling's previous node is an each block - return ( - next_sibling.find_nearest(/EachBlock/) === - child.find_nearest(/EachBlock/) || next_sibling.prev.type === 'EachBlock' - ); + // Whitespace is trimmable if one of the following is true: + // The child and its sibling share a common nearest each block (not at an each block boundary) + // The next sibling's previous node is an each block + return next_sibling.find_nearest(/EachBlock/) === child.find_nearest(/EachBlock/) || next_sibling.prev.type === 'EachBlock'; } function Element(node, renderer, options) { + const children = remove_whitespace_children(node.children, node.next); - const children = remove_whitespace_children(node.children, node.next); - - // awkward special case - let node_contents; - - const contenteditable = ( - node.name !== 'textarea' && - node.name !== 'input' && - node.attributes.some((attribute) => attribute.name === 'contenteditable') - ); - - renderer.add_string(`<${node.name}`); - - const class_expression_list = node.classes.map(class_directive => { - const { expression, name } = class_directive; - const snippet = expression ? expression.node : x`#ctx.${name}`; // TODO is this right? - return x`${snippet} ? "${name}" : ""`; - }); - if (node.needs_manual_style_scoping) { - class_expression_list.push(x`"${node.component.stylesheet.id}"`); - } - const class_expression = - class_expression_list.length > 0 && - class_expression_list.reduce((lhs, rhs) => x`${lhs} + ' ' + ${rhs}`); - - if (node.attributes.some(attr => attr.is_spread)) { - // TODO dry this out - const args = []; - node.attributes.forEach(attribute => { - if (attribute.is_spread) { - args.push(attribute.expression.node); - } else { - const name = attribute.name.toLowerCase(); - if (name === 'value' && node.name.toLowerCase() === 'textarea') { - node_contents = get_attribute_value(attribute); - } else if (attribute.is_true) { - args.push(x`{ ${attribute.name}: true }`); - } else if ( - boolean_attributes.has(name) && - attribute.chunks.length === 1 && - attribute.chunks[0].type !== 'Text' - ) { - // a boolean attribute with one non-Text chunk - args.push(x`{ ${attribute.name}: ${(attribute.chunks[0] ).node} || null }`); - } else { - args.push(x`{ ${attribute.name}: ${get_attribute_value(attribute)} }`); - } - } - }); + // awkward special case + let node_contents; - renderer.add_expression(x`@spread([${args}], ${class_expression})`); - } else { - let add_class_attribute = !!class_expression; - node.attributes.forEach(attribute => { - const name = attribute.name.toLowerCase(); - if (name === 'value' && node.name.toLowerCase() === 'textarea') { - node_contents = get_attribute_value(attribute); - } else if (attribute.is_true) { - renderer.add_string(` ${attribute.name}`); - } else if ( - boolean_attributes.has(name) && - attribute.chunks.length === 1 && - attribute.chunks[0].type !== 'Text' - ) { - // a boolean attribute with one non-Text chunk - renderer.add_string(' '); - renderer.add_expression(x`${(attribute.chunks[0] ).node} ? "${attribute.name}" : ""`); - } else if (name === 'class' && class_expression) { - add_class_attribute = false; - renderer.add_string(` ${attribute.name}="`); - renderer.add_expression(x`[${get_class_attribute_value(attribute)}, ${class_expression}].join(' ').trim()`); - renderer.add_string('"'); - } else if (attribute.chunks.length === 1 && attribute.chunks[0].type !== 'Text') { - const snippet = (attribute.chunks[0] ).node; - renderer.add_expression(x`@add_attribute("${attribute.name}", ${snippet}, ${boolean_attributes.has(name) ? 1 : 0})`); - } else { - renderer.add_string(` ${attribute.name}="`); - renderer.add_expression((name === 'class' ? get_class_attribute_value : get_attribute_value)(attribute)); - renderer.add_string('"'); - } - }); - if (add_class_attribute) { - renderer.add_expression(x`@add_classes([${class_expression}].join(' ').trim())`); - } - } + const contenteditable = node.name !== 'textarea' && node.name !== 'input' && node.attributes.some((attribute) => attribute.name === 'contenteditable'); - node.bindings.forEach(binding => { - const { name, expression } = binding; + renderer.add_string(`<${node.name}`); - if (binding.is_readonly) { - return; - } + const class_expression_list = node.classes.map((class_directive) => { + const { expression, name } = class_directive; + const snippet = expression ? expression.node : x`#ctx.${name}`; // TODO is this right? + return x`${snippet} ? "${name}" : ""`; + }); + if (node.needs_manual_style_scoping) { + class_expression_list.push(x`"${node.component.stylesheet.id}"`); + } + const class_expression = class_expression_list.length > 0 && class_expression_list.reduce((lhs, rhs) => x`${lhs} + ' ' + ${rhs}`); + + if (node.attributes.some((attr) => attr.is_spread)) { + // TODO dry this out + const args = []; + node.attributes.forEach((attribute) => { + if (attribute.is_spread) { + args.push(attribute.expression.node); + } else { + const name = attribute.name.toLowerCase(); + if (name === 'value' && node.name.toLowerCase() === 'textarea') { + node_contents = get_attribute_value(attribute); + } else if (attribute.is_true) { + args.push(x`{ ${attribute.name}: true }`); + } else if (boolean_attributes.has(name) && attribute.chunks.length === 1 && attribute.chunks[0].type !== 'Text') { + // a boolean attribute with one non-Text chunk + args.push(x`{ ${attribute.name}: ${attribute.chunks[0].node} || null }`); + } else { + args.push(x`{ ${attribute.name}: ${get_attribute_value(attribute)} }`); + } + } + }); - if (name === 'group') ; else if (contenteditable && (name === 'textContent' || name === 'innerHTML')) { - node_contents = expression.node; - - // TODO where was this used? - // value = name === 'textContent' ? x`@escape($$value)` : x`$$value`; - } else if (binding.name === 'value' && node.name === 'textarea') { - const snippet = expression.node; - node_contents = x`${snippet} || ""`; - } else { - const snippet = expression.node; - renderer.add_expression(x`@add_attribute("${name}", ${snippet}, 1)`); - } - }); + renderer.add_expression(x`@spread([${args}], ${class_expression})`); + } else { + let add_class_attribute = !!class_expression; + node.attributes.forEach((attribute) => { + const name = attribute.name.toLowerCase(); + if (name === 'value' && node.name.toLowerCase() === 'textarea') { + node_contents = get_attribute_value(attribute); + } else if (attribute.is_true) { + renderer.add_string(` ${attribute.name}`); + } else if (boolean_attributes.has(name) && attribute.chunks.length === 1 && attribute.chunks[0].type !== 'Text') { + // a boolean attribute with one non-Text chunk + renderer.add_string(' '); + renderer.add_expression(x`${attribute.chunks[0].node} ? "${attribute.name}" : ""`); + } else if (name === 'class' && class_expression) { + add_class_attribute = false; + renderer.add_string(` ${attribute.name}="`); + renderer.add_expression(x`[${get_class_attribute_value(attribute)}, ${class_expression}].join(' ').trim()`); + renderer.add_string('"'); + } else if (attribute.chunks.length === 1 && attribute.chunks[0].type !== 'Text') { + const snippet = attribute.chunks[0].node; + renderer.add_expression(x`@add_attribute("${attribute.name}", ${snippet}, ${boolean_attributes.has(name) ? 1 : 0})`); + } else { + renderer.add_string(` ${attribute.name}="`); + renderer.add_expression((name === 'class' ? get_class_attribute_value : get_attribute_value)(attribute)); + renderer.add_string('"'); + } + }); + if (add_class_attribute) { + renderer.add_expression(x`@add_classes([${class_expression}].join(' ').trim())`); + } + } + + node.bindings.forEach((binding) => { + const { name, expression } = binding; - if (options.hydratable && options.head_id) { - renderer.add_string(` data-svelte="${options.head_id}"`); - } + if (binding.is_readonly) { + return; + } - renderer.add_string('>'); + if (name === 'group'); + else if (contenteditable && (name === 'textContent' || name === 'innerHTML')) { + node_contents = expression.node; + + // TODO where was this used? + // value = name === 'textContent' ? x`@escape($$value)` : x`$$value`; + } else if (binding.name === 'value' && node.name === 'textarea') { + const snippet = expression.node; + node_contents = x`${snippet} || ""`; + } else { + const snippet = expression.node; + renderer.add_expression(x`@add_attribute("${name}", ${snippet}, 1)`); + } + }); - if (node_contents !== undefined) { - if (contenteditable) { - renderer.push(); - renderer.render(children, options); - const result = renderer.pop(); + if (options.hydratable && options.head_id) { + renderer.add_string(` data-svelte="${options.head_id}"`); + } - renderer.add_expression(x`($$value => $$value === void 0 ? ${result} : $$value)(${node_contents})`); - } else { - renderer.add_expression(node_contents); - } + renderer.add_string('>'); - if (!is_void(node.name)) { - renderer.add_string(`</${node.name}>`); - } - } else { - renderer.render(children, options); + if (node_contents !== undefined) { + if (contenteditable) { + renderer.push(); + renderer.render(children, options); + const result = renderer.pop(); - if (!is_void(node.name)) { - renderer.add_string(`</${node.name}>`); - } - } + renderer.add_expression(x`($$value => $$value === void 0 ? ${result} : $$value)(${node_contents})`); + } else { + renderer.add_expression(node_contents); + } + + if (!is_void(node.name)) { + renderer.add_string(`</${node.name}>`); + } + } else { + renderer.render(children, options); + + if (!is_void(node.name)) { + renderer.add_string(`</${node.name}>`); + } + } } function Head(node, renderer, options) { - const head_options = { - ...options, - head_id: node.id - }; + const head_options = { + ...options, + head_id: node.id, + }; - renderer.push(); - renderer.render(node.children, head_options); - const result = renderer.pop(); + renderer.push(); + renderer.render(node.children, head_options); + const result = renderer.pop(); - renderer.add_expression(x`$$result.head += ${result}, ""`); + renderer.add_expression(x`$$result.head += ${result}, ""`); } function HtmlTag(node, renderer, _options) { - renderer.add_expression(node.expression.node ); + renderer.add_expression(node.expression.node); } function IfBlock(node, renderer, options) { - const condition = node.expression.node; + const condition = node.expression.node; - renderer.push(); - renderer.render(node.children, options); - const consequent = renderer.pop(); + renderer.push(); + renderer.render(node.children, options); + const consequent = renderer.pop(); - renderer.push(); - if (node.else) renderer.render(node.else.children, options); - const alternate = renderer.pop(); + renderer.push(); + if (node.else) renderer.render(node.else.children, options); + const alternate = renderer.pop(); - renderer.add_expression(x`${condition} ? ${consequent} : ${alternate}`); + renderer.add_expression(x`${condition} ? ${consequent} : ${alternate}`); } function get_prop_value(attribute) { - if (attribute.is_true) return x`true`; - if (attribute.chunks.length === 0) return x`''`; + if (attribute.is_true) return x`true`; + if (attribute.chunks.length === 0) return x`''`; - return attribute.chunks - .map(chunk => { - if (chunk.type === 'Text') return string_literal(chunk.data); - return chunk.node; - }) - .reduce((lhs, rhs) => x`${lhs} + ${rhs}`); + return attribute.chunks + .map((chunk) => { + if (chunk.type === 'Text') return string_literal(chunk.data); + return chunk.node; + }) + .reduce((lhs, rhs) => x`${lhs} + ${rhs}`); } function InlineComponent(node, renderer, options) { - const binding_props = []; - const binding_fns = []; + const binding_props = []; + const binding_fns = []; - node.bindings.forEach(binding => { - renderer.has_bindings = true; + node.bindings.forEach((binding) => { + renderer.has_bindings = true; - // TODO this probably won't work for contextual bindings - const snippet = binding.expression.node; + // TODO this probably won't work for contextual bindings + const snippet = binding.expression.node; - binding_props.push(p`${binding.name}: ${snippet}`); - binding_fns.push(p`${binding.name}: $$value => { ${snippet} = $$value; $$settled = false }`); - }); + binding_props.push(p`${binding.name}: ${snippet}`); + binding_fns.push(p`${binding.name}: $$value => { ${snippet} = $$value; $$settled = false }`); + }); - const uses_spread = node.attributes.find(attr => attr.is_spread); + const uses_spread = node.attributes.find((attr) => attr.is_spread); - let props; + let props; - if (uses_spread) { - props = x`@_Object.assign(${ - node.attributes - .map(attribute => { - if (attribute.is_spread) { - return attribute.expression.node; - } else { - return x`{ ${attribute.name}: ${get_prop_value(attribute)} }`; - } - }) - .concat(binding_props.map(p => x`{ ${p} }`)) - })`; - } else { - props = x`{ - ${node.attributes.map(attribute => p`${attribute.name}: ${get_prop_value(attribute)}`)}, + if (uses_spread) { + props = x`@_Object.assign(${node.attributes + .map((attribute) => { + if (attribute.is_spread) { + return attribute.expression.node; + } else { + return x`{ ${attribute.name}: ${get_prop_value(attribute)} }`; + } + }) + .concat(binding_props.map((p) => x`{ ${p} }`))})`; + } else { + props = x`{ + ${node.attributes.map((attribute) => p`${attribute.name}: ${get_prop_value(attribute)}`)}, ${binding_props} }`; - } + } - const bindings = x`{ + const bindings = x`{ ${binding_fns} }`; - const expression = ( - node.name === 'svelte:self' - ? renderer.name - : node.name === 'svelte:component' - ? x`(${node.expression.node}) || @missing_component` - : node.name.split('.').reduce(((lhs, rhs) => x`${lhs}.${rhs}`) ) - ); + const expression = + node.name === 'svelte:self' + ? renderer.name + : node.name === 'svelte:component' + ? x`(${node.expression.node}) || @missing_component` + : node.name.split('.').reduce((lhs, rhs) => x`${lhs}.${rhs}`); - const slot_fns = []; + const slot_fns = []; - const children = node.children; + const children = node.children; - if (children.length) { - const slot_scopes = new Map(); + if (children.length) { + const slot_scopes = new Map(); - renderer.render(children, Object.assign({}, options, { - slot_scopes - })); + renderer.render( + children, + Object.assign({}, options, { + slot_scopes, + }) + ); - slot_scopes.forEach(({ input, output }, name) => { - slot_fns.push( - p`${name}: (${input}) => ${output}` - ); - }); - } + slot_scopes.forEach(({ input, output }, name) => { + slot_fns.push(p`${name}: (${input}) => ${output}`); + }); + } - const slots = x`{ + const slots = x`{ ${slot_fns} }`; - renderer.add_expression(x`@validate_component(${expression}, "${node.name}").$$render($$result, ${props}, ${bindings}, ${slots})`); + renderer.add_expression(x`@validate_component(${expression}, "${node.name}").$$render($$result, ${props}, ${bindings}, ${slots})`); } function KeyBlock(node, renderer, options) { - renderer.render(node.children, options); + renderer.render(node.children, options); } function get_slot_scope(lets) { - if (lets.length === 0) return null; - - return { - type: 'ObjectPattern', - properties: lets.map(l => { - return { - type: 'Property', - kind: 'init', - method: false, - shorthand: false, - computed: false, - key: l.name, - value: l.value || l.name - }; - }) - }; -} - -function Slot(node, renderer, options - -) { - const slot_data = get_slot_data(node.values); - const slot = node.get_static_attribute_value('slot'); - const nearest_inline_component = node.find_nearest(/InlineComponent/); - - if (slot && nearest_inline_component) { - renderer.push(); - } - - renderer.push(); - renderer.render(node.children, options); - const result = renderer.pop(); - - renderer.add_expression(x` + if (lets.length === 0) return null; + + return { + type: 'ObjectPattern', + properties: lets.map((l) => { + return { + type: 'Property', + kind: 'init', + method: false, + shorthand: false, + computed: false, + key: l.name, + value: l.value || l.name, + }; + }), + }; +} + +function Slot(node, renderer, options) { + const slot_data = get_slot_data(node.values); + const slot = node.get_static_attribute_value('slot'); + const nearest_inline_component = node.find_nearest(/InlineComponent/); + + if (slot && nearest_inline_component) { + renderer.push(); + } + + renderer.push(); + renderer.render(node.children, options); + const result = renderer.pop(); + + renderer.add_expression(x` #slots.${node.slot_name} ? #slots.${node.slot_name}(${slot_data}) : ${result} `); - if (slot && nearest_inline_component) { - const lets = node.lets; - const seen = new Set(lets.map(l => l.name.name)); + if (slot && nearest_inline_component) { + const lets = node.lets; + const seen = new Set(lets.map((l) => l.name.name)); - nearest_inline_component.lets.forEach(l => { - if (!seen.has(l.name.name)) lets.push(l); - }); - options.slot_scopes.set(slot, { - input: get_slot_scope(node.lets), - output: renderer.pop() - }); - } + nearest_inline_component.lets.forEach((l) => { + if (!seen.has(l.name.name)) lets.push(l); + }); + options.slot_scopes.set(slot, { + input: get_slot_scope(node.lets), + output: renderer.pop(), + }); + } } class AbstractBlock extends Node { - - - - constructor(component, parent, scope, info) { - super(component, parent, scope, info); - } + constructor(component, parent, scope, info) { + super(component, parent, scope, info); + } - warn_if_empty_block() { - if (!this.children || this.children.length > 1) return; + warn_if_empty_block() { + if (!this.children || this.children.length > 1) return; - const child = this.children[0]; + const child = this.children[0]; - if (!child || (child.type === 'Text' && !/[^ \r\n\f\v\t]/.test(child.data))) { - this.component.warn(this, { - code: 'empty-block', - message: 'Empty block' - }); - } - } + if (!child || (child.type === 'Text' && !/[^ \r\n\f\v\t]/.test(child.data))) { + this.component.warn(this, { + code: 'empty-block', + message: 'Empty block', + }); + } + } } class PendingBlock extends AbstractBlock { - - constructor(component, parent, scope, info) { - super(component, parent, scope, info); - this.children = map_children(component, parent, scope, info.children); + 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(); - } - } + if (!info.skip) { + this.warn_if_empty_block(); + } + } } class ThenBlock extends AbstractBlock { - - - - constructor(component, parent, scope, info) { - super(component, parent, scope, info); - - this.scope = scope.child(); - if (parent.then_node) { - parent.then_contexts.forEach(context => { - this.scope.add(context.key.name, parent.expression.dependencies, this); - }); - } - this.children = map_children(component, parent, this.scope, info.children); + constructor(component, parent, scope, info) { + super(component, parent, scope, info); + + this.scope = scope.child(); + if (parent.then_node) { + parent.then_contexts.forEach((context) => { + this.scope.add(context.key.name, parent.expression.dependencies, this); + }); + } + this.children = map_children(component, parent, this.scope, info.children); - if (!info.skip) { - this.warn_if_empty_block(); - } - } + if (!info.skip) { + this.warn_if_empty_block(); + } + } } class CatchBlock extends AbstractBlock { - - - - constructor(component, parent, scope, info) { - super(component, parent, scope, info); - - this.scope = scope.child(); - if (parent.catch_node) { - parent.catch_contexts.forEach(context => { - this.scope.add(context.key.name, parent.expression.dependencies, this); - }); - } - this.children = map_children(component, parent, this.scope, info.children); + constructor(component, parent, scope, info) { + super(component, parent, scope, info); + + this.scope = scope.child(); + if (parent.catch_node) { + parent.catch_contexts.forEach((context) => { + this.scope.add(context.key.name, parent.expression.dependencies, this); + }); + } + this.children = map_children(component, parent, this.scope, info.children); - if (!info.skip) { - this.warn_if_empty_block(); - } - } + if (!info.skip) { + this.warn_if_empty_block(); + } + } } -function unpack_destructuring(contexts, node, modifier = node => node, default_modifier = node => node) { - if (!node) return; +function unpack_destructuring(contexts, node, modifier = (node) => node, default_modifier = (node) => node) { + if (!node) return; - if (node.type === 'Identifier') { - contexts.push({ - key: node , - modifier, - default_modifier - }); - } else if (node.type === 'RestElement') { - contexts.push({ - key: node.argument , - modifier, - default_modifier - }); - } else if (node.type === 'ArrayPattern') { - node.elements.forEach((element, i) => { - if (element && element.type === 'RestElement') { - unpack_destructuring(contexts, element, node => x`${modifier(node)}.slice(${i})` , default_modifier); - } else if (element && element.type === 'AssignmentPattern') { - const n = contexts.length; - - unpack_destructuring(contexts, element.left, node => x`${modifier(node)}[${i}]`, (node, to_ctx) => x`${node} !== undefined ? ${node} : ${update_reference(contexts, n, element.right, to_ctx)}` ); - } else { - unpack_destructuring(contexts, element, node => x`${modifier(node)}[${i}]` , default_modifier); - } - }); - } else if (node.type === 'ObjectPattern') { - const used_properties = []; - - node.properties.forEach((property) => { - if (property.type === 'RestElement') { - unpack_destructuring( - contexts, - property.argument, - node => x`@object_without_properties(${modifier(node)}, [${used_properties}])` , - default_modifier - ); - } else { - const key = property.key ; - const value = property.value; - - used_properties.push(x`"${key.name}"`); - if (value.type === 'AssignmentPattern') { - const n = contexts.length; - - unpack_destructuring(contexts, value.left, node => x`${modifier(node)}.${key.name}`, (node, to_ctx) => x`${node} !== undefined ? ${node} : ${update_reference(contexts, n, value.right, to_ctx)}` ); - } else { - unpack_destructuring(contexts, value, node => x`${modifier(node)}.${key.name}` , default_modifier); - } - } - }); - } -} - -function update_reference(contexts, n, expression, to_ctx) { - const find_from_context = (node) => { - for (let i = n; i < contexts.length; i++) { - const { key } = contexts[i]; - 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 = JSON.parse(JSON.stringify(expression)) ; - walk(expression, { - enter(node, parent) { - if (isReference(node, parent)) { - this.replace(find_from_context(node )); - this.skip(); - } - } - }); + if (node.type === 'Identifier') { + contexts.push({ + key: node, + modifier, + default_modifier, + }); + } else if (node.type === 'RestElement') { + contexts.push({ + key: node.argument, + modifier, + default_modifier, + }); + } else if (node.type === 'ArrayPattern') { + node.elements.forEach((element, i) => { + if (element && element.type === 'RestElement') { + unpack_destructuring(contexts, element, (node) => x`${modifier(node)}.slice(${i})`, default_modifier); + } else if (element && element.type === 'AssignmentPattern') { + const n = contexts.length; + + unpack_destructuring( + contexts, + element.left, + (node) => x`${modifier(node)}[${i}]`, + (node, to_ctx) => x`${node} !== undefined ? ${node} : ${update_reference(contexts, n, element.right, to_ctx)}` + ); + } else { + unpack_destructuring(contexts, element, (node) => x`${modifier(node)}[${i}]`, default_modifier); + } + }); + } else if (node.type === 'ObjectPattern') { + const used_properties = []; - return expression; + node.properties.forEach((property) => { + if (property.type === 'RestElement') { + unpack_destructuring(contexts, property.argument, (node) => x`@object_without_properties(${modifier(node)}, [${used_properties}])`, default_modifier); + } else { + const key = property.key; + const value = property.value; + + used_properties.push(x`"${key.name}"`); + if (value.type === 'AssignmentPattern') { + const n = contexts.length; + + unpack_destructuring( + contexts, + value.left, + (node) => x`${modifier(node)}.${key.name}`, + (node, to_ctx) => x`${node} !== undefined ? ${node} : ${update_reference(contexts, n, value.right, to_ctx)}` + ); + } else { + unpack_destructuring(contexts, value, (node) => x`${modifier(node)}.${key.name}`, default_modifier); + } + } + }); + } } -class AwaitBlock$1 extends Node { - - +function update_reference(contexts, n, expression, to_ctx) { + const find_from_context = (node) => { + for (let i = n; i < contexts.length; i++) { + const { key } = contexts[i]; + 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 = JSON.parse(JSON.stringify(expression)); + walk(expression, { + enter(node, parent) { + if (isReference(node, parent)) { + this.replace(find_from_context(node)); + this.skip(); + } + }, + }); - - - + return expression; +} - constructor(component, parent, scope, info) { - super(component, parent, scope, info); +class AwaitBlock$1 extends Node { + constructor(component, parent, scope, info) { + super(component, parent, scope, info); - this.expression = new Expression(component, this, scope, info.expression); + this.expression = new Expression(component, this, scope, info.expression); - this.then_node = info.value; - this.catch_node = info.error; + this.then_node = info.value; + this.catch_node = info.error; - if (this.then_node) { - this.then_contexts = []; - unpack_destructuring(this.then_contexts, info.value); - } + if (this.then_node) { + this.then_contexts = []; + unpack_destructuring(this.then_contexts, info.value); + } - if (this.catch_node) { - this.catch_contexts = []; - unpack_destructuring(this.catch_contexts, info.error); - } + if (this.catch_node) { + this.catch_contexts = []; + unpack_destructuring(this.catch_contexts, info.error); + } - 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); - } + 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); + } } class EventHandler extends Node { - - - - - - __init() {this.uses_context = false;} - __init2() {this.can_make_passive = false;} - - constructor(component, parent, template_scope, info) { - super(component, parent, template_scope, info);EventHandler.prototype.__init.call(this);EventHandler.prototype.__init2.call(this); - 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 (/FunctionExpression/.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 => (d.id ).name === info.expression.name); - node = declarator && declarator.init; - } + __init() { + this.uses_context = false; + } + __init2() { + this.can_make_passive = false; + } - 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`); - } - } + constructor(component, parent, template_scope, info) { + super(component, parent, template_scope, info); + EventHandler.prototype.__init.call(this); + EventHandler.prototype.__init2.call(this); + 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 (/FunctionExpression/.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) => d.id.name === info.expression.name); + node = declarator && declarator.init; + } - get reassigned() { - if (!this.expression) { - return false; - } - const node = this.expression.node; + 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`); + } + } - if (/FunctionExpression/.test(node.type)) { - return false; - } + get reassigned() { + if (!this.expression) { + return false; + } + const node = this.expression.node; + + if (/FunctionExpression/.test(node.type)) { + return false; + } - return this.expression.dynamic_dependencies().length > 0; - } + return this.expression.dynamic_dependencies().length > 0; + } } class Body extends Node { - - - - constructor(component, parent, scope, info) { - super(component, parent, scope, info); + constructor(component, parent, scope, info) { + super(component, parent, scope, info); - this.handlers = []; + this.handlers = []; - info.attributes.forEach((node) => { - if (node.type === 'EventHandler') { - this.handlers.push(new EventHandler(component, this, scope, node)); - } - }); - } + info.attributes.forEach((node) => { + if (node.type === 'EventHandler') { + this.handlers.push(new EventHandler(component, this, scope, node)); + } + }); + } } const pattern = /^\s*svelte-ignore\s+([\s\S]+)\s*$/m; class Comment$1 extends Node { - - - - - constructor(component, parent, scope, info) { - super(component, parent, scope, info); - this.data = info.data; - - const match = pattern.exec(this.data); - this.ignores = match ? match[1].split(/[^\S]/).map(x => x.trim()).filter(Boolean) : []; - } + constructor(component, parent, scope, info) { + super(component, parent, scope, info); + this.data = info.data; + + const match = pattern.exec(this.data); + this.ignores = match + ? match[1] + .split(/[^\S]/) + .map((x) => x.trim()) + .filter(Boolean) + : []; + } } class ElseBlock extends AbstractBlock { - - - constructor(component, parent, scope, info) { - super(component, parent, scope, info); - this.children = map_children(component, this, scope, info.children); + constructor(component, parent, scope, info) { + super(component, parent, scope, info); + this.children = map_children(component, this, scope, info.children); - this.warn_if_empty_block(); - } + this.warn_if_empty_block(); + } } class EachBlock$1 extends AbstractBlock { - + __init() { + this.has_binding = false; + } + __init2() { + this.has_index_binding = false; + } - - + constructor(component, parent, scope, info) { + super(component, parent, scope, info); + EachBlock$1.prototype.__init.call(this); + EachBlock$1.prototype.__init2.call(this); + 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; - - - - - - - - __init() {this.has_binding = false;} - __init2() {this.has_index_binding = false;} + this.scope = scope.child(); - + this.contexts = []; + unpack_destructuring(this.contexts, info.context); - constructor(component, parent, scope, info) { - super(component, parent, scope, info);EachBlock$1.prototype.__init.call(this);EachBlock$1.prototype.__init2.call(this); - 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.contexts.forEach((context) => { + this.scope.add(context.key.name, this.expression.dependencies, this); + }); - this.scope = scope.child(); + 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.contexts = []; - unpack_destructuring(this.contexts, info.context); + this.key = info.key ? new Expression(component, this, this.scope, info.key) : null; - this.contexts.forEach(context => { - this.scope.add(context.key.name, this.expression.dependencies, this); - }); + this.has_animation = false; - 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.children = map_children(component, this, this.scope, info.children); - this.key = info.key - ? new Expression(component, this, this.scope, info.key) - : null; + if (this.has_animation) { + if (this.children.length !== 1) { + const child = this.children.find((child) => !!child.animation); + component.error(child.animation, { + code: 'invalid-animation', + message: 'An element that uses the animate directive must be the sole child of a keyed each block', + }); + } + } - this.has_animation = false; + this.warn_if_empty_block(); - this.children = map_children(component, this, this.scope, info.children); + this.else = info.else ? new ElseBlock(component, this, this.scope, info.else) : null; + } +} - if (this.has_animation) { - if (this.children.length !== 1) { - const child = this.children.find(child => !!(child ).animation); - component.error((child ).animation, { - code: 'invalid-animation', - message: 'An element that uses the animate directive must be the sole child of a keyed each block' - }); - } - } +class Attribute extends Node { + constructor(component, parent, scope, info) { + super(component, parent, scope, info); + this.scope = scope; - this.warn_if_empty_block(); + if (info.type === 'Spread') { + this.name = null; + this.is_spread = true; + this.is_true = false; - this.else = info.else - ? new ElseBlock(component, this, this.scope, info.else) - : null; - } -} + this.expression = new Expression(component, this, scope, info.expression); + this.dependencies = this.expression.dependencies; + this.chunks = null; -class Attribute extends Node { - - - - - - - - - - - - - - - - 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; - }); - } - } + this.is_static = false; + } else { + this.name = info.name; + this.is_true = info.value === true; + this.is_static = true; - get_dependencies() { - if (this.is_spread) return this.expression.dynamic_dependencies(); + this.dependencies = new Set(); - const dependencies = new Set(); - this.chunks.forEach(chunk => { - if (chunk.type === 'Expression') { - add_to_set(dependencies, chunk.dynamic_dependencies()); - } - }); + this.chunks = this.is_true + ? [] + : info.value.map((node) => { + if (node.type === 'Text') return node; - return Array.from(dependencies); - } + this.is_static = false; - get_value(block) { - if (this.is_true) return x`true`; - if (this.chunks.length === 0) return x`""`; + const expression = new Expression(component, this, scope, node.expression); - if (this.chunks.length === 1) { - return this.chunks[0].type === 'Text' - ? string_literal((this.chunks[0] ).data) - : (this.chunks[0] ).manipulate(block); - } + add_to_set(this.dependencies, expression.dependencies); + return expression; + }); + } + } - let expression = this.chunks - .map(chunk => chunk.type === 'Text' ? string_literal(chunk.data) : chunk.manipulate(block)) - .reduce((lhs, rhs) => x`${lhs} + ${rhs}`); + get_dependencies() { + if (this.is_spread) return this.expression.dynamic_dependencies(); - if (this.chunks[0].type !== 'Text') { - expression = x`"" + ${expression}`; - } + const dependencies = new Set(); + this.chunks.forEach((chunk) => { + if (chunk.type === 'Expression') { + add_to_set(dependencies, chunk.dynamic_dependencies()); + } + }); - return expression; - } + return Array.from(dependencies); + } + + get_value(block) { + if (this.is_true) return x`true`; + if (this.chunks.length === 0) return x`""`; - get_static_value() { - if (this.is_spread || this.dependencies.size > 0) return null; + if (this.chunks.length === 1) { + return this.chunks[0].type === 'Text' ? string_literal(this.chunks[0].data) : this.chunks[0].manipulate(block); + } - return this.is_true - ? true - : this.chunks[0] - // method should be called only when `is_static = true` - ? (this.chunks[0] ).data - : ''; - } + let expression = this.chunks.map((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}`; + } - 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; - } + return expression; + } + + get_static_value() { + if (this.is_spread || this.dependencies.size > 0) return null; + + return this.is_true + ? true + : this.chunks[0] + ? // method should be called only when `is_static = true` + 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; + } } // TODO this should live in a specific binding -const read_only_media_attributes = new Set([ - 'duration', - 'buffered', - 'seekable', - 'played', - 'seeking', - 'ended', - 'videoHeight', - 'videoWidth' -]); +const read_only_media_attributes = new Set(['duration', 'buffered', 'seekable', 'played', 'seeking', 'ended', 'videoHeight', 'videoWidth']); class Binding extends Node { - - - - // TODO exists only for bind:this — is there a more elegant solution? - - - - constructor(component, parent, scope, info) { - super(component, parent, scope, info); - - if (info.expression.type !== 'Identifier' && info.expression.type !== 'MemberExpression') { - component.error(info, { - code: 'invalid-directive-value', - message: 'Can only bind to an identifier (e.g. `foo`) or a member expression (e.g. `foo.bar` or `foo[baz]`)' - }); - } - - this.name = info.name; - this.expression = new Expression(component, this, scope, info.expression); - this.raw_expression = JSON.parse(JSON.stringify(info.expression)); + // TODO exists only for bind:this — is there a more elegant solution? - const { name } = get_object(this.expression.node); + constructor(component, parent, scope, info) { + super(component, parent, scope, info); - this.is_contextual = Array.from(this.expression.references).some(name => scope.names.has(name)); - - // make sure we track this as a mutable ref - if (scope.is_let(name)) { - component.error(this, { - code: 'invalid-binding', - message: 'Cannot bind to a variable declared with the let: directive' - }); - } else if (scope.names.has(name)) { - if (scope.is_await(name)) { - component.error(this, { - code: 'invalid-binding', - message: 'Cannot bind to a variable declared with {#await ... then} or {:catch} blocks' - }); - } + if (info.expression.type !== 'Identifier' && info.expression.type !== 'MemberExpression') { + component.error(info, { + code: 'invalid-directive-value', + message: 'Can only bind to an identifier (e.g. `foo`) or a member expression (e.g. `foo.bar` or `foo[baz]`)', + }); + } - 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); + this.name = info.name; + this.expression = new Expression(component, this, scope, info.expression); + this.raw_expression = JSON.parse(JSON.stringify(info.expression)); + + const { name } = get_object(this.expression.node); + + this.is_contextual = Array.from(this.expression.references).some((name) => scope.names.has(name)); + + // make sure we track this as a mutable ref + if (scope.is_let(name)) { + component.error(this, { + code: 'invalid-binding', + message: 'Cannot bind to a variable declared with the let: directive', + }); + } else if (scope.names.has(name)) { + if (scope.is_await(name)) { + component.error(this, { + code: 'invalid-binding', + message: 'Cannot bind to a variable declared with {#await ... then} or {:catch} blocks', + }); + } - if (!variable || variable.global) { - component.error(this.expression.node , { - code: 'binding-undeclared', - message: `${name} is not declared` - }); - } + 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(this.expression.node, { + code: 'binding-undeclared', + message: `${name} is not declared`, + }); + } - variable[this.expression.node.type === 'MemberExpression' ? 'mutated' : 'reassigned'] = true; + variable[this.expression.node.type === 'MemberExpression' ? 'mutated' : 'reassigned'] = true; - if (info.expression.type === 'Identifier' && !variable.writable) { - component.error(this.expression.node , { - code: 'invalid-binding', - message: 'Cannot bind to a variable which is not writable' - }); - } - } + if (info.expression.type === 'Identifier' && !variable.writable) { + component.error(this.expression.node, { + code: 'invalid-binding', + message: 'Cannot bind to a variable which is not writable', + }); + } + } - const type = parent.get_static_attribute_value('type'); + const type = parent.get_static_attribute_value('type'); - this.is_readonly = - dimensions.test(this.name) || - (isElement(parent) && - ((parent.is_media_node() && read_only_media_attributes.has(this.name)) || - (parent.name === 'input' && type === 'file')) /* TODO others? */); - } + this.is_readonly = + dimensions.test(this.name) || + (isElement(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); - } + is_readonly_media_attribute() { + return read_only_media_attributes.has(this.name); + } } function isElement(node) { - return !!(node ).is_media_node; + return !!node.is_media_node; } class Transition extends Node { - - - - - - - constructor(component, parent, scope, info) { - super(component, parent, scope, info); + constructor(component, parent, scope, info) { + super(component, parent, scope, info); - component.warn_if_undefined(info.name, info, scope); + component.warn_if_undefined(info.name, info, scope); - this.name = info.name; - component.add_reference(info.name.split('.')[0]); + this.name = info.name; + component.add_reference(info.name.split('.')[0]); - this.directive = info.intro && info.outro ? 'transition' : info.intro ? 'in' : 'out'; - this.is_local = info.modifiers.includes('local'); + this.directive = info.intro && info.outro ? 'transition' : info.intro ? 'in' : 'out'; + this.is_local = info.modifiers.includes('local'); - if ((info.intro && parent.intro) || (info.outro && parent.outro)) { - const parent_transition = (parent.intro || parent.outro); + if ((info.intro && parent.intro) || (info.outro && parent.outro)) { + const parent_transition = parent.intro || parent.outro; - const message = this.directive === parent_transition.directive - ? `An element can only have one '${this.directive}' directive` - : `An element cannot have both ${describe(parent_transition)} directive and ${describe(this)} directive`; + const message = + this.directive === parent_transition.directive + ? `An element can only have one '${this.directive}' directive` + : `An element cannot have both ${describe(parent_transition)} directive and ${describe(this)} directive`; - component.error(info, { - code: 'duplicate-transition', - message - }); - } + component.error(info, { + code: 'duplicate-transition', + message, + }); + } - this.expression = info.expression - ? new Expression(component, this, scope, info.expression) - : null; - } + this.expression = info.expression ? new Expression(component, this, scope, info.expression) : null; + } } function describe(transition) { - return transition.directive === 'transition' - ? "a 'transition'" - : `an '${transition.directive}'`; + return transition.directive === 'transition' ? "a 'transition'" : `an '${transition.directive}'`; } class Animation extends Node { - - - - - constructor(component, parent, scope, info) { - super(component, parent, scope, info); + constructor(component, parent, scope, info) { + super(component, parent, scope, info); - component.warn_if_undefined(info.name, info, scope); + component.warn_if_undefined(info.name, info, scope); - this.name = info.name; - component.add_reference(info.name.split('.')[0]); + this.name = info.name; + component.add_reference(info.name.split('.')[0]); - if (parent.animation) { - component.error(this, { - code: 'duplicate-animation', - message: "An element can only have one 'animate' directive" - }); - } + if (parent.animation) { + component.error(this, { + code: 'duplicate-animation', + message: "An element can only have one 'animate' directive", + }); + } - const block = parent.parent; - if (!block || block.type !== 'EachBlock' || !block.key) { - // TODO can we relax the 'immediate child' rule? - component.error(this, { - code: 'invalid-animation', - message: 'An element that uses the animate directive must be the immediate child of a keyed each block' - }); - } + const block = parent.parent; + if (!block || block.type !== 'EachBlock' || !block.key) { + // TODO can we relax the 'immediate child' rule? + component.error(this, { + code: 'invalid-animation', + message: 'An element that uses the animate directive must be the immediate child of a keyed each block', + }); + } - (block ).has_animation = true; + block.has_animation = true; - this.expression = info.expression - ? new Expression(component, this, scope, info.expression, true) - : null; - } + this.expression = info.expression ? new Expression(component, this, scope, info.expression, true) : null; + } } class Class extends Node { - - - - - constructor(component, parent, scope, info) { - super(component, parent, scope, info); + constructor(component, parent, scope, info) { + super(component, parent, scope, info); - this.name = info.name; + this.name = info.name; - this.expression = info.expression - ? new Expression(component, this, scope, info.expression) - : null; - } + this.expression = info.expression ? new Expression(component, this, scope, info.expression) : null; + } } // 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 elements_without_text = new Set(['audio', 'datalist', 'dl', 'optgroup', 'select', 'video']); class Text extends Node { - - - - - constructor(component, parent, scope, info) { - super(component, parent, scope, info); - this.data = info.data; - this.synthetic = info.synthetic || false; - } + constructor(component, parent, scope, info) { + super(component, parent, scope, info); + this.data = info.data; + this.synthetic = info.synthetic || false; + } - should_skip() { - if (/\S/.test(this.data)) return false; + should_skip() { + if (/\S/.test(this.data)) return false; - const parent_element = this.find_nearest(/(?:Element|InlineComponent|SlotTemplate|Head)/); - if (!parent_element) 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]; + 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 (/svg$/.test(parent_element.namespace)) { - if (this.prev && this.prev.type === 'Element' && this.prev.name === 'tspan') return false; - } + // svg namespace exclusions + if (/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); - } + return parent_element.namespace || elements_without_text.has(parent_element.name); + } } const applicable = new Set(['Identifier', 'ObjectExpression', 'ArrayExpression', 'Property']); class Let extends Node { - - - - __init() {this.names = [];} - - constructor(component, parent, scope, info) { - super(component, parent, scope, info);Let.prototype.__init.call(this); - this.name = { type: 'Identifier', name: info.name }; - - const { names } = this; - - if (info.expression) { - this.value = info.expression; - - walk(info.expression, { - enter(node) { - if (!applicable.has(node.type)) { - component.error(node , { - code: 'invalid-let', - message: 'let directive value must be an identifier or an object/array pattern' - }); - } + __init() { + this.names = []; + } - if (node.type === 'Identifier') { - names.push((node ).name); - } + constructor(component, parent, scope, info) { + super(component, parent, scope, info); + Let.prototype.__init.call(this); + this.name = { type: 'Identifier', name: info.name }; - // slightly unfortunate hack - if (node.type === 'ArrayExpression') { - node.type = 'ArrayPattern'; - } + const { names } = this; - if (node.type === 'ObjectExpression') { - node.type = 'ObjectPattern'; - } - } - }); - } else { - names.push(this.name.name); - } - } + if (info.expression) { + this.value = info.expression; + + walk(info.expression, { + enter(node) { + if (!applicable.has(node.type)) { + component.error(node, { + code: 'invalid-let', + message: 'let directive value must be an identifier or an object/array pattern', + }); + } + + if (node.type === 'Identifier') { + names.push(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); + } + } } const svg$1 = /^(?:altGlyph|altGlyphDef|altGlyphItem|animate|animateColor|animateMotion|animateTransform|circle|clipPath|color-profile|cursor|defs|desc|discard|ellipse|feBlend|feColorMatrix|feComponentTransfer|feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|feMergeNode|feMorphology|feOffset|fePointLight|feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|font|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|foreignObject|g|glyph|glyphRef|hatch|hatchpath|hkern|image|line|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|metadata|missing-glyph|mpath|path|pattern|polygon|polyline|radialGradient|rect|set|solidcolor|stop|svg|switch|symbol|text|textPath|tref|tspan|unknown|use|view|vkern)$/; -const aria_attributes = 'activedescendant atomic autocomplete busy checked colcount colindex colspan controls current describedby details disabled dropeffect errormessage expanded flowto grabbed haspopup hidden invalid keyshortcuts label labelledby level live modal multiline multiselectable orientation owns placeholder posinset pressed readonly relevant required roledescription rowcount rowindex rowspan selected setsize sort valuemax valuemin valuenow valuetext'.split(' '); +const aria_attributes = 'activedescendant atomic autocomplete busy checked colcount colindex colspan controls current describedby details disabled dropeffect errormessage expanded flowto grabbed haspopup hidden invalid keyshortcuts label labelledby level live modal multiline multiselectable orientation owns placeholder posinset pressed readonly relevant required roledescription rowcount rowindex rowspan selected setsize sort valuemax valuemin valuenow valuetext'.split( + ' ' +); const aria_attribute_set = new Set(aria_attributes); -const aria_roles = 'alert alertdialog application article banner blockquote button caption cell checkbox code columnheader combobox complementary contentinfo definition deletion dialog directory document emphasis feed figure form generic graphics-document graphics-object graphics-symbol grid gridcell group heading img link list listbox listitem log main marquee math meter menu menubar menuitem menuitemcheckbox menuitemradio navigation none note option paragraph presentation progressbar radio radiogroup region row rowgroup rowheader scrollbar search searchbox separator slider spinbutton status strong subscript superscript switch tab table tablist tabpanel term textbox time timer toolbar tooltip tree treegrid treeitem'.split(' '); +const aria_roles = 'alert alertdialog application article banner blockquote button caption cell checkbox code columnheader combobox complementary contentinfo definition deletion dialog directory document emphasis feed figure form generic graphics-document graphics-object graphics-symbol grid gridcell group heading img link list listbox listitem log main marquee math meter menu menubar menuitem menuitemcheckbox menuitemradio navigation none note option paragraph presentation progressbar radio radiogroup region row rowgroup rowheader scrollbar search searchbox separator slider spinbutton status strong subscript superscript switch tab table tablist tabpanel term textbox time timer toolbar tooltip tree treegrid treeitem'.split( + ' ' +); const aria_role_set = new Set(aria_roles); const a11y_required_attributes = { - a: ['href'], - area: ['alt', 'aria-label', 'aria-labelledby'], + a: ['href'], + area: ['alt', 'aria-label', 'aria-labelledby'], - // html-has-lang - html: ['lang'], + // html-has-lang + html: ['lang'], - // iframe-has-title - iframe: ['title'], - img: ['alt'], - object: ['title', 'aria-label', 'aria-labelledby'] + // iframe-has-title + iframe: ['title'], + img: ['alt'], + object: ['title', 'aria-label', 'aria-labelledby'], }; -const a11y_distracting_elements = new Set([ - 'blink', - 'marquee' -]); +const a11y_distracting_elements = new Set(['blink', 'marquee']); const a11y_required_content = new Set([ - // anchor-has-content - 'a', - - // heading-has-content - 'h1', - 'h2', - 'h3', - 'h4', - 'h5', - 'h6' + // anchor-has-content + 'a', + + // heading-has-content + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', ]); -const a11y_no_onchange = new Set([ - 'select', - 'option' -]); +const a11y_no_onchange = new Set(['select', 'option']); -const a11y_labelable = new Set([ - 'button', - 'input', - 'keygen', - 'meter', - 'output', - 'progress', - 'select', - 'textarea' -]); +const a11y_labelable = new Set(['button', 'input', 'keygen', 'meter', 'output', 'progress', 'select', 'textarea']); const invisible_elements = new Set(['meta', 'html', 'script', 'style']); -const valid_modifiers = new Set([ - 'preventDefault', - 'stopPropagation', - 'capture', - 'once', - 'passive', - 'nonpassive', - 'self' -]); +const valid_modifiers = new Set(['preventDefault', 'stopPropagation', 'capture', 'once', 'passive', 'nonpassive', 'self']); -const passive_events = new Set([ - 'wheel', - 'touchstart', - 'touchmove', - 'touchend', - 'touchcancel' -]); +const passive_events = new Set(['wheel', 'touchstart', 'touchmove', 'touchend', 'touchcancel']); const react_attributes = new Map([ - ['className', 'class'], - ['htmlFor', 'for'] + ['className', 'class'], + ['htmlFor', 'for'], ]); function get_namespace(parent, element, explicit_namespace) { - const parent_element = parent.find_nearest(/^Element/); + const parent_element = parent.find_nearest(/^Element/); - if (!parent_element) { - return explicit_namespace || (svg$1.test(element.name) - ? namespaces.svg - : null); - } + if (!parent_element) { + return explicit_namespace || (svg$1.test(element.name) ? namespaces.svg : null); + } - if (svg$1.test(element.name.toLowerCase())) return namespaces.svg; - if (parent_element.name.toLowerCase() === 'foreignobject') return null; + if (svg$1.test(element.name.toLowerCase())) return namespaces.svg; + if (parent_element.name.toLowerCase() === 'foreignobject') return null; - return parent_element.namespace; + return parent_element.namespace; } class Element$1 extends Node { - - - - __init() {this.attributes = [];} - __init2() {this.actions = [];} - __init3() {this.bindings = [];} - __init4() {this.classes = [];} - __init5() {this.handlers = [];} - __init6() {this.lets = [];} - __init7() {this.intro = null;} - __init8() {this.outro = null;} - __init9() {this.animation = null;} - - - - - constructor(component, parent, scope, info) { - super(component, parent, scope, info);Element$1.prototype.__init.call(this);Element$1.prototype.__init2.call(this);Element$1.prototype.__init3.call(this);Element$1.prototype.__init4.call(this);Element$1.prototype.__init5.call(this);Element$1.prototype.__init6.call(this);Element$1.prototype.__init7.call(this);Element$1.prototype.__init8.call(this);Element$1.prototype.__init9.call(this); this.name = info.name; - - this.namespace = get_namespace(parent , this, component.namespace); - - if (this.namespace !== namespaces.foreign) { - if (this.name === 'textarea') { - if (info.children.length > 0) { - const value_attribute = info.attributes.find(node => node.name === 'value'); - if (value_attribute) { - component.error(value_attribute, { - code: 'textarea-duplicate-value', - message: 'A <textarea> can have either a value attribute or (equivalently) child content, but not both' - }); - } + __init() { + this.attributes = []; + } + __init2() { + this.actions = []; + } + __init3() { + this.bindings = []; + } + __init4() { + this.classes = []; + } + __init5() { + this.handlers = []; + } + __init6() { + this.lets = []; + } + __init7() { + this.intro = null; + } + __init8() { + this.outro = null; + } + __init9() { + this.animation = null; + } - // this is an egregious hack, but it's the easiest way to get <textarea> - // children treated the same way as a value attribute - info.attributes.push({ - type: 'Attribute', - name: 'value', - value: info.children - }); + constructor(component, parent, scope, info) { + super(component, parent, scope, info); + Element$1.prototype.__init.call(this); + Element$1.prototype.__init2.call(this); + Element$1.prototype.__init3.call(this); + Element$1.prototype.__init4.call(this); + Element$1.prototype.__init5.call(this); + Element$1.prototype.__init6.call(this); + Element$1.prototype.__init7.call(this); + Element$1.prototype.__init8.call(this); + Element$1.prototype.__init9.call(this); + this.name = info.name; + + this.namespace = get_namespace(parent, this, component.namespace); + + if (this.namespace !== namespaces.foreign) { + if (this.name === 'textarea') { + if (info.children.length > 0) { + const value_attribute = info.attributes.find((node) => node.name === 'value'); + if (value_attribute) { + component.error(value_attribute, { + code: 'textarea-duplicate-value', + message: 'A <textarea> can have either a value attribute or (equivalently) child content, but not both', + }); + } - info.children = []; - } - } + // this is an egregious hack, but it's the easiest way to get <textarea> + // children treated the same way as a value attribute + info.attributes.push({ + type: 'Attribute', + name: 'value', + value: info.children, + }); - if (this.name === 'option') { - // Special case — treat these the same way: - // <option>{foo}</option> - // <option value={foo}>{foo}</option> - const value_attribute = info.attributes.find(attribute => attribute.name === 'value'); - - if (!value_attribute) { - info.attributes.push({ - type: 'Attribute', - name: 'value', - value: info.children, - synthetic: true - }); - } - } - } - const has_let = info.attributes.some(node => node.type === 'Let'); - if (has_let) { - scope = scope.child(); - } + info.children = []; + } + } - // Binding relies on Attribute, defer its evaluation - const order = ['Binding']; // everything else is -1 - info.attributes.sort((a, b) => order.indexOf(a.type) - order.indexOf(b.type)); + if (this.name === 'option') { + // Special case — treat these the same way: + // <option>{foo}</option> + // <option value={foo}>{foo}</option> + const value_attribute = info.attributes.find((attribute) => attribute.name === 'value'); + + if (!value_attribute) { + info.attributes.push({ + type: 'Attribute', + name: 'value', + value: info.children, + synthetic: true, + }); + } + } + } + const has_let = info.attributes.some((node) => node.type === 'Let'); + if (has_let) { + scope = scope.child(); + } - info.attributes.forEach(node => { - switch (node.type) { - case 'Action': - this.actions.push(new Action(component, this, scope, node)); - break; + // Binding relies on Attribute, defer its evaluation + const order = ['Binding']; // everything else is -1 + info.attributes.sort((a, b) => order.indexOf(a.type) - order.indexOf(b.type)); - case 'Attribute': - case 'Spread': - // special case - if (node.name === 'xmlns') this.namespace = node.value[0].data; + info.attributes.forEach((node) => { + switch (node.type) { + case 'Action': + this.actions.push(new Action(component, this, scope, node)); + break; - this.attributes.push(new Attribute(component, this, scope, node)); - break; + case 'Attribute': + case 'Spread': + // special case + if (node.name === 'xmlns') this.namespace = node.value[0].data; - case 'Binding': - this.bindings.push(new Binding(component, this, scope, node)); - break; + this.attributes.push(new Attribute(component, this, scope, node)); + break; - case 'Class': - this.classes.push(new Class(component, this, scope, node)); - break; + case 'Binding': + this.bindings.push(new Binding(component, this, scope, node)); + break; - case 'EventHandler': - this.handlers.push(new EventHandler(component, this, scope, node)); - break; + case 'Class': + this.classes.push(new Class(component, this, scope, node)); + break; - case 'Let': { - const l = new Let(component, this, scope, node); - this.lets.push(l); - const dependencies = new Set([l.name.name]); + case 'EventHandler': + this.handlers.push(new EventHandler(component, this, scope, node)); + break; - l.names.forEach(name => { - scope.add(name, dependencies, this); - }); - break; - } + case 'Let': { + const l = new Let(component, this, scope, node); + this.lets.push(l); + const dependencies = new Set([l.name.name]); - case 'Transition': - { - const transition = new Transition(component, this, scope, node); - if (node.intro) this.intro = transition; - if (node.outro) this.outro = transition; - break; - } + l.names.forEach((name) => { + scope.add(name, dependencies, this); + }); + break; + } - case 'Animation': - this.animation = new Animation(component, this, scope, node); - break; + case 'Transition': { + const transition = new Transition(component, this, scope, node); + if (node.intro) this.intro = transition; + if (node.outro) this.outro = transition; + break; + } - default: - throw new Error(`Not implemented: ${node.type}`); - } - }); + case 'Animation': + this.animation = new Animation(component, this, scope, node); + break; - this.scope = scope; - this.children = map_children(component, this, this.scope, info.children); + default: + throw new Error(`Not implemented: ${node.type}`); + } + }); - this.validate(); + this.scope = scope; + this.children = map_children(component, this, this.scope, info.children); - component.apply_stylesheet(this); - } + this.validate(); - validate() { - if (this.component.var_lookup.has(this.name) && this.component.var_lookup.get(this.name).imported) { - this.component.warn(this, { - code: 'component-name-lowercase', - message: `<${this.name}> will be treated as an HTML element unless it begins with a capital letter` - }); - } + component.apply_stylesheet(this); + } - this.validate_attributes(); - this.validate_event_handlers(); - if (this.namespace === namespaces.foreign) { - this.validate_bindings_foreign(); - } else { - this.validate_attributes_a11y(); - this.validate_special_cases(); - this.validate_bindings(); - this.validate_content(); - } + validate() { + if (this.component.var_lookup.has(this.name) && this.component.var_lookup.get(this.name).imported) { + this.component.warn(this, { + code: 'component-name-lowercase', + message: `<${this.name}> will be treated as an HTML element unless it begins with a capital letter`, + }); + } - } + this.validate_attributes(); + this.validate_event_handlers(); + if (this.namespace === namespaces.foreign) { + this.validate_bindings_foreign(); + } else { + this.validate_attributes_a11y(); + this.validate_special_cases(); + this.validate_bindings(); + this.validate_content(); + } + } - validate_attributes() { - const { component, parent } = this; + validate_attributes() { + const { component, parent } = this; - this.attributes.forEach(attribute => { - if (attribute.is_spread) return; + this.attributes.forEach((attribute) => { + if (attribute.is_spread) return; - const name = attribute.name.toLowerCase(); + const name = attribute.name.toLowerCase(); - // Errors + // Errors - if (/(^[0-9-.])|[\^$@%&#?!|()[\]{}^*+~;]/.test(name)) { - component.error(attribute, { - code: 'illegal-attribute', - message: `'${name}' is not a valid attribute name` - }); - } + if (/(^[0-9-.])|[\^$@%&#?!|()[\]{}^*+~;]/.test(name)) { + component.error(attribute, { + code: 'illegal-attribute', + message: `'${name}' is not a valid attribute name`, + }); + } - if (name === 'slot') { - if (!attribute.is_static) { - component.error(attribute, { - code: 'invalid-slot-attribute', - message: 'slot attribute cannot have a dynamic value' - }); - } + if (name === 'slot') { + if (!attribute.is_static) { + component.error(attribute, { + code: 'invalid-slot-attribute', + message: 'slot attribute cannot have a dynamic value', + }); + } - if (component.slot_outlets.has(name)) { - component.error(attribute, { - code: 'duplicate-slot-attribute', - message: `Duplicate '${name}' slot` - }); + if (component.slot_outlets.has(name)) { + component.error(attribute, { + code: 'duplicate-slot-attribute', + message: `Duplicate '${name}' slot`, + }); - component.slot_outlets.add(name); - } + component.slot_outlets.add(name); + } - if (!(parent.type === 'SlotTemplate' || within_custom_element(parent))) { - component.error(attribute, { - code: 'invalid-slotted-content', - message: 'Element with a slot=\'...\' attribute must be a child of a component or a descendant of a custom element' - }); - } - } + if (!(parent.type === 'SlotTemplate' || within_custom_element(parent))) { + component.error(attribute, { + code: 'invalid-slotted-content', + message: "Element with a slot='...' attribute must be a child of a component or a descendant of a custom element", + }); + } + } - // Warnings + // Warnings - if (this.namespace !== namespaces.foreign) { - if (name === 'is') { - component.warn(attribute, { - code: 'avoid-is', - message: 'The \'is\' attribute is not supported cross-browser and should be avoided' - }); - } + if (this.namespace !== namespaces.foreign) { + if (name === 'is') { + component.warn(attribute, { + code: 'avoid-is', + message: "The 'is' attribute is not supported cross-browser and should be avoided", + }); + } - if (react_attributes.has(attribute.name)) { - component.warn(attribute, { - code: 'invalid-html-attribute', - message: `'${attribute.name}' is not a valid HTML attribute. Did you mean '${react_attributes.get(attribute.name)}'?` - }); - } - } - }); - } + if (react_attributes.has(attribute.name)) { + component.warn(attribute, { + code: 'invalid-html-attribute', + message: `'${attribute.name}' is not a valid HTML attribute. Did you mean '${react_attributes.get(attribute.name)}'?`, + }); + } + } + }); + } - validate_attributes_a11y() { - const { component } = this; + validate_attributes_a11y() { + const { component } = this; - this.attributes.forEach(attribute => { - if (attribute.is_spread) return; + this.attributes.forEach((attribute) => { + if (attribute.is_spread) return; - const name = attribute.name.toLowerCase(); + const name = attribute.name.toLowerCase(); - // aria-props - if (name.startsWith('aria-')) { - if (invisible_elements.has(this.name)) { - // aria-unsupported-elements - component.warn(attribute, { - code: 'a11y-aria-attributes', - message: `A11y: <${this.name}> should not have aria-* attributes` - }); - } + // aria-props + if (name.startsWith('aria-')) { + if (invisible_elements.has(this.name)) { + // aria-unsupported-elements + component.warn(attribute, { + code: 'a11y-aria-attributes', + message: `A11y: <${this.name}> should not have aria-* attributes`, + }); + } - const type = name.slice(5); - if (!aria_attribute_set.has(type)) { - const match = fuzzymatch(type, aria_attributes); - let message = `A11y: Unknown aria attribute 'aria-${type}'`; - if (match) message += ` (did you mean '${match}'?)`; + const type = name.slice(5); + if (!aria_attribute_set.has(type)) { + const match = fuzzymatch(type, aria_attributes); + let message = `A11y: Unknown aria attribute 'aria-${type}'`; + if (match) message += ` (did you mean '${match}'?)`; - component.warn(attribute, { - code: 'a11y-unknown-aria-attribute', - message - }); - } + component.warn(attribute, { + code: 'a11y-unknown-aria-attribute', + message, + }); + } - if (name === 'aria-hidden' && /^h[1-6]$/.test(this.name)) { - component.warn(attribute, { - code: 'a11y-hidden', - message: `A11y: <${this.name}> element should not be hidden` - }); - } - } + if (name === 'aria-hidden' && /^h[1-6]$/.test(this.name)) { + component.warn(attribute, { + code: 'a11y-hidden', + message: `A11y: <${this.name}> element should not be hidden`, + }); + } + } - // aria-role - if (name === 'role') { - if (invisible_elements.has(this.name)) { - // aria-unsupported-elements - component.warn(attribute, { - code: 'a11y-misplaced-role', - message: `A11y: <${this.name}> should not have role attribute` - }); - } + // aria-role + if (name === 'role') { + if (invisible_elements.has(this.name)) { + // aria-unsupported-elements + component.warn(attribute, { + code: 'a11y-misplaced-role', + message: `A11y: <${this.name}> should not have role attribute`, + }); + } - const value = attribute.get_static_value(); - // @ts-ignore - if (value && !aria_role_set.has(value)) { - // @ts-ignore - const match = fuzzymatch(value, aria_roles); - let message = `A11y: Unknown role '${value}'`; - if (match) message += ` (did you mean '${match}'?)`; - - component.warn(attribute, { - code: 'a11y-unknown-role', - message - }); - } - } + const value = attribute.get_static_value(); + // @ts-ignore + if (value && !aria_role_set.has(value)) { + // @ts-ignore + const match = fuzzymatch(value, aria_roles); + let message = `A11y: Unknown role '${value}'`; + if (match) message += ` (did you mean '${match}'?)`; + + component.warn(attribute, { + code: 'a11y-unknown-role', + message, + }); + } + } - // no-access-key - if (name === 'accesskey') { - component.warn(attribute, { - code: 'a11y-accesskey', - message: 'A11y: Avoid using accesskey' - }); - } + // no-access-key + if (name === 'accesskey') { + component.warn(attribute, { + code: 'a11y-accesskey', + message: 'A11y: Avoid using accesskey', + }); + } - // no-autofocus - if (name === 'autofocus') { - component.warn(attribute, { - code: 'a11y-autofocus', - message: 'A11y: Avoid using autofocus' - }); - } + // no-autofocus + if (name === 'autofocus') { + component.warn(attribute, { + code: 'a11y-autofocus', + message: 'A11y: Avoid using autofocus', + }); + } - // scope - if (name === 'scope' && this.name !== 'th') { - component.warn(attribute, { - code: 'a11y-misplaced-scope', - message: 'A11y: The scope attribute should only be used with <th> elements' - }); - } + // scope + if (name === 'scope' && this.name !== 'th') { + component.warn(attribute, { + code: 'a11y-misplaced-scope', + message: 'A11y: The scope attribute should only be used with <th> elements', + }); + } - // tabindex-no-positive - if (name === 'tabindex') { - const value = attribute.get_static_value(); - // @ts-ignore todo is tabindex=true correct case? - if (!isNaN(value) && +value > 0) { - component.warn(attribute, { - code: 'a11y-positive-tabindex', - message: 'A11y: avoid tabindex values above zero' - }); - } - } - }); - } + // tabindex-no-positive + if (name === 'tabindex') { + const value = attribute.get_static_value(); + // @ts-ignore todo is tabindex=true correct case? + if (!isNaN(value) && +value > 0) { + component.warn(attribute, { + code: 'a11y-positive-tabindex', + message: 'A11y: avoid tabindex values above zero', + }); + } + } + }); + } + validate_special_cases() { + const { component, attributes, handlers } = this; - validate_special_cases() { - const { component, attributes, handlers } = this; + const attribute_map = new Map(); + const handlers_map = new Map(); - const attribute_map = new Map(); - const handlers_map = new Map(); + attributes.forEach((attribute) => attribute_map.set(attribute.name, attribute)); - attributes.forEach(attribute => ( - attribute_map.set(attribute.name, attribute) - )); + handlers.forEach((handler) => handlers_map.set(handler.name, handler)); - handlers.forEach(handler => ( - handlers_map.set(handler.name, handler) - )); + if (this.name === 'a') { + const href_attribute = attribute_map.get('href') || attribute_map.get('xlink:href'); + const id_attribute = attribute_map.get('id'); + const name_attribute = attribute_map.get('name'); - if (this.name === 'a') { - const href_attribute = attribute_map.get('href') || attribute_map.get('xlink:href'); - const id_attribute = attribute_map.get('id'); - const name_attribute = attribute_map.get('name'); + if (href_attribute) { + const href_value = href_attribute.get_static_value(); - if (href_attribute) { - const href_value = href_attribute.get_static_value(); + if (href_value === '' || href_value === '#' || /^\W*javascript:/i.test(href_value)) { + component.warn(href_attribute, { + code: 'a11y-invalid-attribute', + message: `A11y: '${href_value}' is not a valid ${href_attribute.name} attribute`, + }); + } + } else { + const id_attribute_valid = id_attribute && id_attribute.get_static_value() !== ''; + const name_attribute_valid = name_attribute && name_attribute.get_static_value() !== ''; + + if (!id_attribute_valid && !name_attribute_valid) { + component.warn(this, { + code: 'a11y-missing-attribute', + message: 'A11y: <a> element should have an href attribute', + }); + } + } + } else { + const required_attributes = a11y_required_attributes[this.name]; + if (required_attributes) { + const has_attribute = required_attributes.some((name) => attribute_map.has(name)); - if (href_value === '' || href_value === '#' || /^\W*javascript:/i.test(href_value)) { - component.warn(href_attribute, { - code: 'a11y-invalid-attribute', - message: `A11y: '${href_value}' is not a valid ${href_attribute.name} attribute` - }); - } - } else { - const id_attribute_valid = id_attribute && id_attribute.get_static_value() !== ''; - const name_attribute_valid = name_attribute && name_attribute.get_static_value() !== ''; - - if (!id_attribute_valid && !name_attribute_valid) { - component.warn(this, { - code: 'a11y-missing-attribute', - message: 'A11y: <a> element should have an href attribute' - }); - } - } - } else { - const required_attributes = a11y_required_attributes[this.name]; - if (required_attributes) { - const has_attribute = required_attributes.some(name => attribute_map.has(name)); + if (!has_attribute) { + should_have_attribute(this, required_attributes); + } + } + } - if (!has_attribute) { - should_have_attribute(this, required_attributes); - } - } - } + if (this.name === 'input') { + const type = attribute_map.get('type'); + if (type && type.get_static_value() === 'image') { + const required_attributes = ['alt', 'aria-label', 'aria-labelledby']; + const has_attribute = required_attributes.some((name) => attribute_map.has(name)); - if (this.name === 'input') { - const type = attribute_map.get('type'); - if (type && type.get_static_value() === 'image') { - const required_attributes = ['alt', 'aria-label', 'aria-labelledby']; - const has_attribute = required_attributes.some(name => attribute_map.has(name)); + if (!has_attribute) { + should_have_attribute(this, required_attributes, 'input type="image"'); + } + } + } - if (!has_attribute) { - should_have_attribute(this, required_attributes, 'input type="image"'); - } - } - } + if (this.name === 'img') { + const alt_attribute = attribute_map.get('alt'); + const aria_hidden_attribute = attribute_map.get('aria-hidden'); - if (this.name === 'img') { - const alt_attribute = attribute_map.get('alt'); - const aria_hidden_attribute = attribute_map.get('aria-hidden'); + const aria_hidden_exist = aria_hidden_attribute && aria_hidden_attribute.get_static_value(); - const aria_hidden_exist = aria_hidden_attribute && aria_hidden_attribute.get_static_value(); + if (alt_attribute && !aria_hidden_exist) { + const alt_value = alt_attribute.get_static_value(); - if (alt_attribute && !aria_hidden_exist) { - const alt_value = alt_attribute.get_static_value(); + if (/\b(image|picture|photo)\b/i.test(alt_value)) { + component.warn(this, { + code: 'a11y-img-redundant-alt', + message: 'A11y: Screenreaders already announce <img> elements as an image.', + }); + } + } + } - if (/\b(image|picture|photo)\b/i.test(alt_value)) { - component.warn(this, { - code: 'a11y-img-redundant-alt', - message: 'A11y: Screenreaders already announce <img> elements as an image.' - }); - } - } - } + if (this.name === 'label') { + const has_input_child = this.children.some((i) => i instanceof Element$1 && a11y_labelable.has(i.name)); + if (!attribute_map.has('for') && !has_input_child) { + component.warn(this, { + code: 'a11y-label-has-associated-control', + message: 'A11y: A form label must be associated with a control.', + }); + } + } - if (this.name === 'label') { - const has_input_child = this.children.some(i => (i instanceof Element$1 && a11y_labelable.has(i.name) )); - if (!attribute_map.has('for') && !has_input_child) { - component.warn(this, { - code: 'a11y-label-has-associated-control', - message: 'A11y: A form label must be associated with a control.' - }); - } - } + if (this.is_media_node()) { + if (attribute_map.has('muted')) { + return; + } - if (this.is_media_node()) { - if (attribute_map.has('muted')) { - return; - } + let has_caption; + const track = this.children.find((i) => i.name === 'track'); + if (track) { + has_caption = track.attributes.find((a) => a.name === 'kind' && a.get_static_value() === 'captions'); + } - let has_caption; - const track = this.children.find((i) => i.name === 'track'); - if (track) { - has_caption = track.attributes.find(a => a.name === 'kind' && a.get_static_value() === 'captions'); - } + if (!has_caption) { + component.warn(this, { + code: 'a11y-media-has-caption', + message: 'A11y: Media elements must have a <track kind="captions">', + }); + } + } - if (!has_caption) { - component.warn(this, { - code: 'a11y-media-has-caption', - message: 'A11y: Media elements must have a <track kind="captions">' - }); - } - } + if (a11y_no_onchange.has(this.name)) { + if (handlers_map.has('change') && !handlers_map.has('blur')) { + component.warn(this, { + code: 'a11y-no-onchange', + message: 'A11y: on:blur must be used instead of on:change, unless absolutely necessary and it causes no negative consequences for keyboard only or screen reader users.', + }); + } + } - if (a11y_no_onchange.has(this.name)) { - if (handlers_map.has('change') && !handlers_map.has('blur')) { - component.warn(this, { - code: 'a11y-no-onchange', - message: 'A11y: on:blur must be used instead of on:change, unless absolutely necessary and it causes no negative consequences for keyboard only or screen reader users.' - }); - } - } + if (a11y_distracting_elements.has(this.name)) { + // no-distracting-elements + component.warn(this, { + code: 'a11y-distracting-elements', + message: `A11y: Avoid <${this.name}> elements`, + }); + } - if (a11y_distracting_elements.has(this.name)) { - // no-distracting-elements - component.warn(this, { - code: 'a11y-distracting-elements', - message: `A11y: Avoid <${this.name}> elements` - }); - } + if (this.name === 'figcaption') { + let { parent } = this; + let is_figure_parent = false; - if (this.name === 'figcaption') { - let { parent } = this; - let is_figure_parent = false; + while (parent) { + if (parent.name === 'figure') { + is_figure_parent = true; + break; + } + if (parent.type === 'Element') { + break; + } + parent = parent.parent; + } - while (parent) { - if ((parent ).name === 'figure') { - is_figure_parent = true; - break; - } - if (parent.type === 'Element') { - break; - } - parent = parent.parent; - } + if (!is_figure_parent) { + component.warn(this, { + code: 'a11y-structure', + message: 'A11y: <figcaption> must be an immediate child of <figure>', + }); + } + } - if (!is_figure_parent) { - component.warn(this, { - code: 'a11y-structure', - message: 'A11y: <figcaption> must be an immediate child of <figure>' - }); - } - } + if (this.name === 'figure') { + const children = this.children.filter((node) => { + if (node.type === 'Comment') return false; + if (node.type === 'Text') return /\S/.test(node.data); + return true; + }); - if (this.name === 'figure') { - const children = this.children.filter(node => { - if (node.type === 'Comment') return false; - if (node.type === 'Text') return /\S/.test(node.data); - return true; - }); + const index = children.findIndex((child) => child.name === 'figcaption'); - const index = children.findIndex(child => (child ).name === 'figcaption'); + if (index !== -1 && index !== 0 && index !== children.length - 1) { + component.warn(children[index], { + code: 'a11y-structure', + message: 'A11y: <figcaption> must be first or last child of <figure>', + }); + } + } + } - if (index !== -1 && (index !== 0 && index !== children.length - 1)) { - component.warn(children[index], { - code: 'a11y-structure', - message: 'A11y: <figcaption> must be first or last child of <figure>' - }); - } - } - } - - validate_bindings_foreign() { - this.bindings.forEach(binding => { - if (binding.name !== 'this') { - this.component.error(binding, { - code: 'invalid-binding', - message: `'${binding.name}' is not a valid binding. Foreign elements only support bind:this` - }); - } - }); - } + validate_bindings_foreign() { + this.bindings.forEach((binding) => { + if (binding.name !== 'this') { + this.component.error(binding, { + code: 'invalid-binding', + message: `'${binding.name}' is not a valid binding. Foreign elements only support bind:this`, + }); + } + }); + } - validate_bindings() { - const { component } = this; + validate_bindings() { + const { component } = this; - const check_type_attribute = () => { - const attribute = this.attributes.find( - (attribute) => attribute.name === 'type' - ); + const check_type_attribute = () => { + const attribute = this.attributes.find((attribute) => attribute.name === 'type'); - if (!attribute) return null; + if (!attribute) return null; - if (!attribute.is_static) { - component.error(attribute, { - code: 'invalid-type', - message: '\'type\' attribute cannot be dynamic if input uses two-way binding' - }); - } + if (!attribute.is_static) { + component.error(attribute, { + code: 'invalid-type', + message: "'type' attribute cannot be dynamic if input uses two-way binding", + }); + } - const value = attribute.get_static_value(); + const value = attribute.get_static_value(); - if (value === true) { - component.error(attribute, { - code: 'missing-type', - message: '\'type\' attribute must be specified' - }); - } + if (value === true) { + component.error(attribute, { + code: 'missing-type', + message: "'type' attribute must be specified", + }); + } - return value; - }; - - this.bindings.forEach(binding => { - const { name } = binding; - - if (name === 'value') { - if ( - this.name !== 'input' && - this.name !== 'textarea' && - this.name !== 'select' - ) { - component.error(binding, { - code: 'invalid-binding', - message: `'value' is not a valid binding on <${this.name}> elements` - }); - } + return value; + }; - if (this.name === 'select') { - const attribute = this.attributes.find( - (attribute) => attribute.name === 'multiple' - ); + this.bindings.forEach((binding) => { + const { name } = binding; - if (attribute && !attribute.is_static) { - component.error(attribute, { - code: 'dynamic-multiple-attribute', - message: '\'multiple\' attribute cannot be dynamic if select uses two-way binding' - }); - } - } else { - check_type_attribute(); - } - } else if (name === 'checked' || name === 'indeterminate') { - if (this.name !== 'input') { - component.error(binding, { - code: 'invalid-binding', - message: `'${name}' is not a valid binding on <${this.name}> elements` - }); - } + if (name === 'value') { + if (this.name !== 'input' && this.name !== 'textarea' && this.name !== 'select') { + component.error(binding, { + code: 'invalid-binding', + message: `'value' is not a valid binding on <${this.name}> elements`, + }); + } - const type = check_type_attribute(); + if (this.name === 'select') { + const attribute = this.attributes.find((attribute) => attribute.name === 'multiple'); - if (type !== 'checkbox') { - let message = `'${name}' binding can only be used with <input type="checkbox">`; - if (type === 'radio') message += ' — for <input type="radio">, use \'group\' binding'; - component.error(binding, { code: 'invalid-binding', message }); - } - } else if (name === 'group') { - if (this.name !== 'input') { - component.error(binding, { - code: 'invalid-binding', - message: `'group' is not a valid binding on <${this.name}> elements` - }); - } + if (attribute && !attribute.is_static) { + component.error(attribute, { + code: 'dynamic-multiple-attribute', + message: "'multiple' attribute cannot be dynamic if select uses two-way binding", + }); + } + } else { + check_type_attribute(); + } + } else if (name === 'checked' || name === 'indeterminate') { + if (this.name !== 'input') { + component.error(binding, { + code: 'invalid-binding', + message: `'${name}' is not a valid binding on <${this.name}> elements`, + }); + } - const type = check_type_attribute(); + const type = check_type_attribute(); - if (type !== 'checkbox' && type !== 'radio') { - component.error(binding, { - code: 'invalid-binding', - message: '\'group\' binding can only be used with <input type="checkbox"> or <input type="radio">' - }); - } - } else if (name === 'files') { - if (this.name !== 'input') { - component.error(binding, { - code: 'invalid-binding', - message: `'files' is not a valid binding on <${this.name}> elements` - }); - } + if (type !== 'checkbox') { + let message = `'${name}' binding can only be used with <input type="checkbox">`; + if (type === 'radio') message += ' — for <input type="radio">, use \'group\' binding'; + component.error(binding, { code: 'invalid-binding', message }); + } + } else if (name === 'group') { + if (this.name !== 'input') { + component.error(binding, { + code: 'invalid-binding', + message: `'group' is not a valid binding on <${this.name}> elements`, + }); + } - const type = check_type_attribute(); + const type = check_type_attribute(); - if (type !== 'file') { - component.error(binding, { - code: 'invalid-binding', - message: '\'files\' binding can only be used with <input type="file">' - }); - } + if (type !== 'checkbox' && type !== 'radio') { + component.error(binding, { + code: 'invalid-binding', + message: '\'group\' binding can only be used with <input type="checkbox"> or <input type="radio">', + }); + } + } else if (name === 'files') { + if (this.name !== 'input') { + component.error(binding, { + code: 'invalid-binding', + message: `'files' is not a valid binding on <${this.name}> elements`, + }); + } - } else if (name === 'open') { - if (this.name !== 'details') { - component.error(binding, { - code: 'invalid-binding', - message: `'${name}' binding can only be used with <details>` - }); - } - } else if ( - name === 'currentTime' || - name === 'duration' || - name === 'paused' || - name === 'buffered' || - name === 'seekable' || - name === 'played' || - name === 'volume' || - name === 'muted' || - name === 'playbackRate' || - name === 'seeking' || - name === 'ended' - ) { - if (this.name !== 'audio' && this.name !== 'video') { - component.error(binding, { - code: 'invalid-binding', - message: `'${name}' binding can only be used with <audio> or <video>` - }); - } - } else if ( - name === 'videoHeight' || - name === 'videoWidth' - ) { - if (this.name !== 'video') { - component.error(binding, { - code: 'invalid-binding', - message: `'${name}' binding can only be used with <video>` - }); - } - } else if (dimensions.test(name)) { - if (this.name === 'svg' && (name === 'offsetWidth' || name === 'offsetHeight')) { - component.error(binding, { - code: 'invalid-binding', - message: `'${binding.name}' is not a valid binding on <svg>. Use '${name.replace('offset', 'client')}' instead` - }); - } else if (svg$1.test(this.name)) { - component.error(binding, { - code: 'invalid-binding', - message: `'${binding.name}' is not a valid binding on SVG elements` - }); - } else if (is_void(this.name)) { - component.error(binding, { - code: 'invalid-binding', - message: `'${binding.name}' is not a valid binding on void elements like <${this.name}>. Use a wrapper element instead` - }); - } - } else if ( - name === 'textContent' || - name === 'innerHTML' - ) { - const contenteditable = this.attributes.find( - (attribute) => attribute.name === 'contenteditable' - ); - - if (!contenteditable) { - component.error(binding, { - code: 'missing-contenteditable-attribute', - message: '\'contenteditable\' attribute is required for textContent and innerHTML two-way bindings' - }); - } else if (contenteditable && !contenteditable.is_static) { - component.error(contenteditable, { - code: 'dynamic-contenteditable-attribute', - message: '\'contenteditable\' attribute cannot be dynamic if element uses two-way binding' - }); - } - } else if (name !== 'this') { - component.error(binding, { - code: 'invalid-binding', - message: `'${binding.name}' is not a valid binding` - }); - } - }); - } - - validate_content() { - if (!a11y_required_content.has(this.name)) return; - if ( - this.bindings - .some((binding) => ['textContent', 'innerHTML'].includes(binding.name)) - ) return; - - if (this.children.length === 0) { - this.component.warn(this, { - code: 'a11y-missing-content', - message: `A11y: <${this.name}> element should have child content` - }); - } - } + const type = check_type_attribute(); - validate_event_handlers() { - const { component } = this; + if (type !== 'file') { + component.error(binding, { + code: 'invalid-binding', + message: '\'files\' binding can only be used with <input type="file">', + }); + } + } else if (name === 'open') { + if (this.name !== 'details') { + component.error(binding, { + code: 'invalid-binding', + message: `'${name}' binding can only be used with <details>`, + }); + } + } else if ( + name === 'currentTime' || + name === 'duration' || + name === 'paused' || + name === 'buffered' || + name === 'seekable' || + name === 'played' || + name === 'volume' || + name === 'muted' || + name === 'playbackRate' || + name === 'seeking' || + name === 'ended' + ) { + if (this.name !== 'audio' && this.name !== 'video') { + component.error(binding, { + code: 'invalid-binding', + message: `'${name}' binding can only be used with <audio> or <video>`, + }); + } + } else if (name === 'videoHeight' || name === 'videoWidth') { + if (this.name !== 'video') { + component.error(binding, { + code: 'invalid-binding', + message: `'${name}' binding can only be used with <video>`, + }); + } + } else if (dimensions.test(name)) { + if (this.name === 'svg' && (name === 'offsetWidth' || name === 'offsetHeight')) { + component.error(binding, { + code: 'invalid-binding', + message: `'${binding.name}' is not a valid binding on <svg>. Use '${name.replace('offset', 'client')}' instead`, + }); + } else if (svg$1.test(this.name)) { + component.error(binding, { + code: 'invalid-binding', + message: `'${binding.name}' is not a valid binding on SVG elements`, + }); + } else if (is_void(this.name)) { + component.error(binding, { + code: 'invalid-binding', + message: `'${binding.name}' is not a valid binding on void elements like <${this.name}>. Use a wrapper element instead`, + }); + } + } else if (name === 'textContent' || name === 'innerHTML') { + const contenteditable = this.attributes.find((attribute) => attribute.name === 'contenteditable'); + + if (!contenteditable) { + component.error(binding, { + code: 'missing-contenteditable-attribute', + message: "'contenteditable' attribute is required for textContent and innerHTML two-way bindings", + }); + } else if (contenteditable && !contenteditable.is_static) { + component.error(contenteditable, { + code: 'dynamic-contenteditable-attribute', + message: "'contenteditable' attribute cannot be dynamic if element uses two-way binding", + }); + } + } else if (name !== 'this') { + component.error(binding, { + code: 'invalid-binding', + message: `'${binding.name}' is not a valid binding`, + }); + } + }); + } - this.handlers.forEach(handler => { - if (handler.modifiers.has('passive') && handler.modifiers.has('preventDefault')) { - component.error(handler, { - code: 'invalid-event-modifier', - message: 'The \'passive\' and \'preventDefault\' modifiers cannot be used together' - }); - } + validate_content() { + if (!a11y_required_content.has(this.name)) return; + if (this.bindings.some((binding) => ['textContent', 'innerHTML'].includes(binding.name))) return; - if (handler.modifiers.has('passive') && handler.modifiers.has('nonpassive')) { - component.error(handler, { - code: 'invalid-event-modifier', - message: 'The \'passive\' and \'nonpassive\' modifiers cannot be used together' - }); - } + if (this.children.length === 0) { + this.component.warn(this, { + code: 'a11y-missing-content', + message: `A11y: <${this.name}> element should have child content`, + }); + } + } - handler.modifiers.forEach(modifier => { - if (!valid_modifiers.has(modifier)) { - component.error(handler, { - code: 'invalid-event-modifier', - message: `Valid event modifiers are ${list(Array.from(valid_modifiers))}` - }); - } + validate_event_handlers() { + const { component } = this; - if (modifier === 'passive') { - if (passive_events.has(handler.name)) { - if (handler.can_make_passive) { - component.warn(handler, { - code: 'redundant-event-modifier', - message: 'Touch event handlers that don\'t use the \'event\' object are passive by default' - }); - } - } else { - component.warn(handler, { - code: 'redundant-event-modifier', - message: 'The passive modifier only works with wheel and touch events' - }); - } - } + this.handlers.forEach((handler) => { + if (handler.modifiers.has('passive') && handler.modifiers.has('preventDefault')) { + component.error(handler, { + code: 'invalid-event-modifier', + message: "The 'passive' and 'preventDefault' modifiers cannot be used together", + }); + } - if (component.compile_options.legacy && (modifier === 'once' || modifier === 'passive')) { - // TODO this could be supported, but it would need a few changes to - // how event listeners work - component.error(handler, { - code: 'invalid-event-modifier', - message: `The '${modifier}' modifier cannot be used in legacy mode` - }); - } - }); + if (handler.modifiers.has('passive') && handler.modifiers.has('nonpassive')) { + component.error(handler, { + code: 'invalid-event-modifier', + message: "The 'passive' and 'nonpassive' modifiers cannot be used together", + }); + } - if (passive_events.has(handler.name) && handler.can_make_passive && !handler.modifiers.has('preventDefault') && !handler.modifiers.has('nonpassive')) { - // touch/wheel events should be passive by default - handler.modifiers.add('passive'); - } - }); - } + handler.modifiers.forEach((modifier) => { + if (!valid_modifiers.has(modifier)) { + component.error(handler, { + code: 'invalid-event-modifier', + message: `Valid event modifiers are ${list(Array.from(valid_modifiers))}`, + }); + } - is_media_node() { - return this.name === 'audio' || this.name === 'video'; - } + if (modifier === 'passive') { + if (passive_events.has(handler.name)) { + if (handler.can_make_passive) { + component.warn(handler, { + code: 'redundant-event-modifier', + message: "Touch event handlers that don't use the 'event' object are passive by default", + }); + } + } else { + component.warn(handler, { + code: 'redundant-event-modifier', + message: 'The passive modifier only works with wheel and touch events', + }); + } + } - add_css_class() { - if (this.attributes.some(attr => attr.is_spread)) { - this.needs_manual_style_scoping = true; - return; - } + if (component.compile_options.legacy && (modifier === 'once' || modifier === 'passive')) { + // TODO this could be supported, but it would need a few changes to + // how event listeners work + component.error(handler, { + code: 'invalid-event-modifier', + message: `The '${modifier}' modifier cannot be used in legacy mode`, + }); + } + }); - const { id } = this.component.stylesheet; - - const class_attribute = this.attributes.find(a => a.name === 'class'); - - if (class_attribute && !class_attribute.is_true) { - if (class_attribute.chunks.length === 1 && class_attribute.chunks[0].type === 'Text') { - (class_attribute.chunks[0] ).data += ` ${id}`; - } else { - (class_attribute.chunks ).push( - new Text(this.component, this, this.scope, { - type: 'Text', - data: ` ${id}`, - synthetic: true - } ) - ); - } - } else { - this.attributes.push( - new Attribute(this.component, this, this.scope, { - type: 'Attribute', - name: 'class', - value: [{ type: 'Text', data: id, synthetic: true }] - } ) - ); - } - } + if (passive_events.has(handler.name) && handler.can_make_passive && !handler.modifiers.has('preventDefault') && !handler.modifiers.has('nonpassive')) { + // touch/wheel events should be passive by default + handler.modifiers.add('passive'); + } + }); + } - get slot_template_name() { - return this.attributes.find(attribute => attribute.name === 'slot').get_static_value() ; - } + is_media_node() { + return this.name === 'audio' || this.name === 'video'; + } + + add_css_class() { + if (this.attributes.some((attr) => attr.is_spread)) { + this.needs_manual_style_scoping = true; + return; + } + + const { id } = this.component.stylesheet; + + const class_attribute = this.attributes.find((a) => a.name === 'class'); + + if (class_attribute && !class_attribute.is_true) { + if (class_attribute.chunks.length === 1 && class_attribute.chunks[0].type === 'Text') { + class_attribute.chunks[0].data += ` ${id}`; + } else { + class_attribute.chunks.push( + new Text(this.component, this, this.scope, { + type: 'Text', + data: ` ${id}`, + synthetic: true, + }) + ); + } + } else { + this.attributes.push( + new Attribute(this.component, this, this.scope, { + type: 'Attribute', + name: 'class', + value: [{ type: 'Text', data: id, synthetic: true }], + }) + ); + } + } + + get slot_template_name() { + return this.attributes.find((attribute) => attribute.name === 'slot').get_static_value(); + } } -function should_have_attribute( - node, - attributes, - name = node.name -) { - const article = /^[aeiou]/.test(attributes[0]) ? 'an' : 'a'; - const sequence = attributes.length > 1 ? - attributes.slice(0, -1).join(', ') + ` or ${attributes[attributes.length - 1]}` : - attributes[0]; +function should_have_attribute(node, attributes, name = node.name) { + const article = /^[aeiou]/.test(attributes[0]) ? 'an' : 'a'; + const sequence = attributes.length > 1 ? attributes.slice(0, -1).join(', ') + ` or ${attributes[attributes.length - 1]}` : attributes[0]; - node.component.warn(node, { - code: 'a11y-missing-attribute', - message: `A11y: <${name}> element should have ${article} ${sequence} attribute` - }); + node.component.warn(node, { + code: 'a11y-missing-attribute', + message: `A11y: <${name}> element should have ${article} ${sequence} attribute`, + }); } function within_custom_element(parent) { - while (parent) { - if (parent.type === 'InlineComponent') return false; - if (parent.type === 'Element' && /-/.test(parent.name)) return true; - parent = parent.parent; - } - return false; + while (parent) { + if (parent.type === 'InlineComponent') return false; + if (parent.type === 'Element' && /-/.test(parent.name)) return true; + parent = parent.parent; + } + return false; } // https://github.com/darkskyapp/string-hash/blob/master/index.js function hash(str) { - str = str.replace(/\r/g, ''); - let hash = 5381; - let i = str.length; + str = str.replace(/\r/g, ''); + let hash = 5381; + let i = str.length; - while (i--) hash = ((hash << 5) - hash) ^ str.charCodeAt(i); - return (hash >>> 0).toString(36); + while (i--) hash = ((hash << 5) - hash) ^ str.charCodeAt(i); + return (hash >>> 0).toString(36); } class Head$1 extends Node { - - // TODO - + // TODO - constructor(component, parent, scope, info) { - super(component, parent, scope, info); + constructor(component, parent, scope, info) { + super(component, parent, scope, info); - if (info.attributes.length) { - component.error(info.attributes[0], { - code: 'invalid-attribute', - message: '<svelte:head> should not have any attributes or directives' - }); - } + if (info.attributes.length) { + component.error(info.attributes[0], { + code: 'invalid-attribute', + message: '<svelte:head> should not have any attributes or directives', + }); + } - this.children = map_children(component, parent, scope, info.children.filter(child => { - return (child.type !== 'Text' || /\S/.test(child.data)); - })); + this.children = map_children( + component, + parent, + scope, + info.children.filter((child) => { + return child.type !== 'Text' || /\S/.test(child.data); + }) + ); - if (this.children.length > 0) { - this.id = `svelte-${hash(this.component.source.slice(this.start, this.end))}`; - } - } + if (this.children.length > 0) { + this.id = `svelte-${hash(this.component.source.slice(this.start, this.end))}`; + } + } } class IfBlock$1 extends AbstractBlock { - - - - - constructor(component, parent, scope, info) { - super(component, parent, scope, info); + constructor(component, parent, scope, info) { + super(component, parent, scope, info); - this.expression = new Expression(component, this, scope, info.expression); - this.children = map_children(component, this, scope, info.children); + this.expression = new Expression(component, this, scope, info.expression); + this.children = map_children(component, this, scope, info.children); - this.else = info.else - ? new ElseBlock(component, this, scope, info.else) - : null; + this.else = info.else ? new ElseBlock(component, this, scope, info.else) : null; - this.warn_if_empty_block(); - } + this.warn_if_empty_block(); + } } class InlineComponent$1 extends Node { - - - - __init() {this.attributes = [];} - __init2() {this.bindings = [];} - __init3() {this.handlers = [];} - __init4() {this.lets = [];} - - - - constructor(component, parent, scope, info) { - super(component, parent, scope, info);InlineComponent$1.prototype.__init.call(this);InlineComponent$1.prototype.__init2.call(this);InlineComponent$1.prototype.__init3.call(this);InlineComponent$1.prototype.__init4.call(this); - 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(name); - } + __init() { + this.attributes = []; + } + __init2() { + this.bindings = []; + } + __init3() { + this.handlers = []; + } + __init4() { + this.lets = []; + } - this.name = info.name; + constructor(component, parent, scope, info) { + super(component, parent, scope, info); + InlineComponent$1.prototype.__init.call(this); + InlineComponent$1.prototype.__init2.call(this); + InlineComponent$1.prototype.__init3.call(this); + InlineComponent$1.prototype.__init4.call(this); + 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(name); + } - this.expression = this.name === 'svelte:component' - ? new Expression(component, this, scope, info.expression) - : null; + this.name = info.name; - info.attributes.forEach(node => { - /* eslint-disable no-fallthrough */ - switch (node.type) { - case 'Action': - component.error(node, { - code: 'invalid-action', - message: 'Actions can only be applied to DOM elements, not components' - }); + this.expression = this.name === 'svelte:component' ? new Expression(component, this, scope, info.expression) : null; - case 'Attribute': - // fallthrough - case 'Spread': - this.attributes.push(new Attribute(component, this, scope, node)); - break; + info.attributes.forEach((node) => { + /* eslint-disable no-fallthrough */ + switch (node.type) { + case 'Action': + component.error(node, { + code: 'invalid-action', + message: 'Actions can only be applied to DOM elements, not components', + }); - case 'Binding': - this.bindings.push(new Binding(component, this, scope, node)); - break; + case 'Attribute': + // fallthrough + case 'Spread': + this.attributes.push(new Attribute(component, this, scope, node)); + break; - case 'Class': - component.error(node, { - code: 'invalid-class', - message: 'Classes can only be applied to DOM elements, not components' - }); + case 'Binding': + this.bindings.push(new Binding(component, this, scope, node)); + break; - case 'EventHandler': - this.handlers.push(new EventHandler(component, this, scope, node)); - break; + case 'Class': + component.error(node, { + code: 'invalid-class', + message: 'Classes can only be applied to DOM elements, not components', + }); - case 'Let': - this.lets.push(new Let(component, this, scope, node)); - break; + case 'EventHandler': + this.handlers.push(new EventHandler(component, this, scope, node)); + break; - case 'Transition': - component.error(node, { - code: 'invalid-transition', - message: 'Transitions can only be applied to DOM elements, not components' - }); + case 'Let': + this.lets.push(new Let(component, this, scope, node)); + break; - default: - throw new Error(`Not implemented: ${node.type}`); - } - /* eslint-enable no-fallthrough */ - }); + case 'Transition': + component.error(node, { + code: 'invalid-transition', + message: 'Transitions can only be applied to DOM elements, not components', + }); - if (this.lets.length > 0) { - this.scope = scope.child(); + default: + throw new Error(`Not implemented: ${node.type}`); + } + /* eslint-enable no-fallthrough */ + }); - this.lets.forEach(l => { - const dependencies = new Set([l.name.name]); + if (this.lets.length > 0) { + this.scope = scope.child(); - l.names.forEach(name => { - this.scope.add(name, dependencies, this); - }); - }); - } else { - this.scope = scope; - } + this.lets.forEach((l) => { + const dependencies = new Set([l.name.name]); - this.handlers.forEach(handler => { - handler.modifiers.forEach(modifier => { - if (modifier !== 'once') { - component.error(handler, { - code: 'invalid-event-modifier', - message: "Event modifiers other than 'once' can only be used on DOM elements" - }); - } - }); - }); + l.names.forEach((name) => { + this.scope.add(name, dependencies, this); + }); + }); + } else { + this.scope = scope; + } - 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] - }; + this.handlers.forEach((handler) => { + handler.modifiers.forEach((modifier) => { + if (modifier !== 'once') { + component.error(handler, { + code: 'invalid-event-modifier', + message: "Event modifiers other than 'once' can only be used on DOM elements", + }); + } + }); + }); - // 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); - } - } - - children.push(slot_template); - info.children.splice(i, 1); - } - } + 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); + } + } - 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 - }); - } + children.push(slot_template); + info.children.splice(i, 1); + } + } - this.children = map_children(component, this, this.scope, children); - } + 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, + }); + } - get slot_template_name() { - return this.attributes.find(attribute => attribute.name === 'slot').get_static_value() ; - } + this.children = map_children(component, this, this.scope, children); + } + + get slot_template_name() { + return this.attributes.find((attribute) => attribute.name === 'slot').get_static_value(); + } } function not_whitespace_text(node) { - return !(node.type === 'Text' && /^\s+$/.test(node.data)); + return !(node.type === 'Text' && /^\s+$/.test(node.data)); } class KeyBlock$1 extends AbstractBlock { - - - + constructor(component, parent, scope, info) { + super(component, parent, scope, info); - constructor(component, parent, scope, info) { - super(component, parent, scope, info); + this.expression = new Expression(component, this, scope, info.expression); - this.expression = new Expression(component, this, scope, info.expression); + this.children = map_children(component, this, scope, info.children); - this.children = map_children(component, this, scope, info.children); - - this.warn_if_empty_block(); - } + this.warn_if_empty_block(); + } } class Tag$1 extends Node { - - - + constructor(component, parent, scope, info) { + super(component, parent, scope, info); + this.expression = new Expression(component, this, scope, info.expression); - constructor(component, parent, scope, info) { - super(component, parent, scope, info); - 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)) - ); - } + this.should_cache = info.expression.type !== 'Identifier' || (this.expression.dependencies.size && scope.names.has(info.expression.name)); + } } -class MustacheTag extends Tag$1 { - -} +class MustacheTag extends Tag$1 {} -class Options extends Node { - -} +class Options extends Node {} -class RawMustacheTag extends Tag$1 { - -} +class RawMustacheTag extends Tag$1 {} class DebugTag$1 extends Node { - - + constructor(component, parent, scope, info) { + super(component, parent, scope, info); - constructor(component, parent, scope, info) { - super(component, parent, scope, info); - - this.expressions = info.identifiers.map((node) => { - return new Expression(component, parent, scope, node); - }); - } + this.expressions = info.identifiers.map((node) => { + return new Expression(component, parent, scope, node); + }); + } } class Slot$1 extends Element$1 { - - - - - __init() {this.values = new Map();} - - constructor(component, parent, scope, info) { - super(component, parent, scope, info);Slot$1.prototype.__init.call(this); - info.attributes.forEach(attr => { - if (attr.type !== 'Attribute' && attr.type !== 'Spread') { - component.error(attr, { - code: 'invalid-slot-directive', - message: '<slot> cannot have directives' - }); - } + __init() { + this.values = new Map(); + } - if (attr.name === 'name') { - if (attr.value.length !== 1 || attr.value[0].type !== 'Text') { - component.error(attr, { - code: 'dynamic-slot-name', - message: '<slot> name cannot be dynamic' - }); - } + constructor(component, parent, scope, info) { + super(component, parent, scope, info); + Slot$1.prototype.__init.call(this); + info.attributes.forEach((attr) => { + if (attr.type !== 'Attribute' && attr.type !== 'Spread') { + component.error(attr, { + code: 'invalid-slot-directive', + message: '<slot> cannot have directives', + }); + } - this.slot_name = attr.value[0].data; - if (this.slot_name === 'default') { - component.error(attr, { - code: 'invalid-slot-name', - message: 'default is a reserved word — it cannot be used as a slot name' - }); - } - } + if (attr.name === 'name') { + if (attr.value.length !== 1 || attr.value[0].type !== 'Text') { + component.error(attr, { + code: 'dynamic-slot-name', + message: '<slot> name cannot be dynamic', + }); + } - this.values.set(attr.name, new Attribute(component, this, scope, attr)); - }); + this.slot_name = attr.value[0].data; + if (this.slot_name === 'default') { + component.error(attr, { + code: 'invalid-slot-name', + message: 'default is a reserved word — it cannot be used as a slot name', + }); + } + } - if (!this.slot_name) this.slot_name = 'default'; + this.values.set(attr.name, new Attribute(component, this, scope, attr)); + }); - if (this.slot_name === 'default') { - // if this is the default slot, add our dependencies to any - // other slots (which inherit our slot values) that were - // previously encountered - component.slots.forEach((slot) => { - this.values.forEach((attribute, name) => { - if (!slot.values.has(name)) { - slot.values.set(name, attribute); - } - }); - }); - } else if (component.slots.has('default')) { - // otherwise, go the other way — inherit values from - // a previously encountered default slot - const default_slot = component.slots.get('default'); - default_slot.values.forEach((attribute, name) => { - if (!this.values.has(name)) { - this.values.set(name, attribute); - } - }); - } + if (!this.slot_name) this.slot_name = 'default'; - component.slots.set(this.slot_name, this); - } + if (this.slot_name === 'default') { + // if this is the default slot, add our dependencies to any + // other slots (which inherit our slot values) that were + // previously encountered + component.slots.forEach((slot) => { + this.values.forEach((attribute, name) => { + if (!slot.values.has(name)) { + slot.values.set(name, attribute); + } + }); + }); + } else if (component.slots.has('default')) { + // otherwise, go the other way — inherit values from + // a previously encountered default slot + const default_slot = component.slots.get('default'); + default_slot.values.forEach((attribute, name) => { + if (!this.values.has(name)) { + this.values.set(name, attribute); + } + }); + } + + component.slots.set(this.slot_name, this); + } } class Title extends Node { - - - - - 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], { - code: 'illegal-attribute', - message: '<title> cannot have attributes' - }); - } + 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], { + code: 'illegal-attribute', + message: '<title> cannot have attributes', + }); + } - info.children.forEach(child => { - if (child.type !== 'Text' && child.type !== 'MustacheTag') { - component.error(child, { - code: 'illegal-structure', - message: '<title> can only contain text and {tags}' - }); - } - }); + info.children.forEach((child) => { + if (child.type !== 'Text' && child.type !== 'MustacheTag') { + component.error(child, { + code: 'illegal-structure', + message: '<title> can only contain text and {tags}', + }); + } + }); - this.should_cache = info.children.length === 1 - ? ( - info.children[0].type !== 'Identifier' || - scope.names.has(info.children[0].name) - ) - : true; - } -} - -const valid_bindings = [ - 'innerWidth', - 'innerHeight', - 'outerWidth', - 'outerHeight', - 'scrollX', - 'scrollY', - 'online' -]; + this.should_cache = info.children.length === 1 ? info.children[0].type !== 'Identifier' || scope.names.has(info.children[0].name) : true; + } +} + +const valid_bindings = ['innerWidth', 'innerHeight', 'outerWidth', 'outerHeight', 'scrollX', 'scrollY', 'online']; class Window extends Node { - - __init() {this.handlers = [];} - __init2() {this.bindings = [];} - __init3() {this.actions = [];} - - constructor(component, parent, scope, info) { - super(component, parent, scope, info);Window.prototype.__init.call(this);Window.prototype.__init2.call(this);Window.prototype.__init3.call(this); - 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? - component.error(node.expression, { - code: 'invalid-binding', - message: `Bindings on <svelte:window> must be to top-level properties, e.g. '${parts[parts.length - 1]}' rather than '${parts.join('.')}'` - }); - } + __init() { + this.handlers = []; + } + __init2() { + this.bindings = []; + } + __init3() { + this.actions = []; + } - if (!~valid_bindings.indexOf(node.name)) { - const match = ( - node.name === 'width' ? 'innerWidth' : - node.name === 'height' ? 'innerHeight' : - fuzzymatch(node.name, valid_bindings) - ); + constructor(component, parent, scope, info) { + super(component, parent, scope, info); + Window.prototype.__init.call(this); + Window.prototype.__init2.call(this); + Window.prototype.__init3.call(this); + 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? + component.error(node.expression, { + code: 'invalid-binding', + message: `Bindings on <svelte:window> must be to top-level properties, e.g. '${parts[parts.length - 1]}' rather than '${parts.join('.')}'`, + }); + } - const message = `'${node.name}' is not a valid binding on <svelte:window>`; + if (!~valid_bindings.indexOf(node.name)) { + const match = node.name === 'width' ? 'innerWidth' : node.name === 'height' ? 'innerHeight' : fuzzymatch(node.name, valid_bindings); - if (match) { - component.error(node, { - code: 'invalid-binding', - message: `${message} (did you mean '${match}'?)` - }); - } else { - component.error(node, { - code: 'invalid-binding', - message: `${message} — valid bindings are ${list(valid_bindings)}` - }); - } - } + const message = `'${node.name}' is not a valid binding on <svelte:window>`; - this.bindings.push(new Binding(component, this, scope, node)); - } else if (node.type === 'Action') { - this.actions.push(new Action(component, this, scope, node)); - } - }); - } + if (match) { + component.error(node, { + code: 'invalid-binding', + message: `${message} (did you mean '${match}'?)`, + }); + } else { + component.error(node, { + code: 'invalid-binding', + message: `${message} — 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)); + } + }); + } } function get_constructor(type) { - switch (type) { - case 'AwaitBlock': return AwaitBlock$1; - case 'Body': return Body; - case 'Comment': return Comment$1; - case 'EachBlock': return EachBlock$1; - case 'Element': return Element$1; - case 'Head': return Head$1; - case 'IfBlock': return IfBlock$1; - case 'InlineComponent': return InlineComponent$1; - case 'KeyBlock': return KeyBlock$1; - case 'MustacheTag': return MustacheTag; - case 'Options': return Options; - case 'RawMustacheTag': return RawMustacheTag; - case 'DebugTag': return DebugTag$1; - case 'Slot': return Slot$1; - case 'SlotTemplate': return SlotTemplate; - case 'Text': return Text; - case 'Title': return Title; - case 'Window': return Window; - default: throw new Error(`Not implemented: ${type}`); - } + switch (type) { + case 'AwaitBlock': + return AwaitBlock$1; + case 'Body': + return Body; + case 'Comment': + return Comment$1; + case 'EachBlock': + return EachBlock$1; + case 'Element': + return Element$1; + case 'Head': + return Head$1; + case 'IfBlock': + return IfBlock$1; + case 'InlineComponent': + return InlineComponent$1; + case 'KeyBlock': + return KeyBlock$1; + case 'MustacheTag': + return MustacheTag; + case 'Options': + return Options; + case 'RawMustacheTag': + return RawMustacheTag; + case 'DebugTag': + return DebugTag$1; + case 'Slot': + return Slot$1; + case 'SlotTemplate': + return SlotTemplate; + case 'Text': + return Text; + case 'Title': + return Title; + case 'Window': + return Window; + default: + throw new Error(`Not implemented: ${type}`); + } } function map_children(component, parent, scope, children) { - let last = null; - let ignores = []; + let last = null; + let ignores = []; - return children.map(child => { - const constructor = get_constructor(child.type); + return children.map((child) => { + const constructor = get_constructor(child.type); - const use_ignores = child.type !== 'Text' && child.type !== 'Comment' && ignores.length; + 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 (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) { - ignores.push(...node.ignores); - } + if (node.type === 'Comment' && node.ignores.length) { + ignores.push(...node.ignores); + } - if (last) last.next = node; - node.prev = last; - last = node; + if (last) last.next = node; + node.prev = last; + last = node; - return node; - }); + return node; + }); } class SlotTemplate extends Node { - - - - __init() {this.lets = [];} - - __init2() {this.slot_template_name = 'default';} - - constructor( - component, - parent, - scope, - info - ) { - super(component, parent, scope, info);SlotTemplate.prototype.__init.call(this);SlotTemplate.prototype.__init2.call(this); - this.validate_slot_template_placement(); - - const has_let = info.attributes.some((node) => node.type === 'Let'); - if (has_let) { - scope = scope.child(); - } + __init() { + this.lets = []; + } - 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]); + __init2() { + this.slot_template_name = 'default'; + } - 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) { - component.error(node, { - code: 'invalid-slot-attribute', - message: 'slot attribute cannot have a dynamic value' - }); - } - const value = this.slot_attribute.get_static_value(); - if (typeof value === 'boolean') { - component.error(node, { - code: 'invalid-slot-attribute', - message: 'slot attribute value is missing' - }); - } - this.slot_template_name = value ; - break; - } - throw new Error(`Invalid attribute '${node.name}' in <svelte:fragment>`); - } - default: - throw new Error(`Not implemented: ${node.type}`); - } - }); + constructor(component, parent, scope, info) { + super(component, parent, scope, info); + SlotTemplate.prototype.__init.call(this); + SlotTemplate.prototype.__init2.call(this); + this.validate_slot_template_placement(); - this.scope = scope; - this.children = map_children(component, this, this.scope, info.children); - } + const has_let = info.attributes.some((node) => node.type === 'Let'); + if (has_let) { + scope = scope.child(); + } - validate_slot_template_placement() { - if (this.parent.type !== 'InlineComponent') { - this.component.error(this, { - code: 'invalid-slotted-content', - message: '<svelte:fragment> must be a child of a component' - }); - } - } -} + 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]); -function SlotTemplate$1(node, renderer, options + 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) { + component.error(node, { + code: 'invalid-slot-attribute', + message: 'slot attribute cannot have a dynamic value', + }); + } + const value = this.slot_attribute.get_static_value(); + if (typeof value === 'boolean') { + component.error(node, { + code: 'invalid-slot-attribute', + message: 'slot attribute value is missing', + }); + } + this.slot_template_name = value; + break; + } + throw new Error(`Invalid attribute '${node.name}' in <svelte:fragment>`); + } + default: + throw new Error(`Not implemented: ${node.type}`); + } + }); -) { - const parent_inline_component = node.parent ; - const children = remove_whitespace_children(node instanceof SlotTemplate ? node.children : [node], node.next); + this.scope = scope; + this.children = map_children(component, this, this.scope, info.children); + } - renderer.push(); - renderer.render(children, options); + validate_slot_template_placement() { + if (this.parent.type !== 'InlineComponent') { + this.component.error(this, { + code: 'invalid-slotted-content', + message: '<svelte:fragment> must be a child of a component', + }); + } + } +} - const lets = node.lets; - const seen = new Set(lets.map(l => l.name.name)); - parent_inline_component.lets.forEach(l => { - if (!seen.has(l.name.name)) lets.push(l); - }); +function SlotTemplate$1(node, renderer, options) { + const parent_inline_component = node.parent; + const children = remove_whitespace_children(node instanceof SlotTemplate ? node.children : [node], node.next); - const slot_fragment_content = renderer.pop(); - if (!is_empty_template_literal(slot_fragment_content)) { - if (options.slot_scopes.has(node.slot_template_name)) { - if (node.slot_template_name === 'default') { - throw new Error('Found elements without slot attribute when using slot="default"'); - } - throw new Error(`Duplicate slot name "${node.slot_template_name}" in <${parent_inline_component.name}>`); - } + renderer.push(); + renderer.render(children, options); - options.slot_scopes.set(node.slot_template_name, { - input: get_slot_scope(node.lets), - output: slot_fragment_content - }); - } + const lets = node.lets; + const seen = new Set(lets.map((l) => l.name.name)); + parent_inline_component.lets.forEach((l) => { + if (!seen.has(l.name.name)) lets.push(l); + }); + + const slot_fragment_content = renderer.pop(); + if (!is_empty_template_literal(slot_fragment_content)) { + if (options.slot_scopes.has(node.slot_template_name)) { + if (node.slot_template_name === 'default') { + throw new Error('Found elements without slot attribute when using slot="default"'); + } + throw new Error(`Duplicate slot name "${node.slot_template_name}" in <${parent_inline_component.name}>`); + } + + options.slot_scopes.set(node.slot_template_name, { + input: get_slot_scope(node.lets), + output: slot_fragment_content, + }); + } } function is_empty_template_literal(template_literal) { - return ( - template_literal.expressions.length === 0 && - template_literal.quasis.length === 1 && - template_literal.quasis[0].value.raw === '' - ); + return template_literal.expressions.length === 0 && template_literal.quasis.length === 1 && template_literal.quasis[0].value.raw === ''; } function Tag$2(node, renderer, _options) { - const snippet = node.expression.node; + const snippet = node.expression.node; - renderer.add_expression( - node.parent && - node.parent.type === 'Element' && - node.parent.name === 'style' - ? snippet - : x`@escape(${snippet})` - ); + renderer.add_expression(node.parent && node.parent.type === 'Element' && node.parent.name === 'style' ? snippet : x`@escape(${snippet})`); } function Text$1(node, renderer, _options) { - let text = node.data; - if ( - !node.parent || - node.parent.type !== 'Element' || - ((node.parent ).name !== 'script' && (node.parent ).name !== 'style') - ) { - // unless this Text node is inside a <script> or <style> element, escape &,<,> - text = escape_html(text); - } + let text = node.data; + if (!node.parent || node.parent.type !== 'Element' || (node.parent.name !== 'script' && node.parent.name !== 'style')) { + // unless this Text node is inside a <script> or <style> element, escape &,<,> + text = escape_html(text); + } - renderer.add_string(text); + renderer.add_string(text); } function Title$1(node, renderer, options) { - renderer.push(); + renderer.push(); - renderer.add_string('<title>'); + renderer.add_string('<title>'); - renderer.render(node.children, options); + renderer.render(node.children, options); - renderer.add_string('</title>'); - const result = renderer.pop(); + renderer.add_string('</title>'); + const result = renderer.pop(); - renderer.add_expression(x`$$result.title = ${result}, ""`); + renderer.add_expression(x`$$result.title = ${result}, ""`); } function noop() {} const handlers$1 = { - AwaitBlock, - Body: noop, - Comment, - DebugTag, - EachBlock, - Element, - Head, - IfBlock, - InlineComponent, - KeyBlock, - MustacheTag: Tag$2, // TODO MustacheTag is an anachronism - Options: noop, - RawMustacheTag: HtmlTag, - Slot, - SlotTemplate: SlotTemplate$1, - Text: Text$1, - Title: Title$1, - Window: noop + AwaitBlock, + Body: noop, + Comment, + DebugTag, + EachBlock, + Element, + Head, + IfBlock, + InlineComponent, + KeyBlock, + MustacheTag: Tag$2, // TODO MustacheTag is an anachronism + Options: noop, + RawMustacheTag: HtmlTag, + Slot, + SlotTemplate: SlotTemplate$1, + Text: Text$1, + Title: Title$1, + Window: noop, }; - - - - - class Renderer$1 { - __init() {this.has_bindings = false;} + __init() { + this.has_bindings = false; + } - + __init2() { + this.stack = []; + } + // TODO can it just be `current: string`? - __init2() {this.stack = [];} - // TODO can it just be `current: string`? - + __init3() { + this.targets = []; + } - __init3() {this.targets = [];} + constructor({ name }) { + Renderer$1.prototype.__init.call(this); + Renderer$1.prototype.__init2.call(this); + Renderer$1.prototype.__init3.call(this); + this.name = name; + this.push(); + } - constructor({ name }) {Renderer$1.prototype.__init.call(this);Renderer$1.prototype.__init2.call(this);Renderer$1.prototype.__init3.call(this); - this.name = name; - this.push(); - } + add_string(str) { + this.current.value += escape_template(str); + } - add_string(str) { - this.current.value += escape_template(str); - } + add_expression(node) { + this.literal.quasis.push({ + type: 'TemplateElement', + value: { raw: this.current.value, cooked: null }, + tail: false, + }); - add_expression(node) { - this.literal.quasis.push({ - type: 'TemplateElement', - value: { raw: this.current.value, cooked: null }, - tail: false - }); + this.literal.expressions.push(node); + this.current.value = ''; + } - this.literal.expressions.push(node); - this.current.value = ''; - } + push() { + const current = (this.current = { value: '' }); - push() { - const current = this.current = { value: '' }; + const literal = (this.literal = { + type: 'TemplateLiteral', + expressions: [], + quasis: [], + }); - const literal = this.literal = { - type: 'TemplateLiteral', - expressions: [], - quasis: [] - }; + this.stack.push({ current, literal }); + } - this.stack.push({ current, literal }); - } + pop() { + this.literal.quasis.push({ + type: 'TemplateElement', + value: { raw: this.current.value, cooked: null }, + tail: true, + }); - pop() { - this.literal.quasis.push({ - type: 'TemplateElement', - value: { raw: this.current.value, cooked: null }, - tail: true - }); + const popped = this.stack.pop(); + const last = this.stack[this.stack.length - 1]; - const popped = this.stack.pop(); - const last = this.stack[this.stack.length - 1]; + if (last) { + this.literal = last.literal; + this.current = last.current; + } - if (last) { - this.literal = last.literal; - this.current = last.current; - } + return popped.literal; + } - return popped.literal; - } + render(nodes, options) { + nodes.forEach((node) => { + const handler = handlers$1[node.type]; - render(nodes, options) { - nodes.forEach(node => { - const handler = handlers$1[node.type]; + if (!handler) { + throw new Error(`No handler for '${node.type}' nodes`); + } - if (!handler) { - throw new Error(`No handler for '${node.type}' nodes`); - } + handler(node, this, options); + }); + } +} - handler(node, this, options); - }); - } -} - -function ssr( - component, - options -) { - const renderer = new Renderer$1({ - name: component.name - }); - - const { name } = component; - - // create $$render function - renderer.render(trim(component.fragment.children), Object.assign({ - locate: component.locate - }, options)); - - // TODO put this inside the Renderer class - const literal = renderer.pop(); - - // TODO concatenate CSS maps - const css = options.customElement ? - { code: null, map: null } : - component.stylesheet.render(options.filename, true); - - const uses_rest = component.var_lookup.has('$$restProps'); - const props = component.vars.filter(variable => !variable.module && variable.export_name); - const rest = uses_rest ? b`let $$restProps = @compute_rest_props($$props, [${props.map(prop => `"${prop.export_name}"`).join(',')}]);` : null; - - const uses_slots = component.var_lookup.has('$$slots'); - const slots = uses_slots ? b`let $$slots = @compute_slots(#slots);` : null; - - const reactive_stores = component.vars.filter(variable => variable.name[0] === '$' && variable.name[1] !== '$'); - const reactive_store_subscriptions = reactive_stores - .filter(store => { - const variable = component.var_lookup.get(store.name.slice(1)); - return !variable || variable.hoistable; - }) - .map(({ name }) => { - const store_name = name.slice(1); - return b` +function ssr(component, options) { + const renderer = new Renderer$1({ + name: component.name, + }); + + const { name } = component; + + // create $$render function + renderer.render( + trim(component.fragment.children), + Object.assign( + { + locate: component.locate, + }, + options + ) + ); + + // TODO put this inside the Renderer class + const literal = renderer.pop(); + + // TODO concatenate CSS maps + const css = options.customElement ? { code: null, map: null } : component.stylesheet.render(options.filename, true); + + const uses_rest = component.var_lookup.has('$$restProps'); + const props = component.vars.filter((variable) => !variable.module && variable.export_name); + const rest = uses_rest ? b`let $$restProps = @compute_rest_props($$props, [${props.map((prop) => `"${prop.export_name}"`).join(',')}]);` : null; + + const uses_slots = component.var_lookup.has('$$slots'); + const slots = uses_slots ? b`let $$slots = @compute_slots(#slots);` : null; + + const reactive_stores = component.vars.filter((variable) => variable.name[0] === '$' && variable.name[1] !== '$'); + const reactive_store_subscriptions = reactive_stores + .filter((store) => { + const variable = component.var_lookup.get(store.name.slice(1)); + return !variable || variable.hoistable; + }) + .map(({ name }) => { + const store_name = name.slice(1); + return b` ${component.compile_options.dev && b`@validate_store(${store_name}, '${store_name}');`} ${`$$unsubscribe_${store_name}`} = @subscribe(${store_name}, #value => ${name} = #value) `; - }); - const reactive_store_unsubscriptions = reactive_stores.map( - ({ name }) => b`${`$$unsubscribe_${name.slice(1)}`}()` - ); - - const reactive_store_declarations = reactive_stores - .map(({ name }) => { - const store_name = name.slice(1); - const store = component.var_lookup.get(store_name); + }); + const reactive_store_unsubscriptions = reactive_stores.map(({ name }) => b`${`$$unsubscribe_${name.slice(1)}`}()`); - if (store && store.reassigned) { - const unsubscribe = `$$unsubscribe_${store_name}`; - const subscribe = `$$subscribe_${store_name}`; + const reactive_store_declarations = reactive_stores.map(({ name }) => { + const store_name = name.slice(1); + const store = component.var_lookup.get(store_name); - return b`let ${name}, ${unsubscribe} = @noop, ${subscribe} = () => (${unsubscribe}(), ${unsubscribe} = @subscribe(${store_name}, $$value => ${name} = $$value), ${store_name})`; - } - return b`let ${name}, ${`$$unsubscribe_${store_name}`};`; - }); + if (store && store.reassigned) { + const unsubscribe = `$$unsubscribe_${store_name}`; + const subscribe = `$$subscribe_${store_name}`; - // instrument get/set store value - if (component.ast.instance) { - let scope = component.instance_scope; - const map = component.instance_scope_map; + return b`let ${name}, ${unsubscribe} = @noop, ${subscribe} = () => (${unsubscribe}(), ${unsubscribe} = @subscribe(${store_name}, $$value => ${name} = $$value), ${store_name})`; + } + return b`let ${name}, ${`$$unsubscribe_${store_name}`};`; + }); + + // instrument get/set store value + if (component.ast.instance) { + let scope = component.instance_scope; + const map = component.instance_scope_map; + + walk(component.ast.instance.content, { + enter(node) { + if (map.has(node)) { + scope = map.get(node); + } + }, + leave(node) { + if (map.has(node)) { + scope = scope.parent; + } - walk(component.ast.instance.content, { - enter(node) { - if (map.has(node)) { - scope = map.get(node); - } - }, - leave(node) { - if (map.has(node)) { - scope = scope.parent; - } + if (node.type === 'AssignmentExpression' || node.type === 'UpdateExpression') { + const assignee = node.type === 'AssignmentExpression' ? node.left : node.argument; + const names = new Set(extract_names(assignee)); + const to_invalidate = new Set(); - if (node.type === 'AssignmentExpression' || node.type === 'UpdateExpression') { - const assignee = node.type === 'AssignmentExpression' ? node.left : node.argument; - const names = new Set(extract_names(assignee)); - const to_invalidate = new Set(); - - for (const name of names) { - const variable = component.var_lookup.get(name); - if (variable && - !variable.hoistable && - !variable.global && - !variable.module && - ( - variable.subscribable || variable.name[0] === '$' - )) { - to_invalidate.add(variable.name); - } - } + for (const name of names) { + const variable = component.var_lookup.get(name); + if (variable && !variable.hoistable && !variable.global && !variable.module && (variable.subscribable || variable.name[0] === '$')) { + to_invalidate.add(variable.name); + } + } - if (to_invalidate.size) { - this.replace( - invalidate( - { component } , - scope, - node, - to_invalidate, - true - ) - ); - } - } - } - }); - } + if (to_invalidate.size) { + this.replace(invalidate({ component }, scope, node, to_invalidate, true)); + } + } + }, + }); + } - component.rewrite_props(({ name, reassigned }) => { - const value = `$${name}`; + component.rewrite_props(({ name, reassigned }) => { + const value = `$${name}`; - let insert = reassigned - ? b`${`$$subscribe_${name}`}()` - : b`${`$$unsubscribe_${name}`} = @subscribe(${name}, #value => $${value} = #value)`; + let insert = reassigned ? b`${`$$subscribe_${name}`}()` : b`${`$$unsubscribe_${name}`} = @subscribe(${name}, #value => $${value} = #value)`; - if (component.compile_options.dev) { - insert = b`@validate_store(${name}, '${name}'); ${insert}`; - } + if (component.compile_options.dev) { + insert = b`@validate_store(${name}, '${name}'); ${insert}`; + } - return insert; - }); + return insert; + }); - const instance_javascript = component.extract_javascript(component.ast.instance); + const instance_javascript = component.extract_javascript(component.ast.instance); - // TODO only do this for props with a default value - const parent_bindings = instance_javascript - ? component.vars - .filter(variable => !variable.module && variable.export_name) - .map(prop => { - return b`if ($$props.${prop.export_name} === void 0 && $$bindings.${prop.export_name} && ${prop.name} !== void 0) $$bindings.${prop.export_name}(${prop.name});`; - }) - : []; + // TODO only do this for props with a default value + const parent_bindings = instance_javascript + ? component.vars + .filter((variable) => !variable.module && variable.export_name) + .map((prop) => { + return b`if ($$props.${prop.export_name} === void 0 && $$bindings.${prop.export_name} && ${prop.name} !== void 0) $$bindings.${prop.export_name}(${prop.name});`; + }) + : []; - const injected = Array.from(component.injected_reactive_declaration_vars).filter(name => { - const variable = component.var_lookup.get(name); - return variable.injected; - }); + const injected = Array.from(component.injected_reactive_declaration_vars).filter((name) => { + const variable = component.var_lookup.get(name); + return variable.injected; + }); - const reactive_declarations = component.reactive_declarations.map(d => { - const body = (d.node ).body; + const reactive_declarations = component.reactive_declarations.map((d) => { + const body = d.node.body; - let statement = b`${body}`; + let statement = b`${body}`; - if (!d.declaration) { // TODO do not add label if it's not referenced - statement = b`$: { ${statement} }`; - } + if (!d.declaration) { + // TODO do not add label if it's not referenced + statement = b`$: { ${statement} }`; + } - return statement; - }); + return statement; + }); - const main = renderer.has_bindings - ? b` + const main = renderer.has_bindings + ? b` let $$settled; let $$rendered; @@ -19078,31 +17709,35 @@ function ssr( return $$rendered; ` - : b` + : b` ${reactive_declarations} ${reactive_store_unsubscriptions} return ${literal};`; - const blocks = [ - ...injected.map(name => b`let ${name};`), - rest, - slots, - ...reactive_store_declarations, - ...reactive_store_subscriptions, - instance_javascript, - ...parent_bindings, - css.code && b`$$result.css.add(#css);`, - main - ].filter(Boolean); - - const js = b` - ${css.code ? b` + const blocks = [ + ...injected.map((name) => b`let ${name};`), + rest, + slots, + ...reactive_store_declarations, + ...reactive_store_subscriptions, + instance_javascript, + ...parent_bindings, + css.code && b`$$result.css.add(#css);`, + main, + ].filter(Boolean); + + const js = b` + ${ + css.code + ? b` const #css = { code: "${css.code}", map: ${css.map ? string_literal(css.map.toString()) : 'null'} - };` : null} + };` + : null + } ${component.extract_javascript(component.ast.module)} @@ -19113,133 +17748,107 @@ function ssr( }); `; - return {js, css}; + return { js, css }; } function trim(nodes) { - let start = 0; - for (; start < nodes.length; start += 1) { - const node = nodes[start] ; - if (node.type !== 'Text') break; + let start = 0; + for (; start < nodes.length; start += 1) { + const node = nodes[start]; + if (node.type !== 'Text') break; - node.data = node.data.replace(/^\s+/, ''); - if (node.data) break; - } + node.data = node.data.replace(/^\s+/, ''); + if (node.data) break; + } - let end = nodes.length; - for (; end > start; end -= 1) { - const node = nodes[end - 1] ; - if (node.type !== 'Text') break; + let end = nodes.length; + for (; end > start; end -= 1) { + const node = nodes[end - 1]; + if (node.type !== 'Text') break; - node.data = node.data.replace(/\s+$/, ''); - if (node.data) break; - } + node.data = node.data.replace(/\s+$/, ''); + if (node.data) break; + } - return nodes.slice(start, end); + return nodes.slice(start, end); } const wrappers$1 = { esm, cjs }; +function create_module(program, format, name, banner, sveltePath = 'svelte', helpers, globals, imports, module_exports) { + const internal_path = `${sveltePath}/internal`; + helpers.sort((a, b) => (a.name < b.name ? -1 : 1)); + globals.sort((a, b) => (a.name < b.name ? -1 : 1)); + if (format === 'esm') { + return esm(program, name, banner, sveltePath, internal_path, helpers, globals, imports, module_exports); + } + if (format === 'cjs') return cjs(program, name, banner, sveltePath, internal_path, helpers, globals, imports, module_exports); + throw new Error(`options.format is invalid (must be ${list(Object.keys(wrappers$1))})`); +} -function create_module( - program, - format, - name, - banner, - sveltePath = 'svelte', - helpers, - globals, - imports, - module_exports -) { - const internal_path = `${sveltePath}/internal`; - - helpers.sort((a, b) => (a.name < b.name) ? -1 : 1); - globals.sort((a, b) => (a.name < b.name) ? -1 : 1); +function edit_source(source, sveltePath) { + return source === 'svelte' || source.startsWith('svelte/') ? source.replace('svelte', sveltePath) : source; +} + +function get_internal_globals(globals, helpers) { + return ( + globals.length > 0 && { + type: 'VariableDeclaration', + kind: 'const', + declarations: [ + { + type: 'VariableDeclarator', + id: { + type: 'ObjectPattern', + properties: globals.map((g) => ({ + type: 'Property', + method: false, + shorthand: false, + computed: false, + key: { type: 'Identifier', name: g.name }, + value: g.alias, + kind: 'init', + })), + }, + init: helpers.find(({ name }) => name === 'globals').alias, + }, + ], + } + ); +} + +function esm(program, name, banner, sveltePath, internal_path, helpers, globals, imports, module_exports) { + const import_declaration = { + type: 'ImportDeclaration', + specifiers: helpers.map((h) => ({ + type: 'ImportSpecifier', + local: h.alias, + imported: { type: 'Identifier', name: h.name }, + })), + source: { type: 'Literal', value: internal_path }, + }; - if (format === 'esm') { - return esm(program, name, banner, sveltePath, internal_path, helpers, globals, imports, module_exports); - } + const internal_globals = get_internal_globals(globals, helpers); - if (format === 'cjs') return cjs(program, name, banner, sveltePath, internal_path, helpers, globals, imports, module_exports); + // edit user imports + imports.forEach((node) => { + node.source.value = edit_source(node.source.value, sveltePath); + }); - throw new Error(`options.format is invalid (must be ${list(Object.keys(wrappers$1))})`); -} + const exports = module_exports.length > 0 && { + type: 'ExportNamedDeclaration', + specifiers: module_exports.map((x) => ({ + type: 'Specifier', + local: { type: 'Identifier', name: x.name }, + exported: { type: 'Identifier', name: x.as }, + })), + }; -function edit_source(source, sveltePath) { - return source === 'svelte' || source.startsWith('svelte/') - ? source.replace('svelte', sveltePath) - : source; -} - -function get_internal_globals( - globals, - helpers -) { - return globals.length > 0 && { - type: 'VariableDeclaration', - kind: 'const', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'ObjectPattern', - properties: globals.map(g => ({ - type: 'Property', - method: false, - shorthand: false, - computed: false, - key: { type: 'Identifier', name: g.name }, - value: g.alias, - kind: 'init' - })) - }, - init: helpers.find(({ name }) => name === 'globals').alias - }] - }; -} - -function esm( - program, - name, - banner, - sveltePath, - internal_path, - helpers, - globals, - imports, - module_exports -) { - const import_declaration = { - type: 'ImportDeclaration', - specifiers: helpers.map(h => ({ - type: 'ImportSpecifier', - local: h.alias, - imported: { type: 'Identifier', name: h.name } - })), - source: { type: 'Literal', value: internal_path } - }; - - const internal_globals = get_internal_globals(globals, helpers); - - // edit user imports - imports.forEach(node => { - node.source.value = edit_source(node.source.value, sveltePath); - }); - - const exports = module_exports.length > 0 && { - type: 'ExportNamedDeclaration', - specifiers: module_exports.map(x => ({ - type: 'Specifier', - local: { type: 'Identifier', name: x.name }, - exported: { type: 'Identifier', name: x.as } - })) - }; - - program.body = b` + program.body = b` /* ${banner} */ ${import_declaration} @@ -19253,72 +17862,67 @@ function esm( `; } -function cjs( - program, - name, - banner, - sveltePath, - internal_path, - helpers, - globals, - imports, - module_exports -) { - const internal_requires = { - type: 'VariableDeclaration', - kind: 'const', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'ObjectPattern', - properties: helpers.map(h => ({ - type: 'Property', - method: false, - shorthand: false, - computed: false, - key: { type: 'Identifier', name: h.name }, - value: h.alias, - kind: 'init' - })) - }, - init: x`require("${internal_path}")` - }] - }; - - const internal_globals = get_internal_globals(globals, helpers); - - const user_requires = imports.map(node => { - const init = x`require("${edit_source(node.source.value, sveltePath)}")`; - if (node.specifiers.length === 0) { - return b`${init};`; - } - return { - type: 'VariableDeclaration', - kind: 'const', - declarations: [{ - type: 'VariableDeclarator', - id: node.specifiers[0].type === 'ImportNamespaceSpecifier' - ? { type: 'Identifier', name: node.specifiers[0].local.name } - : { - type: 'ObjectPattern', - properties: node.specifiers.map(s => ({ - type: 'Property', - method: false, - shorthand: false, - computed: false, - key: s.type === 'ImportSpecifier' ? s.imported : { type: 'Identifier', name: 'default' }, - value: s.local, - kind: 'init' - })) - }, - init - }] - }; - }); - - const exports = module_exports.map(x => b`exports.${{ type: 'Identifier', name: x.as }} = ${{ type: 'Identifier', name: x.name }};`); - - program.body = b` +function cjs(program, name, banner, sveltePath, internal_path, helpers, globals, imports, module_exports) { + const internal_requires = { + type: 'VariableDeclaration', + kind: 'const', + declarations: [ + { + type: 'VariableDeclarator', + id: { + type: 'ObjectPattern', + properties: helpers.map((h) => ({ + type: 'Property', + method: false, + shorthand: false, + computed: false, + key: { type: 'Identifier', name: h.name }, + value: h.alias, + kind: 'init', + })), + }, + init: x`require("${internal_path}")`, + }, + ], + }; + + const internal_globals = get_internal_globals(globals, helpers); + + const user_requires = imports.map((node) => { + const init = x`require("${edit_source(node.source.value, sveltePath)}")`; + if (node.specifiers.length === 0) { + return b`${init};`; + } + return { + type: 'VariableDeclaration', + kind: 'const', + declarations: [ + { + type: 'VariableDeclarator', + id: + node.specifiers[0].type === 'ImportNamespaceSpecifier' + ? { type: 'Identifier', name: node.specifiers[0].local.name } + : { + type: 'ObjectPattern', + properties: node.specifiers.map((s) => ({ + type: 'Property', + method: false, + shorthand: false, + computed: false, + key: s.type === 'ImportSpecifier' ? s.imported : { type: 'Identifier', name: 'default' }, + value: s.local, + kind: 'init', + })), + }, + init, + }, + ], + }; + }); + + const exports = module_exports.map((x) => b`exports.${{ type: 'Identifier', name: x.as }} = ${{ type: 'Identifier', name: x.name }};`); + + program.body = b` /* ${banner} */ "use strict"; @@ -19336,2802 +17940,2844 @@ function cjs( const UNKNOWN = {}; function gather_possible_values(node, set) { - if (node.type === 'Literal') { - set.add(node.value); - } else if (node.type === 'ConditionalExpression') { - gather_possible_values(node.consequent, set); - gather_possible_values(node.alternate, set); - } else { - set.add(UNKNOWN); - } -} - -var BlockAppliesToNode; (function (BlockAppliesToNode) { - const NotPossible = 0; BlockAppliesToNode[BlockAppliesToNode["NotPossible"] = NotPossible] = "NotPossible"; - const Possible = NotPossible + 1; BlockAppliesToNode[BlockAppliesToNode["Possible"] = Possible] = "Possible"; - const UnknownSelectorType = Possible + 1; BlockAppliesToNode[BlockAppliesToNode["UnknownSelectorType"] = UnknownSelectorType] = "UnknownSelectorType"; + if (node.type === 'Literal') { + set.add(node.value); + } else if (node.type === 'ConditionalExpression') { + gather_possible_values(node.consequent, set); + gather_possible_values(node.alternate, set); + } else { + set.add(UNKNOWN); + } +} + +var BlockAppliesToNode; +(function (BlockAppliesToNode) { + const NotPossible = 0; + BlockAppliesToNode[(BlockAppliesToNode['NotPossible'] = NotPossible)] = 'NotPossible'; + const Possible = NotPossible + 1; + BlockAppliesToNode[(BlockAppliesToNode['Possible'] = Possible)] = 'Possible'; + const UnknownSelectorType = Possible + 1; + BlockAppliesToNode[(BlockAppliesToNode['UnknownSelectorType'] = UnknownSelectorType)] = 'UnknownSelectorType'; })(BlockAppliesToNode || (BlockAppliesToNode = {})); -var NodeExist; (function (NodeExist) { - const Probably = 1; NodeExist[NodeExist["Probably"] = Probably] = "Probably"; - const Definitely = 2; NodeExist[NodeExist["Definitely"] = Definitely] = "Definitely"; +var NodeExist; +(function (NodeExist) { + const Probably = 1; + NodeExist[(NodeExist['Probably'] = Probably)] = 'Probably'; + const Definitely = 2; + NodeExist[(NodeExist['Definitely'] = Definitely)] = 'Definitely'; })(NodeExist || (NodeExist = {})); -const whitelist_attribute_selector = new Map([ - ['details', new Set(['open'])] -]); +const whitelist_attribute_selector = new Map([['details', new Set(['open'])]]); class Selector { - - - - - - - constructor(node, stylesheet) { - this.node = node; - this.stylesheet = stylesheet; - - this.blocks = group_selectors(node); - - // take trailing :global(...) selectors out of consideration - let i = this.blocks.length; - while (i > 0) { - if (!this.blocks[i - 1].global) break; - i -= 1; - } + constructor(node, stylesheet) { + this.node = node; + this.stylesheet = stylesheet; - this.local_blocks = this.blocks.slice(0, i); + this.blocks = group_selectors(node); - const host_only = this.blocks.length === 1 && this.blocks[0].host; + // take trailing :global(...) selectors out of consideration + let i = this.blocks.length; + while (i > 0) { + if (!this.blocks[i - 1].global) break; + i -= 1; + } - this.used = this.local_blocks.length === 0 || host_only; - } + this.local_blocks = this.blocks.slice(0, i); - apply(node) { - const to_encapsulate = []; + const host_only = this.blocks.length === 1 && this.blocks[0].host; - apply_selector(this.local_blocks.slice(), node, to_encapsulate); + this.used = this.local_blocks.length === 0 || host_only; + } - if (to_encapsulate.length > 0) { - to_encapsulate.forEach(({ node, block }) => { - this.stylesheet.nodes_with_css_class.add(node); - block.should_encapsulate = true; - }); + apply(node) { + const to_encapsulate = []; - this.used = true; - } - } - - minify(code) { - let c = null; - this.blocks.forEach((block, i) => { - if (i > 0) { - if (block.start - c > 1) { - code.overwrite(c, block.start, block.combinator.name || ' '); - } - } + apply_selector(this.local_blocks.slice(), node, to_encapsulate); - c = block.end; - }); - } + if (to_encapsulate.length > 0) { + to_encapsulate.forEach(({ node, block }) => { + this.stylesheet.nodes_with_css_class.add(node); + block.should_encapsulate = true; + }); - transform(code, attr, max_amount_class_specificity_increased) { - const amount_class_specificity_to_increase = max_amount_class_specificity_increased - this.blocks.filter(block => block.should_encapsulate).length; + this.used = true; + } + } - function encapsulate_block(block, attr) { - let i = block.selectors.length; + minify(code) { + let c = null; + this.blocks.forEach((block, i) => { + if (i > 0) { + if (block.start - c > 1) { + code.overwrite(c, block.start, block.combinator.name || ' '); + } + } - while (i--) { - const selector = block.selectors[i]; - if (selector.type === 'PseudoElementSelector' || selector.type === 'PseudoClassSelector') { - if (selector.name !== 'root' && selector.name !== 'host') { - if (i === 0) code.prependRight(selector.start, attr); - } - continue; - } + c = block.end; + }); + } - if (selector.type === 'TypeSelector' && selector.name === '*') { - code.overwrite(selector.start, selector.end, attr); - } else { - code.appendLeft(selector.end, attr); - } + transform(code, attr, max_amount_class_specificity_increased) { + const amount_class_specificity_to_increase = max_amount_class_specificity_increased - this.blocks.filter((block) => block.should_encapsulate).length; - break; - } - } + function encapsulate_block(block, attr) { + let i = block.selectors.length; - this.blocks.forEach((block, index) => { - if (block.global) { - const selector = block.selectors[0]; - const first = selector.children[0]; - const last = selector.children[selector.children.length - 1]; - code.remove(selector.start, first.start).remove(last.end, selector.end); - } - if (block.should_encapsulate) encapsulate_block(block, index === this.blocks.length - 1 ? attr.repeat(amount_class_specificity_to_increase + 1) : attr); - }); - } - - validate(component) { - this.blocks.forEach((block) => { - let i = block.selectors.length; - while (i-- > 1) { - const selector = block.selectors[i]; - if (selector.type === 'PseudoClassSelector' && selector.name === 'global') { - component.error(selector, { - code: 'css-invalid-global', - message: ':global(...) must be the first element in a compound selector' - }); - } - } - }); + while (i--) { + const selector = block.selectors[i]; + if (selector.type === 'PseudoElementSelector' || selector.type === 'PseudoClassSelector') { + if (selector.name !== 'root' && selector.name !== 'host') { + if (i === 0) code.prependRight(selector.start, attr); + } + continue; + } - let start = 0; - let end = this.blocks.length; + if (selector.type === 'TypeSelector' && selector.name === '*') { + code.overwrite(selector.start, selector.end, attr); + } else { + code.appendLeft(selector.end, attr); + } - for (; start < end; start += 1) { - if (!this.blocks[start].global) break; - } + break; + } + } - for (; end > start; end -= 1) { - if (!this.blocks[end - 1].global) break; - } + this.blocks.forEach((block, index) => { + if (block.global) { + const selector = block.selectors[0]; + const first = selector.children[0]; + const last = selector.children[selector.children.length - 1]; + code.remove(selector.start, first.start).remove(last.end, selector.end); + } + if (block.should_encapsulate) encapsulate_block(block, index === this.blocks.length - 1 ? attr.repeat(amount_class_specificity_to_increase + 1) : attr); + }); + } - for (let i = start; i < end; i += 1) { - if (this.blocks[i].global) { - component.error(this.blocks[i].selectors[0], { - code: 'css-invalid-global', - message: ':global(...) can be at the start or end of a selector sequence, but not in the middle' - }); - } - } - } + validate(component) { + this.blocks.forEach((block) => { + let i = block.selectors.length; + while (i-- > 1) { + const selector = block.selectors[i]; + if (selector.type === 'PseudoClassSelector' && selector.name === 'global') { + component.error(selector, { + code: 'css-invalid-global', + message: ':global(...) must be the first element in a compound selector', + }); + } + } + }); - get_amount_class_specificity_increased() { - let count = 0; - for (const block of this.blocks) { - if (block.should_encapsulate) { - count ++; - } - } - return count; - } + let start = 0; + let end = this.blocks.length; + + for (; start < end; start += 1) { + if (!this.blocks[start].global) break; + } + + for (; end > start; end -= 1) { + if (!this.blocks[end - 1].global) break; + } + + for (let i = start; i < end; i += 1) { + if (this.blocks[i].global) { + component.error(this.blocks[i].selectors[0], { + code: 'css-invalid-global', + message: ':global(...) can be at the start or end of a selector sequence, but not in the middle', + }); + } + } + } + + get_amount_class_specificity_increased() { + let count = 0; + for (const block of this.blocks) { + if (block.should_encapsulate) { + count++; + } + } + return count; + } } function apply_selector(blocks, node, to_encapsulate) { - const block = blocks.pop(); - if (!block) return false; + const block = blocks.pop(); + if (!block) return false; - if (!node) { - return ( - (block.global && blocks.every(block => block.global)) || - (block.host && blocks.length === 0) - ); - } - - switch (block_might_apply_to_node(block, node)) { - case BlockAppliesToNode.NotPossible: - return false; - - case BlockAppliesToNode.UnknownSelectorType: - // bail. TODO figure out what these could be - to_encapsulate.push({ node, block }); - return true; - } - - if (block.combinator) { - if (block.combinator.type === 'WhiteSpace') { - for (const ancestor_block of blocks) { - if (ancestor_block.global) { - continue; - } + if (!node) { + return (block.global && blocks.every((block) => block.global)) || (block.host && blocks.length === 0); + } - if (ancestor_block.host) { - to_encapsulate.push({ node, block }); - return true; - } + switch (block_might_apply_to_node(block, node)) { + case BlockAppliesToNode.NotPossible: + return false; - let parent = node; - while (parent = get_element_parent(parent)) { - if (block_might_apply_to_node(ancestor_block, parent) !== BlockAppliesToNode.NotPossible) { - to_encapsulate.push({ node: parent, block: ancestor_block }); - } - } + case BlockAppliesToNode.UnknownSelectorType: + // bail. TODO figure out what these could be + to_encapsulate.push({ node, block }); + return true; + } - if (to_encapsulate.length) { - to_encapsulate.push({ node, block }); - return true; - } - } + if (block.combinator) { + if (block.combinator.type === 'WhiteSpace') { + for (const ancestor_block of blocks) { + if (ancestor_block.global) { + continue; + } - if (blocks.every(block => block.global)) { - to_encapsulate.push({ node, block }); - return true; - } + if (ancestor_block.host) { + to_encapsulate.push({ node, block }); + return true; + } - return false; - } else if (block.combinator.name === '>') { - if (apply_selector(blocks, get_element_parent(node), to_encapsulate)) { - to_encapsulate.push({ node, block }); - return true; - } + let parent = node; + while ((parent = get_element_parent(parent))) { + if (block_might_apply_to_node(ancestor_block, parent) !== BlockAppliesToNode.NotPossible) { + to_encapsulate.push({ node: parent, block: ancestor_block }); + } + } - return false; - } else if (block.combinator.name === '+' || block.combinator.name === '~') { - const siblings = get_possible_element_siblings(node, block.combinator.name === '+'); - let has_match = false; - - // NOTE: if we have :global(), we couldn't figure out what is selected within `:global` due to the - // css-tree limitation that does not parse the inner selector of :global - // so unless we are sure there will be no sibling to match, we will consider it as matched - const has_global = blocks.some(block => block.global); - if (has_global) { - if (siblings.size === 0 && get_element_parent(node) !== null) { - return false; - } - to_encapsulate.push({ node, block }); - return true; - } + if (to_encapsulate.length) { + to_encapsulate.push({ node, block }); + return true; + } + } - for (const possible_sibling of siblings.keys()) { - if (apply_selector(blocks.slice(), possible_sibling, to_encapsulate)) { - to_encapsulate.push({ node, block }); - has_match = true; - } - } - return has_match; - } + if (blocks.every((block) => block.global)) { + to_encapsulate.push({ node, block }); + return true; + } - // TODO other combinators - to_encapsulate.push({ node, block }); - return true; - } + return false; + } else if (block.combinator.name === '>') { + if (apply_selector(blocks, get_element_parent(node), to_encapsulate)) { + to_encapsulate.push({ node, block }); + return true; + } - to_encapsulate.push({ node, block }); - return true; + return false; + } else if (block.combinator.name === '+' || block.combinator.name === '~') { + const siblings = get_possible_element_siblings(node, block.combinator.name === '+'); + let has_match = false; + + // NOTE: if we have :global(), we couldn't figure out what is selected within `:global` due to the + // css-tree limitation that does not parse the inner selector of :global + // so unless we are sure there will be no sibling to match, we will consider it as matched + const has_global = blocks.some((block) => block.global); + if (has_global) { + if (siblings.size === 0 && get_element_parent(node) !== null) { + return false; + } + to_encapsulate.push({ node, block }); + return true; + } + + for (const possible_sibling of siblings.keys()) { + if (apply_selector(blocks.slice(), possible_sibling, to_encapsulate)) { + to_encapsulate.push({ node, block }); + has_match = true; + } + } + return has_match; + } + + // TODO other combinators + to_encapsulate.push({ node, block }); + return true; + } + + to_encapsulate.push({ node, block }); + return true; } function block_might_apply_to_node(block, node) { - let i = block.selectors.length; + let i = block.selectors.length; - while (i--) { - const selector = block.selectors[i]; - const name = typeof selector.name === 'string' && selector.name.replace(/\\(.)/g, '$1'); + while (i--) { + const selector = block.selectors[i]; + const name = typeof selector.name === 'string' && selector.name.replace(/\\(.)/g, '$1'); - if (selector.type === 'PseudoClassSelector' && name === 'host') { - return BlockAppliesToNode.NotPossible; - } + if (selector.type === 'PseudoClassSelector' && name === 'host') { + return BlockAppliesToNode.NotPossible; + } - if (selector.type === 'PseudoClassSelector' || selector.type === 'PseudoElementSelector') { - continue; - } + if (selector.type === 'PseudoClassSelector' || selector.type === 'PseudoElementSelector') { + continue; + } - if (selector.type === 'PseudoClassSelector' && name === 'global') { - // TODO shouldn't see this here... maybe we should enforce that :global(...) - // cannot be sandwiched between non-global selectors? - return BlockAppliesToNode.NotPossible; - } + if (selector.type === 'PseudoClassSelector' && name === 'global') { + // TODO shouldn't see this here... maybe we should enforce that :global(...) + // cannot be sandwiched between non-global selectors? + return BlockAppliesToNode.NotPossible; + } - if (selector.type === 'ClassSelector') { - if (!attribute_matches(node, 'class', name, '~=', false) && !node.classes.some(c => c.name === name)) return BlockAppliesToNode.NotPossible; - } else if (selector.type === 'IdSelector') { - if (!attribute_matches(node, 'id', name, '=', false)) return BlockAppliesToNode.NotPossible; - } else if (selector.type === 'AttributeSelector') { - if ( - !(whitelist_attribute_selector.has(node.name.toLowerCase()) && whitelist_attribute_selector.get(node.name.toLowerCase()).has(selector.name.name.toLowerCase())) && - !attribute_matches(node, selector.name.name, selector.value && unquote(selector.value), selector.matcher, selector.flags)) { - return BlockAppliesToNode.NotPossible; - } - } else if (selector.type === 'TypeSelector') { - if (node.name.toLowerCase() !== name.toLowerCase() && name !== '*') return BlockAppliesToNode.NotPossible; - } else { - return BlockAppliesToNode.UnknownSelectorType; - } - } + if (selector.type === 'ClassSelector') { + if (!attribute_matches(node, 'class', name, '~=', false) && !node.classes.some((c) => c.name === name)) return BlockAppliesToNode.NotPossible; + } else if (selector.type === 'IdSelector') { + if (!attribute_matches(node, 'id', name, '=', false)) return BlockAppliesToNode.NotPossible; + } else if (selector.type === 'AttributeSelector') { + if ( + !(whitelist_attribute_selector.has(node.name.toLowerCase()) && whitelist_attribute_selector.get(node.name.toLowerCase()).has(selector.name.name.toLowerCase())) && + !attribute_matches(node, selector.name.name, selector.value && unquote(selector.value), selector.matcher, selector.flags) + ) { + return BlockAppliesToNode.NotPossible; + } + } else if (selector.type === 'TypeSelector') { + if (node.name.toLowerCase() !== name.toLowerCase() && name !== '*') return BlockAppliesToNode.NotPossible; + } else { + return BlockAppliesToNode.UnknownSelectorType; + } + } - return BlockAppliesToNode.Possible; + return BlockAppliesToNode.Possible; } function test_attribute(operator, expected_value, case_insensitive, value) { - if (case_insensitive) { - expected_value = expected_value.toLowerCase(); - value = value.toLowerCase(); - } - switch (operator) { - case '=': return value === expected_value; - case '~=': return value.split(/\s/).includes(expected_value); - case '|=': return `${value}-`.startsWith(`${expected_value}-`); - case '^=': return value.startsWith(expected_value); - case '$=': return value.endsWith(expected_value); - case '*=': return value.includes(expected_value); - default: throw new Error("this shouldn't happen"); - } + if (case_insensitive) { + expected_value = expected_value.toLowerCase(); + value = value.toLowerCase(); + } + switch (operator) { + case '=': + return value === expected_value; + case '~=': + return value.split(/\s/).includes(expected_value); + case '|=': + return `${value}-`.startsWith(`${expected_value}-`); + case '^=': + return value.startsWith(expected_value); + case '$=': + return value.endsWith(expected_value); + case '*=': + return value.includes(expected_value); + default: + throw new Error("this shouldn't happen"); + } } function attribute_matches(node, name, expected_value, operator, case_insensitive) { - const spread = node.attributes.find(attr => attr.type === 'Spread'); - if (spread) return true; - - if (node.bindings.some((binding) => binding.name === name)) return true; - - const attr = node.attributes.find((attr) => attr.name === name); - if (!attr) return false; - if (attr.is_true) return operator === null; - if (!expected_value) return true; - - if (attr.chunks.length === 1) { - const value = attr.chunks[0]; - if (!value) return false; - if (value.type === 'Text') return test_attribute(operator, expected_value, case_insensitive, value.data); - } - - const possible_values = new Set(); - - let prev_values = []; - for (const chunk of attr.chunks) { - const current_possible_values = new Set(); - if (chunk.type === 'Text') { - current_possible_values.add(chunk.data); - } else { - gather_possible_values(chunk.node, current_possible_values); - } + const spread = node.attributes.find((attr) => attr.type === 'Spread'); + if (spread) return true; - // impossible to find out all combinations - if (current_possible_values.has(UNKNOWN)) return true; + if (node.bindings.some((binding) => binding.name === name)) return true; - if (prev_values.length > 0) { - const start_with_space = []; - const remaining = []; - current_possible_values.forEach((current_possible_value) => { - if (/^\s/.test(current_possible_value)) { - start_with_space.push(current_possible_value); - } else { - remaining.push(current_possible_value); - } - }); + const attr = node.attributes.find((attr) => attr.name === name); + if (!attr) return false; + if (attr.is_true) return operator === null; + if (!expected_value) return true; - if (remaining.length > 0) { - if (start_with_space.length > 0) { - prev_values.forEach(prev_value => possible_values.add(prev_value)); - } + if (attr.chunks.length === 1) { + const value = attr.chunks[0]; + if (!value) return false; + if (value.type === 'Text') return test_attribute(operator, expected_value, case_insensitive, value.data); + } - const combined = []; - prev_values.forEach((prev_value) => { - remaining.forEach((value) => { - combined.push(prev_value + value); - }); - }); - prev_values = combined; + const possible_values = new Set(); - start_with_space.forEach((value) => { - if (/\s$/.test(value)) { - possible_values.add(value); - } else { - prev_values.push(value); - } - }); - continue; - } else { - prev_values.forEach(prev_value => possible_values.add(prev_value)); - prev_values = []; - } - } + let prev_values = []; + for (const chunk of attr.chunks) { + const current_possible_values = new Set(); + if (chunk.type === 'Text') { + current_possible_values.add(chunk.data); + } else { + gather_possible_values(chunk.node, current_possible_values); + } - current_possible_values.forEach((current_possible_value) => { - if (/\s$/.test(current_possible_value)) { - possible_values.add(current_possible_value); - } else { - prev_values.push(current_possible_value); - } - }); - if (prev_values.length < current_possible_values.size) { - prev_values.push(' '); - } + // impossible to find out all combinations + if (current_possible_values.has(UNKNOWN)) return true; - if (prev_values.length > 20) { - // might grow exponentially, bail out - return true; - } - } - prev_values.forEach(prev_value => possible_values.add(prev_value)); + if (prev_values.length > 0) { + const start_with_space = []; + const remaining = []; + current_possible_values.forEach((current_possible_value) => { + if (/^\s/.test(current_possible_value)) { + start_with_space.push(current_possible_value); + } else { + remaining.push(current_possible_value); + } + }); - if (possible_values.has(UNKNOWN)) return true; + if (remaining.length > 0) { + if (start_with_space.length > 0) { + prev_values.forEach((prev_value) => possible_values.add(prev_value)); + } - for (const value of possible_values) { - if (test_attribute(operator, expected_value, case_insensitive, value)) return true; - } + const combined = []; + prev_values.forEach((prev_value) => { + remaining.forEach((value) => { + combined.push(prev_value + value); + }); + }); + prev_values = combined; + + start_with_space.forEach((value) => { + if (/\s$/.test(value)) { + possible_values.add(value); + } else { + prev_values.push(value); + } + }); + continue; + } else { + prev_values.forEach((prev_value) => possible_values.add(prev_value)); + prev_values = []; + } + } - return false; + current_possible_values.forEach((current_possible_value) => { + if (/\s$/.test(current_possible_value)) { + possible_values.add(current_possible_value); + } else { + prev_values.push(current_possible_value); + } + }); + if (prev_values.length < current_possible_values.size) { + prev_values.push(' '); + } + + if (prev_values.length > 20) { + // might grow exponentially, bail out + return true; + } + } + prev_values.forEach((prev_value) => possible_values.add(prev_value)); + + if (possible_values.has(UNKNOWN)) return true; + + for (const value of possible_values) { + if (test_attribute(operator, expected_value, case_insensitive, value)) return true; + } + + return false; } function unquote(value) { - if (value.type === 'Identifier') return value.name; - const str = value.value; - if (str[0] === str[str.length - 1] && str[0] === "'" || str[0] === '"') { - return str.slice(1, str.length - 1); - } - return str; + if (value.type === 'Identifier') return value.name; + const str = value.value; + if ((str[0] === str[str.length - 1] && str[0] === "'") || str[0] === '"') { + return str.slice(1, str.length - 1); + } + return str; } function get_element_parent(node) { - let parent = node; - while ((parent = parent.parent) && parent.type !== 'Element'); - return parent ; + let parent = node; + while ((parent = parent.parent) && parent.type !== 'Element'); + return parent; } function get_possible_element_siblings(node, adjacent_only) { - const result = new Map(); - let prev = node; - while (prev = prev.prev) { - if (prev.type === 'Element') { - if (!prev.attributes.find(attr => attr.type === 'Attribute' && attr.name.toLowerCase() === 'slot')) { - result.set(prev, NodeExist.Definitely); - } + const result = new Map(); + let prev = node; + while ((prev = prev.prev)) { + if (prev.type === 'Element') { + if (!prev.attributes.find((attr) => attr.type === 'Attribute' && attr.name.toLowerCase() === 'slot')) { + result.set(prev, NodeExist.Definitely); + } - if (adjacent_only) { - break; - } - } else if (prev.type === 'EachBlock' || prev.type === 'IfBlock' || prev.type === 'AwaitBlock') { - const possible_last_child = get_possible_last_child(prev, adjacent_only); + if (adjacent_only) { + break; + } + } else if (prev.type === 'EachBlock' || prev.type === 'IfBlock' || prev.type === 'AwaitBlock') { + const possible_last_child = get_possible_last_child(prev, adjacent_only); - add_to_map(possible_last_child, result); - if (adjacent_only && has_definite_elements(possible_last_child)) { - return result; - } - } - } - - if (!prev || !adjacent_only) { - let parent = node; - let skip_each_for_last_child = node.type === 'ElseBlock'; - while ((parent = parent.parent) && (parent.type === 'EachBlock' || parent.type === 'IfBlock' || parent.type === 'ElseBlock' || parent.type === 'AwaitBlock')) { - const possible_siblings = get_possible_element_siblings(parent, adjacent_only); - add_to_map(possible_siblings, result); - - if (parent.type === 'EachBlock') { - // first child of each block can select the last child of each block as previous sibling - if (skip_each_for_last_child) { - skip_each_for_last_child = false; - } else { - add_to_map(get_possible_last_child(parent, adjacent_only), result); - } - } else if (parent.type === 'ElseBlock') { - skip_each_for_last_child = true; - parent = parent.parent; - } + add_to_map(possible_last_child, result); + if (adjacent_only && has_definite_elements(possible_last_child)) { + return result; + } + } + } - if (adjacent_only && has_definite_elements(possible_siblings)) { - break; - } - } - } + if (!prev || !adjacent_only) { + let parent = node; + let skip_each_for_last_child = node.type === 'ElseBlock'; + while ((parent = parent.parent) && (parent.type === 'EachBlock' || parent.type === 'IfBlock' || parent.type === 'ElseBlock' || parent.type === 'AwaitBlock')) { + const possible_siblings = get_possible_element_siblings(parent, adjacent_only); + add_to_map(possible_siblings, result); + + if (parent.type === 'EachBlock') { + // first child of each block can select the last child of each block as previous sibling + if (skip_each_for_last_child) { + skip_each_for_last_child = false; + } else { + add_to_map(get_possible_last_child(parent, adjacent_only), result); + } + } else if (parent.type === 'ElseBlock') { + skip_each_for_last_child = true; + parent = parent.parent; + } + + if (adjacent_only && has_definite_elements(possible_siblings)) { + break; + } + } + } - return result; + return result; } function get_possible_last_child(block, adjacent_only) { - const result = new Map(); + const result = new Map(); - if (block.type === 'EachBlock') { - const each_result = loop_child(block.children, adjacent_only); - const else_result = block.else ? loop_child(block.else.children, adjacent_only) : new Map(); - - const not_exhaustive = !has_definite_elements(else_result); + if (block.type === 'EachBlock') { + const each_result = loop_child(block.children, adjacent_only); + const else_result = block.else ? loop_child(block.else.children, adjacent_only) : new Map(); - if (not_exhaustive) { - mark_as_probably(each_result); - mark_as_probably(else_result); - } - add_to_map(each_result, result); - add_to_map(else_result, result); - } else if (block.type === 'IfBlock') { - const if_result = loop_child(block.children, adjacent_only); - const else_result = block.else ? loop_child(block.else.children, adjacent_only) : new Map(); + const not_exhaustive = !has_definite_elements(else_result); - const not_exhaustive = !has_definite_elements(if_result) || !has_definite_elements(else_result); + if (not_exhaustive) { + mark_as_probably(each_result); + mark_as_probably(else_result); + } + add_to_map(each_result, result); + add_to_map(else_result, result); + } else if (block.type === 'IfBlock') { + const if_result = loop_child(block.children, adjacent_only); + const else_result = block.else ? loop_child(block.else.children, adjacent_only) : new Map(); - if (not_exhaustive) { - mark_as_probably(if_result); - mark_as_probably(else_result); - } + const not_exhaustive = !has_definite_elements(if_result) || !has_definite_elements(else_result); - add_to_map(if_result, result); - add_to_map(else_result, result); - } else if (block.type === 'AwaitBlock') { - const pending_result = block.pending ? loop_child(block.pending.children, adjacent_only) : new Map(); - const then_result = block.then ? loop_child(block.then.children, adjacent_only) : new Map(); - const catch_result = block.catch ? loop_child(block.catch.children, adjacent_only) : new Map(); + if (not_exhaustive) { + mark_as_probably(if_result); + mark_as_probably(else_result); + } - const not_exhaustive = !has_definite_elements(pending_result) || !has_definite_elements(then_result) || !has_definite_elements(catch_result); + add_to_map(if_result, result); + add_to_map(else_result, result); + } else if (block.type === 'AwaitBlock') { + const pending_result = block.pending ? loop_child(block.pending.children, adjacent_only) : new Map(); + const then_result = block.then ? loop_child(block.then.children, adjacent_only) : new Map(); + const catch_result = block.catch ? loop_child(block.catch.children, adjacent_only) : new Map(); - if (not_exhaustive) { - mark_as_probably(pending_result); - mark_as_probably(then_result); - mark_as_probably(catch_result); - } + const not_exhaustive = !has_definite_elements(pending_result) || !has_definite_elements(then_result) || !has_definite_elements(catch_result); - add_to_map(pending_result, result); - add_to_map(then_result, result); - add_to_map(catch_result, result); - } + if (not_exhaustive) { + mark_as_probably(pending_result); + mark_as_probably(then_result); + mark_as_probably(catch_result); + } - return result; + add_to_map(pending_result, result); + add_to_map(then_result, result); + add_to_map(catch_result, result); + } + + return result; } function has_definite_elements(result) { - if (result.size === 0) return false; - for (const exist of result.values()) { - if (exist === NodeExist.Definitely) { - return true; - } - } - return false; + if (result.size === 0) return false; + for (const exist of result.values()) { + if (exist === NodeExist.Definitely) { + return true; + } + } + return false; } function add_to_map(from, to) { - from.forEach((exist, element) => { - to.set(element, higher_existance(exist, to.get(element))); - }); + from.forEach((exist, element) => { + to.set(element, higher_existance(exist, to.get(element))); + }); } function higher_existance(exist1, exist2) { - if (exist1 === undefined || exist2 === undefined) return exist1 || exist2; - return exist1 > exist2 ? exist1 : exist2; + if (exist1 === undefined || exist2 === undefined) return exist1 || exist2; + return exist1 > exist2 ? exist1 : exist2; } function mark_as_probably(result) { - for (const key of result.keys()) { - result.set(key, NodeExist.Probably); - } + for (const key of result.keys()) { + result.set(key, NodeExist.Probably); + } } function loop_child(children, adjacent_only) { - const result = new Map(); - for (let i = children.length - 1; i >= 0; i--) { - const child = children[i]; - if (child.type === 'Element') { - result.set(child, NodeExist.Definitely); - if (adjacent_only) { - break; - } - } else if (child.type === 'EachBlock' || child.type === 'IfBlock' || child.type === 'AwaitBlock') { - const child_result = get_possible_last_child(child, adjacent_only); - add_to_map(child_result, result); - if (adjacent_only && has_definite_elements(child_result)) { - break; - } - } - } - return result; + const result = new Map(); + for (let i = children.length - 1; i >= 0; i--) { + const child = children[i]; + if (child.type === 'Element') { + result.set(child, NodeExist.Definitely); + if (adjacent_only) { + break; + } + } else if (child.type === 'EachBlock' || child.type === 'IfBlock' || child.type === 'AwaitBlock') { + const child_result = get_possible_last_child(child, adjacent_only); + add_to_map(child_result, result); + if (adjacent_only && has_definite_elements(child_result)) { + break; + } + } + } + return result; } class Block$1 { - - - - - - - - - constructor(combinator) { - this.combinator = combinator; - this.global = false; - this.host = false; - this.selectors = []; - - this.start = null; - this.end = null; - - this.should_encapsulate = false; - } - - add(selector) { - if (this.selectors.length === 0) { - this.start = selector.start; - this.global = selector.type === 'PseudoClassSelector' && selector.name === 'global'; - this.host = selector.type === 'PseudoClassSelector' && selector.name === 'host'; - } + constructor(combinator) { + this.combinator = combinator; + this.global = false; + this.host = false; + this.selectors = []; + + this.start = null; + this.end = null; - this.selectors.push(selector); - this.end = selector.end; - } + this.should_encapsulate = false; + } + + add(selector) { + if (this.selectors.length === 0) { + this.start = selector.start; + this.global = selector.type === 'PseudoClassSelector' && selector.name === 'global'; + this.host = selector.type === 'PseudoClassSelector' && selector.name === 'host'; + } + + this.selectors.push(selector); + this.end = selector.end; + } } function group_selectors(selector) { - let block = new Block$1(null); + let block = new Block$1(null); - const blocks = [block]; + const blocks = [block]; - selector.children.forEach((child) => { - if (child.type === 'WhiteSpace' || child.type === 'Combinator') { - block = new Block$1(child); - blocks.push(block); - } else { - block.add(child); - } - }); + selector.children.forEach((child) => { + if (child.type === 'WhiteSpace' || child.type === 'Combinator') { + block = new Block$1(child); + blocks.push(block); + } else { + block.add(child); + } + }); - return blocks; + return blocks; } function remove_css_prefix(name) { - return name.replace(/^-((webkit)|(moz)|(o)|(ms))-/, ''); + return name.replace(/^-((webkit)|(moz)|(o)|(ms))-/, ''); } -const is_keyframes_node = (node) => - remove_css_prefix(node.name) === 'keyframes'; +const is_keyframes_node = (node) => remove_css_prefix(node.name) === 'keyframes'; -const at_rule_has_declaration = ({ block }) => - block && - block.children && - block.children.find((node) => node.type === 'Declaration'); +const at_rule_has_declaration = ({ block }) => block && block.children && block.children.find((node) => node.type === 'Declaration'); -function minify_declarations( - code, - start, - declarations -) { - let c = start; +function minify_declarations(code, start, declarations) { + let c = start; - declarations.forEach((declaration, i) => { - const separator = i > 0 ? ';' : ''; - if ((declaration.node.start - c) > separator.length) { - code.overwrite(c, declaration.node.start, separator); - } - declaration.minify(code); - c = declaration.node.end; - }); + declarations.forEach((declaration, i) => { + const separator = i > 0 ? ';' : ''; + if (declaration.node.start - c > separator.length) { + code.overwrite(c, declaration.node.start, separator); + } + declaration.minify(code); + c = declaration.node.end; + }); - return c; + return c; } class Rule { - - - - - - constructor(node, stylesheet, parent) { - this.node = node; - this.parent = parent; - this.selectors = node.prelude.children.map((node) => new Selector(node, stylesheet)); - this.declarations = node.block.children.map((node) => new Declaration(node)); - } - - apply(node) { - this.selectors.forEach(selector => selector.apply(node)); // TODO move the logic in here? - } - - is_used(dev) { - if (this.parent && this.parent.node.type === 'Atrule' && is_keyframes_node(this.parent.node)) return true; - if (this.declarations.length === 0) return dev; - return this.selectors.some(s => s.used); - } - - minify(code, _dev) { - let c = this.node.start; - let started = false; - - this.selectors.forEach((selector) => { - if (selector.used) { - const separator = started ? ',' : ''; - if ((selector.node.start - c) > separator.length) { - code.overwrite(c, selector.node.start, separator); - } + constructor(node, stylesheet, parent) { + this.node = node; + this.parent = parent; + this.selectors = node.prelude.children.map((node) => new Selector(node, stylesheet)); + this.declarations = node.block.children.map((node) => new Declaration(node)); + } - selector.minify(code); - c = selector.node.end; + apply(node) { + this.selectors.forEach((selector) => selector.apply(node)); // TODO move the logic in here? + } - started = true; - } - }); + is_used(dev) { + if (this.parent && this.parent.node.type === 'Atrule' && is_keyframes_node(this.parent.node)) return true; + if (this.declarations.length === 0) return dev; + return this.selectors.some((s) => s.used); + } - code.remove(c, this.node.block.start); + minify(code, _dev) { + let c = this.node.start; + let started = false; - c = this.node.block.start + 1; - c = minify_declarations(code, c, this.declarations); + this.selectors.forEach((selector) => { + if (selector.used) { + const separator = started ? ',' : ''; + if (selector.node.start - c > separator.length) { + code.overwrite(c, selector.node.start, separator); + } - code.remove(c, this.node.block.end - 1); - } + selector.minify(code); + c = selector.node.end; - transform(code, id, keyframes, max_amount_class_specificity_increased) { - if (this.parent && this.parent.node.type === 'Atrule' && is_keyframes_node(this.parent.node)) return true; + started = true; + } + }); - const attr = `.${id}`; + code.remove(c, this.node.block.start); - this.selectors.forEach(selector => selector.transform(code, attr, max_amount_class_specificity_increased)); - this.declarations.forEach(declaration => declaration.transform(code, keyframes)); - } + c = this.node.block.start + 1; + c = minify_declarations(code, c, this.declarations); - validate(component) { - this.selectors.forEach(selector => { - selector.validate(component); - }); - } + code.remove(c, this.node.block.end - 1); + } - warn_on_unused_selector(handler) { - this.selectors.forEach(selector => { - if (!selector.used) handler(selector); - }); - } + transform(code, id, keyframes, max_amount_class_specificity_increased) { + if (this.parent && this.parent.node.type === 'Atrule' && is_keyframes_node(this.parent.node)) return true; + + const attr = `.${id}`; + + this.selectors.forEach((selector) => selector.transform(code, attr, max_amount_class_specificity_increased)); + this.declarations.forEach((declaration) => declaration.transform(code, keyframes)); + } - get_max_amount_class_specificity_increased() { - return Math.max(...this.selectors.map(selector => selector.get_amount_class_specificity_increased())); - } + validate(component) { + this.selectors.forEach((selector) => { + selector.validate(component); + }); + } + + warn_on_unused_selector(handler) { + this.selectors.forEach((selector) => { + if (!selector.used) handler(selector); + }); + } + + get_max_amount_class_specificity_increased() { + return Math.max(...this.selectors.map((selector) => selector.get_amount_class_specificity_increased())); + } } class Declaration { - - - constructor(node) { - this.node = node; - } - - transform(code, keyframes) { - const property = this.node.property && remove_css_prefix(this.node.property.toLowerCase()); - if (property === 'animation' || property === 'animation-name') { - this.node.value.children.forEach((block) => { - if (block.type === 'Identifier') { - const name = block.name; - if (keyframes.has(name)) { - code.overwrite(block.start, block.end, keyframes.get(name)); - } - } - }); - } - } + constructor(node) { + this.node = node; + } - minify(code) { - if (!this.node.property) return; // @apply, and possibly other weird cases? + transform(code, keyframes) { + const property = this.node.property && remove_css_prefix(this.node.property.toLowerCase()); + if (property === 'animation' || property === 'animation-name') { + this.node.value.children.forEach((block) => { + if (block.type === 'Identifier') { + const name = block.name; + if (keyframes.has(name)) { + code.overwrite(block.start, block.end, keyframes.get(name)); + } + } + }); + } + } - const c = this.node.start + this.node.property.length; - const first = this.node.value.children - ? this.node.value.children[0] - : this.node.value; + minify(code) { + if (!this.node.property) return; // @apply, and possibly other weird cases? - let start = first.start; - while (/\s/.test(code.original[start])) start += 1; + const c = this.node.start + this.node.property.length; + const first = this.node.value.children ? this.node.value.children[0] : this.node.value; - if (start - c > 1) { - code.overwrite(c, start, ':'); - } - } + let start = first.start; + while (/\s/.test(code.original[start])) start += 1; + + if (start - c > 1) { + code.overwrite(c, start, ':'); + } + } } class Atrule { - - - - - constructor(node) { - this.node = node; - this.children = []; - this.declarations = []; - } - - apply(node) { - if (this.node.name === 'media' || this.node.name === 'supports') { - this.children.forEach(child => { - child.apply(node); - }); - } else if (is_keyframes_node(this.node)) { - this.children.forEach((rule) => { - rule.selectors.forEach(selector => { - selector.used = true; - }); - }); - } - } + constructor(node) { + this.node = node; + this.children = []; + this.declarations = []; + } - is_used(_dev) { - return true; // TODO - } + apply(node) { + if (this.node.name === 'media' || this.node.name === 'supports') { + this.children.forEach((child) => { + child.apply(node); + }); + } else if (is_keyframes_node(this.node)) { + this.children.forEach((rule) => { + rule.selectors.forEach((selector) => { + selector.used = true; + }); + }); + } + } - minify(code, dev) { - if (this.node.name === 'media') { - const expression_char = code.original[this.node.prelude.start]; - let c = this.node.start + (expression_char === '(' ? 6 : 7); - if (this.node.prelude.start > c) code.remove(c, this.node.prelude.start); + is_used(_dev) { + return true; // TODO + } - this.node.prelude.children.forEach((query) => { - // TODO minify queries - c = query.end; - }); + minify(code, dev) { + if (this.node.name === 'media') { + const expression_char = code.original[this.node.prelude.start]; + let c = this.node.start + (expression_char === '(' ? 6 : 7); + if (this.node.prelude.start > c) code.remove(c, this.node.prelude.start); + + this.node.prelude.children.forEach((query) => { + // TODO minify queries + c = query.end; + }); + + code.remove(c, this.node.block.start); + } else if (this.node.name === 'supports') { + let c = this.node.start + 9; + if (this.node.prelude.start - c > 1) code.overwrite(c, this.node.prelude.start, ' '); + this.node.prelude.children.forEach((query) => { + // TODO minify queries + c = query.end; + }); + code.remove(c, this.node.block.start); + } else { + let c = this.node.start + this.node.name.length + 1; + if (this.node.prelude) { + if (this.node.prelude.start - c > 1) code.overwrite(c, this.node.prelude.start, ' '); + c = this.node.prelude.end; + } + if (this.node.block && this.node.block.start - c > 0) { + code.remove(c, this.node.block.start); + } + } - code.remove(c, this.node.block.start); - } else if (this.node.name === 'supports') { - let c = this.node.start + 9; - if (this.node.prelude.start - c > 1) code.overwrite(c, this.node.prelude.start, ' '); - this.node.prelude.children.forEach((query) => { - // TODO minify queries - c = query.end; - }); - code.remove(c, this.node.block.start); - } else { - let c = this.node.start + this.node.name.length + 1; - if (this.node.prelude) { - if (this.node.prelude.start - c > 1) code.overwrite(c, this.node.prelude.start, ' '); - c = this.node.prelude.end; - } - if (this.node.block && this.node.block.start - c > 0) { - code.remove(c, this.node.block.start); - } - } + // TODO other atrules - // TODO other atrules + if (this.node.block) { + let c = this.node.block.start + 1; + if (this.declarations.length) { + c = minify_declarations(code, c, this.declarations); + // if the atrule has children, leave the last declaration semicolon alone + if (this.children.length) c++; + } - if (this.node.block) { - let c = this.node.block.start + 1; - if (this.declarations.length) { - c = minify_declarations(code, c, this.declarations); - // if the atrule has children, leave the last declaration semicolon alone - if (this.children.length) c++; - } + this.children.forEach((child) => { + if (child.is_used(dev)) { + code.remove(c, child.node.start); + child.minify(code, dev); + c = child.node.end; + } + }); - this.children.forEach(child => { - if (child.is_used(dev)) { - code.remove(c, child.node.start); - child.minify(code, dev); - c = child.node.end; - } - }); + code.remove(c, this.node.block.end - 1); + } + } - code.remove(c, this.node.block.end - 1); - } - } - - transform(code, id, keyframes, max_amount_class_specificity_increased) { - if (is_keyframes_node(this.node)) { - this.node.prelude.children.forEach(({ type, name, start, end }) => { - if (type === 'Identifier') { - if (name.startsWith('-global-')) { - code.remove(start, start + 8); - this.children.forEach((rule) => { - rule.selectors.forEach(selector => { - selector.used = true; - }); - }); - } else { - code.overwrite(start, end, keyframes.get(name)); - } - } - }); - } + transform(code, id, keyframes, max_amount_class_specificity_increased) { + if (is_keyframes_node(this.node)) { + this.node.prelude.children.forEach(({ type, name, start, end }) => { + if (type === 'Identifier') { + if (name.startsWith('-global-')) { + code.remove(start, start + 8); + this.children.forEach((rule) => { + rule.selectors.forEach((selector) => { + selector.used = true; + }); + }); + } else { + code.overwrite(start, end, keyframes.get(name)); + } + } + }); + } - this.children.forEach(child => { - child.transform(code, id, keyframes, max_amount_class_specificity_increased); - }); - } + this.children.forEach((child) => { + child.transform(code, id, keyframes, max_amount_class_specificity_increased); + }); + } - validate(component) { - this.children.forEach(child => { - child.validate(component); - }); - } + validate(component) { + this.children.forEach((child) => { + child.validate(component); + }); + } - warn_on_unused_selector(handler) { - if (this.node.name !== 'media') return; + warn_on_unused_selector(handler) { + if (this.node.name !== 'media') return; - this.children.forEach(child => { - child.warn_on_unused_selector(handler); - }); - } + this.children.forEach((child) => { + child.warn_on_unused_selector(handler); + }); + } - get_max_amount_class_specificity_increased() { - return Math.max(...this.children.map(rule => rule.get_max_amount_class_specificity_increased())); - } + get_max_amount_class_specificity_increased() { + return Math.max(...this.children.map((rule) => rule.get_max_amount_class_specificity_increased())); + } } const get_default_css_hash = ({ css, hash }) => { - return `svelte-${hash(css)}`; + return `svelte-${hash(css)}`; }; class Stylesheet { - - - - - - - - - __init() {this.children = [];} - __init2() {this.keyframes = new Map();} - - __init3() {this.nodes_with_css_class = new Set();} + __init() { + this.children = []; + } + __init2() { + this.keyframes = new Map(); + } - constructor({ - source, - ast, - component_name, - filename, - dev, - get_css_hash = get_default_css_hash - } + __init3() { + this.nodes_with_css_class = new Set(); + } + constructor({ source, ast, component_name, filename, dev, get_css_hash = get_default_css_hash }) { + Stylesheet.prototype.__init.call(this); + Stylesheet.prototype.__init2.call(this); + Stylesheet.prototype.__init3.call(this); + this.source = source; + this.ast = ast; + this.filename = filename; + this.dev = dev; + + if (ast.css && ast.css.children.length) { + this.id = get_css_hash({ + filename, + name: component_name, + css: ast.css.content.styles, + hash, + }); + + this.has_styles = true; + + const stack = []; + let depth = 0; + let current_atrule = null; + + walk(ast.css, { + enter: (node) => { + if (node.type === 'Atrule') { + const atrule = new Atrule(node); + stack.push(atrule); + + if (current_atrule) { + current_atrule.children.push(atrule); + } else if (depth <= 1) { + this.children.push(atrule); + } + if (is_keyframes_node(node)) { + node.prelude.children.forEach((expression) => { + if (expression.type === 'Identifier' && !expression.name.startsWith('-global-')) { + this.keyframes.set(expression.name, `${this.id}-${expression.name}`); + } + }); + } else if (at_rule_has_declaration(node)) { + const at_rule_declarations = node.block.children.filter((node) => node.type === 'Declaration').map((node) => new Declaration(node)); + atrule.declarations.push(...at_rule_declarations); + } + current_atrule = atrule; + } + if (node.type === 'Rule') { + const rule = new Rule(node, this, current_atrule); + if (current_atrule) { + current_atrule.children.push(rule); + } else if (depth <= 1) { + this.children.push(rule); + } + } -) {Stylesheet.prototype.__init.call(this);Stylesheet.prototype.__init2.call(this);Stylesheet.prototype.__init3.call(this); - this.source = source; - this.ast = ast; - this.filename = filename; - this.dev = dev; + depth += 1; + }, - if (ast.css && ast.css.children.length) { - this.id = get_css_hash({ - filename, - name: component_name, - css: ast.css.content.styles, - hash - }); + leave: (node) => { + if (node.type === 'Atrule') { + stack.pop(); + current_atrule = stack[stack.length - 1]; + } - this.has_styles = true; + depth -= 1; + }, + }); + } else { + this.has_styles = false; + } + } - const stack = []; - let depth = 0; - let current_atrule = null; + apply(node) { + if (!this.has_styles) return; - walk(ast.css , { - enter: (node) => { - if (node.type === 'Atrule') { - const atrule = new Atrule(node); - stack.push(atrule); + for (let i = 0; i < this.children.length; i += 1) { + const child = this.children[i]; + child.apply(node); + } + } - if (current_atrule) { - current_atrule.children.push(atrule); - } else if (depth <= 1) { - this.children.push(atrule); - } + reify() { + this.nodes_with_css_class.forEach((node) => { + node.add_css_class(); + }); + } - if (is_keyframes_node(node)) { - node.prelude.children.forEach((expression) => { - if (expression.type === 'Identifier' && !expression.name.startsWith('-global-')) { - this.keyframes.set(expression.name, `${this.id}-${expression.name}`); - } - }); - } else if (at_rule_has_declaration(node)) { - const at_rule_declarations = node.block.children - .filter(node => node.type === 'Declaration') - .map(node => new Declaration(node)); - atrule.declarations.push(...at_rule_declarations); - } + render(file, should_transform_selectors) { + if (!this.has_styles) { + return { code: null, map: null }; + } - current_atrule = atrule; - } + const code = new MagicString(this.source); - if (node.type === 'Rule') { - const rule = new Rule(node, this, current_atrule); + walk(this.ast.css, { + enter: (node) => { + code.addSourcemapLocation(node.start); + code.addSourcemapLocation(node.end); + }, + }); - if (current_atrule) { - current_atrule.children.push(rule); - } else if (depth <= 1) { - this.children.push(rule); - } - } + if (should_transform_selectors) { + const max = Math.max(...this.children.map((rule) => rule.get_max_amount_class_specificity_increased())); + this.children.forEach((child) => { + child.transform(code, this.id, this.keyframes, max); + }); + } - depth += 1; - }, + let c = 0; + this.children.forEach((child) => { + if (child.is_used(this.dev)) { + code.remove(c, child.node.start); + child.minify(code, this.dev); + c = child.node.end; + } + }); - leave: (node) => { - if (node.type === 'Atrule') { - stack.pop(); - current_atrule = stack[stack.length - 1]; - } + code.remove(c, this.source.length); - depth -= 1; - } - }); - } else { - this.has_styles = false; - } - } + return { + code: code.toString(), + map: code.generateMap({ + includeContent: true, + source: this.filename, + file, + }), + }; + } - apply(node) { - if (!this.has_styles) return; + validate(component) { + this.children.forEach((child) => { + child.validate(component); + }); + } - for (let i = 0; i < this.children.length; i += 1) { - const child = this.children[i]; - child.apply(node); - } - } + warn_on_unused_selectors(component) { + this.children.forEach((child) => { + child.warn_on_unused_selector((selector) => { + component.warn(selector.node, { + code: 'css-unused-selector', + message: `Unused CSS selector "${this.source.slice(selector.node.start, selector.node.end)}"`, + }); + }); + }); + } +} - reify() { - this.nodes_with_css_class.forEach((node) => { - node.add_css_class(); - }); - } +const test = typeof process !== 'undefined' && process.env.TEST; - render(file, should_transform_selectors) { - if (!this.has_styles) { - return { code: null, map: null }; - } +class TemplateScope { + __init() { + this.owners = new Map(); + } - const code = new MagicString(this.source); + constructor(parent) { + TemplateScope.prototype.__init.call(this); + this.parent = parent; + this.names = new Set(parent ? parent.names : []); + this.dependencies_for_name = new Map(parent ? parent.dependencies_for_name : []); + } - walk(this.ast.css , { - enter: (node) => { - code.addSourcemapLocation(node.start); - code.addSourcemapLocation(node.end); - } - }); + add(name, dependencies, owner) { + this.names.add(name); + this.dependencies_for_name.set(name, dependencies); + this.owners.set(name, owner); + return this; + } - if (should_transform_selectors) { - const max = Math.max(...this.children.map(rule => rule.get_max_amount_class_specificity_increased())); - this.children.forEach((child) => { - child.transform(code, this.id, this.keyframes, max); - }); - } + child() { + const child = new TemplateScope(this); + return child; + } - let c = 0; - this.children.forEach(child => { - if (child.is_used(this.dev)) { - code.remove(c, child.node.start); - child.minify(code, this.dev); - c = child.node.end; - } - }); + is_top_level(name) { + return !this.parent || (!this.names.has(name) && this.parent.is_top_level(name)); + } - code.remove(c, this.source.length); - - return { - code: code.toString(), - map: code.generateMap({ - includeContent: true, - source: this.filename, - file - }) - }; - } - - validate(component) { - this.children.forEach(child => { - child.validate(component); - }); - } - - warn_on_unused_selectors(component) { - this.children.forEach(child => { - child.warn_on_unused_selector((selector) => { - component.warn(selector.node, { - code: 'css-unused-selector', - message: `Unused CSS selector "${this.source.slice(selector.node.start, selector.node.end)}"` - }); - }); - }); - } -} + get_owner(name) { + return this.owners.get(name) || (this.parent && this.parent.get_owner(name)); + } -const test = typeof process !== 'undefined' && process.env.TEST; + is_let(name) { + const owner = this.get_owner(name); + return owner && (owner.type === 'Element' || owner.type === 'InlineComponent' || owner.type === 'SlotTemplate'); + } -class TemplateScope { - - - __init() {this.owners = new Map();} - - - constructor(parent) {TemplateScope.prototype.__init.call(this); - this.parent = parent; - this.names = new Set(parent ? parent.names : []); - this.dependencies_for_name = new Map(parent ? parent.dependencies_for_name : []); - } - - 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; - } - - is_top_level(name) { - return !this.parent || !this.names.has(name) && this.parent.is_top_level(name); - } - - get_owner(name) { - return this.owners.get(name) || (this.parent && this.parent.get_owner(name)); - } - - is_let(name) { - const owner = this.get_owner(name); - return owner && (owner.type === 'Element' || owner.type === 'InlineComponent' || owner.type === 'SlotTemplate'); - } - - is_await(name) { - const owner = this.get_owner(name); - return owner && (owner.type === 'ThenBlock' || owner.type === 'CatchBlock'); - } + is_await(name) { + const owner = this.get_owner(name); + return owner && (owner.type === 'ThenBlock' || owner.type === 'CatchBlock'); + } } class Fragment extends Node { - - - - - - constructor(component, info) { - const scope = new TemplateScope(); - super(component, null, scope, 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); - } + this.scope = scope; + this.children = map_children(component, this, scope, info.children); + } } // This file is automatically generated -var internal_exports = new Set(["HtmlTag","SvelteComponent","SvelteComponentDev","SvelteComponentTyped","SvelteElement","action_destroyer","add_attribute","add_classes","add_flush_callback","add_location","add_render_callback","add_resize_listener","add_transform","afterUpdate","append","append_dev","assign","attr","attr_dev","attribute_to_object","beforeUpdate","bind","binding_callbacks","blank_object","bubble","check_outros","children","claim_component","claim_element","claim_space","claim_text","clear_loops","component_subscribe","compute_rest_props","compute_slots","createEventDispatcher","create_animation","create_bidirectional_transition","create_component","create_in_transition","create_out_transition","create_slot","create_ssr_component","current_component","custom_event","dataset_dev","debug","destroy_block","destroy_component","destroy_each","detach","detach_after_dev","detach_before_dev","detach_between_dev","detach_dev","dirty_components","dispatch_dev","each","element","element_is","empty","escape","escaped","exclude_internal_props","fix_and_destroy_block","fix_and_outro_and_destroy_block","fix_position","flush","getContext","get_binding_group_value","get_current_component","get_custom_elements_slots","get_slot_changes","get_slot_context","get_spread_object","get_spread_update","get_store_value","globals","group_outros","handle_promise","hasContext","has_prop","identity","init","insert","insert_dev","intros","invalid_attribute_name_character","is_client","is_crossorigin","is_empty","is_function","is_promise","listen","listen_dev","loop","loop_guard","missing_component","mount_component","noop","not_equal","now","null_to_empty","object_without_properties","onDestroy","onMount","once","outro_and_destroy_block","prevent_default","prop_dev","query_selector_all","raf","run","run_all","safe_not_equal","schedule_update","select_multiple_value","select_option","select_options","select_value","self","setContext","set_attributes","set_current_component","set_custom_element_data","set_data","set_data_dev","set_input_type","set_input_value","set_now","set_raf","set_store_value","set_style","set_svg_attributes","space","spread","stop_propagation","subscribe","svg_element","text","tick","time_ranges_to_array","to_number","toggle_class","transition_in","transition_out","update_keyed_each","update_slot","update_slot_spread","validate_component","validate_each_argument","validate_each_keys","validate_slots","validate_store","xlink_attr"]); - -function is_used_as_reference( - node, - parent -) { - if (!isReference(node, parent)) { - return false; - } - if (!parent) { - return true; - } - - /* eslint-disable no-fallthrough */ - switch (parent.type) { - // disregard the `foo` in `const foo = bar` - case 'VariableDeclarator': - return node !== parent.id; - // disregard the `foo`, `bar` in `function foo(bar){}` - case 'FunctionDeclaration': - // disregard the `foo` in `import { foo } from 'foo'` - case 'ImportSpecifier': - // disregard the `foo` in `import foo from 'foo'` - case 'ImportDefaultSpecifier': - // disregard the `foo` in `import * as foo from 'foo'` - case 'ImportNamespaceSpecifier': - // disregard the `foo` in `export { foo }` - case 'ExportSpecifier': - return false; - default: - return true; - } +var internal_exports = new Set([ + 'HtmlTag', + 'SvelteComponent', + 'SvelteComponentDev', + 'SvelteComponentTyped', + 'SvelteElement', + 'action_destroyer', + 'add_attribute', + 'add_classes', + 'add_flush_callback', + 'add_location', + 'add_render_callback', + 'add_resize_listener', + 'add_transform', + 'afterUpdate', + 'append', + 'append_dev', + 'assign', + 'attr', + 'attr_dev', + 'attribute_to_object', + 'beforeUpdate', + 'bind', + 'binding_callbacks', + 'blank_object', + 'bubble', + 'check_outros', + 'children', + 'claim_component', + 'claim_element', + 'claim_space', + 'claim_text', + 'clear_loops', + 'component_subscribe', + 'compute_rest_props', + 'compute_slots', + 'createEventDispatcher', + 'create_animation', + 'create_bidirectional_transition', + 'create_component', + 'create_in_transition', + 'create_out_transition', + 'create_slot', + 'create_ssr_component', + 'current_component', + 'custom_event', + 'dataset_dev', + 'debug', + 'destroy_block', + 'destroy_component', + 'destroy_each', + 'detach', + 'detach_after_dev', + 'detach_before_dev', + 'detach_between_dev', + 'detach_dev', + 'dirty_components', + 'dispatch_dev', + 'each', + 'element', + 'element_is', + 'empty', + 'escape', + 'escaped', + 'exclude_internal_props', + 'fix_and_destroy_block', + 'fix_and_outro_and_destroy_block', + 'fix_position', + 'flush', + 'getContext', + 'get_binding_group_value', + 'get_current_component', + 'get_custom_elements_slots', + 'get_slot_changes', + 'get_slot_context', + 'get_spread_object', + 'get_spread_update', + 'get_store_value', + 'globals', + 'group_outros', + 'handle_promise', + 'hasContext', + 'has_prop', + 'identity', + 'init', + 'insert', + 'insert_dev', + 'intros', + 'invalid_attribute_name_character', + 'is_client', + 'is_crossorigin', + 'is_empty', + 'is_function', + 'is_promise', + 'listen', + 'listen_dev', + 'loop', + 'loop_guard', + 'missing_component', + 'mount_component', + 'noop', + 'not_equal', + 'now', + 'null_to_empty', + 'object_without_properties', + 'onDestroy', + 'onMount', + 'once', + 'outro_and_destroy_block', + 'prevent_default', + 'prop_dev', + 'query_selector_all', + 'raf', + 'run', + 'run_all', + 'safe_not_equal', + 'schedule_update', + 'select_multiple_value', + 'select_option', + 'select_options', + 'select_value', + 'self', + 'setContext', + 'set_attributes', + 'set_current_component', + 'set_custom_element_data', + 'set_data', + 'set_data_dev', + 'set_input_type', + 'set_input_value', + 'set_now', + 'set_raf', + 'set_store_value', + 'set_style', + 'set_svg_attributes', + 'space', + 'spread', + 'stop_propagation', + 'subscribe', + 'svg_element', + 'text', + 'tick', + 'time_ranges_to_array', + 'to_number', + 'toggle_class', + 'transition_in', + 'transition_out', + 'update_keyed_each', + 'update_slot', + 'update_slot_spread', + 'validate_component', + 'validate_each_argument', + 'validate_each_keys', + 'validate_slots', + 'validate_store', + 'xlink_attr', +]); + +function is_used_as_reference(node, parent) { + if (!isReference(node, parent)) { + return false; + } + if (!parent) { + return true; + } + + /* eslint-disable no-fallthrough */ + switch (parent.type) { + // disregard the `foo` in `const foo = bar` + case 'VariableDeclarator': + return node !== parent.id; + // disregard the `foo`, `bar` in `function foo(bar){}` + case 'FunctionDeclaration': + // disregard the `foo` in `import { foo } from 'foo'` + case 'ImportSpecifier': + // disregard the `foo` in `import foo from 'foo'` + case 'ImportDefaultSpecifier': + // disregard the `foo` in `import * as foo from 'foo'` + case 'ImportNamespaceSpecifier': + // disregard the `foo` in `export { foo }` + case 'ExportSpecifier': + return false; + default: + return true; + } } function check_graph_for_cycles(edges) { - const graph = edges.reduce((g, edge) => { - const [u, v] = edge; - if (!g.has(u)) g.set(u, []); - if (!g.has(v)) g.set(v, []); - g.get(u).push(v); - return g; - }, new Map()); - - const visited = new Set(); - const on_stack = new Set(); - const cycles = []; - - function visit (v) { - visited.add(v); - on_stack.add(v); - - graph.get(v).forEach(w => { - if (!visited.has(w)) { - visit(w); - } else if (on_stack.has(w)) { - cycles.push([...on_stack, w]); - } - }); + const graph = edges.reduce((g, edge) => { + const [u, v] = edge; + if (!g.has(u)) g.set(u, []); + if (!g.has(v)) g.set(v, []); + g.get(u).push(v); + return g; + }, new Map()); + + const visited = new Set(); + const on_stack = new Set(); + const cycles = []; + + function visit(v) { + visited.add(v); + on_stack.add(v); + + graph.get(v).forEach((w) => { + if (!visited.has(w)) { + visit(w); + } else if (on_stack.has(w)) { + cycles.push([...on_stack, w]); + } + }); - on_stack.delete(v); - } + on_stack.delete(v); + } - graph.forEach((_, v) => { - if (!visited.has(v)) { - visit(v); - } - }); + graph.forEach((_, v) => { + if (!visited.has(v)) { + visit(v); + } + }); - return cycles[0]; + return cycles[0]; } class Component { - - - - __init() {this.ignore_stack = [];} - - - - - - - - - - - - - - - - - __init2() {this.vars = [];} - __init3() {this.var_lookup = new Map();} - - __init4() {this.imports = [];} - - __init5() {this.hoistable_nodes = new Set();} - __init6() {this.node_for_declaration = new Map();} - __init7() {this.partly_hoisted = [];} - __init8() {this.fully_hoisted = [];} - __init9() {this.reactive_declarations - - - - - = [];} - __init10() {this.reactive_declaration_nodes = new Set();} - __init11() {this.has_reactive_assignments = false;} - __init12() {this.injected_reactive_declaration_vars = new Set();} - __init13() {this.helpers = new Map();} - __init14() {this.globals = new Map();} - - __init15() {this.indirect_dependencies = new Map();} - - - - - __init16() {this.elements = [];} - - - __init17() {this.aliases = new Map();} - __init18() {this.used_names = new Set();} - __init19() {this.globally_used_names = new Set();} - - __init20() {this.slots = new Map();} - __init21() {this.slot_outlets = new Set();} - - constructor( - ast, - source, - name, - compile_options, - stats, - warnings - ) {Component.prototype.__init.call(this);Component.prototype.__init2.call(this);Component.prototype.__init3.call(this);Component.prototype.__init4.call(this);Component.prototype.__init5.call(this);Component.prototype.__init6.call(this);Component.prototype.__init7.call(this);Component.prototype.__init8.call(this);Component.prototype.__init9.call(this);Component.prototype.__init10.call(this);Component.prototype.__init11.call(this);Component.prototype.__init12.call(this);Component.prototype.__init13.call(this);Component.prototype.__init14.call(this);Component.prototype.__init15.call(this);Component.prototype.__init16.call(this);Component.prototype.__init17.call(this);Component.prototype.__init18.call(this);Component.prototype.__init19.call(this);Component.prototype.__init20.call(this);Component.prototype.__init21.call(this); - this.name = { type: 'Identifier', name }; - - this.stats = stats; - this.warnings = warnings; - this.ast = ast; - this.source = source; - this.compile_options = compile_options; - - // the instance JS gets mutated, so we park - // a copy here for later. TODO this feels gross - this.original_ast = { - html: ast.html, - css: ast.css, - instance: ast.instance && JSON.parse(JSON.stringify(ast.instance)), - module: ast.module - }; - - this.file = - compile_options.filename && - (typeof process !== 'undefined' - ? compile_options.filename - .replace(process.cwd(), '') - .replace(/^[/\\]/, '') - : compile_options.filename); - this.locate = getLocator(this.source, { offsetLine: 1 }); - - // styles - this.stylesheet = new Stylesheet({ - source, - ast, - filename: compile_options.filename, - component_name: name, - dev: compile_options.dev, - get_css_hash: compile_options.cssHash - }); - this.stylesheet.validate(this); - - this.component_options = process_component_options( - this, - this.ast.html.children - ); - this.namespace = - namespaces[this.component_options.namespace] || - this.component_options.namespace; - - if (compile_options.customElement) { - if ( - this.component_options.tag === undefined && - compile_options.tag === undefined - ) { - const svelteOptions = ast.html.children.find( - child => child.name === 'svelte:options' - ) || { start: 0, end: 0 }; - this.warn(svelteOptions, { - code: 'custom-element-no-tag', - message: 'No custom element \'tag\' option was specified. To automatically register a custom element, specify a name with a hyphen in it, e.g. <svelte:options tag="my-thing"/>. To hide this warning, use <svelte:options tag={null}/>' - }); - } - this.tag = this.component_options.tag || compile_options.tag; - } else { - this.tag = this.name.name; - } + __init() { + this.ignore_stack = []; + } - this.walk_module_js(); - this.walk_instance_js_pre_template(); + __init2() { + this.vars = []; + } + __init3() { + this.var_lookup = new Map(); + } - this.fragment = new Fragment(this, ast.html); - this.name = this.get_unique_name(name); + __init4() { + this.imports = []; + } - this.walk_instance_js_post_template(); + __init5() { + this.hoistable_nodes = new Set(); + } + __init6() { + this.node_for_declaration = new Map(); + } + __init7() { + this.partly_hoisted = []; + } + __init8() { + this.fully_hoisted = []; + } + __init9() { + this.reactive_declarations = []; + } + __init10() { + this.reactive_declaration_nodes = new Set(); + } + __init11() { + this.has_reactive_assignments = false; + } + __init12() { + this.injected_reactive_declaration_vars = new Set(); + } + __init13() { + this.helpers = new Map(); + } + __init14() { + this.globals = new Map(); + } - this.elements.forEach(element => this.stylesheet.apply(element)); - if (!compile_options.customElement) this.stylesheet.reify(); - this.stylesheet.warn_on_unused_selectors(this); - } + __init15() { + this.indirect_dependencies = new Map(); + } - add_var(variable) { - this.vars.push(variable); - this.var_lookup.set(variable.name, variable); - } + __init16() { + this.elements = []; + } - add_reference(name) { - const variable = this.var_lookup.get(name); + __init17() { + this.aliases = new Map(); + } + __init18() { + this.used_names = new Set(); + } + __init19() { + this.globally_used_names = new Set(); + } - if (variable) { - variable.referenced = true; - } else if (is_reserved_keyword(name)) { - this.add_var({ - name, - injected: true, - referenced: true - }); - } else if (name[0] === '$') { - this.add_var({ - name, - injected: true, - referenced: true, - mutated: true, - writable: true - }); + __init20() { + this.slots = new Map(); + } + __init21() { + this.slot_outlets = new Set(); + } - const subscribable_name = name.slice(1); + constructor(ast, source, name, compile_options, stats, warnings) { + Component.prototype.__init.call(this); + Component.prototype.__init2.call(this); + Component.prototype.__init3.call(this); + Component.prototype.__init4.call(this); + Component.prototype.__init5.call(this); + Component.prototype.__init6.call(this); + Component.prototype.__init7.call(this); + Component.prototype.__init8.call(this); + Component.prototype.__init9.call(this); + Component.prototype.__init10.call(this); + Component.prototype.__init11.call(this); + Component.prototype.__init12.call(this); + Component.prototype.__init13.call(this); + Component.prototype.__init14.call(this); + Component.prototype.__init15.call(this); + Component.prototype.__init16.call(this); + Component.prototype.__init17.call(this); + Component.prototype.__init18.call(this); + Component.prototype.__init19.call(this); + Component.prototype.__init20.call(this); + Component.prototype.__init21.call(this); + this.name = { type: 'Identifier', name }; + + this.stats = stats; + this.warnings = warnings; + this.ast = ast; + this.source = source; + this.compile_options = compile_options; + + // the instance JS gets mutated, so we park + // a copy here for later. TODO this feels gross + this.original_ast = { + html: ast.html, + css: ast.css, + instance: ast.instance && JSON.parse(JSON.stringify(ast.instance)), + module: ast.module, + }; - const variable = this.var_lookup.get(subscribable_name); - if (variable) { - variable.referenced = true; - variable.subscribable = true; - } - } else { - this.used_names.add(name); - } - } + this.file = compile_options.filename && (typeof process !== 'undefined' ? compile_options.filename.replace(process.cwd(), '').replace(/^[/\\]/, '') : compile_options.filename); + this.locate = getLocator(this.source, { offsetLine: 1 }); + + // styles + this.stylesheet = new Stylesheet({ + source, + ast, + filename: compile_options.filename, + component_name: name, + dev: compile_options.dev, + get_css_hash: compile_options.cssHash, + }); + this.stylesheet.validate(this); + + this.component_options = process_component_options(this, this.ast.html.children); + this.namespace = namespaces[this.component_options.namespace] || this.component_options.namespace; + + if (compile_options.customElement) { + if (this.component_options.tag === undefined && compile_options.tag === undefined) { + const svelteOptions = ast.html.children.find((child) => child.name === 'svelte:options') || { start: 0, end: 0 }; + this.warn(svelteOptions, { + code: 'custom-element-no-tag', + message: + 'No custom element \'tag\' option was specified. To automatically register a custom element, specify a name with a hyphen in it, e.g. <svelte:options tag="my-thing"/>. To hide this warning, use <svelte:options tag={null}/>', + }); + } + this.tag = this.component_options.tag || compile_options.tag; + } else { + this.tag = this.name.name; + } - alias(name) { - if (!this.aliases.has(name)) { - this.aliases.set(name, this.get_unique_name(name)); - } + this.walk_module_js(); + this.walk_instance_js_pre_template(); - return this.aliases.get(name); - } - - apply_stylesheet(element) { - this.elements.push(element); - } - - global(name) { - const alias = this.alias(name); - this.globals.set(name, alias); - return alias; - } - - generate(result) { - let js = null; - let css = null; - - if (result) { - const { compile_options, name } = this; - const { format = 'esm' } = compile_options; - - const banner = `${this.file ? `${this.file} ` : ''}generated by Svelte v${'3.35.0'}`; - - const program = { type: 'Program', body: result.js }; - - walk(program, { - enter: (node, parent, key) => { - if (node.type === 'Identifier') { - if (node.name[0] === '@') { - if (node.name[1] === '_') { - const alias = this.global(node.name.slice(2)); - node.name = alias.name; - } else { - let name = node.name.slice(1); - - if (compile_options.dev) { - if (internal_exports.has(`${name}_dev`)) { - name += '_dev'; - } else if (internal_exports.has(`${name}Dev`)) { - name += 'Dev'; - } - } - - const alias = this.alias(name); - this.helpers.set(name, alias); - node.name = alias.name; - } - } else if (node.name[0] !== '#' && !is_valid(node.name)) { - // this hack allows x`foo.${bar}` where bar could be invalid - const literal = { type: 'Literal', value: node.name }; - - if (parent.type === 'Property' && key === 'key') { - parent.key = literal; - } else if (parent.type === 'MemberExpression' && key === 'property') { - parent.property = literal; - parent.computed = true; - } - } - } - } - }); + this.fragment = new Fragment(this, ast.html); + this.name = this.get_unique_name(name); - const referenced_globals = Array.from( - this.globals, - ([name, alias]) => name !== alias.name && { name, alias } - ).filter(Boolean); - if (referenced_globals.length) { - this.helpers.set('globals', this.alias('globals')); - } - const imported_helpers = Array.from(this.helpers, ([name, alias]) => ({ - name, - alias - })); - - create_module( - program, - format, - name, - banner, - compile_options.sveltePath, - imported_helpers, - referenced_globals, - this.imports, - this.vars - .filter(variable => variable.module && variable.export_name) - .map(variable => ({ - name: variable.name, - as: variable.export_name - })) - ); - - css = compile_options.customElement - ? { code: null, map: null } - : result.css; - - js = print(program, { - sourceMapSource: compile_options.filename - }); + this.walk_instance_js_post_template(); - js.map.sources = [ - compile_options.filename ? get_relative_path(compile_options.outputFilename || '', compile_options.filename) : null - ]; + this.elements.forEach((element) => this.stylesheet.apply(element)); + if (!compile_options.customElement) this.stylesheet.reify(); + this.stylesheet.warn_on_unused_selectors(this); + } - js.map.sourcesContent = [ - this.source - ]; + add_var(variable) { + this.vars.push(variable); + this.var_lookup.set(variable.name, variable); + } - js.map = apply_preprocessor_sourcemap(this.file, js.map, compile_options.sourcemap ); - } + add_reference(name) { + const variable = this.var_lookup.get(name); + + if (variable) { + variable.referenced = true; + } else if (is_reserved_keyword(name)) { + this.add_var({ + name, + injected: true, + referenced: true, + }); + } else if (name[0] === '$') { + this.add_var({ + name, + injected: true, + referenced: true, + mutated: true, + writable: true, + }); + + const subscribable_name = name.slice(1); + + const variable = this.var_lookup.get(subscribable_name); + if (variable) { + variable.referenced = true; + variable.subscribable = true; + } + } else { + this.used_names.add(name); + } + } - return { - js, - css, - ast: this.original_ast, - warnings: this.warnings, - vars: this.vars - .filter(v => !v.global && !v.internal) - .map(v => ({ - name: v.name, - export_name: v.export_name || null, - injected: v.injected || false, - module: v.module || false, - mutated: v.mutated || false, - reassigned: v.reassigned || false, - referenced: v.referenced || false, - writable: v.writable || false, - referenced_from_script: v.referenced_from_script || false - })), - stats: this.stats.render() - }; - } - - get_unique_name(name, scope) { - if (test) name = `${name}$`; - let alias = name; - for ( - let i = 1; - reserved.has(alias) || - this.var_lookup.has(alias) || - this.used_names.has(alias) || - this.globally_used_names.has(alias) || - (scope && scope.has(alias)); - alias = `${name}_${i++}` - ); - this.used_names.add(alias); - return { type: 'Identifier', name: alias }; - } - - get_unique_name_maker() { - const local_used_names = new Set(); - - function add(name) { - local_used_names.add(name); - } + alias(name) { + if (!this.aliases.has(name)) { + this.aliases.set(name, this.get_unique_name(name)); + } - reserved.forEach(add); - internal_exports.forEach(add); - this.var_lookup.forEach((_value, key) => add(key)); - - return (name) => { - if (test) name = `${name}$`; - let alias = name; - for ( - let i = 1; - this.used_names.has(alias) || local_used_names.has(alias); - alias = `${name}_${i++}` - ); - local_used_names.add(alias); - this.globally_used_names.add(alias); - - return { - type: 'Identifier', - name: alias - }; - }; - } - - error( - pos - - -, - e - - - - ) { - error(e.message, { - name: 'ValidationError', - code: e.code, - source: this.source, - start: pos.start, - end: pos.end, - filename: this.compile_options.filename - }); - } + return this.aliases.get(name); + } - warn( - pos + apply_stylesheet(element) { + this.elements.push(element); + } + global(name) { + const alias = this.alias(name); + this.globals.set(name, alias); + return alias; + } -, - warning + generate(result) { + let js = null; + let css = null; + + if (result) { + const { compile_options, name } = this; + const { format = 'esm' } = compile_options; + + const banner = `${this.file ? `${this.file} ` : ''}generated by Svelte v${'3.35.0'}`; + + const program = { type: 'Program', body: result.js }; + + walk(program, { + enter: (node, parent, key) => { + if (node.type === 'Identifier') { + if (node.name[0] === '@') { + if (node.name[1] === '_') { + const alias = this.global(node.name.slice(2)); + node.name = alias.name; + } else { + let name = node.name.slice(1); + + if (compile_options.dev) { + if (internal_exports.has(`${name}_dev`)) { + name += '_dev'; + } else if (internal_exports.has(`${name}Dev`)) { + name += 'Dev'; + } + } + const alias = this.alias(name); + this.helpers.set(name, alias); + node.name = alias.name; + } + } else if (node.name[0] !== '#' && !is_valid(node.name)) { + // this hack allows x`foo.${bar}` where bar could be invalid + const literal = { type: 'Literal', value: node.name }; + + if (parent.type === 'Property' && key === 'key') { + parent.key = literal; + } else if (parent.type === 'MemberExpression' && key === 'property') { + parent.property = literal; + parent.computed = true; + } + } + } + }, + }); + const referenced_globals = Array.from(this.globals, ([name, alias]) => name !== alias.name && { name, alias }).filter(Boolean); + if (referenced_globals.length) { + this.helpers.set('globals', this.alias('globals')); + } + const imported_helpers = Array.from(this.helpers, ([name, alias]) => ({ + name, + alias, + })); + + create_module( + program, + format, + name, + banner, + compile_options.sveltePath, + imported_helpers, + referenced_globals, + this.imports, + this.vars + .filter((variable) => variable.module && variable.export_name) + .map((variable) => ({ + name: variable.name, + as: variable.export_name, + })) + ); + + css = compile_options.customElement ? { code: null, map: null } : result.css; + + js = print(program, { + sourceMapSource: compile_options.filename, + }); + + js.map.sources = [compile_options.filename ? get_relative_path(compile_options.outputFilename || '', compile_options.filename) : null]; + + js.map.sourcesContent = [this.source]; + + js.map = apply_preprocessor_sourcemap(this.file, js.map, compile_options.sourcemap); + } - ) { - if (this.ignores && this.ignores.has(warning.code)) { - return; - } + return { + js, + css, + ast: this.original_ast, + warnings: this.warnings, + vars: this.vars + .filter((v) => !v.global && !v.internal) + .map((v) => ({ + name: v.name, + export_name: v.export_name || null, + injected: v.injected || false, + module: v.module || false, + mutated: v.mutated || false, + reassigned: v.reassigned || false, + referenced: v.referenced || false, + writable: v.writable || false, + referenced_from_script: v.referenced_from_script || false, + })), + stats: this.stats.render(), + }; + } - const start = this.locate(pos.start); - const end = this.locate(pos.end); - - const frame = get_code_frame(this.source, start.line - 1, start.column); - - this.warnings.push({ - code: warning.code, - message: warning.message, - frame, - start, - end, - pos: pos.start, - filename: this.compile_options.filename, - toString: () => - `${warning.message} (${start.line}:${start.column})\n${frame}` - }); - } + get_unique_name(name, scope) { + if (test) name = `${name}$`; + let alias = name; + for ( + let i = 1; + reserved.has(alias) || this.var_lookup.has(alias) || this.used_names.has(alias) || this.globally_used_names.has(alias) || (scope && scope.has(alias)); + alias = `${name}_${i++}` + ); + this.used_names.add(alias); + return { type: 'Identifier', name: alias }; + } - extract_imports(node) { - this.imports.push(node); - } + get_unique_name_maker() { + const local_used_names = new Set(); - extract_exports(node) { - if (node.type === 'ExportDefaultDeclaration') { - this.error(node, { - code: 'default-export', - message: 'A component cannot have a default export' - }); - } + function add(name) { + local_used_names.add(name); + } - if (node.type === 'ExportNamedDeclaration') { - if (node.source) { - this.error(node, { - code: 'not-implemented', - message: 'A component currently cannot have an export ... from' - }); - } - if (node.declaration) { - if (node.declaration.type === 'VariableDeclaration') { - node.declaration.declarations.forEach(declarator => { - extract_names(declarator.id).forEach(name => { - const variable = this.var_lookup.get(name); - variable.export_name = name; - if (variable.writable && !(variable.referenced || variable.referenced_from_script || variable.subscribable)) { - this.warn(declarator, { - code: 'unused-export-let', - message: `${this.name.name} has unused export property '${name}'. If it is for external reference only, please consider using \`export const ${name}\`` - }); - } - }); - }); - } else { - const { name } = node.declaration.id; + reserved.forEach(add); + internal_exports.forEach(add); + this.var_lookup.forEach((_value, key) => add(key)); + + return (name) => { + if (test) name = `${name}$`; + let alias = name; + for (let i = 1; this.used_names.has(alias) || local_used_names.has(alias); alias = `${name}_${i++}`); + local_used_names.add(alias); + this.globally_used_names.add(alias); + + return { + type: 'Identifier', + name: alias, + }; + }; + } - const variable = this.var_lookup.get(name); - variable.export_name = name; - } + error( + pos, + + e + ) { + error(e.message, { + name: 'ValidationError', + code: e.code, + source: this.source, + start: pos.start, + end: pos.end, + filename: this.compile_options.filename, + }); + } - return node.declaration; - } else { - node.specifiers.forEach(specifier => { - const variable = this.var_lookup.get(specifier.local.name); + warn( + pos, - if (variable) { - variable.export_name = specifier.exported.name; + warning + ) { + if (this.ignores && this.ignores.has(warning.code)) { + return; + } - if (variable.writable && !(variable.referenced || variable.referenced_from_script || variable.subscribable)) { - this.warn(specifier, { - code: 'unused-export-let', - message: `${this.name.name} has unused export property '${specifier.exported.name}'. If it is for external reference only, please consider using \`export const ${specifier.exported.name}\`` - }); - } - } - }); + const start = this.locate(pos.start); + const end = this.locate(pos.end); - return null; - } - } - } - - extract_javascript(script) { - if (!script) return null; - - return script.content.body.filter(node => { - if (!node) return false; - if (this.hoistable_nodes.has(node)) return false; - if (this.reactive_declaration_nodes.has(node)) return false; - if (node.type === 'ImportDeclaration') return false; - if (node.type === 'ExportDeclaration' && node.specifiers.length > 0) return false; - return true; - }); - } - - walk_module_js() { - const component = this; - const script = this.ast.module; - if (!script) return; - - walk(script.content, { - enter(node) { - if (node.type === 'LabeledStatement' && node.label.name === '$') { - component.warn(node , { - code: 'module-script-reactive-declaration', - message: '$: has no effect in a module script' - }); - } - } - }); + const frame = get_code_frame(this.source, start.line - 1, start.column); - const { scope, globals } = create_scopes(script.content); - this.module_scope = scope; + this.warnings.push({ + code: warning.code, + message: warning.message, + frame, + start, + end, + pos: pos.start, + filename: this.compile_options.filename, + toString: () => `${warning.message} (${start.line}:${start.column})\n${frame}`, + }); + } - scope.declarations.forEach((node, name) => { - if (name[0] === '$') { - this.error(node , { - code: 'illegal-declaration', - message: 'The $ prefix is reserved, and cannot be used for variable and import names' - }); - } + extract_imports(node) { + this.imports.push(node); + } - const writable = node.type === 'VariableDeclaration' && (node.kind === 'var' || node.kind === 'let'); + extract_exports(node) { + if (node.type === 'ExportDefaultDeclaration') { + this.error(node, { + code: 'default-export', + message: 'A component cannot have a default export', + }); + } - this.add_var({ - name, - module: true, - hoistable: true, - writable - }); - }); + if (node.type === 'ExportNamedDeclaration') { + if (node.source) { + this.error(node, { + code: 'not-implemented', + message: 'A component currently cannot have an export ... from', + }); + } + if (node.declaration) { + if (node.declaration.type === 'VariableDeclaration') { + node.declaration.declarations.forEach((declarator) => { + extract_names(declarator.id).forEach((name) => { + const variable = this.var_lookup.get(name); + variable.export_name = name; + if (variable.writable && !(variable.referenced || variable.referenced_from_script || variable.subscribable)) { + this.warn(declarator, { + code: 'unused-export-let', + message: `${this.name.name} has unused export property '${name}'. If it is for external reference only, please consider using \`export const ${name}\``, + }); + } + }); + }); + } else { + const { name } = node.declaration.id; - globals.forEach((node, name) => { - if (name[0] === '$') { - this.error(node , { - code: 'illegal-subscription', - message: 'Cannot reference store value inside <script context="module">' - }); - } else { - this.add_var({ - name, - global: true, - hoistable: true - }); - } - }); + const variable = this.var_lookup.get(name); + variable.export_name = name; + } - const { body } = script.content; - let i = body.length; - while (--i >= 0) { - const node = body[i]; - if (node.type === 'ImportDeclaration') { - this.extract_imports(node); - body.splice(i, 1); - } + return node.declaration; + } else { + node.specifiers.forEach((specifier) => { + const variable = this.var_lookup.get(specifier.local.name); - if (/^Export/.test(node.type)) { - const replacement = this.extract_exports(node); - if (replacement) { - body[i] = replacement; - } else { - body.splice(i, 1); - } - } - } - } + if (variable) { + variable.export_name = specifier.exported.name; - walk_instance_js_pre_template() { - const script = this.ast.instance; - if (!script) return; + if (variable.writable && !(variable.referenced || variable.referenced_from_script || variable.subscribable)) { + this.warn(specifier, { + code: 'unused-export-let', + message: `${this.name.name} has unused export property '${specifier.exported.name}'. If it is for external reference only, please consider using \`export const ${specifier.exported.name}\``, + }); + } + } + }); - // inject vars for reactive declarations - script.content.body.forEach(node => { - if (node.type !== 'LabeledStatement') return; - if (node.body.type !== 'ExpressionStatement') return; + return null; + } + } + } - const { expression } = node.body; - if (expression.type !== 'AssignmentExpression') return; - if (expression.left.type === 'MemberExpression') return; + extract_javascript(script) { + if (!script) return null; - extract_names(expression.left).forEach(name => { - if (!this.var_lookup.has(name) && name[0] !== '$') { - this.injected_reactive_declaration_vars.add(name); - } - }); - }); + return script.content.body.filter((node) => { + if (!node) return false; + if (this.hoistable_nodes.has(node)) return false; + if (this.reactive_declaration_nodes.has(node)) return false; + if (node.type === 'ImportDeclaration') return false; + if (node.type === 'ExportDeclaration' && node.specifiers.length > 0) return false; + return true; + }); + } - const { scope: instance_scope, map, globals } = create_scopes( - script.content - ); - this.instance_scope = instance_scope; - this.instance_scope_map = map; - - instance_scope.declarations.forEach((node, name) => { - if (name[0] === '$') { - this.error(node , { - code: 'illegal-declaration', - message: 'The $ prefix is reserved, and cannot be used for variable and import names' - }); - } + walk_module_js() { + const component = this; + const script = this.ast.module; + if (!script) return; + + walk(script.content, { + enter(node) { + if (node.type === 'LabeledStatement' && node.label.name === '$') { + component.warn(node, { + code: 'module-script-reactive-declaration', + message: '$: has no effect in a module script', + }); + } + }, + }); - const writable = node.type === 'VariableDeclaration' && (node.kind === 'var' || node.kind === 'let'); - const imported = node.type.startsWith('Import'); + const { scope, globals } = create_scopes(script.content); + this.module_scope = scope; - this.add_var({ - name, - initialised: instance_scope.initialised_declarations.has(name), - writable, - imported - }); + scope.declarations.forEach((node, name) => { + if (name[0] === '$') { + this.error(node, { + code: 'illegal-declaration', + message: 'The $ prefix is reserved, and cannot be used for variable and import names', + }); + } - this.node_for_declaration.set(name, node); - }); + const writable = node.type === 'VariableDeclaration' && (node.kind === 'var' || node.kind === 'let'); - globals.forEach((node, name) => { - if (this.var_lookup.has(name)) return; + this.add_var({ + name, + module: true, + hoistable: true, + writable, + }); + }); - if (this.injected_reactive_declaration_vars.has(name)) { - this.add_var({ - name, - injected: true, - writable: true, - reassigned: true, - initialised: true - }); - } else if (is_reserved_keyword(name)) { - this.add_var({ - name, - injected: true - }); - } else if (name[0] === '$') { - if (name === '$' || name[1] === '$') { - this.error(node , { - code: 'illegal-global', - message: `${name} is an illegal variable name` - }); - } + globals.forEach((node, name) => { + if (name[0] === '$') { + this.error(node, { + code: 'illegal-subscription', + message: 'Cannot reference store value inside <script context="module">', + }); + } else { + this.add_var({ + name, + global: true, + hoistable: true, + }); + } + }); - this.add_var({ - name, - injected: true, - mutated: true, - writable: true - }); + const { body } = script.content; + let i = body.length; + while (--i >= 0) { + const node = body[i]; + if (node.type === 'ImportDeclaration') { + this.extract_imports(node); + body.splice(i, 1); + } - this.add_reference(name.slice(1)); + if (/^Export/.test(node.type)) { + const replacement = this.extract_exports(node); + if (replacement) { + body[i] = replacement; + } else { + body.splice(i, 1); + } + } + } + } - const variable = this.var_lookup.get(name.slice(1)); - if (variable) { - variable.subscribable = true; - variable.referenced_from_script = true; - } - } else { - this.add_var({ - name, - global: true, - hoistable: true - }); - } - }); + walk_instance_js_pre_template() { + const script = this.ast.instance; + if (!script) return; - this.track_references_and_mutations(); - } + // inject vars for reactive declarations + script.content.body.forEach((node) => { + if (node.type !== 'LabeledStatement') return; + if (node.body.type !== 'ExpressionStatement') return; - walk_instance_js_post_template() { - const script = this.ast.instance; - if (!script) return; + const { expression } = node.body; + if (expression.type !== 'AssignmentExpression') return; + if (expression.left.type === 'MemberExpression') return; - this.post_template_walk(); + extract_names(expression.left).forEach((name) => { + if (!this.var_lookup.has(name) && name[0] !== '$') { + this.injected_reactive_declaration_vars.add(name); + } + }); + }); - this.hoist_instance_declarations(); - this.extract_reactive_declarations(); - } + const { scope: instance_scope, map, globals } = create_scopes(script.content); + this.instance_scope = instance_scope; + this.instance_scope_map = map; - post_template_walk() { - const script = this.ast.instance; - if (!script) return; + instance_scope.declarations.forEach((node, name) => { + if (name[0] === '$') { + this.error(node, { + code: 'illegal-declaration', + message: 'The $ prefix is reserved, and cannot be used for variable and import names', + }); + } - const component = this; - const { content } = script; - const { instance_scope, instance_scope_map: map } = this; + const writable = node.type === 'VariableDeclaration' && (node.kind === 'var' || node.kind === 'let'); + const imported = node.type.startsWith('Import'); - let scope = instance_scope; + this.add_var({ + name, + initialised: instance_scope.initialised_declarations.has(name), + writable, + imported, + }); - const to_remove = []; - const remove = (parent, prop, index) => { - to_remove.unshift([parent, prop, index]); - }; - let scope_updated = false; + this.node_for_declaration.set(name, node); + }); - let generator_count = 0; + globals.forEach((node, name) => { + if (this.var_lookup.has(name)) return; + + if (this.injected_reactive_declaration_vars.has(name)) { + this.add_var({ + name, + injected: true, + writable: true, + reassigned: true, + initialised: true, + }); + } else if (is_reserved_keyword(name)) { + this.add_var({ + name, + injected: true, + }); + } else if (name[0] === '$') { + if (name === '$' || name[1] === '$') { + this.error(node, { + code: 'illegal-global', + message: `${name} is an illegal variable name`, + }); + } - walk(content, { - enter(node, parent, prop, index) { - if ((node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression') && node.generator === true) { - generator_count++; - } + this.add_var({ + name, + injected: true, + mutated: true, + writable: true, + }); - if (map.has(node)) { - scope = map.get(node); - } + this.add_reference(name.slice(1)); - if (node.type === 'ImportDeclaration') { - component.extract_imports(node); - // TODO: to use actual remove - remove(parent, prop, index); - return this.skip(); - } + const variable = this.var_lookup.get(name.slice(1)); + if (variable) { + variable.subscribable = true; + variable.referenced_from_script = true; + } + } else { + this.add_var({ + name, + global: true, + hoistable: true, + }); + } + }); - if (/^Export/.test(node.type)) { - const replacement = component.extract_exports(node); - if (replacement) { - this.replace(replacement); - } else { - // TODO: to use actual remove - remove(parent, prop, index); - } - return this.skip(); - } + this.track_references_and_mutations(); + } - component.warn_on_undefined_store_value_references(node, parent, prop, scope); - }, + walk_instance_js_post_template() { + const script = this.ast.instance; + if (!script) return; - leave(node) { - if ((node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression') && node.generator === true) { - generator_count--; - } + this.post_template_walk(); - // do it on leave, to prevent infinite loop - if (component.compile_options.dev && component.compile_options.loopGuardTimeout > 0 && generator_count <= 0) { - const to_replace_for_loop_protect = component.loop_protect(node, scope, component.compile_options.loopGuardTimeout); - if (to_replace_for_loop_protect) { - this.replace(to_replace_for_loop_protect); - scope_updated = true; - } - } + this.hoist_instance_declarations(); + this.extract_reactive_declarations(); + } - if (map.has(node)) { - scope = scope.parent; - } - } - }); + post_template_walk() { + const script = this.ast.instance; + if (!script) return; - for (const [parent, prop, index] of to_remove) { - if (parent) { - if (index !== null) { - parent[prop].splice(index, 1); - } else { - delete parent[prop]; - } - } - } + const component = this; + const { content } = script; + const { instance_scope, instance_scope_map: map } = this; - if (scope_updated) { - const { scope, map } = create_scopes(script.content); - this.instance_scope = scope; - this.instance_scope_map = map; - } - } + let scope = instance_scope; - track_references_and_mutations() { - const script = this.ast.instance; - if (!script) return; + const to_remove = []; + const remove = (parent, prop, index) => { + to_remove.unshift([parent, prop, index]); + }; + let scope_updated = false; - const component = this; - const { content } = script; - const { instance_scope, module_scope, instance_scope_map: map } = this; + let generator_count = 0; - let scope = instance_scope; + walk(content, { + enter(node, parent, prop, index) { + if ((node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression') && node.generator === true) { + generator_count++; + } - walk(content, { - enter(node, parent) { - if (map.has(node)) { - scope = map.get(node); - } + if (map.has(node)) { + scope = map.get(node); + } - if (node.type === 'AssignmentExpression' || node.type === 'UpdateExpression') { - const assignee = node.type === 'AssignmentExpression' ? node.left : node.argument; - const names = extract_names(assignee); - - const deep = assignee.type === 'MemberExpression'; - - names.forEach(name => { - const scope_owner = scope.find_owner(name); - if ( - scope_owner !== null - ? scope_owner === instance_scope - : module_scope && module_scope.has(name) - ) { - const variable = component.var_lookup.get(name); - variable[deep ? 'mutated' : 'reassigned'] = true; - } - }); - } + if (node.type === 'ImportDeclaration') { + component.extract_imports(node); + // TODO: to use actual remove + remove(parent, prop, index); + return this.skip(); + } - if (is_used_as_reference(node, parent)) { - const object = get_object(node); - if (scope.find_owner(object.name) === instance_scope) { - const variable = component.var_lookup.get(object.name); - variable.referenced_from_script = true; - } - } - }, + if (/^Export/.test(node.type)) { + const replacement = component.extract_exports(node); + if (replacement) { + this.replace(replacement); + } else { + // TODO: to use actual remove + remove(parent, prop, index); + } + return this.skip(); + } - leave(node) { - if (map.has(node)) { - scope = scope.parent; - } - } - }); - } - - warn_on_undefined_store_value_references(node, parent, prop, scope) { - if ( - node.type === 'LabeledStatement' && - node.label.name === '$' && - parent.type !== 'Program' - ) { - this.warn(node , { - code: 'non-top-level-reactive-declaration', - message: '$: has no effect outside of the top-level' - }); - } + component.warn_on_undefined_store_value_references(node, parent, prop, scope); + }, - if (isReference(node, parent)) { - const object = get_object(node); - const { name } = object; + leave(node) { + if ((node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression') && node.generator === true) { + generator_count--; + } - if (name[0] === '$') { - if (!scope.has(name)) { - this.warn_if_undefined(name, object, null); - } + // do it on leave, to prevent infinite loop + if (component.compile_options.dev && component.compile_options.loopGuardTimeout > 0 && generator_count <= 0) { + const to_replace_for_loop_protect = component.loop_protect(node, scope, component.compile_options.loopGuardTimeout); + if (to_replace_for_loop_protect) { + this.replace(to_replace_for_loop_protect); + scope_updated = true; + } + } - if (name[1] !== '$' && scope.has(name.slice(1)) && scope.find_owner(name.slice(1)) !== this.instance_scope) { - if (!((/Function/.test(parent.type) && prop === 'params') || (parent.type === 'VariableDeclarator' && prop === 'id'))) { - this.error(node , { - code: 'contextual-store', - message: 'Stores must be declared at the top level of the component (this may change in a future version of Svelte)' - }); - } - } - } - } - } - - loop_protect(node, scope, timeout) { - if (node.type === 'WhileStatement' || - node.type === 'ForStatement' || - node.type === 'DoWhileStatement') { - const guard = this.get_unique_name('guard', scope); - this.used_names.add(guard.name); - - const before = b`const ${guard} = @loop_guard(${timeout})`; - const inside = b`${guard}();`; - - // wrap expression statement with BlockStatement - if (node.body.type !== 'BlockStatement') { - node.body = { - type: 'BlockStatement', - body: [node.body] - }; - } - node.body.body.push(inside[0]); - - return { - type: 'BlockStatement', - body: [ - before[0], - node - ] - }; - } - return null; - } + if (map.has(node)) { + scope = scope.parent; + } + }, + }); - rewrite_props(get_insert) { - if (!this.ast.instance) return; + for (const [parent, prop, index] of to_remove) { + if (parent) { + if (index !== null) { + parent[prop].splice(index, 1); + } else { + delete parent[prop]; + } + } + } - const component = this; - const { instance_scope, instance_scope_map: map } = this; - let scope = instance_scope; + if (scope_updated) { + const { scope, map } = create_scopes(script.content); + this.instance_scope = scope; + this.instance_scope_map = map; + } + } - walk(this.ast.instance.content, { - enter(node, parent, key, index) { - if (/Function/.test(node.type)) { - return this.skip(); - } + track_references_and_mutations() { + const script = this.ast.instance; + if (!script) return; - if (map.has(node)) { - scope = map.get(node); - } + const component = this; + const { content } = script; + const { instance_scope, module_scope, instance_scope_map: map } = this; - if (node.type === 'VariableDeclaration') { - if (node.kind === 'var' || scope === instance_scope) { - node.declarations.forEach(declarator => { - if (declarator.id.type !== 'Identifier') { - const inserts = []; - - extract_names(declarator.id).forEach(name => { - const variable = component.var_lookup.get(name); - - if (variable.export_name) { - // TODO is this still true post-#3539? - component.error(declarator , { - code: 'destructured-prop', - message: 'Cannot declare props in destructured declaration' - }); - } - - if (variable.subscribable) { - inserts.push(get_insert(variable)); - } - }); - - if (inserts.length) { - parent[key].splice(index + 1, 0, ...inserts); - } - - return; - } - - const { name } = declarator.id; - const variable = component.var_lookup.get(name); - - if (variable.export_name && variable.writable) { - declarator.id = { - type: 'ObjectPattern', - properties: [{ - type: 'Property', - method: false, - shorthand: false, - computed: false, - kind: 'init', - key: { type: 'Identifier', name: variable.export_name }, - value: declarator.init - ? { - type: 'AssignmentPattern', - left: declarator.id, - right: declarator.init - } - : declarator.id - }] - }; - - declarator.init = x`$$props`; - } - - if (variable.subscribable && declarator.init) { - const insert = get_insert(variable); - parent[key].splice(index + 1, 0, ...insert); - } - }); - } - } - }, + let scope = instance_scope; - leave(node, parent, _key, index) { - if (map.has(node)) { - scope = scope.parent; - } + walk(content, { + enter(node, parent) { + if (map.has(node)) { + scope = map.get(node); + } - if (node.type === 'ExportNamedDeclaration' && node.declaration) { - (parent ).body[index] = node.declaration; - } - } - }); - } - - hoist_instance_declarations() { - // we can safely hoist variable declarations that are - // initialised to literals, and functions that don't - // reference instance variables other than other - // hoistable functions. TODO others? - - const { - hoistable_nodes, - var_lookup, - injected_reactive_declaration_vars, - imports - } = this; - - const top_level_function_declarations = new Map(); - - const { body } = this.ast.instance.content; - - for (let i = 0; i < body.length; i += 1) { - const node = body[i]; - - if (node.type === 'VariableDeclaration') { - const all_hoistable = node.declarations.every(d => { - if (!d.init) return false; - if (d.init.type !== 'Literal') return false; - - // everything except const values can be changed by e.g. svelte devtools - // which means we can't hoist it - if (node.kind !== 'const' && this.compile_options.dev) return false; - - const { name } = d.id ; - - const v = this.var_lookup.get(name); - if (v.reassigned) return false; - if (v.export_name) return false; - - if (this.var_lookup.get(name).reassigned) return false; - if ( - this.vars.find( - variable => variable.name === name && variable.module - ) - ) { - return false; - } + if (node.type === 'AssignmentExpression' || node.type === 'UpdateExpression') { + const assignee = node.type === 'AssignmentExpression' ? node.left : node.argument; + const names = extract_names(assignee); - return true; - }); + const deep = assignee.type === 'MemberExpression'; - if (all_hoistable) { - node.declarations.forEach(d => { - const variable = this.var_lookup.get((d.id ).name); - variable.hoistable = true; - }); + names.forEach((name) => { + const scope_owner = scope.find_owner(name); + if (scope_owner !== null ? scope_owner === instance_scope : module_scope && module_scope.has(name)) { + const variable = component.var_lookup.get(name); + variable[deep ? 'mutated' : 'reassigned'] = true; + } + }); + } - hoistable_nodes.add(node); + if (is_used_as_reference(node, parent)) { + const object = get_object(node); + if (scope.find_owner(object.name) === instance_scope) { + const variable = component.var_lookup.get(object.name); + variable.referenced_from_script = true; + } + } + }, - body.splice(i--, 1); - this.fully_hoisted.push(node); - } - } + leave(node) { + if (map.has(node)) { + scope = scope.parent; + } + }, + }); + } - if ( - node.type === 'ExportNamedDeclaration' && - node.declaration && - node.declaration.type === 'FunctionDeclaration' - ) { - top_level_function_declarations.set(node.declaration.id.name, node); - } + warn_on_undefined_store_value_references(node, parent, prop, scope) { + if (node.type === 'LabeledStatement' && node.label.name === '$' && parent.type !== 'Program') { + this.warn(node, { + code: 'non-top-level-reactive-declaration', + message: '$: has no effect outside of the top-level', + }); + } - if (node.type === 'FunctionDeclaration') { - top_level_function_declarations.set(node.id.name, node); - } - } + if (isReference(node, parent)) { + const object = get_object(node); + const { name } = object; - const checked = new Set(); - const walking = new Set(); + if (name[0] === '$') { + if (!scope.has(name)) { + this.warn_if_undefined(name, object, null); + } - const is_hoistable = fn_declaration => { - if (fn_declaration.type === 'ExportNamedDeclaration') { - fn_declaration = fn_declaration.declaration; - } + if (name[1] !== '$' && scope.has(name.slice(1)) && scope.find_owner(name.slice(1)) !== this.instance_scope) { + if (!((/Function/.test(parent.type) && prop === 'params') || (parent.type === 'VariableDeclarator' && prop === 'id'))) { + this.error(node, { + code: 'contextual-store', + message: 'Stores must be declared at the top level of the component (this may change in a future version of Svelte)', + }); + } + } + } + } + } - const instance_scope = this.instance_scope; - let scope = this.instance_scope; - const map = this.instance_scope_map; + loop_protect(node, scope, timeout) { + if (node.type === 'WhileStatement' || node.type === 'ForStatement' || node.type === 'DoWhileStatement') { + const guard = this.get_unique_name('guard', scope); + this.used_names.add(guard.name); - let hoistable = true; + const before = b`const ${guard} = @loop_guard(${timeout})`; + const inside = b`${guard}();`; - // handle cycles - walking.add(fn_declaration); + // wrap expression statement with BlockStatement + if (node.body.type !== 'BlockStatement') { + node.body = { + type: 'BlockStatement', + body: [node.body], + }; + } + node.body.body.push(inside[0]); - walk(fn_declaration, { - enter(node, parent) { - if (!hoistable) return this.skip(); + return { + type: 'BlockStatement', + body: [before[0], node], + }; + } + return null; + } - if (map.has(node)) { - scope = map.get(node); - } + rewrite_props(get_insert) { + if (!this.ast.instance) return; - if (isReference(node , parent )) { - const { name } = flatten_reference(node); - const owner = scope.find_owner(name); - - if (injected_reactive_declaration_vars.has(name)) { - hoistable = false; - } else if (name[0] === '$' && !owner) { - hoistable = false; - } else if (owner === instance_scope) { - const variable = var_lookup.get(name); - - if (variable.reassigned || variable.mutated) hoistable = false; - - if (name === fn_declaration.id.name) return; - - if (variable.hoistable) return; - - if (top_level_function_declarations.has(name)) { - const other_declaration = top_level_function_declarations.get( - name - ); - - if (walking.has(other_declaration)) { - hoistable = false; - } else if ( - other_declaration.type === 'ExportNamedDeclaration' && - walking.has(other_declaration.declaration) - ) { - hoistable = false; - } else if (!is_hoistable(other_declaration)) { - hoistable = false; - } - } else { - hoistable = false; - } - } + const component = this; + const { instance_scope, instance_scope_map: map } = this; + let scope = instance_scope; - this.skip(); - } - }, + walk(this.ast.instance.content, { + enter(node, parent, key, index) { + if (/Function/.test(node.type)) { + return this.skip(); + } - leave(node) { - if (map.has(node)) { - scope = scope.parent; - } - } - }); + if (map.has(node)) { + scope = map.get(node); + } - checked.add(fn_declaration); - walking.delete(fn_declaration); + if (node.type === 'VariableDeclaration') { + if (node.kind === 'var' || scope === instance_scope) { + node.declarations.forEach((declarator) => { + if (declarator.id.type !== 'Identifier') { + const inserts = []; + + extract_names(declarator.id).forEach((name) => { + const variable = component.var_lookup.get(name); + + if (variable.export_name) { + // TODO is this still true post-#3539? + component.error(declarator, { + code: 'destructured-prop', + message: 'Cannot declare props in destructured declaration', + }); + } + + if (variable.subscribable) { + inserts.push(get_insert(variable)); + } + }); + + if (inserts.length) { + parent[key].splice(index + 1, 0, ...inserts); + } - return hoistable; - }; + return; + } + + const { name } = declarator.id; + const variable = component.var_lookup.get(name); + + if (variable.export_name && variable.writable) { + declarator.id = { + type: 'ObjectPattern', + properties: [ + { + type: 'Property', + method: false, + shorthand: false, + computed: false, + kind: 'init', + key: { type: 'Identifier', name: variable.export_name }, + value: declarator.init + ? { + type: 'AssignmentPattern', + left: declarator.id, + right: declarator.init, + } + : declarator.id, + }, + ], + }; + + declarator.init = x`$$props`; + } + + if (variable.subscribable && declarator.init) { + const insert = get_insert(variable); + parent[key].splice(index + 1, 0, ...insert); + } + }); + } + } + }, - for (const [name, node] of top_level_function_declarations) { - if (is_hoistable(node)) { - const variable = this.var_lookup.get(name); - variable.hoistable = true; - hoistable_nodes.add(node); + leave(node, parent, _key, index) { + if (map.has(node)) { + scope = scope.parent; + } - const i = body.indexOf(node); - body.splice(i, 1); - this.fully_hoisted.push(node); - } - } + if (node.type === 'ExportNamedDeclaration' && node.declaration) { + parent.body[index] = node.declaration; + } + }, + }); + } - for (const { specifiers } of imports) { - for (const specifier of specifiers) { - const variable = var_lookup.get(specifier.local.name); + hoist_instance_declarations() { + // we can safely hoist variable declarations that are + // initialised to literals, and functions that don't + // reference instance variables other than other + // hoistable functions. TODO others? - if (!variable.mutated || variable.subscribable) { - variable.hoistable = true; - } - } - } - } + const { hoistable_nodes, var_lookup, injected_reactive_declaration_vars, imports } = this; - extract_reactive_declarations() { - const component = this; + const top_level_function_declarations = new Map(); - const unsorted_reactive_declarations + const { body } = this.ast.instance.content; + for (let i = 0; i < body.length; i += 1) { + const node = body[i]; + if (node.type === 'VariableDeclaration') { + const all_hoistable = node.declarations.every((d) => { + if (!d.init) return false; + if (d.init.type !== 'Literal') return false; + // everything except const values can be changed by e.g. svelte devtools + // which means we can't hoist it + if (node.kind !== 'const' && this.compile_options.dev) return false; - = []; + const { name } = d.id; - this.ast.instance.content.body.forEach(node => { - if (node.type === 'LabeledStatement' && node.label.name === '$') { - this.reactive_declaration_nodes.add(node); + const v = this.var_lookup.get(name); + if (v.reassigned) return false; + if (v.export_name) return false; - const assignees = new Set(); - const assignee_nodes = new Set(); - const dependencies = new Set(); + if (this.var_lookup.get(name).reassigned) return false; + if (this.vars.find((variable) => variable.name === name && variable.module)) { + return false; + } - let scope = this.instance_scope; - const map = this.instance_scope_map; + return true; + }); - walk(node.body, { - enter(node, parent) { - if (map.has(node)) { - scope = map.get(node); - } + if (all_hoistable) { + node.declarations.forEach((d) => { + const variable = this.var_lookup.get(d.id.name); + variable.hoistable = true; + }); - if (node.type === 'AssignmentExpression') { - const left = get_object(node.left); + hoistable_nodes.add(node); - extract_identifiers(left).forEach(node => { - assignee_nodes.add(node); - assignees.add(node.name); - }); + body.splice(i--, 1); + this.fully_hoisted.push(node); + } + } - if (node.operator !== '=') { - dependencies.add(left.name); - } - } else if (node.type === 'UpdateExpression') { - const identifier = get_object(node.argument); - assignees.add(identifier.name); - } else if (isReference(node , parent )) { - const identifier = get_object(node); - if (!assignee_nodes.has(identifier)) { - const { name } = identifier; - const owner = scope.find_owner(name); - const variable = component.var_lookup.get(name); - let should_add_as_dependency = true; - - if (variable) { - variable.is_reactive_dependency = true; - if (variable.module) { - should_add_as_dependency = false; - component.warn(node , { - code: 'module-script-reactive-declaration', - message: `"${name}" is declared in a module script and will not be reactive` - }); - } - } - const is_writable_or_mutated = - variable && (variable.writable || variable.mutated); - if ( - should_add_as_dependency && - (!owner || owner === component.instance_scope) && - (name[0] === '$' || is_writable_or_mutated) - ) { - dependencies.add(name); - } - } - - this.skip(); - } - }, + if (node.type === 'ExportNamedDeclaration' && node.declaration && node.declaration.type === 'FunctionDeclaration') { + top_level_function_declarations.set(node.declaration.id.name, node); + } - leave(node) { - if (map.has(node)) { - scope = scope.parent; - } - } - }); + if (node.type === 'FunctionDeclaration') { + top_level_function_declarations.set(node.id.name, node); + } + } - const { expression } = node.body ; - const declaration = expression && (expression ).left; + const checked = new Set(); + const walking = new Set(); - unsorted_reactive_declarations.push({ - assignees, - dependencies, - node, - declaration - }); - } - }); + const is_hoistable = (fn_declaration) => { + if (fn_declaration.type === 'ExportNamedDeclaration') { + fn_declaration = fn_declaration.declaration; + } - const lookup = new Map(); + const instance_scope = this.instance_scope; + let scope = this.instance_scope; + const map = this.instance_scope_map; - unsorted_reactive_declarations.forEach(declaration => { - declaration.assignees.forEach(name => { - if (!lookup.has(name)) { - lookup.set(name, []); - } + let hoistable = true; - // TODO warn or error if a name is assigned to in - // multiple reactive declarations? - lookup.get(name).push(declaration); - }); - }); + // handle cycles + walking.add(fn_declaration); - const cycle = check_graph_for_cycles(unsorted_reactive_declarations.reduce((acc, declaration) => { - declaration.assignees.forEach(v => { - declaration.dependencies.forEach(w => { - if (!declaration.assignees.has(w)) { - acc.push([v, w]); - } - }); - }); - return acc; - }, [])); - - if (cycle && cycle.length) { - const declarationList = lookup.get(cycle[0]); - const declaration = declarationList[0]; - this.error(declaration.node, { - code: 'cyclical-reactive-declaration', - message: `Cyclical dependency detected: ${cycle.join(' → ')}` - }); - } + walk(fn_declaration, { + enter(node, parent) { + if (!hoistable) return this.skip(); - const add_declaration = declaration => { - if (this.reactive_declarations.includes(declaration)) return; + if (map.has(node)) { + scope = map.get(node); + } - declaration.dependencies.forEach(name => { - if (declaration.assignees.has(name)) return; - const earlier_declarations = lookup.get(name); - if (earlier_declarations) { - earlier_declarations.forEach(add_declaration); - } - }); + if (isReference(node, parent)) { + const { name } = flatten_reference(node); + const owner = scope.find_owner(name); - this.reactive_declarations.push(declaration); - }; + if (injected_reactive_declaration_vars.has(name)) { + hoistable = false; + } else if (name[0] === '$' && !owner) { + hoistable = false; + } else if (owner === instance_scope) { + const variable = var_lookup.get(name); - unsorted_reactive_declarations.forEach(add_declaration); - } + if (variable.reassigned || variable.mutated) hoistable = false; - warn_if_undefined(name, node, template_scope) { - if (name[0] === '$') { - if (name === '$' || name[1] === '$' && !is_reserved_keyword(name)) { - this.error(node, { - code: 'illegal-global', - message: `${name} is an illegal variable name` - }); - } + if (name === fn_declaration.id.name) return; - this.has_reactive_assignments = true; // TODO does this belong here? + if (variable.hoistable) return; - if (is_reserved_keyword(name)) return; + if (top_level_function_declarations.has(name)) { + const other_declaration = top_level_function_declarations.get(name); - name = name.slice(1); - } + if (walking.has(other_declaration)) { + hoistable = false; + } else if (other_declaration.type === 'ExportNamedDeclaration' && walking.has(other_declaration.declaration)) { + hoistable = false; + } else if (!is_hoistable(other_declaration)) { + hoistable = false; + } + } else { + hoistable = false; + } + } - if (this.var_lookup.has(name) && !this.var_lookup.get(name).global) return; - if (template_scope && template_scope.names.has(name)) return; - if (globals.has(name) && node.type !== 'InlineComponent') return; + this.skip(); + } + }, - let message = `'${name}' is not defined`; - if (!this.ast.instance) { - message += `. Consider adding a <script> block with 'export let ${name}' to declare a prop`; - } + leave(node) { + if (map.has(node)) { + scope = scope.parent; + } + }, + }); - this.warn(node, { - code: 'missing-declaration', - message - }); - } + checked.add(fn_declaration); + walking.delete(fn_declaration); + + return hoistable; + }; + + for (const [name, node] of top_level_function_declarations) { + if (is_hoistable(node)) { + const variable = this.var_lookup.get(name); + variable.hoistable = true; + hoistable_nodes.add(node); + + const i = body.indexOf(node); + body.splice(i, 1); + this.fully_hoisted.push(node); + } + } + + for (const { specifiers } of imports) { + for (const specifier of specifiers) { + const variable = var_lookup.get(specifier.local.name); + + if (!variable.mutated || variable.subscribable) { + variable.hoistable = true; + } + } + } + } + + extract_reactive_declarations() { + const component = this; + + const unsorted_reactive_declarations = []; + + this.ast.instance.content.body.forEach((node) => { + if (node.type === 'LabeledStatement' && node.label.name === '$') { + this.reactive_declaration_nodes.add(node); + + const assignees = new Set(); + const assignee_nodes = new Set(); + const dependencies = new Set(); + + let scope = this.instance_scope; + const map = this.instance_scope_map; + + walk(node.body, { + enter(node, parent) { + if (map.has(node)) { + scope = map.get(node); + } + + if (node.type === 'AssignmentExpression') { + const left = get_object(node.left); + + extract_identifiers(left).forEach((node) => { + assignee_nodes.add(node); + assignees.add(node.name); + }); + + if (node.operator !== '=') { + dependencies.add(left.name); + } + } else if (node.type === 'UpdateExpression') { + const identifier = get_object(node.argument); + assignees.add(identifier.name); + } else if (isReference(node, parent)) { + const identifier = get_object(node); + if (!assignee_nodes.has(identifier)) { + const { name } = identifier; + const owner = scope.find_owner(name); + const variable = component.var_lookup.get(name); + let should_add_as_dependency = true; + + if (variable) { + variable.is_reactive_dependency = true; + if (variable.module) { + should_add_as_dependency = false; + component.warn(node, { + code: 'module-script-reactive-declaration', + message: `"${name}" is declared in a module script and will not be reactive`, + }); + } + } + const is_writable_or_mutated = variable && (variable.writable || variable.mutated); + if (should_add_as_dependency && (!owner || owner === component.instance_scope) && (name[0] === '$' || is_writable_or_mutated)) { + dependencies.add(name); + } + } - push_ignores(ignores) { - this.ignores = new Set(this.ignores || []); - add_to_set(this.ignores, ignores); - this.ignore_stack.push(this.ignores); - } + this.skip(); + } + }, + + leave(node) { + if (map.has(node)) { + scope = scope.parent; + } + }, + }); + + const { expression } = node.body; + const declaration = expression && expression.left; + + unsorted_reactive_declarations.push({ + assignees, + dependencies, + node, + declaration, + }); + } + }); + + const lookup = new Map(); + + unsorted_reactive_declarations.forEach((declaration) => { + declaration.assignees.forEach((name) => { + if (!lookup.has(name)) { + lookup.set(name, []); + } + + // TODO warn or error if a name is assigned to in + // multiple reactive declarations? + lookup.get(name).push(declaration); + }); + }); + + const cycle = check_graph_for_cycles( + unsorted_reactive_declarations.reduce((acc, declaration) => { + declaration.assignees.forEach((v) => { + declaration.dependencies.forEach((w) => { + if (!declaration.assignees.has(w)) { + acc.push([v, w]); + } + }); + }); + return acc; + }, []) + ); + + if (cycle && cycle.length) { + const declarationList = lookup.get(cycle[0]); + const declaration = declarationList[0]; + this.error(declaration.node, { + code: 'cyclical-reactive-declaration', + message: `Cyclical dependency detected: ${cycle.join(' → ')}`, + }); + } + + const add_declaration = (declaration) => { + if (this.reactive_declarations.includes(declaration)) return; + + declaration.dependencies.forEach((name) => { + if (declaration.assignees.has(name)) return; + const earlier_declarations = lookup.get(name); + if (earlier_declarations) { + earlier_declarations.forEach(add_declaration); + } + }); + + this.reactive_declarations.push(declaration); + }; + + unsorted_reactive_declarations.forEach(add_declaration); + } + + warn_if_undefined(name, node, template_scope) { + if (name[0] === '$') { + if (name === '$' || (name[1] === '$' && !is_reserved_keyword(name))) { + this.error(node, { + code: 'illegal-global', + message: `${name} is an illegal variable name`, + }); + } + + this.has_reactive_assignments = true; // TODO does this belong here? + + if (is_reserved_keyword(name)) return; + + name = name.slice(1); + } + + if (this.var_lookup.has(name) && !this.var_lookup.get(name).global) return; + if (template_scope && template_scope.names.has(name)) return; + if (globals.has(name) && node.type !== 'InlineComponent') return; + + let message = `'${name}' is not defined`; + if (!this.ast.instance) { + message += `. Consider adding a <script> block with 'export let ${name}' to declare a prop`; + } + + this.warn(node, { + code: 'missing-declaration', + message, + }); + } - pop_ignores() { - this.ignore_stack.pop(); - this.ignores = this.ignore_stack[this.ignore_stack.length - 1]; - } + push_ignores(ignores) { + this.ignores = new Set(this.ignores || []); + add_to_set(this.ignores, ignores); + this.ignore_stack.push(this.ignores); + } + + pop_ignores() { + this.ignore_stack.pop(); + this.ignores = this.ignore_stack[this.ignore_stack.length - 1]; + } } function process_component_options(component, nodes) { - const component_options = { - immutable: component.compile_options.immutable || false, - accessors: - 'accessors' in component.compile_options - ? component.compile_options.accessors - : !!component.compile_options.customElement, - preserveWhitespace: !!component.compile_options.preserveWhitespace, - namespace: component.compile_options.namespace - }; - - const node = nodes.find(node => node.name === 'svelte:options'); - - function get_value(attribute, code, message) { - const { value } = attribute; - const chunk = value[0]; - - if (!chunk) return true; - - if (value.length > 1) { - component.error(attribute, { code, message }); - } + const component_options = { + immutable: component.compile_options.immutable || false, + accessors: 'accessors' in component.compile_options ? component.compile_options.accessors : !!component.compile_options.customElement, + preserveWhitespace: !!component.compile_options.preserveWhitespace, + namespace: component.compile_options.namespace, + }; - if (chunk.type === 'Text') return chunk.data; + const node = nodes.find((node) => node.name === 'svelte:options'); - if (chunk.expression.type !== 'Literal') { - component.error(attribute, { code, message }); - } + function get_value(attribute, code, message) { + const { value } = attribute; + const chunk = value[0]; - return chunk.expression.value; - } + if (!chunk) return true; - if (node) { - node.attributes.forEach(attribute => { - if (attribute.type === 'Attribute') { - const { name } = attribute; + if (value.length > 1) { + component.error(attribute, { code, message }); + } - switch (name) { - case 'tag': { - const code = 'invalid-tag-attribute'; - const message = "'tag' must be a string literal"; - const tag = get_value(attribute, code, message); + if (chunk.type === 'Text') return chunk.data; - if (typeof tag !== 'string' && tag !== null) { - component.error(attribute, { code, message }); - } + if (chunk.expression.type !== 'Literal') { + component.error(attribute, { code, message }); + } - if (tag && !/^[a-zA-Z][a-zA-Z0-9]*-[a-zA-Z0-9-]+$/.test(tag)) { - component.error(attribute, { - code: 'invalid-tag-property', - message: "tag name must be two or more words joined by the '-' character" - }); - } + return chunk.expression.value; + } - if (tag && !component.compile_options.customElement) { - component.warn(attribute, { - code: 'missing-custom-element-compile-options', - message: "The 'tag' option is used when generating a custom element. Did you forget the 'customElement: true' compile option?" - }); - } + if (node) { + node.attributes.forEach((attribute) => { + if (attribute.type === 'Attribute') { + const { name } = attribute; - component_options.tag = tag; - break; - } + switch (name) { + case 'tag': { + const code = 'invalid-tag-attribute'; + const message = "'tag' must be a string literal"; + const tag = get_value(attribute, code, message); - case 'namespace': { - const code = 'invalid-namespace-attribute'; - const message = "The 'namespace' attribute must be a string literal representing a valid namespace"; - const ns = get_value(attribute, code, message); + if (typeof tag !== 'string' && tag !== null) { + component.error(attribute, { code, message }); + } - if (typeof ns !== 'string') { - component.error(attribute, { code, message }); - } + if (tag && !/^[a-zA-Z][a-zA-Z0-9]*-[a-zA-Z0-9-]+$/.test(tag)) { + component.error(attribute, { + code: 'invalid-tag-property', + message: "tag name must be two or more words joined by the '-' character", + }); + } - if (valid_namespaces.indexOf(ns) === -1) { - const match = fuzzymatch(ns, valid_namespaces); - if (match) { - component.error(attribute, { - code: 'invalid-namespace-property', - message: `Invalid namespace '${ns}' (did you mean '${match}'?)` - }); - } else { - component.error(attribute, { - code: 'invalid-namespace-property', - message: `Invalid namespace '${ns}'` - }); - } - } + if (tag && !component.compile_options.customElement) { + component.warn(attribute, { + code: 'missing-custom-element-compile-options', + message: "The 'tag' option is used when generating a custom element. Did you forget the 'customElement: true' compile option?", + }); + } - component_options.namespace = ns; - break; - } + component_options.tag = tag; + break; + } - case 'accessors': - case 'immutable': - case 'preserveWhitespace': { - const code = `invalid-${name}-value`; - const message = `${name} attribute must be true or false`; - const value = get_value(attribute, code, message); + case 'namespace': { + const code = 'invalid-namespace-attribute'; + const message = "The 'namespace' attribute must be a string literal representing a valid namespace"; + const ns = get_value(attribute, code, message); - if (typeof value !== 'boolean') { - component.error(attribute, { code, message }); - } + if (typeof ns !== 'string') { + component.error(attribute, { code, message }); + } - component_options[name] = value; - break; - } + if (valid_namespaces.indexOf(ns) === -1) { + const match = fuzzymatch(ns, valid_namespaces); + if (match) { + component.error(attribute, { + code: 'invalid-namespace-property', + message: `Invalid namespace '${ns}' (did you mean '${match}'?)`, + }); + } else { + component.error(attribute, { + code: 'invalid-namespace-property', + message: `Invalid namespace '${ns}'`, + }); + } + } - default: - component.error(attribute, { - code: 'invalid-options-attribute', - message: '<svelte:options> unknown attribute' - }); - } - } else { - component.error(attribute, { - code: 'invalid-options-attribute', - message: "<svelte:options> can only have static 'tag', 'namespace', 'accessors', 'immutable' and 'preserveWhitespace' attributes" - }); - } - }); - } + component_options.namespace = ns; + break; + } + + case 'accessors': + case 'immutable': + case 'preserveWhitespace': { + const code = `invalid-${name}-value`; + const message = `${name} attribute must be true or false`; + const value = get_value(attribute, code, message); - return component_options; + if (typeof value !== 'boolean') { + component.error(attribute, { code, message }); + } + + component_options[name] = value; + break; + } + + default: + component.error(attribute, { + code: 'invalid-options-attribute', + message: '<svelte:options> unknown attribute', + }); + } + } else { + component.error(attribute, { + code: 'invalid-options-attribute', + message: "<svelte:options> can only have static 'tag', 'namespace', 'accessors', 'immutable' and 'preserveWhitespace' attributes", + }); + } + }); + } + + return component_options; } function get_relative_path(from, to) { - const from_parts = from.split(/[/\\]/); - const to_parts = to.split(/[/\\]/); + const from_parts = from.split(/[/\\]/); + const to_parts = to.split(/[/\\]/); - from_parts.pop(); // get dirname + from_parts.pop(); // get dirname - while (from_parts[0] === to_parts[0]) { - from_parts.shift(); - to_parts.shift(); - } + while (from_parts[0] === to_parts[0]) { + from_parts.shift(); + to_parts.shift(); + } - if (from_parts.length) { - let i = from_parts.length; - while (i--) from_parts[i] = '..'; - } + if (from_parts.length) { + let i = from_parts.length; + while (i--) from_parts[i] = '..'; + } - return from_parts.concat(to_parts).join('/'); + return from_parts.concat(to_parts).join('/'); } function get_name_from_filename(filename) { - if (!filename) return null; - - const parts = filename.split(/[/\\]/).map(encodeURI); + if (!filename) return null; - if (parts.length > 1) { - const index_match = parts[parts.length - 1].match(/^index(\.\w+)/); - if (index_match) { - parts.pop(); - parts[parts.length - 1] += index_match[1]; - } - } + const parts = filename.split(/[/\\]/).map(encodeURI); - const base = parts.pop() - .replace(/%/g, 'u') - .replace(/\.[^.]+$/, '') - .replace(/[^a-zA-Z_$0-9]+/g, '_') - .replace(/^_/, '') - .replace(/_$/, '') - .replace(/^(\d)/, '_$1'); + if (parts.length > 1) { + const index_match = parts[parts.length - 1].match(/^index(\.\w+)/); + if (index_match) { + parts.pop(); + parts[parts.length - 1] += index_match[1]; + } + } - if (!base) { - throw new Error(`Could not derive component name from file ${filename}`); - } + const base = parts + .pop() + .replace(/%/g, 'u') + .replace(/\.[^.]+$/, '') + .replace(/[^a-zA-Z_$0-9]+/g, '_') + .replace(/^_/, '') + .replace(/_$/, '') + .replace(/^(\d)/, '_$1'); + + if (!base) { + throw new Error(`Could not derive component name from file ${filename}`); + } - return base[0].toUpperCase() + base.slice(1); + return base[0].toUpperCase() + base.slice(1); } const valid_options = [ - 'format', - 'name', - 'filename', - 'sourcemap', - 'generate', - 'outputFilename', - 'cssOutputFilename', - 'sveltePath', - 'dev', - 'accessors', - 'immutable', - 'hydratable', - 'legacy', - 'customElement', - 'namespace', - 'tag', - 'css', - 'loopGuardTimeout', - 'preserveComments', - 'preserveWhitespace', - 'cssHash' + 'format', + 'name', + 'filename', + 'sourcemap', + 'generate', + 'outputFilename', + 'cssOutputFilename', + 'sveltePath', + 'dev', + 'accessors', + 'immutable', + 'hydratable', + 'legacy', + 'customElement', + 'namespace', + 'tag', + 'css', + 'loopGuardTimeout', + 'preserveComments', + 'preserveWhitespace', + 'cssHash', ]; function validate_options(options, warnings) { - const { name, filename, loopGuardTimeout, dev, namespace } = options; + const { name, filename, loopGuardTimeout, dev, namespace } = options; - Object.keys(options).forEach(key => { - if (!valid_options.includes(key)) { - const match = fuzzymatch(key, valid_options); - let message = `Unrecognized option '${key}'`; - if (match) message += ` (did you mean '${match}'?)`; + Object.keys(options).forEach((key) => { + if (!valid_options.includes(key)) { + const match = fuzzymatch(key, valid_options); + let message = `Unrecognized option '${key}'`; + if (match) message += ` (did you mean '${match}'?)`; - throw new Error(message); - } - }); - - if (name && !/^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(name)) { - throw new Error(`options.name must be a valid identifier (got '${name}')`); - } - - if (name && /^[a-z]/.test(name)) { - const message = 'options.name should be capitalised'; - warnings.push({ - code: 'options-lowercase-name', - message, - filename, - toString: () => message - }); - } - - if (loopGuardTimeout && !dev) { - const message = 'options.loopGuardTimeout is for options.dev = true only'; - warnings.push({ - code: 'options-loop-guard-timeout', - message, - filename, - toString: () => message - }); - } - - if (namespace && valid_namespaces.indexOf(namespace) === -1) { - const match = fuzzymatch(namespace, valid_namespaces); - if (match) { - throw new Error(`Invalid namespace '${namespace}' (did you mean '${match}'?)`); - } else { - throw new Error(`Invalid namespace '${namespace}'`); - } - } + throw new Error(message); + } + }); + + if (name && !/^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(name)) { + throw new Error(`options.name must be a valid identifier (got '${name}')`); + } + + if (name && /^[a-z]/.test(name)) { + const message = 'options.name should be capitalised'; + warnings.push({ + code: 'options-lowercase-name', + message, + filename, + toString: () => message, + }); + } + + if (loopGuardTimeout && !dev) { + const message = 'options.loopGuardTimeout is for options.dev = true only'; + warnings.push({ + code: 'options-loop-guard-timeout', + message, + filename, + toString: () => message, + }); + } + + if (namespace && valid_namespaces.indexOf(namespace) === -1) { + const match = fuzzymatch(namespace, valid_namespaces); + if (match) { + throw new Error(`Invalid namespace '${namespace}' (did you mean '${match}'?)`); + } else { + throw new Error(`Invalid namespace '${namespace}'`); + } + } } function compile(source, options = {}) { - options = Object.assign({ generate: 'dom', dev: false }, options); + options = Object.assign({ generate: 'dom', dev: false }, options); - const stats = new Stats(); - const warnings = []; + const stats = new Stats(); + const warnings = []; - validate_options(options, warnings); + validate_options(options, warnings); - stats.start('parse'); - const ast = parse$1(source, options); - stats.stop('parse'); + stats.start('parse'); + const ast = parse$1(source, options); + stats.stop('parse'); - stats.start('create component'); - const component = new Component( - ast, - source, - options.name || get_name_from_filename(options.filename) || 'Component', - options, - stats, - warnings - ); - stats.stop('create component'); + stats.start('create component'); + const component = new Component(ast, source, options.name || get_name_from_filename(options.filename) || 'Component', options, stats, warnings); + stats.stop('create component'); - const result = options.generate === false - ? null - : options.generate === 'ssr' - ? ssr(component, options) - : dom(component, options); + const result = options.generate === false ? null : options.generate === 'ssr' ? ssr(component, options) : dom(component, options); - return component.generate(result); + return component.generate(result); } /** @@ -22141,377 +20787,346 @@ function compile(source, options = {}) { * We cannot use source-map.d.ts types, because we access hidden properties. */ function decoded_sourcemap_from_generator(generator) { - let previous_generated_line = 1; - const converted_mappings = [[]]; - let result_line; - let result_segment; - let mapping; + let previous_generated_line = 1; + const converted_mappings = [[]]; + let result_line; + let result_segment; + let mapping; - const source_idx = generator._sources.toArray() - .reduce((acc, val, idx) => (acc[val] = idx, acc), {}); + const source_idx = generator._sources.toArray().reduce((acc, val, idx) => ((acc[val] = idx), acc), {}); - const name_idx = generator._names.toArray() - .reduce((acc, val, idx) => (acc[val] = idx, acc), {}); + const name_idx = generator._names.toArray().reduce((acc, val, idx) => ((acc[val] = idx), acc), {}); - const mappings = generator._mappings.toArray(); - result_line = converted_mappings[0]; + const mappings = generator._mappings.toArray(); + result_line = converted_mappings[0]; - for (let i = 0, len = mappings.length; i < len; i++) { - mapping = mappings[i]; + for (let i = 0, len = mappings.length; i < len; i++) { + mapping = mappings[i]; - if (mapping.generatedLine > previous_generated_line) { - while (mapping.generatedLine > previous_generated_line) { - converted_mappings.push([]); - previous_generated_line++; - } - result_line = converted_mappings[mapping.generatedLine - 1]; // line is one-based - } else if (i > 0) { - const previous_mapping = mappings[i - 1]; - if ( - // sorted by selectivity - mapping.generatedColumn === previous_mapping.generatedColumn && - mapping.originalColumn === previous_mapping.originalColumn && - mapping.name === previous_mapping.name && - mapping.generatedLine === previous_mapping.generatedLine && - mapping.originalLine === previous_mapping.originalLine && - mapping.source === previous_mapping.source - ) { - continue; - } - } - result_line.push([mapping.generatedColumn]); - result_segment = result_line[result_line.length - 1]; - - if (mapping.source != null) { - result_segment.push(...[ - source_idx[mapping.source], - mapping.originalLine - 1, // line is one-based - mapping.originalColumn - ]); - if (mapping.name != null) { - result_segment.push(name_idx[mapping.name]); - } - } - } + if (mapping.generatedLine > previous_generated_line) { + while (mapping.generatedLine > previous_generated_line) { + converted_mappings.push([]); + previous_generated_line++; + } + result_line = converted_mappings[mapping.generatedLine - 1]; // line is one-based + } else if (i > 0) { + const previous_mapping = mappings[i - 1]; + if ( + // sorted by selectivity + mapping.generatedColumn === previous_mapping.generatedColumn && + mapping.originalColumn === previous_mapping.originalColumn && + mapping.name === previous_mapping.name && + mapping.generatedLine === previous_mapping.generatedLine && + mapping.originalLine === previous_mapping.originalLine && + mapping.source === previous_mapping.source + ) { + continue; + } + } + result_line.push([mapping.generatedColumn]); + result_segment = result_line[result_line.length - 1]; + + if (mapping.source != null) { + result_segment.push( + ...[ + source_idx[mapping.source], + mapping.originalLine - 1, // line is one-based + mapping.originalColumn, + ] + ); + if (mapping.name != null) { + result_segment.push(name_idx[mapping.name]); + } + } + } - const map = { - version: generator._version, - sources: generator._sources.toArray(), - names: generator._names.toArray(), - mappings: converted_mappings - }; - if (generator._file != null) { - (map ).file = generator._file; - } - // not needed: map.sourcesContent and map.sourceRoot - return map; + const map = { + version: generator._version, + sources: generator._sources.toArray(), + names: generator._names.toArray(), + mappings: converted_mappings, + }; + if (generator._file != null) { + map.file = generator._file; + } + // not needed: map.sourcesContent and map.sourceRoot + return map; } function decode_map(processed) { - let decoded_map = typeof processed.map === 'string' ? JSON.parse(processed.map) : processed.map; - if (typeof(decoded_map.mappings) === 'string') { - decoded_map.mappings = decode(decoded_map.mappings); - } - if ((decoded_map )._mappings && decoded_map.constructor.name === 'SourceMapGenerator') { - // import decoded sourcemap from mozilla/source-map/SourceMapGenerator - decoded_map = decoded_sourcemap_from_generator(decoded_map); - } - - return decoded_map; -} - -function slice_source( - code_slice, - offset, - { file_basename, filename, get_location } -) { - return { - source: code_slice, - get_location: (index) => get_location(index + offset), - file_basename, - filename - }; -} - -function calculate_replacements( - re, - get_replacement, - source -) { - const replacements = []; - - source.replace(re, (...match) => { - replacements.push( - get_replacement(...match).then( - replacement => { - const matched_string = match[0]; - const offset = match[match.length-2]; - - return ({ offset, length: matched_string.length, replacement }); - } - ) - ); - return ''; - }); + let decoded_map = typeof processed.map === 'string' ? JSON.parse(processed.map) : processed.map; + if (typeof decoded_map.mappings === 'string') { + decoded_map.mappings = decode(decoded_map.mappings); + } + if (decoded_map._mappings && decoded_map.constructor.name === 'SourceMapGenerator') { + // import decoded sourcemap from mozilla/source-map/SourceMapGenerator + decoded_map = decoded_sourcemap_from_generator(decoded_map); + } - return Promise.all(replacements); + return decoded_map; } -function perform_replacements( - replacements, - source -) { - const out = new MappedCode(); - let last_end = 0; - - for (const { offset, length, replacement } of replacements) { - const unchanged_prefix = MappedCode.from_source( - slice_source(source.source.slice(last_end, offset), last_end, source) - ); - out.concat(unchanged_prefix).concat(replacement); - last_end = offset + length; - } +function slice_source(code_slice, offset, { file_basename, filename, get_location }) { + return { + source: code_slice, + get_location: (index) => get_location(index + offset), + file_basename, + filename, + }; +} - const unchanged_suffix = MappedCode.from_source(slice_source(source.source.slice(last_end), last_end, source)); +function calculate_replacements(re, get_replacement, source) { + const replacements = []; - return out.concat(unchanged_suffix); -} + source.replace(re, (...match) => { + replacements.push( + get_replacement(...match).then((replacement) => { + const matched_string = match[0]; + const offset = match[match.length - 2]; -async function replace_in_code( - regex, - get_replacement, - location -) { - const replacements = await calculate_replacements(regex, get_replacement, location.source); + return { offset, length: matched_string.length, replacement }; + }) + ); + return ''; + }); - return perform_replacements(replacements, location); + return Promise.all(replacements); } -function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } - +function perform_replacements(replacements, source) { + const out = new MappedCode(); + let last_end = 0; + for (const { offset, length, replacement } of replacements) { + const unchanged_prefix = MappedCode.from_source(slice_source(source.source.slice(last_end, offset), last_end, source)); + out.concat(unchanged_prefix).concat(replacement); + last_end = offset + length; + } + const unchanged_suffix = MappedCode.from_source(slice_source(source.source.slice(last_end), last_end, source)); + return out.concat(unchanged_suffix); +} +async function replace_in_code(regex, get_replacement, location) { + const replacements = await calculate_replacements(regex, get_replacement, location.source); + return perform_replacements(replacements, location); +} +function _nullishCoalesce(lhs, rhsFn) { + if (lhs != null) { + return lhs; + } else { + return rhsFn(); + } +} function get_file_basename(filename) { - return filename.split(/[/\\]/).pop(); + return filename.split(/[/\\]/).pop(); } /** * Represents intermediate states of the preprocessing. */ -class PreprocessResult { - // sourcemap_list is sorted in reverse order from last map (index 0) to first map (index -1) - // so we use sourcemap_list.unshift() to add new maps - // https://github.com/ampproject/remapping#multiple-transformations-of-a-file - __init() {this.sourcemap_list = [];} - __init2() {this.dependencies = [];} - - - - - constructor( source, filename) {this.source = source;this.filename = filename;PreprocessResult.prototype.__init.call(this);PreprocessResult.prototype.__init2.call(this); - this.update_source({ string: source }); - - // preprocess source must be relative to itself or equal null - this.file_basename = filename == null ? null : get_file_basename(filename); - } - - update_source({ string: source, map, dependencies }) { - if (source != null) { - this.source = source; - this.get_location = getLocator(source); - } +class PreprocessResult { + // sourcemap_list is sorted in reverse order from last map (index 0) to first map (index -1) + // so we use sourcemap_list.unshift() to add new maps + // https://github.com/ampproject/remapping#multiple-transformations-of-a-file + __init() { + this.sourcemap_list = []; + } + __init2() { + this.dependencies = []; + } - if (map) { - this.sourcemap_list.unshift(map); - } + constructor(source, filename) { + this.source = source; + this.filename = filename; + PreprocessResult.prototype.__init.call(this); + PreprocessResult.prototype.__init2.call(this); + this.update_source({ string: source }); - if (dependencies) { - this.dependencies.push(...dependencies); - } - } + // preprocess source must be relative to itself or equal null + this.file_basename = filename == null ? null : get_file_basename(filename); + } - to_processed() { - // Combine all the source maps for each preprocessor function into one - const map = combine_sourcemaps(this.file_basename, this.sourcemap_list); + update_source({ string: source, map, dependencies }) { + if (source != null) { + this.source = source; + this.get_location = getLocator(source); + } - return { - // TODO return separated output, in future version where svelte.compile supports it: - // style: { code: styleCode, map: styleMap }, - // script { code: scriptCode, map: scriptMap }, - // markup { code: markupCode, map: markupMap }, + if (map) { + this.sourcemap_list.unshift(map); + } + + if (dependencies) { + this.dependencies.push(...dependencies); + } + } + + to_processed() { + // Combine all the source maps for each preprocessor function into one + const map = combine_sourcemaps(this.file_basename, this.sourcemap_list); - code: this.source, - dependencies: [...new Set(this.dependencies)], - map: map , - toString: () => this.source - }; - } + return { + // TODO return separated output, in future version where svelte.compile supports it: + // style: { code: styleCode, map: styleMap }, + // script { code: scriptCode, map: scriptMap }, + // markup { code: markupCode, map: markupMap }, + + code: this.source, + dependencies: [...new Set(this.dependencies)], + map: map, + toString: () => this.source, + }; + } } /** * Convert preprocessor output for the tag content into MappedCode */ function processed_content_to_code(processed, location, file_basename) { - // Convert the preprocessed code and its sourcemap to a MappedCode - let decoded_map; - if (processed.map) { - decoded_map = decode_map(processed); - - // offset only segments pointing at original component source - const source_index = decoded_map.sources.indexOf(file_basename); - if (source_index !== -1) { - sourcemap_add_offset(decoded_map, location, source_index); - } - } + // Convert the preprocessed code and its sourcemap to a MappedCode + let decoded_map; + if (processed.map) { + decoded_map = decode_map(processed); + + // offset only segments pointing at original component source + const source_index = decoded_map.sources.indexOf(file_basename); + if (source_index !== -1) { + sourcemap_add_offset(decoded_map, location, source_index); + } + } - return MappedCode.from_processed(processed.code, decoded_map); + return MappedCode.from_processed(processed.code, decoded_map); } /** * Given the whole tag including content, return a `MappedCode` * representing the tag content replaced with `processed`. */ -function processed_tag_to_code( - processed, - tag_name, - attributes, - source -) { - const { file_basename, get_location } = source; +function processed_tag_to_code(processed, tag_name, attributes, source) { + const { file_basename, get_location } = source; - const build_mapped_code = (code, offset) => - MappedCode.from_source(slice_source(code, offset, source)); + const build_mapped_code = (code, offset) => MappedCode.from_source(slice_source(code, offset, source)); - const tag_open = `<${tag_name}${attributes || ''}>`; - const tag_close = `</${tag_name}>`; + const tag_open = `<${tag_name}${attributes || ''}>`; + const tag_close = `</${tag_name}>`; - const tag_open_code = build_mapped_code(tag_open, 0); - const tag_close_code = build_mapped_code(tag_close, tag_open.length + source.source.length); + const tag_open_code = build_mapped_code(tag_open, 0); + const tag_close_code = build_mapped_code(tag_close, tag_open.length + source.source.length); - parse_attached_sourcemap(processed, tag_name); + parse_attached_sourcemap(processed, tag_name); - const content_code = processed_content_to_code(processed, get_location(tag_open.length), file_basename); + const content_code = processed_content_to_code(processed, get_location(tag_open.length), file_basename); - return tag_open_code.concat(content_code).concat(tag_close_code); + return tag_open_code.concat(content_code).concat(tag_close_code); } function parse_tag_attributes(str) { - // note: won't work with attribute values containing spaces. - return str - .split(/\s+/) - .filter(Boolean) - .reduce((attrs, attr) => { - const i = attr.indexOf('='); - const [key, value] = i > 0 ? [attr.slice(0, i), attr.slice(i+1)] : [attr]; - const [, unquoted] = (value && value.match(/^['"](.*)['"]$/)) || []; - - return { ...attrs, [key]: _nullishCoalesce(_nullishCoalesce(unquoted, () => ( value)), () => ( true)) }; - }, {}); + // note: won't work with attribute values containing spaces. + return str + .split(/\s+/) + .filter(Boolean) + .reduce((attrs, attr) => { + const i = attr.indexOf('='); + const [key, value] = i > 0 ? [attr.slice(0, i), attr.slice(i + 1)] : [attr]; + const [, unquoted] = (value && value.match(/^['"](.*)['"]$/)) || []; + + return { + ...attrs, + [key]: _nullishCoalesce( + _nullishCoalesce(unquoted, () => value), + () => true + ), + }; + }, {}); } /** * Calculate the updates required to process all instances of the specified tag. */ -async function process_tag( - tag_name, - preprocessor, - source -) { - const { filename } = source; - const tag_regex = - tag_name === 'style' - ? /<!--[^]*?-->|<style(\s[^]*?)?(?:>([^]*?)<\/style>|\/>)/gi - : /<!--[^]*?-->|<script(\s[^]*?)?(?:>([^]*?)<\/script>|\/>)/gi; - - const dependencies = []; - - async function process_single_tag( - tag_with_content, - attributes = '', - content = '', - tag_offset - ) { - const no_change = () => MappedCode.from_source(slice_source(tag_with_content, tag_offset, source)); - - if (!attributes && !content) return no_change(); - - const processed = await preprocessor({ - content: content || '', - attributes: parse_tag_attributes(attributes || ''), - filename - }); +async function process_tag(tag_name, preprocessor, source) { + const { filename } = source; + const tag_regex = tag_name === 'style' ? /<!--[^]*?-->|<style(\s[^]*?)?(?:>([^]*?)<\/style>|\/>)/gi : /<!--[^]*?-->|<script(\s[^]*?)?(?:>([^]*?)<\/script>|\/>)/gi; + + const dependencies = []; + + async function process_single_tag(tag_with_content, attributes = '', content = '', tag_offset) { + const no_change = () => MappedCode.from_source(slice_source(tag_with_content, tag_offset, source)); + + if (!attributes && !content) return no_change(); + + const processed = await preprocessor({ + content: content || '', + attributes: parse_tag_attributes(attributes || ''), + filename, + }); - if (!processed) return no_change(); - if (processed.dependencies) dependencies.push(...processed.dependencies); - if (!processed.map && processed.code === content) return no_change(); + if (!processed) return no_change(); + if (processed.dependencies) dependencies.push(...processed.dependencies); + if (!processed.map && processed.code === content) return no_change(); - return processed_tag_to_code(processed, tag_name, attributes, slice_source(content, tag_offset, source)); - } + return processed_tag_to_code(processed, tag_name, attributes, slice_source(content, tag_offset, source)); + } - const { string, map } = await replace_in_code(tag_regex, process_single_tag, source); + const { string, map } = await replace_in_code(tag_regex, process_single_tag, source); - return { string, map, dependencies }; + return { string, map, dependencies }; } async function process_markup(filename, process, source) { - const processed = await process({ - content: source.source, - filename - }); - - if (processed) { - return { - string: processed.code, - map: processed.map - ? // TODO: can we use decode_sourcemap? - typeof processed.map === 'string' - ? JSON.parse(processed.map) - : processed.map - : undefined, - dependencies: processed.dependencies - }; - } else { - return {}; - } -} - -async function preprocess( - source, - preprocessor, - options -) { - // @ts-ignore todo: doublecheck - const filename = (options && options.filename) || preprocessor.filename; // legacy - - const preprocessors = preprocessor ? (Array.isArray(preprocessor) ? preprocessor : [preprocessor]) : []; - - const markup = preprocessors.map(p => p.markup).filter(Boolean); - const script = preprocessors.map(p => p.script).filter(Boolean); - const style = preprocessors.map(p => p.style).filter(Boolean); - - const result = new PreprocessResult(source, filename); - - // TODO keep track: what preprocessor generated what sourcemap? - // to make debugging easier = detect low-resolution sourcemaps in fn combine_mappings - - for (const process of markup) { - result.update_source(await process_markup(filename, process, result)); - } - - for (const process of script) { - result.update_source(await process_tag('script', process, result)); - } - - for (const preprocess of style) { - result.update_source(await process_tag('style', preprocess, result)); - } - - return result.to_processed(); + const processed = await process({ + content: source.source, + filename, + }); + + if (processed) { + return { + string: processed.code, + map: processed.map + ? // TODO: can we use decode_sourcemap? + typeof processed.map === 'string' + ? JSON.parse(processed.map) + : processed.map + : undefined, + dependencies: processed.dependencies, + }; + } else { + return {}; + } +} + +async function preprocess(source, preprocessor, options) { + // @ts-ignore todo: doublecheck + const filename = (options && options.filename) || preprocessor.filename; // legacy + + const preprocessors = preprocessor ? (Array.isArray(preprocessor) ? preprocessor : [preprocessor]) : []; + + const markup = preprocessors.map((p) => p.markup).filter(Boolean); + const script = preprocessors.map((p) => p.script).filter(Boolean); + const style = preprocessors.map((p) => p.style).filter(Boolean); + + const result = new PreprocessResult(source, filename); + + // TODO keep track: what preprocessor generated what sourcemap? + // to make debugging easier = detect low-resolution sourcemaps in fn combine_mappings + + for (const process of markup) { + result.update_source(await process_markup(filename, process, result)); + } + + for (const process of script) { + result.update_source(await process_tag('script', process, result)); + } + + for (const preprocess of style) { + result.update_source(await process_tag('style', preprocess, result)); + } + + return result.to_processed(); } const VERSION = '3.35.0'; diff --git a/src/dev.ts b/src/dev.ts index d7a4ec47f..49faafd40 100644 --- a/src/dev.ts +++ b/src/dev.ts @@ -11,15 +11,15 @@ const require = createRequire(import.meta.url); const hostname = '127.0.0.1'; const port = 3000; -export default async function(astroConfig: AstroConfig) { +export default async function (astroConfig: AstroConfig) { const { projectRoot, hmxRoot } = astroConfig; const internalPath = new URL('./frontend/', import.meta.url); const snowpackConfigPath = new URL('./snowpack.config.js', projectRoot); - + // Workaround for SKY-251 - const hmxPlugOptions: {resolve?: (s: string) => string } = {}; - if(existsSync(new URL('./package-lock.json', projectRoot))) { + const hmxPlugOptions: { resolve?: (s: string) => string } = {}; + if (existsSync(new URL('./package-lock.json', projectRoot))) { const pkgLockStr = await readFile(new URL('./package-lock.json', projectRoot), 'utf-8'); const pkgLock = JSON.parse(pkgLockStr); hmxPlugOptions.resolve = (pkgName: string) => { @@ -27,36 +27,37 @@ export default async function(astroConfig: AstroConfig) { return `/_snowpack/pkg/${pkgName}.v${ver}.js`; }; } - - const snowpackConfig = await loadConfiguration({ - root: projectRoot.pathname, - mount: { - [hmxRoot.pathname]: '/_hmx', - [internalPath.pathname]: '/__hmx_internal__' - }, - plugins: [ - ['astro/snowpack-plugin', hmxPlugOptions] - ], - devOptions: { - open: 'none', - output: 'stream', - port: 0 + + const snowpackConfig = await loadConfiguration( + { + root: projectRoot.pathname, + mount: { + [hmxRoot.pathname]: '/_hmx', + [internalPath.pathname]: '/__hmx_internal__', + }, + plugins: [['astro/snowpack-plugin', hmxPlugOptions]], + devOptions: { + open: 'none', + output: 'stream', + port: 0, + }, + packageOptions: { + knownEntrypoints: ['preact-render-to-string'], + external: ['@vue/server-renderer'], + }, }, - packageOptions: { - knownEntrypoints: ['preact-render-to-string'], - external: ['@vue/server-renderer'] - } - }, snowpackConfigPath.pathname); + snowpackConfigPath.pathname + ); const snowpack = await startSnowpackServer({ config: snowpackConfig, - lockfile: null + lockfile: null, }); const runtime = snowpack.getServerRuntime(); const server = http.createServer(async (req, res) => { - const fullurl = new URL(req.url || '/', 'https://example.org/'); + const fullurl = new URL(req.url || '/', 'https://example.org/'); const reqPath = decodeURI(fullurl.pathname); - const selectedPage = (reqPath.substr(1) || 'index'); + const selectedPage = reqPath.substr(1) || 'index'; console.log(reqPath, selectedPage); const selectedPageLoc = new URL(`./pages/${selectedPage}.hmx`, hmxRoot); @@ -67,12 +68,12 @@ export default async function(astroConfig: AstroConfig) { if (!existsSync(selectedPageLoc) && !existsSync(selectedPageMdLoc)) { try { const result = await snowpack.loadUrl(reqPath); - if(result.contentType) { + if (result.contentType) { res.setHeader('Content-Type', result.contentType); } res.write(result.contents); res.end(); - } catch(err) { + } catch (err) { console.log('Not found', reqPath); res.statusCode = 404; res.setHeader('Content-Type', 'text/plain'); @@ -94,5 +95,5 @@ export default async function(astroConfig: AstroConfig) { server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); - }); -}
\ No newline at end of file + }); +} diff --git a/src/frontend/h.ts b/src/frontend/h.ts index 3ba0541e8..77ecf857b 100644 --- a/src/frontend/h.ts +++ b/src/frontend/h.ts @@ -3,8 +3,7 @@ export type HChild = string | undefined | (() => string); export type HMXComponent = (props: HProps, ...children: Array<HChild>) => string; export type HTag = string | HMXComponent; -const voidTags = new Set(['area', 'base', 'br', 'col', 'command', 'embed', 'hr', - 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr']); +const voidTags = new Set(['area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr']); function* _h(tag: string, attrs: HProps, children: Array<HChild>) { yield `<${tag}`; @@ -17,7 +16,7 @@ function* _h(tag: string, attrs: HProps, children: Array<HChild>) { yield '>'; // Void tags have no children. - if(voidTags.has(tag)) { + if (voidTags.has(tag)) { return; } diff --git a/src/frontend/render/preact.ts b/src/frontend/render/preact.ts index eb588209c..3b9e1e6d8 100644 --- a/src/frontend/render/preact.ts +++ b/src/frontend/render/preact.ts @@ -3,25 +3,25 @@ import { h } from 'preact'; import type { Component } from 'preact'; export function __preact_static(PreactComponent: Component) { - return (attrs: Record<string, any>, ...children: any): string => { - let html = render( - h( - PreactComponent as any, // Preact's types seem wrong... - attrs, - children - ) - ); - return html; - }; + return (attrs: Record<string, any>, ...children: any): string => { + let html = render( + h( + PreactComponent as any, // Preact's types seem wrong... + attrs, + children + ) + ); + return html; + }; } export function __preact_dynamic(PreactComponent: Component, importUrl: string, preactUrl: string) { - const placeholderId = `placeholder_${String(Math.random())}`; - return (attrs: Record<string, string>, ...children: any) => { - return `<div id="${placeholderId}"></div><script type="module"> + const placeholderId = `placeholder_${String(Math.random())}`; + return (attrs: Record<string, string>, ...children: any) => { + return `<div id="${placeholderId}"></div><script type="module"> import {h, render} from '${preactUrl}'; import Component from '${importUrl}'; render(h(Component, ${JSON.stringify(attrs)}), document.getElementById('${placeholderId}')); </script>`; - }; + }; } diff --git a/src/frontend/render/svelte.ts b/src/frontend/render/svelte.ts index ffdf70254..51cb778db 100644 --- a/src/frontend/render/svelte.ts +++ b/src/frontend/render/svelte.ts @@ -4,7 +4,7 @@ export function __svelte_static(SvelteComponent: Component) { return (attrs: Record<string, any>, ...children: any): string => { // TODO include head and css stuff too... const { html } = SvelteComponent.render(attrs); - + return html; }; } @@ -12,7 +12,7 @@ export function __svelte_static(SvelteComponent: Component) { export function __svelte_dynamic(SvelteComponent: Component, importUrl: string) { const placeholderId = `placeholder_${String(Math.random())}`; return (attrs: Record<string, string>, ...children: any) => { - return `<div id="${placeholderId}"></div><script type="module"> + return `<div id="${placeholderId}"></div><script type="module"> import Component from '${importUrl}'; new Component({ diff --git a/src/frontend/render/vue.ts b/src/frontend/render/vue.ts index f83c1665a..6b89aa11e 100644 --- a/src/frontend/render/vue.ts +++ b/src/frontend/render/vue.ts @@ -7,11 +7,11 @@ export function __vue_static(VueComponent: Component) { return async (attrs: Record<string, any>, ...children: any): Promise<string> => { const app = createSSRApp({ components: { - VueComponent + VueComponent, }, render() { return createElement(VueComponent as any, attrs); - } + }, }); const html = await renderToString(app); @@ -23,7 +23,7 @@ export function __vue_static(VueComponent: Component) { export function __vue_dynamic(VueComponent: Component, importUrl: string, vueUrl: string) { const placeholderId = `placeholder_${String(Math.random())}`; return (attrs: Record<string, string>, ...children: any) => { - return `<div id="${placeholderId}"></div><script type="module"> + return `<div id="${placeholderId}"></div><script type="module"> import Component from '${importUrl}'; import {createApp, h as createElement} from '${vueUrl}'; @@ -36,4 +36,4 @@ export function __vue_dynamic(VueComponent: Component, importUrl: string, vueUrl createApp(App).mount(document.getElementById('${placeholderId}')); </script>`; }; -}
\ No newline at end of file +} diff --git a/src/generate.ts b/src/generate.ts index 51dbd055a..ad2e9ded9 100644 --- a/src/generate.ts +++ b/src/generate.ts @@ -6,38 +6,39 @@ import { relative as pathRelative } from 'path'; const { mkdir, readdir, stat, writeFile } = fsPromises; async function* allPages(root: URL): AsyncGenerator<URL, void, unknown> { - for(const filename of await readdir(root)) { + for (const filename of await readdir(root)) { const fullpath = new URL(filename, root); const info = await stat(fullpath); - if(info.isDirectory()) { - yield * allPages(new URL(fullpath + '/')); + if (info.isDirectory()) { + yield* allPages(new URL(fullpath + '/')); } else { yield fullpath; } } } -export default async function(astroConfig: AstroConfig) { +export default async function (astroConfig: AstroConfig) { const { projectRoot, hmxRoot } = astroConfig; const pageRoot = new URL('./pages/', hmxRoot); const dist = new URL(astroConfig.dist + '/', projectRoot); const configPath = new URL('./snowpack.config.js', projectRoot).pathname; - const config = await loadConfiguration({ - root: projectRoot.pathname, - devOptions: - {open: 'none', output: 'stream' - } - }, configPath); + const config = await loadConfiguration( + { + root: projectRoot.pathname, + devOptions: { open: 'none', output: 'stream' }, + }, + configPath + ); const snowpack = await startSnowpackServer({ config, - lockfile: null // TODO should this be required? + lockfile: null, // TODO should this be required? }); const runtime = snowpack.getServerRuntime(); - for await(const filepath of allPages(pageRoot)) { + for await (const filepath of allPages(pageRoot)) { const rel = pathRelative(hmxRoot.pathname, filepath.pathname); // pages/index.hmx const pagePath = `/_hmx/${rel.replace(/\.(hmx|md)/, '.js')}`; @@ -49,11 +50,11 @@ export default async function(astroConfig: AstroConfig) { await mkdir(outFolder, { recursive: true }); await writeFile(outPath, html, 'utf-8'); - } catch(err) { + } catch (err) { console.error('Unable to generate page', rel); } } await snowpack.shutdown(); process.exit(0); -}
\ No newline at end of file +} diff --git a/src/markdown-encode.ts b/src/markdown-encode.ts index 0719aaa32..173c63fde 100644 --- a/src/markdown-encode.ts +++ b/src/markdown-encode.ts @@ -6,14 +6,14 @@ const characterReferences = { '<': 'lt', '>': 'gt', '{': 'lbrace', - '}': 'rbrace' + '}': 'rbrace', }; type EncodedChars = '"' | '&' | '<' | '>' | '{' | '}'; function encode(value: string): string { return value.replace(/["&<>{}]/g, (raw: string) => { - return '&' + characterReferences[raw as EncodedChars] + ';' + return '&' + characterReferences[raw as EncodedChars] + ';'; }); } @@ -21,14 +21,12 @@ const plugin: HtmlExtension = { exit: { codeFlowValue() { const token: Token = arguments[0]; - const serialize = this.sliceSerialize as unknown as (t: Token) => string; - const raw = this.raw as unknown as (s: string) => void; + const serialize = (this.sliceSerialize as unknown) as (t: Token) => string; + const raw = (this.raw as unknown) as (s: string) => void; const value = serialize(token); raw(encode(value)); - } - } + }, + }, }; -export { - plugin as default -};
\ No newline at end of file +export { plugin as default }; diff --git a/src/parser.ts b/src/parser.ts index f47486f65..d972e72ce 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -1,15 +1,6 @@ -const [ - CHARS, - TAG_START, - TAG_END, - END_TAG_START, - EQ, - EOF, - UNKNOWN -] = Array.from(new Array(20), (x, i) => i + 1); - -const voidTags = new Set(['area', 'base', 'br', 'col', 'command', 'embed', 'hr', - 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr']); +const [CHARS, TAG_START, TAG_END, END_TAG_START, EQ, EOF, UNKNOWN] = Array.from(new Array(20), (x, i) => i + 1); + +const voidTags = new Set(['area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr']); type Visitor = (tag: Tag) => Tag; @@ -71,27 +62,27 @@ function createState(code: string, visitor: Visitor): State { return { code, index: 0, - visitor + visitor, }; } function* _stringify(tag: Tag): Generator<string, void, unknown> { yield '<'; yield tag.tagName; - for(let attr of tag.attributes) { + for (let attr of tag.attributes) { yield ' '; yield `"${attr.name}"`; - if(!attr.boolean) { + if (!attr.boolean) { yield '='; yield `"${attr.value}"`; } } - if(!tag.void) { - for(let child of tag.children) { - if(child.type === 0) { + if (!tag.void) { + for (let child of tag.children) { + if (child.type === 0) { yield child.data; } else { - yield * _stringify(child); + yield* _stringify(child); } } } @@ -99,7 +90,7 @@ function* _stringify(tag: Tag): Generator<string, void, unknown> { function stringify(tag: Tag) { let out = ''; - for(let chunk of _stringify(tag)) { + for (let chunk of _stringify(tag)) { out += chunk; } return out; @@ -114,7 +105,7 @@ function spliceSlice(str: string, index: number, count: number, add: string) { } } - return str.slice(0, index) + (add || "") + str.slice(index + count); + return str.slice(0, index) + (add || '') + str.slice(index + count); } function replaceTag(state: State, tag: Tag) { @@ -131,28 +122,28 @@ function consumeToken(state: State) { do { const c = stateNext(state); - if(/\s/.test(c)) { + if (/\s/.test(c)) { continue; } - if(c === '<') { + if (c === '<') { return TAG_START; } - if(c === '>') { + if (c === '>') { return TAG_END; } - if(c === '/') { + if (c === '/') { return END_TAG_START; } - if(/[a-zA-Z]/.test(c)) { + if (/[a-zA-Z]/.test(c)) { return CHARS; } return UNKNOWN; - } while(stateInBounds(state)); + } while (stateInBounds(state)); return EOF; } @@ -161,7 +152,7 @@ function consumeText(state: State): Text { let start = state.index; let data = ''; let c = stateNext(state); - while(stateInBounds(state) && c !== '<') { + while (stateInBounds(state) && c !== '<') { data += c; c = stateNext(state); } @@ -170,14 +161,14 @@ function consumeText(state: State): Text { type: 0, data, start, - end: state.index - 1 + end: state.index - 1, }; } function consumeTagName(state: State): string { let name = ''; let token = consumeToken(state); - while(token === CHARS) { + while (token === CHARS) { name += stateChar(state); token = consumeToken(state); } @@ -186,19 +177,20 @@ function consumeTagName(state: State): string { function consumeAttribute(state: State): Attribute { let start = state.index; - let name = '', token; + let name = '', + token; do { name += stateChar(state).toLowerCase(); token = consumeToken(state); - } while(token === CHARS); + } while (token === CHARS); - if(token !== EQ) { + if (token !== EQ) { stateRewind(state); return { name, boolean: true, start, - end: state.index - 1 + end: state.index - 1, }; } @@ -206,26 +198,26 @@ function consumeAttribute(state: State): Attribute { do { value += stateChar(state).toLowerCase(); token = consumeToken(state); - } while(token === CHARS); + } while (token === CHARS); return { name, value, boolean: false, start, - end: state.index - 1 + end: state.index - 1, }; } function consumeChildren(state: State): Array<Tag | Text> { const children: Array<Tag | Text> = []; - childLoop: while(stateInBounds(state)) { + childLoop: while (stateInBounds(state)) { const token = consumeToken(state); - switch(token) { + switch (token) { case TAG_START: { const next = consumeToken(state); - if(next === END_TAG_START) { + if (next === END_TAG_START) { consumeTagName(state); consumeToken(state); // > break childLoop; @@ -256,8 +248,8 @@ function consumeTag(state: State): Tag { let token = consumeToken(state); // Collect attributes - attrLoop: while(token !== TAG_END) { - switch(token) { + attrLoop: while (token !== TAG_END) { + switch (token) { case CHARS: { attributes.push(consumeAttribute(state)); break; @@ -279,11 +271,11 @@ function consumeTag(state: State): Tag { children, void: voidTags.has(tagName), start, - end: state.index - 1 + end: state.index - 1, }; const replacement = state.visitor(node); - if(replacement !== node) { + if (replacement !== node) { replaceTag(state, node); } @@ -294,11 +286,11 @@ function consumeDocument(state: State): Document { const children: Array<Tag | Text> = consumeChildren(state); return { - children + children, }; } export function preparse(code: string, visitor: Visitor) { const state = createState(code, visitor); consumeDocument(state); -}
\ No newline at end of file +} diff --git a/src/transform2.ts b/src/transform2.ts index 485c575c6..ab516deac 100644 --- a/src/transform2.ts +++ b/src/transform2.ts @@ -1,15 +1,15 @@ -import type { TemplateNode } from "./@types/compiler/interfaces"; - -import path from "path"; -import astring from "astring"; -import esbuild from "esbuild"; -import eslexer from "es-module-lexer"; -import micromark from "micromark"; -import gfmSyntax from "micromark-extension-gfm"; -import matter from "gray-matter"; +import type { TemplateNode } from './@types/compiler/interfaces'; + +import path from 'path'; +import astring from 'astring'; +import esbuild from 'esbuild'; +import eslexer from 'es-module-lexer'; +import micromark from 'micromark'; +import gfmSyntax from 'micromark-extension-gfm'; +import matter from 'gray-matter'; // @ts-ignore -import gfmHtml from "micromark-extension-gfm/html.js"; -import { walk, parse } from "./compiler.js"; +import gfmHtml from 'micromark-extension-gfm/html.js'; +import { walk, parse } from './compiler.js'; import markdownEncode from './markdown-encode.js'; import { preparse } from './parser.js'; @@ -18,18 +18,20 @@ const { transformSync } = esbuild; interface Attribute { start: 574; end: 595; - type: "Attribute"; - name: "class"; + type: 'Attribute'; + name: 'class'; value: any; } interface CompileOptions { - resolve: (p: string) => string + resolve: (p: string) => string; } const defaultCompileOptions: CompileOptions = { - resolve(p: string) { return p; } -} + resolve(p: string) { + return p; + }, +}; function internalImport(internalPath: string) { return `/__hmx_internal__/${internalPath}`; @@ -47,7 +49,7 @@ function getAttributes(attrs: Attribute[]): Record<string, string> { } if (attr.value.length > 1) { result[attr.name] = - "(" + + '(' + attr.value .map((v: TemplateNode) => { if (v.expression) { @@ -56,21 +58,21 @@ function getAttributes(attrs: Attribute[]): Record<string, string> { return JSON.stringify(getTextFromAttribute(v)); } }) - .join("+") + - ")"; + .join('+') + + ')'; continue; } const val: TemplateNode = attr.value[0]; switch (val.type) { - case "MustacheTag": - result[attr.name] = "(" + val.expression + ")"; + case 'MustacheTag': + result[attr.name] = '(' + val.expression + ')'; continue; - case "Text": + case 'Text': result[attr.name] = JSON.stringify(getTextFromAttribute(val)); continue; default: console.log(val); - throw new Error("UNKNOWN V"); + throw new Error('UNKNOWN V'); } } return result; @@ -84,24 +86,20 @@ function getTextFromAttribute(attr: any): string { return attr.data; } console.log(attr); - throw new Error("UNKNOWN attr"); + throw new Error('UNKNOWN attr'); } function generateAttributes(attrs: Record<string, string>): string { - let result: string = "{"; + let result: string = '{'; for (const [key, val] of Object.entries(attrs)) { - result += JSON.stringify(key) + ":" + val + ","; + result += JSON.stringify(key) + ':' + val + ','; } - return result + "}"; + return result + '}'; } -function getComponentWrapper( - _name: string, - { type, url }: { type: string; url: string }, - { resolve }: CompileOptions -) { - const [name, kind] = _name.split(":"); - switch(type) { +function getComponentWrapper(_name: string, { type, url }: { type: string; url: string }, { resolve }: CompileOptions) { + const [name, kind] = _name.split(':'); + switch (type) { case '.hmx': { if (kind) { throw new Error(`HMX does not support :${kind}`); @@ -112,11 +110,9 @@ function getComponentWrapper( }; } case '.jsx': { - if (kind === "dynamic") { + if (kind === 'dynamic') { return { - wrapper: `__preact_dynamic(${name}, new URL(${JSON.stringify( - url.replace(/\.[^.]+$/, ".js") - )}, \`http://TEST\${import.meta.url}\`).pathname, '${resolve('preact')}')`, + wrapper: `__preact_dynamic(${name}, new URL(${JSON.stringify(url.replace(/\.[^.]+$/, '.js'))}, \`http://TEST\${import.meta.url}\`).pathname, '${resolve('preact')}')`, wrapperImport: `import {__preact_dynamic} from '${internalImport('render/preact.js')}';`, }; } else { @@ -127,26 +123,22 @@ function getComponentWrapper( } } case '.svelte': { - if(kind === "dynamic") { + if (kind === 'dynamic') { return { - wrapper: `__svelte_dynamic(${name}, new URL(${JSON.stringify( - url.replace(/\.[^.]+$/, ".svelte.js") - )}, \`http://TEST\${import.meta.url}\`).pathname)`, + wrapper: `__svelte_dynamic(${name}, new URL(${JSON.stringify(url.replace(/\.[^.]+$/, '.svelte.js'))}, \`http://TEST\${import.meta.url}\`).pathname)`, wrapperImport: `import {__svelte_dynamic} from '${internalImport('render/svelte.js')}';`, }; } else { return { wrapper: `__svelte_static(${name})`, - wrapperImport: `import {__svelte_static} from '${internalImport('render/svelte.js')}';` + wrapperImport: `import {__svelte_static} from '${internalImport('render/svelte.js')}';`, }; } } case '.vue': { - if(kind === "dynamic") { + if (kind === 'dynamic') { return { - wrapper: `__vue_dynamic(${name}, new URL(${JSON.stringify( - url.replace(/\.[^.]+$/, ".vue.js") - )}, \`http://TEST\${import.meta.url}\`).pathname, '${resolve('vue')}')`, + wrapper: `__vue_dynamic(${name}, new URL(${JSON.stringify(url.replace(/\.[^.]+$/, '.vue.js'))}, \`http://TEST\${import.meta.url}\`).pathname, '${resolve('vue')}')`, wrapperImport: `import {__vue_dynamic} from '${internalImport('render/vue.js')}';`, }; } else { @@ -154,42 +146,44 @@ function getComponentWrapper( wrapper: `__vue_static(${name})`, wrapperImport: ` import {__vue_static} from '${internalImport('render/vue.js')}'; - ` + `, }; } } } - throw new Error("Unknown Component Type: " + name); + throw new Error('Unknown Component Type: ' + name); } function runPreparser(template: string): string { - const doc = preparse(template, tag => { - if(tag.tagName === 'script') { + const doc = preparse(template, (tag) => { + if (tag.tagName === 'script') { let isSetup = false; - for(let attr of tag.attributes) { - if(attr.name === 'hmx' && attr.value === 'setup') { + for (let attr of tag.attributes) { + if (attr.name === 'hmx' && attr.value === 'setup') { isSetup = true; break; } } - if(isSetup && typeof tag.children[0] === 'string') { + if (isSetup && typeof tag.children[0] === 'string') { debugger; const content = tag.children[0]; let { code } = transformSync(content, { - loader: "tsx", - jsxFactory: "h", - jsxFragment: "Fragment", - charset: "utf8", + loader: 'tsx', + jsxFactory: 'h', + jsxFragment: 'Fragment', + charset: 'utf8', }); return { ...tag, - children: [{ - type: 0, - data: code, - start: 0, - end: 0 - }] + children: [ + { + type: 0, + data: code, + start: 0, + end: 0, + }, + ], }; } } @@ -209,9 +203,9 @@ async function convertHmxToJsx(template: string, compileOptions: CompileOptions) const ast = parse(template, {}); // Todo: Validate that `h` and `Fragment` aren't defined in the script - const script = ast.instance ? astring.generate(ast.instance.content) : ""; + const script = ast.instance ? astring.generate(ast.instance.content) : ''; - const [scriptImports] = eslexer.parse(script, "optional-sourcename"); + const [scriptImports] = eslexer.parse(script, 'optional-sourcename'); const components = Object.fromEntries( scriptImports.map((imp) => { const componentType = path.posix.extname(imp.n!); @@ -222,7 +216,7 @@ async function convertHmxToJsx(template: string, compileOptions: CompileOptions) const additionalImports = new Set<string>(); let items: { name: string; jsx: string }[] = []; - let mode: "JSX" | "SCRIPT" | "SLOT" = "JSX"; + let mode: 'JSX' | 'SCRIPT' | 'SLOT' = 'JSX'; let collectionItem: { name: string; jsx: string } | undefined; let currentItemName: string | undefined; let currentDepth = 0; @@ -230,14 +224,14 @@ async function convertHmxToJsx(template: string, compileOptions: CompileOptions) walk(ast.html as any, { // @ts-ignore enter(node: TemplateNode, parent, prop, index) { - // console.log("enter", node.type); + // console.log("enter", node.type); switch (node.type) { - case "MustacheTag": + case 'MustacheTag': let { code } = transformSync(node.expression, { - loader: "jsx", - jsxFactory: "h", - jsxFragment: "Fragment", - charset: "utf8", + loader: 'jsx', + jsxFactory: 'h', + jsxFragment: 'Fragment', + charset: 'utf8', }); let matches: RegExpExecArray[] = []; @@ -249,142 +243,127 @@ async function convertHmxToJsx(template: string, compileOptions: CompileOptions) } for (const match of matches.reverse()) { const name = match[1]; - const [componentName, componentKind] = name.split(":"); + const [componentName, componentKind] = name.split(':'); if (!components[componentName]) { throw new Error(`Unknown Component: ${componentName}`); } - const { wrapper, wrapperImport } = getComponentWrapper( - name, - components[componentName], - compileOptions - ); + const { wrapper, wrapperImport } = getComponentWrapper(name, components[componentName], compileOptions); if (wrapperImport) { additionalImports.add(wrapperImport); } if (wrapper !== name) { - code = - code.slice(0, match.index + 2) + - wrapper + - code.slice(match.index + match[0].length - 1); + code = code.slice(0, match.index + 2) + wrapper + code.slice(match.index + match[0].length - 1); } } - collectionItem!.jsx += `,(${code.trim().replace(/\;$/, "")})`; + collectionItem!.jsx += `,(${code.trim().replace(/\;$/, '')})`; return; - case "Slot": - mode = "SLOT"; + case 'Slot': + mode = 'SLOT'; collectionItem!.jsx += `,child`; return; - case "Comment": + case 'Comment': return; - case "Fragment": + case 'Fragment': // Ignore if its the top level fragment // This should be cleaned up, but right now this is how the old thing worked if (!collectionItem) { return; } - case "InlineComponent": - case "Element": + case 'InlineComponent': + case 'Element': const name: string = node.name; if (!name) { console.log(node); - throw new Error("AHHHH"); + throw new Error('AHHHH'); } const attributes = getAttributes(node.attributes); currentDepth++; currentItemName = name; if (!collectionItem) { - collectionItem = { name, jsx: "" }; + collectionItem = { name, jsx: '' }; items.push(collectionItem); } - collectionItem.jsx += collectionItem.jsx === "" ? "" : ","; + collectionItem.jsx += collectionItem.jsx === '' ? '' : ','; const COMPONENT_NAME_SCANNER = /^[A-Z]/; if (!COMPONENT_NAME_SCANNER.test(name)) { - collectionItem.jsx += `h("${name}", ${ - attributes ? generateAttributes(attributes) : "null" - }`; + collectionItem.jsx += `h("${name}", ${attributes ? generateAttributes(attributes) : 'null'}`; return; } if (name === 'Component') { collectionItem.jsx += `h(Fragment, null`; return; } - const [componentName, componentKind] = name.split(":"); + const [componentName, componentKind] = name.split(':'); const componentImportData = components[componentName]; if (!componentImportData) { throw new Error(`Unknown Component: ${componentName}`); } - const { wrapper, wrapperImport } = getComponentWrapper( - name, - components[componentName], - compileOptions - ); + const { wrapper, wrapperImport } = getComponentWrapper(name, components[componentName], compileOptions); if (wrapperImport) { additionalImports.add(wrapperImport); } - collectionItem.jsx += `h(${wrapper}, ${ - attributes ? generateAttributes(attributes) : "null" - }`; + collectionItem.jsx += `h(${wrapper}, ${attributes ? generateAttributes(attributes) : 'null'}`; return; - case "Attribute": { + case 'Attribute': { this.skip(); return; } - case "Text": { + case 'Text': { const text = getTextFromAttribute(node); - if (mode === "SLOT") { + if (mode === 'SLOT') { return; } if (!text.trim()) { return; } if (!collectionItem) { - throw new Error("Not possible! TEXT:" + text); + throw new Error('Not possible! TEXT:' + text); } - if (currentItemName === "script" || currentItemName === "code") { - collectionItem.jsx += "," + JSON.stringify(text); + if (currentItemName === 'script' || currentItemName === 'code') { + collectionItem.jsx += ',' + JSON.stringify(text); return; } - collectionItem.jsx += "," + JSON.stringify(text); + collectionItem.jsx += ',' + JSON.stringify(text); return; } default: console.log(node); - throw new Error("Unexpected node type: " + node.type); + throw new Error('Unexpected node type: ' + node.type); } }, // @ts-ignore leave(node: TemplateNode, parent, prop, index) { - // console.log("leave", node.type); + // console.log("leave", node.type); switch (node.type) { - case "Text": - case "MustacheTag": - case "Attribute": - case "Comment": + case 'Text': + case 'MustacheTag': + case 'Attribute': + case 'Comment': return; - case "Slot": { + case 'Slot': { const name = node.name; - if (name === "slot") { - mode = "JSX"; + if (name === 'slot') { + mode = 'JSX'; } return; } - case "Fragment": + case 'Fragment': if (!collectionItem) { return; } - case "Element": - case "InlineComponent": + case 'Element': + case 'InlineComponent': if (!collectionItem) { - throw new Error("Not possible! CLOSE " + node.name); + throw new Error('Not possible! CLOSE ' + node.name); } - collectionItem.jsx += ")"; + collectionItem.jsx += ')'; currentDepth--; if (currentDepth === 0) { collectionItem = undefined; } return; default: - throw new Error("Unexpected node type: " + node.type); + throw new Error('Unexpected node type: ' + node.type); } }, }); @@ -398,7 +377,7 @@ async function convertHmxToJsx(template: string, compileOptions: CompileOptions) */ return { - script: script + "\n" + Array.from(additionalImports).join("\n"), + script: script + '\n' + Array.from(additionalImports).join('\n'), items, }; } @@ -427,36 +406,31 @@ async function convertMdToJsx(contents: string, compileOptions: CompileOptions) }, }; - return convertHmxToJsx(`<script hmx="setup">export function setup() { + return convertHmxToJsx( + `<script hmx="setup">export function setup() { return ${JSON.stringify(setupData)}; - }</script><head></head><body>${mdHtml}</body>`, compileOptions); + }</script><head></head><body>${mdHtml}</body>`, + compileOptions + ); } -async function transformFromSource( - contents: string, - filename: string, - compileOptions: CompileOptions -): Promise<ReturnType<typeof convertHmxToJsx>> { +async function transformFromSource(contents: string, filename: string, compileOptions: CompileOptions): Promise<ReturnType<typeof convertHmxToJsx>> { switch (path.extname(filename)) { - case ".hmx": + case '.hmx': return convertHmxToJsx(contents, compileOptions); - case ".md": + case '.md': return convertMdToJsx(contents, compileOptions); default: - throw new Error("Not Supported!"); + throw new Error('Not Supported!'); } } export async function compilePage(source: string, filename: string, opts: CompileOptions = defaultCompileOptions) { const sourceJsx = await transformFromSource(source, filename, opts); - const headItem = sourceJsx.items.find((item) => item.name === "head"); - const bodyItem = sourceJsx.items.find((item) => item.name === "body"); - const headItemJsx = !headItem - ? "null" - : headItem.jsx.replace('"head"', 'isRoot ? "head" : Fragment'); - const bodyItemJsx = !bodyItem - ? "null" - : bodyItem.jsx.replace('"head"', 'isRoot ? "body" : Fragment'); + const headItem = sourceJsx.items.find((item) => item.name === 'head'); + const bodyItem = sourceJsx.items.find((item) => item.name === 'body'); + const headItemJsx = !headItem ? 'null' : headItem.jsx.replace('"head"', 'isRoot ? "head" : Fragment'); + const bodyItemJsx = !bodyItem ? 'null' : bodyItem.jsx.replace('"head"', 'isRoot ? "body" : Fragment'); const modJsx = ` ${sourceJsx.script} @@ -473,9 +447,7 @@ export function body({title, description, props}, child, isRoot) { return (${bod export async function compileComponent(source: string, filename: string, opts: CompileOptions = defaultCompileOptions) { const sourceJsx = await transformFromSource(source, filename, opts); - const componentJsx = sourceJsx.items.find( - (item) => item.name === "Component" - ); + const componentJsx = sourceJsx.items.find((item) => item.name === 'Component'); if (!componentJsx) { throw new Error(`${filename} <Component> expected!`); } |