Update sigpro.js
This commit is contained in:
@@ -60,8 +60,12 @@ const $ = (initialValue) => {
|
|||||||
computedEffect.dependencies.clear();
|
computedEffect.dependencies.clear();
|
||||||
const prev = activeEffect;
|
const prev = activeEffect;
|
||||||
activeEffect = computedEffect;
|
activeEffect = computedEffect;
|
||||||
try { cachedValue = initialValue(); }
|
try {
|
||||||
finally { activeEffect = prev; isDirty = false; }
|
cachedValue = initialValue();
|
||||||
|
} finally {
|
||||||
|
activeEffect = prev;
|
||||||
|
isDirty = false;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -121,7 +125,9 @@ const $e = (effectFn) => {
|
|||||||
try {
|
try {
|
||||||
const res = effectFn();
|
const res = effectFn();
|
||||||
if (typeof res === "function") this.cleanupHandlers.add(res);
|
if (typeof res === "function") this.cleanupHandlers.add(res);
|
||||||
} finally { activeEffect = prev; }
|
} finally {
|
||||||
|
activeEffect = prev;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
stop() {
|
stop() {
|
||||||
this.cleanupHandlers.forEach((h) => h());
|
this.cleanupHandlers.forEach((h) => h());
|
||||||
@@ -442,8 +448,9 @@ const $p = (setupFunction) => {
|
|||||||
* @param {string} tagName - Custom element tag name
|
* @param {string} tagName - Custom element tag name
|
||||||
* @param {Function} setupFunction - Component setup function
|
* @param {Function} setupFunction - Component setup function
|
||||||
* @param {string[]} observedAttributes - Array of observed attributes
|
* @param {string[]} observedAttributes - Array of observed attributes
|
||||||
|
* @param {boolean} useShadowDOM - Enable Shadow DOM (default: false)
|
||||||
*/
|
*/
|
||||||
const $c = (tagName, setupFunction, observedAttributes = []) => {
|
const $c = (tagName, setupFunction, observedAttributes = [], useShadowDOM = false) => {
|
||||||
if (customElements.get(tagName)) return;
|
if (customElements.get(tagName)) return;
|
||||||
|
|
||||||
customElements.define(
|
customElements.define(
|
||||||
@@ -457,12 +464,19 @@ const $c = (tagName, setupFunction, observedAttributes = []) => {
|
|||||||
super();
|
super();
|
||||||
this._propertySignals = {};
|
this._propertySignals = {};
|
||||||
this.cleanupFunctions = [];
|
this.cleanupFunctions = [];
|
||||||
|
|
||||||
|
if (useShadowDOM) {
|
||||||
|
this._root = this.attachShadow({ mode: "open" });
|
||||||
|
} else {
|
||||||
|
this._root = this;
|
||||||
|
}
|
||||||
|
|
||||||
observedAttributes.forEach((attr) => (this._propertySignals[attr] = $(undefined)));
|
observedAttributes.forEach((attr) => (this._propertySignals[attr] = $(undefined)));
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
const frozenChildren = [...this.childNodes];
|
const frozenChildren = [...this.childNodes];
|
||||||
this.innerHTML = "";
|
this._root.innerHTML = "";
|
||||||
|
|
||||||
observedAttributes.forEach((attr) => {
|
observedAttributes.forEach((attr) => {
|
||||||
const initialValue = this.hasOwnProperty(attr) ? this[attr] : this.getAttribute(attr);
|
const initialValue = this.hasOwnProperty(attr) ? this[attr] : this.getAttribute(attr);
|
||||||
@@ -480,7 +494,8 @@ const $c = (tagName, setupFunction, observedAttributes = []) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const context = {
|
const context = {
|
||||||
select: (selector) => this.querySelector(selector),
|
select: (selector) => this._root.querySelector(selector),
|
||||||
|
selectAll: (selector) => this._root.querySelectorAll(selector),
|
||||||
slot: (name) =>
|
slot: (name) =>
|
||||||
frozenChildren.filter((node) => {
|
frozenChildren.filter((node) => {
|
||||||
const slotName = node.nodeType === 1 ? node.getAttribute("slot") : null;
|
const slotName = node.nodeType === 1 ? node.getAttribute("slot") : null;
|
||||||
@@ -488,11 +503,12 @@ const $c = (tagName, setupFunction, observedAttributes = []) => {
|
|||||||
}),
|
}),
|
||||||
emit: (name, detail) => this.dispatchEvent(new CustomEvent(name, { detail, bubbles: true, composed: true })),
|
emit: (name, detail) => this.dispatchEvent(new CustomEvent(name, { detail, bubbles: true, composed: true })),
|
||||||
host: this,
|
host: this,
|
||||||
|
root: this._root,
|
||||||
onUnmount: (cleanupFn) => this.cleanupFunctions.push(cleanupFn),
|
onUnmount: (cleanupFn) => this.cleanupFunctions.push(cleanupFn),
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = setupFunction(this._propertySignals, context);
|
const result = setupFunction(this._propertySignals, context);
|
||||||
if (result instanceof Node) this.appendChild(result);
|
if (result instanceof Node) this._root.appendChild(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
attributeChangedCallback(name, oldValue, newValue) {
|
attributeChangedCallback(name, oldValue, newValue) {
|
||||||
@@ -548,17 +564,43 @@ const $r = (routes) => {
|
|||||||
const container = document.createElement("div");
|
const container = document.createElement("div");
|
||||||
container.style.display = "contents";
|
container.style.display = "contents";
|
||||||
|
|
||||||
|
const matchRoute = (path, routePath) => {
|
||||||
|
if (!routePath.includes(":")) {
|
||||||
|
return routePath === path ? {} : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const parts = routePath.split("/");
|
||||||
|
const pathParts = path.split("/");
|
||||||
|
|
||||||
|
if (parts.length !== pathParts.length) return null;
|
||||||
|
|
||||||
|
const params = {};
|
||||||
|
for (let i = 0; i < parts.length; i++) {
|
||||||
|
if (parts[i].startsWith(":")) {
|
||||||
|
params[parts[i].slice(1)] = pathParts[i];
|
||||||
|
} else if (parts[i] !== pathParts[i]) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
const render = () => {
|
const render = () => {
|
||||||
const path = getCurrentPath();
|
const path = getCurrentPath();
|
||||||
let matchedRoute = routes.find(r => r.path instanceof RegExp ? path.match(r.path) : r.path === path);
|
let matchedRoute = null;
|
||||||
let routeParams = {};
|
let routeParams = {};
|
||||||
|
|
||||||
if (matchedRoute?.path instanceof RegExp) {
|
for (const route of routes) {
|
||||||
const m = path.match(matchedRoute.path);
|
const params = matchRoute(path, route.path);
|
||||||
routeParams = m.groups || { id: m[1] };
|
if (params !== null) {
|
||||||
|
matchedRoute = route;
|
||||||
|
routeParams = params;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const view = matchedRoute ? matchedRoute.component(routeParams) : Object.assign(document.createElement("h1"), { textContent: "404" });
|
const view = matchedRoute ? matchedRoute.component(routeParams) : Object.assign(document.createElement("h1"), { textContent: "404" });
|
||||||
|
|
||||||
container.replaceChildren(view instanceof Node ? view : document.createTextNode(String(view ?? "")));
|
container.replaceChildren(view instanceof Node ? view : document.createTextNode(String(view ?? "")));
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -566,6 +608,7 @@ const $r = (routes) => {
|
|||||||
render();
|
render();
|
||||||
return container;
|
return container;
|
||||||
};
|
};
|
||||||
|
|
||||||
$r.go = (path) => {
|
$r.go = (path) => {
|
||||||
const targetPath = path.startsWith("/") ? path : `/${path}`;
|
const targetPath = path.startsWith("/") ? path : `/${path}`;
|
||||||
if (window.location.hash !== `#${targetPath}`) {
|
if (window.location.hash !== `#${targetPath}`) {
|
||||||
@@ -573,7 +616,6 @@ $r.go = (path) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Can customize the name of your functions */
|
/* Can customize the name of your functions */
|
||||||
|
|
||||||
$.effect = $e;
|
$.effect = $e;
|
||||||
|
|||||||
Reference in New Issue
Block a user