@barefootjs/jsx 0.34.0 → 0.35.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/analyzer.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +344 -215
- package/dist/ir-to-client-js/collect-elements.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/build-branch-loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/build-component-loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/build-composite-loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/build-lazy-row.d.ts +11 -0
- package/dist/ir-to-client-js/control-flow/plan/build-lazy-row.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/build-loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/build-plain-row.d.ts +52 -0
- package/dist/ir-to-client-js/control-flow/plan/build-plain-row.d.ts.map +1 -0
- package/dist/ir-to-client-js/control-flow/plan/build-reactive-effects.d.ts +2 -0
- package/dist/ir-to-client-js/control-flow/plan/build-reactive-effects.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/lazy-conditional.d.ts +6 -7
- package/dist/ir-to-client-js/control-flow/plan/lazy-conditional.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/lazy-preamble.d.ts +5 -7
- package/dist/ir-to-client-js/control-flow/plan/lazy-preamble.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/lazy-row-eligibility.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/loop.d.ts +10 -6
- package/dist/ir-to-client-js/control-flow/plan/loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/shared.d.ts +11 -9
- package/dist/ir-to-client-js/control-flow/shared.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/stringify/composite-loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/stringify/lazy-row.d.ts.map +1 -1
- package/dist/ir-to-client-js/csr-substitute.d.ts +16 -0
- package/dist/ir-to-client-js/csr-substitute.d.ts.map +1 -1
- package/dist/ir-to-client-js/emit-reactive.d.ts.map +1 -1
- package/dist/ir-to-client-js/emit-registration.d.ts.map +1 -1
- package/dist/ir-to-client-js/html-template.d.ts +2 -2
- package/dist/ir-to-client-js/html-template.d.ts.map +1 -1
- package/dist/ir-to-client-js/imports.d.ts +2 -2
- package/dist/ir-to-client-js/imports.d.ts.map +1 -1
- package/dist/ir-to-client-js/index.d.ts.map +1 -1
- package/dist/ir-to-client-js/markup-slots.d.ts +21 -0
- package/dist/ir-to-client-js/markup-slots.d.ts.map +1 -0
- package/dist/ir-to-client-js/safe-html.d.ts +158 -0
- package/dist/ir-to-client-js/safe-html.d.ts.map +1 -0
- package/dist/ir-to-client-js/utils.d.ts +34 -1
- package/dist/ir-to-client-js/utils.d.ts.map +1 -1
- package/dist/jsx-to-ir.d.ts.map +1 -1
- package/dist/prop-rewrite.d.ts +8 -3
- package/dist/prop-rewrite.d.ts.map +1 -1
- package/dist/props-binding.d.ts +22 -1
- package/dist/props-binding.d.ts.map +1 -1
- package/dist/ssr-defaults.d.ts.map +1 -1
- package/dist/types.d.ts +5 -10
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/__snapshots__/doc-examples.test.ts.snap +10 -12
- package/src/__tests__/build-plain-row-consolidation.test.ts +120 -0
- package/src/__tests__/client-template-escape-soundness.test.ts +538 -0
- package/src/__tests__/csr-template-loop-shadowing.test.ts +4 -2
- package/src/__tests__/flatmap-segments.test.ts +1 -1
- package/src/__tests__/lazy-conditional.test.ts +52 -12
- package/src/__tests__/lazy-preamble.test.ts +11 -11
- package/src/__tests__/lazy-row-eligibility.test.ts +8 -3
- package/src/__tests__/loop-child-reactive-attr-const-shadow.test.ts +25 -3
- package/src/__tests__/loop-item-conditional-codegen.test.ts +4 -2
- package/src/__tests__/map-arbitrary-body.test.ts +1 -1
- package/src/__tests__/nested-loop-index-param.test.ts +14 -3
- package/src/__tests__/nested-loop-reactive-attrs.test.ts +4 -2
- package/src/__tests__/reactive-attrs-in-map.test.ts +13 -10
- package/src/__tests__/rewrite-destructured-props.test.ts +37 -0
- package/src/__tests__/safe-html-splice-door.test.ts +61 -0
- package/src/__tests__/ssr-defaults.test.ts +59 -0
- package/src/analyzer.ts +4 -0
- package/src/index.ts +8 -2
- package/src/ir-to-client-js/collect-elements.ts +18 -2
- package/src/ir-to-client-js/control-flow/plan/build-branch-loop.ts +20 -28
- package/src/ir-to-client-js/control-flow/plan/build-component-loop.ts +9 -7
- package/src/ir-to-client-js/control-flow/plan/build-composite-loop.ts +10 -6
- package/src/ir-to-client-js/control-flow/plan/build-inner-loop.ts +8 -8
- package/src/ir-to-client-js/control-flow/plan/build-lazy-row.ts +18 -2
- package/src/ir-to-client-js/control-flow/plan/build-loop-child-arm.ts +3 -3
- package/src/ir-to-client-js/control-flow/plan/build-loop.ts +35 -35
- package/src/ir-to-client-js/control-flow/plan/build-plain-row.ts +110 -0
- package/src/ir-to-client-js/control-flow/plan/build-reactive-effects.ts +5 -2
- package/src/ir-to-client-js/control-flow/plan/lazy-conditional.ts +11 -10
- package/src/ir-to-client-js/control-flow/plan/lazy-preamble.ts +11 -13
- package/src/ir-to-client-js/control-flow/plan/lazy-row-eligibility.ts +13 -3
- package/src/ir-to-client-js/control-flow/plan/loop.ts +10 -6
- package/src/ir-to-client-js/control-flow/shared.ts +40 -17
- package/src/ir-to-client-js/control-flow/stringify/composite-loop.ts +2 -1
- package/src/ir-to-client-js/control-flow/stringify/lazy-row.ts +10 -0
- package/src/ir-to-client-js/csr-substitute.ts +29 -0
- package/src/ir-to-client-js/emit-reactive.ts +4 -1
- package/src/ir-to-client-js/emit-registration.ts +2 -4
- package/src/ir-to-client-js/html-template.ts +58 -244
- package/src/ir-to-client-js/imports.ts +3 -0
- package/src/ir-to-client-js/index.ts +4 -4
- package/src/ir-to-client-js/markup-slots.ts +25 -0
- package/src/ir-to-client-js/safe-html.ts +243 -0
- package/src/ir-to-client-js/utils.ts +58 -10
- package/src/jsx-to-ir.ts +115 -20
- package/src/prop-rewrite.ts +8 -4
- package/src/props-binding.ts +37 -1
- package/src/ssr-defaults.ts +45 -0
- package/src/types.ts +5 -10
- package/src/__tests__/text-slot-escaping.test.ts +0 -65
package/src/types.ts
CHANGED
|
@@ -404,18 +404,13 @@ export interface IRText {
|
|
|
404
404
|
export interface IRExpression {
|
|
405
405
|
type: 'expression'
|
|
406
406
|
expr: string
|
|
407
|
-
/** Pre-transformed expr with destructured prop refs rewritten to _p.xxx (for client JS templates). */
|
|
408
|
-
templateExpr?: string
|
|
409
407
|
/**
|
|
410
|
-
*
|
|
411
|
-
*
|
|
412
|
-
*
|
|
413
|
-
*
|
|
414
|
-
* Not read via `templateExpr` instead: that field also rebinds to
|
|
415
|
-
* `_p.xxx`, which drops a destructured prop's `?? {}` default when the
|
|
416
|
-
* builder's output lives in init scope (`client-js-generation.test.ts`).
|
|
408
|
+
* Pre-transformed expr with destructured prop refs rewritten to _p.xxx
|
|
409
|
+
* (for client JS templates). Carries ONLY that rewrite — never an
|
|
410
|
+
* escaping wrapper: client-side escaping is decided at the splice
|
|
411
|
+
* (`ir-to-client-js/safe-html.ts`), not baked into IR text (#2795).
|
|
417
412
|
*/
|
|
418
|
-
|
|
413
|
+
templateExpr?: string
|
|
419
414
|
/**
|
|
420
415
|
* Structured parse of `expr` (`parseExpression(expr.trim())`), attached once
|
|
421
416
|
* during IR construction so SSR adapters emit from the tree instead of each
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Text-slot HTML-escaping emit shape (#1694 + follow-up, #2651).
|
|
3
|
-
*
|
|
4
|
-
* Pins which interpolations the client template wraps in an escape call:
|
|
5
|
-
* - a plain, non-conditional dynamic text slot (`{stringValue}`) IS
|
|
6
|
-
* escaped — it becomes the slot's text content under `innerHTML`. Since
|
|
7
|
-
* #2651 this goes through `escapeTextOrMarkup`, not bare `escapeText`:
|
|
8
|
-
* the slot is claim-plan `kind: 'markup'` (the value may be a live
|
|
9
|
-
* `Node`, or a `bfMarkup()`-branded JSX-element-prop value), and
|
|
10
|
-
* `escapeTextOrMarkup` is a strict superset of `escapeText` for every
|
|
11
|
-
* non-branded value — this pin's actual escaping behaviour for a plain
|
|
12
|
-
* string is unchanged, only the call name changed to match the
|
|
13
|
-
* REACTIVE side's existing `escapeTextOrNode` classification;
|
|
14
|
-
* - a branch-slot expression (Child-position value inside a conditional
|
|
15
|
-
* `template()` arrow) is routed through `__bfSlot` and must NOT be
|
|
16
|
-
* wrapped in either escape call. `__bfSlot` returns raw
|
|
17
|
-
* `<!--bf-slot:N-->` markers for live nodes; escaping the whole call
|
|
18
|
-
* corrupts them and drops slotted content (the regression that broke
|
|
19
|
-
* `e2e-site-ui`). `__bfSlot` escapes its own plain-string path
|
|
20
|
-
* internally instead.
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
import { describe, test, expect } from 'bun:test'
|
|
24
|
-
import { compileJSX } from '../compiler'
|
|
25
|
-
import { TestAdapter } from '../adapters/test-adapter'
|
|
26
|
-
|
|
27
|
-
const adapter = new TestAdapter()
|
|
28
|
-
|
|
29
|
-
function getClientJs(source: string, filename: string): string {
|
|
30
|
-
const result = compileJSX(source, filename, { adapter })
|
|
31
|
-
expect(result.errors.filter(e => e.severity === 'error')).toHaveLength(0)
|
|
32
|
-
const clientJs = result.files.find(f => f.type === 'clientJs')
|
|
33
|
-
expect(clientJs).toBeDefined()
|
|
34
|
-
return clientJs!.content
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
describe('text-slot escaping', () => {
|
|
38
|
-
test('a plain text slot is wrapped in escapeTextOrMarkup (#2651)', () => {
|
|
39
|
-
const clientJs = getClientJs(
|
|
40
|
-
`'use client'
|
|
41
|
-
export function Label({ text }: { text: string }) {
|
|
42
|
-
return <span>{text}</span>
|
|
43
|
-
}`,
|
|
44
|
-
'Label.tsx',
|
|
45
|
-
)
|
|
46
|
-
expect(clientJs).toMatch(/<!--bf:\w+-->\$\{escapeTextOrMarkup\(_p\.text\)\}<!--\/-->/)
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
test('a branch-slot expression is NOT wrapped in escapeTextOrMarkup or escapeText', () => {
|
|
50
|
-
const clientJs = getClientJs(
|
|
51
|
-
`'use client'
|
|
52
|
-
import { createSignal } from '@barefootjs/client'
|
|
53
|
-
export function Branch({ show }: { show: boolean }) {
|
|
54
|
-
const [t] = createSignal('hi')
|
|
55
|
-
return <div>{show ? <span>{t()}</span> : null}</div>
|
|
56
|
-
}`,
|
|
57
|
-
'Branch.tsx',
|
|
58
|
-
)
|
|
59
|
-
// The branch value goes through __bfSlot (raw markers preserved)…
|
|
60
|
-
expect(clientJs).toMatch(/\$\{__bfSlot\(/)
|
|
61
|
-
// …and must never be double-wrapped by either text-escape call.
|
|
62
|
-
expect(clientJs).not.toMatch(/escapeTextOrMarkup\(\s*__bfSlot/)
|
|
63
|
-
expect(clientJs).not.toMatch(/escapeText\(\s*__bfSlot/)
|
|
64
|
-
})
|
|
65
|
-
})
|