chrome-devtools-frontend 1.0.1029692 → 1.0.1030457
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/config/gni/devtools_grd_files.gni +4 -0
- package/config/gni/devtools_image_files.gni +2 -0
- package/docs/workflows.md +1 -1
- package/front_end/Images/src/file-sync_icon.svg +62 -0
- package/front_end/Images/src/file_icon.svg +52 -0
- package/front_end/core/i18n/locales/en-US.json +6 -0
- package/front_end/core/i18n/locales/en-XL.json +6 -0
- package/front_end/models/issues_manager/AttributionReportingIssue.ts +11 -0
- package/front_end/models/issues_manager/DeprecationIssue.ts +5 -1
- package/front_end/models/issues_manager/descriptions/arInvalidEligibleHeader.md +19 -0
- package/front_end/panels/elements/CSSRuleValidator.ts +356 -21
- package/front_end/panels/elements/CSSRuleValidatorHelper.ts +34 -0
- package/front_end/panels/elements/StylePropertyTreeElement.ts +4 -24
- package/front_end/panels/elements/StylesSidebarPane.ts +31 -1
- package/front_end/panels/issues/AttributionReportingIssueDetailsView.ts +2 -0
- package/front_end/panels/network/components/RequestHeadersView.css +40 -8
- package/front_end/panels/network/components/RequestHeadersView.ts +123 -18
- package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +42 -3
- package/front_end/ui/components/data_grid/DataGrid.ts +15 -10
- package/front_end/ui/components/data_grid/DataGridController.ts +7 -0
- package/front_end/ui/legacy/TextPrompt.ts +1 -1
- package/package.json +6 -5
@@ -4,6 +4,14 @@
|
|
4
4
|
|
5
5
|
import * as i18n from '../../core/i18n/i18n.js';
|
6
6
|
|
7
|
+
import {
|
8
|
+
buildStyledPropertyText,
|
9
|
+
buildStyledRuleText,
|
10
|
+
isFlexContainer,
|
11
|
+
isGridContainer,
|
12
|
+
isMulticolContainer,
|
13
|
+
} from './CSSRuleValidatorHelper.js';
|
14
|
+
|
7
15
|
const UIStrings = {
|
8
16
|
/**
|
9
17
|
*@description Hint prefix for deprecated properties.
|
@@ -18,25 +26,36 @@ const UIStrings = {
|
|
18
26
|
*@example {flex-wrap: nowrap} REASON_RULE_CODE
|
19
27
|
*@example {align-content} AFFECTED_RULE_CODE
|
20
28
|
*/
|
21
|
-
ruleViolatedBySameElementRuleReason:
|
29
|
+
ruleViolatedBySameElementRuleReason:
|
30
|
+
'This element has {REASON_RULE_CODE} rule, therefore {AFFECTED_RULE_CODE} has no effect.',
|
22
31
|
/**
|
23
32
|
*@description Possible fix for rules that was violated because of same elements rule.
|
24
33
|
*@example {flex-wrap: nowrap} REASON_RULE_CODE
|
25
34
|
*/
|
26
|
-
ruleViolatedBySameElementRuleFix:
|
35
|
+
ruleViolatedBySameElementRuleFix:
|
36
|
+
'For this property to work, please remove or change the value of {REASON_RULE_CODE}',
|
37
|
+
/**
|
38
|
+
*@description Possible fix for rules that was violated because of same elements rule.
|
39
|
+
*@example {display: block} EXISTING_RULE
|
40
|
+
*@example {display: flex} TARGET_RULE
|
41
|
+
*/
|
42
|
+
ruleViolatedBySameElementRuleChangeSuggestion:
|
43
|
+
'For this property to work, please change the {EXISTING_RULE} rule to {TARGET_RULE}',
|
27
44
|
/**
|
28
45
|
*@description Hint for rules that was violated because of parent element rule.
|
29
46
|
*@example {display: block} REASON_RULE_CODE
|
30
47
|
*@example {flex} AFFECTED_RULE_CODE
|
31
48
|
*/
|
32
|
-
ruleViolatedByParentElementRuleReason:
|
49
|
+
ruleViolatedByParentElementRuleReason:
|
50
|
+
'Parent element has {REASON_RULE_CODE} rule, therefore this elements {AFFECTED_RULE_CODE} has no effect',
|
33
51
|
/**
|
34
52
|
*@description Posible fix for rules that was violated because of parent element rule.
|
35
53
|
*@example {display: block} EXISTING_PARENT_ELEMENT_RULE
|
36
54
|
*@example {display: flex} TARGET_PARENT_ELEMENT_RULE
|
37
55
|
*/
|
38
|
-
ruleViolatedByParentElementRuleFix:
|
39
|
-
|
56
|
+
ruleViolatedByParentElementRuleFix:
|
57
|
+
'Please change parent elements {EXISTING_PARENT_ELEMENT_RULE} to {TARGET_PARENT_ELEMENT_RULE} to fix this issue.',
|
58
|
+
};
|
40
59
|
const str_ = i18n.i18n.registerUIStrings('panels/elements/CSSRuleValidator.ts', UIStrings);
|
41
60
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
42
61
|
|
@@ -94,7 +113,9 @@ export abstract class CSSRuleValidator {
|
|
94
113
|
return this.#affectedProperties;
|
95
114
|
}
|
96
115
|
|
97
|
-
abstract getAuthoringHint(
|
116
|
+
abstract getAuthoringHint(
|
117
|
+
propertyName: string, computedStyles: Map<String, String>|null,
|
118
|
+
parentComputedStyles: Map<String, String>|null): AuthoringHint;
|
98
119
|
}
|
99
120
|
|
100
121
|
export class AlignContentValidator extends CSSRuleValidator {
|
@@ -106,16 +127,15 @@ export class AlignContentValidator extends CSSRuleValidator {
|
|
106
127
|
if (computedStyles === null || computedStyles === undefined) {
|
107
128
|
return true;
|
108
129
|
}
|
109
|
-
|
110
|
-
if (display !== 'flex' && display !== 'inline-flex') {
|
130
|
+
if (!isFlexContainer(computedStyles)) {
|
111
131
|
return true;
|
112
132
|
}
|
113
133
|
return computedStyles.get('flex-wrap') !== 'nowrap';
|
114
134
|
}
|
115
135
|
|
116
136
|
getAuthoringHint(): AuthoringHint {
|
117
|
-
const reasonRuleCode = '
|
118
|
-
const affectedRuleCode = '
|
137
|
+
const reasonRuleCode = buildStyledPropertyText('flex-wrap');
|
138
|
+
const affectedRuleCode = buildStyledPropertyText('align-content');
|
119
139
|
|
120
140
|
return new AuthoringHint(
|
121
141
|
'align-content',
|
@@ -138,18 +158,18 @@ export class FlexItemValidator extends CSSRuleValidator {
|
|
138
158
|
}
|
139
159
|
|
140
160
|
isRuleValid(computedStyles: Map<String, String>|null, parentsComputedStyles: Map<String, String>|null): boolean {
|
141
|
-
if (
|
142
|
-
parentsComputedStyles === undefined) {
|
161
|
+
if (parentsComputedStyles === null) {
|
143
162
|
return true;
|
144
163
|
}
|
145
|
-
|
146
|
-
return parentDisplay === 'flex' || parentDisplay === 'inline-flex';
|
164
|
+
return isFlexContainer(parentsComputedStyles);
|
147
165
|
}
|
148
166
|
|
149
|
-
getAuthoringHint(
|
150
|
-
|
151
|
-
|
152
|
-
const
|
167
|
+
getAuthoringHint(
|
168
|
+
property: string, computedStyles: Map<String, String>|null,
|
169
|
+
parentsComputedStyles: Map<String, String>|null): AuthoringHint {
|
170
|
+
const reasonRuleCode = buildStyledRuleText('display', parentsComputedStyles?.get('display'));
|
171
|
+
const affectedRuleCode = buildStyledPropertyText(property);
|
172
|
+
const targetParentRuleCode = buildStyledRuleText('display', 'flex');
|
153
173
|
|
154
174
|
return new AuthoringHint(
|
155
175
|
property,
|
@@ -167,11 +187,326 @@ export class FlexItemValidator extends CSSRuleValidator {
|
|
167
187
|
}
|
168
188
|
}
|
169
189
|
|
170
|
-
|
171
|
-
|
190
|
+
export class FlexContainerValidator extends CSSRuleValidator {
|
191
|
+
constructor() {
|
192
|
+
super(['flex-direction', 'flex-flow', 'flex-wrap', 'justify-content']);
|
193
|
+
}
|
194
|
+
|
195
|
+
isRuleValid(computedStyles: Map<String, String>|null): boolean {
|
196
|
+
if (computedStyles === null) {
|
197
|
+
return true;
|
198
|
+
}
|
199
|
+
return isFlexContainer(computedStyles);
|
200
|
+
}
|
201
|
+
|
202
|
+
getAuthoringHint(property: string, computedStyles: Map<String, String>|null): AuthoringHint {
|
203
|
+
const reasonRuleCode = buildStyledRuleText('display', computedStyles?.get('display'));
|
204
|
+
const targetRuleCode = buildStyledRuleText('display', 'flex');
|
205
|
+
const affectedRuleCode = buildStyledPropertyText(property);
|
206
|
+
|
207
|
+
return new AuthoringHint(
|
208
|
+
property,
|
209
|
+
AuthoringHintType.RULE_VALIDATION,
|
210
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
|
211
|
+
'REASON_RULE_CODE': reasonRuleCode,
|
212
|
+
'AFFECTED_RULE_CODE': affectedRuleCode,
|
213
|
+
}),
|
214
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleChangeSuggestion, {
|
215
|
+
'EXISTING_RULE': reasonRuleCode,
|
216
|
+
'TARGET_RULE': targetRuleCode,
|
217
|
+
}),
|
218
|
+
true,
|
219
|
+
);
|
220
|
+
}
|
221
|
+
}
|
222
|
+
|
223
|
+
export class GridContainerValidator extends CSSRuleValidator {
|
224
|
+
constructor() {
|
225
|
+
super([
|
226
|
+
'grid',
|
227
|
+
'grid-auto-columns',
|
228
|
+
'grid-auto-flow',
|
229
|
+
'grid-auto-rows',
|
230
|
+
'grid-template',
|
231
|
+
'grid-template-areas',
|
232
|
+
'grid-template-columns',
|
233
|
+
'grid-template-rows',
|
234
|
+
]);
|
235
|
+
}
|
236
|
+
|
237
|
+
isRuleValid(computedStyles: Map<String, String>|null): boolean {
|
238
|
+
if (computedStyles === null) {
|
239
|
+
return true;
|
240
|
+
}
|
241
|
+
return isGridContainer(computedStyles);
|
242
|
+
}
|
243
|
+
|
244
|
+
getAuthoringHint(property: string, computedStyles: Map<String, String>|null): AuthoringHint {
|
245
|
+
const reasonRuleCode = buildStyledRuleText('display', computedStyles?.get('display'));
|
246
|
+
const targetRuleCode = buildStyledRuleText('display', 'grid');
|
247
|
+
const affectedRuleCode = buildStyledPropertyText(property);
|
248
|
+
|
249
|
+
return new AuthoringHint(
|
250
|
+
property,
|
251
|
+
AuthoringHintType.RULE_VALIDATION,
|
252
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
|
253
|
+
'REASON_RULE_CODE': reasonRuleCode,
|
254
|
+
'AFFECTED_RULE_CODE': affectedRuleCode,
|
255
|
+
}),
|
256
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleChangeSuggestion, {
|
257
|
+
'EXISTING_RULE': reasonRuleCode,
|
258
|
+
'TARGET_RULE': targetRuleCode,
|
259
|
+
}),
|
260
|
+
true,
|
261
|
+
);
|
262
|
+
}
|
263
|
+
}
|
264
|
+
|
265
|
+
export class GridItemValidator extends CSSRuleValidator {
|
266
|
+
constructor() {
|
267
|
+
super([
|
268
|
+
'grid-area',
|
269
|
+
'grid-column',
|
270
|
+
'grid-row',
|
271
|
+
'grid-row-end',
|
272
|
+
'grid-row-start',
|
273
|
+
]);
|
274
|
+
}
|
275
|
+
|
276
|
+
isRuleValid(computedStyles: Map<String, String>|null, parentComputedStyles: Map<String, String>|null): boolean {
|
277
|
+
if (parentComputedStyles === null) {
|
278
|
+
return true;
|
279
|
+
}
|
280
|
+
return isGridContainer(parentComputedStyles);
|
281
|
+
}
|
282
|
+
|
283
|
+
getAuthoringHint(
|
284
|
+
property: string, computedStyles: Map<String, String>|null,
|
285
|
+
parentComputedStyles: Map<String, String>|null): AuthoringHint {
|
286
|
+
const reasonRuleCode = buildStyledRuleText('display', parentComputedStyles?.get('display'));
|
287
|
+
const targetParentRuleCode = buildStyledRuleText('display', 'grid');
|
288
|
+
const affectedRuleCode = buildStyledPropertyText(property);
|
289
|
+
|
290
|
+
return new AuthoringHint(
|
291
|
+
property,
|
292
|
+
AuthoringHintType.RULE_VALIDATION,
|
293
|
+
i18nString(UIStrings.ruleViolatedByParentElementRuleReason, {
|
294
|
+
'REASON_RULE_CODE': reasonRuleCode,
|
295
|
+
'AFFECTED_RULE_CODE': affectedRuleCode,
|
296
|
+
}),
|
297
|
+
i18nString(UIStrings.ruleViolatedByParentElementRuleFix, {
|
298
|
+
'EXISTING_PARENT_ELEMENT_RULE': reasonRuleCode,
|
299
|
+
'TARGET_PARENT_ELEMENT_RULE': targetParentRuleCode,
|
300
|
+
}),
|
301
|
+
true,
|
302
|
+
);
|
303
|
+
}
|
304
|
+
}
|
305
|
+
|
306
|
+
export class FlexGridValidator extends CSSRuleValidator {
|
307
|
+
constructor() {
|
308
|
+
super([
|
309
|
+
'order',
|
310
|
+
'align-content',
|
311
|
+
'align-items',
|
312
|
+
'align-self',
|
313
|
+
]);
|
314
|
+
}
|
315
|
+
|
316
|
+
isRuleValid(computedStyles: Map<String, String>|null): boolean {
|
317
|
+
if (computedStyles === null) {
|
318
|
+
return true;
|
319
|
+
}
|
320
|
+
return isFlexContainer(computedStyles) || isGridContainer(computedStyles);
|
321
|
+
}
|
322
|
+
|
323
|
+
getAuthoringHint(property: string, computedStyles: Map<String, String>|null): AuthoringHint {
|
324
|
+
const reasonRuleCode = buildStyledRuleText('display', computedStyles?.get('display'));
|
325
|
+
const affectedRuleCode = buildStyledPropertyText(property);
|
326
|
+
|
327
|
+
return new AuthoringHint(
|
328
|
+
property,
|
329
|
+
AuthoringHintType.RULE_VALIDATION,
|
330
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
|
331
|
+
'REASON_RULE_CODE': reasonRuleCode,
|
332
|
+
'AFFECTED_RULE_CODE': affectedRuleCode,
|
333
|
+
}),
|
334
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleFix, {
|
335
|
+
'REASON_RULE_CODE': reasonRuleCode,
|
336
|
+
}),
|
337
|
+
true,
|
338
|
+
);
|
339
|
+
}
|
340
|
+
}
|
341
|
+
|
342
|
+
export class MulticolFlexGridValidator extends CSSRuleValidator {
|
343
|
+
constructor() {
|
344
|
+
super([
|
345
|
+
'gap',
|
346
|
+
'column-gap',
|
347
|
+
'row-gap',
|
348
|
+
'grid-gap',
|
349
|
+
'grid-column-gap',
|
350
|
+
'grid-column-end',
|
351
|
+
'grid-row-gap',
|
352
|
+
]);
|
353
|
+
}
|
354
|
+
|
355
|
+
isRuleValid(computedStyles: Map<String, String>|null): boolean {
|
356
|
+
if (computedStyles === null) {
|
357
|
+
return true;
|
358
|
+
}
|
359
|
+
return isMulticolContainer(computedStyles) || isFlexContainer(computedStyles) || isGridContainer(computedStyles);
|
360
|
+
}
|
361
|
+
|
362
|
+
getAuthoringHint(property: string, computedStyles: Map<String, String>|null): AuthoringHint {
|
363
|
+
const reasonRuleCode = buildStyledRuleText('display', computedStyles?.get('display'));
|
364
|
+
const affectedRuleCode = buildStyledPropertyText(property);
|
365
|
+
|
366
|
+
return new AuthoringHint(
|
367
|
+
property,
|
368
|
+
AuthoringHintType.RULE_VALIDATION,
|
369
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
|
370
|
+
'REASON_RULE_CODE': reasonRuleCode,
|
371
|
+
'AFFECTED_RULE_CODE': affectedRuleCode,
|
372
|
+
}),
|
373
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleFix, {
|
374
|
+
'REASON_RULE_CODE': reasonRuleCode,
|
375
|
+
}),
|
376
|
+
true,
|
377
|
+
);
|
378
|
+
}
|
379
|
+
}
|
380
|
+
|
381
|
+
export class PaddingValidator extends CSSRuleValidator {
|
382
|
+
constructor() {
|
383
|
+
super([
|
384
|
+
'padding',
|
385
|
+
'padding-top',
|
386
|
+
'padding-right',
|
387
|
+
'padding-bottom',
|
388
|
+
'padding-left',
|
389
|
+
]);
|
390
|
+
}
|
391
|
+
|
392
|
+
isRuleValid(computedStyles: Map<String, String>|null): boolean {
|
393
|
+
const display = computedStyles?.get('display');
|
394
|
+
if (display === null || display === undefined) {
|
395
|
+
return true;
|
396
|
+
}
|
397
|
+
return !['table-row-group', 'table-header-group', 'table-footer-group', 'table-row', 'table-column-group',
|
398
|
+
'table-column']
|
399
|
+
.includes(display as string);
|
400
|
+
}
|
401
|
+
|
402
|
+
getAuthoringHint(property: string, computedStyles: Map<String, String>|null): AuthoringHint {
|
403
|
+
const reasonRuleCode = buildStyledRuleText('display', computedStyles?.get('display'));
|
404
|
+
const affectedRuleCode = buildStyledPropertyText(property);
|
405
|
+
|
406
|
+
return new AuthoringHint(
|
407
|
+
property,
|
408
|
+
AuthoringHintType.RULE_VALIDATION,
|
409
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
|
410
|
+
'REASON_RULE_CODE': reasonRuleCode,
|
411
|
+
'AFFECTED_RULE_CODE': affectedRuleCode,
|
412
|
+
}),
|
413
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleFix, {
|
414
|
+
'REASON_RULE_CODE': reasonRuleCode,
|
415
|
+
}),
|
416
|
+
true,
|
417
|
+
);
|
418
|
+
}
|
419
|
+
}
|
172
420
|
|
421
|
+
export class PositionValidator extends CSSRuleValidator {
|
422
|
+
constructor() {
|
423
|
+
super([
|
424
|
+
'top',
|
425
|
+
'right',
|
426
|
+
'bottom',
|
427
|
+
'left',
|
428
|
+
]);
|
429
|
+
}
|
430
|
+
|
431
|
+
isRuleValid(computedStyles: Map<String, String>|null): boolean {
|
432
|
+
const position = computedStyles?.get('position');
|
433
|
+
if (position === null || position === undefined) {
|
434
|
+
return true;
|
435
|
+
}
|
436
|
+
return position !== 'static';
|
437
|
+
}
|
438
|
+
|
439
|
+
getAuthoringHint(property: string, computedStyles: Map<String, String>|null): AuthoringHint {
|
440
|
+
const reasonRuleCode = buildStyledRuleText('position', computedStyles?.get('position'));
|
441
|
+
const affectedRuleCode = buildStyledPropertyText(property);
|
442
|
+
|
443
|
+
return new AuthoringHint(
|
444
|
+
property,
|
445
|
+
AuthoringHintType.RULE_VALIDATION,
|
446
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
|
447
|
+
'REASON_RULE_CODE': reasonRuleCode,
|
448
|
+
'AFFECTED_RULE_CODE': affectedRuleCode,
|
449
|
+
}),
|
450
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleFix, {
|
451
|
+
'REASON_RULE_CODE': reasonRuleCode,
|
452
|
+
}),
|
453
|
+
true,
|
454
|
+
);
|
455
|
+
}
|
456
|
+
}
|
457
|
+
|
458
|
+
export class ZIndexValidator extends CSSRuleValidator {
|
459
|
+
constructor() {
|
460
|
+
super([
|
461
|
+
'z-index',
|
462
|
+
]);
|
463
|
+
}
|
464
|
+
|
465
|
+
isRuleValid(computedStyles: Map<String, String>|null, parentComputedStyles: Map<String, String>|null): boolean {
|
466
|
+
const position = computedStyles?.get('position');
|
467
|
+
if (position === null || position === undefined) {
|
468
|
+
return true;
|
469
|
+
}
|
470
|
+
return ['absolute', 'relative', 'fixed', 'sticky'].includes(position as string) ||
|
471
|
+
isFlexContainer(parentComputedStyles);
|
472
|
+
}
|
473
|
+
|
474
|
+
getAuthoringHint(property: string, computedStyles: Map<String, String>|null): AuthoringHint {
|
475
|
+
const reasonRuleCode = buildStyledRuleText('position', computedStyles?.get('position'));
|
476
|
+
const affectedRuleCode = buildStyledPropertyText(property);
|
477
|
+
|
478
|
+
return new AuthoringHint(
|
479
|
+
property,
|
480
|
+
AuthoringHintType.RULE_VALIDATION,
|
481
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
|
482
|
+
'REASON_RULE_CODE': reasonRuleCode,
|
483
|
+
'AFFECTED_RULE_CODE': affectedRuleCode,
|
484
|
+
}),
|
485
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleFix, {
|
486
|
+
'REASON_RULE_CODE': reasonRuleCode,
|
487
|
+
}),
|
488
|
+
true,
|
489
|
+
);
|
490
|
+
}
|
491
|
+
}
|
492
|
+
|
493
|
+
const CSS_RULE_VALIDATORS = [
|
494
|
+
AlignContentValidator,
|
495
|
+
FlexItemValidator,
|
496
|
+
FlexContainerValidator,
|
497
|
+
GridContainerValidator,
|
498
|
+
GridItemValidator,
|
499
|
+
FlexGridValidator,
|
500
|
+
MulticolFlexGridValidator,
|
501
|
+
PaddingValidator,
|
502
|
+
PositionValidator,
|
503
|
+
ZIndexValidator,
|
504
|
+
];
|
505
|
+
|
506
|
+
const setupCSSRulesValidators = (): Map<String, CSSRuleValidator[]> => {
|
173
507
|
const validatorsMap = new Map<String, CSSRuleValidator[]>();
|
174
|
-
for (const
|
508
|
+
for (const validatorClass of CSS_RULE_VALIDATORS) {
|
509
|
+
const validator = new validatorClass();
|
175
510
|
const affectedProperties = validator.getAffectedProperties();
|
176
511
|
|
177
512
|
for (const affectedProperty of affectedProperties) {
|
@@ -0,0 +1,34 @@
|
|
1
|
+
// Copyright 2022 The Chromium Authors. All rights reserved.
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
3
|
+
// found in the LICENSE file.
|
4
|
+
|
5
|
+
export const buildStyledRuleText = (property: String, value: String|undefined): string => {
|
6
|
+
if (value === undefined) {
|
7
|
+
return buildStyledPropertyText(property);
|
8
|
+
}
|
9
|
+
return '<code class="unbreakable-text"><span class="property">' + property + '</span>: ' + value + '</code>';
|
10
|
+
};
|
11
|
+
|
12
|
+
export const buildStyledPropertyText = (property: String): string => {
|
13
|
+
return '<code class="unbreakable-text"><span class="property">' + property + '</span></code>';
|
14
|
+
};
|
15
|
+
|
16
|
+
export const isFlexContainer = (computedStyles: Map<String, String>|null): boolean => {
|
17
|
+
if (computedStyles === null) {
|
18
|
+
return false;
|
19
|
+
}
|
20
|
+
const display = computedStyles.get('display');
|
21
|
+
return display === 'flex' || display === 'inline-flex';
|
22
|
+
};
|
23
|
+
|
24
|
+
export const isGridContainer = (computedStyles: Map<String, String>): boolean => {
|
25
|
+
const display = computedStyles.get('display');
|
26
|
+
return display === 'grid' || display === 'inline-grid';
|
27
|
+
};
|
28
|
+
|
29
|
+
export const isMulticolContainer = (computedStyles: Map<String, String>): boolean => {
|
30
|
+
const columnWidth = computedStyles.get('column-width');
|
31
|
+
const columnCount = computedStyles.get('column-count');
|
32
|
+
|
33
|
+
return columnWidth !== 'auto' || columnCount !== 'auto';
|
34
|
+
};
|
@@ -26,6 +26,8 @@ import {cssRuleValidatorsMap, type AuthoringHint} from './CSSRuleValidator.js';
|
|
26
26
|
const FlexboxEditor = ElementsComponents.StylePropertyEditor.FlexboxEditor;
|
27
27
|
const GridEditor = ElementsComponents.StylePropertyEditor.GridEditor;
|
28
28
|
|
29
|
+
export const activeHints = new WeakMap<Element, AuthoringHint>();
|
30
|
+
|
29
31
|
const UIStrings = {
|
30
32
|
/**
|
31
33
|
*@description Text in Color Swatch Popover Icon of the Elements panel
|
@@ -719,11 +721,7 @@ export class StylePropertyTreeElement extends UI.TreeOutline.TreeElement {
|
|
719
721
|
const showAuthoringHint = authoringHint !== null && this.property.parsedOk;
|
720
722
|
if (showAuthoringHint) {
|
721
723
|
const hintIcon = UI.Icon.Icon.create('mediumicon-info', 'hint');
|
722
|
-
|
723
|
-
new UI.PopoverHelper.PopoverHelper(hintIcon, event => this.handleHintPopoverRequest(authoringHint, event));
|
724
|
-
hintPopover.setHasPadding(true);
|
725
|
-
hintPopover.setTimeout(0, 100);
|
726
|
-
|
724
|
+
activeHints.set(hintIcon, authoringHint);
|
727
725
|
this.listItemElement.append(hintIcon);
|
728
726
|
}
|
729
727
|
|
@@ -829,31 +827,13 @@ export class StylePropertyTreeElement extends UI.TreeOutline.TreeElement {
|
|
829
827
|
|
830
828
|
for (const validator of cssRuleValidatorsMap.get(propertyName) || []) {
|
831
829
|
if (!validator.isRuleValid(computedStyles, parentComputedStyles)) {
|
832
|
-
return validator.getAuthoringHint(propertyName, this.parentsComputedStyles);
|
830
|
+
return validator.getAuthoringHint(propertyName, this.computedStyles, this.parentsComputedStyles);
|
833
831
|
}
|
834
832
|
}
|
835
833
|
|
836
834
|
return null;
|
837
835
|
}
|
838
836
|
|
839
|
-
private handleHintPopoverRequest(authoringHint: AuthoringHint, event: Event): UI.PopoverHelper.PopoverRequest|null {
|
840
|
-
const link = event.composedPath()[0];
|
841
|
-
Platform.DCHECK(() => link instanceof Element, 'Link is not an instance of Element');
|
842
|
-
|
843
|
-
return {
|
844
|
-
box: (link as Element).boxInWindow(),
|
845
|
-
show: async(popover: UI.GlassPane.GlassPane): Promise<boolean> => {
|
846
|
-
const node = this.node();
|
847
|
-
if (!node) {
|
848
|
-
return false;
|
849
|
-
}
|
850
|
-
const popupElement = new ElementsComponents.CSSHintDetailsView.CSSHintDetailsView(authoringHint);
|
851
|
-
popover.contentElement.insertAdjacentElement('beforeend', popupElement);
|
852
|
-
return true;
|
853
|
-
},
|
854
|
-
};
|
855
|
-
}
|
856
|
-
|
857
837
|
private mouseUp(event: MouseEvent): void {
|
858
838
|
const activeTreeElement = parentMap.get(this.parentPaneInternal);
|
859
839
|
parentMap.delete(this.parentPaneInternal);
|
@@ -60,7 +60,7 @@ import {StyleEditorWidget} from './StyleEditorWidget.js';
|
|
60
60
|
import {StylePropertyHighlighter} from './StylePropertyHighlighter.js';
|
61
61
|
import stylesSidebarPaneStyles from './stylesSidebarPane.css.js';
|
62
62
|
|
63
|
-
import {type StylePropertyTreeElement} from './StylePropertyTreeElement.js';
|
63
|
+
import {activeHints, type StylePropertyTreeElement} from './StylePropertyTreeElement.js';
|
64
64
|
import {
|
65
65
|
StylePropertiesSection,
|
66
66
|
BlankStylePropertiesSection,
|
@@ -213,6 +213,7 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
|
|
213
213
|
private needsForceUpdate: boolean;
|
214
214
|
private readonly resizeThrottler: Common.Throttler.Throttler;
|
215
215
|
private readonly imagePreviewPopover: ImagePreviewPopover;
|
216
|
+
#hintPopoverHelper: UI.PopoverHelper.PopoverHelper;
|
216
217
|
activeCSSAngle: InlineEditor.CSSAngle.CSSAngle|null;
|
217
218
|
#urlToChangeTracker: Map<Platform.DevToolsPath.UrlString, ChangeTracker> = new Map();
|
218
219
|
#copyChangesButton?: UI.Toolbar.ToolbarButton;
|
@@ -282,6 +283,35 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
|
|
282
283
|
}, () => this.node());
|
283
284
|
|
284
285
|
this.activeCSSAngle = null;
|
286
|
+
|
287
|
+
this.#hintPopoverHelper = new UI.PopoverHelper.PopoverHelper(this.contentElement, event => {
|
288
|
+
const icon = event.composedPath()[0] as Element;
|
289
|
+
|
290
|
+
if (!icon) {
|
291
|
+
return null;
|
292
|
+
}
|
293
|
+
|
294
|
+
if (!icon.matches('.hint')) {
|
295
|
+
return null;
|
296
|
+
}
|
297
|
+
|
298
|
+
const hint = activeHints.get(icon);
|
299
|
+
|
300
|
+
if (!hint) {
|
301
|
+
return null;
|
302
|
+
}
|
303
|
+
|
304
|
+
return {
|
305
|
+
box: icon.boxInWindow(),
|
306
|
+
show: async(popover: UI.GlassPane.GlassPane): Promise<boolean> => {
|
307
|
+
const popupElement = new ElementsComponents.CSSHintDetailsView.CSSHintDetailsView(hint);
|
308
|
+
popover.contentElement.appendChild(popupElement);
|
309
|
+
return true;
|
310
|
+
},
|
311
|
+
};
|
312
|
+
});
|
313
|
+
this.#hintPopoverHelper.setTimeout(200);
|
314
|
+
this.#hintPopoverHelper.setHasPadding(true);
|
285
315
|
}
|
286
316
|
|
287
317
|
swatchPopoverHelper(): InlineEditor.SwatchPopoverHelper.SwatchPopoverHelper {
|
@@ -57,6 +57,7 @@ export class AttributionReportingIssueDetailsView extends AffectedResourcesView
|
|
57
57
|
switch (issueCode) {
|
58
58
|
case IssuesManager.AttributionReportingIssue.IssueCode.InvalidRegisterSourceHeader:
|
59
59
|
case IssuesManager.AttributionReportingIssue.IssueCode.InvalidRegisterTriggerHeader:
|
60
|
+
case IssuesManager.AttributionReportingIssue.IssueCode.InvalidEligibleHeader:
|
60
61
|
this.appendColumnTitle(header, i18nString(UIStrings.request));
|
61
62
|
this.appendColumnTitle(header, i18nString(UIStrings.invalidHeaderValue));
|
62
63
|
break;
|
@@ -92,6 +93,7 @@ export class AttributionReportingIssueDetailsView extends AffectedResourcesView
|
|
92
93
|
switch (issueCode) {
|
93
94
|
case IssuesManager.AttributionReportingIssue.IssueCode.InvalidRegisterSourceHeader:
|
94
95
|
case IssuesManager.AttributionReportingIssue.IssueCode.InvalidRegisterTriggerHeader:
|
96
|
+
case IssuesManager.AttributionReportingIssue.IssueCode.InvalidEligibleHeader:
|
95
97
|
this.#appendRequestOrEmptyCell(element, details.request);
|
96
98
|
this.appendIssueDetailCell(element, details.invalidParameter || '');
|
97
99
|
break;
|
@@ -27,17 +27,12 @@ details[open] .header-count {
|
|
27
27
|
display: none;
|
28
28
|
}
|
29
29
|
|
30
|
-
details
|
30
|
+
details .hide-when-closed {
|
31
31
|
display: none;
|
32
32
|
}
|
33
33
|
|
34
|
-
details[open]
|
35
|
-
display:
|
36
|
-
gap: 2px;
|
37
|
-
}
|
38
|
-
|
39
|
-
.raw-checkbox-container {
|
40
|
-
float: right;
|
34
|
+
details[open] .hide-when-closed {
|
35
|
+
display: block;
|
41
36
|
}
|
42
37
|
|
43
38
|
details summary input {
|
@@ -175,3 +170,40 @@ div.raw-headers-row {
|
|
175
170
|
font-size: 90%;
|
176
171
|
color: var(--color-text-secondary);
|
177
172
|
}
|
173
|
+
|
174
|
+
.header-grid-container {
|
175
|
+
display: inline-grid;
|
176
|
+
grid-template-columns: 156px 50px 1fr;
|
177
|
+
grid-gap: 4px;
|
178
|
+
/* Make this fit into the same line as the summary marker */
|
179
|
+
width: calc(100% - 15px);
|
180
|
+
}
|
181
|
+
|
182
|
+
.header-grid-container div:last-child {
|
183
|
+
text-align: right;
|
184
|
+
}
|
185
|
+
|
186
|
+
.header .devtools-link {
|
187
|
+
color: var(--color-text-primary);
|
188
|
+
}
|
189
|
+
|
190
|
+
x-link .inline-icon { /* stylelint-disable-line selector-type-no-unknown */
|
191
|
+
padding-right: 3px;
|
192
|
+
}
|
193
|
+
|
194
|
+
.purple-dot {
|
195
|
+
filter: hue-rotate(160deg);
|
196
|
+
}
|
197
|
+
|
198
|
+
.-theme-with-dark-background .purple-dot,
|
199
|
+
:host-context(.-theme-with-dark-background) .purple-dot {
|
200
|
+
filter: invert(80%) hue-rotate(350deg);
|
201
|
+
}
|
202
|
+
|
203
|
+
summary label {
|
204
|
+
color: var(--color-text-secondary);
|
205
|
+
}
|
206
|
+
|
207
|
+
summary label:hover {
|
208
|
+
color: var(--color-text-primary);
|
209
|
+
}
|