@fluid-topics/ft-wc-utils 1.0.63 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- import "../lib/scoped-custom-element-registry.js";
1
+ import "@webcomponents/scoped-custom-element-registry/src/scoped-custom-element-registry.js";
@@ -1,4 +1,4 @@
1
- import "../lib/scoped-custom-element-registry.js";
1
+ import "@webcomponents/scoped-custom-element-registry/src/scoped-custom-element-registry.js";
2
2
  try {
3
3
  // Throws expected error to replace default window.customElements.define
4
4
  //@ts-ignore
@@ -1,17 +1,15 @@
1
1
  !function(){
2
2
  /**
3
- * @license
4
- * Copyright (c) 2020 The Polymer Project Authors. All rights reserved.
5
- * This code may only be used under the BSD style license found at
6
- * http://polymer.github.io/LICENSE.txt
7
- * The complete set of authors may be found at
8
- * http://polymer.github.io/AUTHORS.txt
9
- * The complete set of contributors may be found at
10
- * http://polymer.github.io/CONTRIBUTORS.txt
11
- * Code distributed by Google as part of the polymer project is also
12
- * subject to an additional IP rights grant found at
13
- * http://polymer.github.io/PATENTS.txt
14
- *
15
- * @see https://github.com/webcomponents/polyfills/tree/master/packages/scoped-custom-element-registry
16
- */
17
- if(!ShadowRoot.prototype.createElement){const t=window.HTMLElement,e=window.customElements.define,n=window.customElements.get,s=window.customElements,o=new WeakMap,i=new WeakMap,c=new WeakMap,r=new WeakMap;let a;window.CustomElementRegistry=class{constructor(){this._definitionsByTag=new Map,this._definitionsByClass=new Map,this._whenDefinedPromises=new Map,this._awaitingUpgrade=new Map}define(t,o){if(t=t.toLowerCase(),void 0!==this._getDefinition(t))throw new DOMException(`Failed to execute 'define' on 'CustomElementRegistry': the name "${t}" has already been used with this registry`);if(void 0!==this._definitionsByClass.get(o))throw new DOMException("Failed to execute 'define' on 'CustomElementRegistry': this constructor has already been used with this registry");const r=o.prototype.attributeChangedCallback,a=new Set(o.observedAttributes||[]);w(o,a,r);const l={elementClass:o,connectedCallback:o.prototype.connectedCallback,disconnectedCallback:o.prototype.disconnectedCallback,adoptedCallback:o.prototype.adoptedCallback,attributeChangedCallback:r,formAssociated:o.formAssociated,formAssociatedCallback:o.prototype.formAssociatedCallback,formDisabledCallback:o.prototype.formDisabledCallback,formResetCallback:o.prototype.formResetCallback,formStateRestoreCallback:o.prototype.formStateRestoreCallback,observedAttributes:a};this._definitionsByTag.set(t,l),this._definitionsByClass.set(o,l);let h=n.call(s,t);h||(h=d(t),e.call(s,t,h)),this===window.customElements&&(c.set(o,l),l.standInClass=h);const u=this._awaitingUpgrade.get(t);if(u){this._awaitingUpgrade.delete(t);for(const t of u)i.delete(t),m(t,l,!0)}const f=this._whenDefinedPromises.get(t);return void 0!==f&&(f.resolve(o),this._whenDefinedPromises.delete(t)),o}upgrade(){b.push(this),s.upgrade.apply(s,arguments),b.pop()}get(t){const e=this._definitionsByTag.get(t);return e?.elementClass}_getDefinition(t){return this._definitionsByTag.get(t)}whenDefined(t){const e=this._getDefinition(t);if(void 0!==e)return Promise.resolve(e.elementClass);let n=this._whenDefinedPromises.get(t);return void 0===n&&(n={},n.promise=new Promise((t=>n.resolve=t)),this._whenDefinedPromises.set(t,n)),n.promise}_upgradeWhenDefined(t,e,n){let s=this._awaitingUpgrade.get(e);s||this._awaitingUpgrade.set(e,s=new Set),n?s.add(t):s.delete(t)}},window.HTMLElement=function(){let e=a;if(e)return a=void 0,e;const n=c.get(this.constructor);if(!n)throw new TypeError("Illegal constructor (custom element class must be registered with global customElements registry to be newable)");return e=Reflect.construct(t,[],n.standInClass),Object.setPrototypeOf(e,this.constructor.prototype),o.set(e,n),e},window.HTMLElement.prototype=t.prototype;const l=t=>t===document||t instanceof ShadowRoot,h=t=>{let e=t.getRootNode();if(!l(e)){const t=b[b.length-1];if(t instanceof CustomElementRegistry)return t;e=t.getRootNode(),l(e)||(e=r.get(e)?.getRootNode()||document)}return e.customElements},d=e=>class{static get formAssociated(){return!0}constructor(){const n=Reflect.construct(t,[],this.constructor);Object.setPrototypeOf(n,HTMLElement.prototype);const s=h(n)||window.customElements,o=s._getDefinition(e);return o?m(n,o):i.set(n,s),n}connectedCallback(){const t=o.get(this);t?t.connectedCallback&&t.connectedCallback.apply(this,arguments):i.get(this)._upgradeWhenDefined(this,e,!0)}disconnectedCallback(){const t=o.get(this);t?t.disconnectedCallback&&t.disconnectedCallback.apply(this,arguments):i.get(this)._upgradeWhenDefined(this,e,!1)}adoptedCallback(){const t=o.get(this);t?.adoptedCallback?.apply(this,arguments)}formAssociatedCallback(){const t=o.get(this);t&&t.formAssociated&&t?.formAssociatedCallback?.apply(this,arguments)}formDisabledCallback(){const t=o.get(this);t?.formAssociated&&t?.formDisabledCallback?.apply(this,arguments)}formResetCallback(){const t=o.get(this);t?.formAssociated&&t?.formResetCallback?.apply(this,arguments)}formStateRestoreCallback(){const t=o.get(this);t?.formAssociated&&t?.formStateRestoreCallback?.apply(this,arguments)}},w=(t,e,n)=>{if(0===e.size||void 0===n)return;const s=t.prototype.setAttribute;s&&(t.prototype.setAttribute=function(t,o){const i=t.toLowerCase();if(e.has(i)){const t=this.getAttribute(i);s.call(this,i,o),n.call(this,i,t,o)}else s.call(this,i,o)});const o=t.prototype.removeAttribute;o&&(t.prototype.removeAttribute=function(t){const s=t.toLowerCase();if(e.has(s)){const t=this.getAttribute(s);o.call(this,s),n.call(this,s,t,null)}else o.call(this,s)})},u=e=>{const n=Object.getPrototypeOf(e);if(n!==window.HTMLElement)return n===t||"HTMLElement"===n?.prototype?.constructor?.name?Object.setPrototypeOf(e,window.HTMLElement):u(n)},m=(t,e,n=!1)=>{Object.setPrototypeOf(t,e.elementClass.prototype),o.set(t,e),a=t;try{new e.elementClass}catch(t){u(e.elementClass),new e.elementClass}e.observedAttributes.forEach((n=>{t.hasAttribute(n)&&e.attributeChangedCallback.call(t,n,null,t.getAttribute(n))})),n&&e.connectedCallback&&t.isConnected&&e.connectedCallback.call(t)},f=Element.prototype.attachShadow;Element.prototype.attachShadow=function(t){const e=f.apply(this,arguments);return t.customElements&&(e.customElements=t.customElements),e};let b=[document];const E=(t,e,n=void 0)=>{const s=(n?Object.getPrototypeOf(n):t.prototype)[e];t.prototype[e]=function(){b.push(this);const t=s.apply(n||this,arguments);return void 0!==t&&r.set(t,this),b.pop(),t}};E(ShadowRoot,"createElement",document),E(ShadowRoot,"importNode",document),E(Element,"insertAdjacentHTML");const M=(t,e)=>{const n=Object.getOwnPropertyDescriptor(t.prototype,e);Object.defineProperty(t.prototype,e,{...n,set(t){b.push(this),n.set.call(this,t),b.pop()}})};if(M(Element,"innerHTML"),M(ShadowRoot,"innerHTML"),Object.defineProperty(window,"customElements",{value:new CustomElementRegistry,configurable:!0,writable:!0}),window.ElementInternals&&window.ElementInternals.prototype.setFormValue){const t=new WeakMap,e=HTMLElement.prototype.attachInternals,n=["setFormValue","setValidity","checkValidity","reportValidity"];HTMLElement.prototype.attachInternals=function(...n){const s=e.call(this,...n);return t.set(s,this),s},n.forEach((e=>{const n=window.ElementInternals.prototype,s=n[e];n[e]=function(...e){const n=t.get(this);if(!0!==o.get(n).formAssociated)throw new DOMException(`Failed to execute ${s} on 'ElementInternals': The target element is not a form-associated custom element.`);s?.call(this,...e)}}));class s extends Array{constructor(t){super(...t),this._elements=t}get value(){return this._elements.find((t=>!0===t.checked))?.value||""}}class i{constructor(t){const e=new Map;t.forEach(((t,n)=>{const s=t.getAttribute("name"),o=e.get(s)||[];this[+n]=t,o.push(t),e.set(s,o)})),this.length=t.length,e.forEach(((t,e)=>{t&&(1===t.length?this[e]=t[0]:this[e]=new s(t))}))}namedItem(t){return this[t]}}const c=Object.getOwnPropertyDescriptor(HTMLFormElement.prototype,"elements");Object.defineProperty(HTMLFormElement.prototype,"elements",{get:function(){const t=c.get.call(this,[]),e=[];for(const n of t){const t=o.get(n);t&&!0!==t.formAssociated||e.push(n)}return new i(e)}})}}try{window.customElements.define("custom-element",null)}catch(t){const e=window.customElements.define;window.customElements.define=(t,n,s)=>{if(null!==n)try{e.bind(window.customElements)(t,n,s)}catch(e){console.info(t,n,s,e)}}}}();
3
+ * @license
4
+ * Copyright (c) 2020 The Polymer Project Authors. All rights reserved.
5
+ * This code may only be used under the BSD style license found at
6
+ * http://polymer.github.io/LICENSE.txt
7
+ * The complete set of authors may be found at
8
+ * http://polymer.github.io/AUTHORS.txt
9
+ * The complete set of contributors may be found at
10
+ * http://polymer.github.io/CONTRIBUTORS.txt
11
+ * Code distributed by Google as part of the polymer project is also
12
+ * subject to an additional IP rights grant found at
13
+ * http://polymer.github.io/PATENTS.txt
14
+ */
15
+ if(!ShadowRoot.prototype.createElement){const t=window.HTMLElement,e=window.customElements.define,n=window.customElements.get,s=window.customElements,o=new WeakMap,i=new WeakMap,c=new WeakMap,r=new WeakMap;let a;window.CustomElementRegistry=class{constructor(){this._definitionsByTag=new Map,this._definitionsByClass=new Map,this._whenDefinedPromises=new Map,this._awaitingUpgrade=new Map}define(t,o){if(t=t.toLowerCase(),void 0!==this._getDefinition(t))throw new DOMException(`Failed to execute 'define' on 'CustomElementRegistry': the name "${t}" has already been used with this registry`);if(void 0!==this._definitionsByClass.get(o))throw new DOMException("Failed to execute 'define' on 'CustomElementRegistry': this constructor has already been used with this registry");const r=o.prototype.attributeChangedCallback,a=new Set(o.observedAttributes||[]);w(o,a,r);const l={elementClass:o,connectedCallback:o.prototype.connectedCallback,disconnectedCallback:o.prototype.disconnectedCallback,adoptedCallback:o.prototype.adoptedCallback,attributeChangedCallback:r,formAssociated:o.formAssociated,formAssociatedCallback:o.prototype.formAssociatedCallback,formDisabledCallback:o.prototype.formDisabledCallback,formResetCallback:o.prototype.formResetCallback,formStateRestoreCallback:o.prototype.formStateRestoreCallback,observedAttributes:a};this._definitionsByTag.set(t,l),this._definitionsByClass.set(o,l);let h=n.call(s,t);h||(h=d(t),e.call(s,t,h)),this===window.customElements&&(c.set(o,l),l.standInClass=h);const u=this._awaitingUpgrade.get(t);if(u){this._awaitingUpgrade.delete(t);for(const t of u)i.delete(t),m(t,l,!0)}const f=this._whenDefinedPromises.get(t);return void 0!==f&&(f.resolve(o),this._whenDefinedPromises.delete(t)),o}upgrade(){b.push(this),s.upgrade.apply(s,arguments),b.pop()}get(t){const e=this._definitionsByTag.get(t);return e?.elementClass}_getDefinition(t){return this._definitionsByTag.get(t)}whenDefined(t){const e=this._getDefinition(t);if(void 0!==e)return Promise.resolve(e.elementClass);let n=this._whenDefinedPromises.get(t);return void 0===n&&(n={},n.promise=new Promise((t=>n.resolve=t)),this._whenDefinedPromises.set(t,n)),n.promise}_upgradeWhenDefined(t,e,n){let s=this._awaitingUpgrade.get(e);s||this._awaitingUpgrade.set(e,s=new Set),n?s.add(t):s.delete(t)}},window.HTMLElement=function(){let e=a;if(e)return a=void 0,e;const n=c.get(this.constructor);if(!n)throw new TypeError("Illegal constructor (custom element class must be registered with global customElements registry to be newable)");return e=Reflect.construct(t,[],n.standInClass),Object.setPrototypeOf(e,this.constructor.prototype),o.set(e,n),e},window.HTMLElement.prototype=t.prototype;const l=t=>t===document||t instanceof ShadowRoot,h=t=>{let e=t.getRootNode();if(!l(e)){const t=b[b.length-1];if(t instanceof CustomElementRegistry)return t;e=t.getRootNode(),l(e)||(e=r.get(e)?.getRootNode()||document)}return e.customElements},d=e=>class{static get formAssociated(){return!0}constructor(){const n=Reflect.construct(t,[],this.constructor);Object.setPrototypeOf(n,HTMLElement.prototype);const s=h(n)||window.customElements,o=s._getDefinition(e);return o?m(n,o):i.set(n,s),n}connectedCallback(){const t=o.get(this);t?t.connectedCallback&&t.connectedCallback.apply(this,arguments):i.get(this)._upgradeWhenDefined(this,e,!0)}disconnectedCallback(){const t=o.get(this);t?t.disconnectedCallback&&t.disconnectedCallback.apply(this,arguments):i.get(this)._upgradeWhenDefined(this,e,!1)}adoptedCallback(){const t=o.get(this);t?.adoptedCallback?.apply(this,arguments)}formAssociatedCallback(){const t=o.get(this);t&&t.formAssociated&&t?.formAssociatedCallback?.apply(this,arguments)}formDisabledCallback(){const t=o.get(this);t?.formAssociated&&t?.formDisabledCallback?.apply(this,arguments)}formResetCallback(){const t=o.get(this);t?.formAssociated&&t?.formResetCallback?.apply(this,arguments)}formStateRestoreCallback(){const t=o.get(this);t?.formAssociated&&t?.formStateRestoreCallback?.apply(this,arguments)}},w=(t,e,n)=>{if(0===e.size||void 0===n)return;const s=t.prototype.setAttribute;s&&(t.prototype.setAttribute=function(t,o){const i=t.toLowerCase();if(e.has(i)){const t=this.getAttribute(i);s.call(this,i,o),n.call(this,i,t,o)}else s.call(this,i,o)});const o=t.prototype.removeAttribute;o&&(t.prototype.removeAttribute=function(t){const s=t.toLowerCase();if(e.has(s)){const t=this.getAttribute(s);o.call(this,s),n.call(this,s,t,null)}else o.call(this,s)});const i=t.prototype.toggleAttribute;i&&(t.prototype.toggleAttribute=function(t,s){const o=t.toLowerCase();if(e.has(o)){const t=this.getAttribute(o);i.call(this,o,s);const e=this.getAttribute(o);n.call(this,o,t,e)}else i.call(this,o,s)})},u=e=>{const n=Object.getPrototypeOf(e);if(n!==window.HTMLElement)return n===t?Object.setPrototypeOf(e,window.HTMLElement):u(n)},m=(t,e,n=!1)=>{Object.setPrototypeOf(t,e.elementClass.prototype),o.set(t,e),a=t;try{new e.elementClass}catch(t){u(e.elementClass),new e.elementClass}e.attributeChangedCallback&&e.observedAttributes.forEach((n=>{t.hasAttribute(n)&&e.attributeChangedCallback.call(t,n,null,t.getAttribute(n))})),n&&e.connectedCallback&&t.isConnected&&e.connectedCallback.call(t)},f=Element.prototype.attachShadow;Element.prototype.attachShadow=function(t){const e=f.apply(this,arguments);return t.customElements&&(e.customElements=t.customElements),e};let b=[document];const k=(t,e,n=void 0)=>{const s=(n?Object.getPrototypeOf(n):t.prototype)[e];t.prototype[e]=function(){b.push(this);const t=s.apply(n||this,arguments);return void 0!==t&&r.set(t,this),b.pop(),t}};k(ShadowRoot,"createElement",document),k(ShadowRoot,"importNode",document),k(Element,"insertAdjacentHTML");const p=(t,e)=>{const n=Object.getOwnPropertyDescriptor(t.prototype,e);Object.defineProperty(t.prototype,e,{...n,set(t){b.push(this),n.set.call(this,t),b.pop()}})};if(p(Element,"innerHTML"),p(ShadowRoot,"innerHTML"),Object.defineProperty(window,"customElements",{value:new CustomElementRegistry,configurable:!0,writable:!0}),window.ElementInternals&&window.ElementInternals.prototype.setFormValue){const t=new WeakMap,e=HTMLElement.prototype.attachInternals,n=["setFormValue","setValidity","checkValidity","reportValidity"];HTMLElement.prototype.attachInternals=function(...n){const s=e.call(this,...n);return t.set(s,this),s},n.forEach((e=>{const n=window.ElementInternals.prototype,s=n[e];n[e]=function(...e){const n=t.get(this);if(!0===o.get(n).formAssociated)return s?.call(this,...e);throw new DOMException(`Failed to execute ${s} on 'ElementInternals': The target element is not a form-associated custom element.`)}}));class s extends Array{constructor(t){super(...t),this._elements=t}get value(){return this._elements.find((t=>!0===t.checked))?.value||""}}class i{constructor(t){const e=new Map;t.forEach(((t,n)=>{const s=t.getAttribute("name"),o=e.get(s)||[];this[+n]=t,o.push(t),e.set(s,o)})),this.length=t.length,e.forEach(((t,e)=>{t&&(1===t.length?this[e]=t[0]:this[e]=new s(t))}))}namedItem(t){return this[t]}}const c=Object.getOwnPropertyDescriptor(HTMLFormElement.prototype,"elements");Object.defineProperty(HTMLFormElement.prototype,"elements",{get:function(){const t=c.get.call(this,[]),e=[];for(const n of t){const t=o.get(n);t&&!0!==t.formAssociated||e.push(n)}return new i(e)}})}}try{window.customElements.define("custom-element",null)}catch(t){const e=window.customElements.define;window.customElements.define=(t,n,s)=>{if(null!==n)try{e.bind(window.customElements)(t,n,s)}catch(e){console.info(t,n,s,e)}}}}();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluid-topics/ft-wc-utils",
3
- "version": "1.0.63",
3
+ "version": "1.1.1",
4
4
  "description": "Internal web components tools",
