@geometra/core 1.0.0 → 1.0.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/README.md +10 -1
- package/dist/a11y.d.ts.map +1 -1
- package/dist/a11y.js +6 -2
- package/dist/a11y.js.map +1 -1
- package/dist/animation.d.ts +39 -1
- package/dist/animation.d.ts.map +1 -1
- package/dist/animation.js +148 -1
- package/dist/animation.js.map +1 -1
- package/dist/app.d.ts +4 -1
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +17 -3
- package/dist/app.js.map +1 -1
- package/dist/direction.d.ts +11 -0
- package/dist/direction.d.ts.map +1 -0
- package/dist/direction.js +18 -0
- package/dist/direction.js.map +1 -0
- package/dist/elements.d.ts +4 -4
- package/dist/elements.d.ts.map +1 -1
- package/dist/elements.js.map +1 -1
- package/dist/focus-trap.d.ts +12 -1
- package/dist/focus-trap.d.ts.map +1 -1
- package/dist/focus-trap.js +12 -1
- package/dist/focus-trap.js.map +1 -1
- package/dist/focus.d.ts +3 -2
- package/dist/focus.d.ts.map +1 -1
- package/dist/focus.js +6 -0
- package/dist/focus.js.map +1 -1
- package/dist/fonts.d.ts +35 -2
- package/dist/fonts.d.ts.map +1 -1
- package/dist/fonts.js +335 -12
- package/dist/fonts.js.map +1 -1
- package/dist/hit-test.d.ts +35 -4
- package/dist/hit-test.d.ts.map +1 -1
- package/dist/hit-test.js +195 -70
- package/dist/hit-test.js.map +1 -1
- package/dist/index.d.ts +21 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -6
- package/dist/index.js.map +1 -1
- package/dist/keyboard.d.ts +5 -2
- package/dist/keyboard.d.ts.map +1 -1
- package/dist/keyboard.js +5 -2
- package/dist/keyboard.js.map +1 -1
- package/dist/selection.d.ts +5 -2
- package/dist/selection.d.ts.map +1 -1
- package/dist/selection.js +37 -8
- package/dist/selection.js.map +1 -1
- package/dist/seo.d.ts +27 -0
- package/dist/seo.d.ts.map +1 -1
- package/dist/seo.js +240 -13
- package/dist/seo.js.map +1 -1
- package/dist/signals.d.ts.map +1 -1
- package/dist/signals.js +44 -7
- package/dist/signals.js.map +1 -1
- package/dist/text-input-history.d.ts +14 -4
- package/dist/text-input-history.d.ts.map +1 -1
- package/dist/text-input-history.js +37 -8
- package/dist/text-input-history.js.map +1 -1
- package/dist/text-input.d.ts +8 -8
- package/dist/text-input.d.ts.map +1 -1
- package/dist/text-input.js +45 -17
- package/dist/text-input.js.map +1 -1
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +3 -0
- package/dist/tree.js.map +1 -1
- package/dist/types.d.ts +29 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/virtual-scroll.d.ts +11 -1
- package/dist/virtual-scroll.d.ts.map +1 -1
- package/dist/virtual-scroll.js +14 -5
- package/dist/virtual-scroll.js.map +1 -1
- package/package.json +2 -2
package/dist/selection.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
import { resolveElementDirection } from './direction.js';
|
|
1
2
|
/** Collect all selectable text nodes from the element tree with their absolute positions. */
|
|
2
|
-
export function collectTextNodes(element, layout, offsetX, offsetY, results) {
|
|
3
|
+
export function collectTextNodes(element, layout, offsetX, offsetY, results, parentDirection = 'ltr') {
|
|
3
4
|
const x = offsetX + layout.x;
|
|
4
5
|
const y = offsetY + layout.y;
|
|
6
|
+
const direction = resolveElementDirection(element, parentDirection);
|
|
5
7
|
if (element.kind === 'text') {
|
|
6
8
|
if (element.props.selectable !== false) {
|
|
7
9
|
results.push({
|
|
8
10
|
element,
|
|
11
|
+
direction,
|
|
9
12
|
x,
|
|
10
13
|
y,
|
|
11
14
|
width: layout.width,
|
|
@@ -21,7 +24,7 @@ export function collectTextNodes(element, layout, offsetX, offsetY, results) {
|
|
|
21
24
|
for (let i = 0; i < element.children.length; i++) {
|
|
22
25
|
const childLayout = layout.children[i];
|
|
23
26
|
if (childLayout) {
|
|
24
|
-
collectTextNodes(element.children[i], childLayout, x, y, results);
|
|
27
|
+
collectTextNodes(element.children[i], childLayout, x, y, results, direction);
|
|
25
28
|
}
|
|
26
29
|
}
|
|
27
30
|
}
|
|
@@ -60,9 +63,19 @@ export function getSelectedText(range, textNodes) {
|
|
|
60
63
|
}
|
|
61
64
|
return parts.join('\n');
|
|
62
65
|
}
|
|
63
|
-
|
|
66
|
+
function textNodeBoundsAreFinite(node) {
|
|
67
|
+
return (Number.isFinite(node.x) &&
|
|
68
|
+
Number.isFinite(node.y) &&
|
|
69
|
+
Number.isFinite(node.width) &&
|
|
70
|
+
Number.isFinite(node.height));
|
|
71
|
+
}
|
|
72
|
+
/** Find which text node and character offset is at a given (x, y) point. Non-finite pointer coordinates return `null`; nodes with non-finite bounds are skipped (same invariant as pointer hit-testing). */
|
|
64
73
|
export function hitTestText(textNodes, px, py) {
|
|
74
|
+
if (!Number.isFinite(px) || !Number.isFinite(py))
|
|
75
|
+
return null;
|
|
65
76
|
for (const node of textNodes) {
|
|
77
|
+
if (!textNodeBoundsAreFinite(node))
|
|
78
|
+
continue;
|
|
66
79
|
// Check if point is within the text node's bounding box
|
|
67
80
|
if (px < node.x || px > node.x + node.width || py < node.y || py > node.y + node.height) {
|
|
68
81
|
continue;
|
|
@@ -74,11 +87,27 @@ export function hitTestText(textNodes, px, py) {
|
|
|
74
87
|
if (py >= line.y && py < lineBottom) {
|
|
75
88
|
// Find the character within the line
|
|
76
89
|
const localX = px - line.x;
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
90
|
+
const lineVisualWidth = line.charOffsets.length > 0
|
|
91
|
+
? (line.charOffsets[line.charOffsets.length - 1] ?? 0) + (line.charWidths[line.charWidths.length - 1] ?? 0)
|
|
92
|
+
: 0;
|
|
93
|
+
if (node.direction === 'rtl') {
|
|
94
|
+
// In RTL mode, map visual x from the right edge back to logical indices.
|
|
95
|
+
const visualFromRight = lineVisualWidth - localX;
|
|
96
|
+
for (let c = 0; c < line.charOffsets.length; c++) {
|
|
97
|
+
const charStart = line.charOffsets[c];
|
|
98
|
+
const charEnd = charStart + line.charWidths[c];
|
|
99
|
+
if (visualFromRight < (charStart + charEnd) / 2) {
|
|
100
|
+
return { nodeIndex: node.index, charOffset: globalCharOffset + c };
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
for (let c = 0; c < line.charOffsets.length; c++) {
|
|
106
|
+
const charStart = line.charOffsets[c];
|
|
107
|
+
const charEnd = charStart + line.charWidths[c];
|
|
108
|
+
if (localX < (charStart + charEnd) / 2) {
|
|
109
|
+
return { nodeIndex: node.index, charOffset: globalCharOffset + c };
|
|
110
|
+
}
|
|
82
111
|
}
|
|
83
112
|
}
|
|
84
113
|
// Past the end of the line — snap to end
|
package/dist/selection.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../src/selection.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../src/selection.ts"],"names":[],"mappings":"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"}
|
package/dist/seo.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { UIElement } from './types.js';
|
|
2
2
|
/** Options for semantic HTML generation. */
|
|
3
3
|
export interface SemanticHTMLOptions {
|
|
4
|
+
/**
|
|
5
|
+
* BCP 47 language tag for the root `<html lang="...">` attribute (defaults to `en`).
|
|
6
|
+
* Value is HTML-escaped; prefer well-formed tags like `en-US` or `fr`.
|
|
7
|
+
*/
|
|
8
|
+
lang?: string;
|
|
4
9
|
/** Page title for the <title> tag. */
|
|
5
10
|
title?: string;
|
|
6
11
|
/** Meta description. */
|
|
@@ -15,6 +20,19 @@ export interface SemanticHTMLOptions {
|
|
|
15
20
|
url?: string;
|
|
16
21
|
type?: string;
|
|
17
22
|
};
|
|
23
|
+
/**
|
|
24
|
+
* Twitter / X Card metadata (`name="twitter:..."`).
|
|
25
|
+
* Values are HTML-escaped; URLs and handles should be passed as plain strings.
|
|
26
|
+
*/
|
|
27
|
+
twitter?: {
|
|
28
|
+
/** e.g. `summary`, `summary_large_image`. */
|
|
29
|
+
card?: string;
|
|
30
|
+
/** Site handle, e.g. `@myapp`. */
|
|
31
|
+
site?: string;
|
|
32
|
+
title?: string;
|
|
33
|
+
description?: string;
|
|
34
|
+
image?: string;
|
|
35
|
+
};
|
|
18
36
|
/** Additional <head> content (raw HTML string). */
|
|
19
37
|
headExtra?: string;
|
|
20
38
|
}
|
|
@@ -24,6 +42,15 @@ export interface SemanticHTMLOptions {
|
|
|
24
42
|
* This produces a full HTML document suitable for search engine crawlers.
|
|
25
43
|
* Serve this to user-agents like Googlebot while rendering the canvas
|
|
26
44
|
* version for real users.
|
|
45
|
+
*
|
|
46
|
+
* When `props.dir` is `ltr`, `rtl`, or `auto` on a box, text, or image node, the HTML `dir`
|
|
47
|
+
* attribute is emitted on that element’s tag.
|
|
48
|
+
*
|
|
49
|
+
* `semantic.tag` is validated as a safe HTML local name (letter, then letters/digits/hyphen, ≤128
|
|
50
|
+
* chars); invalid values fall back to font/box inference so crawlers cannot receive broken markup.
|
|
51
|
+
*
|
|
52
|
+
* Default box tags: `onClick` maps to `<button>` only for an empty box or a box whose sole child is
|
|
53
|
+
* `text()`; otherwise `div` (compound click targets should use `semantic.tag` / roles when needed).
|
|
27
54
|
*/
|
|
28
55
|
export declare function toSemanticHTML(tree: UIElement, options?: SemanticHTMLOptions): string;
|
|
29
56
|
//# sourceMappingURL=seo.d.ts.map
|
package/dist/seo.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seo.d.ts","sourceRoot":"","sources":["../src/seo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAyC,MAAM,YAAY,CAAA;AAElF,4CAA4C;AAC5C,MAAM,WAAW,mBAAmB;IAClC,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wBAAwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,2BAA2B;IAC3B,EAAE,CAAC,EAAE;QACH,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,IAAI,CAAC,EAAE,MAAM,CAAA;KACd,CAAA;IACD,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;
|
|
1
|
+
{"version":3,"file":"seo.d.ts","sourceRoot":"","sources":["../src/seo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAyC,MAAM,YAAY,CAAA;AAElF,4CAA4C;AAC5C,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wBAAwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,2BAA2B;IAC3B,EAAE,CAAC,EAAE;QACH,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,IAAI,CAAC,EAAE,MAAM,CAAA;KACd,CAAA;IACD;;;OAGG;IACH,OAAO,CAAC,EAAE;QACR,6CAA6C;QAC7C,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,kCAAkC;QAClC,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,KAAK,CAAC,EAAE,MAAM,CAAA;KACf,CAAA;IACD,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AA2QD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,SAAS,EACf,OAAO,GAAE,mBAAwB,GAChC,MAAM,CAkDR"}
|
package/dist/seo.js
CHANGED
|
@@ -1,10 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* First explicit `font-size` length in the shorthand (supports scientific notation).
|
|
3
|
+
* Used only for heading-level heuristics in static HTML; non-px units map to approximate px.
|
|
4
|
+
* Covers `%`, viewport units (including dynamic `d*`, small `s*`, and large `l*` variants), common font-relative units (`ch`, `cap`, `math`), and absolute lengths
|
|
5
|
+
* (`pt`, `pc`, `in`, `cm`, `mm`, `Q`) aligned with typical `fonts.ts` shorthand shapes (subset of units;
|
|
6
|
+
* coarse px mapping for tier heuristics only). Longer viewport unit tokens precede shorter prefixes
|
|
7
|
+
* (e.g. `dvmin` before `vmin`), aligned with `fonts.ts`.
|
|
8
|
+
*/
|
|
9
|
+
const FONT_SIZE_LENGTH = /(\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)\s*(%|px|rem|em|pt|pc|in|cm|mm|Q|math|dvmin|dvmax|svmin|svmax|lvmin|lvmax|dvh|dvw|dvi|dvb|svh|svw|svi|svb|lvh|lvw|lvi|lvb|vmin|vmax|vh|vw|vi|vb|rlh|lh|rcap|rch|rex|ric|cap|ch|ex|ic|cqmin|cqmax|cqw|cqh|cqi|cqb)(?=[\s,;/]|$)/i;
|
|
10
|
+
/**
|
|
11
|
+
* True when the **leading** font shorthand style segment (before the first font-size length token)
|
|
12
|
+
* indicates bold weight: `bold` / `bolder` as whole tokens, or numeric 700–900.
|
|
13
|
+
* Substrings such as `semibold` must not match. Tokens after the size (e.g. family names like
|
|
14
|
+
* `Bold` or `2024`) must not affect heading inference.
|
|
15
|
+
*/
|
|
16
|
+
function isFontBoldShorthand(stylePrefixLower) {
|
|
17
|
+
if (/\bbold\b/.test(stylePrefixLower) || /\bbolder\b/.test(stylePrefixLower))
|
|
18
|
+
return true;
|
|
19
|
+
const tokens = stylePrefixLower.match(/\b([1-9]\d{2,3})\b/g);
|
|
20
|
+
if (!tokens)
|
|
21
|
+
return false;
|
|
22
|
+
for (const token of tokens) {
|
|
23
|
+
const n = Number.parseInt(token, 10);
|
|
24
|
+
if (n >= 700 && n <= 900)
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Approximate CSS px used for heading inference when the first size token is not `px`.
|
|
31
|
+
* Percent is treated as a fraction of a 16px parent (common root text size). Viewport units use a
|
|
32
|
+
* coarse middle viewport so hero-style `vw`/`vmin` titles map to heading tiers without a real layout.
|
|
33
|
+
*/
|
|
34
|
+
function fontLengthToApproxPx(value, unit) {
|
|
35
|
+
switch (unit.toLowerCase()) {
|
|
36
|
+
case 'px':
|
|
37
|
+
return value;
|
|
38
|
+
case 'rem':
|
|
39
|
+
return value * 16;
|
|
40
|
+
case 'em':
|
|
41
|
+
return value * 14;
|
|
42
|
+
case 'pt':
|
|
43
|
+
return value * (96 / 72);
|
|
44
|
+
case 'pc':
|
|
45
|
+
return value * 16;
|
|
46
|
+
case 'in':
|
|
47
|
+
return value * 96;
|
|
48
|
+
case 'cm':
|
|
49
|
+
return (value * 96) / 2.54;
|
|
50
|
+
case 'mm':
|
|
51
|
+
return (value * 96) / 25.4;
|
|
52
|
+
case 'q':
|
|
53
|
+
return (value * 96) / 25.4 / 4;
|
|
54
|
+
case 'math':
|
|
55
|
+
return value * 16;
|
|
56
|
+
case '%':
|
|
57
|
+
return (value / 100) * 16;
|
|
58
|
+
case 'dvmin':
|
|
59
|
+
case 'dvmax':
|
|
60
|
+
case 'svmin':
|
|
61
|
+
case 'svmax':
|
|
62
|
+
case 'lvmin':
|
|
63
|
+
case 'lvmax':
|
|
64
|
+
case 'vmin':
|
|
65
|
+
case 'vmax':
|
|
66
|
+
return value * 9;
|
|
67
|
+
case 'dvh':
|
|
68
|
+
case 'dvw':
|
|
69
|
+
case 'svh':
|
|
70
|
+
case 'svw':
|
|
71
|
+
case 'lvh':
|
|
72
|
+
case 'lvw':
|
|
73
|
+
case 'vh':
|
|
74
|
+
case 'vw':
|
|
75
|
+
return value * 3;
|
|
76
|
+
case 'dvi':
|
|
77
|
+
case 'dvb':
|
|
78
|
+
case 'svi':
|
|
79
|
+
case 'svb':
|
|
80
|
+
case 'lvi':
|
|
81
|
+
case 'lvb':
|
|
82
|
+
case 'vi':
|
|
83
|
+
case 'vb':
|
|
84
|
+
return value * 3;
|
|
85
|
+
// Container query units: no real container in static HTML; coarse tiers only.
|
|
86
|
+
case 'cqmin':
|
|
87
|
+
return value * 9;
|
|
88
|
+
case 'cqmax':
|
|
89
|
+
return value * 12;
|
|
90
|
+
case 'cqw':
|
|
91
|
+
case 'cqh':
|
|
92
|
+
return value * 3;
|
|
93
|
+
case 'cqi':
|
|
94
|
+
return value * 8;
|
|
95
|
+
case 'cqb':
|
|
96
|
+
return value * 18;
|
|
97
|
+
// Root-relative font metrics (aligned with `fonts.ts` unit set).
|
|
98
|
+
case 'rcap':
|
|
99
|
+
return value * 12;
|
|
100
|
+
case 'rch':
|
|
101
|
+
return value * 8;
|
|
102
|
+
case 'rex':
|
|
103
|
+
return value * 8;
|
|
104
|
+
case 'ric':
|
|
105
|
+
return value * 16;
|
|
106
|
+
// Cap-height unit: approximate vs a 16px root for heading-tier heuristics only.
|
|
107
|
+
case 'cap':
|
|
108
|
+
return value * 12;
|
|
109
|
+
// `ch` advance width: coarse ~half-em on a 16px body for static HTML inference.
|
|
110
|
+
case 'ch':
|
|
111
|
+
return value * 8;
|
|
112
|
+
// Root / used line-height: approximate one line at typical body scale (static HTML only).
|
|
113
|
+
case 'rlh':
|
|
114
|
+
return value * 24;
|
|
115
|
+
case 'lh':
|
|
116
|
+
return value * 18;
|
|
117
|
+
// x-height and ideographic character advance vs ~16px body.
|
|
118
|
+
case 'ex':
|
|
119
|
+
return value * 8;
|
|
120
|
+
case 'ic':
|
|
121
|
+
return value * 16;
|
|
122
|
+
default:
|
|
123
|
+
return value;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
1
126
|
/** Infer an HTML tag from a text element's font property. */
|
|
2
127
|
function inferTag(element) {
|
|
3
128
|
const font = element.props.font.toLowerCase();
|
|
4
|
-
// Detect heading-like fonts by size
|
|
5
|
-
const sizeMatch = font.match(
|
|
6
|
-
|
|
7
|
-
|
|
129
|
+
// Detect heading-like fonts by size (first length token in shorthand)
|
|
130
|
+
const sizeMatch = font.match(FONT_SIZE_LENGTH);
|
|
131
|
+
let size = 14;
|
|
132
|
+
if (sizeMatch) {
|
|
133
|
+
const n = parseFloat(sizeMatch[1]);
|
|
134
|
+
const unit = sizeMatch[2];
|
|
135
|
+
if (Number.isFinite(n))
|
|
136
|
+
size = fontLengthToApproxPx(n, unit);
|
|
137
|
+
}
|
|
138
|
+
const stylePrefix = sizeMatch && sizeMatch.index !== undefined ? font.slice(0, sizeMatch.index) : font;
|
|
139
|
+
const isBold = isFontBoldShorthand(stylePrefix);
|
|
8
140
|
if (isBold && size >= 28)
|
|
9
141
|
return 'h1';
|
|
10
142
|
if (isBold && size >= 22)
|
|
@@ -15,13 +147,57 @@ function inferTag(element) {
|
|
|
15
147
|
return 'h4';
|
|
16
148
|
return 'p';
|
|
17
149
|
}
|
|
18
|
-
/**
|
|
150
|
+
/**
|
|
151
|
+
* Infer an HTML tag for a box without `semantic.tag`.
|
|
152
|
+
* Click handlers on compound regions (multiple nodes or non-text children) stay `div` so crawlers do
|
|
153
|
+
* not see one oversized `<button>`; leaf controls (`onClick` + lone text, or empty with `onClick`) map to `button`.
|
|
154
|
+
*/
|
|
19
155
|
function inferBoxTag(element) {
|
|
20
|
-
|
|
21
|
-
|
|
156
|
+
if (!element.handlers?.onClick)
|
|
157
|
+
return 'div';
|
|
158
|
+
const kids = element.children;
|
|
159
|
+
if (kids.length === 0)
|
|
160
|
+
return 'button';
|
|
161
|
+
if (kids.length === 1 && kids[0].kind === 'text')
|
|
22
162
|
return 'button';
|
|
23
163
|
return 'div';
|
|
24
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* HTML void elements: no closing tag in HTML5.
|
|
167
|
+
* Used when `semantic.tag` names a void element and the node has no children.
|
|
168
|
+
*/
|
|
169
|
+
const VOID_HTML_TAGS = new Set([
|
|
170
|
+
'area',
|
|
171
|
+
'base',
|
|
172
|
+
'br',
|
|
173
|
+
'col',
|
|
174
|
+
'embed',
|
|
175
|
+
'hr',
|
|
176
|
+
'img',
|
|
177
|
+
'input',
|
|
178
|
+
'link',
|
|
179
|
+
'meta',
|
|
180
|
+
'param',
|
|
181
|
+
'source',
|
|
182
|
+
'track',
|
|
183
|
+
'wbr',
|
|
184
|
+
]);
|
|
185
|
+
/**
|
|
186
|
+
* HTML5 local name: starts with a-z, then letters/digits/hyphen. Rejects spaces, quotes, and
|
|
187
|
+
* attribute injection. Used so `semantic.tag` cannot break out of the tag token in `toSemanticHTML`.
|
|
188
|
+
*/
|
|
189
|
+
const SAFE_HTML_TAG_NAME = /^[a-z][a-z0-9-]{0,127}$/;
|
|
190
|
+
/**
|
|
191
|
+
* Return a safe tag name for static HTML, or `fallback` when `tag` is missing or malformed.
|
|
192
|
+
*/
|
|
193
|
+
function sanitizeHtmlTagName(tag, fallback) {
|
|
194
|
+
if (tag === undefined || tag === '')
|
|
195
|
+
return fallback;
|
|
196
|
+
const t = tag.trim().toLowerCase();
|
|
197
|
+
if (!SAFE_HTML_TAG_NAME.test(t))
|
|
198
|
+
return fallback;
|
|
199
|
+
return t;
|
|
200
|
+
}
|
|
25
201
|
/** Escape HTML special characters. */
|
|
26
202
|
function escapeHTML(str) {
|
|
27
203
|
return str
|
|
@@ -30,17 +206,33 @@ function escapeHTML(str) {
|
|
|
30
206
|
.replace(/>/g, '>')
|
|
31
207
|
.replace(/"/g, '"');
|
|
32
208
|
}
|
|
209
|
+
/**
|
|
210
|
+
* HTML `dir` attribute for explicit bidi hints. Only known values are emitted so malformed
|
|
211
|
+
* serialized trees cannot inject attribute text.
|
|
212
|
+
*/
|
|
213
|
+
function dirAttribute(props) {
|
|
214
|
+
const d = props.dir;
|
|
215
|
+
if (d === 'ltr' || d === 'rtl' || d === 'auto') {
|
|
216
|
+
return `dir="${escapeHTML(d)}"`;
|
|
217
|
+
}
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
33
220
|
/** Convert a UIElement tree to a semantic HTML string body. */
|
|
34
221
|
function elementToHTML(element, indent) {
|
|
35
222
|
const pad = ' '.repeat(indent);
|
|
36
223
|
if (element.kind === 'image') {
|
|
37
224
|
const imgEl = element;
|
|
38
225
|
const alt = imgEl.semantic?.alt ?? imgEl.props.alt ?? '';
|
|
39
|
-
|
|
226
|
+
const dir = dirAttribute(imgEl.props);
|
|
227
|
+
const dirStr = dir ? ` ${dir}` : '';
|
|
228
|
+
return `${pad}<img src="${escapeHTML(imgEl.props.src)}" alt="${escapeHTML(alt)}"${dirStr}>`;
|
|
40
229
|
}
|
|
41
230
|
if (element.kind === 'text') {
|
|
42
|
-
const tag = element.semantic?.tag
|
|
231
|
+
const tag = sanitizeHtmlTagName(element.semantic?.tag, inferTag(element));
|
|
43
232
|
const attrs = [];
|
|
233
|
+
const dir = dirAttribute(element.props);
|
|
234
|
+
if (dir)
|
|
235
|
+
attrs.push(dir);
|
|
44
236
|
if (element.semantic?.role)
|
|
45
237
|
attrs.push(`role="${escapeHTML(element.semantic.role)}"`);
|
|
46
238
|
if (element.semantic?.ariaLabel)
|
|
@@ -48,16 +240,24 @@ function elementToHTML(element, indent) {
|
|
|
48
240
|
const attrStr = attrs.length ? ' ' + attrs.join(' ') : '';
|
|
49
241
|
return `${pad}<${tag}${attrStr}>${escapeHTML(element.props.text)}</${tag}>`;
|
|
50
242
|
}
|
|
51
|
-
const tag = element.semantic?.tag
|
|
243
|
+
const tag = sanitizeHtmlTagName(element.semantic?.tag, inferBoxTag(element));
|
|
52
244
|
const attrs = [];
|
|
245
|
+
const dir = dirAttribute(element.props);
|
|
246
|
+
if (dir)
|
|
247
|
+
attrs.push(dir);
|
|
53
248
|
if (element.semantic?.role)
|
|
54
249
|
attrs.push(`role="${escapeHTML(element.semantic.role)}"`);
|
|
55
|
-
if (element.semantic?.ariaLabel)
|
|
250
|
+
if (element.semantic?.ariaLabel) {
|
|
56
251
|
attrs.push(`aria-label="${escapeHTML(element.semantic.ariaLabel)}"`);
|
|
57
|
-
|
|
252
|
+
}
|
|
253
|
+
else if (element.semantic?.alt) {
|
|
58
254
|
attrs.push(`aria-label="${escapeHTML(element.semantic.alt)}"`);
|
|
255
|
+
}
|
|
59
256
|
const attrStr = attrs.length ? ' ' + attrs.join(' ') : '';
|
|
60
257
|
if (element.children.length === 0) {
|
|
258
|
+
if (VOID_HTML_TAGS.has(tag.toLowerCase())) {
|
|
259
|
+
return `${pad}<${tag}${attrStr}>`;
|
|
260
|
+
}
|
|
61
261
|
return `${pad}<${tag}${attrStr}></${tag}>`;
|
|
62
262
|
}
|
|
63
263
|
const children = element.children.map(c => elementToHTML(c, indent + 1)).join('\n');
|
|
@@ -69,6 +269,15 @@ function elementToHTML(element, indent) {
|
|
|
69
269
|
* This produces a full HTML document suitable for search engine crawlers.
|
|
70
270
|
* Serve this to user-agents like Googlebot while rendering the canvas
|
|
71
271
|
* version for real users.
|
|
272
|
+
*
|
|
273
|
+
* When `props.dir` is `ltr`, `rtl`, or `auto` on a box, text, or image node, the HTML `dir`
|
|
274
|
+
* attribute is emitted on that element’s tag.
|
|
275
|
+
*
|
|
276
|
+
* `semantic.tag` is validated as a safe HTML local name (letter, then letters/digits/hyphen, ≤128
|
|
277
|
+
* chars); invalid values fall back to font/box inference so crawlers cannot receive broken markup.
|
|
278
|
+
*
|
|
279
|
+
* Default box tags: `onClick` maps to `<button>` only for an empty box or a box whose sole child is
|
|
280
|
+
* `text()`; otherwise `div` (compound click targets should use `semantic.tag` / roles when needed).
|
|
72
281
|
*/
|
|
73
282
|
export function toSemanticHTML(tree, options = {}) {
|
|
74
283
|
const meta = [
|
|
@@ -93,11 +302,29 @@ export function toSemanticHTML(tree, options = {}) {
|
|
|
93
302
|
if (options.og.type)
|
|
94
303
|
meta.push(`<meta property="og:type" content="${escapeHTML(options.og.type)}">`);
|
|
95
304
|
}
|
|
305
|
+
if (options.twitter) {
|
|
306
|
+
if (options.twitter.card) {
|
|
307
|
+
meta.push(`<meta name="twitter:card" content="${escapeHTML(options.twitter.card)}">`);
|
|
308
|
+
}
|
|
309
|
+
if (options.twitter.site) {
|
|
310
|
+
meta.push(`<meta name="twitter:site" content="${escapeHTML(options.twitter.site)}">`);
|
|
311
|
+
}
|
|
312
|
+
if (options.twitter.title) {
|
|
313
|
+
meta.push(`<meta name="twitter:title" content="${escapeHTML(options.twitter.title)}">`);
|
|
314
|
+
}
|
|
315
|
+
if (options.twitter.description) {
|
|
316
|
+
meta.push(`<meta name="twitter:description" content="${escapeHTML(options.twitter.description)}">`);
|
|
317
|
+
}
|
|
318
|
+
if (options.twitter.image) {
|
|
319
|
+
meta.push(`<meta name="twitter:image" content="${escapeHTML(options.twitter.image)}">`);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
96
322
|
if (options.headExtra)
|
|
97
323
|
meta.push(options.headExtra);
|
|
98
324
|
const body = elementToHTML(tree, 2);
|
|
325
|
+
const lang = escapeHTML(options.lang ?? 'en');
|
|
99
326
|
return `<!DOCTYPE html>
|
|
100
|
-
<html lang="
|
|
327
|
+
<html lang="${lang}">
|
|
101
328
|
<head>
|
|
102
329
|
${meta.join('\n ')}
|
|
103
330
|
</head>
|
package/dist/seo.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seo.js","sourceRoot":"","sources":["../src/seo.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"seo.js","sourceRoot":"","sources":["../src/seo.ts"],"names":[],"mappings":"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"}
|
package/dist/signals.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signals.d.ts","sourceRoot":"","sources":["../src/signals.ts"],"names":[],"mappings":"AAAA,+CAA+C;
|
|
1
|
+
{"version":3,"file":"signals.d.ts","sourceRoot":"","sources":["../src/signals.ts"],"names":[],"mappings":"AAAA,+CAA+C;AA4B/C,yDAAyD;AACzD,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAY1C;AAED,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;IACjB,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAA;IACnB,IAAI,IAAI,CAAC,CAAA;CACV;AAED,gCAAgC;AAChC,wBAAgB,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAgC/C;AAED,MAAM,WAAW,QAAQ,CAAC,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAClB;AAED,0EAA0E;AAC1E,wBAAgB,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAuCpD;AAED,6FAA6F;AAC7F,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAoBjD"}
|
package/dist/signals.js
CHANGED
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
let currentSubscriber = null;
|
|
3
3
|
const batchQueue = new Set();
|
|
4
4
|
let batchDepth = 0;
|
|
5
|
+
/** Per-subscriber cleanups so re-runs drop stale signal/computed edges (conditional reads). */
|
|
6
|
+
const subscriberCleanups = new WeakMap();
|
|
7
|
+
function trackDependency(cleanup) {
|
|
8
|
+
if (!currentSubscriber)
|
|
9
|
+
return;
|
|
10
|
+
let set = subscriberCleanups.get(currentSubscriber);
|
|
11
|
+
if (!set) {
|
|
12
|
+
set = new Set();
|
|
13
|
+
subscriberCleanups.set(currentSubscriber, set);
|
|
14
|
+
}
|
|
15
|
+
set.add(cleanup);
|
|
16
|
+
}
|
|
17
|
+
function releaseSubscriber(sub) {
|
|
18
|
+
const cleanups = subscriberCleanups.get(sub);
|
|
19
|
+
if (!cleanups || cleanups.size === 0)
|
|
20
|
+
return;
|
|
21
|
+
for (const c of cleanups)
|
|
22
|
+
c();
|
|
23
|
+
cleanups.clear();
|
|
24
|
+
}
|
|
5
25
|
/** Batch multiple signal updates into a single flush. */
|
|
6
26
|
export function batch(fn) {
|
|
7
27
|
batchDepth++;
|
|
@@ -24,15 +44,22 @@ export function signal(initial) {
|
|
|
24
44
|
const subscribers = new Set();
|
|
25
45
|
return {
|
|
26
46
|
get value() {
|
|
27
|
-
if (currentSubscriber)
|
|
28
|
-
|
|
47
|
+
if (currentSubscriber) {
|
|
48
|
+
const sub = currentSubscriber;
|
|
49
|
+
subscribers.add(sub);
|
|
50
|
+
trackDependency(() => {
|
|
51
|
+
subscribers.delete(sub);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
29
54
|
return value;
|
|
30
55
|
},
|
|
31
56
|
set(next) {
|
|
32
57
|
if (Object.is(value, next))
|
|
33
58
|
return;
|
|
34
59
|
value = next;
|
|
35
|
-
|
|
60
|
+
// Notify a stable snapshot so unsubscribe/resubscribe during a run
|
|
61
|
+
// cannot perturb the current flush.
|
|
62
|
+
for (const sub of [...subscribers]) {
|
|
36
63
|
if (batchDepth > 0) {
|
|
37
64
|
batchQueue.add(sub);
|
|
38
65
|
}
|
|
@@ -53,7 +80,7 @@ export function computed(fn) {
|
|
|
53
80
|
const subscribers = new Set();
|
|
54
81
|
const recompute = () => {
|
|
55
82
|
dirty = true;
|
|
56
|
-
for (const sub of subscribers) {
|
|
83
|
+
for (const sub of [...subscribers]) {
|
|
57
84
|
if (batchDepth > 0) {
|
|
58
85
|
batchQueue.add(sub);
|
|
59
86
|
}
|
|
@@ -64,9 +91,8 @@ export function computed(fn) {
|
|
|
64
91
|
};
|
|
65
92
|
return {
|
|
66
93
|
get value() {
|
|
67
|
-
if (currentSubscriber)
|
|
68
|
-
subscribers.add(currentSubscriber);
|
|
69
94
|
if (dirty) {
|
|
95
|
+
releaseSubscriber(recompute);
|
|
70
96
|
const prev = currentSubscriber;
|
|
71
97
|
currentSubscriber = recompute;
|
|
72
98
|
try {
|
|
@@ -77,6 +103,13 @@ export function computed(fn) {
|
|
|
77
103
|
}
|
|
78
104
|
dirty = false;
|
|
79
105
|
}
|
|
106
|
+
if (currentSubscriber) {
|
|
107
|
+
const sub = currentSubscriber;
|
|
108
|
+
subscribers.add(sub);
|
|
109
|
+
trackDependency(() => {
|
|
110
|
+
subscribers.delete(sub);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
80
113
|
return cached;
|
|
81
114
|
},
|
|
82
115
|
};
|
|
@@ -87,6 +120,7 @@ export function effect(fn) {
|
|
|
87
120
|
const run = () => {
|
|
88
121
|
if (disposed)
|
|
89
122
|
return;
|
|
123
|
+
releaseSubscriber(run);
|
|
90
124
|
const prev = currentSubscriber;
|
|
91
125
|
currentSubscriber = run;
|
|
92
126
|
try {
|
|
@@ -97,6 +131,9 @@ export function effect(fn) {
|
|
|
97
131
|
}
|
|
98
132
|
};
|
|
99
133
|
run();
|
|
100
|
-
return () => {
|
|
134
|
+
return () => {
|
|
135
|
+
disposed = true;
|
|
136
|
+
releaseSubscriber(run);
|
|
137
|
+
};
|
|
101
138
|
}
|
|
102
139
|
//# sourceMappingURL=signals.js.map
|
package/dist/signals.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signals.js","sourceRoot":"","sources":["../src/signals.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAI/C,IAAI,iBAAiB,GAAsB,IAAI,CAAA;AAC/C,MAAM,UAAU,GAAG,IAAI,GAAG,EAAc,CAAA;AACxC,IAAI,UAAU,GAAG,CAAC,CAAA;AAElB,yDAAyD;AACzD,MAAM,UAAU,KAAK,CAAC,EAAc;IAClC,UAAU,EAAE,CAAA;IACZ,IAAI,CAAC;QACH,EAAE,EAAE,CAAA;IACN,CAAC;YAAS,CAAC;QACT,UAAU,EAAE,CAAA;QACZ,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;YACrB,MAAM,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,CAAA;YAC9B,UAAU,CAAC,KAAK,EAAE,CAAA;YAClB,KAAK,MAAM,GAAG,IAAI,MAAM;gBAAE,GAAG,EAAE,CAAA;QACjC,CAAC;IACH,CAAC;AACH,CAAC;AAQD,gCAAgC;AAChC,MAAM,UAAU,MAAM,CAAI,OAAU;IAClC,IAAI,KAAK,GAAG,OAAO,CAAA;IACnB,MAAM,WAAW,GAAG,IAAI,GAAG,EAAc,CAAA;IAEzC,OAAO;QACL,IAAI,KAAK;YACP,IAAI,iBAAiB;
|
|
1
|
+
{"version":3,"file":"signals.js","sourceRoot":"","sources":["../src/signals.ts"],"names":[],"mappings":"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"}
|