Skip to content

Commit

Permalink
Implement built-in customElements proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
schlusslicht committed Apr 11, 2022
1 parent d718256 commit 8466115
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/shell/src/component/component.ts
@@ -1,3 +1,4 @@
import { customElements } from './registry';
import { createElement, render } from './runtime';

/**
Expand Down
49 changes: 49 additions & 0 deletions packages/shell/src/component/registry.ts
@@ -0,0 +1,49 @@
/**
* Internal weak mapping of all registered elements to their name.
*/
const elements = new WeakMap<CustomElementConstructor, string>();

/**
* Proxy around the built-in `customElements` object, maintaining a mapping of
* all registered elements and their corresponding names, which can be queried
* by calling `customElements.getName()`.
*
* @see https://github.com/WICG/webcomponents/issues/566
*/
const registry = new Proxy(customElements, {
get: (_, propertyKey: keyof CustomElementRegistry | 'getName') => {
switch (propertyKey) {
case 'define': return (
name: string,
constructor: CustomElementConstructor,
options?: ElementDefinitionOptions
) => {
customElements.define(name, constructor, options);
elements.set(constructor, name);
};

case 'getName': return (
constructor: CustomElementConstructor
) => {
let name = elements.get(constructor);

if (!name) {
try {
name = Reflect.construct(HTMLElement, [], constructor).localName;
elements.set(constructor, name as string);
} catch {
return undefined;
}
}

return name;
};

default: return customElements[propertyKey].bind(customElements);
}
}
}) as CustomElementRegistry & {
getName(constructor: CustomElementConstructor): string | undefined;
};

export { registry as customElements };

0 comments on commit 8466115

Please sign in to comment.