browser-debugger-cli 0.11.0 → 0.13.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/.claude/skills/bdg/SKILL.md +4 -4
- package/README.md +143 -79
- package/dist/commands/cdp.d.ts +22 -1
- package/dist/commands/cdp.js +100 -43
- package/dist/commands/console.d.ts +12 -0
- package/dist/commands/console.js +62 -12
- package/dist/commands/css.d.ts +13 -0
- package/dist/commands/css.js +53 -0
- package/dist/commands/dom/DomElementResolver.d.ts +3 -1
- package/dist/commands/dom/DomElementResolver.js +10 -3
- package/dist/commands/dom/a11y.js +3 -2
- package/dist/commands/dom/audit.d.ts +14 -0
- package/dist/commands/dom/audit.js +87 -0
- package/dist/commands/dom/eval.d.ts +3 -2
- package/dist/commands/dom/eval.js +11 -5
- package/dist/commands/dom/form.js +10 -9
- package/dist/commands/dom/formInteraction.js +42 -11
- package/dist/commands/dom/get.js +8 -8
- 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 +3 -2
- package/dist/commands/dom/helpers/keyAttributes.js +6 -4
- package/dist/commands/dom/helpers/query.d.ts +27 -3
- package/dist/commands/dom/helpers/query.js +152 -64
- package/dist/commands/dom/helpers/screenshot.d.ts +1 -0
- package/dist/commands/dom/helpers/screenshot.js +169 -49
- package/dist/commands/dom/index.js +7 -2
- package/dist/commands/dom/query.d.ts +19 -2
- package/dist/commands/dom/query.js +37 -6
- package/dist/commands/dom/screenshot.js +12 -7
- package/dist/commands/dom/semanticUtils.d.ts +3 -2
- package/dist/commands/dom/semanticUtils.js +40 -9
- package/dist/commands/dom/wait.js +5 -3
- package/dist/commands/helpJson.d.ts +82 -19
- package/dist/commands/helpJson.js +112 -41
- package/dist/commands/helpTopic.d.ts +16 -1
- package/dist/commands/helpTopic.js +59 -1
- package/dist/commands/installSkill.d.ts +15 -5
- package/dist/commands/installSkill.js +86 -16
- package/dist/commands/network/list.js +22 -12
- package/dist/commands/optionBehaviors.js +53 -16
- package/dist/commands/page.js +7 -4
- package/dist/commands/peek.d.ts +7 -0
- package/dist/commands/peek.js +65 -23
- package/dist/commands/shared/daemonErrorHandler.d.ts +5 -2
- package/dist/commands/shared/daemonErrorHandler.js +20 -9
- package/dist/commands/shared/dataFetcher.d.ts +12 -4
- package/dist/commands/shared/dataFetcher.js +12 -4
- package/dist/commands/shared/followMode.d.ts +9 -1
- package/dist/commands/shared/followMode.js +22 -4
- package/dist/commands/shared/optionTypes.d.ts +9 -2
- package/dist/commands/shared/outputFile.js +6 -1
- package/dist/commands/start.d.ts +20 -5
- package/dist/commands/start.js +84 -23
- package/dist/commands/stop.d.ts +11 -0
- package/dist/commands/stop.js +24 -1
- package/dist/commands/tail.d.ts +7 -1
- package/dist/commands/tail.js +13 -62
- package/dist/commands.js +2 -0
- package/dist/connection/cdp.d.ts +7 -0
- package/dist/connection/cdp.js +9 -0
- package/dist/connection/launcher.js +3 -2
- package/dist/daemon/SessionController.js +6 -1
- package/dist/daemon/launcher.d.ts +3 -2
- package/dist/daemon/launcher.js +47 -3
- package/dist/daemon/session/Session.d.ts +4 -1
- package/dist/daemon/session/Session.js +33 -2
- package/dist/daemon/session/TelemetryStore.d.ts +8 -1
- package/dist/daemon/session/TelemetryStore.js +13 -1
- package/dist/daemon/session/commandRegistry.js +36 -14
- package/dist/daemon/session/interactions.d.ts +2 -1
- package/dist/daemon/session/interactions.js +13 -1
- package/dist/daemon/session/plugins.js +19 -53
- package/dist/daemon/session/teardown.js +1 -1
- package/dist/daemon.js +9234 -7222
- package/dist/errors/messages.d.ts +88 -15
- package/dist/errors/messages.js +177 -27
- package/dist/index.js +19322 -13961
- package/dist/ipc/client.d.ts +22 -2
- package/dist/ipc/client.js +34 -5
- package/dist/ipc/protocol/auditTypes.d.ts +135 -0
- package/dist/ipc/protocol/auditTypes.js +6 -0
- package/dist/ipc/protocol/commands.d.ts +35 -0
- package/dist/ipc/protocol/commands.js +2 -0
- package/dist/ipc/protocol/domTypes.d.ts +16 -0
- package/dist/ipc/protocol/inspectTypes.d.ts +73 -8
- package/dist/ipc/session/types.d.ts +2 -0
- package/dist/runtime/css/search.d.ts +39 -0
- package/dist/runtime/css/search.js +122 -0
- package/dist/runtime/dom/actionEffects.d.ts +9 -2
- package/dist/runtime/dom/actionEffects.js +30 -14
- package/dist/runtime/dom/audit.d.ts +19 -0
- package/dist/runtime/dom/audit.js +37 -0
- package/dist/runtime/dom/auditModel.d.ts +45 -0
- package/dist/runtime/dom/auditModel.js +220 -0
- package/dist/runtime/dom/auditScripts.d.ts +113 -0
- package/dist/runtime/dom/auditScripts.js +148 -0
- package/dist/runtime/dom/elementGeometry.d.ts +16 -3
- package/dist/runtime/dom/elementGeometry.js +49 -10
- package/dist/runtime/dom/elementInfo.d.ts +74 -17
- package/dist/runtime/dom/elementInfo.js +187 -34
- package/dist/runtime/dom/evalHelpers.d.ts +12 -2
- package/dist/runtime/dom/evalHelpers.js +67 -7
- package/dist/runtime/dom/formDiscovery.d.ts +6 -2
- package/dist/runtime/dom/formDiscovery.js +20 -3
- package/dist/runtime/dom/formFillHelpers/fill.js +8 -12
- package/dist/runtime/dom/formFillHelpers/pressKey.js +2 -2
- package/dist/runtime/dom/formFillHelpers/shared.d.ts +16 -10
- package/dist/runtime/dom/formFillHelpers/shared.js +19 -52
- package/dist/runtime/dom/formSubmitHelpers.js +4 -3
- package/dist/runtime/dom/frameLayout.js +1 -0
- package/dist/runtime/dom/inspect.d.ts +7 -0
- package/dist/runtime/dom/inspect.js +92 -28
- package/dist/runtime/dom/inspectAllStyles.d.ts +16 -4
- package/dist/runtime/dom/inspectAllStyles.js +90 -7
- package/dist/runtime/dom/inspectCascade.d.ts +19 -2
- package/dist/runtime/dom/inspectCascade.js +214 -44
- package/dist/runtime/dom/inspectCascadeModel.d.ts +8 -0
- package/dist/runtime/dom/inspectCascadeModel.js +108 -34
- package/dist/runtime/dom/inspectHints.d.ts +26 -3
- package/dist/runtime/dom/inspectHints.js +125 -9
- package/dist/runtime/dom/inspectModel.d.ts +5 -1
- package/dist/runtime/dom/inspectModel.js +37 -10
- package/dist/runtime/dom/inspectPaintModel.d.ts +50 -22
- package/dist/runtime/dom/inspectPaintModel.js +182 -68
- package/dist/runtime/dom/inspectRules.d.ts +19 -0
- package/dist/runtime/dom/inspectRules.js +21 -5
- package/dist/runtime/dom/inspectScripts.d.ts +112 -12
- package/dist/runtime/dom/inspectScripts.js +357 -32
- package/dist/runtime/dom/inspectTree.js +10 -2
- package/dist/runtime/dom/inspectWhyModel.d.ts +2 -1
- package/dist/runtime/dom/inspectWhyModel.js +52 -10
- package/dist/runtime/dom/layout.js +40 -16
- package/dist/runtime/dom/reactEventHelpers.d.ts +21 -4
- package/dist/runtime/dom/reactEventHelpers.js +90 -36
- package/dist/runtime/dom/targetNode.d.ts +18 -5
- package/dist/runtime/dom/targetNode.js +268 -8
- package/dist/runtime/dom/wait.js +2 -1
- package/dist/runtime/page/bdgWorld.d.ts +57 -0
- package/dist/runtime/page/bdgWorld.js +180 -0
- package/dist/runtime/page/emulation.d.ts +13 -4
- package/dist/runtime/page/emulation.js +69 -4
- package/dist/runtime/page/replacedBuiltins.d.ts +28 -0
- package/dist/runtime/page/replacedBuiltins.js +136 -0
- package/dist/runtime/page/userAgent.d.ts +17 -0
- package/dist/runtime/page/userAgent.js +57 -0
- package/dist/session/QueryCacheManager.d.ts +4 -1
- package/dist/session/QueryCacheManager.js +5 -2
- package/dist/session/chrome.d.ts +4 -1
- package/dist/session/chrome.js +7 -1
- package/dist/session/cleanup/staleSession.d.ts +21 -4
- package/dist/session/cleanup/staleSession.js +79 -9
- package/dist/session/cleanup/userCommands.d.ts +4 -1
- package/dist/session/cleanup/userCommands.js +10 -5
- package/dist/session/daemonSocket.d.ts +10 -0
- package/dist/session/daemonSocket.js +22 -0
- package/dist/session/lastSession.d.ts +6 -3
- package/dist/session/lastSession.js +11 -5
- package/dist/session/paths.d.ts +3 -1
- package/dist/session/paths.js +5 -5
- package/dist/session/portClaims.js +4 -3
- package/dist/session/sessionList.d.ts +13 -5
- package/dist/session/sessionList.js +31 -7
- package/dist/telemetry/a11y.js +2 -2
- package/dist/telemetry/console.d.ts +2 -1
- package/dist/telemetry/console.js +30 -21
- package/dist/telemetry/pageCrash.d.ts +26 -0
- package/dist/telemetry/pageCrash.js +53 -0
- package/dist/types.d.ts +20 -0
- package/dist/ui/formatters/audit.d.ts +19 -0
- package/dist/ui/formatters/audit.js +115 -0
- package/dist/ui/formatters/cdp.d.ts +138 -0
- package/dist/ui/formatters/cdp.js +131 -0
- package/dist/ui/formatters/console/chronological.js +3 -1
- package/dist/ui/formatters/console/follow.d.ts +2 -1
- package/dist/ui/formatters/console/follow.js +2 -2
- package/dist/ui/formatters/console/json.d.ts +2 -2
- package/dist/ui/formatters/console/json.js +11 -5
- package/dist/ui/formatters/console/shared.d.ts +30 -0
- package/dist/ui/formatters/console/shared.js +16 -0
- package/dist/ui/formatters/console/summarize.d.ts +9 -2
- package/dist/ui/formatters/console/summarize.js +40 -9
- package/dist/ui/formatters/console.d.ts +2 -1
- package/dist/ui/formatters/console.js +7 -5
- package/dist/ui/formatters/details.js +3 -1
- package/dist/ui/formatters/dom.d.ts +2 -2
- package/dist/ui/formatters/dom.js +10 -8
- package/dist/ui/formatters/helpFormatters.js +1 -1
- package/dist/ui/formatters/inspect.js +50 -17
- package/dist/ui/formatters/installSkill.d.ts +9 -1
- package/dist/ui/formatters/installSkill.js +32 -6
- package/dist/ui/formatters/layout.js +2 -1
- package/dist/ui/formatters/networkList.d.ts +1 -1
- package/dist/ui/formatters/networkList.js +1 -2
- package/dist/ui/formatters/preview.d.ts +2 -0
- package/dist/ui/formatters/preview.js +17 -7
- package/dist/ui/formatters/sessions.d.ts +2 -2
- package/dist/ui/formatters/sessions.js +9 -2
- package/dist/ui/formatters/status.js +1 -1
- package/dist/ui/logging/logger.d.ts +1 -1
- package/dist/ui/messages/commands.d.ts +168 -11
- package/dist/ui/messages/commands.js +245 -18
- package/dist/ui/messages/consoleMessages.d.ts +24 -0
- package/dist/ui/messages/consoleMessages.js +32 -0
- package/dist/ui/messages/preview.d.ts +12 -0
- package/dist/ui/messages/preview.js +18 -2
- package/dist/ui/messages/session.d.ts +13 -2
- package/dist/ui/messages/session.js +22 -3
- package/dist/utils/cssValues.js +36 -4
- package/dist/utils/decisionTrees.js +0 -5
- package/dist/utils/directories.d.ts +34 -0
- package/dist/utils/directories.js +88 -0
- package/dist/utils/display.d.ts +16 -0
- package/dist/utils/display.js +42 -0
- package/dist/utils/exitCodes.d.ts +1 -0
- package/dist/utils/exitCodes.js +6 -0
- package/dist/utils/process.d.ts +12 -0
- package/dist/utils/process.js +25 -0
- package/dist/utils/suggestions.d.ts +4 -2
- package/dist/utils/suggestions.js +7 -5
- package/dist/utils/taskMappings.js +1 -1
- package/package.json +3 -2
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
*
|
|
4
4
|
* `--all` lists every computed longhand that is not noise and not its
|
|
5
5
|
* default, collapsed into shorthands (margin, padding, inset, border,
|
|
6
|
-
* radius, overflow, gap, flex, grid area, outline, animation). Defaults are
|
|
6
|
+
* radius, overflow, gap, flex, grid area, outline, animation, transition). Defaults are
|
|
7
7
|
* the CSS initial values as Chrome computes them; the UA stylesheet's
|
|
8
8
|
* per-tag values (a `<p>`'s margins, a button's padding) are real values and
|
|
9
9
|
* are listed. Display, font, size, line height and color are always listed.
|
|
10
10
|
*
|
|
11
11
|
* Noise: custom properties, logical duplicates of physical properties,
|
|
12
|
-
* width/height (in the header),
|
|
12
|
+
* width/height (in the header), origins without a transform,
|
|
13
13
|
* colors that only repeat `color` (currentColor), properties of borders,
|
|
14
14
|
* outlines and rules that are not drawn, SVG paint properties on HTML
|
|
15
15
|
* elements, and vendor-prefixed internals.
|
|
@@ -98,6 +98,28 @@ const INITIAL_BY_VALUE = [
|
|
|
98
98
|
['collapse', 'white-space-collapse'],
|
|
99
99
|
['horizontal-tb', 'writing-mode'],
|
|
100
100
|
['isolate', 'unicode-bidi'],
|
|
101
|
+
['rgb(0, 0, 0)', 'fill flood-color stop-color'],
|
|
102
|
+
['1', 'fill-opacity flood-opacity stop-opacity stroke-opacity'],
|
|
103
|
+
['rgb(255, 255, 255)', 'lighting-color'],
|
|
104
|
+
['1px', 'stroke-width'],
|
|
105
|
+
['4', 'stroke-miterlimit'],
|
|
106
|
+
['butt', 'stroke-linecap'],
|
|
107
|
+
['miter', 'stroke-linejoin'],
|
|
108
|
+
['nonzero', 'fill-rule clip-rule'],
|
|
109
|
+
['none', 'stroke stroke-dasharray marker-start marker-mid marker-end vector-effect'],
|
|
110
|
+
['0px', 'stroke-dashoffset baseline-shift'],
|
|
111
|
+
[
|
|
112
|
+
'auto',
|
|
113
|
+
'shape-rendering dominant-baseline alignment-baseline buffered-rendering color-rendering',
|
|
114
|
+
],
|
|
115
|
+
['srgb', 'color-interpolation'],
|
|
116
|
+
['linearrgb', 'color-interpolation-filters'],
|
|
117
|
+
['all', 'transition-property'],
|
|
118
|
+
['0s', 'transition-duration transition-delay'],
|
|
119
|
+
['ease', 'transition-timing-function'],
|
|
120
|
+
['normal', 'transition-behavior paint-order'],
|
|
121
|
+
['start', 'text-anchor'],
|
|
122
|
+
['rgba(0, 0, 0, 0.18)', '-webkit-tap-highlight-color'],
|
|
101
123
|
];
|
|
102
124
|
/** Initial value per property ({@link INITIAL_BY_VALUE}) */
|
|
103
125
|
const INITIAL_VALUES = new Map(INITIAL_BY_VALUE.flatMap(([value, names]) => names.split(' ').map((name) => [name, value])));
|
|
@@ -144,9 +166,11 @@ const NOISE = new Set([
|
|
|
144
166
|
const LOGICAL = /((^|-)block(-|$)|(^|-)inline(-|$)|^inset-|-start-start|-start-end|-end-end|-end-start)/;
|
|
145
167
|
/** Vendor-prefixed properties worth listing */
|
|
146
168
|
const PREFIXED_KEPT = new Set([
|
|
169
|
+
'-webkit-tap-highlight-color',
|
|
147
170
|
'-webkit-line-clamp',
|
|
148
171
|
'-webkit-text-stroke-width',
|
|
149
172
|
'-webkit-text-security',
|
|
173
|
+
'-webkit-text-fill-color',
|
|
150
174
|
]);
|
|
151
175
|
/** SVG paint and geometry properties (noise on HTML elements) */
|
|
152
176
|
const SVG_ONLY = /^(fill|fill-opacity|fill-rule|stroke|stroke-.*|stop-.*|flood-.*|lighting-color|marker-.*|clip-rule|color-interpolation.*|color-rendering|shape-rendering|text-anchor|dominant-baseline|alignment-baseline|baseline-shift|vector-effect|buffered-rendering|paint-order|mask-type)$/;
|
|
@@ -161,7 +185,9 @@ const CURRENT_COLOR_ECHOES = /^(border-(top|right|bottom|left)-color|outline-col
|
|
|
161
185
|
* @returns True when it is left out
|
|
162
186
|
*/
|
|
163
187
|
function isNoise(name, style, svg) {
|
|
164
|
-
if (name.startsWith('--') || NOISE.has(name)
|
|
188
|
+
if (name.startsWith('--') || NOISE.has(name))
|
|
189
|
+
return true;
|
|
190
|
+
if (name.startsWith('transition') && style['transition-duration'] === '0s')
|
|
165
191
|
return true;
|
|
166
192
|
if (LOGICAL.test(name) && !name.endsWith('-axis'))
|
|
167
193
|
return true;
|
|
@@ -266,7 +292,56 @@ const COLLAPSES = [
|
|
|
266
292
|
],
|
|
267
293
|
write: (v) => v.join(' '),
|
|
268
294
|
},
|
|
295
|
+
{
|
|
296
|
+
shorthand: 'transition',
|
|
297
|
+
longhands: [
|
|
298
|
+
'transition-property',
|
|
299
|
+
'transition-duration',
|
|
300
|
+
'transition-timing-function',
|
|
301
|
+
'transition-delay',
|
|
302
|
+
'transition-behavior',
|
|
303
|
+
],
|
|
304
|
+
write: transitionList,
|
|
305
|
+
},
|
|
269
306
|
];
|
|
307
|
+
/**
|
|
308
|
+
* A transition list from its longhands' comma lists, one transition per
|
|
309
|
+
* property, defaults left out (`background-color 0.25s ease-in, opacity 0.2s`).
|
|
310
|
+
*
|
|
311
|
+
* @param values - Property, duration, timing function, delay and behavior lists
|
|
312
|
+
* @returns Transition shorthand
|
|
313
|
+
*/
|
|
314
|
+
function transitionList(values) {
|
|
315
|
+
const lists = values.map((value) => value.split(/,\s*(?![^(]*\))/));
|
|
316
|
+
const [properties = []] = lists;
|
|
317
|
+
return properties
|
|
318
|
+
.map((property, i) => {
|
|
319
|
+
const at = (list) => list?.[i % list.length] ?? '';
|
|
320
|
+
const [duration, timing, delay, behavior] = lists.slice(1).map(at);
|
|
321
|
+
return [
|
|
322
|
+
property,
|
|
323
|
+
duration,
|
|
324
|
+
timing === 'ease' ? '' : timing,
|
|
325
|
+
delay === '0s' ? '' : delay,
|
|
326
|
+
behavior === 'normal' ? '' : behavior,
|
|
327
|
+
]
|
|
328
|
+
.filter(Boolean)
|
|
329
|
+
.join(' ');
|
|
330
|
+
})
|
|
331
|
+
.join(', ');
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* A shorthand's computed value as `--all` writes it (`margin 0 8`,
|
|
335
|
+
* `outline 2 solid #f00`, `transition color 1s ease-in`).
|
|
336
|
+
*
|
|
337
|
+
* @param shorthand - Shorthand name
|
|
338
|
+
* @param style - Computed longhands
|
|
339
|
+
* @returns Value, or undefined for a shorthand `--all` does not collapse
|
|
340
|
+
*/
|
|
341
|
+
export function collapsedValue(shorthand, style) {
|
|
342
|
+
const group = COLLAPSES.find((entry) => entry.shorthand === shorthand);
|
|
343
|
+
return group?.write(group.longhands.map((longhand) => normalizeProperty(longhand, style[longhand] ?? '')));
|
|
344
|
+
}
|
|
270
345
|
/**
|
|
271
346
|
* Border longhands collapsed: one `border` when the four drawn sides are
|
|
272
347
|
* equal, else one entry per drawn side.
|
|
@@ -337,13 +412,15 @@ function isUnsetOffset(name, value, style) {
|
|
|
337
412
|
*
|
|
338
413
|
* @param style - Computed styles
|
|
339
414
|
* @param svg - The element is an SVG element (SVG properties are listed)
|
|
415
|
+
* @param formControl - A form control (`appearance: none` is not its default)
|
|
340
416
|
* @returns Properties and values
|
|
341
417
|
*/
|
|
342
|
-
export function allStyles(style, svg) {
|
|
418
|
+
export function allStyles(style, svg, formControl = false) {
|
|
343
419
|
const kept = new Map();
|
|
344
420
|
const transformed = (style['transform'] ?? 'none') !== 'none';
|
|
345
421
|
for (const [name, value] of Object.entries(style)) {
|
|
346
|
-
|
|
422
|
+
const set = (name === 'transform-origin' && transformed) || (name === 'appearance' && formControl);
|
|
423
|
+
if (set) {
|
|
347
424
|
kept.set(name, normalizeProperty(name, value));
|
|
348
425
|
continue;
|
|
349
426
|
}
|
|
@@ -364,10 +441,12 @@ export function allStyles(style, svg) {
|
|
|
364
441
|
* @param style - Computed longhands (CDP)
|
|
365
442
|
* @param pageValues - Values the page read
|
|
366
443
|
* @param pageUnknown - Names the page does not know as CSS properties
|
|
444
|
+
* @param rootFontSize - Root font size (px): a custom property that is one
|
|
445
|
+
* rem length is also given in px
|
|
367
446
|
* @returns Values by name (an unset custom property is empty), and the
|
|
368
447
|
* names that are not properties
|
|
369
448
|
*/
|
|
370
|
-
export function selectedProps(names, style, pageValues, pageUnknown = []) {
|
|
449
|
+
export function selectedProps(names, style, pageValues, pageUnknown = [], rootFontSize = 16) {
|
|
371
450
|
const props = {};
|
|
372
451
|
const unknown = [];
|
|
373
452
|
for (const name of names) {
|
|
@@ -377,7 +456,11 @@ export function selectedProps(names, style, pageValues, pageUnknown = []) {
|
|
|
377
456
|
unknown.push(name);
|
|
378
457
|
}
|
|
379
458
|
else {
|
|
380
|
-
|
|
459
|
+
const rem = name.startsWith('--') ? /^(-?\d*\.?\d+)rem$/.exec(computed.trim()) : null;
|
|
460
|
+
const value = rem
|
|
461
|
+
? String(Math.round(Number(rem[1]) * rootFontSize * 10) / 10)
|
|
462
|
+
: normalizeProperty(name, computed);
|
|
463
|
+
props[name] = { computed, value };
|
|
381
464
|
}
|
|
382
465
|
}
|
|
383
466
|
return { props, unknown };
|
|
@@ -32,6 +32,11 @@ export interface DeclarationSource {
|
|
|
32
32
|
condition?: string;
|
|
33
33
|
/** Specificity of the matching selector (ids, classes, types) */
|
|
34
34
|
specificity?: [number, number, number];
|
|
35
|
+
/** The rule as written, whitespace collapsed (no selector: the style attribute) */
|
|
36
|
+
rule?: {
|
|
37
|
+
selector?: string;
|
|
38
|
+
declarations: string;
|
|
39
|
+
};
|
|
35
40
|
}
|
|
36
41
|
/** One declaration of a longhand */
|
|
37
42
|
export interface Declaration {
|
|
@@ -66,9 +71,11 @@ export declare function shorthandLonghands(name: string): readonly string[] | un
|
|
|
66
71
|
* Whether a property inherits.
|
|
67
72
|
*
|
|
68
73
|
* @param property - Longhand
|
|
69
|
-
* @
|
|
74
|
+
* @param notInherited - Custom properties registered with `inherits: false`
|
|
75
|
+
* @returns True for inherited properties (custom properties inherit unless
|
|
76
|
+
* registered otherwise)
|
|
70
77
|
*/
|
|
71
|
-
export declare function isInherited(property: string): boolean;
|
|
78
|
+
export declare function isInherited(property: string, notInherited?: ReadonlySet<string>): boolean;
|
|
72
79
|
/**
|
|
73
80
|
* The physical longhand a logical property sets.
|
|
74
81
|
*
|
|
@@ -91,4 +98,14 @@ export declare function ownProperties(matched: Protocol.CSS.GetMatchedStylesForN
|
|
|
91
98
|
* @returns Resolution per property
|
|
92
99
|
*/
|
|
93
100
|
export declare function resolveCascade(matched: Protocol.CSS.GetMatchedStylesForNodeResponse, properties: readonly string[]): Map<string, Resolution>;
|
|
101
|
+
/**
|
|
102
|
+
* The rule a declaration is in, as written: whole when short, else its
|
|
103
|
+
* selector and that declaration (`.btn { … background-color:var(--bs-btn-bg); … }`).
|
|
104
|
+
*
|
|
105
|
+
* @param declaration - Declaration
|
|
106
|
+
* @returns `{ rule }`, or nothing for a browser, extension or attribute style
|
|
107
|
+
*/
|
|
108
|
+
export declare function ruleField(declaration: Declaration): {
|
|
109
|
+
rule?: string;
|
|
110
|
+
};
|
|
94
111
|
//# sourceMappingURL=inspectCascade.d.ts.map
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* writing). With no declaration of its own, an inherited property comes from
|
|
14
14
|
* the nearest ancestor that declares it.
|
|
15
15
|
*/
|
|
16
|
+
import { truncateByLength } from '../../utils/strings.js';
|
|
16
17
|
/**
|
|
17
18
|
* The four side longhands of a pattern.
|
|
18
19
|
*
|
|
@@ -64,9 +65,37 @@ const SHORTHANDS = {
|
|
|
64
65
|
`border-${side}`,
|
|
65
66
|
['width', 'style', 'color'].map((part) => `border-${side}-${part}`),
|
|
66
67
|
])),
|
|
67
|
-
background: [
|
|
68
|
+
background: [
|
|
69
|
+
'background-color',
|
|
70
|
+
'background-image',
|
|
71
|
+
'background-position-x',
|
|
72
|
+
'background-position-y',
|
|
73
|
+
'background-size',
|
|
74
|
+
'background-repeat',
|
|
75
|
+
'background-origin',
|
|
76
|
+
'background-clip',
|
|
77
|
+
'background-attachment',
|
|
78
|
+
],
|
|
68
79
|
font: ['font-style', 'font-weight', 'font-size', 'line-height', 'font-family'],
|
|
69
80
|
flex: ['flex-grow', 'flex-shrink', 'flex-basis'],
|
|
81
|
+
'flex-flow': ['flex-direction', 'flex-wrap'],
|
|
82
|
+
outline: ['outline-width', 'outline-style', 'outline-color'],
|
|
83
|
+
'text-decoration': [
|
|
84
|
+
'text-decoration-line',
|
|
85
|
+
'text-decoration-style',
|
|
86
|
+
'text-decoration-color',
|
|
87
|
+
'text-decoration-thickness',
|
|
88
|
+
],
|
|
89
|
+
transition: [
|
|
90
|
+
'transition-property',
|
|
91
|
+
'transition-duration',
|
|
92
|
+
'transition-timing-function',
|
|
93
|
+
'transition-delay',
|
|
94
|
+
'transition-behavior',
|
|
95
|
+
],
|
|
96
|
+
'background-position': ['background-position-x', 'background-position-y'],
|
|
97
|
+
'list-style': ['list-style-position', 'list-style-image', 'list-style-type'],
|
|
98
|
+
columns: ['column-width', 'column-count'],
|
|
70
99
|
'place-items': ['align-items', 'justify-items'],
|
|
71
100
|
'place-content': ['align-content', 'justify-content'],
|
|
72
101
|
'place-self': ['align-self', 'justify-self'],
|
|
@@ -91,35 +120,31 @@ const LOGICAL_SIDES = {
|
|
|
91
120
|
'inline-start': 'left',
|
|
92
121
|
'inline-end': 'right',
|
|
93
122
|
};
|
|
94
|
-
/**
|
|
123
|
+
/** Longhands that inherit (CSS, SVG and the prefixed ones Chrome computes) */
|
|
95
124
|
const INHERITED = new Set([
|
|
96
|
-
'color',
|
|
97
|
-
'font-family',
|
|
98
|
-
'font-
|
|
99
|
-
'font-
|
|
100
|
-
'font-
|
|
101
|
-
'font-variant',
|
|
102
|
-
'font-
|
|
103
|
-
'
|
|
104
|
-
'
|
|
105
|
-
'
|
|
106
|
-
'
|
|
107
|
-
'
|
|
108
|
-
'
|
|
109
|
-
'
|
|
110
|
-
'
|
|
111
|
-
'
|
|
112
|
-
'
|
|
113
|
-
'
|
|
114
|
-
'
|
|
115
|
-
'
|
|
116
|
-
'
|
|
117
|
-
'
|
|
118
|
-
|
|
119
|
-
'pointer-events',
|
|
120
|
-
'user-select',
|
|
121
|
-
'-webkit-text-security',
|
|
122
|
-
]);
|
|
125
|
+
'color caret-color accent-color color-scheme forced-color-adjust print-color-adjust',
|
|
126
|
+
'font-family font-size font-style font-weight font-stretch font-size-adjust font-kerning',
|
|
127
|
+
'font-optical-sizing font-palette font-language-override font-feature-settings',
|
|
128
|
+
'font-variation-settings font-variant font-variant-caps font-variant-ligatures',
|
|
129
|
+
'font-variant-numeric font-variant-east-asian font-variant-alternates',
|
|
130
|
+
'font-variant-position font-variant-emoji font-synthesis-weight font-synthesis-style',
|
|
131
|
+
'font-synthesis-small-caps line-height letter-spacing word-spacing text-align',
|
|
132
|
+
'text-align-last text-indent text-justify text-transform text-shadow text-rendering',
|
|
133
|
+
'text-size-adjust text-underline-position text-underline-offset text-decoration-skip-ink',
|
|
134
|
+
'text-emphasis-style text-emphasis-color text-emphasis-position text-orientation',
|
|
135
|
+
'text-wrap-mode text-wrap-style text-spacing-trim text-autospace white-space-collapse',
|
|
136
|
+
'word-break overflow-wrap line-break hyphens hyphenate-character hyphenate-limit-chars',
|
|
137
|
+
'tab-size direction writing-mode ruby-position ruby-align visibility cursor',
|
|
138
|
+
'pointer-events user-select interpolate-size list-style-type list-style-position',
|
|
139
|
+
'list-style-image quotes border-collapse border-spacing caption-side empty-cells orphans',
|
|
140
|
+
'widows image-rendering fill fill-opacity fill-rule stroke stroke-width stroke-opacity',
|
|
141
|
+
'stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit',
|
|
142
|
+
'paint-order marker-start marker-mid marker-end clip-rule color-interpolation',
|
|
143
|
+
'color-interpolation-filters color-rendering shape-rendering text-anchor dominant-baseline',
|
|
144
|
+
'math-depth math-style math-shift scrollbar-color text-combine-upright',
|
|
145
|
+
'-webkit-text-security -webkit-text-fill-color',
|
|
146
|
+
'-webkit-text-stroke-color -webkit-text-stroke-width',
|
|
147
|
+
].flatMap((names) => names.split(' ')));
|
|
123
148
|
/**
|
|
124
149
|
* The longhands of a shorthand.
|
|
125
150
|
*
|
|
@@ -133,10 +158,30 @@ export function shorthandLonghands(name) {
|
|
|
133
158
|
* Whether a property inherits.
|
|
134
159
|
*
|
|
135
160
|
* @param property - Longhand
|
|
136
|
-
* @
|
|
161
|
+
* @param notInherited - Custom properties registered with `inherits: false`
|
|
162
|
+
* @returns True for inherited properties (custom properties inherit unless
|
|
163
|
+
* registered otherwise)
|
|
164
|
+
*/
|
|
165
|
+
export function isInherited(property, notInherited) {
|
|
166
|
+
if (property.startsWith('--'))
|
|
167
|
+
return !notInherited?.has(property);
|
|
168
|
+
return INHERITED.has(property);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Custom properties registered not to inherit, with `@property` or
|
|
172
|
+
* `CSS.registerProperty`.
|
|
173
|
+
*
|
|
174
|
+
* @param matched - `CSS.getMatchedStylesForNode` response
|
|
175
|
+
* @returns Their names
|
|
137
176
|
*/
|
|
138
|
-
|
|
139
|
-
|
|
177
|
+
function nonInheritingProperties(matched) {
|
|
178
|
+
const fromRules = (matched.cssPropertyRules ?? [])
|
|
179
|
+
.filter((rule) => rule.style.cssProperties.some((property) => property.name === 'inherits' && property.value.trim() === 'false'))
|
|
180
|
+
.map((rule) => rule.propertyName.text);
|
|
181
|
+
const fromScript = (matched.cssPropertyRegistrations ?? [])
|
|
182
|
+
.filter((registration) => !registration.inherits)
|
|
183
|
+
.map((registration) => registration.propertyName);
|
|
184
|
+
return new Set([...fromRules, ...fromScript]);
|
|
140
185
|
}
|
|
141
186
|
/**
|
|
142
187
|
* The physical longhand a logical property sets.
|
|
@@ -211,23 +256,43 @@ function declarationsOf(style, source) {
|
|
|
211
256
|
});
|
|
212
257
|
}
|
|
213
258
|
/**
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
259
|
+
* The selector of a rule's list that matched with the highest specificity
|
|
260
|
+
* (the one the cascade uses: `.title` of `h1, .title`).
|
|
261
|
+
*
|
|
262
|
+
* @param match - CDP rule match
|
|
263
|
+
* @returns Selector
|
|
264
|
+
*/
|
|
265
|
+
function strongestMatchingSelector(match) {
|
|
266
|
+
const weight = (value) => {
|
|
267
|
+
const s = value?.specificity;
|
|
268
|
+
return s ? s.a * 1e6 + s.b * 1e3 + s.c : -1;
|
|
269
|
+
};
|
|
270
|
+
const selectors = match.rule.selectorList.selectors;
|
|
271
|
+
const matching = match.matchingSelectors.map((index) => selectors[index]);
|
|
272
|
+
return (matching.reduce((best, value) => (weight(value) > weight(best) ? value : best), matching[0]) ??
|
|
273
|
+
selectors[0]);
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Source of a matched rule: its matching selector (the strongest of a list),
|
|
277
|
+
* origin, stylesheet, layer (nested ones as `outer.inner`), the media,
|
|
278
|
+
* container, `@supports` and `@scope` conditions it is under (`not all and
|
|
279
|
+
* (…)`, as Chrome writes `not (…)`, shortened) and the selector's specificity.
|
|
218
280
|
*
|
|
219
281
|
* @param match - CDP rule match
|
|
220
282
|
* @returns Declaration source
|
|
221
283
|
*/
|
|
222
284
|
function ruleSource(match) {
|
|
223
285
|
const { rule } = match;
|
|
224
|
-
const matching =
|
|
286
|
+
const matching = strongestMatchingSelector(match);
|
|
225
287
|
const selector = matching?.text ?? rule.selectorList.text;
|
|
226
288
|
const layer = rule.layers?.map((l) => l.text || '(anonymous)').join('.');
|
|
227
|
-
const condition = [
|
|
228
|
-
.map((c) => c.text.replace(/^not all and /, 'not '))
|
|
229
|
-
.
|
|
289
|
+
const condition = [
|
|
290
|
+
...[...(rule.media ?? []), ...(rule.containerQueries ?? [])].map((c) => c.text.replace(/^not all and /, 'not ')),
|
|
291
|
+
...(rule.supports ?? []).map((c) => `supports ${c.text}`),
|
|
292
|
+
...(rule.scopes ?? []).map((c) => `scope ${c.text}`),
|
|
293
|
+
].join(' and ');
|
|
230
294
|
const specificity = matching?.specificity;
|
|
295
|
+
const declarations = rule.style.cssText;
|
|
231
296
|
return {
|
|
232
297
|
kind: 'rule',
|
|
233
298
|
selector,
|
|
@@ -236,6 +301,9 @@ function ruleSource(match) {
|
|
|
236
301
|
...(rule.styleSheetId && { styleSheetId: rule.styleSheetId }),
|
|
237
302
|
...(layer && { layer }),
|
|
238
303
|
...(condition && { condition }),
|
|
304
|
+
...(declarations && {
|
|
305
|
+
rule: { selector: collapse(rule.selectorList.text), declarations: collapse(declarations) },
|
|
306
|
+
}),
|
|
239
307
|
};
|
|
240
308
|
}
|
|
241
309
|
/**
|
|
@@ -248,9 +316,23 @@ function orderedDeclarations(entry) {
|
|
|
248
316
|
return [
|
|
249
317
|
...declarationsOf(entry.attributesStyle, { kind: 'attribute' }),
|
|
250
318
|
...(entry.matchedCSSRules ?? []).flatMap((match) => declarationsOf(match.rule.style, ruleSource(match))),
|
|
251
|
-
...declarationsOf(entry.inlineStyle, {
|
|
319
|
+
...declarationsOf(entry.inlineStyle, {
|
|
320
|
+
kind: 'inline',
|
|
321
|
+
...(entry.inlineStyle?.cssText && {
|
|
322
|
+
rule: { declarations: collapse(entry.inlineStyle.cssText) },
|
|
323
|
+
}),
|
|
324
|
+
}),
|
|
252
325
|
];
|
|
253
326
|
}
|
|
327
|
+
/**
|
|
328
|
+
* Text with runs of whitespace collapsed to one space.
|
|
329
|
+
*
|
|
330
|
+
* @param text - CSS text
|
|
331
|
+
* @returns Collapsed, trimmed
|
|
332
|
+
*/
|
|
333
|
+
function collapse(text) {
|
|
334
|
+
return text.replace(/\s+/g, ' ').trim();
|
|
335
|
+
}
|
|
254
336
|
/**
|
|
255
337
|
* Whether a declaration comes from the page's authors (not the browser's
|
|
256
338
|
* own stylesheet or an extension's).
|
|
@@ -337,6 +419,7 @@ export function ownProperties(matched) {
|
|
|
337
419
|
export function resolveCascade(matched, properties) {
|
|
338
420
|
const own = orderedDeclarations(matched);
|
|
339
421
|
const ancestors = (matched.inherited ?? []).map(orderedDeclarations);
|
|
422
|
+
const notInherited = nonInheritingProperties(matched);
|
|
340
423
|
const resolved = new Map();
|
|
341
424
|
for (const property of properties) {
|
|
342
425
|
const ranked = byPrecedence(own.filter((d) => d.property === property));
|
|
@@ -345,7 +428,7 @@ export function resolveCascade(matched, properties) {
|
|
|
345
428
|
resolved.set(property, { winner, overridden });
|
|
346
429
|
continue;
|
|
347
430
|
}
|
|
348
|
-
resolved.set(property, inheritedWinner(property, ancestors));
|
|
431
|
+
resolved.set(property, inheritedWinner(property, ancestors, notInherited));
|
|
349
432
|
}
|
|
350
433
|
return resolved;
|
|
351
434
|
}
|
|
@@ -354,11 +437,12 @@ export function resolveCascade(matched, properties) {
|
|
|
354
437
|
*
|
|
355
438
|
* @param property - Longhand
|
|
356
439
|
* @param ancestors - Declarations of each ancestor, nearest first
|
|
440
|
+
* @param notInherited - Custom properties registered not to inherit
|
|
357
441
|
* @returns The winner and the declarations it beat on that ancestor (none for
|
|
358
442
|
* non-inherited properties or when no ancestor sets it)
|
|
359
443
|
*/
|
|
360
|
-
function inheritedWinner(property, ancestors) {
|
|
361
|
-
if (!isInherited(property))
|
|
444
|
+
function inheritedWinner(property, ancestors, notInherited) {
|
|
445
|
+
if (!isInherited(property, notInherited))
|
|
362
446
|
return { overridden: [] };
|
|
363
447
|
for (const [depth, declarations] of ancestors.entries()) {
|
|
364
448
|
const ranked = byPrecedence(declarations.filter((d) => d.property === property)).map((declaration) => ({ ...declaration, ancestor: depth + 1 }));
|
|
@@ -368,4 +452,90 @@ function inheritedWinner(property, ancestors) {
|
|
|
368
452
|
}
|
|
369
453
|
return { overridden: [] };
|
|
370
454
|
}
|
|
455
|
+
/** Longest rule given whole; a longer one (minified CSS) is cut to the declaration */
|
|
456
|
+
const RULE_TEXT_LENGTH = 300;
|
|
457
|
+
/**
|
|
458
|
+
* The rule a declaration is in, as written: whole when short, else its
|
|
459
|
+
* selector and that declaration (`.btn { … background-color:var(--bs-btn-bg); … }`).
|
|
460
|
+
*
|
|
461
|
+
* @param declaration - Declaration
|
|
462
|
+
* @returns `{ rule }`, or nothing for a browser, extension or attribute style
|
|
463
|
+
*/
|
|
464
|
+
export function ruleField(declaration) {
|
|
465
|
+
const { rule } = declaration.source;
|
|
466
|
+
if (!rule || !isAuthor(declaration))
|
|
467
|
+
return {};
|
|
468
|
+
const whole = ruleText(rule.selector, rule.declarations);
|
|
469
|
+
if (whole.length <= RULE_TEXT_LENGTH)
|
|
470
|
+
return { rule: whole };
|
|
471
|
+
const own = lastDeclarationOf(rule.declarations, declaration.via ?? declaration.property);
|
|
472
|
+
if (!own)
|
|
473
|
+
return { rule: truncateByLength(whole, RULE_TEXT_LENGTH) };
|
|
474
|
+
const selector = rule.selector === undefined ? undefined : truncateByLength(rule.selector, 80);
|
|
475
|
+
return { rule: ruleText(selector, `… ${truncateByLength(own, RULE_TEXT_LENGTH - 100)}; …`) };
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* A rule's text: `selector { declarations }`, or `style="declarations"`.
|
|
479
|
+
*
|
|
480
|
+
* @param selector - Selector (absent: the style attribute)
|
|
481
|
+
* @param declarations - Declarations
|
|
482
|
+
* @returns Text
|
|
483
|
+
*/
|
|
484
|
+
function ruleText(selector, declarations) {
|
|
485
|
+
return selector === undefined
|
|
486
|
+
? `style="${declarations.replaceAll('"', '\\"')}"`
|
|
487
|
+
: `${selector} { ${declarations} }`;
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* The last declaration of a property in a declaration block (the one that
|
|
491
|
+
* counts when it is repeated), split at semicolons outside strings and
|
|
492
|
+
* parentheses (`url(data:image/png;base64,…)` stays whole).
|
|
493
|
+
*
|
|
494
|
+
* @param declarations - Declaration block
|
|
495
|
+
* @param property - Property as written (custom properties are case-sensitive)
|
|
496
|
+
* @returns The declaration, without its semicolon
|
|
497
|
+
*/
|
|
498
|
+
function lastDeclarationOf(declarations, property) {
|
|
499
|
+
const name = (part) => {
|
|
500
|
+
const raw = part.slice(0, part.indexOf(':')).trim();
|
|
501
|
+
return raw.startsWith('--') ? raw : raw.toLowerCase();
|
|
502
|
+
};
|
|
503
|
+
const wanted = property.startsWith('--') ? property : property.toLowerCase();
|
|
504
|
+
return splitDeclarations(declarations)
|
|
505
|
+
.filter((part) => part.includes(':') && name(part) === wanted)
|
|
506
|
+
.at(-1);
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Split a declaration block at its top-level semicolons.
|
|
510
|
+
*
|
|
511
|
+
* @param block - Declarations
|
|
512
|
+
* @returns Declarations, trimmed, empty ones dropped
|
|
513
|
+
*/
|
|
514
|
+
function splitDeclarations(block) {
|
|
515
|
+
const parts = [];
|
|
516
|
+
let depth = 0;
|
|
517
|
+
let quote;
|
|
518
|
+
let start = 0;
|
|
519
|
+
for (let i = 0; i < block.length; i++) {
|
|
520
|
+
const char = block[i];
|
|
521
|
+
if (quote) {
|
|
522
|
+
if (char === '\\')
|
|
523
|
+
i++;
|
|
524
|
+
else if (char === quote)
|
|
525
|
+
quote = undefined;
|
|
526
|
+
}
|
|
527
|
+
else if (char === '"' || char === "'")
|
|
528
|
+
quote = char;
|
|
529
|
+
else if (char === '(')
|
|
530
|
+
depth++;
|
|
531
|
+
else if (char === ')')
|
|
532
|
+
depth = Math.max(0, depth - 1);
|
|
533
|
+
else if (char === ';' && depth === 0) {
|
|
534
|
+
parts.push(block.slice(start, i));
|
|
535
|
+
start = i + 1;
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
parts.push(block.slice(start));
|
|
539
|
+
return parts.map((part) => part.trim()).filter(Boolean);
|
|
540
|
+
}
|
|
371
541
|
//# sourceMappingURL=inspectCascade.js.map
|
|
@@ -8,6 +8,7 @@ import type { Protocol } from '../../connection/typed-cdp.js';
|
|
|
8
8
|
import type { InspectResult } from '../../ipc/protocol/inspectTypes.js';
|
|
9
9
|
import { type Declaration } from './inspectCascade.js';
|
|
10
10
|
import type { StyleMap } from './inspectLayoutModel.js';
|
|
11
|
+
import type { InactiveRule } from './inspectScripts.js';
|
|
11
12
|
/** Longhands reported together, so a shorthand can stand for its sides */
|
|
12
13
|
export interface PropertyGroup {
|
|
13
14
|
shorthand?: string;
|
|
@@ -25,8 +26,15 @@ export interface CascadeInput {
|
|
|
25
26
|
why?: string;
|
|
26
27
|
/** `--props` names: `--rules` then covers only these */
|
|
27
28
|
props?: string[];
|
|
29
|
+
/** Longhands of the `--why` shorthand as the browser expands it */
|
|
30
|
+
whyLonghands?: string[];
|
|
31
|
+
/** Computed value of the `--why` shorthand, as the page writes it */
|
|
32
|
+
whyComputed?: string;
|
|
33
|
+
/** Rules that set the `--why` property under a condition that does not apply now */
|
|
34
|
+
whyInactive?: InactiveRule[];
|
|
28
35
|
/** Check for declarations that have no effect (default true) */
|
|
29
36
|
hints?: boolean;
|
|
37
|
+
/** A form control that draws text (its font is checked against the parent's) */
|
|
30
38
|
formControl?: boolean;
|
|
31
39
|
}
|
|
32
40
|
/**
|