5
5
  "author": "Fluid Topics <devtopics@antidot.net>",
6
6
  "license": "ISC",
@@ -13,10 +13,11 @@
13
13
  "lib/*"
14
14
  ],
15
15
  "dependencies": {
16
- "@fluid-topics/design-system-variables": "0.0.17",
17
- "@fluid-topics/public-api": "1.0.50",
16
+ "@fluid-topics/design-system-variables": "0.0.18",
17
+ "@fluid-topics/public-api": "1.0.51",
18
18
  "@reduxjs/toolkit": "1.9.5",
19
- "lit": "2.7.2"
19
+ "@webcomponents/scoped-custom-element-registry": "0.0.9",
20
+ "lit": "3.1.0"
20
21
  },
21
- "gitHead": "020d13bf82a28437f4d7a7395ad9b628bc4342f1"
22
+ "gitHead": "ceae4aed142c27cbf6034f45bb6e3f562163cc15"
22
23
  }
@@ -1,556 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2020 The Polymer Project Authors. All rights reserved.
4
- * This code may only be used under the BSD style license found at
5
- * http://polymer.github.io/LICENSE.txt
6
- * The complete set of authors may be found at
7
- * http://polymer.github.io/AUTHORS.txt
8
- * The complete set of contributors may be found at
9
- * http://polymer.github.io/CONTRIBUTORS.txt
10
- * Code distributed by Google as part of the polymer project is also
11
- * subject to an additional IP rights grant found at
12
- * http://polymer.github.io/PATENTS.txt
13
- *
14
- * @see https://github.com/webcomponents/polyfills/tree/master/packages/scoped-custom-element-registry
15
- */
16
- if (!ShadowRoot.prototype.createElement) {
17
- const NativeHTMLElement = window.HTMLElement;
18
- const nativeDefine = window.customElements.define;
19
- const nativeGet = window.customElements.get;
20
- const nativeRegistry = window.customElements;
21
-
22
- const definitionForElement = new WeakMap();
23
- const pendingRegistryForElement = new WeakMap();
24
- const globalDefinitionForConstructor = new WeakMap();
25
- // TBD: This part of the spec proposal is unclear:
26
- // > Another option for looking up registries is to store an element's
27
- // > originating registry with the element. The Chrome DOM team was concerned
28
- // > about the small additional memory overhead on all elements. Looking up the
29
- // > root avoids this.
30
- const scopeForElement = new WeakMap();
31
-
32
- // Constructable CE registry class, which uses the native CE registry to
33
- // register stand-in elements that can delegate out to CE classes registered
34
- // in scoped registries
35
- window.CustomElementRegistry = class {
36
- constructor() {
37
- this._definitionsByTag = new Map();
38
- this._definitionsByClass = new Map();
39
- this._whenDefinedPromises = new Map();
40
- this._awaitingUpgrade = new Map();
41
- }
42
-
43
- define(tagName, elementClass) {
44
- tagName = tagName.toLowerCase();
45
- if (this._getDefinition(tagName) !== undefined) {
46
- throw new DOMException(
47
- `Failed to execute 'define' on 'CustomElementRegistry': the name "${ tagName }" has already been used with this registry`
48
- );
49
- }
50
- if (this._definitionsByClass.get(elementClass) !== undefined) {
51
- throw new DOMException(
52
- `Failed to execute 'define' on 'CustomElementRegistry': this constructor has already been used with this registry`
53
- );
54
- }
55
- // Since observedAttributes can't change, we approximate it by patching
56
- // set/removeAttribute on the user's class
57
- const attributeChangedCallback =
58
- elementClass.prototype.attributeChangedCallback;
59
- const observedAttributes = new Set(elementClass.observedAttributes || []);
60
- patchAttributes(
61
- elementClass,
62
- observedAttributes,
63
- attributeChangedCallback
64
- );
65
- // Register the definition
66
- const definition = {
67
- elementClass,
68
- connectedCallback: elementClass.prototype.connectedCallback,
69
- disconnectedCallback: elementClass.prototype.disconnectedCallback,
70
- adoptedCallback: elementClass.prototype.adoptedCallback,
71
- attributeChangedCallback,
72
- 'formAssociated': elementClass['formAssociated'],
73
- 'formAssociatedCallback':
74
- elementClass.prototype['formAssociatedCallback'],
75
- 'formDisabledCallback': elementClass.prototype['formDisabledCallback'],
76
- 'formResetCallback': elementClass.prototype['formResetCallback'],
77
- 'formStateRestoreCallback':
78
- elementClass.prototype['formStateRestoreCallback'],
79
- observedAttributes,
80
- };
81
- this._definitionsByTag.set(tagName, definition);
82
- this._definitionsByClass.set(elementClass, definition);
83
- // Register a stand-in class which will handle the registry lookup & delegation
84
- let standInClass = nativeGet.call(nativeRegistry, tagName);
85
- if (!standInClass) {
86
- standInClass = createStandInElement(tagName);
87
- nativeDefine.call(nativeRegistry, tagName, standInClass);
88
- }
89
- if (this === window.customElements) {
90
- globalDefinitionForConstructor.set(elementClass, definition);
91
- definition.standInClass = standInClass;
92
- }
93
- // Upgrade any elements created in this scope before define was called
94
- const awaiting = this._awaitingUpgrade.get(tagName);
95
- if (awaiting) {
96
- this._awaitingUpgrade.delete(tagName);
97
- for (const element of awaiting) {
98
- pendingRegistryForElement.delete(element);
99
- customize(element, definition, true);
100
- }
101
- }
102
- // Flush whenDefined callbacks
103
- const info = this._whenDefinedPromises.get(tagName);
104
- if (info !== undefined) {
105
- info.resolve(elementClass);
106
- this._whenDefinedPromises.delete(tagName);
107
- }
108
- return elementClass;
109
- }
110
-
111
- upgrade() {
112
- creationContext.push(this);
113
- nativeRegistry.upgrade.apply(nativeRegistry, arguments);
114
- creationContext.pop();
115
- }
116
-
117
- get(tagName) {
118
- const definition = this._definitionsByTag.get(tagName);
119
- return definition?.elementClass;
120
- }
121
-
122
- _getDefinition(tagName) {
123
- return this._definitionsByTag.get(tagName);
124
- }
125
-
126
- whenDefined(tagName) {
127
- const definition = this._getDefinition(tagName);
128
- if (definition !== undefined) {
129
- return Promise.resolve(definition.elementClass);
130
- }
131
- let info = this._whenDefinedPromises.get(tagName);
132
- if (info === undefined) {
133
- info = {};
134
- info.promise = new Promise((r) => (info.resolve = r));
135
- this._whenDefinedPromises.set(tagName, info);
136
- }
137
- return info.promise;
138
- }
139
-
140
- _upgradeWhenDefined(element, tagName, shouldUpgrade) {
141
- let awaiting = this._awaitingUpgrade.get(tagName);
142
- if (!awaiting) {
143
- this._awaitingUpgrade.set(tagName, (awaiting = new Set()));
144
- }
145
- if (shouldUpgrade) {
146
- awaiting.add(element);
147
- } else {
148
- awaiting.delete(element);
149
- }
150
- }
151
- };
152
-
153
- // User extends this HTMLElement, which returns the CE being upgraded
154
- let upgradingInstance;
155
- window.HTMLElement = function HTMLElement() {
156
- // Upgrading case: the StandInElement constructor was run by the browser's
157
- // native custom elements and we're in the process of running the
158
- // "constructor-call trick" on the natively constructed instance, so just
159
- // return that here
160
- let instance = upgradingInstance;
161
- if (instance) {
162
- upgradingInstance = undefined;
163
- return instance;
164
- }
165
- // Construction case: we need to construct the StandInElement and return
166
- // it; note the current spec proposal only allows new'ing the constructor
167
- // of elements registered with the global registry
168
- const definition = globalDefinitionForConstructor.get(this.constructor);
169
- if (!definition) {
170
- throw new TypeError(
171
- 'Illegal constructor (custom element class must be registered with global customElements registry to be newable)'
172
- );
173
- }
174
- instance = Reflect.construct(
175
- NativeHTMLElement,
176
- [],
177
- definition.standInClass
178
- );
179
- Object.setPrototypeOf(instance, this.constructor.prototype);
180
- definitionForElement.set(instance, definition);
181
- return instance;
182
- };
183
- window.HTMLElement.prototype = NativeHTMLElement.prototype;
184
-
185
- // Helpers to return the scope for a node where its registry would be located
186
- const isValidScope = (node) =>
187
- node === document || node instanceof ShadowRoot;
188
- const registryForNode = (node) => {
189
- // TODO: the algorithm for finding the scope is a bit up in the air; assigning
190
- // a one-time scope at creation time would require walking every tree ever
191
- // created, which is avoided for now
192
- let scope = node.getRootNode();
193
- // If we're not attached to the document (i.e. in a disconnected tree or
194
- // fragment), we need to get the scope from the creation context; that should
195
- // be a Document or ShadowRoot, unless it was created via innerHTML
196
- if (!isValidScope(scope)) {
197
- const context = creationContext[creationContext.length - 1];
198
- // When upgrading via registry.upgrade(), the registry itself is put on the
199
- // creationContext stack
200
- if (context instanceof CustomElementRegistry) {
201
- return context;
202
- }
203
- // Otherwise, get the root node of the element this was created from
204
- scope = context.getRootNode();
205
- // The creation context wasn't a Document or ShadowRoot or in one; this
206
- // means we're being innerHTML'ed into a disconnected element; for now, we
207
- // hope that root node was created imperatively, where we stash _its_
208
- // scopeForElement. Beyond that, we'd need more costly tracking.
209
- if (!isValidScope(scope)) {
210
- scope = scopeForElement.get(scope)?.getRootNode() || document;
211
- }
212
- }
213
- return scope.customElements;
214
- };
215
-
216
- // Helper to create stand-in element for each tagName registered that delegates
217
- // out to the registry for the given element
218
- const createStandInElement = (tagName) => {
219
- return class ScopedCustomElementBase {
220
- static get ['formAssociated']() {
221
- return true;
222
- }
223
-
224
- constructor() {
225
- // Create a raw HTMLElement first
226
- const instance = Reflect.construct(
227
- NativeHTMLElement,
228
- [],
229
- this.constructor
230
- );
231
- // We need to install the minimum HTMLElement prototype so that
232
- // scopeForNode can use DOM API to determine our construction scope;
233
- // upgrade will eventually install the full CE prototype
234
- Object.setPrototypeOf(instance, HTMLElement.prototype);
235
- // Get the node's scope, and its registry (falls back to global registry)
236
- const registry = registryForNode(instance) || window.customElements;
237
- const definition = registry._getDefinition(tagName);
238
- if (definition) {
239
- customize(instance, definition);
240
- } else {
241
- pendingRegistryForElement.set(instance, registry);
242
- }
243
- return instance;
244
- }
245
-
246
- connectedCallback() {
247
- const definition = definitionForElement.get(this);
248
- if (definition) {
249
- // Delegate out to user callback
250
- definition.connectedCallback &&
251
- definition.connectedCallback.apply(this, arguments);
252
- } else {
253
- // Register for upgrade when defined (only when connected, so we don't leak)
254
- pendingRegistryForElement
255
- .get(this)
256
- ._upgradeWhenDefined(this, tagName, true);
257
- }
258
- }
259
-
260
- disconnectedCallback() {
261
- const definition = definitionForElement.get(this);
262
- if (definition) {
263
- // Delegate out to user callback
264
- definition.disconnectedCallback &&
265
- definition.disconnectedCallback.apply(this, arguments);
266
- } else {
267
- // Un-register for upgrade when defined (so we don't leak)
268
- pendingRegistryForElement
269
- .get(this)
270
- ._upgradeWhenDefined(this, tagName, false);
271
- }
272
- }
273
-
274
- adoptedCallback() {
275
- const definition = definitionForElement.get(this);
276
- definition?.adoptedCallback?.apply(this, arguments);
277
- }
278
-
279
- // Form-associated custom elements lifecycle methods
280
- ['formAssociatedCallback']() {
281
- const definition = definitionForElement.get(this);
282
- if (definition && definition['formAssociated']) {
283
- definition?.['formAssociatedCallback']?.apply(this, arguments);
284
- }
285
- }
286
-
287
- ['formDisabledCallback']() {
288
- const definition = definitionForElement.get(this);
289
- if (definition?.['formAssociated']) {
290
- definition?.['formDisabledCallback']?.apply(this, arguments);
291
- }
292
- }
293
-
294
- ['formResetCallback']() {
295
- const definition = definitionForElement.get(this);
296
- if (definition?.['formAssociated']) {
297
- definition?.['formResetCallback']?.apply(this, arguments);
298
- }
299
- }
300
-
301
- ['formStateRestoreCallback']() {
302
- const definition = definitionForElement.get(this);
303
- if (definition?.['formAssociated']) {
304
- definition?.['formStateRestoreCallback']?.apply(this, arguments);
305
- }
306
- }
307
-
308
- // no attributeChangedCallback or observedAttributes since these
309
- // are simulated via setAttribute/removeAttribute patches
310
- };
311
- };
312
-
313
- // Helper to patch CE class setAttribute/getAttribute to implement
314
- // attributeChangedCallback
315
- const patchAttributes = (
316
- elementClass,
317
- observedAttributes,
318
- attributeChangedCallback
319
- ) => {
320
- if (
321
- observedAttributes.size === 0 ||
322
- attributeChangedCallback === undefined
323
- ) {
324
- return;
325
- }
326
- const setAttribute = elementClass.prototype.setAttribute;
327
- if (setAttribute) {
328
- elementClass.prototype.setAttribute = function (n, value) {
329
- const name = n.toLowerCase();
330
- if (observedAttributes.has(name)) {
331
- const old = this.getAttribute(name);
332
- setAttribute.call(this, name, value);
333
- attributeChangedCallback.call(this, name, old, value);
334
- } else {
335
- setAttribute.call(this, name, value);
336
- }
337
- };
338
- }
339
- const removeAttribute = elementClass.prototype.removeAttribute;
340
- if (removeAttribute) {
341
- elementClass.prototype.removeAttribute = function (n) {
342
- const name = n.toLowerCase();
343
- if (observedAttributes.has(name)) {
344
- const old = this.getAttribute(name);
345
- removeAttribute.call(this, name);
346
- attributeChangedCallback.call(this, name, old, null);
347
- } else {
348
- removeAttribute.call(this, name);
349
- }
350
- };
351
- }
352
- };
353
-
354
- // Helper to patch CE class hierarchy changing those CE classes created before applying the polyfill
355
- // to make them work with the new patched CustomElementsRegistry
356
- const patchHTMLElement = (elementClass) => {
357
- const parentClass = Object.getPrototypeOf(elementClass);
358
-
359
- if (parentClass !== window.HTMLElement) {
360
- if (parentClass === NativeHTMLElement || parentClass?.prototype?.constructor?.name === "HTMLElement") {
361
- return Object.setPrototypeOf(elementClass, window.HTMLElement);
362
- }
363
-
364
- return patchHTMLElement(parentClass);
365
- }
366
- };
367
-
368
- // Helper to upgrade an instance with a CE definition using "constructor call trick"
369
- const customize = (instance, definition, isUpgrade = false) => {
370
- Object.setPrototypeOf(instance, definition.elementClass.prototype);
371
- definitionForElement.set(instance, definition);
372
- upgradingInstance = instance;
373
- try {
374
- new definition.elementClass();
375
- } catch (_) {
376
- patchHTMLElement(definition.elementClass);
377
- new definition.elementClass();
378
- }
379
- // Approximate observedAttributes from the user class, since the stand-in element had none
380
- definition.observedAttributes.forEach((attr) => {
381
- if (instance.hasAttribute(attr)) {
382
- definition.attributeChangedCallback.call(
383
- instance,
384
- attr,
385
- null,
386
- instance.getAttribute(attr)
387
- );
388
- }
389
- });
390
- if (isUpgrade && definition.connectedCallback && instance.isConnected) {
391
- definition.connectedCallback.call(instance);
392
- }
393
- };
394
-
395
- // Patch attachShadow to set customElements on shadowRoot when provided
396
- const nativeAttachShadow = Element.prototype.attachShadow;
397
- Element.prototype.attachShadow = function (init) {
398
- const shadowRoot = nativeAttachShadow.apply(this, arguments);
399
- if (init.customElements) {
400
- shadowRoot.customElements = init.customElements;
401
- }
402
- return shadowRoot;
403
- };
404
-
405
- // Install scoped creation API on Element & ShadowRoot
406
- let creationContext = [ document ];
407
- const installScopedCreationMethod = (ctor, method, from = undefined) => {
408
- const native = (from ? Object.getPrototypeOf(from) : ctor.prototype)[
409
- method
410
- ];
411
- ctor.prototype[method] = function () {
412
- creationContext.push(this);
413
- const ret = native.apply(from || this, arguments);
414
- // For disconnected elements, note their creation scope so that e.g.
415
- // innerHTML into them will use the correct scope; note that
416
- // insertAdjacentHTML doesn't return an element, but that's fine since
417
- // it will have a parent that should have a scope
418
- if (ret !== undefined) {
419
- scopeForElement.set(ret, this);
420
- }
421
- creationContext.pop();
422
- return ret;
423
- };
424
- };
425
- installScopedCreationMethod(ShadowRoot, 'createElement', document);
426
- installScopedCreationMethod(ShadowRoot, 'importNode', document);
427
- installScopedCreationMethod(Element, 'insertAdjacentHTML');
428
-
429
- // Install scoped innerHTML on Element & ShadowRoot
430
- const installScopedCreationSetter = (ctor, name) => {
431
- const descriptor = Object.getOwnPropertyDescriptor(ctor.prototype, name);
432
- Object.defineProperty(ctor.prototype, name, {
433
- ...descriptor,
434
- set(value) {
435
- creationContext.push(this);
436
- descriptor.set.call(this, value);
437
- creationContext.pop();
438
- },
439
- });
440
- };
441
- installScopedCreationSetter(Element, 'innerHTML');
442
- installScopedCreationSetter(ShadowRoot, 'innerHTML');
443
-
444
- // Install global registry
445
- Object.defineProperty(window, 'customElements', {
446
- value: new CustomElementRegistry(),
447
- configurable: true,
448
- writable: true,
449
- });
450
-
451
- if (
452
- !!window['ElementInternals'] &&
453
- !!window['ElementInternals'].prototype['setFormValue']
454
- ) {
455
- const internalsToHostMap = new WeakMap();
456
- const attachInternals = HTMLElement.prototype['attachInternals'];
457
- const methods = [
458
- 'setFormValue',
459
- 'setValidity',
460
- 'checkValidity',
461
- 'reportValidity',
462
- ];
463
-
464
- HTMLElement.prototype['attachInternals'] = function (...args) {
465
- const internals = attachInternals.call(this, ...args);
466
- internalsToHostMap.set(internals, this);
467
- return internals;
468
- };
469
-
470
- methods.forEach((method) => {
471
- const proto = window['ElementInternals'].prototype;
472
- const originalMethod = proto[method];
473
-
474
- proto[method] = function (...args) {
475
- const host = internalsToHostMap.get(this);
476
- const definition = definitionForElement.get(host);
477
- if (definition['formAssociated'] === true) {
478
- originalMethod?.call(this, ...args);
479
- } else {
480
- throw new DOMException(
481
- `Failed to execute ${ originalMethod } on 'ElementInternals': The target element is not a form-associated custom element.`
482
- );
483
- }
484
- };
485
- });
486
-
487
- // Emulate the native RadioNodeList object
488
- class RadioNodeList extends Array {
489
- constructor(elements) {
490
- super(...elements);
491
- this._elements = elements;
492
- }
493
-
494
- get ['value']() {
495
- return (
496
- this._elements.find((element) => element['checked'] === true)
497
- ?.value || ''
498
- );
499
- }
500
- }
501
-
502
- // Emulate the native HTMLFormControlsCollection object
503
- class HTMLFormControlsCollection {
504
- constructor(elements) {
505
- const entries = new Map();
506
- elements.forEach((element, index) => {
507
- const name = element.getAttribute('name');
508
- const nameReference = entries.get(name) || [];
509
- this[+index] = element;
510
- nameReference.push(element);
511
- entries.set(name, nameReference);
512
- });
513
- this['length'] = elements.length;
514
- entries.forEach((value, key) => {
515
- if (!value) {
516
- return;
517
- }
518
- if (value.length === 1) {
519
- this[key] = value[0];
520
- } else {
521
- this[key] = new RadioNodeList(value);
522
- }
523
- });
524
- }
525
-
526
- ['namedItem'](key) {
527
- return this[key];
528
- }
529
- }
530
-
531
- // Override the built-in HTMLFormElements.prototype.elements getter
532
- const formElementsDescriptor = Object.getOwnPropertyDescriptor(
533
- HTMLFormElement.prototype,
534
- 'elements'
535
- );
536
-
537
- Object.defineProperty(HTMLFormElement.prototype, 'elements', {
538
- get: function () {
539
- const nativeElements = formElementsDescriptor.get.call(this, []);
540
-
541
- const include = [];
542
-
543
- for (const element of nativeElements) {
544
- const definition = definitionForElement.get(element);
545
-
546
- // Only purposefully formAssociated elements or built-ins will feature in elements
547
- if (!definition || definition['formAssociated'] === true) {
548
- include.push(element);
549
- }
550
- }
551
-
552
- return new HTMLFormControlsCollection(include);
553
- },
554
- });
555
- }
556
- }