From f2eb632bc9e9483f4663277fa9e500d6e1d25b42 Mon Sep 17 00:00:00 2001 From: Pontus Lundin Date: Wed, 18 Dec 2019 12:34:55 +0000 Subject: [PATCH 1/4] pseudo code --- src/runtime/internal/lifecycle.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/runtime/internal/lifecycle.ts b/src/runtime/internal/lifecycle.ts index a8e37e9632a3..809a39d717f5 100644 --- a/src/runtime/internal/lifecycle.ts +++ b/src/runtime/internal/lifecycle.ts @@ -28,6 +28,8 @@ export function onDestroy(fn) { } export function createEventDispatcher() { + // is compile target customElement? + // always dispatch! const component = get_current_component(); return (type: string, detail?: any) => { @@ -61,4 +63,4 @@ export function bubble(component, event) { if (callbacks) { callbacks.slice().forEach(fn => fn(event)); } -} \ No newline at end of file +} From 6ebffd2882576aa23cda26b9dd193217ffcf51d5 Mon Sep 17 00:00:00 2001 From: Pontus Lundin Date: Wed, 18 Dec 2019 12:37:34 +0000 Subject: [PATCH 2/4] pseudo code --- src/runtime/internal/dom.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts index c641315bc37b..5b3c70261d98 100644 --- a/src/runtime/internal/dom.ts +++ b/src/runtime/internal/dom.ts @@ -268,6 +268,9 @@ export function toggle_class(element, name, toggle) { } export function custom_event(type: string, detail?: T) { + // is compile target customElement? + // is event not a Svelte event? + // use new CustomEvent with bubbles/composed = true for non, svelte event const e: CustomEvent = document.createEvent('CustomEvent'); e.initCustomEvent(type, false, false, detail); return e; @@ -307,4 +310,4 @@ export class HtmlTag { d() { this.n.forEach(detach); } -} \ No newline at end of file +} From 0b40585b7ae72f293f8bd8a6507c3bb8624ee75f Mon Sep 17 00:00:00 2001 From: hontas Date: Sun, 22 Dec 2019 01:33:24 +0100 Subject: [PATCH 3/4] always dispatch event if component is custom element --- src/runtime/internal/dom.ts | 3 --- src/runtime/internal/lifecycle.ts | 7 ++++-- .../samples/dispatch/main.svelte | 14 +++++++++++ test/custom-elements/samples/dispatch/test.js | 23 +++++++++++++++++++ 4 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 test/custom-elements/samples/dispatch/main.svelte create mode 100644 test/custom-elements/samples/dispatch/test.js diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts index 5b3c70261d98..5bd9998daac0 100644 --- a/src/runtime/internal/dom.ts +++ b/src/runtime/internal/dom.ts @@ -268,9 +268,6 @@ export function toggle_class(element, name, toggle) { } export function custom_event(type: string, detail?: T) { - // is compile target customElement? - // is event not a Svelte event? - // use new CustomEvent with bubbles/composed = true for non, svelte event const e: CustomEvent = document.createEvent('CustomEvent'); e.initCustomEvent(type, false, false, detail); return e; diff --git a/src/runtime/internal/lifecycle.ts b/src/runtime/internal/lifecycle.ts index 809a39d717f5..def46c771257 100644 --- a/src/runtime/internal/lifecycle.ts +++ b/src/runtime/internal/lifecycle.ts @@ -28,8 +28,6 @@ export function onDestroy(fn) { } export function createEventDispatcher() { - // is compile target customElement? - // always dispatch! const component = get_current_component(); return (type: string, detail?: any) => { @@ -43,6 +41,11 @@ export function createEventDispatcher() { fn.call(component, event); }); } + + if (component.shadowRoot) { + const event = custom_event(type, detail); + component.dispatchEvent(event); + } }; } diff --git a/test/custom-elements/samples/dispatch/main.svelte b/test/custom-elements/samples/dispatch/main.svelte new file mode 100644 index 000000000000..540e5495928e --- /dev/null +++ b/test/custom-elements/samples/dispatch/main.svelte @@ -0,0 +1,14 @@ + + + + diff --git a/test/custom-elements/samples/dispatch/test.js b/test/custom-elements/samples/dispatch/test.js new file mode 100644 index 000000000000..698e74e3978a --- /dev/null +++ b/test/custom-elements/samples/dispatch/test.js @@ -0,0 +1,23 @@ +import * as assert from 'assert'; +import './main.svelte'; + +console.log('console.log'); + +export default async function(target) { + target.innerHTML = ''; + const el = target.querySelector('custom-element'); + const label = el.shadowRoot.querySelector('label'); + const input = el.shadowRoot.querySelector('input'); + + return new Promise(resolve => { + el.addEventListener('change', function changeHandler(evt) { + el.removeEventListener('change', changeHandler); + + assert.equal(evt.target, el); + assert.equal(input.checked, true); + resolve(); + }); + + label.dispatchEvent(new MouseEvent('click')); + }); +} From 9b69b6520b1a52d58e8ddc8217b8cacae9299445 Mon Sep 17 00:00:00 2001 From: hontas Date: Sun, 22 Dec 2019 01:48:19 +0100 Subject: [PATCH 4/4] more generic test --- .../samples/dispatch/main.svelte | 12 ++++++---- test/custom-elements/samples/dispatch/test.js | 23 ++++++++++--------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/test/custom-elements/samples/dispatch/main.svelte b/test/custom-elements/samples/dispatch/main.svelte index 540e5495928e..30e6633db222 100644 --- a/test/custom-elements/samples/dispatch/main.svelte +++ b/test/custom-elements/samples/dispatch/main.svelte @@ -3,12 +3,14 @@ const dispatch = createEventDispatcher(); - const handleChange = evt => { - dispatch('change', evt); + const sayHello = () => { + dispatch('message', { + text: 'Hello!' + }); }; - + diff --git a/test/custom-elements/samples/dispatch/test.js b/test/custom-elements/samples/dispatch/test.js index 698e74e3978a..f301bb15bca7 100644 --- a/test/custom-elements/samples/dispatch/test.js +++ b/test/custom-elements/samples/dispatch/test.js @@ -1,23 +1,24 @@ import * as assert from 'assert'; import './main.svelte'; -console.log('console.log'); - export default async function(target) { target.innerHTML = ''; const el = target.querySelector('custom-element'); - const label = el.shadowRoot.querySelector('label'); - const input = el.shadowRoot.querySelector('input'); + const button = el.shadowRoot.querySelector('button'); - return new Promise(resolve => { - el.addEventListener('change', function changeHandler(evt) { - el.removeEventListener('change', changeHandler); + return new Promise((resolve, reject) => { + el.addEventListener('message', function changeHandler(evt) { + el.removeEventListener('message', changeHandler); - assert.equal(evt.target, el); - assert.equal(input.checked, true); - resolve(); + try { + assert.equal(evt.target, el); + assert.equal(evt.detail.text, 'Hello!'); + resolve(); + } catch (err) { + reject(err); + } }); - label.dispatchEvent(new MouseEvent('click')); + button.dispatchEvent(new MouseEvent('click')); }); }