tutuca 0.9.3 → 0.9.4

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.
@@ -2389,7 +2389,7 @@ class App {
2389
2389
  this.render();
2390
2390
  }
2391
2391
  });
2392
- injectCss("tutuca-app", this.comps.compileStyles());
2392
+ injectCss("tutuca-app", this.comps.compileStyles(), opts?.head ?? document.head);
2393
2393
  if (opts?.noCache) {
2394
2394
  this.renderer.setNullCache();
2395
2395
  this.comps.setNullComputedCache();
@@ -2434,15 +2434,15 @@ class App {
2434
2434
  this._evictCacheId = null;
2435
2435
  }
2436
2436
  }
2437
- function injectCss(nodeId, style) {
2437
+ function injectCss(nodeId, style, styleTarget = document.head) {
2438
2438
  const styleNode = document.createElement("style");
2439
- const currentNodeWithId = document.head.querySelector(`#${nodeId}`);
2439
+ const currentNodeWithId = styleTarget.querySelector(`#${nodeId}`);
2440
2440
  if (currentNodeWithId) {
2441
- document.head.removeChild(currentNodeWithId);
2441
+ styleTarget.removeChild(currentNodeWithId);
2442
2442
  }
2443
2443
  styleNode.id = nodeId;
2444
2444
  styleNode.innerHTML = style;
2445
- document.head.appendChild(styleNode);
2445
+ styleTarget.appendChild(styleNode);
2446
2446
  }
2447
2447
  function getClosestDropTarget(target, rootNode, count) {
2448
2448
  let node = target;
@@ -7449,12 +7449,6 @@ seqInfoByClass.set(KList, ["data-sk", klistEntries]);
7449
7449
  function isHtmlAttribute(propName) {
7450
7450
  return propName[4] === "-" && (propName[0] === "d" || propName[0] === "a");
7451
7451
  }
7452
- function getDomProp(node, propName) {
7453
- return node[propName];
7454
- }
7455
- function setDomProp(node, propName, value) {
7456
- node[propName] = value;
7457
- }
7458
7452
  function applyProperties(node, props, previous) {
7459
7453
  for (const propName in props) {
7460
7454
  const propValue = props[propName];
@@ -7462,37 +7456,42 @@ function applyProperties(node, props, previous) {
7462
7456
  removeProperty(node, propName, previous);
7463
7457
  } else if (isHtmlAttribute(propName)) {
7464
7458
  node.setAttribute(propName, propValue);
7459
+ } else if (propName === "dangerouslySetInnerHTML") {
7460
+ node.innerHTML = propValue.__html ?? "";
7461
+ } else if (typeof propValue === "object" && propValue !== null) {
7462
+ patchObject(node, previous, propName, propValue);
7463
+ } else if (propName === "className") {
7464
+ node.setAttribute("class", propValue);
7465
7465
  } else {
7466
- if (typeof propValue === "object" && propValue !== null) {
7467
- patchObject(node, previous, propName, propValue);
7468
- } else {
7469
- setDomProp(node, propName, propValue);
7470
- }
7466
+ node[propName] = propValue;
7471
7467
  }
7472
7468
  }
7473
7469
  }
7474
7470
  function removeProperty(node, propName, previous) {
7475
7471
  const previousValue = previous[propName];
7476
- if (isHtmlAttribute(propName)) {
7472
+ if (propName === "dangerouslySetInnerHTML") {
7473
+ node.innerHTML = "";
7474
+ } else if (isHtmlAttribute(propName)) {
7477
7475
  node.removeAttribute(propName);
7478
7476
  } else if (typeof previousValue === "string") {
7479
- setDomProp(node, propName, "");
7477
+ if (propName !== "className")
7478
+ node[propName] = "";
7480
7479
  const attrName = propName === "className" ? "class" : propName === "htmlFor" ? "for" : propName;
7481
7480
  node.removeAttribute(attrName);
7482
7481
  } else {
7483
- setDomProp(node, propName, null);
7482
+ node[propName] = null;
7484
7483
  }
7485
7484
  }
7486
7485
  function patchObject(node, previous, propName, propValue) {
7487
7486
  const previousValue = previous?.[propName];
7488
7487
  if (previousValue && typeof previousValue === "object" && Object.getPrototypeOf(previousValue) !== Object.getPrototypeOf(propValue)) {
7489
- setDomProp(node, propName, propValue);
7488
+ node[propName] = propValue;
7490
7489
  return;
7491
7490
  }
7492
- let current = getDomProp(node, propName);
7491
+ let current = node[propName];
7493
7492
  if (typeof current !== "object" || current === null) {
7494
- setDomProp(node, propName, {});
7495
- current = getDomProp(node, propName);
7493
+ node[propName] = {};
7494
+ current = node[propName];
7496
7495
  }
7497
7496
  const target = current;
7498
7497
  for (const k in propValue) {
@@ -7500,23 +7499,6 @@ function patchObject(node, previous, propName, propValue) {
7500
7499
  }
7501
7500
  }
7502
7501
 
7503
- class Warning {
7504
- constructor(type, message) {
7505
- this.type = type;
7506
- this.message = message;
7507
- }
7508
- }
7509
-
7510
- class DuplicatedKeysWarning extends Warning {
7511
- constructor(duplicatedKeys, parentTag, parentIndex) {
7512
- const keys = [...duplicatedKeys].join(", ");
7513
- super("DuplicatedKeys", `Duplicate keys found: [${keys}] in ${parentTag || "fragment"} at index ${parentIndex}. Nodes with duplicated keys are matched positionally.`);
7514
- this.duplicatedKeys = duplicatedKeys;
7515
- this.parentTag = parentTag;
7516
- this.parentIndex = parentIndex;
7517
- }
7518
- }
7519
-
7520
7502
  class VBase {
7521
7503
  isEqualTo(other) {
7522
7504
  return this === other;
@@ -7525,12 +7507,8 @@ class VBase {
7525
7507
  return null;
7526
7508
  }
7527
7509
  }
7528
- function getKey(node) {
7529
- return node instanceof VNode2 ? node.key : undefined;
7530
- }
7531
- function effectiveKey(node, duplicatedKeys) {
7532
- const key = getKey(node);
7533
- return key && duplicatedKeys?.has(key) ? undefined : key;
7510
+ function getKey(child) {
7511
+ return child instanceof VNode2 ? child.key : undefined;
7534
7512
  }
7535
7513
  function isIterable(obj) {
7536
7514
  return obj != null && typeof obj !== "string" && typeof obj[Symbol.iterator] === "function";
@@ -7627,13 +7605,12 @@ class VNode2 extends VBase {
7627
7605
  this.childs = childs ?? [];
7628
7606
  this.key = key != null ? String(key) : undefined;
7629
7607
  this.namespace = typeof namespace === "string" ? namespace : null;
7630
- this.attrCount = Object.keys(this.attrs).length;
7631
7608
  }
7632
7609
  get nodeType() {
7633
7610
  return 1;
7634
7611
  }
7635
7612
  isEqualTo(other) {
7636
- if (!(other instanceof VNode2) || this.tag !== other.tag || this.key !== other.key || this.namespace !== other.namespace || this.attrCount !== other.attrCount || this.childs.length !== other.childs.length) {
7613
+ if (!(other instanceof VNode2) || this.tag !== other.tag || this.key !== other.key || this.namespace !== other.namespace || this.childs.length !== other.childs.length) {
7637
7614
  return false;
7638
7615
  }
7639
7616
  for (const key in this.attrs) {
@@ -7641,6 +7618,11 @@ class VNode2 extends VBase {
7641
7618
  return false;
7642
7619
  }
7643
7620
  }
7621
+ for (const key in other.attrs) {
7622
+ if (!Object.hasOwn(this.attrs, key)) {
7623
+ return false;
7624
+ }
7625
+ }
7644
7626
  for (let i = 0;i < this.childs.length; i++) {
7645
7627
  if (!this.childs[i].isEqualTo(other.childs[i])) {
7646
7628
  return false;
@@ -7695,155 +7677,6 @@ function diffProps(a, b) {
7695
7677
  }
7696
7678
  return diff;
7697
7679
  }
7698
- function reorder(oldChildren, newChildren) {
7699
- const rawNew = keyIndex(newChildren);
7700
- if (rawNew.free.length === newChildren.length) {
7701
- return {
7702
- children: newChildren,
7703
- moves: null,
7704
- duplicatedKeys: rawNew.duplicatedKeys
7705
- };
7706
- }
7707
- const rawOld = keyIndex(oldChildren);
7708
- const duplicatedKeys = rawNew.duplicatedKeys || rawOld.duplicatedKeys ? new Set([...rawNew.duplicatedKeys || [], ...rawOld.duplicatedKeys || []]) : null;
7709
- if (rawOld.free.length === oldChildren.length) {
7710
- return {
7711
- children: newChildren,
7712
- moves: null,
7713
- duplicatedKeys
7714
- };
7715
- }
7716
- let newKeys;
7717
- let newFree;
7718
- let oldKeys;
7719
- if (duplicatedKeys) {
7720
- const updatedNew = keyIndex(newChildren, duplicatedKeys);
7721
- newKeys = updatedNew.keys;
7722
- newFree = updatedNew.free;
7723
- oldKeys = keyIndex(oldChildren, duplicatedKeys).keys;
7724
- } else {
7725
- newKeys = rawNew.keys;
7726
- newFree = rawNew.free;
7727
- oldKeys = rawOld.keys;
7728
- }
7729
- const reordered = [];
7730
- let freeIndex = 0;
7731
- const freeCount = newFree.length;
7732
- let deletedItems = 0;
7733
- for (let i = 0;i < oldChildren.length; i++) {
7734
- const oldItem = oldChildren[i];
7735
- const oldKey = effectiveKey(oldItem, duplicatedKeys);
7736
- if (oldKey) {
7737
- if (Object.hasOwn(newKeys, oldKey)) {
7738
- const itemIndex = newKeys[oldKey];
7739
- reordered.push(newChildren[itemIndex]);
7740
- } else {
7741
- deletedItems++;
7742
- reordered.push(null);
7743
- }
7744
- } else {
7745
- if (freeIndex < freeCount) {
7746
- const itemIndex = newFree[freeIndex++];
7747
- reordered.push(newChildren[itemIndex]);
7748
- } else {
7749
- deletedItems++;
7750
- reordered.push(null);
7751
- }
7752
- }
7753
- }
7754
- const lastFreeIndex = freeIndex >= newFree.length ? newChildren.length : newFree[freeIndex];
7755
- for (let j = 0;j < newChildren.length; j++) {
7756
- const newItem = newChildren[j];
7757
- const newKey = effectiveKey(newItem, duplicatedKeys);
7758
- if (newKey) {
7759
- if (!Object.hasOwn(oldKeys, newKey)) {
7760
- reordered.push(newItem);
7761
- }
7762
- } else if (j >= lastFreeIndex) {
7763
- reordered.push(newItem);
7764
- }
7765
- }
7766
- const moves = computeMoves(reordered, newChildren, newKeys, duplicatedKeys, deletedItems);
7767
- return { children: reordered, moves, duplicatedKeys };
7768
- }
7769
- function computeMoves(reordered, newChildren, newKeys, duplicatedKeys, deletedItems) {
7770
- const simulate = reordered.slice();
7771
- let simulateIndex = 0;
7772
- const removes = [];
7773
- const inserts = [];
7774
- const wantedKeys = new Array(newChildren.length);
7775
- for (let i = 0;i < newChildren.length; i++) {
7776
- wantedKeys[i] = effectiveKey(newChildren[i], duplicatedKeys);
7777
- }
7778
- for (let k = 0;k < newChildren.length; ) {
7779
- const wantedKey = wantedKeys[k];
7780
- let simulateItem = simulate[simulateIndex];
7781
- let simulateKey = effectiveKey(simulateItem, duplicatedKeys);
7782
- while (simulateItem === null && simulate.length) {
7783
- simulate.splice(simulateIndex, 1);
7784
- removes.push({ from: simulateIndex, key: null });
7785
- simulateItem = simulate[simulateIndex];
7786
- simulateKey = effectiveKey(simulateItem, duplicatedKeys);
7787
- }
7788
- if (simulateItem && simulateKey === wantedKey) {
7789
- simulateIndex++;
7790
- k++;
7791
- continue;
7792
- }
7793
- if (wantedKey) {
7794
- if (simulateKey && newKeys[simulateKey] !== k + 1) {
7795
- simulate.splice(simulateIndex, 1);
7796
- removes.push({ from: simulateIndex, key: simulateKey });
7797
- simulateItem = simulate[simulateIndex];
7798
- simulateKey = effectiveKey(simulateItem, duplicatedKeys);
7799
- if (simulateItem && simulateKey === wantedKey) {
7800
- simulateIndex++;
7801
- k++;
7802
- continue;
7803
- }
7804
- }
7805
- inserts.push({ key: wantedKey, to: k });
7806
- k++;
7807
- continue;
7808
- }
7809
- if (simulateKey) {
7810
- simulate.splice(simulateIndex, 1);
7811
- removes.push({ from: simulateIndex, key: simulateKey });
7812
- continue;
7813
- }
7814
- k++;
7815
- }
7816
- while (simulateIndex < simulate.length) {
7817
- const simulateItem = simulate[simulateIndex];
7818
- simulate.splice(simulateIndex, 1);
7819
- removes.push({
7820
- from: simulateIndex,
7821
- key: effectiveKey(simulateItem, duplicatedKeys)
7822
- });
7823
- }
7824
- if (removes.length === deletedItems && !inserts.length) {
7825
- return null;
7826
- }
7827
- return { removes, inserts };
7828
- }
7829
- function keyIndex(children, excludeKeys) {
7830
- const keys = {};
7831
- const free = [];
7832
- let duplicatedKeys = null;
7833
- for (let i = 0;i < children.length; i++) {
7834
- const key = getKey(children[i]);
7835
- if (key && !excludeKeys?.has(key)) {
7836
- if (key in keys) {
7837
- duplicatedKeys ??= new Set;
7838
- duplicatedKeys.add(key);
7839
- }
7840
- keys[key] = i;
7841
- } else {
7842
- free.push(i);
7843
- }
7844
- }
7845
- return { keys, free, duplicatedKeys };
7846
- }
7847
7680
  function replaceNode(domNode, vnode, options) {
7848
7681
  const parentNode = domNode.parentNode;
7849
7682
  const newNode = vnode.toDom(options);
@@ -7864,7 +7697,9 @@ function morphNode(domNode, source, target, opts) {
7864
7697
  if (propsDiff) {
7865
7698
  applyProperties(domNode, propsDiff, source.attrs);
7866
7699
  }
7867
- morphChildren(domNode, source.childs, target.childs, source.tag, opts);
7700
+ if (!target.attrs.dangerouslySetInnerHTML) {
7701
+ morphChildren(domNode, source.childs, target.childs, source.tag, opts);
7702
+ }
7868
7703
  return domNode;
7869
7704
  }
7870
7705
  if (source instanceof VFragment && target instanceof VFragment) {
@@ -7873,7 +7708,7 @@ function morphNode(domNode, source, target, opts) {
7873
7708
  }
7874
7709
  return replaceNode(domNode, target, opts);
7875
7710
  }
7876
- function morphChildren(parentDom, oldChilds, newChilds, parentTag, opts) {
7711
+ function morphChildren(parentDom, oldChilds, newChilds, _parentTag, opts) {
7877
7712
  if (oldChilds.length === 0) {
7878
7713
  for (const child of newChilds) {
7879
7714
  const node = child.toDom(opts);
@@ -7888,58 +7723,50 @@ function morphChildren(parentDom, oldChilds, newChilds, parentTag, opts) {
7888
7723
  }
7889
7724
  return;
7890
7725
  }
7891
- const orderedSet = reorder(oldChilds, newChilds);
7892
- const reorderedChilds = orderedSet.children;
7893
- if (orderedSet.duplicatedKeys && opts.onWarning) {
7894
- opts.onWarning(new DuplicatedKeysWarning(orderedSet.duplicatedKeys, parentTag, 0));
7895
- }
7896
- const domChildren = Array.from(parentDom.childNodes);
7897
- const oldLen = oldChilds.length;
7898
- const reorderedLen = reorderedChilds.length;
7899
- const len = Math.max(oldLen, reorderedLen);
7900
- const toRemove = [];
7901
- for (let i = 0;i < len; i++) {
7902
- const leftNode = oldChilds[i];
7903
- const rightNode = reorderedChilds[i];
7904
- if (!leftNode && rightNode) {
7905
- const newNode = rightNode.toDom(opts);
7906
- if (newNode)
7907
- parentDom.appendChild(newNode);
7908
- } else if (leftNode && rightNode) {
7909
- const domChild = domChildren[i];
7910
- if (domChild) {
7911
- morphNode(domChild, leftNode, rightNode, opts);
7912
- }
7913
- } else if (leftNode && !rightNode) {
7914
- if (!orderedSet.moves && domChildren[i]) {
7915
- toRemove.push(domChildren[i]);
7916
- }
7917
- }
7918
- }
7919
- for (const node of toRemove) {
7920
- if (node.parentNode === parentDom) {
7921
- parentDom.removeChild(node);
7922
- }
7923
- }
7924
- if (orderedSet.moves) {
7925
- applyMoves(parentDom, orderedSet.moves);
7926
- }
7927
- }
7928
- function applyMoves(domNode, moves) {
7929
- const childNodes = domNode.childNodes;
7930
- const keyMap = {};
7931
- for (const remove2 of moves.removes) {
7932
- const node = childNodes[remove2.from];
7933
- if (remove2.key)
7934
- keyMap[remove2.key] = node;
7935
- domNode.removeChild(node);
7936
- }
7937
- let length = childNodes.length;
7938
- for (let j = 0;j < moves.inserts.length; j++) {
7939
- const insert = moves.inserts[j];
7940
- const node = keyMap[insert.key];
7941
- if (node) {
7942
- domNode.insertBefore(node, insert.to >= length++ ? null : childNodes[insert.to]);
7726
+ const domNodes = Array.from(parentDom.childNodes);
7727
+ const oldKeyMap = {};
7728
+ for (let i = 0;i < oldChilds.length; i++) {
7729
+ const key = getKey(oldChilds[i]);
7730
+ if (key != null)
7731
+ oldKeyMap[key] = i;
7732
+ }
7733
+ const used = new Uint8Array(oldChilds.length);
7734
+ let unkeyedCursor = 0;
7735
+ for (let j = 0;j < newChilds.length; j++) {
7736
+ const newChild = newChilds[j];
7737
+ const newKey = getKey(newChild);
7738
+ let oldIdx = -1;
7739
+ if (newKey != null) {
7740
+ if (newKey in oldKeyMap && !used[oldKeyMap[newKey]]) {
7741
+ oldIdx = oldKeyMap[newKey];
7742
+ }
7743
+ } else {
7744
+ while (unkeyedCursor < oldChilds.length) {
7745
+ if (!used[unkeyedCursor] && getKey(oldChilds[unkeyedCursor]) == null) {
7746
+ oldIdx = unkeyedCursor++;
7747
+ break;
7748
+ }
7749
+ unkeyedCursor++;
7750
+ }
7751
+ }
7752
+ if (oldIdx >= 0) {
7753
+ used[oldIdx] = 1;
7754
+ const dom = domNodes[oldIdx];
7755
+ const newDom = morphNode(dom, oldChilds[oldIdx], newChild, opts);
7756
+ const ref = parentDom.childNodes[j] ?? null;
7757
+ if (newDom !== ref)
7758
+ parentDom.insertBefore(newDom, ref);
7759
+ } else {
7760
+ const dom = newChild.toDom(opts);
7761
+ if (dom) {
7762
+ const ref = parentDom.childNodes[j] ?? null;
7763
+ parentDom.insertBefore(dom, ref);
7764
+ }
7765
+ }
7766
+ }
7767
+ for (let i = oldChilds.length - 1;i >= 0; i--) {
7768
+ if (!used[i] && domNodes[i].parentNode === parentDom) {
7769
+ parentDom.removeChild(domNodes[i]);
7943
7770
  }
7944
7771
  }
7945
7772
  }