@stacksjs/stx 0.2.343 → 0.2.345
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/binding-manifest.d.ts +32 -0
- package/dist/binding-manifest.js +64 -0
- package/dist/{chunk-zr1x54bt.js → chunk-05zfez2g.js} +1 -1
- package/dist/{chunk-jagf7h9y.js → chunk-0k1mtwby.js} +1 -1
- package/dist/{chunk-jh6f1a9y.js → chunk-1c9453w0.js} +1 -1
- package/dist/chunk-1qyg1q6d.js +2 -0
- package/dist/chunk-1t4ece3v.js +2 -0
- package/dist/{chunk-7zxv2631.js → chunk-1vt1h19d.js} +1 -1
- package/dist/chunk-1vtdege3.js +2 -0
- package/dist/{chunk-stqm4brp.js → chunk-1vv9g6cj.js} +1 -1
- package/dist/{chunk-p3awq80d.js → chunk-1yh6pq6b.js} +1 -1
- package/dist/{chunk-57dxdvjh.js → chunk-223makqc.js} +1 -1
- package/dist/chunk-2fhk4e68.js +2 -0
- package/dist/{chunk-wyhb3nb0.js → chunk-34f8c48f.js} +1 -1
- package/dist/chunk-3zm4hgcf.js +2 -0
- package/dist/{chunk-xgw269cf.js → chunk-4spaszfn.js} +286 -286
- package/dist/chunk-57t402mn.js +2 -0
- package/dist/{chunk-wdaf98ya.js → chunk-59906baj.js} +1 -1
- package/dist/{chunk-z9hb80mk.js → chunk-64n10kpa.js} +1 -1
- package/dist/chunk-66tgkvqw.js +2 -0
- package/dist/{chunk-daxr6p6q.js → chunk-6fwp7gee.js} +1 -1
- package/dist/{chunk-1bfvdjpy.js → chunk-6h3r8v55.js} +1 -1
- package/dist/{chunk-safmgrq5.js → chunk-6wmjwbq9.js} +1 -1
- package/dist/{chunk-53sjbp3z.js → chunk-72x62kch.js} +2 -2
- package/dist/{chunk-amfq5rnz.js → chunk-72yrrggn.js} +2 -2
- package/dist/{chunk-2853ye06.js → chunk-77p1kjg2.js} +2 -2
- package/dist/chunk-7g5vk4c3.js +2 -0
- package/dist/{chunk-7mc1k1tq.js → chunk-7h9fajgs.js} +1 -1
- package/dist/{chunk-gvfgrve8.js → chunk-7m9qk7da.js} +1 -1
- package/dist/{chunk-3d3x7dwy.js → chunk-7qp3zphs.js} +1 -1
- package/dist/{chunk-grnmr3y1.js → chunk-86c461ca.js} +1 -1
- package/dist/chunk-86q2h34b.js +2 -0
- package/dist/{chunk-7r79j1hs.js → chunk-89mqnh67.js} +1 -1
- package/dist/{chunk-5hq25yky.js → chunk-8cc4vdkh.js} +1 -1
- package/dist/chunk-8rhjt6fh.js +2 -0
- package/dist/{chunk-45ydb29q.js → chunk-8v2k21n4.js} +1 -1
- package/dist/{chunk-aqxwwq6w.js → chunk-8y1ve8tc.js} +2 -2
- package/dist/{chunk-ag8gdk51.js → chunk-99b5tfxc.js} +1 -1
- package/dist/{chunk-4vd0rqfs.js → chunk-9jbssgem.js} +197 -88
- package/dist/{chunk-s60eccqk.js → chunk-9nrgjtah.js} +1 -1
- package/dist/{chunk-y5sxa2sq.js → chunk-9qtf2b1p.js} +1 -1
- package/dist/chunk-aapqf6bj.js +2 -0
- package/dist/{chunk-k8skvm0d.js → chunk-at622hg0.js} +1 -1
- package/dist/{chunk-1qtd4ex2.js → chunk-avwywzsj.js} +2 -2
- package/dist/{chunk-a0ajg9z5.js → chunk-b5hank5e.js} +1 -1
- package/dist/chunk-b5mnam29.js +2 -0
- package/dist/{chunk-4fafxr8d.js → chunk-bk1zb1xp.js} +1 -1
- package/dist/{chunk-hrdd26r4.js → chunk-bqdfbwdf.js} +1 -1
- package/dist/{chunk-c7qdnc5d.js → chunk-c30qnb6z.js} +1 -1
- package/dist/chunk-c4tf1vpy.js +2 -0
- package/dist/{chunk-g0dbtyk7.js → chunk-c8e2deyp.js} +1 -1
- package/dist/chunk-cypg8qwn.js +2 -0
- package/dist/{chunk-fbmjw0bh.js → chunk-d86q27j8.js} +1 -1
- package/dist/{chunk-dj5mqnp1.js → chunk-dgv43ccd.js} +1 -1
- package/dist/{chunk-em8cr7wy.js → chunk-dsztk2kp.js} +1 -1
- package/dist/{chunk-mwvxhv0r.js → chunk-dxkjvajv.js} +1 -1
- package/dist/{chunk-4pg6wbt6.js → chunk-e631svvs.js} +1 -1
- package/dist/chunk-e7gs18rc.js +2 -0
- package/dist/{chunk-h6y99nak.js → chunk-e7np0h2q.js} +1 -1
- package/dist/{chunk-0s3ry262.js → chunk-ejqpq0wc.js} +1 -1
- package/dist/chunk-ek2m0kkw.js +2 -0
- package/dist/chunk-eqzc88et.js +2 -0
- package/dist/chunk-erb294sv.js +2 -0
- package/dist/{chunk-36j9qset.js → chunk-esjcyxa9.js} +2 -2
- package/dist/{chunk-5azeswj2.js → chunk-evfr2zgg.js} +1 -1
- package/dist/{chunk-e53pwshq.js → chunk-fp868yhg.js} +1 -1
- package/dist/{chunk-5zemhhwe.js → chunk-gsc2vds7.js} +1 -1
- package/dist/{chunk-q6825wwz.js → chunk-gvemapw4.js} +1 -1
- package/dist/chunk-h1vax4wg.js +2 -0
- package/dist/chunk-hke0k33t.js +2 -0
- package/dist/{chunk-zcytk5w9.js → chunk-jekrtm2j.js} +1 -1
- package/dist/{chunk-pwhf5kte.js → chunk-jnbg3e4r.js} +1 -1
- package/dist/{chunk-brjfzbq9.js → chunk-kfkf9v2d.js} +1 -1
- package/dist/chunk-kq30wqp6.js +2 -0
- package/dist/{chunk-s7qbba8r.js → chunk-kqzpmwx2.js} +10 -10
- package/dist/{chunk-0dpgh7a6.js → chunk-kw9cgyfc.js} +1 -1
- package/dist/{chunk-0fp16c1x.js → chunk-m2j5skez.js} +1 -1
- package/dist/{chunk-vj3nx26v.js → chunk-mph46gkj.js} +1 -1
- package/dist/chunk-mr8ccsnm.js +2 -0
- package/dist/{chunk-1h1c2048.js → chunk-msywnv5n.js} +1 -1
- package/dist/{chunk-649dfqqz.js → chunk-n5657hm3.js} +1 -1
- package/dist/{chunk-t00ga194.js → chunk-njx93b4z.js} +1 -1
- package/dist/{chunk-m0xaw0qw.js → chunk-nm60wh6r.js} +1 -1
- package/dist/{chunk-8ah5mhst.js → chunk-nqz501eq.js} +2 -2
- package/dist/{chunk-hq3phk1a.js → chunk-nrt99ptw.js} +1 -1
- package/dist/{chunk-62vng8g8.js → chunk-pajk5680.js} +2 -2
- package/dist/{chunk-ey1tsk22.js → chunk-ppzz953j.js} +1 -1
- package/dist/{chunk-7yfk9393.js → chunk-qkdcbeaw.js} +1 -1
- package/dist/chunk-qr3zcm87.js +2 -0
- package/dist/chunk-r38xq7fp.js +33 -0
- package/dist/{chunk-tqw1yean.js → chunk-rwwfzkz4.js} +1 -1
- package/dist/{chunk-rns7wjy9.js → chunk-rzda6bd6.js} +1 -1
- package/dist/{chunk-rzg9pars.js → chunk-san1eq0r.js} +2 -2
- package/dist/{chunk-eh3meyd3.js → chunk-tc4pj651.js} +2 -2
- package/dist/{chunk-6g8rvnhc.js → chunk-v6e35j4g.js} +1 -1
- package/dist/{chunk-wnmegbw0.js → chunk-v7aa7v85.js} +1 -1
- package/dist/{chunk-e6rxvz3p.js → chunk-vhg91hnw.js} +1 -1
- package/dist/{chunk-k3dtvay1.js → chunk-vhta1be7.js} +1 -1
- package/dist/{chunk-tz68qv47.js → chunk-w5j9tbsk.js} +1 -1
- package/dist/{chunk-ec18ftcg.js → chunk-wj21f1e0.js} +1 -1
- package/dist/{chunk-12qteqk8.js → chunk-ws0282jr.js} +1 -1
- package/dist/chunk-x054qzma.js +2 -0
- package/dist/{chunk-q9ckfwhh.js → chunk-xj6bcwqa.js} +1 -1
- package/dist/chunk-xq0e2y4x.js +2 -0
- package/dist/chunk-xrjx7b2v.js +2 -0
- package/dist/{chunk-ay336sqb.js → chunk-xvh1k1a4.js} +1 -1
- package/dist/{chunk-vaggjvsm.js → chunk-y2f41kaq.js} +1 -1
- package/dist/{chunk-1zav2sf1.js → chunk-y6xzr30x.js} +1 -1
- package/dist/chunk-ybx8n794.js +2 -0
- package/dist/{chunk-yefnrr5z.js → chunk-yca761bm.js} +1 -1
- package/dist/{chunk-kgbz86sa.js → chunk-yg5r7bnm.js} +2 -2
- package/dist/{chunk-kbah2k8e.js → chunk-z8wb7kbj.js} +2 -2
- package/dist/chunk-zkxnarrh.js +2 -0
- package/dist/{chunk-hzbty7hz.js → chunk-zmazqcb8.js} +1 -1
- package/dist/chunk-zp14ksx1.js +2 -0
- package/dist/chunk-zwr4bn6a.js +2 -0
- package/dist/cli.js +14 -14
- package/dist/craft-entry.js +1 -1
- package/dist/craft.js +1 -1
- package/dist/database.js +1 -1
- package/dist/expressions.d.ts +1 -1
- package/dist/expressions.js +15 -3
- package/dist/includes.js +2 -2
- package/dist/pwa.js +2 -2
- package/dist/runtime-globals.d.ts +22 -0
- package/dist/runtime-globals.js +46 -0
- package/dist/signals.js +193 -84
- package/dist/slots.js +3 -3
- package/dist/ssg.js +2 -2
- package/dist/theme-tokens.d.ts +59 -0
- package/dist/theme-tokens.js +83 -17
- package/dist/ts-css-config.js +4 -2
- package/dist/utils.d.ts +10 -0
- package/dist/utils.js +77 -12
- package/dist/variable-extractor.d.ts +1 -1
- package/dist/variable-extractor.js +23 -3
- package/dist/visual-testing.js +1 -1
- package/package.json +5 -5
- package/dist/chunk-160g7ynw.js +0 -2
- package/dist/chunk-16hr5y08.js +0 -2
- package/dist/chunk-3h97y3n3.js +0 -2
- package/dist/chunk-3j915h2d.js +0 -2
- package/dist/chunk-4hkg6kx4.js +0 -2
- package/dist/chunk-57494khk.js +0 -2
- package/dist/chunk-5xavmr4t.js +0 -2
- package/dist/chunk-6rsfkms1.js +0 -2
- package/dist/chunk-6xs80tka.js +0 -32
- package/dist/chunk-905j49fe.js +0 -2
- package/dist/chunk-9czj483k.js +0 -2
- package/dist/chunk-9kv0qavn.js +0 -2
- package/dist/chunk-bcz8yp2g.js +0 -2
- package/dist/chunk-bxefsc7k.js +0 -2
- package/dist/chunk-c4kv3r8t.js +0 -2
- package/dist/chunk-fytemc96.js +0 -2
- package/dist/chunk-g7gc0ten.js +0 -2
- package/dist/chunk-gqsxxd81.js +0 -2
- package/dist/chunk-gx9z0wmm.js +0 -2
- package/dist/chunk-jnxzzzm4.js +0 -2
- package/dist/chunk-jy6jwxhs.js +0 -2
- package/dist/chunk-khqn40gv.js +0 -2
- package/dist/chunk-mhbzrh5y.js +0 -2
- package/dist/chunk-p8anntjb.js +0 -2
- package/dist/chunk-pwe51myj.js +0 -2
- package/dist/chunk-rqqdvnp5.js +0 -2
- package/dist/chunk-w1mbrq1g.js +0 -2
- package/dist/chunk-w84qe2m6.js +0 -2
- package/dist/chunk-wjm7hv5e.js +0 -2
- package/dist/chunk-yr7s02f7.js +0 -2
- package/dist/chunk-zq3tm2c2.js +0 -2
package/dist/signals.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { state, derived, effect, batch, onMount, onDestroy, isSignal, isDerived, untrack, peek } from "./signals-api.js";
|
|
2
|
-
import { runtimeHandledXAttrsLiteral } from "./runtime-globals.js";
|
|
2
|
+
import { runtimeDirectiveNamesLiteral, runtimeEventRegexLiteral, runtimeHandledXAttrsLiteral } from "./runtime-globals.js";
|
|
3
3
|
import { createModelSignal } from "./component-model.js";
|
|
4
4
|
import { readHydratedData, clearServerData } from "./composables/use-fetch.js";
|
|
5
5
|
|
|
@@ -64,6 +64,82 @@ console.log('[stx] entering IIFE');
|
|
|
64
64
|
(function() {
|
|
65
65
|
'use strict';
|
|
66
66
|
|
|
67
|
+
// \u2500\u2500 Host \u2500\u2500
|
|
68
|
+
//
|
|
69
|
+
// The tree this runtime mutates. Every write the binding layer makes to a
|
|
70
|
+
// node goes through here, so the same runtime can drive something that is not
|
|
71
|
+
// the document -- native views over a bridge (stacksjs/stx#1984).
|
|
72
|
+
//
|
|
73
|
+
// Signals never touch a node, so nothing above this line needs to change; the
|
|
74
|
+
// coupling is entirely in the bind layer. A host is swapped in by assigning
|
|
75
|
+
// window.__stx_host before the runtime executes. The name is stxHost, not
|
|
76
|
+
// host, because the runtime already calls two local DOM nodes host -- a
|
|
77
|
+
// shadowed adapter fails as node.anchor is not a function, deep inside a
|
|
78
|
+
// branch swap, and nowhere near the line that caused it, which keeps the web path
|
|
79
|
+
// exactly as it was: same calls, one property lookup earlier.
|
|
80
|
+
var stxHost = window.__stx_host || {
|
|
81
|
+
setText: function(node, value) { node.textContent = value; },
|
|
82
|
+
setAttribute: function(node, name, value) { node.setAttribute(name, value); },
|
|
83
|
+
removeAttribute: function(node, name) { node.removeAttribute(name); },
|
|
84
|
+
|
|
85
|
+
// Structural operations, for the bindings that build rows rather than
|
|
86
|
+
// update one node (#1984).
|
|
87
|
+
//
|
|
88
|
+
// anchor() is a position in the child list that survives the nodes around
|
|
89
|
+
// it moving -- a comment node here, since the document has one; a native
|
|
90
|
+
// host keeps an index or a zero-size sentinel.
|
|
91
|
+
//
|
|
92
|
+
// clone() is the one that does not carry over as-is: a DOM subtree can be
|
|
93
|
+
// deep-copied, a native view hierarchy cannot. A native host materialises a
|
|
94
|
+
// fresh subtree from the template it was given instead of copying views,
|
|
95
|
+
// which is why the row template is passed rather than a node to duplicate.
|
|
96
|
+
// A native host registers the handler against the view and has the platform
|
|
97
|
+
// call it; nothing about the binding layer changes, which is the point.
|
|
98
|
+
// The options argument carries passive/capture/once. A native host has no use for
|
|
99
|
+
// passive -- there is no scroll thread to block -- but dropping the
|
|
100
|
+
// parameter silently makes every touch listener blocking again, so it stays
|
|
101
|
+
// in the signature and each host decides what to do with it.
|
|
102
|
+
listen: function(node, event, handler, options) { node.addEventListener(event, handler, options); },
|
|
103
|
+
|
|
104
|
+
// Returns the PREVIOUS visibility. bindShow needs to know whether it just
|
|
105
|
+
// revealed something, and asking the node afterwards is the one read-back
|
|
106
|
+
// in the binding layer -- a native host cannot answer what a UIView's
|
|
107
|
+
// display value was, because it has none. A write that reports what it
|
|
108
|
+
// replaced removes the question: the DOM host reads its own style, a native
|
|
109
|
+
// host reads isHidden, and the binder reads neither.
|
|
110
|
+
//
|
|
111
|
+
// Restoring an explicit display (a flex row, an inline-block) is the host's
|
|
112
|
+
// business too; it records it the first time it hides the node.
|
|
113
|
+
// The scope root a node belongs to: nearest ancestor-or-self that owns a
|
|
114
|
+
// scope, or null. Three binding paths need it -- ref ownership, and an
|
|
115
|
+
// if-chain finding the scope its branch belongs to.
|
|
116
|
+
//
|
|
117
|
+
// Not a query method. A host is never handed a selector, because a native
|
|
118
|
+
// view tree has nothing to match one against: the DOM host walks with
|
|
119
|
+
// closest(), a native host reads the node-to-scope map it maintains as it
|
|
120
|
+
// creates views. The from flag skips the node itself, which the ref path needs
|
|
121
|
+
// when it walks outward past a receiver it has already rejected.
|
|
122
|
+
scopeOf: function(node, from) {
|
|
123
|
+
var start = from ? (node && node.parentElement) : node;
|
|
124
|
+
return (start && start.closest) ? start.closest('[data-stx-scope]') : null;
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
setVisible: function(node, visible) {
|
|
128
|
+
if (node.__stx_display === undefined) {
|
|
129
|
+
var d = node.style.display;
|
|
130
|
+
node.__stx_display = (d && d !== 'none') ? d : '';
|
|
131
|
+
}
|
|
132
|
+
var was = node.style.display !== 'none';
|
|
133
|
+
node.style.display = visible ? node.__stx_display : 'none';
|
|
134
|
+
return was;
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
anchor: function(label) { return document.createComment(label); },
|
|
138
|
+
clone: function(node) { return node.cloneNode(true); },
|
|
139
|
+
insert: function(parent, node, before) { parent.insertBefore(node, before); },
|
|
140
|
+
remove: function(node) { if (node.parentNode) node.parentNode.removeChild(node); }
|
|
141
|
+
};
|
|
142
|
+
|
|
67
143
|
// Inject x-cloak CSS to prevent FOUC (Flash of Unstyled Content)
|
|
68
144
|
// Elements with x-cloak are hidden until the runtime removes the attribute after mount
|
|
69
145
|
var cloakStyle = document.getElementById ? document.getElementById('stx-cloak-style') : null;
|
|
@@ -2572,7 +2648,41 @@ catch (e) {
|
|
|
2572
2648
|
return scripts;
|
|
2573
2649
|
}
|
|
2574
2650
|
|
|
2575
|
-
|
|
2651
|
+
/**
|
|
2652
|
+
* Bind what the server said carries a binding, instead of looking for it.
|
|
2653
|
+
*
|
|
2654
|
+
* The walk exists because the runtime does not know where the bindings are.
|
|
2655
|
+
* The server does -- it rendered them -- so when it ships that list the
|
|
2656
|
+
* runtime stops searching: resolve each id, bind that element, never touch
|
|
2657
|
+
* its children. An element with no bindings is never visited at all.
|
|
2658
|
+
*
|
|
2659
|
+
* This is the piece a native host needs. A view hierarchy has no attributes
|
|
2660
|
+
* to read and no selector to match, so discovery cannot happen there; handed
|
|
2661
|
+
* the list, it does not have to. On the DOM the ids resolve by attribute,
|
|
2662
|
+
* which is one query per entry rather than a full traversal.
|
|
2663
|
+
*
|
|
2664
|
+
* Absent a manifest nothing changes: the walk is still the default, and a
|
|
2665
|
+
* page that ships no list hydrates exactly as it did.
|
|
2666
|
+
*/
|
|
2667
|
+
function processFromManifest(root, scope, manifest) {
|
|
2668
|
+
if (!root || !manifest || !manifest.length) return false;
|
|
2669
|
+
for (var i = 0; i < manifest.length; i++) {
|
|
2670
|
+
var entry = manifest[i];
|
|
2671
|
+
var id = entry && entry.id;
|
|
2672
|
+
if (id === undefined || id === null) continue;
|
|
2673
|
+
var node = root.getAttribute && root.getAttribute('data-stx-b') === String(id)
|
|
2674
|
+
? root
|
|
2675
|
+
: (root.querySelector ? root.querySelector('[data-stx-b="' + id + '"]') : null);
|
|
2676
|
+
if (!node) continue;
|
|
2677
|
+
processElement(node, scope, true);
|
|
2678
|
+
}
|
|
2679
|
+
return true;
|
|
2680
|
+
}
|
|
2681
|
+
|
|
2682
|
+
// skipChildren: this element's bindings only, because something else already
|
|
2683
|
+
// knows where the rest are. The manifest path passes it for every entry, so
|
|
2684
|
+
// the tree is never walked; see processFromManifest.
|
|
2685
|
+
function processElement(el, scope = componentScope, skipChildren) {
|
|
2576
2686
|
// Lazy hydration: if this element has stx-hydrate and hasn't been hydrated
|
|
2577
2687
|
// yet, defer its subtree processing until the trigger fires.
|
|
2578
2688
|
if (el.nodeType === Node.ELEMENT_NODE && el.hasAttribute && el.hasAttribute('stx-hydrate') && !el.__stx_hydrated) {
|
|
@@ -2818,7 +2928,7 @@ catch (e2) {
|
|
|
2818
2928
|
};
|
|
2819
2929
|
|
|
2820
2930
|
// Known directive names to exclude from generic :attr binding
|
|
2821
|
-
var DIRECTIVE_NAMES = {
|
|
2931
|
+
var DIRECTIVE_NAMES = ${runtimeDirectiveNamesLiteral()};
|
|
2822
2932
|
|
|
2823
2933
|
// A bound value cannot introduce a URL scheme the page did not ask for.
|
|
2824
2934
|
// This is the client half of url-safety.ts: the server refuses a scheme
|
|
@@ -2853,7 +2963,7 @@ catch (e2) {
|
|
|
2853
2963
|
// a dead duplicate attribute and the real viewBox never updates.
|
|
2854
2964
|
var SVG_ATTR_CASE = {attributename:'attributeName', attributetype:'attributeType', basefrequency:'baseFrequency', baseprofile:'baseProfile', calcmode:'calcMode', clippathunits:'clipPathUnits', diffuseconstant:'diffuseConstant', edgemode:'edgeMode', filterunits:'filterUnits', glyphref:'glyphRef', gradienttransform:'gradientTransform', gradientunits:'gradientUnits', kernelmatrix:'kernelMatrix', kernelunitlength:'kernelUnitLength', keypoints:'keyPoints', keysplines:'keySplines', keytimes:'keyTimes', lengthadjust:'lengthAdjust', limitingconeangle:'limitingConeAngle', markerheight:'markerHeight', markerunits:'markerUnits', markerwidth:'markerWidth', maskcontentunits:'maskContentUnits', maskunits:'maskUnits', numoctaves:'numOctaves', pathlength:'pathLength', patterncontentunits:'patternContentUnits', patterntransform:'patternTransform', patternunits:'patternUnits', pointsatx:'pointsAtX', pointsaty:'pointsAtY', pointsatz:'pointsAtZ', preservealpha:'preserveAlpha', preserveaspectratio:'preserveAspectRatio', primitiveunits:'primitiveUnits', refx:'refX', refy:'refY', repeatcount:'repeatCount', repeatdur:'repeatDur', requiredextensions:'requiredExtensions', requiredfeatures:'requiredFeatures', specularconstant:'specularConstant', specularexponent:'specularExponent', spreadmethod:'spreadMethod', startoffset:'startOffset', stddeviation:'stdDeviation', stitchtiles:'stitchTiles', surfacescale:'surfaceScale', systemlanguage:'systemLanguage', tablevalues:'tableValues', targetx:'targetX', targety:'targetY', textlength:'textLength', viewbox:'viewBox', viewtarget:'viewTarget', xchannelselector:'xChannelSelector', ychannelselector:'yChannelSelector', zoomandpan:'zoomAndPan'};
|
|
2855
2965
|
var SVG_NS = 'http://www.w3.org/2000/svg';
|
|
2856
|
-
var EVENT_RE =
|
|
2966
|
+
var EVENT_RE = ${runtimeEventRegexLiteral()};
|
|
2857
2967
|
var KEY_MAP = {enter:'Enter', tab:'Tab', escape:'Escape', space:' ', up:'ArrowUp', down:'ArrowDown', left:'ArrowLeft', right:'ArrowRight', 'delete':'Delete', backspace:'Backspace'};
|
|
2858
2968
|
|
|
2859
2969
|
// Handle attributes
|
|
@@ -2942,7 +3052,7 @@ catch (e2) {
|
|
|
2942
3052
|
el.setAttribute(attrName, String(v));
|
|
2943
3053
|
}
|
|
2944
3054
|
else if (v === false || v === null || v === undefined) {
|
|
2945
|
-
|
|
3055
|
+
stxHost.removeAttribute(el, attrName);
|
|
2946
3056
|
}
|
|
2947
3057
|
else if (v === true) {
|
|
2948
3058
|
el.setAttribute(attrName, '');
|
|
@@ -2953,7 +3063,7 @@ else {
|
|
|
2953
3063
|
try { attrValue = JSON.stringify(v); }
|
|
2954
3064
|
catch (e) { attrValue = String(v); }
|
|
2955
3065
|
}
|
|
2956
|
-
|
|
3066
|
+
stxHost.setAttribute(el, attrName, safeUrlAttr(attrName, attrValue));
|
|
2957
3067
|
}
|
|
2958
3068
|
});
|
|
2959
3069
|
el.removeAttribute(name);
|
|
@@ -2968,7 +3078,7 @@ else if (name === '@style' || name === ':style' || name === 'x-style') {
|
|
|
2968
3078
|
}
|
|
2969
3079
|
else if (name === '@text' || name === ':text' || name === 'x-text') {
|
|
2970
3080
|
effect(() => {
|
|
2971
|
-
el
|
|
3081
|
+
stxHost.setText(el, evalAttrExpr(value));
|
|
2972
3082
|
});
|
|
2973
3083
|
el.removeAttribute(name);
|
|
2974
3084
|
}
|
|
@@ -2984,14 +3094,14 @@ else if (name === 'ref' || name === ':ref' || name === 'x-ref' || name === 'data
|
|
|
2984
3094
|
// A page ref can be projected through a component whose own $refs
|
|
2985
3095
|
// replaced the compatibility scope's map. The compiler retains the
|
|
2986
3096
|
// receiver boundary so named and signal refs use the same caller.
|
|
2987
|
-
var refRoot =
|
|
3097
|
+
var refRoot = stxHost.scopeOf(el);
|
|
2988
3098
|
var refCaller = el.getAttribute('data-stx-ref-caller');
|
|
2989
3099
|
var refOwnerScope = findElementScope(el);
|
|
2990
3100
|
if (refCaller) {
|
|
2991
3101
|
var receiver = refRoot;
|
|
2992
3102
|
while (receiver && receiver.getAttribute('data-stx-scope') !== refCaller
|
|
2993
3103
|
&& receiver.getAttribute('data-stx-template-scope') !== refCaller) {
|
|
2994
|
-
receiver = receiver
|
|
3104
|
+
receiver = stxHost.scopeOf(receiver, true);
|
|
2995
3105
|
}
|
|
2996
3106
|
refOwnerScope = receiver && receiver.__stx_parent_scope;
|
|
2997
3107
|
}
|
|
@@ -3042,7 +3152,7 @@ else if (name === 'ref' || name === ':ref' || name === 'x-ref' || name === 'data
|
|
|
3042
3152
|
? { ...globalHelpers, ...el.__stx_parent_scope }
|
|
3043
3153
|
: { ...globalHelpers, ...scope, ...(findElementScope(el) || {}) };
|
|
3044
3154
|
|
|
3045
|
-
|
|
3155
|
+
stxHost.listen(el, eventName, (event) => {
|
|
3046
3156
|
// Vue-style component listeners fall through to the rendered native
|
|
3047
3157
|
// root unless the child emits the same event. Signal components use
|
|
3048
3158
|
// a scope wrapper, so native events arrive here from a descendant.
|
|
@@ -3165,7 +3275,7 @@ catch (e) {
|
|
|
3165
3275
|
|
|
3166
3276
|
// Process children (skip script/style elements \u2014 their text content is not template markup)
|
|
3167
3277
|
// Skip elements that are roots of nested stx.mount() components \u2014 those have their own scope
|
|
3168
|
-
if (el.tagName !== 'SCRIPT' && el.tagName !== 'STYLE') {
|
|
3278
|
+
if (!skipChildren && el.tagName !== 'SCRIPT' && el.tagName !== 'STYLE') {
|
|
3169
3279
|
var children = Array.from(el.childNodes);
|
|
3170
3280
|
children.forEach(function(child) {
|
|
3171
3281
|
if (child.nodeType !== Node.ELEMENT_NODE) { processElement(child, scope); return; }
|
|
@@ -3243,8 +3353,6 @@ catch (e) {
|
|
|
3243
3353
|
if (el.__stx_show_bound) return;
|
|
3244
3354
|
el.__stx_show_bound = true;
|
|
3245
3355
|
|
|
3246
|
-
const currentDisplay = el.style.display;
|
|
3247
|
-
const originalDisplay = (currentDisplay && currentDisplay !== 'none') ? currentDisplay : '';
|
|
3248
3356
|
const capturedScope = { ...globalHelpers, ...passedScope, ...(findElementScope(el) || {}) };
|
|
3249
3357
|
|
|
3250
3358
|
// Check if the expression is a simple signal reference (most common case for :show)
|
|
@@ -3254,7 +3362,7 @@ catch (e) {
|
|
|
3254
3362
|
effect(() => {
|
|
3255
3363
|
const value = directSignal();
|
|
3256
3364
|
|
|
3257
|
-
el
|
|
3365
|
+
stxHost.setVisible(el, !!value);
|
|
3258
3366
|
});
|
|
3259
3367
|
} else {
|
|
3260
3368
|
// Complex expression path \u2014 use createAutoUnwrapProxy with fallback,
|
|
@@ -3279,16 +3387,15 @@ catch (e) {
|
|
|
3279
3387
|
// or object may not be ready yet on the first effect run, and
|
|
3280
3388
|
// the next pass will re-evaluate once data arrives.
|
|
3281
3389
|
if (!(e2 instanceof ReferenceError) && !(e2 instanceof TypeError)) console.warn('[STX] Show expression error:', expr, e2);
|
|
3282
|
-
el
|
|
3390
|
+
stxHost.setVisible(el, false);
|
|
3283
3391
|
return;
|
|
3284
3392
|
}
|
|
3285
3393
|
}
|
|
3286
|
-
var
|
|
3287
|
-
el.style.display = value ? originalDisplay : 'none';
|
|
3394
|
+
var wasVisible = stxHost.setVisible(el, !!value);
|
|
3288
3395
|
// When transitioning from hidden to visible, stamp the element so
|
|
3289
3396
|
// @click handlers can ignore clicks from the same frame (prevents
|
|
3290
3397
|
// modal backdrop from catching the click that opened the modal)
|
|
3291
|
-
if (value &&
|
|
3398
|
+
if (value && !wasVisible) {
|
|
3292
3399
|
el.__stx_shown_at = performance.now();
|
|
3293
3400
|
}
|
|
3294
3401
|
});
|
|
@@ -3365,7 +3472,7 @@ catch (e) {
|
|
|
3365
3472
|
};
|
|
3366
3473
|
el.__stx_model_sync = syncCheckbox;
|
|
3367
3474
|
effect(syncCheckbox);
|
|
3368
|
-
|
|
3475
|
+
stxHost.listen(el, 'change', () => {
|
|
3369
3476
|
var current = getValue();
|
|
3370
3477
|
if (!Array.isArray(current)) {
|
|
3371
3478
|
setValue(el.checked);
|
|
@@ -3382,7 +3489,7 @@ catch (e) {
|
|
|
3382
3489
|
var syncRadio = () => { el.checked = String(getValue()) === String(el.value); };
|
|
3383
3490
|
el.__stx_model_sync = syncRadio;
|
|
3384
3491
|
effect(syncRadio);
|
|
3385
|
-
|
|
3492
|
+
stxHost.listen(el, 'change', () => {
|
|
3386
3493
|
if (el.checked) setValue(coerceValue(el.value));
|
|
3387
3494
|
});
|
|
3388
3495
|
}
|
|
@@ -3408,7 +3515,7 @@ catch (e) {
|
|
|
3408
3515
|
el.__stx_model_observer = null;
|
|
3409
3516
|
});
|
|
3410
3517
|
}
|
|
3411
|
-
|
|
3518
|
+
stxHost.listen(el, 'change', () => setValue(coerceValue(el.value)));
|
|
3412
3519
|
}
|
|
3413
3520
|
else {
|
|
3414
3521
|
// Writing el.value moves the text cursor to the END of the control, and
|
|
@@ -3446,7 +3553,7 @@ else {
|
|
|
3446
3553
|
catch (e) { /* type does not support selection */ }
|
|
3447
3554
|
}
|
|
3448
3555
|
});
|
|
3449
|
-
|
|
3556
|
+
stxHost.listen(el, modifiers.includes('lazy') ? 'change' : 'input', () => setValue(coerceValue(el.value)));
|
|
3450
3557
|
}
|
|
3451
3558
|
|
|
3452
3559
|
el.removeAttribute(attrName);
|
|
@@ -3854,7 +3961,7 @@ else if (typeof value === 'string') {
|
|
|
3854
3961
|
return;
|
|
3855
3962
|
}
|
|
3856
3963
|
|
|
3857
|
-
const placeholder =
|
|
3964
|
+
const placeholder = stxHost.anchor('stx-for');
|
|
3858
3965
|
const isTemplate = el.tagName === 'TEMPLATE';
|
|
3859
3966
|
const componentSetupTemplates = [];
|
|
3860
3967
|
if (!isTemplate && el.hasAttribute('data-stx-scope')) {
|
|
@@ -3876,8 +3983,8 @@ else if (typeof value === 'string') {
|
|
|
3876
3983
|
&& setupSibling.hasAttribute('data-stx-scoped')
|
|
3877
3984
|
&& ((setupSibling.textContent || '').indexOf(componentScopeId) !== -1
|
|
3878
3985
|
|| (componentTemplateScopeId && (setupSibling.textContent || '').indexOf(componentTemplateScopeId) !== -1))) {
|
|
3879
|
-
componentSetupTemplates.push(
|
|
3880
|
-
|
|
3986
|
+
componentSetupTemplates.push(stxHost.clone(setupSibling));
|
|
3987
|
+
stxHost.remove(setupSibling);
|
|
3881
3988
|
setupSibling = nextSetupSibling;
|
|
3882
3989
|
continue;
|
|
3883
3990
|
}
|
|
@@ -3900,16 +4007,16 @@ else if (typeof value === 'string') {
|
|
|
3900
4007
|
let sibling = el.nextElementSibling;
|
|
3901
4008
|
while (sibling) {
|
|
3902
4009
|
if (sibling.hasAttribute('@for-loading')) {
|
|
3903
|
-
loadingTemplate =
|
|
4010
|
+
loadingTemplate = stxHost.clone(sibling);
|
|
3904
4011
|
loadingTemplate.removeAttribute('@for-loading');
|
|
3905
|
-
|
|
4012
|
+
stxHost.remove(sibling);
|
|
3906
4013
|
sibling = el.nextElementSibling;
|
|
3907
4014
|
continue;
|
|
3908
4015
|
}
|
|
3909
4016
|
if (sibling.hasAttribute('@for-empty')) {
|
|
3910
|
-
emptyTemplate =
|
|
4017
|
+
emptyTemplate = stxHost.clone(sibling);
|
|
3911
4018
|
emptyTemplate.removeAttribute('@for-empty');
|
|
3912
|
-
|
|
4019
|
+
stxHost.remove(sibling);
|
|
3913
4020
|
sibling = el.nextElementSibling;
|
|
3914
4021
|
continue;
|
|
3915
4022
|
}
|
|
@@ -3919,13 +4026,13 @@ else if (typeof value === 'string') {
|
|
|
3919
4026
|
// Capture the scope NOW before element is removed from DOM
|
|
3920
4027
|
const capturedScope = findElementScope(el) || findElementScope(parent);
|
|
3921
4028
|
|
|
3922
|
-
|
|
4029
|
+
stxHost.insert(parent, placeholder, el);
|
|
3923
4030
|
// Component setup scripts execute while the server-rendered loop source is
|
|
3924
4031
|
// still in the document. That source becomes a template, not a live
|
|
3925
4032
|
// instance, so reclaim all registered scopes before removing it. Every
|
|
3926
4033
|
// rendered iteration receives remapped setup scripts and fresh scopes.
|
|
3927
4034
|
disposeSubtreeScopes(el);
|
|
3928
|
-
|
|
4035
|
+
stxHost.remove(el);
|
|
3929
4036
|
|
|
3930
4037
|
// Capture :key expression BEFORE removing the attribute
|
|
3931
4038
|
const keyExpr = el.getAttribute(':key') || el.getAttribute('x-bind:key');
|
|
@@ -3936,7 +4043,7 @@ else if (typeof value === 'string') {
|
|
|
3936
4043
|
templateContent = el.content;
|
|
3937
4044
|
}
|
|
3938
4045
|
else {
|
|
3939
|
-
const wrapper =
|
|
4046
|
+
const wrapper = stxHost.clone(el);
|
|
3940
4047
|
wrapper.removeAttribute('@for');
|
|
3941
4048
|
wrapper.removeAttribute(':for');
|
|
3942
4049
|
wrapper.removeAttribute('x-for');
|
|
@@ -3989,12 +4096,12 @@ else {
|
|
|
3989
4096
|
const removeGroup = (group) => {
|
|
3990
4097
|
const liveNodes = liveGroupNodes(group);
|
|
3991
4098
|
const liveSet = new Set(liveNodes);
|
|
3992
|
-
liveNodes.forEach(e => { disposeSubtreeEffects(e); disposeSubtreeScopes(e);
|
|
4099
|
+
liveNodes.forEach(e => { disposeSubtreeEffects(e); disposeSubtreeScopes(e); stxHost.remove(e); });
|
|
3993
4100
|
group.forEach(groupNode => {
|
|
3994
4101
|
if (liveSet.has(groupNode)) return;
|
|
3995
4102
|
disposeSubtreeEffects(groupNode);
|
|
3996
4103
|
disposeSubtreeScopes(groupNode);
|
|
3997
|
-
|
|
4104
|
+
stxHost.remove(groupNode);
|
|
3998
4105
|
});
|
|
3999
4106
|
};
|
|
4000
4107
|
|
|
@@ -4057,15 +4164,15 @@ catch (e) {
|
|
|
4057
4164
|
hideLoading();
|
|
4058
4165
|
hideEmpty();
|
|
4059
4166
|
if (loadingTemplate) {
|
|
4060
|
-
loadingElement =
|
|
4061
|
-
|
|
4167
|
+
loadingElement = stxHost.clone(loadingTemplate);
|
|
4168
|
+
stxHost.insert(parent, loadingElement, placeholder);
|
|
4062
4169
|
}
|
|
4063
4170
|
};
|
|
4064
4171
|
|
|
4065
4172
|
// Helper to hide loading state
|
|
4066
4173
|
const hideLoading = () => {
|
|
4067
4174
|
if (loadingElement) {
|
|
4068
|
-
|
|
4175
|
+
stxHost.remove(loadingElement);
|
|
4069
4176
|
loadingElement = null;
|
|
4070
4177
|
}
|
|
4071
4178
|
};
|
|
@@ -4075,8 +4182,8 @@ catch (e) {
|
|
|
4075
4182
|
hideLoading();
|
|
4076
4183
|
hideEmpty();
|
|
4077
4184
|
if (emptyTemplate) {
|
|
4078
|
-
emptyElement =
|
|
4079
|
-
|
|
4185
|
+
emptyElement = stxHost.clone(emptyTemplate);
|
|
4186
|
+
stxHost.insert(parent, emptyElement, placeholder);
|
|
4080
4187
|
const shownEmpty = emptyElement;
|
|
4081
4188
|
shownEmpty.__stx_effect_disposers = trackEffects(function() { processElement(shownEmpty); });
|
|
4082
4189
|
}
|
|
@@ -4087,7 +4194,7 @@ catch (e) {
|
|
|
4087
4194
|
if (emptyElement) {
|
|
4088
4195
|
// A string @empty renders a text node, which has no subtree to dispose.
|
|
4089
4196
|
if (emptyElement.nodeType === 1) disposeSubtreeEffects(emptyElement);
|
|
4090
|
-
|
|
4197
|
+
stxHost.remove(emptyElement);
|
|
4091
4198
|
emptyElement = null;
|
|
4092
4199
|
}
|
|
4093
4200
|
};
|
|
@@ -4109,9 +4216,9 @@ catch (e) {
|
|
|
4109
4216
|
|
|
4110
4217
|
const elements = [];
|
|
4111
4218
|
if (isTemplate) {
|
|
4112
|
-
elements.push(
|
|
4219
|
+
elements.push(stxHost.anchor('stx-for-item-start'));
|
|
4113
4220
|
Array.from(templateContent.childNodes).forEach(node => {
|
|
4114
|
-
const clone =
|
|
4221
|
+
const clone = stxHost.clone(node);
|
|
4115
4222
|
if (clone.nodeType === 1) {
|
|
4116
4223
|
// Structural directives need a live parent. Keep the iteration
|
|
4117
4224
|
// scope on the clone until the keyed diff inserts it, then bind.
|
|
@@ -4119,13 +4226,13 @@ catch (e) {
|
|
|
4119
4226
|
}
|
|
4120
4227
|
elements.push(clone);
|
|
4121
4228
|
});
|
|
4122
|
-
elements.push(
|
|
4229
|
+
elements.push(stxHost.anchor('stx-for-item-end'));
|
|
4123
4230
|
} else {
|
|
4124
|
-
const clone =
|
|
4231
|
+
const clone = stxHost.clone(templateContent);
|
|
4125
4232
|
clone.__stx_for_scope = itemScope;
|
|
4126
4233
|
elements.push(clone);
|
|
4127
4234
|
componentSetupTemplates.forEach(function(setupTemplate) {
|
|
4128
|
-
elements.push(
|
|
4235
|
+
elements.push(stxHost.clone(setupTemplate));
|
|
4129
4236
|
});
|
|
4130
4237
|
}
|
|
4131
4238
|
remapForComponentScopes(elements);
|
|
@@ -4251,7 +4358,7 @@ catch (e) {
|
|
|
4251
4358
|
hideEmpty();
|
|
4252
4359
|
if (emptyContent && typeof emptyContent === 'string') {
|
|
4253
4360
|
emptyElement = document.createTextNode(emptyContent);
|
|
4254
|
-
|
|
4361
|
+
stxHost.insert(parent, emptyElement, placeholder);
|
|
4255
4362
|
}
|
|
4256
4363
|
} else if (emptyTemplate) {
|
|
4257
4364
|
showEmpty();
|
|
@@ -4345,7 +4452,7 @@ catch (e) {
|
|
|
4345
4452
|
// Moves without detaching. The cursor does not advance: this node
|
|
4346
4453
|
// is now behind it, and the cursor still marks the next position
|
|
4347
4454
|
// to fill.
|
|
4348
|
-
|
|
4455
|
+
stxHost.insert(parent, groupNode, cursor || placeholder);
|
|
4349
4456
|
}
|
|
4350
4457
|
}
|
|
4351
4458
|
newElements.push(...group);
|
|
@@ -4365,7 +4472,7 @@ catch (e) {
|
|
|
4365
4472
|
// Before the cursor, not before the placeholder: a new row inserted
|
|
4366
4473
|
// in the MIDDLE of the list must land at its own position, without
|
|
4367
4474
|
// forcing every row after it to be moved to get back in order.
|
|
4368
|
-
|
|
4475
|
+
stxHost.insert(parent, el, cursor || placeholder);
|
|
4369
4476
|
if (tgReady && el.isConnected) tgEnter(el, tgName);
|
|
4370
4477
|
});
|
|
4371
4478
|
hydrateComponentScopes(elements, elements.find(function(node) {
|
|
@@ -4409,13 +4516,13 @@ catch (e) {
|
|
|
4409
4516
|
disposeSubtreeEffects(el);
|
|
4410
4517
|
disposeSubtreeScopes(el);
|
|
4411
4518
|
if (tgLeave(el, tgName)) transitioned.add(el);
|
|
4412
|
-
else
|
|
4519
|
+
else stxHost.remove(el);
|
|
4413
4520
|
});
|
|
4414
4521
|
group.forEach((el) => {
|
|
4415
4522
|
if (transitioned.has(el) || liveNodes.includes(el)) return;
|
|
4416
4523
|
disposeSubtreeEffects(el);
|
|
4417
4524
|
disposeSubtreeScopes(el);
|
|
4418
|
-
|
|
4525
|
+
stxHost.remove(el);
|
|
4419
4526
|
});
|
|
4420
4527
|
}
|
|
4421
4528
|
else {
|
|
@@ -4505,8 +4612,8 @@ catch (e) {
|
|
|
4505
4612
|
b.el.__stx_chain_member = true;
|
|
4506
4613
|
b.el.__stx_chain_active = false;
|
|
4507
4614
|
b.capturedElementScope = findElementScope(b.el);
|
|
4508
|
-
b.placeholder =
|
|
4509
|
-
|
|
4615
|
+
b.placeholder = stxHost.anchor('stx-if-chain');
|
|
4616
|
+
stxHost.insert(parent, b.placeholder, b.el);
|
|
4510
4617
|
b.el.removeAttribute(b.attr);
|
|
4511
4618
|
// A <template> branch (the wrapper convertSignalDirectivesToAttributes
|
|
4512
4619
|
// emits for a multi-child / text branch) is INERT \u2014 inserting the element
|
|
@@ -4535,10 +4642,10 @@ catch (e) {
|
|
|
4535
4642
|
// and the attributes it consumed (x-model, :id) do not come back -- so a
|
|
4536
4643
|
// second clone taken from the element would arrive already stripped, with
|
|
4537
4644
|
// no binding and no way to acquire one.
|
|
4538
|
-
b.pristine = b.isTemplate ? b.el.content
|
|
4645
|
+
b.pristine = b.isTemplate ? stxHost.clone(b.el.content) : null;
|
|
4539
4646
|
b.nodes = b.isTemplate ? [] : [b.el];
|
|
4540
4647
|
b.endMarker = null;
|
|
4541
|
-
b.el
|
|
4648
|
+
stxHost.remove(b.el);
|
|
4542
4649
|
b.childrenProcessed = false;
|
|
4543
4650
|
});
|
|
4544
4651
|
|
|
@@ -4602,7 +4709,7 @@ catch (e2) {
|
|
|
4602
4709
|
console.log('[stx] bindIfChain pick:', pickedIdx, 'of', chain.length, '(', pickedIdx >= 0 ? chain[pickedIdx].attr : 'none', ') prev:', currentIdx);
|
|
4603
4710
|
if (__stxDevtoolsTracking) {
|
|
4604
4711
|
var __ifScope = null;
|
|
4605
|
-
try { __ifScope = (head
|
|
4712
|
+
try { __ifScope = stxHost.scopeOf(head); } catch (e) { __ifScope = null; }
|
|
4606
4713
|
__stxDevtoolsRecordIf({
|
|
4607
4714
|
scopeId: __ifScope ? __ifScope.getAttribute('data-stx-scope') : null,
|
|
4608
4715
|
branches: chain.map(function(c) { return c.attr; }),
|
|
@@ -4630,21 +4737,20 @@ catch (e2) {
|
|
|
4630
4737
|
// contains. The marker bounds the range, so a sibling that belongs to
|
|
4631
4738
|
// a later branch or to ordinary markup is never touched.
|
|
4632
4739
|
if (gone.endMarker && gone.endMarker.parentNode) {
|
|
4633
|
-
var host = gone.endMarker.parentNode;
|
|
4634
4740
|
var doomed = gone.placeholder.nextSibling;
|
|
4635
4741
|
while (doomed && doomed !== gone.endMarker) {
|
|
4636
4742
|
var nextDoomed = doomed.nextSibling;
|
|
4637
4743
|
disposeSubtreeEffects(doomed);
|
|
4638
|
-
|
|
4744
|
+
stxHost.remove(doomed);
|
|
4639
4745
|
doomed = nextDoomed;
|
|
4640
4746
|
}
|
|
4641
|
-
gone.endMarker
|
|
4747
|
+
stxHost.remove(gone.endMarker);
|
|
4642
4748
|
gone.endMarker = null;
|
|
4643
4749
|
}
|
|
4644
4750
|
gone.nodes.forEach(function (n) {
|
|
4645
4751
|
if (!n.parentNode) return;
|
|
4646
4752
|
disposeSubtreeEffects(n);
|
|
4647
|
-
|
|
4753
|
+
stxHost.remove(n);
|
|
4648
4754
|
});
|
|
4649
4755
|
// The next show clones afresh and processes again, so these effects
|
|
4650
4756
|
// are finished with; leaving them bound only accumulates work (#1954).
|
|
@@ -4662,10 +4768,10 @@ catch (e) { /* a disposer of its own is not this branch's problem */ }
|
|
|
4662
4768
|
// Detached nodes are out of reach of a DOM walk, so a row removed
|
|
4663
4769
|
// while this branch is hidden could not dispose the effects it was
|
|
4664
4770
|
// processed with (#1954). Same registry the single-element :if uses.
|
|
4665
|
-
var
|
|
4666
|
-
if (!
|
|
4667
|
-
|
|
4668
|
-
|
|
4771
|
+
var parentEl = n.parentNode;
|
|
4772
|
+
if (!parentEl.__stx_detached_if) parentEl.__stx_detached_if = new Set();
|
|
4773
|
+
parentEl.__stx_detached_if.add(n);
|
|
4774
|
+
stxHost.remove(n);
|
|
4669
4775
|
});
|
|
4670
4776
|
}
|
|
4671
4777
|
}
|
|
@@ -4679,16 +4785,16 @@ catch (e) { /* a disposer of its own is not this branch's problem */ }
|
|
|
4679
4785
|
var anchor = pick.placeholder.nextSibling;
|
|
4680
4786
|
var pickHost = pick.placeholder.parentNode;
|
|
4681
4787
|
if (pick.isTemplate && pick.nodes.length === 0)
|
|
4682
|
-
pick.nodes = Array.prototype.slice.call(pick.pristine
|
|
4788
|
+
pick.nodes = Array.prototype.slice.call(stxHost.clone(pick.pristine).childNodes);
|
|
4683
4789
|
pick.nodes.forEach(function (n) {
|
|
4684
4790
|
if (pickHost.__stx_detached_if) pickHost.__stx_detached_if.delete(n);
|
|
4685
|
-
|
|
4791
|
+
stxHost.insert(pickHost, n, anchor);
|
|
4686
4792
|
});
|
|
4687
4793
|
// Bound AFTER the clones, so hiding can remove whatever a structural
|
|
4688
4794
|
// directive inside the branch renders as their sibling.
|
|
4689
4795
|
if (pick.isTemplate) {
|
|
4690
|
-
if (!pick.endMarker) pick.endMarker =
|
|
4691
|
-
|
|
4796
|
+
if (!pick.endMarker) pick.endMarker = stxHost.anchor('stx-if-chain-end');
|
|
4797
|
+
stxHost.insert(pickHost, pick.endMarker, anchor);
|
|
4692
4798
|
}
|
|
4693
4799
|
pick.el.__stx_shown_at = performance.now();
|
|
4694
4800
|
if (!pick.childrenProcessed) {
|
|
@@ -4751,7 +4857,7 @@ catch (e) { /* a disposer of its own is not this branch's problem */ }
|
|
|
4751
4857
|
return;
|
|
4752
4858
|
}
|
|
4753
4859
|
|
|
4754
|
-
const placeholder =
|
|
4860
|
+
const placeholder = stxHost.anchor('stx-if');
|
|
4755
4861
|
// Marks where this branch's rendered content ENDS (stacksjs/stx#1955).
|
|
4756
4862
|
// Hiding used to remove only the cloned nodes, but a structural directive
|
|
4757
4863
|
// directly inside the template renders its own output as siblings that are
|
|
@@ -4773,27 +4879,27 @@ catch (e) { /* a disposer of its own is not this branch's problem */ }
|
|
|
4773
4879
|
const capturedComponentScope = { ...passedScope };
|
|
4774
4880
|
|
|
4775
4881
|
preserveConditionalComponentScopes(el, capturedComponentScope);
|
|
4776
|
-
|
|
4882
|
+
stxHost.insert(parent, placeholder, el);
|
|
4777
4883
|
el.removeAttribute(attrName);
|
|
4778
4884
|
|
|
4779
4885
|
if (isTemplate) {
|
|
4780
4886
|
// For templates, we need to handle the content fragment
|
|
4781
4887
|
const content = el.content;
|
|
4782
|
-
currentNodes = Array.from(content.childNodes).map(n =>
|
|
4888
|
+
currentNodes = Array.from(content.childNodes).map(n => stxHost.clone(n));
|
|
4783
4889
|
// Insert cloned content initially
|
|
4784
4890
|
// Capture the anchor once. Re-reading placeholder.nextSibling after
|
|
4785
4891
|
// every insertion points at the node just inserted and reverses a
|
|
4786
4892
|
// multi-root template branch.
|
|
4787
4893
|
const initialAnchor = placeholder.nextSibling;
|
|
4788
|
-
currentNodes.forEach(node =>
|
|
4894
|
+
currentNodes.forEach(node => stxHost.insert(parent, node, initialAnchor));
|
|
4789
4895
|
// The end of this branch's range, bound at the same time as the content
|
|
4790
4896
|
// it closes (#1955). Needed here too, not only on re-show: the first
|
|
4791
4897
|
// hide of a branch that was never toggled removes THIS content, and a
|
|
4792
4898
|
// nested :for renders rows that are siblings of these clones rather than
|
|
4793
4899
|
// among them.
|
|
4794
|
-
endMarker =
|
|
4795
|
-
|
|
4796
|
-
|
|
4900
|
+
endMarker = stxHost.anchor('stx-if-end');
|
|
4901
|
+
stxHost.insert(parent, endMarker, initialAnchor);
|
|
4902
|
+
stxHost.remove(el); // Remove the template element itself
|
|
4797
4903
|
}
|
|
4798
4904
|
|
|
4799
4905
|
// Helper to evaluate with captured scope (auto-unwraps signals).
|
|
@@ -4883,13 +4989,13 @@ catch (e2) {
|
|
|
4883
4989
|
if (isTemplate) {
|
|
4884
4990
|
if (value && !isInserted) {
|
|
4885
4991
|
// Re-insert cloned content
|
|
4886
|
-
currentNodes = Array.from(el.content.childNodes).map(n =>
|
|
4992
|
+
currentNodes = Array.from(el.content.childNodes).map(n => stxHost.clone(n));
|
|
4887
4993
|
const insertionAnchor = placeholder.nextSibling;
|
|
4888
|
-
currentNodes.forEach(node =>
|
|
4994
|
+
currentNodes.forEach(node => stxHost.insert(parent, node, insertionAnchor));
|
|
4889
4995
|
// Bound AFTER the clones, so hiding can remove whatever a nested
|
|
4890
4996
|
// structural directive rendered as their sibling (#1955).
|
|
4891
|
-
if (!endMarker) endMarker =
|
|
4892
|
-
|
|
4997
|
+
if (!endMarker) endMarker = stxHost.anchor('stx-if-end');
|
|
4998
|
+
stxHost.insert(parent, endMarker, insertionAnchor);
|
|
4893
4999
|
processTemplateNodes(currentNodes);
|
|
4894
5000
|
childrenProcessed = true;
|
|
4895
5001
|
// Stamp insertion time for click propagation guard
|
|
@@ -4915,12 +5021,12 @@ else if (!value && isInserted) {
|
|
|
4915
5021
|
while (doomed && doomed !== endMarker) {
|
|
4916
5022
|
var nextDoomed = doomed.nextSibling;
|
|
4917
5023
|
disposeSubtreeEffects(doomed);
|
|
4918
|
-
|
|
5024
|
+
stxHost.remove(doomed);
|
|
4919
5025
|
doomed = nextDoomed;
|
|
4920
5026
|
}
|
|
4921
|
-
|
|
5027
|
+
stxHost.remove(endMarker);
|
|
4922
5028
|
}
|
|
4923
|
-
currentNodes.forEach(node => { disposeSubtreeEffects(node);
|
|
5029
|
+
currentNodes.forEach(node => { disposeSubtreeEffects(node); stxHost.remove(node); });
|
|
4924
5030
|
currentNodes = [];
|
|
4925
5031
|
isInserted = false;
|
|
4926
5032
|
childrenProcessed = false;
|
|
@@ -4941,7 +5047,7 @@ else {
|
|
|
4941
5047
|
if (value && !isInserted) {
|
|
4942
5048
|
console.log('[stx] bindIf INSERTING element for :if=' + expr);
|
|
4943
5049
|
const insertionAnchor = placeholder.nextSibling;
|
|
4944
|
-
currentNodes.forEach(node =>
|
|
5050
|
+
currentNodes.forEach(node => stxHost.insert(parent, node, insertionAnchor));
|
|
4945
5051
|
if (parent && parent.__stx_detached_if) currentNodes.forEach(node => parent.__stx_detached_if.delete(node));
|
|
4946
5052
|
el.__stx_shown_at = performance.now();
|
|
4947
5053
|
isInserted = true;
|
|
@@ -4957,7 +5063,7 @@ else if (!value && isInserted) {
|
|
|
4957
5063
|
// once (#1737). Permanent disposal stays in bindFor (item removal)
|
|
4958
5064
|
// and cleanupContainer (SPA navigation). The double-bind guards make
|
|
4959
5065
|
// re-show idempotent, so toggling doesn't leak.
|
|
4960
|
-
currentNodes.forEach(node =>
|
|
5066
|
+
currentNodes.forEach(node => stxHost.remove(node));
|
|
4961
5067
|
// Detached nodes are out of reach of a DOM walk, so an ancestor row or
|
|
4962
5068
|
// branch removed while this is hidden could not dispose their effects
|
|
4963
5069
|
// (#1954). Record them on the parent that keeps the placeholder.
|
|
@@ -7843,7 +7949,10 @@ else {
|
|
|
7843
7949
|
// Bind page roots after child components have registered their local scope.
|
|
7844
7950
|
document.querySelectorAll('[data-stx]').forEach(el => {
|
|
7845
7951
|
console.log('[DOMContentLoaded] processElement on:', el.tagName, 'scope keys:', Object.keys(componentScope).slice(0, 10));
|
|
7846
|
-
var disposeEffects = trackEffects(function() {
|
|
7952
|
+
var disposeEffects = trackEffects(function() {
|
|
7953
|
+
// The server's list when the page shipped one, the walk otherwise.
|
|
7954
|
+
if (!processFromManifest(el, componentScope, window.__stx_bindings)) processElement(el);
|
|
7955
|
+
});
|
|
7847
7956
|
el.__stx_disposers = disposeEffects;
|
|
7848
7957
|
|
|
7849
7958
|
// Remove x-cloak after bindings are applied (prevents FOUC)
|