Skip to content

Commit 3c069b1

Browse files
committed
fix: update defined custom elements
1 parent 73922ea commit 3c069b1

File tree

3 files changed

+60
-1
lines changed

3 files changed

+60
-1
lines changed

packages/repl/src/lib/Output/ReplProxy.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ export default class ReplProxy {
2323
return this.handlers.on_error(event.data);
2424
case 'unhandledrejection':
2525
return this.handlers.on_unhandled_rejection(event.data);
26+
case 'iframe_reload':
27+
return this.handlers.on_iframe_reload(event.data);
2628
case 'console':
2729
if (event.data.command === 'info' && event.data.args[0]?.type === '__error') {
2830
const data = event.data.args[0];

packages/repl/src/lib/Output/Viewer.svelte

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@
7777
error.message = 'Uncaught (in promise): ' + error.message;
7878
push_logs({ command: 'error', args: [error] });
7979
},
80+
on_iframe_reload: () => {
81+
ready = false;
82+
},
8083
on_console: (log) => {
8184
switch (log.command) {
8285
case 'clear':
@@ -169,11 +172,65 @@
169172
console.error(err);
170173
}
171174
}
175+
window.__reset_custom_elements?.();
172176
173177
document.body.innerHTML = '';
174178
window._svelteTransitionManager = null;
175179
}
176180
181+
if (!window.__reset_custom_elements) {
182+
const registered = new Map();
183+
const define = CustomElementRegistry.prototype.define;
184+
CustomElementRegistry.prototype.define = function(name, el, options) {
185+
let ce = registered.get(name);
186+
if (ce) {
187+
if (ce.registered) {
188+
// trigger error of re-registering
189+
define.call(this, name, ce.el, options);
190+
}
191+
if (ce.options?.extends != options?.extends) {
192+
parent.postMessage({ action: 'iframe_reload' }, '*');
193+
location.reload();
194+
}
195+
ce.el = el;
196+
ce.registered = true;
197+
} else {
198+
ce = { el, options, registered: true };
199+
registered.set(name, ce);
200+
const Wrapper = class extends el {
201+
connectedCallback() {
202+
ce.el.prototype.connectedCallback?.apply(this, arguments);
203+
}
204+
disconnectedCallback() {
205+
ce.el.prototype.disconnectedCallback?.apply(this, arguments);
206+
}
207+
adoptedCallback() {
208+
ce.el.prototype.adoptedCallback?.apply(this, arguments);
209+
}
210+
};
211+
const DynamicWrapper = new Proxy(Wrapper, {
212+
construct: function (_, args, newTarget) {
213+
return Reflect.construct(ce.el, args, newTarget);
214+
}
215+
});
216+
try {
217+
define.call(this, name, DynamicWrapper, options);
218+
} catch (error) {
219+
console.error(error);
220+
throw new Error('Failed to define a custom element '+name);
221+
}
222+
}
223+
};
224+
window.__reset_custom_elements = () => {
225+
for (const ce of registered.values()) {
226+
if (ce.registered) {
227+
ce.el = HTMLElement;
228+
ce.registered = false;
229+
}
230+
}
231+
}
232+
}
233+
177234
const __repl_exports = ${bundle.client?.code};
178235
{
179236
const { mount, unmount, App, untrack } = __repl_exports;
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
export type Handlers = Record<
2-
'on_fetch_progress' | 'on_error' | 'on_unhandled_rejection' | 'on_console',
2+
'on_fetch_progress' | 'on_error' | 'on_unhandled_rejection' | 'on_iframe_reload' | 'on_console',
33
(data: any) => void
44
>;

0 commit comments

Comments
 (0)