Skip to content

Commit e22fd30

Browse files
committed
fix(event): fix CustomEvent polyfill
Fixes #1173
1 parent 6015be8 commit e22fd30

5 files changed

Lines changed: 94 additions & 0 deletions

File tree

src/renderer/dom-api.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export function createDomApi(App: AppGlobal, win: any, doc: Document): DomApi {
1919
// CustomEvent polyfill
2020
win.CustomEvent = (event: any, data: EventEmitterData, evt?: any) => {
2121
evt = doc.createEvent('CustomEvent');
22+
data = data || {};
2223
evt.initCustomEvent(event, data.bubbles, data.cancelable, data.detail);
2324
return evt;
2425
};

test/karma/test-app/components.d.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ export namespace Components {
9191
interface CssVariables {}
9292
interface CssVariablesAttributes extends StencilHTMLAttributes {}
9393

94+
interface CustomEvent {}
95+
interface CustomEventAttributes extends StencilHTMLAttributes {}
96+
9497
interface DynamicCssVariable {}
9598
interface DynamicCssVariableAttributes extends StencilHTMLAttributes {}
9699

@@ -367,6 +370,7 @@ declare global {
367370
'ConditionalRerender': Components.ConditionalRerender;
368371
'CssVariablesRoot': Components.CssVariablesRoot;
369372
'CssVariables': Components.CssVariables;
373+
'CustomEvent': Components.CustomEvent;
370374
'DynamicCssVariable': Components.DynamicCssVariable;
371375
'DynamicImport': Components.DynamicImport;
372376
'Es5AddclassSvg': Components.Es5AddclassSvg;
@@ -439,6 +443,7 @@ declare global {
439443
'conditional-rerender': Components.ConditionalRerenderAttributes;
440444
'css-variables-root': Components.CssVariablesRootAttributes;
441445
'css-variables': Components.CssVariablesAttributes;
446+
'custom-event': Components.CustomEventAttributes;
442447
'dynamic-css-variable': Components.DynamicCssVariableAttributes;
443448
'dynamic-import': Components.DynamicImportAttributes;
444449
'es5-addclass-svg': Components.Es5AddclassSvgAttributes;
@@ -571,6 +576,12 @@ declare global {
571576
new (): HTMLCssVariablesElement;
572577
};
573578

579+
interface HTMLCustomEventElement extends Components.CustomEvent, HTMLStencilElement {}
580+
var HTMLCustomEventElement: {
581+
prototype: HTMLCustomEventElement;
582+
new (): HTMLCustomEventElement;
583+
};
584+
574585
interface HTMLDynamicCssVariableElement extends Components.DynamicCssVariable, HTMLStencilElement {}
575586
var HTMLDynamicCssVariableElement: {
576587
prototype: HTMLDynamicCssVariableElement;
@@ -926,6 +937,7 @@ declare global {
926937
'conditional-rerender': HTMLConditionalRerenderElement
927938
'css-variables-root': HTMLCssVariablesRootElement
928939
'css-variables': HTMLCssVariablesElement
940+
'custom-event': HTMLCustomEventElement
929941
'dynamic-css-variable': HTMLDynamicCssVariableElement
930942
'dynamic-import': HTMLDynamicImportElement
931943
'es5-addclass-svg': HTMLEs5AddclassSvgElement
@@ -998,6 +1010,7 @@ declare global {
9981010
'conditional-rerender': HTMLConditionalRerenderElement;
9991011
'css-variables-root': HTMLCssVariablesRootElement;
10001012
'css-variables': HTMLCssVariablesElement;
1013+
'custom-event': HTMLCustomEventElement;
10011014
'dynamic-css-variable': HTMLDynamicCssVariableElement;
10021015
'dynamic-import': HTMLDynamicImportElement;
10031016
'es5-addclass-svg': HTMLEs5AddclassSvgElement;
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { Component, Element, State } from '../../../../dist';
2+
3+
@Component({
4+
tag: 'custom-event'
5+
})
6+
export class CustomEventCmp {
7+
8+
@Element() elm: HTMLElement;
9+
10+
@State() output = '';
11+
12+
componentDidLoad() {
13+
this.elm.addEventListener('eventNoDetail', this.receiveEvent.bind(this));
14+
this.elm.addEventListener('eventWithDetail', this.receiveEvent.bind(this));
15+
}
16+
17+
receiveEvent(ev: CustomEvent) {
18+
this.output = `${ev.type} ${ev.detail || ''}`.trim();
19+
}
20+
21+
fireCustomEventNoDetail() {
22+
const ev = new CustomEvent('eventNoDetail');
23+
this.elm.dispatchEvent(ev);
24+
}
25+
26+
fireCustomEventWithDetail() {
27+
const ev = new CustomEvent('eventWithDetail', { detail: 88 });
28+
this.elm.dispatchEvent(ev);
29+
}
30+
31+
render() {
32+
return (
33+
<div>
34+
<div>
35+
<button id="btnNoDetail" onClick={this.fireCustomEventNoDetail.bind(this)}>Fire Custom Event, no detail</button>
36+
</div>
37+
<div>
38+
<button id="btnWithDetail" onClick={this.fireCustomEventWithDetail.bind(this)}>Fire Custom Event, with detail</button>
39+
</div>
40+
<pre id="output">
41+
{this.output}
42+
</pre>
43+
</div>
44+
);
45+
}
46+
47+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf8">
3+
<script src="/build/testapp.js"></script>
4+
5+
<custom-event></custom-event>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { setupDomTests, waitForChanges } from '../util';
2+
3+
describe('custom event', () => {
4+
const { setupDom, tearDownDom } = setupDomTests(document);
5+
let app: HTMLElement;
6+
7+
beforeEach(async () => {
8+
app = await setupDom('/custom-event/index.html');
9+
});
10+
afterEach(tearDownDom);
11+
12+
it('should fire raw custom event', async () => {
13+
const btnNoDetail = app.querySelector('#btnNoDetail') as HTMLButtonElement;
14+
const btnWithDetail = app.querySelector('#btnWithDetail') as HTMLButtonElement;
15+
const output = app.querySelector('#output') as HTMLDivElement;
16+
17+
btnNoDetail.click();
18+
await waitForChanges();
19+
20+
expect(output.textContent.trim()).toBe('eventNoDetail');
21+
22+
btnWithDetail.click();
23+
await waitForChanges();
24+
25+
expect(output.textContent.trim()).toBe('eventWithDetail 88');
26+
});
27+
28+
});

0 commit comments

Comments
 (0)