@reticlehq/browser 3.7.0 → 3.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/actions/action-report.d.ts +10 -0
- package/dist/actions/action-report.js +29 -2
- package/dist/actions/actions-dom.d.ts +4 -0
- package/dist/actions/actions-dom.js +20 -4
- package/dist/actions/actions.d.ts +1 -0
- package/dist/actions/actions.js +35 -17
- package/dist/actions/appeared-text.js +2 -2
- package/dist/actions/click-target.d.ts +1 -0
- package/dist/actions/click-target.js +14 -0
- package/dist/actions/danger-context.d.ts +2 -1
- package/dist/actions/danger-context.js +20 -5
- package/dist/activate.d.ts +14 -0
- package/dist/activate.js +43 -0
- package/dist/busy.d.ts +3 -0
- package/dist/busy.js +42 -0
- package/dist/commands/commands.js +45 -17
- package/dist/connect-options.d.ts +12 -1
- package/dist/connect-options.js +18 -1
- package/dist/dom/a11y.d.ts +2 -0
- package/dist/dom/a11y.js +191 -159
- package/dist/dom/chart.d.ts +3 -2
- package/dist/dom/chart.js +3 -2
- package/dist/dom/dom-ignore.d.ts +6 -0
- package/dist/dom/dom-ignore.js +43 -1
- package/dist/dom/layout-audit.d.ts +15 -0
- package/dist/dom/layout-audit.js +208 -0
- package/dist/dom/paint-context.d.ts +15 -0
- package/dist/dom/paint-context.js +78 -0
- package/dist/dom/query.d.ts +2 -1
- package/dist/dom/query.js +97 -34
- package/dist/dom/shadow-registry.d.ts +1 -0
- package/dist/dom/shadow-registry.js +27 -0
- package/dist/dom/snapshot.d.ts +5 -0
- package/dist/dom/snapshot.js +85 -34
- package/dist/dom/stable-selector.d.ts +1 -0
- package/dist/dom/stable-selector.js +19 -0
- package/dist/dom/text-match.d.ts +12 -0
- package/dist/dom/text-match.js +115 -0
- package/dist/dom/theme.d.ts +1 -0
- package/dist/dom/theme.js +21 -9
- package/dist/dom/virtualized.js +5 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +5 -0
- package/dist/observers/blind-spots.js +3 -2
- package/dist/observers/canvas.d.ts +18 -0
- package/dist/observers/canvas.js +76 -0
- package/dist/observers/dom.js +66 -18
- package/dist/observers/field.d.ts +11 -0
- package/dist/observers/field.js +117 -13
- package/dist/observers/install-all.js +4 -0
- package/dist/observers/media.d.ts +2 -0
- package/dist/observers/media.js +32 -0
- package/dist/observers/net-detail/network-body.d.ts +2 -0
- package/dist/observers/net-detail/network-body.js +8 -1
- package/dist/observers/network.js +26 -6
- package/dist/observers/route.d.ts +2 -0
- package/dist/observers/route.js +33 -4
- package/dist/presenter/chrome/presenter-report-copy.d.ts +0 -5
- package/dist/presenter/chrome/presenter-report-copy.js +0 -14
- package/dist/presenter/hud-telemetry.js +1 -1
- package/dist/presenter/presenter-chat-views.d.ts +3 -4
- package/dist/presenter/presenter-chat-views.js +47 -20
- package/dist/presenter/presenter-config.d.ts +1 -0
- package/dist/presenter/presenter-config.js +1 -0
- package/dist/presenter/presenter-frame.d.ts +3 -2
- package/dist/presenter/presenter-frame.js +24 -15
- package/dist/presenter/presenter-harness-row.d.ts +4 -15
- package/dist/presenter/presenter-harness-row.js +11 -50
- package/dist/presenter/presenter-report-styles.js +0 -17
- package/dist/presenter/presenter-report.d.ts +1 -2
- package/dist/presenter/presenter-report.js +4 -54
- package/dist/presenter/presenter-run-state.js +2 -1
- package/dist/presenter/presenter-settings.d.ts +2 -3
- package/dist/presenter/presenter-settings.js +14 -17
- package/dist/presenter/presenter-shell.d.ts +6 -4
- package/dist/presenter/presenter-shell.js +37 -7
- package/dist/presenter/presenter.js +32 -11
- package/dist/registry/store-adapters.d.ts +5 -2
- package/dist/registry/store-adapters.js +40 -10
- package/dist/reticle-inject.js +602 -611
- package/dist/reticle.d.ts +4 -2
- package/dist/reticle.js +36 -6
- package/dist/security/page-location.d.ts +2 -0
- package/dist/security/page-location.js +7 -0
- package/dist/security/serialization.js +1 -1
- package/dist/storage-keys.d.ts +1 -0
- package/dist/storage-keys.js +1 -0
- package/dist/timers/native/native-timers.d.ts +1 -0
- package/dist/timers/native/native-timers.js +5 -0
- package/dist/transport/transport.d.ts +1 -0
- package/dist/transport/transport.js +18 -0
- package/package.json +6 -2
package/dist/dom/a11y.js
CHANGED
|
@@ -2,7 +2,8 @@ import { readTestId } from './addressing/testid-attr.js';
|
|
|
2
2
|
import { DEFAULT_TESTID_ATTR, ElementState, REDACTED_VALUE, } from '@reticlehq/core';
|
|
3
3
|
import { isButton, isHtmlElement, isImage, isInput, isMeter, isOutput, isProgress, isSelect, isTextArea, } from './realm.js';
|
|
4
4
|
import { refs } from './addressing/refs.js';
|
|
5
|
-
import {
|
|
5
|
+
import { parentAcrossShadowBoundary } from './shadow-registry.js';
|
|
6
|
+
import { clippingBox, overflowAxes, scrolledInto, } from './paint-context.js';
|
|
6
7
|
import { inspectChart } from './chart.js';
|
|
7
8
|
import { isSensitiveKey } from '../security/serialization.js';
|
|
8
9
|
import { formatSource, sourceFromDom } from './addressing/source.js';
|
|
@@ -35,36 +36,46 @@ const NAME_FROM_CONTENT = new Set([
|
|
|
35
36
|
const INPUT_TEXT_TYPES = new Set(['text', 'email', 'tel', 'url', 'password', '']);
|
|
36
37
|
function inputRole(input) {
|
|
37
38
|
const type = input.type.toLowerCase();
|
|
38
|
-
if ('search' === type)
|
|
39
|
+
if ('search' === type) {
|
|
39
40
|
return 'searchbox';
|
|
40
|
-
|
|
41
|
+
}
|
|
42
|
+
if (INPUT_TEXT_TYPES.has(type)) {
|
|
41
43
|
return 'textbox';
|
|
42
|
-
|
|
44
|
+
}
|
|
45
|
+
if ('checkbox' === type) {
|
|
43
46
|
return 'checkbox';
|
|
44
|
-
|
|
47
|
+
}
|
|
48
|
+
if ('radio' === type) {
|
|
45
49
|
return 'radio';
|
|
46
|
-
|
|
50
|
+
}
|
|
51
|
+
if ('range' === type) {
|
|
47
52
|
return 'slider';
|
|
48
|
-
|
|
53
|
+
}
|
|
54
|
+
if ('number' === type) {
|
|
49
55
|
return 'spinbutton';
|
|
50
|
-
|
|
56
|
+
}
|
|
57
|
+
if ('submit' === type || 'button' === type || 'reset' === type) {
|
|
51
58
|
return 'button';
|
|
59
|
+
}
|
|
52
60
|
return 'textbox';
|
|
53
61
|
}
|
|
54
62
|
function hasAuthorNaming(el) {
|
|
55
63
|
const label = el.getAttribute('aria-label');
|
|
56
|
-
if (label !== null && label.trim().length > 0)
|
|
64
|
+
if (label !== null && label.trim().length > 0) {
|
|
57
65
|
return true;
|
|
66
|
+
}
|
|
58
67
|
const labelledby = el.getAttribute('aria-labelledby');
|
|
59
|
-
if (labelledby !== null && labelledby.trim().length > 0)
|
|
68
|
+
if (labelledby !== null && labelledby.trim().length > 0) {
|
|
60
69
|
return true;
|
|
70
|
+
}
|
|
61
71
|
const title = el.getAttribute('title');
|
|
62
72
|
return title !== null && title.trim().length > 0;
|
|
63
73
|
}
|
|
64
74
|
export function getRole(el) {
|
|
65
75
|
const explicit = el.getAttribute('role');
|
|
66
|
-
if (explicit !== null && explicit.trim().length > 0)
|
|
76
|
+
if (explicit !== null && explicit.trim().length > 0) {
|
|
67
77
|
return explicit.trim();
|
|
78
|
+
}
|
|
68
79
|
const tag = el.tagName.toLowerCase();
|
|
69
80
|
switch (tag) {
|
|
70
81
|
case 'a':
|
|
@@ -154,25 +165,30 @@ function collapse(text) {
|
|
|
154
165
|
}
|
|
155
166
|
function labelledByText(el) {
|
|
156
167
|
const ids = el.getAttribute('aria-labelledby');
|
|
157
|
-
if (null === ids)
|
|
168
|
+
if (null === ids) {
|
|
158
169
|
return null;
|
|
170
|
+
}
|
|
159
171
|
const parts = [];
|
|
160
172
|
for (const id of ids.split(/\s+/)) {
|
|
161
173
|
const ref = el.ownerDocument.getElementById(id);
|
|
162
|
-
if (ref !== null)
|
|
174
|
+
if (ref !== null) {
|
|
163
175
|
parts.push(collapse(textWithoutHidden(ref)));
|
|
176
|
+
}
|
|
164
177
|
}
|
|
165
178
|
const joined = parts.join(' ').trim();
|
|
166
179
|
return joined.length > 0 ? joined : null;
|
|
167
180
|
}
|
|
168
181
|
function textWithoutHidden(node) {
|
|
169
|
-
if (node.nodeType === Node.TEXT_NODE)
|
|
182
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
170
183
|
return node.textContent ?? '';
|
|
171
|
-
|
|
184
|
+
}
|
|
185
|
+
if (node.nodeType !== Node.ELEMENT_NODE) {
|
|
172
186
|
return '';
|
|
187
|
+
}
|
|
173
188
|
const el = node;
|
|
174
|
-
if ('true' === el.getAttribute('aria-hidden'))
|
|
189
|
+
if ('true' === el.getAttribute('aria-hidden')) {
|
|
175
190
|
return '';
|
|
191
|
+
}
|
|
176
192
|
if (isImage(el)) {
|
|
177
193
|
const alt = el.getAttribute('alt');
|
|
178
194
|
return null === alt ? '' : alt;
|
|
@@ -181,11 +197,13 @@ function textWithoutHidden(node) {
|
|
|
181
197
|
let lastWasElement = false;
|
|
182
198
|
for (const child of el.childNodes) {
|
|
183
199
|
const piece = textWithoutHidden(child);
|
|
184
|
-
if (0 === piece.length)
|
|
200
|
+
if (0 === piece.length) {
|
|
185
201
|
continue;
|
|
202
|
+
}
|
|
186
203
|
const isEl = Node.ELEMENT_NODE === child.nodeType;
|
|
187
|
-
if (result.length > 0 && (isEl || lastWasElement))
|
|
204
|
+
if (result.length > 0 && (isEl || lastWasElement)) {
|
|
188
205
|
result += ' ';
|
|
206
|
+
}
|
|
189
207
|
result += piece;
|
|
190
208
|
lastWasElement = isEl;
|
|
191
209
|
}
|
|
@@ -193,15 +211,18 @@ function textWithoutHidden(node) {
|
|
|
193
211
|
}
|
|
194
212
|
export function getAccessibleName(el) {
|
|
195
213
|
const labelled = labelledByText(el);
|
|
196
|
-
if (labelled !== null)
|
|
214
|
+
if (labelled !== null) {
|
|
197
215
|
return labelled;
|
|
216
|
+
}
|
|
198
217
|
const ariaLabel = el.getAttribute('aria-label');
|
|
199
|
-
if (ariaLabel !== null && ariaLabel.trim().length > 0)
|
|
218
|
+
if (ariaLabel !== null && ariaLabel.trim().length > 0) {
|
|
200
219
|
return ariaLabel.trim();
|
|
220
|
+
}
|
|
201
221
|
if (isImage(el)) {
|
|
202
222
|
const alt = el.getAttribute('alt');
|
|
203
|
-
if (alt !== null)
|
|
223
|
+
if (alt !== null) {
|
|
204
224
|
return alt.trim();
|
|
225
|
+
}
|
|
205
226
|
}
|
|
206
227
|
const isLabelable = isInput(el) ||
|
|
207
228
|
isTextArea(el) ||
|
|
@@ -217,16 +238,36 @@ export function getAccessibleName(el) {
|
|
|
217
238
|
.map((l) => collapse(textWithoutHidden(l)))
|
|
218
239
|
.join(' ')
|
|
219
240
|
.trim();
|
|
220
|
-
if (text.length > 0)
|
|
241
|
+
if (text.length > 0) {
|
|
221
242
|
return text;
|
|
243
|
+
}
|
|
222
244
|
}
|
|
223
245
|
}
|
|
224
246
|
if ('fieldset' === el.tagName.toLowerCase()) {
|
|
225
247
|
const legend = [...el.children].find((child) => 'legend' === child.tagName.toLowerCase());
|
|
226
248
|
if (legend !== undefined) {
|
|
227
249
|
const text = collapse(textWithoutHidden(legend));
|
|
228
|
-
if (text.length > 0)
|
|
250
|
+
if (text.length > 0) {
|
|
251
|
+
return text;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if ('table' === el.tagName.toLowerCase()) {
|
|
256
|
+
const caption = [...el.children].find((child) => 'caption' === child.tagName.toLowerCase());
|
|
257
|
+
if (caption !== undefined) {
|
|
258
|
+
const text = collapse(textWithoutHidden(caption));
|
|
259
|
+
if (text.length > 0) {
|
|
260
|
+
return text;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
if ('figure' === el.tagName.toLowerCase()) {
|
|
265
|
+
const figcaption = [...el.children].find((child) => 'figcaption' === child.tagName.toLowerCase());
|
|
266
|
+
if (figcaption !== undefined) {
|
|
267
|
+
const text = collapse(textWithoutHidden(figcaption));
|
|
268
|
+
if (text.length > 0) {
|
|
229
269
|
return text;
|
|
270
|
+
}
|
|
230
271
|
}
|
|
231
272
|
}
|
|
232
273
|
if (isInput(el) || isTextArea(el) || isSelect(el)) {
|
|
@@ -234,49 +275,67 @@ export function getAccessibleName(el) {
|
|
|
234
275
|
const type = el.type.toLowerCase();
|
|
235
276
|
if ('submit' === type || 'button' === type || 'reset' === type) {
|
|
236
277
|
const value = collapse(el.value);
|
|
237
|
-
if (value.length > 0)
|
|
278
|
+
if (value.length > 0) {
|
|
238
279
|
return value;
|
|
280
|
+
}
|
|
239
281
|
}
|
|
240
282
|
}
|
|
241
283
|
if (isInput(el) || isTextArea(el)) {
|
|
242
284
|
const placeholder = el.getAttribute('placeholder');
|
|
243
|
-
if (placeholder !== null && placeholder.trim().length > 0)
|
|
285
|
+
if (placeholder !== null && placeholder.trim().length > 0) {
|
|
244
286
|
return placeholder.trim();
|
|
287
|
+
}
|
|
245
288
|
}
|
|
246
289
|
}
|
|
247
290
|
if (NAME_FROM_CONTENT.has(getRole(el))) {
|
|
248
291
|
const text = collapse(textWithoutHidden(el));
|
|
249
|
-
if (text.length > 0)
|
|
292
|
+
if (text.length > 0) {
|
|
250
293
|
return text;
|
|
294
|
+
}
|
|
251
295
|
}
|
|
252
296
|
const title = el.getAttribute('title');
|
|
253
|
-
if (title !== null && title.trim().length > 0)
|
|
297
|
+
if (title !== null && title.trim().length > 0) {
|
|
254
298
|
return title.trim();
|
|
299
|
+
}
|
|
255
300
|
return '';
|
|
256
301
|
}
|
|
257
302
|
function ariaBool(el, attr) {
|
|
258
303
|
const value = el.getAttribute(attr);
|
|
259
|
-
if (null === value)
|
|
304
|
+
if (null === value) {
|
|
260
305
|
return undefined;
|
|
306
|
+
}
|
|
261
307
|
return 'true' === value;
|
|
262
308
|
}
|
|
263
309
|
export function getStates(el, visible = isVisible(el)) {
|
|
264
310
|
const states = [ElementState.PRESENT];
|
|
265
311
|
states.push(visible ? ElementState.VISIBLE : ElementState.HIDDEN);
|
|
266
|
-
const
|
|
267
|
-
const disabled = disabledProp || true === ariaBool(el, 'aria-disabled');
|
|
312
|
+
const disabled = el.matches(':disabled') || true === ariaBool(el, 'aria-disabled');
|
|
268
313
|
states.push(disabled ? ElementState.DISABLED : ElementState.ENABLED);
|
|
269
314
|
const checkedProp = isInput(el) && ('checkbox' === el.type || 'radio' === el.type) && el.checked;
|
|
270
|
-
if (checkedProp || true === ariaBool(el, 'aria-checked'))
|
|
315
|
+
if (checkedProp || true === ariaBool(el, 'aria-checked')) {
|
|
271
316
|
states.push(ElementState.CHECKED);
|
|
272
|
-
|
|
317
|
+
}
|
|
318
|
+
if (true === ariaBool(el, 'aria-expanded') || isOpenDetailsSummary(el)) {
|
|
273
319
|
states.push(ElementState.EXPANDED);
|
|
274
|
-
|
|
320
|
+
}
|
|
321
|
+
if (true === ariaBool(el, 'aria-pressed')) {
|
|
275
322
|
states.push(ElementState.PRESSED);
|
|
276
|
-
|
|
323
|
+
}
|
|
324
|
+
if (el.ownerDocument.activeElement === el) {
|
|
277
325
|
states.push(ElementState.FOCUSED);
|
|
326
|
+
}
|
|
278
327
|
return states;
|
|
279
328
|
}
|
|
329
|
+
function isOpenDetailsSummary(el) {
|
|
330
|
+
const details = el.parentElement;
|
|
331
|
+
if (HTML_SUMMARY_TAG !== el.localName ||
|
|
332
|
+
null === details ||
|
|
333
|
+
HTML_DETAILS_TAG !== details.localName) {
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
336
|
+
const summary = Array.from(details.children).find((child) => HTML_SUMMARY_TAG === child.localName);
|
|
337
|
+
return summary === el && details.hasAttribute(HTML_DETAILS_OPEN_ATTRIBUTE);
|
|
338
|
+
}
|
|
280
339
|
const SENSITIVE_AUTOCOMPLETE = /\b(cc-|current-password|new-password|one-time-code)/i;
|
|
281
340
|
export function isSensitiveField(el) {
|
|
282
341
|
if (!isInput(el) && !isTextArea(el) && !isSelect(el)) {
|
|
@@ -297,8 +356,9 @@ export function isSensitiveField(el) {
|
|
|
297
356
|
}
|
|
298
357
|
export function getValue(el) {
|
|
299
358
|
if (isInput(el) || isTextArea(el) || isSelect(el)) {
|
|
300
|
-
if (isSensitiveField(el))
|
|
359
|
+
if (isSensitiveField(el)) {
|
|
301
360
|
return '' === el.value ? '' : REDACTED_VALUE;
|
|
361
|
+
}
|
|
302
362
|
return el.value;
|
|
303
363
|
}
|
|
304
364
|
const valueNow = el.getAttribute('aria-valuenow');
|
|
@@ -306,62 +366,79 @@ export function getValue(el) {
|
|
|
306
366
|
}
|
|
307
367
|
function hiddenInsideClosedDetails(el) {
|
|
308
368
|
const parent = el.parentElement;
|
|
309
|
-
if (null === parent)
|
|
369
|
+
if (null === parent) {
|
|
310
370
|
return false;
|
|
371
|
+
}
|
|
311
372
|
const details = parent.closest(HTML_DETAILS_TAG);
|
|
312
|
-
if (null === details || details.hasAttribute(HTML_DETAILS_OPEN_ATTRIBUTE))
|
|
373
|
+
if (null === details || details.hasAttribute(HTML_DETAILS_OPEN_ATTRIBUTE)) {
|
|
313
374
|
return false;
|
|
375
|
+
}
|
|
314
376
|
const summary = Array.from(details.children).find((child) => HTML_SUMMARY_TAG === child.localName);
|
|
315
377
|
return summary === undefined || !summary.contains(el);
|
|
316
378
|
}
|
|
317
379
|
function stalledFade(el) {
|
|
318
|
-
if (!el.ownerDocument.hidden || !('getAnimations' in el))
|
|
380
|
+
if (!el.ownerDocument.hidden || !('getAnimations' in el)) {
|
|
319
381
|
return false;
|
|
382
|
+
}
|
|
320
383
|
return el.getAnimations().some((a) => 'running' === a.playState || a.pending);
|
|
321
384
|
}
|
|
322
385
|
const OVERLAY_ARIA_HIDDEN = 'data-aria-hidden';
|
|
323
386
|
function hiddenByAnOverlay(el) {
|
|
324
387
|
return el.hasAttribute(OVERLAY_ARIA_HIDDEN);
|
|
325
388
|
}
|
|
326
|
-
function
|
|
327
|
-
if (
|
|
328
|
-
return true;
|
|
329
|
-
if (isHtmlElement(el) && el.hidden)
|
|
389
|
+
function selfCssHidden(el, style) {
|
|
390
|
+
if (isHtmlElement(el) && el.hidden) {
|
|
330
391
|
return true;
|
|
331
|
-
|
|
392
|
+
}
|
|
393
|
+
if (hiddenInsideClosedDetails(el)) {
|
|
332
394
|
return true;
|
|
395
|
+
}
|
|
333
396
|
if (style !== null) {
|
|
334
397
|
if ('none' === style.display ||
|
|
335
398
|
'hidden' === style.visibility ||
|
|
336
399
|
'collapse' === style.visibility) {
|
|
337
400
|
return true;
|
|
338
401
|
}
|
|
339
|
-
if (0 === Number.parseFloat(style.opacity || '1') && !stalledFade(el))
|
|
402
|
+
if (0 === Number.parseFloat(style.opacity || '1') && !stalledFade(el)) {
|
|
340
403
|
return true;
|
|
404
|
+
}
|
|
341
405
|
}
|
|
342
406
|
return false;
|
|
343
407
|
}
|
|
344
|
-
function
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
return null;
|
|
348
|
-
const root = capturedRootOf(host);
|
|
349
|
-
if (null === root)
|
|
350
|
-
return null;
|
|
351
|
-
for (const slot of Array.from(root.querySelectorAll('slot'))) {
|
|
352
|
-
if (slot.assignedElements().includes(el))
|
|
353
|
-
return slot;
|
|
408
|
+
function selfHidden(el, style) {
|
|
409
|
+
if ('true' === el.getAttribute('aria-hidden') && !hiddenByAnOverlay(el)) {
|
|
410
|
+
return true;
|
|
354
411
|
}
|
|
355
|
-
return
|
|
412
|
+
return selfCssHidden(el, style);
|
|
356
413
|
}
|
|
357
|
-
function
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
414
|
+
export function isHiddenByAriaOnly(el) {
|
|
415
|
+
let foundAriaHidden = false;
|
|
416
|
+
let current = el;
|
|
417
|
+
while (null !== current) {
|
|
418
|
+
if ('true' === current.getAttribute('aria-hidden')) {
|
|
419
|
+
foundAriaHidden = true;
|
|
420
|
+
}
|
|
421
|
+
const style = current.ownerDocument.defaultView?.getComputedStyle(current) ?? null;
|
|
422
|
+
if (selfCssHidden(current, style)) {
|
|
423
|
+
return false;
|
|
424
|
+
}
|
|
425
|
+
current = parentAcrossShadowBoundary(current);
|
|
426
|
+
}
|
|
427
|
+
return foundAriaHidden;
|
|
428
|
+
}
|
|
429
|
+
export function isRenderedOutsideAriaHidden(el) {
|
|
430
|
+
let current = el;
|
|
431
|
+
while (null !== current) {
|
|
432
|
+
if ('true' === current.getAttribute('aria-hidden')) {
|
|
433
|
+
return false;
|
|
434
|
+
}
|
|
435
|
+
const style = current.ownerDocument.defaultView?.getComputedStyle(current) ?? null;
|
|
436
|
+
if (selfCssHidden(current, style)) {
|
|
437
|
+
return false;
|
|
438
|
+
}
|
|
439
|
+
current = parentAcrossShadowBoundary(current);
|
|
440
|
+
}
|
|
441
|
+
return true;
|
|
365
442
|
}
|
|
366
443
|
const CLIPPING_OVERFLOW = new Set(['hidden', 'clip']);
|
|
367
444
|
const SCROLLING_OVERFLOW = new Set(['auto', 'scroll']);
|
|
@@ -401,8 +478,9 @@ const REPLACED_INLINE_TAGS = new Set([
|
|
|
401
478
|
]);
|
|
402
479
|
const visibilityInfoMemos = new WeakMap();
|
|
403
480
|
function visibilityInfoMemo(memo) {
|
|
404
|
-
if (memo === undefined)
|
|
481
|
+
if (memo === undefined) {
|
|
405
482
|
return new Map();
|
|
483
|
+
}
|
|
406
484
|
let info = visibilityInfoMemos.get(memo);
|
|
407
485
|
if (info === undefined) {
|
|
408
486
|
info = new Map();
|
|
@@ -454,21 +532,15 @@ function ownVisibilityInfo(el, memo) {
|
|
|
454
532
|
}
|
|
455
533
|
return info;
|
|
456
534
|
}
|
|
457
|
-
function overflowAxes(style) {
|
|
458
|
-
const shorthand = style?.overflow ?? '';
|
|
459
|
-
const [x = 'visible', y = x] = ('' === shorthand ? 'visible' : shorthand).split(/\s+/);
|
|
460
|
-
return [
|
|
461
|
-
null === style || '' === style.overflowX ? x : style.overflowX,
|
|
462
|
-
null === style || '' === style.overflowY ? y : style.overflowY,
|
|
463
|
-
];
|
|
464
|
-
}
|
|
465
535
|
function positionedContainingBlock(el, fixed, memo) {
|
|
466
536
|
for (let parent = ownVisibilityInfo(el, memo).parent; parent !== null; parent = ownVisibilityInfo(parent, memo).parent) {
|
|
467
537
|
const style = ownVisibilityInfo(parent, memo).style;
|
|
468
|
-
if (null === style || 'contents' === style.display)
|
|
538
|
+
if (null === style || 'contents' === style.display) {
|
|
469
539
|
continue;
|
|
470
|
-
|
|
540
|
+
}
|
|
541
|
+
if (!fixed && '' !== style.position && 'static' !== style.position) {
|
|
471
542
|
return parent;
|
|
543
|
+
}
|
|
472
544
|
const transformable = !('inline' === style.display &&
|
|
473
545
|
isHtmlElement(parent) &&
|
|
474
546
|
!REPLACED_INLINE_TAGS.has(parent.localName)) &&
|
|
@@ -485,92 +557,30 @@ function positionedContainingBlock(el, fixed, memo) {
|
|
|
485
557
|
(transformable &&
|
|
486
558
|
!NON_CLIPPING_DISPLAY.has(style.display) &&
|
|
487
559
|
(style.contain.split(/\s+/).some((value) => CONTAINING_BLOCK_CONTAIN.has(value)) ||
|
|
488
|
-
'auto' === style.contentVisibility)))
|
|
560
|
+
'auto' === style.contentVisibility))) {
|
|
489
561
|
return parent;
|
|
562
|
+
}
|
|
490
563
|
}
|
|
491
564
|
return null;
|
|
492
565
|
}
|
|
493
|
-
function clippingBox(el, info) {
|
|
494
|
-
if (info.clipBox !== undefined)
|
|
495
|
-
return info.clipBox;
|
|
496
|
-
const rect = el.getBoundingClientRect();
|
|
497
|
-
const style = info.style;
|
|
498
|
-
const px = (value) => Number.parseFloat(value ?? '') || 0;
|
|
499
|
-
const border = (value, kind) => kind === undefined || '' === kind || 'none' === kind || 'hidden' === kind ? 0 : px(value);
|
|
500
|
-
const scaleX = isHtmlElement(el) && el.offsetWidth > 0 ? rect.width / el.offsetWidth : 1;
|
|
501
|
-
const scaleY = isHtmlElement(el) && el.offsetHeight > 0 ? rect.height / el.offsetHeight : 1;
|
|
502
|
-
const left = isHtmlElement(el) && el.offsetWidth > 0
|
|
503
|
-
? rect.left + el.clientLeft * scaleX
|
|
504
|
-
: rect.left + border(style?.borderLeftWidth, style?.borderLeftStyle);
|
|
505
|
-
const top = isHtmlElement(el) && el.offsetHeight > 0
|
|
506
|
-
? rect.top + el.clientTop * scaleY
|
|
507
|
-
: rect.top + border(style?.borderTopWidth, style?.borderTopStyle);
|
|
508
|
-
const right = isHtmlElement(el) && el.offsetWidth > 0
|
|
509
|
-
? left + el.clientWidth * scaleX
|
|
510
|
-
: rect.right - border(style?.borderRightWidth, style?.borderRightStyle);
|
|
511
|
-
const bottom = isHtmlElement(el) && el.offsetHeight > 0
|
|
512
|
-
? top + el.clientHeight * scaleY
|
|
513
|
-
: rect.bottom - border(style?.borderBottomWidth, style?.borderBottomStyle);
|
|
514
|
-
const margin = (style?.overflowClipMargin ?? '').split(/\s+/);
|
|
515
|
-
const outset = px(margin.at(-1));
|
|
516
|
-
const borderBox = margin.includes('border-box');
|
|
517
|
-
const contentBox = margin.includes('content-box');
|
|
518
|
-
const [x, y] = overflowAxes(style);
|
|
519
|
-
const clipLeft = 'clip' === x
|
|
520
|
-
? (borderBox ? rect.left : left + (contentBox ? px(style?.paddingLeft) * scaleX : 0)) -
|
|
521
|
-
outset * scaleX
|
|
522
|
-
: left;
|
|
523
|
-
const clipRight = 'clip' === x
|
|
524
|
-
? (borderBox ? rect.right : right - (contentBox ? px(style?.paddingRight) * scaleX : 0)) +
|
|
525
|
-
outset * scaleX
|
|
526
|
-
: right;
|
|
527
|
-
const clipTop = 'clip' === y
|
|
528
|
-
? (borderBox ? rect.top : top + (contentBox ? px(style?.paddingTop) * scaleY : 0)) -
|
|
529
|
-
outset * scaleY
|
|
530
|
-
: top;
|
|
531
|
-
const clipBottom = 'clip' === y
|
|
532
|
-
? (borderBox ? rect.bottom : bottom - (contentBox ? px(style?.paddingBottom) * scaleY : 0)) +
|
|
533
|
-
outset * scaleY
|
|
534
|
-
: bottom;
|
|
535
|
-
info.clipBox = {
|
|
536
|
-
left: clipLeft,
|
|
537
|
-
right: clipRight,
|
|
538
|
-
top: clipTop,
|
|
539
|
-
bottom: clipBottom,
|
|
540
|
-
width: clipRight - clipLeft,
|
|
541
|
-
height: clipBottom - clipTop,
|
|
542
|
-
};
|
|
543
|
-
return info.clipBox;
|
|
544
|
-
}
|
|
545
|
-
function scrolledInto(b, port, alongX, alongY) {
|
|
546
|
-
const axis = (lo, hi, size, from, to) => {
|
|
547
|
-
if (hi > from && lo < to)
|
|
548
|
-
return [lo, hi];
|
|
549
|
-
const span = Math.min(size, to - from);
|
|
550
|
-
return lo >= to ? [to - span, to] : [from, from + span];
|
|
551
|
-
};
|
|
552
|
-
const [left, right] = alongX
|
|
553
|
-
? axis(b.left, b.right, b.width, port.left, port.right)
|
|
554
|
-
: [b.left, b.right];
|
|
555
|
-
const [top, bottom] = alongY
|
|
556
|
-
? axis(b.top, b.bottom, b.height, port.top, port.bottom)
|
|
557
|
-
: [b.top, b.bottom];
|
|
558
|
-
return { left, right, top, bottom, width: right - left, height: bottom - top };
|
|
559
|
-
}
|
|
560
566
|
function visibleBounds(el, memo, initial, throughScrollers = false) {
|
|
561
567
|
let bounds = initial;
|
|
562
568
|
const target = ownVisibilityInfo(el, memo);
|
|
563
|
-
if (target.hidden)
|
|
569
|
+
if (target.hidden) {
|
|
564
570
|
return null;
|
|
565
|
-
|
|
571
|
+
}
|
|
572
|
+
if (null === target.parent || !ownVisibilityInfo(target.parent, memo).hasClipping) {
|
|
566
573
|
return bounds;
|
|
574
|
+
}
|
|
567
575
|
let clipFrom;
|
|
568
576
|
for (let current = el; current !== null; current = ownVisibilityInfo(current, memo).parent) {
|
|
569
577
|
const info = ownVisibilityInfo(current, memo);
|
|
570
|
-
if (info.hidden)
|
|
578
|
+
if (info.hidden) {
|
|
571
579
|
return null;
|
|
572
|
-
|
|
580
|
+
}
|
|
581
|
+
if (current === clipFrom) {
|
|
573
582
|
clipFrom = undefined;
|
|
583
|
+
}
|
|
574
584
|
const style = info.style;
|
|
575
585
|
if (throughScrollers &&
|
|
576
586
|
current !== el &&
|
|
@@ -589,8 +599,9 @@ function visibleBounds(el, memo, initial, throughScrollers = false) {
|
|
|
589
599
|
const right = info.clipX ? Math.min(bounds.right, clip.right) : bounds.right;
|
|
590
600
|
const top = info.clipY ? Math.max(bounds.top, clip.top) : bounds.top;
|
|
591
601
|
const bottom = info.clipY ? Math.min(bounds.bottom, clip.bottom) : bounds.bottom;
|
|
592
|
-
if (right <= left || bottom <= top)
|
|
602
|
+
if (right <= left || bottom <= top) {
|
|
593
603
|
return null;
|
|
604
|
+
}
|
|
594
605
|
bounds = { left, right, top, bottom, width: right - left, height: bottom - top };
|
|
595
606
|
}
|
|
596
607
|
}
|
|
@@ -601,27 +612,44 @@ function visibleBounds(el, memo, initial, throughScrollers = false) {
|
|
|
601
612
|
return bounds;
|
|
602
613
|
}
|
|
603
614
|
export function isInViewport(el, memo) {
|
|
604
|
-
if (!isVisible(el, memo))
|
|
615
|
+
if (!isVisible(el, memo)) {
|
|
605
616
|
return false;
|
|
617
|
+
}
|
|
606
618
|
const view = el.ownerDocument.defaultView;
|
|
607
|
-
if (null === view)
|
|
619
|
+
if (null === view) {
|
|
608
620
|
return false;
|
|
621
|
+
}
|
|
609
622
|
const r = visibleBounds(el, visibilityInfoMemo(memo), el.getBoundingClientRect());
|
|
610
|
-
if (null === r || undefined === r)
|
|
623
|
+
if (null === r || undefined === r) {
|
|
611
624
|
return false;
|
|
612
|
-
|
|
625
|
+
}
|
|
626
|
+
if (r.width <= 0 || r.height <= 0) {
|
|
613
627
|
return false;
|
|
628
|
+
}
|
|
614
629
|
return r.bottom > 0 && r.right > 0 && r.top < view.innerHeight && r.left < view.innerWidth;
|
|
615
630
|
}
|
|
631
|
+
function collapsed(el, memo) {
|
|
632
|
+
const own = ownVisibilityInfo(el, memo);
|
|
633
|
+
if (!own.clipX && !own.clipY) {
|
|
634
|
+
return false;
|
|
635
|
+
}
|
|
636
|
+
const rects = Array.from(el.getClientRects());
|
|
637
|
+
return (rects.length > 0 &&
|
|
638
|
+
rects.every((r) => (own.clipX && 0 === r.width) || (own.clipY && 0 === r.height)));
|
|
639
|
+
}
|
|
616
640
|
export function isVisible(el, memo) {
|
|
617
|
-
if (!el.isConnected)
|
|
641
|
+
if (!el.isConnected) {
|
|
618
642
|
return false;
|
|
643
|
+
}
|
|
619
644
|
const cached = memo?.get(el);
|
|
620
|
-
if (cached !== undefined)
|
|
645
|
+
if (cached !== undefined) {
|
|
621
646
|
return cached;
|
|
622
|
-
|
|
623
|
-
|
|
647
|
+
}
|
|
648
|
+
const info = visibilityInfoMemo(memo);
|
|
649
|
+
const result = visibleBounds(el, info, undefined, true) !== null && !collapsed(el, info);
|
|
650
|
+
if (memo !== undefined) {
|
|
624
651
|
memo.set(el, result);
|
|
652
|
+
}
|
|
625
653
|
return result;
|
|
626
654
|
}
|
|
627
655
|
const MAX_TEXT = 80;
|
|
@@ -641,17 +669,21 @@ export function describe(el, memo) {
|
|
|
641
669
|
states: getStates(el, visible),
|
|
642
670
|
visible,
|
|
643
671
|
};
|
|
644
|
-
if (value !== undefined && value.length > 0)
|
|
672
|
+
if (value !== undefined && value.length > 0) {
|
|
645
673
|
base.value = value;
|
|
646
|
-
|
|
674
|
+
}
|
|
675
|
+
if (text.length > 0 && text !== name) {
|
|
647
676
|
base.text = text;
|
|
677
|
+
}
|
|
648
678
|
const source = formatSource(sourceFromDom(el));
|
|
649
|
-
if (source !== undefined)
|
|
679
|
+
if (source !== undefined) {
|
|
650
680
|
base.source = source;
|
|
681
|
+
}
|
|
651
682
|
if (el.querySelector('path, polyline, polygon') !== null) {
|
|
652
683
|
const faults = inspectChart(el).findings;
|
|
653
|
-
if (faults.length > 0)
|
|
684
|
+
if (faults.length > 0) {
|
|
654
685
|
base.chart = faults;
|
|
686
|
+
}
|
|
655
687
|
}
|
|
656
688
|
return base;
|
|
657
689
|
}
|
package/dist/dom/chart.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export interface CanvasChartData {
|
|
|
17
17
|
library: 'chartjs' | 'echarts';
|
|
18
18
|
data: unknown;
|
|
19
19
|
}
|
|
20
|
-
export
|
|
20
|
+
export interface ChartGlobals {
|
|
21
21
|
Chart?: {
|
|
22
22
|
getChart?: (el: Element) => {
|
|
23
23
|
data?: unknown;
|
|
@@ -28,4 +28,5 @@ export declare function canvasChartData(canvas: Element, globals: {
|
|
|
28
28
|
getOption?: () => unknown;
|
|
29
29
|
} | undefined;
|
|
30
30
|
};
|
|
31
|
-
}
|
|
31
|
+
}
|
|
32
|
+
export declare function canvasChartData(canvas: Element, globals: ChartGlobals | Window): CanvasChartData | null;
|
package/dist/dom/chart.js
CHANGED
|
@@ -46,11 +46,12 @@ export function inspectChart(root) {
|
|
|
46
46
|
return { examined, findings, canvas };
|
|
47
47
|
}
|
|
48
48
|
export function canvasChartData(canvas, globals) {
|
|
49
|
-
const
|
|
49
|
+
const libs = globals;
|
|
50
|
+
const chartjs = libs.Chart?.getChart?.(canvas);
|
|
50
51
|
if (chartjs !== undefined && chartjs !== null) {
|
|
51
52
|
return { library: 'chartjs', data: chartjs.data ?? null };
|
|
52
53
|
}
|
|
53
|
-
const echart =
|
|
54
|
+
const echart = libs.echarts?.getInstanceByDom?.(canvas);
|
|
54
55
|
if (echart !== undefined && echart !== null) {
|
|
55
56
|
return { library: 'echarts', data: echart.getOption?.() ?? null };
|
|
56
57
|
}
|
package/dist/dom/dom-ignore.d.ts
CHANGED
|
@@ -7,4 +7,10 @@ export declare function isReticleOverlay(el: Element): boolean;
|
|
|
7
7
|
export declare function isUnobserved(el: Element): boolean;
|
|
8
8
|
export declare function isReticleUi(node: Element | null): boolean;
|
|
9
9
|
export declare function isIgnored(el: Element): boolean;
|
|
10
|
+
export declare function isWordsIgnored(el: Element): boolean;
|
|
11
|
+
export declare const FrameworkErrorDialog: {
|
|
12
|
+
readonly NEXT: "Next.js error dialog";
|
|
13
|
+
readonly VITE: "Vite error overlay";
|
|
14
|
+
};
|
|
15
|
+
export declare function dialogCovering(matches: readonly Element[]): string | undefined;
|
|
10
16
|
export declare function appModalOpen(doc: Document): boolean;
|