browser-debugger-cli 0.8.0 → 0.10.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 +7 -1
- package/dist/cdp/schema.d.ts +4 -1
- package/dist/cdp/schema.js +48 -7
- package/dist/commands/cdp.js +3 -2
- package/dist/commands/cleanup.d.ts +11 -0
- package/dist/commands/cleanup.js +161 -57
- package/dist/commands/console.d.ts +20 -1
- package/dist/commands/console.js +57 -17
- package/dist/commands/details.js +3 -2
- package/dist/commands/dom/DomElementResolver.d.ts +10 -3
- package/dist/commands/dom/DomElementResolver.js +35 -17
- package/dist/commands/dom/a11y.d.ts +10 -0
- package/dist/commands/dom/a11y.js +29 -6
- package/dist/commands/dom/eval.d.ts +3 -1
- package/dist/commands/dom/eval.js +29 -4
- package/dist/commands/dom/form.js +16 -62
- package/dist/commands/dom/formInteraction.js +189 -119
- package/dist/commands/dom/formSummary.d.ts +49 -0
- package/dist/commands/dom/formSummary.js +180 -0
- package/dist/commands/dom/frames.d.ts +2 -1
- package/dist/commands/dom/frames.js +17 -2
- package/dist/commands/dom/get.d.ts +6 -5
- package/dist/commands/dom/get.js +92 -82
- package/dist/commands/dom/helpers/index.d.ts +1 -1
- package/dist/commands/dom/helpers/index.js +1 -1
- package/dist/commands/dom/helpers/keyAttributes.d.ts +20 -0
- package/dist/commands/dom/helpers/keyAttributes.js +54 -0
- package/dist/commands/dom/helpers/query.d.ts +44 -17
- package/dist/commands/dom/helpers/query.js +300 -106
- package/dist/commands/dom/helpers/runElementCommand.d.ts +10 -2
- package/dist/commands/dom/helpers/runElementCommand.js +98 -30
- package/dist/commands/dom/helpers/screenshot.d.ts +4 -1
- package/dist/commands/dom/helpers/screenshot.js +239 -51
- package/dist/commands/dom/index.d.ts +4 -1
- package/dist/commands/dom/index.js +22 -7
- package/dist/commands/dom/inspect.d.ts +15 -0
- package/dist/commands/dom/inspect.js +82 -0
- package/dist/commands/dom/layout.d.ts +14 -0
- package/dist/commands/dom/layout.js +54 -0
- package/dist/commands/dom/listeners.d.ts +5 -1
- package/dist/commands/dom/listeners.js +15 -5
- package/dist/commands/dom/query.js +2 -3
- package/dist/commands/dom/screenshot.d.ts +12 -2
- package/dist/commands/dom/screenshot.js +27 -3
- package/dist/commands/dom/semanticUtils.d.ts +16 -10
- package/dist/commands/dom/semanticUtils.js +53 -16
- package/dist/commands/dom/wait.d.ts +13 -0
- package/dist/commands/dom/wait.js +83 -0
- package/dist/commands/helpJson.js +2 -2
- package/dist/commands/network/list.js +17 -13
- package/dist/commands/optionBehaviors.js +154 -21
- package/dist/commands/page.d.ts +3 -2
- package/dist/commands/page.js +100 -5
- package/dist/commands/peek.js +4 -11
- package/dist/commands/sessions.d.ts +8 -0
- package/dist/commands/sessions.js +19 -0
- package/dist/commands/shared/CommandRunner.js +4 -4
- package/dist/commands/shared/commonOptions.d.ts +4 -0
- package/dist/commands/shared/commonOptions.js +9 -0
- package/dist/commands/shared/dataFetcher.js +2 -2
- package/dist/commands/shared/followMode.d.ts +21 -1
- package/dist/commands/shared/followMode.js +29 -2
- package/dist/commands/shared/handleValidationError.d.ts +2 -2
- package/dist/commands/shared/handleValidationError.js +12 -3
- package/dist/commands/shared/optionTypes.d.ts +61 -5
- package/dist/commands/shared/startHelpers.d.ts +66 -0
- package/dist/commands/shared/startHelpers.js +103 -13
- package/dist/commands/shared/validation.d.ts +14 -2
- package/dist/commands/shared/validation.js +20 -3
- package/dist/commands/start.d.ts +63 -0
- package/dist/commands/start.js +115 -15
- package/dist/commands/status.js +29 -7
- package/dist/commands/stop.js +7 -6
- package/dist/commands/tail.js +4 -11
- package/dist/commands/types.d.ts +2 -0
- package/dist/commands.js +2 -0
- package/dist/connection/chromeIdentity.d.ts +65 -0
- package/dist/connection/chromeIdentity.js +143 -0
- package/dist/connection/launcher/profilePreferences.d.ts +47 -0
- package/dist/connection/launcher/profilePreferences.js +151 -0
- package/dist/connection/launcher.d.ts +21 -2
- package/dist/connection/launcher.js +42 -16
- package/dist/connection/portReservation.d.ts +14 -4
- package/dist/connection/portReservation.js +21 -6
- package/dist/connection/startupExit.d.ts +8 -0
- package/dist/connection/startupExit.js +15 -6
- package/dist/constants.d.ts +6 -2
- package/dist/constants.js +9 -2
- package/dist/daemon/SessionController.js +23 -7
- package/dist/daemon/errors.d.ts +1 -1
- package/dist/daemon/errors.js +1 -1
- package/dist/daemon/launcher.d.ts +10 -2
- package/dist/daemon/launcher.js +8 -7
- package/dist/daemon/server/SocketServer.js +1 -2
- package/dist/daemon/session/Session.d.ts +20 -0
- package/dist/daemon/session/Session.js +80 -9
- package/dist/daemon/session/chromeConnection.d.ts +9 -0
- package/dist/daemon/session/chromeConnection.js +45 -8
- package/dist/daemon/session/commandRegistry.d.ts +14 -1
- package/dist/daemon/session/commandRegistry.js +113 -67
- package/dist/daemon/session/interactions.d.ts +48 -9
- package/dist/daemon/session/interactions.js +46 -9
- package/dist/daemon/session/triggeredRequests.d.ts +67 -0
- package/dist/daemon/session/triggeredRequests.js +157 -0
- package/dist/daemon/session/types.d.ts +5 -1
- package/dist/daemon.js +10630 -3601
- package/dist/errors/messages.d.ts +456 -24
- package/dist/errors/messages.js +862 -67
- package/dist/index.js +6915 -3401
- package/dist/ipc/client.d.ts +21 -1
- package/dist/ipc/client.js +35 -3
- package/dist/ipc/protocol/commands.d.ts +145 -5
- package/dist/ipc/protocol/commands.js +4 -0
- package/dist/ipc/protocol/domTypes.d.ts +291 -7
- package/dist/ipc/protocol/inspectTypes.d.ts +388 -0
- package/dist/ipc/protocol/inspectTypes.js +10 -0
- package/dist/ipc/session/lifecycle.d.ts +8 -1
- package/dist/ipc/session/queries.d.ts +5 -1
- package/dist/ipc/session/types.d.ts +5 -0
- package/dist/ipc/transport/index.d.ts +2 -1
- package/dist/ipc/transport/index.js +2 -2
- package/dist/runtime/dom/actionEffects.d.ts +185 -0
- package/dist/runtime/dom/actionEffects.js +402 -0
- package/dist/runtime/dom/actionEffectsScripts.d.ts +90 -0
- package/dist/runtime/dom/actionEffectsScripts.js +426 -0
- package/dist/runtime/dom/elementGeometry.d.ts +170 -0
- package/dist/runtime/dom/elementGeometry.js +553 -0
- package/dist/runtime/dom/elementInfo.d.ts +103 -0
- package/dist/runtime/dom/elementInfo.js +256 -0
- package/dist/runtime/dom/evalHelpers.d.ts +51 -6
- package/dist/runtime/dom/evalHelpers.js +136 -26
- package/dist/runtime/dom/eventListeners.d.ts +2 -1
- package/dist/runtime/dom/eventListeners.js +184 -47
- package/dist/runtime/dom/formDiscovery.d.ts +1 -1
- package/dist/runtime/dom/formDiscovery.js +116 -16
- package/dist/runtime/dom/formFillHelpers/fill.d.ts +9 -0
- package/dist/runtime/dom/formFillHelpers/fill.js +178 -14
- package/dist/runtime/dom/formFillHelpers/index.d.ts +2 -2
- package/dist/runtime/dom/formFillHelpers/index.js +2 -2
- package/dist/runtime/dom/formFillHelpers/pressKey.js +14 -3
- package/dist/runtime/dom/formFillHelpers/scroll.d.ts +3 -0
- package/dist/runtime/dom/formFillHelpers/scroll.js +60 -18
- package/dist/runtime/dom/formFillHelpers/shared.d.ts +17 -0
- package/dist/runtime/dom/formFillHelpers/shared.js +25 -1
- package/dist/runtime/dom/formFillHelpers/stability.d.ts +20 -6
- package/dist/runtime/dom/formFillHelpers/stability.js +50 -19
- package/dist/runtime/dom/formSubmitHelpers.d.ts +3 -0
- package/dist/runtime/dom/formSubmitHelpers.js +89 -15
- package/dist/runtime/dom/frameLayout.d.ts +60 -0
- package/dist/runtime/dom/frameLayout.js +140 -0
- package/dist/runtime/dom/frameOrigin.d.ts +50 -0
- package/dist/runtime/dom/frameOrigin.js +62 -0
- package/dist/runtime/dom/frameScopedConnection.d.ts +92 -0
- package/dist/runtime/dom/frameScopedConnection.js +252 -0
- package/dist/runtime/dom/frameSelection.d.ts +12 -1
- package/dist/runtime/dom/frameSelection.js +22 -3
- package/dist/runtime/dom/frames.d.ts +61 -5
- package/dist/runtime/dom/frames.js +329 -75
- package/dist/runtime/dom/inspect.d.ts +28 -0
- package/dist/runtime/dom/inspect.js +557 -0
- package/dist/runtime/dom/inspectAllStyles.d.ts +62 -0
- package/dist/runtime/dom/inspectAllStyles.js +385 -0
- package/dist/runtime/dom/inspectCascade.d.ts +94 -0
- package/dist/runtime/dom/inspectCascade.js +371 -0
- package/dist/runtime/dom/inspectCascadeModel.d.ts +39 -0
- package/dist/runtime/dom/inspectCascadeModel.js +232 -0
- package/dist/runtime/dom/inspectHints.d.ts +62 -0
- package/dist/runtime/dom/inspectHints.js +305 -0
- package/dist/runtime/dom/inspectLayoutModel.d.ts +87 -0
- package/dist/runtime/dom/inspectLayoutModel.js +346 -0
- package/dist/runtime/dom/inspectModel.d.ts +74 -0
- package/dist/runtime/dom/inspectModel.js +184 -0
- package/dist/runtime/dom/inspectPaintModel.d.ts +157 -0
- package/dist/runtime/dom/inspectPaintModel.js +461 -0
- package/dist/runtime/dom/inspectRules.d.ts +37 -0
- package/dist/runtime/dom/inspectRules.js +101 -0
- package/dist/runtime/dom/inspectScripts.d.ts +132 -0
- package/dist/runtime/dom/inspectScripts.js +263 -0
- package/dist/runtime/dom/inspectTree.d.ts +40 -0
- package/dist/runtime/dom/inspectTree.js +134 -0
- package/dist/runtime/dom/inspectVariables.d.ts +33 -0
- package/dist/runtime/dom/inspectVariables.js +94 -0
- package/dist/runtime/dom/inspectWhyModel.d.ts +20 -0
- package/dist/runtime/dom/inspectWhyModel.js +134 -0
- package/dist/runtime/dom/layout.d.ts +71 -0
- package/dist/runtime/dom/layout.js +340 -0
- package/dist/runtime/dom/listenerPageScripts.d.ts +72 -0
- package/dist/runtime/dom/listenerPageScripts.js +365 -0
- package/dist/runtime/dom/listenerSummary.d.ts +136 -11
- package/dist/runtime/dom/listenerSummary.js +361 -22
- package/dist/runtime/dom/pageActivity.d.ts +41 -0
- package/dist/runtime/dom/pageActivity.js +123 -0
- package/dist/runtime/dom/reactEventHelpers.d.ts +63 -2
- package/dist/runtime/dom/reactEventHelpers.js +220 -41
- package/dist/runtime/dom/targetNode.d.ts +80 -27
- package/dist/runtime/dom/targetNode.js +249 -33
- package/dist/runtime/dom/wait.d.ts +25 -0
- package/dist/runtime/dom/wait.js +199 -0
- package/dist/runtime/dom/waitCondition.d.ts +71 -0
- package/dist/runtime/dom/waitCondition.js +75 -0
- package/dist/runtime/page/emulation.d.ts +71 -0
- package/dist/runtime/page/emulation.js +117 -0
- package/dist/runtime/page/loadingState.d.ts +36 -0
- package/dist/runtime/page/loadingState.js +86 -0
- package/dist/runtime/page/navigation.d.ts +46 -2
- package/dist/runtime/page/navigation.js +69 -33
- package/dist/session/QueryCacheManager.d.ts +11 -1
- package/dist/session/QueryCacheManager.js +25 -3
- package/dist/session/chromeOwners.d.ts +34 -0
- package/dist/session/chromeOwners.js +51 -0
- package/dist/session/cleanup/staleSession.d.ts +11 -1
- package/dist/session/cleanup/staleSession.js +17 -6
- package/dist/session/cleanup/userCommands.js +2 -4
- package/dist/session/metadata.d.ts +5 -1
- package/dist/session/metadata.js +2 -1
- package/dist/session/paths.d.ts +77 -3
- package/dist/session/paths.js +111 -5
- package/dist/session/port.d.ts +31 -7
- package/dist/session/port.js +50 -43
- package/dist/session/portClaims.d.ts +66 -0
- package/dist/session/portClaims.js +284 -0
- package/dist/session/sessionList.d.ts +58 -0
- package/dist/session/sessionList.js +199 -0
- package/dist/session/sessionName.d.ts +46 -0
- package/dist/session/sessionName.js +97 -0
- package/dist/telemetry/a11y.d.ts +18 -3
- package/dist/telemetry/a11y.js +170 -29
- package/dist/telemetry/console.d.ts +1 -0
- package/dist/telemetry/console.js +100 -5
- package/dist/telemetry/network.js +3 -1
- package/dist/telemetry/requestKinds.d.ts +32 -0
- package/dist/telemetry/requestKinds.js +61 -0
- package/dist/telemetry/requestState.d.ts +31 -0
- package/dist/telemetry/requestState.js +38 -0
- package/dist/types.d.ts +112 -3
- package/dist/ui/formatters/a11y.js +3 -0
- package/dist/ui/formatters/console/chronological.d.ts +8 -0
- package/dist/ui/formatters/console/chronological.js +17 -4
- package/dist/ui/formatters/console/json.js +3 -4
- package/dist/ui/formatters/console/shared.d.ts +12 -0
- package/dist/ui/formatters/console.d.ts +2 -2
- package/dist/ui/formatters/console.js +1 -1
- package/dist/ui/formatters/details.d.ts +8 -0
- package/dist/ui/formatters/details.js +61 -4
- package/dist/ui/formatters/dom.d.ts +27 -14
- package/dist/ui/formatters/dom.js +88 -59
- package/dist/ui/formatters/form.js +29 -18
- package/dist/ui/formatters/inspect.d.ts +39 -0
- package/dist/ui/formatters/inspect.js +596 -0
- package/dist/ui/formatters/keyAttributes.d.ts +19 -0
- package/dist/ui/formatters/keyAttributes.js +84 -0
- package/dist/ui/formatters/layout.d.ts +31 -0
- package/dist/ui/formatters/layout.js +53 -0
- package/dist/ui/formatters/listeners.d.ts +3 -2
- package/dist/ui/formatters/listeners.js +73 -9
- package/dist/ui/formatters/networkHeaders.d.ts +13 -0
- package/dist/ui/formatters/networkHeaders.js +36 -3
- package/dist/ui/formatters/networkList.d.ts +29 -1
- package/dist/ui/formatters/networkList.js +86 -20
- package/dist/ui/formatters/preview.js +2 -1
- package/dist/ui/formatters/requestStatus.d.ts +1 -17
- package/dist/ui/formatters/requestStatus.js +2 -30
- package/dist/ui/formatters/sessions.d.ts +12 -0
- package/dist/ui/formatters/sessions.js +40 -0
- package/dist/ui/formatters/status.d.ts +21 -2
- package/dist/ui/formatters/status.js +47 -10
- package/dist/ui/formatters/triggeredRequests.d.ts +36 -0
- package/dist/ui/formatters/triggeredRequests.js +65 -0
- package/dist/ui/formatting.d.ts +19 -0
- package/dist/ui/formatting.js +31 -36
- package/dist/ui/messages/chrome.d.ts +9 -0
- package/dist/ui/messages/chrome.js +17 -5
- package/dist/ui/messages/commands.d.ts +504 -14
- package/dist/ui/messages/commands.js +835 -21
- package/dist/ui/messages/consoleMessages.d.ts +10 -0
- package/dist/ui/messages/consoleMessages.js +17 -0
- package/dist/ui/messages/hints.js +2 -1
- package/dist/ui/messages/networkMessages.d.ts +14 -0
- package/dist/ui/messages/networkMessages.js +18 -0
- package/dist/ui/messages/preview.js +5 -4
- package/dist/ui/messages/session.d.ts +30 -21
- package/dist/ui/messages/session.js +48 -26
- package/dist/ui/messages/sessionCommand.d.ts +43 -0
- package/dist/ui/messages/sessionCommand.js +52 -0
- package/dist/utils/async.d.ts +17 -0
- package/dist/utils/async.js +36 -0
- package/dist/utils/color.d.ts +84 -0
- package/dist/utils/color.js +376 -0
- package/dist/utils/cssValues.d.ts +109 -0
- package/dist/utils/cssValues.js +236 -0
- package/dist/utils/http.d.ts +22 -1
- package/dist/utils/http.js +28 -9
- package/dist/utils/selectorFilters.d.ts +48 -8
- package/dist/utils/selectorFilters.js +296 -53
- package/dist/utils/shellDetection.d.ts +8 -2
- package/dist/utils/shellDetection.js +120 -33
- package/dist/utils/suggestions.d.ts +26 -0
- package/dist/utils/suggestions.js +73 -0
- package/dist/utils/taskMappings.js +10 -0
- package/dist/utils/url.d.ts +12 -2
- package/dist/utils/url.js +69 -7
- package/package.json +1 -1
- package/dist/ui/formatters/sessionFormatters.d.ts +0 -58
- package/dist/ui/formatters/sessionFormatters.js +0 -121
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a DOM action changed on the page: whether it navigated (to a new
|
|
3
|
+
* document or within the same one), which messages and elements appeared,
|
|
4
|
+
* whether it had no visible effect at all, and whether the page was still
|
|
5
|
+
* working on the result. Costs one page script sent before the action (not
|
|
6
|
+
* waited for: CDP runs it before the action's own scripts) and one read
|
|
7
|
+
* after it, plus a second look 300 ms later when nothing seemed to happen.
|
|
8
|
+
* Worst case, when the page does not answer (a navigation is pending, or a
|
|
9
|
+
* long script runs), the snapshot is given up after {@link START_TIMEOUT_MS}
|
|
10
|
+
* and each read after {@link READ_TIMEOUT_MS}.
|
|
11
|
+
*/
|
|
12
|
+
import { EFFECTS_READ_SCRIPT, EFFECTS_START_SCRIPT, EFFECTS_STOP_SCRIPT, } from './actionEffectsScripts.js';
|
|
13
|
+
import { listenForActivity, } from './pageActivity.js';
|
|
14
|
+
import { createLogger } from '../../ui/logging/index.js';
|
|
15
|
+
import { delay, raceTimeout } from '../../utils/async.js';
|
|
16
|
+
import { getErrorMessage } from '../../utils/errors.js';
|
|
17
|
+
const log = createLogger('dom');
|
|
18
|
+
/** Messages reported per action */
|
|
19
|
+
const MAX_NEW_MESSAGES = 3;
|
|
20
|
+
/** Shown elements reported per action */
|
|
21
|
+
const MAX_SHOWN_ELEMENTS = 3;
|
|
22
|
+
/**
|
|
23
|
+
* Bursts of DOM changes that make the DOM look busy: at least this many
|
|
24
|
+
* within {@link BUSY_WINDOW_MS}, the last within {@link BUSY_RECENT_MS}
|
|
25
|
+
*/
|
|
26
|
+
const BUSY_BURSTS = 2;
|
|
27
|
+
const BUSY_WINDOW_MS = 500;
|
|
28
|
+
const BUSY_RECENT_MS = 150;
|
|
29
|
+
/** Second look at a DOM that looked busy; it is still changing with {@link BUSY_BURSTS} new bursts by then (ms) */
|
|
30
|
+
const STILL_CHANGING_RECHECK_MS = 250;
|
|
31
|
+
/** Resource types of pending requests that mean more content is coming */
|
|
32
|
+
const CONTENT_REQUEST_TYPES = new Set(['Document', 'XHR', 'Fetch', 'Script']);
|
|
33
|
+
/** Longest message text reported */
|
|
34
|
+
const MAX_MESSAGE_LENGTH = 120;
|
|
35
|
+
/** How long collecting waits for the snapshot taken before the action */
|
|
36
|
+
const START_TIMEOUT_MS = 200;
|
|
37
|
+
/** How long a read after the action may take before its part is skipped */
|
|
38
|
+
const READ_TIMEOUT_MS = 250;
|
|
39
|
+
/** Second look before claiming "no effect" (late timers, animations) */
|
|
40
|
+
const NO_EFFECT_RECHECK_MS = 300;
|
|
41
|
+
/**
|
|
42
|
+
* Texts that tick on their own (clocks, counters, countdowns, percentages):
|
|
43
|
+
* digits with separators and at most a time unit, e.g. `12:04:33`, `57%`,
|
|
44
|
+
* `3 s`. Their changes are not reported as new messages.
|
|
45
|
+
*/
|
|
46
|
+
const TICKING_TEXT = /^[\d\s:.,/%+\-–—()]*\d[\d\s:.,/%+\-–—()]*(ms|s|sec|secs|min|mins|h|am|pm)?$/i;
|
|
47
|
+
/**
|
|
48
|
+
* Messages that are new after the action: all of them after a new document
|
|
49
|
+
* loaded; otherwise those whose text is shown more often than before (a
|
|
50
|
+
* re-rendered message with the same text is not new) and those whose
|
|
51
|
+
* element changed its text. Texts that tick on their own
|
|
52
|
+
* ({@link TICKING_TEXT}: clocks, counters) are left out; other elements
|
|
53
|
+
* that change on their own (a rotating banner) are not recognised. Each text
|
|
54
|
+
* is reported once, at most {@link MAX_NEW_MESSAGES}, cut to
|
|
55
|
+
* {@link MAX_MESSAGE_LENGTH} characters.
|
|
56
|
+
*
|
|
57
|
+
* @param before - Messages before the action
|
|
58
|
+
* @param after - Messages after the action
|
|
59
|
+
* @param newDocument - Whether a new document loaded
|
|
60
|
+
* @returns New messages
|
|
61
|
+
*/
|
|
62
|
+
export function newMessages(before, after, newDocument) {
|
|
63
|
+
const countTexts = (messages) => {
|
|
64
|
+
const counts = new Map();
|
|
65
|
+
messages.forEach(({ text }) => counts.set(text, (counts.get(text) ?? 0) + 1));
|
|
66
|
+
return counts;
|
|
67
|
+
};
|
|
68
|
+
const beforeCounts = countTexts(before);
|
|
69
|
+
const afterCounts = countTexts(after);
|
|
70
|
+
const textBefore = new Map(before.map((message) => [message.id, message.text]));
|
|
71
|
+
const isNew = (message) => {
|
|
72
|
+
if (newDocument)
|
|
73
|
+
return true;
|
|
74
|
+
const previous = textBefore.get(message.id);
|
|
75
|
+
if (previous === message.text)
|
|
76
|
+
return false;
|
|
77
|
+
if (previous !== undefined)
|
|
78
|
+
return true;
|
|
79
|
+
return (afterCounts.get(message.text) ?? 0) > (beforeCounts.get(message.text) ?? 0);
|
|
80
|
+
};
|
|
81
|
+
const reported = new Set();
|
|
82
|
+
const result = [];
|
|
83
|
+
for (const message of after) {
|
|
84
|
+
if (result.length >= MAX_NEW_MESSAGES)
|
|
85
|
+
break;
|
|
86
|
+
if (reported.has(message.text) || TICKING_TEXT.test(message.text))
|
|
87
|
+
continue;
|
|
88
|
+
if (!isNew(message))
|
|
89
|
+
continue;
|
|
90
|
+
reported.add(message.text);
|
|
91
|
+
result.push({ text: cutText(message.text), element: message.element });
|
|
92
|
+
}
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Cut a text to {@link MAX_MESSAGE_LENGTH} characters, marking the cut.
|
|
97
|
+
*
|
|
98
|
+
* @param text - Text
|
|
99
|
+
* @returns Text of at most that length
|
|
100
|
+
*/
|
|
101
|
+
function cutText(text) {
|
|
102
|
+
const characters = Array.from(text);
|
|
103
|
+
if (characters.length <= MAX_MESSAGE_LENGTH)
|
|
104
|
+
return text;
|
|
105
|
+
return `${characters.slice(0, MAX_MESSAGE_LENGTH - 1).join('')}…`;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Elements to report as shown: those whose text is not already reported as
|
|
109
|
+
* a new message, at most {@link MAX_SHOWN_ELEMENTS}, texts cut to
|
|
110
|
+
* {@link MAX_MESSAGE_LENGTH} characters.
|
|
111
|
+
*
|
|
112
|
+
* @param shown - Elements the page found shown by the action
|
|
113
|
+
* @param messages - New messages being reported
|
|
114
|
+
* @returns Elements to report
|
|
115
|
+
*/
|
|
116
|
+
export function shownElements(shown, messages) {
|
|
117
|
+
const reported = new Set(messages.map((message) => message.text));
|
|
118
|
+
return shown
|
|
119
|
+
.filter((element) => !reported.has(cutText(element.text)))
|
|
120
|
+
.slice(0, MAX_SHOWN_ELEMENTS)
|
|
121
|
+
.map((element) => ({ ...element, text: cutText(element.text) }));
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Whether a read's DOM looks busy, worth a second look: at least
|
|
125
|
+
* {@link BUSY_BURSTS} bursts of structural changes within
|
|
126
|
+
* {@link BUSY_WINDOW_MS}, the last within {@link BUSY_RECENT_MS}. Text-only
|
|
127
|
+
* changes (clocks) and style changes (animations) are not bursts.
|
|
128
|
+
*
|
|
129
|
+
* @param settle - Signals of the read
|
|
130
|
+
* @returns True when the DOM may still be changing
|
|
131
|
+
*/
|
|
132
|
+
export function domLooksBusy(settle) {
|
|
133
|
+
if (!settle)
|
|
134
|
+
return false;
|
|
135
|
+
const recent = settle.burstAges.filter((age) => age <= BUSY_WINDOW_MS);
|
|
136
|
+
return recent.length >= BUSY_BURSTS && Math.min(...recent) <= BUSY_RECENT_MS;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Whether the DOM kept changing during the second look: at least
|
|
140
|
+
* {@link BUSY_BURSTS} new bursts within the time since the first read (a
|
|
141
|
+
* render that ends in two commits, or a poller updating once a second, does
|
|
142
|
+
* not count).
|
|
143
|
+
*
|
|
144
|
+
* @param settle - Signals of the second read
|
|
145
|
+
* @param sinceMs - Time since the first read
|
|
146
|
+
* @returns True when the DOM is still changing
|
|
147
|
+
*/
|
|
148
|
+
export function domKeptChanging(settle, sinceMs) {
|
|
149
|
+
if (!settle)
|
|
150
|
+
return false;
|
|
151
|
+
return settle.burstAges.filter((age) => age < sinceMs).length >= BUSY_BURSTS;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* What the page was still working on when the action returned, or undefined
|
|
155
|
+
* when it looked settled: content requests (documents, fetch/XHR, scripts)
|
|
156
|
+
* still pending, a new document still loading, a loading indicator that
|
|
157
|
+
* appeared, a DOM still changing ({@link domKeptChanging}), or a page that
|
|
158
|
+
* did not answer (a long script). A result a timer renders later, with no
|
|
159
|
+
* DOM change before it, is not seen.
|
|
160
|
+
*
|
|
161
|
+
* @param work - What collecting saw
|
|
162
|
+
* @param requests - Requests the action triggered (with pending ones)
|
|
163
|
+
* @returns Pending work, or undefined
|
|
164
|
+
*/
|
|
165
|
+
export function pendingChanges(work, requests = []) {
|
|
166
|
+
const settle = work.settle;
|
|
167
|
+
const pendingRequests = requests.filter((request) => request.pending && CONTENT_REQUEST_TYPES.has(request.resourceType ?? '')).length;
|
|
168
|
+
const pending = {
|
|
169
|
+
...(pendingRequests > 0 && { requests: pendingRequests }),
|
|
170
|
+
...(work.navigating && { navigation: true }),
|
|
171
|
+
...(settle?.loading && { loading: settle.loading }),
|
|
172
|
+
...(work.domChanging && { domChanging: true }),
|
|
173
|
+
...(work.unresponsive && { busy: true }),
|
|
174
|
+
};
|
|
175
|
+
return Object.keys(pending).length > 0 ? pending : undefined;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* How the page's location changed: a new document committed in the main
|
|
179
|
+
* frame (also when it has the URL it had, as after a form POST that
|
|
180
|
+
* redirects back), or a same-document URL change (history API, hash).
|
|
181
|
+
*
|
|
182
|
+
* Without the URL before the action, a same-document change is reported
|
|
183
|
+
* only when Chrome announced one.
|
|
184
|
+
*
|
|
185
|
+
* @param startHref - URL before the action (undefined when not read)
|
|
186
|
+
* @param read - Page read after the action (undefined when not read)
|
|
187
|
+
* @param events - Main-frame navigation events
|
|
188
|
+
* @returns Navigation, or undefined when the location did not change
|
|
189
|
+
*/
|
|
190
|
+
export function pageNavigation(startHref, read, events) {
|
|
191
|
+
if (events.document) {
|
|
192
|
+
const status = events.statusByLoader.get(events.document.loaderId);
|
|
193
|
+
return {
|
|
194
|
+
url: read?.href ?? events.document.url,
|
|
195
|
+
sameDocument: false,
|
|
196
|
+
...(status !== undefined && { status }),
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
const url = read?.href ?? events.withinDocumentUrl;
|
|
200
|
+
if (url === undefined || url === startHref)
|
|
201
|
+
return undefined;
|
|
202
|
+
if (startHref === undefined && events.withinDocumentUrl === undefined)
|
|
203
|
+
return undefined;
|
|
204
|
+
return { url, sameDocument: true };
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Whether an action had no visible effect: the page was read before and
|
|
208
|
+
* after in the same document, it counted no DOM change, nothing made the
|
|
209
|
+
* check uncertain, and no navigation, message, shown element, request,
|
|
210
|
+
* dialog or new window happened.
|
|
211
|
+
*
|
|
212
|
+
* @param read - Page read after the action
|
|
213
|
+
* @param effects - Navigation and messages found
|
|
214
|
+
* @param activity - Requests, dialogs and windows during the action
|
|
215
|
+
* @returns True to report `effect: "none"`
|
|
216
|
+
*/
|
|
217
|
+
export function hadNoEffect(read, effects, activity) {
|
|
218
|
+
return (read !== undefined &&
|
|
219
|
+
!read.fresh &&
|
|
220
|
+
read.changes === 0 &&
|
|
221
|
+
read.uncertain === undefined &&
|
|
222
|
+
effects.navigation === undefined &&
|
|
223
|
+
(effects.messages ?? []).length === 0 &&
|
|
224
|
+
(effects.shown ?? []).length === 0 &&
|
|
225
|
+
activity.requests === 0 &&
|
|
226
|
+
activity.dialogs === 0 &&
|
|
227
|
+
!activity.opened);
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Start watching an action's effects: listen for main-frame navigations,
|
|
231
|
+
* document statuses, requests and new windows, and send the page snapshot
|
|
232
|
+
* without waiting for it.
|
|
233
|
+
*
|
|
234
|
+
* @param cdp - CDP connection
|
|
235
|
+
* @returns Watch to collect from after the action
|
|
236
|
+
*/
|
|
237
|
+
export function watchActionEffects(cdp) {
|
|
238
|
+
const watch = {
|
|
239
|
+
cdp,
|
|
240
|
+
listener: listenForActivity(cdp),
|
|
241
|
+
start: evaluate(cdp, EFFECTS_START_SCRIPT),
|
|
242
|
+
stopConfirmed: false,
|
|
243
|
+
unresponsive: false,
|
|
244
|
+
};
|
|
245
|
+
return {
|
|
246
|
+
collect: (options) => collectEffects(watch, options),
|
|
247
|
+
dispose: () => disposeWatch(watch),
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* What changed: the navigation (from CDP events even without a snapshot),
|
|
252
|
+
* new messages, shown elements when asked, "no effect" after a second look
|
|
253
|
+
* when asked, and the page's work at the end.
|
|
254
|
+
*
|
|
255
|
+
* @param watch - The action's watch
|
|
256
|
+
* @param options - Dialogs, and what to decide and list
|
|
257
|
+
* @returns What changed
|
|
258
|
+
*/
|
|
259
|
+
async function collectEffects(watch, options) {
|
|
260
|
+
const start = await awaitStart(watch);
|
|
261
|
+
if (!start) {
|
|
262
|
+
return { ...effectsOf(undefined, undefined, watch.listener.events), work: pageWork(watch) };
|
|
263
|
+
}
|
|
264
|
+
const reportShown = options.reportShown === true;
|
|
265
|
+
let snapshot = await readPage(watch, { stop: false, reportShown });
|
|
266
|
+
let effects = effectsOf(start, snapshot, watch.listener.events);
|
|
267
|
+
const quiet = () => hadNoEffect(snapshot, effects, { ...watch.listener.activity(), dialogs: options.dialogs });
|
|
268
|
+
if (options.detectNoEffect && quiet()) {
|
|
269
|
+
await delay(NO_EFFECT_RECHECK_MS);
|
|
270
|
+
snapshot = await readPage(watch, { stop: true, reportShown });
|
|
271
|
+
effects = effectsOf(start, snapshot, watch.listener.events);
|
|
272
|
+
if (quiet())
|
|
273
|
+
effects = { ...effects, effect: 'none' };
|
|
274
|
+
}
|
|
275
|
+
const domChanging = options.detectUnsettled === true && (await stillChanging(watch, snapshot));
|
|
276
|
+
return { ...effects, work: pageWork(watch, snapshot, domChanging) };
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* The snapshot taken before the action, waiting at most
|
|
280
|
+
* {@link START_TIMEOUT_MS}; a snapshot still unanswered then (and no
|
|
281
|
+
* navigation pending) marks the page unresponsive.
|
|
282
|
+
*
|
|
283
|
+
* @param watch - The action's watch
|
|
284
|
+
* @returns The snapshot, or undefined
|
|
285
|
+
*/
|
|
286
|
+
async function awaitStart(watch) {
|
|
287
|
+
const started = await raceTimeout(watch.start.then((value) => ({ value })), START_TIMEOUT_MS);
|
|
288
|
+
if (!started)
|
|
289
|
+
watch.unresponsive = !watch.listener.navigationPending();
|
|
290
|
+
return started?.value;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Whether the DOM is still changing: when the last read looked busy
|
|
294
|
+
* ({@link domLooksBusy}), a second read {@link STILL_CHANGING_RECHECK_MS}
|
|
295
|
+
* later must see it keep changing ({@link domKeptChanging}).
|
|
296
|
+
*
|
|
297
|
+
* @param watch - The action's watch
|
|
298
|
+
* @param snapshot - Last read, if any
|
|
299
|
+
* @returns True when the DOM kept changing
|
|
300
|
+
*/
|
|
301
|
+
async function stillChanging(watch, snapshot) {
|
|
302
|
+
if (!domLooksBusy(snapshot?.settle))
|
|
303
|
+
return false;
|
|
304
|
+
const firstRead = Date.now();
|
|
305
|
+
await delay(STILL_CHANGING_RECHECK_MS);
|
|
306
|
+
const recheck = await readPage(watch, { stop: false, reportShown: false });
|
|
307
|
+
return domKeptChanging(recheck?.settle, Date.now() - firstRead);
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* The page's work as the last read and the CDP events saw it.
|
|
311
|
+
*
|
|
312
|
+
* @param watch - The action's watch
|
|
313
|
+
* @param snapshot - Last read, if any
|
|
314
|
+
* @param domChanging - Whether the DOM kept changing over a second look
|
|
315
|
+
* @returns Page work
|
|
316
|
+
*/
|
|
317
|
+
function pageWork(watch, snapshot, domChanging = false) {
|
|
318
|
+
return {
|
|
319
|
+
...(snapshot?.settle && { settle: snapshot.settle }),
|
|
320
|
+
domChanging,
|
|
321
|
+
unresponsive: watch.unresponsive,
|
|
322
|
+
navigating: watch.listener.navigationPending(),
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Navigation, new messages and shown elements from the snapshots and CDP
|
|
327
|
+
* events.
|
|
328
|
+
*
|
|
329
|
+
* @param start - Snapshot before the action, if taken
|
|
330
|
+
* @param snapshot - Read after the action, if taken
|
|
331
|
+
* @param events - Main-frame navigation events
|
|
332
|
+
* @returns Effects, without empty parts
|
|
333
|
+
*/
|
|
334
|
+
function effectsOf(start, snapshot, events) {
|
|
335
|
+
const navigation = pageNavigation(start?.href, snapshot, events);
|
|
336
|
+
const messages = start && snapshot ? newMessages(start.messages, snapshot.messages, snapshot.fresh) : [];
|
|
337
|
+
const shown = shownElements(snapshot?.shown ?? [], messages);
|
|
338
|
+
return {
|
|
339
|
+
...(navigation && { navigation }),
|
|
340
|
+
...(messages.length > 0 && { messages }),
|
|
341
|
+
...(shown.length > 0 && { shown }),
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Read the page after the action, unless a main-frame load is pending (the
|
|
346
|
+
* read would wait for the new page). A stopping read that answered stops the
|
|
347
|
+
* page's watch, so disposing need not. A read that got no answer in time
|
|
348
|
+
* marks the page unresponsive.
|
|
349
|
+
*
|
|
350
|
+
* @param watch - The action's watch
|
|
351
|
+
* @param options - Also stop the page's watch; list shown elements
|
|
352
|
+
* @returns The read, or undefined
|
|
353
|
+
*/
|
|
354
|
+
async function readPage(watch, options) {
|
|
355
|
+
if (watch.listener.navigationPending())
|
|
356
|
+
return undefined;
|
|
357
|
+
const expression = `(${EFFECTS_READ_SCRIPT})(${options.stop}, ${options.reportShown})`;
|
|
358
|
+
const answer = await raceTimeout(evaluate(watch.cdp, expression).then((value) => ({ value })), READ_TIMEOUT_MS);
|
|
359
|
+
if (!answer)
|
|
360
|
+
watch.unresponsive = !watch.listener.navigationPending();
|
|
361
|
+
const snapshot = answer?.value;
|
|
362
|
+
if (options.stop && snapshot)
|
|
363
|
+
watch.stopConfirmed = true;
|
|
364
|
+
return snapshot;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Stop listening, and stop the page's watch unless a read did. The stop is
|
|
368
|
+
* sent even when the snapshot never answered: CDP runs it after the
|
|
369
|
+
* snapshot, wherever that ran (the page also stops watching on its own
|
|
370
|
+
* after 30 s).
|
|
371
|
+
*
|
|
372
|
+
* @param watch - The action's watch
|
|
373
|
+
*/
|
|
374
|
+
function disposeWatch(watch) {
|
|
375
|
+
watch.listener.dispose();
|
|
376
|
+
if (watch.stopConfirmed)
|
|
377
|
+
return;
|
|
378
|
+
void watch.cdp
|
|
379
|
+
.send('Runtime.evaluate', { expression: EFFECTS_STOP_SCRIPT })
|
|
380
|
+
.catch((error) => log.debug(`Effects watch not stopped: ${getErrorMessage(error)}`));
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Evaluate a page script for its value (undefined on an exception or a
|
|
384
|
+
* failed call).
|
|
385
|
+
*
|
|
386
|
+
* @param cdp - CDP connection
|
|
387
|
+
* @param expression - Script
|
|
388
|
+
* @returns Its value, or undefined
|
|
389
|
+
*/
|
|
390
|
+
async function evaluate(cdp, expression) {
|
|
391
|
+
try {
|
|
392
|
+
const reply = (await cdp.send('Runtime.evaluate', { expression, returnByValue: true }));
|
|
393
|
+
if (!reply.exceptionDetails)
|
|
394
|
+
return reply.result?.value;
|
|
395
|
+
log.debug(`Effects script failed: ${reply.exceptionDetails.text}`);
|
|
396
|
+
}
|
|
397
|
+
catch (error) {
|
|
398
|
+
log.debug(`Effects script not run: ${getErrorMessage(error)}`);
|
|
399
|
+
}
|
|
400
|
+
return undefined;
|
|
401
|
+
}
|
|
402
|
+
//# sourceMappingURL=actionEffects.js.map
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Page scripts behind the "what changed" part of DOM action results: one
|
|
3
|
+
* snapshot before the action ({@link EFFECTS_START_SCRIPT}) and one read after
|
|
4
|
+
* it ({@link EFFECTS_READ_SCRIPT}), plus the snapshot a hover takes of what
|
|
5
|
+
* is hidden around its target ({@link REVEAL_SNAPSHOT_JS}).
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Page-side test whether an element is part of a message's chrome rather
|
|
9
|
+
* than its text: aria-hidden parts, buttons, and elements whose class or
|
|
10
|
+
* aria-label names a close/dismiss control (`close`, `btn-close`, `close_x`;
|
|
11
|
+
* not `closeable`, `enclosed` or `disclosure`).
|
|
12
|
+
*/
|
|
13
|
+
export declare const MESSAGE_CHROME_JS = "(node) => {\n const closer = /(^|[-_\\s])(close|dismiss)($|[-_\\s])/i;\n return node.getAttribute('aria-hidden') === 'true' ||\n /^(button|script|style|template)$/.test(node.localName) ||\n node.getAttribute('role') === 'button' ||\n closer.test(node.getAttribute('class') || '') ||\n closer.test(node.getAttribute('aria-label') || '');\n}";
|
|
14
|
+
/**
|
|
15
|
+
* Page-side snapshot a hover takes right before the mouse moves (called by
|
|
16
|
+
* the click script with the hovered element): the elements around it (its
|
|
17
|
+
* parent and everything in it) and the tooltips, menus, listboxes, dialogs
|
|
18
|
+
* and popovers anywhere on the page that are hidden, at most
|
|
19
|
+
* {@link MAX_REVEAL_CANDIDATES} looked at within {@link REVEAL_BUDGET_MS}.
|
|
20
|
+
* They are kept by identity in the action's watch, so its read can tell
|
|
21
|
+
* which of them the hover revealed, also through CSS `:hover` rules that
|
|
22
|
+
* change no DOM, and elements moving in the page can't pass for revealed
|
|
23
|
+
* ones. Does nothing without a running watch (another frame).
|
|
24
|
+
*/
|
|
25
|
+
export declare const REVEAL_SNAPSHOT_JS: string;
|
|
26
|
+
/**
|
|
27
|
+
* Page-side list of the elements an action showed: elements added during
|
|
28
|
+
* the watch inside the target's container ({@link NEAR_SCOPE_JS}) or, anywhere,
|
|
29
|
+
* popups and messages (tooltip, menu, listbox, dialog, alert and status
|
|
30
|
+
* roles, `aria-live`, message-like classes), plus, after a hover, the
|
|
31
|
+
* elements hidden before it that are shown now ({@link REVEAL_SNAPSHOT_JS}).
|
|
32
|
+
* Background widgets elsewhere on the page do not count. Only shown ones
|
|
33
|
+
* with visible text count, the outermost of nested ones, and not those
|
|
34
|
+
* whose text a removed element had (a re-render). At most
|
|
35
|
+
* {@link MAX_SHOWN}, within {@link SHOWN_BUDGET_MS}.
|
|
36
|
+
*/
|
|
37
|
+
export declare const SHOWN_ELEMENTS_JS: string;
|
|
38
|
+
/**
|
|
39
|
+
* Page-side test whether a mutation is only focus/hover churn: a class
|
|
40
|
+
* change on an element the action's events hit (`targets`) that only adds
|
|
41
|
+
* or removes classes containing "focus" or "hover".
|
|
42
|
+
*/
|
|
43
|
+
export declare const CHURN_ONLY_JS = "(record, targets) => {\n if (record.type !== 'attributes' || record.attributeName !== 'class' || !targets.has(record.target)) return false;\n const tokens = (text) => new Set((text || '').split(/\\s+/).filter(Boolean));\n const before = tokens(record.oldValue);\n const after = tokens(record.target.getAttribute('class'));\n const changed = [...before].filter((c) => !after.has(c)).concat([...after].filter((c) => !before.has(c)));\n return changed.every((c) => /focus|hover/i.test(c));\n}";
|
|
44
|
+
/**
|
|
45
|
+
* Page-side test whether a mutation changes the page's structure or state
|
|
46
|
+
* rather than only animating it: elements added or removed, or an attribute
|
|
47
|
+
* other than `style` changed. Text-only changes (clocks, counters) and style
|
|
48
|
+
* changes (script-driven animations) do not count.
|
|
49
|
+
*/
|
|
50
|
+
export declare const STRUCTURAL_CHANGE_JS = "(record) => {\n if (record.type === 'attributes') return record.attributeName !== 'style';\n if (record.type !== 'childList') return false;\n const element = (node) => node.nodeType === 1;\n return Array.from(record.addedNodes).some(element) || Array.from(record.removedNodes).some(element);\n}";
|
|
51
|
+
/**
|
|
52
|
+
* Page-side reason why "no effect" can't be claimed even without DOM
|
|
53
|
+
* changes, or undefined: `clipboard` (a copy or cut happened), `no-event`
|
|
54
|
+
* (no event reached the page), `control` (form controls, labels, media,
|
|
55
|
+
* frames, popover/command buttons: their effect needs no DOM change),
|
|
56
|
+
* `new-window` (download or `target` links), `external-link` (mailto:, tel:,
|
|
57
|
+
* javascript: and other non-http links), `closed-shadow` (a custom element
|
|
58
|
+
* whose inside is not observed) or `focus` (focus moved to an element that
|
|
59
|
+
* may reveal content with CSS).
|
|
60
|
+
*/
|
|
61
|
+
export declare const UNCERTAIN_JS = "(state, active) => {\n if (state.copied) return 'clipboard';\n if (state.targets.size === 0) return 'no-event';\n const controls = /^(input|select|textarea|option|label|canvas|video|audio|iframe|embed|object)$/;\n for (const node of state.path) {\n if (controls.test(node.localName) || node.isContentEditable) return 'control';\n if (node.hasAttribute('popovertarget') || node.hasAttribute('commandfor')) return 'control';\n if (node.localName === 'a' && node.hasAttribute('href')) {\n if (node.hasAttribute('download') || (node.target && node.target !== '_self')) return 'new-window';\n if (!/^https?:$/.test(node.protocol)) return 'external-link';\n }\n }\n for (const node of state.targets) if (node.localName.includes('-') && !node.shadowRoot) return 'closed-shadow';\n const plain = (node) => /^(body|button|summary)$/.test(node.localName) ||\n (node.localName === 'a' && node.hasAttribute('href')) ||\n (node.localName === 'input' && /^(button|submit|reset)$/i.test(node.type || ''));\n if (active && active !== state.focus && !plain(active)) return 'focus';\n return undefined;\n}";
|
|
62
|
+
/**
|
|
63
|
+
* Snapshot before an action, left in `window.__bdgEffects`: the messages
|
|
64
|
+
* and loading indicators shown, and a MutationObserver (on the document,
|
|
65
|
+
* its open shadow roots and any shadow root attached while watching, which
|
|
66
|
+
* also counts as a change) counting changes other than
|
|
67
|
+
* {@link CHURN_ONLY_JS}, keeping the elements added and removed and the
|
|
68
|
+
* times of {@link STRUCTURAL_CHANGE_JS} bursts. Capture listeners record
|
|
69
|
+
* which elements the action's events reached, the first key press's target,
|
|
70
|
+
* copy/cut events and the scroll position at the first press (a click
|
|
71
|
+
* scrolls its target into view first). The watch stops itself after
|
|
72
|
+
* {@link MAX_WATCH_MS}, so a snapshot that ran late (after a navigation,
|
|
73
|
+
* with nobody reading it) leaves nothing behind. Evaluates to the URL and
|
|
74
|
+
* the messages.
|
|
75
|
+
*/
|
|
76
|
+
export declare const EFFECTS_START_SCRIPT: string;
|
|
77
|
+
/**
|
|
78
|
+
* Read after an action, called with `(stop, shown)`: `stop` also stops
|
|
79
|
+
* watching, `shown` lists the elements the action showed
|
|
80
|
+
* ({@link SHOWN_ELEMENTS_JS}). Returns the URL, the messages shown and,
|
|
81
|
+
* when the snapshot is still there (same document), the number of changes
|
|
82
|
+
* counted (plus one when the page scrolled after the press), why "no
|
|
83
|
+
* effect" could not be claimed ({@link UNCERTAIN_JS}) and whether the page
|
|
84
|
+
* is still working ({@link SETTLE_JS}). `fresh` means a new document
|
|
85
|
+
* (everything shown is new).
|
|
86
|
+
*/
|
|
87
|
+
export declare const EFFECTS_READ_SCRIPT: string;
|
|
88
|
+
/** Stops the watch {@link EFFECTS_START_SCRIPT} left (when no read stopped it) */
|
|
89
|
+
export declare const EFFECTS_STOP_SCRIPT = "if (window.__bdgEffects) { window.__bdgEffects.stop(); delete window.__bdgEffects; }";
|
|
90
|
+
//# sourceMappingURL=actionEffectsScripts.d.ts.map
|