@caelo-cms/shared 0.10.72 → 0.11.1
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/ai-tools.d.ts +103 -142
- package/dist/ai-tools.d.ts.map +1 -1
- package/dist/ai-tools.js +79 -167
- package/dist/ai-tools.js.map +1 -1
- package/dist/build-page.d.ts +115 -35
- package/dist/build-page.d.ts.map +1 -1
- package/dist/build-page.js +31 -12
- package/dist/build-page.js.map +1 -1
- package/dist/content.d.ts +214 -102
- package/dist/content.d.ts.map +1 -1
- package/dist/content.js +219 -84
- package/dist/content.js.map +1 -1
- package/dist/css-scope-scan.js +1 -1
- package/dist/css-var-aliases.d.ts +20 -0
- package/dist/css-var-aliases.d.ts.map +1 -0
- package/dist/css-var-aliases.js +95 -0
- package/dist/css-var-aliases.js.map +1 -0
- package/dist/css-var-scan.d.ts +0 -16
- package/dist/css-var-scan.d.ts.map +1 -1
- package/dist/css-var-scan.js +24 -0
- package/dist/css-var-scan.js.map +1 -1
- package/dist/edit-markers.d.ts +41 -5
- package/dist/edit-markers.d.ts.map +1 -1
- package/dist/edit-markers.js +47 -50
- package/dist/edit-markers.js.map +1 -1
- package/dist/escaped-line-breaks.d.ts +44 -0
- package/dist/escaped-line-breaks.d.ts.map +1 -0
- package/dist/escaped-line-breaks.js +203 -0
- package/dist/escaped-line-breaks.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/interactions.js +6 -6
- package/dist/interactions.js.map +1 -1
- package/dist/link-canonicalise.d.ts.map +1 -1
- package/dist/link-canonicalise.js +7 -1
- package/dist/link-canonicalise.js.map +1 -1
- package/dist/link-refs.d.ts +1 -1
- package/dist/link-refs.js +3 -3
- package/dist/lists/address.d.ts +34 -0
- package/dist/lists/address.d.ts.map +1 -0
- package/dist/lists/address.js +43 -0
- package/dist/lists/address.js.map +1 -0
- package/dist/lists/default-types.d.ts +22 -0
- package/dist/lists/default-types.d.ts.map +1 -0
- package/dist/lists/default-types.js +127 -0
- package/dist/lists/default-types.js.map +1 -0
- package/dist/lists/fields.d.ts +152 -0
- package/dist/lists/fields.d.ts.map +1 -0
- package/dist/lists/fields.js +259 -0
- package/dist/lists/fields.js.map +1 -0
- package/dist/lists/index.d.ts +14 -0
- package/dist/lists/index.d.ts.map +1 -0
- package/dist/lists/index.js +15 -0
- package/dist/lists/index.js.map +1 -0
- package/dist/lists/item-attr.d.ts +26 -0
- package/dist/lists/item-attr.d.ts.map +1 -0
- package/dist/lists/item-attr.js +31 -0
- package/dist/lists/item-attr.js.map +1 -0
- package/dist/lists/items.d.ts +105 -0
- package/dist/lists/items.d.ts.map +1 -0
- package/dist/lists/items.js +304 -0
- package/dist/lists/items.js.map +1 -0
- package/dist/lists/list-type.d.ts +401 -0
- package/dist/lists/list-type.d.ts.map +1 -0
- package/dist/lists/list-type.js +275 -0
- package/dist/lists/list-type.js.map +1 -0
- package/dist/lists/model.d.ts +14 -0
- package/dist/lists/model.d.ts.map +1 -0
- package/dist/lists/model.js +15 -0
- package/dist/lists/model.js.map +1 -0
- package/dist/lists/page-type.d.ts +115 -0
- package/dist/lists/page-type.d.ts.map +1 -0
- package/dist/lists/page-type.js +66 -0
- package/dist/lists/page-type.js.map +1 -0
- package/dist/lists/refs.d.ts +13 -0
- package/dist/lists/refs.d.ts.map +1 -0
- package/dist/lists/refs.js +18 -0
- package/dist/lists/refs.js.map +1 -0
- package/dist/lists/render-data.d.ts +123 -0
- package/dist/lists/render-data.d.ts.map +1 -0
- package/dist/lists/render-data.js +3 -0
- package/dist/lists/render-data.js.map +1 -0
- package/dist/lists/render-deps.d.ts +69 -0
- package/dist/lists/render-deps.d.ts.map +1 -0
- package/dist/lists/render-deps.js +93 -0
- package/dist/lists/render-deps.js.map +1 -0
- package/dist/lists/resolve-values.d.ts +63 -0
- package/dist/lists/resolve-values.d.ts.map +1 -0
- package/dist/lists/resolve-values.js +181 -0
- package/dist/lists/resolve-values.js.map +1 -0
- package/dist/lists/resolve.d.ts +119 -0
- package/dist/lists/resolve.d.ts.map +1 -0
- package/dist/lists/resolve.js +970 -0
- package/dist/lists/resolve.js.map +1 -0
- package/dist/lists/scope.d.ts +81 -0
- package/dist/lists/scope.d.ts.map +1 -0
- package/dist/lists/scope.js +3 -0
- package/dist/lists/scope.js.map +1 -0
- package/dist/markup-structure.d.ts +8 -0
- package/dist/markup-structure.d.ts.map +1 -1
- package/dist/markup-structure.js +2 -0
- package/dist/markup-structure.js.map +1 -1
- package/dist/media.d.ts +1 -1
- package/dist/nested-module-render.d.ts +38 -20
- package/dist/nested-module-render.d.ts.map +1 -1
- package/dist/nested-module-render.js +156 -31
- package/dist/nested-module-render.js.map +1 -1
- package/dist/page-log.d.ts +1 -1
- package/dist/preview-compose.d.ts +24 -21
- package/dist/preview-compose.d.ts.map +1 -1
- package/dist/preview-compose.js +34 -118
- package/dist/preview-compose.js.map +1 -1
- package/dist/redirect-plan.d.ts +13 -0
- package/dist/redirect-plan.d.ts.map +1 -1
- package/dist/redirect-plan.js +22 -0
- package/dist/redirect-plan.js.map +1 -1
- package/dist/seo.d.ts +21 -0
- package/dist/seo.d.ts.map +1 -1
- package/dist/seo.js +32 -0
- package/dist/seo.js.map +1 -1
- package/dist/source-text-transport.d.ts +43 -0
- package/dist/source-text-transport.d.ts.map +1 -0
- package/dist/source-text-transport.js +79 -0
- package/dist/source-text-transport.js.map +1 -0
- package/dist/template-engine.d.ts +44 -31
- package/dist/template-engine.d.ts.map +1 -1
- package/dist/template-engine.js +75 -174
- package/dist/template-engine.js.map +1 -1
- package/dist/template-sections.d.ts +69 -0
- package/dist/template-sections.d.ts.map +1 -0
- package/dist/template-sections.js +436 -0
- package/dist/template-sections.js.map +1 -0
- package/dist/version.d.ts +2 -2
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +8 -1
- package/src/__tests__/redos-hardening.test.ts +51 -16
- package/src/ai-tools-add-module-modes.test.ts +51 -1
- package/src/ai-tools.test.ts +7 -10
- package/src/ai-tools.ts +90 -180
- package/src/bug-intake.test.ts +1 -1
- package/src/build-page.test.ts +34 -3
- package/src/build-page.ts +34 -11
- package/src/content.test.ts +137 -4
- package/src/content.ts +230 -85
- package/src/css-scope-scan.ts +1 -1
- package/src/css-var-aliases.test.ts +61 -0
- package/src/css-var-aliases.ts +109 -0
- package/src/css-var-scan.ts +9 -0
- package/src/edit-markers.test.ts +37 -21
- package/src/edit-markers.ts +52 -20
- package/src/escaped-line-breaks.ts +221 -0
- package/src/index.ts +4 -1
- package/src/interactions.ts +6 -6
- package/src/link-canonicalise.test.ts +36 -6
- package/src/link-canonicalise.ts +6 -1
- package/src/link-refs.test.ts +67 -42
- package/src/link-refs.ts +3 -3
- package/src/lists/address.ts +75 -0
- package/src/lists/default-types.ts +141 -0
- package/src/lists/fields.ts +286 -0
- package/src/lists/index.ts +16 -0
- package/src/lists/item-attr.test.ts +36 -0
- package/src/lists/item-attr.ts +49 -0
- package/src/lists/items.ts +402 -0
- package/src/lists/list-fixtures.test.ts +308 -0
- package/src/lists/list-type.ts +306 -0
- package/src/lists/lists.test.ts +328 -0
- package/src/lists/model.ts +16 -0
- package/src/lists/page-type.ts +71 -0
- package/src/lists/refs.ts +21 -0
- package/src/lists/render-data.ts +134 -0
- package/src/lists/render-deps.test.ts +132 -0
- package/src/lists/render-deps.ts +147 -0
- package/src/lists/resolve-values.ts +224 -0
- package/src/lists/resolve.test.ts +472 -0
- package/src/lists/resolve.ts +1246 -0
- package/src/lists/scope.ts +69 -0
- package/src/lists-compose-parity.test.ts +262 -0
- package/src/markup-structure.ts +10 -0
- package/src/nested-module-render.test.ts +147 -74
- package/src/nested-module-render.ts +120 -48
- package/src/preview-compose.test.ts +55 -19
- package/src/preview-compose.ts +59 -154
- package/src/redirect-plan.test.ts +25 -0
- package/src/redirect-plan.ts +24 -0
- package/src/seo.test.ts +58 -0
- package/src/seo.ts +49 -0
- package/src/source-text-transport.test.ts +158 -0
- package/src/source-text-transport.ts +81 -0
- package/src/template-engine-lists.test.ts +608 -0
- package/src/template-engine.test.ts +62 -80
- package/src/template-engine.ts +102 -245
- package/src/template-sections.ts +514 -0
- package/src/version.ts +1 -1
- package/dist/structured-sets.d.ts +0 -70
- package/dist/structured-sets.d.ts.map +0 -1
- package/dist/structured-sets.js +0 -92
- package/dist/structured-sets.js.map +0 -1
- package/src/structured-sets.ts +0 -114
- package/src/template-engine-data-lists.test.ts +0 -90
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
+
/**
|
|
3
|
+
* Common names for theme roles, mapped to the names Caelo's theme emits.
|
|
4
|
+
*
|
|
5
|
+
* Module CSS is authored against conventions the model knows from other
|
|
6
|
+
* design systems: `--color-text`, `--color-surface`, `--color-text-muted`.
|
|
7
|
+
* Caelo's theme calls those roles `--color-foreground`, `--color-background`
|
|
8
|
+
* and `--color-muted-foreground`. The write-time scan used to answer with an
|
|
9
|
+
* edit-distance guess (`--color-text` → "did you mean `--color-accent`?"),
|
|
10
|
+
* so the AI loaded the theme and renamed every reference with edit_content
|
|
11
|
+
* — two to three extra tool calls per module, and a failed one when the
|
|
12
|
+
* same declaration appeared twice (e2e-livedit run 40351690739). A name
|
|
13
|
+
* that unambiguously means a role the theme has is renamed before the
|
|
14
|
+
* write instead, and the tool result says so, the same way theme-literal
|
|
15
|
+
* binding rewrites a literal that equals a token (issue #164). Only names
|
|
16
|
+
* in this table are touched, and only when the theme emits the target.
|
|
17
|
+
*/
|
|
18
|
+
/** Role name (without `--` and an optional `color-` prefix) → theme role. */
|
|
19
|
+
const ROLE_ALIASES = {
|
|
20
|
+
text: "foreground",
|
|
21
|
+
"text-primary": "foreground",
|
|
22
|
+
"text-color": "foreground",
|
|
23
|
+
"body-text": "foreground",
|
|
24
|
+
fg: "foreground",
|
|
25
|
+
heading: "foreground",
|
|
26
|
+
"text-muted": "muted-foreground",
|
|
27
|
+
"text-secondary": "muted-foreground",
|
|
28
|
+
"text-subtle": "muted-foreground",
|
|
29
|
+
"muted-text": "muted-foreground",
|
|
30
|
+
"fg-muted": "muted-foreground",
|
|
31
|
+
surface: "background",
|
|
32
|
+
bg: "background",
|
|
33
|
+
"page-bg": "background",
|
|
34
|
+
"body-bg": "background",
|
|
35
|
+
"surface-muted": "muted",
|
|
36
|
+
"surface-alt": "muted",
|
|
37
|
+
"bg-muted": "muted",
|
|
38
|
+
"bg-subtle": "muted",
|
|
39
|
+
"surface-raised": "card",
|
|
40
|
+
"card-bg": "card",
|
|
41
|
+
"border-color": "border",
|
|
42
|
+
divider: "border",
|
|
43
|
+
line: "border",
|
|
44
|
+
};
|
|
45
|
+
/** The theme var an unknown name stands for, or null. */
|
|
46
|
+
export function themeVarForAlias(name, knownVars) {
|
|
47
|
+
const bare = name.replace(/^--/, "").replace(/^color-/, "");
|
|
48
|
+
const role = ROLE_ALIASES[bare];
|
|
49
|
+
if (role === undefined)
|
|
50
|
+
return null;
|
|
51
|
+
const target = `--color-${role}`;
|
|
52
|
+
return knownVars.has(target) ? target : null;
|
|
53
|
+
}
|
|
54
|
+
/** `var(` + the referenced name, when the name ends there. */
|
|
55
|
+
const VAR_NAME_RE = /(var\(\s*)(--[a-zA-Z0-9_-]+)(?![a-zA-Z0-9_-])/g;
|
|
56
|
+
/**
|
|
57
|
+
* Rename `var(--alias…)` references to the theme's name for that role.
|
|
58
|
+
* A name the CSS itself defines (`--surface: …`) is the author's own
|
|
59
|
+
* property and stays.
|
|
60
|
+
*/
|
|
61
|
+
export function renameCssVarAliases(css, knownVars, definedInCss) {
|
|
62
|
+
const known = new Set(knownVars);
|
|
63
|
+
const targets = new Map();
|
|
64
|
+
const counts = new Map();
|
|
65
|
+
// One pass over the references, no pattern built from a name.
|
|
66
|
+
const out = css.replace(VAR_NAME_RE, (match, open, name) => {
|
|
67
|
+
if (known.has(name) || definedInCss.has(name))
|
|
68
|
+
return match;
|
|
69
|
+
let to = targets.get(name);
|
|
70
|
+
if (to === undefined) {
|
|
71
|
+
const resolved = themeVarForAlias(name, known);
|
|
72
|
+
if (resolved === null)
|
|
73
|
+
return match;
|
|
74
|
+
to = resolved;
|
|
75
|
+
targets.set(name, to);
|
|
76
|
+
}
|
|
77
|
+
counts.set(name, (counts.get(name) ?? 0) + 1);
|
|
78
|
+
return `${open}${to}`;
|
|
79
|
+
});
|
|
80
|
+
const renames = [...targets].map(([from, to]) => ({
|
|
81
|
+
from,
|
|
82
|
+
to,
|
|
83
|
+
count: counts.get(from) ?? 0,
|
|
84
|
+
}));
|
|
85
|
+
return { css: out, renames };
|
|
86
|
+
}
|
|
87
|
+
/** Tool-result sentence for the renames, or null. */
|
|
88
|
+
export function formatCssVarRenameReport(renames) {
|
|
89
|
+
if (renames.length === 0)
|
|
90
|
+
return null;
|
|
91
|
+
return ` 🔗 renamed to the theme's names: ${renames
|
|
92
|
+
.map((r) => `${r.from}→${r.to}${r.count > 1 ? `×${r.count}` : ""}`)
|
|
93
|
+
.join(", ")} — the STORED css uses the theme's names, so anchor later edit_content calls on those.`;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=css-var-aliases.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css-var-aliases.js","sourceRoot":"","sources":["../src/css-var-aliases.ts"],"names":[],"mappings":"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"}
|
package/dist/css-var-scan.d.ts
CHANGED
|
@@ -1,19 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* issue #156 — CSS custom-property reference scanner.
|
|
3
|
-
*
|
|
4
|
-
* The silent-fallback trap: module/template/layout CSS referencing a
|
|
5
|
-
* `var(--…)` the active theme never emits renders the hardcoded
|
|
6
|
-
* fallback (or nothing), so the page quietly diverges from the theme —
|
|
7
|
-
* the monochrome regression class documented in theme-render.ts. The
|
|
8
|
-
* prompt-level var inventory guards the happy path; this scanner is the
|
|
9
|
-
* mechanical write-time guard (CLAUDE.md §2: misses must be loud).
|
|
10
|
-
*
|
|
11
|
-
* Pure string analysis — callers (authoring tools, preview op) supply
|
|
12
|
-
* the known-var set from `listThemeCssVarNames(activeTheme.tokens)`.
|
|
13
|
-
* Custom properties DEFINED anywhere in the scanned bundle are treated
|
|
14
|
-
* as known: a layout may define `--site-gutter` for its modules, and
|
|
15
|
-
* that is legitimate authoring, not drift.
|
|
16
|
-
*/
|
|
17
1
|
/** One `var(--x)` reference found in CSS. */
|
|
18
2
|
export interface CssVarReference {
|
|
19
3
|
readonly name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"css-var-scan.d.ts","sourceRoot":"","sources":["../src/css-var-scan.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"css-var-scan.d.ts","sourceRoot":"","sources":["../src/css-var-scan.ts"],"names":[],"mappings":"AAqBA,6CAA6C;AAC7C,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC/B;AAKD,iFAAiF;AACjF,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,EAAE,CAStE;AAED,4DAA4D;AAC5D,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAMjE;AAsBD,sEAAsE;AACtE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,qEAAqE;IACrE,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,eAAe;IAC9B,yEAAyE;IACzE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,eAAe,GAAG,aAAa,EAAE,CAiCnE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,GAAG,MAAM,GAAG,IAAI,CAa3F"}
|
package/dist/css-var-scan.js
CHANGED
|
@@ -1,4 +1,21 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
+
/**
|
|
3
|
+
* issue #156 — CSS custom-property reference scanner.
|
|
4
|
+
*
|
|
5
|
+
* The silent-fallback trap: module/template/layout CSS referencing a
|
|
6
|
+
* `var(--…)` the active theme never emits renders the hardcoded
|
|
7
|
+
* fallback (or nothing), so the page quietly diverges from the theme —
|
|
8
|
+
* the monochrome regression class documented in theme-render.ts. The
|
|
9
|
+
* prompt-level var inventory guards the happy path; this scanner is the
|
|
10
|
+
* mechanical write-time guard (CLAUDE.md §2: misses must be loud).
|
|
11
|
+
*
|
|
12
|
+
* Pure string analysis — callers (authoring tools, preview op) supply
|
|
13
|
+
* the known-var set from `listThemeCssVarNames(activeTheme.tokens)`.
|
|
14
|
+
* Custom properties DEFINED anywhere in the scanned bundle are treated
|
|
15
|
+
* as known: a layout may define `--site-gutter` for its modules, and
|
|
16
|
+
* that is legitimate authoring, not drift.
|
|
17
|
+
*/
|
|
18
|
+
import { themeVarForAlias } from "./css-var-aliases.js";
|
|
2
19
|
const VAR_REFERENCE_RE = /var\(\s*(--[a-zA-Z0-9_-]+)\s*(,)?/g;
|
|
3
20
|
const VAR_DEFINITION_RE = /(?:^|[{;\s])(--[a-zA-Z0-9_-]+)\s*:/g;
|
|
4
21
|
/** Extract every `var(--x[, fallback])` reference (deduped by name+fallback). */
|
|
@@ -52,6 +69,13 @@ export function scanCssVars(input) {
|
|
|
52
69
|
if (known.has(ref.name) || reported.has(ref.name))
|
|
53
70
|
continue;
|
|
54
71
|
reported.add(ref.name);
|
|
72
|
+
// A common role name (`--color-text`) suggests the theme's name for
|
|
73
|
+
// that role, not the nearest spelling (which was `--color-accent`).
|
|
74
|
+
const alias = themeVarForAlias(ref.name, known);
|
|
75
|
+
if (alias !== null) {
|
|
76
|
+
unknown.push({ name: ref.name, hasFallback: ref.hasFallback, suggestion: alias });
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
55
79
|
let best = null;
|
|
56
80
|
let bestDist = Number.POSITIVE_INFINITY;
|
|
57
81
|
for (const candidate of known) {
|
package/dist/css-var-scan.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"css-var-scan.js","sourceRoot":"","sources":["../src/css-var-scan.ts"],"names":[],"mappings":"AAAA,mCAAmC;
|
|
1
|
+
{"version":3,"file":"css-var-scan.js","sourceRoot":"","sources":["../src/css-var-scan.ts"],"names":[],"mappings":"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"}
|
package/dist/edit-markers.d.ts
CHANGED
|
@@ -1,23 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #917 — field markers for the Live Edit preview. They let the preview
|
|
3
|
+
* iframe tell which placement + field a piece of visible text came from,
|
|
4
|
+
* so the operator can edit that text in place.
|
|
5
|
+
*
|
|
6
|
+
* Two steps around the normal module render:
|
|
7
|
+
*
|
|
8
|
+
* 1. {@link wrapEditableValues} wraps every plain-text value of a
|
|
9
|
+
* placement's content instance in private-use sentinels that carry
|
|
10
|
+
* the field path. The template engine substitutes the wrapped value
|
|
11
|
+
* like any other string (its escape is the identity), so the
|
|
12
|
+
* sentinels land wherever the module author put `{{field}}`.
|
|
13
|
+
* 2. {@link finalizeEditMarkers} scans the rendered HTML. A sentinel in
|
|
14
|
+
* text content becomes a pair of HTML comments around the value:
|
|
15
|
+
* `<!--caelo:f p=<placement> s=<0|1> f=<path>-->value<!--/caelo:f-->`.
|
|
16
|
+
* Comments do not affect layout or CSS selectors. A sentinel in a
|
|
17
|
+
* comment or a raw-text element (`<script>`, `<style>`, `<title>`,
|
|
18
|
+
* `<textarea>`) is removed and the value stays as it was. In a tag
|
|
19
|
+
* it is removed too; an `href` / `src` / `alt` that is exactly one
|
|
20
|
+
* marked value also gets `data-caelo-fields` on its tag (#918).
|
|
21
|
+
*
|
|
22
|
+
* Only the editor preview runs this. Published output never carries
|
|
23
|
+
* markers: the static generator and every other caller of
|
|
24
|
+
* `pages.render_preview` leave `editMarkers` off.
|
|
25
|
+
*
|
|
26
|
+
* Only values without `<` are wrapped: a value that carries markup cannot
|
|
27
|
+
* be edited as plain text without destroying that markup.
|
|
28
|
+
*/
|
|
29
|
+
import type { ListTypeDef } from "./lists/list-type.js";
|
|
1
30
|
/** Comment prefix of an opening marker; the closing marker is `/caelo:f`. */
|
|
2
31
|
export declare const EDIT_MARKER_PREFIX = "caelo:f";
|
|
3
|
-
/** Field shape {@link wrapEditableValues} needs: name + kind. */
|
|
32
|
+
/** Field shape {@link wrapEditableValues} needs: name + kind (+ a list field's type and binding). */
|
|
4
33
|
export interface EditableFieldDef {
|
|
5
34
|
readonly name: string;
|
|
6
35
|
readonly kind?: string;
|
|
36
|
+
readonly listType?: string;
|
|
37
|
+
readonly bind?: string;
|
|
7
38
|
}
|
|
39
|
+
/** List type lookup by slug, for marking a local list's entries. */
|
|
40
|
+
export type EditableListTypes = (slug: string) => ListTypeDef | undefined;
|
|
8
41
|
/**
|
|
9
42
|
* Wrap the editable text of a content instance's values in sentinels.
|
|
10
43
|
* Returns a new object; non-editable values pass through untouched.
|
|
11
44
|
*
|
|
12
|
-
* Paths: `<field>` for a `text` / `url` / `image` field
|
|
13
|
-
* for a `text
|
|
14
|
-
* `link
|
|
45
|
+
* Paths: `<field>` for a `text` / `url` / `image` field;
|
|
46
|
+
* `<field>.<itemId>.<key>` for a `text` value of a local list entry and
|
|
47
|
+
* `<field>.<itemId>.<key>.href` for the target of its `link` value (item
|
|
48
|
+
* ids are stable uuids, so a path survives reordering). Shared lists are
|
|
49
|
+
* edited in the list editor, not in place: their values are not part of
|
|
50
|
+
* the placement.
|
|
15
51
|
*
|
|
16
52
|
* @example
|
|
17
53
|
* wrapEditableValues({ hero_title: "Hi" }, [{ name: "hero_title", kind: "text" }]);
|
|
18
54
|
* // → { hero_title: "\uE000hero_title\uE001Hi\uE002" }
|
|
19
55
|
*/
|
|
20
|
-
export declare function wrapEditableValues(values: Readonly<Record<string, unknown>>, fields: readonly EditableFieldDef[]): Record<string, unknown>;
|
|
56
|
+
export declare function wrapEditableValues(values: Readonly<Record<string, unknown>>, fields: readonly EditableFieldDef[], listTypes?: EditableListTypes): Record<string, unknown>;
|
|
21
57
|
/**
|
|
22
58
|
* Turn sentinels in rendered module HTML into marker comments (text
|
|
23
59
|
* content) or drop them (everywhere else). See the file header.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edit-markers.d.ts","sourceRoot":"","sources":["../src/edit-markers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"edit-markers.d.ts","sourceRoot":"","sources":["../src/edit-markers.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAOxD,6EAA6E;AAC7E,eAAO,MAAM,kBAAkB,YAAY,CAAC;AAa5C,qGAAqG;AACrG,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,oEAAoE;AACpE,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,WAAW,GAAG,SAAS,CAAC;AAY1E;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,MAAM,EAAE,SAAS,gBAAgB,EAAE,EACnC,SAAS,CAAC,EAAE,iBAAiB,GAC5B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAczB;AAoDD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CA2ChG;AA+BD,+BAA+B;AAC/B,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAgBlE"}
|
package/dist/edit-markers.js
CHANGED
|
@@ -1,32 +1,4 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
-
/**
|
|
3
|
-
* #917 — field markers for the Live Edit preview. They let the preview
|
|
4
|
-
* iframe tell which placement + field a piece of visible text came from,
|
|
5
|
-
* so the operator can edit that text in place.
|
|
6
|
-
*
|
|
7
|
-
* Two steps around the normal module render:
|
|
8
|
-
*
|
|
9
|
-
* 1. {@link wrapEditableValues} wraps every plain-text value of a
|
|
10
|
-
* placement's content instance in private-use sentinels that carry
|
|
11
|
-
* the field path. The template engine substitutes the wrapped value
|
|
12
|
-
* like any other string (its escape is the identity), so the
|
|
13
|
-
* sentinels land wherever the module author put `{{field}}`.
|
|
14
|
-
* 2. {@link finalizeEditMarkers} scans the rendered HTML. A sentinel in
|
|
15
|
-
* text content becomes a pair of HTML comments around the value:
|
|
16
|
-
* `<!--caelo:f p=<placement> s=<0|1> f=<path>-->value<!--/caelo:f-->`.
|
|
17
|
-
* Comments do not affect layout or CSS selectors. A sentinel in a
|
|
18
|
-
* comment or a raw-text element (`<script>`, `<style>`, `<title>`,
|
|
19
|
-
* `<textarea>`) is removed and the value stays as it was. In a tag
|
|
20
|
-
* it is removed too; an `href` / `src` / `alt` that is exactly one
|
|
21
|
-
* marked value also gets `data-caelo-fields` on its tag (#918).
|
|
22
|
-
*
|
|
23
|
-
* Only the editor preview runs this. Published output never carries
|
|
24
|
-
* markers: the static generator and every other caller of
|
|
25
|
-
* `pages.render_preview` leave `editMarkers` off.
|
|
26
|
-
*
|
|
27
|
-
* Only values without `<` are wrapped: a value that carries markup cannot
|
|
28
|
-
* be edited as plain text without destroying that markup.
|
|
29
|
-
*/
|
|
30
2
|
const START = "\uE000";
|
|
31
3
|
const SEP = "\uE001";
|
|
32
4
|
const END = "\uE002";
|
|
@@ -34,13 +6,15 @@ const SENTINELS = /[\uE000-\uE002]/g;
|
|
|
34
6
|
/** Comment prefix of an opening marker; the closing marker is `/caelo:f`. */
|
|
35
7
|
export const EDIT_MARKER_PREFIX = "caelo:f";
|
|
36
8
|
/**
|
|
37
|
-
* Field kinds the preview marks: text (`text`, `text
|
|
38
|
-
* `
|
|
39
|
-
* `
|
|
9
|
+
* Field kinds the preview marks: text (`text`, the `text` fields of a
|
|
10
|
+
* local `list`'s entries) and link / image targets (`url`, `image`, the
|
|
11
|
+
* `href` of a local list entry's `link` fields, #918) — the latter
|
|
12
|
+
* usually land in `href` / `src`.
|
|
40
13
|
*/
|
|
41
|
-
const EDITABLE_KINDS = new Set(["text", "
|
|
14
|
+
const EDITABLE_KINDS = new Set(["text", "url", "image", "list"]);
|
|
42
15
|
/** Attributes whose marked value the editor can change (link target, image, alt text). */
|
|
43
16
|
const MARKABLE_ATTRIBUTES = new Set(["href", "src", "alt"]);
|
|
17
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
44
18
|
function editable(value) {
|
|
45
19
|
return typeof value === "string" && value.trim().length > 0 && !value.includes("<");
|
|
46
20
|
}
|
|
@@ -51,15 +25,18 @@ function wrap(path, value) {
|
|
|
51
25
|
* Wrap the editable text of a content instance's values in sentinels.
|
|
52
26
|
* Returns a new object; non-editable values pass through untouched.
|
|
53
27
|
*
|
|
54
|
-
* Paths: `<field>` for a `text` / `url` / `image` field
|
|
55
|
-
* for a `text
|
|
56
|
-
* `link
|
|
28
|
+
* Paths: `<field>` for a `text` / `url` / `image` field;
|
|
29
|
+
* `<field>.<itemId>.<key>` for a `text` value of a local list entry and
|
|
30
|
+
* `<field>.<itemId>.<key>.href` for the target of its `link` value (item
|
|
31
|
+
* ids are stable uuids, so a path survives reordering). Shared lists are
|
|
32
|
+
* edited in the list editor, not in place: their values are not part of
|
|
33
|
+
* the placement.
|
|
57
34
|
*
|
|
58
35
|
* @example
|
|
59
36
|
* wrapEditableValues({ hero_title: "Hi" }, [{ name: "hero_title", kind: "text" }]);
|
|
60
37
|
* // → { hero_title: "\uE000hero_title\uE001Hi\uE002" }
|
|
61
38
|
*/
|
|
62
|
-
export function wrapEditableValues(values, fields) {
|
|
39
|
+
export function wrapEditableValues(values, fields, listTypes) {
|
|
63
40
|
const out = { ...values };
|
|
64
41
|
for (const f of fields) {
|
|
65
42
|
const kind = f.kind ?? "text";
|
|
@@ -70,24 +47,44 @@ export function wrapEditableValues(values, fields) {
|
|
|
70
47
|
if (editable(v))
|
|
71
48
|
out[f.name] = wrap(f.name, v);
|
|
72
49
|
}
|
|
73
|
-
else if (kind === "
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
out[f.name] = v.map((item, i) => {
|
|
78
|
-
if (typeof item !== "object" || item === null)
|
|
79
|
-
return item;
|
|
80
|
-
const { label, href } = item;
|
|
81
|
-
return {
|
|
82
|
-
...item,
|
|
83
|
-
...(editable(label) ? { label: wrap(`${f.name}.${i}.label`, label) } : {}),
|
|
84
|
-
...(editable(href) ? { href: wrap(`${f.name}.${i}.href`, href) } : {}),
|
|
85
|
-
};
|
|
86
|
-
});
|
|
50
|
+
else if (kind === "list" && (f.bind ?? "local") === "local" && Array.isArray(v)) {
|
|
51
|
+
const type = f.listType === undefined ? undefined : listTypes?.(f.listType);
|
|
52
|
+
if (type)
|
|
53
|
+
out[f.name] = wrapListEntries(f.name, v, type);
|
|
87
54
|
}
|
|
88
55
|
}
|
|
89
56
|
return out;
|
|
90
57
|
}
|
|
58
|
+
/** Mark the text and link targets of local list entries, at any depth. */
|
|
59
|
+
function wrapListEntries(field, items, type) {
|
|
60
|
+
return items.map((raw) => {
|
|
61
|
+
if (typeof raw !== "object" || raw === null)
|
|
62
|
+
return raw;
|
|
63
|
+
const item = raw;
|
|
64
|
+
const node = typeof item.node === "string" ? type.nodes[item.node] : undefined;
|
|
65
|
+
if (!node || typeof item.id !== "string" || !UUID_RE.test(item.id))
|
|
66
|
+
return raw;
|
|
67
|
+
const values = { ...(item.values ?? {}) };
|
|
68
|
+
for (const def of node.fields) {
|
|
69
|
+
const v = values[def.name];
|
|
70
|
+
const at = `${field}.${item.id}.${def.name}`;
|
|
71
|
+
if (def.type === "text" && editable(v))
|
|
72
|
+
values[def.name] = wrap(at, v);
|
|
73
|
+
if (def.type === "link" && typeof v === "object" && v !== null) {
|
|
74
|
+
const href = v.href;
|
|
75
|
+
if (editable(href))
|
|
76
|
+
values[def.name] = { ...v, href: wrap(`${at}.href`, href) };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
...item,
|
|
81
|
+
values,
|
|
82
|
+
...(Array.isArray(item.children)
|
|
83
|
+
? { children: wrapListEntries(field, item.children, type) }
|
|
84
|
+
: {}),
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
}
|
|
91
88
|
/** Comment-safe encoding: no `--`, no `>`, no whitespace. */
|
|
92
89
|
function attr(value) {
|
|
93
90
|
return encodeURIComponent(value).replace(/-/g, "%2D");
|
package/dist/edit-markers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edit-markers.js","sourceRoot":"","sources":["../src/edit-markers.ts"],"names":[],"mappings":"AAAA,mCAAmC;
|
|
1
|
+
{"version":3,"file":"edit-markers.js","sourceRoot":"","sources":["../src/edit-markers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source text whose line breaks arrived string-escaped as a whole.
|
|
3
|
+
*
|
|
4
|
+
* e2e-livedit run 40532297620 (release gate v0.11.1): `add_module`'s html,
|
|
5
|
+
* css and js came in with every line break as the two characters `\` `n`
|
|
6
|
+
* (`(function () {\n document…`). Stored as sent, the footer showed `\n`
|
|
7
|
+
* text, its CSS broke, and the page's shared module `<script>` threw
|
|
8
|
+
* `SyntaxError: Invalid or unexpected token` — a backslash outside a string
|
|
9
|
+
* is not JavaScript. Like the other whole-value transport encodings
|
|
10
|
+
* (`source-text-transport.ts`) the AI tool boundary decodes it, once.
|
|
11
|
+
*
|
|
12
|
+
* The same two characters are legitimate inside a string literal (`"a\nb"`
|
|
13
|
+
* in JS or a CSS `content`), a regex, an HTML attribute value, or the body
|
|
14
|
+
* of a raw-text element. A value is only decoded when EVERY escaped line
|
|
15
|
+
* break sits where a real line break could have stood — between tokens of
|
|
16
|
+
* code, or in markup text between tags. One escape inside a literal makes
|
|
17
|
+
* the value ambiguous and it is left exactly as sent: decoding it would
|
|
18
|
+
* turn valid source into broken source (a raw newline inside a JS string
|
|
19
|
+
* is a syntax error). The op validators still refuse what is left broken
|
|
20
|
+
* (module js is parsed in admin-core `module-js-syntax.ts`).
|
|
21
|
+
*/
|
|
22
|
+
/** Which grammar a source value is written in; decides what counts as a literal. */
|
|
23
|
+
export type SourceLanguage = "html" | "css" | "js";
|
|
24
|
+
/**
|
|
25
|
+
* True when a source value's line breaks were string-escaped as a whole:
|
|
26
|
+
* no real line break at all, at least two escaped ones, one of them
|
|
27
|
+
* followed by indentation (the signature of pretty-printed source), and
|
|
28
|
+
* none inside a literal of `language` (see the file comment).
|
|
29
|
+
*
|
|
30
|
+
* @param value - the source text as sent.
|
|
31
|
+
* @param language - the grammar the value is written in.
|
|
32
|
+
*/
|
|
33
|
+
export declare function hasEscapedLineBreaks(value: string, language: SourceLanguage): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* The value with every escaped line break turned back into a real one (and
|
|
36
|
+
* the escaped tabs indenting the next line into real tabs) when
|
|
37
|
+
* `hasEscapedLineBreaks` holds; the input unchanged otherwise. Nothing else
|
|
38
|
+
* is unescaped: quotes and backslashes arrived as they were meant.
|
|
39
|
+
*
|
|
40
|
+
* @param value - the tool argument (non-strings pass through).
|
|
41
|
+
* @param language - the grammar the value is written in.
|
|
42
|
+
*/
|
|
43
|
+
export declare function decodeEscapedLineBreaks(value: unknown, language: SourceLanguage): unknown;
|
|
44
|
+
//# sourceMappingURL=escaped-line-breaks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escaped-line-breaks.d.ts","sourceRoot":"","sources":["../src/escaped-line-breaks.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,oFAAoF;AACpF,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,KAAK,GAAG,IAAI,CAAC;AAmKnD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAMrF;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAMzF"}
|