@reticlehq/browser 3.6.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 +64 -0
- package/dist/actions/action-report.js +87 -0
- package/dist/actions/actions-dom.d.ts +5 -0
- package/dist/actions/actions-dom.js +32 -4
- package/dist/actions/actions-press.d.ts +1 -0
- package/dist/actions/actions-press.js +25 -1
- package/dist/actions/actions.d.ts +2 -37
- package/dist/actions/actions.js +56 -80
- package/dist/actions/appeared-text.js +5 -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 +4 -1
- package/dist/actions/danger-context.js +45 -4
- package/dist/actions/value-input.d.ts +1 -0
- package/dist/actions/value-input.js +11 -0
- 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 +49 -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 +353 -80
- package/dist/dom/addressing/coverage-markers.d.ts +6 -0
- package/dist/dom/addressing/coverage-markers.js +13 -0
- package/dist/dom/chart.d.ts +3 -2
- package/dist/dom/chart.js +3 -2
- package/dist/dom/dom-ignore.d.ts +8 -0
- package/dist/dom/dom-ignore.js +57 -2
- 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 +163 -38
- package/dist/dom/render-page.d.ts +12 -0
- package/dist/dom/render-page.js +135 -0
- 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 +135 -36
- 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 +96 -32
- package/dist/observers/field.d.ts +11 -0
- package/dist/observers/field.js +116 -30
- 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 +82 -13
- package/dist/observers/perf.js +53 -1
- package/dist/observers/route.d.ts +2 -0
- package/dist/observers/route.js +39 -9
- package/dist/presenter/carousel/carousel.js +2 -7
- package/dist/presenter/carousel/panel-slides.d.ts +2 -4
- package/dist/presenter/carousel/panel-slides.js +17 -15
- package/dist/presenter/chrome/log-memory.d.ts +1 -0
- package/dist/presenter/chrome/presenter-log.d.ts +7 -0
- package/dist/presenter/chrome/presenter-log.js +48 -8
- package/dist/presenter/chrome/presenter-morph.d.ts +1 -0
- package/dist/presenter/chrome/presenter-morph.js +34 -0
- package/dist/presenter/chrome/presenter-report-copy.d.ts +12 -4
- package/dist/presenter/chrome/presenter-report-copy.js +12 -4
- package/dist/presenter/hud-telemetry.js +55 -4
- package/dist/presenter/presenter-account-styles.js +3 -3
- package/dist/presenter/presenter-account.d.ts +27 -5
- package/dist/presenter/presenter-account.js +83 -6
- package/dist/presenter/presenter-agent-link.d.ts +9 -0
- package/dist/presenter/presenter-agent-link.js +62 -0
- package/dist/presenter/presenter-chat-views.d.ts +25 -4
- package/dist/presenter/presenter-chat-views.js +339 -72
- package/dist/presenter/presenter-config.d.ts +3 -0
- package/dist/presenter/presenter-config.js +2 -0
- package/dist/presenter/presenter-controls.d.ts +0 -1
- package/dist/presenter/presenter-controls.js +13 -91
- package/dist/presenter/presenter-design-tokens.js +1 -1
- package/dist/presenter/presenter-frame.d.ts +3 -2
- package/dist/presenter/presenter-frame.js +31 -24
- package/dist/presenter/presenter-harness-row.d.ts +56 -0
- package/dist/presenter/presenter-harness-row.js +170 -0
- package/dist/presenter/presenter-personas.d.ts +35 -0
- package/dist/presenter/presenter-personas.js +95 -0
- package/dist/presenter/presenter-plan.js +25 -24
- package/dist/presenter/presenter-report-styles.js +23 -22
- package/dist/presenter/presenter-report.js +29 -13
- package/dist/presenter/presenter-run-state.js +2 -1
- package/dist/presenter/presenter-settings-styles.js +8 -4
- package/dist/presenter/presenter-settings.d.ts +4 -4
- package/dist/presenter/presenter-settings.js +66 -28
- package/dist/presenter/presenter-shell-styles.js +12 -3
- package/dist/presenter/presenter-shell.d.ts +11 -3
- package/dist/presenter/presenter-shell.js +60 -22
- package/dist/presenter/presenter-styles.js +0 -2
- package/dist/presenter/presenter-workspace.js +10 -3
- package/dist/presenter/presenter.d.ts +3 -2
- package/dist/presenter/presenter.js +107 -25
- package/dist/registry/declared-platform.js +2 -0
- package/dist/registry/store-adapters.d.ts +5 -2
- package/dist/registry/store-adapters.js +40 -10
- package/dist/reticle-inject.js +771 -703
- package/dist/reticle.d.ts +4 -2
- package/dist/reticle.js +72 -8
- 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 +4 -2
- package/dist/storage-keys.js +8 -3
- 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 +23 -3
- package/dist/transport/unreachable-message.d.ts +1 -1
- package/dist/transport/unreachable-message.js +3 -5
- package/package.json +6 -2
- package/dist/presenter/carousel/offer-card.d.ts +0 -21
- package/dist/presenter/carousel/offer-card.js +0 -56
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) {
|
|
229
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) {
|
|
269
|
+
return text;
|
|
270
|
+
}
|
|
230
271
|
}
|
|
231
272
|
}
|
|
232
273
|
if (isInput(el) || isTextArea(el) || isSelect(el)) {
|
|
@@ -234,49 +275,68 @@ 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
|
+
}
|
|
339
|
+
const SENSITIVE_AUTOCOMPLETE = /\b(cc-|current-password|new-password|one-time-code)/i;
|
|
280
340
|
export function isSensitiveField(el) {
|
|
281
341
|
if (!isInput(el) && !isTextArea(el) && !isSelect(el)) {
|
|
282
342
|
return false;
|
|
@@ -289,15 +349,16 @@ export function isSensitiveField(el) {
|
|
|
289
349
|
el.getAttribute(DEFAULT_TESTID_ATTR) ?? '',
|
|
290
350
|
el.getAttribute('aria-label') ?? '',
|
|
291
351
|
];
|
|
292
|
-
const sensitiveAutocomplete =
|
|
352
|
+
const sensitiveAutocomplete = SENSITIVE_AUTOCOMPLETE.test(autocomplete);
|
|
293
353
|
return ((isInput(el) && 'password' === el.type.toLowerCase()) ||
|
|
294
354
|
sensitiveAutocomplete ||
|
|
295
355
|
identifiers.some(isSensitiveKey));
|
|
296
356
|
}
|
|
297
357
|
export function getValue(el) {
|
|
298
358
|
if (isInput(el) || isTextArea(el) || isSelect(el)) {
|
|
299
|
-
if (isSensitiveField(el))
|
|
300
|
-
return REDACTED_VALUE;
|
|
359
|
+
if (isSensitiveField(el)) {
|
|
360
|
+
return '' === el.value ? '' : REDACTED_VALUE;
|
|
361
|
+
}
|
|
301
362
|
return el.value;
|
|
302
363
|
}
|
|
303
364
|
const valueNow = el.getAttribute('aria-valuenow');
|
|
@@ -305,82 +366,290 @@ export function getValue(el) {
|
|
|
305
366
|
}
|
|
306
367
|
function hiddenInsideClosedDetails(el) {
|
|
307
368
|
const parent = el.parentElement;
|
|
308
|
-
if (null === parent)
|
|
369
|
+
if (null === parent) {
|
|
309
370
|
return false;
|
|
371
|
+
}
|
|
310
372
|
const details = parent.closest(HTML_DETAILS_TAG);
|
|
311
|
-
if (null === details || details.hasAttribute(HTML_DETAILS_OPEN_ATTRIBUTE))
|
|
373
|
+
if (null === details || details.hasAttribute(HTML_DETAILS_OPEN_ATTRIBUTE)) {
|
|
312
374
|
return false;
|
|
375
|
+
}
|
|
313
376
|
const summary = Array.from(details.children).find((child) => HTML_SUMMARY_TAG === child.localName);
|
|
314
377
|
return summary === undefined || !summary.contains(el);
|
|
315
378
|
}
|
|
316
379
|
function stalledFade(el) {
|
|
317
|
-
if (!el.ownerDocument.hidden || !('getAnimations' in el))
|
|
380
|
+
if (!el.ownerDocument.hidden || !('getAnimations' in el)) {
|
|
318
381
|
return false;
|
|
382
|
+
}
|
|
319
383
|
return el.getAnimations().some((a) => 'running' === a.playState || a.pending);
|
|
320
384
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
385
|
+
const OVERLAY_ARIA_HIDDEN = 'data-aria-hidden';
|
|
386
|
+
function hiddenByAnOverlay(el) {
|
|
387
|
+
return el.hasAttribute(OVERLAY_ARIA_HIDDEN);
|
|
388
|
+
}
|
|
389
|
+
function selfCssHidden(el, style) {
|
|
390
|
+
if (isHtmlElement(el) && el.hidden) {
|
|
325
391
|
return true;
|
|
326
|
-
|
|
392
|
+
}
|
|
393
|
+
if (hiddenInsideClosedDetails(el)) {
|
|
327
394
|
return true;
|
|
328
|
-
|
|
329
|
-
if (
|
|
330
|
-
const style = view.getComputedStyle(el);
|
|
395
|
+
}
|
|
396
|
+
if (style !== null) {
|
|
331
397
|
if ('none' === style.display ||
|
|
332
398
|
'hidden' === style.visibility ||
|
|
333
399
|
'collapse' === style.visibility) {
|
|
334
400
|
return true;
|
|
335
401
|
}
|
|
336
|
-
if (0 === Number.parseFloat(style.opacity || '1') && !stalledFade(el))
|
|
402
|
+
if (0 === Number.parseFloat(style.opacity || '1') && !stalledFade(el)) {
|
|
337
403
|
return true;
|
|
404
|
+
}
|
|
338
405
|
}
|
|
339
406
|
return false;
|
|
340
407
|
}
|
|
341
|
-
function
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
408
|
+
function selfHidden(el, style) {
|
|
409
|
+
if ('true' === el.getAttribute('aria-hidden') && !hiddenByAnOverlay(el)) {
|
|
410
|
+
return true;
|
|
411
|
+
}
|
|
412
|
+
return selfCssHidden(el, style);
|
|
413
|
+
}
|
|
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;
|
|
442
|
+
}
|
|
443
|
+
const CLIPPING_OVERFLOW = new Set(['hidden', 'clip']);
|
|
444
|
+
const SCROLLING_OVERFLOW = new Set(['auto', 'scroll']);
|
|
445
|
+
const NON_CLIPPING_DISPLAY = new Set([
|
|
446
|
+
'contents',
|
|
447
|
+
'table-row',
|
|
448
|
+
'table-row-group',
|
|
449
|
+
'table-header-group',
|
|
450
|
+
'table-footer-group',
|
|
451
|
+
'table-column',
|
|
452
|
+
'table-column-group',
|
|
453
|
+
]);
|
|
454
|
+
const TRANSFORM_CONTAINING_BLOCK_PROPERTIES = new Set([
|
|
455
|
+
'transform',
|
|
456
|
+
'translate',
|
|
457
|
+
'rotate',
|
|
458
|
+
'scale',
|
|
459
|
+
'perspective',
|
|
460
|
+
]);
|
|
461
|
+
const CONTAINING_BLOCK_PROPERTIES = new Set([
|
|
462
|
+
...TRANSFORM_CONTAINING_BLOCK_PROPERTIES,
|
|
463
|
+
'filter',
|
|
464
|
+
'backdrop-filter',
|
|
465
|
+
]);
|
|
466
|
+
const CONTAINING_BLOCK_CONTAIN = new Set(['layout', 'paint', 'strict', 'content']);
|
|
467
|
+
const REPLACED_INLINE_TAGS = new Set([
|
|
468
|
+
'img',
|
|
469
|
+
'video',
|
|
470
|
+
'audio',
|
|
471
|
+
'canvas',
|
|
472
|
+
'iframe',
|
|
473
|
+
'embed',
|
|
474
|
+
'object',
|
|
475
|
+
'input',
|
|
476
|
+
'textarea',
|
|
477
|
+
'select',
|
|
478
|
+
]);
|
|
479
|
+
const visibilityInfoMemos = new WeakMap();
|
|
480
|
+
function visibilityInfoMemo(memo) {
|
|
481
|
+
if (memo === undefined) {
|
|
482
|
+
return new Map();
|
|
483
|
+
}
|
|
484
|
+
let info = visibilityInfoMemos.get(memo);
|
|
485
|
+
if (info === undefined) {
|
|
486
|
+
info = new Map();
|
|
487
|
+
visibilityInfoMemos.set(memo, info);
|
|
488
|
+
}
|
|
489
|
+
return info;
|
|
490
|
+
}
|
|
491
|
+
function ownVisibilityInfo(el, memo) {
|
|
492
|
+
let info = memo.get(el);
|
|
493
|
+
if (info === undefined) {
|
|
494
|
+
const style = el.ownerDocument.defaultView?.getComputedStyle(el) ?? null;
|
|
495
|
+
if (selfHidden(el, style)) {
|
|
496
|
+
info = {
|
|
497
|
+
hidden: true,
|
|
498
|
+
style,
|
|
499
|
+
parent: null,
|
|
500
|
+
clipX: false,
|
|
501
|
+
clipY: false,
|
|
502
|
+
scrollX: false,
|
|
503
|
+
scrollY: false,
|
|
504
|
+
hasClipping: false,
|
|
505
|
+
};
|
|
506
|
+
memo.set(el, info);
|
|
507
|
+
return info;
|
|
508
|
+
}
|
|
509
|
+
const parent = parentAcrossShadowBoundary(el);
|
|
510
|
+
const inherited = null === parent ? undefined : ownVisibilityInfo(parent, memo);
|
|
511
|
+
const [overflowX, overflowY] = overflowAxes(style);
|
|
512
|
+
const root = el.ownerDocument.documentElement;
|
|
513
|
+
const viewportOverflow = el === root ||
|
|
514
|
+
(el === el.ownerDocument.body &&
|
|
515
|
+
overflowAxes(ownVisibilityInfo(root, memo).style).every((axis) => 'visible' === axis));
|
|
516
|
+
const hasClipBox = !viewportOverflow &&
|
|
517
|
+
!NON_CLIPPING_DISPLAY.has(style?.display ?? '') &&
|
|
518
|
+
!(isHtmlElement(el) && 'inline' === style?.display);
|
|
519
|
+
const clipX = hasClipBox && CLIPPING_OVERFLOW.has(overflowX);
|
|
520
|
+
const clipY = hasClipBox && CLIPPING_OVERFLOW.has(overflowY);
|
|
521
|
+
info = {
|
|
522
|
+
hidden: true === inherited?.hidden,
|
|
523
|
+
style,
|
|
524
|
+
parent,
|
|
525
|
+
clipX,
|
|
526
|
+
clipY,
|
|
527
|
+
scrollX: hasClipBox && SCROLLING_OVERFLOW.has(overflowX),
|
|
528
|
+
scrollY: hasClipBox && SCROLLING_OVERFLOW.has(overflowY),
|
|
529
|
+
hasClipping: clipX || clipY || true === inherited?.hasClipping,
|
|
530
|
+
};
|
|
531
|
+
memo.set(el, info);
|
|
532
|
+
}
|
|
533
|
+
return info;
|
|
534
|
+
}
|
|
535
|
+
function positionedContainingBlock(el, fixed, memo) {
|
|
536
|
+
for (let parent = ownVisibilityInfo(el, memo).parent; parent !== null; parent = ownVisibilityInfo(parent, memo).parent) {
|
|
537
|
+
const style = ownVisibilityInfo(parent, memo).style;
|
|
538
|
+
if (null === style || 'contents' === style.display) {
|
|
539
|
+
continue;
|
|
540
|
+
}
|
|
541
|
+
if (!fixed && '' !== style.position && 'static' !== style.position) {
|
|
542
|
+
return parent;
|
|
543
|
+
}
|
|
544
|
+
const transformable = !('inline' === style.display &&
|
|
545
|
+
isHtmlElement(parent) &&
|
|
546
|
+
!REPLACED_INLINE_TAGS.has(parent.localName)) &&
|
|
547
|
+
'table-column' !== style.display &&
|
|
548
|
+
'table-column-group' !== style.display;
|
|
549
|
+
const applies = (property) => transformable || !TRANSFORM_CONTAINING_BLOCK_PROPERTIES.has(property);
|
|
550
|
+
if ([...CONTAINING_BLOCK_PROPERTIES].some((property) => {
|
|
551
|
+
const value = style.getPropertyValue(property);
|
|
552
|
+
return applies(property) && '' !== value && 'none' !== value;
|
|
553
|
+
}) ||
|
|
554
|
+
style.willChange
|
|
555
|
+
.split(',')
|
|
556
|
+
.some((property) => CONTAINING_BLOCK_PROPERTIES.has(property.trim()) && applies(property.trim())) ||
|
|
557
|
+
(transformable &&
|
|
558
|
+
!NON_CLIPPING_DISPLAY.has(style.display) &&
|
|
559
|
+
(style.contain.split(/\s+/).some((value) => CONTAINING_BLOCK_CONTAIN.has(value)) ||
|
|
560
|
+
'auto' === style.contentVisibility))) {
|
|
561
|
+
return parent;
|
|
562
|
+
}
|
|
351
563
|
}
|
|
352
564
|
return null;
|
|
353
565
|
}
|
|
354
|
-
function
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
566
|
+
function visibleBounds(el, memo, initial, throughScrollers = false) {
|
|
567
|
+
let bounds = initial;
|
|
568
|
+
const target = ownVisibilityInfo(el, memo);
|
|
569
|
+
if (target.hidden) {
|
|
570
|
+
return null;
|
|
571
|
+
}
|
|
572
|
+
if (null === target.parent || !ownVisibilityInfo(target.parent, memo).hasClipping) {
|
|
573
|
+
return bounds;
|
|
574
|
+
}
|
|
575
|
+
let clipFrom;
|
|
576
|
+
for (let current = el; current !== null; current = ownVisibilityInfo(current, memo).parent) {
|
|
577
|
+
const info = ownVisibilityInfo(current, memo);
|
|
578
|
+
if (info.hidden) {
|
|
579
|
+
return null;
|
|
580
|
+
}
|
|
581
|
+
if (current === clipFrom) {
|
|
582
|
+
clipFrom = undefined;
|
|
583
|
+
}
|
|
584
|
+
const style = info.style;
|
|
585
|
+
if (throughScrollers &&
|
|
586
|
+
current !== el &&
|
|
587
|
+
undefined === clipFrom &&
|
|
588
|
+
(info.scrollX || info.scrollY)) {
|
|
589
|
+
bounds ??= el.getBoundingClientRect();
|
|
590
|
+
if (bounds.width > 0 && bounds.height > 0) {
|
|
591
|
+
bounds = scrolledInto(bounds, clippingBox(current, info), info.scrollX, info.scrollY);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
if (current !== el && undefined === clipFrom && (info.clipX || info.clipY)) {
|
|
595
|
+
bounds ??= el.getBoundingClientRect();
|
|
596
|
+
if (bounds.width > 0 && bounds.height > 0) {
|
|
597
|
+
const clip = clippingBox(current, info);
|
|
598
|
+
const left = info.clipX ? Math.max(bounds.left, clip.left) : bounds.left;
|
|
599
|
+
const right = info.clipX ? Math.min(bounds.right, clip.right) : bounds.right;
|
|
600
|
+
const top = info.clipY ? Math.max(bounds.top, clip.top) : bounds.top;
|
|
601
|
+
const bottom = info.clipY ? Math.min(bounds.bottom, clip.bottom) : bounds.bottom;
|
|
602
|
+
if (right <= left || bottom <= top) {
|
|
603
|
+
return null;
|
|
604
|
+
}
|
|
605
|
+
bounds = { left, right, top, bottom, width: right - left, height: bottom - top };
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
if (clipFrom === undefined && ('absolute' === style?.position || 'fixed' === style?.position)) {
|
|
609
|
+
clipFrom = positionedContainingBlock(current, 'fixed' === style?.position, memo);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
return bounds;
|
|
362
613
|
}
|
|
363
614
|
export function isInViewport(el, memo) {
|
|
364
|
-
if (!isVisible(el, memo))
|
|
615
|
+
if (!isVisible(el, memo)) {
|
|
365
616
|
return false;
|
|
617
|
+
}
|
|
366
618
|
const view = el.ownerDocument.defaultView;
|
|
367
|
-
if (null === view)
|
|
619
|
+
if (null === view) {
|
|
620
|
+
return false;
|
|
621
|
+
}
|
|
622
|
+
const r = visibleBounds(el, visibilityInfoMemo(memo), el.getBoundingClientRect());
|
|
623
|
+
if (null === r || undefined === r) {
|
|
368
624
|
return false;
|
|
369
|
-
|
|
370
|
-
if (r.width <= 0 || r.height <= 0)
|
|
625
|
+
}
|
|
626
|
+
if (r.width <= 0 || r.height <= 0) {
|
|
371
627
|
return false;
|
|
628
|
+
}
|
|
372
629
|
return r.bottom > 0 && r.right > 0 && r.top < view.innerHeight && r.left < view.innerWidth;
|
|
373
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
|
+
}
|
|
374
640
|
export function isVisible(el, memo) {
|
|
375
|
-
if (!el.isConnected)
|
|
641
|
+
if (!el.isConnected) {
|
|
376
642
|
return false;
|
|
643
|
+
}
|
|
377
644
|
const cached = memo?.get(el);
|
|
378
|
-
if (cached !== undefined)
|
|
645
|
+
if (cached !== undefined) {
|
|
379
646
|
return cached;
|
|
380
|
-
|
|
381
|
-
const
|
|
382
|
-
|
|
647
|
+
}
|
|
648
|
+
const info = visibilityInfoMemo(memo);
|
|
649
|
+
const result = visibleBounds(el, info, undefined, true) !== null && !collapsed(el, info);
|
|
650
|
+
if (memo !== undefined) {
|
|
383
651
|
memo.set(el, result);
|
|
652
|
+
}
|
|
384
653
|
return result;
|
|
385
654
|
}
|
|
386
655
|
const MAX_TEXT = 80;
|
|
@@ -400,17 +669,21 @@ export function describe(el, memo) {
|
|
|
400
669
|
states: getStates(el, visible),
|
|
401
670
|
visible,
|
|
402
671
|
};
|
|
403
|
-
if (value !== undefined && value.length > 0)
|
|
672
|
+
if (value !== undefined && value.length > 0) {
|
|
404
673
|
base.value = value;
|
|
405
|
-
|
|
674
|
+
}
|
|
675
|
+
if (text.length > 0 && text !== name) {
|
|
406
676
|
base.text = text;
|
|
677
|
+
}
|
|
407
678
|
const source = formatSource(sourceFromDom(el));
|
|
408
|
-
if (source !== undefined)
|
|
679
|
+
if (source !== undefined) {
|
|
409
680
|
base.source = source;
|
|
681
|
+
}
|
|
410
682
|
if (el.querySelector('path, polyline, polygon') !== null) {
|
|
411
683
|
const faults = inspectChart(el).findings;
|
|
412
|
-
if (faults.length > 0)
|
|
684
|
+
if (faults.length > 0) {
|
|
413
685
|
base.chart = faults;
|
|
686
|
+
}
|
|
414
687
|
}
|
|
415
688
|
return base;
|
|
416
689
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { CoverageMarker, SOURCE_MAPPING_CAPABILITY, DATA_RETICLE_SOURCE_ATTR, RETICLE_OVERLAY_SELECTOR, } from '@reticlehq/core';
|
|
2
|
+
import { testIdSelector } from './testid-attr.js';
|
|
3
|
+
const appCarries = (doc, selector) => Array.from(doc.querySelectorAll(selector)).some((el) => null === el.closest(RETICLE_OVERLAY_SELECTOR));
|
|
4
|
+
export function coverageMarkers(doc) {
|
|
5
|
+
return [
|
|
6
|
+
...(appCarries(doc, `[${DATA_RETICLE_SOURCE_ATTR}]`) ? [CoverageMarker.SOURCE] : []),
|
|
7
|
+
...(appCarries(doc, testIdSelector()) ? [CoverageMarker.TESTID] : []),
|
|
8
|
+
];
|
|
9
|
+
}
|
|
10
|
+
export function notApplicableFor(page) {
|
|
11
|
+
const couldStamp = page.buildPlugin || 0 < page.adapters.length || page.markers.includes(CoverageMarker.SOURCE);
|
|
12
|
+
return couldStamp ? [] : [SOURCE_MAPPING_CAPABILITY];
|
|
13
|
+
}
|
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;
|