basic events

pull/1864/head
Rich Harris 7 years ago
parent 834e342276
commit 3e962b9c90

@ -1,3 +1,3 @@
import { onprops, onmount, onupdate, ondestroy } from './internal.js'; import { onprops, onmount, onupdate, ondestroy, createEventDispatcher } from './internal.js';
export { onprops, onmount, onupdate, ondestroy }; export { onprops, onmount, onupdate, ondestroy, createEventDispatcher };

@ -174,9 +174,6 @@ export default class ElementWrapper extends Wrapper {
}); });
if (this.parent) { if (this.parent) {
// console.log(`has intro ${!!node.intro}`);
// console.log(`has outro ${!!node.outro}`);
if (node.actions.length > 0) this.parent.cannotUseInnerHTML(); if (node.actions.length > 0) this.parent.cannotUseInnerHTML();
if (node.animation) this.parent.cannotUseInnerHTML(); if (node.animation) this.parent.cannotUseInnerHTML();
if (node.bindings.length > 0) this.parent.cannotUseInnerHTML(); if (node.bindings.length > 0) this.parent.cannotUseInnerHTML();

@ -278,7 +278,7 @@ export default class InlineComponentWrapper extends Wrapper {
hasStoreBindings && 'newStoreState = {}', hasStoreBindings && 'newStoreState = {}',
].filter(Boolean).join(', '); ].filter(Boolean).join(', ');
// TODO use component.on('state', ...) instead of _bind // TODO use component.$on('state', ...) instead of _bind
componentInitProperties.push(deindent` componentInitProperties.push(deindent`
_bind(changed, childState) { _bind(changed, childState) {
var ${initialisers}; var ${initialisers};
@ -327,10 +327,10 @@ export default class InlineComponentWrapper extends Wrapper {
${this.node.handlers.map(handler => deindent` ${this.node.handlers.map(handler => deindent`
function ${handler.var}(event) { function ${handler.var}(event) {
${handler.snippet || `#component.fire("${handler.name}", event);`} (${handler.snippet || `() => { throw new Error('TODO shorthand events'); }`})(event);
} }
if (${name}) ${name}.on("${handler.name}", ${handler.var}); if (${name}) ${name}.$on("${handler.name}", ${handler.var});
`)} `)}
`); `);
@ -389,7 +389,7 @@ export default class InlineComponentWrapper extends Wrapper {
${name}.$$mount(${updateMountNode}, ${anchor}); ${name}.$$mount(${updateMountNode}, ${anchor});
${this.node.handlers.map(handler => deindent` ${this.node.handlers.map(handler => deindent`
${name}.on("${handler.name}", ${handler.var}); ${name}.$on("${handler.name}", ${handler.var});
`)} `)}
${this.node.ref && `#component.$$refs.${this.node.ref.name} = ${name};`} ${this.node.ref && `#component.$$refs.${this.node.ref.name} = ${name};`}
@ -429,8 +429,8 @@ export default class InlineComponentWrapper extends Wrapper {
${beforecreate} ${beforecreate}
${this.node.handlers.map(handler => deindent` ${this.node.handlers.map(handler => deindent`
${name}.on("${handler.name}", function(event) { ${name}.$on("${handler.name}", function(event) {
${handler.snippet || `#component.fire("${handler.name}", event);`} (${handler.snippet || `() => { throw new Error('TODO shorthand events'); }`})(event);
}); });
`)} `)}

@ -168,7 +168,7 @@ export default class WindowWrapper extends Wrapper {
// special case... might need to abstract this out if we add more special cases // special case... might need to abstract this out if we add more special cases
if (bindings.scrollX || bindings.scrollY) { if (bindings.scrollX || bindings.scrollY) {
block.builders.init.addBlock(deindent` block.builders.init.addBlock(deindent`
#component.on("state", ({ changed, current }) => { #component.$on("state", ({ changed, current }) => {
if (${ if (${
[bindings.scrollX, bindings.scrollY].map( [bindings.scrollX, bindings.scrollY].map(
binding => binding && `changed["${binding}"]` binding => binding && `changed["${binding}"]`

@ -1,6 +1,7 @@
import { schedule_update, flush } from './scheduler.js'; import { schedule_update, flush } from './scheduler.js';
import { set_current_component } from './lifecycle.js' import { set_current_component } from './lifecycle.js'
import { run_all } from '../shared/utils.js'; import { run_all } from '../shared/utils.js';
import { blankObject } from './utils.js';
export class SvelteComponent { export class SvelteComponent {
constructor(options) { constructor(options) {
@ -9,6 +10,8 @@ export class SvelteComponent {
this.$$onupdate = []; this.$$onupdate = [];
this.$$ondestroy = []; this.$$ondestroy = [];
this.$$callbacks = blankObject();
this.$$slotted = options.slots; this.$$slotted = options.slots;
set_current_component(this); set_current_component(this);
@ -35,8 +38,14 @@ export class SvelteComponent {
} }
} }
$on(eventName, callback) { $on(type, callback) {
const callbacks = (this.$$callbacks[type] || (this.$$callbacks[type] = []));
callbacks.push(callback);
return () => {
const index = callbacks.indexOf(callback);
if (index !== -1) callbacks.splice(index, 1);
};
} }
$destroy() { $destroy() {

@ -19,3 +19,18 @@ export function onupdate(fn) {
export function ondestroy(fn) { export function ondestroy(fn) {
current_component.$$ondestroy.push(fn); current_component.$$ondestroy.push(fn);
} }
export function createEventDispatcher() {
const component = current_component;
return (type, detail) => {
const callbacks = component.$$callbacks[type];
if (callbacks) {
// TODO are there situations where events could be dispatched
// in a server (non-DOM) environment?
const event = new window.CustomEvent(type, { detail });
callbacks.slice().forEach(fn => fn(event));
}
};
}
Loading…
Cancel
Save