diff --git a/src/compile/Component.ts b/src/compile/Component.ts index 5b403095fd..560cc98961 100644 --- a/src/compile/Component.ts +++ b/src/compile/Component.ts @@ -69,6 +69,7 @@ export default class Component { templateVars: Map; aliases: Map; usedNames: Set; + init_uses_self = false; locator: (search: number, startIndex?: number) => { line: number, diff --git a/src/compile/nodes/EventHandler.ts b/src/compile/nodes/EventHandler.ts index 20af76e305..ff75bf5309 100644 --- a/src/compile/nodes/EventHandler.ts +++ b/src/compile/nodes/EventHandler.ts @@ -3,6 +3,7 @@ import Expression from './shared/Expression'; import flattenReference from '../../utils/flattenReference'; import { createScopes } from '../../utils/annotateWithScopes'; import { walk } from 'estree-walker'; +import Component from '../Component'; export default class EventHandler extends Node { name: string; @@ -19,7 +20,7 @@ export default class EventHandler extends Node { args: Expression[]; snippet: string; - constructor(component, parent, template_scope, info) { + constructor(component: Component, parent, template_scope, info) { super(component, parent, template_scope, info); this.name = info.name; @@ -53,7 +54,8 @@ export default class EventHandler extends Node { } }); } else { - this.snippet = null; // TODO handle shorthand events here? + component.init_uses_self = true; + this.snippet = `e => @bubble($$self, e)` } // TODO figure out what to do about custom events diff --git a/src/compile/render-dom/index.ts b/src/compile/render-dom/index.ts index e9416c6c8e..80d26de0ce 100644 --- a/src/compile/render-dom/index.ts +++ b/src/compile/render-dom/index.ts @@ -121,6 +121,7 @@ export default function dom( builder.addBlock(deindent` class ${name} extends ${superclass} { $$init($$make_dirty) { + ${component.init_uses_self && `const $$self = this;`} ${component.javascript || component.exports.map(x => `let ${x.name};`)} ${component.event_handlers.map(handler => handler.body)} diff --git a/src/compile/render-dom/wrappers/Element/index.ts b/src/compile/render-dom/wrappers/Element/index.ts index d0de4cc9e7..432eb20909 100644 --- a/src/compile/render-dom/wrappers/Element/index.ts +++ b/src/compile/render-dom/wrappers/Element/index.ts @@ -171,7 +171,9 @@ export default class ElementWrapper extends Wrapper { }); node.handlers.forEach(handler => { - block.addDependencies(handler.expression.dependencies); + if (handler.expression) { + block.addDependencies(handler.expression.dependencies); + } }); if (this.parent) { @@ -662,7 +664,7 @@ export default class ElementWrapper extends Wrapper { let name; - if (handler.expression.contextual_dependencies.size > 0) { + if (handler.expression && handler.expression.contextual_dependencies.size > 0) { name = handler_name; const deps = Array.from(handler.expression.contextual_dependencies); diff --git a/src/internal/lifecycle.js b/src/internal/lifecycle.js index df39b84f94..c22118d68d 100644 --- a/src/internal/lifecycle.js +++ b/src/internal/lifecycle.js @@ -33,4 +33,15 @@ export function createEventDispatcher() { callbacks.slice().forEach(fn => fn(event)); } }; +} + +// TODO figure out if we still want to support +// shorthand events, or if we want to implement +// a real bubbling mechanism +export function bubble(component, event) { + const callbacks = component.$$callbacks[event.type]; + + if (callbacks) { + callbacks.slice().forEach(fn => fn(event)); + } } \ No newline at end of file