@geometra/core 1.0.0 → 1.1.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/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/fonts.d.ts
CHANGED
|
@@ -1,14 +1,47 @@
|
|
|
1
1
|
import type { UIElement } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Extract custom font family names from a CSS `font` shorthand (e.g. `600 14px Inter`).
|
|
4
|
-
* Drops generic fallbacks like `sans-serif
|
|
4
|
+
* Drops generic fallbacks like `sans-serif`, CSS-wide keywords (`inherit`, `initial`, …), and
|
|
5
|
+
* system font keywords (`caption`, `menu`, …).
|
|
6
|
+
* Repeated custom names in the same list collapse
|
|
7
|
+
* to the first spelling (comparison is case-insensitive, e.g. `Inter, inter` → one entry).
|
|
8
|
+
* Best-effort parsing for common patterns.
|
|
9
|
+
* Commas inside quoted family names are ignored; `\\` escapes the next character inside quotes (e.g. `\"` for a literal `"`).
|
|
10
|
+
* Recognizes common font-size units (px, em, rem, cap/ic/lh/rlh, root-relative r* units, pt, %, viewport, viewport inline/block (`vi`/`vb` and `d*`/`s*`/`l*` variants), dynamic-viewport, container query, Q, and math units), including scientific notation on the numeric part (e.g. `1e2px`).
|
|
11
|
+
* CSS math functions `calc()`, `min()`, `max()`, and `clamp()` are treated as a single font-size token (balanced parentheses; commas inside are allowed).
|
|
12
|
+
* When a percentage is used as `font-stretch` before the real font size (e.g. `75% 14px Inter`),
|
|
13
|
+
* skips that leading dimension so the size + family tail is parsed correctly.
|
|
14
|
+
* Very long chains of leading size tokens are peeled with a bounded primary budget, then a secondary pass on modest remainders.
|
|
15
|
+
* If an oversized tail still looks like stacked size tokens, returns [] rather than inventing a family name or doing pathological work.
|
|
16
|
+
* Line-height after `/` may be numeric (with optional unit) or the `normal` keyword; a slash line-height
|
|
17
|
+
* with no following family list yields no families (e.g. `14px / normal` alone).
|
|
18
|
+
* Leading relative size keywords `smaller` and `larger` (CSS Fonts) are stripped so
|
|
19
|
+
* values like `smaller Inter, serif` resolve to concrete families for {@link waitForFonts}.
|
|
20
|
+
* Leading absolute size keywords (`medium`, `xx-small`, `large`, …) are stripped the same way.
|
|
21
|
+
* A comma-list segment that is exactly an absolute size keyword is dropped when unquoted; the same word
|
|
22
|
+
* inside quotes is kept (CSS requires quoting when a family name matches a keyword).
|
|
23
|
+
* Unquoted `url(...)` and `format(...)` segments (e.g. mistaken `@font-face` `src` paste) are not
|
|
24
|
+
* concrete family names and are skipped so {@link waitForFonts} does not call `load` with them.
|
|
25
|
+
* The same spellings inside quotes are kept as literal family names (CSS `font-family` rules).
|
|
5
26
|
*/
|
|
6
27
|
export declare function extractFontFamiliesFromCSSFont(font: string): string[];
|
|
7
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Collect unique font families referenced by text nodes in a UI tree.
|
|
30
|
+
* Order is first-seen in a depth-first preorder walk (later duplicates are skipped).
|
|
31
|
+
*/
|
|
8
32
|
export declare function collectFontFamiliesFromTree(root: UIElement): string[];
|
|
33
|
+
/**
|
|
34
|
+
* Resolve a font-load timeout in milliseconds. Used by {@link waitForFonts} and `createApp`'s
|
|
35
|
+
* `fontLoadTimeoutMs` so `NaN`, `±Infinity`, negative values, and non-numbers all fall back to
|
|
36
|
+
* `defaultMs` (avoids `??` missing `NaN` and odd `setTimeout` coercion).
|
|
37
|
+
*/
|
|
38
|
+
export declare function resolveFontLoadTimeoutMs(timeoutMs: number | undefined, defaultMs?: number): number;
|
|
9
39
|
/**
|
|
10
40
|
* Wait for web fonts used by the app. Browser only; no-op on server.
|
|
11
41
|
* Uses `document.fonts.load` per family; timeouts are swallowed so startup never hard-fails.
|
|
42
|
+
* Empty and whitespace-only family strings are ignored; names are trimmed before load and deduped.
|
|
43
|
+
* `timeoutMs` must be a finite non-negative number; otherwise the default `10_000` is used (avoids
|
|
44
|
+
* relying on `setTimeout` coercion for `NaN`, `±Infinity`, or negative values).
|
|
12
45
|
*/
|
|
13
46
|
export declare function waitForFonts(families: string[], timeoutMs?: number): Promise<void>;
|
|
14
47
|
//# sourceMappingURL=fonts.d.ts.map
|
package/dist/fonts.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fonts.d.ts","sourceRoot":"","sources":["../src/fonts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"fonts.d.ts","sourceRoot":"","sources":["../src/fonts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AA6K3C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAgKrE;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,EAAE,CAarE;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,SAAS,GAAG,MAAM,CAElG;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,SAAS,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBxF"}
|
package/dist/fonts.js
CHANGED
|
@@ -8,22 +8,331 @@ const GENERIC_FAMILIES = new Set([
|
|
|
8
8
|
'ui-sans-serif',
|
|
9
9
|
'ui-serif',
|
|
10
10
|
'ui-monospace',
|
|
11
|
+
'ui-rounded',
|
|
11
12
|
'emoji',
|
|
12
13
|
]);
|
|
14
|
+
/** CSS-wide keywords that may appear in `font` / family lists but are not concrete family names. */
|
|
15
|
+
const CSS_WIDE_FONT_KEYWORDS = new Set([
|
|
16
|
+
'inherit',
|
|
17
|
+
'initial',
|
|
18
|
+
'unset',
|
|
19
|
+
'revert',
|
|
20
|
+
'revert-layer',
|
|
21
|
+
]);
|
|
22
|
+
/**
|
|
23
|
+
* Single-keyword `font` values that select the UA system font (CSS Fonts); not concrete families
|
|
24
|
+
* and must not be passed to `document.fonts.load`.
|
|
25
|
+
*/
|
|
26
|
+
const SYSTEM_FONT_KEYWORDS = new Set([
|
|
27
|
+
'caption',
|
|
28
|
+
'icon',
|
|
29
|
+
'menu',
|
|
30
|
+
'message-box',
|
|
31
|
+
'small-caption',
|
|
32
|
+
'status-bar',
|
|
33
|
+
]);
|
|
34
|
+
/**
|
|
35
|
+
* Font-size units we treat as the numeric token before the family list in `font` shorthand.
|
|
36
|
+
* Longer tokens precede shorter prefixes (e.g. `dvmin` before `vmin`, `rlh` before `lh`, `rch` before `ch`).
|
|
37
|
+
*/
|
|
38
|
+
const FONT_SIZE_UNIT = '(?:dvmin|dvmax|svmin|svmax|lvmin|lvmax|dvh|dvw|dvi|dvb|svh|svw|svi|svb|lvh|lvw|lvi|lvb|' +
|
|
39
|
+
'vmin|vmax|vh|vw|vi|vb|' +
|
|
40
|
+
'cqmin|cqmax|cqi|cqb|cqw|cqh|' +
|
|
41
|
+
'rlh|rcap|rch|rex|ric|' +
|
|
42
|
+
'rem|cap|px|em|pt|pc|in|cm|math|mm|Q|%|ch|ex|ic|lh)';
|
|
43
|
+
/** Magnitude in a `font-size` dimension token (allows scientific notation, e.g. `1e2px`). */
|
|
44
|
+
const FONT_SIZE_NUMBER = String.raw `\d+(?:\.\d+)?(?:[eE][+-]?\d+)?`;
|
|
45
|
+
/** Optional `/ line-height` after font-size in shorthand (numeric length or keyword `normal`). */
|
|
46
|
+
const FONT_SHORTHAND_LINE_HEIGHT = String.raw `(?:\/\s*(?:` + FONT_SIZE_NUMBER + FONT_SIZE_UNIT + String.raw `?|normal))?`;
|
|
47
|
+
/**
|
|
48
|
+
* Size + required `/ line-height` before the family list. Family tail may be empty (invalid shorthand
|
|
49
|
+
* with no family); tried before {@link FONT_SHORTHAND_FAMILY_TAIL} so `/ normal` is not misparsed as a family.
|
|
50
|
+
*/
|
|
51
|
+
const FONT_SHORTHAND_SLASH_LINE_TAIL = new RegExp(String.raw `\b(` +
|
|
52
|
+
FONT_SIZE_NUMBER +
|
|
53
|
+
FONT_SIZE_UNIT +
|
|
54
|
+
String.raw `)\s*\/\s*(?:` +
|
|
55
|
+
FONT_SIZE_NUMBER +
|
|
56
|
+
FONT_SIZE_UNIT +
|
|
57
|
+
String.raw `?|normal)\s*(.*)$`, 'i');
|
|
58
|
+
const FONT_SHORTHAND_FAMILY_TAIL = new RegExp(String.raw `\b(` + FONT_SIZE_NUMBER + FONT_SIZE_UNIT + String.raw `)\s*` + FONT_SHORTHAND_LINE_HEIGHT + String.raw `\s+(.+)$`, 'i');
|
|
59
|
+
const FONT_SIZE_ONLY = new RegExp(String.raw `^` + FONT_SIZE_NUMBER + FONT_SIZE_UNIT + String.raw `$`, 'i');
|
|
60
|
+
/** True when the family tail begins with a dimension token + space (another size before the real family). */
|
|
61
|
+
const TAIL_LEADS_WITH_SIZE_TOKEN = new RegExp(String.raw `^` + FONT_SIZE_NUMBER + FONT_SIZE_UNIT + String.raw `\s+`, 'i');
|
|
62
|
+
/**
|
|
63
|
+
* Upper bound on leading token strips for `font` shorthand parsing (pathological inputs stay finite).
|
|
64
|
+
* Long font-stretch / leading-percent stacks before the real size + family can consume one strip each.
|
|
65
|
+
*/
|
|
66
|
+
const MAX_SHORTHAND_STRIP_ITERATIONS = 4096;
|
|
67
|
+
/**
|
|
68
|
+
* After the primary strip budget, if this many characters remain and another peel is still required,
|
|
69
|
+
* return [] instead of continuing (avoids O(n²) regex work and bogus synthesized family names).
|
|
70
|
+
*/
|
|
71
|
+
const MAX_REMAINDER_AFTER_PRIMARY_STRIP = 16_384;
|
|
72
|
+
/** Extra peels allowed on modest remainders once the primary budget is exhausted. */
|
|
73
|
+
const EXTRA_SHORTHAND_STRIP_ITERATIONS = 8192;
|
|
74
|
+
/** Max leading `smaller` / `larger` peels (relative font-size keywords before family or explicit size). */
|
|
75
|
+
const MAX_RELATIVE_SIZE_PREFIX_STRIPS = 8;
|
|
76
|
+
/**
|
|
77
|
+
* CSS absolute font-size keywords (CSS Fonts). When they lead the shorthand they must be peeled before
|
|
78
|
+
* size+family parsing; when a comma-separated segment is exactly one of these (unquoted), it is not a
|
|
79
|
+
* family name (quoted names still pass through).
|
|
80
|
+
*/
|
|
81
|
+
const ABSOLUTE_FONT_SIZE_KEYWORDS = new Set([
|
|
82
|
+
'xx-small',
|
|
83
|
+
'x-small',
|
|
84
|
+
'small',
|
|
85
|
+
'medium',
|
|
86
|
+
'large',
|
|
87
|
+
'x-large',
|
|
88
|
+
'xx-large',
|
|
89
|
+
'xxx-large',
|
|
90
|
+
]);
|
|
91
|
+
/** Longest-match alternation so `xx-large` does not match as `x-large` + `large`. */
|
|
92
|
+
const ABSOLUTE_FONT_SIZE_PREFIX = /^(xxx-large|xx-large|xx-small|x-large|x-small|small|medium|large)\s+/i;
|
|
93
|
+
/** Max leading absolute keyword strips (pathological stacks stay bounded). */
|
|
94
|
+
const MAX_ABSOLUTE_SIZE_PREFIX_STRIPS = 16;
|
|
95
|
+
/** Index after the closing `)` that matches `s[openParenIndex]` (which must be `(`). */
|
|
96
|
+
function indexAfterMatchingParen(s, openParenIndex) {
|
|
97
|
+
let depth = 0;
|
|
98
|
+
for (let i = openParenIndex; i < s.length; i++) {
|
|
99
|
+
const c = s[i];
|
|
100
|
+
if (c === '(')
|
|
101
|
+
depth++;
|
|
102
|
+
else if (c === ')') {
|
|
103
|
+
depth--;
|
|
104
|
+
if (depth === 0)
|
|
105
|
+
return i + 1;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
/** Split a CSS font-family list on commas not inside single or double quotes. */
|
|
111
|
+
function splitFontFamilyList(tail) {
|
|
112
|
+
const parts = [];
|
|
113
|
+
let cur = '';
|
|
114
|
+
let quote = null;
|
|
115
|
+
for (let i = 0; i < tail.length; i++) {
|
|
116
|
+
const c = tail[i];
|
|
117
|
+
if (quote) {
|
|
118
|
+
if (c === '\\' && i + 1 < tail.length) {
|
|
119
|
+
cur += tail[i + 1];
|
|
120
|
+
i++;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
cur += c;
|
|
124
|
+
if (c === quote)
|
|
125
|
+
quote = null;
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (c === '"' || c === "'") {
|
|
129
|
+
quote = c;
|
|
130
|
+
cur += c;
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (c === ',') {
|
|
134
|
+
const t = cur.trim();
|
|
135
|
+
if (t.length > 0)
|
|
136
|
+
parts.push(t);
|
|
137
|
+
cur = '';
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
cur += c;
|
|
141
|
+
}
|
|
142
|
+
const last = cur.trim();
|
|
143
|
+
if (last.length > 0)
|
|
144
|
+
parts.push(last);
|
|
145
|
+
return parts;
|
|
146
|
+
}
|
|
13
147
|
/**
|
|
14
148
|
* Extract custom font family names from a CSS `font` shorthand (e.g. `600 14px Inter`).
|
|
15
|
-
* Drops generic fallbacks like `sans-serif
|
|
149
|
+
* Drops generic fallbacks like `sans-serif`, CSS-wide keywords (`inherit`, `initial`, …), and
|
|
150
|
+
* system font keywords (`caption`, `menu`, …).
|
|
151
|
+
* Repeated custom names in the same list collapse
|
|
152
|
+
* to the first spelling (comparison is case-insensitive, e.g. `Inter, inter` → one entry).
|
|
153
|
+
* Best-effort parsing for common patterns.
|
|
154
|
+
* Commas inside quoted family names are ignored; `\\` escapes the next character inside quotes (e.g. `\"` for a literal `"`).
|
|
155
|
+
* Recognizes common font-size units (px, em, rem, cap/ic/lh/rlh, root-relative r* units, pt, %, viewport, viewport inline/block (`vi`/`vb` and `d*`/`s*`/`l*` variants), dynamic-viewport, container query, Q, and math units), including scientific notation on the numeric part (e.g. `1e2px`).
|
|
156
|
+
* CSS math functions `calc()`, `min()`, `max()`, and `clamp()` are treated as a single font-size token (balanced parentheses; commas inside are allowed).
|
|
157
|
+
* When a percentage is used as `font-stretch` before the real font size (e.g. `75% 14px Inter`),
|
|
158
|
+
* skips that leading dimension so the size + family tail is parsed correctly.
|
|
159
|
+
* Very long chains of leading size tokens are peeled with a bounded primary budget, then a secondary pass on modest remainders.
|
|
160
|
+
* If an oversized tail still looks like stacked size tokens, returns [] rather than inventing a family name or doing pathological work.
|
|
161
|
+
* Line-height after `/` may be numeric (with optional unit) or the `normal` keyword; a slash line-height
|
|
162
|
+
* with no following family list yields no families (e.g. `14px / normal` alone).
|
|
163
|
+
* Leading relative size keywords `smaller` and `larger` (CSS Fonts) are stripped so
|
|
164
|
+
* values like `smaller Inter, serif` resolve to concrete families for {@link waitForFonts}.
|
|
165
|
+
* Leading absolute size keywords (`medium`, `xx-small`, `large`, …) are stripped the same way.
|
|
166
|
+
* A comma-list segment that is exactly an absolute size keyword is dropped when unquoted; the same word
|
|
167
|
+
* inside quotes is kept (CSS requires quoting when a family name matches a keyword).
|
|
168
|
+
* Unquoted `url(...)` and `format(...)` segments (e.g. mistaken `@font-face` `src` paste) are not
|
|
169
|
+
* concrete family names and are skipped so {@link waitForFonts} does not call `load` with them.
|
|
170
|
+
* The same spellings inside quotes are kept as literal family names (CSS `font-family` rules).
|
|
16
171
|
*/
|
|
17
172
|
export function extractFontFamiliesFromCSSFont(font) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
173
|
+
function filterFamilies(tail) {
|
|
174
|
+
const out = [];
|
|
175
|
+
const seen = new Set();
|
|
176
|
+
for (const seg of splitFontFamilyList(tail)) {
|
|
177
|
+
const t = seg.trim();
|
|
178
|
+
if (t.length === 0)
|
|
179
|
+
continue;
|
|
180
|
+
const doubleQuoted = t.length >= 2 && t.startsWith('"') && t.endsWith('"');
|
|
181
|
+
const singleQuoted = t.length >= 2 && t.startsWith("'") && t.endsWith("'");
|
|
182
|
+
const quoted = doubleQuoted || singleQuoted;
|
|
183
|
+
const inner = t.replace(/^["']|["']$/g, '');
|
|
184
|
+
if (inner.length === 0)
|
|
185
|
+
continue;
|
|
186
|
+
const lead = inner.trimStart();
|
|
187
|
+
if (!quoted && /^url\s*\(/i.test(lead))
|
|
188
|
+
continue;
|
|
189
|
+
if (!quoted && /^format\s*\(/i.test(lead))
|
|
190
|
+
continue;
|
|
191
|
+
if (!quoted && ABSOLUTE_FONT_SIZE_KEYWORDS.has(inner.toLowerCase()))
|
|
192
|
+
continue;
|
|
193
|
+
if (GENERIC_FAMILIES.has(inner.toLowerCase()) ||
|
|
194
|
+
CSS_WIDE_FONT_KEYWORDS.has(inner.toLowerCase()) ||
|
|
195
|
+
SYSTEM_FONT_KEYWORDS.has(inner.toLowerCase()) ||
|
|
196
|
+
FONT_SIZE_ONLY.test(inner)) {
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
const key = inner.toLowerCase();
|
|
200
|
+
if (seen.has(key))
|
|
201
|
+
continue;
|
|
202
|
+
seen.add(key);
|
|
203
|
+
out.push(inner);
|
|
204
|
+
}
|
|
205
|
+
return out;
|
|
206
|
+
}
|
|
207
|
+
function firstFamilyListSegment(tail) {
|
|
208
|
+
return splitFontFamilyList(tail)[0]?.trim() ?? '';
|
|
209
|
+
}
|
|
210
|
+
/** True when the family tail still begins with another size token (dimension, stacked shorthand, or CSS math size). */
|
|
211
|
+
function tailLeadsWithStackedSize(tail) {
|
|
212
|
+
const first = firstFamilyListSegment(tail);
|
|
213
|
+
return (FONT_SIZE_ONLY.test(first) ||
|
|
214
|
+
TAIL_LEADS_WITH_SIZE_TOKEN.test(tail) ||
|
|
215
|
+
/^(calc|min|max|clamp)\s*\(/i.test(first));
|
|
216
|
+
}
|
|
217
|
+
const MATH_SIZE_OPEN = /\b(calc|min|max|clamp)\s*\(/gi;
|
|
218
|
+
function tryPeelMathSlashLine(s) {
|
|
219
|
+
const re = new RegExp(MATH_SIZE_OPEN.source, 'gi');
|
|
220
|
+
let ma;
|
|
221
|
+
while ((ma = re.exec(s)) !== null) {
|
|
222
|
+
const openIdx = ma.index + ma[0].length - 1;
|
|
223
|
+
const afterClose = indexAfterMatchingParen(s, openIdx);
|
|
224
|
+
if (afterClose === null)
|
|
225
|
+
continue;
|
|
226
|
+
const restRaw = s.slice(afterClose);
|
|
227
|
+
if (!/^\s*\//.test(restRaw))
|
|
228
|
+
continue;
|
|
229
|
+
const slashRestMatch = restRaw.match(new RegExp(String.raw `^\s*\/\s*(?:` + FONT_SIZE_NUMBER + FONT_SIZE_UNIT + String.raw `?|normal)\s*(.*)$`, 'i'));
|
|
230
|
+
if (!slashRestMatch)
|
|
231
|
+
continue;
|
|
232
|
+
const tail = slashRestMatch[1] ?? '';
|
|
233
|
+
if (tailLeadsWithStackedSize(tail)) {
|
|
234
|
+
return { kind: 'peeled', next: s.slice(afterClose).trimStart() };
|
|
235
|
+
}
|
|
236
|
+
if (tail.trim().length === 0)
|
|
237
|
+
continue;
|
|
238
|
+
return { kind: 'family', tail: tail.trimStart() };
|
|
239
|
+
}
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
function tryPeelMathFamily(s) {
|
|
243
|
+
const re = new RegExp(MATH_SIZE_OPEN.source, 'gi');
|
|
244
|
+
let ma;
|
|
245
|
+
while ((ma = re.exec(s)) !== null) {
|
|
246
|
+
const openIdx = ma.index + ma[0].length - 1;
|
|
247
|
+
const afterClose = indexAfterMatchingParen(s, openIdx);
|
|
248
|
+
if (afterClose === null)
|
|
249
|
+
continue;
|
|
250
|
+
const restRaw = s.slice(afterClose);
|
|
251
|
+
if (/^\s*\//.test(restRaw))
|
|
252
|
+
continue;
|
|
253
|
+
const famM = restRaw.match(/^\s+(.+)$/);
|
|
254
|
+
if (!famM)
|
|
255
|
+
continue;
|
|
256
|
+
const tail = famM[1];
|
|
257
|
+
if (tailLeadsWithStackedSize(tail)) {
|
|
258
|
+
return { kind: 'peeled', next: s.slice(afterClose).trimStart() };
|
|
259
|
+
}
|
|
260
|
+
return { kind: 'family', tail };
|
|
261
|
+
}
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
function peelFontShorthand(s) {
|
|
265
|
+
const slashM = s.match(FONT_SHORTHAND_SLASH_LINE_TAIL);
|
|
266
|
+
if (slashM) {
|
|
267
|
+
const tail = slashM[2] ?? '';
|
|
268
|
+
if (!tailLeadsWithStackedSize(tail))
|
|
269
|
+
return { kind: 'family', tail };
|
|
270
|
+
const matchIndex = slashM.index ?? 0;
|
|
271
|
+
return { kind: 'peeled', next: s.slice(matchIndex + slashM[1].length).trimStart() };
|
|
272
|
+
}
|
|
273
|
+
const mathSlash = tryPeelMathSlashLine(s);
|
|
274
|
+
if (mathSlash)
|
|
275
|
+
return mathSlash;
|
|
276
|
+
// Before numeric size + family: math sizes can contain dimension tokens (e.g. `14px` inside
|
|
277
|
+
// `calc(14px + 1vmin)`) that would otherwise match {@link FONT_SHORTHAND_FAMILY_TAIL} early.
|
|
278
|
+
const mathFam = tryPeelMathFamily(s);
|
|
279
|
+
if (mathFam)
|
|
280
|
+
return mathFam;
|
|
281
|
+
const m = s.match(FONT_SHORTHAND_FAMILY_TAIL);
|
|
282
|
+
if (m) {
|
|
283
|
+
const tail = m[2];
|
|
284
|
+
if (!tailLeadsWithStackedSize(tail))
|
|
285
|
+
return { kind: 'family', tail };
|
|
286
|
+
const matchIndex = m.index ?? 0;
|
|
287
|
+
return { kind: 'peeled', next: s.slice(matchIndex + m[1].length).trimStart() };
|
|
288
|
+
}
|
|
289
|
+
return { kind: 'none' };
|
|
290
|
+
}
|
|
291
|
+
let trimmed = font.trim();
|
|
292
|
+
for (let p = 0; p < MAX_RELATIVE_SIZE_PREFIX_STRIPS; p++) {
|
|
293
|
+
const withoutRel = trimmed.replace(/^(smaller|larger)\s+/i, '');
|
|
294
|
+
if (withoutRel === trimmed)
|
|
295
|
+
break;
|
|
296
|
+
trimmed = withoutRel;
|
|
297
|
+
}
|
|
298
|
+
for (let p = 0; p < MAX_ABSOLUTE_SIZE_PREFIX_STRIPS; p++) {
|
|
299
|
+
const m = trimmed.match(ABSOLUTE_FONT_SIZE_PREFIX);
|
|
300
|
+
if (!m)
|
|
301
|
+
break;
|
|
302
|
+
trimmed = trimmed.slice(m[0].length).trimStart();
|
|
303
|
+
}
|
|
304
|
+
for (let i = 0; i < MAX_SHORTHAND_STRIP_ITERATIONS; i++) {
|
|
305
|
+
const r = peelFontShorthand(trimmed);
|
|
306
|
+
if (r.kind === 'none')
|
|
307
|
+
break;
|
|
308
|
+
if (r.kind === 'family')
|
|
309
|
+
return filterFamilies(r.tail);
|
|
310
|
+
trimmed = r.next;
|
|
311
|
+
}
|
|
312
|
+
if (trimmed.length > MAX_REMAINDER_AFTER_PRIMARY_STRIP) {
|
|
313
|
+
const r = peelFontShorthand(trimmed);
|
|
314
|
+
if (r.kind === 'peeled')
|
|
315
|
+
return [];
|
|
316
|
+
}
|
|
317
|
+
for (let i = 0; i < EXTRA_SHORTHAND_STRIP_ITERATIONS; i++) {
|
|
318
|
+
const r = peelFontShorthand(trimmed);
|
|
319
|
+
if (r.kind === 'none')
|
|
320
|
+
break;
|
|
321
|
+
if (r.kind === 'family')
|
|
322
|
+
return filterFamilies(r.tail);
|
|
323
|
+
trimmed = r.next;
|
|
324
|
+
}
|
|
325
|
+
const last = peelFontShorthand(trimmed);
|
|
326
|
+
if (last.kind === 'family')
|
|
327
|
+
return filterFamilies(last.tail);
|
|
328
|
+
if (last.kind === 'peeled')
|
|
329
|
+
return [];
|
|
330
|
+
return filterFamilies(trimmed);
|
|
25
331
|
}
|
|
26
|
-
/**
|
|
332
|
+
/**
|
|
333
|
+
* Collect unique font families referenced by text nodes in a UI tree.
|
|
334
|
+
* Order is first-seen in a depth-first preorder walk (later duplicates are skipped).
|
|
335
|
+
*/
|
|
27
336
|
export function collectFontFamiliesFromTree(root) {
|
|
28
337
|
const out = new Set();
|
|
29
338
|
function walk(el) {
|
|
@@ -40,9 +349,20 @@ export function collectFontFamiliesFromTree(root) {
|
|
|
40
349
|
walk(root);
|
|
41
350
|
return [...out];
|
|
42
351
|
}
|
|
352
|
+
/**
|
|
353
|
+
* Resolve a font-load timeout in milliseconds. Used by {@link waitForFonts} and `createApp`'s
|
|
354
|
+
* `fontLoadTimeoutMs` so `NaN`, `±Infinity`, negative values, and non-numbers all fall back to
|
|
355
|
+
* `defaultMs` (avoids `??` missing `NaN` and odd `setTimeout` coercion).
|
|
356
|
+
*/
|
|
357
|
+
export function resolveFontLoadTimeoutMs(timeoutMs, defaultMs = 10_000) {
|
|
358
|
+
return typeof timeoutMs === 'number' && Number.isFinite(timeoutMs) && timeoutMs >= 0 ? timeoutMs : defaultMs;
|
|
359
|
+
}
|
|
43
360
|
/**
|
|
44
361
|
* Wait for web fonts used by the app. Browser only; no-op on server.
|
|
45
362
|
* Uses `document.fonts.load` per family; timeouts are swallowed so startup never hard-fails.
|
|
363
|
+
* Empty and whitespace-only family strings are ignored; names are trimmed before load and deduped.
|
|
364
|
+
* `timeoutMs` must be a finite non-negative number; otherwise the default `10_000` is used (avoids
|
|
365
|
+
* relying on `setTimeout` coercion for `NaN`, `±Infinity`, or negative values).
|
|
46
366
|
*/
|
|
47
367
|
export async function waitForFonts(families, timeoutMs = 10_000) {
|
|
48
368
|
if (typeof document === 'undefined' || families.length === 0)
|
|
@@ -50,13 +370,16 @@ export async function waitForFonts(families, timeoutMs = 10_000) {
|
|
|
50
370
|
const api = document.fonts;
|
|
51
371
|
if (!api?.load)
|
|
52
372
|
return;
|
|
53
|
-
const unique = [...new Set(families)];
|
|
54
|
-
|
|
373
|
+
const unique = [...new Set(families.map(f => f.trim()).filter(f => f.length > 0))];
|
|
374
|
+
if (unique.length === 0)
|
|
375
|
+
return;
|
|
376
|
+
const safeTimeoutMs = resolveFontLoadTimeoutMs(timeoutMs, 10_000);
|
|
377
|
+
const work = Promise.all(unique.map(f => api.load(`16px ${f}`).catch(() => undefined))).then(() => Promise.resolve(api.ready).catch(() => undefined));
|
|
55
378
|
try {
|
|
56
379
|
await Promise.race([
|
|
57
380
|
work,
|
|
58
381
|
new Promise((_, reject) => {
|
|
59
|
-
setTimeout(() => reject(new Error('Font load timeout')),
|
|
382
|
+
setTimeout(() => reject(new Error('Font load timeout')), safeTimeoutMs);
|
|
60
383
|
}),
|
|
61
384
|
]);
|
|
62
385
|
}
|
package/dist/fonts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fonts.js","sourceRoot":"","sources":["../src/fonts.ts"],"names":[],"mappings":"AAEA,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;IAC/B,OAAO;IACP,YAAY;IACZ,WAAW;IACX,SAAS;IACT,SAAS;IACT,WAAW;IACX,eAAe;IACf,UAAU;IACV,cAAc;IACd,OAAO;CACR,CAAC,CAAA;AAEF;;;GAGG;AACH,MAAM,UAAU,8BAA8B,CAAC,IAAY;IACzD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;IAC3B,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAA;IAChG,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,OAAO,CAAA;IAChC,OAAO,IAAI;SACR,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;SAC9C,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAA;AACxE,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,2BAA2B,CAAC,IAAe;IACzD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAA;IAC7B,SAAS,IAAI,CAAC,EAAa;QACzB,IAAI,EAAE,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACvB,KAAK,MAAM,CAAC,IAAI,8BAA8B,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9D,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;YACZ,CAAC;QACH,CAAC;aAAM,IAAI,EAAE,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YAC7B,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,QAAQ;gBAAE,IAAI,CAAC,CAAC,CAAC,CAAA;QACtC,CAAC;IACH,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,CAAA;IACV,OAAO,CAAC,GAAG,GAAG,CAAC,CAAA;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAkB,EAAE,SAAS,GAAG,MAAM;IACvE,IAAI,OAAO,QAAQ,KAAK,WAAW,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAM;IACpE,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAA;IAC1B,IAAI,CAAC,GAAG,EAAE,IAAI;QAAE,OAAM;IAEtB,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;IACrC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAChG,GAAG,CAAC,KAAK,CACV,CAAA;IAED,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,IAAI,CAAC;YACjB,IAAI;YACJ,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;gBAC9B,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,EAAE,SAAS,CAAC,CAAA;YACrE,CAAC,CAAC;SACH,CAAC,CAAA;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,iBAAiB;IACnB,CAAC;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"fonts.js","sourceRoot":"","sources":["../src/fonts.ts"],"names":[],"mappings":"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"}
|
package/dist/hit-test.d.ts
CHANGED
|
@@ -1,18 +1,49 @@
|
|
|
1
1
|
import type { ComputedLayout } from 'textura';
|
|
2
2
|
import type { UIElement, BoxElement, EventHandlers } from './types.js';
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* Result of routing a hit to {@link EventHandlers} on the deepest matching target.
|
|
5
|
+
* `focusTarget` is only populated for `onClick` (see {@link dispatchHit}).
|
|
6
|
+
*/
|
|
4
7
|
export interface HitDispatchResult {
|
|
5
8
|
handled: boolean;
|
|
6
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* Present only when `dispatchHit` was called with `'onClick'`: the deepest focusable box under the point
|
|
11
|
+
* (`onClick`, `onKeyDown` / `onKeyUp`, or composition handlers). Set after a successful
|
|
12
|
+
* `onClick` handler **or** via click-to-focus when the box has no `onClick` but should
|
|
13
|
+
* still receive keyboard/composition input (`handled` may be `false`). Omitted for all
|
|
14
|
+
* other event types.
|
|
15
|
+
*/
|
|
7
16
|
focusTarget?: {
|
|
8
17
|
element: BoxElement;
|
|
9
18
|
layout: ComputedLayout;
|
|
10
19
|
};
|
|
11
20
|
}
|
|
12
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Dispatch a hit at `(x, y)` against the element tree for the given handler key
|
|
23
|
+
* (e.g. `onClick`, `onPointerDown`, `onKeyDown`, composition events).
|
|
24
|
+
* The deepest hit with a matching handler runs first; only one handler runs per call.
|
|
25
|
+
* Optional `extra` is shallow-merged onto the `HitEvent` after base fields so callers
|
|
26
|
+
* can pass modifier keys, `button`, wheel deltas, and other renderer-specific metadata.
|
|
27
|
+
* For `onClick` only, the return value may include `focusTarget` for focus routing
|
|
28
|
+
* (including click-to-focus when there is no `onClick` handler).
|
|
29
|
+
* Layout bounds must be finite and non-negative on `width` and `height`; otherwise the node is
|
|
30
|
+
* skipped for hit-testing (corrupt geometry from Yoga or a bad snapshot).
|
|
31
|
+
*/
|
|
13
32
|
export declare function dispatchHit(element: UIElement, layout: ComputedLayout, eventType: keyof EventHandlers, x: number, y: number, extra?: Record<string, unknown>): HitDispatchResult;
|
|
14
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* True when the point is over an element that participates in pointer hit-testing
|
|
35
|
+
* (`onClick`, `onPointerDown` / `Up` / `Move`, `onWheel`). Keyboard and composition
|
|
36
|
+
* handlers alone do not count — use this for hover / pointer-capture style checks.
|
|
37
|
+
*/
|
|
15
38
|
export declare function hasInteractiveHitAtPoint(element: UIElement, layout: ComputedLayout, x: number, y: number): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Child indices from root to the deepest box under (x, y). Among overlapping siblings, prefers higher z-index (topmost);
|
|
41
|
+
* non-finite or non-number `zIndex` values match `dispatchHit` / paint order (treated as `0`).
|
|
42
|
+
* Boxes with `pointerEvents: 'none'` do not terminate the path when they have no deeper hit (same idea as `getCursorAtPoint` and `collectHits`).
|
|
43
|
+
* Returns `null` when the point misses the tree. Returns `[]` when the point hits the
|
|
44
|
+
* root (or a leaf box) with no deeper box hit.
|
|
45
|
+
*/
|
|
46
|
+
export declare function hitPathAtPoint(element: UIElement, layout: ComputedLayout, x: number, y: number, offsetX?: number, offsetY?: number): number[] | null;
|
|
16
47
|
/** Get the cursor style at a given point by walking the tree. Returns the deepest element's cursor prop. */
|
|
17
48
|
export declare function getCursorAtPoint(element: UIElement, layout: ComputedLayout, x: number, y: number, offsetX?: number, offsetY?: number): string | null;
|
|
18
49
|
//# sourceMappingURL=hit-test.d.ts.map
|
package/dist/hit-test.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hit-test.d.ts","sourceRoot":"","sources":["../src/hit-test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAY,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"hit-test.d.ts","sourceRoot":"","sources":["../src/hit-test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAY,MAAM,YAAY,CAAA;AA2EhF;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAA;IAChB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,UAAU,CAAC;QAAC,MAAM,EAAE,cAAc,CAAA;KAAE,CAAA;CAC9D;AAmJD;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,SAAS,EAClB,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,MAAM,aAAa,EAC9B,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,iBAAiB,CAEnB;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,SAAS,EAClB,MAAM,EAAE,cAAc,EACtB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,GACR,OAAO,CAgBT;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,SAAS,EAClB,MAAM,EAAE,cAAc,EACtB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,OAAO,SAAI,EACX,OAAO,SAAI,GACV,MAAM,EAAE,GAAG,IAAI,CA0CjB;AAED,4GAA4G;AAC5G,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,SAAS,EAClB,MAAM,EAAE,cAAc,EACtB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,OAAO,SAAI,EACX,OAAO,SAAI,GACV,MAAM,GAAG,IAAI,CAoCf"}
|