@webreflection/elements 0.1.5 → 0.1.7
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.
- package/README.md +18 -2
- package/dist/auto.js +1 -0
- package/{min.js → dist/index-CUAunxU3.js} +2 -2
- package/index.js +3 -7
- package/native.js +6 -5
- package/package.json +4 -5
- package/types/native.d.ts +2 -2
package/README.md
CHANGED
|
@@ -18,6 +18,7 @@ HTML & SVG Custom Elements, glueing [qsa-observer](https://github.com/WebReflect
|
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
// native extends out of the box
|
|
21
|
+
// <h1 is="my-h1"></h1>
|
|
21
22
|
elements.define('my-h1', class MyH1 extends HTML.H1 {
|
|
22
23
|
// anything that works with classes works here
|
|
23
24
|
#private;
|
|
@@ -32,18 +33,33 @@ HTML & SVG Custom Elements, glueing [qsa-observer](https://github.com/WebReflect
|
|
|
32
33
|
// custom elements lifecycle (connected/disconnected/attributeChanged)
|
|
33
34
|
connectedCallback() {
|
|
34
35
|
console.log('connected', this.#private);
|
|
35
|
-
this.innerHTML = '
|
|
36
|
+
this.innerHTML = '@webreflection/elements 🥳';
|
|
36
37
|
}
|
|
37
38
|
});
|
|
38
39
|
|
|
40
|
+
// regular HTMLElement extends out of the box too
|
|
41
|
+
// <my-element></my-element>
|
|
42
|
+
elements.define('my-element', class MyElement extends HTML.Element {
|
|
43
|
+
connectedCallback() {
|
|
44
|
+
this.innerHTML = '<small>made with ❤️ by <a href="https://github.com/WebReflection/elements">@webreflection</a></small>';
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// as it is for customElements, whenDefined works both
|
|
49
|
+
// before and after an element has been defined
|
|
50
|
+
elements.whenDefined('my-element').then(Class => {
|
|
51
|
+
console.log(Class.name, 'defined');
|
|
52
|
+
});
|
|
53
|
+
|
|
39
54
|
</script>
|
|
40
55
|
<h1 is="my-h1"></h1>
|
|
56
|
+
<my-element></my-element>
|
|
41
57
|
```
|
|
42
58
|
|
|
43
59
|
Enjoy 👋
|
|
44
60
|
|
|
45
61
|
### Native Support Included
|
|
46
62
|
|
|
47
|
-
If your browser supports natively *HTML* custom elements builtin extends (i.e. Chrome/ium based), and *HTML* is all you want/need to extend 'cause *SVG* custom elements do not exist natively on the Web, you can use [@webreflection/elements/native](./native.js) export instead, which offers the **exact same API** without any dependency, hence it's lightweight, easier to reason about, and natively wonderful.
|
|
63
|
+
If your browser supports natively *HTML* custom elements builtin extends (i.e. Chrome/ium or Firefox based), and *HTML* is all you want/need to extend 'cause *SVG* custom elements do not exist natively on the Web, you can use [@webreflection/elements/native](./native.js) export instead, which offers the **exact same API** without any dependency, hence it's lightweight, easier to reason about, and natively wonderful.
|
|
48
64
|
|
|
49
65
|
If you don't know if that's supported and you would like to feature detect this ability, you can pick the [@webreflection/elements/auto](./auto.js) export insted.
|
package/dist/auto.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=new Map,t=document.createElement.bind(document),n=new Proxy(new Map,{get(n,s){let o=s.toLowerCase();return n.get(o)||((n,s)=>{let o=e.get(s);o||(o="element"===s?HTMLElement:t(s).constructor,e.set(s,o));class l extends o{static tag=s}return n.set(s,l),l})(n,o)}}),s=new Proxy(new Map,{get(){throw new DOMException("SVG extends not natively supported")}}),o={define:(e,t)=>{const n=[e,t];return"element"!==t.tag&&n.push({extends:t.tag}),customElements.define(...n)},get:e=>customElements.get(e),whenDefined:e=>customElements.whenDefined(e)};var l=Object.freeze({__proto__:null,HTML:n,SVG:s,elements:o});let{HTML:r,SVG:c,elements:m}=l;try{const e=class extends HTMLLIElement{};customElements.define("li-"+Date.now(),e,{extends:"li"}),new e}catch{({HTML:r,elements:m}=await import("./index-CUAunxU3.js"))}export{r as HTML,c as SVG,m as elements};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/*! (c) Andrea Giammarchi - ISC */
|
|
2
|
-
const e=!0,t=!1,o="querySelectorAll",r="querySelectorAll",{document:n,Element:s,MutationObserver:l,Set:a,WeakMap:c}=self,d=e=>r in e,{filter:i}=[];const{setPrototypeOf:u}=Object;const h="attributeChangedCallback",
|
|
3
|
-
/*! (c) Andrea Giammarchi - ISC */let b={HTML:"http://www.w3.org/1999/xhtml",SVG:"http://www.w3.org/2000/svg"};const g=[],m=new Map,v=new Map,{parse:S}=(u=>{const h=new c,
|
|
2
|
+
const e=!0,t=!1,o="querySelectorAll",r="querySelectorAll",{document:n,Element:s,MutationObserver:l,Set:a,WeakMap:c}=self,d=e=>r in e,{filter:i}=[];const{setPrototypeOf:u}=Object;const h="attributeChangedCallback",w="connectedCallback",f="disconnectedCallback";var p=(e,{MutationObserver:t,Element:o})=>{const r=new WeakSet,n=(e,t,o,s,l)=>{for(const a of e)(l||"querySelectorAll"in a)&&(s?t.has(a)||(t.add(a),o.delete(a),r.has(a)&&a[w]?.()):o.has(a)||(o.add(a),t.delete(a),r.has(a)&&a[f]?.()),l||n(a.querySelectorAll("*"),t,o,s,!0))},s=e=>{const t=new Set,o=new Set;for(const{addedNodes:r,removedNodes:s}of e)n(s,t,o,!1,!1),n(r,t,o,!0,!1)},l=t||globalThis.MutationObserver,a=new l(s),c=new l(e=>{for(const{target:t,attributeName:o,oldValue:r}of e)t[h](o,r,t.getAttribute(o))}),d=e=>{a.observe(e,{subtree:!0,childList:!0})};d(e);const i=o||globalThis.Element;if(i){const e=i.prototype.attachShadow;i.prototype.attachShadow=function(t){const o=e.call(this,t);return d(o),o}}return e=>{const{[h]:t,[w]:o,[f]:n}=e;if(t&&c.observe(e,{attributes:!0,attributeOldValue:!0,attributeFilter:e.constructor.observedAttributes.map(o=>{const r=e.getAttribute(o);return null!=r&&t.call(e,o,null,r),o})}),o||n){const t=a.takeRecords();t.length&&s(t),r.add(e),Promise.resolve().then(()=>{e.isConnected&&o?.call(e)})}return e}};
|
|
3
|
+
/*! (c) Andrea Giammarchi - ISC */let b={HTML:"http://www.w3.org/1999/xhtml",SVG:"http://www.w3.org/2000/svg"};const g=[],m=new Map,v=new Map,{parse:S}=(u=>{const h=new c,w=(e,t)=>{let o;if(t)for(let r,n=(e=>e.matches||e.webkitMatchesSelector||e.msMatchesSelector)(e),s=0,{length:l}=p;s<l;s++)n.call(e,r=p[s])&&(h.has(e)||h.set(e,new a),o=h.get(e),o.has(r)||(o.add(r),u.handle(e,t,r)));else h.has(e)&&(o=h.get(e),h.delete(e),o.forEach(o=>{u.handle(e,t,o)}))},f=(e,t=!0)=>{for(let o=0,{length:r}=e;o<r;o++)w(e[o],t)},{query:p}=u,b=u.root||n,g=((r,n=document,s=MutationObserver,l=["*"])=>{const a=(t,n,s,l,c,d)=>{for(const i of t)(d||o in i)&&(c?s.has(i)||(s.add(i),l.delete(i),r(i,c)):l.has(i)||(l.add(i),s.delete(i),r(i,c)),d||a(i[o](n),n,s,l,c,e))},c=new s(o=>{if(l.length){const r=l.join(","),n=new Set,s=new Set;for(const{addedNodes:l,removedNodes:c}of o)a(c,r,n,s,t,t),a(l,r,n,s,e,t)}}),{observe:d}=c;return(c.observe=t=>d.call(c,t,{subtree:e,childList:e}))(n),c})(w,b,l,p),{attachShadow:m}=s.prototype;return m&&(s.prototype.attachShadow=function(e){const t=m.call(this,e);return g.observe(t),t}),p.length&&f(b[r](p)),{drop:e=>{for(let t=0,{length:o}=e;t<o;t++)h.delete(e[t])},flush:()=>{const e=g.takeRecords();for(let t=0,{length:o}=e;t<o;t++)f(i.call(e[t].removedNodes,d),!1),f(i.call(e[t].addedNodes,d),!0)},observer:g,parse:f}})({query:g,handle(e,t,o){if(t){const t="["===o[0]?o.slice(5,-2):o,r=m.get(t);e instanceof r||new r(e)}}}),y=e=>(v.has(e)||v.set(e,Promise.withResolvers()),v.get(e)),{HTML:M,SVG:A}=((e=b)=>{const t=e.document||document,o=p(t,e);return new Proxy(new Map,{get(r,n){let s=r.get(n);if(!s){const l=new Map,a=t.createElementNS.bind(t,e[n]||b[n]),c=(t,r)=>{let s=l.get(r);s||l.set(r,s=a(r).constructor);class c extends((e=>{function t(e){return u(e,new.target.prototype)}return t.prototype=e.prototype,t})(s)){static tag=r;constructor(t){const s=e[n]||b[n];if(t&&t.namespaceURI!==s){const{attributes:e,childNodes:o}=t;t=a(r);for(const{name:o,value:r}of e)t.setAttribute(o,r);t.replaceChildren(...o)}return o(super(t||a(r)))}}return t.set(r,c),c};r.set(n,s=new Proxy(new Map,{get(e,t){const o=t.toLowerCase();return e.get(o)||c(e,o)}}))}return s}})})(),N={define(e,t){if(m.has(e)||customElements.get(e))throw new DOMException(`Element ${e} already defined`);m.set(e,t),y(e).resolve(t);const o="element"===t.tag?e:`[is="${e}"]`;g.push(o),S(document.querySelectorAll(o))},get:e=>m.get(e),whenDefined:e=>y(e).promise};export{M as HTML,A as SVG,N as elements};
|
package/index.js
CHANGED
|
@@ -5,16 +5,12 @@ const query = [];
|
|
|
5
5
|
const registry = new Map;
|
|
6
6
|
const waitlist = new Map;
|
|
7
7
|
|
|
8
|
-
const name = selector => {
|
|
9
|
-
const i = selector.indexOf('="');
|
|
10
|
-
return selector.slice(i + 2, -2);
|
|
11
|
-
};
|
|
12
|
-
|
|
13
8
|
const { parse } = QSAO({
|
|
14
9
|
query,
|
|
15
10
|
handle(element, connected, selector) {
|
|
16
11
|
if (connected) {
|
|
17
|
-
const
|
|
12
|
+
const name = selector[0] === '[' ? selector.slice(5, -2) : selector;
|
|
13
|
+
const constructor = registry.get(name);
|
|
18
14
|
if (!(element instanceof constructor))
|
|
19
15
|
new constructor(element);
|
|
20
16
|
}
|
|
@@ -43,7 +39,7 @@ export const elements = {
|
|
|
43
39
|
registry.set(name, constructor);
|
|
44
40
|
wait(name).resolve(constructor);
|
|
45
41
|
|
|
46
|
-
const selector = `[is="${name}"]`;
|
|
42
|
+
const selector = constructor.tag === 'element' ? name : `[is="${name}"]`;
|
|
47
43
|
query.push(selector);
|
|
48
44
|
parse(document.querySelectorAll(selector));
|
|
49
45
|
},
|
package/native.js
CHANGED
|
@@ -4,7 +4,10 @@ const create = document.createElement.bind(document);
|
|
|
4
4
|
|
|
5
5
|
const set = (map, tag) => {
|
|
6
6
|
let Class = DOM.get(tag);
|
|
7
|
-
if (!Class)
|
|
7
|
+
if (!Class) {
|
|
8
|
+
Class = tag === 'element' ? HTMLElement : create(tag).constructor;
|
|
9
|
+
DOM.set(tag, Class);
|
|
10
|
+
}
|
|
8
11
|
class CustomElement extends Class {
|
|
9
12
|
static tag = tag;
|
|
10
13
|
}
|
|
@@ -13,7 +16,7 @@ const set = (map, tag) => {
|
|
|
13
16
|
};
|
|
14
17
|
|
|
15
18
|
// @ts-ignore
|
|
16
|
-
const HTML = /** @type {import("nonchalance/ce").HTML} */(new Proxy(new Map, {
|
|
19
|
+
export const HTML = /** @type {import("nonchalance/ce").HTML} */(new Proxy(new Map, {
|
|
17
20
|
get(map, tag) {
|
|
18
21
|
let _ = /** @type {string} */ (tag).toLowerCase();
|
|
19
22
|
return map.get(_) || set(map, _);
|
|
@@ -21,14 +24,12 @@ const HTML = /** @type {import("nonchalance/ce").HTML} */(new Proxy(new Map, {
|
|
|
21
24
|
}));
|
|
22
25
|
|
|
23
26
|
// @ts-ignore
|
|
24
|
-
const SVG = /** @type {import("nonchalance/ce").SVG} */(new Proxy(new Map, {
|
|
27
|
+
export const SVG = /** @type {import("nonchalance/ce").SVG} */(new Proxy(new Map, {
|
|
25
28
|
get() {
|
|
26
29
|
throw new DOMException('SVG extends not natively supported');
|
|
27
30
|
}
|
|
28
31
|
}));
|
|
29
32
|
|
|
30
|
-
export { HTML, SVG };
|
|
31
|
-
|
|
32
33
|
export const elements = {
|
|
33
34
|
/**
|
|
34
35
|
* @param {string} name
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webreflection/elements",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "HTML & SVG Custom Elements",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "index.js",
|
|
7
7
|
"types": "./types/index.d.ts",
|
|
8
8
|
"scripts": {
|
|
9
|
-
"build": "rollup -c rollup.js && npm run types",
|
|
9
|
+
"build": "rm -rf dist && rollup -c rollup.js && npm run types",
|
|
10
10
|
"types": "rm -rf types && tsc --allowJs --checkJs --lib esnext,dom --moduleResolution nodenext --module NodeNext --target esnext -d --emitDeclarationOnly --outDir ./types ./index.js ./auto.js ./native.js"
|
|
11
11
|
},
|
|
12
12
|
"exports": {
|
|
@@ -15,21 +15,20 @@
|
|
|
15
15
|
"types": "./types/index.d.ts"
|
|
16
16
|
},
|
|
17
17
|
"./auto": {
|
|
18
|
-
"import": "./auto.js",
|
|
18
|
+
"import": "./dist/auto.js",
|
|
19
19
|
"types": "./types/auto.d.ts"
|
|
20
20
|
},
|
|
21
21
|
"./native": {
|
|
22
22
|
"import": "./native.js",
|
|
23
23
|
"types": "./types/native.d.ts"
|
|
24
24
|
},
|
|
25
|
-
"./min": "./min.js",
|
|
26
25
|
"./package.json": "./package.json"
|
|
27
26
|
},
|
|
28
27
|
"files": [
|
|
28
|
+
"dist/*",
|
|
29
29
|
"types/*",
|
|
30
30
|
"auto.js",
|
|
31
31
|
"index.js",
|
|
32
|
-
"min.js",
|
|
33
32
|
"native.js",
|
|
34
33
|
"README.md",
|
|
35
34
|
"LICENSE"
|
package/types/native.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
export const HTML: import("nonchalance/ce").HTML;
|
|
2
|
+
export const SVG: import("nonchalance/ce").SVG;
|
|
1
3
|
export namespace elements {
|
|
2
4
|
function define(name: string, constructor: CustomElementConstructor): void;
|
|
3
5
|
function get(name: string): CustomElementConstructor | null;
|
|
4
6
|
function whenDefined(name: string): Promise<CustomElementConstructor>;
|
|
5
7
|
}
|
|
6
|
-
export const HTML: import("nonchalance/ce").HTML;
|
|
7
|
-
export const SVG: import("nonchalance/ce").SVG;
|