This commit is contained in:
2026-04-11 02:08:07 +02:00
parent 290c87cec3
commit c4ebf5847b
14 changed files with 802 additions and 361 deletions

View File

@@ -47,7 +47,6 @@ const createEffect = (fn, isComputed = false) => {
effect._depth = activeEffect ? activeEffect._depth + 1 : 0;
effect._mounts = [];
effect._parent = activeOwner;
effect._provisions = activeOwner ? { ...activeOwner._provisions } : {};
if (activeOwner) (activeOwner._children ||= new Set()).add(effect);
return effect;
};
@@ -162,20 +161,6 @@ const cleanupNode = node => {
if (node.childNodes) node.childNodes.forEach(cleanupNode);
};
// provide/inject
const provide = (key, value) => {
if (activeOwner) activeOwner._provisions[key] = value;
};
const inject = (key, defaultValue) => {
let ctx = activeOwner;
while (ctx) {
if (key in ctx._provisions) return ctx._provisions[key];
ctx = ctx._parent;
}
return defaultValue;
};
// --- Seguridad optimizada ---
const DANGEROUS_PROTOCOL = /^\s*(javascript|data|vbscript):/i;
const isDangerousAttr = key => key === 'src' || key === 'href' || key.startsWith('on');
@@ -196,16 +181,9 @@ const validateAttr = (key, val) => {
const Tag = (tag, props = {}, children = []) => {
if (props instanceof Node || isArr(props) || !isObj(props)) { children = props; props = {}; }
if (isFunc(tag)) {
const ctx = {
_mounts: [],
_cleanups: new Set(),
_provisions: activeOwner?._provisions ? { ...activeOwner._provisions } : {}
};
const ctx = { _mounts: [], _cleanups: new Set() };
const effect = createEffect(() => {
const result = tag(props, {
children,
emit: (ev, ...args) => props[`on${ev[0].toUpperCase()}${ev.slice(1)}`]?.(...args)
});
const result = tag(props, { children, emit: (ev, ...args) => props[`on${ev[0].toUpperCase()}${ev.slice(1)}`]?.(...args) });
effect._result = result;
return result;
});
@@ -359,29 +337,28 @@ const For = (src, itemFn, keyFn) => {
const anchor = doc.createTextNode("");
const root = Tag("div", { style: "display:contents" }, [anchor]);
let cache = new Map();
Watch(
() => (isFunc(src) ? src() : src) || [],
(items) => {
const next = new Map(), order = [];
for (let i = 0; i < items.length; i++) {
const item = items[i];
const key = keyFn ? keyFn(item, i) : i;
let view = cache.get(key);
if (!view) view = Render(() => itemFn(item, i));
next.set(key, view);
order.push(key);
cache.delete(key);
}
cache.forEach(v => v.destroy());
cache = next;
let ref = anchor;
for (let i = order.length - 1; i >= 0; i--) {
const view = next.get(order[i]);
if (view.container.nextSibling !== ref) root.insertBefore(view.container, ref);
ref = view.container;
}
Watch(() => (isFunc(src) ? src() : src) || [], (items) => {
const nextCache = new Map();
const nextOrder = [];
const newItems = items || [];
for (let i = 0; i < newItems.length; i++) {
const item = newItems[i];
const key = keyFn ? keyFn(item, i) : (item?.id ?? i);
let view = cache.get(key);
if (!view) view = Render(() => itemFn(item, i)); else cache.delete(key);
nextCache.set(key, view);
nextOrder.push(view);
}
);
cache.forEach(view => view.destroy());
let lastRef = anchor;
for (let i = nextOrder.length - 1; i >= 0; i--) {
const view = nextOrder[i];
const node = view.container;
if (node.nextSibling !== lastRef) root.insertBefore(node, lastRef);
lastRef = node;
}
cache = nextCache;
});
return root;
};
@@ -428,12 +405,12 @@ const Mount = (comp, target) => {
return inst;
};
const SigPro = Object.freeze({ $, $$, Watch, Tag, Render, If, For, Router, Mount, onMount, onUnmount, provide, inject });
const SigPro = Object.freeze({ $, $$, Watch, Tag, Render, If, For, Router, Mount, onMount, onUnmount });
if (typeof window !== "undefined") {
Object.assign(window, SigPro);
"div span p h1 h2 h3 h4 h5 h6 br hr section article aside nav main header footer ul ol li a em strong pre code form label input textarea select button img svg"
.split(" ").forEach(t => window[t[0].toUpperCase() + t.slice(1)] = (p, c) => SigPro.Tag(t, p, c));
}
export { $, $$, Watch, Tag, Render, If, For, Router, Mount, onMount, onUnmount, provide, inject };
export { $, $$, Watch, Tag, Render, If, For, Router, Mount, onMount, onUnmount };
export default SigPro;