@qontinui/ui-bridge-native 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/control/index.js +2 -0
- package/dist/control/index.js.map +1 -1
- package/dist/control/index.mjs +2 -0
- package/dist/control/index.mjs.map +1 -1
- package/dist/core/index.js +267 -15
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +267 -16
- package/dist/core/index.mjs.map +1 -1
- package/dist/core/registry.d.ts +13 -0
- package/dist/core/registry.d.ts.map +1 -1
- package/dist/core/sha256.d.ts +19 -0
- package/dist/core/sha256.d.ts.map +1 -0
- package/dist/core/types.d.ts +20 -7
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/vision-fields.d.ts +164 -11
- package/dist/core/vision-fields.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +320 -44
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +315 -45
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.js +314 -44
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +314 -44
- package/dist/react/index.mjs.map +1 -1
- package/dist/react/useRouteAwareness.d.ts.map +1 -1
- package/dist/server/handlers.d.ts.map +1 -1
- package/dist/server/index.js +303 -37
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +303 -37
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/page-health.d.ts +10 -1
- package/dist/server/page-health.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/react/index.mjs
CHANGED
|
@@ -9,6 +9,164 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
9
9
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
10
10
|
});
|
|
11
11
|
|
|
12
|
+
// src/core/sha256.ts
|
|
13
|
+
var K = new Uint32Array([
|
|
14
|
+
1116352408,
|
|
15
|
+
1899447441,
|
|
16
|
+
3049323471,
|
|
17
|
+
3921009573,
|
|
18
|
+
961987163,
|
|
19
|
+
1508970993,
|
|
20
|
+
2453635748,
|
|
21
|
+
2870763221,
|
|
22
|
+
3624381080,
|
|
23
|
+
310598401,
|
|
24
|
+
607225278,
|
|
25
|
+
1426881987,
|
|
26
|
+
1925078388,
|
|
27
|
+
2162078206,
|
|
28
|
+
2614888103,
|
|
29
|
+
3248222580,
|
|
30
|
+
3835390401,
|
|
31
|
+
4022224774,
|
|
32
|
+
264347078,
|
|
33
|
+
604807628,
|
|
34
|
+
770255983,
|
|
35
|
+
1249150122,
|
|
36
|
+
1555081692,
|
|
37
|
+
1996064986,
|
|
38
|
+
2554220882,
|
|
39
|
+
2821834349,
|
|
40
|
+
2952996808,
|
|
41
|
+
3210313671,
|
|
42
|
+
3336571891,
|
|
43
|
+
3584528711,
|
|
44
|
+
113926993,
|
|
45
|
+
338241895,
|
|
46
|
+
666307205,
|
|
47
|
+
773529912,
|
|
48
|
+
1294757372,
|
|
49
|
+
1396182291,
|
|
50
|
+
1695183700,
|
|
51
|
+
1986661051,
|
|
52
|
+
2177026350,
|
|
53
|
+
2456956037,
|
|
54
|
+
2730485921,
|
|
55
|
+
2820302411,
|
|
56
|
+
3259730800,
|
|
57
|
+
3345764771,
|
|
58
|
+
3516065817,
|
|
59
|
+
3600352804,
|
|
60
|
+
4094571909,
|
|
61
|
+
275423344,
|
|
62
|
+
430227734,
|
|
63
|
+
506948616,
|
|
64
|
+
659060556,
|
|
65
|
+
883997877,
|
|
66
|
+
958139571,
|
|
67
|
+
1322822218,
|
|
68
|
+
1537002063,
|
|
69
|
+
1747873779,
|
|
70
|
+
1955562222,
|
|
71
|
+
2024104815,
|
|
72
|
+
2227730452,
|
|
73
|
+
2361852424,
|
|
74
|
+
2428436474,
|
|
75
|
+
2756734187,
|
|
76
|
+
3204031479,
|
|
77
|
+
3329325298
|
|
78
|
+
]);
|
|
79
|
+
var H0 = [
|
|
80
|
+
1779033703,
|
|
81
|
+
3144134277,
|
|
82
|
+
1013904242,
|
|
83
|
+
2773480762,
|
|
84
|
+
1359893119,
|
|
85
|
+
2600822924,
|
|
86
|
+
528734635,
|
|
87
|
+
1541459225
|
|
88
|
+
];
|
|
89
|
+
function utf8Bytes(input) {
|
|
90
|
+
const out = [];
|
|
91
|
+
for (let i = 0; i < input.length; i++) {
|
|
92
|
+
let cp = input.charCodeAt(i);
|
|
93
|
+
if (cp >= 55296 && cp <= 56319) {
|
|
94
|
+
const next = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
|
|
95
|
+
if (next >= 56320 && next <= 57343) {
|
|
96
|
+
cp = 65536 + (cp - 55296 << 10) + (next - 56320);
|
|
97
|
+
i++;
|
|
98
|
+
} else {
|
|
99
|
+
cp = 65533;
|
|
100
|
+
}
|
|
101
|
+
} else if (cp >= 56320 && cp <= 57343) {
|
|
102
|
+
cp = 65533;
|
|
103
|
+
}
|
|
104
|
+
if (cp < 128) {
|
|
105
|
+
out.push(cp);
|
|
106
|
+
} else if (cp < 2048) {
|
|
107
|
+
out.push(192 | cp >> 6, 128 | cp & 63);
|
|
108
|
+
} else if (cp < 65536) {
|
|
109
|
+
out.push(224 | cp >> 12, 128 | cp >> 6 & 63, 128 | cp & 63);
|
|
110
|
+
} else {
|
|
111
|
+
out.push(
|
|
112
|
+
240 | cp >> 18,
|
|
113
|
+
128 | cp >> 12 & 63,
|
|
114
|
+
128 | cp >> 6 & 63,
|
|
115
|
+
128 | cp & 63
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return Uint8Array.from(out);
|
|
120
|
+
}
|
|
121
|
+
var rotr = (x, n) => x >>> n | x << 32 - n;
|
|
122
|
+
function sha256Hex(input) {
|
|
123
|
+
const bytes = utf8Bytes(input);
|
|
124
|
+
const blockBytes = Math.ceil((bytes.length + 9) / 64) * 64;
|
|
125
|
+
const buffer = new Uint8Array(blockBytes);
|
|
126
|
+
buffer.set(bytes);
|
|
127
|
+
buffer[bytes.length] = 128;
|
|
128
|
+
const view = new DataView(buffer.buffer);
|
|
129
|
+
const bitLength = bytes.length * 8;
|
|
130
|
+
view.setUint32(blockBytes - 8, Math.floor(bitLength / 4294967296));
|
|
131
|
+
view.setUint32(blockBytes - 4, bitLength >>> 0);
|
|
132
|
+
const h = H0.slice();
|
|
133
|
+
const w = new Uint32Array(64);
|
|
134
|
+
for (let block = 0; block < blockBytes; block += 64) {
|
|
135
|
+
for (let t = 0; t < 16; t++) w[t] = view.getUint32(block + t * 4);
|
|
136
|
+
for (let t = 16; t < 64; t++) {
|
|
137
|
+
const s0 = rotr(w[t - 15], 7) ^ rotr(w[t - 15], 18) ^ w[t - 15] >>> 3;
|
|
138
|
+
const s1 = rotr(w[t - 2], 17) ^ rotr(w[t - 2], 19) ^ w[t - 2] >>> 10;
|
|
139
|
+
w[t] = w[t - 16] + s0 + w[t - 7] + s1;
|
|
140
|
+
}
|
|
141
|
+
let [a, b, c, d, e, f, g, hh] = h;
|
|
142
|
+
for (let t = 0; t < 64; t++) {
|
|
143
|
+
const S1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
|
|
144
|
+
const ch = e & f ^ ~e & g;
|
|
145
|
+
const t1 = hh + S1 + ch + K[t] + w[t] | 0;
|
|
146
|
+
const S0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
|
|
147
|
+
const maj = a & b ^ a & c ^ b & c;
|
|
148
|
+
const t2 = S0 + maj | 0;
|
|
149
|
+
hh = g;
|
|
150
|
+
g = f;
|
|
151
|
+
f = e;
|
|
152
|
+
e = d + t1 | 0;
|
|
153
|
+
d = c;
|
|
154
|
+
c = b;
|
|
155
|
+
b = a;
|
|
156
|
+
a = t1 + t2 | 0;
|
|
157
|
+
}
|
|
158
|
+
h[0] = h[0] + a | 0;
|
|
159
|
+
h[1] = h[1] + b | 0;
|
|
160
|
+
h[2] = h[2] + c | 0;
|
|
161
|
+
h[3] = h[3] + d | 0;
|
|
162
|
+
h[4] = h[4] + e | 0;
|
|
163
|
+
h[5] = h[5] + f | 0;
|
|
164
|
+
h[6] = h[6] + g | 0;
|
|
165
|
+
h[7] = h[7] + hh | 0;
|
|
166
|
+
}
|
|
167
|
+
return h.map((word) => (word >>> 0).toString(16).padStart(8, "0")).join("");
|
|
168
|
+
}
|
|
169
|
+
|
|
12
170
|
// src/core/vision-fields.ts
|
|
13
171
|
var INTERACTIVE_HANDLER_NAMES = /* @__PURE__ */ new Set([
|
|
14
172
|
"onPress",
|
|
@@ -92,13 +250,18 @@ var NAMED_COLORS = {
|
|
|
92
250
|
gray: { r: 128, g: 128, b: 128 },
|
|
93
251
|
grey: { r: 128, g: 128, b: 128 },
|
|
94
252
|
silver: { r: 192, g: 192, b: 192 },
|
|
95
|
-
transparent: { r: 0, g: 0, b: 0 },
|
|
96
253
|
orange: { r: 255, g: 165, b: 0 },
|
|
97
254
|
yellow: { r: 255, g: 255, b: 0 },
|
|
98
255
|
purple: { r: 128, g: 0, b: 128 },
|
|
99
256
|
navy: { r: 0, g: 0, b: 128 }
|
|
100
257
|
};
|
|
101
258
|
var clamp255 = (n) => Math.max(0, Math.min(255, Math.round(n)));
|
|
259
|
+
function parseAlpha(p) {
|
|
260
|
+
const pct = p.endsWith("%");
|
|
261
|
+
const n = parseFloat(pct ? p.slice(0, -1) : p);
|
|
262
|
+
if (!Number.isFinite(n)) return void 0;
|
|
263
|
+
return Math.min(1, pct ? n / 100 : n);
|
|
264
|
+
}
|
|
102
265
|
function parseColorToRgb(input) {
|
|
103
266
|
if (typeof input !== "string") return void 0;
|
|
104
267
|
const raw = input.trim().toLowerCase();
|
|
@@ -109,6 +272,7 @@ function parseColorToRgb(input) {
|
|
|
109
272
|
if (raw.startsWith("#")) {
|
|
110
273
|
const hex = raw.slice(1);
|
|
111
274
|
if (hex.length === 3 || hex.length === 4) {
|
|
275
|
+
if (hex.length === 4 && hex[3] !== "f") return void 0;
|
|
112
276
|
const r = parseInt(hex[0] + hex[0], 16);
|
|
113
277
|
const g = parseInt(hex[1] + hex[1], 16);
|
|
114
278
|
const b = parseInt(hex[2] + hex[2], 16);
|
|
@@ -116,6 +280,7 @@ function parseColorToRgb(input) {
|
|
|
116
280
|
return void 0;
|
|
117
281
|
}
|
|
118
282
|
if (hex.length === 6 || hex.length === 8) {
|
|
283
|
+
if (hex.length === 8 && hex.slice(6, 8) !== "ff") return void 0;
|
|
119
284
|
const r = parseInt(hex.slice(0, 2), 16);
|
|
120
285
|
const g = parseInt(hex.slice(2, 4), 16);
|
|
121
286
|
const b = parseInt(hex.slice(4, 6), 16);
|
|
@@ -127,7 +292,11 @@ function parseColorToRgb(input) {
|
|
|
127
292
|
const rgbMatch = raw.match(/^rgba?\(([^)]+)\)$/);
|
|
128
293
|
if (rgbMatch) {
|
|
129
294
|
const parts = rgbMatch[1].split(",").map((p) => p.trim());
|
|
130
|
-
if (parts.length < 3) return void 0;
|
|
295
|
+
if (parts.length < 3 || parts.length > 4) return void 0;
|
|
296
|
+
if (parts.length === 4) {
|
|
297
|
+
const alpha = parseAlpha(parts[3]);
|
|
298
|
+
if (alpha === void 0 || alpha < 1) return void 0;
|
|
299
|
+
}
|
|
131
300
|
const channel = (p) => {
|
|
132
301
|
if (p.endsWith("%")) {
|
|
133
302
|
const pct = parseFloat(p.slice(0, -1));
|
|
@@ -159,13 +328,87 @@ function parseFontSizePx(input) {
|
|
|
159
328
|
}
|
|
160
329
|
return void 0;
|
|
161
330
|
}
|
|
331
|
+
var ASCII_WHITESPACE_EDGES = /^[\t\n\f\r ]+|[\t\n\f\r ]+$/g;
|
|
332
|
+
function nonEmptyString(v) {
|
|
333
|
+
return typeof v === "string" && v.length > 0 ? v : void 0;
|
|
334
|
+
}
|
|
335
|
+
var OBJECT_FIT_TO_RESIZE_MODE = /* @__PURE__ */ new Map([
|
|
336
|
+
["contain", "contain"],
|
|
337
|
+
["cover", "cover"],
|
|
338
|
+
["fill", "stretch"],
|
|
339
|
+
["scale-down", "contain"],
|
|
340
|
+
["none", "none"]
|
|
341
|
+
]);
|
|
342
|
+
var RESIZE_MODE_TO_OBJECT_FIT = /* @__PURE__ */ new Map([
|
|
343
|
+
["cover", "cover"],
|
|
344
|
+
["contain", "contain"],
|
|
345
|
+
["stretch", "fill"],
|
|
346
|
+
["center", "scale-down"],
|
|
347
|
+
["none", "none"]
|
|
348
|
+
]);
|
|
349
|
+
function resolveObjectFit(props, flatStyle) {
|
|
350
|
+
const styleFit = nonEmptyString(flatStyle?.objectFit);
|
|
351
|
+
const mode = (styleFit !== void 0 ? OBJECT_FIT_TO_RESIZE_MODE.get(styleFit) : void 0) ?? nonEmptyString(props?.resizeMode) ?? nonEmptyString(flatStyle?.resizeMode);
|
|
352
|
+
return mode !== void 0 ? RESIZE_MODE_TO_OBJECT_FIT.get(mode) : void 0;
|
|
353
|
+
}
|
|
354
|
+
function resolveImageSource(props) {
|
|
355
|
+
if (!props) return void 0;
|
|
356
|
+
if (props.srcSet !== void 0 && props.srcSet !== null) return void 0;
|
|
357
|
+
const src = nonEmptyString(props.src);
|
|
358
|
+
if (src !== void 0) return src;
|
|
359
|
+
const source = props.source;
|
|
360
|
+
const one = Array.isArray(source) ? source.length === 1 ? source[0] : void 0 : source;
|
|
361
|
+
if (one && typeof one === "object") {
|
|
362
|
+
return nonEmptyString(one.uri);
|
|
363
|
+
}
|
|
364
|
+
return void 0;
|
|
365
|
+
}
|
|
366
|
+
function isHiddenFromAccessibility(props) {
|
|
367
|
+
if (!props) return false;
|
|
368
|
+
return props.accessible === false && props.alt === void 0 || props.importantForAccessibility === "no" || props.importantForAccessibility === "no-hide-descendants" || props.accessibilityElementsHidden === true;
|
|
369
|
+
}
|
|
370
|
+
function resolveImageLabel(props, registryLabel) {
|
|
371
|
+
if (props === void 0) return registryLabel;
|
|
372
|
+
const own = props["aria-label"] ?? props.accessibilityLabel ?? props.alt;
|
|
373
|
+
return typeof own === "string" ? own : void 0;
|
|
374
|
+
}
|
|
375
|
+
function projectMedia(args) {
|
|
376
|
+
const { layout, props, flatStyle, accessibilityLabel, inViewport } = args;
|
|
377
|
+
const media = { kind: "img" };
|
|
378
|
+
if (layout && Number.isFinite(layout.width) && Number.isFinite(layout.height) && layout.width >= 0 && layout.height >= 0) {
|
|
379
|
+
media.rendered_px = { w: layout.width, h: layout.height };
|
|
380
|
+
}
|
|
381
|
+
const objectFit = resolveObjectFit(props, flatStyle);
|
|
382
|
+
if (objectFit !== void 0) media.object_fit = objectFit;
|
|
383
|
+
if (isHiddenFromAccessibility(props)) {
|
|
384
|
+
media.alt = { decorative: true };
|
|
385
|
+
} else {
|
|
386
|
+
const label = resolveImageLabel(props, accessibilityLabel);
|
|
387
|
+
const text = label?.replace(ASCII_WHITESPACE_EDGES, "");
|
|
388
|
+
if (text) media.alt = { decorative: false, text };
|
|
389
|
+
}
|
|
390
|
+
const src = resolveImageSource(props);
|
|
391
|
+
if (src !== void 0) media.src_digest = sha256Hex(src);
|
|
392
|
+
if (inViewport !== void 0) media.in_viewport = inViewport;
|
|
393
|
+
return media;
|
|
394
|
+
}
|
|
162
395
|
function projectVisionFields(args) {
|
|
163
396
|
const { type, label, handlerNames, state, flatStyle } = args;
|
|
164
397
|
const fields = {
|
|
165
398
|
interactable: deriveInteractable(type, handlerNames)
|
|
166
399
|
};
|
|
167
|
-
|
|
168
|
-
|
|
400
|
+
if (type === "image") {
|
|
401
|
+
fields.media = projectMedia({
|
|
402
|
+
layout: state.layout,
|
|
403
|
+
props: args.props,
|
|
404
|
+
flatStyle,
|
|
405
|
+
accessibilityLabel: args.accessibilityLabel,
|
|
406
|
+
inViewport: args.inViewport
|
|
407
|
+
});
|
|
408
|
+
} else {
|
|
409
|
+
const text = deriveText(state, label);
|
|
410
|
+
if (text !== void 0) fields.text = text;
|
|
411
|
+
}
|
|
169
412
|
const role = roleForType(type);
|
|
170
413
|
if (role !== void 0) fields.role = role;
|
|
171
414
|
if (flatStyle) {
|
|
@@ -305,11 +548,17 @@ function computeVisibility(state, clip) {
|
|
|
305
548
|
if (!rect) {
|
|
306
549
|
return { visibility: "visible" };
|
|
307
550
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
return
|
|
551
|
+
return rectReachesClip(rect, clip) ? { visibility: "visible" } : { visibility: "hidden", visibilityReason: "off-screen" };
|
|
552
|
+
}
|
|
553
|
+
function rectReachesClip(rect, clip) {
|
|
554
|
+
if (isEmptyRect(clip)) return false;
|
|
555
|
+
return spansOverlap(rect.left, rect.right, clip.left, clip.right) && spansOverlap(rect.top, rect.bottom, clip.top, clip.bottom);
|
|
556
|
+
}
|
|
557
|
+
function computeInViewport(state, clip) {
|
|
558
|
+
if (!state.visible || !clip) return void 0;
|
|
559
|
+
const rect = pageRectOf(state);
|
|
560
|
+
if (!rect) return void 0;
|
|
561
|
+
return rectReachesClip(rect, clip);
|
|
313
562
|
}
|
|
314
563
|
function copyRouteInfo(info) {
|
|
315
564
|
const copy = { ...info };
|
|
@@ -1252,10 +1501,9 @@ var NativeUIBridgeRegistry = class {
|
|
|
1252
1501
|
elements: elements.map((e) => {
|
|
1253
1502
|
const handlers = extractHandlerNames(e.props);
|
|
1254
1503
|
const state = e.getState();
|
|
1255
|
-
const
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
);
|
|
1504
|
+
const identifier = e.getIdentifier();
|
|
1505
|
+
const clip = this.getClipRectFor(e, viewport);
|
|
1506
|
+
const { visibility, visibilityReason } = computeVisibility(state, clip);
|
|
1259
1507
|
const bbox = projectBbox(state, visibility, this.pixelRatio);
|
|
1260
1508
|
const vision = projectVisionFields({
|
|
1261
1509
|
type: e.type,
|
|
@@ -1266,13 +1514,16 @@ var NativeUIBridgeRegistry = class {
|
|
|
1266
1514
|
// using it would mark plain text/view nodes interactable.
|
|
1267
1515
|
handlerNames: handlers,
|
|
1268
1516
|
state,
|
|
1269
|
-
flatStyle: e.flatStyle
|
|
1517
|
+
flatStyle: e.flatStyle,
|
|
1518
|
+
props: e.props,
|
|
1519
|
+
accessibilityLabel: identifier.accessibilityLabel,
|
|
1520
|
+
inViewport: computeInViewport(state, clip)
|
|
1270
1521
|
});
|
|
1271
1522
|
return {
|
|
1272
1523
|
id: e.id,
|
|
1273
1524
|
type: e.type,
|
|
1274
1525
|
label: e.label,
|
|
1275
|
-
identifier
|
|
1526
|
+
identifier,
|
|
1276
1527
|
state,
|
|
1277
1528
|
actions: e.actions,
|
|
1278
1529
|
customActions: serializeElementCustomActions(e.customActions),
|
|
@@ -3359,7 +3610,7 @@ var NATIVE_PAGE_HEALTH_PRODUCER_ID = "sdk-native/page-health";
|
|
|
3359
3610
|
function defaultProducer() {
|
|
3360
3611
|
return {
|
|
3361
3612
|
id: NATIVE_PAGE_HEALTH_PRODUCER_ID,
|
|
3362
|
-
version: "0.
|
|
3613
|
+
version: "0.8.0"
|
|
3363
3614
|
};
|
|
3364
3615
|
}
|
|
3365
3616
|
function pageHealthUnknown(code, detail, options = {}) {
|
|
@@ -3401,14 +3652,7 @@ var LOADING_PHRASES = [
|
|
|
3401
3652
|
"initializing",
|
|
3402
3653
|
"fetching"
|
|
3403
3654
|
];
|
|
3404
|
-
var EMPTY_PHRASES = [
|
|
3405
|
-
"no data",
|
|
3406
|
-
"no results",
|
|
3407
|
-
"nothing here",
|
|
3408
|
-
"empty",
|
|
3409
|
-
"no items",
|
|
3410
|
-
"get started"
|
|
3411
|
-
];
|
|
3655
|
+
var EMPTY_PHRASES = ["no data", "no results", "nothing here", "empty", "no items", "get started"];
|
|
3412
3656
|
function severityRank(s) {
|
|
3413
3657
|
if (s === "CRITICAL") return 3;
|
|
3414
3658
|
if (s === "WARNING") return 2;
|
|
@@ -3483,20 +3727,44 @@ function observe(input, producer, evaluatedAt) {
|
|
|
3483
3727
|
}
|
|
3484
3728
|
return analyze(elements, viewport, base);
|
|
3485
3729
|
}
|
|
3730
|
+
function nothingOnScreenDetail(elements, visibleCount, visibilityUnstated) {
|
|
3731
|
+
if (visibilityUnstated === 0 && visibleCount > 0) {
|
|
3732
|
+
return `all ${visibleCount} visible element(s) have no measured layout yet, so spatial coverage, layout regions and visual anomalies cannot be measured`;
|
|
3733
|
+
}
|
|
3734
|
+
if (visibilityUnstated > 0) {
|
|
3735
|
+
const geometry = visibleCount > 0 ? ` and none of the ${visibleCount} visible one(s) has a measured layout` : "";
|
|
3736
|
+
return `${visibilityUnstated} of ${elements.length} element(s) carry no boolean \`state.visible\`${geometry}, so no element can be placed on screen; spatial coverage, layout regions and visual anomalies cannot be measured`;
|
|
3737
|
+
}
|
|
3738
|
+
const unmounted = elements.filter((el) => el.state?.mounted === false).length;
|
|
3739
|
+
return `all ${elements.length} registered element(s) report visible: false (unmounted=${unmounted}, off-screen route or otherwise=${elements.length - unmounted}), so whatever is on screen is not a registered element and there is nothing on screen to measure; this says nothing about whether the screen is blank`;
|
|
3740
|
+
}
|
|
3486
3741
|
function analyze(elements, viewport, base) {
|
|
3487
3742
|
const findings = [];
|
|
3488
|
-
const
|
|
3489
|
-
const
|
|
3743
|
+
const onScreen = elements.filter((el) => el.state?.visible === true);
|
|
3744
|
+
const visibilityUnstated = elements.filter(
|
|
3745
|
+
(el) => typeof el.state?.visible !== "boolean"
|
|
3746
|
+
).length;
|
|
3747
|
+
const visible = onScreen.flatMap((el) => {
|
|
3490
3748
|
const rect = normalizeRect(el.state, viewport);
|
|
3491
3749
|
return rect ? [{ el, rect }] : [];
|
|
3492
3750
|
});
|
|
3493
|
-
const withoutGeometry =
|
|
3494
|
-
const unmeasured =
|
|
3495
|
-
|
|
3496
|
-
|
|
3751
|
+
const withoutGeometry = onScreen.length - visible.length;
|
|
3752
|
+
const unmeasured = [];
|
|
3753
|
+
if (withoutGeometry > 0) {
|
|
3754
|
+
unmeasured.push({ dimension: "geometry", count: withoutGeometry, code: "input_missing" });
|
|
3755
|
+
}
|
|
3756
|
+
if (visibilityUnstated > 0) {
|
|
3757
|
+
unmeasured.push({ dimension: "visibility", count: visibilityUnstated, code: "input_missing" });
|
|
3758
|
+
}
|
|
3759
|
+
const coverage = {
|
|
3760
|
+
considered: onScreen.length + visibilityUnstated,
|
|
3761
|
+
measured: visible.length,
|
|
3762
|
+
unmeasured
|
|
3763
|
+
};
|
|
3764
|
+
if (elements.length > 0 && visible.length === 0) {
|
|
3497
3765
|
return Observation.unknown(
|
|
3498
3766
|
"input_missing",
|
|
3499
|
-
|
|
3767
|
+
nothingOnScreenDetail(elements, onScreen.length, visibilityUnstated),
|
|
3500
3768
|
Observation.provenance({ ...base, coverage })
|
|
3501
3769
|
);
|
|
3502
3770
|
}
|
|
@@ -3586,7 +3854,7 @@ function analyze(elements, viewport, base) {
|
|
|
3586
3854
|
for (const el of elements) {
|
|
3587
3855
|
const elType = el.type ?? "";
|
|
3588
3856
|
if (SKIP_TEXT_TYPES.has(elType)) continue;
|
|
3589
|
-
const text = (el.state
|
|
3857
|
+
const text = (el.state?.textContent ?? "").toString();
|
|
3590
3858
|
if (!text) continue;
|
|
3591
3859
|
const textLower = text.toLowerCase();
|
|
3592
3860
|
for (const p of ERROR_PHRASES) {
|
|
@@ -3627,7 +3895,7 @@ function analyze(elements, viewport, base) {
|
|
|
3627
3895
|
for (const el of elements) {
|
|
3628
3896
|
if (!INTERACTIVE_TYPES2.has(el.type)) continue;
|
|
3629
3897
|
interactiveTotal++;
|
|
3630
|
-
if (el.state
|
|
3898
|
+
if (el.state?.enabled === false) interactiveDisabled++;
|
|
3631
3899
|
}
|
|
3632
3900
|
const interactiveSeverity = interactiveTotal > 0 && interactiveDisabled / interactiveTotal > 0.5 ? "WARNING" : "OK";
|
|
3633
3901
|
findings.push({
|
|
@@ -3651,9 +3919,7 @@ function analyze(elements, viewport, base) {
|
|
|
3651
3919
|
detail: `zero_size=${zeroSize}, outside_viewport=${outsideViewport} (horizontal-overflow only; below/above-fold scrollable content is not an anomaly)`,
|
|
3652
3920
|
data: { zero_size: zeroSize, outside_viewport: outsideViewport }
|
|
3653
3921
|
});
|
|
3654
|
-
const heatmap = grid.map(
|
|
3655
|
-
(row) => row.map((cell) => cell ? "#" : ".").join("")
|
|
3656
|
-
);
|
|
3922
|
+
const heatmap = grid.map((row) => row.map((cell) => cell ? "#" : ".").join(""));
|
|
3657
3923
|
return Observation.measured(
|
|
3658
3924
|
{
|
|
3659
3925
|
summary: worstSeverity(findings),
|
|
@@ -3913,10 +4179,9 @@ function createServerHandlers(registry, executor, config) {
|
|
|
3913
4179
|
const elements = allElements.map((e) => {
|
|
3914
4180
|
const handlers = extractHandlerNames(e.props);
|
|
3915
4181
|
const state = e.getState();
|
|
3916
|
-
const
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
);
|
|
4182
|
+
const identifier = e.getIdentifier();
|
|
4183
|
+
const clip = registry.getClipRectFor(e, viewport);
|
|
4184
|
+
const { visibility, visibilityReason } = computeVisibility(state, clip);
|
|
3920
4185
|
const bbox = projectBbox(state, visibility, registry.getPixelRatio());
|
|
3921
4186
|
const vision = projectVisionFields({
|
|
3922
4187
|
type: e.type,
|
|
@@ -3925,13 +4190,16 @@ function createServerHandlers(registry, executor, config) {
|
|
|
3925
4190
|
// synthesize press/click onto every element. See projectVisionFields.
|
|
3926
4191
|
handlerNames: handlers,
|
|
3927
4192
|
state,
|
|
3928
|
-
flatStyle: e.flatStyle
|
|
4193
|
+
flatStyle: e.flatStyle,
|
|
4194
|
+
props: e.props,
|
|
4195
|
+
accessibilityLabel: identifier.accessibilityLabel,
|
|
4196
|
+
inViewport: computeInViewport(state, clip)
|
|
3929
4197
|
});
|
|
3930
4198
|
return {
|
|
3931
4199
|
id: e.id,
|
|
3932
4200
|
type: e.type,
|
|
3933
4201
|
label: e.label,
|
|
3934
|
-
identifier
|
|
4202
|
+
identifier,
|
|
3935
4203
|
state,
|
|
3936
4204
|
actions: e.actions,
|
|
3937
4205
|
customActions: serializeElementCustomActions(e.customActions),
|
|
@@ -4639,7 +4907,7 @@ function createServerHandlers(registry, executor, config) {
|
|
|
4639
4907
|
};
|
|
4640
4908
|
if (config?.appInfo) {
|
|
4641
4909
|
response.uiBridge = {
|
|
4642
|
-
version: "0.
|
|
4910
|
+
version: "0.8.0",
|
|
4643
4911
|
...config.appInfo,
|
|
4644
4912
|
capabilities: ["elements", "components", "actions", "design"],
|
|
4645
4913
|
elementCount: stats.elements,
|
|
@@ -8202,7 +8470,9 @@ function TransitionTo(props) {
|
|
|
8202
8470
|
return /* @__PURE__ */ jsx(Fragment, { children: props.children });
|
|
8203
8471
|
}
|
|
8204
8472
|
function effectiveInfo(info, unmatched) {
|
|
8205
|
-
|
|
8473
|
+
if (!unmatched) return info;
|
|
8474
|
+
const { params: _dropped, ...rest } = info;
|
|
8475
|
+
return { ...rest, pattern: null };
|
|
8206
8476
|
}
|
|
8207
8477
|
function useRouteAwareness(info, options = {}) {
|
|
8208
8478
|
const bridge = useUIBridgeNativeOptional();
|