diff --git a/.eslintrc.js b/.eslintrc.js index 2023207f74de..c8ec8d1d01b0 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -35,12 +35,7 @@ module.exports = { argsIgnorePattern: '^_' } ], - '@typescript-eslint/no-object-literal-type-assertion': [ - 'error', - { - allowAsParameter: true - } - ], + '@typescript-eslint/no-object-literal-type-assertion': 'off', '@typescript-eslint/no-unused-vars': 'off' }, globals: { diff --git a/package-lock.json b/package-lock.json index 1af50ed64291..dd9d418f1873 100644 --- a/package-lock.json +++ b/package-lock.json @@ -500,9 +500,9 @@ "dev": true }, "code-red": { - "version": "0.0.25", - "resolved": "https://registry.npmjs.org/code-red/-/code-red-0.0.25.tgz", - "integrity": "sha512-KxR5fi6hN3Lhg/VFBaucVaWe5LT8HvgKE7+q09ZV73PbBuuLWSK8DKeOtZTbpZ41BLimaggzawSgK7HQr+m1DA==", + "version": "0.0.26", + "resolved": "https://registry.npmjs.org/code-red/-/code-red-0.0.26.tgz", + "integrity": "sha512-W4t68vk3xJjmkbuAKfEtaj7E+K82BtV+A4VjBlxHA6gDoSLc+sTB643JdJMSk27vpp5iEqHFuGnHieQGy/GmUQ==", "dev": true, "requires": { "acorn": "^7.1.0", diff --git a/package.json b/package.json index 8584ac6ff867..27ee2f5f9496 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "acorn": "^7.1.0", "agadoo": "^1.1.0", "c8": "^5.0.1", - "code-red": "0.0.25", + "code-red": "0.0.26", "codecov": "^3.5.0", "css-tree": "1.0.0-alpha22", "eslint": "^6.3.0", diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts index 2d696ad306c7..0df89a25de4a 100644 --- a/src/compiler/compile/Component.ts +++ b/src/compiler/compile/Component.ts @@ -209,7 +209,6 @@ export default class Component { }); const subscribable_name = name.slice(1); - this.add_reference(subscribable_name); const variable = this.var_lookup.get(subscribable_name); if (variable) variable.subscribable = true; @@ -889,50 +888,6 @@ export default class Component { return null; } - invalidate(name, value?) { - const variable = this.var_lookup.get(name); - - if (variable && (variable.subscribable && (variable.reassigned || variable.export_name))) { - return x`${`$$subscribe_${name}`}($$invalidate('${name}', ${value || name}))`; - } - - if (name[0] === '$' && name[1] !== '$') { - return x`${name.slice(1)}.set(${value || name})`; - } - - if ( - variable && - !variable.referenced && - !variable.is_reactive_dependency && - !variable.export_name && - !name.startsWith('$$') - ) { - return value || name; - } - - if (value) { - return x`$$invalidate('${name}', ${value})`; - } - - // if this is a reactive declaration, invalidate dependencies recursively - const deps = new Set([name]); - - deps.forEach(name => { - const reactive_declarations = this.reactive_declarations.filter(x => - x.assignees.has(name) - ); - reactive_declarations.forEach(declaration => { - declaration.dependencies.forEach(name => { - deps.add(name); - }); - }); - }); - - return Array.from(deps) - .map(n => x`$$invalidate('${n}', ${n})`) - .reduce((lhs, rhs) => x`${lhs}, ${rhs}}`); - } - rewrite_props(get_insert: (variable: Var) => Node[]) { if (!this.ast.instance) return; @@ -1054,6 +1009,10 @@ export default class Component { 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 as Identifier; const v = this.var_lookup.get(name); @@ -1325,25 +1284,6 @@ export default class Component { }); } - qualify(name) { - if (name === `$$props`) return x`#ctx.$$props`; - - let [head, ...tail] = name.split('.'); - - const variable = this.var_lookup.get(head); - - if (variable) { - this.add_reference(name); // TODO we can probably remove most other occurrences of this - - if (!variable.hoistable) { - tail.unshift(head); - head = '#ctx'; - } - } - - return [head, ...tail].reduce((lhs, rhs) => x`${lhs}.${rhs}`); - } - warn_if_undefined(name: string, node, template_scope: TemplateScope) { if (name[0] === '$') { if (name === '$' || name[1] === '$' && name !== '$$props') { diff --git a/src/compiler/compile/nodes/Action.ts b/src/compiler/compile/nodes/Action.ts index 77b9e3c8461b..86aefa0cedac 100644 --- a/src/compiler/compile/nodes/Action.ts +++ b/src/compiler/compile/nodes/Action.ts @@ -14,7 +14,7 @@ export default class Action extends Node { component.warn_if_undefined(info.name, info, scope); this.name = info.name; - component.qualify(info.name); + component.add_reference(info.name.split('.')[0]); this.expression = info.expression ? new Expression(component, this, scope, info.expression) diff --git a/src/compiler/compile/nodes/Animation.ts b/src/compiler/compile/nodes/Animation.ts index ef48b4d745dc..10cc9364a02e 100644 --- a/src/compiler/compile/nodes/Animation.ts +++ b/src/compiler/compile/nodes/Animation.ts @@ -13,7 +13,7 @@ export default class Animation extends Node { component.warn_if_undefined(info.name, info, scope); this.name = info.name; - component.qualify(info.name); + component.add_reference(info.name.split('.')[0]); if (parent.animation) { component.error(this, { diff --git a/src/compiler/compile/nodes/Transition.ts b/src/compiler/compile/nodes/Transition.ts index ceb5880e647f..a680fde46e97 100644 --- a/src/compiler/compile/nodes/Transition.ts +++ b/src/compiler/compile/nodes/Transition.ts @@ -15,7 +15,7 @@ export default class Transition extends Node { component.warn_if_undefined(info.name, info, scope); this.name = info.name; - component.qualify(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'); diff --git a/src/compiler/compile/nodes/shared/Expression.ts b/src/compiler/compile/nodes/shared/Expression.ts index ad4a1bc24d88..1882c19267cd 100644 --- a/src/compiler/compile/nodes/shared/Expression.ts +++ b/src/compiler/compile/nodes/shared/Expression.ts @@ -9,9 +9,9 @@ import TemplateScope from './TemplateScope'; import get_object from '../../utils/get_object'; import Block from '../../render_dom/Block'; import is_dynamic from '../../render_dom/wrappers/shared/is_dynamic'; -import { x, b, p } from 'code-red'; -import { invalidate } from '../../utils/invalidate'; -import { Node, FunctionExpression } from 'estree'; +import { b } from 'code-red'; +import { invalidate } from '../../render_dom/invalidate'; +import { Node, FunctionExpression, Identifier } from 'estree'; import { TemplateNode } from '../../../interfaces'; type Owner = Wrapper | TemplateNode; @@ -213,7 +213,8 @@ export default class Expression { component.add_reference(name); // TODO is this redundant/misplaced? } } else if (is_contextual(component, template_scope, name)) { - this.replace(x`#ctx.${node}`); + const reference = block.renderer.reference(node); + this.replace(reference); } this.skip(); @@ -260,42 +261,38 @@ export default class Expression { // function can be hoisted inside the component init component.partly_hoisted.push(declaration); - this.replace(x`#ctx.${id}` as any); - - component.add_var({ - name: id.name, - internal: true, - referenced: true - }); + block.renderer.add_to_context(id.name); + this.replace(block.renderer.reference(id)); } else { // we need a combo block/init recipe - (node as FunctionExpression).params.unshift({ - type: 'ObjectPattern', - properties: Array.from(contextual_dependencies).map(name => p`${name}` as any) - }); + const deps = Array.from(contextual_dependencies); + + (node as FunctionExpression).params = [ + ...deps.map(name => ({ type: 'Identifier', name } as Identifier)), + ...(node as FunctionExpression).params + ]; + + const context_args = deps.map(name => block.renderer.reference(name)); component.partly_hoisted.push(declaration); - this.replace(id as any); + block.renderer.add_to_context(id.name); + const callee = block.renderer.reference(id); - component.add_var({ - name: id.name, - internal: true, - referenced: true - }); + this.replace(id as any); if ((node as FunctionExpression).params.length > 0) { declarations.push(b` function ${id}(...args) { - return #ctx.${id}(#ctx, ...args); + return ${callee}(${context_args}, ...args); } `); } else { declarations.push(b` function ${id}() { - return #ctx.${id}(#ctx); + return ${callee}(${context_args}); } `); } @@ -329,7 +326,7 @@ export default class Expression { } }); - this.replace(invalidate(component, scope, node, traced)); + this.replace(invalidate(block.renderer, scope, node, traced)); } } }); diff --git a/src/compiler/compile/render_dom/Block.ts b/src/compiler/compile/render_dom/Block.ts index 74822ef9bed0..c8fa88472161 100644 --- a/src/compiler/compile/render_dom/Block.ts +++ b/src/compiler/compile/render_dom/Block.ts @@ -1,7 +1,7 @@ import Renderer from './Renderer'; import Wrapper from './wrappers/shared/Wrapper'; import { b, x } from 'code-red'; -import { Node, Identifier } from 'estree'; +import { Node, Identifier, ArrayPattern } from 'estree'; import { is_head } from './wrappers/shared/is_head'; export interface BlockOptions { @@ -34,7 +34,7 @@ export default class Block { key: Identifier; first: Identifier; - dependencies: Set; + dependencies: Set = new Set(); bindings: Map = new Map(); + context_overflow: boolean; blocks: Array = []; readonly: Set = new Set(); meta_bindings: Array = []; // initial values for e.g. window.innerWidth, if there's a meta tag @@ -27,6 +40,24 @@ export default class Renderer { 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)); + + // ensure store values are included in context + component.vars.filter(v => v.subscribable).forEach(v => this.add_to_context(`$${v.name}`)); + + if (component.var_lookup.has('$$props')) { + this.add_to_context('$$props'); + } + + if (component.slots.size > 0) { + this.add_to_context('$$scope'); + this.add_to_context('$$slots'); + } + + if (this.binding_groups.length > 0) { + this.add_to_context('$$binding_groups'); + } + // main block this.block = new Block({ renderer: this, @@ -50,6 +81,8 @@ export default class Renderer { null ); + this.context_overflow = this.context.length > 31; + // TODO messy this.blocks.forEach(block => { if (block instanceof Block) { @@ -60,5 +93,195 @@ export default class Renderer { this.block.assign_variable_names(); this.fragment.render(this.block, null, x`#nodes` as Identifier); + + this.context.forEach(member => { + const { variable } = member; + if (variable) { + member.priority += 2; + if (variable.mutated || variable.reassigned) member.priority += 4; + + // these determine whether variable is included in initial context + // array, so must have the highest priority + if (variable.export_name) member.priority += 8; + if (variable.referenced) member.priority += 16; + } + + if (!member.is_contextual) { + member.priority += 1; + } + }); + + this.context.sort((a, b) => (b.priority - a.priority) || ((a.index.value as number) - (b.index.value as number))); + this.context.forEach((member, i) => member.index.value = i); + } + + add_to_context(name: string, contextual = false) { + if (!this.context_lookup.has(name)) { + const member: ContextMember = { + 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); + } + + const member = this.context_lookup.get(name); + + if (contextual) { + member.is_contextual = true; + } else { + member.is_non_contextual = true; + const variable = this.component.var_lookup.get(name); + member.variable = variable; + } + + return member; + } + + invalidate(name: string, value?) { + const variable = this.component.var_lookup.get(name); + const member = this.context_lookup.get(name); + + if (variable && (variable.subscribable && (variable.reassigned || variable.export_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.referenced && + !variable.is_reactive_dependency && + !variable.export_name && + !name.startsWith('$$') + ) { + return value || name; + } + + if (value) { + return x`$$invalidate(${member.index}, ${value})`; + } + + // if this is a reactive declaration, invalidate dependencies recursively + const deps = new Set([name]); + + deps.forEach(name => { + const reactive_declarations = this.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 => this.context_lookup.has(n)); + if (!filtered.length) return null; + + return filtered + .map(n => x`$$invalidate(${this.context_lookup.get(n).index}, ${n})`) + .reduce((lhs, rhs) => x`${lhs}, ${rhs}}`); + } + + dirty(names, is_reactive_declaration = false): Expression { + const renderer = this; + + const dirty = (is_reactive_declaration + ? x`$$self.$$.dirty` + : x`#dirty`) as Identifier | MemberExpression; + + const get_bitmask = () => names.reduce((bitmask, name) => { + const member = renderer.context_lookup.get(name); + + if (!member) return bitmask; + + if (member.index.value === -1) { + throw new Error(`unset index`); + } + + const value = member.index.value as number; + const i = (value / 31) | 0; + const n = 1 << (value % 31); + + if (!bitmask[i]) bitmask[i] = { n: 0, names: [] }; + + bitmask[i].n |= n; + bitmask[i].names.push(name); + + return bitmask; + }, Array((this.context.length / 31) | 0).fill(null)); + + let operator; + let left; + let right; + + return { + get type() { + // we make the type a getter, even though it's always + // a BinaryExpression, because it gives us an opportunity + // to lazily create the node. TODO would be better if + // context was determined before rendering, so that + // this indirection was unnecessary + + const bitmask = get_bitmask(); + + if (renderer.context_overflow) { + const expression = 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}`); + + ({ operator, left, right } = expression); + } else { + ({ operator, left, right } = x`${dirty} & /*${names.join(', ')}*/ ${bitmask[0] ? bitmask[0].n : 0}` as BinaryExpression); // TODO the `: 0` case should never apply + } + + return 'BinaryExpression'; + }, + get operator() { + return operator; + }, + get left() { + return left; + }, + get right() { + return right; + } + } as Expression; + } + + reference(node: string | Identifier | MemberExpression) { + if (typeof node === 'string') { + node = { type: 'Identifier', name: node }; + } + + const { name, nodes } = flatten_reference(node); + const member = this.context_lookup.get(name); + + // TODO is this correct? + if (this.component.var_lookup.get(name)) { + this.component.add_reference(name); + } + + if (member !== undefined) { + const replacement = x`/*${member.name}*/ #ctx[${member.index}]` as MemberExpression; + + if (nodes[0].loc) replacement.object.loc = nodes[0].loc; + nodes[0] = replacement; + + return nodes.reduce((lhs, rhs) => x`${lhs}.${rhs}`); + } + + return node; } } diff --git a/src/compiler/compile/render_dom/index.ts b/src/compiler/compile/render_dom/index.ts index cc0c7dfe315d..559b99f85a1a 100644 --- a/src/compiler/compile/render_dom/index.ts +++ b/src/compiler/compile/render_dom/index.ts @@ -3,11 +3,10 @@ import Component from '../Component'; import Renderer from './Renderer'; import { CompileOptions } from '../../interfaces'; import { walk } from 'estree-walker'; -import add_to_set from '../utils/add_to_set'; import { extract_names } from '../utils/scope'; -import { invalidate } from '../utils/invalidate'; +import { invalidate } from './invalidate'; import Block from './Block'; -import { ClassDeclaration, FunctionExpression, Node, Statement, ObjectExpression } from 'estree'; +import { ClassDeclaration, FunctionExpression, Node, Statement, ObjectExpression, Expression } from 'estree'; export default function dom( component: Component, @@ -80,12 +79,12 @@ export default function dom( const set = (uses_props || writable_props.length > 0 || component.slots.size > 0) ? x` ${$$props} => { - ${uses_props && component.invalidate('$$props', x`$$props = @assign(@assign({}, $$props), $$new_props)`)} + ${uses_props && renderer.invalidate('$$props', x`$$props = @assign(@assign({}, $$props), @exclude_internal_props($$new_props))`)} ${writable_props.map(prop => - b`if ('${prop.export_name}' in ${$$props}) ${component.invalidate(prop.name, x`${prop.name} = ${$$props}.${prop.export_name}`)};` + 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}) ${component.invalidate('$$scope', x`$$scope = ${$$props}.$$scope`)};`} + b`if ('$$scope' in ${$$props}) ${renderer.invalidate('$$scope', x`$$scope = ${$$props}.$$scope`)};`} } ` : null; @@ -105,7 +104,7 @@ export default function dom( kind: 'get', key: { type: 'Identifier', name: prop.export_name }, value: x`function() { - return ${prop.hoistable ? prop.name : x`this.$$.ctx.${prop.name}`} + return ${prop.hoistable ? prop.name : x`this.$$.ctx[${renderer.context_lookup.get(prop.name).index}]`} }` }); } else if (component.compile_options.dev) { @@ -161,7 +160,7 @@ export default function dom( const { ctx: #ctx } = this.$$; const props = ${options.customElement ? x`this.attributes` : x`options.props || {}`}; ${expected.map(prop => b` - if (#ctx.${prop.name} === undefined && !('${prop.export_name}' in props)) { + if (${renderer.reference(prop.name)} === undefined && !('${prop.export_name}' in props)) { @_console.warn("<${component.tag}> was created without expected prop '${prop.export_name}'"); }`)} `; @@ -180,9 +179,9 @@ export default function dom( const writable_vars = component.vars.filter(variable => !variable.module && variable.writable); inject_state = (uses_props || writable_vars.length > 0) ? x` ${$$props} => { - ${uses_props && component.invalidate('$$props', x`$$props = @assign(@assign({}, $$props), $$new_props)`)} + ${uses_props && renderer.invalidate('$$props', x`$$props = @assign(@assign({}, $$props), $$new_props)`)} ${writable_vars.map(prop => b` - if ('${prop.name}' in $$props) ${component.invalidate(prop.name, x`${prop.name} = ${$$props}.${prop.name}`)}; + if ('${prop.name}' in $$props) ${renderer.invalidate(prop.name, x`${prop.name} = ${$$props}.${prop.name}`)}; `)} } ` : x` @@ -216,17 +215,18 @@ export default function dom( // onto the initial function call const names = new Set(extract_names(assignee)); - this.replace(invalidate(component, scope, node, names)); + this.replace(invalidate(renderer, scope, node, names)); } } }); 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('${value}', ${value} = #value))`; + : b`@component_subscribe($$self, ${name}, #value => $$invalidate(${i}, ${value} = #value))`; if (component.compile_options.dev) { return b`@validate_store(${name}, '${name}'); ${insert}`; @@ -256,12 +256,6 @@ export default function dom( ${component.fully_hoisted} `); - const filtered_declarations = component.vars - .filter(v => ((v.referenced || v.export_name) && !v.hoistable)) - .map(v => p`${v.name}`); - - if (uses_props) filtered_declarations.push(p`$$props: $$props = @exclude_internal_props($$props)`); - const filtered_props = props.filter(prop => { const variable = component.var_lookup.get(prop.name); @@ -272,22 +266,25 @@ export default function dom( const reactive_stores = component.vars.filter(variable => variable.name[0] === '$' && variable.name[1] !== '$'); - if (component.slots.size > 0) { - filtered_declarations.push(p`$$slots`, p`$$scope`); - } + const instance_javascript = component.extract_javascript(component.ast.instance); - if (renderer.binding_groups.length > 0) { - filtered_declarations.push(p`$$binding_groups`); + let i = renderer.context.length; + while (i--) { + const member = renderer.context[i]; + if (member.variable) { + if (member.variable.referenced || member.variable.export_name) break; + } else if (member.is_non_contextual) { + break; + } } - - const instance_javascript = component.extract_javascript(component.ast.instance); + const initial_context = renderer.context.slice(0, i + 1); const has_definition = ( (instance_javascript && instance_javascript.length > 0) || filtered_props.length > 0 || uses_props || component.partly_hoisted.length > 0 || - filtered_declarations.length > 0 || + initial_context.length > 0 || component.reactive_declarations.length > 0 ); @@ -295,11 +292,6 @@ export default function dom( ? component.alias('instance') : { type: 'Literal', value: null }; - const all_reactive_dependencies = new Set(); - component.reactive_declarations.forEach(d => { - add_to_set(all_reactive_dependencies, d.dependencies); - }); - const reactive_store_subscriptions = reactive_stores .filter(store => { const variable = component.var_lookup.get(store.name.slice(1)); @@ -307,7 +299,7 @@ export default function dom( }) .map(({ name }) => b` ${component.compile_options.dev && b`@validate_store(${name.slice(1)}, '${name.slice(1)}');`} - @component_subscribe($$self, ${name.slice(1)}, $$value => $$invalidate('${name}', ${name} = $$value)); + @component_subscribe($$self, ${name.slice(1)}, $$value => $$invalidate(${renderer.context_lookup.get(name).index}, ${name} = $$value)); `); const resubscribable_reactive_store_unsubscribers = reactive_stores @@ -327,12 +319,10 @@ export default function dom( const writable = dependencies.filter(n => { const variable = component.var_lookup.get(n); - return variable && (variable.writable || variable.mutated); + return variable && (variable.export_name || variable.mutated || variable.reassigned); }); - const condition = !uses_props && writable.length > 0 && (writable - .map(n => x`#changed.${n}`) - .reduce((lhs, rhs) => x`${lhs} || ${rhs}`)); + const condition = !uses_props && writable.length > 0 && renderer.dirty(writable, true); let statement = d.node; // TODO remove label (use d.node.body) if it's not referenced @@ -358,7 +348,9 @@ export default function dom( if (store && (store.reassigned || store.export_name)) { const unsubscribe = `$$unsubscribe_${name}`; const subscribe = `$$subscribe_${name}`; - return b`let ${$name}, ${unsubscribe} = @noop, ${subscribe} = () => (${unsubscribe}(), ${unsubscribe} = @subscribe(${name}, $$value => $$invalidate('${$name}', ${$name} = $$value)), ${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};`; @@ -375,20 +367,11 @@ export default function dom( } const return_value = { - type: 'ObjectExpression', - properties: filtered_declarations - }; - - const reactive_dependencies = { - type: 'ObjectPattern', - properties: Array.from(all_reactive_dependencies).map(name => { - return { - type: 'Property', - kind: 'init', - key: { type: 'Identifier', name }, - value: { type: 'Literal', value: 1 } - }; - }) + type: 'ArrayExpression', + elements: initial_context.map(member => ({ + type: 'Identifier', + name: member.name + }) as Expression) }; body.push(b` @@ -418,22 +401,32 @@ export default function dom( ${injected.map(name => b`let ${name};`)} ${reactive_declarations.length > 0 && b` - $$self.$$.update = (#changed = ${reactive_dependencies}) => { + $$self.$$.update = () => { ${reactive_declarations} }; `} ${fixed_reactive_declarations} + ${uses_props && b`$$props = @exclude_internal_props($$props);`} + return ${return_value}; } `); } - const prop_names = x`{ - ${props.map(v => p`${v.export_name}: ${v.export_name === v.name ? 0 : x`"${v.name}"`}}`)} + 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}`)} }` as ObjectExpression; + let dirty; + if (renderer.context_overflow) { + dirty = x`[]`; + for (let i = 0; i < renderer.context.length; i += 31) { + dirty.elements.push(x`-1`); + } + } + if (options.customElement) { const declaration = b` class ${name} extends @SvelteElement { @@ -442,7 +435,7 @@ export default function dom( ${css.code && b`this.shadowRoot.innerHTML = \`\`;`} - @init(this, { target: this.shadowRoot }, ${definition}, ${has_create_fragment ? 'create_fragment': 'null'}, ${not_equal}, ${prop_names}); + @init(this, { target: this.shadowRoot }, ${definition}, ${has_create_fragment ? 'create_fragment': 'null'}, ${not_equal}, ${prop_indexes}, ${dirty}); ${dev_props_check} @@ -494,7 +487,7 @@ export default function dom( constructor(options) { super(${options.dev && `options`}); ${should_add_css && b`if (!@_document.getElementById("${component.stylesheet.id}-style")) ${add_css}();`} - @init(this, options, ${definition}, ${has_create_fragment ? 'create_fragment': 'null'}, ${not_equal}, ${prop_names}); + @init(this, options, ${definition}, ${has_create_fragment ? 'create_fragment': 'null'}, ${not_equal}, ${prop_indexes}, ${dirty}); ${options.dev && b`@dispatch_dev("SvelteRegisterComponent", { component: this, tagName: "${name.name}", options, id: create_fragment.name });`} ${dev_props_check} diff --git a/src/compiler/compile/utils/invalidate.ts b/src/compiler/compile/render_dom/invalidate.ts similarity index 72% rename from src/compiler/compile/utils/invalidate.ts rename to src/compiler/compile/render_dom/invalidate.ts index f386991d0438..98fca59028d3 100644 --- a/src/compiler/compile/utils/invalidate.ts +++ b/src/compiler/compile/render_dom/invalidate.ts @@ -1,10 +1,12 @@ -import Component from '../Component'; import { nodes_match } from '../../utils/nodes_match'; -import { Scope } from './scope'; +import { Scope } from '../utils/scope'; import { x } from 'code-red'; import { Node } from 'estree'; +import Renderer from './Renderer'; + +export function invalidate(renderer: Renderer, scope: Scope, node: Node, names: Set) { + const { component } = renderer; -export function invalidate(component: Component, scope: Scope, node: Node, names: Set) { const [head, ...tail] = Array.from(names).filter(name => { const owner = scope.find_owner(name); if (owner && owner !== component.instance_scope) return false; @@ -17,6 +19,7 @@ export function invalidate(component: Component, scope: Scope, node: Node, names !variable.module && ( variable.referenced || + variable.subscribable || variable.is_reactive_dependency || variable.export_name || variable.name[0] === '$' @@ -28,12 +31,12 @@ export function invalidate(component: Component, scope: Scope, node: Node, names component.has_reactive_assignments = true; if (node.type === 'AssignmentExpression' && node.operator === '=' && nodes_match(node.left, node.right) && tail.length === 0) { - return component.invalidate(head); + return renderer.invalidate(head); } else { const is_store_value = head[0] === '$'; const variable = component.var_lookup.get(head); - const extra_args = tail.map(name => component.invalidate(name)); + const extra_args = tail.map(name => renderer.invalidate(name)); const pass_value = ( extra_args.length > 0 || @@ -48,8 +51,9 @@ export function invalidate(component: Component, scope: Scope, node: Node, names }); } - const callee = is_store_value ? `@set_store_value` : `$$invalidate`; - let invalidate = x`${callee}(${is_store_value ? head.slice(1) : x`"${head}"`}, ${node}, ${extra_args})`; + let invalidate = is_store_value + ? x`@set_store_value(${head.slice(1)}, ${node}, ${extra_args})` + : x`$$invalidate(${renderer.context_lookup.get(head).index}, ${node}, ${extra_args})`; if (variable.subscribable && variable.reassigned) { const subscribe = `$$subscribe_${head}`; diff --git a/src/compiler/compile/render_dom/wrappers/AwaitBlock.ts b/src/compiler/compile/render_dom/wrappers/AwaitBlock.ts index d20d8f6f949f..8ce7495fd7bf 100644 --- a/src/compiler/compile/render_dom/wrappers/AwaitBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/AwaitBlock.ts @@ -8,7 +8,6 @@ import FragmentWrapper from './Fragment'; import PendingBlock from '../../nodes/PendingBlock'; import ThenBlock from '../../nodes/ThenBlock'; import CatchBlock from '../../nodes/CatchBlock'; -import { changed } from './shared/changed'; import { Identifier } from 'estree'; class AwaitBlockBranch extends Wrapper { @@ -119,6 +118,9 @@ export default class AwaitBlockWrapper extends Wrapper { if (has_outros) { block.add_outro(); } + + if (this.node.value) block.renderer.add_to_context(this.node.value, true); + if (this.node.error) block.renderer.add_to_context(this.node.error, true); } render( @@ -138,6 +140,9 @@ export default class AwaitBlockWrapper extends Wrapper { block.maintain_context = true; + const value_index = this.node.value && block.renderer.context_lookup.get(this.node.value).index; + const error_index = this.node.error && block.renderer.context_lookup.get(this.node.error).index; + const info_props: any = x`{ ctx: #ctx, current: null, @@ -145,8 +150,8 @@ export default class AwaitBlockWrapper extends Wrapper { pending: ${this.pending.block.name}, then: ${this.then.block.name}, catch: ${this.catch.block.name}, - value: ${this.then.block.name && x`"${this.node.value}"`}, - error: ${this.catch.block.name && x`"${this.node.error}"`}, + value: ${value_index}, + error: ${error_index}, blocks: ${this.pending.block.has_outro_method && x`[,,,]`} }`; @@ -187,7 +192,7 @@ export default class AwaitBlockWrapper extends Wrapper { if (dependencies.length > 0) { const condition = x` - ${changed(dependencies)} && + ${block.renderer.dirty(dependencies)} && ${promise} !== (${promise} = ${snippet}) && @handle_promise(${promise}, ${info})`; @@ -198,9 +203,11 @@ export default class AwaitBlockWrapper extends Wrapper { if (this.pending.block.has_update_method) { block.chunks.update.push(b` if (${condition}) { - // nothing + } else { - ${info}.block.p(#changed, @assign(@assign({}, #ctx), ${info}.resolved)); + const #child_ctx = #ctx.slice(); + #child_ctx[${value_index}] = ${info}.resolved; + ${info}.block.p(#child_ctx, #dirty); } `); } else { @@ -211,7 +218,11 @@ export default class AwaitBlockWrapper extends Wrapper { } else { if (this.pending.block.has_update_method) { block.chunks.update.push(b` - ${info}.block.p(#changed, @assign(@assign({}, #ctx), ${info}.resolved)); + { + const #child_ctx = #ctx.slice(); + #child_ctx[${value_index}] = ${info}.resolved; + ${info}.block.p(#child_ctx, #dirty); + } `); } } diff --git a/src/compiler/compile/render_dom/wrappers/DebugTag.ts b/src/compiler/compile/render_dom/wrappers/DebugTag.ts index dc3a2f2857c6..442b548994f2 100644 --- a/src/compiler/compile/render_dom/wrappers/DebugTag.ts +++ b/src/compiler/compile/render_dom/wrappers/DebugTag.ts @@ -5,7 +5,6 @@ import DebugTag from '../../nodes/DebugTag'; import add_to_set from '../../utils/add_to_set'; import { b, p } from 'code-red'; import { Identifier, DebuggerStatement } from 'estree'; -import { changed } from './shared/changed'; export default class DebugTagWrapper extends Wrapper { node: DebugTag; @@ -60,17 +59,17 @@ export default class DebugTagWrapper extends Wrapper { const variable = var_lookup.get(e.node.name); return !(variable && variable.hoistable); }) - .map(e => p`${e.node.name}`); + .map(e => e.node.name); const logged_identifiers = this.node.expressions.map(e => p`${e.node.name}`); const debug_statements = b` - const { ${contextual_identifiers} } = #ctx; + ${contextual_identifiers.map(name => b`const ${name} = ${renderer.reference(name)};`)} @_console.${log}({ ${logged_identifiers} }); debugger;`; if (dependencies.size) { - const condition = changed(Array.from(dependencies)); + const condition = renderer.dirty(Array.from(dependencies)); block.chunks.update.push(b` if (${condition}) { diff --git a/src/compiler/compile/render_dom/wrappers/EachBlock.ts b/src/compiler/compile/render_dom/wrappers/EachBlock.ts index 33b4a9cbd55b..5b13b486e61d 100644 --- a/src/compiler/compile/render_dom/wrappers/EachBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/EachBlock.ts @@ -7,7 +7,6 @@ import FragmentWrapper from './Fragment'; import { b, x } from 'code-red'; import ElseBlock from '../../nodes/ElseBlock'; import { Identifier, Node } from 'estree'; -import { changed } from './shared/changed'; export class ElseBlockWrapper extends Wrapper { node: ElseBlock; @@ -81,6 +80,10 @@ export default class EachBlockWrapper extends Wrapper { 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'), @@ -119,6 +122,9 @@ export default class EachBlockWrapper extends Wrapper { 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, @@ -190,18 +196,19 @@ export default class EachBlockWrapper extends Wrapper { ? !this.next.is_dom_node() : !parent_node || !this.parent.is_dom_node(); - this.context_props = this.node.contexts.map(prop => b`child_ctx.${prop.key.name} = ${prop.modifier(x`list[i]`)};`); + this.context_props = this.node.contexts.map(prop => b`child_ctx[${renderer.context_lookup.get(prop.key.name).index}] = ${prop.modifier(x`list[i]`)};`); - if (this.node.has_binding) this.context_props.push(b`child_ctx.${this.vars.each_block_value} = list;`); - if (this.node.has_binding || this.node.index) this.context_props.push(b`child_ctx.${this.index_name} = i;`); + 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.index) this.context_props.push(b`child_ctx[${renderer.context_lookup.get(this.index_name.name).index}] = i;`); const snippet = this.node.expression.manipulate(block); block.chunks.init.push(b`let ${this.vars.each_block_value} = ${snippet};`); + // 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 = @_Object.create(#ctx); + const child_ctx = #ctx.slice(); ${this.context_props} return child_ctx; } @@ -270,7 +277,7 @@ export default class EachBlockWrapper extends Wrapper { if (this.else.block.has_update_method) { block.chunks.update.push(b` if (!${this.vars.data_length} && ${each_block_else}) { - ${each_block_else}.p(#changed, #ctx); + ${each_block_else}.p(#ctx, #dirty); } else if (!${this.vars.data_length}) { ${each_block_else} = ${this.else.block.name}(#ctx); ${each_block_else}.c(); @@ -396,7 +403,7 @@ export default class EachBlockWrapper extends Wrapper { ${this.block.has_outros && b`@group_outros();`} ${this.node.has_animation && b`for (let #i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].r();`} - ${iterations} = @update_keyed_each(${iterations}, #changed, ${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();`} `); @@ -469,9 +476,8 @@ export default class EachBlockWrapper extends Wrapper { } `); - const all_dependencies = new Set(this.block.dependencies); - const { dependencies } = this.node.expression; - dependencies.forEach((dependency: string) => { + const all_dependencies = new Set(this.block.dependencies); // TODO should be dynamic deps only + this.node.expression.dynamic_dependencies().forEach((dependency: string) => { all_dependencies.add(dependency); }); @@ -481,7 +487,7 @@ export default class EachBlockWrapper extends Wrapper { const for_loop_body = this.block.has_update_method ? b` if (${iterations}[#i]) { - ${iterations}[#i].p(#changed, child_ctx); + ${iterations}[#i].p(child_ctx, #dirty); ${has_transitions && b`@transition_in(${this.vars.iterations}[#i], 1);`} } else { ${iterations}[#i] = ${create_each_block}(child_ctx); @@ -554,7 +560,7 @@ export default class EachBlockWrapper extends Wrapper { `; block.chunks.update.push(b` - if (${changed(Array.from(all_dependencies))}) { + if (${block.renderer.dirty(Array.from(all_dependencies))}) { ${update} } `); diff --git a/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts b/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts index db3cf7a66251..d796dc2ab33c 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts @@ -6,7 +6,6 @@ import { string_literal } from '../../../utils/stringify'; import { b, x } from 'code-red'; import Expression from '../../../nodes/shared/Expression'; import Text from '../../../nodes/Text'; -import { changed } from '../shared/changed'; export default class AttributeWrapper { node: Attribute; @@ -140,7 +139,7 @@ export default class AttributeWrapper { } if (dependencies.length > 0) { - let condition = changed(dependencies); + let condition = block.renderer.dirty(dependencies); if (should_cache) { condition = is_src @@ -197,8 +196,8 @@ export default class AttributeWrapper { } let value = this.node.name === 'class' - ? this.get_class_name_text() - : this.render_chunks().reduce((lhs, rhs) => x`${lhs} + ${rhs}`); + ? this.get_class_name_text(block) + : this.render_chunks(block).reduce((lhs, rhs) => x`${lhs} + ${rhs}`); // '{foo} {bar}' — treat as string concatenation if (this.node.chunks[0].type !== 'Text') { @@ -208,9 +207,9 @@ export default class AttributeWrapper { return value; } - get_class_name_text() { + get_class_name_text(block) { const scoped_css = this.node.chunks.some((chunk: Text) => chunk.synthetic); - const rendered = this.render_chunks(); + const rendered = this.render_chunks(block); if (scoped_css && rendered.length === 2) { // we have a situation like class={possiblyUndefined} @@ -220,13 +219,13 @@ export default class AttributeWrapper { return rendered.reduce((lhs, rhs) => x`${lhs} + ${rhs}`); } - render_chunks() { + render_chunks(block: Block) { return this.node.chunks.map((chunk) => { if (chunk.type === 'Text') { return string_literal(chunk.data); } - return chunk.manipulate(); + return chunk.manipulate(block); }); } diff --git a/src/compiler/compile/render_dom/wrappers/Element/Binding.ts b/src/compiler/compile/render_dom/wrappers/Element/Binding.ts index 9618ad3c2cc0..7244d9203d55 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/Binding.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/Binding.ts @@ -6,7 +6,6 @@ import Block from '../../Block'; import Renderer from '../../Renderer'; import flatten_reference from '../../../utils/flatten_reference'; import EachBlock from '../../../nodes/EachBlock'; -import { changed } from '../shared/changed'; import { Node, Identifier } from 'estree'; export default class BindingWrapper { @@ -91,7 +90,7 @@ export default class BindingWrapper { const dependency_array = [...this.node.expression.dependencies]; if (dependency_array.length > 0) { - update_conditions.push(changed(dependency_array)); + update_conditions.push(block.renderer.dirty(dependency_array)); } if (parent.node.name === 'input') { @@ -112,12 +111,15 @@ export default class BindingWrapper { { const binding_group = get_binding_group(parent.renderer, this.node.expression.node); + block.renderer.add_to_context(`$$binding_groups`); + const reference = block.renderer.reference(`$$binding_groups`); + block.chunks.hydrate.push( - b`#ctx.$$binding_groups[${binding_group}].push(${parent.var});` + b`${reference}[${binding_group}].push(${parent.var});` ); block.chunks.destroy.push( - b`#ctx.$$binding_groups[${binding_group}].splice(#ctx.$$binding_groups[${binding_group}].indexOf(${parent.var}), 1);` + b`${reference}[${binding_group}].splice(${reference}[${binding_group}].indexOf(${parent.var}), 1);` ); break; } diff --git a/src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts b/src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts index 37089e74932d..bc798d2e530d 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts @@ -15,40 +15,36 @@ export default class EventHandlerWrapper { this.parent = parent; if (!node.expression) { - this.parent.renderer.component.add_var({ - name: node.handler_name.name, - internal: true, - referenced: true, - }); + this.parent.renderer.add_to_context(node.handler_name.name); this.parent.renderer.component.partly_hoisted.push(b` - function ${node.handler_name.name}(event) { - @bubble($$self, event); - } - `); + function ${node.handler_name.name}(event) { + @bubble($$self, event); + } + `); } } - get_snippet(block) { - const snippet = this.node.expression ? this.node.expression.manipulate(block) : x`#ctx.${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 () { ${snippet}.apply(this, arguments); }`; } return snippet; - } + } render(block: Block, target: string) { let snippet = this.get_snippet(block); - if (this.node.modifiers.has('preventDefault')) snippet = x`@prevent_default(${snippet})`; + 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 = ['passive', 'once', 'capture'].filter(mod => this.node.modifiers.has(mod)); + const args = []; + + const opts = ['passive', 'once', 'capture'].filter(mod => this.node.modifiers.has(mod)); if (opts.length) { args.push((opts.length === 1 && opts[0] === 'capture') ? TRUE @@ -62,7 +58,7 @@ export default class EventHandlerWrapper { args.push(this.node.modifiers.has('preventDefault') ? TRUE : FALSE); } - block.event_listeners.push( + block.event_listeners.push( x`@listen(${target}, "${this.node.name}", ${snippet}, ${args})` ); } diff --git a/src/compiler/compile/render_dom/wrappers/Element/StyleAttribute.ts b/src/compiler/compile/render_dom/wrappers/Element/StyleAttribute.ts index c60a89f66f03..9dc36dabf58c 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/StyleAttribute.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/StyleAttribute.ts @@ -7,7 +7,6 @@ import { string_literal } from '../../../utils/stringify'; import add_to_set from '../../../utils/add_to_set'; import Expression from '../../../nodes/shared/Expression'; import Text from '../../../nodes/Text'; -import { changed } from '../shared/changed'; export interface StyleProp { key: string; @@ -46,7 +45,7 @@ export default class StyleAttributeWrapper extends AttributeWrapper { // } if (prop_dependencies.size) { - let condition = changed(Array.from(prop_dependencies)); + let condition = block.renderer.dirty(Array.from(prop_dependencies)); if (block.has_outros) { condition = x`!#current || ${condition}`; diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts index 0c3b05a6bf16..cd660f202c08 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/index.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts @@ -19,12 +19,12 @@ import add_to_set from '../../../utils/add_to_set'; import add_event_handlers from '../shared/add_event_handlers'; import add_actions from '../shared/add_actions'; import create_debugging_comment from '../shared/create_debugging_comment'; -import { get_context_merger } from '../shared/get_context_merger'; +import { get_slot_definition } from '../shared/get_slot_definition'; import bind_this from '../shared/bind_this'; -import { changed } from '../shared/changed'; import { is_head } from '../shared/is_head'; import { Identifier } from 'estree'; import EventHandler from './EventHandler'; +import { extract_names } from 'periscopic'; const events = [ { @@ -159,6 +159,14 @@ export default class ElementWrapper extends Wrapper { 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); + }); + }); + } + this.attributes = this.node.attributes.map(attribute => { if (attribute.name === 'slot') { // TODO make separate subclass for this? @@ -185,20 +193,17 @@ export default class ElementWrapper extends Wrapper { type: 'slot' }); - const lets = this.node.lets; + const { scope, lets } = this.node; const seen = new Set(lets.map(l => l.name.name)); (owner as unknown as InlineComponentWrapper).node.lets.forEach(l => { if (!seen.has(l.name.name)) lets.push(l); }); - const fn = get_context_merger(lets); - - (owner as unknown as InlineComponentWrapper).slots.set(name, { - block: child_block, - scope: this.node.scope, - fn - }); + (owner as unknown as InlineComponentWrapper).slots.set( + name, + get_slot_definition(child_block, scope, lets) + ); this.renderer.blocks.push(child_block); } @@ -282,7 +287,7 @@ export default class ElementWrapper extends Wrapper { const children = x`@children(${this.node.name === 'template' ? x`${node}.content` : node})`; block.add_variable(node); - const render_statement = this.get_render_statement(); + const render_statement = this.get_render_statement(block); block.chunks.create.push( b`${node} = ${render_statement};` ); @@ -398,7 +403,7 @@ export default class ElementWrapper extends Wrapper { return this.is_static_content && this.fragment.nodes.every(node => node.node.type === 'Text' || node.node.type === 'MustacheTag'); } - get_render_statement() { + get_render_statement(block: Block) { const { name, namespace } = this.node; if (namespace === 'http://www.w3.org/2000/svg') { @@ -411,7 +416,7 @@ export default class ElementWrapper extends Wrapper { const is = this.attributes.find(attr => attr.node.name === 'is'); if (is) { - return x`@element_is("${name}", ${is.render_chunks().reduce((lhs, rhs) => x`${lhs} + ${rhs}`)});`; + return x`@element_is("${name}", ${is.render_chunks(block).reduce((lhs, rhs) => x`${lhs} + ${rhs}`)});`; } return x`@element("${name}")`; @@ -455,18 +460,13 @@ export default class ElementWrapper extends Wrapper { groups.forEach(group => { const handler = renderer.component.get_unique_name(`${this.var.name}_${group.events.join('_')}_handler`); - - renderer.component.add_var({ - name: handler.name, - internal: true, - referenced: true - }); + renderer.add_to_context(handler.name); // TODO figure out how to handle locks const needs_lock = group.bindings.some(binding => binding.needs_lock); - const dependencies = new Set(); - const contextual_dependencies = new Set(); + const dependencies: Set = new Set(); + const contextual_dependencies: Set = new Set(); group.bindings.forEach(binding => { // TODO this is a mess @@ -488,10 +488,12 @@ export default class ElementWrapper extends Wrapper { const has_local_function = contextual_dependencies.size > 0 || needs_lock || animation_frame; - let callee; + 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` @@ -501,43 +503,33 @@ export default class ElementWrapper extends Wrapper { ${animation_frame} = @raf(${handler}); ${needs_lock && b`${lock} = true;`} } - #ctx.${handler}.call(${this.var}, ${contextual_dependencies.size > 0 ? '#ctx' : null}); + ${callee}.call(${this.var}, ${args}); } `); } else { block.chunks.init.push(b` function ${handler}() { ${needs_lock && b`${lock} = true;`} - #ctx.${handler}.call(${this.var}, ${contextual_dependencies.size > 0 ? '#ctx' : null}); + ${callee}.call(${this.var}, ${args}); } `); } callee = handler; - } else { - callee = x`#ctx.${handler}`; } - const arg = contextual_dependencies.size > 0 && { - type: 'ObjectPattern', - properties: Array.from(contextual_dependencies).map(name => { - const id = { type: 'Identifier', name }; - return { - type: 'Property', - kind: 'init', - key: id, - value: id - }; - }) - }; + const params = Array.from(contextual_dependencies).map(name => ({ + type: 'Identifier', + name + })); this.renderer.component.partly_hoisted.push(b` - function ${handler}(${arg}) { + function ${handler}(${params}) { ${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.component.invalidate(dep)};`)} + .map(dep => b`${this.renderer.invalidate(dep)};`)} } `); @@ -632,7 +624,7 @@ export default class ElementWrapper extends Wrapper { this.attributes .forEach(attr => { const condition = attr.node.dependencies.size > 0 - ? changed(Array.from(attr.node.dependencies)) + ? block.renderer.dirty(Array.from(attr.node.dependencies)) : null; if (attr.node.is_spread) { @@ -685,8 +677,6 @@ export default class ElementWrapper extends Wrapper { const { intro, outro } = this.node; if (!intro && !outro) return; - const { component } = this.renderer; - if (intro === outro) { // bidirectional transition const name = block.get_unique_name(`${this.var.name}_transition`); @@ -696,7 +686,7 @@ export default class ElementWrapper extends Wrapper { block.add_variable(name); - const fn = component.qualify(intro.name); + const fn = this.renderer.reference(intro.name); const intro_block = b` @add_render_callback(() => { @@ -740,7 +730,7 @@ export default class ElementWrapper extends Wrapper { ? intro.expression.manipulate(block) : x`{}`; - const fn = component.qualify(intro.name); + const fn = this.renderer.reference(intro.name); let intro_block; @@ -782,7 +772,7 @@ export default class ElementWrapper extends Wrapper { ? outro.expression.manipulate(block) : x`{}`; - const fn = component.qualify(outro.name); + const fn = this.renderer.reference(outro.name); if (!intro) { block.chunks.intro.push(b` @@ -814,7 +804,6 @@ export default class ElementWrapper extends Wrapper { add_animation(block: Block) { if (!this.node.animation) return; - const { component } = this.renderer; const { outro } = this.node; const rect = block.get_unique_name('rect'); @@ -835,7 +824,7 @@ export default class ElementWrapper extends Wrapper { const params = this.node.animation.expression ? this.node.animation.expression.manipulate(block) : x`{}`; - const name = component.qualify(this.node.animation.name); + const name = this.renderer.reference(this.node.animation.name); block.chunks.animate.push(b` ${stop_animation}(); @@ -844,7 +833,7 @@ export default class ElementWrapper extends Wrapper { } add_actions(block: Block) { - add_actions(this.renderer.component, block, this.var, this.node.actions); + add_actions(block, this.var, this.node.actions); } add_classes(block: Block) { @@ -868,7 +857,7 @@ export default class ElementWrapper extends Wrapper { 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 = changed(all_dependencies); + const condition = block.renderer.dirty(all_dependencies); block.chunks.update.push(b` if (${condition}) { diff --git a/src/compiler/compile/render_dom/wrappers/IfBlock.ts b/src/compiler/compile/render_dom/wrappers/IfBlock.ts index 6ef505cd3bd9..d2d4c7948609 100644 --- a/src/compiler/compile/render_dom/wrappers/IfBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/IfBlock.ts @@ -10,7 +10,6 @@ import { b, x } from 'code-red'; import { walk } from 'estree-walker'; import { is_head } from './shared/is_head'; import { Identifier, Node } from 'estree'; -import { changed } from './shared/changed'; function is_else_if(node: ElseBlock) { return ( @@ -267,12 +266,12 @@ export default class IfBlockWrapper extends Wrapper { /* eslint-disable @typescript-eslint/indent,indent */ if (this.needs_update) { block.chunks.init.push(b` - function ${select_block_type}(#changed, #ctx) { + function ${select_block_type}(#ctx, #dirty) { ${this.branches.map(({ dependencies, condition, snippet, block }) => condition ? b` ${snippet && ( dependencies.length > 0 - ? b`if (${condition} == null || ${changed(dependencies)}) ${condition} = !!${snippet}` + ? b`if (${condition} == null || ${block.renderer.dirty(dependencies)}) ${condition} = !!${snippet}` : b`if (${condition} == null) ${condition} = !!${snippet}` )} if (${condition}) return ${block.name};` @@ -281,7 +280,7 @@ export default class IfBlockWrapper extends Wrapper { `); } else { block.chunks.init.push(b` - function ${select_block_type}(#changed, #ctx) { + function ${select_block_type}(#ctx, #dirty) { ${this.branches.map(({ condition, snippet, block }) => condition ? b`if (${snippet || condition}) return ${block.name};` : b`return ${block.name};`)} @@ -291,7 +290,7 @@ export default class IfBlockWrapper extends Wrapper { /* eslint-enable @typescript-eslint/indent,indent */ block.chunks.init.push(b` - let ${current_block_type} = ${select_block_type}(null, #ctx); + let ${current_block_type} = ${select_block_type}(#ctx, -1); let ${name} = ${get_block}; `); @@ -323,21 +322,21 @@ export default class IfBlockWrapper extends Wrapper { if (dynamic) { block.chunks.update.push(b` - if (${current_block_type} === (${current_block_type} = ${select_block_type}(#changed, #ctx)) && ${name}) { - ${name}.p(#changed, #ctx); + 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` - if (${current_block_type} !== (${current_block_type} = ${select_block_type}(#changed, #ctx))) { + if (${current_block_type} !== (${current_block_type} = ${select_block_type}(#ctx, #dirty))) { ${change_block} } `); } } else if (dynamic) { - block.chunks.update.push(b`${name}.p(#changed, #ctx);`); + block.chunks.update.push(b`${name}.p(#ctx, #dirty);`); } if (if_exists_condition) { @@ -386,13 +385,13 @@ export default class IfBlockWrapper extends Wrapper { ${this.needs_update ? b` - function ${select_block_type}(#changed, #ctx) { + function ${select_block_type}(#ctx, #dirty) { ${this.branches.map(({ dependencies, condition, snippet }, i) => condition ? b` ${snippet && ( dependencies.length > 0 - ? b`if (${condition} == null || ${changed(dependencies)}) ${condition} = !!${snippet}` - : b`if (${condition} == null) ${condition} = !!${snippet}` + ? b`if (${block.renderer.dirty(dependencies)}) ${condition} = !!${snippet}` + : b`if (${condition} == -1) ${condition} = !!${snippet}` )} if (${condition}) return ${i};` : b`return ${i};`)} @@ -400,7 +399,7 @@ export default class IfBlockWrapper extends Wrapper { } ` : b` - function ${select_block_type}(#changed, #ctx) { + function ${select_block_type}(#ctx, #dirty) { ${this.branches.map(({ condition, snippet }, i) => condition ? b`if (${snippet || condition}) return ${i};` : b`return ${i};`)} @@ -412,12 +411,12 @@ export default class IfBlockWrapper extends Wrapper { if (has_else) { block.chunks.init.push(b` - ${current_block_type_index} = ${select_block_type}(null, #ctx); + ${current_block_type_index} = ${select_block_type}(#ctx, -1); ${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](#ctx); `); } else { block.chunks.init.push(b` - if (~(${current_block_type_index} = ${select_block_type}(null, #ctx))) { + if (~(${current_block_type_index} = ${select_block_type}(#ctx, -1))) { ${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](#ctx); } `); @@ -474,9 +473,9 @@ export default class IfBlockWrapper extends Wrapper { if (dynamic) { block.chunks.update.push(b` let ${previous_block_index} = ${current_block_type_index}; - ${current_block_type_index} = ${select_block_type}(#changed, #ctx); + ${current_block_type_index} = ${select_block_type}(#ctx, #dirty); if (${current_block_type_index} === ${previous_block_index}) { - ${if_current_block_type_index(b`${if_blocks}[${current_block_type_index}].p(#changed, #ctx);`)} + ${if_current_block_type_index(b`${if_blocks}[${current_block_type_index}].p(#ctx, #dirty);`)} } else { ${change_block} } @@ -484,14 +483,14 @@ export default class IfBlockWrapper extends Wrapper { } else { block.chunks.update.push(b` let ${previous_block_index} = ${current_block_type_index}; - ${current_block_type_index} = ${select_block_type}(#changed, #ctx); + ${current_block_type_index} = ${select_block_type}(#ctx, #dirty); if (${current_block_type_index} !== ${previous_block_index}) { ${change_block} } `); } } else if (dynamic) { - block.chunks.update.push(b`${name}.p(#changed, #ctx);`); + block.chunks.update.push(b`${name}.p(#ctx, #dirty);`); } block.chunks.destroy.push( @@ -528,7 +527,7 @@ export default class IfBlockWrapper extends Wrapper { const enter = dynamic ? b` if (${name}) { - ${name}.p(#changed, #ctx); + ${name}.p(#ctx, #dirty); ${has_transitions && b`@transition_in(${name}, 1);`} } else { ${name} = ${branch.block.name}(#ctx); @@ -549,7 +548,7 @@ export default class IfBlockWrapper extends Wrapper { `; if (branch.snippet) { - block.chunks.update.push(b`if (${changed(branch.dependencies)}) ${branch.condition} = ${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, @@ -578,7 +577,7 @@ export default class IfBlockWrapper extends Wrapper { } } else if (dynamic) { block.chunks.update.push(b` - if (${branch.condition}) ${name}.p(#changed, #ctx); + if (${branch.condition}) ${name}.p(#ctx, #dirty); `); } diff --git a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts index cc02c171edad..13c96d0065ae 100644 --- a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts +++ b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts @@ -9,18 +9,18 @@ import { b, x, p } from 'code-red'; import Attribute from '../../../nodes/Attribute'; import get_object from '../../../utils/get_object'; import create_debugging_comment from '../shared/create_debugging_comment'; -import { get_context_merger } from '../shared/get_context_merger'; +import { get_slot_definition } from '../shared/get_slot_definition'; import EachBlock from '../../../nodes/EachBlock'; import TemplateScope from '../../../nodes/shared/TemplateScope'; import is_dynamic from '../shared/is_dynamic'; import bind_this from '../shared/bind_this'; -import { changed } from '../shared/changed'; import { Node, Identifier, ObjectExpression } from 'estree'; import EventHandler from '../Element/EventHandler'; +import { extract_names } from 'periscopic'; export default class InlineComponentWrapper extends Wrapper { var: Identifier; - slots: Map = new Map(); + slots: Map = new Map(); node: InlineComponent; fragment: FragmentWrapper; @@ -74,6 +74,12 @@ export default class InlineComponentWrapper extends Wrapper { }; if (this.node.children.length) { + this.node.lets.forEach(l => { + extract_names(l.value || l.name).forEach(name => { + renderer.add_to_context(name, true); + }); + }); + const default_slot = block.child({ comment: create_debugging_comment(node, renderer.component), name: renderer.component.get_unique_name(`create_default_slot`), @@ -82,13 +88,7 @@ export default class InlineComponentWrapper extends Wrapper { this.renderer.blocks.push(default_slot); - const fn = get_context_merger(this.node.lets); - - this.slots.set('default', { - block: default_slot, - scope: this.node.scope, - fn - }); + this.slots.set('default', get_slot_definition(default_slot, this.node.scope, this.node.lets)); this.fragment = new FragmentWrapper(renderer, default_slot, node.children, this, strip_whitespace, next_sibling); const dependencies: Set = new Set(); @@ -130,7 +130,7 @@ export default class InlineComponentWrapper extends Wrapper { ? [ p`$$slots: { ${Array.from(this.slots).map(([name, slot]) => { - return p`${name}: [${slot.block.name}, ${slot.fn || null}]`; + return p`${name}: [${slot.block.name}, ${slot.get_context || null}, ${slot.get_changes || null}]`; })} }`, p`$$scope: { @@ -156,6 +156,7 @@ export default class InlineComponentWrapper extends Wrapper { } if (this.fragment) { + this.renderer.add_to_context('$$scope', true); const default_slot = this.slots.get('default'); this.fragment.nodes.forEach((child) => { @@ -206,7 +207,7 @@ export default class InlineComponentWrapper extends Wrapper { const { name, dependencies } = attr; const condition = dependencies.size > 0 && (dependencies.size !== all_dependencies.size) - ? changed(Array.from(dependencies)) + ? renderer.dirty(Array.from(dependencies)) : null; if (attr.is_spread) { @@ -239,7 +240,7 @@ export default class InlineComponentWrapper extends Wrapper { `); if (all_dependencies.size) { - const condition = changed(Array.from(all_dependencies)); + const condition = renderer.dirty(Array.from(all_dependencies)); updates.push(b` const ${name_changes} = ${condition} ? @get_spread_update(${levels}, [ @@ -255,7 +256,7 @@ export default class InlineComponentWrapper extends Wrapper { dynamic_attributes.forEach((attribute: Attribute) => { const dependencies = attribute.get_dependencies(); if (dependencies.length > 0) { - const condition = changed(dependencies); + const condition = renderer.dirty(dependencies); updates.push(b` if (${condition}) ${name_changes}.${attribute.name} = ${attribute.get_value(block)}; @@ -267,8 +268,8 @@ export default class InlineComponentWrapper extends Wrapper { if (non_let_dependencies.length > 0) { updates.push(b` - if (${changed(non_let_dependencies)}) { - ${name_changes}.$$scope = { changed: #changed, ctx: #ctx }; + if (${renderer.dirty(non_let_dependencies)}) { + ${name_changes}.$$scope = { dirty: #dirty, ctx: #ctx }; }`); } @@ -280,12 +281,8 @@ export default class InlineComponentWrapper extends Wrapper { } const id = component.get_unique_name(`${this.var.name}_${binding.name}_binding`); - - component.add_var({ - name: id.name, - internal: true, - referenced: true - }); + renderer.add_to_context(id.name); + const callee = renderer.reference(id); const updating = block.get_unique_name(`updating_${binding.name}`); block.add_variable(updating); @@ -299,7 +296,7 @@ export default class InlineComponentWrapper extends Wrapper { ); updates.push(b` - if (!${updating} && ${changed(Array.from(binding.expression.dependencies))}) { + if (!${updating} && ${renderer.dirty(Array.from(binding.expression.dependencies))}) { ${updating} = true; ${name_changes}.${binding.name} = ${snippet}; @add_flush_callback(() => ${updating} = false); @@ -321,24 +318,24 @@ export default class InlineComponentWrapper extends Wrapper { } const value = block.get_unique_name('value'); - const args: any[] = [value]; + const params: any[] = [value]; if (contextual_dependencies.length > 0) { - args.push({ - type: 'ObjectPattern', - properties: contextual_dependencies.map(name => { - const id = { type: 'Identifier', name }; - return { - type: 'Property', - kind: 'init', - key: id, - value: id - }; - }) + const args = []; + + contextual_dependencies.forEach(name => { + params.push({ + type: 'Identifier', + name + }); + + renderer.add_to_context(name, true); + args.push(renderer.reference(name)); }); + block.chunks.init.push(b` function ${id}(${value}) { - #ctx.${id}.call(null, ${value}, #ctx); + ${callee}.call(null, ${value}, ${args}); } `); @@ -346,15 +343,15 @@ export default class InlineComponentWrapper extends Wrapper { } else { block.chunks.init.push(b` function ${id}(${value}) { - #ctx.${id}.call(null, ${value}); + ${callee}.call(null, ${value}); } `); } const body = b` - function ${id}(${args}) { + function ${id}(${params}) { ${lhs} = ${value}; - ${component.invalidate(dependencies[0])}; + ${renderer.invalidate(dependencies[0])}; } `; @@ -460,7 +457,7 @@ export default class InlineComponentWrapper extends Wrapper { } else { const expression = this.node.name === 'svelte:self' ? component.name - : component.qualify(this.node.name); + : this.renderer.reference(this.node.name); block.chunks.init.push(b` ${(this.node.attributes.length > 0 || this.node.bindings.length > 0) && b` diff --git a/src/compiler/compile/render_dom/wrappers/Slot.ts b/src/compiler/compile/render_dom/wrappers/Slot.ts index 4d575d21d305..0443ecc2e56f 100644 --- a/src/compiler/compile/render_dom/wrappers/Slot.ts +++ b/src/compiler/compile/render_dom/wrappers/Slot.ts @@ -6,11 +6,39 @@ import FragmentWrapper from './Fragment'; import { b, p, x } from 'code-red'; import { sanitize } from '../../../utils/names'; import add_to_set from '../../utils/add_to_set'; -import get_slot_data from '../../utils/get_slot_data'; import Expression from '../../nodes/shared/Expression'; import is_dynamic from './shared/is_dynamic'; import { Identifier, ObjectExpression } from 'estree'; -import { changed } from './shared/changed'; +import Attribute from '../../nodes/Attribute'; +import { string_literal } from '../../utils/stringify'; + +function get_slot_data(block: Block, values: Map) { + return { + type: 'ObjectExpression', + properties: Array.from(values.values()) + .filter(attribute => attribute.name !== 'name') + .map(attribute => { + const value = get_value(block, attribute); + return p`${attribute.name}: ${value}`; + }) + }; +} + +// TODO fairly sure this is duplicated at least once +function get_value(block: Block, attribute: Attribute) { + 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) : chunk.manipulate(block)) + .reduce((lhs, rhs) => x`${lhs} + ${rhs}`); + + if (attribute.chunks.length > 1 && attribute.chunks[0].type !== 'Text') { + value = x`"" + ${value}`; + } + + return value; +} export default class SlotWrapper extends Wrapper { node: Slot; @@ -60,14 +88,13 @@ export default class SlotWrapper extends Wrapper { const { slot_name } = this.node; - let get_slot_changes; - let get_slot_context; + let get_slot_changes_fn; + let get_slot_context_fn; if (this.node.values.size > 0) { - get_slot_changes = renderer.component.get_unique_name(`get_${sanitize(slot_name)}_slot_changes`); - get_slot_context = renderer.component.get_unique_name(`get_${sanitize(slot_name)}_slot_context`); + 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 context = get_slot_data(this.node.values); const changes = x`{}` as ObjectExpression; const dependencies = new Set(); @@ -92,34 +119,25 @@ export default class SlotWrapper extends Wrapper { }); if (dynamic_dependencies.length > 0) { - const expression = dynamic_dependencies - .map(name => ({ type: 'Identifier', name } as any)) - .reduce((lhs, rhs) => x`${lhs} || ${rhs}`); - - changes.properties.push(p`${attribute.name}: ${expression}`); + changes.properties.push(p`${attribute.name}: ${renderer.dirty(dynamic_dependencies)}`); } }); - const arg = dependencies.size > 0 && { - type: 'ObjectPattern', - properties: Array.from(dependencies).map(name => p`${name}`) - }; - renderer.blocks.push(b` - const ${get_slot_changes} = (${arg}) => (${changes}); - const ${get_slot_context} = (${arg}) => (${context}); + const ${get_slot_changes_fn} = #dirty => ${changes}; + const ${get_slot_context_fn} = #ctx => ${get_slot_data(block, this.node.values)}; `); } else { - get_slot_changes = 'null'; - get_slot_context = 'null'; + get_slot_changes_fn = 'null'; + get_slot_context_fn = 'null'; } const slot = block.get_unique_name(`${sanitize(slot_name)}_slot`); const slot_definition = block.get_unique_name(`${sanitize(slot_name)}_slot_template`); block.chunks.init.push(b` - const ${slot_definition} = #ctx.$$slots.${slot_name}; - const ${slot} = @create_slot(${slot_definition}, #ctx, ${get_slot_context}); + const ${slot_definition} = ${renderer.reference('$$slots')}.${slot_name}; + const ${slot} = @create_slot(${slot_definition}, #ctx, ${renderer.reference('$$scope')}, ${get_slot_context_fn}); `); // TODO this is a dreadful hack! Should probably make this nicer @@ -184,10 +202,10 @@ export default class SlotWrapper extends Wrapper { }); block.chunks.update.push(b` - if (${slot} && ${slot}.p && ${changed(dynamic_dependencies)}) { + if (${slot} && ${slot}.p && ${renderer.dirty(dynamic_dependencies)}) { ${slot}.p( - @get_slot_changes(${slot_definition}, #ctx, #changed, ${get_slot_changes}), - @get_slot_context(${slot_definition}, #ctx, ${get_slot_context}) + @get_slot_context(${slot_definition}, #ctx, ${renderer.reference('$$scope')}, ${get_slot_context_fn}), + @get_slot_changes(${slot_definition}, ${renderer.reference('$$scope')}, #dirty, ${get_slot_changes_fn}) ); } `); diff --git a/src/compiler/compile/render_dom/wrappers/Title.ts b/src/compiler/compile/render_dom/wrappers/Title.ts index 2a02f1bc0843..428073ddd228 100644 --- a/src/compiler/compile/render_dom/wrappers/Title.ts +++ b/src/compiler/compile/render_dom/wrappers/Title.ts @@ -7,7 +7,6 @@ import { string_literal } from '../../utils/stringify'; import add_to_set from '../../utils/add_to_set'; import Text from '../../nodes/Text'; import { Identifier } from 'estree'; -import { changed } from './shared/changed'; import MustacheTag from '../../nodes/MustacheTag'; export default class TitleWrapper extends Wrapper { @@ -76,7 +75,7 @@ export default class TitleWrapper extends Wrapper { if (all_dependencies.size) { const dependencies = Array.from(all_dependencies); - let condition = changed(dependencies); + let condition = block.renderer.dirty(dependencies); if (block.has_outros) { condition = x`!#current || ${condition}`; diff --git a/src/compiler/compile/render_dom/wrappers/Window.ts b/src/compiler/compile/render_dom/wrappers/Window.ts index 7594adee6747..18691ae9a82b 100644 --- a/src/compiler/compile/render_dom/wrappers/Window.ts +++ b/src/compiler/compile/render_dom/wrappers/Window.ts @@ -5,7 +5,6 @@ import { b, x } from 'code-red'; import add_event_handlers from './shared/add_event_handlers'; import Window from '../../nodes/Window'; import add_actions from './shared/add_actions'; -import { changed } from './shared/changed'; import { Identifier } from 'estree'; import { TemplateNode } from '../../../interfaces'; import EventHandler from './Element/EventHandler'; @@ -49,7 +48,7 @@ export default class WindowWrapper extends Wrapper { const events = {}; const bindings: Record = {}; - add_actions(component, block, '@_window', this.node.actions); + add_actions(block, '@_window', this.node.actions); add_event_handlers(block, '@_window', this.handlers); this.node.bindings.forEach(binding => { @@ -81,6 +80,9 @@ export default class WindowWrapper extends Wrapper { const id = block.get_unique_name(`onwindow${event}`); const props = events[event]; + 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`); @@ -107,7 +109,7 @@ export default class WindowWrapper extends Wrapper { ${scrolling} = true; @_clearTimeout(${scrolling_timeout}); ${scrolling_timeout} = @_setTimeout(${clear_scrolling}, 100); - #ctx.${id}(); + ${fn}(); }) `); } else { @@ -118,24 +120,18 @@ export default class WindowWrapper extends Wrapper { }); block.event_listeners.push(x` - @listen(@_window, "${event}", #ctx.${id}) + @listen(@_window, "${event}", ${fn}) `); } - component.add_var({ - name: id.name, - internal: true, - referenced: true - }); - component.partly_hoisted.push(b` function ${id}() { - ${props.map(prop => component.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` - @add_render_callback(#ctx.${id}); + @add_render_callback(${fn}); `); component.has_reactive_assignments = true; @@ -143,9 +139,10 @@ export default class WindowWrapper extends Wrapper { // special case... might need to abstract this out if we add more special cases if (bindings.scrollX || bindings.scrollY) { - const condition = changed([bindings.scrollX, bindings.scrollY].filter(Boolean)); - const scrollX = bindings.scrollX ? x`#ctx.${bindings.scrollX}` : x`@_window.pageXOffset`; - const scrollY = bindings.scrollY ? x`#ctx.${bindings.scrollY}` : x`@_window.pageYOffset`; + 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`; block.chunks.update.push(b` if (${condition} && !${scrolling}) { @@ -162,25 +159,22 @@ export default class WindowWrapper extends Wrapper { const id = block.get_unique_name(`onlinestatuschanged`); const name = bindings.online; - component.add_var({ - name: id.name, - internal: true, - referenced: true - }); + renderer.add_to_context(id.name); + const reference = renderer.reference(id.name); component.partly_hoisted.push(b` function ${id}() { - ${component.invalidate(name, x`${name} = @_navigator.onLine`)} + ${renderer.invalidate(name, x`${name} = @_navigator.onLine`)} } `); block.chunks.init.push(b` - @add_render_callback(#ctx.${id}); + @add_render_callback(${reference}); `); block.event_listeners.push( - x`@listen(@_window, "online", #ctx.${id})`, - x`@listen(@_window, "offline", #ctx.${id})` + x`@listen(@_window, "online", ${reference})`, + x`@listen(@_window, "offline", ${reference})` ); component.has_reactive_assignments = true; diff --git a/src/compiler/compile/render_dom/wrappers/shared/Tag.ts b/src/compiler/compile/render_dom/wrappers/shared/Tag.ts index ccb7c6ea40f4..10e2a4a18d1b 100644 --- a/src/compiler/compile/render_dom/wrappers/shared/Tag.ts +++ b/src/compiler/compile/render_dom/wrappers/shared/Tag.ts @@ -5,7 +5,6 @@ import Block from '../../Block'; import MustacheTag from '../../../nodes/MustacheTag'; import RawMustacheTag from '../../../nodes/RawMustacheTag'; import { Node } from 'estree'; -import { changed } from './changed'; export default class Tag extends Wrapper { node: MustacheTag | RawMustacheTag; @@ -40,7 +39,7 @@ export default class Tag extends Wrapper { if (this.node.should_cache) block.add_variable(value, snippet); // TODO may need to coerce snippet to string if (dependencies.length > 0) { - let condition = changed(dependencies); + let condition = block.renderer.dirty(dependencies); if (block.has_outros) { condition = x`!#current || ${condition}`; diff --git a/src/compiler/compile/render_dom/wrappers/shared/add_actions.ts b/src/compiler/compile/render_dom/wrappers/shared/add_actions.ts index 538bfc7a9558..e8f1ecb916e8 100644 --- a/src/compiler/compile/render_dom/wrappers/shared/add_actions.ts +++ b/src/compiler/compile/render_dom/wrappers/shared/add_actions.ts @@ -1,10 +1,8 @@ import { b, x } from 'code-red'; import Block from '../../Block'; import Action from '../../../nodes/Action'; -import Component from '../../../Component'; export default function add_actions( - component: Component, block: Block, target: string, actions: Action[] @@ -25,7 +23,7 @@ export default function add_actions( block.add_variable(id); - const fn = component.qualify(action.name); + const fn = block.renderer.reference(action.name); block.chunks.mount.push( b`${id} = ${fn}.call(null, ${target}, ${snippet}) || {};` @@ -34,14 +32,8 @@ export default function add_actions( if (dependencies && dependencies.length > 0) { let condition = x`@is_function(${id}.update)`; - // TODO can this case be handled more elegantly? if (dependencies.length > 0) { - let changed = x`#changed.${dependencies[0]}`; - for (let i = 1; i < dependencies.length; i += 1) { - changed = x`${changed} || #changed.${dependencies[i]}`; - } - - condition = x`${condition} && ${changed}`; + condition = x`${condition} && ${block.renderer.dirty(dependencies)}`; } block.chunks.update.push( diff --git a/src/compiler/compile/render_dom/wrappers/shared/bind_this.ts b/src/compiler/compile/render_dom/wrappers/shared/bind_this.ts index 504e20976364..97199a71c2e3 100644 --- a/src/compiler/compile/render_dom/wrappers/shared/bind_this.ts +++ b/src/compiler/compile/render_dom/wrappers/shared/bind_this.ts @@ -8,11 +8,8 @@ import { Identifier } from 'estree'; export default function bind_this(component: Component, block: Block, binding: Binding, variable: Identifier) { const fn = component.get_unique_name(`${variable.name}_binding`); - component.add_var({ - name: fn.name, - internal: true, - referenced: true - }); + block.renderer.add_to_context(fn.name); + const callee = block.renderer.reference(fn.name); let lhs; let object; @@ -32,11 +29,11 @@ export default function bind_this(component: Component, block: Block, binding: B body = binding.raw_expression.type === 'Identifier' ? b` - ${component.invalidate(object, x`${lhs} = $$value`)}; + ${block.renderer.invalidate(object, x`${lhs} = $$value`)}; ` : b` ${lhs} = $$value; - ${component.invalidate(object)}; + ${block.renderer.invalidate(object)}; `; } @@ -58,19 +55,19 @@ export default function bind_this(component: Component, block: Block, binding: B const args = []; for (const id of contextual_dependencies) { args.push(id); - block.add_variable(id, x`#ctx.${id}`); + block.add_variable(id, block.renderer.reference(id.name)); } const assign = block.get_unique_name(`assign_${variable.name}`); const unassign = block.get_unique_name(`unassign_${variable.name}`); block.chunks.init.push(b` - const ${assign} = () => #ctx.${fn}(${variable}, ${args}); - const ${unassign} = () => #ctx.${fn}(null, ${args}); + const ${assign} = () => ${callee}(${variable}, ${args}); + const ${unassign} = () => ${callee}(null, ${args}); `); const condition = Array.from(contextual_dependencies) - .map(name => x`${name} !== #ctx.${name}`) + .map(name => x`${name} !== ${block.renderer.reference(name.name)}`) .reduce((lhs, rhs) => x`${lhs} || ${rhs}`); // we push unassign and unshift assign so that references are @@ -79,7 +76,7 @@ export default function bind_this(component: Component, block: Block, binding: B block.chunks.update.push(b` if (${condition}) { ${unassign}(); - ${args.map(a => b`${a} = #ctx.${a}`)}; + ${args.map(a => b`${a} = ${block.renderer.reference(a.name)}`)}; ${assign}(); }` ); @@ -96,6 +93,6 @@ export default function bind_this(component: Component, block: Block, binding: B } `); - block.chunks.destroy.push(b`#ctx.${fn}(null);`); - return b`#ctx.${fn}(${variable});`; + block.chunks.destroy.push(b`${callee}(null);`); + return b`${callee}(${variable});`; } \ No newline at end of file diff --git a/src/compiler/compile/render_dom/wrappers/shared/changed.ts b/src/compiler/compile/render_dom/wrappers/shared/changed.ts deleted file mode 100644 index b7dc12e53fbb..000000000000 --- a/src/compiler/compile/render_dom/wrappers/shared/changed.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { x } from 'code-red'; - -export function changed(dependencies: string[]) { - return dependencies - .map(d => x`#changed.${d}`) - .reduce((lhs, rhs) => x`${lhs} || ${rhs}`); -} \ No newline at end of file diff --git a/src/compiler/compile/render_dom/wrappers/shared/get_context_merger.ts b/src/compiler/compile/render_dom/wrappers/shared/get_context_merger.ts deleted file mode 100644 index 8c27e8b503d1..000000000000 --- a/src/compiler/compile/render_dom/wrappers/shared/get_context_merger.ts +++ /dev/null @@ -1,39 +0,0 @@ -import Let from '../../../nodes/Let'; -import { x } from 'code-red'; - -export function get_context_merger(lets: Let[]) { - if (lets.length === 0) return null; - - const input = { - type: 'ObjectPattern', - properties: lets.map(l => ({ - type: 'Property', - kind: 'init', - key: l.name, - value: l.value || l.name - })) - }; - - const names = new Set(); - lets.forEach(l => { - l.names.forEach(name => { - names.add(name); - }); - }); - - const output = { - type: 'ObjectExpression', - properties: Array.from(names).map(name => { - const id = { type: 'Identifier', name }; - - return { - type: 'Property', - kind: 'init', - key: id, - value: id - }; - }) - }; - - return x`(${input}) => (${output})`; -} \ No newline at end of file diff --git a/src/compiler/compile/render_dom/wrappers/shared/get_slot_definition.ts b/src/compiler/compile/render_dom/wrappers/shared/get_slot_definition.ts new file mode 100644 index 000000000000..24ca813684b8 --- /dev/null +++ b/src/compiler/compile/render_dom/wrappers/shared/get_slot_definition.ts @@ -0,0 +1,53 @@ +import Let from '../../../nodes/Let'; +import { x, p } from 'code-red'; +import Block from '../../Block'; +import TemplateScope from '../../../nodes/shared/TemplateScope'; + +export function get_slot_definition(block: Block, scope: TemplateScope, lets: Let[]) { + if (lets.length === 0) return { block, scope }; + + const input = { + type: 'ObjectPattern', + properties: lets.map(l => ({ + type: 'Property', + kind: 'init', + key: l.name, + value: l.value || l.name + })) + }; + + const names: Set = new Set(); + lets.forEach(l => { + l.names.forEach(name => { + names.add(name); + }); + }); + + const context = { + type: 'ObjectExpression', + properties: Array.from(names).map(name => p`${block.renderer.context_lookup.get(name).index}: ${name}`) + }; + + const changes = Array.from(names) + .map(name => { + const { context_lookup } = block.renderer; + + const literal = { + type: 'Literal', + get value() { + const i = context_lookup.get(name).index.value as number; + return 1 << i; + } + }; + + return x`${name} ? ${literal} : 0`; + }) + .reduce((lhs, rhs) => x`${lhs} | ${rhs}`); + + return { + block, + scope, + get_context: x`${input} => ${context}`, + get_changes: x`${input} => ${changes}` + }; +} \ No newline at end of file diff --git a/src/compiler/compile/render_ssr/handlers/Element.ts b/src/compiler/compile/render_ssr/handlers/Element.ts index c77a44990ca9..81b8801686e1 100644 --- a/src/compiler/compile/render_ssr/handlers/Element.ts +++ b/src/compiler/compile/render_ssr/handlers/Element.ts @@ -30,7 +30,7 @@ export default function(node: Element, renderer: Renderer, options: RenderOption const class_expression_list = node.classes.map(class_directive => { const { expression, name } = class_directive; - const snippet = expression ? expression.node : x`#ctx.${name}`; + const snippet = expression ? expression.node : x`#ctx.${name}`; // TODO is this right? return x`${snippet} ? "${name}" : ""`; }); if (node.needs_manual_style_scoping) { diff --git a/src/compiler/compile/render_ssr/handlers/Slot.ts b/src/compiler/compile/render_ssr/handlers/Slot.ts index 9f8d617c531f..897efeb382fb 100644 --- a/src/compiler/compile/render_ssr/handlers/Slot.ts +++ b/src/compiler/compile/render_ssr/handlers/Slot.ts @@ -1,7 +1,37 @@ -import get_slot_data from '../../utils/get_slot_data'; import Renderer, { RenderOptions } from '../Renderer'; import Slot from '../../nodes/Slot'; -import { x } from 'code-red'; +import { x, p } from 'code-red'; +import Attribute from '../../nodes/Attribute'; +import { string_literal } from '../../utils/stringify'; + +// TODO this is *almost* but not quite duplicated with non-SSR +function get_slot_data(values: Map) { + return { + type: 'ObjectExpression', + properties: Array.from(values.values()) + .filter(attribute => attribute.name !== 'name') + .map(attribute => { + const value = get_value(attribute); + return p`${attribute.name}: ${value}`; + }) + }; +} + +// TODO fairly sure this is duplicated at least once +function get_value(attribute: Attribute) { + 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) : chunk.node) + .reduce((lhs, rhs) => x`${lhs} + ${rhs}`); + + if (attribute.chunks.length > 1 && attribute.chunks[0].type !== 'Text') { + value = x`"" + ${value}`; + } + + return value; +} export default function(node: Slot, renderer: Renderer, options: RenderOptions) { const slot_data = get_slot_data(node.values); diff --git a/src/compiler/compile/utils/get_slot_data.ts b/src/compiler/compile/utils/get_slot_data.ts index 936dc85977cf..87811684a314 100644 --- a/src/compiler/compile/utils/get_slot_data.ts +++ b/src/compiler/compile/utils/get_slot_data.ts @@ -1,26 +1,27 @@ import Attribute from '../nodes/Attribute'; import { p, x } from 'code-red'; import { string_literal } from './stringify'; +import Block from '../render_dom/Block'; -export default function get_slot_data(values: Map) { +export default function get_slot_data(block: Block, values: Map) { return { type: 'ObjectExpression', properties: Array.from(values.values()) .filter(attribute => attribute.name !== 'name') .map(attribute => { - const value = get_value(attribute); + const value = get_value(block, attribute); return p`${attribute.name}: ${value}`; }) }; } // TODO fairly sure this is duplicated at least once -function get_value(attribute: Attribute) { +function get_value(block: Block, attribute: Attribute) { 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) : chunk.node) + .map(chunk => chunk.type === 'Text' ? string_literal(chunk.data) : chunk.manipulate(block)) .reduce((lhs, rhs) => x`${lhs} + ${rhs}`); if (attribute.chunks.length > 1 && attribute.chunks[0].type !== 'Text') { diff --git a/src/runtime/internal/Component.ts b/src/runtime/internal/Component.ts index 0ce3b3209bb6..c1d2f80101b1 100644 --- a/src/runtime/internal/Component.ts +++ b/src/runtime/internal/Component.ts @@ -1,6 +1,6 @@ import { add_render_callback, flush, schedule_update, dirty_components } from './scheduler'; import { current_component, set_current_component } from './lifecycle'; -import { blank_object, is_function, run, run_all, noop, has_prop } from './utils'; +import { blank_object, is_function, run, run_all, noop } from './utils'; import { children } from './dom'; import { transition_in } from './transitions'; @@ -11,7 +11,7 @@ interface Fragment { /* claim */ l: (nodes: any) => void; /* hydrate */ h: () => void; /* mount */ m: (target: HTMLElement, anchor: any) => void; - /* update */ p: (changed: any, ctx: any) => void; + /* update */ p: (ctx: any, dirty: any) => void; /* measure */ r: () => void; /* fix */ f: () => void; /* animate */ a: () => void; @@ -21,7 +21,7 @@ interface Fragment { } // eslint-disable-next-line @typescript-eslint/class-name-casing interface T$$ { - dirty: null; + dirty: number[]; ctx: null|any; bound: any; update: () => void; @@ -37,10 +37,10 @@ interface T$$ { } export function bind(component, name, callback) { - if (has_prop(component.$$.props, name)) { - name = component.$$.props[name] || name; - component.$$.bound[name] = callback; - callback(component.$$.ctx[name]); + const index = component.$$.props[name]; + if (index !== undefined) { + component.$$.bound[index] = callback; + callback(component.$$.ctx[index]); } } @@ -83,20 +83,20 @@ export function destroy_component(component, detaching) { // TODO null out other refs, including component.$$ (but need to // preserve final state?) $$.on_destroy = $$.fragment = null; - $$.ctx = {}; + $$.ctx = []; } } -function make_dirty(component, key) { - if (!component.$$.dirty) { +function make_dirty(component, i) { + if (component.$$.dirty[0] === -1) { dirty_components.push(component); schedule_update(); - component.$$.dirty = blank_object(); + component.$$.dirty.fill(0); } - component.$$.dirty[key] = true; + component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31)); } -export function init(component, options, instance, create_fragment, not_equal, props) { +export function init(component, options, instance, create_fragment, not_equal, props, dirty = [-1]) { const parent_component = current_component; set_current_component(component); @@ -121,25 +121,25 @@ export function init(component, options, instance, create_fragment, not_equal, p // everything else callbacks: blank_object(), - dirty: null + dirty }; let ready = false; $$.ctx = instance - ? instance(component, prop_values, (key, ret, value = ret) => { - if ($$.ctx && not_equal($$.ctx[key], $$.ctx[key] = value)) { - if ($$.bound[key]) $$.bound[key](value); - if (ready) make_dirty(component, key); + ? instance(component, prop_values, (i, ret, value = ret) => { + if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) { + if ($$.bound[i]) $$.bound[i](value); + if (ready) make_dirty(component, i); } return ret; }) - : prop_values; + : []; $$.update(); ready = true; run_all($$.before_update); - + // `false` as a special case of no DOM component $$.fragment = create_fragment ? create_fragment($$.ctx) : false; diff --git a/src/runtime/internal/await_block.ts b/src/runtime/internal/await_block.ts index 6cd7ee5cb454..f70cbd6c2c7d 100644 --- a/src/runtime/internal/await_block.ts +++ b/src/runtime/internal/await_block.ts @@ -1,4 +1,4 @@ -import { assign, is_promise } from './utils'; +import { is_promise } from './utils'; import { check_outros, group_outros, transition_in, transition_out } from './transitions'; import { flush } from './scheduler'; import { get_current_component, set_current_component } from './lifecycle'; @@ -9,9 +9,15 @@ export function handle_promise(promise, info) { function update(type, index, key?, value?) { if (info.token !== token) return; - info.resolved = key && { [key]: value }; + info.resolved = value; + + let child_ctx = info.ctx; + + if (key !== undefined) { + child_ctx = child_ctx.slice(); + child_ctx[key] = value; + } - const child_ctx = assign(assign({}, info.ctx), info.resolved); const block = type && (info.current = type)(child_ctx); let needs_flush = false; @@ -69,6 +75,6 @@ export function handle_promise(promise, info) { return true; } - info.resolved = { [info.value]: promise }; + info.resolved = promise; } } diff --git a/src/runtime/internal/keyed_each.ts b/src/runtime/internal/keyed_each.ts index 76708c93dbd4..8382a2f76a3f 100644 --- a/src/runtime/internal/keyed_each.ts +++ b/src/runtime/internal/keyed_each.ts @@ -21,7 +21,7 @@ export function fix_and_outro_and_destroy_block(block, lookup) { outro_and_destroy_block(block, lookup); } -export function update_keyed_each(old_blocks, changed, get_key, dynamic, ctx, list, lookup, node, destroy, create_each_block, next, get_context) { +export function update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list, lookup, node, destroy, create_each_block, next, get_context) { let o = old_blocks.length; let n = list.length; @@ -43,7 +43,7 @@ export function update_keyed_each(old_blocks, changed, get_key, dynamic, ctx, li block = create_each_block(key, child_ctx); block.c(); } else if (dynamic) { - block.p(changed, child_ctx); + block.p(child_ctx, dirty); } new_lookup.set(key, new_blocks[i] = block); diff --git a/src/runtime/internal/scheduler.ts b/src/runtime/internal/scheduler.ts index 7cb00c085bbc..2f864743a2f4 100644 --- a/src/runtime/internal/scheduler.ts +++ b/src/runtime/internal/scheduler.ts @@ -71,10 +71,10 @@ export function flush() { function update($$) { if ($$.fragment !== null) { - $$.update($$.dirty); + $$.update(); run_all($$.before_update); - $$.fragment && $$.fragment.p($$.dirty, $$.ctx); - $$.dirty = null; + $$.fragment && $$.fragment.p($$.ctx, $$.dirty); + $$.dirty = [-1]; $$.after_update.forEach(add_render_callback); } diff --git a/src/runtime/internal/utils.ts b/src/runtime/internal/utils.ts index 6816f8684adc..7e8769cd885e 100644 --- a/src/runtime/internal/utils.ts +++ b/src/runtime/internal/utils.ts @@ -63,23 +63,23 @@ export function component_subscribe(component, store, callback) { component.$$.on_destroy.push(subscribe(store, callback)); } -export function create_slot(definition, ctx, fn) { +export function create_slot(definition, ctx, $$scope, fn) { if (definition) { - const slot_ctx = get_slot_context(definition, ctx, fn); + const slot_ctx = get_slot_context(definition, ctx, $$scope, fn); return definition[0](slot_ctx); } } -export function get_slot_context(definition, ctx, fn) { - return definition[1] - ? assign({}, assign(ctx.$$scope.ctx, definition[1](fn ? fn(ctx) : {}))) - : ctx.$$scope.ctx; +export function get_slot_context(definition, ctx, $$scope, fn) { + return definition[1] && fn + ? assign($$scope.ctx.slice(), definition[1](fn(ctx))) + : $$scope.ctx; } -export function get_slot_changes(definition, ctx, changed, fn) { - return definition[1] - ? assign({}, assign(ctx.$$scope.changed || {}, definition[1](fn ? fn(changed) : {}))) - : ctx.$$scope.changed || {}; +export function get_slot_changes(definition, $$scope, dirty, fn) { + return definition[2] && fn + ? $$scope.dirty | definition[2](fn(dirty)) + : $$scope.dirty; } export function exclude_internal_props(props) { diff --git a/test/js/samples/action-custom-event-handler/expected.js b/test/js/samples/action-custom-event-handler/expected.js index 3fad4fb8cc8d..6c3a2a5b0b30 100644 --- a/test/js/samples/action-custom-event-handler/expected.js +++ b/test/js/samples/action-custom-event-handler/expected.js @@ -21,10 +21,10 @@ function create_fragment(ctx) { }, m(target, anchor) { insert(target, button, anchor); - foo_action = foo.call(null, button, ctx.foo_function) || ({}); + foo_action = foo.call(null, button, /*foo_function*/ ctx[1]) || ({}); }, - p(changed, ctx) { - if (is_function(foo_action.update) && changed.bar) foo_action.update.call(null, ctx.foo_function); + p(ctx, [dirty]) { + if (is_function(foo_action.update) && dirty & /*bar*/ 1) foo_action.update.call(null, /*foo_function*/ ctx[1]); }, i: noop, o: noop, @@ -48,10 +48,10 @@ function instance($$self, $$props, $$invalidate) { const foo_function = () => handleFoo(bar); $$self.$set = $$props => { - if ("bar" in $$props) $$invalidate("bar", bar = $$props.bar); + if ("bar" in $$props) $$invalidate(0, bar = $$props.bar); }; - return { bar, foo_function }; + return [bar, foo_function]; } class Component extends SvelteComponent { diff --git a/test/js/samples/bind-online/expected.js b/test/js/samples/bind-online/expected.js index d34e84330f77..8285646481a2 100644 --- a/test/js/samples/bind-online/expected.js +++ b/test/js/samples/bind-online/expected.js @@ -11,13 +11,13 @@ import { function create_fragment(ctx) { let dispose; - add_render_callback(ctx.onlinestatuschanged); + add_render_callback(/*onlinestatuschanged*/ ctx[1]); return { c() { dispose = [ - listen(window, "online", ctx.onlinestatuschanged), - listen(window, "offline", ctx.onlinestatuschanged) + listen(window, "online", /*onlinestatuschanged*/ ctx[1]), + listen(window, "offline", /*onlinestatuschanged*/ ctx[1]) ]; }, m: noop, @@ -34,10 +34,10 @@ function instance($$self, $$props, $$invalidate) { let online; function onlinestatuschanged() { - $$invalidate("online", online = navigator.onLine); + $$invalidate(0, online = navigator.onLine); } - return { online, onlinestatuschanged }; + return [online, onlinestatuschanged]; } class Component extends SvelteComponent { diff --git a/test/js/samples/bind-open/expected.js b/test/js/samples/bind-open/expected.js index f7bede2b4ef7..d4f148cac9d0 100644 --- a/test/js/samples/bind-open/expected.js +++ b/test/js/samples/bind-open/expected.js @@ -21,15 +21,15 @@ function create_fragment(ctx) { details.innerHTML = `summarycontent `; - dispose = listen(details, "toggle", ctx.details_toggle_handler); + dispose = listen(details, "toggle", /*details_toggle_handler*/ ctx[1]); }, m(target, anchor) { insert(target, details, anchor); - details.open = ctx.open; + details.open = /*open*/ ctx[0]; }, - p(changed, ctx) { - if (changed.open) { - details.open = ctx.open; + p(ctx, [dirty]) { + if (dirty & /*open*/ 1) { + details.open = /*open*/ ctx[0]; } }, i: noop, @@ -46,14 +46,14 @@ function instance($$self, $$props, $$invalidate) { function details_toggle_handler() { open = this.open; - $$invalidate("open", open); + $$invalidate(0, open); } $$self.$set = $$props => { - if ("open" in $$props) $$invalidate("open", open = $$props.open); + if ("open" in $$props) $$invalidate(0, open = $$props.open); }; - return { open, details_toggle_handler }; + return [open, details_toggle_handler]; } class Component extends SvelteComponent { diff --git a/test/js/samples/bind-width-height/expected.js b/test/js/samples/bind-width-height/expected.js index 18efcfdc082b..5c1888b7db02 100644 --- a/test/js/samples/bind-width-height/expected.js +++ b/test/js/samples/bind-width-height/expected.js @@ -19,11 +19,11 @@ function create_fragment(ctx) { c() { div = element("div"); div.textContent = "some content"; - add_render_callback(() => ctx.div_elementresize_handler.call(div)); + add_render_callback(() => /*div_elementresize_handler*/ ctx[2].call(div)); }, m(target, anchor) { insert(target, div, anchor); - div_resize_listener = add_resize_listener(div, ctx.div_elementresize_handler.bind(div)); + div_resize_listener = add_resize_listener(div, /*div_elementresize_handler*/ ctx[2].bind(div)); }, p: noop, i: noop, @@ -42,22 +42,22 @@ function instance($$self, $$props, $$invalidate) { function div_elementresize_handler() { w = this.offsetWidth; h = this.offsetHeight; - $$invalidate("w", w); - $$invalidate("h", h); + $$invalidate(0, w); + $$invalidate(1, h); } $$self.$set = $$props => { - if ("w" in $$props) $$invalidate("w", w = $$props.w); - if ("h" in $$props) $$invalidate("h", h = $$props.h); + if ("w" in $$props) $$invalidate(0, w = $$props.w); + if ("h" in $$props) $$invalidate(1, h = $$props.h); }; - return { w, h, div_elementresize_handler }; + return [w, h, div_elementresize_handler]; } class Component extends SvelteComponent { constructor(options) { super(); - init(this, options, instance, create_fragment, safe_not_equal, { w: 0, h: 0 }); + init(this, options, instance, create_fragment, safe_not_equal, { w: 0, h: 1 }); } } diff --git a/test/js/samples/bindings-readonly-order/expected.js b/test/js/samples/bindings-readonly-order/expected.js index 04eff699f8cb..cf3068666215 100644 --- a/test/js/samples/bindings-readonly-order/expected.js +++ b/test/js/samples/bindings-readonly-order/expected.js @@ -28,8 +28,8 @@ function create_fragment(ctx) { attr(input1, "type", "file"); dispose = [ - listen(input0, "change", ctx.input0_change_handler), - listen(input1, "change", ctx.input1_change_handler) + listen(input0, "change", /*input0_change_handler*/ ctx[1]), + listen(input1, "change", /*input1_change_handler*/ ctx[2]) ]; }, m(target, anchor) { @@ -54,23 +54,19 @@ function instance($$self, $$props, $$invalidate) { function input0_change_handler() { files = this.files; - $$invalidate("files", files); + $$invalidate(0, files); } function input1_change_handler() { files = this.files; - $$invalidate("files", files); + $$invalidate(0, files); } $$self.$set = $$props => { - if ("files" in $$props) $$invalidate("files", files = $$props.files); + if ("files" in $$props) $$invalidate(0, files = $$props.files); }; - return { - files, - input0_change_handler, - input1_change_handler - }; + return [files, input0_change_handler, input1_change_handler]; } class Component extends SvelteComponent { diff --git a/test/js/samples/capture-inject-dev-only/expected.js b/test/js/samples/capture-inject-dev-only/expected.js index ee2f6d0dc929..6c639d9207f6 100644 --- a/test/js/samples/capture-inject-dev-only/expected.js +++ b/test/js/samples/capture-inject-dev-only/expected.js @@ -25,23 +25,23 @@ function create_fragment(ctx) { return { c() { p = element("p"); - t0 = text(ctx.foo); + t0 = text(/*foo*/ ctx[0]); t1 = space(); input = element("input"); - dispose = listen(input, "input", ctx.input_input_handler); + dispose = listen(input, "input", /*input_input_handler*/ ctx[1]); }, m(target, anchor) { insert(target, p, anchor); append(p, t0); insert(target, t1, anchor); insert(target, input, anchor); - set_input_value(input, ctx.foo); + set_input_value(input, /*foo*/ ctx[0]); }, - p(changed, ctx) { - if (changed.foo) set_data(t0, ctx.foo); + p(ctx, [dirty]) { + if (dirty & /*foo*/ 1) set_data(t0, /*foo*/ ctx[0]); - if (changed.foo && input.value !== ctx.foo) { - set_input_value(input, ctx.foo); + if (dirty & /*foo*/ 1 && input.value !== /*foo*/ ctx[0]) { + set_input_value(input, /*foo*/ ctx[0]); } }, i: noop, @@ -60,10 +60,10 @@ function instance($$self, $$props, $$invalidate) { function input_input_handler() { foo = this.value; - $$invalidate("foo", foo); + $$invalidate(0, foo); } - return { foo, input_input_handler }; + return [foo, input_input_handler]; } class Component extends SvelteComponent { diff --git a/test/js/samples/collapses-text-around-comments/expected.js b/test/js/samples/collapses-text-around-comments/expected.js index 5fb7aaef1519..6fef0f9490d8 100644 --- a/test/js/samples/collapses-text-around-comments/expected.js +++ b/test/js/samples/collapses-text-around-comments/expected.js @@ -27,15 +27,15 @@ function create_fragment(ctx) { return { c() { p = element("p"); - t = text(ctx.foo); + t = text(/*foo*/ ctx[0]); attr(p, "class", "svelte-1a7i8ec"); }, m(target, anchor) { insert(target, p, anchor); append(p, t); }, - p(changed, ctx) { - if (changed.foo) set_data(t, ctx.foo); + p(ctx, [dirty]) { + if (dirty & /*foo*/ 1) set_data(t, /*foo*/ ctx[0]); }, i: noop, o: noop, @@ -49,10 +49,10 @@ function instance($$self, $$props, $$invalidate) { let { foo = 42 } = $$props; $$self.$set = $$props => { - if ("foo" in $$props) $$invalidate("foo", foo = $$props.foo); + if ("foo" in $$props) $$invalidate(0, foo = $$props.foo); }; - return { foo }; + return [foo]; } class Component extends SvelteComponent { diff --git a/test/js/samples/component-static-array/expected.js b/test/js/samples/component-static-array/expected.js index b89ee4676433..44e8dbfe330f 100644 --- a/test/js/samples/component-static-array/expected.js +++ b/test/js/samples/component-static-array/expected.js @@ -13,7 +13,7 @@ import { function create_fragment(ctx) { let current; - const nested = new ctx.Nested({ props: { foo: [1, 2, 3] } }); + const nested = new /*Nested*/ ctx[0]({ props: { foo: [1, 2, 3] } }); return { c() { @@ -41,7 +41,7 @@ function create_fragment(ctx) { function instance($$self) { const Nested = window.Nested; - return { Nested }; + return [Nested]; } class Component extends SvelteComponent { diff --git a/test/js/samples/component-static-immutable/expected.js b/test/js/samples/component-static-immutable/expected.js index 17b42a4a43ff..a7dd8128fa94 100644 --- a/test/js/samples/component-static-immutable/expected.js +++ b/test/js/samples/component-static-immutable/expected.js @@ -13,7 +13,7 @@ import { function create_fragment(ctx) { let current; - const nested = new ctx.Nested({ props: { foo: "bar" } }); + const nested = new /*Nested*/ ctx[0]({ props: { foo: "bar" } }); return { c() { @@ -41,7 +41,7 @@ function create_fragment(ctx) { function instance($$self) { const Nested = window.Nested; - return { Nested }; + return [Nested]; } class Component extends SvelteComponent { diff --git a/test/js/samples/component-static-immutable2/expected.js b/test/js/samples/component-static-immutable2/expected.js index 17b42a4a43ff..a7dd8128fa94 100644 --- a/test/js/samples/component-static-immutable2/expected.js +++ b/test/js/samples/component-static-immutable2/expected.js @@ -13,7 +13,7 @@ import { function create_fragment(ctx) { let current; - const nested = new ctx.Nested({ props: { foo: "bar" } }); + const nested = new /*Nested*/ ctx[0]({ props: { foo: "bar" } }); return { c() { @@ -41,7 +41,7 @@ function create_fragment(ctx) { function instance($$self) { const Nested = window.Nested; - return { Nested }; + return [Nested]; } class Component extends SvelteComponent { diff --git a/test/js/samples/component-static-var/expected.js b/test/js/samples/component-static-var/expected.js index 29c585744eac..e01402b6d445 100644 --- a/test/js/samples/component-static-var/expected.js +++ b/test/js/samples/component-static-var/expected.js @@ -26,7 +26,7 @@ function create_fragment(ctx) { let current; let dispose; const foo = new Foo({ props: { x: y } }); - const bar = new Bar({ props: { x: ctx.z } }); + const bar = new Bar({ props: { x: /*z*/ ctx[0] } }); return { c() { @@ -35,7 +35,7 @@ function create_fragment(ctx) { create_component(bar.$$.fragment); t1 = space(); input = element("input"); - dispose = listen(input, "input", ctx.input_input_handler); + dispose = listen(input, "input", /*input_input_handler*/ ctx[1]); }, m(target, anchor) { mount_component(foo, target, anchor); @@ -43,16 +43,16 @@ function create_fragment(ctx) { mount_component(bar, target, anchor); insert(target, t1, anchor); insert(target, input, anchor); - set_input_value(input, ctx.z); + set_input_value(input, /*z*/ ctx[0]); current = true; }, - p(changed, ctx) { + p(ctx, [dirty]) { const bar_changes = {}; - if (changed.z) bar_changes.x = ctx.z; + if (dirty & /*z*/ 1) bar_changes.x = /*z*/ ctx[0]; bar.$set(bar_changes); - if (changed.z && input.value !== ctx.z) { - set_input_value(input, ctx.z); + if (dirty & /*z*/ 1 && input.value !== /*z*/ ctx[0]) { + set_input_value(input, /*z*/ ctx[0]); } }, i(local) { @@ -84,10 +84,10 @@ function instance($$self, $$props, $$invalidate) { function input_input_handler() { z = this.value; - $$invalidate("z", z); + $$invalidate(0, z); } - return { z, input_input_handler }; + return [z, input_input_handler]; } class Component extends SvelteComponent { diff --git a/test/js/samples/component-static/expected.js b/test/js/samples/component-static/expected.js index 16d9ea9c4c6e..26c63f550b65 100644 --- a/test/js/samples/component-static/expected.js +++ b/test/js/samples/component-static/expected.js @@ -13,7 +13,7 @@ import { function create_fragment(ctx) { let current; - const nested = new ctx.Nested({ props: { foo: "bar" } }); + const nested = new /*Nested*/ ctx[0]({ props: { foo: "bar" } }); return { c() { @@ -41,7 +41,7 @@ function create_fragment(ctx) { function instance($$self) { const Nested = window.Nested; - return { Nested }; + return [Nested]; } class Component extends SvelteComponent { diff --git a/test/js/samples/component-store-access-invalidate/expected.js b/test/js/samples/component-store-access-invalidate/expected.js index b3eedd3d6e7a..151bd6ed0e87 100644 --- a/test/js/samples/component-store-access-invalidate/expected.js +++ b/test/js/samples/component-store-access-invalidate/expected.js @@ -22,14 +22,14 @@ function create_fragment(ctx) { return { c() { h1 = element("h1"); - t = text(ctx.$foo); + t = text(/*$foo*/ ctx[0]); }, m(target, anchor) { insert(target, h1, anchor); append(h1, t); }, - p(changed, ctx) { - if (changed.$foo) set_data(t, ctx.$foo); + p(ctx, [dirty]) { + if (dirty & /*$foo*/ 1) set_data(t, /*$foo*/ ctx[0]); }, i: noop, o: noop, @@ -42,8 +42,8 @@ function create_fragment(ctx) { function instance($$self, $$props, $$invalidate) { let $foo; const foo = writable(0); - component_subscribe($$self, foo, value => $$invalidate("$foo", $foo = value)); - return { foo, $foo }; + component_subscribe($$self, foo, value => $$invalidate(0, $foo = value)); + return [$foo]; } class Component extends SvelteComponent { diff --git a/test/js/samples/component-store-file-invalidate/expected.js b/test/js/samples/component-store-file-invalidate/expected.js index a4d7ad5c10f9..d2fb3d0be467 100644 --- a/test/js/samples/component-store-file-invalidate/expected.js +++ b/test/js/samples/component-store-file-invalidate/expected.js @@ -11,13 +11,13 @@ import { count } from "./store.js"; function instance($$self, $$props, $$invalidate) { let $count; - component_subscribe($$self, count, $$value => $$invalidate("$count", $count = $$value)); + component_subscribe($$self, count, $$value => $$invalidate(1, $count = $$value)); function increment() { set_store_value(count, $count++, $count); } - return { increment }; + return [increment]; } class Component extends SvelteComponent { @@ -27,7 +27,7 @@ class Component extends SvelteComponent { } get increment() { - return this.$$.ctx.increment; + return this.$$.ctx[0]; } } diff --git a/test/js/samples/component-store-reassign-invalidate/expected.js b/test/js/samples/component-store-reassign-invalidate/expected.js index 890e28f79c3c..02a74cf22eb3 100644 --- a/test/js/samples/component-store-reassign-invalidate/expected.js +++ b/test/js/samples/component-store-reassign-invalidate/expected.js @@ -27,11 +27,11 @@ function create_fragment(ctx) { return { c() { h1 = element("h1"); - t0 = text(ctx.$foo); + t0 = text(/*$foo*/ ctx[1]); t1 = space(); button = element("button"); button.textContent = "reset"; - dispose = listen(button, "click", ctx.click_handler); + dispose = listen(button, "click", /*click_handler*/ ctx[2]); }, m(target, anchor) { insert(target, h1, anchor); @@ -39,8 +39,8 @@ function create_fragment(ctx) { insert(target, t1, anchor); insert(target, button, anchor); }, - p(changed, ctx) { - if (changed.$foo) set_data(t0, ctx.$foo); + p(ctx, [dirty]) { + if (dirty & /*$foo*/ 2) set_data(t0, /*$foo*/ ctx[1]); }, i: noop, o: noop, @@ -56,13 +56,13 @@ function create_fragment(ctx) { function instance($$self, $$props, $$invalidate) { let $foo, $$unsubscribe_foo = noop, - $$subscribe_foo = () => ($$unsubscribe_foo(), $$unsubscribe_foo = subscribe(foo, $$value => $$invalidate("$foo", $foo = $$value)), foo); + $$subscribe_foo = () => ($$unsubscribe_foo(), $$unsubscribe_foo = subscribe(foo, $$value => $$invalidate(1, $foo = $$value)), foo); $$self.$$.on_destroy.push(() => $$unsubscribe_foo()); let foo = writable(0); $$subscribe_foo(); - const click_handler = () => $$subscribe_foo($$invalidate("foo", foo = writable(0))); - return { foo, $foo, click_handler }; + const click_handler = () => $$subscribe_foo($$invalidate(0, foo = writable(0))); + return [foo, $foo, click_handler]; } class Component extends SvelteComponent { diff --git a/test/js/samples/computed-collapsed-if/expected.js b/test/js/samples/computed-collapsed-if/expected.js index 4d3954358e3d..8e5964f8a691 100644 --- a/test/js/samples/computed-collapsed-if/expected.js +++ b/test/js/samples/computed-collapsed-if/expected.js @@ -13,24 +13,24 @@ function instance($$self, $$props, $$invalidate) { } $$self.$set = $$props => { - if ("x" in $$props) $$invalidate("x", x = $$props.x); + if ("x" in $$props) $$invalidate(0, x = $$props.x); }; - return { x, a, b }; + return [x, a, b]; } class Component extends SvelteComponent { constructor(options) { super(); - init(this, options, instance, null, safe_not_equal, { x: 0, a: 0, b: 0 }); + init(this, options, instance, null, safe_not_equal, { x: 0, a: 1, b: 2 }); } get a() { - return this.$$.ctx.a; + return this.$$.ctx[1]; } get b() { - return this.$$.ctx.b; + return this.$$.ctx[2]; } } diff --git a/test/js/samples/data-attribute/expected.js b/test/js/samples/data-attribute/expected.js index 674be31867af..49ad2f2626ba 100644 --- a/test/js/samples/data-attribute/expected.js +++ b/test/js/samples/data-attribute/expected.js @@ -22,16 +22,16 @@ function create_fragment(ctx) { t = space(); div1 = element("div"); attr(div0, "data-foo", "bar"); - attr(div1, "data-foo", ctx.bar); + attr(div1, "data-foo", /*bar*/ ctx[0]); }, m(target, anchor) { insert(target, div0, anchor); insert(target, t, anchor); insert(target, div1, anchor); }, - p(changed, ctx) { - if (changed.bar) { - attr(div1, "data-foo", ctx.bar); + p(ctx, [dirty]) { + if (dirty & /*bar*/ 1) { + attr(div1, "data-foo", /*bar*/ ctx[0]); } }, i: noop, @@ -48,10 +48,10 @@ function instance($$self, $$props, $$invalidate) { let { bar } = $$props; $$self.$set = $$props => { - if ("bar" in $$props) $$invalidate("bar", bar = $$props.bar); + if ("bar" in $$props) $$invalidate(0, bar = $$props.bar); }; - return { bar }; + return [bar]; } class Component extends SvelteComponent { diff --git a/test/js/samples/debug-empty/expected.js b/test/js/samples/debug-empty/expected.js index b545823c575c..5821faadf1e8 100644 --- a/test/js/samples/debug-empty/expected.js +++ b/test/js/samples/debug-empty/expected.js @@ -28,7 +28,7 @@ function create_fragment(ctx) { c: function create() { h1 = element("h1"); t0 = text("Hello "); - t1 = text(ctx.name); + t1 = text(/*name*/ ctx[0]); t2 = text("!"); t3 = space(); debugger; @@ -44,8 +44,8 @@ function create_fragment(ctx) { append_dev(h1, t2); insert_dev(target, t3, anchor); }, - p: function update(changed, ctx) { - if (changed.name) set_data_dev(t1, ctx.name); + p: function update(ctx, [dirty]) { + if (dirty & /*name*/ 1) set_data_dev(t1, /*name*/ ctx[0]); debugger; }, i: noop, @@ -76,7 +76,7 @@ function instance($$self, $$props, $$invalidate) { }); $$self.$set = $$props => { - if ("name" in $$props) $$invalidate("name", name = $$props.name); + if ("name" in $$props) $$invalidate(0, name = $$props.name); }; $$self.$capture_state = () => { @@ -84,10 +84,10 @@ function instance($$self, $$props, $$invalidate) { }; $$self.$inject_state = $$props => { - if ("name" in $$props) $$invalidate("name", name = $$props.name); + if ("name" in $$props) $$invalidate(0, name = $$props.name); }; - return { name }; + return [name]; } class Component extends SvelteComponentDev { @@ -105,7 +105,7 @@ class Component extends SvelteComponentDev { const { ctx } = this.$$; const props = options.props || ({}); - if (ctx.name === undefined && !("name" in props)) { + if (/*name*/ ctx[0] === undefined && !("name" in props)) { console.warn(" was created without expected prop 'name'"); } } diff --git a/test/js/samples/debug-foo-bar-baz-things/expected.js b/test/js/samples/debug-foo-bar-baz-things/expected.js index 448fc82176f3..a1d6dba3b355 100644 --- a/test/js/samples/debug-foo-bar-baz-things/expected.js +++ b/test/js/samples/debug-foo-bar-baz-things/expected.js @@ -19,15 +19,15 @@ import { const file = undefined; function get_each_context(ctx, list, i) { - const child_ctx = Object.create(ctx); - child_ctx.thing = list[i]; + const child_ctx = ctx.slice(); + child_ctx[4] = list[i]; return child_ctx; } // (8:0) {#each things as thing} function create_each_block(ctx) { let span; - let t0_value = ctx.thing.name + ""; + let t0_value = /*thing*/ ctx[4].name + ""; let t0; let t1; @@ -38,7 +38,10 @@ function create_each_block(ctx) { t1 = space(); { - const { foo, bar, baz, thing } = ctx; + const foo = /*foo*/ ctx[1]; + const bar = /*bar*/ ctx[2]; + const baz = /*baz*/ ctx[3]; + const thing = /*thing*/ ctx[4]; console.log({ foo, bar, baz, thing }); debugger; } @@ -50,11 +53,14 @@ function create_each_block(ctx) { append_dev(span, t0); insert_dev(target, t1, anchor); }, - p: function update(changed, ctx) { - if (changed.things && t0_value !== (t0_value = ctx.thing.name + "")) set_data_dev(t0, t0_value); - - if (changed.foo || changed.bar || changed.baz || changed.things) { - const { foo, bar, baz, thing } = ctx; + p: function update(ctx, dirty) { + if (dirty & /*things*/ 1 && t0_value !== (t0_value = /*thing*/ ctx[4].name + "")) set_data_dev(t0, t0_value); + + if (dirty & /*foo, bar, baz, things*/ 15) { + const foo = /*foo*/ ctx[1]; + const bar = /*bar*/ ctx[2]; + const baz = /*baz*/ ctx[3]; + const thing = /*thing*/ ctx[4]; console.log({ foo, bar, baz, thing }); debugger; } @@ -81,7 +87,7 @@ function create_fragment(ctx) { let p; let t1; let t2; - let each_value = ctx.things; + let each_value = /*things*/ ctx[0]; let each_blocks = []; for (let i = 0; i < each_value.length; i += 1) { @@ -97,7 +103,7 @@ function create_fragment(ctx) { t0 = space(); p = element("p"); t1 = text("foo: "); - t2 = text(ctx.foo); + t2 = text(/*foo*/ ctx[1]); add_location(p, file, 12, 0, 182); }, l: function claim(nodes) { @@ -113,16 +119,16 @@ function create_fragment(ctx) { append_dev(p, t1); append_dev(p, t2); }, - p: function update(changed, ctx) { - if (changed.things) { - each_value = ctx.things; + p: function update(ctx, [dirty]) { + if (dirty & /*things*/ 1) { + each_value = /*things*/ ctx[0]; let i; for (i = 0; i < each_value.length; i += 1) { const child_ctx = get_each_context(ctx, each_value, i); if (each_blocks[i]) { - each_blocks[i].p(changed, child_ctx); + each_blocks[i].p(child_ctx, dirty); } else { each_blocks[i] = create_each_block(child_ctx); each_blocks[i].c(); @@ -137,7 +143,7 @@ function create_fragment(ctx) { each_blocks.length = each_value.length; } - if (changed.foo) set_data_dev(t2, ctx.foo); + if (dirty & /*foo*/ 2) set_data_dev(t2, /*foo*/ ctx[1]); }, i: noop, o: noop, @@ -171,10 +177,10 @@ function instance($$self, $$props, $$invalidate) { }); $$self.$set = $$props => { - if ("things" in $$props) $$invalidate("things", things = $$props.things); - if ("foo" in $$props) $$invalidate("foo", foo = $$props.foo); - if ("bar" in $$props) $$invalidate("bar", bar = $$props.bar); - if ("baz" in $$props) $$invalidate("baz", baz = $$props.baz); + if ("things" in $$props) $$invalidate(0, things = $$props.things); + if ("foo" in $$props) $$invalidate(1, foo = $$props.foo); + if ("bar" in $$props) $$invalidate(2, bar = $$props.bar); + if ("baz" in $$props) $$invalidate(3, baz = $$props.baz); }; $$self.$capture_state = () => { @@ -182,19 +188,19 @@ function instance($$self, $$props, $$invalidate) { }; $$self.$inject_state = $$props => { - if ("things" in $$props) $$invalidate("things", things = $$props.things); - if ("foo" in $$props) $$invalidate("foo", foo = $$props.foo); - if ("bar" in $$props) $$invalidate("bar", bar = $$props.bar); - if ("baz" in $$props) $$invalidate("baz", baz = $$props.baz); + if ("things" in $$props) $$invalidate(0, things = $$props.things); + if ("foo" in $$props) $$invalidate(1, foo = $$props.foo); + if ("bar" in $$props) $$invalidate(2, bar = $$props.bar); + if ("baz" in $$props) $$invalidate(3, baz = $$props.baz); }; - return { things, foo, bar, baz }; + return [things, foo, bar, baz]; } class Component extends SvelteComponentDev { constructor(options) { super(options); - init(this, options, instance, create_fragment, safe_not_equal, { things: 0, foo: 0, bar: 0, baz: 0 }); + init(this, options, instance, create_fragment, safe_not_equal, { things: 0, foo: 1, bar: 2, baz: 3 }); dispatch_dev("SvelteRegisterComponent", { component: this, @@ -206,19 +212,19 @@ class Component extends SvelteComponentDev { const { ctx } = this.$$; const props = options.props || ({}); - if (ctx.things === undefined && !("things" in props)) { + if (/*things*/ ctx[0] === undefined && !("things" in props)) { console.warn(" was created without expected prop 'things'"); } - if (ctx.foo === undefined && !("foo" in props)) { + if (/*foo*/ ctx[1] === undefined && !("foo" in props)) { console.warn(" was created without expected prop 'foo'"); } - if (ctx.bar === undefined && !("bar" in props)) { + if (/*bar*/ ctx[2] === undefined && !("bar" in props)) { console.warn(" was created without expected prop 'bar'"); } - if (ctx.baz === undefined && !("baz" in props)) { + if (/*baz*/ ctx[3] === undefined && !("baz" in props)) { console.warn(" was created without expected prop 'baz'"); } } diff --git a/test/js/samples/debug-foo/expected.js b/test/js/samples/debug-foo/expected.js index 8abfd1bae100..af79667cc237 100644 --- a/test/js/samples/debug-foo/expected.js +++ b/test/js/samples/debug-foo/expected.js @@ -19,15 +19,15 @@ import { const file = undefined; function get_each_context(ctx, list, i) { - const child_ctx = Object.create(ctx); - child_ctx.thing = list[i]; + const child_ctx = ctx.slice(); + child_ctx[2] = list[i]; return child_ctx; } // (6:0) {#each things as thing} function create_each_block(ctx) { let span; - let t0_value = ctx.thing.name + ""; + let t0_value = /*thing*/ ctx[2].name + ""; let t0; let t1; @@ -38,7 +38,7 @@ function create_each_block(ctx) { t1 = space(); { - const { foo } = ctx; + const foo = /*foo*/ ctx[1]; console.log({ foo }); debugger; } @@ -50,11 +50,11 @@ function create_each_block(ctx) { append_dev(span, t0); insert_dev(target, t1, anchor); }, - p: function update(changed, ctx) { - if (changed.things && t0_value !== (t0_value = ctx.thing.name + "")) set_data_dev(t0, t0_value); + p: function update(ctx, dirty) { + if (dirty & /*things*/ 1 && t0_value !== (t0_value = /*thing*/ ctx[2].name + "")) set_data_dev(t0, t0_value); - if (changed.foo) { - const { foo } = ctx; + if (dirty & /*foo*/ 2) { + const foo = /*foo*/ ctx[1]; console.log({ foo }); debugger; } @@ -81,7 +81,7 @@ function create_fragment(ctx) { let p; let t1; let t2; - let each_value = ctx.things; + let each_value = /*things*/ ctx[0]; let each_blocks = []; for (let i = 0; i < each_value.length; i += 1) { @@ -97,7 +97,7 @@ function create_fragment(ctx) { t0 = space(); p = element("p"); t1 = text("foo: "); - t2 = text(ctx.foo); + t2 = text(/*foo*/ ctx[1]); add_location(p, file, 10, 0, 131); }, l: function claim(nodes) { @@ -113,16 +113,16 @@ function create_fragment(ctx) { append_dev(p, t1); append_dev(p, t2); }, - p: function update(changed, ctx) { - if (changed.things) { - each_value = ctx.things; + p: function update(ctx, [dirty]) { + if (dirty & /*things*/ 1) { + each_value = /*things*/ ctx[0]; let i; for (i = 0; i < each_value.length; i += 1) { const child_ctx = get_each_context(ctx, each_value, i); if (each_blocks[i]) { - each_blocks[i].p(changed, child_ctx); + each_blocks[i].p(child_ctx, dirty); } else { each_blocks[i] = create_each_block(child_ctx); each_blocks[i].c(); @@ -137,7 +137,7 @@ function create_fragment(ctx) { each_blocks.length = each_value.length; } - if (changed.foo) set_data_dev(t2, ctx.foo); + if (dirty & /*foo*/ 2) set_data_dev(t2, /*foo*/ ctx[1]); }, i: noop, o: noop, @@ -169,8 +169,8 @@ function instance($$self, $$props, $$invalidate) { }); $$self.$set = $$props => { - if ("things" in $$props) $$invalidate("things", things = $$props.things); - if ("foo" in $$props) $$invalidate("foo", foo = $$props.foo); + if ("things" in $$props) $$invalidate(0, things = $$props.things); + if ("foo" in $$props) $$invalidate(1, foo = $$props.foo); }; $$self.$capture_state = () => { @@ -178,17 +178,17 @@ function instance($$self, $$props, $$invalidate) { }; $$self.$inject_state = $$props => { - if ("things" in $$props) $$invalidate("things", things = $$props.things); - if ("foo" in $$props) $$invalidate("foo", foo = $$props.foo); + if ("things" in $$props) $$invalidate(0, things = $$props.things); + if ("foo" in $$props) $$invalidate(1, foo = $$props.foo); }; - return { things, foo }; + return [things, foo]; } class Component extends SvelteComponentDev { constructor(options) { super(options); - init(this, options, instance, create_fragment, safe_not_equal, { things: 0, foo: 0 }); + init(this, options, instance, create_fragment, safe_not_equal, { things: 0, foo: 1 }); dispatch_dev("SvelteRegisterComponent", { component: this, @@ -200,11 +200,11 @@ class Component extends SvelteComponentDev { const { ctx } = this.$$; const props = options.props || ({}); - if (ctx.things === undefined && !("things" in props)) { + if (/*things*/ ctx[0] === undefined && !("things" in props)) { console.warn(" was created without expected prop 'things'"); } - if (ctx.foo === undefined && !("foo" in props)) { + if (/*foo*/ ctx[1] === undefined && !("foo" in props)) { console.warn(" was created without expected prop 'foo'"); } } diff --git a/test/js/samples/debug-hoisted/expected.js b/test/js/samples/debug-hoisted/expected.js index 7ab1d3348e9a..eeb946549965 100644 --- a/test/js/samples/debug-hoisted/expected.js +++ b/test/js/samples/debug-hoisted/expected.js @@ -13,7 +13,8 @@ function create_fragment(ctx) { const block = { c: function create() { { - const { obj } = ctx; + const obj = /*obj*/ ctx[0]; + const kobzol = /*kobzol*/ ctx[1]; console.log({ obj, kobzol }); debugger; } @@ -22,9 +23,10 @@ function create_fragment(ctx) { throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); }, m: noop, - p: function update(changed, ctx) { - if (changed.obj || changed.kobzol) { - const { obj } = ctx; + p: function update(ctx, [dirty]) { + if (dirty & /*obj, kobzol*/ 3) { + const obj = /*obj*/ ctx[0]; + const kobzol = /*kobzol*/ ctx[1]; console.log({ obj, kobzol }); debugger; } @@ -45,21 +47,20 @@ function create_fragment(ctx) { return block; } -let kobzol = 5; - function instance($$self) { let obj = { x: 5 }; + let kobzol = 5; $$self.$capture_state = () => { return {}; }; $$self.$inject_state = $$props => { - if ("obj" in $$props) $$invalidate("obj", obj = $$props.obj); - if ("kobzol" in $$props) $$invalidate("kobzol", kobzol = $$props.kobzol); + if ("obj" in $$props) $$invalidate(0, obj = $$props.obj); + if ("kobzol" in $$props) $$invalidate(1, kobzol = $$props.kobzol); }; - return { obj }; + return [obj, kobzol]; } class Component extends SvelteComponentDev { diff --git a/test/js/samples/debug-no-dependencies/expected.js b/test/js/samples/debug-no-dependencies/expected.js index 903bdb83b683..054dda795328 100644 --- a/test/js/samples/debug-no-dependencies/expected.js +++ b/test/js/samples/debug-no-dependencies/expected.js @@ -16,22 +16,22 @@ import { const file = undefined; function get_each_context(ctx, list, i) { - const child_ctx = Object.create(ctx); - child_ctx.thing = list[i]; - child_ctx.index = i; + const child_ctx = ctx.slice(); + child_ctx[0] = list[i]; + child_ctx[2] = i; return child_ctx; } // (4:0) {#each things as thing, index} function create_each_block(ctx) { let t0; - let t1_value = ctx.thing + ""; + let t1_value = /*thing*/ ctx[0] + ""; let t1; const block = { c: function create() { { - const { index } = ctx; + const index = /*index*/ ctx[2]; console.log({ index }); debugger; } @@ -88,8 +88,8 @@ function create_fragment(ctx) { insert_dev(target, each_1_anchor, anchor); }, - p: function update(changed, ctx) { - if (changed.things) { + p: function update(ctx, [dirty]) { + if (dirty & /*things*/ 0) { each_value = things; let i; @@ -97,7 +97,7 @@ function create_fragment(ctx) { const child_ctx = get_each_context(ctx, each_value, i); if (each_blocks[i]) { - each_blocks[i].p(changed, child_ctx); + each_blocks[i].p(child_ctx, dirty); } else { each_blocks[i] = create_each_block(child_ctx); each_blocks[i].c(); diff --git a/test/js/samples/deconflict-builtins/expected.js b/test/js/samples/deconflict-builtins/expected.js index 54448a91b491..fb98844ef7a9 100644 --- a/test/js/samples/deconflict-builtins/expected.js +++ b/test/js/samples/deconflict-builtins/expected.js @@ -15,15 +15,15 @@ import { } from "svelte/internal"; function get_each_context(ctx, list, i) { - const child_ctx = Object.create(ctx); - child_ctx.node = list[i]; + const child_ctx = ctx.slice(); + child_ctx[1] = list[i]; return child_ctx; } // (5:0) {#each createElement as node} function create_each_block(ctx) { let span; - let t_value = ctx.node + ""; + let t_value = /*node*/ ctx[1] + ""; let t; return { @@ -35,8 +35,8 @@ function create_each_block(ctx) { insert(target, span, anchor); append(span, t); }, - p(changed, ctx) { - if (changed.createElement && t_value !== (t_value = ctx.node + "")) set_data(t, t_value); + p(ctx, dirty) { + if (dirty & /*createElement*/ 1 && t_value !== (t_value = /*node*/ ctx[1] + "")) set_data(t, t_value); }, d(detaching) { if (detaching) detach(span); @@ -46,7 +46,7 @@ function create_each_block(ctx) { function create_fragment(ctx) { let each_1_anchor; - let each_value = ctx.createElement; + let each_value = /*createElement*/ ctx[0]; let each_blocks = []; for (let i = 0; i < each_value.length; i += 1) { @@ -68,16 +68,16 @@ function create_fragment(ctx) { insert(target, each_1_anchor, anchor); }, - p(changed, ctx) { - if (changed.createElement) { - each_value = ctx.createElement; + p(ctx, [dirty]) { + if (dirty & /*createElement*/ 1) { + each_value = /*createElement*/ ctx[0]; let i; for (i = 0; i < each_value.length; i += 1) { const child_ctx = get_each_context(ctx, each_value, i); if (each_blocks[i]) { - each_blocks[i].p(changed, child_ctx); + each_blocks[i].p(child_ctx, dirty); } else { each_blocks[i] = create_each_block(child_ctx); each_blocks[i].c(); @@ -105,10 +105,10 @@ function instance($$self, $$props, $$invalidate) { let { createElement } = $$props; $$self.$set = $$props => { - if ("createElement" in $$props) $$invalidate("createElement", createElement = $$props.createElement); + if ("createElement" in $$props) $$invalidate(0, createElement = $$props.createElement); }; - return { createElement }; + return [createElement]; } class Component extends SvelteComponent { diff --git a/test/js/samples/deconflict-globals/expected.js b/test/js/samples/deconflict-globals/expected.js index 6bd0c596b92f..7e83c21f0e6e 100644 --- a/test/js/samples/deconflict-globals/expected.js +++ b/test/js/samples/deconflict-globals/expected.js @@ -11,10 +11,10 @@ function instance($$self, $$props, $$invalidate) { }); $$self.$set = $$props => { - if ("foo" in $$props) $$invalidate("foo", foo = $$props.foo); + if ("foo" in $$props) $$invalidate(0, foo = $$props.foo); }; - return { foo }; + return [foo]; } class Component extends SvelteComponent { diff --git a/test/js/samples/dev-warning-missing-data-computed/expected.js b/test/js/samples/dev-warning-missing-data-computed/expected.js index 5da2b4aead10..beb794a50c7a 100644 --- a/test/js/samples/dev-warning-missing-data-computed/expected.js +++ b/test/js/samples/dev-warning-missing-data-computed/expected.js @@ -19,7 +19,7 @@ const file = undefined; function create_fragment(ctx) { let p; - let t0_value = Math.max(0, ctx.foo) + ""; + let t0_value = Math.max(0, /*foo*/ ctx[0]) + ""; let t0; let t1; let t2; @@ -29,7 +29,7 @@ function create_fragment(ctx) { p = element("p"); t0 = text(t0_value); t1 = space(); - t2 = text(ctx.bar); + t2 = text(/*bar*/ ctx[1]); add_location(p, file, 7, 0, 67); }, l: function claim(nodes) { @@ -41,9 +41,9 @@ function create_fragment(ctx) { append_dev(p, t1); append_dev(p, t2); }, - p: function update(changed, ctx) { - if (changed.foo && t0_value !== (t0_value = Math.max(0, ctx.foo) + "")) set_data_dev(t0, t0_value); - if (changed.bar) set_data_dev(t2, ctx.bar); + p: function update(ctx, [dirty]) { + if (dirty & /*foo*/ 1 && t0_value !== (t0_value = Math.max(0, /*foo*/ ctx[0]) + "")) set_data_dev(t0, t0_value); + if (dirty & /*bar*/ 2) set_data_dev(t2, /*bar*/ ctx[1]); }, i: noop, o: noop, @@ -73,7 +73,7 @@ function instance($$self, $$props, $$invalidate) { }); $$self.$set = $$props => { - if ("foo" in $$props) $$invalidate("foo", foo = $$props.foo); + if ("foo" in $$props) $$invalidate(0, foo = $$props.foo); }; $$self.$capture_state = () => { @@ -81,17 +81,17 @@ function instance($$self, $$props, $$invalidate) { }; $$self.$inject_state = $$props => { - if ("foo" in $$props) $$invalidate("foo", foo = $$props.foo); - if ("bar" in $$props) $$invalidate("bar", bar = $$props.bar); + if ("foo" in $$props) $$invalidate(0, foo = $$props.foo); + if ("bar" in $$props) $$invalidate(1, bar = $$props.bar); }; - $$self.$$.update = (changed = { foo: 1 }) => { - if (changed.foo) { - $: $$invalidate("bar", bar = foo * 2); + $$self.$$.update = () => { + if ($$self.$$.dirty & /*foo*/ 1) { + $: $$invalidate(1, bar = foo * 2); } }; - return { foo, bar }; + return [foo, bar]; } class Component extends SvelteComponentDev { @@ -109,7 +109,7 @@ class Component extends SvelteComponentDev { const { ctx } = this.$$; const props = options.props || ({}); - if (ctx.foo === undefined && !("foo" in props)) { + if (/*foo*/ ctx[0] === undefined && !("foo" in props)) { console.warn(" was created without expected prop 'foo'"); } } diff --git a/test/js/samples/each-block-array-literal/expected.js b/test/js/samples/each-block-array-literal/expected.js index 3804cab6bbd0..10d835cf7805 100644 --- a/test/js/samples/each-block-array-literal/expected.js +++ b/test/js/samples/each-block-array-literal/expected.js @@ -15,15 +15,15 @@ import { } from "svelte/internal"; function get_each_context(ctx, list, i) { - const child_ctx = Object.create(ctx); - child_ctx.num = list[i]; + const child_ctx = ctx.slice(); + child_ctx[5] = list[i]; return child_ctx; } // (9:0) {#each [a, b, c, d, e] as num} function create_each_block(ctx) { let span; - let t_value = ctx.num + ""; + let t_value = /*num*/ ctx[5] + ""; let t; return { @@ -35,8 +35,8 @@ function create_each_block(ctx) { insert(target, span, anchor); append(span, t); }, - p(changed, ctx) { - if ((changed.a || changed.b || changed.c || changed.d || changed.e) && t_value !== (t_value = ctx.num + "")) set_data(t, t_value); + p(ctx, dirty) { + if (dirty & /*a, b, c, d, e*/ 31 && t_value !== (t_value = /*num*/ ctx[5] + "")) set_data(t, t_value); }, d(detaching) { if (detaching) detach(span); @@ -46,7 +46,7 @@ function create_each_block(ctx) { function create_fragment(ctx) { let each_1_anchor; - let each_value = [ctx.a, ctx.b, ctx.c, ctx.d, ctx.e]; + let each_value = [/*a*/ ctx[0], /*b*/ ctx[1], /*c*/ ctx[2], /*d*/ ctx[3], /*e*/ ctx[4]]; let each_blocks = []; for (let i = 0; i < 5; i += 1) { @@ -68,16 +68,16 @@ function create_fragment(ctx) { insert(target, each_1_anchor, anchor); }, - p(changed, ctx) { - if (changed.a || changed.b || changed.c || changed.d || changed.e) { - each_value = [ctx.a, ctx.b, ctx.c, ctx.d, ctx.e]; + p(ctx, [dirty]) { + if (dirty & /*a, b, c, d, e*/ 31) { + each_value = [/*a*/ ctx[0], /*b*/ ctx[1], /*c*/ ctx[2], /*d*/ ctx[3], /*e*/ ctx[4]]; let i; for (i = 0; i < 5; i += 1) { const child_ctx = get_each_context(ctx, each_value, i); if (each_blocks[i]) { - each_blocks[i].p(changed, child_ctx); + each_blocks[i].p(child_ctx, dirty); } else { each_blocks[i] = create_each_block(child_ctx); each_blocks[i].c(); @@ -107,20 +107,20 @@ function instance($$self, $$props, $$invalidate) { let { e } = $$props; $$self.$set = $$props => { - if ("a" in $$props) $$invalidate("a", a = $$props.a); - if ("b" in $$props) $$invalidate("b", b = $$props.b); - if ("c" in $$props) $$invalidate("c", c = $$props.c); - if ("d" in $$props) $$invalidate("d", d = $$props.d); - if ("e" in $$props) $$invalidate("e", e = $$props.e); + if ("a" in $$props) $$invalidate(0, a = $$props.a); + if ("b" in $$props) $$invalidate(1, b = $$props.b); + if ("c" in $$props) $$invalidate(2, c = $$props.c); + if ("d" in $$props) $$invalidate(3, d = $$props.d); + if ("e" in $$props) $$invalidate(4, e = $$props.e); }; - return { a, b, c, d, e }; + return [a, b, c, d, e]; } class Component extends SvelteComponent { constructor(options) { super(); - init(this, options, instance, create_fragment, safe_not_equal, { a: 0, b: 0, c: 0, d: 0, e: 0 }); + init(this, options, instance, create_fragment, safe_not_equal, { a: 0, b: 1, c: 2, d: 3, e: 4 }); } } diff --git a/test/js/samples/each-block-changed-check/expected.js b/test/js/samples/each-block-changed-check/expected.js index a2735ae9c4ef..5d88032b8794 100644 --- a/test/js/samples/each-block-changed-check/expected.js +++ b/test/js/samples/each-block-changed-check/expected.js @@ -17,9 +17,9 @@ import { } from "svelte/internal"; function get_each_context(ctx, list, i) { - const child_ctx = Object.create(ctx); - child_ctx.comment = list[i]; - child_ctx.i = i; + const child_ctx = ctx.slice(); + child_ctx[4] = list[i]; + child_ctx[6] = i; return child_ctx; } @@ -30,21 +30,21 @@ function create_each_block(ctx) { let t0; let t1; let span; - let t2_value = ctx.comment.author + ""; + let t2_value = /*comment*/ ctx[4].author + ""; let t2; let t3; - let t4_value = ctx.elapsed(ctx.comment.time, ctx.time) + ""; + let t4_value = /*elapsed*/ ctx[1](/*comment*/ ctx[4].time, /*time*/ ctx[2]) + ""; let t4; let t5; let t6; let html_tag; - let raw_value = ctx.comment.html + ""; + let raw_value = /*comment*/ ctx[4].html + ""; return { c() { div = element("div"); strong = element("strong"); - t0 = text(ctx.i); + t0 = text(/*i*/ ctx[6]); t1 = space(); span = element("span"); t2 = text(t2_value); @@ -69,10 +69,10 @@ function create_each_block(ctx) { append(div, t6); html_tag.m(div); }, - p(changed, ctx) { - if (changed.comments && t2_value !== (t2_value = ctx.comment.author + "")) set_data(t2, t2_value); - if ((changed.elapsed || changed.comments || changed.time) && t4_value !== (t4_value = ctx.elapsed(ctx.comment.time, ctx.time) + "")) set_data(t4, t4_value); - if (changed.comments && raw_value !== (raw_value = ctx.comment.html + "")) html_tag.p(raw_value); + p(ctx, dirty) { + if (dirty & /*comments*/ 1 && t2_value !== (t2_value = /*comment*/ ctx[4].author + "")) set_data(t2, t2_value); + if (dirty & /*elapsed, comments, time*/ 7 && t4_value !== (t4_value = /*elapsed*/ ctx[1](/*comment*/ ctx[4].time, /*time*/ ctx[2]) + "")) set_data(t4, t4_value); + if (dirty & /*comments*/ 1 && raw_value !== (raw_value = /*comment*/ ctx[4].html + "")) html_tag.p(raw_value); }, d(detaching) { if (detaching) detach(div); @@ -84,7 +84,7 @@ function create_fragment(ctx) { let t0; let p; let t1; - let each_value = ctx.comments; + let each_value = /*comments*/ ctx[0]; let each_blocks = []; for (let i = 0; i < each_value.length; i += 1) { @@ -99,7 +99,7 @@ function create_fragment(ctx) { t0 = space(); p = element("p"); - t1 = text(ctx.foo); + t1 = text(/*foo*/ ctx[3]); }, m(target, anchor) { for (let i = 0; i < each_blocks.length; i += 1) { @@ -110,16 +110,16 @@ function create_fragment(ctx) { insert(target, p, anchor); append(p, t1); }, - p(changed, ctx) { - if (changed.comments || changed.elapsed || changed.time) { - each_value = ctx.comments; + p(ctx, [dirty]) { + if (dirty & /*comments, elapsed, time*/ 7) { + each_value = /*comments*/ ctx[0]; let i; for (i = 0; i < each_value.length; i += 1) { const child_ctx = get_each_context(ctx, each_value, i); if (each_blocks[i]) { - each_blocks[i].p(changed, child_ctx); + each_blocks[i].p(child_ctx, dirty); } else { each_blocks[i] = create_each_block(child_ctx); each_blocks[i].c(); @@ -134,7 +134,7 @@ function create_fragment(ctx) { each_blocks.length = each_value.length; } - if (changed.foo) set_data(t1, ctx.foo); + if (dirty & /*foo*/ 8) set_data(t1, /*foo*/ ctx[3]); }, i: noop, o: noop, @@ -153,19 +153,19 @@ function instance($$self, $$props, $$invalidate) { let { foo } = $$props; $$self.$set = $$props => { - if ("comments" in $$props) $$invalidate("comments", comments = $$props.comments); - if ("elapsed" in $$props) $$invalidate("elapsed", elapsed = $$props.elapsed); - if ("time" in $$props) $$invalidate("time", time = $$props.time); - if ("foo" in $$props) $$invalidate("foo", foo = $$props.foo); + if ("comments" in $$props) $$invalidate(0, comments = $$props.comments); + if ("elapsed" in $$props) $$invalidate(1, elapsed = $$props.elapsed); + if ("time" in $$props) $$invalidate(2, time = $$props.time); + if ("foo" in $$props) $$invalidate(3, foo = $$props.foo); }; - return { comments, elapsed, time, foo }; + return [comments, elapsed, time, foo]; } class Component extends SvelteComponent { constructor(options) { super(); - init(this, options, instance, create_fragment, safe_not_equal, { comments: 0, elapsed: 0, time: 0, foo: 0 }); + init(this, options, instance, create_fragment, safe_not_equal, { comments: 0, elapsed: 1, time: 2, foo: 3 }); } } diff --git a/test/js/samples/each-block-keyed-animated/expected.js b/test/js/samples/each-block-keyed-animated/expected.js index e3661764b1f6..3b697d68607e 100644 --- a/test/js/samples/each-block-keyed-animated/expected.js +++ b/test/js/samples/each-block-keyed-animated/expected.js @@ -18,15 +18,15 @@ import { } from "svelte/internal"; function get_each_context(ctx, list, i) { - const child_ctx = Object.create(ctx); - child_ctx.thing = list[i]; + const child_ctx = ctx.slice(); + child_ctx[1] = list[i]; return child_ctx; } // (19:0) {#each things as thing (thing.id)} function create_each_block(key_1, ctx) { let div; - let t_value = ctx.thing.name + ""; + let t_value = /*thing*/ ctx[1].name + ""; let t; let rect; let stop_animation = noop; @@ -43,8 +43,8 @@ function create_each_block(key_1, ctx) { insert(target, div, anchor); append(div, t); }, - p(changed, ctx) { - if (changed.things && t_value !== (t_value = ctx.thing.name + "")) set_data(t, t_value); + p(ctx, dirty) { + if (dirty & /*things*/ 1 && t_value !== (t_value = /*thing*/ ctx[1].name + "")) set_data(t, t_value); }, r() { rect = div.getBoundingClientRect(); @@ -67,8 +67,8 @@ function create_fragment(ctx) { let each_blocks = []; let each_1_lookup = new Map(); let each_1_anchor; - let each_value = ctx.things; - const get_key = ctx => ctx.thing.id; + let each_value = /*things*/ ctx[0]; + const get_key = ctx => /*thing*/ ctx[1].id; for (let i = 0; i < each_value.length; i += 1) { let child_ctx = get_each_context(ctx, each_value, i); @@ -91,10 +91,10 @@ function create_fragment(ctx) { insert(target, each_1_anchor, anchor); }, - p(changed, ctx) { - const each_value = ctx.things; + p(ctx, [dirty]) { + const each_value = /*things*/ ctx[0]; for (let i = 0; i < each_blocks.length; i += 1) each_blocks[i].r(); - each_blocks = update_keyed_each(each_blocks, changed, get_key, 1, ctx, each_value, each_1_lookup, each_1_anchor.parentNode, fix_and_destroy_block, create_each_block, each_1_anchor, get_each_context); + each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, each_1_anchor.parentNode, fix_and_destroy_block, create_each_block, each_1_anchor, get_each_context); for (let i = 0; i < each_blocks.length; i += 1) each_blocks[i].a(); }, i: noop, @@ -127,10 +127,10 @@ function instance($$self, $$props, $$invalidate) { let { things } = $$props; $$self.$set = $$props => { - if ("things" in $$props) $$invalidate("things", things = $$props.things); + if ("things" in $$props) $$invalidate(0, things = $$props.things); }; - return { things }; + return [things]; } class Component extends SvelteComponent { diff --git a/test/js/samples/each-block-keyed/expected.js b/test/js/samples/each-block-keyed/expected.js index beb5a613bc04..1cd9a31ecee3 100644 --- a/test/js/samples/each-block-keyed/expected.js +++ b/test/js/samples/each-block-keyed/expected.js @@ -16,15 +16,15 @@ import { } from "svelte/internal"; function get_each_context(ctx, list, i) { - const child_ctx = Object.create(ctx); - child_ctx.thing = list[i]; + const child_ctx = ctx.slice(); + child_ctx[1] = list[i]; return child_ctx; } // (5:0) {#each things as thing (thing.id)} function create_each_block(key_1, ctx) { let div; - let t_value = ctx.thing.name + ""; + let t_value = /*thing*/ ctx[1].name + ""; let t; return { @@ -39,8 +39,8 @@ function create_each_block(key_1, ctx) { insert(target, div, anchor); append(div, t); }, - p(changed, ctx) { - if (changed.things && t_value !== (t_value = ctx.thing.name + "")) set_data(t, t_value); + p(ctx, dirty) { + if (dirty & /*things*/ 1 && t_value !== (t_value = /*thing*/ ctx[1].name + "")) set_data(t, t_value); }, d(detaching) { if (detaching) detach(div); @@ -52,8 +52,8 @@ function create_fragment(ctx) { let each_blocks = []; let each_1_lookup = new Map(); let each_1_anchor; - let each_value = ctx.things; - const get_key = ctx => ctx.thing.id; + let each_value = /*things*/ ctx[0]; + const get_key = ctx => /*thing*/ ctx[1].id; for (let i = 0; i < each_value.length; i += 1) { let child_ctx = get_each_context(ctx, each_value, i); @@ -76,9 +76,9 @@ function create_fragment(ctx) { insert(target, each_1_anchor, anchor); }, - p(changed, ctx) { - const each_value = ctx.things; - each_blocks = update_keyed_each(each_blocks, changed, get_key, 1, ctx, each_value, each_1_lookup, each_1_anchor.parentNode, destroy_block, create_each_block, each_1_anchor, get_each_context); + p(ctx, [dirty]) { + const each_value = /*things*/ ctx[0]; + each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, each_1_anchor.parentNode, destroy_block, create_each_block, each_1_anchor, get_each_context); }, i: noop, o: noop, @@ -96,10 +96,10 @@ function instance($$self, $$props, $$invalidate) { let { things } = $$props; $$self.$set = $$props => { - if ("things" in $$props) $$invalidate("things", things = $$props.things); + if ("things" in $$props) $$invalidate(0, things = $$props.things); }; - return { things }; + return [things]; } class Component extends SvelteComponent { diff --git a/test/js/samples/empty-dom/expected.js b/test/js/samples/empty-dom/expected.js index bd5a9fb7ef24..d5c80be696b5 100644 --- a/test/js/samples/empty-dom/expected.js +++ b/test/js/samples/empty-dom/expected.js @@ -3,7 +3,7 @@ import { SvelteComponent, init, safe_not_equal } from "svelte/internal"; function instance($$self) { const a = 1 + 2; - return {}; + return []; } class Component extends SvelteComponent { diff --git a/test/js/samples/event-handler-dynamic/expected.js b/test/js/samples/event-handler-dynamic/expected.js index 515d7e36a9c4..34c33151bf2b 100644 --- a/test/js/samples/event-handler-dynamic/expected.js +++ b/test/js/samples/event-handler-dynamic/expected.js @@ -37,16 +37,16 @@ function create_fragment(ctx) { button1.textContent = "set handler 2"; t3 = space(); p1 = element("p"); - t4 = text(ctx.number); + t4 = text(/*number*/ ctx[1]); t5 = space(); button2 = element("button"); button2.textContent = "click"; dispose = [ - listen(button0, "click", ctx.updateHandler1), - listen(button1, "click", ctx.updateHandler2), + listen(button0, "click", /*updateHandler1*/ ctx[2]), + listen(button1, "click", /*updateHandler2*/ ctx[3]), listen(button2, "click", function () { - ctx.clickHandler.apply(this, arguments); + /*clickHandler*/ ctx[0].apply(this, arguments); }) ]; }, @@ -61,9 +61,9 @@ function create_fragment(ctx) { insert(target, t5, anchor); insert(target, button2, anchor); }, - p(changed, new_ctx) { + p(new_ctx, [dirty]) { ctx = new_ctx; - if (changed.number) set_data(t4, ctx.number); + if (dirty & /*number*/ 2) set_data(t4, /*number*/ ctx[1]); }, i: noop, o: noop, @@ -83,19 +83,14 @@ function instance($$self, $$props, $$invalidate) { let number = 0; function updateHandler1() { - $$invalidate("clickHandler", clickHandler = () => $$invalidate("number", number = 1)); + $$invalidate(0, clickHandler = () => $$invalidate(1, number = 1)); } function updateHandler2() { - $$invalidate("clickHandler", clickHandler = () => $$invalidate("number", number = 2)); + $$invalidate(0, clickHandler = () => $$invalidate(1, number = 2)); } - return { - clickHandler, - number, - updateHandler1, - updateHandler2 - }; + return [clickHandler, number, updateHandler1, updateHandler2]; } class Component extends SvelteComponent { diff --git a/test/js/samples/if-block-complex/expected.js b/test/js/samples/if-block-complex/expected.js index badae4a2c0ee..a8244de8b02d 100644 --- a/test/js/samples/if-block-complex/expected.js +++ b/test/js/samples/if-block-complex/expected.js @@ -29,7 +29,7 @@ function create_if_block(ctx) { } function create_fragment(ctx) { - let show_if = ctx.item.divider && ctx.item.divider.includes(1); + let show_if = /*item*/ ctx[0].divider && /*item*/ ctx[0].divider.includes(1); let if_block_anchor; let if_block = show_if && create_if_block(ctx); @@ -54,7 +54,7 @@ function create_fragment(ctx) { function instance($$self) { let item = { divider: [1] }; - return { item }; + return [item]; } class Component extends SvelteComponent { diff --git a/test/js/samples/if-block-no-update/expected.js b/test/js/samples/if-block-no-update/expected.js index b057041e8882..f225c221bfe3 100644 --- a/test/js/samples/if-block-no-update/expected.js +++ b/test/js/samples/if-block-no-update/expected.js @@ -48,12 +48,12 @@ function create_if_block(ctx) { function create_fragment(ctx) { let if_block_anchor; - function select_block_type(changed, ctx) { - if (ctx.foo) return create_if_block; + function select_block_type(ctx, dirty) { + if (/*foo*/ ctx[0]) return create_if_block; return create_else_block; } - let current_block_type = select_block_type(null, ctx); + let current_block_type = select_block_type(ctx, -1); let if_block = current_block_type(ctx); return { @@ -65,8 +65,8 @@ function create_fragment(ctx) { if_block.m(target, anchor); insert(target, if_block_anchor, anchor); }, - p(changed, ctx) { - if (current_block_type !== (current_block_type = select_block_type(changed, ctx))) { + p(ctx, [dirty]) { + if (current_block_type !== (current_block_type = select_block_type(ctx, dirty))) { if_block.d(1); if_block = current_block_type(ctx); @@ -89,10 +89,10 @@ function instance($$self, $$props, $$invalidate) { let { foo } = $$props; $$self.$set = $$props => { - if ("foo" in $$props) $$invalidate("foo", foo = $$props.foo); + if ("foo" in $$props) $$invalidate(0, foo = $$props.foo); }; - return { foo }; + return [foo]; } class Component extends SvelteComponent { diff --git a/test/js/samples/if-block-simple/expected.js b/test/js/samples/if-block-simple/expected.js index fd2185b86d60..b9fad863e2c0 100644 --- a/test/js/samples/if-block-simple/expected.js +++ b/test/js/samples/if-block-simple/expected.js @@ -29,7 +29,7 @@ function create_if_block(ctx) { function create_fragment(ctx) { let if_block_anchor; - let if_block = ctx.foo && create_if_block(ctx); + let if_block = /*foo*/ ctx[0] && create_if_block(ctx); return { c() { @@ -40,8 +40,8 @@ function create_fragment(ctx) { if (if_block) if_block.m(target, anchor); insert(target, if_block_anchor, anchor); }, - p(changed, ctx) { - if (ctx.foo) { + p(ctx, [dirty]) { + if (/*foo*/ ctx[0]) { if (!if_block) { if_block = create_if_block(ctx); if_block.c(); @@ -67,10 +67,10 @@ function instance($$self, $$props, $$invalidate) { let { foo } = $$props; $$self.$set = $$props => { - if ("foo" in $$props) $$invalidate("foo", foo = $$props.foo); + if ("foo" in $$props) $$invalidate(0, foo = $$props.foo); }; - return { foo }; + return [foo]; } class Component extends SvelteComponent { diff --git a/test/js/samples/inline-style-optimized-multiple/expected.js b/test/js/samples/inline-style-optimized-multiple/expected.js index 636a4f19bb55..84a38abd7bbe 100644 --- a/test/js/samples/inline-style-optimized-multiple/expected.js +++ b/test/js/samples/inline-style-optimized-multiple/expected.js @@ -16,19 +16,19 @@ function create_fragment(ctx) { return { c() { div = element("div"); - set_style(div, "color", ctx.color); - set_style(div, "transform", "translate(" + ctx.x + "px," + ctx.y + "px)"); + set_style(div, "color", /*color*/ ctx[0]); + set_style(div, "transform", "translate(" + /*x*/ ctx[1] + "px," + /*y*/ ctx[2] + "px)"); }, m(target, anchor) { insert(target, div, anchor); }, - p(changed, ctx) { - if (changed.color) { - set_style(div, "color", ctx.color); + p(ctx, [dirty]) { + if (dirty & /*color*/ 1) { + set_style(div, "color", /*color*/ ctx[0]); } - if (changed.x || changed.y) { - set_style(div, "transform", "translate(" + ctx.x + "px," + ctx.y + "px)"); + if (dirty & /*x, y*/ 6) { + set_style(div, "transform", "translate(" + /*x*/ ctx[1] + "px," + /*y*/ ctx[2] + "px)"); } }, i: noop, @@ -45,18 +45,18 @@ function instance($$self, $$props, $$invalidate) { let { y } = $$props; $$self.$set = $$props => { - if ("color" in $$props) $$invalidate("color", color = $$props.color); - if ("x" in $$props) $$invalidate("x", x = $$props.x); - if ("y" in $$props) $$invalidate("y", y = $$props.y); + if ("color" in $$props) $$invalidate(0, color = $$props.color); + if ("x" in $$props) $$invalidate(1, x = $$props.x); + if ("y" in $$props) $$invalidate(2, y = $$props.y); }; - return { color, x, y }; + return [color, x, y]; } class Component extends SvelteComponent { constructor(options) { super(); - init(this, options, instance, create_fragment, safe_not_equal, { color: 0, x: 0, y: 0 }); + init(this, options, instance, create_fragment, safe_not_equal, { color: 0, x: 1, y: 2 }); } } diff --git a/test/js/samples/inline-style-optimized-url/expected.js b/test/js/samples/inline-style-optimized-url/expected.js index 53a9434369b4..77870348a572 100644 --- a/test/js/samples/inline-style-optimized-url/expected.js +++ b/test/js/samples/inline-style-optimized-url/expected.js @@ -16,14 +16,14 @@ function create_fragment(ctx) { return { c() { div = element("div"); - set_style(div, "background", "url(data:image/png;base64," + ctx.data + ")"); + set_style(div, "background", "url(data:image/png;base64," + /*data*/ ctx[0] + ")"); }, m(target, anchor) { insert(target, div, anchor); }, - p(changed, ctx) { - if (changed.data) { - set_style(div, "background", "url(data:image/png;base64," + ctx.data + ")"); + p(ctx, [dirty]) { + if (dirty & /*data*/ 1) { + set_style(div, "background", "url(data:image/png;base64," + /*data*/ ctx[0] + ")"); } }, i: noop, @@ -38,10 +38,10 @@ function instance($$self, $$props, $$invalidate) { let { data } = $$props; $$self.$set = $$props => { - if ("data" in $$props) $$invalidate("data", data = $$props.data); + if ("data" in $$props) $$invalidate(0, data = $$props.data); }; - return { data }; + return [data]; } class Component extends SvelteComponent { diff --git a/test/js/samples/inline-style-optimized/expected.js b/test/js/samples/inline-style-optimized/expected.js index 95079a63fe34..5bef284f0946 100644 --- a/test/js/samples/inline-style-optimized/expected.js +++ b/test/js/samples/inline-style-optimized/expected.js @@ -16,14 +16,14 @@ function create_fragment(ctx) { return { c() { div = element("div"); - set_style(div, "color", ctx.color); + set_style(div, "color", /*color*/ ctx[0]); }, m(target, anchor) { insert(target, div, anchor); }, - p(changed, ctx) { - if (changed.color) { - set_style(div, "color", ctx.color); + p(ctx, [dirty]) { + if (dirty & /*color*/ 1) { + set_style(div, "color", /*color*/ ctx[0]); } }, i: noop, @@ -38,10 +38,10 @@ function instance($$self, $$props, $$invalidate) { let { color } = $$props; $$self.$set = $$props => { - if ("color" in $$props) $$invalidate("color", color = $$props.color); + if ("color" in $$props) $$invalidate(0, color = $$props.color); }; - return { color }; + return [color]; } class Component extends SvelteComponent { diff --git a/test/js/samples/inline-style-unoptimized/expected.js b/test/js/samples/inline-style-unoptimized/expected.js index 11eaddbdf74f..fdff685eade2 100644 --- a/test/js/samples/inline-style-unoptimized/expected.js +++ b/test/js/samples/inline-style-unoptimized/expected.js @@ -22,20 +22,20 @@ function create_fragment(ctx) { div0 = element("div"); t = space(); div1 = element("div"); - attr(div0, "style", ctx.style); - attr(div1, "style", div1_style_value = "" + (ctx.key + ": " + ctx.value)); + attr(div0, "style", /*style*/ ctx[0]); + attr(div1, "style", div1_style_value = "" + (/*key*/ ctx[1] + ": " + /*value*/ ctx[2])); }, m(target, anchor) { insert(target, div0, anchor); insert(target, t, anchor); insert(target, div1, anchor); }, - p(changed, ctx) { - if (changed.style) { - attr(div0, "style", ctx.style); + p(ctx, [dirty]) { + if (dirty & /*style*/ 1) { + attr(div0, "style", /*style*/ ctx[0]); } - if ((changed.key || changed.value) && div1_style_value !== (div1_style_value = "" + (ctx.key + ": " + ctx.value))) { + if (dirty & /*key, value*/ 6 && div1_style_value !== (div1_style_value = "" + (/*key*/ ctx[1] + ": " + /*value*/ ctx[2]))) { attr(div1, "style", div1_style_value); } }, @@ -55,18 +55,18 @@ function instance($$self, $$props, $$invalidate) { let { value } = $$props; $$self.$set = $$props => { - if ("style" in $$props) $$invalidate("style", style = $$props.style); - if ("key" in $$props) $$invalidate("key", key = $$props.key); - if ("value" in $$props) $$invalidate("value", value = $$props.value); + if ("style" in $$props) $$invalidate(0, style = $$props.style); + if ("key" in $$props) $$invalidate(1, key = $$props.key); + if ("value" in $$props) $$invalidate(2, value = $$props.value); }; - return { style, key, value }; + return [style, key, value]; } class Component extends SvelteComponent { constructor(options) { super(); - init(this, options, instance, create_fragment, safe_not_equal, { style: 0, key: 0, value: 0 }); + init(this, options, instance, create_fragment, safe_not_equal, { style: 0, key: 1, value: 2 }); } } diff --git a/test/js/samples/input-files/expected.js b/test/js/samples/input-files/expected.js index a190d6cf7228..c3e46f0c798a 100644 --- a/test/js/samples/input-files/expected.js +++ b/test/js/samples/input-files/expected.js @@ -20,7 +20,7 @@ function create_fragment(ctx) { input = element("input"); attr(input, "type", "file"); input.multiple = true; - dispose = listen(input, "change", ctx.input_change_handler); + dispose = listen(input, "change", /*input_change_handler*/ ctx[1]); }, m(target, anchor) { insert(target, input, anchor); @@ -40,14 +40,14 @@ function instance($$self, $$props, $$invalidate) { function input_change_handler() { files = this.files; - $$invalidate("files", files); + $$invalidate(0, files); } $$self.$set = $$props => { - if ("files" in $$props) $$invalidate("files", files = $$props.files); + if ("files" in $$props) $$invalidate(0, files = $$props.files); }; - return { files, input_change_handler }; + return [files, input_change_handler]; } class Component extends SvelteComponent { diff --git a/test/js/samples/input-no-initial-value/expected.js b/test/js/samples/input-no-initial-value/expected.js index 85bc9dfcefc0..8ff2b2798b74 100644 --- a/test/js/samples/input-no-initial-value/expected.js +++ b/test/js/samples/input-no-initial-value/expected.js @@ -33,20 +33,20 @@ function create_fragment(ctx) { input.required = true; dispose = [ - listen(input, "input", ctx.input_input_handler), - listen(form, "submit", ctx.handleSubmit) + listen(input, "input", /*input_input_handler*/ ctx[2]), + listen(form, "submit", /*handleSubmit*/ ctx[1]) ]; }, m(target, anchor) { insert(target, form, anchor); append(form, input); - set_input_value(input, ctx.test); + set_input_value(input, /*test*/ ctx[0]); append(form, t0); append(form, button); }, - p(changed, ctx) { - if (changed.test && input.value !== ctx.test) { - set_input_value(input, ctx.test); + p(ctx, [dirty]) { + if (dirty & /*test*/ 1 && input.value !== /*test*/ ctx[0]) { + set_input_value(input, /*test*/ ctx[0]); } }, i: noop, @@ -68,10 +68,10 @@ function instance($$self, $$props, $$invalidate) { function input_input_handler() { test = this.value; - $$invalidate("test", test); + $$invalidate(0, test); } - return { test, handleSubmit, input_input_handler }; + return [test, handleSubmit, input_input_handler]; } class Component extends SvelteComponent { diff --git a/test/js/samples/input-range/expected.js b/test/js/samples/input-range/expected.js index 2ea13df0380b..5a074d9754b3 100644 --- a/test/js/samples/input-range/expected.js +++ b/test/js/samples/input-range/expected.js @@ -24,17 +24,17 @@ function create_fragment(ctx) { attr(input, "type", "range"); dispose = [ - listen(input, "change", ctx.input_change_input_handler), - listen(input, "input", ctx.input_change_input_handler) + listen(input, "change", /*input_change_input_handler*/ ctx[1]), + listen(input, "input", /*input_change_input_handler*/ ctx[1]) ]; }, m(target, anchor) { insert(target, input, anchor); - set_input_value(input, ctx.value); + set_input_value(input, /*value*/ ctx[0]); }, - p(changed, ctx) { - if (changed.value) { - set_input_value(input, ctx.value); + p(ctx, [dirty]) { + if (dirty & /*value*/ 1) { + set_input_value(input, /*value*/ ctx[0]); } }, i: noop, @@ -51,14 +51,14 @@ function instance($$self, $$props, $$invalidate) { function input_change_input_handler() { value = to_number(this.value); - $$invalidate("value", value); + $$invalidate(0, value); } $$self.$set = $$props => { - if ("value" in $$props) $$invalidate("value", value = $$props.value); + if ("value" in $$props) $$invalidate(0, value = $$props.value); }; - return { value, input_change_input_handler }; + return [value, input_change_input_handler]; } class Component extends SvelteComponent { diff --git a/test/js/samples/input-without-blowback-guard/expected.js b/test/js/samples/input-without-blowback-guard/expected.js index eacdbece8362..344976ade602 100644 --- a/test/js/samples/input-without-blowback-guard/expected.js +++ b/test/js/samples/input-without-blowback-guard/expected.js @@ -19,15 +19,15 @@ function create_fragment(ctx) { c() { input = element("input"); attr(input, "type", "checkbox"); - dispose = listen(input, "change", ctx.input_change_handler); + dispose = listen(input, "change", /*input_change_handler*/ ctx[1]); }, m(target, anchor) { insert(target, input, anchor); - input.checked = ctx.foo; + input.checked = /*foo*/ ctx[0]; }, - p(changed, ctx) { - if (changed.foo) { - input.checked = ctx.foo; + p(ctx, [dirty]) { + if (dirty & /*foo*/ 1) { + input.checked = /*foo*/ ctx[0]; } }, i: noop, @@ -44,14 +44,14 @@ function instance($$self, $$props, $$invalidate) { function input_change_handler() { foo = this.checked; - $$invalidate("foo", foo); + $$invalidate(0, foo); } $$self.$set = $$props => { - if ("foo" in $$props) $$invalidate("foo", foo = $$props.foo); + if ("foo" in $$props) $$invalidate(0, foo = $$props.foo); }; - return { foo, input_change_handler }; + return [foo, input_change_handler]; } class Component extends SvelteComponent { diff --git a/test/js/samples/instrumentation-script-if-no-block/expected.js b/test/js/samples/instrumentation-script-if-no-block/expected.js index 4b0574b79dda..4127a6d7d693 100644 --- a/test/js/samples/instrumentation-script-if-no-block/expected.js +++ b/test/js/samples/instrumentation-script-if-no-block/expected.js @@ -29,8 +29,8 @@ function create_fragment(ctx) { t1 = space(); p = element("p"); t2 = text("x: "); - t3 = text(ctx.x); - dispose = listen(button, "click", ctx.foo); + t3 = text(/*x*/ ctx[0]); + dispose = listen(button, "click", /*foo*/ ctx[1]); }, m(target, anchor) { insert(target, button, anchor); @@ -39,8 +39,8 @@ function create_fragment(ctx) { append(p, t2); append(p, t3); }, - p(changed, ctx) { - if (changed.x) set_data(t3, ctx.x); + p(ctx, [dirty]) { + if (dirty & /*x*/ 1) set_data(t3, /*x*/ ctx[0]); }, i: noop, o: noop, @@ -57,10 +57,10 @@ function instance($$self, $$props, $$invalidate) { let x = 0; function foo() { - if (true) $$invalidate("x", x += 1); + if (true) $$invalidate(0, x += 1); } - return { x, foo }; + return [x, foo]; } class Component extends SvelteComponent { diff --git a/test/js/samples/instrumentation-script-x-equals-x/expected.js b/test/js/samples/instrumentation-script-x-equals-x/expected.js index 8a3fa9366a3b..0d4493baf3c0 100644 --- a/test/js/samples/instrumentation-script-x-equals-x/expected.js +++ b/test/js/samples/instrumentation-script-x-equals-x/expected.js @@ -19,7 +19,7 @@ function create_fragment(ctx) { let t1; let p; let t2; - let t3_value = ctx.things.length + ""; + let t3_value = /*things*/ ctx[0].length + ""; let t3; let dispose; @@ -31,7 +31,7 @@ function create_fragment(ctx) { p = element("p"); t2 = text("number of things: "); t3 = text(t3_value); - dispose = listen(button, "click", ctx.foo); + dispose = listen(button, "click", /*foo*/ ctx[1]); }, m(target, anchor) { insert(target, button, anchor); @@ -40,8 +40,8 @@ function create_fragment(ctx) { append(p, t2); append(p, t3); }, - p(changed, ctx) { - if (changed.things && t3_value !== (t3_value = ctx.things.length + "")) set_data(t3, t3_value); + p(ctx, [dirty]) { + if (dirty & /*things*/ 1 && t3_value !== (t3_value = /*things*/ ctx[0].length + "")) set_data(t3, t3_value); }, i: noop, o: noop, @@ -59,10 +59,10 @@ function instance($$self, $$props, $$invalidate) { function foo() { things.push(1); - $$invalidate("things", things); + $$invalidate(0, things); } - return { things, foo }; + return [things, foo]; } class Component extends SvelteComponent { diff --git a/test/js/samples/instrumentation-template-if-no-block/expected.js b/test/js/samples/instrumentation-template-if-no-block/expected.js index e2d8c4466f95..0bd627eb87b3 100644 --- a/test/js/samples/instrumentation-template-if-no-block/expected.js +++ b/test/js/samples/instrumentation-template-if-no-block/expected.js @@ -29,8 +29,8 @@ function create_fragment(ctx) { t1 = space(); p = element("p"); t2 = text("x: "); - t3 = text(ctx.x); - dispose = listen(button, "click", ctx.click_handler); + t3 = text(/*x*/ ctx[0]); + dispose = listen(button, "click", /*click_handler*/ ctx[1]); }, m(target, anchor) { insert(target, button, anchor); @@ -39,8 +39,8 @@ function create_fragment(ctx) { append(p, t2); append(p, t3); }, - p(changed, ctx) { - if (changed.x) set_data(t3, ctx.x); + p(ctx, [dirty]) { + if (dirty & /*x*/ 1) set_data(t3, /*x*/ ctx[0]); }, i: noop, o: noop, @@ -57,10 +57,10 @@ function instance($$self, $$props, $$invalidate) { let x = 0; const click_handler = () => { - if (true) $$invalidate("x", x += 1); + if (true) $$invalidate(0, x += 1); }; - return { x, click_handler }; + return [x, click_handler]; } class Component extends SvelteComponent { diff --git a/test/js/samples/instrumentation-template-x-equals-x/expected.js b/test/js/samples/instrumentation-template-x-equals-x/expected.js index eefda55f31d8..e049a6d39be8 100644 --- a/test/js/samples/instrumentation-template-x-equals-x/expected.js +++ b/test/js/samples/instrumentation-template-x-equals-x/expected.js @@ -19,7 +19,7 @@ function create_fragment(ctx) { let t1; let p; let t2; - let t3_value = ctx.things.length + ""; + let t3_value = /*things*/ ctx[0].length + ""; let t3; let dispose; @@ -31,7 +31,7 @@ function create_fragment(ctx) { p = element("p"); t2 = text("number of things: "); t3 = text(t3_value); - dispose = listen(button, "click", ctx.click_handler); + dispose = listen(button, "click", /*click_handler*/ ctx[1]); }, m(target, anchor) { insert(target, button, anchor); @@ -40,8 +40,8 @@ function create_fragment(ctx) { append(p, t2); append(p, t3); }, - p(changed, ctx) { - if (changed.things && t3_value !== (t3_value = ctx.things.length + "")) set_data(t3, t3_value); + p(ctx, [dirty]) { + if (dirty & /*things*/ 1 && t3_value !== (t3_value = /*things*/ ctx[0].length + "")) set_data(t3, t3_value); }, i: noop, o: noop, @@ -59,10 +59,10 @@ function instance($$self, $$props, $$invalidate) { const click_handler = () => { things.push(1); - $$invalidate("things", things); + $$invalidate(0, things); }; - return { things, click_handler }; + return [things, click_handler]; } class Component extends SvelteComponent { diff --git a/test/js/samples/loop-protect/expected.js b/test/js/samples/loop-protect/expected.js index 59d9a7e43b45..093cccf63c66 100644 --- a/test/js/samples/loop-protect/expected.js +++ b/test/js/samples/loop-protect/expected.js @@ -89,7 +89,7 @@ function instance($$self) { } while (true); } - return {}; + return []; } class Component extends SvelteComponentDev { diff --git a/test/js/samples/media-bindings/expected.js b/test/js/samples/media-bindings/expected.js index 0538f07055e4..bfb1b8911d39 100644 --- a/test/js/samples/media-bindings/expected.js +++ b/test/js/samples/media-bindings/expected.js @@ -29,59 +29,59 @@ function create_fragment(ctx) { audio_updating = true; } - ctx.audio_timeupdate_handler.call(audio); + /*audio_timeupdate_handler*/ ctx[10].call(audio); } return { c() { audio = element("audio"); - if (ctx.played === void 0 || ctx.currentTime === void 0 || ctx.ended === void 0) add_render_callback(audio_timeupdate_handler); - if (ctx.duration === void 0) add_render_callback(() => ctx.audio_durationchange_handler.call(audio)); - if (ctx.buffered === void 0) add_render_callback(() => ctx.audio_progress_handler.call(audio)); - if (ctx.buffered === void 0 || ctx.seekable === void 0) add_render_callback(() => ctx.audio_loadedmetadata_handler.call(audio)); - if (ctx.seeking === void 0) add_render_callback(() => ctx.audio_seeking_seeked_handler.call(audio)); - if (ctx.ended === void 0) add_render_callback(() => ctx.audio_ended_handler.call(audio)); + if (/*played*/ ctx[2] === void 0 || /*currentTime*/ ctx[3] === void 0 || /*ended*/ ctx[9] === void 0) add_render_callback(audio_timeupdate_handler); + if (/*duration*/ ctx[4] === void 0) add_render_callback(() => /*audio_durationchange_handler*/ ctx[11].call(audio)); + if (/*buffered*/ ctx[0] === void 0) add_render_callback(() => /*audio_progress_handler*/ ctx[13].call(audio)); + if (/*buffered*/ ctx[0] === void 0 || /*seekable*/ ctx[1] === void 0) add_render_callback(() => /*audio_loadedmetadata_handler*/ ctx[14].call(audio)); + if (/*seeking*/ ctx[8] === void 0) add_render_callback(() => /*audio_seeking_seeked_handler*/ ctx[17].call(audio)); + if (/*ended*/ ctx[9] === void 0) add_render_callback(() => /*audio_ended_handler*/ ctx[18].call(audio)); dispose = [ listen(audio, "timeupdate", audio_timeupdate_handler), - listen(audio, "durationchange", ctx.audio_durationchange_handler), - listen(audio, "play", ctx.audio_play_pause_handler), - listen(audio, "pause", ctx.audio_play_pause_handler), - listen(audio, "progress", ctx.audio_progress_handler), - listen(audio, "loadedmetadata", ctx.audio_loadedmetadata_handler), - listen(audio, "volumechange", ctx.audio_volumechange_handler), - listen(audio, "ratechange", ctx.audio_ratechange_handler), - listen(audio, "seeking", ctx.audio_seeking_seeked_handler), - listen(audio, "seeked", ctx.audio_seeking_seeked_handler), - listen(audio, "ended", ctx.audio_ended_handler) + listen(audio, "durationchange", /*audio_durationchange_handler*/ ctx[11]), + listen(audio, "play", /*audio_play_pause_handler*/ ctx[12]), + listen(audio, "pause", /*audio_play_pause_handler*/ ctx[12]), + listen(audio, "progress", /*audio_progress_handler*/ ctx[13]), + listen(audio, "loadedmetadata", /*audio_loadedmetadata_handler*/ ctx[14]), + listen(audio, "volumechange", /*audio_volumechange_handler*/ ctx[15]), + listen(audio, "ratechange", /*audio_ratechange_handler*/ ctx[16]), + listen(audio, "seeking", /*audio_seeking_seeked_handler*/ ctx[17]), + listen(audio, "seeked", /*audio_seeking_seeked_handler*/ ctx[17]), + listen(audio, "ended", /*audio_ended_handler*/ ctx[18]) ]; }, m(target, anchor) { insert(target, audio, anchor); - if (!isNaN(ctx.volume)) { - audio.volume = ctx.volume; + if (!isNaN(/*volume*/ ctx[6])) { + audio.volume = /*volume*/ ctx[6]; } - if (!isNaN(ctx.playbackRate)) { - audio.playbackRate = ctx.playbackRate; + if (!isNaN(/*playbackRate*/ ctx[7])) { + audio.playbackRate = /*playbackRate*/ ctx[7]; } }, - p(changed, ctx) { - if (!audio_updating && changed.currentTime && !isNaN(ctx.currentTime)) { - audio.currentTime = ctx.currentTime; + p(ctx, [dirty]) { + if (!audio_updating && dirty & /*currentTime*/ 8 && !isNaN(/*currentTime*/ ctx[3])) { + audio.currentTime = /*currentTime*/ ctx[3]; } - if (changed.paused && audio_is_paused !== (audio_is_paused = ctx.paused)) { + if (dirty & /*paused*/ 32 && audio_is_paused !== (audio_is_paused = /*paused*/ ctx[5])) { audio[audio_is_paused ? "pause" : "play"](); } - if (changed.volume && !isNaN(ctx.volume)) { - audio.volume = ctx.volume; + if (dirty & /*volume*/ 64 && !isNaN(/*volume*/ ctx[6])) { + audio.volume = /*volume*/ ctx[6]; } - if (changed.playbackRate && !isNaN(ctx.playbackRate)) { - audio.playbackRate = ctx.playbackRate; + if (dirty & /*playbackRate*/ 128 && !isNaN(/*playbackRate*/ ctx[7])) { + audio.playbackRate = /*playbackRate*/ ctx[7]; } audio_updating = false; @@ -111,67 +111,67 @@ function instance($$self, $$props, $$invalidate) { played = time_ranges_to_array(this.played); currentTime = this.currentTime; ended = this.ended; - $$invalidate("played", played); - $$invalidate("currentTime", currentTime); - $$invalidate("ended", ended); + $$invalidate(2, played); + $$invalidate(3, currentTime); + $$invalidate(9, ended); } function audio_durationchange_handler() { duration = this.duration; - $$invalidate("duration", duration); + $$invalidate(4, duration); } function audio_play_pause_handler() { paused = this.paused; - $$invalidate("paused", paused); + $$invalidate(5, paused); } function audio_progress_handler() { buffered = time_ranges_to_array(this.buffered); - $$invalidate("buffered", buffered); + $$invalidate(0, buffered); } function audio_loadedmetadata_handler() { buffered = time_ranges_to_array(this.buffered); seekable = time_ranges_to_array(this.seekable); - $$invalidate("buffered", buffered); - $$invalidate("seekable", seekable); + $$invalidate(0, buffered); + $$invalidate(1, seekable); } function audio_volumechange_handler() { volume = this.volume; - $$invalidate("volume", volume); + $$invalidate(6, volume); } function audio_ratechange_handler() { playbackRate = this.playbackRate; - $$invalidate("playbackRate", playbackRate); + $$invalidate(7, playbackRate); } function audio_seeking_seeked_handler() { seeking = this.seeking; - $$invalidate("seeking", seeking); + $$invalidate(8, seeking); } function audio_ended_handler() { ended = this.ended; - $$invalidate("ended", ended); + $$invalidate(9, ended); } $$self.$set = $$props => { - if ("buffered" in $$props) $$invalidate("buffered", buffered = $$props.buffered); - if ("seekable" in $$props) $$invalidate("seekable", seekable = $$props.seekable); - if ("played" in $$props) $$invalidate("played", played = $$props.played); - if ("currentTime" in $$props) $$invalidate("currentTime", currentTime = $$props.currentTime); - if ("duration" in $$props) $$invalidate("duration", duration = $$props.duration); - if ("paused" in $$props) $$invalidate("paused", paused = $$props.paused); - if ("volume" in $$props) $$invalidate("volume", volume = $$props.volume); - if ("playbackRate" in $$props) $$invalidate("playbackRate", playbackRate = $$props.playbackRate); - if ("seeking" in $$props) $$invalidate("seeking", seeking = $$props.seeking); - if ("ended" in $$props) $$invalidate("ended", ended = $$props.ended); + if ("buffered" in $$props) $$invalidate(0, buffered = $$props.buffered); + if ("seekable" in $$props) $$invalidate(1, seekable = $$props.seekable); + if ("played" in $$props) $$invalidate(2, played = $$props.played); + if ("currentTime" in $$props) $$invalidate(3, currentTime = $$props.currentTime); + if ("duration" in $$props) $$invalidate(4, duration = $$props.duration); + if ("paused" in $$props) $$invalidate(5, paused = $$props.paused); + if ("volume" in $$props) $$invalidate(6, volume = $$props.volume); + if ("playbackRate" in $$props) $$invalidate(7, playbackRate = $$props.playbackRate); + if ("seeking" in $$props) $$invalidate(8, seeking = $$props.seeking); + if ("ended" in $$props) $$invalidate(9, ended = $$props.ended); }; - return { + return [ buffered, seekable, played, @@ -191,7 +191,7 @@ function instance($$self, $$props, $$invalidate) { audio_ratechange_handler, audio_seeking_seeked_handler, audio_ended_handler - }; + ]; } class Component extends SvelteComponent { @@ -200,15 +200,15 @@ class Component extends SvelteComponent { init(this, options, instance, create_fragment, safe_not_equal, { buffered: 0, - seekable: 0, - played: 0, - currentTime: 0, - duration: 0, - paused: 0, - volume: 0, - playbackRate: 0, - seeking: 0, - ended: 0 + seekable: 1, + played: 2, + currentTime: 3, + duration: 4, + paused: 5, + volume: 6, + playbackRate: 7, + seeking: 8, + ended: 9 }); } } diff --git a/test/js/samples/reactive-values-non-topologically-ordered/expected.js b/test/js/samples/reactive-values-non-topologically-ordered/expected.js index 3d1b6aaae3f7..3d266f10acfb 100644 --- a/test/js/samples/reactive-values-non-topologically-ordered/expected.js +++ b/test/js/samples/reactive-values-non-topologically-ordered/expected.js @@ -7,20 +7,20 @@ function instance($$self, $$props, $$invalidate) { let b; $$self.$set = $$props => { - if ("x" in $$props) $$invalidate("x", x = $$props.x); + if ("x" in $$props) $$invalidate(0, x = $$props.x); }; - $$self.$$.update = (changed = { x: 1, b: 1 }) => { - if (changed.x) { - $: $$invalidate("b", b = x); + $$self.$$.update = () => { + if ($$self.$$.dirty & /*x*/ 1) { + $: $$invalidate(2, b = x); } - if (changed.b) { + if ($$self.$$.dirty & /*b*/ 4) { $: a = b; } }; - return { x }; + return [x]; } class Component extends SvelteComponent { diff --git a/test/js/samples/reactive-values-non-writable-dependencies/expected.js b/test/js/samples/reactive-values-non-writable-dependencies/expected.js index 393af95df027..38bd356d85e4 100644 --- a/test/js/samples/reactive-values-non-writable-dependencies/expected.js +++ b/test/js/samples/reactive-values-non-writable-dependencies/expected.js @@ -6,23 +6,23 @@ function instance($$self, $$props, $$invalidate) { let { b = 2 } = $$props; $$self.$set = $$props => { - if ("a" in $$props) $$invalidate("a", a = $$props.a); - if ("b" in $$props) $$invalidate("b", b = $$props.b); + if ("a" in $$props) $$invalidate(0, a = $$props.a); + if ("b" in $$props) $$invalidate(1, b = $$props.b); }; - $$self.$$.update = (changed = { a: 1, b: 1 }) => { - if (changed.a || changed.b) { + $$self.$$.update = () => { + if ($$self.$$.dirty & /*a, b*/ 3) { $: console.log("max", Math.max(a, b)); } }; - return { a, b }; + return [a, b]; } class Component extends SvelteComponent { constructor(options) { super(); - init(this, options, instance, null, safe_not_equal, { a: 0, b: 0 }); + init(this, options, instance, null, safe_not_equal, { a: 0, b: 1 }); } } diff --git a/test/js/samples/select-dynamic-value/expected.js b/test/js/samples/select-dynamic-value/expected.js index da284d977a4a..a93a47bd3ac4 100644 --- a/test/js/samples/select-dynamic-value/expected.js +++ b/test/js/samples/select-dynamic-value/expected.js @@ -32,7 +32,7 @@ function create_fragment(ctx) { insert(target, select, anchor); append(select, option0); append(select, option1); - select_value_value = ctx.current; + select_value_value = /*current*/ ctx[0]; for (var i = 0; i < select.options.length; i += 1) { var option = select.options[i]; @@ -43,8 +43,8 @@ function create_fragment(ctx) { } } }, - p(changed, ctx) { - if (changed.current && select_value_value !== (select_value_value = ctx.current)) { + p(ctx, [dirty]) { + if (dirty & /*current*/ 1 && select_value_value !== (select_value_value = /*current*/ ctx[0])) { for (var i = 0; i < select.options.length; i += 1) { var option = select.options[i]; @@ -67,10 +67,10 @@ function instance($$self, $$props, $$invalidate) { let { current } = $$props; $$self.$set = $$props => { - if ("current" in $$props) $$invalidate("current", current = $$props.current); + if ("current" in $$props) $$invalidate(0, current = $$props.current); }; - return { current }; + return [current]; } class Component extends SvelteComponent { diff --git a/test/js/samples/setup-method/expected.js b/test/js/samples/setup-method/expected.js index 5ee43a9f1f16..8e30a03a7dd4 100644 --- a/test/js/samples/setup-method/expected.js +++ b/test/js/samples/setup-method/expected.js @@ -7,10 +7,14 @@ function foo(bar) { console.log(bar); } +function instance($$self, $$props, $$invalidate) { + return [foo]; +} + class Component extends SvelteComponent { constructor(options) { super(); - init(this, options, null, null, safe_not_equal, { foo: 0 }); + init(this, options, instance, null, safe_not_equal, { foo: 0 }); } get foo() { diff --git a/test/js/samples/src-attribute-check/expected.js b/test/js/samples/src-attribute-check/expected.js index 8af33a962bc0..e03b3a6ba7ee 100644 --- a/test/js/samples/src-attribute-check/expected.js +++ b/test/js/samples/src-attribute-check/expected.js @@ -35,21 +35,21 @@ function create_fragment(ctx) { }, h() { attr(img0, "alt", "potato"); - if (img0.src !== (img0_src_value = ctx.url)) attr(img0, "src", img0_src_value); + if (img0.src !== (img0_src_value = /*url*/ ctx[0])) attr(img0, "src", img0_src_value); attr(img1, "alt", "potato"); - if (img1.src !== (img1_src_value = "" + (ctx.slug + ".jpg"))) attr(img1, "src", img1_src_value); + if (img1.src !== (img1_src_value = "" + (/*slug*/ ctx[1] + ".jpg"))) attr(img1, "src", img1_src_value); }, m(target, anchor) { insert(target, img0, anchor); insert(target, t, anchor); insert(target, img1, anchor); }, - p(changed, ctx) { - if (changed.url && img0.src !== (img0_src_value = ctx.url)) { + p(ctx, [dirty]) { + if (dirty & /*url*/ 1 && img0.src !== (img0_src_value = /*url*/ ctx[0])) { attr(img0, "src", img0_src_value); } - if (changed.slug && img1.src !== (img1_src_value = "" + (ctx.slug + ".jpg"))) { + if (dirty & /*slug*/ 2 && img1.src !== (img1_src_value = "" + (/*slug*/ ctx[1] + ".jpg"))) { attr(img1, "src", img1_src_value); } }, @@ -68,17 +68,17 @@ function instance($$self, $$props, $$invalidate) { let { slug } = $$props; $$self.$set = $$props => { - if ("url" in $$props) $$invalidate("url", url = $$props.url); - if ("slug" in $$props) $$invalidate("slug", slug = $$props.slug); + if ("url" in $$props) $$invalidate(0, url = $$props.url); + if ("slug" in $$props) $$invalidate(1, slug = $$props.slug); }; - return { url, slug }; + return [url, slug]; } class Component extends SvelteComponent { constructor(options) { super(); - init(this, options, instance, create_fragment, safe_not_equal, { url: 0, slug: 0 }); + init(this, options, instance, create_fragment, safe_not_equal, { url: 0, slug: 1 }); } } diff --git a/test/js/samples/title/expected.js b/test/js/samples/title/expected.js index 205f35295048..d4e7e1a58491 100644 --- a/test/js/samples/title/expected.js +++ b/test/js/samples/title/expected.js @@ -3,13 +3,13 @@ import { SvelteComponent, init, noop, safe_not_equal } from "svelte/internal"; function create_fragment(ctx) { let title_value; - document.title = title_value = "a " + ctx.custom + " title"; + document.title = title_value = "a " + /*custom*/ ctx[0] + " title"; return { c: noop, m: noop, - p(changed, ctx) { - if (changed.custom && title_value !== (title_value = "a " + ctx.custom + " title")) { + p(ctx, [dirty]) { + if (dirty & /*custom*/ 1 && title_value !== (title_value = "a " + /*custom*/ ctx[0] + " title")) { document.title = title_value; } }, @@ -23,10 +23,10 @@ function instance($$self, $$props, $$invalidate) { let { custom } = $$props; $$self.$set = $$props => { - if ("custom" in $$props) $$invalidate("custom", custom = $$props.custom); + if ("custom" in $$props) $$invalidate(0, custom = $$props.custom); }; - return { custom }; + return [custom]; } class Component extends SvelteComponent { diff --git a/test/js/samples/transition-local/expected.js b/test/js/samples/transition-local/expected.js index 7fa88f4254f8..a5d3b6318fe5 100644 --- a/test/js/samples/transition-local/expected.js +++ b/test/js/samples/transition-local/expected.js @@ -15,7 +15,7 @@ import { function create_if_block(ctx) { let if_block_anchor; - let if_block = ctx.y && create_if_block_1(ctx); + let if_block = /*y*/ ctx[1] && create_if_block_1(ctx); return { c() { @@ -26,8 +26,8 @@ function create_if_block(ctx) { if (if_block) if_block.m(target, anchor); insert(target, if_block_anchor, anchor); }, - p(changed, ctx) { - if (ctx.y) { + p(ctx, dirty) { + if (/*y*/ ctx[1]) { if (!if_block) { if_block = create_if_block_1(ctx); if_block.c(); @@ -80,7 +80,7 @@ function create_if_block_1(ctx) { function create_fragment(ctx) { let if_block_anchor; - let if_block = ctx.x && create_if_block(ctx); + let if_block = /*x*/ ctx[0] && create_if_block(ctx); return { c() { @@ -91,10 +91,10 @@ function create_fragment(ctx) { if (if_block) if_block.m(target, anchor); insert(target, if_block_anchor, anchor); }, - p(changed, ctx) { - if (ctx.x) { + p(ctx, [dirty]) { + if (/*x*/ ctx[0]) { if (if_block) { - if_block.p(changed, ctx); + if_block.p(ctx, dirty); } else { if_block = create_if_block(ctx); if_block.c(); @@ -123,17 +123,17 @@ function instance($$self, $$props, $$invalidate) { let { y } = $$props; $$self.$set = $$props => { - if ("x" in $$props) $$invalidate("x", x = $$props.x); - if ("y" in $$props) $$invalidate("y", y = $$props.y); + if ("x" in $$props) $$invalidate(0, x = $$props.x); + if ("y" in $$props) $$invalidate(1, y = $$props.y); }; - return { x, y }; + return [x, y]; } class Component extends SvelteComponent { constructor(options) { super(); - init(this, options, instance, create_fragment, safe_not_equal, { x: 0, y: 0 }); + init(this, options, instance, create_fragment, safe_not_equal, { x: 0, y: 1 }); } } diff --git a/test/js/samples/transition-repeated-outro/expected.js b/test/js/samples/transition-repeated-outro/expected.js index c40818dc4e6c..6f071328a491 100644 --- a/test/js/samples/transition-repeated-outro/expected.js +++ b/test/js/samples/transition-repeated-outro/expected.js @@ -49,7 +49,7 @@ function create_if_block(ctx) { function create_fragment(ctx) { let if_block_anchor; let current; - let if_block = ctx.num < 5 && create_if_block(ctx); + let if_block = /*num*/ ctx[0] < 5 && create_if_block(ctx); return { c() { @@ -61,8 +61,8 @@ function create_fragment(ctx) { insert(target, if_block_anchor, anchor); current = true; }, - p(changed, ctx) { - if (ctx.num < 5) { + p(ctx, [dirty]) { + if (/*num*/ ctx[0] < 5) { if (!if_block) { if_block = create_if_block(ctx); if_block.c(); @@ -101,10 +101,10 @@ function instance($$self, $$props, $$invalidate) { let { num = 1 } = $$props; $$self.$set = $$props => { - if ("num" in $$props) $$invalidate("num", num = $$props.num); + if ("num" in $$props) $$invalidate(0, num = $$props.num); }; - return { num }; + return [num]; } class Component extends SvelteComponent { diff --git a/test/js/samples/unchanged-expression/expected.js b/test/js/samples/unchanged-expression/expected.js index 231960bb49a3..673d5b6abc8d 100644 --- a/test/js/samples/unchanged-expression/expected.js +++ b/test/js/samples/unchanged-expression/expected.js @@ -41,7 +41,7 @@ function create_fragment(ctx) { div1 = element("div"); p3 = element("p"); t8 = text("Hello "); - t9 = text(ctx.world3); + t9 = text(/*world3*/ ctx[0]); }, m(target, anchor) { insert(target, div0, anchor); @@ -56,8 +56,8 @@ function create_fragment(ctx) { append(p3, t8); append(p3, t9); }, - p(changed, ctx) { - if (changed.world3) set_data(t9, ctx.world3); + p(ctx, [dirty]) { + if (dirty & /*world3*/ 1) set_data(t9, /*world3*/ ctx[0]); }, i: noop, o: noop, @@ -76,10 +76,10 @@ function instance($$self, $$props, $$invalidate) { const world3 = "world"; function foo() { - $$invalidate("world3", world3 = "svelte"); + $$invalidate(0, world3 = "svelte"); } - return { world3 }; + return [world3]; } class Component extends SvelteComponent { diff --git a/test/js/samples/unreferenced-state-not-invalidated/expected.js b/test/js/samples/unreferenced-state-not-invalidated/expected.js index f0409c3cca6e..b10ea815b966 100644 --- a/test/js/samples/unreferenced-state-not-invalidated/expected.js +++ b/test/js/samples/unreferenced-state-not-invalidated/expected.js @@ -21,14 +21,14 @@ function create_fragment(ctx) { return { c() { p = element("p"); - t = text(ctx.y); + t = text(/*y*/ ctx[0]); }, m(target, anchor) { insert(target, p, anchor); append(p, t); }, - p(changed, ctx) { - if (changed.y) set_data(t, ctx.y); + p(ctx, [dirty]) { + if (dirty & /*y*/ 1) set_data(t, /*y*/ ctx[0]); }, i: noop, o: noop, @@ -39,12 +39,12 @@ function create_fragment(ctx) { } function instance($$self, $$props, $$invalidate) { - let a, b, c; + let a = 1, b = 2, c = 3; onMount(() => { const interval = setInterval( () => { - $$invalidate("b", b += 1); + $$invalidate(1, b += 1); c += 1; console.log(b, c); }, @@ -57,17 +57,14 @@ function instance($$self, $$props, $$invalidate) { let x; let y; - $$self.$$.update = (changed = { a: 1, b: 1 }) => { - if (changed.a) { - $: x = a * 2; - } - - if (changed.b) { - $: $$invalidate("y", y = b * 2); + $$self.$$.update = () => { + if ($$self.$$.dirty & /*b*/ 2) { + $: $$invalidate(0, y = b * 2); } }; - return { y }; + $: x = a * 2; + return [y]; } class Component extends SvelteComponent { diff --git a/test/js/samples/unreferenced-state-not-invalidated/input.svelte b/test/js/samples/unreferenced-state-not-invalidated/input.svelte index fff60f181d4c..a453f9a23e27 100644 --- a/test/js/samples/unreferenced-state-not-invalidated/input.svelte +++ b/test/js/samples/unreferenced-state-not-invalidated/input.svelte @@ -1,7 +1,7 @@ diff --git a/test/runtime/samples/binding-input-text-contextual-deconflicted/_config.js b/test/runtime/samples/binding-input-text-contextual-deconflicted/_config.js index 37af5080b906..28cffdfa5772 100644 --- a/test/runtime/samples/binding-input-text-contextual-deconflicted/_config.js +++ b/test/runtime/samples/binding-input-text-contextual-deconflicted/_config.js @@ -16,7 +16,6 @@ export default { async test({ assert, component, target, window }) { const inputs = [...target.querySelectorAll('input')]; - const items = component.items; const event = new window.Event('input'); assert.equal(inputs[0].value, 'a'); diff --git a/test/runtime/samples/bitmask-overflow/_config.js b/test/runtime/samples/bitmask-overflow/_config.js new file mode 100644 index 000000000000..ada3195c8134 --- /dev/null +++ b/test/runtime/samples/bitmask-overflow/_config.js @@ -0,0 +1,122 @@ +export default { + html: ` +

0

+

1

+

2

+

3

+

4

+

5

+

6

+

7

+

8

+

9

+

10

+

11

+

12

+

13

+

14

+

15

+

16

+

17

+

18

+

19

+

20

+

21

+

22

+

23

+

24

+

25

+

26

+

27

+

28

+

29

+

30

+

31

+

32

+

33

+

34

+

35

+

36

+

37

+

38

+

39

+

40

+

5:36

+

6:37

+

38

+ `, + + test({ assert, component, target }) { + component.reads = {}; + + component._0 = 'a'; + component._30 = 'b'; + component._31 = 'c'; + component._32 = 'd'; + component._40 = 'e'; + + component._5 = 'f'; + component._6 = 'g'; + component._36 = 'h'; + component._37 = 'i'; + + assert.htmlEqual(target.innerHTML, ` +

a

+

1

+

2

+

3

+

4

+

f

+

g

+

7

+

8

+

9

+

10

+

11

+

12

+

13

+

14

+

15

+

16

+

17

+

18

+

19

+

20

+

21

+

22

+

23

+

24

+

25

+

26

+

27

+

28

+

29

+

b

+

c

+

d

+

33

+

34

+

35

+

h

+

i

+

38

+

39

+

e

+

f:h

+

g:i

+

38

+ `); + + assert.deepEqual(component.reads, { + _0: 1, + _5: 3, + _6: 3, + _30: 1, + _31: 1, + _32: 1, + _36: 3, + _37: 3, + _40: 1 + }); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/bitmask-overflow/main.svelte b/test/runtime/samples/bitmask-overflow/main.svelte new file mode 100644 index 000000000000..32eb8802daab --- /dev/null +++ b/test/runtime/samples/bitmask-overflow/main.svelte @@ -0,0 +1,101 @@ + + +

{read(_0, '_0')}

+

{read(_1, '_1')}

+

{read(_2, '_2')}

+

{read(_3, '_3')}

+

{read(_4, '_4')}

+

{read(_5, '_5')}

+

{read(_6, '_6')}

+

{read(_7, '_7')}

+

{read(_8, '_8')}

+

{read(_9, '_9')}

+

{read(_10, '_10')}

+

{read(_11, '_11')}

+

{read(_12, '_12')}

+

{read(_13, '_13')}

+

{read(_14, '_14')}

+

{read(_15, '_15')}

+

{read(_16, '_16')}

+

{read(_17, '_17')}

+

{read(_18, '_18')}

+

{read(_19, '_19')}

+

{read(_20, '_20')}

+

{read(_21, '_21')}

+

{read(_22, '_22')}

+

{read(_23, '_23')}

+

{read(_24, '_24')}

+

{read(_25, '_25')}

+

{read(_26, '_26')}

+

{read(_27, '_27')}

+

{read(_28, '_28')}

+

{read(_29, '_29')}

+

{read(_30, '_30')}

+

{read(_31, '_31')}

+

{read(_32, '_32')}

+

{read(_33, '_33')}

+

{read(_34, '_34')}

+

{read(_35, '_35')}

+

{read(_36, '_36')}

+

{read(_37, '_37')}

+

{read(_38, '_38')}

+

{read(_39, '_39')}

+

{read(_40, '_40')}

+ +

{read(_5, '_5') + ':' + read(_36, '_36')}

+

{foo}

+

{bar}

\ No newline at end of file diff --git a/test/runtime/samples/each-block-scope-shadow/_config.js b/test/runtime/samples/each-block-scope-shadow/_config.js index 8005bc93d5b7..dff254a7c488 100644 --- a/test/runtime/samples/each-block-scope-shadow/_config.js +++ b/test/runtime/samples/each-block-scope-shadow/_config.js @@ -1,3 +1,3 @@ export default { - html: '(alpaca)(baboon)(capybara)' + html: '(alpaca)(baboon)(capybara) (lemur)' }; diff --git a/test/runtime/samples/each-block-scope-shadow/main.svelte b/test/runtime/samples/each-block-scope-shadow/main.svelte index b6c256e14f00..58294d35b43b 100644 --- a/test/runtime/samples/each-block-scope-shadow/main.svelte +++ b/test/runtime/samples/each-block-scope-shadow/main.svelte @@ -2,7 +2,9 @@ ({animal}) {/each} +({animal}) + \ No newline at end of file diff --git a/test/sourcemaps/samples/basic/test.js b/test/sourcemaps/samples/basic/test.js index f2ce4198fdb3..705976167461 100644 --- a/test/sourcemaps/samples/basic/test.js +++ b/test/sourcemaps/samples/basic/test.js @@ -1,31 +1,31 @@ export function test({ assert, smc, locateInSource, locateInGenerated }) { - const expected = locateInSource( 'foo.bar.baz' ); + const expected = locateInSource('foo.bar.baz'); let start; let actual; - start = locateInGenerated('foo.bar.baz'); + start = locateInGenerated('ctx[0].bar.baz'); actual = smc.originalPositionFor({ line: start.line + 1, column: start.column }); - assert.deepEqual( actual, { + assert.deepEqual(actual, { source: 'input.svelte', name: null, line: expected.line + 1, column: expected.column }); - start = locateInGenerated( 'foo.bar.baz', start.character + 1 ); + start = locateInGenerated('ctx[0].bar.baz', start.character + 1); actual = smc.originalPositionFor({ line: start.line + 1, column: start.column }); - assert.deepEqual( actual, { + assert.deepEqual(actual, { source: 'input.svelte', name: null, line: expected.line + 1, diff --git a/test/vars/samples/store-referenced/_config.js b/test/vars/samples/store-referenced/_config.js index bac35d1dbabf..cb92b67ea473 100644 --- a/test/vars/samples/store-referenced/_config.js +++ b/test/vars/samples/store-referenced/_config.js @@ -8,7 +8,7 @@ export default { module: false, mutated: false, reassigned: false, - referenced: true, + referenced: false, referenced_from_script: false, writable: true },