From af1057b4a3e0db7e62e0afb692fb4c62bdbe3ac2 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 12 Sep 2019 12:53:31 -0400 Subject: [PATCH] various --- package-lock.json | 10 +- src/compiler/compile/Component.ts | 16 +-- src/compiler/compile/create_module.ts | 3 +- src/compiler/compile/nodes/Binding.ts | 5 +- src/compiler/compile/nodes/EventHandler.ts | 8 +- src/compiler/compile/render_dom/Block.ts | 4 +- src/compiler/compile/render_dom/index.ts | 105 +++++++++++------- .../compile/render_dom/wrappers/DebugTag.ts | 4 +- .../render_dom/wrappers/Element/Binding.ts | 4 +- .../render_dom/wrappers/Element/index.ts | 8 +- .../wrappers/InlineComponent/index.ts | 16 +-- .../compile/render_dom/wrappers/Slot.ts | 8 +- .../compile/render_dom/wrappers/Window.ts | 31 +++--- .../wrappers/shared/add_event_handlers.ts | 49 ++++---- .../render_dom/wrappers/shared/bind_this.ts | 18 +-- .../compile/render_ssr/handlers/Element.ts | 2 +- src/compiler/compile/utils/invalidate.ts | 5 +- src/runtime/internal/Component.ts | 1 - test/runtime/samples/action-this/main.svelte | 2 +- test/runtime/samples/action-update/_config.js | 2 +- 20 files changed, 167 insertions(+), 134 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5e7b60bdc7..827178a325 100644 --- a/package-lock.json +++ b/package-lock.json @@ -330,11 +330,6 @@ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true }, - "astring": { - "version": "github:Rich-Harris/astring#ff83f5e4e75b304cdd428ada4a71372276b0084d", - "from": "github:Rich-Harris/astring#generic-handler", - "dev": true - }, "async-limiter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", @@ -513,13 +508,16 @@ "dev": true, "requires": { "acorn": "^7.0.0", - "astring": "github:Rich-Harris/astring#ff83f5e4e75b304cdd428ada4a71372276b0084d", "estree-walker": "^0.6.1", "is-reference": "^1.1.3", "periscopic": "^1.0.0", "source-map": "^0.7.3" }, "dependencies": { + "astring": { + "version": "github:Rich-Harris/astring#ff83f5e4e75b304cdd428ada4a71372276b0084d", + "from": "github:Rich-Harris/astring#ff83f5e4e75b304cdd428ada4a71372276b0084d" + }, "estree-walker": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts index 7f61df306a..7711fd2684 100644 --- a/src/compiler/compile/Component.ts +++ b/src/compiler/compile/Component.ts @@ -912,11 +912,13 @@ export default class Component { computed: false, kind: 'init', key: declarator.id, - value: { - type: 'AssignmentPattern', - left: declarator.id, - right: declarator.init - } + value: declarator.init + ? { + type: 'AssignmentPattern', + left: declarator.id, + right: declarator.init + } + : declarator.id }] }; @@ -1228,7 +1230,7 @@ export default class Component { } qualify(name) { - if (name === `$$props`) return `#ctx.$$props`; + if (name === `$$props`) return x`#ctx.$$props`; const variable = this.var_lookup.get(name); @@ -1238,7 +1240,7 @@ export default class Component { if (variable.hoistable) return name; - return `#ctx.${name}`; + return x`#ctx.${name}`; } warn_if_undefined(name: string, node, template_scope: TemplateScope) { diff --git a/src/compiler/compile/create_module.ts b/src/compiler/compile/create_module.ts index 73ab84bdc1..0a70b42f2d 100644 --- a/src/compiler/compile/create_module.ts +++ b/src/compiler/compile/create_module.ts @@ -173,7 +173,8 @@ function cjs( shorthand: false, computed: false, key: s.imported || { type: 'Identifier', name: 'default' }, - value: s.local + value: s.local, + kind: 'init' })) }, init: x`require("${edit_source(node.source.value, sveltePath)}")` diff --git a/src/compiler/compile/nodes/Binding.ts b/src/compiler/compile/nodes/Binding.ts index 949b0c657c..29992f940f 100644 --- a/src/compiler/compile/nodes/Binding.ts +++ b/src/compiler/compile/nodes/Binding.ts @@ -4,6 +4,7 @@ import Expression from './shared/Expression'; import Component from '../Component'; import TemplateScope from './shared/TemplateScope'; import {dimensions} from "../../utils/patterns"; +import { x } from 'code-red'; // TODO this should live in a specific binding const read_only_media_attributes = new Set([ @@ -68,8 +69,8 @@ export default class Binding extends Node { if (!this.expression.node.computed) prop = `'${prop}'`; obj = `[✂${this.expression.node.object.start}-${this.expression.node.object.end}✂]`; } else { - obj = '#ctx'; - prop = `'${name}'`; + obj = x`#ctx`; + prop = x`'${name}'`; } this.obj = obj; diff --git a/src/compiler/compile/nodes/EventHandler.ts b/src/compiler/compile/nodes/EventHandler.ts index 3abb2cff54..0cd8000550 100644 --- a/src/compiler/compile/nodes/EventHandler.ts +++ b/src/compiler/compile/nodes/EventHandler.ts @@ -1,7 +1,7 @@ import Node from './shared/Node'; import Expression from './shared/Expression'; import Component from '../Component'; -import { b } from 'code-red'; +import { b, x } from 'code-red'; import Block from '../render_dom/Block'; import { sanitize } from '../../utils/names'; import { Identifier } from '../../interfaces'; @@ -63,9 +63,11 @@ export default class EventHandler extends Node { // TODO move this? it is specific to render-dom render(block: Block) { - if (this.expression) this.expression.manipulate(block); + if (this.expression) { + return this.expression.manipulate(block); + } // this.component.add_reference(this.handler_name); - return `#ctx.${this.handler_name}`; + return x`#ctx.${this.handler_name}`; } } diff --git a/src/compiler/compile/render_dom/Block.ts b/src/compiler/compile/render_dom/Block.ts index f50b412f38..179c647ae1 100644 --- a/src/compiler/compile/render_dom/Block.ts +++ b/src/compiler/compile/render_dom/Block.ts @@ -57,7 +57,7 @@ export default class Block { destroy: Node[]; }; - event_listeners: string[] = []; + event_listeners: Node[] = []; maintain_context: boolean; has_animation: boolean; @@ -430,7 +430,7 @@ export default class Block { } else { this.chunks.hydrate.push(b` ${dispose} = [ - ${this.event_listeners.join(',\n')} + ${this.event_listeners} ]; `); diff --git a/src/compiler/compile/render_dom/index.ts b/src/compiler/compile/render_dom/index.ts index 7d57a48f91..5fd0d294ee 100644 --- a/src/compiler/compile/render_dom/index.ts +++ b/src/compiler/compile/render_dom/index.ts @@ -1,5 +1,4 @@ import { b, x } from 'code-red'; -import deindent from '../utils/deindent'; import { stringify, escape } from '../utils/stringify'; import Component from '../Component'; import Renderer from './Renderer'; @@ -99,44 +98,59 @@ export default function dom( const not_equal = component.component_options.immutable ? x`@not_equal` : x`@safe_not_equal`; let dev_props_check; let inject_state; let capture_state; - props.forEach(x => { - const variable = component.var_lookup.get(x.name); + props.forEach(prop => { + const variable = component.var_lookup.get(prop.name); if (!variable.writable || component.component_options.accessors) { - accessors.push(deindent` - get ${x.export_name}() { - return ${x.hoistable ? x.name : 'this.$$.ctx.' + x.name}; - } - `); + accessors.push({ + type: 'MethodDefinition', + kind: 'get', + key: { type: 'Identifier', name: prop.export_name }, + value: x`function() { + return ${prop.hoistable ? prop.name : x`this.$$.ctx.${prop.name}`} + }` + }); } else if (component.compile_options.dev) { - accessors.push(deindent` - get ${x.export_name}() { + accessors.push({ + type: 'MethodDefinition', + kind: 'get', + key: { type: 'Identifier', name: prop.export_name }, + value: x`function() { throw new @_Error("<${component.tag}>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); - } - `); + }` + }); } if (component.component_options.accessors) { - if (variable.writable && !renderer.readonly.has(x.name)) { - accessors.push(deindent` - set ${x.export_name}(${x.name}) { - this.$set({ ${x.name === x.export_name ? x.name : `${x.export_name}: ${x.name}`} }); + if (variable.writable && !renderer.readonly.has(prop.name)) { + accessors.push({ + type: 'MethodDefinition', + kind: 'set', + key: { type: 'Identifier', name: prop.export_name }, + value: x`function(${prop.name}) { + this.$set({ ${prop.export_name}: ${prop.name} }); @flush(); - } - `); + }` + }); } else if (component.compile_options.dev) { - accessors.push(deindent` - set ${x.export_name}(value) { - throw new @_Error("<${component.tag}>: Cannot set read-only property '${x.export_name}'"); - } - `); + accessors.push({ + type: 'MethodDefinition', + kind: 'set', + key: { type: 'Identifier', name: prop.export_name }, + value: x`function(value) { + throw new @_Error("<${component.tag}>: Cannot set read-only property '${prop.export_name}'"); + }` + }); } } else if (component.compile_options.dev) { - accessors.push(deindent` - set ${x.export_name}(value) { + accessors.push({ + type: 'MethodDefinition', + kind: 'set', + key: { type: 'Identifier', name: prop.export_name }, + value: x`function(value) { throw new @_Error("<${component.tag}>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); - } - `); + }` + }); } }); @@ -204,7 +218,7 @@ export default function dom( // onto the initial function call const names = new Set(extract_names(assignee)); - invalidate(component, scope, node, names); + this.replace(invalidate(component, scope, node, names)); } } }); @@ -405,7 +419,7 @@ export default function dom( }); if (options.customElement) { - body.push(b` + const declaration = b` class ${name} extends @SvelteElement { constructor(options) { super(); @@ -428,15 +442,24 @@ export default function dom( }`} } } + } + `[0]; + + if (props.length > 0) { + declaration.body.body.push({ + type: 'MethodDefinition', + kind: 'get', + static: true, + key: { type: 'Identifier', name: 'observedAttributes' }, + value: x`function() { + return [${props.map(prop => x`"${prop.export_name}"`)}]; + }` + }) + } - ${props.length > 0 && deindent` - static get observedAttributes() { - return ${JSON.stringify(props.map(x => x.export_name))}; - }`} + declaration.body.body.push(...accessors); - ${body.length > 0 && body.join('\n\n')} - } - `); + body.push(declaration); if (component.tag != null) { body.push(b` @@ -449,9 +472,7 @@ export default function dom( name: options.dev ? '@SvelteComponentDev' : '@SvelteComponent' }; - // TODO add accessors - - body.push(b` + const declaration = b` class ${name} extends ${superclass} { constructor(options) { super(${options.dev && `options`}); @@ -462,7 +483,11 @@ export default function dom( ${dev_props_check} } } - `); + `[0]; + + declaration.body.body.push(...accessors); + + body.push(declaration); } return flatten(body, []); diff --git a/src/compiler/compile/render_dom/wrappers/DebugTag.ts b/src/compiler/compile/render_dom/wrappers/DebugTag.ts index c7c0daf890..aa74f2f89d 100644 --- a/src/compiler/compile/render_dom/wrappers/DebugTag.ts +++ b/src/compiler/compile/render_dom/wrappers/DebugTag.ts @@ -63,7 +63,7 @@ export default class DebugTagWrapper extends Wrapper { // block.chunks.update.push(b` // if (${condition}) { - // const { ${ctx_identifiers} } = ctx; + // const { ${ctx_identifiers} } = #ctx; // @_console.${log}({ ${logged_identifiers} }); // debugger; // } @@ -71,7 +71,7 @@ export default class DebugTagWrapper extends Wrapper { // block.chunks.create.push(b` // { - // const { ${ctx_identifiers} } = ctx; + // const { ${ctx_identifiers} } = #ctx; // @_console.${log}({ ${logged_identifiers} }); // debugger; // } diff --git a/src/compiler/compile/render_dom/wrappers/Element/Binding.ts b/src/compiler/compile/render_dom/wrappers/Element/Binding.ts index 09426db67a..994354037f 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/Binding.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/Binding.ts @@ -125,11 +125,11 @@ export default class BindingWrapper { const binding_group = get_binding_group(parent.renderer, this.node.expression.node); block.chunks.hydrate.push( - b`ctx.$$binding_groups[${binding_group}].push(${parent.var});` + b`#ctx.$$binding_groups[${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`#ctx.$$binding_groups[${binding_group}].splice(#ctx.$$binding_groups[${binding_group}].indexOf(${parent.var}), 1);` ); break; } diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts index 4aac73aac7..f30fc912b6 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/index.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts @@ -480,21 +480,21 @@ export default class ElementWrapper extends Wrapper { ${animation_frame} = @raf(${handler}); ${needs_lock && `${lock} = true;`} } - ctx.${handler}.call(${this.var}${contextual_dependencies.size > 0 ? ', ctx' : ''}); + #ctx.${handler}.call(${this.var}${contextual_dependencies.size > 0 ? ', #ctx' : ''}); } `); } else { block.chunks.init.push(b` function ${handler}() { ${needs_lock && `${lock} = true;`} - ctx.${handler}.call(${this.var}${contextual_dependencies.size > 0 ? ', ctx' : ''}); + #ctx.${handler}.call(${this.var}${contextual_dependencies.size > 0 ? ', #ctx' : ''}); } `); } callee = handler; } else { - callee = `ctx.${handler}`; + callee = x`#ctx.${handler}`; } this.renderer.component.partly_hoisted.push(b` @@ -519,7 +519,7 @@ export default class ElementWrapper extends Wrapper { ); } else { block.event_listeners.push( - `@listen(${this.var}, "${name}", ${callee})` + x`@listen(${this.var}, "${name}", ${callee})` ); } }); diff --git a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts index b8405b7df3..82c6862171 100644 --- a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts +++ b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts @@ -250,14 +250,14 @@ export default class InlineComponentWrapper extends Wrapper { } if (non_let_dependencies.length > 0) { - updates.push(`if (${non_let_dependencies.map(n => `changed.${n}`).join(' || ')}) ${name_changes}.$$scope = { changed, ctx };`); + updates.push(`if (${non_let_dependencies.map(n => `changed.${n}`).join(' || ')}) ${name_changes}.$$scope = { changed: #changed, ctx: #ctx };`); } const munged_bindings = this.node.bindings.map(binding => { component.has_reactive_assignments = true; if (binding.name === 'this') { - return bind_this(component, block, binding, this.var.name); + return bind_this(component, block, binding, this.var); } const id = component.get_unique_name(`${this.var}_${binding.name}_binding`); @@ -306,7 +306,7 @@ export default class InlineComponentWrapper extends Wrapper { block.chunks.init.push(b` function ${name}(${value}) { - ctx.${name}.call(null, ${value}, ctx); + #ctx.${name}.call(null, ${value}, #ctx); ${updating} = true; @add_flush_callback(() => ${updating} = false); } @@ -316,7 +316,7 @@ export default class InlineComponentWrapper extends Wrapper { } else { block.chunks.init.push(b` function ${id}(${value}) { - ctx.${name}.call(null, ${value}); + #ctx.${name}.call(null, ${value}); ${updating} = true; @add_flush_callback(() => ${updating} = false); } @@ -337,7 +337,7 @@ export default class InlineComponentWrapper extends Wrapper { const munged_handlers = this.node.handlers.map(handler => { let snippet = handler.render(block); - if (handler.modifiers.has('once')) snippet = `@once(${snippet})`; + if (handler.modifiers.has('once')) snippet = x`@once(${snippet})`; return `${name}.$on("${handler.name}", ${snippet});`; }); @@ -351,7 +351,7 @@ export default class InlineComponentWrapper extends Wrapper { block.chunks.init.push(b` var ${switch_value} = ${snippet}; - function ${switch_props}(ctx) { + function ${switch_props}(#ctx) { ${(this.node.attributes.length || this.node.bindings.length) && b` ${props && `let ${props} = ${attribute_object};`}`} ${statements} @@ -359,7 +359,7 @@ export default class InlineComponentWrapper extends Wrapper { } if (${switch_value}) { - var ${name} = new ${switch_value}(${switch_props}(ctx)); + var ${name} = new ${switch_value}(${switch_props}(#ctx)); ${munged_bindings} ${munged_handlers} @@ -403,7 +403,7 @@ export default class InlineComponentWrapper extends Wrapper { } if (${switch_value}) { - ${name} = new ${switch_value}(${switch_props}(ctx)); + ${name} = new ${switch_value}(${switch_props}(#ctx)); ${munged_bindings} ${munged_handlers} diff --git a/src/compiler/compile/render_dom/wrappers/Slot.ts b/src/compiler/compile/render_dom/wrappers/Slot.ts index 6bd1b24e07..aa05bd7fb9 100644 --- a/src/compiler/compile/render_dom/wrappers/Slot.ts +++ b/src/compiler/compile/render_dom/wrappers/Slot.ts @@ -110,8 +110,8 @@ export default class SlotWrapper extends Wrapper { const slot_definition = block.get_unique_name(`${sanitize(slot_name)}_slot_template`); block.chunks.init.push(b` - const ${slot_definition} = ctx.$$slots${quote_prop_if_necessary(slot_name)}; - const ${slot} = @create_slot(${slot_definition}, ctx, ${get_slot_context}); + const ${slot_definition} = #ctx.$$slots${quote_prop_if_necessary(slot_name)}; + const ${slot} = @create_slot(${slot_definition}, #ctx, ${get_slot_context}); `); const mount_before = block.chunks.mount.slice(); @@ -175,8 +175,8 @@ export default class SlotWrapper extends Wrapper { block.chunks.update.push(b` if (${slot} && ${slot}.p && ${update_conditions}) { ${slot}.p( - @get_slot_changes(${slot_definition}, ctx, changed, ${get_slot_changes}), - @get_slot_context(${slot_definition}, ctx, ${get_slot_context}) + @get_slot_changes(${slot_definition}, #ctx, changed, ${get_slot_changes}), + @get_slot_context(${slot_definition}, #ctx, ${get_slot_context}) ); } `); diff --git a/src/compiler/compile/render_dom/wrappers/Window.ts b/src/compiler/compile/render_dom/wrappers/Window.ts index 2bc6840a9d..bd7ea5441c 100644 --- a/src/compiler/compile/render_dom/wrappers/Window.ts +++ b/src/compiler/compile/render_dom/wrappers/Window.ts @@ -82,13 +82,12 @@ export default class WindowWrapper extends Wrapper { block.add_variable(clear_scrolling, x`() => { ${scrolling} = false }`); block.add_variable(scrolling_timeout); - const condition = [ - bindings.scrollX && `"${bindings.scrollX}" in this._state`, - bindings.scrollY && `"${bindings.scrollY}" in this._state` - ].filter(Boolean).join(' || '); + const condition = bindings.scrollX && bindings.scrollY + ? x`"${bindings.scrollX}" in this._state || "${bindings.scrollY}" in this._state` + : x`"${bindings.scrollX || bindings.scrollY}" in this._state`; - const scrollX = bindings.scrollX && `this._state.${bindings.scrollX}`; - const scrollY = bindings.scrollY && `this._state.${bindings.scrollY}`; + const scrollX = bindings.scrollX && x`this._state.${bindings.scrollX}`; + const scrollY = bindings.scrollY && x`this._state.${bindings.scrollY}`; renderer.meta_bindings.push(b` if (${condition}) { @@ -98,12 +97,12 @@ export default class WindowWrapper extends Wrapper { ${scrollY && `${scrollY} = @_window.pageYOffset;`} `); - block.event_listeners.push(b` + block.event_listeners.push(x` @listen(@_window, "${event}", () => { ${scrolling} = true; @_clearTimeout(${scrolling_timeout}); ${scrolling_timeout} = @_setTimeout(${clear_scrolling}, 100); - ctx.${id}(); + #ctx.${id}(); }) `); } else { @@ -113,8 +112,8 @@ export default class WindowWrapper extends Wrapper { ); }); - block.event_listeners.push(b` - @listen(@_window, "${event}", ctx.${id}) + block.event_listeners.push(x` + @listen(@_window, "${event}", #ctx.${id}) `); } @@ -131,7 +130,7 @@ export default class WindowWrapper extends Wrapper { `); block.chunks.init.push(b` - @add_render_callback(ctx.${id}); + @add_render_callback(#ctx.${id}); `); component.has_reactive_assignments = true; @@ -148,9 +147,9 @@ export default class WindowWrapper extends Wrapper { ${scrolling} = true; @_clearTimeout(${scrolling_timeout}); @_scrollTo(${ - bindings.scrollX ? `ctx.${bindings.scrollX}` : `@_window.pageXOffset` + bindings.scrollX ? `#ctx.${bindings.scrollX}` : `@_window.pageXOffset` }, ${ - bindings.scrollY ? `ctx.${bindings.scrollY}` : `@_window.pageYOffset` + bindings.scrollY ? `#ctx.${bindings.scrollY}` : `@_window.pageYOffset` }); ${scrolling_timeout} = @_setTimeout(${clear_scrolling}, 100); } @@ -175,12 +174,12 @@ export default class WindowWrapper extends Wrapper { `); block.chunks.init.push(b` - @add_render_callback(ctx.${id}); + @add_render_callback(#ctx.${id}); `); block.event_listeners.push( - `@listen(@_window, "online", ctx.${id})`, - `@listen(@_window, "offline", ctx.${id})` + x`@listen(@_window, "online", #ctx.${id})`, + x`@listen(@_window, "offline", #ctx.${id})` ); component.has_reactive_assignments = true; diff --git a/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts b/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts index 3f39f33146..588611de60 100644 --- a/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts +++ b/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts @@ -1,5 +1,6 @@ import Block from '../../Block'; import EventHandler from '../../../nodes/EventHandler'; +import { x } from 'code-red'; export default function add_event_handlers( block: Block, @@ -8,35 +9,37 @@ export default function add_event_handlers( ) { handlers.forEach(handler => { let snippet = handler.render(block); - if (handler.modifiers.has('preventDefault')) snippet = `@prevent_default(${snippet})`; - if (handler.modifiers.has('stopPropagation')) snippet = `@stop_propagation(${snippet})`; - if (handler.modifiers.has('self')) snippet = `@self(${snippet})`; + if (handler.modifiers.has('preventDefault')) snippet = x`@prevent_default(${snippet})`; + if (handler.modifiers.has('stopPropagation')) snippet = x`@stop_propagation(${snippet})`; + if (handler.modifiers.has('self')) snippet = x`@self(${snippet})`; - let opts_string = ''; + // let opts_string = ''; - if (block.renderer.options.dev) { - if (handler.modifiers.has('stopPropagation')) { - opts_string = ', true'; - } + // if (block.renderer.options.dev) { + // if (handler.modifiers.has('stopPropagation')) { + // opts_string = ', true'; + // } - if (handler.modifiers.has('preventDefault')) { - opts_string = ', true' + opts_string; - } else if (opts_string) { - opts_string = ', false' + opts_string; - } - } + // if (handler.modifiers.has('preventDefault')) { + // opts_string = ', true' + opts_string; + // } else if (opts_string) { + // opts_string = ', false' + opts_string; + // } + // } - const opts = ['passive', 'once', 'capture'].filter(mod => handler.modifiers.has(mod)); - if (opts.length) { - opts_string = (opts.length === 1 && opts[0] === 'capture') - ? ', true' - : `, { ${opts.map(opt => `${opt}: true`).join(', ')} }`; - } else if (opts_string) { - opts_string = ', false' + opts_string; - } + // const opts = ['passive', 'once', 'capture'].filter(mod => handler.modifiers.has(mod)); + // if (opts.length) { + // opts_string = (opts.length === 1 && opts[0] === 'capture') + // ? ', true' + // : `, { ${opts.map(opt => `${opt}: true`).join(', ')} }`; + // } else if (opts_string) { + // opts_string = ', false' + opts_string; + // } + + // TODO modifiers block.event_listeners.push( - `@listen(${target}, "${handler.name}", ${snippet}${opts_string})` + x`@listen(${target}, "${handler.name}", ${snippet})` ); }); } 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 24dd2b3972..63d280e87b 100644 --- a/src/compiler/compile/render_dom/wrappers/shared/bind_this.ts +++ b/src/compiler/compile/render_dom/wrappers/shared/bind_this.ts @@ -5,8 +5,8 @@ import Block from '../../Block'; import Binding from '../../../nodes/Binding'; import { Identifier } from '../../../../interfaces'; -export default function bind_this(component: Component, block: Block, binding: Binding, variable: string) { - const fn = component.get_unique_name(`${variable}_binding`); +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, @@ -56,18 +56,18 @@ export default function bind_this(component: Component, block: Block, binding: B for (const arg of contextual_dependencies) { const id: Identifier = { type: 'Identifier', name: arg }; args.push(id); - block.add_variable(id, x`ctx.${id}`); + block.add_variable(id, x`#ctx.${id}`); } const assign = block.get_unique_name(`assign_${variable}`); const unassign = block.get_unique_name(`unassign_${variable}`); block.chunks.init.push(b` - const ${assign} = () => ctx.${fn}(${[variable].concat(args).join(', ')}); - const ${unassign} = () => ctx.${fn}(${['null'].concat(args).join(', ')}); + const ${assign} = () => #ctx.${fn}(${[variable].concat(args).join(', ')}); + const ${unassign} = () => #ctx.${fn}(${['null'].concat(args).join(', ')}); `); - const condition = Array.from(contextual_dependencies).map(name => `${name} !== ctx.${name}`).join(' || '); + const condition = Array.from(contextual_dependencies).map(name => `${name} !== #ctx.${name}`).join(' || '); // we push unassign and unshift assign so that references are // nulled out before they're created, to avoid glitches @@ -75,7 +75,7 @@ export default function bind_this(component: Component, block: Block, binding: B block.chunks.update.push(b` if (${condition}) { ${unassign}(); - ${args.map(a => `${a} = ctx.${a}`).join(', ')}; + ${args.map(a => `${a} = #ctx.${a}`).join(', ')}; ${assign}(); }` ); @@ -92,6 +92,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`#ctx.${fn}(null);`); + return b`#ctx.${fn}(${variable});`; } \ 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 146324f2a4..1b56a50939 100644 --- a/src/compiler/compile/render_ssr/handlers/Element.ts +++ b/src/compiler/compile/render_ssr/handlers/Element.ts @@ -85,7 +85,7 @@ export default function(node: Element, renderer: Renderer, options: RenderOption const class_expression = node.classes.map((class_directive: Class) => { const { expression, name } = class_directive; - const snippet = expression ? snip(expression) : `ctx${quote_prop_if_necessary(name)}`; + const snippet = expression ? snip(expression) : `#ctx${quote_prop_if_necessary(name)}`; return `${snippet} ? "${name}" : ""`; }).join(', '); diff --git a/src/compiler/compile/utils/invalidate.ts b/src/compiler/compile/utils/invalidate.ts index 053e64bf3e..b21c9c7816 100644 --- a/src/compiler/compile/utils/invalidate.ts +++ b/src/compiler/compile/utils/invalidate.ts @@ -55,7 +55,10 @@ export function invalidate(component: Component, scope: Scope, node: Node, names ); if (pass_value) { - extra_args.unshift(head); + extra_args.unshift({ + type: 'Identifier', + name: head + }); } return x`$$invalidate("${head}", ${node}, ${extra_args})`; diff --git a/src/runtime/internal/Component.ts b/src/runtime/internal/Component.ts index 5b9007b6bc..ae80ae38c1 100644 --- a/src/runtime/internal/Component.ts +++ b/src/runtime/internal/Component.ts @@ -102,7 +102,6 @@ export function init(component, options, instance, create_fragment, not_equal, p $$.ctx = instance ? instance(component, props, (key, ret, value = ret) => { - console.log(`invalidating`, key, ret, value); if ($$.ctx && not_equal($$.ctx[key], $$.ctx[key] = value)) { if ($$.bound[key]) $$.bound[key](value); if (ready) make_dirty(component, key); diff --git a/test/runtime/samples/action-this/main.svelte b/test/runtime/samples/action-this/main.svelte index 28d5444b32..c7d74a8b97 100644 --- a/test/runtime/samples/action-this/main.svelte +++ b/test/runtime/samples/action-this/main.svelte @@ -4,7 +4,7 @@ function foo(node) { const handler = () => { x += 1; - } + }; node.addEventListener('click', handler); handler(); diff --git a/test/runtime/samples/action-update/_config.js b/test/runtime/samples/action-update/_config.js index 305c890ca8..b5e90e4b10 100644 --- a/test/runtime/samples/action-update/_config.js +++ b/test/runtime/samples/action-update/_config.js @@ -3,7 +3,7 @@ export default { `, - async test({ assert, component, target, window }) { + async test({ assert, target, window }) { const button = target.querySelector('button'); const enter = new window.MouseEvent('mouseenter'); const leave = new window.MouseEvent('mouseleave');