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 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.Network.Headers):
625
+ mergeHeaders(baseHeaders: Protocol.Fetch.HeaderEntry[], overrideHeaders: Protocol.Fetch.HeaderEntry[]):
626
626
  Protocol.Fetch.HeaderEntry[] {
627
- const result: Protocol.Fetch.HeaderEntry[] = [];
628
- const headerMap = new Map<string, string>();
629
- for (const header of baseHeaders) {
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
- for (const [headerName, headerValue] of Object.entries(overrideHeaders)) {
633
- headerMap.set(headerName, headerValue);
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.Network.Headers;
777
+ headers: Protocol.Fetch.HeaderEntry[];
770
778
  }
771
779
 
772
780
  interface HeaderOverrideWithRegex {
773
781
  applyToRegex: RegExp;
774
- headers: Protocol.Network.Headers;
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 (arg.applyTo === 'string') && arg.headers && Object.keys(arg.headers).length)) {
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 Object.values(arg.headers).every(value => typeof value === 'string');
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 = buildPropertyText('flex-wrap');
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
- private updateAuthoringHint(): void {
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 this.generateCurlCommand(request, platform);
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
- private async generateCurlCommand(request: SDK.NetworkRequest.NetworkRequest, platform: string): Promise<string> {
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 it's place. We cannot escape them with %
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
- command.push('-H ' + escapeString(name + ': ' + header.value));
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 = await Promise.all(nonBlobRequests.map(request => this.generateCurlCommand(request, platform)));
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: arrayOfHeaderOverrideArrays,
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: Header[]): string {
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
- // In the editor header overrides are represented by items in an array, so
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: Header, blockIndex: number, headerIndex: number): LitHtml.TemplateResult {
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
- <button class="delete-highlight-button" title=${
99
- i18nString(UIStrings.deleteHighlight)} @click=${():void => this.#onDeleteHighlightClick(highlightInfo)}>
100
- <${IconButton.Icon.Icon.litTagName} .data=${{
101
- iconName: 'close-icon',
102
- color: 'black',
103
- width: '7px',
104
- } as IconButton.Icon.IconData}>
105
- </${IconButton.Icon.Icon.litTagName}>
106
- </button>
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: 24px;
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
- color: var(--color-text-primary);
14
+ margin: 8px 0;
15
+ gap: 8px;
16
+ row-gap: 6px;
15
17
  }
16
18
 
17
19
  .highlight-chip {
18
- background: transparent;
19
- color: var(--color-text-primary);
20
- border: 1px solid var(--color-background-elevation-2);
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
- margin-bottom: 1px;
26
- display: flex;
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
- background: none;
40
- border-radius: 50%;
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
- margin: 0 2px;
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-button {
52
- visibility: hidden;
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-button {
56
- visibility: visible;
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 0 0 4px;
76
+ padding: 0;
62
77
  border: none;
63
78
  background: none;
64
- display: flex;
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
- --icon-color: var(--color-text-primary);
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
@@ -56,5 +56,5 @@
56
56
  "unittest": "scripts/test/run_unittests.py --no-text-coverage",
57
57
  "watch": "vpython third_party/node/node.py --output scripts/watch_build.js"
58
58
  },
59
- "version": "1.0.1035963"
59
+ "version": "1.0.1036501"
60
60
  }