tutuca 0.9.63 → 0.9.64

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.
@@ -8823,197 +8823,531 @@ class RequestHandler {
8823
8823
  }
8824
8824
  }
8825
8825
 
8826
- // src/anode.js
8827
- function resolveDynProducer(comp, dynName) {
8828
- const dyn = comp?.dynamic?.[dynName];
8829
- if (dyn == null)
8830
- return null;
8831
- let producerComp, producerDyn;
8832
- if (dyn.compName != null) {
8833
- producerComp = comp.scope?.lookupComponent(dyn.compName);
8834
- producerDyn = producerComp?.dynamic?.[dyn.dynName];
8835
- } else {
8836
- producerComp = comp;
8837
- producerDyn = dyn;
8826
+ // src/vdom.js
8827
+ var isHtmlAttribute = (propName) => propName[4] === "-" && (propName[0] === "d" || propName[0] === "a");
8828
+ var HTML_NS = "http://www.w3.org/1999/xhtml";
8829
+ var isNamespaced = (node) => {
8830
+ const ns = node.namespaceURI;
8831
+ return ns !== null && ns !== HTML_NS;
8832
+ };
8833
+ function applyProperties(node, props, previous) {
8834
+ const namespaced = isNamespaced(node);
8835
+ for (const propName in props) {
8836
+ const propValue = props[propName];
8837
+ if (propValue === undefined)
8838
+ removeProperty(node, propName, previous);
8839
+ else if (propName === "dangerouslySetInnerHTML")
8840
+ node.innerHTML = propValue.__html ?? "";
8841
+ else if (propName === "className")
8842
+ node.setAttribute("class", propValue);
8843
+ else if (namespaced || isHtmlAttribute(propName))
8844
+ node.setAttribute(propName, propValue);
8845
+ else
8846
+ node[propName] = propValue;
8838
8847
  }
8839
- if (producerComp == null || producerDyn == null)
8840
- return null;
8841
- const pi = producerDyn.val?.toPathItem?.() ?? null;
8842
- return { producerCompId: producerComp.id, producerSteps: pi ? [pi] : [] };
8843
8848
  }
8844
-
8845
- class BaseNode {
8846
- render(_stack, _rx) {
8847
- return null;
8848
- }
8849
- setDataAttr(key, val) {
8850
- console.warn("setDataAttr not implemented for", this, { key, val });
8851
- }
8852
- isConstant() {
8853
- return false;
8854
- }
8855
- optimize() {}
8849
+ function removeProperty(node, propName, previous) {
8850
+ const previousValue = previous[propName];
8851
+ if (propName === "dangerouslySetInnerHTML")
8852
+ node.replaceChildren();
8853
+ else if (propName === "className")
8854
+ node.removeAttribute("class");
8855
+ else if (propName === "htmlFor")
8856
+ node.removeAttribute("for");
8857
+ else if (isNamespaced(node) || typeof previousValue === "string" || isHtmlAttribute(propName))
8858
+ node.removeAttribute(propName);
8859
+ else
8860
+ node[propName] = null;
8856
8861
  }
8857
8862
 
8858
- class TextNode extends BaseNode {
8859
- constructor(val) {
8860
- super();
8861
- this.val = val;
8862
- }
8863
- render(_stack, _rx) {
8864
- return this.val;
8865
- }
8866
- isWhiteSpace() {
8867
- for (let i = 0;i < this.val.length; i++) {
8868
- const c = this.val.charCodeAt(i);
8869
- if (!(c === 32 || c === 10 || c === 9 || c === 13))
8870
- return false;
8871
- }
8872
- return true;
8873
- }
8874
- hasNewLine() {
8875
- for (let i = 0;i < this.val.length; i++) {
8876
- const c = this.val.charCodeAt(i);
8877
- if (c === 10 || c === 13)
8878
- return true;
8879
- }
8880
- return false;
8881
- }
8882
- condenseWhiteSpace(replacement = "") {
8883
- this.val = replacement;
8884
- }
8885
- isConstant() {
8863
+ class VBase {
8864
+ }
8865
+ var getKey = (child) => child instanceof VNode2 ? child.key : undefined;
8866
+ var isIterable = (obj) => obj != null && typeof obj !== "string" && typeof obj[Symbol.iterator] === "function";
8867
+ function childsEqual(a, b) {
8868
+ if (a === b)
8886
8869
  return true;
8887
- }
8888
- setDataAttr(_key, _val) {}
8870
+ for (let i = 0;i < a.length; i++)
8871
+ if (!a[i].isEqualTo(b[i]))
8872
+ return false;
8873
+ return true;
8889
8874
  }
8890
-
8891
- class CommentNode extends TextNode {
8892
- render(_stack, rx) {
8893
- return rx.renderComment(this.val);
8894
- }
8875
+ function appendChildNodes(parent, childs, opts) {
8876
+ for (const child of childs)
8877
+ parent.appendChild(child.toDom(opts));
8895
8878
  }
8896
- function optimizeChilds(childs) {
8897
- for (let i = 0;i < childs.length; i++) {
8898
- const child = childs[i];
8899
- if (child.isConstant())
8900
- childs[i] = new RenderOnceNode(child);
8879
+ function addChild(normalizedChildren, child) {
8880
+ if (child == null)
8881
+ return;
8882
+ if (isIterable(child)) {
8883
+ for (const c of child)
8884
+ addChild(normalizedChildren, c);
8885
+ } else if (child instanceof VBase) {
8886
+ if (child instanceof VFragment)
8887
+ normalizedChildren.push(...child.childs);
8901
8888
  else
8902
- child.optimize();
8903
- }
8904
- }
8905
- function optimizeNode(node) {
8906
- if (node.isConstant())
8907
- return new RenderOnceNode(node);
8908
- node.optimize();
8909
- return node;
8889
+ normalizedChildren.push(child);
8890
+ } else
8891
+ normalizedChildren.push(new VText(child));
8910
8892
  }
8911
8893
 
8912
- class ChildsNode extends BaseNode {
8913
- constructor(childs) {
8894
+ class VText extends VBase {
8895
+ constructor(text) {
8914
8896
  super();
8915
- this.childs = childs;
8897
+ this.text = String(text);
8916
8898
  }
8917
- isConstant() {
8918
- return this.childs.every((v) => v.isConstant());
8899
+ get nodeType() {
8900
+ return 3;
8919
8901
  }
8920
- optimize() {
8921
- optimizeChilds(this.childs);
8902
+ isEqualTo(other) {
8903
+ return other instanceof VText && this.text === other.text;
8904
+ }
8905
+ toDom(opts) {
8906
+ return opts.document.createTextNode(this.text);
8922
8907
  }
8923
8908
  }
8924
8909
 
8925
- class DomNode extends ChildsNode {
8926
- constructor(tagName, attrs, childs) {
8927
- super(childs);
8928
- this.tagName = tagName;
8929
- this.attrs = attrs;
8910
+ class VComment extends VBase {
8911
+ constructor(text) {
8912
+ super();
8913
+ this.text = text;
8930
8914
  }
8931
- render(stack, rx) {
8932
- const childNodes = new Array(this.childs.length);
8933
- for (let i = 0;i < childNodes.length; i++)
8934
- childNodes[i] = this.childs[i]?.render?.(stack, rx) ?? null;
8935
- return rx.renderTag(this.tagName, this.attrs.eval(stack), childNodes);
8915
+ get nodeType() {
8916
+ return 8;
8936
8917
  }
8937
- setDataAttr(key, val) {
8938
- this.attrs.setDataAttr(key, val);
8918
+ isEqualTo(other) {
8919
+ return other instanceof VComment && this.text === other.text;
8939
8920
  }
8940
- isConstant() {
8941
- return this.attrs.isConstant() && super.isConstant();
8921
+ toDom(opts) {
8922
+ return opts.document.createComment(this.text);
8942
8923
  }
8943
8924
  }
8944
8925
 
8945
- class FragmentNode extends ChildsNode {
8946
- render(stack, rx) {
8947
- return rx.renderFragment(this.childs.map((c) => c?.render(stack, rx)));
8926
+ class VFragment extends VBase {
8927
+ constructor(childs) {
8928
+ super();
8929
+ this.childs = [];
8930
+ addChild(this.childs, childs);
8948
8931
  }
8949
- setDataAttr(key, val) {
8950
- for (const child of this.childs)
8951
- child.setDataAttr(key, val);
8932
+ get nodeType() {
8933
+ return 11;
8934
+ }
8935
+ isEqualTo(other) {
8936
+ if (!(other instanceof VFragment) || this.childs.length !== other.childs.length)
8937
+ return false;
8938
+ return childsEqual(this.childs, other.childs);
8939
+ }
8940
+ toDom(opts) {
8941
+ const fragment = opts.document.createDocumentFragment();
8942
+ appendChildNodes(fragment, this.childs, opts);
8943
+ return fragment;
8952
8944
  }
8953
8945
  }
8954
- var maybeFragment = (xs) => xs.length === 1 ? xs[0] : new FragmentNode(xs);
8955
- var VALID_NODE_RE = /^[a-zA-Z][a-zA-Z0-9-]*$/;
8956
8946
 
8957
- class ANode extends BaseNode {
8958
- constructor(nodeId, val) {
8947
+ class VNode2 extends VBase {
8948
+ constructor(tag, attrs, childs, key, namespace) {
8959
8949
  super();
8960
- this.nodeId = nodeId;
8961
- this.val = val;
8950
+ this.tag = tag;
8951
+ this.attrs = attrs ?? {};
8952
+ this.childs = childs ?? [];
8953
+ this.key = key != null ? String(key) : undefined;
8954
+ this.namespace = typeof namespace === "string" ? namespace : null;
8962
8955
  }
8963
- toPathStep(ctx) {
8964
- return ctx.applyKey(this.val?.toPathItem?.() ?? null);
8956
+ get nodeType() {
8957
+ return 1;
8965
8958
  }
8966
- static parse(html, px) {
8967
- const nodes = px.parseHTML(html);
8968
- if (nodes.length === 0)
8969
- return new CommentNode("Empty View in ANode.parse");
8970
- if (nodes.length === 1)
8971
- return ANode.fromDOM(nodes[0], px);
8972
- const childs = [];
8973
- for (let i = 0;i < nodes.length; i++) {
8974
- const child = ANode.fromDOM(nodes[i], px);
8975
- if (child !== null)
8976
- childs.push(child);
8977
- }
8978
- const trimmed = condenseChildsWhites(childs);
8979
- if (trimmed.length === 0)
8980
- return new CommentNode("Empty View in ANode.parse");
8981
- return maybeFragment(trimmed);
8959
+ isSameKind(other) {
8960
+ return this.tag === other.tag && this.namespace === other.namespace && this.key === other.key;
8982
8961
  }
8983
- static fromDOM(node, px) {
8984
- if (node instanceof px.Text)
8985
- return new TextNode(node.textContent);
8986
- else if (node instanceof px.Comment)
8987
- return new CommentNode(node.textContent);
8988
- const { childNodes, attributes: attrs, tagName: tag } = node;
8989
- const childs = [];
8990
- for (let i = 0;i < childNodes.length; i++) {
8991
- const child = ANode.fromDOM(childNodes[i], px);
8992
- if (child !== null)
8993
- childs.push(child);
8962
+ isEqualTo(other) {
8963
+ if (this === other)
8964
+ return true;
8965
+ if (!(other instanceof VNode2) || !this.isSameKind(other) || this.childs.length !== other.childs.length) {
8966
+ return false;
8994
8967
  }
8995
- const prevTag = px.currentTag;
8996
- px.currentTag = tag;
8997
- try {
8998
- const isPseudoX = attrs[0]?.name === "@x";
8999
- if (tag === "X" || isPseudoX)
9000
- return parseXOp(attrs, childs, isPseudoX ? 1 : 0, px);
9001
- else if (tag.charCodeAt(1) === 58 && tag.charCodeAt(0) === 88) {
9002
- const macroName = tag.slice(2).toLowerCase();
9003
- if (macroName === "slot") {
9004
- const slotName = attrs.getNamedItem("name")?.value ?? "_";
9005
- return px.frame.macroSlots[slotName] ?? maybeFragment(childs);
9006
- }
9007
- const [nAttrs, wrappers] = Attributes.parse(attrs, px, true);
9008
- px.onAttributes(nAttrs, wrappers, null, true, tag);
9009
- return wrap(px.newMacroNode(macroName, nAttrs.toMacroVars(), childs), px, wrappers);
9010
- } else if (VALID_NODE_RE.test(tag)) {
8968
+ if (this.attrs !== other.attrs) {
8969
+ for (const key in this.attrs)
8970
+ if (this.attrs[key] !== other.attrs[key])
8971
+ return false;
8972
+ for (const key in other.attrs)
8973
+ if (!Object.hasOwn(this.attrs, key))
8974
+ return false;
8975
+ }
8976
+ return childsEqual(this.childs, other.childs);
8977
+ }
8978
+ toDom(opts) {
8979
+ const doc = opts.document;
8980
+ const node = this.namespace === null ? doc.createElement(this.tag) : doc.createElementNS(this.namespace, this.tag);
8981
+ if (this.tag === "SELECT" && "value" in this.attrs) {
8982
+ const { value, ...rest } = this.attrs;
8983
+ applyProperties(node, rest, {});
8984
+ appendChildNodes(node, this.childs, opts);
8985
+ applyProperties(node, { value }, {});
8986
+ } else {
8987
+ applyProperties(node, this.attrs, {});
8988
+ appendChildNodes(node, this.childs, opts);
8989
+ }
8990
+ return node;
8991
+ }
8992
+ }
8993
+ function diffProps(a, b) {
8994
+ if (a === b)
8995
+ return null;
8996
+ let diff = null;
8997
+ for (const aKey in a) {
8998
+ if (!Object.hasOwn(b, aKey)) {
8999
+ diff ??= {};
9000
+ diff[aKey] = undefined;
9001
+ } else if (a[aKey] !== b[aKey]) {
9002
+ diff ??= {};
9003
+ diff[aKey] = b[aKey];
9004
+ }
9005
+ }
9006
+ for (const bKey in b) {
9007
+ if (!Object.hasOwn(a, bKey)) {
9008
+ diff ??= {};
9009
+ diff[bKey] = b[bKey];
9010
+ }
9011
+ }
9012
+ return diff;
9013
+ }
9014
+ function morphNode(domNode, source, target, opts) {
9015
+ if (source === target || source.isEqualTo(target))
9016
+ return domNode;
9017
+ const type3 = source.nodeType;
9018
+ if (type3 === target.nodeType) {
9019
+ if (type3 === 3 || type3 === 8) {
9020
+ domNode.data = target.text;
9021
+ return domNode;
9022
+ }
9023
+ if (type3 === 1 && source.isSameKind(target)) {
9024
+ const propsDiff = diffProps(source.attrs, target.attrs);
9025
+ const isSelect = source.tag === "SELECT";
9026
+ if (propsDiff) {
9027
+ if (isSelect && "value" in propsDiff) {
9028
+ const { value: _v, ...rest } = propsDiff;
9029
+ applyProperties(domNode, rest, source.attrs);
9030
+ } else
9031
+ applyProperties(domNode, propsDiff, source.attrs);
9032
+ }
9033
+ if (!target.attrs.dangerouslySetInnerHTML)
9034
+ morphChildren(domNode, source.childs, target.childs, opts);
9035
+ if (isSelect && target.attrs.value !== undefined)
9036
+ applyProperties(domNode, { value: target.attrs.value }, source.attrs);
9037
+ return domNode;
9038
+ }
9039
+ if (type3 === 11) {
9040
+ morphChildren(domNode, source.childs, target.childs, opts);
9041
+ return domNode;
9042
+ }
9043
+ }
9044
+ const newNode = target.toDom(opts);
9045
+ domNode.parentNode?.replaceChild(newNode, domNode);
9046
+ return newNode;
9047
+ }
9048
+ function morphChildren(parentDom, oldChilds, newChilds, opts) {
9049
+ if (oldChilds.length === 0) {
9050
+ appendChildNodes(parentDom, newChilds, opts);
9051
+ return;
9052
+ }
9053
+ if (newChilds.length === 0) {
9054
+ parentDom.replaceChildren();
9055
+ return;
9056
+ }
9057
+ if (oldChilds.length === newChilds.length) {
9058
+ let hasKey = false;
9059
+ for (let i = 0;i < oldChilds.length; i++) {
9060
+ if (getKey(oldChilds[i]) != null || getKey(newChilds[i]) != null) {
9061
+ hasKey = true;
9062
+ break;
9063
+ }
9064
+ }
9065
+ if (!hasKey) {
9066
+ let dom = parentDom.firstChild;
9067
+ for (let i = 0;i < oldChilds.length; i++) {
9068
+ const next = dom.nextSibling;
9069
+ morphNode(dom, oldChilds[i], newChilds[i], opts);
9070
+ dom = next;
9071
+ }
9072
+ return;
9073
+ }
9074
+ }
9075
+ const domNodes = Array.from(parentDom.childNodes);
9076
+ const oldKeyMap = Object.create(null);
9077
+ for (let i = 0;i < oldChilds.length; i++) {
9078
+ const key = getKey(oldChilds[i]);
9079
+ if (key != null)
9080
+ oldKeyMap[key] = i;
9081
+ }
9082
+ const used2 = new Uint8Array(oldChilds.length);
9083
+ let unkeyedCursor = 0;
9084
+ for (let j = 0;j < newChilds.length; j++) {
9085
+ const newChild = newChilds[j];
9086
+ const newKey = getKey(newChild);
9087
+ let oldIdx = -1;
9088
+ if (newKey != null) {
9089
+ if (newKey in oldKeyMap && !used2[oldKeyMap[newKey]])
9090
+ oldIdx = oldKeyMap[newKey];
9091
+ } else {
9092
+ while (unkeyedCursor < oldChilds.length) {
9093
+ if (!used2[unkeyedCursor] && getKey(oldChilds[unkeyedCursor]) == null) {
9094
+ oldIdx = unkeyedCursor++;
9095
+ break;
9096
+ }
9097
+ unkeyedCursor++;
9098
+ }
9099
+ }
9100
+ if (oldIdx >= 0) {
9101
+ used2[oldIdx] = 1;
9102
+ const newDom = morphNode(domNodes[oldIdx], oldChilds[oldIdx], newChild, opts);
9103
+ const ref = parentDom.childNodes[j] ?? null;
9104
+ if (newDom !== ref)
9105
+ parentDom.insertBefore(newDom, ref);
9106
+ } else {
9107
+ const ref = parentDom.childNodes[j] ?? null;
9108
+ parentDom.insertBefore(newChild.toDom(opts), ref);
9109
+ }
9110
+ }
9111
+ for (let i = oldChilds.length - 1;i >= 0; i--)
9112
+ if (!used2[i] && domNodes[i].parentNode === parentDom)
9113
+ parentDom.removeChild(domNodes[i]);
9114
+ }
9115
+ function render(vnode, container, options, prev) {
9116
+ const isFragment = vnode instanceof VFragment;
9117
+ if (prev && prev.vnode instanceof VFragment === isFragment) {
9118
+ const oldDom = isFragment ? container : prev.dom;
9119
+ const newDom = morphNode(oldDom, prev.vnode, vnode, options);
9120
+ return { vnode, dom: isFragment ? container : newDom };
9121
+ }
9122
+ const domNode = vnode.toDom(options);
9123
+ container.replaceChildren(domNode);
9124
+ return { vnode, dom: isFragment ? container : domNode };
9125
+ }
9126
+ function h(tagName, properties, children, namespace) {
9127
+ const props = {};
9128
+ let key;
9129
+ if (properties) {
9130
+ for (const propName in properties) {
9131
+ const propVal = properties[propName];
9132
+ switch (propName) {
9133
+ case "key":
9134
+ key = propVal;
9135
+ break;
9136
+ case "namespace":
9137
+ namespace = namespace ?? propVal;
9138
+ break;
9139
+ case "class":
9140
+ props.className = propVal;
9141
+ break;
9142
+ case "for":
9143
+ props.htmlFor = propVal;
9144
+ break;
9145
+ default:
9146
+ props[propName] = isHtmlAttribute(propName) ? String(propVal) : propVal;
9147
+ }
9148
+ }
9149
+ }
9150
+ const c = tagName.charCodeAt(0);
9151
+ const tag = namespace == null && c >= 97 && c <= 122 ? tagName.toUpperCase() : tagName;
9152
+ const normalizedChildren = [];
9153
+ addChild(normalizedChildren, children);
9154
+ return new VNode2(tag, props, normalizedChildren, key, namespace);
9155
+ }
9156
+
9157
+ // src/anode.js
9158
+ function resolveDynProducer(comp, dynName) {
9159
+ const dyn = comp?.dynamic?.[dynName];
9160
+ if (dyn == null)
9161
+ return null;
9162
+ let producerComp, producerDyn;
9163
+ if (dyn.compName != null) {
9164
+ producerComp = comp.scope?.lookupComponent(dyn.compName);
9165
+ producerDyn = producerComp?.dynamic?.[dyn.dynName];
9166
+ } else {
9167
+ producerComp = comp;
9168
+ producerDyn = dyn;
9169
+ }
9170
+ if (producerComp == null || producerDyn == null)
9171
+ return null;
9172
+ const pi = producerDyn.val?.toPathItem?.() ?? null;
9173
+ return { producerCompId: producerComp.id, producerSteps: pi ? [pi] : [] };
9174
+ }
9175
+
9176
+ class BaseNode {
9177
+ render(_stack, _rx) {
9178
+ return null;
9179
+ }
9180
+ setDataAttr(key, val) {
9181
+ console.warn("setDataAttr not implemented for", this, { key, val });
9182
+ }
9183
+ isConstant() {
9184
+ return false;
9185
+ }
9186
+ optimize() {}
9187
+ }
9188
+
9189
+ class TextNode extends BaseNode {
9190
+ constructor(val) {
9191
+ super();
9192
+ this.val = val;
9193
+ }
9194
+ render(_stack, _rx) {
9195
+ return this.val;
9196
+ }
9197
+ isWhiteSpace() {
9198
+ for (let i = 0;i < this.val.length; i++) {
9199
+ const c = this.val.charCodeAt(i);
9200
+ if (!(c === 32 || c === 10 || c === 9 || c === 13))
9201
+ return false;
9202
+ }
9203
+ return true;
9204
+ }
9205
+ hasNewLine() {
9206
+ for (let i = 0;i < this.val.length; i++) {
9207
+ const c = this.val.charCodeAt(i);
9208
+ if (c === 10 || c === 13)
9209
+ return true;
9210
+ }
9211
+ return false;
9212
+ }
9213
+ condenseWhiteSpace(replacement = "") {
9214
+ this.val = replacement;
9215
+ }
9216
+ isConstant() {
9217
+ return true;
9218
+ }
9219
+ setDataAttr(_key, _val) {}
9220
+ }
9221
+
9222
+ class CommentNode extends TextNode {
9223
+ render(_stack, rx) {
9224
+ return rx.renderComment(this.val);
9225
+ }
9226
+ }
9227
+ function optimizeChilds(childs) {
9228
+ for (let i = 0;i < childs.length; i++) {
9229
+ const child = childs[i];
9230
+ if (child.isConstant())
9231
+ childs[i] = new RenderOnceNode(child);
9232
+ else
9233
+ child.optimize();
9234
+ }
9235
+ }
9236
+ function optimizeNode(node) {
9237
+ if (node.isConstant())
9238
+ return new RenderOnceNode(node);
9239
+ node.optimize();
9240
+ return node;
9241
+ }
9242
+
9243
+ class ChildsNode extends BaseNode {
9244
+ constructor(childs) {
9245
+ super();
9246
+ this.childs = childs;
9247
+ }
9248
+ isConstant() {
9249
+ return this.childs.every((v) => v.isConstant());
9250
+ }
9251
+ optimize() {
9252
+ optimizeChilds(this.childs);
9253
+ }
9254
+ }
9255
+
9256
+ class DomNode extends ChildsNode {
9257
+ constructor(tagName, attrs, childs, namespace = null) {
9258
+ super(childs);
9259
+ this.tagName = tagName;
9260
+ this.attrs = attrs;
9261
+ this.namespace = namespace;
9262
+ }
9263
+ render(stack, rx) {
9264
+ const childNodes = new Array(this.childs.length);
9265
+ for (let i = 0;i < childNodes.length; i++)
9266
+ childNodes[i] = this.childs[i]?.render?.(stack, rx) ?? null;
9267
+ return rx.renderTag(this.tagName, this.attrs.eval(stack), childNodes, this.namespace);
9268
+ }
9269
+ setDataAttr(key, val) {
9270
+ this.attrs.setDataAttr(key, val);
9271
+ }
9272
+ isConstant() {
9273
+ return this.attrs.isConstant() && super.isConstant();
9274
+ }
9275
+ }
9276
+
9277
+ class FragmentNode extends ChildsNode {
9278
+ render(stack, rx) {
9279
+ return rx.renderFragment(this.childs.map((c) => c?.render(stack, rx)));
9280
+ }
9281
+ setDataAttr(key, val) {
9282
+ for (const child of this.childs)
9283
+ child.setDataAttr(key, val);
9284
+ }
9285
+ }
9286
+ var maybeFragment = (xs) => xs.length === 1 ? xs[0] : new FragmentNode(xs);
9287
+ var VALID_NODE_RE = /^[a-zA-Z][a-zA-Z0-9-]*$/;
9288
+
9289
+ class ANode extends BaseNode {
9290
+ constructor(nodeId, val) {
9291
+ super();
9292
+ this.nodeId = nodeId;
9293
+ this.val = val;
9294
+ }
9295
+ toPathStep(ctx) {
9296
+ return ctx.applyKey(this.val?.toPathItem?.() ?? null);
9297
+ }
9298
+ static parse(html, px) {
9299
+ const nodes = px.parseHTML(html);
9300
+ if (nodes.length === 0)
9301
+ return new CommentNode("Empty View in ANode.parse");
9302
+ if (nodes.length === 1)
9303
+ return ANode.fromDOM(nodes[0], px);
9304
+ const childs = [];
9305
+ for (let i = 0;i < nodes.length; i++) {
9306
+ const child = ANode.fromDOM(nodes[i], px);
9307
+ if (child !== null)
9308
+ childs.push(child);
9309
+ }
9310
+ const trimmed = condenseChildsWhites(childs);
9311
+ if (trimmed.length === 0)
9312
+ return new CommentNode("Empty View in ANode.parse");
9313
+ return maybeFragment(trimmed);
9314
+ }
9315
+ static fromDOM(node, px) {
9316
+ if (node instanceof px.Text)
9317
+ return new TextNode(node.textContent);
9318
+ else if (node instanceof px.Comment)
9319
+ return new CommentNode(node.textContent);
9320
+ const { childNodes, attributes: attrs, tagName: tag } = node;
9321
+ const childs = [];
9322
+ for (let i = 0;i < childNodes.length; i++) {
9323
+ const child = ANode.fromDOM(childNodes[i], px);
9324
+ if (child !== null)
9325
+ childs.push(child);
9326
+ }
9327
+ const prevTag = px.currentTag;
9328
+ px.currentTag = tag;
9329
+ try {
9330
+ const isPseudoX = attrs[0]?.name === "@x";
9331
+ if (tag === "X" || isPseudoX)
9332
+ return parseXOp(attrs, childs, isPseudoX ? 1 : 0, px);
9333
+ else if (tag.charCodeAt(1) === 58 && tag.charCodeAt(0) === 88) {
9334
+ const macroName = tag.slice(2).toLowerCase();
9335
+ if (macroName === "slot") {
9336
+ const slotName = attrs.getNamedItem("name")?.value ?? "_";
9337
+ return px.frame.macroSlots[slotName] ?? maybeFragment(childs);
9338
+ }
9339
+ const [nAttrs, wrappers] = Attributes.parse(attrs, px, true);
9340
+ px.onAttributes(nAttrs, wrappers, null, true, tag);
9341
+ return wrap(px.newMacroNode(macroName, nAttrs.toMacroVars(), childs), px, wrappers);
9342
+ } else if (VALID_NODE_RE.test(tag)) {
9011
9343
  const [nAttrs, wrappers, textChild] = Attributes.parse(attrs, px);
9012
9344
  px.onAttributes(nAttrs, wrappers, textChild, false, tag);
9013
9345
  if (textChild)
9014
9346
  childs.unshift(new RenderTextNode(null, textChild));
9015
9347
  const domChilds = tag !== "PRE" ? condenseChildsWhites(childs) : childs;
9016
- return wrap(new DomNode(tag, nAttrs, domChilds), px, wrappers);
9348
+ const ns = node.namespaceURI;
9349
+ const namespace = ns && ns !== HTML_NS ? ns : null;
9350
+ return wrap(new DomNode(tag, nAttrs, domChilds, namespace), px, wrappers);
9017
9351
  }
9018
9352
  return new CommentNode(`Error: InvalidTagName ${tag}`);
9019
9353
  } finally {
@@ -13740,418 +14074,93 @@ class BubbleEvent extends SendEvent {
13740
14074
  super(path, transactor, name, args, parent, opts);
13741
14075
  this.targetPath = targetPath ?? path;
13742
14076
  }
13743
- stopPropagation() {
13744
- this.opts.bubbles = false;
13745
- }
13746
- }
13747
-
13748
- class Task {
13749
- constructor() {
13750
- this.deps = [];
13751
- this.val = this.resolve = this.reject = null;
13752
- this.promise = new Promise((res, rej) => {
13753
- this.resolve = res;
13754
- this.reject = rej;
13755
- });
13756
- this.isCompleted = false;
13757
- }
13758
- addDep(task) {
13759
- console.assert(!this.isCompleted, "addDep for completed task", this, task);
13760
- this.deps.push(task);
13761
- task.promise.then((_) => this._check());
13762
- }
13763
- complete(val) {
13764
- this.val = val;
13765
- this._check();
13766
- }
13767
- _check() {
13768
- if (this.deps.every((task) => task.isCompleted)) {
13769
- this.isCompleted = true;
13770
- this.resolve(this);
13771
- }
13772
- }
13773
- }
13774
-
13775
- class Dispatcher {
13776
- constructor(path, transactor, parentTransaction) {
13777
- this.path = path;
13778
- this.transactor = transactor;
13779
- this.parent = parentTransaction;
13780
- }
13781
- get at() {
13782
- return new PathChanges(this);
13783
- }
13784
- send(name, args, opts) {
13785
- return this.sendAtPath(this.path, name, args, opts);
13786
- }
13787
- bubble(name, args, opts) {
13788
- return this.send(name, args, { skipSelf: true, bubbles: true, ...opts });
13789
- }
13790
- sendAtPath(path, name, args, opts) {
13791
- return this.transactor.pushSend(path, name, args, opts, this.parent);
13792
- }
13793
- request(name, args, opts) {
13794
- return this.requestAtPath(this.path, name, args, opts);
13795
- }
13796
- requestAtPath(path, name, args, opts) {
13797
- return this.transactor.pushRequest(path, name, args, opts, this.parent);
13798
- }
13799
- lookupTypeFor(name, inst) {
13800
- return this.transactor.comps.getCompFor(inst).scope.lookupComponent(name);
13801
- }
13802
- }
13803
-
13804
- class EventContext extends Dispatcher {
13805
- get name() {
13806
- return this.parent?.name ?? null;
13807
- }
13808
- get targetPath() {
13809
- return this.parent.targetPath;
13810
- }
13811
- stopPropagation() {
13812
- return this.parent.stopPropagation();
13813
- }
13814
- }
13815
-
13816
- class PathChanges extends PathBuilder {
13817
- constructor(dispatcher) {
13818
- super();
13819
- this.dispatcher = dispatcher;
13820
- }
13821
- send(name, args, opts) {
13822
- return this.dispatcher.sendAtPath(this.buildPath(), name, args, opts);
13823
- }
13824
- bubble(name, args, opts) {
13825
- return this.send(name, args, { skipSelf: true, bubbles: true, ...opts });
13826
- }
13827
- buildPath() {
13828
- return this.dispatcher.path.concat(this.pathChanges);
13829
- }
13830
- }
13831
-
13832
- // src/vdom.js
13833
- var isHtmlAttribute = (propName) => propName[4] === "-" && (propName[0] === "d" || propName[0] === "a");
13834
- function applyProperties(node, props, previous) {
13835
- for (const propName in props) {
13836
- const propValue = props[propName];
13837
- if (propValue === undefined)
13838
- removeProperty(node, propName, previous);
13839
- else if (isHtmlAttribute(propName))
13840
- node.setAttribute(propName, propValue);
13841
- else if (propName === "dangerouslySetInnerHTML")
13842
- node.innerHTML = propValue.__html ?? "";
13843
- else if (propName === "className")
13844
- node.setAttribute("class", propValue);
13845
- else
13846
- node[propName] = propValue;
13847
- }
13848
- }
13849
- function removeProperty(node, propName, previous) {
13850
- const previousValue = previous[propName];
13851
- if (propName === "dangerouslySetInnerHTML")
13852
- node.replaceChildren();
13853
- else if (propName === "className")
13854
- node.removeAttribute("class");
13855
- else if (propName === "htmlFor")
13856
- node.removeAttribute("for");
13857
- else if (typeof previousValue === "string" || isHtmlAttribute(propName))
13858
- node.removeAttribute(propName);
13859
- else
13860
- node[propName] = null;
13861
- }
13862
-
13863
- class VBase {
13864
- }
13865
- var getKey = (child) => child instanceof VNode2 ? child.key : undefined;
13866
- var isIterable = (obj) => obj != null && typeof obj !== "string" && typeof obj[Symbol.iterator] === "function";
13867
- function childsEqual(a, b) {
13868
- if (a === b)
13869
- return true;
13870
- for (let i = 0;i < a.length; i++)
13871
- if (!a[i].isEqualTo(b[i]))
13872
- return false;
13873
- return true;
13874
- }
13875
- function appendChildNodes(parent, childs, opts) {
13876
- for (const child of childs)
13877
- parent.appendChild(child.toDom(opts));
13878
- }
13879
- function addChild(normalizedChildren, child) {
13880
- if (child == null)
13881
- return;
13882
- if (isIterable(child)) {
13883
- for (const c of child)
13884
- addChild(normalizedChildren, c);
13885
- } else if (child instanceof VBase) {
13886
- if (child instanceof VFragment)
13887
- normalizedChildren.push(...child.childs);
13888
- else
13889
- normalizedChildren.push(child);
13890
- } else
13891
- normalizedChildren.push(new VText(child));
13892
- }
13893
-
13894
- class VText extends VBase {
13895
- constructor(text) {
13896
- super();
13897
- this.text = String(text);
13898
- }
13899
- get nodeType() {
13900
- return 3;
13901
- }
13902
- isEqualTo(other) {
13903
- return other instanceof VText && this.text === other.text;
13904
- }
13905
- toDom(opts) {
13906
- return opts.document.createTextNode(this.text);
13907
- }
13908
- }
13909
-
13910
- class VComment extends VBase {
13911
- constructor(text) {
13912
- super();
13913
- this.text = text;
13914
- }
13915
- get nodeType() {
13916
- return 8;
13917
- }
13918
- isEqualTo(other) {
13919
- return other instanceof VComment && this.text === other.text;
13920
- }
13921
- toDom(opts) {
13922
- return opts.document.createComment(this.text);
13923
- }
13924
- }
13925
-
13926
- class VFragment extends VBase {
13927
- constructor(childs) {
13928
- super();
13929
- this.childs = [];
13930
- addChild(this.childs, childs);
13931
- }
13932
- get nodeType() {
13933
- return 11;
13934
- }
13935
- isEqualTo(other) {
13936
- if (!(other instanceof VFragment) || this.childs.length !== other.childs.length)
13937
- return false;
13938
- return childsEqual(this.childs, other.childs);
13939
- }
13940
- toDom(opts) {
13941
- const fragment = opts.document.createDocumentFragment();
13942
- appendChildNodes(fragment, this.childs, opts);
13943
- return fragment;
14077
+ stopPropagation() {
14078
+ this.opts.bubbles = false;
13944
14079
  }
13945
14080
  }
13946
14081
 
13947
- class VNode2 extends VBase {
13948
- constructor(tag, attrs, childs, key, namespace) {
13949
- super();
13950
- this.tag = tag;
13951
- this.attrs = attrs ?? {};
13952
- this.childs = childs ?? [];
13953
- this.key = key != null ? String(key) : undefined;
13954
- this.namespace = typeof namespace === "string" ? namespace : null;
13955
- }
13956
- get nodeType() {
13957
- return 1;
14082
+ class Task {
14083
+ constructor() {
14084
+ this.deps = [];
14085
+ this.val = this.resolve = this.reject = null;
14086
+ this.promise = new Promise((res, rej) => {
14087
+ this.resolve = res;
14088
+ this.reject = rej;
14089
+ });
14090
+ this.isCompleted = false;
13958
14091
  }
13959
- isSameKind(other) {
13960
- return this.tag === other.tag && this.namespace === other.namespace && this.key === other.key;
14092
+ addDep(task) {
14093
+ console.assert(!this.isCompleted, "addDep for completed task", this, task);
14094
+ this.deps.push(task);
14095
+ task.promise.then((_) => this._check());
13961
14096
  }
13962
- isEqualTo(other) {
13963
- if (this === other)
13964
- return true;
13965
- if (!(other instanceof VNode2) || !this.isSameKind(other) || this.childs.length !== other.childs.length) {
13966
- return false;
13967
- }
13968
- if (this.attrs !== other.attrs) {
13969
- for (const key in this.attrs)
13970
- if (this.attrs[key] !== other.attrs[key])
13971
- return false;
13972
- for (const key in other.attrs)
13973
- if (!Object.hasOwn(this.attrs, key))
13974
- return false;
13975
- }
13976
- return childsEqual(this.childs, other.childs);
14097
+ complete(val) {
14098
+ this.val = val;
14099
+ this._check();
13977
14100
  }
13978
- toDom(opts) {
13979
- const doc = opts.document;
13980
- const node = this.namespace === null ? doc.createElement(this.tag) : doc.createElementNS(this.namespace, this.tag);
13981
- if (this.tag === "SELECT" && "value" in this.attrs) {
13982
- const { value, ...rest } = this.attrs;
13983
- applyProperties(node, rest, {});
13984
- appendChildNodes(node, this.childs, opts);
13985
- applyProperties(node, { value }, {});
13986
- } else {
13987
- applyProperties(node, this.attrs, {});
13988
- appendChildNodes(node, this.childs, opts);
14101
+ _check() {
14102
+ if (this.deps.every((task) => task.isCompleted)) {
14103
+ this.isCompleted = true;
14104
+ this.resolve(this);
13989
14105
  }
13990
- return node;
13991
14106
  }
13992
14107
  }
13993
- function diffProps(a, b) {
13994
- if (a === b)
13995
- return null;
13996
- let diff = null;
13997
- for (const aKey in a) {
13998
- if (!Object.hasOwn(b, aKey)) {
13999
- diff ??= {};
14000
- diff[aKey] = undefined;
14001
- } else if (a[aKey] !== b[aKey]) {
14002
- diff ??= {};
14003
- diff[aKey] = b[aKey];
14004
- }
14108
+
14109
+ class Dispatcher {
14110
+ constructor(path, transactor, parentTransaction) {
14111
+ this.path = path;
14112
+ this.transactor = transactor;
14113
+ this.parent = parentTransaction;
14005
14114
  }
14006
- for (const bKey in b) {
14007
- if (!Object.hasOwn(a, bKey)) {
14008
- diff ??= {};
14009
- diff[bKey] = b[bKey];
14010
- }
14115
+ get at() {
14116
+ return new PathChanges(this);
14011
14117
  }
14012
- return diff;
14013
- }
14014
- function morphNode(domNode, source, target, opts) {
14015
- if (source === target || source.isEqualTo(target))
14016
- return domNode;
14017
- const type3 = source.nodeType;
14018
- if (type3 === target.nodeType) {
14019
- if (type3 === 3 || type3 === 8) {
14020
- domNode.data = target.text;
14021
- return domNode;
14022
- }
14023
- if (type3 === 1 && source.isSameKind(target)) {
14024
- const propsDiff = diffProps(source.attrs, target.attrs);
14025
- const isSelect = source.tag === "SELECT";
14026
- if (propsDiff) {
14027
- if (isSelect && "value" in propsDiff) {
14028
- const { value: _v, ...rest } = propsDiff;
14029
- applyProperties(domNode, rest, source.attrs);
14030
- } else
14031
- applyProperties(domNode, propsDiff, source.attrs);
14032
- }
14033
- if (!target.attrs.dangerouslySetInnerHTML)
14034
- morphChildren(domNode, source.childs, target.childs, opts);
14035
- if (isSelect && target.attrs.value !== undefined)
14036
- applyProperties(domNode, { value: target.attrs.value }, source.attrs);
14037
- return domNode;
14038
- }
14039
- if (type3 === 11) {
14040
- morphChildren(domNode, source.childs, target.childs, opts);
14041
- return domNode;
14042
- }
14118
+ send(name, args, opts) {
14119
+ return this.sendAtPath(this.path, name, args, opts);
14043
14120
  }
14044
- const newNode = target.toDom(opts);
14045
- domNode.parentNode?.replaceChild(newNode, domNode);
14046
- return newNode;
14047
- }
14048
- function morphChildren(parentDom, oldChilds, newChilds, opts) {
14049
- if (oldChilds.length === 0) {
14050
- appendChildNodes(parentDom, newChilds, opts);
14051
- return;
14121
+ bubble(name, args, opts) {
14122
+ return this.send(name, args, { skipSelf: true, bubbles: true, ...opts });
14052
14123
  }
14053
- if (newChilds.length === 0) {
14054
- parentDom.replaceChildren();
14055
- return;
14124
+ sendAtPath(path, name, args, opts) {
14125
+ return this.transactor.pushSend(path, name, args, opts, this.parent);
14056
14126
  }
14057
- if (oldChilds.length === newChilds.length) {
14058
- let hasKey = false;
14059
- for (let i = 0;i < oldChilds.length; i++) {
14060
- if (getKey(oldChilds[i]) != null || getKey(newChilds[i]) != null) {
14061
- hasKey = true;
14062
- break;
14063
- }
14064
- }
14065
- if (!hasKey) {
14066
- let dom = parentDom.firstChild;
14067
- for (let i = 0;i < oldChilds.length; i++) {
14068
- const next = dom.nextSibling;
14069
- morphNode(dom, oldChilds[i], newChilds[i], opts);
14070
- dom = next;
14071
- }
14072
- return;
14073
- }
14127
+ request(name, args, opts) {
14128
+ return this.requestAtPath(this.path, name, args, opts);
14074
14129
  }
14075
- const domNodes = Array.from(parentDom.childNodes);
14076
- const oldKeyMap = Object.create(null);
14077
- for (let i = 0;i < oldChilds.length; i++) {
14078
- const key = getKey(oldChilds[i]);
14079
- if (key != null)
14080
- oldKeyMap[key] = i;
14130
+ requestAtPath(path, name, args, opts) {
14131
+ return this.transactor.pushRequest(path, name, args, opts, this.parent);
14081
14132
  }
14082
- const used2 = new Uint8Array(oldChilds.length);
14083
- let unkeyedCursor = 0;
14084
- for (let j = 0;j < newChilds.length; j++) {
14085
- const newChild = newChilds[j];
14086
- const newKey = getKey(newChild);
14087
- let oldIdx = -1;
14088
- if (newKey != null) {
14089
- if (newKey in oldKeyMap && !used2[oldKeyMap[newKey]])
14090
- oldIdx = oldKeyMap[newKey];
14091
- } else {
14092
- while (unkeyedCursor < oldChilds.length) {
14093
- if (!used2[unkeyedCursor] && getKey(oldChilds[unkeyedCursor]) == null) {
14094
- oldIdx = unkeyedCursor++;
14095
- break;
14096
- }
14097
- unkeyedCursor++;
14098
- }
14099
- }
14100
- if (oldIdx >= 0) {
14101
- used2[oldIdx] = 1;
14102
- const newDom = morphNode(domNodes[oldIdx], oldChilds[oldIdx], newChild, opts);
14103
- const ref = parentDom.childNodes[j] ?? null;
14104
- if (newDom !== ref)
14105
- parentDom.insertBefore(newDom, ref);
14106
- } else {
14107
- const ref = parentDom.childNodes[j] ?? null;
14108
- parentDom.insertBefore(newChild.toDom(opts), ref);
14109
- }
14133
+ lookupTypeFor(name, inst) {
14134
+ return this.transactor.comps.getCompFor(inst).scope.lookupComponent(name);
14110
14135
  }
14111
- for (let i = oldChilds.length - 1;i >= 0; i--)
14112
- if (!used2[i] && domNodes[i].parentNode === parentDom)
14113
- parentDom.removeChild(domNodes[i]);
14114
14136
  }
14115
- function render(vnode, container, options, prev) {
14116
- const isFragment = vnode instanceof VFragment;
14117
- if (prev && prev.vnode instanceof VFragment === isFragment) {
14118
- const oldDom = isFragment ? container : prev.dom;
14119
- const newDom = morphNode(oldDom, prev.vnode, vnode, options);
14120
- return { vnode, dom: isFragment ? container : newDom };
14137
+
14138
+ class EventContext extends Dispatcher {
14139
+ get name() {
14140
+ return this.parent?.name ?? null;
14141
+ }
14142
+ get targetPath() {
14143
+ return this.parent.targetPath;
14144
+ }
14145
+ stopPropagation() {
14146
+ return this.parent.stopPropagation();
14121
14147
  }
14122
- const domNode = vnode.toDom(options);
14123
- container.replaceChildren(domNode);
14124
- return { vnode, dom: isFragment ? container : domNode };
14125
14148
  }
14126
- function h(tagName, properties, children) {
14127
- const c = tagName.charCodeAt(0);
14128
- const tag = c >= 97 && c <= 122 ? tagName.toUpperCase() : tagName;
14129
- const props = {};
14130
- let key, namespace;
14131
- if (properties) {
14132
- for (const propName in properties) {
14133
- const propVal = properties[propName];
14134
- switch (propName) {
14135
- case "key":
14136
- key = propVal;
14137
- break;
14138
- case "namespace":
14139
- namespace = propVal;
14140
- break;
14141
- case "class":
14142
- props.className = propVal;
14143
- break;
14144
- case "for":
14145
- props.htmlFor = propVal;
14146
- break;
14147
- default:
14148
- props[propName] = isHtmlAttribute(propName) ? String(propVal) : propVal;
14149
- }
14150
- }
14149
+
14150
+ class PathChanges extends PathBuilder {
14151
+ constructor(dispatcher) {
14152
+ super();
14153
+ this.dispatcher = dispatcher;
14154
+ }
14155
+ send(name, args, opts) {
14156
+ return this.dispatcher.sendAtPath(this.buildPath(), name, args, opts);
14157
+ }
14158
+ bubble(name, args, opts) {
14159
+ return this.send(name, args, { skipSelf: true, bubbles: true, ...opts });
14160
+ }
14161
+ buildPath() {
14162
+ return this.dispatcher.path.concat(this.pathChanges);
14151
14163
  }
14152
- const normalizedChildren = [];
14153
- addChild(normalizedChildren, children);
14154
- return new VNode2(tag, props, normalizedChildren, key, namespace);
14155
14164
  }
14156
14165
 
14157
14166
  // src/app.js