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.
package/dist/tutuca.js CHANGED
@@ -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;
@@ -6897,12 +6897,6 @@ function basicGetSeqInfo(seq) {
6897
6897
  function isHtmlAttribute(propName) {
6898
6898
  return propName[4] === "-" && (propName[0] === "d" || propName[0] === "a");
6899
6899
  }
6900
- function getDomProp(node, propName) {
6901
- return node[propName];
6902
- }
6903
- function setDomProp(node, propName, value) {
6904
- node[propName] = value;
6905
- }
6906
6900
  function applyProperties(node, props, previous) {
6907
6901
  for (const propName in props) {
6908
6902
  const propValue = props[propName];
@@ -6910,37 +6904,42 @@ function applyProperties(node, props, previous) {
6910
6904
  removeProperty(node, propName, previous);
6911
6905
  } else if (isHtmlAttribute(propName)) {
6912
6906
  node.setAttribute(propName, propValue);
6907
+ } else if (propName === "dangerouslySetInnerHTML") {
6908
+ node.innerHTML = propValue.__html ?? "";
6909
+ } else if (typeof propValue === "object" && propValue !== null) {
6910
+ patchObject(node, previous, propName, propValue);
6911
+ } else if (propName === "className") {
6912
+ node.setAttribute("class", propValue);
6913
6913
  } else {
6914
- if (typeof propValue === "object" && propValue !== null) {
6915
- patchObject(node, previous, propName, propValue);
6916
- } else {
6917
- setDomProp(node, propName, propValue);
6918
- }
6914
+ node[propName] = propValue;
6919
6915
  }
6920
6916
  }
6921
6917
  }
6922
6918
  function removeProperty(node, propName, previous) {
6923
6919
  const previousValue = previous[propName];
6924
- if (isHtmlAttribute(propName)) {
6920
+ if (propName === "dangerouslySetInnerHTML") {
6921
+ node.innerHTML = "";
6922
+ } else if (isHtmlAttribute(propName)) {
6925
6923
  node.removeAttribute(propName);
6926
6924
  } else if (typeof previousValue === "string") {
6927
- setDomProp(node, propName, "");
6925
+ if (propName !== "className")
6926
+ node[propName] = "";
6928
6927
  const attrName = propName === "className" ? "class" : propName === "htmlFor" ? "for" : propName;
6929
6928
  node.removeAttribute(attrName);
6930
6929
  } else {
6931
- setDomProp(node, propName, null);
6930
+ node[propName] = null;
6932
6931
  }
6933
6932
  }
6934
6933
  function patchObject(node, previous, propName, propValue) {
6935
6934
  const previousValue = previous?.[propName];
6936
6935
  if (previousValue && typeof previousValue === "object" && Object.getPrototypeOf(previousValue) !== Object.getPrototypeOf(propValue)) {
6937
- setDomProp(node, propName, propValue);
6936
+ node[propName] = propValue;
6938
6937
  return;
6939
6938
  }
6940
- let current = getDomProp(node, propName);
6939
+ let current = node[propName];
6941
6940
  if (typeof current !== "object" || current === null) {
6942
- setDomProp(node, propName, {});
6943
- current = getDomProp(node, propName);
6941
+ node[propName] = {};
6942
+ current = node[propName];
6944
6943
  }
6945
6944
  const target = current;
6946
6945
  for (const k in propValue) {
@@ -6948,23 +6947,6 @@ function patchObject(node, previous, propName, propValue) {
6948
6947
  }
6949
6948
  }
6950
6949
 
6951
- class Warning {
6952
- constructor(type, message) {
6953
- this.type = type;
6954
- this.message = message;
6955
- }
6956
- }
6957
-
6958
- class DuplicatedKeysWarning extends Warning {
6959
- constructor(duplicatedKeys, parentTag, parentIndex) {
6960
- const keys = [...duplicatedKeys].join(", ");
6961
- super("DuplicatedKeys", `Duplicate keys found: [${keys}] in ${parentTag || "fragment"} at index ${parentIndex}. Nodes with duplicated keys are matched positionally.`);
6962
- this.duplicatedKeys = duplicatedKeys;
6963
- this.parentTag = parentTag;
6964
- this.parentIndex = parentIndex;
6965
- }
6966
- }
6967
-
6968
6950
  class VBase {
6969
6951
  isEqualTo(other) {
6970
6952
  return this === other;
@@ -6973,12 +6955,8 @@ class VBase {
6973
6955
  return null;
6974
6956
  }
6975
6957
  }
6976
- function getKey(node) {
6977
- return node instanceof VNode2 ? node.key : undefined;
6978
- }
6979
- function effectiveKey(node, duplicatedKeys) {
6980
- const key = getKey(node);
6981
- return key && duplicatedKeys?.has(key) ? undefined : key;
6958
+ function getKey(child) {
6959
+ return child instanceof VNode2 ? child.key : undefined;
6982
6960
  }
6983
6961
  function isIterable(obj) {
6984
6962
  return obj != null && typeof obj !== "string" && typeof obj[Symbol.iterator] === "function";
@@ -7075,13 +7053,12 @@ class VNode2 extends VBase {
7075
7053
  this.childs = childs ?? [];
7076
7054
  this.key = key != null ? String(key) : undefined;
7077
7055
  this.namespace = typeof namespace === "string" ? namespace : null;
7078
- this.attrCount = Object.keys(this.attrs).length;
7079
7056
  }
7080
7057
  get nodeType() {
7081
7058
  return 1;
7082
7059
  }
7083
7060
  isEqualTo(other) {
7084
- 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) {
7061
+ if (!(other instanceof VNode2) || this.tag !== other.tag || this.key !== other.key || this.namespace !== other.namespace || this.childs.length !== other.childs.length) {
7085
7062
  return false;
7086
7063
  }
7087
7064
  for (const key in this.attrs) {
@@ -7089,6 +7066,11 @@ class VNode2 extends VBase {
7089
7066
  return false;
7090
7067
  }
7091
7068
  }
7069
+ for (const key in other.attrs) {
7070
+ if (!Object.hasOwn(this.attrs, key)) {
7071
+ return false;
7072
+ }
7073
+ }
7092
7074
  for (let i = 0;i < this.childs.length; i++) {
7093
7075
  if (!this.childs[i].isEqualTo(other.childs[i])) {
7094
7076
  return false;
@@ -7143,155 +7125,6 @@ function diffProps(a, b) {
7143
7125
  }
7144
7126
  return diff;
7145
7127
  }
7146
- function reorder(oldChildren, newChildren) {
7147
- const rawNew = keyIndex(newChildren);
7148
- if (rawNew.free.length === newChildren.length) {
7149
- return {
7150
- children: newChildren,
7151
- moves: null,
7152
- duplicatedKeys: rawNew.duplicatedKeys
7153
- };
7154
- }
7155
- const rawOld = keyIndex(oldChildren);
7156
- const duplicatedKeys = rawNew.duplicatedKeys || rawOld.duplicatedKeys ? new Set([...rawNew.duplicatedKeys || [], ...rawOld.duplicatedKeys || []]) : null;
7157
- if (rawOld.free.length === oldChildren.length) {
7158
- return {
7159
- children: newChildren,
7160
- moves: null,
7161
- duplicatedKeys
7162
- };
7163
- }
7164
- let newKeys;
7165
- let newFree;
7166
- let oldKeys;
7167
- if (duplicatedKeys) {
7168
- const updatedNew = keyIndex(newChildren, duplicatedKeys);
7169
- newKeys = updatedNew.keys;
7170
- newFree = updatedNew.free;
7171
- oldKeys = keyIndex(oldChildren, duplicatedKeys).keys;
7172
- } else {
7173
- newKeys = rawNew.keys;
7174
- newFree = rawNew.free;
7175
- oldKeys = rawOld.keys;
7176
- }
7177
- const reordered = [];
7178
- let freeIndex = 0;
7179
- const freeCount = newFree.length;
7180
- let deletedItems = 0;
7181
- for (let i = 0;i < oldChildren.length; i++) {
7182
- const oldItem = oldChildren[i];
7183
- const oldKey = effectiveKey(oldItem, duplicatedKeys);
7184
- if (oldKey) {
7185
- if (Object.hasOwn(newKeys, oldKey)) {
7186
- const itemIndex = newKeys[oldKey];
7187
- reordered.push(newChildren[itemIndex]);
7188
- } else {
7189
- deletedItems++;
7190
- reordered.push(null);
7191
- }
7192
- } else {
7193
- if (freeIndex < freeCount) {
7194
- const itemIndex = newFree[freeIndex++];
7195
- reordered.push(newChildren[itemIndex]);
7196
- } else {
7197
- deletedItems++;
7198
- reordered.push(null);
7199
- }
7200
- }
7201
- }
7202
- const lastFreeIndex = freeIndex >= newFree.length ? newChildren.length : newFree[freeIndex];
7203
- for (let j = 0;j < newChildren.length; j++) {
7204
- const newItem = newChildren[j];
7205
- const newKey = effectiveKey(newItem, duplicatedKeys);
7206
- if (newKey) {
7207
- if (!Object.hasOwn(oldKeys, newKey)) {
7208
- reordered.push(newItem);
7209
- }
7210
- } else if (j >= lastFreeIndex) {
7211
- reordered.push(newItem);
7212
- }
7213
- }
7214
- const moves = computeMoves(reordered, newChildren, newKeys, duplicatedKeys, deletedItems);
7215
- return { children: reordered, moves, duplicatedKeys };
7216
- }
7217
- function computeMoves(reordered, newChildren, newKeys, duplicatedKeys, deletedItems) {
7218
- const simulate = reordered.slice();
7219
- let simulateIndex = 0;
7220
- const removes = [];
7221
- const inserts = [];
7222
- const wantedKeys = new Array(newChildren.length);
7223
- for (let i = 0;i < newChildren.length; i++) {
7224
- wantedKeys[i] = effectiveKey(newChildren[i], duplicatedKeys);
7225
- }
7226
- for (let k = 0;k < newChildren.length; ) {
7227
- const wantedKey = wantedKeys[k];
7228
- let simulateItem = simulate[simulateIndex];
7229
- let simulateKey = effectiveKey(simulateItem, duplicatedKeys);
7230
- while (simulateItem === null && simulate.length) {
7231
- simulate.splice(simulateIndex, 1);
7232
- removes.push({ from: simulateIndex, key: null });
7233
- simulateItem = simulate[simulateIndex];
7234
- simulateKey = effectiveKey(simulateItem, duplicatedKeys);
7235
- }
7236
- if (simulateItem && simulateKey === wantedKey) {
7237
- simulateIndex++;
7238
- k++;
7239
- continue;
7240
- }
7241
- if (wantedKey) {
7242
- if (simulateKey && newKeys[simulateKey] !== k + 1) {
7243
- simulate.splice(simulateIndex, 1);
7244
- removes.push({ from: simulateIndex, key: simulateKey });
7245
- simulateItem = simulate[simulateIndex];
7246
- simulateKey = effectiveKey(simulateItem, duplicatedKeys);
7247
- if (simulateItem && simulateKey === wantedKey) {
7248
- simulateIndex++;
7249
- k++;
7250
- continue;
7251
- }
7252
- }
7253
- inserts.push({ key: wantedKey, to: k });
7254
- k++;
7255
- continue;
7256
- }
7257
- if (simulateKey) {
7258
- simulate.splice(simulateIndex, 1);
7259
- removes.push({ from: simulateIndex, key: simulateKey });
7260
- continue;
7261
- }
7262
- k++;
7263
- }
7264
- while (simulateIndex < simulate.length) {
7265
- const simulateItem = simulate[simulateIndex];
7266
- simulate.splice(simulateIndex, 1);
7267
- removes.push({
7268
- from: simulateIndex,
7269
- key: effectiveKey(simulateItem, duplicatedKeys)
7270
- });
7271
- }
7272
- if (removes.length === deletedItems && !inserts.length) {
7273
- return null;
7274
- }
7275
- return { removes, inserts };
7276
- }
7277
- function keyIndex(children, excludeKeys) {
7278
- const keys = {};
7279
- const free = [];
7280
- let duplicatedKeys = null;
7281
- for (let i = 0;i < children.length; i++) {
7282
- const key = getKey(children[i]);
7283
- if (key && !excludeKeys?.has(key)) {
7284
- if (key in keys) {
7285
- duplicatedKeys ??= new Set;
7286
- duplicatedKeys.add(key);
7287
- }
7288
- keys[key] = i;
7289
- } else {
7290
- free.push(i);
7291
- }
7292
- }
7293
- return { keys, free, duplicatedKeys };
7294
- }
7295
7128
  function replaceNode(domNode, vnode, options) {
7296
7129
  const parentNode = domNode.parentNode;
7297
7130
  const newNode = vnode.toDom(options);
@@ -7312,7 +7145,9 @@ function morphNode(domNode, source, target, opts) {
7312
7145
  if (propsDiff) {
7313
7146
  applyProperties(domNode, propsDiff, source.attrs);
7314
7147
  }
7315
- morphChildren(domNode, source.childs, target.childs, source.tag, opts);
7148
+ if (!target.attrs.dangerouslySetInnerHTML) {
7149
+ morphChildren(domNode, source.childs, target.childs, source.tag, opts);
7150
+ }
7316
7151
  return domNode;
7317
7152
  }
7318
7153
  if (source instanceof VFragment && target instanceof VFragment) {
@@ -7321,7 +7156,7 @@ function morphNode(domNode, source, target, opts) {
7321
7156
  }
7322
7157
  return replaceNode(domNode, target, opts);
7323
7158
  }
7324
- function morphChildren(parentDom, oldChilds, newChilds, parentTag, opts) {
7159
+ function morphChildren(parentDom, oldChilds, newChilds, _parentTag, opts) {
7325
7160
  if (oldChilds.length === 0) {
7326
7161
  for (const child of newChilds) {
7327
7162
  const node = child.toDom(opts);
@@ -7336,58 +7171,50 @@ function morphChildren(parentDom, oldChilds, newChilds, parentTag, opts) {
7336
7171
  }
7337
7172
  return;
7338
7173
  }
7339
- const orderedSet = reorder(oldChilds, newChilds);
7340
- const reorderedChilds = orderedSet.children;
7341
- if (orderedSet.duplicatedKeys && opts.onWarning) {
7342
- opts.onWarning(new DuplicatedKeysWarning(orderedSet.duplicatedKeys, parentTag, 0));
7343
- }
7344
- const domChildren = Array.from(parentDom.childNodes);
7345
- const oldLen = oldChilds.length;
7346
- const reorderedLen = reorderedChilds.length;
7347
- const len = Math.max(oldLen, reorderedLen);
7348
- const toRemove = [];
7349
- for (let i = 0;i < len; i++) {
7350
- const leftNode = oldChilds[i];
7351
- const rightNode = reorderedChilds[i];
7352
- if (!leftNode && rightNode) {
7353
- const newNode = rightNode.toDom(opts);
7354
- if (newNode)
7355
- parentDom.appendChild(newNode);
7356
- } else if (leftNode && rightNode) {
7357
- const domChild = domChildren[i];
7358
- if (domChild) {
7359
- morphNode(domChild, leftNode, rightNode, opts);
7360
- }
7361
- } else if (leftNode && !rightNode) {
7362
- if (!orderedSet.moves && domChildren[i]) {
7363
- toRemove.push(domChildren[i]);
7364
- }
7365
- }
7366
- }
7367
- for (const node of toRemove) {
7368
- if (node.parentNode === parentDom) {
7369
- parentDom.removeChild(node);
7370
- }
7371
- }
7372
- if (orderedSet.moves) {
7373
- applyMoves(parentDom, orderedSet.moves);
7374
- }
7375
- }
7376
- function applyMoves(domNode, moves) {
7377
- const childNodes = domNode.childNodes;
7378
- const keyMap = {};
7379
- for (const remove2 of moves.removes) {
7380
- const node = childNodes[remove2.from];
7381
- if (remove2.key)
7382
- keyMap[remove2.key] = node;
7383
- domNode.removeChild(node);
7384
- }
7385
- let length = childNodes.length;
7386
- for (let j = 0;j < moves.inserts.length; j++) {
7387
- const insert = moves.inserts[j];
7388
- const node = keyMap[insert.key];
7389
- if (node) {
7390
- domNode.insertBefore(node, insert.to >= length++ ? null : childNodes[insert.to]);
7174
+ const domNodes = Array.from(parentDom.childNodes);
7175
+ const oldKeyMap = {};
7176
+ for (let i = 0;i < oldChilds.length; i++) {
7177
+ const key = getKey(oldChilds[i]);
7178
+ if (key != null)
7179
+ oldKeyMap[key] = i;
7180
+ }
7181
+ const used = new Uint8Array(oldChilds.length);
7182
+ let unkeyedCursor = 0;
7183
+ for (let j = 0;j < newChilds.length; j++) {
7184
+ const newChild = newChilds[j];
7185
+ const newKey = getKey(newChild);
7186
+ let oldIdx = -1;
7187
+ if (newKey != null) {
7188
+ if (newKey in oldKeyMap && !used[oldKeyMap[newKey]]) {
7189
+ oldIdx = oldKeyMap[newKey];
7190
+ }
7191
+ } else {
7192
+ while (unkeyedCursor < oldChilds.length) {
7193
+ if (!used[unkeyedCursor] && getKey(oldChilds[unkeyedCursor]) == null) {
7194
+ oldIdx = unkeyedCursor++;
7195
+ break;
7196
+ }
7197
+ unkeyedCursor++;
7198
+ }
7199
+ }
7200
+ if (oldIdx >= 0) {
7201
+ used[oldIdx] = 1;
7202
+ const dom = domNodes[oldIdx];
7203
+ const newDom = morphNode(dom, oldChilds[oldIdx], newChild, opts);
7204
+ const ref = parentDom.childNodes[j] ?? null;
7205
+ if (newDom !== ref)
7206
+ parentDom.insertBefore(newDom, ref);
7207
+ } else {
7208
+ const dom = newChild.toDom(opts);
7209
+ if (dom) {
7210
+ const ref = parentDom.childNodes[j] ?? null;
7211
+ parentDom.insertBefore(dom, ref);
7212
+ }
7213
+ }
7214
+ }
7215
+ for (let i = oldChilds.length - 1;i >= 0; i--) {
7216
+ if (!used[i] && domNodes[i].parentNode === parentDom) {
7217
+ parentDom.removeChild(domNodes[i]);
7391
7218
  }
7392
7219
  }
7393
7220
  }