@lightspeed-js/core 0.4.6 → 0.4.8

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/compile.js CHANGED
@@ -913,9 +913,9 @@ class BindingEvaluator {
913
913
  compileExpression(expr, params = []) {
914
914
  return this.compile(expr, params);
915
915
  }
916
- evaluate(expr, instance, locals = []) {
916
+ evaluate(expr, instance, locals = [], params = []) {
917
917
  try {
918
- return this.compile(expr, [])(instance.state, instance.props, this.cells.createReadProxy(), this.pendingProbe(), ...locals);
918
+ return this.compile(expr, params)(instance.state, instance.props, this.cells.createReadProxy(), this.pendingProbe(), ...locals);
919
919
  } catch (error) {
920
920
  warn(`Error evaluating "${expr}" in ${instance.id}:`, error);
921
921
  return;
@@ -1019,7 +1019,7 @@ class BindingEvaluator {
1019
1019
  binding.el.innerHTML = value == null ? "" : String(value);
1020
1020
  break;
1021
1021
  case "attr": {
1022
- const attr = binding.attr;
1022
+ const attr = svgAttributeName(binding.el, binding.attr);
1023
1023
  const aria = attr.startsWith("aria-");
1024
1024
  if (BOOLEAN_ATTRIBUTES.has(attr) && !aria) {
1025
1025
  if (value)
@@ -1132,6 +1132,70 @@ function isPlain(value) {
1132
1132
  const proto = Object.getPrototypeOf(value);
1133
1133
  return proto === Object.prototype || proto === null;
1134
1134
  }
1135
+ var SVG_NS = "http://www.w3.org/2000/svg";
1136
+ var SVG_ATTRIBUTES = new Map([
1137
+ "attributeName",
1138
+ "attributeType",
1139
+ "baseFrequency",
1140
+ "baseProfile",
1141
+ "calcMode",
1142
+ "clipPathUnits",
1143
+ "diffuseConstant",
1144
+ "edgeMode",
1145
+ "filterUnits",
1146
+ "glyphRef",
1147
+ "gradientTransform",
1148
+ "gradientUnits",
1149
+ "kernelMatrix",
1150
+ "kernelUnitLength",
1151
+ "keyPoints",
1152
+ "keySplines",
1153
+ "keyTimes",
1154
+ "lengthAdjust",
1155
+ "limitingConeAngle",
1156
+ "markerHeight",
1157
+ "markerUnits",
1158
+ "markerWidth",
1159
+ "maskContentUnits",
1160
+ "maskUnits",
1161
+ "numOctaves",
1162
+ "pathLength",
1163
+ "patternContentUnits",
1164
+ "patternTransform",
1165
+ "patternUnits",
1166
+ "pointsAtX",
1167
+ "pointsAtY",
1168
+ "pointsAtZ",
1169
+ "preserveAlpha",
1170
+ "preserveAspectRatio",
1171
+ "primitiveUnits",
1172
+ "refX",
1173
+ "refY",
1174
+ "repeatCount",
1175
+ "repeatDur",
1176
+ "requiredExtensions",
1177
+ "requiredFeatures",
1178
+ "specularConstant",
1179
+ "specularExponent",
1180
+ "spreadMethod",
1181
+ "startOffset",
1182
+ "stdDeviation",
1183
+ "stitchTiles",
1184
+ "surfaceScale",
1185
+ "systemLanguage",
1186
+ "tableValues",
1187
+ "targetX",
1188
+ "targetY",
1189
+ "textLength",
1190
+ "viewBox",
1191
+ "viewTarget",
1192
+ "xChannelSelector",
1193
+ "yChannelSelector",
1194
+ "zoomAndPan"
1195
+ ].map((name) => [name.toLowerCase(), name]));
1196
+ function svgAttributeName(el, attr) {
1197
+ return el.namespaceURI === SVG_NS ? SVG_ATTRIBUTES.get(attr) ?? attr : attr;
1198
+ }
1135
1199
  // src/runtime/dom/ForBlock.ts
1136
1200
  var TAG_NAME = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
1137
1201
  var REFUSED_TAGS = new Set([
package/dist/index.js CHANGED
@@ -485,9 +485,9 @@ class BindingEvaluator {
485
485
  compileExpression(expr, params = []) {
486
486
  return this.compile(expr, params);
487
487
  }
488
- evaluate(expr, instance, locals = []) {
488
+ evaluate(expr, instance, locals = [], params = []) {
489
489
  try {
490
- return this.compile(expr, [])(instance.state, instance.props, this.cells.createReadProxy(), this.pendingProbe(), ...locals);
490
+ return this.compile(expr, params)(instance.state, instance.props, this.cells.createReadProxy(), this.pendingProbe(), ...locals);
491
491
  } catch (error) {
492
492
  warn(`Error evaluating "${expr}" in ${instance.id}:`, error);
493
493
  return;
@@ -591,7 +591,7 @@ class BindingEvaluator {
591
591
  binding.el.innerHTML = value == null ? "" : String(value);
592
592
  break;
593
593
  case "attr": {
594
- const attr = binding.attr;
594
+ const attr = svgAttributeName(binding.el, binding.attr);
595
595
  const aria = attr.startsWith("aria-");
596
596
  if (BOOLEAN_ATTRIBUTES.has(attr) && !aria) {
597
597
  if (value)
@@ -704,6 +704,70 @@ function isPlain(value) {
704
704
  const proto = Object.getPrototypeOf(value);
705
705
  return proto === Object.prototype || proto === null;
706
706
  }
707
+ var SVG_NS = "http://www.w3.org/2000/svg";
708
+ var SVG_ATTRIBUTES = new Map([
709
+ "attributeName",
710
+ "attributeType",
711
+ "baseFrequency",
712
+ "baseProfile",
713
+ "calcMode",
714
+ "clipPathUnits",
715
+ "diffuseConstant",
716
+ "edgeMode",
717
+ "filterUnits",
718
+ "glyphRef",
719
+ "gradientTransform",
720
+ "gradientUnits",
721
+ "kernelMatrix",
722
+ "kernelUnitLength",
723
+ "keyPoints",
724
+ "keySplines",
725
+ "keyTimes",
726
+ "lengthAdjust",
727
+ "limitingConeAngle",
728
+ "markerHeight",
729
+ "markerUnits",
730
+ "markerWidth",
731
+ "maskContentUnits",
732
+ "maskUnits",
733
+ "numOctaves",
734
+ "pathLength",
735
+ "patternContentUnits",
736
+ "patternTransform",
737
+ "patternUnits",
738
+ "pointsAtX",
739
+ "pointsAtY",
740
+ "pointsAtZ",
741
+ "preserveAlpha",
742
+ "preserveAspectRatio",
743
+ "primitiveUnits",
744
+ "refX",
745
+ "refY",
746
+ "repeatCount",
747
+ "repeatDur",
748
+ "requiredExtensions",
749
+ "requiredFeatures",
750
+ "specularConstant",
751
+ "specularExponent",
752
+ "spreadMethod",
753
+ "startOffset",
754
+ "stdDeviation",
755
+ "stitchTiles",
756
+ "surfaceScale",
757
+ "systemLanguage",
758
+ "tableValues",
759
+ "targetX",
760
+ "targetY",
761
+ "textLength",
762
+ "viewBox",
763
+ "viewTarget",
764
+ "xChannelSelector",
765
+ "yChannelSelector",
766
+ "zoomAndPan"
767
+ ].map((name) => [name.toLowerCase(), name]));
768
+ function svgAttributeName(el, attr) {
769
+ return el.namespaceURI === SVG_NS ? SVG_ATTRIBUTES.get(attr) ?? attr : attr;
770
+ }
707
771
  // src/runtime/events/EventBinder.ts
708
772
  class EventBinder {
709
773
  bind(el, eventType, handlerName, owner, cleanupTarget = owner) {
@@ -1505,7 +1569,8 @@ class Mounter {
1505
1569
  outlet.replaceWith(holder);
1506
1570
  }
1507
1571
  for (const [name, nodes] of byName) {
1508
- if (!nodes.length)
1572
+ const dropped = nodes.filter((node) => node.nodeType === 1 || node.nodeType === 3 && (node.textContent ?? "").trim() !== "");
1573
+ if (!dropped.length)
1509
1574
  continue;
1510
1575
  warn(name ? `No <slot name="${name}"> to receive this content - it was dropped.` : "Content passed to a component with no unnamed <slot> - it was dropped.");
1511
1576
  }
@@ -1687,10 +1752,13 @@ class Mounter {
1687
1752
  }
1688
1753
  if (el.tagName === "SLOT") {
1689
1754
  if (!found[d] || !isSlotStart(found[d])) {
1690
- if (!this.adoptNodes(Array.from(el.childNodes), found.slice(d), context, markers)) {
1755
+ const fallback = significant(Array.from(el.childNodes));
1756
+ const countable = fallback.every((n) => n.nodeType === 3 || n.nodeType === 1 && !isBlockTemplate(n) && n.tagName !== "SLOT");
1757
+ const share = countable ? found.slice(d, d + fallback.length) : found.slice(d);
1758
+ if (!this.adoptNodes(fallback, share, context, markers)) {
1691
1759
  return false;
1692
1760
  }
1693
- d = found.length;
1761
+ d += share.length;
1694
1762
  continue;
1695
1763
  }
1696
1764
  const name = found[d].data.slice(SLOT_MARK.length);
@@ -1853,7 +1921,7 @@ class Mounter {
1853
1921
  return block;
1854
1922
  }
1855
1923
  adoptRows(block, slices, context) {
1856
- const value = this.bindings.evaluate(block.itemsExpr, context.owner, context.locals);
1924
+ const value = this.bindings.evaluate(block.itemsExpr, context.owner, context.locals, block.params);
1857
1925
  const items = block.toItems(value);
1858
1926
  if (items.length !== slices.length)
1859
1927
  return false;
@@ -2346,6 +2414,9 @@ function isBlockAnchor(node) {
2346
2414
  const data = node.data.trim();
2347
2415
  return data.startsWith("for:") || data.startsWith("if:") || data.startsWith("tag:");
2348
2416
  }
2417
+ function isBlockTemplate(el) {
2418
+ return el.hasAttribute("data-bind-for") || el.hasAttribute("data-bind-if") || el.hasAttribute("data-bind-tag");
2419
+ }
2349
2420
  function isInsignificant(node) {
2350
2421
  return node.nodeType === 3 && !(node.textContent ?? "").trim();
2351
2422
  }
package/dist/ssg.js CHANGED
@@ -504,9 +504,9 @@ class BindingEvaluator {
504
504
  compileExpression(expr, params = []) {
505
505
  return this.compile(expr, params);
506
506
  }
507
- evaluate(expr, instance, locals = []) {
507
+ evaluate(expr, instance, locals = [], params = []) {
508
508
  try {
509
- return this.compile(expr, [])(instance.state, instance.props, this.cells.createReadProxy(), this.pendingProbe(), ...locals);
509
+ return this.compile(expr, params)(instance.state, instance.props, this.cells.createReadProxy(), this.pendingProbe(), ...locals);
510
510
  } catch (error) {
511
511
  warn(`Error evaluating "${expr}" in ${instance.id}:`, error);
512
512
  return;
@@ -610,7 +610,7 @@ class BindingEvaluator {
610
610
  binding.el.innerHTML = value == null ? "" : String(value);
611
611
  break;
612
612
  case "attr": {
613
- const attr = binding.attr;
613
+ const attr = svgAttributeName(binding.el, binding.attr);
614
614
  const aria = attr.startsWith("aria-");
615
615
  if (BOOLEAN_ATTRIBUTES.has(attr) && !aria) {
616
616
  if (value)
@@ -723,6 +723,70 @@ function isPlain(value) {
723
723
  const proto = Object.getPrototypeOf(value);
724
724
  return proto === Object.prototype || proto === null;
725
725
  }
726
+ var SVG_NS = "http://www.w3.org/2000/svg";
727
+ var SVG_ATTRIBUTES = new Map([
728
+ "attributeName",
729
+ "attributeType",
730
+ "baseFrequency",
731
+ "baseProfile",
732
+ "calcMode",
733
+ "clipPathUnits",
734
+ "diffuseConstant",
735
+ "edgeMode",
736
+ "filterUnits",
737
+ "glyphRef",
738
+ "gradientTransform",
739
+ "gradientUnits",
740
+ "kernelMatrix",
741
+ "kernelUnitLength",
742
+ "keyPoints",
743
+ "keySplines",
744
+ "keyTimes",
745
+ "lengthAdjust",
746
+ "limitingConeAngle",
747
+ "markerHeight",
748
+ "markerUnits",
749
+ "markerWidth",
750
+ "maskContentUnits",
751
+ "maskUnits",
752
+ "numOctaves",
753
+ "pathLength",
754
+ "patternContentUnits",
755
+ "patternTransform",
756
+ "patternUnits",
757
+ "pointsAtX",
758
+ "pointsAtY",
759
+ "pointsAtZ",
760
+ "preserveAlpha",
761
+ "preserveAspectRatio",
762
+ "primitiveUnits",
763
+ "refX",
764
+ "refY",
765
+ "repeatCount",
766
+ "repeatDur",
767
+ "requiredExtensions",
768
+ "requiredFeatures",
769
+ "specularConstant",
770
+ "specularExponent",
771
+ "spreadMethod",
772
+ "startOffset",
773
+ "stdDeviation",
774
+ "stitchTiles",
775
+ "surfaceScale",
776
+ "systemLanguage",
777
+ "tableValues",
778
+ "targetX",
779
+ "targetY",
780
+ "textLength",
781
+ "viewBox",
782
+ "viewTarget",
783
+ "xChannelSelector",
784
+ "yChannelSelector",
785
+ "zoomAndPan"
786
+ ].map((name) => [name.toLowerCase(), name]));
787
+ function svgAttributeName(el, attr) {
788
+ return el.namespaceURI === SVG_NS ? SVG_ATTRIBUTES.get(attr) ?? attr : attr;
789
+ }
726
790
  // src/runtime/events/EventBinder.ts
727
791
  class EventBinder {
728
792
  bind(el, eventType, handlerName, owner, cleanupTarget = owner) {
@@ -1528,7 +1592,8 @@ class Mounter {
1528
1592
  outlet.replaceWith(holder);
1529
1593
  }
1530
1594
  for (const [name, nodes] of byName) {
1531
- if (!nodes.length)
1595
+ const dropped = nodes.filter((node) => node.nodeType === 1 || node.nodeType === 3 && (node.textContent ?? "").trim() !== "");
1596
+ if (!dropped.length)
1532
1597
  continue;
1533
1598
  warn(name ? `No <slot name="${name}"> to receive this content - it was dropped.` : "Content passed to a component with no unnamed <slot> - it was dropped.");
1534
1599
  }
@@ -1710,10 +1775,13 @@ class Mounter {
1710
1775
  }
1711
1776
  if (el.tagName === "SLOT") {
1712
1777
  if (!found[d] || !isSlotStart(found[d])) {
1713
- if (!this.adoptNodes(Array.from(el.childNodes), found.slice(d), context, markers)) {
1778
+ const fallback = significant(Array.from(el.childNodes));
1779
+ const countable = fallback.every((n) => n.nodeType === 3 || n.nodeType === 1 && !isBlockTemplate(n) && n.tagName !== "SLOT");
1780
+ const share = countable ? found.slice(d, d + fallback.length) : found.slice(d);
1781
+ if (!this.adoptNodes(fallback, share, context, markers)) {
1714
1782
  return false;
1715
1783
  }
1716
- d = found.length;
1784
+ d += share.length;
1717
1785
  continue;
1718
1786
  }
1719
1787
  const name = found[d].data.slice(SLOT_MARK.length);
@@ -1876,7 +1944,7 @@ class Mounter {
1876
1944
  return block;
1877
1945
  }
1878
1946
  adoptRows(block, slices, context) {
1879
- const value = this.bindings.evaluate(block.itemsExpr, context.owner, context.locals);
1947
+ const value = this.bindings.evaluate(block.itemsExpr, context.owner, context.locals, block.params);
1880
1948
  const items = block.toItems(value);
1881
1949
  if (items.length !== slices.length)
1882
1950
  return false;
@@ -2369,6 +2437,9 @@ function isBlockAnchor(node) {
2369
2437
  const data = node.data.trim();
2370
2438
  return data.startsWith("for:") || data.startsWith("if:") || data.startsWith("tag:");
2371
2439
  }
2440
+ function isBlockTemplate(el) {
2441
+ return el.hasAttribute("data-bind-for") || el.hasAttribute("data-bind-if") || el.hasAttribute("data-bind-tag");
2442
+ }
2372
2443
  function isInsignificant(node) {
2373
2444
  return node.nodeType === 3 && !(node.textContent ?? "").trim();
2374
2445
  }
@@ -133,7 +133,12 @@ export declare class BindingEvaluator {
133
133
  get cellManager(): CellManager;
134
134
  /** Compile a standalone expression, e.g. a `$key`. */
135
135
  compileExpression(expr: string, params?: string[]): Compiled;
136
- evaluate(expr: string, instance: ComponentInstance, locals?: any[]): any;
136
+ /**
137
+ * Evaluate once, outside a binding. `params` names the loop aliases `locals`
138
+ * holds: the compiled table is keyed by scope, so a block inside a `$for`
139
+ * row has to be looked up with the row's alias in scope, or it misses.
140
+ */
141
+ evaluate(expr: string, instance: ComponentInstance, locals?: any[], params?: string[]): any;
137
142
  applyBinding(binding: Binding, scope: BindingScope): void;
138
143
  /** Re-evaluate everything owned by this instance, including its blocks. */
139
144
  updateInstance(instance: ComponentInstance): void;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
package/dist/vite.js CHANGED
@@ -243,9 +243,9 @@ class BindingEvaluator {
243
243
  compileExpression(expr, params = []) {
244
244
  return this.compile(expr, params);
245
245
  }
246
- evaluate(expr, instance, locals = []) {
246
+ evaluate(expr, instance, locals = [], params = []) {
247
247
  try {
248
- return this.compile(expr, [])(instance.state, instance.props, this.cells.createReadProxy(), this.pendingProbe(), ...locals);
248
+ return this.compile(expr, params)(instance.state, instance.props, this.cells.createReadProxy(), this.pendingProbe(), ...locals);
249
249
  } catch (error) {
250
250
  warn(`Error evaluating "${expr}" in ${instance.id}:`, error);
251
251
  return;
@@ -349,7 +349,7 @@ class BindingEvaluator {
349
349
  binding.el.innerHTML = value == null ? "" : String(value);
350
350
  break;
351
351
  case "attr": {
352
- const attr = binding.attr;
352
+ const attr = svgAttributeName(binding.el, binding.attr);
353
353
  const aria = attr.startsWith("aria-");
354
354
  if (BOOLEAN_ATTRIBUTES.has(attr) && !aria) {
355
355
  if (value)
@@ -462,6 +462,70 @@ function isPlain(value) {
462
462
  const proto = Object.getPrototypeOf(value);
463
463
  return proto === Object.prototype || proto === null;
464
464
  }
465
+ var SVG_NS = "http://www.w3.org/2000/svg";
466
+ var SVG_ATTRIBUTES = new Map([
467
+ "attributeName",
468
+ "attributeType",
469
+ "baseFrequency",
470
+ "baseProfile",
471
+ "calcMode",
472
+ "clipPathUnits",
473
+ "diffuseConstant",
474
+ "edgeMode",
475
+ "filterUnits",
476
+ "glyphRef",
477
+ "gradientTransform",
478
+ "gradientUnits",
479
+ "kernelMatrix",
480
+ "kernelUnitLength",
481
+ "keyPoints",
482
+ "keySplines",
483
+ "keyTimes",
484
+ "lengthAdjust",
485
+ "limitingConeAngle",
486
+ "markerHeight",
487
+ "markerUnits",
488
+ "markerWidth",
489
+ "maskContentUnits",
490
+ "maskUnits",
491
+ "numOctaves",
492
+ "pathLength",
493
+ "patternContentUnits",
494
+ "patternTransform",
495
+ "patternUnits",
496
+ "pointsAtX",
497
+ "pointsAtY",
498
+ "pointsAtZ",
499
+ "preserveAlpha",
500
+ "preserveAspectRatio",
501
+ "primitiveUnits",
502
+ "refX",
503
+ "refY",
504
+ "repeatCount",
505
+ "repeatDur",
506
+ "requiredExtensions",
507
+ "requiredFeatures",
508
+ "specularConstant",
509
+ "specularExponent",
510
+ "spreadMethod",
511
+ "startOffset",
512
+ "stdDeviation",
513
+ "stitchTiles",
514
+ "surfaceScale",
515
+ "systemLanguage",
516
+ "tableValues",
517
+ "targetX",
518
+ "targetY",
519
+ "textLength",
520
+ "viewBox",
521
+ "viewTarget",
522
+ "xChannelSelector",
523
+ "yChannelSelector",
524
+ "zoomAndPan"
525
+ ].map((name) => [name.toLowerCase(), name]));
526
+ function svgAttributeName(el, attr) {
527
+ return el.namespaceURI === SVG_NS ? SVG_ATTRIBUTES.get(attr) ?? attr : attr;
528
+ }
465
529
  // src/runtime/dom/ForBlock.ts
466
530
  class Row {
467
531
  locals;
@@ -959,7 +1023,8 @@ class Mounter {
959
1023
  outlet.replaceWith(holder);
960
1024
  }
961
1025
  for (const [name, nodes] of byName) {
962
- if (!nodes.length)
1026
+ const dropped = nodes.filter((node) => node.nodeType === 1 || node.nodeType === 3 && (node.textContent ?? "").trim() !== "");
1027
+ if (!dropped.length)
963
1028
  continue;
964
1029
  warn(name ? `No <slot name="${name}"> to receive this content - it was dropped.` : "Content passed to a component with no unnamed <slot> - it was dropped.");
965
1030
  }
@@ -1141,10 +1206,13 @@ class Mounter {
1141
1206
  }
1142
1207
  if (el.tagName === "SLOT") {
1143
1208
  if (!found[d] || !isSlotStart(found[d])) {
1144
- if (!this.adoptNodes(Array.from(el.childNodes), found.slice(d), context, markers)) {
1209
+ const fallback = significant(Array.from(el.childNodes));
1210
+ const countable = fallback.every((n) => n.nodeType === 3 || n.nodeType === 1 && !isBlockTemplate(n) && n.tagName !== "SLOT");
1211
+ const share = countable ? found.slice(d, d + fallback.length) : found.slice(d);
1212
+ if (!this.adoptNodes(fallback, share, context, markers)) {
1145
1213
  return false;
1146
1214
  }
1147
- d = found.length;
1215
+ d += share.length;
1148
1216
  continue;
1149
1217
  }
1150
1218
  const name = found[d].data.slice(SLOT_MARK.length);
@@ -1307,7 +1375,7 @@ class Mounter {
1307
1375
  return block;
1308
1376
  }
1309
1377
  adoptRows(block, slices, context) {
1310
- const value = this.bindings.evaluate(block.itemsExpr, context.owner, context.locals);
1378
+ const value = this.bindings.evaluate(block.itemsExpr, context.owner, context.locals, block.params);
1311
1379
  const items = block.toItems(value);
1312
1380
  if (items.length !== slices.length)
1313
1381
  return false;
@@ -1800,6 +1868,9 @@ function isBlockAnchor(node) {
1800
1868
  const data = node.data.trim();
1801
1869
  return data.startsWith("for:") || data.startsWith("if:") || data.startsWith("tag:");
1802
1870
  }
1871
+ function isBlockTemplate(el) {
1872
+ return el.hasAttribute("data-bind-for") || el.hasAttribute("data-bind-if") || el.hasAttribute("data-bind-tag");
1873
+ }
1803
1874
  function isInsignificant(node) {
1804
1875
  return node.nodeType === 3 && !(node.textContent ?? "").trim();
1805
1876
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightspeed-js/core",
3
- "version": "0.4.6",
3
+ "version": "0.4.8",
4
4
  "description": "Lightspeed: a compile-first framework for islands of reactivity in static HTML.",
5
5
  "keywords": [
6
6
  "lightspeed",