Skip to content

Commit 974ce1a

Browse files
author
Steve Orvell
committed
update to latest proposed spec
1 parent 3813889 commit 974ce1a

File tree

5 files changed

+233
-105
lines changed

5 files changed

+233
-105
lines changed

packages/scoped-custom-element-registry/src/scoped-custom-element-registry.ts

Lines changed: 82 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,7 @@ interface CustomHTMLElement {
7676

7777
interface CustomElementRegistry {
7878
_getDefinition(tagName: string): CustomElementDefinition | undefined;
79-
createElement(tagName: string): Node;
80-
cloneSubtree(node: Node): Node;
79+
initialize: (node: Node) => Node;
8180
}
8281

8382
interface CustomElementDefinition {
@@ -343,24 +342,7 @@ class ShimmedCustomElementsRegistry implements CustomElementRegistry {
343342
}
344343
}
345344

346-
['createElement'](localName: string) {
347-
creationContext.push(this);
348-
const el = document.createElement(localName);
349-
creationContext.pop();
350-
registryToSubtree(el, this);
351-
return el;
352-
}
353-
354-
['cloneSubtree'](node: Node) {
355-
creationContext.push(this);
356-
// Note, cannot use `cloneNode` here becuase the node may not be in this document
357-
const subtree = document.importNode(node, true);
358-
creationContext.pop();
359-
registryToSubtree(subtree, this);
360-
return subtree;
361-
}
362-
363-
['initializeSubtree'](node: Node) {
345+
['initialize'](node: Node) {
364346
registryToSubtree(node, this, true);
365347
return node;
366348
}
@@ -758,16 +740,91 @@ const customElementsDescriptor = {
758740
configurable: true,
759741
};
760742

743+
const {createElement, createElementNS, importNode} = Document.prototype;
744+
761745
Object.defineProperty(
762746
Element.prototype,
763747
'customElements',
764748
customElementsDescriptor
765749
);
766-
Object.defineProperty(
767-
Document.prototype,
768-
'customElements',
769-
customElementsDescriptor
770-
);
750+
Object.defineProperties(Document.prototype, {
751+
'customElements': customElementsDescriptor,
752+
'createElement': {
753+
value<K extends keyof HTMLElementTagNameMap>(
754+
this: Document,
755+
tagName: K,
756+
options?: ElementCreationOptions
757+
): HTMLElementTagNameMap[K] {
758+
const {customElements} = options ?? {};
759+
if (customElements === undefined) {
760+
return createElement.call(this, tagName) as HTMLElementTagNameMap[K];
761+
} else {
762+
creationContext.push(customElements);
763+
const el = createElement.call(
764+
this,
765+
tagName
766+
) as HTMLElementTagNameMap[K];
767+
creationContext.pop();
768+
registryToSubtree(el, customElements as ShimmedCustomElementsRegistry);
769+
return el;
770+
}
771+
},
772+
enumerable: true,
773+
configurable: true,
774+
},
775+
'createElementNS': {
776+
value<K extends keyof HTMLElementTagNameMap>(
777+
this: Document,
778+
namespace: string | null,
779+
tagName: K,
780+
options?: ElementCreationOptions
781+
): HTMLElementTagNameMap[K] {
782+
const {customElements} = options ?? {};
783+
if (customElements === undefined) {
784+
return createElementNS.call(
785+
this,
786+
namespace,
787+
tagName
788+
) as HTMLElementTagNameMap[K];
789+
} else {
790+
creationContext.push(customElements);
791+
const el = createElementNS.call(
792+
this,
793+
namespace,
794+
tagName
795+
) as HTMLElementTagNameMap[K];
796+
creationContext.pop();
797+
registryToSubtree(el, customElements as ShimmedCustomElementsRegistry);
798+
return el;
799+
}
800+
},
801+
enumerable: true,
802+
configurable: true,
803+
},
804+
'importNode': {
805+
value<T extends Node>(
806+
this: Document,
807+
node: T,
808+
options?: boolean | ImportNodeOptions
809+
): T {
810+
const deep = typeof options === 'boolean' ? options : !options?.selfOnly;
811+
const {customElements} = (options ?? {}) as ImportNodeOptions;
812+
if (customElements === undefined) {
813+
return importNode.call(this, node, deep) as T;
814+
}
815+
creationContext.push(customElements);
816+
const imported = importNode.call(this, node, deep) as T;
817+
creationContext.pop();
818+
registryToSubtree(
819+
imported,
820+
customElements as ShimmedCustomElementsRegistry
821+
);
822+
return imported;
823+
},
824+
enumerable: true,
825+
configurable: true,
826+
},
827+
});
771828
Object.defineProperty(
772829
ShadowRoot.prototype,
773830
'customElements',

packages/scoped-custom-element-registry/src/types.d.ts

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,7 @@ export {};
33
declare global {
44
interface CustomElementRegistry {
55
// This overload is for roots that use the global registry
6-
createElement<K extends keyof HTMLElementTagNameMap>(
7-
tagName: K,
8-
options?: ElementCreationOptions
9-
): HTMLElementTagNameMap[K];
10-
// This overload is for roots that use a scoped registry
11-
createElement<K extends keyof BuiltInHTMLElementTagNameMap>(
12-
tagName: K,
13-
options?: ElementCreationOptions
14-
): BuiltInHTMLElementTagNameMap[K];
15-
createElement(
16-
tagName: string,
17-
options?: ElementCreationOptions
18-
): HTMLElement;
19-
cloneSubtree(node: Node): Node;
20-
initializeSubtree: (node: Node) => Node;
6+
initialize: (node: Node) => Node;
217
}
228

239
interface ShadowRootInit {
@@ -30,6 +16,21 @@ declare global {
3016

3117
interface Document {
3218
readonly customElements: CustomElementRegistry | null;
19+
createElement<K extends keyof HTMLElementTagNameMap>(
20+
tagName: K,
21+
options?: ElementCreationOptions
22+
): HTMLElementTagNameMap[K];
23+
24+
createElementNS<K extends keyof HTMLElementTagNameMap>(
25+
namespace: string | null,
26+
tagName: K,
27+
options?: ElementCreationOptions
28+
): HTMLElementTagNameMap[K];
29+
30+
importNode<T extends Node>(
31+
node: T,
32+
options?: boolean | ImportNodeOptions
33+
): T;
3334
}
3435

3536
interface Element {
@@ -40,6 +41,16 @@ declare global {
4041
customElements?: CustomElementRegistry;
4142
}
4243

44+
interface ImportNodeOptions {
45+
selfOnly?: boolean;
46+
customElements?: CustomElementRegistry;
47+
}
48+
49+
interface ElementCreationOptions {
50+
is?: string;
51+
customElements?: CustomElementRegistry;
52+
}
53+
4354
/*
4455
* Many custom element definitions will add themselves to the global
4556
* HTMLElementTagNameMap interface. Using that interface in

0 commit comments

Comments
 (0)