browser-debugger-cli 0.9.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 +4 -1
- package/dist/commands/dom/a11y.js +2 -1
- package/dist/commands/dom/formInteraction.js +56 -25
- 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 +1 -1
- package/dist/commands/dom/helpers/query.js +66 -19
- package/dist/commands/dom/helpers/runElementCommand.js +4 -3
- package/dist/commands/dom/helpers/screenshot.js +85 -12
- package/dist/commands/dom/index.d.ts +1 -0
- package/dist/commands/dom/index.js +8 -3
- package/dist/commands/dom/inspect.d.ts +15 -0
- package/dist/commands/dom/inspect.js +82 -0
- package/dist/commands/dom/layout.js +2 -2
- package/dist/commands/dom/listeners.js +2 -2
- package/dist/commands/dom/semanticUtils.d.ts +14 -1
- package/dist/commands/dom/semanticUtils.js +44 -3
- package/dist/commands/network/list.js +13 -2
- package/dist/commands/optionBehaviors.js +48 -6
- package/dist/commands/page.d.ts +1 -1
- package/dist/commands/page.js +62 -3
- package/dist/commands/shared/commonOptions.d.ts +4 -0
- package/dist/commands/shared/commonOptions.js +9 -0
- package/dist/commands/shared/optionTypes.d.ts +21 -0
- package/dist/commands/shared/startHelpers.d.ts +66 -0
- package/dist/commands/shared/startHelpers.js +91 -10
- package/dist/commands/shared/validation.d.ts +11 -0
- package/dist/commands/shared/validation.js +16 -0
- package/dist/daemon/launcher.d.ts +8 -1
- package/dist/daemon/launcher.js +3 -1
- package/dist/daemon/session/Session.d.ts +7 -0
- package/dist/daemon/session/Session.js +23 -1
- package/dist/daemon/session/commandRegistry.d.ts +14 -1
- package/dist/daemon/session/commandRegistry.js +65 -9
- package/dist/daemon/session/interactions.d.ts +18 -5
- package/dist/daemon/session/interactions.js +22 -12
- package/dist/daemon.js +3565 -329
- package/dist/errors/messages.d.ts +69 -0
- package/dist/errors/messages.js +102 -1
- package/dist/index.js +2416 -1320
- package/dist/ipc/client.d.ts +9 -0
- package/dist/ipc/client.js +13 -0
- package/dist/ipc/protocol/commands.d.ts +56 -1
- package/dist/ipc/protocol/commands.js +2 -0
- package/dist/ipc/protocol/domTypes.d.ts +35 -2
- package/dist/ipc/protocol/inspectTypes.d.ts +388 -0
- package/dist/ipc/protocol/inspectTypes.js +10 -0
- package/dist/runtime/dom/actionEffects.d.ts +94 -15
- package/dist/runtime/dom/actionEffects.js +173 -27
- package/dist/runtime/dom/actionEffectsScripts.d.ts +52 -14
- package/dist/runtime/dom/actionEffectsScripts.js +224 -32
- package/dist/runtime/dom/elementInfo.d.ts +26 -0
- package/dist/runtime/dom/elementInfo.js +65 -0
- package/dist/runtime/dom/eventListeners.js +14 -4
- package/dist/runtime/dom/formFillHelpers/fill.d.ts +3 -4
- package/dist/runtime/dom/formFillHelpers/fill.js +77 -28
- package/dist/runtime/dom/frameSelection.d.ts +11 -0
- package/dist/runtime/dom/frameSelection.js +20 -1
- package/dist/runtime/dom/frames.d.ts +38 -5
- package/dist/runtime/dom/frames.js +136 -21
- 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 +5 -1
- package/dist/runtime/dom/layout.js +10 -3
- package/dist/runtime/dom/listenerPageScripts.d.ts +11 -5
- package/dist/runtime/dom/listenerPageScripts.js +95 -9
- package/dist/runtime/dom/listenerSummary.d.ts +4 -0
- package/dist/runtime/dom/listenerSummary.js +26 -9
- package/dist/runtime/dom/reactEventHelpers.d.ts +5 -0
- package/dist/runtime/dom/reactEventHelpers.js +12 -4
- package/dist/runtime/page/emulation.d.ts +20 -0
- package/dist/runtime/page/emulation.js +37 -0
- package/dist/telemetry/a11y.d.ts +10 -0
- package/dist/telemetry/a11y.js +78 -1
- package/dist/telemetry/console.d.ts +1 -0
- package/dist/telemetry/console.js +100 -5
- package/dist/telemetry/network.js +3 -1
- package/dist/types.d.ts +32 -0
- package/dist/ui/formatters/details.d.ts +8 -0
- package/dist/ui/formatters/details.js +59 -3
- package/dist/ui/formatters/dom.d.ts +2 -1
- package/dist/ui/formatters/dom.js +25 -9
- 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.js +2 -2
- package/dist/ui/formatters/networkHeaders.d.ts +13 -0
- package/dist/ui/formatters/networkHeaders.js +23 -3
- package/dist/ui/formatters/networkList.d.ts +29 -1
- package/dist/ui/formatters/networkList.js +86 -20
- package/dist/ui/formatters/status.js +1 -1
- package/dist/ui/formatting.d.ts +9 -0
- package/dist/ui/formatting.js +6 -3
- package/dist/ui/messages/commands.d.ts +123 -7
- package/dist/ui/messages/commands.js +181 -10
- package/dist/ui/messages/networkMessages.d.ts +14 -0
- package/dist/ui/messages/networkMessages.js +18 -0
- package/dist/ui/messages/session.d.ts +14 -0
- package/dist/ui/messages/session.js +20 -0
- package/dist/utils/async.d.ts +9 -0
- package/dist/utils/async.js +17 -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/selectorFilters.d.ts +12 -0
- package/dist/utils/selectorFilters.js +29 -0
- package/package.json +1 -1
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Declarations that have no effect, with why and what to change: Chrome
|
|
3
|
+
* DevTools' inactive-CSS rules (CSSRuleValidator) plus some of Firefox's,
|
|
4
|
+
* checked against authored declarations only (never the browser's own
|
|
5
|
+
* styles), and `var()` references to custom properties that are not set.
|
|
6
|
+
*/
|
|
7
|
+
import type { Declaration, Resolution } from './inspectCascade.js';
|
|
8
|
+
import type { StyleMap } from './inspectLayoutModel.js';
|
|
9
|
+
/** A declaration that has no effect */
|
|
10
|
+
export interface CssHint {
|
|
11
|
+
kind: 'inactive' | 'unset-variable' | 'not-inherited';
|
|
12
|
+
/** Property as written */
|
|
13
|
+
property: string;
|
|
14
|
+
/** Its value */
|
|
15
|
+
value: string;
|
|
16
|
+
/** Why it has no effect */
|
|
17
|
+
reason: string;
|
|
18
|
+
/** What would make it work */
|
|
19
|
+
fix: string;
|
|
20
|
+
/** The declaration */
|
|
21
|
+
declaration: Declaration;
|
|
22
|
+
}
|
|
23
|
+
/** What the checks look at */
|
|
24
|
+
interface HintContext {
|
|
25
|
+
style: StyleMap;
|
|
26
|
+
parentStyle: StyleMap | undefined;
|
|
27
|
+
/** The element is replaced (img, input, video…) */
|
|
28
|
+
replaced: boolean;
|
|
29
|
+
/** The element is a form control (input, textarea, select, button) */
|
|
30
|
+
formControl?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Declarations of the element that have no effect: every longhand a
|
|
34
|
+
* declaration wins is inactive (`margin: 0 4px` on an inline element still
|
|
35
|
+
* moves it sideways, `gap` on a multi-column block still spaces the columns).
|
|
36
|
+
*
|
|
37
|
+
* @param cascade - Resolved properties (winning declarations are checked)
|
|
38
|
+
* @param ctx - Computed styles of the element and its parent
|
|
39
|
+
* @returns Hints, in property order
|
|
40
|
+
*/
|
|
41
|
+
export declare function inactiveHints(cascade: Map<string, Resolution>, ctx: HintContext): CssHint[];
|
|
42
|
+
/**
|
|
43
|
+
* Winning declarations that use a custom property that is not set: the
|
|
44
|
+
* declaration is invalid at computed-value time, so the property falls back
|
|
45
|
+
* to inherited or initial.
|
|
46
|
+
*
|
|
47
|
+
* @param cascade - Resolved properties
|
|
48
|
+
* @param style - Computed styles of the element (custom properties included)
|
|
49
|
+
* @returns Hints
|
|
50
|
+
*/
|
|
51
|
+
export declare function undefinedVariableHints(cascade: Map<string, Resolution>, style: StyleMap): CssHint[];
|
|
52
|
+
/**
|
|
53
|
+
* A form control drawn in the browser's font while its parent uses another:
|
|
54
|
+
* controls do not inherit the font unless told to (a common oversight).
|
|
55
|
+
*
|
|
56
|
+
* @param cascade - Resolved properties
|
|
57
|
+
* @param ctx - Computed styles of the element and its parent
|
|
58
|
+
* @returns The hint, when the browser's own font-family wins
|
|
59
|
+
*/
|
|
60
|
+
export declare function formControlFontHints(cascade: Map<string, Resolution>, ctx: HintContext): CssHint[];
|
|
61
|
+
export {};
|
|
62
|
+
//# sourceMappingURL=inspectHints.d.ts.map
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Declarations that have no effect, with why and what to change: Chrome
|
|
3
|
+
* DevTools' inactive-CSS rules (CSSRuleValidator) plus some of Firefox's,
|
|
4
|
+
* checked against authored declarations only (never the browser's own
|
|
5
|
+
* styles), and `var()` references to custom properties that are not set.
|
|
6
|
+
*/
|
|
7
|
+
import { unsetVariables } from './inspectVariables.js';
|
|
8
|
+
import { findSimilarNames } from '../../utils/suggestions.js';
|
|
9
|
+
const display = (style) => style?.['display'] ?? 'inline';
|
|
10
|
+
const isFlex = (value) => /(^|-)flex$/.test(value);
|
|
11
|
+
const isGrid = (value) => /(^|-)grid$/.test(value);
|
|
12
|
+
const isFlexOrGrid = (value) => isFlex(value) || isGrid(value);
|
|
13
|
+
const isMulticol = (style) => (style['column-count'] ?? 'auto') !== 'auto' || (style['column-width'] ?? 'auto') !== 'auto';
|
|
14
|
+
/** The checks, in DevTools' wording */
|
|
15
|
+
const RULES = [
|
|
16
|
+
{
|
|
17
|
+
properties: ['flex-direction', 'flex-wrap', 'flex-flow'],
|
|
18
|
+
inactive: ({ style }) => isFlex(display(style))
|
|
19
|
+
? undefined
|
|
20
|
+
: { reason: `display is ${display(style)}`, fix: 'use display: flex or inline-flex' },
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
properties: [
|
|
24
|
+
'grid-template-columns',
|
|
25
|
+
'grid-template-rows',
|
|
26
|
+
'grid-template-areas',
|
|
27
|
+
'grid-auto-flow',
|
|
28
|
+
'grid-auto-columns',
|
|
29
|
+
'grid-auto-rows',
|
|
30
|
+
],
|
|
31
|
+
inactive: ({ style }) => isGrid(display(style))
|
|
32
|
+
? undefined
|
|
33
|
+
: { reason: `display is ${display(style)}`, fix: 'use display: grid or inline-grid' },
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
properties: ['justify-content', 'align-items', 'row-gap'],
|
|
37
|
+
inactive: ({ style }) => isFlexOrGrid(display(style))
|
|
38
|
+
? undefined
|
|
39
|
+
: {
|
|
40
|
+
reason: `display is ${display(style)}`,
|
|
41
|
+
fix: 'use display: flex or grid on this element',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
properties: ['column-gap'],
|
|
46
|
+
inactive: ({ style }) => isFlexOrGrid(display(style)) || isMulticol(style)
|
|
47
|
+
? undefined
|
|
48
|
+
: {
|
|
49
|
+
reason: `display is ${display(style)}`,
|
|
50
|
+
fix: 'use display: flex or grid on this element (or columns)',
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
properties: ['align-content'],
|
|
55
|
+
inactive: ({ style }) => {
|
|
56
|
+
if (isFlex(display(style)) && (style['flex-wrap'] ?? 'nowrap') === 'nowrap') {
|
|
57
|
+
return { reason: 'flex-wrap is nowrap (one line)', fix: 'use flex-wrap: wrap' };
|
|
58
|
+
}
|
|
59
|
+
return undefined;
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
properties: ['flex', 'flex-grow', 'flex-shrink', 'flex-basis'],
|
|
64
|
+
inactive: ({ parentStyle }) => isFlex(display(parentStyle))
|
|
65
|
+
? undefined
|
|
66
|
+
: {
|
|
67
|
+
reason: `the parent's display is ${display(parentStyle)}`,
|
|
68
|
+
fix: 'use display: flex on the parent',
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
properties: [
|
|
73
|
+
'grid-area',
|
|
74
|
+
'grid-column',
|
|
75
|
+
'grid-row',
|
|
76
|
+
'grid-column-start',
|
|
77
|
+
'grid-column-end',
|
|
78
|
+
'grid-row-start',
|
|
79
|
+
'grid-row-end',
|
|
80
|
+
],
|
|
81
|
+
inactive: ({ parentStyle }) => isGrid(display(parentStyle))
|
|
82
|
+
? undefined
|
|
83
|
+
: {
|
|
84
|
+
reason: `the parent's display is ${display(parentStyle)}`,
|
|
85
|
+
fix: 'use display: grid on the parent',
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
properties: ['order', 'align-self'],
|
|
90
|
+
inactive: ({ style, parentStyle }) => isFlexOrGrid(display(parentStyle)) || /^(absolute|fixed)$/.test(style['position'] ?? '')
|
|
91
|
+
? undefined
|
|
92
|
+
: {
|
|
93
|
+
reason: `the parent's display is ${display(parentStyle)}`,
|
|
94
|
+
fix: 'use display: flex or grid on the parent',
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
properties: ['top', 'right', 'bottom', 'left', 'inset'],
|
|
99
|
+
inactive: ({ style }) => (style['position'] ?? 'static') === 'static'
|
|
100
|
+
? {
|
|
101
|
+
reason: 'position is static',
|
|
102
|
+
fix: 'use position: absolute (out of the flow) or relative (shifted in place)',
|
|
103
|
+
}
|
|
104
|
+
: undefined,
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
properties: ['z-index'],
|
|
108
|
+
inactive: ({ style, parentStyle }) => (style['position'] ?? 'static') === 'static' && !isFlexOrGrid(display(parentStyle))
|
|
109
|
+
? {
|
|
110
|
+
reason: 'position is static',
|
|
111
|
+
fix: 'use position: relative, or absolute to take it out of the flow',
|
|
112
|
+
}
|
|
113
|
+
: undefined,
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
properties: ['width', 'height', 'min-width', 'min-height', 'max-width', 'max-height'],
|
|
117
|
+
inactive: ({ style, replaced }) => display(style) === 'inline' && !replaced
|
|
118
|
+
? { reason: 'display is inline', fix: 'use display: inline-block or block' }
|
|
119
|
+
: undefined,
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
properties: ['margin-top', 'margin-bottom'],
|
|
123
|
+
inactive: ({ style, replaced }) => display(style) === 'inline' && !replaced
|
|
124
|
+
? {
|
|
125
|
+
reason: 'display is inline (vertical margins do not move it)',
|
|
126
|
+
fix: 'use display: inline-block or block',
|
|
127
|
+
}
|
|
128
|
+
: undefined,
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
properties: ['vertical-align'],
|
|
132
|
+
inactive: ({ style }) => /^(inline|inline-block|inline-flex|inline-grid|table-cell)$/.test(display(style))
|
|
133
|
+
? undefined
|
|
134
|
+
: {
|
|
135
|
+
reason: `display is ${display(style)}`,
|
|
136
|
+
fix: 'vertical-align works on inline and table-cell boxes; use flex alignment instead',
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
properties: ['text-overflow'],
|
|
141
|
+
inactive: ({ style }) => (style['overflow-x'] ?? 'visible') === 'visible'
|
|
142
|
+
? {
|
|
143
|
+
reason: 'overflow is visible (nothing is cut)',
|
|
144
|
+
fix: 'add overflow: hidden and white-space: nowrap',
|
|
145
|
+
}
|
|
146
|
+
: undefined,
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
properties: ['float'],
|
|
150
|
+
inactive: ({ parentStyle }) => isFlexOrGrid(display(parentStyle))
|
|
151
|
+
? {
|
|
152
|
+
reason: `the parent is a ${display(parentStyle)} container`,
|
|
153
|
+
fix: 'remove float; use flex or grid alignment',
|
|
154
|
+
}
|
|
155
|
+
: undefined,
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
properties: ['object-fit', 'object-position'],
|
|
159
|
+
inactive: ({ replaced }) => replaced
|
|
160
|
+
? undefined
|
|
161
|
+
: {
|
|
162
|
+
reason: 'the element is not an image or video',
|
|
163
|
+
fix: 'use background-size/position for backgrounds',
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
];
|
|
167
|
+
/**
|
|
168
|
+
* Declarations of the element that have no effect: every longhand a
|
|
169
|
+
* declaration wins is inactive (`margin: 0 4px` on an inline element still
|
|
170
|
+
* moves it sideways, `gap` on a multi-column block still spaces the columns).
|
|
171
|
+
*
|
|
172
|
+
* @param cascade - Resolved properties (winning declarations are checked)
|
|
173
|
+
* @param ctx - Computed styles of the element and its parent
|
|
174
|
+
* @returns Hints, in property order
|
|
175
|
+
*/
|
|
176
|
+
export function inactiveHints(cascade, ctx) {
|
|
177
|
+
return [...ownWinnersByDeclaration(cascade).values()].flatMap((winners) => {
|
|
178
|
+
const checks = winners.map((declaration) => RULES.find((rule) => rule.properties.includes(declaration.property))?.inactive(ctx));
|
|
179
|
+
const [first] = winners;
|
|
180
|
+
const [inactive] = checks;
|
|
181
|
+
if (!first || !inactive || checks.some((check) => !check))
|
|
182
|
+
return [];
|
|
183
|
+
return [
|
|
184
|
+
{
|
|
185
|
+
kind: 'inactive',
|
|
186
|
+
property: first.via ?? first.property,
|
|
187
|
+
value: first.written ?? first.value,
|
|
188
|
+
...inactive,
|
|
189
|
+
declaration: first,
|
|
190
|
+
},
|
|
191
|
+
];
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* The element's own authored winning declarations, the longhands each wins
|
|
196
|
+
* grouped by the declaration as written.
|
|
197
|
+
*
|
|
198
|
+
* @param cascade - Resolved properties
|
|
199
|
+
* @returns Winning longhands by declaration
|
|
200
|
+
*/
|
|
201
|
+
function ownWinnersByDeclaration(cascade) {
|
|
202
|
+
const groups = new Map();
|
|
203
|
+
for (const { winner } of cascade.values()) {
|
|
204
|
+
if (!winner || winner.ancestor !== undefined || winner.source.origin === 'user-agent')
|
|
205
|
+
continue;
|
|
206
|
+
const { source } = winner;
|
|
207
|
+
const key = [
|
|
208
|
+
winner.via ?? winner.property,
|
|
209
|
+
source.kind,
|
|
210
|
+
source.styleSheetId,
|
|
211
|
+
source.line,
|
|
212
|
+
source.column,
|
|
213
|
+
].join('|');
|
|
214
|
+
groups.set(key, [...(groups.get(key) ?? []), winner]);
|
|
215
|
+
}
|
|
216
|
+
return groups;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Winning declarations that use a custom property that is not set: the
|
|
220
|
+
* declaration is invalid at computed-value time, so the property falls back
|
|
221
|
+
* to inherited or initial.
|
|
222
|
+
*
|
|
223
|
+
* @param cascade - Resolved properties
|
|
224
|
+
* @param style - Computed styles of the element (custom properties included)
|
|
225
|
+
* @returns Hints
|
|
226
|
+
*/
|
|
227
|
+
export function undefinedVariableHints(cascade, style) {
|
|
228
|
+
const hints = [];
|
|
229
|
+
const seen = new Set();
|
|
230
|
+
for (const resolution of cascade.values()) {
|
|
231
|
+
const declaration = resolution.winner;
|
|
232
|
+
if (!declaration || declaration.ancestor !== undefined)
|
|
233
|
+
continue;
|
|
234
|
+
const value = declaration.written ?? declaration.value;
|
|
235
|
+
const missing = unsetVariables(value, style);
|
|
236
|
+
const written = declaration.via ?? declaration.property;
|
|
237
|
+
if (missing.length === 0 || seen.has(written))
|
|
238
|
+
continue;
|
|
239
|
+
seen.add(written);
|
|
240
|
+
hints.push({
|
|
241
|
+
kind: 'unset-variable',
|
|
242
|
+
property: written,
|
|
243
|
+
value,
|
|
244
|
+
reason: `${missing.join(', ')} is not set`,
|
|
245
|
+
fix: variableFix(missing[0] ?? '', style),
|
|
246
|
+
declaration,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
return hints;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* How to fix a `var()` of an unset custom property, naming a similar one
|
|
253
|
+
* that is set (a typo or a renamed token).
|
|
254
|
+
*
|
|
255
|
+
* @param name - The unset custom property
|
|
256
|
+
* @param style - Computed styles (custom properties included)
|
|
257
|
+
* @returns Fix
|
|
258
|
+
*/
|
|
259
|
+
function variableFix(name, style) {
|
|
260
|
+
const defined = Object.keys(style).filter((key) => key.startsWith('--'));
|
|
261
|
+
const [similar] = findSimilarNames(name, defined);
|
|
262
|
+
const fix = `define ${name} or give var() a fallback`;
|
|
263
|
+
return similar ? `${fix} (did you mean ${similar}? it is set)` : fix;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* A form control drawn in the browser's font while its parent uses another:
|
|
267
|
+
* controls do not inherit the font unless told to (a common oversight).
|
|
268
|
+
*
|
|
269
|
+
* @param cascade - Resolved properties
|
|
270
|
+
* @param ctx - Computed styles of the element and its parent
|
|
271
|
+
* @returns The hint, when the browser's own font-family wins
|
|
272
|
+
*/
|
|
273
|
+
export function formControlFontHints(cascade, ctx) {
|
|
274
|
+
const declaration = cascade.get('font-family')?.winner;
|
|
275
|
+
if (!ctx.formControl || declaration?.source.origin !== 'user-agent')
|
|
276
|
+
return [];
|
|
277
|
+
const own = firstFamily(ctx.style['font-family']);
|
|
278
|
+
const parent = firstFamily(ctx.parentStyle?.['font-family']);
|
|
279
|
+
if (!own || !parent || own.toLowerCase() === parent.toLowerCase())
|
|
280
|
+
return [];
|
|
281
|
+
return [
|
|
282
|
+
{
|
|
283
|
+
kind: 'not-inherited',
|
|
284
|
+
property: 'font-family',
|
|
285
|
+
value: own,
|
|
286
|
+
reason: `form controls do not inherit the font (the parent uses ${parent})`,
|
|
287
|
+
fix: 'add font: inherit (or font-family: inherit) to the control',
|
|
288
|
+
declaration,
|
|
289
|
+
},
|
|
290
|
+
];
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* The first family of a font-family list, unquoted.
|
|
294
|
+
*
|
|
295
|
+
* @param value - font-family value
|
|
296
|
+
* @returns First family, or undefined
|
|
297
|
+
*/
|
|
298
|
+
function firstFamily(value) {
|
|
299
|
+
const family = value
|
|
300
|
+
?.split(',')[0]
|
|
301
|
+
?.trim()
|
|
302
|
+
.replace(/^["']|["']$/g, '');
|
|
303
|
+
return family === '' ? undefined : family;
|
|
304
|
+
}
|
|
305
|
+
//# sourceMappingURL=inspectHints.js.map
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Box and layout groups of `bdg dom inspect`, from computed styles.
|
|
3
|
+
*
|
|
4
|
+
* Core facts are always there (display, padding/margin/border as computed,
|
|
5
|
+
* even when they equal the UA default); the rest only when it applies
|
|
6
|
+
* (container fields for flex and grid containers, item fields in a flex or
|
|
7
|
+
* grid parent) and is not a no-op default. Sizing is named like Figma's
|
|
8
|
+
* auto layout: hug (sized by the content), fill (stretched by the parent)
|
|
9
|
+
* or fixed, from the computed (not resolved) width and height.
|
|
10
|
+
*/
|
|
11
|
+
import type { InspectBox, InspectContainer, InspectLayout, Sides, SizingMode } from '../../ipc/protocol/inspectTypes.js';
|
|
12
|
+
import type { RawInspect } from './inspectScripts.js';
|
|
13
|
+
/** Computed styles by property name */
|
|
14
|
+
export type StyleMap = Record<string, string>;
|
|
15
|
+
/**
|
|
16
|
+
* The four sides of a box property.
|
|
17
|
+
*
|
|
18
|
+
* @param style - Computed styles
|
|
19
|
+
* @param name - e.g. `padding-{side}`, `border-{side}-width`
|
|
20
|
+
* @returns Top, right, bottom, left
|
|
21
|
+
*/
|
|
22
|
+
export declare function sides(style: StyleMap, name: string): Sides;
|
|
23
|
+
/**
|
|
24
|
+
* The box group: padding, margin, border widths, box-sizing, size limits,
|
|
25
|
+
* overflow and the content size when it overflows.
|
|
26
|
+
*
|
|
27
|
+
* @param style - Computed styles
|
|
28
|
+
* @param raw - Page-side measurements
|
|
29
|
+
* @returns Box group
|
|
30
|
+
*/
|
|
31
|
+
export declare function buildBox(style: StyleMap, raw: Pick<RawInspect, 'scroll'>): InspectBox;
|
|
32
|
+
/**
|
|
33
|
+
* Whether a display value makes a flex or grid container.
|
|
34
|
+
*
|
|
35
|
+
* @param display - Computed display
|
|
36
|
+
* @returns `flex`, `grid` or undefined
|
|
37
|
+
*/
|
|
38
|
+
export declare function containerKind(display: string | undefined): 'flex' | 'grid' | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Flex or grid container fields that are not no-op defaults (the flex
|
|
41
|
+
* direction is always there).
|
|
42
|
+
*
|
|
43
|
+
* @param style - Computed styles
|
|
44
|
+
* @returns Container fields, empty for other displays
|
|
45
|
+
*/
|
|
46
|
+
export declare function buildContainer(style: StyleMap): InspectContainer;
|
|
47
|
+
/** Inputs to {@link deriveSizing} */
|
|
48
|
+
export interface SizingInput {
|
|
49
|
+
/** Computed (not resolved) size: `auto`, `200px`, `100%`, `fit-content`, … */
|
|
50
|
+
size: string;
|
|
51
|
+
axis: 'w' | 'h';
|
|
52
|
+
display: string;
|
|
53
|
+
position: string;
|
|
54
|
+
float: string;
|
|
55
|
+
flexGrow: number;
|
|
56
|
+
flexBasis: string;
|
|
57
|
+
alignSelf: string;
|
|
58
|
+
justifySelf: string;
|
|
59
|
+
parentDisplay?: string;
|
|
60
|
+
parentDirection?: string;
|
|
61
|
+
parentAlignItems?: string;
|
|
62
|
+
parentJustifyItems?: string;
|
|
63
|
+
/** A replaced element (img, video, canvas, iframe, form control…): sized by its intrinsic content */
|
|
64
|
+
replaced?: boolean;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* How the element is sized along an axis: `fill` when its parent stretches
|
|
68
|
+
* it (a flex item that grows, a stretched cross axis or grid cell, a block's
|
|
69
|
+
* width in normal flow, 100%), `hug` when its content sizes it (`auto` and
|
|
70
|
+
* the content keywords elsewhere), `fixed` for a length.
|
|
71
|
+
*
|
|
72
|
+
* @param input - Computed size, display and the parent's layout
|
|
73
|
+
* @returns Sizing mode
|
|
74
|
+
*/
|
|
75
|
+
export declare function deriveSizing(input: SizingInput): SizingMode;
|
|
76
|
+
/**
|
|
77
|
+
* The layout group: display, position, container and item fields, valign
|
|
78
|
+
* for inline displays, float, sizing, and the parent with the element's
|
|
79
|
+
* place in it (offsets from its content edges, gaps to the siblings).
|
|
80
|
+
*
|
|
81
|
+
* @param style - Computed styles
|
|
82
|
+
* @param parentStyle - Computed styles of the layout parent (none for the root)
|
|
83
|
+
* @param raw - Page-side measurements
|
|
84
|
+
* @returns Layout group
|
|
85
|
+
*/
|
|
86
|
+
export declare function buildLayout(style: StyleMap, parentStyle: StyleMap | undefined, raw: Pick<RawInspect, 'typed' | 'replaced' | 'parent' | 'inParent' | 'siblings'>): InspectLayout;
|
|
87
|
+
//# sourceMappingURL=inspectLayoutModel.d.ts.map
|