diff --git a/src/compiler/compile/render_dom/index.ts b/src/compiler/compile/render_dom/index.ts index 6380843b87..d57635aaa9 100644 --- a/src/compiler/compile/render_dom/index.ts +++ b/src/compiler/compile/render_dom/index.ts @@ -70,6 +70,14 @@ export default function dom( ); } + const uses_dispatch = component.var_lookup.has('$$dispatch'); + let create_dispatch; + if (uses_dispatch) { + create_dispatch = b` + const $$dispatch = @createEventDispatcher(); + `; + } + const uses_slots = component.var_lookup.has('$$slots'); let compute_slots; if (uses_slots) { @@ -417,6 +425,8 @@ export default function dom( ${resubscribable_reactive_store_unsubscribers} + ${create_dispatch} + ${component.slots.size || component.compile_options.dev || uses_slots ? b`let { $$slots: #slots = {}, $$scope } = $$props;` : null} ${component.compile_options.dev && b`@validate_slots('${component.tag}', #slots, [${[...component.slots.keys()].map(key => `'${key}'`).join(',')}]);`} ${compute_slots} diff --git a/src/compiler/compile/utils/reserved_keywords.ts b/src/compiler/compile/utils/reserved_keywords.ts index a68819a493..d603e28730 100644 --- a/src/compiler/compile/utils/reserved_keywords.ts +++ b/src/compiler/compile/utils/reserved_keywords.ts @@ -1,4 +1,4 @@ -export const reserved_keywords = new Set(['$$props', '$$restProps', '$$slots']); +export const reserved_keywords = new Set(['$$props', '$$restProps', '$$slots', '$$dispatch']); export function is_reserved_keyword(name) { return reserved_keywords.has(name); diff --git a/test/runtime/samples/$$dispatch-script/_config.js b/test/runtime/samples/$$dispatch-script/_config.js new file mode 100644 index 0000000000..2122a7e0e1 --- /dev/null +++ b/test/runtime/samples/$$dispatch-script/_config.js @@ -0,0 +1,24 @@ +export default { + props: { + + }, + html: ` + + `, + + async test({ assert, component, target, window}) { + const button = target.querySelector('button'); + const event = new window.MouseEvent('click'); + + const clicked = []; + + component.$on('clicked', event => { + clicked.push(event.detail); + }); + + button.dispatchEvent(event); + + assert.equal(clicked.length, 1); + assert.equal(clicked[0], 'info'); + } +}; diff --git a/test/runtime/samples/$$dispatch-script/main.svelte b/test/runtime/samples/$$dispatch-script/main.svelte new file mode 100644 index 0000000000..9d7b549cb0 --- /dev/null +++ b/test/runtime/samples/$$dispatch-script/main.svelte @@ -0,0 +1,7 @@ + + + `, + + async test({ assert, component, target, window}) { + const button = target.querySelector('button'); + const event = new window.MouseEvent('click'); + + const clicked = []; + + component.$on('clicked', event => { + clicked.push(event.detail); + }); + + button.dispatchEvent(event); + + assert.equal(clicked.length, 1); + assert.equal(clicked[0], 'info'); + } +}; diff --git a/test/runtime/samples/$$dispatch-template/main.svelte b/test/runtime/samples/$$dispatch-template/main.svelte new file mode 100644 index 0000000000..c7339194dd --- /dev/null +++ b/test/runtime/samples/$$dispatch-template/main.svelte @@ -0,0 +1,2 @@ + +