mirror of
https://github.com/jaandrle/deka-dom-el
synced 2025-04-01 19:55:53 +02:00
Merge 2105776d2ace97eab735b32bc57b185e2ab469c8 into b50f8449aab6ad8445719fa3062e086c6bd83678
This commit is contained in:
commit
ea4bc4d51b
26
.editorconfig
Normal file
26
.editorconfig
Normal file
@ -0,0 +1,26 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_style = tab
|
||||
trim_trailing_whitespace = true
|
||||
max_line_length = 120
|
||||
|
||||
[*.json]
|
||||
max_line_length = unset
|
||||
|
||||
[*.yml]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[LICENSE]
|
||||
max_line_length = unset
|
||||
|
||||
[dist/**]
|
||||
indent_style = unset
|
||||
max_line_length = unset
|
||||
trim_trailing_whitespace = unset
|
23
.github/workflows/pr.yml
vendored
Normal file
23
.github/workflows/pr.yml
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
# https://nektosact.com/usage/index.html
|
||||
# https://github.com/reviewdog/action-eclint
|
||||
name: On PR
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
pr:
|
||||
name: Validates formatting and linting
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: reviewdog/action-eclint@d51e853275e707b64c0526881ada324f454c1110 # v1.7.1
|
||||
with:
|
||||
reporter: github-pr-check
|
||||
eclint_flags: '--fix'
|
||||
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
||||
with:
|
||||
node-version: 20.16
|
||||
- run: npm ci
|
||||
- run: bs/lint.sh
|
78
README.md
78
README.md
@ -1,52 +1,61 @@
|
||||
**WIP** (the experimentation phase) | [source code on GitHub](https://github.com/jaandrle/deka-dom-el) | [*mirrored* on Gitea](https://gitea.jaandrle.cz/jaandrle/deka-dom-el)
|
||||
**WIP** (the experimentation phase)
|
||||
| [source code on GitHub](https://github.com/jaandrle/deka-dom-el)
|
||||
| [*mirrored* on Gitea](https://gitea.jaandrle.cz/jaandrle/deka-dom-el)
|
||||
|
||||
***Vanilla for flavouring — a full-fledged feast for large projects***
|
||||
|
||||
*…use simple DOM API by default and library tools and logic when you need them*
|
||||
|
||||
```js
|
||||
```javascript
|
||||
document.body.append(
|
||||
el("h1", "Hello World 👋"),
|
||||
el("p", "See some syntax examples here:"),
|
||||
el("ul").append(
|
||||
el("li").append(
|
||||
el("a", { textContent: "Link to the library repo", title: "Deka DOM El — GitHub", href: "https://github.com/jaandrle/deka-dom-el" })
|
||||
),
|
||||
el("li").append(
|
||||
"Use extended Vanilla JavaScript DOM/IDL API: ",
|
||||
el("span", { textContent: "» this is a span with class=cN and data-a=A, data-b=B «", className: "cN", dataset: { a: "A", b: "B" } })
|
||||
),
|
||||
el("li").append(
|
||||
el(component, { textContent: "A component", className: "example" }, on("change", console.log))
|
||||
)
|
||||
)
|
||||
|
||||
el(HelloWorldComponent)
|
||||
);
|
||||
function component({ textContent, className }){
|
||||
const value= S("onchange");
|
||||
|
||||
function HelloWorldComponent(){
|
||||
const clicks= S(0);
|
||||
const emoji= S("🚀");
|
||||
const isSelected= el=> (el.selected= el.value===emoji());
|
||||
|
||||
return el().append(
|
||||
el("p", { textContent, className }),
|
||||
el("p", { className: [ className, "second-line" ] }).append(
|
||||
"…with reactivity: ", el("em", { style: { fontWeight: "bold" }, ariaset: { live: "polite" }, textContent: value }),
|
||||
el("p", {
|
||||
textContent: S(() => `Hello World ${emoji().repeat(clicks())}`),
|
||||
className: "example",
|
||||
ariaLive: "polite", //OR ariaset: { live: "polite" },
|
||||
dataset: { example: "Example" }, //OR dataExample: "Example",
|
||||
}),
|
||||
el("button",
|
||||
{ textContent: "Fire", type: "button" },
|
||||
on("click", ()=> clicks(clicks() + 1)),
|
||||
on("keyup", ()=> clicks(clicks() - 2)),
|
||||
),
|
||||
el("input", { type: "text", value: value() }, on("change", event=> value(event.target.value)))
|
||||
el("select", {
|
||||
onchange: event=> emoji(event.target.value),
|
||||
}).append(
|
||||
el(OptionComponent, "🎉", isSelected),
|
||||
el(OptionComponent, "🚀", isSelected),
|
||||
)
|
||||
);
|
||||
}
|
||||
function OptionComponent({ textContent }){
|
||||
return el("option", { value: textContent, textContent })
|
||||
}
|
||||
```
|
||||
# Deka DOM Elements
|
||||
Creating reactive elements, components and Web components using [IDL](https://developer.mozilla.org/en-US/docs/Glossary/IDL)/JavaScript DOM API and [**signals/observables**](#signals).
|
||||
Creating reactive elements, components and Web components using [IDL](https://developer.mozilla.org/en-US/docs/
|
||||
Glossary/IDL)/JavaScript DOM API and [**signals/observables**](#signals).
|
||||
|
||||
## Inspiration and suggested alternatives
|
||||
- my previous library (mostly used internaly): [jaandrle/dollar_dom_component: Functional DOM components without JSX and virtual DOM.](https://github.com/jaandrle/dollar_dom_component)
|
||||
- [vanjs-org/van: 🍦 VanJS: World's smallest reactive UI framework. Incredibly Powerful, Insanely Small - Everyone can build a useful UI app in an hour.](https://github.com/vanjs-org/van)
|
||||
- my previous library (mostly used internaly): [jaandrle/dollar_dom_component: Functional DOM components without
|
||||
JSX and virtual DOM.](https://github.com/jaandrle/dollar_dom_component)
|
||||
- [vanjs-org/van: 🍦 VanJS: World's smallest reactive UI framework. Incredibly Powerful, Insanely Small -
|
||||
Everyone can build a useful UI app in an hour.](https://github.com/vanjs-org/van)
|
||||
- [hyperhype/hyperscript: Create HyperText with JavaScript.](https://github.com/hyperhype/hyperscript)
|
||||
- [adamhaile/S: S.js - Simple, Clean, Fast Reactive Programming in Javascript](https://github.com/adamhaile/S) ([adamhaile/surplus: High performance JSX web views for S.js applications](https://github.com/adamhaile/surplus))
|
||||
- [adamhaile/S: S.js - Simple, Clean, Fast Reactive Programming in Javascript](https://github.com/adamhaile/S)
|
||||
([adamhaile/surplus: High performance JSX web views for S.js applications](https://github.com/adamhaile/surplus))
|
||||
- [potch/signals: a small reactive signals library](https://github.com/potch/signals)
|
||||
|
||||
## Why an another one?
|
||||
This library falls somewhere between van/hyperscript and [solid-js](https://github.com/solidjs/solid) in terms of size, complexity,
|
||||
and usability.
|
||||
This library falls somewhere between van/hyperscript and [solid-js](https://github.com/solidjs/solid) in terms of size,
|
||||
complexity, and usability.
|
||||
|
||||
Another goal is to proceed in the best spirit of functional programming. This involves starting with
|
||||
pure JavaScript (DOM API) and gradually adding auxiliary functions, ranging from “minor” improvements
|
||||
@ -74,7 +83,10 @@ To balance these requirements, numerous compromises have been made. To summarize
|
||||
- [dist/](dist/) (`https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/`…)
|
||||
|
||||
## Signals
|
||||
- [Signals — whats going on behind the scenes | by Ryan Hoffnan | ITNEXT](https://itnext.io/signals-whats-going-on-behind-the-scenes-ec858589ea63)
|
||||
- [The Evolution of Signals in JavaScript - DEV Community](https://dev.to/this-is-learning/the-evolution-of-signals-in-javascript-8ob)
|
||||
- there is also [tc39/proposal-signals: A proposal to add signals to JavaScript.](https://github.com/tc39/proposal-signals)
|
||||
- [Signals — whats going on behind the scenes | by Ryan Hoffnan | ITNEXT](https://itnext.io/
|
||||
signals-whats-going-on-behind-the-scenes-ec858589ea63)
|
||||
- [The Evolution of Signals in JavaScript - DEV Community](https://dev.to/this-is-learning/the-evolution-of-signals-in-
|
||||
javascript-8ob)
|
||||
- there is also [tc39/proposal-signals: A proposal to add signals to JavaScript.](https://github.com/tc39/proposal-
|
||||
signals)
|
||||
- [Observer pattern - Wikipedia](https://en.wikipedia.org/wiki/Observer_pattern)
|
||||
|
17
bs/README.md
17
bs/README.md
@ -1 +1,16 @@
|
||||
[jaandrle/bs: The simplest possible build system using executables](https://github.com/jaandrle/bs/)
|
||||
## bs: Build system based on executables
|
||||
This project uses [jaandrle/bs: The simplest possible build system using executable/bash scripts](
|
||||
https://github.com/jaandrle/bs).
|
||||
|
||||
#### bs/build.js [--minify|--help]
|
||||
Generates alternative versions of the project (other than native ESM code).
|
||||
Also generates typescript definitions.
|
||||
|
||||
#### bs/docs.js
|
||||
Generates documentation, from `docs/`. Uses “SSR” technique, using deka-dom-el itself.
|
||||
|
||||
#### bs/lint.sh
|
||||
Lints size of the project, jshint. See configs:
|
||||
|
||||
- `package.json`: key `size-limit`
|
||||
- `package.json`: key `jshintConfig`
|
||||
|
@ -34,7 +34,7 @@ $.api("", true)
|
||||
const file_dts_out= filesOut(file_dts);
|
||||
echoVariant(file_dts_out);
|
||||
s.echo(bundleDTS(file_dts)).to(file_dts_out);
|
||||
|
||||
|
||||
await toDDE(out, file_root);
|
||||
}
|
||||
$.exit(0);
|
||||
@ -43,10 +43,13 @@ $.api("", true)
|
||||
const name= "dde";
|
||||
const out= filesOut(file_root+".js", name);
|
||||
echoVariant(`${out} (${file} → globalThis.${name})`)
|
||||
|
||||
|
||||
let content= s.cat(file).toString().split(/export ?{/);
|
||||
content.splice(1, 0, `\nglobalThis.${name}= {`);
|
||||
content[2]= content[2].replace(/,(?!\n)/g, ",\n").replace(/(?<!\n)}/, "\n}").replace(/^(\t*)(.*) as ([^,\n]*)(,?)$/mg, "$1$3: $2$4");
|
||||
content[2]= content[2]
|
||||
.replace(/,(?!\n)/g, ",\n")
|
||||
.replace(/(?<!\n)}/, "\n}")
|
||||
.replace(/^(\t*)(.*) as ([^,\n]*)(,?)$/mg, "$1$3: $2$4");
|
||||
s.echo([
|
||||
`//deka-dom-el library is available via global namespace \`${name}\``,
|
||||
"(()=> {",
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env -S npx nodejsscript
|
||||
/* jshint esversion: 11,-W097, -W040, module: true, node: true, expr: true, undef: true *//* global echo, $, pipe, s, fetch, cyclicLoop */
|
||||
/* jshint esversion: 11,-W097, -W040, module: true, node: true, expr: true, undef: true *//* global echo, $, pipe, s, fetch, cyclicLoop */// editorconfig-checker-disable-line
|
||||
echo("Building static documentation files…");
|
||||
echo("Preparing…");
|
||||
import { path_target, pages as pages_registered, styles, dispatchEvent, t } from "../docs/ssr.js";
|
||||
|
@ -10,7 +10,7 @@ export function createHTMl(html, options= {}){
|
||||
if(dom) cleanHTML();
|
||||
// set a default url if we don't get one - otherwise things explode when we copy localstorage keys
|
||||
if (!('url' in options)) { Object.assign(options, { url: 'http://localhost:3000' }) }
|
||||
|
||||
|
||||
dom= new JSDOM(html, options);
|
||||
const window= dom.window;
|
||||
return {
|
||||
|
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eou pipefail
|
||||
npx editorconfig-checker -format gcc
|
||||
npx size-limit
|
||||
npx jshint index.js src
|
||||
|
238
dist/dde-with-signals.js
vendored
238
dist/dde-with-signals.js
vendored
@ -36,16 +36,16 @@ function q(t, e) {
|
||||
function F(t, e) {
|
||||
let { observedAttributes: n = [] } = t.constructor;
|
||||
return n.reduce(function(r, o) {
|
||||
return r[pt(o)] = e(t, o), r;
|
||||
return r[dt(o)] = e(t, o), r;
|
||||
}, {});
|
||||
}
|
||||
function pt(t) {
|
||||
function dt(t) {
|
||||
return t.replace(/-./g, (e) => e[1].toUpperCase());
|
||||
}
|
||||
|
||||
// src/dom-common.js
|
||||
var d = {
|
||||
setDeleteAttr: lt,
|
||||
setDeleteAttr: pt,
|
||||
ssr: "",
|
||||
D: globalThis.document,
|
||||
F: globalThis.DocumentFragment,
|
||||
@ -53,7 +53,7 @@ var d = {
|
||||
S: globalThis.SVGElement,
|
||||
M: globalThis.MutationObserver
|
||||
};
|
||||
function lt(t, e, n) {
|
||||
function pt(t, e, n) {
|
||||
if (Reflect.set(t, e, n), !!S(n)) {
|
||||
if (Reflect.deleteProperty(t, e), t instanceof d.H && t.getAttribute(e) === "undefined")
|
||||
return t.removeAttribute(e);
|
||||
@ -70,7 +70,7 @@ var A = [{
|
||||
},
|
||||
host: (t) => t ? t(d.D.body) : d.D.body,
|
||||
prevent: !0
|
||||
}], m = {
|
||||
}], x = {
|
||||
get current() {
|
||||
return A[A.length - 1];
|
||||
},
|
||||
@ -98,7 +98,7 @@ var A = [{
|
||||
function Y(...t) {
|
||||
return this.appendOriginal(...t), this;
|
||||
}
|
||||
function ht(t) {
|
||||
function lt(t) {
|
||||
return t.append === Y || (t.appendOriginal = t.append, t.append = Y), t;
|
||||
}
|
||||
var $;
|
||||
@ -106,15 +106,17 @@ function P(t, e, ...n) {
|
||||
let r = W(this), o = 0, c, i;
|
||||
switch ((Object(e) !== e || r.isSignal(e)) && (e = { textContent: e }), !0) {
|
||||
case typeof t == "function": {
|
||||
o = 1, m.push({ scope: t, host: (...v) => v.length ? (o === 1 ? n.unshift(...v) : v.forEach((h) => h(i)), void 0) : i }), c = t(e || void 0);
|
||||
let a = c instanceof d.F;
|
||||
o = 1;
|
||||
let a = (...p) => p.length ? (o === 1 ? n.unshift(...p) : p.forEach((m) => m(i)), void 0) : i;
|
||||
x.push({ scope: t, host: a }), c = t(e || void 0);
|
||||
let h = c instanceof d.F;
|
||||
if (c.nodeName === "#comment") break;
|
||||
let l = P.mark({
|
||||
let v = P.mark({
|
||||
type: "component",
|
||||
name: t.name,
|
||||
host: a ? "this" : "parentElement"
|
||||
host: h ? "this" : "parentElement"
|
||||
});
|
||||
c.prepend(l), a && (i = l);
|
||||
c.prepend(v), h && (i = v);
|
||||
break;
|
||||
}
|
||||
case t === "#text":
|
||||
@ -129,23 +131,28 @@ function P(t, e, ...n) {
|
||||
case !c:
|
||||
c = j.call(this, d.D.createElement(t), e);
|
||||
}
|
||||
return ht(c), i || (i = c), n.forEach((a) => a(i)), o && m.pop(), o = 2, c;
|
||||
return lt(c), i || (i = c), n.forEach((a) => a(i)), o && x.pop(), o = 2, c;
|
||||
}
|
||||
P.mark = function(t, e = !1) {
|
||||
t = Object.entries(t).map(([o, c]) => o + `="${c}"`).join(" ");
|
||||
let n = e ? "" : "/", r = d.D.createComment(`<dde:mark ${t}${d.ssr}${n}>`);
|
||||
return e && (r.end = d.D.createComment("</dde:mark>")), r;
|
||||
};
|
||||
function Wt(t, e, n) {
|
||||
typeof e != "object" && (n = e, e = t);
|
||||
let r = Symbol.for("default"), o = Array.from(e.querySelectorAll("slot")).reduce((i, a) => Reflect.set(i, a.name || r, a) && i, {}), c = T(o, r);
|
||||
if (t.append = new Proxy(t.append, {
|
||||
apply(i, a, l) {
|
||||
if (l[0] === e) return i.apply(t, l);
|
||||
if (!l.length) return t;
|
||||
apply(i, a, h) {
|
||||
if (h[0] === e) return i.apply(t, h);
|
||||
if (!h.length) return t;
|
||||
let v = d.D.createDocumentFragment();
|
||||
for (let h of l) {
|
||||
if (!h || !h.slot) {
|
||||
c && v.append(h);
|
||||
for (let p of h) {
|
||||
if (!p || !p.slot) {
|
||||
c && v.append(p);
|
||||
continue;
|
||||
}
|
||||
let x = h.slot, w = o[x];
|
||||
vt(h, "remove", "slot"), w && (bt(w, h, n), Reflect.deleteProperty(o, x));
|
||||
let m = p.slot, y = o[m];
|
||||
vt(p, "remove", "slot"), y && (bt(y, p, n), Reflect.deleteProperty(o, m));
|
||||
}
|
||||
return c && (o[r].replaceWith(v), Reflect.deleteProperty(o, r)), t.append = i, t;
|
||||
}
|
||||
@ -155,19 +162,20 @@ function Wt(t, e, n) {
|
||||
}
|
||||
return e;
|
||||
}
|
||||
function ht(...t) {
|
||||
return t.filter(Boolean).join(" ");
|
||||
}
|
||||
function bt(t, e, n) {
|
||||
n && n(t, e);
|
||||
try {
|
||||
t.replaceWith(j(e, { className: [e.className, t.className], dataset: { ...t.dataset } }));
|
||||
t.replaceWith(j(e, {
|
||||
className: ht(e.className, t.className),
|
||||
dataset: { ...t.dataset }
|
||||
}));
|
||||
} catch {
|
||||
t.replaceWith(e);
|
||||
}
|
||||
}
|
||||
P.mark = function(t, e = !1) {
|
||||
t = Object.entries(t).map(([o, c]) => o + `="${c}"`).join(" ");
|
||||
let n = e ? "" : "/", r = d.D.createComment(`<dde:mark ${t}${d.ssr}${n}>`);
|
||||
return e && (r.end = d.D.createComment("</dde:mark>")), r;
|
||||
};
|
||||
function qt(t) {
|
||||
let e = this;
|
||||
return function(...r) {
|
||||
@ -190,7 +198,7 @@ function nt(t, e, n) {
|
||||
t,
|
||||
e,
|
||||
n,
|
||||
(a, l) => nt.call(c, t, a, l)
|
||||
(a, h) => nt.call(c, t, a, h)
|
||||
);
|
||||
let [i] = e;
|
||||
if (i === "=") return r(e.slice(1), n);
|
||||
@ -208,7 +216,7 @@ function nt(t, e, n) {
|
||||
case "dataset":
|
||||
return I(o, n, et.bind(null, t[e]));
|
||||
case "ariaset":
|
||||
return I(o, n, (a, l) => r("aria-" + a, l));
|
||||
return I(o, n, (a, h) => r("aria-" + a, h));
|
||||
case "classList":
|
||||
return gt.call(c, t, n);
|
||||
}
|
||||
@ -227,9 +235,6 @@ function gt(t, e) {
|
||||
(r, o) => t.classList.toggle(r, o === -1 ? void 0 : !!o)
|
||||
), t;
|
||||
}
|
||||
function Ft(t) {
|
||||
return Array.from(t.children).forEach((e) => e.remove()), t;
|
||||
}
|
||||
function vt(t, e, n, r) {
|
||||
return t instanceof d.H ? t[e + "Attribute"](n, r) : t[e + "AttributeNS"](null, n, r);
|
||||
}
|
||||
@ -249,14 +254,11 @@ function I(t, e, n) {
|
||||
o && (c = t.processReactiveAttribute(e, o, c, n), n(o, c));
|
||||
});
|
||||
}
|
||||
function ct(t) {
|
||||
return Array.isArray(t) ? t.filter(Boolean).join(" ") : t;
|
||||
}
|
||||
function mt(t, e, n, r) {
|
||||
return t[(S(r) ? "remove" : "set") + e](n, ct(r));
|
||||
return t[(S(r) ? "remove" : "set") + e](n, r);
|
||||
}
|
||||
function xt(t, e, n, r, o = null) {
|
||||
return t[(S(r) ? "remove" : "set") + e + "NS"](o, n, ct(r));
|
||||
return t[(S(r) ? "remove" : "set") + e + "NS"](o, n, r);
|
||||
}
|
||||
function et(t, e, n) {
|
||||
if (Reflect.set(t, e, n), !!S(n))
|
||||
@ -264,21 +266,21 @@ function et(t, e, n) {
|
||||
}
|
||||
|
||||
// src/events-observer.js
|
||||
var D = d.M ? yt() : new Proxy({}, {
|
||||
var D = d.M ? wt() : new Proxy({}, {
|
||||
get() {
|
||||
return () => {
|
||||
};
|
||||
}
|
||||
});
|
||||
function yt() {
|
||||
function wt() {
|
||||
let t = /* @__PURE__ */ new Map(), e = !1, n = (s) => function(u) {
|
||||
for (let f of u)
|
||||
if (f.type === "childList") {
|
||||
if (h(f.addedNodes, !0)) {
|
||||
if (p(f.addedNodes, !0)) {
|
||||
s();
|
||||
continue;
|
||||
}
|
||||
x(f.removedNodes, !0) && s();
|
||||
m(f.removedNodes, !0) && s();
|
||||
}
|
||||
}, r = new d.M(n(a));
|
||||
return {
|
||||
@ -327,35 +329,35 @@ function yt() {
|
||||
function a() {
|
||||
!e || t.size || (e = !1, r.disconnect());
|
||||
}
|
||||
function l() {
|
||||
function h() {
|
||||
return new Promise(function(s) {
|
||||
(requestIdleCallback || requestAnimationFrame)(s);
|
||||
});
|
||||
}
|
||||
async function v(s) {
|
||||
t.size > 30 && await l();
|
||||
t.size > 30 && await h();
|
||||
let u = [];
|
||||
if (!(s instanceof Node)) return u;
|
||||
for (let f of t.keys())
|
||||
f === s || !(f instanceof Node) || s.contains(f) && u.push(f);
|
||||
return u;
|
||||
}
|
||||
function h(s, u) {
|
||||
function p(s, u) {
|
||||
let f = !1;
|
||||
for (let b of s) {
|
||||
if (u && v(b).then(h), !t.has(b)) continue;
|
||||
if (u && v(b).then(p), !t.has(b)) continue;
|
||||
let N = t.get(b);
|
||||
N.length_c && (b.dispatchEvent(new Event(_)), N.connected = /* @__PURE__ */ new WeakSet(), N.length_c = 0, N.length_d || t.delete(b), f = !0);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
function x(s, u) {
|
||||
function m(s, u) {
|
||||
let f = !1;
|
||||
for (let b of s)
|
||||
u && v(b).then(x), !(!t.has(b) || !t.get(b).length_d) && ((globalThis.queueMicrotask || setTimeout)(w(b)), f = !0);
|
||||
u && v(b).then(m), !(!t.has(b) || !t.get(b).length_d) && ((globalThis.queueMicrotask || setTimeout)(y(b)), f = !0);
|
||||
return f;
|
||||
}
|
||||
function w(s) {
|
||||
function y(s) {
|
||||
return () => {
|
||||
s.isConnected || (s.dispatchEvent(new Event(C)), t.delete(s));
|
||||
};
|
||||
@ -363,17 +365,17 @@ function yt() {
|
||||
}
|
||||
|
||||
// src/customElement.js
|
||||
function Zt(t, e, n, r = _t) {
|
||||
m.push({
|
||||
function Jt(t, e, n, r = _t) {
|
||||
x.push({
|
||||
scope: t,
|
||||
host: (...i) => i.length ? i.forEach((a) => a(t)) : t
|
||||
}), typeof r == "function" && (r = r.call(t, t));
|
||||
let o = t[O];
|
||||
o || wt(t);
|
||||
o || yt(t);
|
||||
let c = n.call(t, r);
|
||||
return o || t.dispatchEvent(new Event(_)), e.nodeType === 11 && typeof e.mode == "string" && t.addEventListener(C, D.observe(e), { once: !0 }), m.pop(), e.append(c);
|
||||
return o || t.dispatchEvent(new Event(_)), e.nodeType === 11 && typeof e.mode == "string" && t.addEventListener(C, D.observe(e), { once: !0 }), x.pop(), e.append(c);
|
||||
}
|
||||
function wt(t) {
|
||||
function yt(t) {
|
||||
return J(t.prototype, "connectedCallback", function(e, n, r) {
|
||||
e.apply(n, r), n.dispatchEvent(new Event(_));
|
||||
}), J(t.prototype, "disconnectedCallback", function(e, n, r) {
|
||||
@ -396,43 +398,43 @@ function _t(t) {
|
||||
}
|
||||
|
||||
// src/events.js
|
||||
function Qt(t, e, n) {
|
||||
function Kt(t, e, n) {
|
||||
return e || (e = {}), function(o, ...c) {
|
||||
n && (c.unshift(o), o = typeof n == "function" ? n() : n);
|
||||
let i = c.length ? new CustomEvent(t, Object.assign({ detail: c[0] }, e)) : new Event(t, e);
|
||||
return o.dispatchEvent(i);
|
||||
};
|
||||
}
|
||||
function y(t, e, n) {
|
||||
function w(t, e, n) {
|
||||
return function(o) {
|
||||
return o.addEventListener(t, e, n), o;
|
||||
};
|
||||
}
|
||||
var it = (t) => Object.assign({}, typeof t == "object" ? t : null, { once: !0 });
|
||||
y.connected = function(t, e) {
|
||||
return e = it(e), function(r) {
|
||||
var ct = (t) => Object.assign({}, typeof t == "object" ? t : null, { once: !0 });
|
||||
w.connected = function(t, e) {
|
||||
return e = ct(e), function(r) {
|
||||
return r.addEventListener(_, t, e), r[O] ? r : r.isConnected ? (r.dispatchEvent(new Event(_)), r) : (q(e.signal, () => D.offConnected(r, t)) && D.onConnected(r, t), r);
|
||||
};
|
||||
};
|
||||
y.disconnected = function(t, e) {
|
||||
return e = it(e), function(r) {
|
||||
w.disconnected = function(t, e) {
|
||||
return e = ct(e), function(r) {
|
||||
return r.addEventListener(C, t, e), r[O] || q(e.signal, () => D.offDisconnected(r, t)) && D.onDisconnected(r, t), r;
|
||||
};
|
||||
};
|
||||
var Z = /* @__PURE__ */ new WeakMap();
|
||||
y.disconnectedAsAbort = function(t) {
|
||||
w.disconnectedAsAbort = function(t) {
|
||||
if (Z.has(t)) return Z.get(t);
|
||||
let e = new AbortController();
|
||||
return Z.set(t, e), t(y.disconnected(() => e.abort())), e;
|
||||
return Z.set(t, e), t(w.disconnected(() => e.abort())), e;
|
||||
};
|
||||
var At = /* @__PURE__ */ new WeakSet();
|
||||
y.attributeChanged = function(t, e) {
|
||||
w.attributeChanged = function(t, e) {
|
||||
return typeof e != "object" && (e = {}), function(r) {
|
||||
if (r.addEventListener(M, t, e), r[O] || At.has(r) || !d.M) return r;
|
||||
let o = new d.M(function(i) {
|
||||
for (let { attributeName: a, target: l } of i)
|
||||
l.dispatchEvent(
|
||||
new CustomEvent(M, { detail: [a, l.getAttribute(a)] })
|
||||
for (let { attributeName: a, target: h } of i)
|
||||
h.dispatchEvent(
|
||||
new CustomEvent(M, { detail: [a, h.getAttribute(a)] })
|
||||
);
|
||||
});
|
||||
return q(e.signal, () => o.disconnect()) && o.observe(r, { attributes: !0 }), r;
|
||||
@ -440,10 +442,10 @@ y.attributeChanged = function(t, e) {
|
||||
};
|
||||
|
||||
// src/signals-lib.js
|
||||
var p = "__dde_signal";
|
||||
var l = "__dde_signal";
|
||||
function z(t) {
|
||||
try {
|
||||
return T(t, p);
|
||||
return T(t, l);
|
||||
} catch {
|
||||
return !1;
|
||||
}
|
||||
@ -451,19 +453,19 @@ function z(t) {
|
||||
var H = [], g = /* @__PURE__ */ new WeakMap();
|
||||
function E(t, e) {
|
||||
if (typeof t != "function")
|
||||
return st(!1, t, e);
|
||||
return it(!1, t, e);
|
||||
if (z(t)) return t;
|
||||
let n = st(!0), r = function() {
|
||||
let n = it(!0), r = function() {
|
||||
let [o, ...c] = g.get(r);
|
||||
if (g.set(r, /* @__PURE__ */ new Set([o])), H.push(r), dt(n, t()), H.pop(), !c.length) return;
|
||||
if (g.set(r, /* @__PURE__ */ new Set([o])), H.push(r), at(n, t()), H.pop(), !c.length) return;
|
||||
let i = g.get(r);
|
||||
for (let a of c)
|
||||
i.has(a) || L(a, r);
|
||||
};
|
||||
return g.set(n[p], r), g.set(r, /* @__PURE__ */ new Set([n])), r(), n;
|
||||
return g.set(n[l], r), g.set(r, /* @__PURE__ */ new Set([n])), r(), n;
|
||||
}
|
||||
E.action = function(t, e, ...n) {
|
||||
let r = t[p], { actions: o } = r;
|
||||
let r = t[l], { actions: o } = r;
|
||||
if (!o || !(e in o))
|
||||
throw new Error(`'${t}' has no action with name '${e}'!`);
|
||||
if (o[e].apply(r, n), r.skip) return delete r.skip;
|
||||
@ -482,8 +484,8 @@ E.symbols = {
|
||||
};
|
||||
E.clear = function(...t) {
|
||||
for (let n of t) {
|
||||
let r = n[p];
|
||||
r && (delete n.toJSON, r.onclear.forEach((o) => o.call(r)), e(n, r), delete n[p]);
|
||||
let r = n[l];
|
||||
r && (delete n.toJSON, r.onclear.forEach((o) => o.call(r)), e(n, r), delete n[l]);
|
||||
}
|
||||
function e(n, r) {
|
||||
r.listeners.forEach((o) => {
|
||||
@ -497,24 +499,24 @@ var R = "__dde_reactive";
|
||||
E.el = function(t, e) {
|
||||
let n = P.mark({ type: "reactive" }, !0), r = n.end, o = d.D.createDocumentFragment();
|
||||
o.append(n, r);
|
||||
let { current: c } = m, i = {}, a = (l) => {
|
||||
let { current: c } = x, i = {}, a = (h) => {
|
||||
if (!n.parentNode || !r.parentNode)
|
||||
return L(t, a);
|
||||
let v = i;
|
||||
i = {}, m.push(c);
|
||||
let h = e(l, function(u, f) {
|
||||
i = {}, x.push(c);
|
||||
let p = e(h, function(u, f) {
|
||||
let b;
|
||||
return T(v, u) ? (b = v[u], delete v[u]) : b = f(), i[u] = b, b;
|
||||
});
|
||||
m.pop(), Array.isArray(h) || (h = [h]);
|
||||
let x = document.createComment("");
|
||||
h.push(x), n.after(...h);
|
||||
let w;
|
||||
for (; (w = x.nextSibling) && w !== r; )
|
||||
w.remove();
|
||||
x.remove(), n.isConnected && St(c.host());
|
||||
x.pop(), Array.isArray(p) || (p = [p]);
|
||||
let m = document.createComment("");
|
||||
p.push(m), n.after(...p);
|
||||
let y;
|
||||
for (; (y = m.nextSibling) && y !== r; )
|
||||
y.remove();
|
||||
m.remove(), n.isConnected && St(c.host());
|
||||
};
|
||||
return Q(t, a), ft(t, a, n, e), a(t()), o;
|
||||
return Q(t, a), ut(t, a, n, e), a(t()), o;
|
||||
};
|
||||
function St(t) {
|
||||
!t || !t[R] || (requestIdleCallback || setTimeout)(function() {
|
||||
@ -528,25 +530,25 @@ var Ot = {
|
||||
};
|
||||
function Ct(t) {
|
||||
return function(e, n) {
|
||||
let r = (...c) => c.length ? e.setAttribute(n, ...c) : K(r), o = at(r, e.getAttribute(n), Ot);
|
||||
let r = (...c) => c.length ? e.setAttribute(n, ...c) : K(r), o = ft(r, e.getAttribute(n), Ot);
|
||||
return t[n] = o, o;
|
||||
};
|
||||
}
|
||||
var G = "__dde_attributes";
|
||||
E.observedAttributes = function(t) {
|
||||
let e = t[G] = {}, n = F(t, Ct(e));
|
||||
return y.attributeChanged(function({ detail: o }) {
|
||||
return w.attributeChanged(function({ detail: o }) {
|
||||
/*! This maps attributes to signals (`S.observedAttributes`).
|
||||
* Investigate `__dde_attributes` key of the element.*/
|
||||
let [c, i] = o, a = this[G][c];
|
||||
if (a) return E.action(a, "_set", i);
|
||||
})(t), y.disconnected(function() {
|
||||
})(t), w.disconnected(function() {
|
||||
/*! This removes all signals mapped to attributes (`S.observedAttributes`).
|
||||
* Investigate `__dde_attributes` key of the element.*/
|
||||
E.clear(...Object.values(this[G]));
|
||||
})(t), n;
|
||||
};
|
||||
var ut = {
|
||||
var st = {
|
||||
isSignal: z,
|
||||
processReactiveAttribute(t, e, n, r) {
|
||||
if (!z(n)) return n;
|
||||
@ -555,26 +557,26 @@ var ut = {
|
||||
return L(n, o);
|
||||
r(e, c);
|
||||
};
|
||||
return Q(n, o), ft(n, o, t, e), n();
|
||||
return Q(n, o), ut(n, o, t, e), n();
|
||||
}
|
||||
};
|
||||
function ft(t, e, ...n) {
|
||||
let { current: r } = m;
|
||||
function ut(t, e, ...n) {
|
||||
let { current: r } = x;
|
||||
r.prevent || r.host(function(o) {
|
||||
o[R] || (o[R] = [], y.disconnected(
|
||||
o[R] || (o[R] = [], w.disconnected(
|
||||
() => (
|
||||
/*!
|
||||
* Clears all Signals listeners added in the current scope/host (`S.el`, `assign`, …?).
|
||||
* You can investigate the `__dde_reactive` key of the element.
|
||||
* */
|
||||
o[R].forEach(([[c, i]]) => L(c, i, c[p] && c[p].host && c[p].host() === o))
|
||||
o[R].forEach(([[c, i]]) => L(c, i, c[l] && c[l].host && c[l].host() === o))
|
||||
)
|
||||
)(o)), o[R].push([[t, e], ...n]);
|
||||
});
|
||||
}
|
||||
function st(t, e, n) {
|
||||
let r = t ? () => K(r) : (...o) => o.length ? dt(r, ...o) : K(r);
|
||||
return at(r, e, n, t);
|
||||
function it(t, e, n) {
|
||||
let r = t ? () => K(r) : (...o) => o.length ? at(r, ...o) : K(r);
|
||||
return ft(r, e, n, t);
|
||||
}
|
||||
var Dt = Object.assign(/* @__PURE__ */ Object.create(null), {
|
||||
stopPropagation() {
|
||||
@ -588,13 +590,13 @@ var Dt = Object.assign(/* @__PURE__ */ Object.create(null), {
|
||||
this.stack = n.find((o) => !o.includes(r));
|
||||
}
|
||||
};
|
||||
function at(t, e, n, r = !1) {
|
||||
function ft(t, e, n, r = !1) {
|
||||
let o = [];
|
||||
X(n) !== "[object Object]" && (n = {});
|
||||
let { onclear: c } = E.symbols;
|
||||
n[c] && (o.push(n[c]), delete n[c]);
|
||||
let { host: i } = m;
|
||||
return Reflect.defineProperty(t, p, {
|
||||
let { host: i } = x;
|
||||
return Reflect.defineProperty(t, l, {
|
||||
value: {
|
||||
value: e,
|
||||
actions: n,
|
||||
@ -607,28 +609,28 @@ function at(t, e, n, r = !1) {
|
||||
enumerable: !1,
|
||||
writable: !1,
|
||||
configurable: !0
|
||||
}), t.toJSON = () => t(), t.valueOf = () => t[p] && t[p].value, Object.setPrototypeOf(t[p], Dt), t;
|
||||
}), t.toJSON = () => t(), t.valueOf = () => t[l] && t[l].value, Object.setPrototypeOf(t[l], Dt), t;
|
||||
}
|
||||
function Rt() {
|
||||
return H[H.length - 1];
|
||||
}
|
||||
function K(t) {
|
||||
if (!t[p]) return;
|
||||
let { value: e, listeners: n } = t[p], r = Rt();
|
||||
if (!t[l]) return;
|
||||
let { value: e, listeners: n } = t[l], r = Rt();
|
||||
return r && n.add(r), g.has(r) && g.get(r).add(t), e;
|
||||
}
|
||||
function dt(t, e, n) {
|
||||
if (!t[p]) return;
|
||||
let r = t[p];
|
||||
function at(t, e, n) {
|
||||
if (!t[l]) return;
|
||||
let r = t[l];
|
||||
if (!(!n && r.value === e))
|
||||
return r.value = e, r.listeners.forEach((o) => o(e)), e;
|
||||
}
|
||||
function Q(t, e) {
|
||||
if (t[p])
|
||||
return t[p].listeners.add(e);
|
||||
if (t[l])
|
||||
return t[l].listeners.add(e);
|
||||
}
|
||||
function L(t, e, n) {
|
||||
let r = t[p];
|
||||
let r = t[l];
|
||||
if (!r) return;
|
||||
let o = r.listeners.delete(e);
|
||||
if (n && !r.listeners.size) {
|
||||
@ -641,29 +643,29 @@ function L(t, e, n) {
|
||||
}
|
||||
|
||||
// signals.js
|
||||
B(ut);
|
||||
B(st);
|
||||
|
||||
globalThis.dde= {
|
||||
S: E,
|
||||
assign: j,
|
||||
assignAttribute: nt,
|
||||
chainableAppend: ht,
|
||||
chainableAppend: lt,
|
||||
classListDeclarative: gt,
|
||||
cn: ht,
|
||||
createElement: P,
|
||||
createElementNS: qt,
|
||||
customElementRender: Zt,
|
||||
customElementWithDDE: wt,
|
||||
dispatchEvent: Qt,
|
||||
customElementRender: Jt,
|
||||
customElementWithDDE: yt,
|
||||
dispatchEvent: Kt,
|
||||
el: P,
|
||||
elNS: qt,
|
||||
elementAttribute: vt,
|
||||
empty: Ft,
|
||||
isSignal: z,
|
||||
lifecyclesToEvents: wt,
|
||||
lifecyclesToEvents: yt,
|
||||
observedAttributes: _t,
|
||||
on: y,
|
||||
on: w,
|
||||
registerReactivity: B,
|
||||
scope: m,
|
||||
scope: x,
|
||||
signal: E,
|
||||
simulateSlots: Wt
|
||||
};
|
||||
|
134
dist/dde.js
vendored
134
dist/dde.js
vendored
@ -1,7 +1,7 @@
|
||||
//deka-dom-el library is available via global namespace `dde`
|
||||
(()=> {
|
||||
// src/signals-common.js
|
||||
var C = {
|
||||
var m = {
|
||||
isSignal(t) {
|
||||
return !1;
|
||||
},
|
||||
@ -9,16 +9,16 @@ var C = {
|
||||
return n;
|
||||
}
|
||||
};
|
||||
function V(t, e = !0) {
|
||||
return e ? Object.assign(C, t) : (Object.setPrototypeOf(t, C), t);
|
||||
function G(t, e = !0) {
|
||||
return e ? Object.assign(m, t) : (Object.setPrototypeOf(t, m), t);
|
||||
}
|
||||
function L(t) {
|
||||
return C.isPrototypeOf(t) && t !== C ? t : C;
|
||||
return m.isPrototypeOf(t) && t !== m ? t : m;
|
||||
}
|
||||
|
||||
// src/helpers.js
|
||||
var q = (...t) => Object.prototype.hasOwnProperty.call(...t);
|
||||
function E(t) {
|
||||
function x(t) {
|
||||
return typeof t > "u";
|
||||
}
|
||||
function N(t, e) {
|
||||
@ -32,16 +32,16 @@ function N(t, e) {
|
||||
function F(t, e) {
|
||||
let { observedAttributes: n = [] } = t.constructor;
|
||||
return n.reduce(function(r, o) {
|
||||
return r[J(o)] = e(t, o), r;
|
||||
return r[V(o)] = e(t, o), r;
|
||||
}, {});
|
||||
}
|
||||
function J(t) {
|
||||
function V(t) {
|
||||
return t.replace(/-./g, (e) => e[1].toUpperCase());
|
||||
}
|
||||
|
||||
// src/dom-common.js
|
||||
var a = {
|
||||
setDeleteAttr: K,
|
||||
setDeleteAttr: J,
|
||||
ssr: "",
|
||||
D: globalThis.document,
|
||||
F: globalThis.DocumentFragment,
|
||||
@ -49,15 +49,15 @@ var a = {
|
||||
S: globalThis.SVGElement,
|
||||
M: globalThis.MutationObserver
|
||||
};
|
||||
function K(t, e, n) {
|
||||
if (Reflect.set(t, e, n), !!E(n)) {
|
||||
function J(t, e, n) {
|
||||
if (Reflect.set(t, e, n), !!x(n)) {
|
||||
if (Reflect.deleteProperty(t, e), t instanceof a.H && t.getAttribute(e) === "undefined")
|
||||
return t.removeAttribute(e);
|
||||
if (Reflect.get(t, e) === "undefined")
|
||||
return Reflect.set(t, e, "");
|
||||
}
|
||||
}
|
||||
var x = "__dde_lifecyclesToEvents", g = "dde:connected", y = "dde:disconnected", D = "dde:attributeChanged";
|
||||
var w = "__dde_lifecyclesToEvents", g = "dde:connected", y = "dde:disconnected", D = "dde:attributeChanged";
|
||||
|
||||
// src/dom.js
|
||||
var v = [{
|
||||
@ -94,7 +94,7 @@ var v = [{
|
||||
function $(...t) {
|
||||
return this.appendOriginal(...t), this;
|
||||
}
|
||||
function Q(t) {
|
||||
function K(t) {
|
||||
return t.append === $ || (t.appendOriginal = t.append, t.append = $), t;
|
||||
}
|
||||
var T;
|
||||
@ -102,15 +102,17 @@ function j(t, e, ...n) {
|
||||
let r = L(this), o = 0, c, f;
|
||||
switch ((Object(e) !== e || r.isSignal(e)) && (e = { textContent: e }), !0) {
|
||||
case typeof t == "function": {
|
||||
o = 1, S.push({ scope: t, host: (...b) => b.length ? (o === 1 ? n.unshift(...b) : b.forEach((h) => h(f)), void 0) : f }), c = t(e || void 0);
|
||||
let d = c instanceof a.F;
|
||||
o = 1;
|
||||
let d = (...l) => l.length ? (o === 1 ? n.unshift(...l) : l.forEach((E) => E(f)), void 0) : f;
|
||||
S.push({ scope: t, host: d }), c = t(e || void 0);
|
||||
let p = c instanceof a.F;
|
||||
if (c.nodeName === "#comment") break;
|
||||
let p = j.mark({
|
||||
let b = j.mark({
|
||||
type: "component",
|
||||
name: t.name,
|
||||
host: d ? "this" : "parentElement"
|
||||
host: p ? "this" : "parentElement"
|
||||
});
|
||||
c.prepend(p), d && (f = p);
|
||||
c.prepend(b), p && (f = b);
|
||||
break;
|
||||
}
|
||||
case t === "#text":
|
||||
@ -125,8 +127,13 @@ function j(t, e, ...n) {
|
||||
case !c:
|
||||
c = O.call(this, a.D.createElement(t), e);
|
||||
}
|
||||
return Q(c), f || (f = c), n.forEach((d) => d(f)), o && S.pop(), o = 2, c;
|
||||
return K(c), f || (f = c), n.forEach((d) => d(f)), o && S.pop(), o = 2, c;
|
||||
}
|
||||
j.mark = function(t, e = !1) {
|
||||
t = Object.entries(t).map(([o, c]) => o + `="${c}"`).join(" ");
|
||||
let n = e ? "" : "/", r = a.D.createComment(`<dde:mark ${t}${a.ssr}${n}>`);
|
||||
return e && (r.end = a.D.createComment("</dde:mark>")), r;
|
||||
};
|
||||
function bt(t, e, n) {
|
||||
typeof e != "object" && (n = e, e = t);
|
||||
let r = Symbol.for("default"), o = Array.from(e.querySelectorAll("slot")).reduce((f, d) => Reflect.set(f, d.name || r, d) && f, {}), c = q(o, r);
|
||||
@ -135,13 +142,13 @@ function bt(t, e, n) {
|
||||
if (p[0] === e) return f.apply(t, p);
|
||||
if (!p.length) return t;
|
||||
let b = a.D.createDocumentFragment();
|
||||
for (let h of p) {
|
||||
if (!h || !h.slot) {
|
||||
c && b.append(h);
|
||||
for (let l of p) {
|
||||
if (!l || !l.slot) {
|
||||
c && b.append(l);
|
||||
continue;
|
||||
}
|
||||
let A = h.slot, _ = o[A];
|
||||
tt(h, "remove", "slot"), _ && (X(_, h, n), Reflect.deleteProperty(o, A));
|
||||
let E = l.slot, _ = o[E];
|
||||
tt(l, "remove", "slot"), _ && (X(_, l, n), Reflect.deleteProperty(o, E));
|
||||
}
|
||||
return c && (o[r].replaceWith(b), Reflect.deleteProperty(o, r)), t.append = f, t;
|
||||
}
|
||||
@ -151,19 +158,20 @@ function bt(t, e, n) {
|
||||
}
|
||||
return e;
|
||||
}
|
||||
function Q(...t) {
|
||||
return t.filter(Boolean).join(" ");
|
||||
}
|
||||
function X(t, e, n) {
|
||||
n && n(t, e);
|
||||
try {
|
||||
t.replaceWith(O(e, { className: [e.className, t.className], dataset: { ...t.dataset } }));
|
||||
t.replaceWith(O(e, {
|
||||
className: Q(e.className, t.className),
|
||||
dataset: { ...t.dataset }
|
||||
}));
|
||||
} catch {
|
||||
t.replaceWith(e);
|
||||
}
|
||||
}
|
||||
j.mark = function(t, e = !1) {
|
||||
t = Object.entries(t).map(([o, c]) => o + `="${c}"`).join(" ");
|
||||
let n = e ? "" : "/", r = a.D.createComment(`<dde:mark ${t}${a.ssr}${n}>`);
|
||||
return e && (r.end = a.D.createComment("</dde:mark>")), r;
|
||||
};
|
||||
function gt(t) {
|
||||
let e = this;
|
||||
return function(...r) {
|
||||
@ -223,16 +231,13 @@ function Y(t, e) {
|
||||
(r, o) => t.classList.toggle(r, o === -1 ? void 0 : !!o)
|
||||
), t;
|
||||
}
|
||||
function vt(t) {
|
||||
return Array.from(t.children).forEach((e) => e.remove()), t;
|
||||
}
|
||||
function tt(t, e, n, r) {
|
||||
return t instanceof a.H ? t[e + "Attribute"](n, r) : t[e + "AttributeNS"](null, n, r);
|
||||
}
|
||||
function et(t, e) {
|
||||
if (!(e in t)) return !1;
|
||||
let n = I(t, e);
|
||||
return !E(n.set);
|
||||
return !x(n.set);
|
||||
}
|
||||
function I(t, e) {
|
||||
if (t = Object.getPrototypeOf(t), !t) return {};
|
||||
@ -245,22 +250,19 @@ function M(t, e, n) {
|
||||
o && (c = t.processReactiveAttribute(e, o, c, n), n(o, c));
|
||||
});
|
||||
}
|
||||
function Z(t) {
|
||||
return Array.isArray(t) ? t.filter(Boolean).join(" ") : t;
|
||||
}
|
||||
function nt(t, e, n, r) {
|
||||
return t[(E(r) ? "remove" : "set") + e](n, Z(r));
|
||||
return t[(x(r) ? "remove" : "set") + e](n, r);
|
||||
}
|
||||
function rt(t, e, n, r, o = null) {
|
||||
return t[(E(r) ? "remove" : "set") + e + "NS"](o, n, Z(r));
|
||||
return t[(x(r) ? "remove" : "set") + e + "NS"](o, n, r);
|
||||
}
|
||||
function H(t, e, n) {
|
||||
if (Reflect.set(t, e, n), !!E(n))
|
||||
if (Reflect.set(t, e, n), !!x(n))
|
||||
return Reflect.deleteProperty(t, e);
|
||||
}
|
||||
|
||||
// src/events-observer.js
|
||||
var w = a.M ? ot() : new Proxy({}, {
|
||||
var A = a.M ? ot() : new Proxy({}, {
|
||||
get() {
|
||||
return () => {
|
||||
};
|
||||
@ -270,11 +272,11 @@ function ot() {
|
||||
let t = /* @__PURE__ */ new Map(), e = !1, n = (i) => function(u) {
|
||||
for (let s of u)
|
||||
if (s.type === "childList") {
|
||||
if (h(s.addedNodes, !0)) {
|
||||
if (l(s.addedNodes, !0)) {
|
||||
i();
|
||||
continue;
|
||||
}
|
||||
A(s.removedNodes, !0) && i();
|
||||
E(s.removedNodes, !0) && i();
|
||||
}
|
||||
}, r = new a.M(n(d));
|
||||
return {
|
||||
@ -336,19 +338,19 @@ function ot() {
|
||||
s === i || !(s instanceof Node) || i.contains(s) && u.push(s);
|
||||
return u;
|
||||
}
|
||||
function h(i, u) {
|
||||
function l(i, u) {
|
||||
let s = !1;
|
||||
for (let l of i) {
|
||||
if (u && b(l).then(h), !t.has(l)) continue;
|
||||
let m = t.get(l);
|
||||
m.length_c && (l.dispatchEvent(new Event(g)), m.connected = /* @__PURE__ */ new WeakSet(), m.length_c = 0, m.length_d || t.delete(l), s = !0);
|
||||
for (let h of i) {
|
||||
if (u && b(h).then(l), !t.has(h)) continue;
|
||||
let C = t.get(h);
|
||||
C.length_c && (h.dispatchEvent(new Event(g)), C.connected = /* @__PURE__ */ new WeakSet(), C.length_c = 0, C.length_d || t.delete(h), s = !0);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
function A(i, u) {
|
||||
function E(i, u) {
|
||||
let s = !1;
|
||||
for (let l of i)
|
||||
u && b(l).then(A), !(!t.has(l) || !t.get(l).length_d) && ((globalThis.queueMicrotask || setTimeout)(_(l)), s = !0);
|
||||
for (let h of i)
|
||||
u && b(h).then(E), !(!t.has(h) || !t.get(h).length_d) && ((globalThis.queueMicrotask || setTimeout)(_(h)), s = !0);
|
||||
return s;
|
||||
}
|
||||
function _(i) {
|
||||
@ -359,15 +361,15 @@ function ot() {
|
||||
}
|
||||
|
||||
// src/customElement.js
|
||||
function Dt(t, e, n, r = it) {
|
||||
function mt(t, e, n, r = it) {
|
||||
S.push({
|
||||
scope: t,
|
||||
host: (...f) => f.length ? f.forEach((d) => d(t)) : t
|
||||
}), typeof r == "function" && (r = r.call(t, t));
|
||||
let o = t[x];
|
||||
let o = t[w];
|
||||
o || ct(t);
|
||||
let c = n.call(t, r);
|
||||
return o || t.dispatchEvent(new Event(g)), e.nodeType === 11 && typeof e.mode == "string" && t.addEventListener(y, w.observe(e), { once: !0 }), S.pop(), e.append(c);
|
||||
return o || t.dispatchEvent(new Event(g)), e.nodeType === 11 && typeof e.mode == "string" && t.addEventListener(y, A.observe(e), { once: !0 }), S.pop(), e.append(c);
|
||||
}
|
||||
function ct(t) {
|
||||
return k(t.prototype, "connectedCallback", function(e, n, r) {
|
||||
@ -381,7 +383,7 @@ function ct(t) {
|
||||
n.dispatchEvent(new CustomEvent(D, {
|
||||
detail: [o, c]
|
||||
})), e.apply(n, r);
|
||||
}), t.prototype[x] = !0, t;
|
||||
}), t.prototype[w] = !0, t;
|
||||
}
|
||||
function k(t, e, n) {
|
||||
t[e] = new Proxy(t[e] || (() => {
|
||||
@ -392,7 +394,7 @@ function it(t) {
|
||||
}
|
||||
|
||||
// src/events.js
|
||||
function _t(t, e, n) {
|
||||
function Rt(t, e, n) {
|
||||
return e || (e = {}), function(o, ...c) {
|
||||
n && (c.unshift(o), o = typeof n == "function" ? n() : n);
|
||||
let f = c.length ? new CustomEvent(t, Object.assign({ detail: c[0] }, e)) : new Event(t, e);
|
||||
@ -404,15 +406,15 @@ function R(t, e, n) {
|
||||
return o.addEventListener(t, e, n), o;
|
||||
};
|
||||
}
|
||||
var G = (t) => Object.assign({}, typeof t == "object" ? t : null, { once: !0 });
|
||||
var Z = (t) => Object.assign({}, typeof t == "object" ? t : null, { once: !0 });
|
||||
R.connected = function(t, e) {
|
||||
return e = G(e), function(r) {
|
||||
return r.addEventListener(g, t, e), r[x] ? r : r.isConnected ? (r.dispatchEvent(new Event(g)), r) : (N(e.signal, () => w.offConnected(r, t)) && w.onConnected(r, t), r);
|
||||
return e = Z(e), function(r) {
|
||||
return r.addEventListener(g, t, e), r[w] ? r : r.isConnected ? (r.dispatchEvent(new Event(g)), r) : (N(e.signal, () => A.offConnected(r, t)) && A.onConnected(r, t), r);
|
||||
};
|
||||
};
|
||||
R.disconnected = function(t, e) {
|
||||
return e = G(e), function(r) {
|
||||
return r.addEventListener(y, t, e), r[x] || N(e.signal, () => w.offDisconnected(r, t)) && w.onDisconnected(r, t), r;
|
||||
return e = Z(e), function(r) {
|
||||
return r.addEventListener(y, t, e), r[w] || N(e.signal, () => A.offDisconnected(r, t)) && A.onDisconnected(r, t), r;
|
||||
};
|
||||
};
|
||||
var W = /* @__PURE__ */ new WeakMap();
|
||||
@ -424,7 +426,7 @@ R.disconnectedAsAbort = function(t) {
|
||||
var st = /* @__PURE__ */ new WeakSet();
|
||||
R.attributeChanged = function(t, e) {
|
||||
return typeof e != "object" && (e = {}), function(r) {
|
||||
if (r.addEventListener(D, t, e), r[x] || st.has(r) || !a.M) return r;
|
||||
if (r.addEventListener(D, t, e), r[w] || st.has(r) || !a.M) return r;
|
||||
let o = new a.M(function(f) {
|
||||
for (let { attributeName: d, target: p } of f)
|
||||
p.dispatchEvent(
|
||||
@ -438,21 +440,21 @@ R.attributeChanged = function(t, e) {
|
||||
globalThis.dde= {
|
||||
assign: O,
|
||||
assignAttribute: z,
|
||||
chainableAppend: Q,
|
||||
chainableAppend: K,
|
||||
classListDeclarative: Y,
|
||||
cn: Q,
|
||||
createElement: j,
|
||||
createElementNS: gt,
|
||||
customElementRender: Dt,
|
||||
customElementRender: mt,
|
||||
customElementWithDDE: ct,
|
||||
dispatchEvent: _t,
|
||||
dispatchEvent: Rt,
|
||||
el: j,
|
||||
elNS: gt,
|
||||
elementAttribute: tt,
|
||||
empty: vt,
|
||||
lifecyclesToEvents: ct,
|
||||
observedAttributes: it,
|
||||
on: R,
|
||||
registerReactivity: V,
|
||||
registerReactivity: G,
|
||||
scope: S,
|
||||
simulateSlots: bt
|
||||
};
|
||||
|
136
dist/esm-with-signals.d.ts
vendored
136
dist/esm-with-signals.d.ts
vendored
@ -1,13 +1,15 @@
|
||||
declare global{ /* ddeSignal */ }
|
||||
type CustomElementTagNameMap= { '#text': Text, '#comment': Comment }
|
||||
type SupportedElement=
|
||||
HTMLElementTagNameMap[keyof HTMLElementTagNameMap]
|
||||
| SVGElementTagNameMap[keyof SVGElementTagNameMap]
|
||||
| MathMLElementTagNameMap[keyof MathMLElementTagNameMap]
|
||||
| CustomElementTagNameMap[keyof CustomElementTagNameMap]
|
||||
HTMLElementTagNameMap[keyof HTMLElementTagNameMap]
|
||||
| SVGElementTagNameMap[keyof SVGElementTagNameMap]
|
||||
| MathMLElementTagNameMap[keyof MathMLElementTagNameMap]
|
||||
| CustomElementTagNameMap[keyof CustomElementTagNameMap]
|
||||
declare global {
|
||||
type ddeComponentAttributes= Record<any, any> | undefined;
|
||||
type ddeElementAddon<El extends SupportedElement | DocumentFragment>= (element: El)=> El | void;
|
||||
type ddeElementAddon<El extends SupportedElement | DocumentFragment | Node>= (element: El)=> any;
|
||||
type ddeString= string | ddeSignal<string>
|
||||
type ddeStringable= ddeString | number | ddeSignal<number>
|
||||
}
|
||||
type PascalCase=
|
||||
`${Capitalize<string>}${string}`;
|
||||
@ -15,50 +17,72 @@ type AttrsModified= {
|
||||
/**
|
||||
* Use string like in HTML (internally uses `*.setAttribute("style", *)`), or object representation (like DOM API).
|
||||
*/
|
||||
style: string | Partial<CSSStyleDeclaration> | ddeSignal<string> | Partial<{ [K in keyof CSSStyleDeclaration]: ddeSignal<CSSStyleDeclaration[K]> }>
|
||||
style: Partial<CSSStyleDeclaration> | ddeString
|
||||
| Partial<{ [K in keyof CSSStyleDeclaration]: ddeSignal<CSSStyleDeclaration[K]> }>
|
||||
/**
|
||||
* Provide option to add/remove/toggle CSS clasess (index of object) using 1/0/-1. In fact `el.classList.toggle(class_name)` for `-1` and `el.classList.toggle(class_name, Boolean(...))` for others.
|
||||
* Provide option to add/remove/toggle CSS clasess (index of object) using 1/0/-1.
|
||||
* In fact `el.classList.toggle(class_name)` for `-1` and `el.classList.toggle(class_name, Boolean(...))`
|
||||
* for others.
|
||||
*/
|
||||
classList: Record<string,-1|0|1|boolean|ddeSignal<-1|0|1|boolean>>,
|
||||
/**
|
||||
* By default simiral to `className`, but also supports `string[]`
|
||||
* Used by the dataset HTML attribute to represent data for custom attributes added to elements.
|
||||
* Values are converted to string (see {@link DOMStringMap}).
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMStringMap)
|
||||
* */
|
||||
className: string | (string|boolean|undefined|ddeSignal<string|boolean|undefined>)[];
|
||||
dataset: Record<string, ddeStringable>,
|
||||
/**
|
||||
* Sets `aria-*` simiraly to `dataset`
|
||||
* */
|
||||
ariaset: Record<string,string|ddeSignal<string>>,
|
||||
} & Record<`=${string}` | `data${PascalCase}` | `aria${PascalCase}`, string|ddeSignal<string>> & Record<`.${string}`, any>
|
||||
ariaset: Record<string, ddeString>,
|
||||
} & Record<`=${string}` | `data${PascalCase}` | `aria${PascalCase}`, ddeString>
|
||||
& Record<`.${string}`, any>
|
||||
type _fromElsInterfaces<EL extends SupportedElement>= Omit<EL, keyof AttrsModified>;
|
||||
type IsReadonly<T, K extends keyof T> =
|
||||
T extends { readonly [P in K]: T[K] } ? true : false;
|
||||
/**
|
||||
* Just element attributtes
|
||||
*
|
||||
* In most cases, you can use native propertie such as [MDN WEB/API/Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) and so on (e.g. [`Text`](https://developer.mozilla.org/en-US/docs/Web/API/Text)).
|
||||
* In most cases, you can use native propertie such as
|
||||
* [MDN WEB/API/Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) and so on
|
||||
* (e.g. [`Text`](https://developer.mozilla.org/en-US/docs/Web/API/Text)).
|
||||
*
|
||||
* There is added support for `data[A-Z].*`/`aria[A-Z].*` to be converted to the kebab-case alternatives.
|
||||
* @private
|
||||
*/
|
||||
type ElementAttributes<T extends SupportedElement>= Partial<{ [K in keyof _fromElsInterfaces<T>]: _fromElsInterfaces<T>[K] | ddeSignal<_fromElsInterfaces<T>[K]> } & AttrsModified> & Record<string, any>;
|
||||
export function classListDeclarative<El extends SupportedElement>(element: El, classList: AttrsModified["classList"]): El
|
||||
type ElementAttributes<T extends SupportedElement>= Partial<{
|
||||
[K in keyof _fromElsInterfaces<T>]: IsReadonly<_fromElsInterfaces<T>, K> extends false
|
||||
? _fromElsInterfaces<T>[K] | ddeSignal<_fromElsInterfaces<T>[K]>
|
||||
: ddeStringable
|
||||
} & AttrsModified> & Record<string, any>;
|
||||
export function classListDeclarative<El extends SupportedElement>(
|
||||
element: El,
|
||||
classList: AttrsModified["classList"]
|
||||
): El
|
||||
export function assign<El extends SupportedElement>(element: El, ...attrs_array: ElementAttributes<El>[]): El
|
||||
export function assignAttribute<El extends SupportedElement, ATT extends keyof ElementAttributes<El>>(element: El, attr: ATT, value: ElementAttributes<El>[ATT]): ElementAttributes<El>[ATT]
|
||||
export function assignAttribute<El extends SupportedElement, ATT extends keyof ElementAttributes<El>>(
|
||||
element: El,
|
||||
attr: ATT,
|
||||
value: ElementAttributes<El>[ATT]
|
||||
): ElementAttributes<El>[ATT]
|
||||
|
||||
type ExtendedHTMLElementTagNameMap= HTMLElementTagNameMap & CustomElementTagNameMap;
|
||||
type textContent= string | ddeSignal<string>;
|
||||
export function el<
|
||||
TAG extends keyof ExtendedHTMLElementTagNameMap,
|
||||
EL extends ExtendedHTMLElementTagNameMap[TAG]
|
||||
>(
|
||||
tag_name: TAG,
|
||||
attrs?: ElementAttributes<EL> | textContent,
|
||||
...addons: ddeElementAddon<EL>[]
|
||||
attrs?: ElementAttributes<ExtendedHTMLElementTagNameMap[NoInfer<TAG>]> | ddeString,
|
||||
...addons: ddeElementAddon<
|
||||
ExtendedHTMLElementTagNameMap[NoInfer<TAG>]
|
||||
>[], // TODO: for now addons must have the same element
|
||||
): TAG extends keyof ddeHTMLElementTagNameMap ? ddeHTMLElementTagNameMap[TAG] : ddeHTMLElement
|
||||
export function el(
|
||||
tag_name?: "<>",
|
||||
): ddeDocumentFragment
|
||||
export function el(
|
||||
tag_name: string,
|
||||
attrs?: ElementAttributes<HTMLElement> | textContent,
|
||||
attrs?: ElementAttributes<HTMLElement> | ddeString,
|
||||
...addons: ddeElementAddon<HTMLElement>[]
|
||||
): ddeHTMLElement
|
||||
|
||||
@ -66,9 +90,11 @@ export function el<
|
||||
C extends (attr: ddeComponentAttributes)=> SupportedElement | ddeDocumentFragment
|
||||
>(
|
||||
component: C,
|
||||
attrs?: Parameters<C>[0] | textContent,
|
||||
attrs?: Parameters<C>[0] | ddeString,
|
||||
...addons: ddeElementAddon<ReturnType<C>>[]
|
||||
): ReturnType<C> extends ddeHTMLElementTagNameMap[keyof ddeHTMLElementTagNameMap] ? ReturnType<C> : ( ReturnType<C> extends ddeDocumentFragment ? ReturnType<C> : ddeHTMLElement )
|
||||
): ReturnType<C> extends ddeHTMLElementTagNameMap[keyof ddeHTMLElementTagNameMap]
|
||||
? ReturnType<C>
|
||||
: ( ReturnType<C> extends ddeDocumentFragment ? ReturnType<C> : ddeHTMLElement )
|
||||
export { el as createElement }
|
||||
|
||||
export function elNS(
|
||||
@ -78,8 +104,8 @@ export function elNS(
|
||||
EL extends ( TAG extends keyof SVGElementTagNameMap ? SVGElementTagNameMap[TAG] : SVGElement ),
|
||||
>(
|
||||
tag_name: TAG,
|
||||
attrs?: ElementAttributes<EL> | textContent,
|
||||
...addons: ddeElementAddon<EL>[]
|
||||
attrs?: ElementAttributes<NoInfer<EL>> | ddeString,
|
||||
...addons: ddeElementAddon<NoInfer<EL>>[]
|
||||
)=> TAG extends keyof ddeSVGElementTagNameMap ? ddeSVGElementTagNameMap[TAG] : ddeSVGElement
|
||||
export function elNS(
|
||||
namespace: "http://www.w3.org/1998/Math/MathML"
|
||||
@ -88,14 +114,16 @@ export function elNS(
|
||||
EL extends ( TAG extends keyof MathMLElementTagNameMap ? MathMLElementTagNameMap[TAG] : MathMLElement ),
|
||||
>(
|
||||
tag_name: TAG,
|
||||
attrs?: string | textContent | Partial<{ [key in keyof EL]: EL[key] | ddeSignal<EL[key]> | string | number | boolean }>,
|
||||
...addons: ddeElementAddon<EL>[]
|
||||
attrs?: ddeString | Partial<{
|
||||
[key in keyof EL]: EL[key] | ddeSignal<EL[key]> | string | number | boolean
|
||||
}>,
|
||||
...addons: ddeElementAddon<NoInfer<EL>>[]
|
||||
)=> ddeMathMLElement
|
||||
export function elNS(
|
||||
namespace: string
|
||||
): (
|
||||
tag_name: string,
|
||||
attrs?: string | textContent | Record<string, any>,
|
||||
attrs?: string | ddeString | Record<string, any>,
|
||||
...addons: ddeElementAddon<SupportedElement>[]
|
||||
)=> SupportedElement
|
||||
export { elNS as createElementNS }
|
||||
@ -106,36 +134,45 @@ export function chainableAppend<EL extends SupportedElement>(el: EL): EL;
|
||||
* */
|
||||
type simulateSlotsMapper= (body: HTMLSlotElement, el: HTMLElement)=> void;
|
||||
/** Simulate slots for ddeComponents */
|
||||
export function simulateSlots<EL extends SupportedElement | DocumentFragment>(root: EL, mapper?: simulateSlotsMapper): EL
|
||||
export function simulateSlots<EL extends SupportedElement | DocumentFragment>(
|
||||
root: EL,
|
||||
mapper?: simulateSlotsMapper
|
||||
): EL
|
||||
/**
|
||||
* Simulate slots in Custom Elements without using `shadowRoot`.
|
||||
* @param el Custom Element root element
|
||||
* @param body Body of the custom element
|
||||
* */
|
||||
export function simulateSlots<EL extends SupportedElement | DocumentFragment>(el: HTMLElement, body: EL, mapper?: simulateSlotsMapper): EL
|
||||
export function simulateSlots<EL extends SupportedElement | DocumentFragment>(
|
||||
el: HTMLElement,
|
||||
body: EL, mapper?: simulateSlotsMapper
|
||||
): EL
|
||||
|
||||
export function dispatchEvent(name: keyof DocumentEventMap | string, options?: EventInit):
|
||||
(element: SupportedElement, data?: any)=> void;
|
||||
export function dispatchEvent(name: keyof DocumentEventMap | string, options: EventInit | null, element: SupportedElement | (()=> SupportedElement)):
|
||||
(data?: any)=> void;
|
||||
export function dispatchEvent(
|
||||
name: keyof DocumentEventMap | string,
|
||||
options: EventInit | null,
|
||||
element: SupportedElement | (()=> SupportedElement)
|
||||
): (data?: any)=> void;
|
||||
interface On{
|
||||
/** Listens to the DOM event. See {@link Document.addEventListener} */
|
||||
<
|
||||
EE extends ddeElementAddon<SupportedElement>,
|
||||
El extends ( EE extends ddeElementAddon<infer El> ? El : never ),
|
||||
Event extends keyof DocumentEventMap>(
|
||||
Event extends keyof DocumentEventMap,
|
||||
EE extends ddeElementAddon<SupportedElement>= ddeElementAddon<HTMLElement>,
|
||||
>(
|
||||
type: Event,
|
||||
listener: (this: El, ev: DocumentEventMap[Event]) => any,
|
||||
listener: (this: EE extends ddeElementAddon<infer El> ? El : never, ev: DocumentEventMap[Event]) => any,
|
||||
options?: AddEventListenerOptions
|
||||
) : EE;
|
||||
<
|
||||
EE extends ddeElementAddon<SupportedElement>,
|
||||
El extends ( EE extends ddeElementAddon<infer El> ? El : never )>(
|
||||
EE extends ddeElementAddon<SupportedElement>= ddeElementAddon<HTMLElement>,
|
||||
>(
|
||||
type: string,
|
||||
listener: (this: El, ev: Event | CustomEvent ) => any,
|
||||
listener: (this: EE extends ddeElementAddon<infer El> ? El : never, ev: Event | CustomEvent ) => any,
|
||||
options?: AddEventListenerOptions
|
||||
) : EE;
|
||||
/** Listens to the element is connected to the live DOM. In case of custom elements uses [`connectedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */
|
||||
/** Listens to the element is connected to the live DOM. In case of custom elements uses [`connectedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */// editorconfig-checker-disable-line
|
||||
connected<
|
||||
EE extends ddeElementAddon<SupportedElement>,
|
||||
El extends ( EE extends ddeElementAddon<infer El> ? El : never )
|
||||
@ -143,7 +180,7 @@ interface On{
|
||||
listener: (this: El, event: CustomEvent<El>) => any,
|
||||
options?: AddEventListenerOptions
|
||||
) : EE;
|
||||
/** Listens to the element is disconnected from the live DOM. In case of custom elements uses [`disconnectedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */
|
||||
/** Listens to the element is disconnected from the live DOM. In case of custom elements uses [`disconnectedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */// editorconfig-checker-disable-line
|
||||
disconnected<
|
||||
EE extends ddeElementAddon<SupportedElement>,
|
||||
El extends ( EE extends ddeElementAddon<infer El> ? El : never )
|
||||
@ -151,7 +188,7 @@ interface On{
|
||||
listener: (this: El, event: CustomEvent<void>) => any,
|
||||
options?: AddEventListenerOptions
|
||||
) : EE;
|
||||
/** Listens to the element attribute changes. In case of custom elements uses [`attributeChangedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */
|
||||
/** Listens to the element attribute changes. In case of custom elements uses [`attributeChangedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */// editorconfig-checker-disable-line
|
||||
attributeChanged<
|
||||
EE extends ddeElementAddon<SupportedElement>,
|
||||
El extends ( EE extends ddeElementAddon<infer El> ? El : never )
|
||||
@ -162,7 +199,12 @@ interface On{
|
||||
}
|
||||
export const on: On;
|
||||
|
||||
type Scope= { scope: Node | Function | Object, host: ddeElementAddon<any>, custom_element: false | HTMLElement, prevent: boolean }
|
||||
type Scope= {
|
||||
scope: Node | Function | Object,
|
||||
host: ddeElementAddon<any>,
|
||||
custom_element: false | HTMLElement,
|
||||
prevent: boolean
|
||||
};
|
||||
/** Current scope created last time the `el(Function)` was invoke. (Or {@link scope.push}) */
|
||||
export const scope: {
|
||||
current: Scope,
|
||||
@ -176,7 +218,7 @@ export const scope: {
|
||||
* — `scope.host(on.connected(console.log))`.
|
||||
* */
|
||||
host: (...addons: ddeElementAddon<SupportedElement>[])=> HTMLElement,
|
||||
|
||||
|
||||
state: Scope[],
|
||||
/** Adds new child scope. All attributes are inherited by default. */
|
||||
push(scope: Partial<Scope>): ReturnType<Array<Scope>["push"]>,
|
||||
@ -202,12 +244,12 @@ export function observedAttributes(custom_element: HTMLElement): Record<string,
|
||||
/* TypeScript MEH */
|
||||
declare global{
|
||||
type ddeAppend<el>= (...nodes: (Node | string)[])=> el;
|
||||
|
||||
|
||||
interface ddeDocumentFragment extends DocumentFragment{ append: ddeAppend<ddeDocumentFragment>; }
|
||||
interface ddeHTMLElement extends HTMLElement{ append: ddeAppend<ddeHTMLElement>; }
|
||||
interface ddeSVGElement extends SVGElement{ append: ddeAppend<ddeSVGElement>; }
|
||||
interface ddeMathMLElement extends MathMLElement{ append: ddeAppend<ddeMathMLElement>; }
|
||||
|
||||
|
||||
interface ddeHTMLElementTagNameMap {
|
||||
"a": ddeHTMLAnchorElement;
|
||||
"area": ddeHTMLAreaElement;
|
||||
@ -350,6 +392,7 @@ declare global{
|
||||
}
|
||||
}
|
||||
|
||||
// editorconfig-checker-disable
|
||||
interface ddeHTMLAnchorElement extends HTMLAnchorElement{ append: ddeAppend<ddeHTMLAnchorElement>; }
|
||||
interface ddeHTMLAreaElement extends HTMLAreaElement{ append: ddeAppend<ddeHTMLAreaElement>; }
|
||||
interface ddeHTMLAudioElement extends HTMLAudioElement{ append: ddeAppend<ddeHTMLAudioElement>; }
|
||||
@ -477,6 +520,7 @@ interface ddeSVGTitleElement extends SVGTitleElement{ append: ddeAppend<ddeSVGTi
|
||||
interface ddeSVGTSpanElement extends SVGTSpanElement{ append: ddeAppend<ddeSVGTSpanElement>; }
|
||||
interface ddeSVGUseElement extends SVGUseElement{ append: ddeAppend<ddeSVGUseElement>; }
|
||||
interface ddeSVGViewElement extends SVGViewElement{ append: ddeAppend<ddeSVGViewElement>; }
|
||||
// editorconfig-checker-enable
|
||||
export type Signal<V, A>= (set?: V)=> V & A;
|
||||
type Action<V>= (this: { value: V, stopPropagation(): void }, ...a: any[])=> typeof signal._ | void;
|
||||
//type SymbolSignal= Symbol;
|
||||
@ -534,7 +578,7 @@ interface signal{
|
||||
* */
|
||||
el<S extends any>(signal: Signal<S, any>, el: (v: S)=> Element | Element[] | DocumentFragment): DocumentFragment;
|
||||
|
||||
observedAttributes(custom_element: HTMLElement): Record<string, Signal<string, {}>>;
|
||||
observedAttributes(custom_element: HTMLElement): Record<string, Signal<string, {}>>;
|
||||
}
|
||||
export const signal: signal;
|
||||
export const S: signal;
|
||||
|
238
dist/esm-with-signals.js
vendored
238
dist/esm-with-signals.js
vendored
@ -34,16 +34,16 @@ function q(t, e) {
|
||||
function F(t, e) {
|
||||
let { observedAttributes: n = [] } = t.constructor;
|
||||
return n.reduce(function(r, o) {
|
||||
return r[pt(o)] = e(t, o), r;
|
||||
return r[dt(o)] = e(t, o), r;
|
||||
}, {});
|
||||
}
|
||||
function pt(t) {
|
||||
function dt(t) {
|
||||
return t.replace(/-./g, (e) => e[1].toUpperCase());
|
||||
}
|
||||
|
||||
// src/dom-common.js
|
||||
var d = {
|
||||
setDeleteAttr: lt,
|
||||
setDeleteAttr: pt,
|
||||
ssr: "",
|
||||
D: globalThis.document,
|
||||
F: globalThis.DocumentFragment,
|
||||
@ -51,7 +51,7 @@ var d = {
|
||||
S: globalThis.SVGElement,
|
||||
M: globalThis.MutationObserver
|
||||
};
|
||||
function lt(t, e, n) {
|
||||
function pt(t, e, n) {
|
||||
if (Reflect.set(t, e, n), !!S(n)) {
|
||||
if (Reflect.deleteProperty(t, e), t instanceof d.H && t.getAttribute(e) === "undefined")
|
||||
return t.removeAttribute(e);
|
||||
@ -68,7 +68,7 @@ var A = [{
|
||||
},
|
||||
host: (t) => t ? t(d.D.body) : d.D.body,
|
||||
prevent: !0
|
||||
}], m = {
|
||||
}], x = {
|
||||
get current() {
|
||||
return A[A.length - 1];
|
||||
},
|
||||
@ -96,7 +96,7 @@ var A = [{
|
||||
function Y(...t) {
|
||||
return this.appendOriginal(...t), this;
|
||||
}
|
||||
function ht(t) {
|
||||
function lt(t) {
|
||||
return t.append === Y || (t.appendOriginal = t.append, t.append = Y), t;
|
||||
}
|
||||
var $;
|
||||
@ -104,15 +104,17 @@ function P(t, e, ...n) {
|
||||
let r = W(this), o = 0, c, i;
|
||||
switch ((Object(e) !== e || r.isSignal(e)) && (e = { textContent: e }), !0) {
|
||||
case typeof t == "function": {
|
||||
o = 1, m.push({ scope: t, host: (...v) => v.length ? (o === 1 ? n.unshift(...v) : v.forEach((h) => h(i)), void 0) : i }), c = t(e || void 0);
|
||||
let a = c instanceof d.F;
|
||||
o = 1;
|
||||
let a = (...p) => p.length ? (o === 1 ? n.unshift(...p) : p.forEach((m) => m(i)), void 0) : i;
|
||||
x.push({ scope: t, host: a }), c = t(e || void 0);
|
||||
let h = c instanceof d.F;
|
||||
if (c.nodeName === "#comment") break;
|
||||
let l = P.mark({
|
||||
let v = P.mark({
|
||||
type: "component",
|
||||
name: t.name,
|
||||
host: a ? "this" : "parentElement"
|
||||
host: h ? "this" : "parentElement"
|
||||
});
|
||||
c.prepend(l), a && (i = l);
|
||||
c.prepend(v), h && (i = v);
|
||||
break;
|
||||
}
|
||||
case t === "#text":
|
||||
@ -127,23 +129,28 @@ function P(t, e, ...n) {
|
||||
case !c:
|
||||
c = j.call(this, d.D.createElement(t), e);
|
||||
}
|
||||
return ht(c), i || (i = c), n.forEach((a) => a(i)), o && m.pop(), o = 2, c;
|
||||
return lt(c), i || (i = c), n.forEach((a) => a(i)), o && x.pop(), o = 2, c;
|
||||
}
|
||||
P.mark = function(t, e = !1) {
|
||||
t = Object.entries(t).map(([o, c]) => o + `="${c}"`).join(" ");
|
||||
let n = e ? "" : "/", r = d.D.createComment(`<dde:mark ${t}${d.ssr}${n}>`);
|
||||
return e && (r.end = d.D.createComment("</dde:mark>")), r;
|
||||
};
|
||||
function Wt(t, e, n) {
|
||||
typeof e != "object" && (n = e, e = t);
|
||||
let r = Symbol.for("default"), o = Array.from(e.querySelectorAll("slot")).reduce((i, a) => Reflect.set(i, a.name || r, a) && i, {}), c = T(o, r);
|
||||
if (t.append = new Proxy(t.append, {
|
||||
apply(i, a, l) {
|
||||
if (l[0] === e) return i.apply(t, l);
|
||||
if (!l.length) return t;
|
||||
apply(i, a, h) {
|
||||
if (h[0] === e) return i.apply(t, h);
|
||||
if (!h.length) return t;
|
||||
let v = d.D.createDocumentFragment();
|
||||
for (let h of l) {
|
||||
if (!h || !h.slot) {
|
||||
c && v.append(h);
|
||||
for (let p of h) {
|
||||
if (!p || !p.slot) {
|
||||
c && v.append(p);
|
||||
continue;
|
||||
}
|
||||
let x = h.slot, w = o[x];
|
||||
vt(h, "remove", "slot"), w && (bt(w, h, n), Reflect.deleteProperty(o, x));
|
||||
let m = p.slot, y = o[m];
|
||||
vt(p, "remove", "slot"), y && (bt(y, p, n), Reflect.deleteProperty(o, m));
|
||||
}
|
||||
return c && (o[r].replaceWith(v), Reflect.deleteProperty(o, r)), t.append = i, t;
|
||||
}
|
||||
@ -153,19 +160,20 @@ function Wt(t, e, n) {
|
||||
}
|
||||
return e;
|
||||
}
|
||||
function ht(...t) {
|
||||
return t.filter(Boolean).join(" ");
|
||||
}
|
||||
function bt(t, e, n) {
|
||||
n && n(t, e);
|
||||
try {
|
||||
t.replaceWith(j(e, { className: [e.className, t.className], dataset: { ...t.dataset } }));
|
||||
t.replaceWith(j(e, {
|
||||
className: ht(e.className, t.className),
|
||||
dataset: { ...t.dataset }
|
||||
}));
|
||||
} catch {
|
||||
t.replaceWith(e);
|
||||
}
|
||||
}
|
||||
P.mark = function(t, e = !1) {
|
||||
t = Object.entries(t).map(([o, c]) => o + `="${c}"`).join(" ");
|
||||
let n = e ? "" : "/", r = d.D.createComment(`<dde:mark ${t}${d.ssr}${n}>`);
|
||||
return e && (r.end = d.D.createComment("</dde:mark>")), r;
|
||||
};
|
||||
function qt(t) {
|
||||
let e = this;
|
||||
return function(...r) {
|
||||
@ -188,7 +196,7 @@ function nt(t, e, n) {
|
||||
t,
|
||||
e,
|
||||
n,
|
||||
(a, l) => nt.call(c, t, a, l)
|
||||
(a, h) => nt.call(c, t, a, h)
|
||||
);
|
||||
let [i] = e;
|
||||
if (i === "=") return r(e.slice(1), n);
|
||||
@ -206,7 +214,7 @@ function nt(t, e, n) {
|
||||
case "dataset":
|
||||
return I(o, n, et.bind(null, t[e]));
|
||||
case "ariaset":
|
||||
return I(o, n, (a, l) => r("aria-" + a, l));
|
||||
return I(o, n, (a, h) => r("aria-" + a, h));
|
||||
case "classList":
|
||||
return gt.call(c, t, n);
|
||||
}
|
||||
@ -225,9 +233,6 @@ function gt(t, e) {
|
||||
(r, o) => t.classList.toggle(r, o === -1 ? void 0 : !!o)
|
||||
), t;
|
||||
}
|
||||
function Ft(t) {
|
||||
return Array.from(t.children).forEach((e) => e.remove()), t;
|
||||
}
|
||||
function vt(t, e, n, r) {
|
||||
return t instanceof d.H ? t[e + "Attribute"](n, r) : t[e + "AttributeNS"](null, n, r);
|
||||
}
|
||||
@ -247,14 +252,11 @@ function I(t, e, n) {
|
||||
o && (c = t.processReactiveAttribute(e, o, c, n), n(o, c));
|
||||
});
|
||||
}
|
||||
function ct(t) {
|
||||
return Array.isArray(t) ? t.filter(Boolean).join(" ") : t;
|
||||
}
|
||||
function mt(t, e, n, r) {
|
||||
return t[(S(r) ? "remove" : "set") + e](n, ct(r));
|
||||
return t[(S(r) ? "remove" : "set") + e](n, r);
|
||||
}
|
||||
function xt(t, e, n, r, o = null) {
|
||||
return t[(S(r) ? "remove" : "set") + e + "NS"](o, n, ct(r));
|
||||
return t[(S(r) ? "remove" : "set") + e + "NS"](o, n, r);
|
||||
}
|
||||
function et(t, e, n) {
|
||||
if (Reflect.set(t, e, n), !!S(n))
|
||||
@ -262,21 +264,21 @@ function et(t, e, n) {
|
||||
}
|
||||
|
||||
// src/events-observer.js
|
||||
var D = d.M ? yt() : new Proxy({}, {
|
||||
var D = d.M ? wt() : new Proxy({}, {
|
||||
get() {
|
||||
return () => {
|
||||
};
|
||||
}
|
||||
});
|
||||
function yt() {
|
||||
function wt() {
|
||||
let t = /* @__PURE__ */ new Map(), e = !1, n = (s) => function(u) {
|
||||
for (let f of u)
|
||||
if (f.type === "childList") {
|
||||
if (h(f.addedNodes, !0)) {
|
||||
if (p(f.addedNodes, !0)) {
|
||||
s();
|
||||
continue;
|
||||
}
|
||||
x(f.removedNodes, !0) && s();
|
||||
m(f.removedNodes, !0) && s();
|
||||
}
|
||||
}, r = new d.M(n(a));
|
||||
return {
|
||||
@ -325,35 +327,35 @@ function yt() {
|
||||
function a() {
|
||||
!e || t.size || (e = !1, r.disconnect());
|
||||
}
|
||||
function l() {
|
||||
function h() {
|
||||
return new Promise(function(s) {
|
||||
(requestIdleCallback || requestAnimationFrame)(s);
|
||||
});
|
||||
}
|
||||
async function v(s) {
|
||||
t.size > 30 && await l();
|
||||
t.size > 30 && await h();
|
||||
let u = [];
|
||||
if (!(s instanceof Node)) return u;
|
||||
for (let f of t.keys())
|
||||
f === s || !(f instanceof Node) || s.contains(f) && u.push(f);
|
||||
return u;
|
||||
}
|
||||
function h(s, u) {
|
||||
function p(s, u) {
|
||||
let f = !1;
|
||||
for (let b of s) {
|
||||
if (u && v(b).then(h), !t.has(b)) continue;
|
||||
if (u && v(b).then(p), !t.has(b)) continue;
|
||||
let N = t.get(b);
|
||||
N.length_c && (b.dispatchEvent(new Event(_)), N.connected = /* @__PURE__ */ new WeakSet(), N.length_c = 0, N.length_d || t.delete(b), f = !0);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
function x(s, u) {
|
||||
function m(s, u) {
|
||||
let f = !1;
|
||||
for (let b of s)
|
||||
u && v(b).then(x), !(!t.has(b) || !t.get(b).length_d) && ((globalThis.queueMicrotask || setTimeout)(w(b)), f = !0);
|
||||
u && v(b).then(m), !(!t.has(b) || !t.get(b).length_d) && ((globalThis.queueMicrotask || setTimeout)(y(b)), f = !0);
|
||||
return f;
|
||||
}
|
||||
function w(s) {
|
||||
function y(s) {
|
||||
return () => {
|
||||
s.isConnected || (s.dispatchEvent(new Event(C)), t.delete(s));
|
||||
};
|
||||
@ -361,17 +363,17 @@ function yt() {
|
||||
}
|
||||
|
||||
// src/customElement.js
|
||||
function Zt(t, e, n, r = _t) {
|
||||
m.push({
|
||||
function Jt(t, e, n, r = _t) {
|
||||
x.push({
|
||||
scope: t,
|
||||
host: (...i) => i.length ? i.forEach((a) => a(t)) : t
|
||||
}), typeof r == "function" && (r = r.call(t, t));
|
||||
let o = t[O];
|
||||
o || wt(t);
|
||||
o || yt(t);
|
||||
let c = n.call(t, r);
|
||||
return o || t.dispatchEvent(new Event(_)), e.nodeType === 11 && typeof e.mode == "string" && t.addEventListener(C, D.observe(e), { once: !0 }), m.pop(), e.append(c);
|
||||
return o || t.dispatchEvent(new Event(_)), e.nodeType === 11 && typeof e.mode == "string" && t.addEventListener(C, D.observe(e), { once: !0 }), x.pop(), e.append(c);
|
||||
}
|
||||
function wt(t) {
|
||||
function yt(t) {
|
||||
return J(t.prototype, "connectedCallback", function(e, n, r) {
|
||||
e.apply(n, r), n.dispatchEvent(new Event(_));
|
||||
}), J(t.prototype, "disconnectedCallback", function(e, n, r) {
|
||||
@ -394,43 +396,43 @@ function _t(t) {
|
||||
}
|
||||
|
||||
// src/events.js
|
||||
function Qt(t, e, n) {
|
||||
function Kt(t, e, n) {
|
||||
return e || (e = {}), function(o, ...c) {
|
||||
n && (c.unshift(o), o = typeof n == "function" ? n() : n);
|
||||
let i = c.length ? new CustomEvent(t, Object.assign({ detail: c[0] }, e)) : new Event(t, e);
|
||||
return o.dispatchEvent(i);
|
||||
};
|
||||
}
|
||||
function y(t, e, n) {
|
||||
function w(t, e, n) {
|
||||
return function(o) {
|
||||
return o.addEventListener(t, e, n), o;
|
||||
};
|
||||
}
|
||||
var it = (t) => Object.assign({}, typeof t == "object" ? t : null, { once: !0 });
|
||||
y.connected = function(t, e) {
|
||||
return e = it(e), function(r) {
|
||||
var ct = (t) => Object.assign({}, typeof t == "object" ? t : null, { once: !0 });
|
||||
w.connected = function(t, e) {
|
||||
return e = ct(e), function(r) {
|
||||
return r.addEventListener(_, t, e), r[O] ? r : r.isConnected ? (r.dispatchEvent(new Event(_)), r) : (q(e.signal, () => D.offConnected(r, t)) && D.onConnected(r, t), r);
|
||||
};
|
||||
};
|
||||
y.disconnected = function(t, e) {
|
||||
return e = it(e), function(r) {
|
||||
w.disconnected = function(t, e) {
|
||||
return e = ct(e), function(r) {
|
||||
return r.addEventListener(C, t, e), r[O] || q(e.signal, () => D.offDisconnected(r, t)) && D.onDisconnected(r, t), r;
|
||||
};
|
||||
};
|
||||
var Z = /* @__PURE__ */ new WeakMap();
|
||||
y.disconnectedAsAbort = function(t) {
|
||||
w.disconnectedAsAbort = function(t) {
|
||||
if (Z.has(t)) return Z.get(t);
|
||||
let e = new AbortController();
|
||||
return Z.set(t, e), t(y.disconnected(() => e.abort())), e;
|
||||
return Z.set(t, e), t(w.disconnected(() => e.abort())), e;
|
||||
};
|
||||
var At = /* @__PURE__ */ new WeakSet();
|
||||
y.attributeChanged = function(t, e) {
|
||||
w.attributeChanged = function(t, e) {
|
||||
return typeof e != "object" && (e = {}), function(r) {
|
||||
if (r.addEventListener(M, t, e), r[O] || At.has(r) || !d.M) return r;
|
||||
let o = new d.M(function(i) {
|
||||
for (let { attributeName: a, target: l } of i)
|
||||
l.dispatchEvent(
|
||||
new CustomEvent(M, { detail: [a, l.getAttribute(a)] })
|
||||
for (let { attributeName: a, target: h } of i)
|
||||
h.dispatchEvent(
|
||||
new CustomEvent(M, { detail: [a, h.getAttribute(a)] })
|
||||
);
|
||||
});
|
||||
return q(e.signal, () => o.disconnect()) && o.observe(r, { attributes: !0 }), r;
|
||||
@ -438,10 +440,10 @@ y.attributeChanged = function(t, e) {
|
||||
};
|
||||
|
||||
// src/signals-lib.js
|
||||
var p = "__dde_signal";
|
||||
var l = "__dde_signal";
|
||||
function z(t) {
|
||||
try {
|
||||
return T(t, p);
|
||||
return T(t, l);
|
||||
} catch {
|
||||
return !1;
|
||||
}
|
||||
@ -449,19 +451,19 @@ function z(t) {
|
||||
var H = [], g = /* @__PURE__ */ new WeakMap();
|
||||
function E(t, e) {
|
||||
if (typeof t != "function")
|
||||
return st(!1, t, e);
|
||||
return it(!1, t, e);
|
||||
if (z(t)) return t;
|
||||
let n = st(!0), r = function() {
|
||||
let n = it(!0), r = function() {
|
||||
let [o, ...c] = g.get(r);
|
||||
if (g.set(r, /* @__PURE__ */ new Set([o])), H.push(r), dt(n, t()), H.pop(), !c.length) return;
|
||||
if (g.set(r, /* @__PURE__ */ new Set([o])), H.push(r), at(n, t()), H.pop(), !c.length) return;
|
||||
let i = g.get(r);
|
||||
for (let a of c)
|
||||
i.has(a) || L(a, r);
|
||||
};
|
||||
return g.set(n[p], r), g.set(r, /* @__PURE__ */ new Set([n])), r(), n;
|
||||
return g.set(n[l], r), g.set(r, /* @__PURE__ */ new Set([n])), r(), n;
|
||||
}
|
||||
E.action = function(t, e, ...n) {
|
||||
let r = t[p], { actions: o } = r;
|
||||
let r = t[l], { actions: o } = r;
|
||||
if (!o || !(e in o))
|
||||
throw new Error(`'${t}' has no action with name '${e}'!`);
|
||||
if (o[e].apply(r, n), r.skip) return delete r.skip;
|
||||
@ -480,8 +482,8 @@ E.symbols = {
|
||||
};
|
||||
E.clear = function(...t) {
|
||||
for (let n of t) {
|
||||
let r = n[p];
|
||||
r && (delete n.toJSON, r.onclear.forEach((o) => o.call(r)), e(n, r), delete n[p]);
|
||||
let r = n[l];
|
||||
r && (delete n.toJSON, r.onclear.forEach((o) => o.call(r)), e(n, r), delete n[l]);
|
||||
}
|
||||
function e(n, r) {
|
||||
r.listeners.forEach((o) => {
|
||||
@ -495,24 +497,24 @@ var R = "__dde_reactive";
|
||||
E.el = function(t, e) {
|
||||
let n = P.mark({ type: "reactive" }, !0), r = n.end, o = d.D.createDocumentFragment();
|
||||
o.append(n, r);
|
||||
let { current: c } = m, i = {}, a = (l) => {
|
||||
let { current: c } = x, i = {}, a = (h) => {
|
||||
if (!n.parentNode || !r.parentNode)
|
||||
return L(t, a);
|
||||
let v = i;
|
||||
i = {}, m.push(c);
|
||||
let h = e(l, function(u, f) {
|
||||
i = {}, x.push(c);
|
||||
let p = e(h, function(u, f) {
|
||||
let b;
|
||||
return T(v, u) ? (b = v[u], delete v[u]) : b = f(), i[u] = b, b;
|
||||
});
|
||||
m.pop(), Array.isArray(h) || (h = [h]);
|
||||
let x = document.createComment("");
|
||||
h.push(x), n.after(...h);
|
||||
let w;
|
||||
for (; (w = x.nextSibling) && w !== r; )
|
||||
w.remove();
|
||||
x.remove(), n.isConnected && St(c.host());
|
||||
x.pop(), Array.isArray(p) || (p = [p]);
|
||||
let m = document.createComment("");
|
||||
p.push(m), n.after(...p);
|
||||
let y;
|
||||
for (; (y = m.nextSibling) && y !== r; )
|
||||
y.remove();
|
||||
m.remove(), n.isConnected && St(c.host());
|
||||
};
|
||||
return Q(t, a), ft(t, a, n, e), a(t()), o;
|
||||
return Q(t, a), ut(t, a, n, e), a(t()), o;
|
||||
};
|
||||
function St(t) {
|
||||
!t || !t[R] || (requestIdleCallback || setTimeout)(function() {
|
||||
@ -526,25 +528,25 @@ var Ot = {
|
||||
};
|
||||
function Ct(t) {
|
||||
return function(e, n) {
|
||||
let r = (...c) => c.length ? e.setAttribute(n, ...c) : K(r), o = at(r, e.getAttribute(n), Ot);
|
||||
let r = (...c) => c.length ? e.setAttribute(n, ...c) : K(r), o = ft(r, e.getAttribute(n), Ot);
|
||||
return t[n] = o, o;
|
||||
};
|
||||
}
|
||||
var G = "__dde_attributes";
|
||||
E.observedAttributes = function(t) {
|
||||
let e = t[G] = {}, n = F(t, Ct(e));
|
||||
return y.attributeChanged(function({ detail: o }) {
|
||||
return w.attributeChanged(function({ detail: o }) {
|
||||
/*! This maps attributes to signals (`S.observedAttributes`).
|
||||
* Investigate `__dde_attributes` key of the element.*/
|
||||
let [c, i] = o, a = this[G][c];
|
||||
if (a) return E.action(a, "_set", i);
|
||||
})(t), y.disconnected(function() {
|
||||
})(t), w.disconnected(function() {
|
||||
/*! This removes all signals mapped to attributes (`S.observedAttributes`).
|
||||
* Investigate `__dde_attributes` key of the element.*/
|
||||
E.clear(...Object.values(this[G]));
|
||||
})(t), n;
|
||||
};
|
||||
var ut = {
|
||||
var st = {
|
||||
isSignal: z,
|
||||
processReactiveAttribute(t, e, n, r) {
|
||||
if (!z(n)) return n;
|
||||
@ -553,26 +555,26 @@ var ut = {
|
||||
return L(n, o);
|
||||
r(e, c);
|
||||
};
|
||||
return Q(n, o), ft(n, o, t, e), n();
|
||||
return Q(n, o), ut(n, o, t, e), n();
|
||||
}
|
||||
};
|
||||
function ft(t, e, ...n) {
|
||||
let { current: r } = m;
|
||||
function ut(t, e, ...n) {
|
||||
let { current: r } = x;
|
||||
r.prevent || r.host(function(o) {
|
||||
o[R] || (o[R] = [], y.disconnected(
|
||||
o[R] || (o[R] = [], w.disconnected(
|
||||
() => (
|
||||
/*!
|
||||
* Clears all Signals listeners added in the current scope/host (`S.el`, `assign`, …?).
|
||||
* You can investigate the `__dde_reactive` key of the element.
|
||||
* */
|
||||
o[R].forEach(([[c, i]]) => L(c, i, c[p] && c[p].host && c[p].host() === o))
|
||||
o[R].forEach(([[c, i]]) => L(c, i, c[l] && c[l].host && c[l].host() === o))
|
||||
)
|
||||
)(o)), o[R].push([[t, e], ...n]);
|
||||
});
|
||||
}
|
||||
function st(t, e, n) {
|
||||
let r = t ? () => K(r) : (...o) => o.length ? dt(r, ...o) : K(r);
|
||||
return at(r, e, n, t);
|
||||
function it(t, e, n) {
|
||||
let r = t ? () => K(r) : (...o) => o.length ? at(r, ...o) : K(r);
|
||||
return ft(r, e, n, t);
|
||||
}
|
||||
var Dt = Object.assign(/* @__PURE__ */ Object.create(null), {
|
||||
stopPropagation() {
|
||||
@ -586,13 +588,13 @@ var Dt = Object.assign(/* @__PURE__ */ Object.create(null), {
|
||||
this.stack = n.find((o) => !o.includes(r));
|
||||
}
|
||||
};
|
||||
function at(t, e, n, r = !1) {
|
||||
function ft(t, e, n, r = !1) {
|
||||
let o = [];
|
||||
X(n) !== "[object Object]" && (n = {});
|
||||
let { onclear: c } = E.symbols;
|
||||
n[c] && (o.push(n[c]), delete n[c]);
|
||||
let { host: i } = m;
|
||||
return Reflect.defineProperty(t, p, {
|
||||
let { host: i } = x;
|
||||
return Reflect.defineProperty(t, l, {
|
||||
value: {
|
||||
value: e,
|
||||
actions: n,
|
||||
@ -605,28 +607,28 @@ function at(t, e, n, r = !1) {
|
||||
enumerable: !1,
|
||||
writable: !1,
|
||||
configurable: !0
|
||||
}), t.toJSON = () => t(), t.valueOf = () => t[p] && t[p].value, Object.setPrototypeOf(t[p], Dt), t;
|
||||
}), t.toJSON = () => t(), t.valueOf = () => t[l] && t[l].value, Object.setPrototypeOf(t[l], Dt), t;
|
||||
}
|
||||
function Rt() {
|
||||
return H[H.length - 1];
|
||||
}
|
||||
function K(t) {
|
||||
if (!t[p]) return;
|
||||
let { value: e, listeners: n } = t[p], r = Rt();
|
||||
if (!t[l]) return;
|
||||
let { value: e, listeners: n } = t[l], r = Rt();
|
||||
return r && n.add(r), g.has(r) && g.get(r).add(t), e;
|
||||
}
|
||||
function dt(t, e, n) {
|
||||
if (!t[p]) return;
|
||||
let r = t[p];
|
||||
function at(t, e, n) {
|
||||
if (!t[l]) return;
|
||||
let r = t[l];
|
||||
if (!(!n && r.value === e))
|
||||
return r.value = e, r.listeners.forEach((o) => o(e)), e;
|
||||
}
|
||||
function Q(t, e) {
|
||||
if (t[p])
|
||||
return t[p].listeners.add(e);
|
||||
if (t[l])
|
||||
return t[l].listeners.add(e);
|
||||
}
|
||||
function L(t, e, n) {
|
||||
let r = t[p];
|
||||
let r = t[l];
|
||||
if (!r) return;
|
||||
let o = r.listeners.delete(e);
|
||||
if (n && !r.listeners.size) {
|
||||
@ -639,28 +641,28 @@ function L(t, e, n) {
|
||||
}
|
||||
|
||||
// signals.js
|
||||
B(ut);
|
||||
B(st);
|
||||
export {
|
||||
E as S,
|
||||
j as assign,
|
||||
nt as assignAttribute,
|
||||
ht as chainableAppend,
|
||||
lt as chainableAppend,
|
||||
gt as classListDeclarative,
|
||||
ht as cn,
|
||||
P as createElement,
|
||||
qt as createElementNS,
|
||||
Zt as customElementRender,
|
||||
wt as customElementWithDDE,
|
||||
Qt as dispatchEvent,
|
||||
Jt as customElementRender,
|
||||
yt as customElementWithDDE,
|
||||
Kt as dispatchEvent,
|
||||
P as el,
|
||||
qt as elNS,
|
||||
vt as elementAttribute,
|
||||
Ft as empty,
|
||||
z as isSignal,
|
||||
wt as lifecyclesToEvents,
|
||||
yt as lifecyclesToEvents,
|
||||
_t as observedAttributes,
|
||||
y as on,
|
||||
w as on,
|
||||
B as registerReactivity,
|
||||
m as scope,
|
||||
x as scope,
|
||||
E as signal,
|
||||
Wt as simulateSlots
|
||||
};
|
||||
|
136
dist/esm.d.ts
vendored
136
dist/esm.d.ts
vendored
@ -1,13 +1,15 @@
|
||||
declare global{ /* ddeSignal */ }
|
||||
type CustomElementTagNameMap= { '#text': Text, '#comment': Comment }
|
||||
type SupportedElement=
|
||||
HTMLElementTagNameMap[keyof HTMLElementTagNameMap]
|
||||
| SVGElementTagNameMap[keyof SVGElementTagNameMap]
|
||||
| MathMLElementTagNameMap[keyof MathMLElementTagNameMap]
|
||||
| CustomElementTagNameMap[keyof CustomElementTagNameMap]
|
||||
HTMLElementTagNameMap[keyof HTMLElementTagNameMap]
|
||||
| SVGElementTagNameMap[keyof SVGElementTagNameMap]
|
||||
| MathMLElementTagNameMap[keyof MathMLElementTagNameMap]
|
||||
| CustomElementTagNameMap[keyof CustomElementTagNameMap]
|
||||
declare global {
|
||||
type ddeComponentAttributes= Record<any, any> | undefined;
|
||||
type ddeElementAddon<El extends SupportedElement | DocumentFragment>= (element: El)=> El | void;
|
||||
type ddeElementAddon<El extends SupportedElement | DocumentFragment | Node>= (element: El)=> any;
|
||||
type ddeString= string | ddeSignal<string>
|
||||
type ddeStringable= ddeString | number | ddeSignal<number>
|
||||
}
|
||||
type PascalCase=
|
||||
`${Capitalize<string>}${string}`;
|
||||
@ -15,50 +17,72 @@ type AttrsModified= {
|
||||
/**
|
||||
* Use string like in HTML (internally uses `*.setAttribute("style", *)`), or object representation (like DOM API).
|
||||
*/
|
||||
style: string | Partial<CSSStyleDeclaration> | ddeSignal<string> | Partial<{ [K in keyof CSSStyleDeclaration]: ddeSignal<CSSStyleDeclaration[K]> }>
|
||||
style: Partial<CSSStyleDeclaration> | ddeString
|
||||
| Partial<{ [K in keyof CSSStyleDeclaration]: ddeSignal<CSSStyleDeclaration[K]> }>
|
||||
/**
|
||||
* Provide option to add/remove/toggle CSS clasess (index of object) using 1/0/-1. In fact `el.classList.toggle(class_name)` for `-1` and `el.classList.toggle(class_name, Boolean(...))` for others.
|
||||
* Provide option to add/remove/toggle CSS clasess (index of object) using 1/0/-1.
|
||||
* In fact `el.classList.toggle(class_name)` for `-1` and `el.classList.toggle(class_name, Boolean(...))`
|
||||
* for others.
|
||||
*/
|
||||
classList: Record<string,-1|0|1|boolean|ddeSignal<-1|0|1|boolean>>,
|
||||
/**
|
||||
* By default simiral to `className`, but also supports `string[]`
|
||||
* Used by the dataset HTML attribute to represent data for custom attributes added to elements.
|
||||
* Values are converted to string (see {@link DOMStringMap}).
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMStringMap)
|
||||
* */
|
||||
className: string | (string|boolean|undefined|ddeSignal<string|boolean|undefined>)[];
|
||||
dataset: Record<string, ddeStringable>,
|
||||
/**
|
||||
* Sets `aria-*` simiraly to `dataset`
|
||||
* */
|
||||
ariaset: Record<string,string|ddeSignal<string>>,
|
||||
} & Record<`=${string}` | `data${PascalCase}` | `aria${PascalCase}`, string|ddeSignal<string>> & Record<`.${string}`, any>
|
||||
ariaset: Record<string, ddeString>,
|
||||
} & Record<`=${string}` | `data${PascalCase}` | `aria${PascalCase}`, ddeString>
|
||||
& Record<`.${string}`, any>
|
||||
type _fromElsInterfaces<EL extends SupportedElement>= Omit<EL, keyof AttrsModified>;
|
||||
type IsReadonly<T, K extends keyof T> =
|
||||
T extends { readonly [P in K]: T[K] } ? true : false;
|
||||
/**
|
||||
* Just element attributtes
|
||||
*
|
||||
* In most cases, you can use native propertie such as [MDN WEB/API/Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) and so on (e.g. [`Text`](https://developer.mozilla.org/en-US/docs/Web/API/Text)).
|
||||
* In most cases, you can use native propertie such as
|
||||
* [MDN WEB/API/Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) and so on
|
||||
* (e.g. [`Text`](https://developer.mozilla.org/en-US/docs/Web/API/Text)).
|
||||
*
|
||||
* There is added support for `data[A-Z].*`/`aria[A-Z].*` to be converted to the kebab-case alternatives.
|
||||
* @private
|
||||
*/
|
||||
type ElementAttributes<T extends SupportedElement>= Partial<{ [K in keyof _fromElsInterfaces<T>]: _fromElsInterfaces<T>[K] | ddeSignal<_fromElsInterfaces<T>[K]> } & AttrsModified> & Record<string, any>;
|
||||
export function classListDeclarative<El extends SupportedElement>(element: El, classList: AttrsModified["classList"]): El
|
||||
type ElementAttributes<T extends SupportedElement>= Partial<{
|
||||
[K in keyof _fromElsInterfaces<T>]: IsReadonly<_fromElsInterfaces<T>, K> extends false
|
||||
? _fromElsInterfaces<T>[K] | ddeSignal<_fromElsInterfaces<T>[K]>
|
||||
: ddeStringable
|
||||
} & AttrsModified> & Record<string, any>;
|
||||
export function classListDeclarative<El extends SupportedElement>(
|
||||
element: El,
|
||||
classList: AttrsModified["classList"]
|
||||
): El
|
||||
export function assign<El extends SupportedElement>(element: El, ...attrs_array: ElementAttributes<El>[]): El
|
||||
export function assignAttribute<El extends SupportedElement, ATT extends keyof ElementAttributes<El>>(element: El, attr: ATT, value: ElementAttributes<El>[ATT]): ElementAttributes<El>[ATT]
|
||||
export function assignAttribute<El extends SupportedElement, ATT extends keyof ElementAttributes<El>>(
|
||||
element: El,
|
||||
attr: ATT,
|
||||
value: ElementAttributes<El>[ATT]
|
||||
): ElementAttributes<El>[ATT]
|
||||
|
||||
type ExtendedHTMLElementTagNameMap= HTMLElementTagNameMap & CustomElementTagNameMap;
|
||||
type textContent= string | ddeSignal<string>;
|
||||
export function el<
|
||||
TAG extends keyof ExtendedHTMLElementTagNameMap,
|
||||
EL extends ExtendedHTMLElementTagNameMap[TAG]
|
||||
>(
|
||||
tag_name: TAG,
|
||||
attrs?: ElementAttributes<EL> | textContent,
|
||||
...addons: ddeElementAddon<EL>[]
|
||||
attrs?: ElementAttributes<ExtendedHTMLElementTagNameMap[NoInfer<TAG>]> | ddeString,
|
||||
...addons: ddeElementAddon<
|
||||
ExtendedHTMLElementTagNameMap[NoInfer<TAG>]
|
||||
>[], // TODO: for now addons must have the same element
|
||||
): TAG extends keyof ddeHTMLElementTagNameMap ? ddeHTMLElementTagNameMap[TAG] : ddeHTMLElement
|
||||
export function el(
|
||||
tag_name?: "<>",
|
||||
): ddeDocumentFragment
|
||||
export function el(
|
||||
tag_name: string,
|
||||
attrs?: ElementAttributes<HTMLElement> | textContent,
|
||||
attrs?: ElementAttributes<HTMLElement> | ddeString,
|
||||
...addons: ddeElementAddon<HTMLElement>[]
|
||||
): ddeHTMLElement
|
||||
|
||||
@ -66,9 +90,11 @@ export function el<
|
||||
C extends (attr: ddeComponentAttributes)=> SupportedElement | ddeDocumentFragment
|
||||
>(
|
||||
component: C,
|
||||
attrs?: Parameters<C>[0] | textContent,
|
||||
attrs?: Parameters<C>[0] | ddeString,
|
||||
...addons: ddeElementAddon<ReturnType<C>>[]
|
||||
): ReturnType<C> extends ddeHTMLElementTagNameMap[keyof ddeHTMLElementTagNameMap] ? ReturnType<C> : ( ReturnType<C> extends ddeDocumentFragment ? ReturnType<C> : ddeHTMLElement )
|
||||
): ReturnType<C> extends ddeHTMLElementTagNameMap[keyof ddeHTMLElementTagNameMap]
|
||||
? ReturnType<C>
|
||||
: ( ReturnType<C> extends ddeDocumentFragment ? ReturnType<C> : ddeHTMLElement )
|
||||
export { el as createElement }
|
||||
|
||||
export function elNS(
|
||||
@ -78,8 +104,8 @@ export function elNS(
|
||||
EL extends ( TAG extends keyof SVGElementTagNameMap ? SVGElementTagNameMap[TAG] : SVGElement ),
|
||||
>(
|
||||
tag_name: TAG,
|
||||
attrs?: ElementAttributes<EL> | textContent,
|
||||
...addons: ddeElementAddon<EL>[]
|
||||
attrs?: ElementAttributes<NoInfer<EL>> | ddeString,
|
||||
...addons: ddeElementAddon<NoInfer<EL>>[]
|
||||
)=> TAG extends keyof ddeSVGElementTagNameMap ? ddeSVGElementTagNameMap[TAG] : ddeSVGElement
|
||||
export function elNS(
|
||||
namespace: "http://www.w3.org/1998/Math/MathML"
|
||||
@ -88,14 +114,16 @@ export function elNS(
|
||||
EL extends ( TAG extends keyof MathMLElementTagNameMap ? MathMLElementTagNameMap[TAG] : MathMLElement ),
|
||||
>(
|
||||
tag_name: TAG,
|
||||
attrs?: string | textContent | Partial<{ [key in keyof EL]: EL[key] | ddeSignal<EL[key]> | string | number | boolean }>,
|
||||
...addons: ddeElementAddon<EL>[]
|
||||
attrs?: ddeString | Partial<{
|
||||
[key in keyof EL]: EL[key] | ddeSignal<EL[key]> | string | number | boolean
|
||||
}>,
|
||||
...addons: ddeElementAddon<NoInfer<EL>>[]
|
||||
)=> ddeMathMLElement
|
||||
export function elNS(
|
||||
namespace: string
|
||||
): (
|
||||
tag_name: string,
|
||||
attrs?: string | textContent | Record<string, any>,
|
||||
attrs?: string | ddeString | Record<string, any>,
|
||||
...addons: ddeElementAddon<SupportedElement>[]
|
||||
)=> SupportedElement
|
||||
export { elNS as createElementNS }
|
||||
@ -106,36 +134,45 @@ export function chainableAppend<EL extends SupportedElement>(el: EL): EL;
|
||||
* */
|
||||
type simulateSlotsMapper= (body: HTMLSlotElement, el: HTMLElement)=> void;
|
||||
/** Simulate slots for ddeComponents */
|
||||
export function simulateSlots<EL extends SupportedElement | DocumentFragment>(root: EL, mapper?: simulateSlotsMapper): EL
|
||||
export function simulateSlots<EL extends SupportedElement | DocumentFragment>(
|
||||
root: EL,
|
||||
mapper?: simulateSlotsMapper
|
||||
): EL
|
||||
/**
|
||||
* Simulate slots in Custom Elements without using `shadowRoot`.
|
||||
* @param el Custom Element root element
|
||||
* @param body Body of the custom element
|
||||
* */
|
||||
export function simulateSlots<EL extends SupportedElement | DocumentFragment>(el: HTMLElement, body: EL, mapper?: simulateSlotsMapper): EL
|
||||
export function simulateSlots<EL extends SupportedElement | DocumentFragment>(
|
||||
el: HTMLElement,
|
||||
body: EL, mapper?: simulateSlotsMapper
|
||||
): EL
|
||||
|
||||
export function dispatchEvent(name: keyof DocumentEventMap | string, options?: EventInit):
|
||||
(element: SupportedElement, data?: any)=> void;
|
||||
export function dispatchEvent(name: keyof DocumentEventMap | string, options: EventInit | null, element: SupportedElement | (()=> SupportedElement)):
|
||||
(data?: any)=> void;
|
||||
export function dispatchEvent(
|
||||
name: keyof DocumentEventMap | string,
|
||||
options: EventInit | null,
|
||||
element: SupportedElement | (()=> SupportedElement)
|
||||
): (data?: any)=> void;
|
||||
interface On{
|
||||
/** Listens to the DOM event. See {@link Document.addEventListener} */
|
||||
<
|
||||
EE extends ddeElementAddon<SupportedElement>,
|
||||
El extends ( EE extends ddeElementAddon<infer El> ? El : never ),
|
||||
Event extends keyof DocumentEventMap>(
|
||||
Event extends keyof DocumentEventMap,
|
||||
EE extends ddeElementAddon<SupportedElement>= ddeElementAddon<HTMLElement>,
|
||||
>(
|
||||
type: Event,
|
||||
listener: (this: El, ev: DocumentEventMap[Event]) => any,
|
||||
listener: (this: EE extends ddeElementAddon<infer El> ? El : never, ev: DocumentEventMap[Event]) => any,
|
||||
options?: AddEventListenerOptions
|
||||
) : EE;
|
||||
<
|
||||
EE extends ddeElementAddon<SupportedElement>,
|
||||
El extends ( EE extends ddeElementAddon<infer El> ? El : never )>(
|
||||
EE extends ddeElementAddon<SupportedElement>= ddeElementAddon<HTMLElement>,
|
||||
>(
|
||||
type: string,
|
||||
listener: (this: El, ev: Event | CustomEvent ) => any,
|
||||
listener: (this: EE extends ddeElementAddon<infer El> ? El : never, ev: Event | CustomEvent ) => any,
|
||||
options?: AddEventListenerOptions
|
||||
) : EE;
|
||||
/** Listens to the element is connected to the live DOM. In case of custom elements uses [`connectedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */
|
||||
/** Listens to the element is connected to the live DOM. In case of custom elements uses [`connectedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */// editorconfig-checker-disable-line
|
||||
connected<
|
||||
EE extends ddeElementAddon<SupportedElement>,
|
||||
El extends ( EE extends ddeElementAddon<infer El> ? El : never )
|
||||
@ -143,7 +180,7 @@ interface On{
|
||||
listener: (this: El, event: CustomEvent<El>) => any,
|
||||
options?: AddEventListenerOptions
|
||||
) : EE;
|
||||
/** Listens to the element is disconnected from the live DOM. In case of custom elements uses [`disconnectedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */
|
||||
/** Listens to the element is disconnected from the live DOM. In case of custom elements uses [`disconnectedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */// editorconfig-checker-disable-line
|
||||
disconnected<
|
||||
EE extends ddeElementAddon<SupportedElement>,
|
||||
El extends ( EE extends ddeElementAddon<infer El> ? El : never )
|
||||
@ -151,7 +188,7 @@ interface On{
|
||||
listener: (this: El, event: CustomEvent<void>) => any,
|
||||
options?: AddEventListenerOptions
|
||||
) : EE;
|
||||
/** Listens to the element attribute changes. In case of custom elements uses [`attributeChangedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */
|
||||
/** Listens to the element attribute changes. In case of custom elements uses [`attributeChangedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */// editorconfig-checker-disable-line
|
||||
attributeChanged<
|
||||
EE extends ddeElementAddon<SupportedElement>,
|
||||
El extends ( EE extends ddeElementAddon<infer El> ? El : never )
|
||||
@ -162,7 +199,12 @@ interface On{
|
||||
}
|
||||
export const on: On;
|
||||
|
||||
type Scope= { scope: Node | Function | Object, host: ddeElementAddon<any>, custom_element: false | HTMLElement, prevent: boolean }
|
||||
type Scope= {
|
||||
scope: Node | Function | Object,
|
||||
host: ddeElementAddon<any>,
|
||||
custom_element: false | HTMLElement,
|
||||
prevent: boolean
|
||||
};
|
||||
/** Current scope created last time the `el(Function)` was invoke. (Or {@link scope.push}) */
|
||||
export const scope: {
|
||||
current: Scope,
|
||||
@ -176,7 +218,7 @@ export const scope: {
|
||||
* — `scope.host(on.connected(console.log))`.
|
||||
* */
|
||||
host: (...addons: ddeElementAddon<SupportedElement>[])=> HTMLElement,
|
||||
|
||||
|
||||
state: Scope[],
|
||||
/** Adds new child scope. All attributes are inherited by default. */
|
||||
push(scope: Partial<Scope>): ReturnType<Array<Scope>["push"]>,
|
||||
@ -202,12 +244,12 @@ export function observedAttributes(custom_element: HTMLElement): Record<string,
|
||||
/* TypeScript MEH */
|
||||
declare global{
|
||||
type ddeAppend<el>= (...nodes: (Node | string)[])=> el;
|
||||
|
||||
|
||||
interface ddeDocumentFragment extends DocumentFragment{ append: ddeAppend<ddeDocumentFragment>; }
|
||||
interface ddeHTMLElement extends HTMLElement{ append: ddeAppend<ddeHTMLElement>; }
|
||||
interface ddeSVGElement extends SVGElement{ append: ddeAppend<ddeSVGElement>; }
|
||||
interface ddeMathMLElement extends MathMLElement{ append: ddeAppend<ddeMathMLElement>; }
|
||||
|
||||
|
||||
interface ddeHTMLElementTagNameMap {
|
||||
"a": ddeHTMLAnchorElement;
|
||||
"area": ddeHTMLAreaElement;
|
||||
@ -350,6 +392,7 @@ declare global{
|
||||
}
|
||||
}
|
||||
|
||||
// editorconfig-checker-disable
|
||||
interface ddeHTMLAnchorElement extends HTMLAnchorElement{ append: ddeAppend<ddeHTMLAnchorElement>; }
|
||||
interface ddeHTMLAreaElement extends HTMLAreaElement{ append: ddeAppend<ddeHTMLAreaElement>; }
|
||||
interface ddeHTMLAudioElement extends HTMLAudioElement{ append: ddeAppend<ddeHTMLAudioElement>; }
|
||||
@ -476,4 +519,5 @@ interface ddeSVGTextPathElement extends SVGTextPathElement{ append: ddeAppend<dd
|
||||
interface ddeSVGTitleElement extends SVGTitleElement{ append: ddeAppend<ddeSVGTitleElement>; }
|
||||
interface ddeSVGTSpanElement extends SVGTSpanElement{ append: ddeAppend<ddeSVGTSpanElement>; }
|
||||
interface ddeSVGUseElement extends SVGUseElement{ append: ddeAppend<ddeSVGUseElement>; }
|
||||
interface ddeSVGViewElement extends SVGViewElement{ append: ddeAppend<ddeSVGViewElement>; }
|
||||
interface ddeSVGViewElement extends SVGViewElement{ append: ddeAppend<ddeSVGViewElement>; }
|
||||
// editorconfig-checker-enable
|
134
dist/esm.js
vendored
134
dist/esm.js
vendored
@ -1,5 +1,5 @@
|
||||
// src/signals-common.js
|
||||
var C = {
|
||||
var m = {
|
||||
isSignal(t) {
|
||||
return !1;
|
||||
},
|
||||
@ -7,16 +7,16 @@ var C = {
|
||||
return n;
|
||||
}
|
||||
};
|
||||
function V(t, e = !0) {
|
||||
return e ? Object.assign(C, t) : (Object.setPrototypeOf(t, C), t);
|
||||
function G(t, e = !0) {
|
||||
return e ? Object.assign(m, t) : (Object.setPrototypeOf(t, m), t);
|
||||
}
|
||||
function L(t) {
|
||||
return C.isPrototypeOf(t) && t !== C ? t : C;
|
||||
return m.isPrototypeOf(t) && t !== m ? t : m;
|
||||
}
|
||||
|
||||
// src/helpers.js
|
||||
var q = (...t) => Object.prototype.hasOwnProperty.call(...t);
|
||||
function E(t) {
|
||||
function x(t) {
|
||||
return typeof t > "u";
|
||||
}
|
||||
function N(t, e) {
|
||||
@ -30,16 +30,16 @@ function N(t, e) {
|
||||
function F(t, e) {
|
||||
let { observedAttributes: n = [] } = t.constructor;
|
||||
return n.reduce(function(r, o) {
|
||||
return r[J(o)] = e(t, o), r;
|
||||
return r[V(o)] = e(t, o), r;
|
||||
}, {});
|
||||
}
|
||||
function J(t) {
|
||||
function V(t) {
|
||||
return t.replace(/-./g, (e) => e[1].toUpperCase());
|
||||
}
|
||||
|
||||
// src/dom-common.js
|
||||
var a = {
|
||||
setDeleteAttr: K,
|
||||
setDeleteAttr: J,
|
||||
ssr: "",
|
||||
D: globalThis.document,
|
||||
F: globalThis.DocumentFragment,
|
||||
@ -47,15 +47,15 @@ var a = {
|
||||
S: globalThis.SVGElement,
|
||||
M: globalThis.MutationObserver
|
||||
};
|
||||
function K(t, e, n) {
|
||||
if (Reflect.set(t, e, n), !!E(n)) {
|
||||
function J(t, e, n) {
|
||||
if (Reflect.set(t, e, n), !!x(n)) {
|
||||
if (Reflect.deleteProperty(t, e), t instanceof a.H && t.getAttribute(e) === "undefined")
|
||||
return t.removeAttribute(e);
|
||||
if (Reflect.get(t, e) === "undefined")
|
||||
return Reflect.set(t, e, "");
|
||||
}
|
||||
}
|
||||
var x = "__dde_lifecyclesToEvents", g = "dde:connected", y = "dde:disconnected", D = "dde:attributeChanged";
|
||||
var w = "__dde_lifecyclesToEvents", g = "dde:connected", y = "dde:disconnected", D = "dde:attributeChanged";
|
||||
|
||||
// src/dom.js
|
||||
var v = [{
|
||||
@ -92,7 +92,7 @@ var v = [{
|
||||
function $(...t) {
|
||||
return this.appendOriginal(...t), this;
|
||||
}
|
||||
function Q(t) {
|
||||
function K(t) {
|
||||
return t.append === $ || (t.appendOriginal = t.append, t.append = $), t;
|
||||
}
|
||||
var T;
|
||||
@ -100,15 +100,17 @@ function j(t, e, ...n) {
|
||||
let r = L(this), o = 0, c, f;
|
||||
switch ((Object(e) !== e || r.isSignal(e)) && (e = { textContent: e }), !0) {
|
||||
case typeof t == "function": {
|
||||
o = 1, S.push({ scope: t, host: (...b) => b.length ? (o === 1 ? n.unshift(...b) : b.forEach((h) => h(f)), void 0) : f }), c = t(e || void 0);
|
||||
let d = c instanceof a.F;
|
||||
o = 1;
|
||||
let d = (...l) => l.length ? (o === 1 ? n.unshift(...l) : l.forEach((E) => E(f)), void 0) : f;
|
||||
S.push({ scope: t, host: d }), c = t(e || void 0);
|
||||
let p = c instanceof a.F;
|
||||
if (c.nodeName === "#comment") break;
|
||||
let p = j.mark({
|
||||
let b = j.mark({
|
||||
type: "component",
|
||||
name: t.name,
|
||||
host: d ? "this" : "parentElement"
|
||||
host: p ? "this" : "parentElement"
|
||||
});
|
||||
c.prepend(p), d && (f = p);
|
||||
c.prepend(b), p && (f = b);
|
||||
break;
|
||||
}
|
||||
case t === "#text":
|
||||
@ -123,8 +125,13 @@ function j(t, e, ...n) {
|
||||
case !c:
|
||||
c = O.call(this, a.D.createElement(t), e);
|
||||
}
|
||||
return Q(c), f || (f = c), n.forEach((d) => d(f)), o && S.pop(), o = 2, c;
|
||||
return K(c), f || (f = c), n.forEach((d) => d(f)), o && S.pop(), o = 2, c;
|
||||
}
|
||||
j.mark = function(t, e = !1) {
|
||||
t = Object.entries(t).map(([o, c]) => o + `="${c}"`).join(" ");
|
||||
let n = e ? "" : "/", r = a.D.createComment(`<dde:mark ${t}${a.ssr}${n}>`);
|
||||
return e && (r.end = a.D.createComment("</dde:mark>")), r;
|
||||
};
|
||||
function bt(t, e, n) {
|
||||
typeof e != "object" && (n = e, e = t);
|
||||
let r = Symbol.for("default"), o = Array.from(e.querySelectorAll("slot")).reduce((f, d) => Reflect.set(f, d.name || r, d) && f, {}), c = q(o, r);
|
||||
@ -133,13 +140,13 @@ function bt(t, e, n) {
|
||||
if (p[0] === e) return f.apply(t, p);
|
||||
if (!p.length) return t;
|
||||
let b = a.D.createDocumentFragment();
|
||||
for (let h of p) {
|
||||
if (!h || !h.slot) {
|
||||
c && b.append(h);
|
||||
for (let l of p) {
|
||||
if (!l || !l.slot) {
|
||||
c && b.append(l);
|
||||
continue;
|
||||
}
|
||||
let A = h.slot, _ = o[A];
|
||||
tt(h, "remove", "slot"), _ && (X(_, h, n), Reflect.deleteProperty(o, A));
|
||||
let E = l.slot, _ = o[E];
|
||||
tt(l, "remove", "slot"), _ && (X(_, l, n), Reflect.deleteProperty(o, E));
|
||||
}
|
||||
return c && (o[r].replaceWith(b), Reflect.deleteProperty(o, r)), t.append = f, t;
|
||||
}
|
||||
@ -149,19 +156,20 @@ function bt(t, e, n) {
|
||||
}
|
||||
return e;
|
||||
}
|
||||
function Q(...t) {
|
||||
return t.filter(Boolean).join(" ");
|
||||
}
|
||||
function X(t, e, n) {
|
||||
n && n(t, e);
|
||||
try {
|
||||
t.replaceWith(O(e, { className: [e.className, t.className], dataset: { ...t.dataset } }));
|
||||
t.replaceWith(O(e, {
|
||||
className: Q(e.className, t.className),
|
||||
dataset: { ...t.dataset }
|
||||
}));
|
||||
} catch {
|
||||
t.replaceWith(e);
|
||||
}
|
||||
}
|
||||
j.mark = function(t, e = !1) {
|
||||
t = Object.entries(t).map(([o, c]) => o + `="${c}"`).join(" ");
|
||||
let n = e ? "" : "/", r = a.D.createComment(`<dde:mark ${t}${a.ssr}${n}>`);
|
||||
return e && (r.end = a.D.createComment("</dde:mark>")), r;
|
||||
};
|
||||
function gt(t) {
|
||||
let e = this;
|
||||
return function(...r) {
|
||||
@ -221,16 +229,13 @@ function Y(t, e) {
|
||||
(r, o) => t.classList.toggle(r, o === -1 ? void 0 : !!o)
|
||||
), t;
|
||||
}
|
||||
function vt(t) {
|
||||
return Array.from(t.children).forEach((e) => e.remove()), t;
|
||||
}
|
||||
function tt(t, e, n, r) {
|
||||
return t instanceof a.H ? t[e + "Attribute"](n, r) : t[e + "AttributeNS"](null, n, r);
|
||||
}
|
||||
function et(t, e) {
|
||||
if (!(e in t)) return !1;
|
||||
let n = I(t, e);
|
||||
return !E(n.set);
|
||||
return !x(n.set);
|
||||
}
|
||||
function I(t, e) {
|
||||
if (t = Object.getPrototypeOf(t), !t) return {};
|
||||
@ -243,22 +248,19 @@ function M(t, e, n) {
|
||||
o && (c = t.processReactiveAttribute(e, o, c, n), n(o, c));
|
||||
});
|
||||
}
|
||||
function Z(t) {
|
||||
return Array.isArray(t) ? t.filter(Boolean).join(" ") : t;
|
||||
}
|
||||
function nt(t, e, n, r) {
|
||||
return t[(E(r) ? "remove" : "set") + e](n, Z(r));
|
||||
return t[(x(r) ? "remove" : "set") + e](n, r);
|
||||
}
|
||||
function rt(t, e, n, r, o = null) {
|
||||
return t[(E(r) ? "remove" : "set") + e + "NS"](o, n, Z(r));
|
||||
return t[(x(r) ? "remove" : "set") + e + "NS"](o, n, r);
|
||||
}
|
||||
function H(t, e, n) {
|
||||
if (Reflect.set(t, e, n), !!E(n))
|
||||
if (Reflect.set(t, e, n), !!x(n))
|
||||
return Reflect.deleteProperty(t, e);
|
||||
}
|
||||
|
||||
// src/events-observer.js
|
||||
var w = a.M ? ot() : new Proxy({}, {
|
||||
var A = a.M ? ot() : new Proxy({}, {
|
||||
get() {
|
||||
return () => {
|
||||
};
|
||||
@ -268,11 +270,11 @@ function ot() {
|
||||
let t = /* @__PURE__ */ new Map(), e = !1, n = (i) => function(u) {
|
||||
for (let s of u)
|
||||
if (s.type === "childList") {
|
||||
if (h(s.addedNodes, !0)) {
|
||||
if (l(s.addedNodes, !0)) {
|
||||
i();
|
||||
continue;
|
||||
}
|
||||
A(s.removedNodes, !0) && i();
|
||||
E(s.removedNodes, !0) && i();
|
||||
}
|
||||
}, r = new a.M(n(d));
|
||||
return {
|
||||
@ -334,19 +336,19 @@ function ot() {
|
||||
s === i || !(s instanceof Node) || i.contains(s) && u.push(s);
|
||||
return u;
|
||||
}
|
||||
function h(i, u) {
|
||||
function l(i, u) {
|
||||
let s = !1;
|
||||
for (let l of i) {
|
||||
if (u && b(l).then(h), !t.has(l)) continue;
|
||||
let m = t.get(l);
|
||||
m.length_c && (l.dispatchEvent(new Event(g)), m.connected = /* @__PURE__ */ new WeakSet(), m.length_c = 0, m.length_d || t.delete(l), s = !0);
|
||||
for (let h of i) {
|
||||
if (u && b(h).then(l), !t.has(h)) continue;
|
||||
let C = t.get(h);
|
||||
C.length_c && (h.dispatchEvent(new Event(g)), C.connected = /* @__PURE__ */ new WeakSet(), C.length_c = 0, C.length_d || t.delete(h), s = !0);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
function A(i, u) {
|
||||
function E(i, u) {
|
||||
let s = !1;
|
||||
for (let l of i)
|
||||
u && b(l).then(A), !(!t.has(l) || !t.get(l).length_d) && ((globalThis.queueMicrotask || setTimeout)(_(l)), s = !0);
|
||||
for (let h of i)
|
||||
u && b(h).then(E), !(!t.has(h) || !t.get(h).length_d) && ((globalThis.queueMicrotask || setTimeout)(_(h)), s = !0);
|
||||
return s;
|
||||
}
|
||||
function _(i) {
|
||||
@ -357,15 +359,15 @@ function ot() {
|
||||
}
|
||||
|
||||
// src/customElement.js
|
||||
function Dt(t, e, n, r = it) {
|
||||
function mt(t, e, n, r = it) {
|
||||
S.push({
|
||||
scope: t,
|
||||
host: (...f) => f.length ? f.forEach((d) => d(t)) : t
|
||||
}), typeof r == "function" && (r = r.call(t, t));
|
||||
let o = t[x];
|
||||
let o = t[w];
|
||||
o || ct(t);
|
||||
let c = n.call(t, r);
|
||||
return o || t.dispatchEvent(new Event(g)), e.nodeType === 11 && typeof e.mode == "string" && t.addEventListener(y, w.observe(e), { once: !0 }), S.pop(), e.append(c);
|
||||
return o || t.dispatchEvent(new Event(g)), e.nodeType === 11 && typeof e.mode == "string" && t.addEventListener(y, A.observe(e), { once: !0 }), S.pop(), e.append(c);
|
||||
}
|
||||
function ct(t) {
|
||||
return k(t.prototype, "connectedCallback", function(e, n, r) {
|
||||
@ -379,7 +381,7 @@ function ct(t) {
|
||||
n.dispatchEvent(new CustomEvent(D, {
|
||||
detail: [o, c]
|
||||
})), e.apply(n, r);
|
||||
}), t.prototype[x] = !0, t;
|
||||
}), t.prototype[w] = !0, t;
|
||||
}
|
||||
function k(t, e, n) {
|
||||
t[e] = new Proxy(t[e] || (() => {
|
||||
@ -390,7 +392,7 @@ function it(t) {
|
||||
}
|
||||
|
||||
// src/events.js
|
||||
function _t(t, e, n) {
|
||||
function Rt(t, e, n) {
|
||||
return e || (e = {}), function(o, ...c) {
|
||||
n && (c.unshift(o), o = typeof n == "function" ? n() : n);
|
||||
let f = c.length ? new CustomEvent(t, Object.assign({ detail: c[0] }, e)) : new Event(t, e);
|
||||
@ -402,15 +404,15 @@ function R(t, e, n) {
|
||||
return o.addEventListener(t, e, n), o;
|
||||
};
|
||||
}
|
||||
var G = (t) => Object.assign({}, typeof t == "object" ? t : null, { once: !0 });
|
||||
var Z = (t) => Object.assign({}, typeof t == "object" ? t : null, { once: !0 });
|
||||
R.connected = function(t, e) {
|
||||
return e = G(e), function(r) {
|
||||
return r.addEventListener(g, t, e), r[x] ? r : r.isConnected ? (r.dispatchEvent(new Event(g)), r) : (N(e.signal, () => w.offConnected(r, t)) && w.onConnected(r, t), r);
|
||||
return e = Z(e), function(r) {
|
||||
return r.addEventListener(g, t, e), r[w] ? r : r.isConnected ? (r.dispatchEvent(new Event(g)), r) : (N(e.signal, () => A.offConnected(r, t)) && A.onConnected(r, t), r);
|
||||
};
|
||||
};
|
||||
R.disconnected = function(t, e) {
|
||||
return e = G(e), function(r) {
|
||||
return r.addEventListener(y, t, e), r[x] || N(e.signal, () => w.offDisconnected(r, t)) && w.onDisconnected(r, t), r;
|
||||
return e = Z(e), function(r) {
|
||||
return r.addEventListener(y, t, e), r[w] || N(e.signal, () => A.offDisconnected(r, t)) && A.onDisconnected(r, t), r;
|
||||
};
|
||||
};
|
||||
var W = /* @__PURE__ */ new WeakMap();
|
||||
@ -422,7 +424,7 @@ R.disconnectedAsAbort = function(t) {
|
||||
var st = /* @__PURE__ */ new WeakSet();
|
||||
R.attributeChanged = function(t, e) {
|
||||
return typeof e != "object" && (e = {}), function(r) {
|
||||
if (r.addEventListener(D, t, e), r[x] || st.has(r) || !a.M) return r;
|
||||
if (r.addEventListener(D, t, e), r[w] || st.has(r) || !a.M) return r;
|
||||
let o = new a.M(function(f) {
|
||||
for (let { attributeName: d, target: p } of f)
|
||||
p.dispatchEvent(
|
||||
@ -435,21 +437,21 @@ R.attributeChanged = function(t, e) {
|
||||
export {
|
||||
O as assign,
|
||||
z as assignAttribute,
|
||||
Q as chainableAppend,
|
||||
K as chainableAppend,
|
||||
Y as classListDeclarative,
|
||||
Q as cn,
|
||||
j as createElement,
|
||||
gt as createElementNS,
|
||||
Dt as customElementRender,
|
||||
mt as customElementRender,
|
||||
ct as customElementWithDDE,
|
||||
_t as dispatchEvent,
|
||||
Rt as dispatchEvent,
|
||||
j as el,
|
||||
gt as elNS,
|
||||
tt as elementAttribute,
|
||||
vt as empty,
|
||||
ct as lifecyclesToEvents,
|
||||
it as observedAttributes,
|
||||
R as on,
|
||||
V as registerReactivity,
|
||||
G as registerReactivity,
|
||||
S as scope,
|
||||
bt as simulateSlots
|
||||
};
|
||||
|
@ -51,9 +51,9 @@ let is_registered= {};
|
||||
/** @param {string} page_id */
|
||||
function registerClientPart(page_id){
|
||||
if(is_registered[page_id]) return;
|
||||
|
||||
|
||||
document.head.append(
|
||||
el("script", { src: "https://cdn.jsdelivr.net/npm/shiki@0.9", defer: true }),
|
||||
el("script", { src: "https://cdn.jsdelivr.net/npm/shiki@0.9", defer: true }),
|
||||
);
|
||||
registerClientFile(
|
||||
new URL("./code.js.js", import.meta.url),
|
||||
|
@ -47,7 +47,7 @@ let is_registered= {};
|
||||
/** @param {string} page_id */
|
||||
function registerClientPart(page_id){
|
||||
if(is_registered[page_id]) return;
|
||||
|
||||
|
||||
document.head.append(
|
||||
el("script", { src: "https://flems.io/flems.html", type: "text/javascript", charset: "utf-8" }),
|
||||
);
|
||||
@ -64,5 +64,5 @@ function generateCodeId(src){
|
||||
.replace(/000+/g, "");
|
||||
const count= 1 + ( store_prev.get(candidate) || 0 );
|
||||
store_prev.set(candidate, count);
|
||||
return count.toString()+"-"+candidate;
|
||||
return count.toString()+"-"+candidate;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import {
|
||||
customElementRender,
|
||||
customElementWithDDE,
|
||||
observedAttributes,
|
||||
el, on, scope
|
||||
el, on, scope,
|
||||
} from "deka-dom-el";
|
||||
import { S } from "deka-dom-el/signals";
|
||||
export class HTMLCustomElement extends HTMLElement{
|
||||
@ -24,7 +24,7 @@ export class HTMLCustomElement extends HTMLElement{
|
||||
/** @param {{ attr: ddeSignal<string, {}> }} props */
|
||||
function ddeComponent({ attr }){
|
||||
scope.host(
|
||||
on.connected(e=> console.log(e.target.outerHTML)),
|
||||
on.connected(e=> console.log(( /** @type {HTMLParagraphElement} */ (e.target)).outerHTML)),
|
||||
);
|
||||
return el().append(
|
||||
el("p", S(()=> `Hello from Custom Element with attribute '${attr()}'`))
|
||||
|
@ -11,7 +11,7 @@ document.body.append(
|
||||
);
|
||||
|
||||
function component({ className, textContent }){
|
||||
return el("div", { className: [ "class1", className ] }).append(
|
||||
return el("div", { className: [ "class1", className ].join(" ") }).append(
|
||||
el("p", textContent)
|
||||
);
|
||||
}
|
||||
|
@ -2,8 +2,8 @@ import { elNS, assign } from "deka-dom-el";
|
||||
const elSVG= elNS("http://www.w3.org/2000/svg");
|
||||
const elMath= elNS("http://www.w3.org/1998/Math/MathML");
|
||||
document.body.append(
|
||||
elSVG("svg"), // see https://developer.mozilla.org/en-US/docs/Web/SVG and https://developer.mozilla.org/en-US/docs/Web/API/SVGElement
|
||||
elMath("math") // see https://developer.mozilla.org/en-US/docs/Web/MathML and https://developer.mozilla.org/en-US/docs/Web/MathML/Global_attributes
|
||||
elSVG("svg"), // see https://developer.mozilla.org/en-US/docs/Web/SVG and https://developer.mozilla.org/en-US/docs/Web/API/SVGElement // editorconfig-checker-disable-line
|
||||
elMath("math") // see https://developer.mozilla.org/en-US/docs/Web/MathML and https://developer.mozilla.org/en-US/docs/Web/MathML/Global_attributes // editorconfig-checker-disable-line
|
||||
);
|
||||
|
||||
console.log(
|
||||
|
@ -1,15 +1,18 @@
|
||||
import { el } from "deka-dom-el";
|
||||
import { S } from "deka-dom-el/signals";
|
||||
const clicks= S(0); // A
|
||||
document.body.append(
|
||||
el().append(
|
||||
el(HelloWorldComponent)
|
||||
);
|
||||
function HelloWorldComponent(){
|
||||
const clicksS= S(0); // A
|
||||
return el().append(
|
||||
el("p", S(()=>
|
||||
"Hello World "+"🎉".repeat(clicks()) // B
|
||||
"Hello World "+"🎉".repeat(clicksS()) // B
|
||||
)),
|
||||
el("button", {
|
||||
type: "button",
|
||||
onclick: ()=> clicks(clicks()+1), // C
|
||||
onclick: ()=> clicksS(clicksS()+1), // C
|
||||
textContent: "Fire",
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ function elClass(_class, attributes, ...addons){
|
||||
});
|
||||
element.prepend(el_mark);
|
||||
if(is_fragment) element_host= el_mark;
|
||||
|
||||
|
||||
chainableAppend(element);
|
||||
addons.forEach(c=> c(element_host));
|
||||
scope.pop();
|
||||
|
@ -1,4 +1,6 @@
|
||||
import { el, empty, on } from "deka-dom-el";
|
||||
import { el, on } from "deka-dom-el";
|
||||
/** @param {HTMLElement} el */
|
||||
const empty= el=> Array.from(el.children).forEach(c=> c.remove());
|
||||
document.body.append(
|
||||
el(component),
|
||||
el("button", {
|
||||
|
@ -23,7 +23,7 @@ function component(){
|
||||
* const data= O("data");
|
||||
* ul.append(el("li", data));
|
||||
* });
|
||||
*
|
||||
*
|
||||
* // THE HOST IS PROBABLY DIFFERENT THAN
|
||||
* // YOU EXPECT AND OBSERVABLES MAY BE
|
||||
* // UNEXPECTEDLY REMOVED!!!
|
||||
|
@ -4,7 +4,7 @@ const count= S(0);
|
||||
import { el } from "deka-dom-el";
|
||||
document.body.append(
|
||||
el("p", S(()=> "Currently: "+count())),
|
||||
el("p", { classList: { red: S(()=> count()%2) }, dataset: { count }, textContent: "Attributes example" })
|
||||
el("p", { classList: { red: S(()=> count()%2 === 0) }, dataset: { count }, textContent: "Attributes example" })
|
||||
);
|
||||
document.head.append(
|
||||
el("style", ".red { color: red; }")
|
||||
|
@ -4,25 +4,32 @@ import { mnemonicUl } from "../mnemonicUl.html.js";
|
||||
export function mnemonic(){
|
||||
return mnemonicUl().append(
|
||||
el("li").append(
|
||||
el("code", "customElementRender(<custom-element>, <connect-target>, <render-function>[, <properties>])"), " — use function to render DOM structure for given <custom-element>",
|
||||
el("code", "customElementRender(<custom-element>, <connect-target>, <render-function>[, <properties>])"),
|
||||
" — use function to render DOM structure for given <custom-element>",
|
||||
),
|
||||
el("li").append(
|
||||
el("code", "customElementWithDDE(<custom-element>)"), " — register <custom-element> to DDE library, see also `lifecyclesToEvents`, can be also used as decorator",
|
||||
el("code", "customElementWithDDE(<custom-element>)"),
|
||||
" — register <custom-element> to DDE library, see also `lifecyclesToEvents`, can be also used as decorator",
|
||||
),
|
||||
el("li").append(
|
||||
el("code", "observedAttributes(<custom-element>)"), " — returns record of observed attributes (keys uses camelCase)",
|
||||
el("code", "observedAttributes(<custom-element>)"),
|
||||
" — returns record of observed attributes (keys uses camelCase)",
|
||||
),
|
||||
el("li").append(
|
||||
el("code", "S.observedAttributes(<custom-element>)"), " — returns record of observed attributes (keys uses camelCase and values are signals)",
|
||||
el("code", "S.observedAttributes(<custom-element>)"),
|
||||
" — returns record of observed attributes (keys uses camelCase and values are signals)",
|
||||
),
|
||||
el("li").append(
|
||||
el("code", "lifecyclesToEvents(<class-declaration>)"), " — convert lifecycle methods to events, can be also used as decorator",
|
||||
el("code", "lifecyclesToEvents(<class-declaration>)"),
|
||||
" — convert lifecycle methods to events, can be also used as decorator",
|
||||
),
|
||||
el("li").append(
|
||||
el("code", "simulateSlots(<class-instance>, <body>[, <mapper>])"), " — simulate slots for Custom Elements without shadow DOM",
|
||||
el("code", "simulateSlots(<class-instance>, <body>[, <mapper>])"),
|
||||
" — simulate slots for Custom Elements without shadow DOM",
|
||||
),
|
||||
el("li").append(
|
||||
el("code", "simulateSlots(<dde-component>[, <mapper>])"), " — simulate slots for “dde”/functional components",
|
||||
el("code", "simulateSlots(<dde-component>[, <mapper>])"),
|
||||
" — simulate slots for “dde”/functional components",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -4,22 +4,28 @@ import { mnemonicUl } from "../mnemonicUl.html.js";
|
||||
export function mnemonic(){
|
||||
return mnemonicUl().append(
|
||||
el("li").append(
|
||||
el("code", "assign(<element>, ...<idl-objects>): <element>"), " — assign properties to the element",
|
||||
el("code", "assign(<element>, ...<objects>): <element>"),
|
||||
" — assign properties (prefered, or attributes) to the element",
|
||||
),
|
||||
el("li").append(
|
||||
el("code", "el(<tag-name>, <primitive>)[.append(...)]: <element-from-tag-name>"), " — simple element containing only text",
|
||||
el("code", "el(<tag-name>, <primitive>)[.append(...)]: <element-from-tag-name>"),
|
||||
" — simple element containing only text",
|
||||
),
|
||||
el("li").append(
|
||||
el("code", "el(<tag-name>, <idl-object>)[.append(...)]: <element-from-tag-name>"), " — element with more properties",
|
||||
el("code", "el(<tag-name>, <object>)[.append(...)]: <element-from-tag-name>"),
|
||||
" — element with more properties (prefered, or attributes)",
|
||||
),
|
||||
el("li").append(
|
||||
el("code", "el(<function>, <function-argument(s)>)[.append(...)]: <element-returned-by-function>"), " — using component represented by function",
|
||||
el("code", "el(<function>, <function-argument(s)>)[.append(...)]: <element-returned-by-function>"),
|
||||
" — using component represented by function (must accept object like for <tag-name>)",
|
||||
),
|
||||
el("li").append(
|
||||
el("code", "el(<...>, <...>, ...<addons>)"), " — see following page"
|
||||
el("code", "el(<...>, <...>, ...<addons>)"),
|
||||
" — see following section of documentation",
|
||||
),
|
||||
el("li").append(
|
||||
el("code", "elNS(<namespace>)(<as-el-see-above>)[.append(...)]: <element-based-on-arguments>"), " — typically SVG elements",
|
||||
el("code", "elNS(<namespace>)(<as-el-see-above>)[.append(...)]: <element-based-on-arguments>"),
|
||||
" — typically SVG elements",
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -4,17 +4,21 @@ import { mnemonicUl } from "../mnemonicUl.html.js";
|
||||
export function mnemonic(){
|
||||
return mnemonicUl().append(
|
||||
el("li").append(
|
||||
el("code", "on(<event>, <listener>[, <options>])(<element>)"), " — just ", el("code", "<element>.addEventListener(<event>, <listener>[, <options>])")
|
||||
el("code", "on(<event>, <listener>[, <options>])(<element>)"),
|
||||
" — just ", el("code", "<element>.addEventListener(<event>, <listener>[, <options>])")
|
||||
),
|
||||
el("li").append(
|
||||
el("code", "on.<live-cycle>(<event>, <listener>[, <options>])(<element>)"), " — corresponds to custom elemnets callbacks ", el("code", "<live-cycle>Callback(...){...}"),
|
||||
el("code", "on.<live-cycle>(<event>, <listener>[, <options>])(<element>)"),
|
||||
" — corresponds to custom elemnets callbacks ", el("code", "<live-cycle>Callback(...){...}"),
|
||||
". To connect to custom element see following page, else it is simulated by MutationObserver."
|
||||
),
|
||||
el("li").append(
|
||||
el("code", "dispatchEvent(<event>[, <options>])(element)"), " — just ", el("code", "<element>.dispatchEvent(new Event(<event>[, <options>]))")
|
||||
el("code", "dispatchEvent(<event>[, <options>])(element)"),
|
||||
" — just ", el("code", "<element>.dispatchEvent(new Event(<event>[, <options>]))")
|
||||
),
|
||||
el("li").append(
|
||||
el("code", "dispatchEvent(<event>[, <options>])(element, detail)"), " — just ", el("code", "<element>.dispatchEvent(new CustomEvent(<event>, { detail, ...<options> }))")
|
||||
el("code", "dispatchEvent(<event>[, <options>])(element, detail)"),
|
||||
" — just ", el("code", "<element>.dispatchEvent(new CustomEvent(<event>, { detail, ...<options> }))")
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -4,13 +4,16 @@ import { mnemonicUl } from "../mnemonicUl.html.js";
|
||||
export function mnemonic(){
|
||||
return mnemonicUl().append(
|
||||
el("li").append(
|
||||
el("code", "el(<function>, <function-argument(s)>)[.append(...)]: <element-returned-by-function>"), " — using component represented by function",
|
||||
el("code", "el(<function>, <function-argument(s)>)[.append(...)]: <element-returned-by-function>"),
|
||||
" — using component represented by function",
|
||||
),
|
||||
el("li").append(
|
||||
el("code", "scope.host()"), " — get current component reference"
|
||||
el("code", "scope.host()"),
|
||||
" — get current component reference"
|
||||
),
|
||||
el("li").append(
|
||||
el("code", "scope.host(...<addons>)"), " — use addons to current component",
|
||||
el("code", "scope.host(...<addons>)"),
|
||||
" — use addons to current component",
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -7,22 +7,28 @@ export function mnemonic(){
|
||||
el("code", "S(<value>)"), " — signal: reactive value",
|
||||
),
|
||||
el("li").append(
|
||||
el("code", "S(()=> <computation>)"), " — read-only signal: reactive value dependent on calculation using other signals",
|
||||
el("code", "S(()=> <computation>)"),
|
||||
" — read-only signal: reactive value dependent on calculation using other signals",
|
||||
),
|
||||
el("li").append(
|
||||
el("code", "S.on(<signal>, <listener>[, <options>])"), " — listen to the signal value changes",
|
||||
el("code", "S.on(<signal>, <listener>[, <options>])"),
|
||||
" — listen to the signal value changes",
|
||||
),
|
||||
el("li").append(
|
||||
el("code", "S.clear(...<signals>)"), " — off and clear signals",
|
||||
el("code", "S.clear(...<signals>)"),
|
||||
" — off and clear signals",
|
||||
),
|
||||
el("li").append(
|
||||
el("code", "S(<value>, <actions>)"), " — signal: pattern to create complex reactive objects/arrays",
|
||||
el("code", "S(<value>, <actions>)"),
|
||||
" — signal: pattern to create complex reactive objects/arrays",
|
||||
),
|
||||
el("li").append(
|
||||
el("code", "S.action(<signal>, <action-name>, ...<action-arguments>)"), " — invoke an action for given signal"
|
||||
el("code", "S.action(<signal>, <action-name>, ...<action-arguments>)"),
|
||||
" — invoke an action for given signal"
|
||||
),
|
||||
el("li").append(
|
||||
el("code", "S.el(<signal>, <function-returning-dom>)"), " — render partial dom structure (template) based on the current signal value",
|
||||
el("code", "S.el(<signal>, <function-returning-dom>)"),
|
||||
" — render partial dom structure (template) based on the current signal value",
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ export function page({ pkg, info }){
|
||||
const page_id= info.id;
|
||||
return el(simplePage, { info, pkg }).append(
|
||||
el("p", t`The library tries to provide pure JavaScript tool(s) to create reactive interfaces using …`),
|
||||
|
||||
|
||||
el(h3, t`Event-driven programming (3 parts separation ≡ 3PS)`),
|
||||
el("p").append(t`
|
||||
Let's introduce the basic principle on which the library is built. We'll use the JavaScript listener as
|
||||
@ -56,7 +56,7 @@ export function page({ pkg, info }){
|
||||
describe usage in specific situations, see for example ${el("a", { textContent: t`MVVM`, ...references.w_mvv })}
|
||||
or ${el("a", { textContent: t`MVC`, ...references.w_mvc })}.
|
||||
`),
|
||||
|
||||
|
||||
el(h3, t`Organization of the documentation`),
|
||||
);
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ function metaFacebook({ name, description, homepage }){
|
||||
function iconGitHub(){
|
||||
const el= elNS("http://www.w3.org/2000/svg");
|
||||
return el("svg", { className: "icon", viewBox: "0 0 32 32" }).append(
|
||||
el("path", { d: [ //see https://svg-path-visualizer.netlify.app/#M16%200.395c-8.836%200-16%207.163-16%2016%200%207.069%204.585%2013.067%2010.942%2015.182%200.8%200.148%201.094-0.347%201.094-0.77%200-0.381-0.015-1.642-0.022-2.979-4.452%200.968-5.391-1.888-5.391-1.888-0.728-1.849-1.776-2.341-1.776-2.341-1.452-0.993%200.11-0.973%200.11-0.973%201.606%200.113%202.452%201.649%202.452%201.649%201.427%202.446%203.743%201.739%204.656%201.33%200.143-1.034%200.558-1.74%201.016-2.14-3.554-0.404-7.29-1.777-7.29-7.907%200-1.747%200.625-3.174%201.649-4.295-0.166-0.403-0.714-2.030%200.155-4.234%200%200%201.344-0.43%204.401%201.64%201.276-0.355%202.645-0.532%204.005-0.539%201.359%200.006%202.729%200.184%204.008%200.539%203.054-2.070%204.395-1.64%204.395-1.64%200.871%202.204%200.323%203.831%200.157%204.234%201.026%201.12%201.647%202.548%201.647%204.295%200%206.145-3.743%207.498-7.306%207.895%200.574%200.497%201.085%201.47%201.085%202.963%200%202.141-0.019%203.864-0.019%204.391%200%200.426%200.288%200.925%201.099%200.768%206.354-2.118%2010.933-8.113%2010.933-15.18%200-8.837-7.164-16-16-16z
|
||||
el("path", { d: [ //see https://svg-path-visualizer.netlify.app/#M16%200.395c-8.836%200-16%207.163-16%2016%200%207.069%204.585%2013.067%2010.942%2015.182%200.8%200.148%201.094-0.347%201.094-0.77%200-0.381-0.015-1.642-0.022-2.979-4.452%200.968-5.391-1.888-5.391-1.888-0.728-1.849-1.776-2.341-1.776-2.341-1.452-0.993%200.11-0.973%200.11-0.973%201.606%200.113%202.452%201.649%202.452%201.649%201.427%202.446%203.743%201.739%204.656%201.33%200.143-1.034%200.558-1.74%201.016-2.14-3.554-0.404-7.29-1.777-7.29-7.907%200-1.747%200.625-3.174%201.649-4.295-0.166-0.403-0.714-2.030%200.155-4.234%200%200%201.344-0.43%204.401%201.64%201.276-0.355%202.645-0.532%204.005-0.539%201.359%200.006%202.729%200.184%204.008%200.539%203.054-2.070%204.395-1.64%204.395-1.64%200.871%202.204%200.323%203.831%200.157%204.234%201.026%201.12%201.647%202.548%201.647%204.295%200%206.145-3.743%207.498-7.306%207.895%200.574%200.497%201.085%201.47%201.085%202.963%200%202.141-0.019%203.864-0.019%204.391%200%200.426%200.288%200.925%201.099%200.768%206.354-2.118%2010.933-8.113%2010.933-15.18%200-8.837-7.164-16-16-16z // editorconfig-checker-disable-line
|
||||
"M 16,0.395",
|
||||
"c -8.836,0 -16,7.163 -16,16",
|
||||
"c 0,7.069 4.585,13.067 10.942,15.182",
|
||||
|
@ -54,7 +54,7 @@ export function page({ pkg, info }){
|
||||
`),
|
||||
|
||||
el(code, { src: fileURL("./components/examples/elements/intro.js"), page_id }),
|
||||
|
||||
|
||||
el(h3, t`Creating element(s) (with custom attributes)`),
|
||||
el("p").append(...T`
|
||||
You can create a native DOM element by using the ${el("a", references.mdn_create).append(
|
||||
@ -77,8 +77,9 @@ export function page({ pkg, info }){
|
||||
el("p").append(...T`
|
||||
You can study all JavaScript elements interfaces to the corresponding HTML elements. All HTML elements
|
||||
inherits from ${el("a", { textContent: "HTMLElement", ...references.mdn_el })}. To see
|
||||
all available IDLs for example for paragraphs, see ${el("a", { textContent: "HTMLParagraphElement", ...references.mdn_p })}.
|
||||
Moreover, the ${el("code", "assign")} provides a way to sets declaratively some convenient properties:
|
||||
all available IDLs for example for paragraphs, see ${el("a", { textContent: "HTMLParagraphElement",
|
||||
...references.mdn_p })}. Moreover, the ${el("code", "assign")} provides a way to sets declaratively
|
||||
some convenient properties:
|
||||
`),
|
||||
el("ul").append(
|
||||
el("li").append(...T`
|
||||
@ -91,8 +92,7 @@ export function page({ pkg, info }){
|
||||
el("li").append(...T`You can use string or object as a value for ${el("code", "style")} property.`),
|
||||
el("li").append(...T`
|
||||
${el("code", "className")} (IDL – preffered)/${el("code", "class")} are ways to add CSS classes
|
||||
to the element. You can use string (similarly to ${el("code", "class=\"…\"")} syntax in HTML) or
|
||||
array of strings. This is handy to concat conditional classes.
|
||||
to the element. You can use string (similarly to ${el("code", "class=\"…\"")} syntax in HTML).
|
||||
`),
|
||||
el("li").append(...T`
|
||||
Use ${el("code", "classList")} to toggle specific classes. This will be handy later when
|
||||
@ -114,7 +114,7 @@ export function page({ pkg, info }){
|
||||
${el("code", "classListDeclarative")}.
|
||||
`),
|
||||
el(example, { src: fileURL("./components/examples/elements/dekaAssign.js"), page_id }),
|
||||
|
||||
|
||||
el(h3, t`Native JavaScript templating`),
|
||||
el("p", t`By default, the native JS has no good way to define HTML template using DOM API:`),
|
||||
el(example, { src: fileURL("./components/examples/elements/nativeAppend.js"), page_id }),
|
||||
@ -123,8 +123,8 @@ export function page({ pkg, info }){
|
||||
parent element.
|
||||
`),
|
||||
el(example, { src: fileURL("./components/examples/elements/dekaAppend.js"), page_id }),
|
||||
|
||||
|
||||
|
||||
|
||||
el(h3, t`Basic (state-less) components`),
|
||||
el("p").append(...T`
|
||||
You can use functions for encapsulation (repeating) logic. The ${el("code", "el")} accepts function
|
||||
@ -149,7 +149,7 @@ export function page({ pkg, info }){
|
||||
the ${el("code", "elNS")} function:
|
||||
`),
|
||||
el(example, { src: fileURL("./components/examples/elements/dekaElNS.js"), page_id }),
|
||||
|
||||
|
||||
el(mnemonic)
|
||||
);
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ const references= {
|
||||
},
|
||||
/** Custom Element lifecycle callbacks */
|
||||
mdn_customElement: {
|
||||
href: "https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks"
|
||||
href: "https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks" // editorconfig-checker-disable-line
|
||||
},
|
||||
/** MutationObserver */
|
||||
mdn_mutation: {
|
||||
@ -50,9 +50,9 @@ export function page({ pkg, info }){
|
||||
We quickly introduce helper to listening to the native DOM events. And library syntax/pattern so-called
|
||||
${el("em", t`Addon`)} to incorporate not only this in UI templates declaratively.
|
||||
`),
|
||||
|
||||
|
||||
el(code, { src: fileURL("./components/examples/events/intro.js"), page_id }),
|
||||
|
||||
|
||||
el(h3, t`Events and listenners`),
|
||||
el("p").append(...T`
|
||||
In JavaScript you can listen to the native DOM events of the given element by using
|
||||
@ -105,17 +105,20 @@ export function page({ pkg, info }){
|
||||
`),
|
||||
el("p").append(...T`
|
||||
The library provide three additional live-cycle events corresponding to how they are named in a case of
|
||||
custom elements: ${el("code", "on.connected")}, ${el("code", "on.disconnected")} and ${el("code", "on.attributeChanged")}.
|
||||
custom elements: ${el("code", "on.connected")}, ${el("code", "on.disconnected")} and ${el("code",
|
||||
"on.attributeChanged")}.
|
||||
`),
|
||||
el(example, { src: fileURL("./components/examples/events/live-cycle.js"), page_id }),
|
||||
el("p").append(...T`
|
||||
For Custom elements, we will later introduce a way to replace ${el("code", "*Callback")} syntax with
|
||||
${el("code", "dde:*")} events. The ${el("code", "on.*")} functions then listen to the appropriate
|
||||
Custom Elements events (see ${el("a", { textContent: t`Custom element lifecycle callbacks | MDN`, ...references.mdn_customElement })}).
|
||||
Custom Elements events (see ${el("a", { textContent: t`Custom element lifecycle callbacks | MDN`,
|
||||
...references.mdn_customElement })}).
|
||||
`),
|
||||
el("p").append(...T`
|
||||
But, in case of regular elemnets the ${el("a", references.mdn_mutation).append(el("code", "MutationObserver"), " | MDN")}
|
||||
is internaly used to track these events. Therefore, there are some drawbacks:
|
||||
But, in case of regular elemnets the ${el("a", references.mdn_mutation).append(el("code",
|
||||
"MutationObserver"), " | MDN")} is internaly used to track these events. Therefore, there are some
|
||||
drawbacks:
|
||||
`),
|
||||
el("ul").append(
|
||||
el("li").append(...T`
|
||||
@ -136,14 +139,15 @@ export function page({ pkg, info }){
|
||||
native behaviour re-(dis)connecting element, use:
|
||||
`),
|
||||
el("ul").append(
|
||||
el("li").append(...T`custom ${el("code", "MutationObserver")} or logic in (dis)${el("code", "connectedCallback")} or…`),
|
||||
el("li").append(...T`custom ${el("code", "MutationObserver")} or logic in (dis)${el("code",
|
||||
"connectedCallback")} or…`),
|
||||
el("li").append(...T`re-add ${el("code", "on.connected")} or ${el("code", "on.disconnected")} listeners.`)
|
||||
),
|
||||
|
||||
el(h3, t`Final notes`),
|
||||
el("p", t`The library also provides a method to dispatch the events.`),
|
||||
el(example, { src: fileURL("./components/examples/events/compareDispatch.js"), page_id }),
|
||||
|
||||
|
||||
el(mnemonic)
|
||||
);
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ export function page({ pkg, info }){
|
||||
programming. If we desire to solve the issue in a declarative manner, signals may be a viable approach.
|
||||
`),
|
||||
el(code, { src: fileURL("./components/examples/signals/intro.js"), page_id }),
|
||||
|
||||
|
||||
el(h3, t`Introducing signals`),
|
||||
el("p").append(...T`
|
||||
Let’s re-introduce
|
||||
@ -62,7 +62,7 @@ export function page({ pkg, info }){
|
||||
`),
|
||||
el(example, { src: fileURL("./components/examples/signals/signals.js"), page_id }),
|
||||
el("p").append(...T`
|
||||
All this is just an example of
|
||||
All this is just an example of
|
||||
${el("a", { textContent: t`Event-driven programming`, ...references.wiki_event_driven })} and
|
||||
${el("a", { textContent: t`Publish–subscribe pattern`, ...references.wiki_pubsub })} (compare for example
|
||||
with ${el("a", { textContent: t`fpubsub library`, ...references.fpubsub })}). All three parts can be in
|
||||
@ -109,8 +109,8 @@ export function page({ pkg, info }){
|
||||
el("p").append(...T`
|
||||
To derived attribute based on value of signal variable just use the signal as a value of the attribute
|
||||
(${el("code", "assign(element, { attribute: S('value') })")}). ${el("code", "assign")}/${el("code", "el")}
|
||||
provides ways to glue reactive attributes/classes more granularly into the DOM. Just use dedicated build-in
|
||||
attributes ${el("code", "dataset")}, ${el("code", "ariaset")} and ${el("code", "classList")}.
|
||||
provides ways to glue reactive attributes/classes more granularly into the DOM. Just use dedicated build-in
|
||||
attributes ${el("code", "dataset")}, ${el("code", "ariaset")} and ${el("code", "classList")}.
|
||||
`),
|
||||
el("p").append(...T`
|
||||
For computation, you can use the “derived signal” (see above) like
|
||||
|
@ -36,7 +36,7 @@ export function page({ pkg, info }){
|
||||
`),
|
||||
el(code, { src: fileURL("./components/examples/scopes/intro.js"), page_id }),
|
||||
el("p").append(...T`The library therefore use ${el("em", t`scopes`)} to provide these functionalities.`),
|
||||
|
||||
|
||||
el(h3, t`Scopes and hosts`),
|
||||
el("p").append(...T`
|
||||
The ${el("strong", "host")} is the name for the element representing the component. This is typically
|
||||
|
@ -21,7 +21,7 @@ const references= {
|
||||
/** observedAttributes on MDN */
|
||||
mdn_observedAttributes: {
|
||||
title: t`MDN documentation page for observedAttributes`,
|
||||
href: "https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#responding_to_attribute_changes",
|
||||
href: "https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#responding_to_attribute_changes", // editorconfig-checker-disable-line
|
||||
},
|
||||
/** Custom Elements on MDN */
|
||||
mdn_custom_elements: {
|
||||
@ -55,10 +55,10 @@ export function page({ pkg, info }){
|
||||
return el(simplePage, { info, pkg }).append(
|
||||
el("h2", t`Using web components in combinantion with DDE`),
|
||||
el("p").append(...T`
|
||||
The DDE library allows for use within ${el("a", references.mdn_web_components).append( el("strong", t`Web Components`) )}
|
||||
for dom-tree generation. However, in order to be able to use signals (possibly mapping to registered
|
||||
${el("a", references.mdn_observedAttributes).append( el("code", "observedAttributes") )}) and additional
|
||||
functionality is (unfortunately) required to use helpers provided by the library.
|
||||
The DDE library allows for use within ${el("a", references.mdn_web_components).append( el("strong",
|
||||
t`Web Components`) )} for dom-tree generation. However, in order to be able to use signals (possibly
|
||||
mapping to registered ${el("a", references.mdn_observedAttributes).append( el("code", "observedAttributes")
|
||||
)}) and additional functionality is (unfortunately) required to use helpers provided by the library.
|
||||
`),
|
||||
el(code, { src: fileURL("./components/examples/customElement/intro.js"), page_id }),
|
||||
|
||||
@ -82,8 +82,8 @@ export function page({ pkg, info }){
|
||||
`),
|
||||
el("p").append(...T`
|
||||
Also see the Life Cycle Events sections, very similarly we would like to use
|
||||
${el("a", { textContent: t`DDE events`, href: "./p03-events.html", title: t`See events part of the library documentation` })}.
|
||||
To do it, the library provides function ${el("code", "customElementWithDDE")}…
|
||||
${el("a", { textContent: t`DDE events`, href: "./p03-events.html", title: t`See events part of the library
|
||||
documentation` })}. To do it, the library provides function ${el("code", "customElementWithDDE")}…
|
||||
`),
|
||||
el(example, { src: fileURL("./components/examples/customElement/customElementWithDDE.js"), page_id }),
|
||||
|
||||
|
@ -21,7 +21,8 @@ export function thirdParty(){
|
||||
});
|
||||
// Array.from((new URL(location)).searchParams.entries())
|
||||
// .forEach(([ key, value ])=> S.action(store, "set", key, value));
|
||||
// S.on(store, data=> history.replaceState("", "", "?"+(new URLSearchParams(JSON.parse(JSON.stringify(data)))).toString()));
|
||||
// S.on(store, data=> history.replaceState("", "",
|
||||
// "?"+(new URLSearchParams(JSON.parse(JSON.stringify(data)))).toString()));
|
||||
useStore(store_adapter, {
|
||||
onread(data){
|
||||
Array.from(data.entries())
|
||||
|
@ -15,6 +15,7 @@ export function fullNameComponent(){
|
||||
on.disconnected(()=> console.log(fullNameComponent))
|
||||
);
|
||||
|
||||
const style= { height: "80px", display: "block", fill: "currentColor" };
|
||||
const elSVG= elNS("http://www.w3.org/2000/svg");
|
||||
return el("div", { className }).append(
|
||||
el("h2", "Simple form:"),
|
||||
@ -29,7 +30,7 @@ export function fullNameComponent(){
|
||||
": ",
|
||||
el("#text", full_name)
|
||||
),
|
||||
elSVG("svg", { viewBox: "0 0 240 80", style: { height: "80px", display: "block" } }).append(
|
||||
elSVG("svg", { viewBox: "0 0 240 80", style }).append(
|
||||
//elSVG("style", { })
|
||||
elSVG("text", { x: 20, y: 35, textContent: "Text" }),
|
||||
)
|
||||
|
@ -17,22 +17,25 @@ const className= style.host(todosComponent).css`
|
||||
/** @param {{ todos: string[] }} */
|
||||
export function todosComponent({ todos= [ "Task A" ] }= {}){
|
||||
let key= 0;
|
||||
const todosO= S(new Map(), {
|
||||
const todosO= S( /** @type {Map<number, ddeSignal<string>>} */ (new Map()), {
|
||||
/** @param {string} v */
|
||||
add(v){ this.value.set(key++, S(v)); },
|
||||
/** @param {number} key */
|
||||
remove(key){ S.clear(this.value.get(key)); this.value.delete(key); }
|
||||
});
|
||||
todos.forEach(text=> S.action(todosO, "add", text));
|
||||
|
||||
const name= "todoName";
|
||||
const onsubmitAdd= on("submit", event=> {
|
||||
const el= event.target.elements[name];
|
||||
const el_form= /** @type {HTMLFormElement} */ (event.target);
|
||||
const el= /** @type {HTMLInputElement} */ (el_form.elements[name]);
|
||||
event.preventDefault();
|
||||
S.action(todosO, "add", el.value);
|
||||
el.value= "";
|
||||
});
|
||||
const onremove= on("remove", event=>
|
||||
S.action(todosO, "remove", event.detail));
|
||||
|
||||
const onremove= on("remove", /** @param {CustomEvent<number>} event */
|
||||
event=> S.action(todosO, "remove", event.detail));
|
||||
|
||||
return el("div", { className }).append(
|
||||
el("div").append(
|
||||
el("h2", "Todos:"),
|
||||
@ -60,19 +63,24 @@ export function todosComponent({ todos= [ "Task A" ] }= {}){
|
||||
)
|
||||
}
|
||||
/**
|
||||
* @param {{ textContent: ddeSignal<string>, value: ddeSignal<number> }} attrs
|
||||
* @dispatchs {number} remove
|
||||
* */
|
||||
function todoComponent({ textContent, value }){
|
||||
const { host }= scope;
|
||||
const dispatchRemove= /** @type {(data: number) => void} */
|
||||
(dispatchEvent("remove", null, host));
|
||||
const onclick= on("click", event=> {
|
||||
const value= Number(event.target.value);
|
||||
const el= /** @type {HTMLButtonElement} */ (event.target);
|
||||
const value= Number(el.value);
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
dispatchEvent("remove")(host(), value);
|
||||
dispatchRemove(value);
|
||||
});
|
||||
const is_editable= S(false);
|
||||
const onedited= on("change", ev=> {
|
||||
textContent(ev.target.value);
|
||||
const el= /** @type {HTMLInputElement} */ (ev.target);
|
||||
textContent(el.value);
|
||||
is_editable(false);
|
||||
});
|
||||
return el("li").append(
|
||||
|
@ -38,7 +38,7 @@ export class CustomHTMLTestElement extends HTMLElement{
|
||||
);
|
||||
}
|
||||
test= "A";
|
||||
|
||||
|
||||
get name(){ return this.getAttribute("name"); }
|
||||
set name(value){ this.setAttribute("name", value); }
|
||||
/** @attr pre-name */
|
||||
|
@ -1,4 +1,9 @@
|
||||
import { style, el, S } from './exports.js';
|
||||
style.css`
|
||||
:root{
|
||||
color-scheme: dark light;
|
||||
}
|
||||
`;
|
||||
document.head.append(style.element);
|
||||
import { fullNameComponent } from './components/fullNameComponent.js';
|
||||
import { todosComponent } from './components/todosComponent.js';
|
||||
|
134
index.d.ts
vendored
134
index.d.ts
vendored
@ -2,63 +2,87 @@ declare global{ /* ddeSignal */ }
|
||||
|
||||
type CustomElementTagNameMap= { '#text': Text, '#comment': Comment }
|
||||
type SupportedElement=
|
||||
HTMLElementTagNameMap[keyof HTMLElementTagNameMap]
|
||||
| SVGElementTagNameMap[keyof SVGElementTagNameMap]
|
||||
| MathMLElementTagNameMap[keyof MathMLElementTagNameMap]
|
||||
| CustomElementTagNameMap[keyof CustomElementTagNameMap]
|
||||
HTMLElementTagNameMap[keyof HTMLElementTagNameMap]
|
||||
| SVGElementTagNameMap[keyof SVGElementTagNameMap]
|
||||
| MathMLElementTagNameMap[keyof MathMLElementTagNameMap]
|
||||
| CustomElementTagNameMap[keyof CustomElementTagNameMap]
|
||||
declare global {
|
||||
type ddeComponentAttributes= Record<any, any> | undefined;
|
||||
type ddeElementAddon<El extends SupportedElement | DocumentFragment>= (element: El)=> El | void;
|
||||
type ddeElementAddon<El extends SupportedElement | DocumentFragment | Node>= (element: El)=> any;
|
||||
type ddeString= string | ddeSignal<string>
|
||||
type ddeStringable= ddeString | number | ddeSignal<number>
|
||||
}
|
||||
type PascalCase= `${Capitalize<string>}${string}`;
|
||||
type AttrsModified= {
|
||||
/**
|
||||
* Use string like in HTML (internally uses `*.setAttribute("style", *)`), or object representation (like DOM API).
|
||||
*/
|
||||
style: string | Partial<CSSStyleDeclaration> | ddeSignal<string> | Partial<{ [K in keyof CSSStyleDeclaration]: ddeSignal<CSSStyleDeclaration[K]> }>
|
||||
style: Partial<CSSStyleDeclaration> | ddeString
|
||||
| Partial<{ [K in keyof CSSStyleDeclaration]: ddeSignal<CSSStyleDeclaration[K]> }>
|
||||
/**
|
||||
* Provide option to add/remove/toggle CSS clasess (index of object) using 1/0/-1. In fact `el.classList.toggle(class_name)` for `-1` and `el.classList.toggle(class_name, Boolean(...))` for others.
|
||||
* Provide option to add/remove/toggle CSS clasess (index of object) using 1/0/-1.
|
||||
* In fact `el.classList.toggle(class_name)` for `-1` and `el.classList.toggle(class_name, Boolean(...))`
|
||||
* for others.
|
||||
*/
|
||||
classList: Record<string,-1|0|1|boolean|ddeSignal<-1|0|1|boolean>>,
|
||||
/**
|
||||
* By default simiral to `className`, but also supports `string[]`
|
||||
* Used by the dataset HTML attribute to represent data for custom attributes added to elements.
|
||||
* Values are converted to string (see {@link DOMStringMap}).
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMStringMap)
|
||||
* */
|
||||
className: string | (string|boolean|undefined|ddeSignal<string|boolean|undefined>)[];
|
||||
dataset: Record<string, ddeStringable>,
|
||||
/**
|
||||
* Sets `aria-*` simiraly to `dataset`
|
||||
* */
|
||||
ariaset: Record<string,string|ddeSignal<string>>,
|
||||
} & Record<`=${string}` | `data${PascalCase}` | `aria${PascalCase}`, string|ddeSignal<string>> & Record<`.${string}`, any>
|
||||
ariaset: Record<string, ddeString>,
|
||||
} & Record<`=${string}` | `data${PascalCase}` | `aria${PascalCase}`, ddeString>
|
||||
& Record<`.${string}`, any>
|
||||
type _fromElsInterfaces<EL extends SupportedElement>= Omit<EL, keyof AttrsModified>;
|
||||
type IsReadonly<T, K extends keyof T> =
|
||||
T extends { readonly [P in K]: T[K] } ? true : false;
|
||||
/**
|
||||
* Just element attributtes
|
||||
*
|
||||
* In most cases, you can use native propertie such as [MDN WEB/API/Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) and so on (e.g. [`Text`](https://developer.mozilla.org/en-US/docs/Web/API/Text)).
|
||||
* In most cases, you can use native propertie such as
|
||||
* [MDN WEB/API/Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) and so on
|
||||
* (e.g. [`Text`](https://developer.mozilla.org/en-US/docs/Web/API/Text)).
|
||||
*
|
||||
* There is added support for `data[A-Z].*`/`aria[A-Z].*` to be converted to the kebab-case alternatives.
|
||||
* @private
|
||||
*/
|
||||
type ElementAttributes<T extends SupportedElement>= Partial<{ [K in keyof _fromElsInterfaces<T>]: _fromElsInterfaces<T>[K] | ddeSignal<_fromElsInterfaces<T>[K]> } & AttrsModified> & Record<string, any>;
|
||||
export function classListDeclarative<El extends SupportedElement>(element: El, classList: AttrsModified["classList"]): El
|
||||
type ElementAttributes<T extends SupportedElement>= Partial<{
|
||||
[K in keyof _fromElsInterfaces<T>]: IsReadonly<_fromElsInterfaces<T>, K> extends false
|
||||
? _fromElsInterfaces<T>[K] | ddeSignal<_fromElsInterfaces<T>[K]>
|
||||
: ddeStringable
|
||||
} & AttrsModified> & Record<string, any>;
|
||||
export function classListDeclarative<El extends SupportedElement>(
|
||||
element: El,
|
||||
classList: AttrsModified["classList"]
|
||||
): El
|
||||
export function assign<El extends SupportedElement>(element: El, ...attrs_array: ElementAttributes<El>[]): El
|
||||
export function assignAttribute<El extends SupportedElement, ATT extends keyof ElementAttributes<El>>(element: El, attr: ATT, value: ElementAttributes<El>[ATT]): ElementAttributes<El>[ATT]
|
||||
export function assignAttribute<El extends SupportedElement, ATT extends keyof ElementAttributes<El>>(
|
||||
element: El,
|
||||
attr: ATT,
|
||||
value: ElementAttributes<El>[ATT]
|
||||
): ElementAttributes<El>[ATT]
|
||||
|
||||
type ExtendedHTMLElementTagNameMap= HTMLElementTagNameMap & CustomElementTagNameMap;
|
||||
type textContent= string | ddeSignal<string>;
|
||||
export function el<
|
||||
TAG extends keyof ExtendedHTMLElementTagNameMap,
|
||||
EL extends ExtendedHTMLElementTagNameMap[TAG]
|
||||
>(
|
||||
tag_name: TAG,
|
||||
attrs?: ElementAttributes<EL> | textContent,
|
||||
...addons: ddeElementAddon<EL>[]
|
||||
attrs?: ElementAttributes<ExtendedHTMLElementTagNameMap[NoInfer<TAG>]> | ddeString,
|
||||
...addons: ddeElementAddon<
|
||||
ExtendedHTMLElementTagNameMap[NoInfer<TAG>]
|
||||
>[], // TODO: for now addons must have the same element
|
||||
): TAG extends keyof ddeHTMLElementTagNameMap ? ddeHTMLElementTagNameMap[TAG] : ddeHTMLElement
|
||||
export function el(
|
||||
tag_name?: "<>",
|
||||
): ddeDocumentFragment
|
||||
export function el(
|
||||
tag_name: string,
|
||||
attrs?: ElementAttributes<HTMLElement> | textContent,
|
||||
attrs?: ElementAttributes<HTMLElement> | ddeString,
|
||||
...addons: ddeElementAddon<HTMLElement>[]
|
||||
): ddeHTMLElement
|
||||
|
||||
@ -66,9 +90,11 @@ export function el<
|
||||
C extends (attr: ddeComponentAttributes)=> SupportedElement | ddeDocumentFragment
|
||||
>(
|
||||
component: C,
|
||||
attrs?: Parameters<C>[0] | textContent,
|
||||
attrs?: Parameters<C>[0] | ddeString,
|
||||
...addons: ddeElementAddon<ReturnType<C>>[]
|
||||
): ReturnType<C> extends ddeHTMLElementTagNameMap[keyof ddeHTMLElementTagNameMap] ? ReturnType<C> : ( ReturnType<C> extends ddeDocumentFragment ? ReturnType<C> : ddeHTMLElement )
|
||||
): ReturnType<C> extends ddeHTMLElementTagNameMap[keyof ddeHTMLElementTagNameMap]
|
||||
? ReturnType<C>
|
||||
: ( ReturnType<C> extends ddeDocumentFragment ? ReturnType<C> : ddeHTMLElement )
|
||||
export { el as createElement }
|
||||
|
||||
export function elNS(
|
||||
@ -78,8 +104,8 @@ export function elNS(
|
||||
EL extends ( TAG extends keyof SVGElementTagNameMap ? SVGElementTagNameMap[TAG] : SVGElement ),
|
||||
>(
|
||||
tag_name: TAG,
|
||||
attrs?: ElementAttributes<EL> | textContent,
|
||||
...addons: ddeElementAddon<EL>[]
|
||||
attrs?: ElementAttributes<NoInfer<EL>> | ddeString,
|
||||
...addons: ddeElementAddon<NoInfer<EL>>[]
|
||||
)=> TAG extends keyof ddeSVGElementTagNameMap ? ddeSVGElementTagNameMap[TAG] : ddeSVGElement
|
||||
export function elNS(
|
||||
namespace: "http://www.w3.org/1998/Math/MathML"
|
||||
@ -88,14 +114,16 @@ export function elNS(
|
||||
EL extends ( TAG extends keyof MathMLElementTagNameMap ? MathMLElementTagNameMap[TAG] : MathMLElement ),
|
||||
>(
|
||||
tag_name: TAG,
|
||||
attrs?: string | textContent | Partial<{ [key in keyof EL]: EL[key] | ddeSignal<EL[key]> | string | number | boolean }>,
|
||||
...addons: ddeElementAddon<EL>[]
|
||||
attrs?: ddeString | Partial<{
|
||||
[key in keyof EL]: EL[key] | ddeSignal<EL[key]> | string | number | boolean
|
||||
}>,
|
||||
...addons: ddeElementAddon<NoInfer<EL>>[]
|
||||
)=> ddeMathMLElement
|
||||
export function elNS(
|
||||
namespace: string
|
||||
): (
|
||||
tag_name: string,
|
||||
attrs?: string | textContent | Record<string, any>,
|
||||
attrs?: string | ddeString | Record<string, any>,
|
||||
...addons: ddeElementAddon<SupportedElement>[]
|
||||
)=> SupportedElement
|
||||
export { elNS as createElementNS }
|
||||
@ -106,36 +134,45 @@ export function chainableAppend<EL extends SupportedElement>(el: EL): EL;
|
||||
* */
|
||||
type simulateSlotsMapper= (body: HTMLSlotElement, el: HTMLElement)=> void;
|
||||
/** Simulate slots for ddeComponents */
|
||||
export function simulateSlots<EL extends SupportedElement | DocumentFragment>(root: EL, mapper?: simulateSlotsMapper): EL
|
||||
export function simulateSlots<EL extends SupportedElement | DocumentFragment>(
|
||||
root: EL,
|
||||
mapper?: simulateSlotsMapper
|
||||
): EL
|
||||
/**
|
||||
* Simulate slots in Custom Elements without using `shadowRoot`.
|
||||
* @param el Custom Element root element
|
||||
* @param body Body of the custom element
|
||||
* */
|
||||
export function simulateSlots<EL extends SupportedElement | DocumentFragment>(el: HTMLElement, body: EL, mapper?: simulateSlotsMapper): EL
|
||||
export function simulateSlots<EL extends SupportedElement | DocumentFragment>(
|
||||
el: HTMLElement,
|
||||
body: EL, mapper?: simulateSlotsMapper
|
||||
): EL
|
||||
|
||||
export function dispatchEvent(name: keyof DocumentEventMap | string, options?: EventInit):
|
||||
(element: SupportedElement, data?: any)=> void;
|
||||
export function dispatchEvent(name: keyof DocumentEventMap | string, options: EventInit | null, element: SupportedElement | (()=> SupportedElement)):
|
||||
(data?: any)=> void;
|
||||
export function dispatchEvent(
|
||||
name: keyof DocumentEventMap | string,
|
||||
options: EventInit | null,
|
||||
element: SupportedElement | (()=> SupportedElement)
|
||||
): (data?: any)=> void;
|
||||
interface On{
|
||||
/** Listens to the DOM event. See {@link Document.addEventListener} */
|
||||
<
|
||||
EE extends ddeElementAddon<SupportedElement>,
|
||||
El extends ( EE extends ddeElementAddon<infer El> ? El : never ),
|
||||
Event extends keyof DocumentEventMap>(
|
||||
Event extends keyof DocumentEventMap,
|
||||
EE extends ddeElementAddon<SupportedElement>= ddeElementAddon<HTMLElement>,
|
||||
>(
|
||||
type: Event,
|
||||
listener: (this: El, ev: DocumentEventMap[Event]) => any,
|
||||
listener: (this: EE extends ddeElementAddon<infer El> ? El : never, ev: DocumentEventMap[Event]) => any,
|
||||
options?: AddEventListenerOptions
|
||||
) : EE;
|
||||
<
|
||||
EE extends ddeElementAddon<SupportedElement>,
|
||||
El extends ( EE extends ddeElementAddon<infer El> ? El : never )>(
|
||||
EE extends ddeElementAddon<SupportedElement>= ddeElementAddon<HTMLElement>,
|
||||
>(
|
||||
type: string,
|
||||
listener: (this: El, ev: Event | CustomEvent ) => any,
|
||||
listener: (this: EE extends ddeElementAddon<infer El> ? El : never, ev: Event | CustomEvent ) => any,
|
||||
options?: AddEventListenerOptions
|
||||
) : EE;
|
||||
/** Listens to the element is connected to the live DOM. In case of custom elements uses [`connectedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */
|
||||
/** Listens to the element is connected to the live DOM. In case of custom elements uses [`connectedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */// editorconfig-checker-disable-line
|
||||
connected<
|
||||
EE extends ddeElementAddon<SupportedElement>,
|
||||
El extends ( EE extends ddeElementAddon<infer El> ? El : never )
|
||||
@ -143,7 +180,7 @@ interface On{
|
||||
listener: (this: El, event: CustomEvent<El>) => any,
|
||||
options?: AddEventListenerOptions
|
||||
) : EE;
|
||||
/** Listens to the element is disconnected from the live DOM. In case of custom elements uses [`disconnectedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */
|
||||
/** Listens to the element is disconnected from the live DOM. In case of custom elements uses [`disconnectedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */// editorconfig-checker-disable-line
|
||||
disconnected<
|
||||
EE extends ddeElementAddon<SupportedElement>,
|
||||
El extends ( EE extends ddeElementAddon<infer El> ? El : never )
|
||||
@ -151,7 +188,7 @@ interface On{
|
||||
listener: (this: El, event: CustomEvent<void>) => any,
|
||||
options?: AddEventListenerOptions
|
||||
) : EE;
|
||||
/** Listens to the element attribute changes. In case of custom elements uses [`attributeChangedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */
|
||||
/** Listens to the element attribute changes. In case of custom elements uses [`attributeChangedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */// editorconfig-checker-disable-line
|
||||
attributeChanged<
|
||||
EE extends ddeElementAddon<SupportedElement>,
|
||||
El extends ( EE extends ddeElementAddon<infer El> ? El : never )
|
||||
@ -162,7 +199,12 @@ interface On{
|
||||
}
|
||||
export const on: On;
|
||||
|
||||
type Scope= { scope: Node | Function | Object, host: ddeElementAddon<any>, custom_element: false | HTMLElement, prevent: boolean }
|
||||
type Scope= {
|
||||
scope: Node | Function | Object,
|
||||
host: ddeElementAddon<any>,
|
||||
custom_element: false | HTMLElement,
|
||||
prevent: boolean
|
||||
};
|
||||
/** Current scope created last time the `el(Function)` was invoke. (Or {@link scope.push}) */
|
||||
export const scope: {
|
||||
current: Scope,
|
||||
@ -176,7 +218,7 @@ export const scope: {
|
||||
* — `scope.host(on.connected(console.log))`.
|
||||
* */
|
||||
host: (...addons: ddeElementAddon<SupportedElement>[])=> HTMLElement,
|
||||
|
||||
|
||||
state: Scope[],
|
||||
/** Adds new child scope. All attributes are inherited by default. */
|
||||
push(scope: Partial<Scope>): ReturnType<Array<Scope>["push"]>,
|
||||
@ -202,12 +244,12 @@ export function observedAttributes(custom_element: HTMLElement): Record<string,
|
||||
/* TypeScript MEH */
|
||||
declare global{
|
||||
type ddeAppend<el>= (...nodes: (Node | string)[])=> el;
|
||||
|
||||
|
||||
interface ddeDocumentFragment extends DocumentFragment{ append: ddeAppend<ddeDocumentFragment>; }
|
||||
interface ddeHTMLElement extends HTMLElement{ append: ddeAppend<ddeHTMLElement>; }
|
||||
interface ddeSVGElement extends SVGElement{ append: ddeAppend<ddeSVGElement>; }
|
||||
interface ddeMathMLElement extends MathMLElement{ append: ddeAppend<ddeMathMLElement>; }
|
||||
|
||||
|
||||
interface ddeHTMLElementTagNameMap {
|
||||
"a": ddeHTMLAnchorElement;
|
||||
"area": ddeHTMLAreaElement;
|
||||
@ -350,6 +392,7 @@ declare global{
|
||||
}
|
||||
}
|
||||
|
||||
// editorconfig-checker-disable
|
||||
interface ddeHTMLAnchorElement extends HTMLAnchorElement{ append: ddeAppend<ddeHTMLAnchorElement>; }
|
||||
interface ddeHTMLAreaElement extends HTMLAreaElement{ append: ddeAppend<ddeHTMLAreaElement>; }
|
||||
interface ddeHTMLAudioElement extends HTMLAudioElement{ append: ddeAppend<ddeHTMLAudioElement>; }
|
||||
@ -477,3 +520,4 @@ interface ddeSVGTitleElement extends SVGTitleElement{ append: ddeAppend<ddeSVGTi
|
||||
interface ddeSVGTSpanElement extends SVGTSpanElement{ append: ddeAppend<ddeSVGTSpanElement>; }
|
||||
interface ddeSVGUseElement extends SVGUseElement{ append: ddeAppend<ddeSVGUseElement>; }
|
||||
interface ddeSVGViewElement extends SVGViewElement{ append: ddeAppend<ddeSVGViewElement>; }
|
||||
// editorconfig-checker-enable
|
||||
|
2
jsdom.js
2
jsdom.js
@ -29,7 +29,7 @@ export function register(dom){
|
||||
export function unregister(){
|
||||
if(!dom_last)
|
||||
return false;
|
||||
|
||||
|
||||
Object.assign(env, env_bk);
|
||||
env_bk= {};
|
||||
dom_last= undefined;
|
||||
|
19
package-lock.json
generated
19
package-lock.json
generated
@ -11,6 +11,7 @@
|
||||
"devDependencies": {
|
||||
"@size-limit/preset-small-lib": "~11.0",
|
||||
"dts-bundler": "~0.1",
|
||||
"editorconfig-checker": "^6.0.0",
|
||||
"esbuild": "~0.24",
|
||||
"jsdom": "~25.0",
|
||||
"jshint": "~2.13",
|
||||
@ -1424,6 +1425,24 @@
|
||||
"typescript": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/editorconfig-checker": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/editorconfig-checker/-/editorconfig-checker-6.0.0.tgz",
|
||||
"integrity": "sha512-uyTOwLJzR/k7ugiu7ITjCzkLKBhXeirQZ8hGlUkt1u/hq2Qu1E8EslgFZDN+lxZoQc97eiI87sUFgVILK4P+YQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"ec": "dist/index.js",
|
||||
"editorconfig-checker": "dist/index.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.11.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "buymeacoffee",
|
||||
"url": "https://www.buymeacoffee.com/mstruebing"
|
||||
}
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
|
@ -83,9 +83,7 @@
|
||||
"modifyEsbuildConfig": {
|
||||
"platform": "browser"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"scripts": {},
|
||||
"keywords": [
|
||||
"dom",
|
||||
"javascript",
|
||||
@ -95,6 +93,7 @@
|
||||
"devDependencies": {
|
||||
"@size-limit/preset-small-lib": "~11.0",
|
||||
"dts-bundler": "~0.1",
|
||||
"editorconfig-checker": "~6.0",
|
||||
"esbuild": "~0.24",
|
||||
"jsdom": "~25.0",
|
||||
"jshint": "~2.13",
|
||||
|
2
signals.d.ts
vendored
2
signals.d.ts
vendored
@ -55,7 +55,7 @@ interface signal{
|
||||
* */
|
||||
el<S extends any>(signal: Signal<S, any>, el: (v: S)=> Element | Element[] | DocumentFragment): DocumentFragment;
|
||||
|
||||
observedAttributes(custom_element: HTMLElement): Record<string, Signal<string, {}>>;
|
||||
observedAttributes(custom_element: HTMLElement): Record<string, Signal<string, {}>>;
|
||||
}
|
||||
export const signal: signal;
|
||||
export const S: signal;
|
||||
|
@ -13,11 +13,11 @@ function setDeleteAttr(obj, prop, val){
|
||||
For some native attrs you can unset only to set empty string.
|
||||
This can be confusing as it is seen in inspector `<… id=""`.
|
||||
Options:
|
||||
1. Leave it, as it is native behaviour
|
||||
2. Sets as empty string and removes the corresponding attribute when also has empty string
|
||||
*3. Sets as undefined and removes the corresponding attribute when "undefined" string discovered
|
||||
4. Point 2. with checks for coincidence (e.g. use special string)
|
||||
*/
|
||||
1. Leave it, as it is native behaviour
|
||||
2. Sets as empty string and removes the corresponding attribute when also has empty string
|
||||
3. (*) Sets as undefined and removes the corresponding attribute when "undefined" string discovered
|
||||
4. Point 2. with checks for coincidence (e.g. use special string)
|
||||
*/
|
||||
Reflect.set(obj, prop, val);
|
||||
if(!isUndef(val)) return;
|
||||
Reflect.deleteProperty(obj, prop);
|
||||
|
66
src/dom.js
66
src/dom.js
@ -10,13 +10,13 @@ const scopes= [ {
|
||||
export const scope= {
|
||||
get current(){ return scopes[scopes.length-1]; },
|
||||
get host(){ return this.current.host; },
|
||||
|
||||
|
||||
preventDefault(){
|
||||
const { current }= this;
|
||||
current.prevent= true;
|
||||
return current;
|
||||
},
|
||||
|
||||
|
||||
get state(){ return [ ...scopes ]; },
|
||||
push(s= {}){ return scopes.push(Object.assign({}, this.current, { prevent: false }, s)); },
|
||||
pushRoot(){ return scopes.push(scopes[0]); },
|
||||
@ -25,9 +25,11 @@ export const scope= {
|
||||
return scopes.pop();
|
||||
},
|
||||
};
|
||||
// following chainableAppend implementation is OK as the ElementPrototype.append description already is { writable: true, enumerable: true, configurable: true }
|
||||
// following chainableAppend implementation is OK as the ElementPrototype.append description already is { writable: true, enumerable: true, configurable: true } // editorconfig-checker-disable-line
|
||||
function append(...els){ this.appendOriginal(...els); return this; }
|
||||
export function chainableAppend(el){ if(el.append===append) return el; el.appendOriginal= el.append; el.append= append; return el; }
|
||||
export function chainableAppend(el){
|
||||
if(el.append===append) return el; el.appendOriginal= el.append; el.append= append; return el;
|
||||
}
|
||||
let namespace;
|
||||
export function createElement(tag, attributes, ...addons){
|
||||
/* jshint maxcomplexity: 15 */
|
||||
@ -40,7 +42,9 @@ export function createElement(tag, attributes, ...addons){
|
||||
switch(true){
|
||||
case typeof tag==="function": {
|
||||
scoped= 1;
|
||||
scope.push({ scope: tag, host: (...c)=> c.length ? (scoped===1 ? addons.unshift(...c) : c.forEach(c=> c(el_host)), undefined) : el_host });
|
||||
const host= (...c)=> !c.length ? el_host :
|
||||
(scoped===1 ? addons.unshift(...c) : c.forEach(c=> c(el_host)), undefined);
|
||||
scope.push({ scope: tag, host });
|
||||
el= tag(attributes || undefined);
|
||||
const is_fragment= el instanceof env.F;
|
||||
if(el.nodeName==="#comment") break;
|
||||
@ -65,6 +69,19 @@ export function createElement(tag, attributes, ...addons){
|
||||
scoped= 2;
|
||||
return el;
|
||||
}
|
||||
/**
|
||||
* @param { { type: "component", name: string, host: "this" | "parentElement" } | { type: "reactive" | "later" } } attrs
|
||||
* @param {boolean} [is_open=false]
|
||||
* */
|
||||
createElement.mark= function(attrs, is_open= false){
|
||||
attrs= Object.entries(attrs).map(([ n, v ])=> n+`="${v}"`).join(" ");
|
||||
const end= is_open ? "" : "/";
|
||||
const out= env.D.createComment(`<dde:mark ${attrs}${env.ssr}${end}>`);
|
||||
if(is_open) out.end= env.D.createComment("</dde:mark>");
|
||||
return out;
|
||||
};
|
||||
export { createElement as el };
|
||||
|
||||
import { hasOwn } from "./helpers.js";
|
||||
/** @param {HTMLElement} element @param {HTMLElement} [root] */
|
||||
export function simulateSlots(element, root, mapper){
|
||||
@ -106,23 +123,14 @@ export function simulateSlots(element, root, mapper){
|
||||
}
|
||||
return root;
|
||||
}
|
||||
export function cn(...s){ return s.filter(Boolean).join(" "); }
|
||||
function simulateSlotReplace(slot, element, mapper){
|
||||
if(mapper) mapper(slot, element);
|
||||
try{ slot.replaceWith(assign(element, { className: [ element.className, slot.className ], dataset: { ...slot.dataset } })); }
|
||||
try{ slot.replaceWith(assign(element, {
|
||||
className: cn(element.className, slot.className),
|
||||
dataset: { ...slot.dataset } })); }
|
||||
catch(_){ slot.replaceWith(element); }
|
||||
}
|
||||
/**
|
||||
* @param { { type: "component", name: string, host: "this" | "parentElement" } | { type: "reactive" | "later" } } attrs
|
||||
* @param {boolean} [is_open=false]
|
||||
* */
|
||||
createElement.mark= function(attrs, is_open= false){
|
||||
attrs= Object.entries(attrs).map(([ n, v ])=> n+`="${v}"`).join(" ");
|
||||
const end= is_open ? "" : "/";
|
||||
const out= env.D.createComment(`<dde:mark ${attrs}${env.ssr}${end}>`);
|
||||
if(is_open) out.end= env.D.createComment("</dde:mark>");
|
||||
return out;
|
||||
};
|
||||
export { createElement as el };
|
||||
|
||||
//const namespaceHelper= ns=> ns==="svg" ? "http://www.w3.org/2000/svg" : ns;
|
||||
export function createElementNS(ns){
|
||||
@ -141,7 +149,7 @@ const { setDeleteAttr }= env;
|
||||
export function assign(element, ...attributes){
|
||||
if(!attributes.length) return element;
|
||||
assign_context.set(element, assignContext(element, this));
|
||||
|
||||
|
||||
for(const [ key, value ] of Object.entries(Object.assign({}, ...attributes)))
|
||||
assignAttribute.call(this, element, key, value);
|
||||
assign_context.delete(element);
|
||||
@ -150,7 +158,7 @@ export function assign(element, ...attributes){
|
||||
export function assignAttribute(element, key, value){
|
||||
const { setRemoveAttr, s }= assignContext(element, this);
|
||||
const _this= this;
|
||||
|
||||
|
||||
value= s.processReactiveAttribute(element, key, value,
|
||||
(key, value)=> assignAttribute.call(_this, element, key, value));
|
||||
const [ k ]= key;
|
||||
@ -192,10 +200,6 @@ export function classListDeclarative(element, toggle){
|
||||
element.classList.toggle(class_name, val===-1 ? undefined : Boolean(val)));
|
||||
return element;
|
||||
}
|
||||
export function empty(el){
|
||||
Array.from(el.children).forEach(el=> el.remove());
|
||||
return el;
|
||||
}
|
||||
export function elementAttribute(element, op, key, value){
|
||||
if(element instanceof env.H)
|
||||
return element[op+"Attribute"](key, value);
|
||||
@ -216,7 +220,9 @@ function getPropDescriptor(p, key){
|
||||
return des;
|
||||
}
|
||||
|
||||
/** @template {Record<any, any>} T @param {object} s @param {T} obj @param {(param: [ keyof T, T[keyof T] ])=> void} cb */
|
||||
/**
|
||||
* @template {Record<any, any>} T @param {object} s @param {T} obj @param {(param: [ keyof T, T[keyof T] ])=> void} cb
|
||||
* */
|
||||
function forEachEntries(s, obj, cb){
|
||||
if(typeof obj !== "object" || obj===null) return;
|
||||
return Object.entries(obj).forEach(function process([ key, val ]){
|
||||
@ -226,7 +232,9 @@ function forEachEntries(s, obj, cb){
|
||||
});
|
||||
}
|
||||
|
||||
function attrArrToStr(attr){ return Array.isArray(attr) ? attr.filter(Boolean).join(" ") : attr; }
|
||||
function setRemove(obj, prop, key, val){ return obj[ (isUndef(val) ? "remove" : "set") + prop ](key, attrArrToStr(val)); }
|
||||
function setRemoveNS(obj, prop, key, val, ns= null){ return obj[ (isUndef(val) ? "remove" : "set") + prop + "NS" ](ns, key, attrArrToStr(val)); }
|
||||
function setDelete(obj, key, val){ Reflect.set(obj, key, val); if(!isUndef(val)) return; return Reflect.deleteProperty(obj, key); }
|
||||
function setRemove(obj, prop, key, val){
|
||||
return obj[ (isUndef(val) ? "remove" : "set") + prop ](key, val); }
|
||||
function setRemoveNS(obj, prop, key, val, ns= null){
|
||||
return obj[ (isUndef(val) ? "remove" : "set") + prop + "NS" ](ns, key, val); }
|
||||
function setDelete(obj, key, val){
|
||||
Reflect.set(obj, key, val); if(!isUndef(val)) return; return Reflect.deleteProperty(obj, key); }
|
||||
|
@ -103,10 +103,10 @@ function connectionsChangesObserverConstructor(){
|
||||
for(const element of addedNodes){
|
||||
if(is_root) collectChildren(element).then(observerAdded);
|
||||
if(!store.has(element)) continue;
|
||||
|
||||
|
||||
const ls= store.get(element);
|
||||
if(!ls.length_c) continue;
|
||||
|
||||
|
||||
element.dispatchEvent(new Event(evc));
|
||||
ls.connected= new WeakSet();
|
||||
ls.length_c= 0;
|
||||
@ -120,7 +120,7 @@ function connectionsChangesObserverConstructor(){
|
||||
for(const element of removedNodes){
|
||||
if(is_root) collectChildren(element).then(observerRemoved);
|
||||
if(!store.has(element)) continue;
|
||||
|
||||
|
||||
const ls= store.get(element);
|
||||
if(!ls.length_d) continue;
|
||||
(globalThis.queueMicrotask || setTimeout)(dispatchRemove(element));
|
||||
|
@ -64,9 +64,9 @@ on.attributeChanged= function(listener, options){
|
||||
element.addEventListener(eva, listener, options);
|
||||
if(element[keyLTE] || els_attribute_store.has(element))
|
||||
return element;
|
||||
|
||||
|
||||
if(!env.M) return element;
|
||||
|
||||
|
||||
const observer= new env.M(function(mutations){
|
||||
for(const { attributeName, target } of mutations)
|
||||
target.dispatchEvent(
|
||||
@ -77,4 +77,4 @@ on.attributeChanged= function(listener, options){
|
||||
//TODO: clean up when element disconnected
|
||||
return element;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -21,7 +21,7 @@ export function signal(value, actions){
|
||||
if(typeof value!=="function")
|
||||
return create(false, value, actions);
|
||||
if(isSignal(value)) return value;
|
||||
|
||||
|
||||
const out= create(true);
|
||||
const contextReWatch= function(){
|
||||
const [ origin, ...deps_old ]= deps.get(contextReWatch);
|
||||
@ -77,11 +77,11 @@ signal.clear= function(...signals){
|
||||
o.listeners.forEach(l=> {
|
||||
o.listeners.delete(l);
|
||||
if(!deps.has(l)) return;
|
||||
|
||||
|
||||
const ls= deps.get(l);
|
||||
ls.delete(s);
|
||||
if(ls.size>1) return;
|
||||
|
||||
|
||||
s.clear(...ls);
|
||||
deps.delete(l);
|
||||
});
|
||||
|
@ -21,7 +21,7 @@ export function signal(value, actions){
|
||||
if(typeof value!=="function")
|
||||
return create(false, value, actions);
|
||||
if(isSignal(value)) return value;
|
||||
|
||||
|
||||
const out= create(true);
|
||||
const contextReWatch= function(){
|
||||
const [ origin, ...deps_old ]= deps.get(contextReWatch);
|
||||
@ -77,11 +77,11 @@ signal.clear= function(...signals){
|
||||
o.listeners.forEach(l=> {
|
||||
o.listeners.delete(l);
|
||||
if(!deps.has(l)) return;
|
||||
|
||||
|
||||
const ls= deps.get(l);
|
||||
ls.delete(s);
|
||||
if(ls.size>1) return;
|
||||
|
||||
|
||||
s.clear(...ls);
|
||||
deps.delete(l);
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"emitDeclarationOnly": true,
|
||||
"declaration": true,
|
||||
"declarationDir": "dist"
|
||||
}
|
||||
"compilerOptions": {
|
||||
"emitDeclarationOnly": true,
|
||||
"declaration": true,
|
||||
"declarationDir": "dist"
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user