rip-lang 3.13.63 → 3.13.65

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/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
  </p>
10
10
 
11
11
  <p align="center">
12
- <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-3.13.63-blue.svg" alt="Version"></a>
12
+ <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-3.13.65-blue.svg" alt="Version"></a>
13
13
  <a href="#zero-dependencies"><img src="https://img.shields.io/badge/dependencies-ZERO-brightgreen.svg" alt="Dependencies"></a>
14
14
  <a href="#"><img src="https://img.shields.io/badge/tests-1%2C436%2F1%2C436-brightgreen.svg" alt="Tests"></a>
15
15
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License"></a>
@@ -213,6 +213,7 @@ All use `globalThis` with `??=` — override any by redeclaring locally.
213
213
  | `?.` `?.[]` `?.()` | `a?.b` `a?.[0]` `a?.()` | Optional chaining (ES6) |
214
214
  | `?[]` `?()` | `a?[0]` `a?(x)` | Optional chaining shorthand |
215
215
  | `?.` `=` | `el?.scrollTop = 0` | Optional chain assignment — guarded write |
216
+ | `=` (render) | `= item.textContent` | Expression output as text node in render blocks |
216
217
  | `??` | `a ?? b` | Nullish coalescing |
217
218
  | `...` (spread) | `[...items, last]` | Prefix spread (ES6) |
218
219
  | `//` | `7 // 2` | Floor division |
package/docs/RIP-LANG.md CHANGED
@@ -388,6 +388,25 @@ JavaScript does not allow optional chaining on the left side of assignments
388
388
  automatically. This is particularly useful for DOM element references that
389
389
  may not exist yet (before mount, inside conditionals, etc.).
390
390
 
391
+ ### Render Expression Output (`= prefix`)
392
+
393
+ In component render blocks, `x.y` on its own line is parsed as a tag
394
+ with a CSS class (`<x class="y">`), not a property access. The `=`
395
+ prefix forces the line to be an expression, outputting it as a text node:
396
+
397
+ ```coffee
398
+ # In a render block:
399
+ render
400
+ div
401
+ = item.textContent # text node — not a tag
402
+ = nav.dataset.trigger # works even when 'nav' is an HTML tag
403
+ = link.href # works even when 'link' is an HTML tag
404
+ div.card # tag — <div class="card"> (no = prefix)
405
+ ```
406
+
407
+ The `=` removes itself and stamps the expression so the codegen skips
408
+ tag detection. Output is clean: `createTextNode(String(expr))`.
409
+
391
410
  ## Ternary Operator
392
411
 
393
412
  ```coffee
package/docs/dist/rip.js CHANGED
@@ -3511,6 +3511,7 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
3511
3511
  return Array.isArray(target) && target[0] === "." && target[1] === "this";
3512
3512
  }
3513
3513
  function installComponentSupport(CodeGenerator, Lexer2) {
3514
+ let meta = (node, key) => node instanceof String ? node[key] : undefined;
3514
3515
  const origClassify = Lexer2.prototype.classifyKeyword;
3515
3516
  Lexer2.prototype.classifyKeyword = function(id, fallback, data) {
3516
3517
  if (id === "offer" || id === "accept") {
@@ -3633,12 +3634,16 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
3633
3634
  if (tag === "=" && i > 0) {
3634
3635
  let prev = tokens[i - 1][0];
3635
3636
  if (prev === "TERMINATOR" || prev === "INDENT" || prev === "RENDER") {
3636
- let end = i + 1;
3637
- while (end < tokens.length && tokens[end][0] !== "TERMINATOR" && tokens[end][0] !== "INDENT" && tokens[end][0] !== "OUTDENT")
3638
- end++;
3639
- tokens.splice(end, 0, gen2("INTERPOLATION_END", ")", token), gen2("STRING", '""', token), gen2("STRING_END", ")", token));
3640
- tokens.splice(i, 1, gen2("STRING_START", "(", token), gen2("STRING", '""', token), gen2("INTERPOLATION_START", "(", token));
3641
- return 3;
3637
+ tokens.splice(i, 1);
3638
+ if (tokens[i] && tokens[i][0] === "IDENTIFIER") {
3639
+ let val = tokens[i][1];
3640
+ if (typeof val === "string") {
3641
+ val = new String(val);
3642
+ tokens[i][1] = val;
3643
+ }
3644
+ val.text = true;
3645
+ }
3646
+ return 0;
3642
3647
  }
3643
3648
  }
3644
3649
  if (tag === "UNARY_MATH" && token[1] === "~" && nextToken && nextToken[0] === "IDENTIFIER") {
@@ -3845,11 +3850,11 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
3845
3850
  }
3846
3851
  let raw = typeof current === "string" ? current : current instanceof String ? current.valueOf() : null;
3847
3852
  if (raw === null)
3848
- return { tag: null, classes, id: undefined };
3853
+ return { tag: null, classes, id: undefined, base: current };
3849
3854
  let [tag, id] = raw.split("#");
3850
3855
  if (!tag)
3851
3856
  tag = "div";
3852
- return { tag, classes, id };
3857
+ return { tag, classes, id, base: current };
3853
3858
  };
3854
3859
  const _str = (s) => typeof s === "string" ? s : s instanceof String ? s.valueOf() : null;
3855
3860
  const _transferMeta = (from, to) => {
@@ -4240,7 +4245,7 @@ ${blockFactoriesCode}return ${lines.join(`
4240
4245
  this._createLines.push(`${slotVar} = ${s}.children instanceof Node ? ${s}.children : (${s}.children != null ? document.createTextNode(String(${s}.children)) : document.createComment(''));`);
4241
4246
  return slotVar;
4242
4247
  }
4243
- if (headStr && this.isHtmlTag(headStr)) {
4248
+ if (headStr && this.isHtmlTag(headStr) && !meta(head, "text")) {
4244
4249
  let [tagName, id] = headStr.split("#");
4245
4250
  return this.generateTag(tagName || "div", [], rest, id);
4246
4251
  }
@@ -4258,8 +4263,8 @@ ${blockFactoriesCode}return ${lines.join(`
4258
4263
  this._createLines.push(`${slotVar} = ${s}.${prop} instanceof Node ? ${s}.${prop} : (${s}.${prop} != null ? document.createTextNode(String(${s}.${prop})) : document.createComment(''));`);
4259
4264
  return slotVar;
4260
4265
  }
4261
- const { tag, classes, id } = this.collectTemplateClasses(sexpr);
4262
- if (tag && this.isHtmlTag(tag)) {
4266
+ const { tag, classes, id, base } = this.collectTemplateClasses(sexpr);
4267
+ if (!meta(base, "text") && tag && this.isHtmlTag(tag)) {
4263
4268
  return this.generateTag(tag, classes, [], id);
4264
4269
  }
4265
4270
  const textVar2 = this.newTextVar();
@@ -8714,8 +8719,8 @@ globalThis.zip ??= (...a) => a[0].map((_, i) => a.map(b => b[i]));
8714
8719
  return new CodeGenerator({}).getComponentRuntime();
8715
8720
  }
8716
8721
  // src/browser.js
8717
- var VERSION = "3.13.62";
8718
- var BUILD_DATE = "2026-03-01@06:05:45GMT";
8722
+ var VERSION = "3.13.63";
8723
+ var BUILD_DATE = "2026-03-01@06:49:01GMT";
8719
8724
  if (typeof globalThis !== "undefined") {
8720
8725
  if (!globalThis.__rip)
8721
8726
  new Function(getReactiveRuntime())();