@barefootjs/jinja 0.19.0 → 0.20.0
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/adapter/index.js +5 -4
- package/dist/adapter/jinja-adapter.d.ts +8 -7
- package/dist/adapter/jinja-adapter.d.ts.map +1 -1
- package/dist/build.js +5 -4
- package/dist/conformance-pins.d.ts.map +1 -1
- package/dist/index.js +7 -5
- package/package.json +3 -3
- package/python/barefootjs/runtime.py +80 -1
- package/python/pyproject.toml +1 -1
- package/src/__tests__/jinja-adapter.test.ts +1 -13
- package/src/adapter/jinja-adapter.ts +13 -26
- package/src/conformance-pins.ts +6 -0
package/dist/adapter/index.js
CHANGED
|
@@ -188930,10 +188930,11 @@ ${name}="{{ bf.string(${val}) }}"
|
|
|
188930
188930
|
if (e.kind === "expr" && !isSupported(parseExpression2(e.expr)).supported)
|
|
188931
188931
|
return null;
|
|
188932
188932
|
}
|
|
188933
|
-
|
|
188934
|
-
|
|
188935
|
-
|
|
188936
|
-
|
|
188933
|
+
const args = entries.flatMap((e) => [
|
|
188934
|
+
JSON.stringify(e.cssKey),
|
|
188935
|
+
e.kind === "literal" ? JSON.stringify(e.value) : this.convertExpressionToJinja(e.expr)
|
|
188936
|
+
]);
|
|
188937
|
+
return `{{ bf.style_object(${args.join(", ")}) }}`;
|
|
188937
188938
|
}
|
|
188938
188939
|
renderAttributes(element) {
|
|
188939
188940
|
const parts = [];
|
|
@@ -300,15 +300,16 @@ export declare class JinjaAdapter extends BaseAdapter implements IRNodeEmitter<J
|
|
|
300
300
|
*/
|
|
301
301
|
private readonly elementAttrEmitter;
|
|
302
302
|
/**
|
|
303
|
-
* Lower a `style={{ … }}` object literal to a
|
|
304
|
-
*
|
|
305
|
-
*
|
|
306
|
-
*
|
|
307
|
-
*
|
|
303
|
+
* Lower a `style={{ … }}` object literal to a `bf.style_object(...)` call,
|
|
304
|
+
* e.g. `{ backgroundColor: color }` → `{{ bf.style_object("background-color",
|
|
305
|
+
* color) }}`. `style_object` is the single oracle-matching sanitizer (ported
|
|
306
|
+
* from Hono's `hasUnsafeStyleValue`): it drops any key:value pair whose
|
|
307
|
+
* value could break out of a CSS declaration and HTML-escapes the rest,
|
|
308
|
+
* returning a `Markup` so Jinja's autoescape doesn't double-escape it (#2261).
|
|
309
|
+
* Returns null when the shape is unsupported or any value can't be lowered
|
|
310
|
+
* (caller falls through to BF101). (#1322)
|
|
308
311
|
*/
|
|
309
312
|
private tryLowerStyleObject;
|
|
310
|
-
/** HTML-attribute escape for static text inlined into a `"..."` attribute. */
|
|
311
|
-
private escapeAttrText;
|
|
312
313
|
private renderAttributes;
|
|
313
314
|
renderScopeMarker(_instanceIdExpr: string): string;
|
|
314
315
|
renderSlotMarker(slotId: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jinja-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/jinja-adapter.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"jinja-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/jinja-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwFG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,MAAM,EACN,SAAS,EACT,MAAM,EACN,YAAY,EACZ,aAAa,EACb,MAAM,EACN,WAAW,EACX,UAAU,EACV,MAAM,EACN,aAAa,EACb,UAAU,EACV,OAAO,EAKP,yBAAyB,EAE1B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,sBAAsB,EAE3B,KAAK,aAAa,EAClB,KAAK,UAAU,EA+BhB,MAAM,iBAAiB,CAAA;AAKxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAkCpD,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAEzD,qBAAa,YAAa,SAAQ,WAAY,YAAW,aAAa,CAAC,cAAc,CAAC;IACpF,IAAI,SAAU;IACd,SAAS,SAAW;IACpB,qBAAqB,UAAO;IAG5B,kBAAkB,EAAG,cAAc,CAAS;IAE5C;;;;;OAKG;IACH,kBAAkB,EAAE,yBAAyB,CAA2B;IAExE,OAAO,CAAC,aAAa,CAAa;IAClC;;;uCAGmC;IACnC,OAAO,CAAC,cAAc,CAAyB;IAC/C,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,MAAM,CAAiB;IAC/B;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB,CAAI;IAC/B;;;;;OAKG;IACH,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,iBAAiB,CAAyB;IAClD;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB,CAAyB;IAEjD;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB,CAAiC;IAE3D;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB,CAAyB;IAEpD;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB,CAAwB;IAEjD;;;;;OAKG;IACH,OAAO,CAAC,cAAc,CAAmC;IAEzD;;;;;;;;OAQG;IACH,OAAO,CAAC,0BAA0B,CAAyB;IAE3D;;;;;;;OAOG;IACH,OAAO,CAAC,qBAAqB,CAAyB;IAEtD,YAAY,OAAO,GAAE,mBAAwB,EAM5C;IAED,QAAQ,CAAC,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,aAAa,CA6EzE;IAMD,OAAO,CAAC,2BAA2B;IAyBnC;;;;OAIG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/B;IAMD,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAE5F;IAED,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI7B;IAED,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAEzC;IAED,eAAe,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAEpG;IAED,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAEtF;IAED,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAEhG;IAED,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAE9F;IAED,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7B;IAED,eAAe,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAEpG;IAED,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAe9F;IAED,uEAAuE;IACvE,OAAO,CAAC,kBAAkB;IAmB1B;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,0BAA0B;IAYlC,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAExF;IAMD,aAAa,CAAC,OAAO,EAAE,SAAS,GAAG,MAAM,CAqCxC;IAED;;;;;OAKG;IACH,OAAO,CAAC,wBAAwB;IAoBhC,gBAAgB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAqB3C;IAMD,iBAAiB,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAuC7C;IAED,OAAO,CAAC,gBAAgB;IAOxB;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IAcnC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAsQ/B;IAMD;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAoCpC;IAED;;;;;;;;;;OAUG;IACH,OAAO,CAAC,2BAA2B;IAUnC;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,4BAA4B;IAiBpC,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAoGzC;IAED,OAAO,CAAC,sBAAsB,CAAI;IAElC;+DAC2D;IAC3D,OAAO,CAAC,kBAAkB,CAAI;IAE9B,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,UAAU;IAYT,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAQ1C;IAMD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CA0JlC;IAED;;;;;;;;;OASG;IACH,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,gBAAgB;IAoCxB,iBAAiB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAIjD;IAED,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvC;IAED,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvC;IAMD;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB;IAuB7B,OAAO,CAAC,kCAAkC;IA8B1C;;;;;OAKG;IACH,OAAO,CAAC,iCAAiC;IAmBzC;;;;;OAKG;IACH,OAAO,CAAC,+BAA+B;IAuBvC;;;;;;;OAOG;IACH,OAAO,KAAK,OAAO,GASlB;IAED;;;;;OAKG;IACH,OAAO,KAAK,SAAS,GASpB;IAED,sEAAsE;IACtE,OAAO,KAAK,OAAO,GAKlB;IAED,OAAO,CAAC,wBAAwB;IAyEhC;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB;IAK/B;;;;;;;OAOG;IACH,OAAO,CAAC,iBAAiB;IAOzB;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAI/B;;gFAE4E;IAC5E,OAAO,CAAC,kBAAkB;IAI1B;;;;OAIG;IACH,8BAA8B,CAC5B,IAAI,EAAE,MAAM,GACX;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAgBlD;IAED,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAO3C;IAED;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,aAAa;IAKrB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,oBAAoB;IAW5B;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,2BAA2B;IASnC,OAAO,CAAC,yBAAyB;IAUjC,OAAO,CAAC,gBAAgB;IAcxB,iFAAiF;IACjF,OAAO,CAAC,4BAA4B;CAGrC;AAED,eAAO,MAAM,YAAY,cAAqB,CAAA"}
|
package/dist/build.js
CHANGED
|
@@ -188930,10 +188930,11 @@ ${name}="{{ bf.string(${val}) }}"
|
|
|
188930
188930
|
if (e.kind === "expr" && !isSupported(parseExpression2(e.expr)).supported)
|
|
188931
188931
|
return null;
|
|
188932
188932
|
}
|
|
188933
|
-
|
|
188934
|
-
|
|
188935
|
-
|
|
188936
|
-
|
|
188933
|
+
const args = entries.flatMap((e) => [
|
|
188934
|
+
JSON.stringify(e.cssKey),
|
|
188935
|
+
e.kind === "literal" ? JSON.stringify(e.value) : this.convertExpressionToJinja(e.expr)
|
|
188936
|
+
]);
|
|
188937
|
+
return `{{ bf.style_object(${args.join(", ")}) }}`;
|
|
188937
188938
|
}
|
|
188938
188939
|
renderAttributes(element) {
|
|
188939
188940
|
const parts = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,eAmG7B,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -188930,10 +188930,11 @@ ${name}="{{ bf.string(${val}) }}"
|
|
|
188930
188930
|
if (e.kind === "expr" && !isSupported(parseExpression2(e.expr)).supported)
|
|
188931
188931
|
return null;
|
|
188932
188932
|
}
|
|
188933
|
-
|
|
188934
|
-
|
|
188935
|
-
|
|
188936
|
-
|
|
188933
|
+
const args = entries.flatMap((e) => [
|
|
188934
|
+
JSON.stringify(e.cssKey),
|
|
188935
|
+
e.kind === "literal" ? JSON.stringify(e.value) : this.convertExpressionToJinja(e.expr)
|
|
188936
|
+
]);
|
|
188937
|
+
return `{{ bf.style_object(${args.join(", ")}) }}`;
|
|
188937
188938
|
}
|
|
188938
188939
|
renderAttributes(element) {
|
|
188939
188940
|
const parts = [];
|
|
@@ -189206,7 +189207,8 @@ var conformancePins = {
|
|
|
189206
189207
|
"filter-nested-find-predicate": [
|
|
189207
189208
|
{ code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2038" }
|
|
189208
189209
|
],
|
|
189209
|
-
"dangerous-inner-html-dynamic": [{ code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2215" }]
|
|
189210
|
+
"dangerous-inner-html-dynamic": [{ code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2215" }],
|
|
189211
|
+
"date-method-uncatalogued": [{ code: "BF021", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2274" }]
|
|
189210
189212
|
};
|
|
189211
189213
|
// src/render-divergences.ts
|
|
189212
189214
|
var renderDivergences = {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/jinja",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "Jinja2 adapter for BarefootJS — compiles IR to .jinja templates and ships the Python BarefootJS rendering runtime; runs under any Python web framework (Flask, etc.)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -53,14 +53,14 @@
|
|
|
53
53
|
"directory": "packages/adapter-jinja"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@barefootjs/shared": "0.
|
|
56
|
+
"@barefootjs/shared": "0.20.0"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"@barefootjs/jsx": ">=0.2.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@barefootjs/adapter-tests": "0.1.0",
|
|
63
|
-
"@barefootjs/jsx": "0.
|
|
63
|
+
"@barefootjs/jsx": "0.20.0",
|
|
64
64
|
"typescript": "^5.0.0"
|
|
65
65
|
}
|
|
66
66
|
}
|
|
@@ -76,6 +76,8 @@ import re
|
|
|
76
76
|
import uuid
|
|
77
77
|
from typing import Any, Callable, Optional
|
|
78
78
|
|
|
79
|
+
from markupsafe import Markup
|
|
80
|
+
|
|
79
81
|
from . import evaluator as _evaluator
|
|
80
82
|
from .evaluator import looks_like_number, parse_number_literal
|
|
81
83
|
from .search_params import SearchParams
|
|
@@ -360,6 +362,55 @@ def _html_escape(value: Any) -> str:
|
|
|
360
362
|
return s
|
|
361
363
|
|
|
362
364
|
|
|
365
|
+
def _has_unsafe_style_value(value: str) -> bool:
|
|
366
|
+
"""Mirrors Hono's own CSS-injection guard (`hono/jsx/utils.ts`'s
|
|
367
|
+
`hasUnsafeStyleValue` -- the ORACLE a dynamic `style={{...}}` value
|
|
368
|
+
must match, #2261): a hand-rolled structural scan for characters that
|
|
369
|
+
could break out of a CSS declaration, NOT real CSSOM property
|
|
370
|
+
validation. Ported character-for-character (codepoint comparisons,
|
|
371
|
+
consistently, throughout -- every tested character is ASCII, so a
|
|
372
|
+
multibyte codepoint can never spuriously match one of these
|
|
373
|
+
single-character comparisons regardless of scan unit). Skips the
|
|
374
|
+
reference implementation's regex fast-path (a pure optimization -- the
|
|
375
|
+
scan below already returns `False` promptly for a clean value)."""
|
|
376
|
+
quote = ""
|
|
377
|
+
block_stack: list[str] = []
|
|
378
|
+
i = 0
|
|
379
|
+
length = len(value)
|
|
380
|
+
while i < length:
|
|
381
|
+
c = value[i]
|
|
382
|
+
if c == "\\":
|
|
383
|
+
if i == length - 1:
|
|
384
|
+
return True
|
|
385
|
+
i += 1
|
|
386
|
+
elif quote:
|
|
387
|
+
if c in ("\n", "\f", "\r"):
|
|
388
|
+
return True
|
|
389
|
+
if c == quote:
|
|
390
|
+
quote = ""
|
|
391
|
+
elif c == "/" and i + 1 < length and value[i + 1] == "*":
|
|
392
|
+
end = value.find("*/", i + 2)
|
|
393
|
+
if end == -1:
|
|
394
|
+
return True
|
|
395
|
+
i = end + 1
|
|
396
|
+
elif c in ('"', "'"):
|
|
397
|
+
quote = c
|
|
398
|
+
elif c == "(":
|
|
399
|
+
block_stack.append(")")
|
|
400
|
+
elif c == "[":
|
|
401
|
+
block_stack.append("]")
|
|
402
|
+
elif c in ("{", "}"):
|
|
403
|
+
return True
|
|
404
|
+
elif c in (")", "]"):
|
|
405
|
+
if not block_stack or block_stack[-1] != c:
|
|
406
|
+
return True
|
|
407
|
+
block_stack.pop()
|
|
408
|
+
elif c == ";" and not block_stack:
|
|
409
|
+
return True
|
|
410
|
+
i += 1
|
|
411
|
+
return bool(quote) or bool(block_stack)
|
|
412
|
+
|
|
413
|
+
|
|
363
414
|
def _style_to_css(value: Any) -> Optional[str]:
|
|
364
415
|
if value is None:
|
|
365
416
|
return None
|
|
@@ -912,6 +963,29 @@ class BarefootJS:
|
|
|
912
963
|
return i
|
|
913
964
|
return -1
|
|
914
965
|
|
|
966
|
+
def style_object(self, *pairs: Any) -> Markup:
|
|
967
|
+
"""Builds the CSS string for a `style={{...}}` JSX object-literal
|
|
968
|
+
attribute (#2261) -- `pairs` alternates CSS key (always a
|
|
969
|
+
compile-time-known literal), then value. A value that fails
|
|
970
|
+
`_has_unsafe_style_value` (after JS-`String()`-style
|
|
971
|
+
stringification) is DROPPED -- the whole `key:value` pair is
|
|
972
|
+
omitted -- matching Hono's oracle behavior exactly. The final
|
|
973
|
+
joined string is STILL HTML-escaped (mirroring Hono's own
|
|
974
|
+
`escapeToBuffer` call on its accumulated style string) -- a "safe"
|
|
975
|
+
value can still carry a literal `"`/`'`/`&` (e.g. a BALANCED-quote
|
|
976
|
+
CSS string value like `"hello"` passes the structural scan) that
|
|
977
|
+
would otherwise break out of the double-quoted `style="..."`
|
|
978
|
+
attribute. Returns `Markup` so Jinja's autoescape treats the
|
|
979
|
+
(already-escaped) result as safe instead of double-escaping it."""
|
|
980
|
+
parts = []
|
|
981
|
+
for i in range(0, len(pairs) - 1, 2):
|
|
982
|
+
key, value = pairs[i], pairs[i + 1]
|
|
983
|
+
v = js_string(value)
|
|
984
|
+
if _has_unsafe_style_value(v):
|
|
985
|
+
continue
|
|
986
|
+
parts.append(f"{_html_escape(key)}:{_html_escape(v)}")
|
|
987
|
+
return Markup(";".join(parts))
|
|
988
|
+
|
|
915
989
|
def lc(self, s: Any) -> str:
|
|
916
990
|
return js_string(s).lower()
|
|
917
991
|
|
|
@@ -929,7 +1003,12 @@ class BarefootJS:
|
|
|
929
1003
|
return len(recv)
|
|
930
1004
|
if isinstance(recv, dict):
|
|
931
1005
|
return 0
|
|
932
|
-
|
|
1006
|
+
# JS `String.prototype.length` counts UTF-16 CODE UNITS, not
|
|
1007
|
+
# Python's codepoint-counting `len(str)` (#2255). A codepoint
|
|
1008
|
+
# outside the Basic Multilingual Plane (astral, U+10000-U+10FFFF —
|
|
1009
|
+
# e.g. '👍') is a surrogate PAIR in UTF-16, so it counts as 2, not
|
|
1010
|
+
# 1; '日本語' is 3 either way (BMP-only).
|
|
1011
|
+
return sum(2 if ord(c) > 0xFFFF else 1 for c in js_string(recv))
|
|
933
1012
|
|
|
934
1013
|
def index_of(self, recv: Any, elem: Any) -> int:
|
|
935
1014
|
return _array_index_of(recv, elem, reverse=False)
|
package/python/pyproject.toml
CHANGED
|
@@ -20,7 +20,7 @@ classifiers = [
|
|
|
20
20
|
"Programming Language :: Python :: 3.11",
|
|
21
21
|
"Programming Language :: Python :: 3.12",
|
|
22
22
|
]
|
|
23
|
-
dependencies = ["jinja2>=3.1"]
|
|
23
|
+
dependencies = ["jinja2>=3.1", "markupsafe>=2.0"]
|
|
24
24
|
|
|
25
25
|
[project.urls]
|
|
26
26
|
Homepage = "https://github.com/piconic-ai/barefootjs"
|
|
@@ -51,19 +51,7 @@ runAdapterConformanceTests({
|
|
|
51
51
|
// Same `/* @client */` keyed-map elision (data-table).
|
|
52
52
|
'data-table',
|
|
53
53
|
]),
|
|
54
|
-
skipDataPoints: new Set<string>(
|
|
55
|
-
// #2255 — Python len() counts codepoints; JS counts UTF-16 code
|
|
56
|
-
// units, so a surrogate-pair character is 2 in JS, 1 here.
|
|
57
|
-
'string-length-text:astral',
|
|
58
|
-
// #2260 — controlled boolean props: the SSR seed evaluates only the
|
|
59
|
-
// static fallback of `props.X ?? internal()` chains.
|
|
60
|
-
'toggle:gen:pressed:true',
|
|
61
|
-
'switch:gen:checked:true',
|
|
62
|
-
'checkbox:gen:checked:true',
|
|
63
|
-
// #2261 — invalid dynamic CSS value kept (escaped) where the oracle
|
|
64
|
-
// drops the property.
|
|
65
|
-
'style-object-dynamic:gen:color:markup',
|
|
66
|
-
]),
|
|
54
|
+
skipDataPoints: new Set<string>(),
|
|
67
55
|
onRenderError: (err, id) => {
|
|
68
56
|
if (err instanceof PythonNotAvailableError) {
|
|
69
57
|
console.log(`Skipping [${id}]: ${err.message}`)
|
|
@@ -1404,11 +1404,14 @@ export class JinjaAdapter extends BaseAdapter implements IRNodeEmitter<JinjaRend
|
|
|
1404
1404
|
}
|
|
1405
1405
|
|
|
1406
1406
|
/**
|
|
1407
|
-
* Lower a `style={{ … }}` object literal to a
|
|
1408
|
-
*
|
|
1409
|
-
*
|
|
1410
|
-
*
|
|
1411
|
-
*
|
|
1407
|
+
* Lower a `style={{ … }}` object literal to a `bf.style_object(...)` call,
|
|
1408
|
+
* e.g. `{ backgroundColor: color }` → `{{ bf.style_object("background-color",
|
|
1409
|
+
* color) }}`. `style_object` is the single oracle-matching sanitizer (ported
|
|
1410
|
+
* from Hono's `hasUnsafeStyleValue`): it drops any key:value pair whose
|
|
1411
|
+
* value could break out of a CSS declaration and HTML-escapes the rest,
|
|
1412
|
+
* returning a `Markup` so Jinja's autoescape doesn't double-escape it (#2261).
|
|
1413
|
+
* Returns null when the shape is unsupported or any value can't be lowered
|
|
1414
|
+
* (caller falls through to BF101). (#1322)
|
|
1412
1415
|
*/
|
|
1413
1416
|
private tryLowerStyleObject(expr: string): string | null {
|
|
1414
1417
|
const entries = parseStyleObjectEntries(expr)
|
|
@@ -1416,27 +1419,11 @@ export class JinjaAdapter extends BaseAdapter implements IRNodeEmitter<JinjaRend
|
|
|
1416
1419
|
for (const e of entries) {
|
|
1417
1420
|
if (e.kind === 'expr' && !isSupported(parseExpression(e.expr)).supported) return null
|
|
1418
1421
|
}
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
return
|
|
1424
|
-
.map(e =>
|
|
1425
|
-
e.kind === 'literal'
|
|
1426
|
-
? `${this.escapeAttrText(e.cssKey)}:${this.escapeAttrText(e.value)}`
|
|
1427
|
-
: `${this.escapeAttrText(e.cssKey)}:{{ bf.string(${this.convertExpressionToJinja(e.expr)}) }}`,
|
|
1428
|
-
)
|
|
1429
|
-
.join(';')
|
|
1430
|
-
}
|
|
1431
|
-
|
|
1432
|
-
/** HTML-attribute escape for static text inlined into a `"..."` attribute. */
|
|
1433
|
-
private escapeAttrText(s: string): string {
|
|
1434
|
-
return s
|
|
1435
|
-
.replace(/&/g, '&')
|
|
1436
|
-
.replace(/"/g, '"')
|
|
1437
|
-
.replace(/'/g, ''')
|
|
1438
|
-
.replace(/</g, '<')
|
|
1439
|
-
.replace(/>/g, '>')
|
|
1422
|
+
const args = entries.flatMap(e => [
|
|
1423
|
+
JSON.stringify(e.cssKey),
|
|
1424
|
+
e.kind === 'literal' ? JSON.stringify(e.value) : this.convertExpressionToJinja(e.expr),
|
|
1425
|
+
])
|
|
1426
|
+
return `{{ bf.style_object(${args.join(', ')}) }}`
|
|
1440
1427
|
}
|
|
1441
1428
|
|
|
1442
1429
|
private renderAttributes(element: IRElement): string {
|
package/src/conformance-pins.ts
CHANGED
|
@@ -103,4 +103,10 @@ export const conformancePins: ConformancePins = {
|
|
|
103
103
|
// A dynamic/signal-derived value still refuses with BF101 — see the
|
|
104
104
|
// `dangerous-inner-html-dynamic` fixture/pin below (tracked: #2215).
|
|
105
105
|
'dangerous-inner-html-dynamic': [{ code: 'BF101', severity: 'error', issue: 'https://github.com/piconic-ai/barefootjs/issues/2215' }],
|
|
106
|
+
// #2273: a method call on a prop typed as a built-in host rich type
|
|
107
|
+
// (Date, Map, …) has no catalogued lowering in any adapter — this is a
|
|
108
|
+
// compiler-level refusal (`checkRichTypeMethodCalls`, wired ahead of
|
|
109
|
+
// `adapter.generate()`), not an adapter-specific gap, so it is pinned
|
|
110
|
+
// identically across every adapter package including Hono.
|
|
111
|
+
'date-method-uncatalogued': [{ code: 'BF021', severity: 'error', issue: 'https://github.com/piconic-ai/barefootjs/issues/2274' }],
|
|
106
112
|
}
|