veles 1.1.2 → 1.1.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.
@@ -151,6 +151,9 @@ function parseChildren({ children, htmlElement, velesNode, portal }) {
151
151
  childComponent.parentVelesElement = velesNode;
152
152
  childComponents.push(childComponent);
153
153
  } else if (childComponent.portal) {
154
+ if (!childComponent.portalAnchor) throw new Error("Portal node is missing its source anchor");
155
+ htmlElement.append(childComponent.portalAnchor);
156
+ lastInsertedNode = childComponent.portalAnchor;
154
157
  childComponent.parentVelesElement = velesNode;
155
158
  childComponents.push(childComponent);
156
159
  } else {
@@ -183,6 +186,7 @@ const FORM_VALUE_TAGS = new Set([
183
186
  "TEXTAREA",
184
187
  "SELECT"
185
188
  ]);
189
+ const ATTRIBUTE_ALIASES = { htmlfor: "for" };
186
190
  const ENUMERATED_BOOLEAN_ATTRIBUTES = {
187
191
  draggable: {
188
192
  trueValue: "true",
@@ -203,6 +207,11 @@ const ENUMERATED_BOOLEAN_ATTRIBUTES = {
203
207
  };
204
208
  function assignDomAttribute({ htmlElement, attributeName, value, previousValue }) {
205
209
  const normalizedAttributeName = attributeName.toLowerCase();
210
+ const domAttributeName = ATTRIBUTE_ALIASES[normalizedAttributeName] ?? attributeName;
211
+ if (normalizedAttributeName === "dangerouslysetinnerhtml") {
212
+ assignInnerHTML(htmlElement, value);
213
+ return;
214
+ }
206
215
  if (normalizedAttributeName === "value" && isFormValueElement(htmlElement)) {
207
216
  assignFormValueProperty(htmlElement, value);
208
217
  return;
@@ -215,7 +224,7 @@ function assignDomAttribute({ htmlElement, attributeName, value, previousValue }
215
224
  assignBooleanProperty(htmlElement, "selected", value);
216
225
  return;
217
226
  }
218
- if (attributeName === "style") {
227
+ if (normalizedAttributeName === "style") {
219
228
  assignStyle({
220
229
  value,
221
230
  previousValue,
@@ -223,21 +232,32 @@ function assignDomAttribute({ htmlElement, attributeName, value, previousValue }
223
232
  });
224
233
  return;
225
234
  }
235
+ if (typeof value === "boolean" && (normalizedAttributeName.startsWith("aria-") || normalizedAttributeName.startsWith("data-"))) {
236
+ htmlElement.setAttribute(domAttributeName, String(value));
237
+ return;
238
+ }
226
239
  if (typeof value === "boolean") {
227
240
  const enumeratedConfig = ENUMERATED_BOOLEAN_ATTRIBUTES[normalizedAttributeName];
228
241
  if (enumeratedConfig) {
229
- htmlElement.setAttribute(attributeName, value ? enumeratedConfig.trueValue : enumeratedConfig.falseValue);
242
+ htmlElement.setAttribute(domAttributeName, value ? enumeratedConfig.trueValue : enumeratedConfig.falseValue);
230
243
  return;
231
244
  }
232
- if (value) htmlElement.setAttribute(attributeName, "");
233
- else htmlElement.removeAttribute(attributeName);
245
+ if (value) htmlElement.setAttribute(domAttributeName, "");
246
+ else htmlElement.removeAttribute(domAttributeName);
234
247
  return;
235
248
  }
236
249
  if (value == null) {
237
- htmlElement.removeAttribute(attributeName);
250
+ htmlElement.removeAttribute(domAttributeName);
251
+ return;
252
+ }
253
+ htmlElement.setAttribute(domAttributeName, value);
254
+ }
255
+ function assignInnerHTML(htmlElement, value) {
256
+ if (value == null) {
257
+ htmlElement.innerHTML = "";
238
258
  return;
239
259
  }
240
- htmlElement.setAttribute(attributeName, value);
260
+ if (typeof value === "object" && "__html" in value) htmlElement.innerHTML = value.__html == null ? "" : String(value.__html);
241
261
  }
242
262
  function isFormValueElement(htmlElement) {
243
263
  return FORM_VALUE_TAGS.has(htmlElement.tagName);
@@ -326,6 +346,7 @@ function createElement(element, props = {}) {
326
346
  velesNode.childComponents = childComponents;
327
347
  velesNode.phantom = phantom;
328
348
  velesNode.portal = portal;
349
+ if (portal) velesNode.portalAnchor = document.createTextNode("");
329
350
  const mountHandlers = [];
330
351
  velesNode._privateMethods = {
331
352
  _addMountHandler(cb) {
@@ -397,10 +418,17 @@ function cleanupComponentFromPortal(componentNode) {
397
418
  //#endregion
398
419
  //#region src/fragment.ts
399
420
  function Fragment({ children }) {
400
- return createElement("div", {
421
+ const fragment = createElement("div", {
401
422
  phantom: true,
402
423
  children
403
424
  });
425
+ if (fragment.childComponents.length === 0) {
426
+ const anchor = createTextElement("");
427
+ anchor.parentVelesElement = fragment;
428
+ fragment.childComponents.push(anchor);
429
+ fragment.html.append(anchor.html);
430
+ }
431
+ return fragment;
404
432
  }
405
433
  //#endregion
406
434
  //#region src/context/index.ts
@@ -523,45 +551,43 @@ function renderTree(component, { parentVelesElement } = {}) {
523
551
  executedNode.html = component.html;
524
552
  if (parentVelesElement) executedNode.parentVelesElement = parentVelesElement;
525
553
  if (component.phantom) executedNode.phantom = component.phantom;
526
- if (component.portal) executedNode.portal = component.portal;
554
+ if (component.portal) {
555
+ if (!component.portalAnchor) throw new Error("Portal node is missing its source anchor");
556
+ executedNode.portal = component.portal;
557
+ executedNode.portalAnchor = component.portalAnchor;
558
+ }
527
559
  executedNode.childComponents = component.childComponents.map((childComponent) => renderTree(childComponent, { parentVelesElement: executedNode }));
528
560
  if (component.needExecutedVersion) component.executedVersion = executedNode;
529
561
  return executedNode;
530
562
  }
531
563
  throw new Error("Unknown component type in renderTree");
532
564
  }
565
+ function getExecutedVelesNodeSourceNode(node) {
566
+ if ("executedVelesNode" in node && node.portal) {
567
+ if (!node.portalAnchor) throw new Error("Portal node is missing its source anchor");
568
+ return node.portalAnchor;
569
+ }
570
+ return node.html;
571
+ }
533
572
  function insertNode({ velesElement, adjacentNode, parentVelesElement }) {
534
573
  if (velesElement.phantom) {
535
574
  let lastInsertedNode = null;
536
575
  velesElement.childComponents.forEach((childComponentofPhantom) => {
537
- if ("executedVelesNode" in childComponentofPhantom) {
538
- if (lastInsertedNode) lastInsertedNode.after(childComponentofPhantom.html);
539
- else if (adjacentNode) adjacentNode.after(childComponentofPhantom.html);
540
- else parentVelesElement.html.prepend(childComponentofPhantom.html);
541
- childComponentofPhantom.parentVelesElement = parentVelesElement;
542
- lastInsertedNode = childComponentofPhantom.html;
543
- } else if ("executedVelesStringElement" in childComponentofPhantom) {
544
- if (lastInsertedNode) lastInsertedNode.after(childComponentofPhantom.html);
545
- else if (adjacentNode) adjacentNode.after(childComponentofPhantom.html);
546
- else parentVelesElement.html.prepend(childComponentofPhantom.html);
547
- childComponentofPhantom.parentVelesElement = parentVelesElement;
548
- lastInsertedNode = childComponentofPhantom.html;
549
- } else {
550
- const executedNode = getExecutedComponentVelesNode(childComponentofPhantom);
551
- if (lastInsertedNode) lastInsertedNode.after(executedNode.html);
552
- else if (adjacentNode) adjacentNode.after(executedNode.html);
553
- else parentVelesElement.html.prepend(executedNode.html);
554
- executedNode.parentVelesElement = parentVelesElement;
555
- lastInsertedNode = executedNode.html;
556
- }
576
+ const lastInsertedChildNode = insertNode({
577
+ velesElement: "executedVelesComponent" in childComponentofPhantom ? getExecutedComponentVelesNode(childComponentofPhantom) : childComponentofPhantom,
578
+ adjacentNode: lastInsertedNode ?? adjacentNode,
579
+ parentVelesElement
580
+ });
581
+ if (lastInsertedChildNode) lastInsertedNode = lastInsertedChildNode;
557
582
  });
558
583
  velesElement.parentVelesElement = parentVelesElement;
559
584
  return lastInsertedNode;
560
585
  } else {
561
- if (adjacentNode) adjacentNode.after(velesElement.html);
562
- else parentVelesElement.html.prepend(velesElement.html);
586
+ const sourceNode = getExecutedVelesNodeSourceNode(velesElement);
587
+ if (adjacentNode) adjacentNode.after(sourceNode);
588
+ else parentVelesElement.html.prepend(sourceNode);
563
589
  velesElement.parentVelesElement = parentVelesElement;
564
- return velesElement.html;
590
+ return sourceNode;
565
591
  }
566
592
  }
567
593
  function getMountedNodeExecutedVersion(node, errorMessage) {
@@ -593,4 +619,4 @@ function unique(arr) {
593
619
  return resultArr;
594
620
  }
595
621
  //#endregion
596
- export { onMount as _, identity as a, addPublicContext as c, popPublicContext as d, Fragment as f, hasCurrentLifecycleContext as g, createTextElement as h, getMountedNodeExecutedVersion as i, createContext as l, assignDomAttribute as m, callUnmountHandlers as n, renderTree as o, createElement as p, getExecutedComponentVelesNode as r, unique as s, callMountHandlers as t, getCurrentContext as u, onUnmount as v };
622
+ export { hasCurrentLifecycleContext as _, getMountedNodeExecutedVersion as a, unique as c, getCurrentContext as d, popPublicContext as f, createTextElement as g, assignDomAttribute as h, getExecutedVelesNodeSourceNode as i, addPublicContext as l, createElement as m, callUnmountHandlers as n, identity as o, Fragment as p, getExecutedComponentVelesNode as r, renderTree as s, callMountHandlers as t, createContext as u, onMount as v, onUnmount as y };
@@ -151,6 +151,9 @@ function parseChildren({ children, htmlElement, velesNode, portal }) {
151
151
  childComponent.parentVelesElement = velesNode;
152
152
  childComponents.push(childComponent);
153
153
  } else if (childComponent.portal) {
154
+ if (!childComponent.portalAnchor) throw new Error("Portal node is missing its source anchor");
155
+ htmlElement.append(childComponent.portalAnchor);
156
+ lastInsertedNode = childComponent.portalAnchor;
154
157
  childComponent.parentVelesElement = velesNode;
155
158
  childComponents.push(childComponent);
156
159
  } else {
@@ -183,6 +186,7 @@ const FORM_VALUE_TAGS = new Set([
183
186
  "TEXTAREA",
184
187
  "SELECT"
185
188
  ]);
189
+ const ATTRIBUTE_ALIASES = { htmlfor: "for" };
186
190
  const ENUMERATED_BOOLEAN_ATTRIBUTES = {
187
191
  draggable: {
188
192
  trueValue: "true",
@@ -203,6 +207,11 @@ const ENUMERATED_BOOLEAN_ATTRIBUTES = {
203
207
  };
204
208
  function assignDomAttribute({ htmlElement, attributeName, value, previousValue }) {
205
209
  const normalizedAttributeName = attributeName.toLowerCase();
210
+ const domAttributeName = ATTRIBUTE_ALIASES[normalizedAttributeName] ?? attributeName;
211
+ if (normalizedAttributeName === "dangerouslysetinnerhtml") {
212
+ assignInnerHTML(htmlElement, value);
213
+ return;
214
+ }
206
215
  if (normalizedAttributeName === "value" && isFormValueElement(htmlElement)) {
207
216
  assignFormValueProperty(htmlElement, value);
208
217
  return;
@@ -215,7 +224,7 @@ function assignDomAttribute({ htmlElement, attributeName, value, previousValue }
215
224
  assignBooleanProperty(htmlElement, "selected", value);
216
225
  return;
217
226
  }
218
- if (attributeName === "style") {
227
+ if (normalizedAttributeName === "style") {
219
228
  assignStyle({
220
229
  value,
221
230
  previousValue,
@@ -223,21 +232,32 @@ function assignDomAttribute({ htmlElement, attributeName, value, previousValue }
223
232
  });
224
233
  return;
225
234
  }
235
+ if (typeof value === "boolean" && (normalizedAttributeName.startsWith("aria-") || normalizedAttributeName.startsWith("data-"))) {
236
+ htmlElement.setAttribute(domAttributeName, String(value));
237
+ return;
238
+ }
226
239
  if (typeof value === "boolean") {
227
240
  const enumeratedConfig = ENUMERATED_BOOLEAN_ATTRIBUTES[normalizedAttributeName];
228
241
  if (enumeratedConfig) {
229
- htmlElement.setAttribute(attributeName, value ? enumeratedConfig.trueValue : enumeratedConfig.falseValue);
242
+ htmlElement.setAttribute(domAttributeName, value ? enumeratedConfig.trueValue : enumeratedConfig.falseValue);
230
243
  return;
231
244
  }
232
- if (value) htmlElement.setAttribute(attributeName, "");
233
- else htmlElement.removeAttribute(attributeName);
245
+ if (value) htmlElement.setAttribute(domAttributeName, "");
246
+ else htmlElement.removeAttribute(domAttributeName);
247
+ return;
248
+ }
249
+ if (value == null) {
250
+ htmlElement.removeAttribute(domAttributeName);
234
251
  return;
235
252
  }
253
+ htmlElement.setAttribute(domAttributeName, value);
254
+ }
255
+ function assignInnerHTML(htmlElement, value) {
236
256
  if (value == null) {
237
- htmlElement.removeAttribute(attributeName);
257
+ htmlElement.innerHTML = "";
238
258
  return;
239
259
  }
240
- htmlElement.setAttribute(attributeName, value);
260
+ if (typeof value === "object" && "__html" in value) htmlElement.innerHTML = value.__html == null ? "" : String(value.__html);
241
261
  }
242
262
  function isFormValueElement(htmlElement) {
243
263
  return FORM_VALUE_TAGS.has(htmlElement.tagName);
@@ -326,6 +346,7 @@ function createElement(element, props = {}) {
326
346
  velesNode.childComponents = childComponents;
327
347
  velesNode.phantom = phantom;
328
348
  velesNode.portal = portal;
349
+ if (portal) velesNode.portalAnchor = document.createTextNode("");
329
350
  const mountHandlers = [];
330
351
  velesNode._privateMethods = {
331
352
  _addMountHandler(cb) {
@@ -397,10 +418,17 @@ function cleanupComponentFromPortal(componentNode) {
397
418
  //#endregion
398
419
  //#region src/fragment.ts
399
420
  function Fragment({ children }) {
400
- return createElement("div", {
421
+ const fragment = createElement("div", {
401
422
  phantom: true,
402
423
  children
403
424
  });
425
+ if (fragment.childComponents.length === 0) {
426
+ const anchor = createTextElement("");
427
+ anchor.parentVelesElement = fragment;
428
+ fragment.childComponents.push(anchor);
429
+ fragment.html.append(anchor.html);
430
+ }
431
+ return fragment;
404
432
  }
405
433
  //#endregion
406
434
  //#region src/context/index.ts
@@ -523,45 +551,43 @@ function renderTree(component, { parentVelesElement } = {}) {
523
551
  executedNode.html = component.html;
524
552
  if (parentVelesElement) executedNode.parentVelesElement = parentVelesElement;
525
553
  if (component.phantom) executedNode.phantom = component.phantom;
526
- if (component.portal) executedNode.portal = component.portal;
554
+ if (component.portal) {
555
+ if (!component.portalAnchor) throw new Error("Portal node is missing its source anchor");
556
+ executedNode.portal = component.portal;
557
+ executedNode.portalAnchor = component.portalAnchor;
558
+ }
527
559
  executedNode.childComponents = component.childComponents.map((childComponent) => renderTree(childComponent, { parentVelesElement: executedNode }));
528
560
  if (component.needExecutedVersion) component.executedVersion = executedNode;
529
561
  return executedNode;
530
562
  }
531
563
  throw new Error("Unknown component type in renderTree");
532
564
  }
565
+ function getExecutedVelesNodeSourceNode(node) {
566
+ if ("executedVelesNode" in node && node.portal) {
567
+ if (!node.portalAnchor) throw new Error("Portal node is missing its source anchor");
568
+ return node.portalAnchor;
569
+ }
570
+ return node.html;
571
+ }
533
572
  function insertNode({ velesElement, adjacentNode, parentVelesElement }) {
534
573
  if (velesElement.phantom) {
535
574
  let lastInsertedNode = null;
536
575
  velesElement.childComponents.forEach((childComponentofPhantom) => {
537
- if ("executedVelesNode" in childComponentofPhantom) {
538
- if (lastInsertedNode) lastInsertedNode.after(childComponentofPhantom.html);
539
- else if (adjacentNode) adjacentNode.after(childComponentofPhantom.html);
540
- else parentVelesElement.html.prepend(childComponentofPhantom.html);
541
- childComponentofPhantom.parentVelesElement = parentVelesElement;
542
- lastInsertedNode = childComponentofPhantom.html;
543
- } else if ("executedVelesStringElement" in childComponentofPhantom) {
544
- if (lastInsertedNode) lastInsertedNode.after(childComponentofPhantom.html);
545
- else if (adjacentNode) adjacentNode.after(childComponentofPhantom.html);
546
- else parentVelesElement.html.prepend(childComponentofPhantom.html);
547
- childComponentofPhantom.parentVelesElement = parentVelesElement;
548
- lastInsertedNode = childComponentofPhantom.html;
549
- } else {
550
- const executedNode = getExecutedComponentVelesNode(childComponentofPhantom);
551
- if (lastInsertedNode) lastInsertedNode.after(executedNode.html);
552
- else if (adjacentNode) adjacentNode.after(executedNode.html);
553
- else parentVelesElement.html.prepend(executedNode.html);
554
- executedNode.parentVelesElement = parentVelesElement;
555
- lastInsertedNode = executedNode.html;
556
- }
576
+ const lastInsertedChildNode = insertNode({
577
+ velesElement: "executedVelesComponent" in childComponentofPhantom ? getExecutedComponentVelesNode(childComponentofPhantom) : childComponentofPhantom,
578
+ adjacentNode: lastInsertedNode ?? adjacentNode,
579
+ parentVelesElement
580
+ });
581
+ if (lastInsertedChildNode) lastInsertedNode = lastInsertedChildNode;
557
582
  });
558
583
  velesElement.parentVelesElement = parentVelesElement;
559
584
  return lastInsertedNode;
560
585
  } else {
561
- if (adjacentNode) adjacentNode.after(velesElement.html);
562
- else parentVelesElement.html.prepend(velesElement.html);
586
+ const sourceNode = getExecutedVelesNodeSourceNode(velesElement);
587
+ if (adjacentNode) adjacentNode.after(sourceNode);
588
+ else parentVelesElement.html.prepend(sourceNode);
563
589
  velesElement.parentVelesElement = parentVelesElement;
564
- return velesElement.html;
590
+ return sourceNode;
565
591
  }
566
592
  }
567
593
  function getMountedNodeExecutedVersion(node, errorMessage) {
@@ -653,6 +679,12 @@ Object.defineProperty(exports, "getExecutedComponentVelesNode", {
653
679
  return getExecutedComponentVelesNode;
654
680
  }
655
681
  });
682
+ Object.defineProperty(exports, "getExecutedVelesNodeSourceNode", {
683
+ enumerable: true,
684
+ get: function() {
685
+ return getExecutedVelesNodeSourceNode;
686
+ }
687
+ });
656
688
  Object.defineProperty(exports, "getMountedNodeExecutedVersion", {
657
689
  enumerable: true,
658
690
  get: function() {
@@ -1428,6 +1428,7 @@ type VelesElement = {
1428
1428
  html: HTMLElement;
1429
1429
  phantom?: boolean;
1430
1430
  portal?: null | HTMLElement;
1431
+ portalAnchor?: Text;
1431
1432
  needExecutedVersion?: boolean;
1432
1433
  executedVersion?: ExecutedVelesElement; // every element except the most top one should have one
1433
1434
  parentVelesElement?: VelesElement;
@@ -1443,7 +1444,8 @@ type ExecutedVelesElement = {
1443
1444
  executedVelesNode: true;
1444
1445
  html: HTMLElement;
1445
1446
  phantom?: boolean;
1446
- portal?: HTMLElement; // every element except the most top one should have one
1447
+ portal?: HTMLElement;
1448
+ portalAnchor?: Text; // every element except the most top one should have one
1447
1449
  parentVelesElement?: ExecutedVelesElement;
1448
1450
  childComponents: (ExecutedVelesElement | ExecutedVelesComponent | ExecutedVelesStringElement)[]; // not intended to be used directly
1449
1451
  _privateMethods: {
@@ -1428,6 +1428,7 @@ type VelesElement = {
1428
1428
  html: HTMLElement;
1429
1429
  phantom?: boolean;
1430
1430
  portal?: null | HTMLElement;
1431
+ portalAnchor?: Text;
1431
1432
  needExecutedVersion?: boolean;
1432
1433
  executedVersion?: ExecutedVelesElement; // every element except the most top one should have one
1433
1434
  parentVelesElement?: VelesElement;
@@ -1443,7 +1444,8 @@ type ExecutedVelesElement = {
1443
1444
  executedVelesNode: true;
1444
1445
  html: HTMLElement;
1445
1446
  phantom?: boolean;
1446
- portal?: HTMLElement; // every element except the most top one should have one
1447
+ portal?: HTMLElement;
1448
+ portalAnchor?: Text; // every element except the most top one should have one
1447
1449
  parentVelesElement?: ExecutedVelesElement;
1448
1450
  childComponents: (ExecutedVelesElement | ExecutedVelesComponent | ExecutedVelesStringElement)[]; // not intended to be used directly
1449
1451
  _privateMethods: {