chrome-devtools-frontend 1.0.1035963 → 1.0.1036501
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/AUTHORS +1 -0
- package/front_end/models/persistence/NetworkPersistenceManager.ts +25 -14
- package/front_end/panels/elements/CSSRuleValidator.ts +1 -1
- package/front_end/panels/elements/StylePropertiesSection.ts +12 -0
- package/front_end/panels/elements/StylePropertyTreeElement.ts +1 -1
- package/front_end/panels/elements/StylesSidebarPane.ts +1 -0
- package/front_end/panels/network/NetworkLogView.ts +13 -5
- package/front_end/panels/sources/components/HeadersView.ts +8 -41
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryHighlightChipList.ts +11 -9
- package/front_end/ui/components/linear_memory_inspector/linearMemoryHighlightChipList.css +48 -30
- package/package.json +1 -1
package/AUTHORS
CHANGED
@@ -17,6 +17,7 @@ Alexey Rodionov <fluorescent.hallucinogen@gmail.com>
|
|
17
17
|
Ankit Mishra <ankit.mishra131990@gmail.com>
|
18
18
|
Anna Agoha <annaagoha@gmail.com>
|
19
19
|
Anthony Xie <anthonyxie64@gmail.com>
|
20
|
+
Boris Verkhovskiy <boris.verk@gmail.com>
|
20
21
|
Carl Espe <carl@cpespe.com>
|
21
22
|
Conner Turner <cturner@zyme.xyz>
|
22
23
|
Daniel bellfield <dnlbellfield@gmail.com>
|
@@ -622,19 +622,27 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
|
|
622
622
|
}
|
623
623
|
}
|
624
624
|
|
625
|
-
mergeHeaders(baseHeaders: Protocol.Fetch.HeaderEntry[], overrideHeaders: Protocol.
|
625
|
+
mergeHeaders(baseHeaders: Protocol.Fetch.HeaderEntry[], overrideHeaders: Protocol.Fetch.HeaderEntry[]):
|
626
626
|
Protocol.Fetch.HeaderEntry[] {
|
627
|
-
const
|
628
|
-
const
|
629
|
-
|
630
|
-
headerMap.set(header.name, header.value);
|
627
|
+
const headerMap = new Platform.MapUtilities.Multimap<string, string>();
|
628
|
+
for (const {name, value} of overrideHeaders) {
|
629
|
+
headerMap.set(name.toLowerCase(), value);
|
631
630
|
}
|
632
|
-
|
633
|
-
|
631
|
+
|
632
|
+
const overriddenHeaderNames = new Set(headerMap.keysArray());
|
633
|
+
for (const {name, value} of baseHeaders) {
|
634
|
+
const lowerCaseName = name.toLowerCase();
|
635
|
+
if (!overriddenHeaderNames.has(lowerCaseName)) {
|
636
|
+
headerMap.set(lowerCaseName, value);
|
637
|
+
}
|
638
|
+
}
|
639
|
+
|
640
|
+
const result: Protocol.Fetch.HeaderEntry[] = [];
|
641
|
+
for (const headerName of headerMap.keysArray()) {
|
642
|
+
for (const headerValue of headerMap.get(headerName)) {
|
643
|
+
result.push({name: headerName, value: headerValue});
|
644
|
+
}
|
634
645
|
}
|
635
|
-
headerMap.forEach((headerValue, headerName) => {
|
636
|
-
result.push({name: headerName, value: headerValue});
|
637
|
-
});
|
638
646
|
return result;
|
639
647
|
}
|
640
648
|
|
@@ -766,20 +774,23 @@ export type EventTypes = {
|
|
766
774
|
|
767
775
|
export interface HeaderOverride {
|
768
776
|
applyTo: string;
|
769
|
-
headers: Protocol.
|
777
|
+
headers: Protocol.Fetch.HeaderEntry[];
|
770
778
|
}
|
771
779
|
|
772
780
|
interface HeaderOverrideWithRegex {
|
773
781
|
applyToRegex: RegExp;
|
774
|
-
headers: Protocol.
|
782
|
+
headers: Protocol.Fetch.HeaderEntry[];
|
775
783
|
}
|
776
784
|
|
777
785
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
778
786
|
export function isHeaderOverride(arg: any): arg is HeaderOverride {
|
779
|
-
if (!(arg && arg.applyTo && typeof
|
787
|
+
if (!(arg && arg.applyTo && typeof arg.applyTo === 'string' && arg.headers && arg.headers.length &&
|
788
|
+
Array.isArray(arg.headers))) {
|
780
789
|
return false;
|
781
790
|
}
|
782
|
-
return
|
791
|
+
return arg.headers.every(
|
792
|
+
(header: Protocol.Fetch.HeaderEntry) =>
|
793
|
+
header.name && typeof header.name === 'string' && header.value && typeof header.value === 'string');
|
783
794
|
}
|
784
795
|
|
785
796
|
export function escapeRegex(pattern: string): string {
|
@@ -142,7 +142,7 @@ export class AlignContentValidator extends CSSRuleValidator {
|
|
142
142
|
if (this.#isRuleValid(computedStyles)) {
|
143
143
|
return;
|
144
144
|
}
|
145
|
-
const reasonPropertyDeclaration =
|
145
|
+
const reasonPropertyDeclaration = buildPropertyDefinitionText('flex-wrap', 'nowrap');
|
146
146
|
const affectedPropertyDeclarationCode = buildPropertyText('align-content');
|
147
147
|
|
148
148
|
return new Hint(
|
@@ -298,6 +298,18 @@ export class StylePropertiesSection {
|
|
298
298
|
this.parentsComputedStyles = parentsComputedStyles;
|
299
299
|
}
|
300
300
|
|
301
|
+
updateAuthoringHint(): void {
|
302
|
+
let child = this.propertiesTreeOutline.firstChild();
|
303
|
+
while (child) {
|
304
|
+
if (child instanceof StylePropertyTreeElement) {
|
305
|
+
child.setComputedStyles(this.computedStyles);
|
306
|
+
child.setParentsComputedStyles(this.parentsComputedStyles);
|
307
|
+
child.updateAuthoringHint();
|
308
|
+
}
|
309
|
+
child = child.nextSibling;
|
310
|
+
}
|
311
|
+
}
|
312
|
+
|
301
313
|
setSectionIdx(sectionIdx: number): void {
|
302
314
|
this.sectionIdx = sectionIdx;
|
303
315
|
this.onpopulate();
|
@@ -761,7 +761,7 @@ export class StylePropertyTreeElement extends UI.TreeOutline.TreeElement {
|
|
761
761
|
}
|
762
762
|
}
|
763
763
|
|
764
|
-
|
764
|
+
updateAuthoringHint(): void {
|
765
765
|
if (!Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.CSS_AUTHORING_HINTS)) {
|
766
766
|
return;
|
767
767
|
}
|
@@ -785,6 +785,7 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
|
|
785
785
|
for (const section of this.allSections()) {
|
786
786
|
section.setComputedStyles(computedStyles);
|
787
787
|
section.setParentsComputedStyles(parentsComputedStyles);
|
788
|
+
section.updateAuthoringHint();
|
788
789
|
}
|
789
790
|
}
|
790
791
|
|
@@ -1662,7 +1662,7 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
1662
1662
|
}
|
1663
1663
|
|
1664
1664
|
private async copyCurlCommand(request: SDK.NetworkRequest.NetworkRequest, platform: string): Promise<void> {
|
1665
|
-
const command = await
|
1665
|
+
const command = await NetworkLogView.generateCurlCommand(request, platform);
|
1666
1666
|
Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(command);
|
1667
1667
|
}
|
1668
1668
|
|
@@ -2092,7 +2092,7 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
2092
2092
|
return commands.join(' ;\n');
|
2093
2093
|
}
|
2094
2094
|
|
2095
|
-
|
2095
|
+
static async generateCurlCommand(request: SDK.NetworkRequest.NetworkRequest, platform: string): Promise<string> {
|
2096
2096
|
let command: string[] = [];
|
2097
2097
|
// Most of these headers are derived from the URL and are automatically added by cURL.
|
2098
2098
|
// The |Accept-Encoding| header is ignored to prevent decompression errors. crbug.com/1015321
|
@@ -2115,7 +2115,7 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
2115
2115
|
gets to MS Crt parser safely.
|
2116
2116
|
|
2117
2117
|
The % character is special because MS Crt parser will try and look for
|
2118
|
-
ENV variables and fill them in
|
2118
|
+
ENV variables and fill them in its place. We cannot escape them with %
|
2119
2119
|
and cannot escape them with ^ (because it's cmd.exe's escape not MS Crt
|
2120
2120
|
parser); So we can get cmd.exe parser to escape the character after it,
|
2121
2121
|
if it is followed by a valid beginning character of an ENV variable.
|
@@ -2191,7 +2191,14 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
2191
2191
|
if (ignoredHeaders.has(name.toLowerCase())) {
|
2192
2192
|
continue;
|
2193
2193
|
}
|
2194
|
-
|
2194
|
+
if (header.value.trim()) {
|
2195
|
+
command.push('-H ' + escapeString(name + ': ' + header.value));
|
2196
|
+
} else {
|
2197
|
+
// A header passed with -H with no value or only whitespace as its
|
2198
|
+
// value tells curl to not set the header at all. To post an empty
|
2199
|
+
// header, you have to terminate it with a semicolon.
|
2200
|
+
command.push('-H ' + escapeString(name + ';'));
|
2201
|
+
}
|
2195
2202
|
}
|
2196
2203
|
command = command.concat(data);
|
2197
2204
|
command.push('--compressed');
|
@@ -2205,7 +2212,8 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
2205
2212
|
private async generateAllCurlCommand(requests: SDK.NetworkRequest.NetworkRequest[], platform: string):
|
2206
2213
|
Promise<string> {
|
2207
2214
|
const nonBlobRequests = this.filterOutBlobRequests(requests);
|
2208
|
-
const commands =
|
2215
|
+
const commands =
|
2216
|
+
await Promise.all(nonBlobRequests.map(request => NetworkLogView.generateCurlCommand(request, platform)));
|
2209
2217
|
if (platform === 'win') {
|
2210
2218
|
return commands.join(' &\r\n');
|
2211
2219
|
}
|
@@ -9,6 +9,7 @@ import * as Buttons from '../../../ui/components/buttons/buttons.js';
|
|
9
9
|
import * as ComponentHelpers from '../../../ui/components/helpers/helpers.js';
|
10
10
|
import * as UI from '../../../ui/legacy/legacy.js';
|
11
11
|
import * as LitHtml from '../../../ui/lit-html/lit-html.js';
|
12
|
+
import type * as Protocol from '../../../generated/protocol.js';
|
12
13
|
|
13
14
|
import HeadersViewStyles from './HeadersView.css.js';
|
14
15
|
|
@@ -81,23 +82,8 @@ export class HeadersView extends UI.View.SimpleView {
|
|
81
82
|
parsingError = true;
|
82
83
|
}
|
83
84
|
|
84
|
-
// Header overrides are stored as the key-value pairs of a JSON object on
|
85
|
-
// disk. For the editor we want them as an array instead, so that we can
|
86
|
-
// access/add/remove entries by their index.
|
87
|
-
const arrayOfHeaderOverrideArrays: HeaderOverride[] = headerOverrides.map(headerOverride => {
|
88
|
-
return {
|
89
|
-
applyTo: headerOverride.applyTo,
|
90
|
-
headers: Object.entries(headerOverride.headers).map(([headerName, headerValue]) => {
|
91
|
-
return {
|
92
|
-
name: headerName,
|
93
|
-
value: headerValue,
|
94
|
-
};
|
95
|
-
}),
|
96
|
-
};
|
97
|
-
});
|
98
|
-
|
99
85
|
this.#headersViewComponent.data = {
|
100
|
-
headerOverrides
|
86
|
+
headerOverrides,
|
101
87
|
uiSourceCode: this.#uiSourceCode,
|
102
88
|
parsingError,
|
103
89
|
};
|
@@ -128,18 +114,8 @@ export class HeadersView extends UI.View.SimpleView {
|
|
128
114
|
}
|
129
115
|
}
|
130
116
|
|
131
|
-
type Header = {
|
132
|
-
name: string,
|
133
|
-
value: string,
|
134
|
-
};
|
135
|
-
|
136
|
-
type HeaderOverride = {
|
137
|
-
applyTo: string,
|
138
|
-
headers: Header[],
|
139
|
-
};
|
140
|
-
|
141
117
|
export interface HeadersViewComponentData {
|
142
|
-
headerOverrides: HeaderOverride[];
|
118
|
+
headerOverrides: Persistence.NetworkPersistenceManager.HeaderOverride[];
|
143
119
|
uiSourceCode: Workspace.UISourceCode.UISourceCode;
|
144
120
|
parsingError: boolean;
|
145
121
|
}
|
@@ -148,7 +124,7 @@ export class HeadersViewComponent extends HTMLElement {
|
|
148
124
|
static readonly litTagName = LitHtml.literal`devtools-sources-headers-view`;
|
149
125
|
readonly #shadow = this.attachShadow({mode: 'open'});
|
150
126
|
readonly #boundRender = this.#render.bind(this);
|
151
|
-
#headerOverrides: HeaderOverride[] = [];
|
127
|
+
#headerOverrides: Persistence.NetworkPersistenceManager.HeaderOverride[] = [];
|
152
128
|
#uiSourceCode: Workspace.UISourceCode.UISourceCode|null = null;
|
153
129
|
#parsingError = false;
|
154
130
|
#focusElement: {blockIndex: number, headerIndex?: number}|null = null;
|
@@ -213,7 +189,7 @@ export class HeadersViewComponent extends HTMLElement {
|
|
213
189
|
selection?.removeAllRanges();
|
214
190
|
}
|
215
191
|
|
216
|
-
#generateNextHeaderName(headers:
|
192
|
+
#generateNextHeaderName(headers: Protocol.Fetch.HeaderEntry[]): string {
|
217
193
|
const takenNames = new Set<string>(headers.map(header => header.name));
|
218
194
|
let idx = 1;
|
219
195
|
while (takenNames.has('headerName' + idx)) {
|
@@ -270,17 +246,7 @@ export class HeadersViewComponent extends HTMLElement {
|
|
270
246
|
}
|
271
247
|
|
272
248
|
#onHeadersChanged(): void {
|
273
|
-
|
274
|
-
// that we can access/add/remove entries by their index. On disk, they are
|
275
|
-
// stored as key-value pairs of a JSON object instead.
|
276
|
-
const arrayOfHeaderOverrideObjects: Persistence.NetworkPersistenceManager.HeaderOverride[] =
|
277
|
-
this.#headerOverrides.map(headerOverride => {
|
278
|
-
return {
|
279
|
-
applyTo: headerOverride.applyTo,
|
280
|
-
headers: headerOverride.headers.reduce((a, v) => ({...a, [v.name]: v.value}), {}),
|
281
|
-
};
|
282
|
-
});
|
283
|
-
this.#uiSourceCode?.setWorkingCopy(JSON.stringify(arrayOfHeaderOverrideObjects, null, 2));
|
249
|
+
this.#uiSourceCode?.setWorkingCopy(JSON.stringify(this.#headerOverrides, null, 2));
|
284
250
|
}
|
285
251
|
|
286
252
|
#render(): void {
|
@@ -355,7 +321,8 @@ export class HeadersViewComponent extends HTMLElement {
|
|
355
321
|
// clang-format on
|
356
322
|
}
|
357
323
|
|
358
|
-
#renderHeaderRow(header:
|
324
|
+
#renderHeaderRow(header: Protocol.Fetch.HeaderEntry, blockIndex: number, headerIndex: number):
|
325
|
+
LitHtml.TemplateResult {
|
359
326
|
// clang-format off
|
360
327
|
return LitHtml.html`
|
361
328
|
<div class="row padded" data-block-index=${blockIndex} data-header-index=${headerIndex}>
|
@@ -95,15 +95,17 @@ export class LinearMemoryHighlightChipList extends HTMLElement {
|
|
95
95
|
<span class="value">${expressionName}</span><span class="separator">: </span><span>${expressionType}</span>
|
96
96
|
</span>
|
97
97
|
</button>
|
98
|
-
<
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
98
|
+
<div class="delete-highlight-container">
|
99
|
+
<button class="delete-highlight-button" title=${
|
100
|
+
i18nString(UIStrings.deleteHighlight)} @click=${():void => this.#onDeleteHighlightClick(highlightInfo)}>
|
101
|
+
<${IconButton.Icon.Icon.litTagName} .data=${{
|
102
|
+
iconName: 'close-icon',
|
103
|
+
color: 'var(--color-text-primary)',
|
104
|
+
width: '7px',
|
105
|
+
} as IconButton.Icon.IconData}>
|
106
|
+
</${IconButton.Icon.Icon.litTagName}>
|
107
|
+
</button>
|
108
|
+
</div>
|
107
109
|
</div>
|
108
110
|
`;
|
109
111
|
// clang-format off
|
@@ -5,81 +5,99 @@
|
|
5
5
|
*/
|
6
6
|
|
7
7
|
.highlight-chip-list {
|
8
|
-
min-height:
|
8
|
+
min-height: 20px;
|
9
9
|
display: flex;
|
10
10
|
flex-wrap: wrap;
|
11
11
|
justify-content: left;
|
12
12
|
align-items: center;
|
13
13
|
background-color: var(--color-background);
|
14
|
-
|
14
|
+
margin: 8px 0;
|
15
|
+
gap: 8px;
|
16
|
+
row-gap: 6px;
|
15
17
|
}
|
16
18
|
|
17
19
|
.highlight-chip {
|
18
|
-
background:
|
19
|
-
|
20
|
-
|
21
|
-
height: 15px;
|
22
|
-
margin-right: 5px;
|
23
|
-
padding: 1px;
|
20
|
+
background: var(--color-background);
|
21
|
+
border: 1px solid var(--color-button-secondary-border);
|
22
|
+
height: 18px;
|
24
23
|
border-radius: 4px;
|
25
|
-
|
26
|
-
|
24
|
+
flex: 0 0 auto;
|
25
|
+
max-width: 250px;
|
26
|
+
position: relative;
|
27
|
+
padding: 0 6px;
|
27
28
|
}
|
28
29
|
|
29
30
|
.highlight-chip:hover {
|
30
31
|
background-color: var(--color-background-elevation-1);
|
31
32
|
}
|
32
33
|
|
34
|
+
.delete-highlight-container {
|
35
|
+
display: none;
|
36
|
+
height: 100%;
|
37
|
+
position: absolute;
|
38
|
+
right: 0;
|
39
|
+
top: 0;
|
40
|
+
border-radius: 4px;
|
41
|
+
width: 24px;
|
42
|
+
align-items: center;
|
43
|
+
justify-content: center;
|
44
|
+
}
|
45
|
+
|
33
46
|
.delete-highlight-button {
|
34
|
-
width: 15px;
|
35
|
-
height: 15px;
|
36
|
-
border: none;
|
37
|
-
padding: 0;
|
38
47
|
cursor: pointer;
|
39
|
-
|
40
|
-
|
48
|
+
width: 13px;
|
49
|
+
height: 13px;
|
50
|
+
border: none;
|
51
|
+
background-color: transparent;
|
41
52
|
display: flex;
|
42
|
-
justify-content: center;
|
43
53
|
align-items: center;
|
44
|
-
|
54
|
+
justify-content: center;
|
45
55
|
}
|
46
56
|
|
47
57
|
.delete-highlight-button:hover {
|
48
58
|
background-color: var(--color-details-hairline);
|
59
|
+
border-radius: 50%;
|
49
60
|
}
|
50
61
|
|
51
|
-
.highlight-chip > .delete-highlight-
|
52
|
-
|
62
|
+
.highlight-chip:hover > .delete-highlight-container {
|
63
|
+
display: flex;
|
64
|
+
/* To avoid issues with stacking semi-transparent colors, we use a hardcoded solid color here. */
|
65
|
+
background: linear-gradient(90deg, transparent 0%, rgb(241 243 244) 25%); /* stylelint-disable-line plugin/use_theme_colors */
|
53
66
|
}
|
54
67
|
|
55
|
-
.highlight-chip:hover > .delete-highlight-
|
56
|
-
|
68
|
+
:host-context(.-theme-with-dark-background) .highlight-chip:hover > .delete-highlight-container {
|
69
|
+
display: flex;
|
70
|
+
/* To avoid issues with stacking semi-transparent colors, we use a hardcoded solid color here. */
|
71
|
+
background: linear-gradient(90deg, transparent 0%, rgb(41 42 45) 25%); /* stylelint-disable-line plugin/use_theme_colors */
|
57
72
|
}
|
58
73
|
|
59
74
|
.jump-to-highlight-button {
|
60
75
|
cursor: pointer;
|
61
|
-
padding: 0
|
76
|
+
padding: 0;
|
62
77
|
border: none;
|
63
78
|
background: none;
|
64
|
-
|
79
|
+
height: 100%;
|
65
80
|
align-items: center;
|
66
|
-
|
67
|
-
|
68
|
-
.jump-to-highlight-button:hover {
|
69
|
-
color: var(--color-text-primary);
|
81
|
+
max-width: 100%;
|
82
|
+
overflow: hidden;
|
70
83
|
}
|
71
84
|
|
72
85
|
.delete-highlight-button devtools-icon {
|
73
|
-
|
86
|
+
width: 13px;
|
87
|
+
height: 13px;
|
88
|
+
display: flex;
|
89
|
+
align-items: center;
|
90
|
+
justify-content: center;
|
91
|
+
border-radius: 50%;
|
74
92
|
}
|
75
93
|
|
76
94
|
.source-code {
|
77
95
|
font-family: var(--source-code-font-family);
|
78
96
|
font-size: var(--source-code-font-size);
|
79
|
-
max-width: 250px;
|
80
97
|
overflow: hidden;
|
81
98
|
text-overflow: ellipsis;
|
82
99
|
white-space: nowrap;
|
100
|
+
color: var(--color-text-primary);
|
83
101
|
}
|
84
102
|
|
85
103
|
.value {
|
package/package.json
CHANGED