Skip to content

Commit 49615d1

Browse files
committed
Fix: make sure to call cleanup function
1 parent 4a20433 commit 49615d1

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

src/ReactHTMLElement.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ interface LooseShadowRoot extends ShadowRoot {
66
}
77

88
// See https://github.com/facebook/react/issues/9242#issuecomment-543117675
9-
function retargetReactEvents(container: Node, shadow: LooseShadowRoot): void {
9+
function retargetReactEvents(
10+
container: Node,
11+
shadow: LooseShadowRoot,
12+
): () => void {
1013
Object.defineProperty(container, 'ownerDocument', { value: shadow });
1114
/* eslint-disable no-param-reassign */
1215
shadow.defaultView = window;
@@ -20,7 +23,7 @@ function retargetReactEvents(container: Node, shadow: LooseShadowRoot): void {
2023
options: ElementCreationOptions,
2124
): Element => document.createElementNS(ns, tagName, options);
2225
shadow.createTextNode = (text: string): Text => document.createTextNode(text);
23-
forceRetarget(shadow);
26+
return forceRetarget(shadow);
2427
/* eslint-enable no-param-reassign */
2528
}
2629

@@ -31,34 +34,48 @@ class ReactHTMLElement extends HTMLElement {
3134

3235
private mountSelector: string;
3336

37+
private retargetCleanupFunction: () => void;
38+
3439
get mountPoint(): Element {
3540
if (this._mountPoint) return this._mountPoint;
3641

3742
const shadow = this.attachShadow({ mode: 'open' });
3843
shadow.innerHTML = this.template;
3944
this._mountPoint = shadow.querySelector(this.mountSelector) as Element;
4045

41-
retargetReactEvents(this._mountPoint, shadow);
46+
this.retargetCleanup = retargetReactEvents(this._mountPoint, shadow);
4247

4348
return this._mountPoint;
4449
}
4550

4651
set mountPoint(mount: Element) {
4752
this._mountPoint = mount;
4853
if (this.shadowRoot) {
49-
retargetReactEvents(mount, this.shadowRoot);
54+
this.retargetCleanup = retargetReactEvents(mount, this.shadowRoot);
5055
}
5156
}
5257

58+
get retargetCleanup(): () => void {
59+
return this.retargetCleanupFunction;
60+
}
61+
62+
set retargetCleanup(cleanupFunction: () => void) {
63+
// Ensure that we cleanup an old listeners before we forget the cleanup function.
64+
this.retargetCleanup();
65+
this.retargetCleanupFunction = cleanupFunction;
66+
}
67+
5368
disconnectedCallback(): void {
5469
if (!this._mountPoint) return;
70+
this.retargetCleanup();
5571
ReactDOM.unmountComponentAtNode(this._mountPoint);
5672
}
5773

5874
constructor(template = '<div></div>', mountSelector = 'div') {
5975
super();
6076
this.template = template;
6177
this.mountSelector = mountSelector;
78+
this.retargetCleanupFunction = () => {};
6279
}
6380
}
6481

src/forcedRetargeting.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const reactEvents = [
77
'onMouseOut',
88
'onMouseOver',
99
'onMouseUp',
10+
'onClick',
1011
];
1112

1213
function findReactProperty(item: any, propertyPrefix: string): any {

0 commit comments

Comments
 (0)