chrome-devtools-frontend 1.0.1030070 → 1.0.1031400
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 +3 -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/Tests.js +0 -28
- package/front_end/core/host/UserMetrics.ts +2 -1
- package/front_end/core/i18n/locales/en-US.json +18 -9
- package/front_end/core/i18n/locales/en-XL.json +18 -9
- package/front_end/core/platform/string-utilities.ts +2 -5
- package/front_end/core/root/Runtime.ts +1 -0
- package/front_end/core/sdk/CSSStyleSheetHeader.ts +0 -4
- package/front_end/core/sdk/CompilerSourceMappingContentProvider.ts +0 -4
- package/front_end/core/sdk/NetworkRequest.ts +0 -4
- package/front_end/core/sdk/Resource.ts +0 -5
- package/front_end/core/sdk/Script.ts +71 -76
- package/front_end/core/sdk/Target.ts +4 -0
- package/front_end/entrypoints/inspector_main/InspectorMain.ts +4 -1
- package/front_end/entrypoints/main/MainImpl.ts +4 -0
- package/front_end/generated/InspectorBackendCommands.js +10 -8
- package/front_end/generated/protocol-mapping.d.ts +16 -2
- package/front_end/generated/protocol-proxy-api.d.ts +11 -1
- package/front_end/generated/protocol.ts +75 -1
- package/front_end/models/bindings/CompilerScriptMapping.ts +6 -3
- package/front_end/models/bindings/ContentProviderBasedProject.ts +2 -3
- package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +1 -4
- package/front_end/models/bindings/IgnoreListManager.ts +10 -8
- package/front_end/models/bindings/ResourceMapping.ts +0 -4
- package/front_end/models/bindings/StylesSourceMapping.ts +0 -5
- package/front_end/models/extensions/ExtensionServer.ts +2 -3
- package/front_end/models/issues_manager/AttributionReportingIssue.ts +8 -0
- package/front_end/models/issues_manager/DeprecationIssue.ts +5 -1
- package/front_end/models/issues_manager/descriptions/arTooManyConcurrentRequests.md +5 -0
- package/front_end/models/javascript_metadata/NativeFunctions.js +6 -2
- package/front_end/models/persistence/NetworkPersistenceManager.ts +4 -6
- package/front_end/models/persistence/PersistenceActions.ts +5 -4
- package/front_end/models/text_utils/CodeMirrorUtils.ts +17 -4
- package/front_end/models/text_utils/ContentProvider.ts +0 -1
- package/front_end/models/text_utils/StaticContentProvider.ts +0 -4
- package/front_end/models/workspace/UISourceCode.ts +10 -5
- package/front_end/panels/application/components/StackTrace.ts +2 -2
- package/front_end/panels/elements/CSSRuleValidator.ts +382 -63
- package/front_end/panels/elements/CSSRuleValidatorHelper.ts +34 -0
- package/front_end/panels/elements/ElementsTreeOutline.ts +23 -7
- package/front_end/panels/elements/StylePropertyTreeElement.ts +1 -1
- package/front_end/panels/elements/TopLayerContainer.ts +17 -28
- package/front_end/panels/elements/components/CSSHintDetailsView.ts +23 -20
- package/front_end/panels/elements/components/cssHintDetailsView.css +8 -2
- package/front_end/panels/elements/stylesSectionTree.css +1 -1
- package/front_end/panels/issues/AttributionReportingIssueDetailsView.ts +12 -0
- package/front_end/panels/network/components/RequestHeadersView.css +41 -8
- package/front_end/panels/network/components/RequestHeadersView.ts +102 -12
- package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +1 -0
- package/front_end/panels/sources/FilteredUISourceCodeListProvider.ts +7 -0
- package/front_end/panels/sources/NavigatorView.ts +22 -0
- package/front_end/panels/sources/ScopeChainSidebarPane.ts +3 -3
- package/front_end/third_party/codemirror.next/bundle.ts +1 -1
- package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/cpp.js +1 -2
- package/front_end/third_party/codemirror.next/chunk/java.js +1 -2
- package/front_end/third_party/codemirror.next/chunk/json.js +1 -2
- package/front_end/third_party/codemirror.next/chunk/markdown.js +1 -2
- package/front_end/third_party/codemirror.next/chunk/php.js +1 -2
- package/front_end/third_party/codemirror.next/chunk/python.js +1 -2
- package/front_end/third_party/codemirror.next/chunk/wast.js +1 -2
- package/front_end/third_party/codemirror.next/chunk/xml.js +1 -2
- package/front_end/third_party/codemirror.next/codemirror.next.d.ts +1247 -116
- package/front_end/third_party/codemirror.next/codemirror.next.js +1 -2
- 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/components/docs/building-ui-documentation/StylingComponents.md +64 -0
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryInspector.ts +2 -3
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryInspectorController.ts +97 -17
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryInspectorPane.ts +1 -1
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryViewerUtils.ts +4 -0
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +9 -7
- package/front_end/ui/legacy/components/source_frame/ImageView.ts +10 -11
- package/front_end/ui/legacy/components/source_frame/PreviewFactory.ts +1 -1
- package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +49 -0
- package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +18 -17
- package/package.json +6 -5
@@ -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
|
+
};
|
@@ -103,7 +103,7 @@ export class ElementsTreeOutline extends
|
|
103
103
|
private treeElementBeingDragged?: ElementsTreeElement;
|
104
104
|
private dragOverTreeElement?: ElementsTreeElement;
|
105
105
|
private updateModifiedNodesTimeout?: number;
|
106
|
-
|
106
|
+
#topLayerContainerByParent: Map<UI.TreeOutline.TreeElement, TopLayerContainer> = new Map();
|
107
107
|
|
108
108
|
constructor(omitRootDOMNode?: boolean, selectEnabled?: boolean, hideGutter?: boolean) {
|
109
109
|
super();
|
@@ -453,7 +453,7 @@ export class ElementsTreeOutline extends
|
|
453
453
|
}
|
454
454
|
}
|
455
455
|
|
456
|
-
this.createTopLayerContainer();
|
456
|
+
void this.createTopLayerContainer(this.rootElement(), this.rootDOMNode.domModel());
|
457
457
|
|
458
458
|
if (selectedNode) {
|
459
459
|
this.revealAndSelectNode(selectedNode, true);
|
@@ -1183,9 +1183,16 @@ export class ElementsTreeOutline extends
|
|
1183
1183
|
});
|
1184
1184
|
}
|
1185
1185
|
|
1186
|
-
createTopLayerContainer(): void {
|
1187
|
-
|
1188
|
-
|
1186
|
+
async createTopLayerContainer(parent: UI.TreeOutline.TreeElement, domModel: SDK.DOMModel.DOMModel): Promise<void> {
|
1187
|
+
if (!parent.treeOutline || !(parent.treeOutline instanceof ElementsTreeOutline)) {
|
1188
|
+
return;
|
1189
|
+
}
|
1190
|
+
const container = new TopLayerContainer(parent.treeOutline, domModel);
|
1191
|
+
await container.throttledUpdateTopLayerElements();
|
1192
|
+
if (container.currentTopLayerElements.size > 0) {
|
1193
|
+
parent.appendChild(container);
|
1194
|
+
}
|
1195
|
+
this.#topLayerContainerByParent.set(parent, container);
|
1189
1196
|
}
|
1190
1197
|
|
1191
1198
|
private createElementTreeElement(node: SDK.DOMModel.DOMNode, isClosingTag?: boolean): ElementsTreeElement {
|
@@ -1342,6 +1349,9 @@ export class ElementsTreeOutline extends
|
|
1342
1349
|
isClosingTag?: boolean): ElementsTreeElement {
|
1343
1350
|
const newElement = this.createElementTreeElement(child, isClosingTag);
|
1344
1351
|
treeElement.insertChild(newElement, index);
|
1352
|
+
if (child.nodeType() === Node.DOCUMENT_NODE) {
|
1353
|
+
void this.createTopLayerContainer(newElement, child.domModel());
|
1354
|
+
}
|
1345
1355
|
return newElement;
|
1346
1356
|
}
|
1347
1357
|
|
@@ -1447,8 +1457,14 @@ export class ElementsTreeOutline extends
|
|
1447
1457
|
}
|
1448
1458
|
}
|
1449
1459
|
|
1450
|
-
private topLayerElementsChanged(): void {
|
1451
|
-
|
1460
|
+
private async topLayerElementsChanged(): Promise<void> {
|
1461
|
+
for (const [parent, container] of this.#topLayerContainerByParent) {
|
1462
|
+
await container.throttledUpdateTopLayerElements();
|
1463
|
+
if (container.currentTopLayerElements.size > 0 && container.parent !== parent) {
|
1464
|
+
parent.appendChild(container);
|
1465
|
+
}
|
1466
|
+
container.hidden = container.currentTopLayerElements.size === 0;
|
1467
|
+
}
|
1452
1468
|
}
|
1453
1469
|
|
1454
1470
|
private static treeOutlineSymbol = Symbol('treeOutline');
|
@@ -827,7 +827,7 @@ export class StylePropertyTreeElement extends UI.TreeOutline.TreeElement {
|
|
827
827
|
|
828
828
|
for (const validator of cssRuleValidatorsMap.get(propertyName) || []) {
|
829
829
|
if (!validator.isRuleValid(computedStyles, parentComputedStyles)) {
|
830
|
-
return validator.getAuthoringHint(propertyName, this.parentsComputedStyles);
|
830
|
+
return validator.getAuthoringHint(propertyName, this.computedStyles, this.parentsComputedStyles);
|
831
831
|
}
|
832
832
|
}
|
833
833
|
|
@@ -14,23 +14,24 @@ import {type ElementsTreeElement} from './ElementsTreeElement.js';
|
|
14
14
|
|
15
15
|
const UIStrings = {
|
16
16
|
/**
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
*@description Link text content in Elements Tree Outline of the Elements panel. When clicked, it "reveals" the true location of an element.
|
18
|
+
*/
|
19
|
+
reveal: 'reveal',
|
20
20
|
};
|
21
21
|
|
22
22
|
const str_ = i18n.i18n.registerUIStrings('panels/elements/TopLayerContainer.ts', UIStrings);
|
23
23
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
24
24
|
|
25
25
|
export class TopLayerContainer extends UI.TreeOutline.TreeElement {
|
26
|
-
|
26
|
+
tree: ElementsTreeOutline.ElementsTreeOutline;
|
27
|
+
domModel: SDK.DOMModel.DOMModel;
|
27
28
|
currentTopLayerElements: Set<ElementsTreeElement>;
|
28
29
|
topLayerUpdateThrottler: Common.Throttler.Throttler;
|
29
|
-
#inserted = false;
|
30
30
|
|
31
|
-
constructor(
|
31
|
+
constructor(tree: ElementsTreeOutline.ElementsTreeOutline, domModel: SDK.DOMModel.DOMModel) {
|
32
32
|
super('#top-layer');
|
33
|
-
this.
|
33
|
+
this.tree = tree;
|
34
|
+
this.domModel = domModel;
|
34
35
|
this.currentTopLayerElements = new Set();
|
35
36
|
this.topLayerUpdateThrottler = new Common.Throttler.Throttler(1);
|
36
37
|
}
|
@@ -44,26 +45,19 @@ export class TopLayerContainer extends UI.TreeOutline.TreeElement {
|
|
44
45
|
this.removeCurrentTopLayerElementsAdorners();
|
45
46
|
this.currentTopLayerElements = new Set();
|
46
47
|
|
47
|
-
const
|
48
|
-
if (!domModel) {
|
49
|
-
this.hidden = true;
|
50
|
-
return;
|
51
|
-
}
|
52
|
-
|
53
|
-
const newTopLayerElementsIDs = await domModel.getTopLayerElements();
|
48
|
+
const newTopLayerElementsIDs = await this.domModel.getTopLayerElements();
|
54
49
|
if (!newTopLayerElementsIDs || newTopLayerElementsIDs.length === 0) {
|
55
|
-
this.hidden = true;
|
56
50
|
return;
|
57
51
|
}
|
58
52
|
|
59
53
|
let topLayerElementIndex = 0;
|
60
54
|
for (let i = 0; i < newTopLayerElementsIDs.length; i++) {
|
61
|
-
const topLayerDOMNode = domModel.idToDOMNode.get(newTopLayerElementsIDs[i]);
|
55
|
+
const topLayerDOMNode = this.domModel.idToDOMNode.get(newTopLayerElementsIDs[i]);
|
62
56
|
if (topLayerDOMNode && topLayerDOMNode.nodeName() !== '::backdrop') {
|
63
57
|
const topLayerElementShortcut = new SDK.DOMModel.DOMNodeShortcut(
|
64
|
-
domModel.target(), topLayerDOMNode.backendNodeId(), 0, topLayerDOMNode.nodeName());
|
58
|
+
this.domModel.target(), topLayerDOMNode.backendNodeId(), 0, topLayerDOMNode.nodeName());
|
65
59
|
const topLayerElementRepresentation = new ElementsTreeOutline.ShortcutTreeElement(topLayerElementShortcut);
|
66
|
-
const topLayerTreeElement = this.
|
60
|
+
const topLayerTreeElement = this.tree.treeElementByNode.get(topLayerDOMNode);
|
67
61
|
if (!topLayerTreeElement) {
|
68
62
|
continue;
|
69
63
|
}
|
@@ -73,21 +67,16 @@ export class TopLayerContainer extends UI.TreeOutline.TreeElement {
|
|
73
67
|
this.currentTopLayerElements.add(topLayerTreeElement);
|
74
68
|
this.appendChild(topLayerElementRepresentation);
|
75
69
|
// Add the element's backdrop if previous top layer element is a backdrop.
|
76
|
-
const previousTopLayerDOMNode =
|
70
|
+
const previousTopLayerDOMNode =
|
71
|
+
(i > 0) ? this.domModel.idToDOMNode.get(newTopLayerElementsIDs[i - 1]) : undefined;
|
77
72
|
if (previousTopLayerDOMNode && previousTopLayerDOMNode.nodeName() === '::backdrop') {
|
78
73
|
const backdropElementShortcut = new SDK.DOMModel.DOMNodeShortcut(
|
79
|
-
domModel.target(), previousTopLayerDOMNode.backendNodeId(), 0, previousTopLayerDOMNode.nodeName());
|
74
|
+
this.domModel.target(), previousTopLayerDOMNode.backendNodeId(), 0, previousTopLayerDOMNode.nodeName());
|
80
75
|
const backdropElementRepresentation = new ElementsTreeOutline.ShortcutTreeElement(backdropElementShortcut);
|
81
76
|
topLayerElementRepresentation.appendChild(backdropElementRepresentation);
|
82
77
|
}
|
83
78
|
}
|
84
79
|
}
|
85
|
-
|
86
|
-
this.hidden = topLayerElementIndex <= 0;
|
87
|
-
if (!this.hidden && !this.#inserted) {
|
88
|
-
this.domContainer.appendChild(this);
|
89
|
-
this.#inserted = true;
|
90
|
-
}
|
91
80
|
}
|
92
81
|
|
93
82
|
private removeCurrentTopLayerElementsAdorners(): void {
|
@@ -118,8 +107,8 @@ export class TopLayerContainer extends UI.TreeOutline.TreeElement {
|
|
118
107
|
adorner.addInteraction(onClick, {
|
119
108
|
isToggle: false,
|
120
109
|
shouldPropagateOnKeydown: false,
|
121
|
-
ariaLabelDefault: i18nString(UIStrings.
|
122
|
-
ariaLabelActive: i18nString(UIStrings.
|
110
|
+
ariaLabelDefault: i18nString(UIStrings.reveal),
|
111
|
+
ariaLabelActive: i18nString(UIStrings.reveal),
|
123
112
|
});
|
124
113
|
adorner.addEventListener('mousedown', e => e.consume(), false);
|
125
114
|
}
|
@@ -23,7 +23,7 @@ interface Hint {
|
|
23
23
|
getHintPrefix(): string;
|
24
24
|
getHintMessage(): string;
|
25
25
|
getPossibleFixMessage(): string|null;
|
26
|
-
getLearnMoreLink(): string|
|
26
|
+
getLearnMoreLink(): string|undefined;
|
27
27
|
}
|
28
28
|
|
29
29
|
export class CSSHintDetailsView extends HTMLElement {
|
@@ -39,25 +39,28 @@ export class CSSHintDetailsView extends HTMLElement {
|
|
39
39
|
}
|
40
40
|
|
41
41
|
#render(): void {
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
42
|
+
const link = this.#authoringHint.getLearnMoreLink();
|
43
|
+
// clang-format off
|
44
|
+
render(html`
|
45
|
+
<div class="hint-popup-wrapper">
|
46
|
+
<div class="hint-popup-reason">
|
47
|
+
<strong>${this.#authoringHint.getHintPrefix()}:</strong> ${Directives.unsafeHTML(this.#authoringHint.getHintMessage())}
|
48
|
+
</div>
|
49
|
+
${this.#authoringHint.getPossibleFixMessage() ? html`
|
50
|
+
<div class="hint-popup-possible-fix">
|
51
|
+
${Directives.unsafeHTML(this.#authoringHint.getPossibleFixMessage())}
|
52
|
+
${link ? html`
|
53
|
+
<x-link id="learn-more" href=${link} class="clickable underlined unbreakable-text"}>
|
54
|
+
${i18nString(UIStrings.learnMore)}
|
55
|
+
</x-link>
|
56
|
+
`: ''}
|
57
|
+
</div>
|
58
|
+
` : ''}
|
59
|
+
</div>
|
60
|
+
`, this.#shadow, {
|
61
|
+
host: this,
|
62
|
+
});
|
63
|
+
// clang-format on
|
61
64
|
}
|
62
65
|
}
|
63
66
|
|
@@ -4,15 +4,21 @@
|
|
4
4
|
* found in the LICENSE file.
|
5
5
|
*/
|
6
6
|
|
7
|
+
:host {
|
8
|
+
padding: 6px;
|
9
|
+
}
|
10
|
+
|
7
11
|
.hint-popup-wrapper {
|
8
|
-
width:
|
9
|
-
line-height: 1.1;
|
12
|
+
max-width: 232px;
|
10
13
|
font-size: 12px;
|
14
|
+
line-height: 1.4;
|
11
15
|
}
|
12
16
|
|
13
17
|
code {
|
14
18
|
background-color: var(--color-background-elevation-1);
|
15
19
|
padding: 0 2px;
|
20
|
+
font-size: var(--source-code-font-size);
|
21
|
+
font-family: var(--source-code-font-family);
|
16
22
|
}
|
17
23
|
|
18
24
|
.property {
|
@@ -22,6 +22,10 @@ const UIStrings = {
|
|
22
22
|
* @description Noun, label for the column showing the invalid header value in the issue details table.
|
23
23
|
*/
|
24
24
|
invalidHeaderValue: 'Invalid Header Value',
|
25
|
+
/**
|
26
|
+
* @description Noun, label for the column showing the maximum concurrent registrations header value in the issue details table.
|
27
|
+
*/
|
28
|
+
maximumConcurrentRegistrations: 'Maximum Concurrent Registrations',
|
25
29
|
/**
|
26
30
|
* @description Noun, label for the column showing the associated network request in the issue details table.
|
27
31
|
*/
|
@@ -71,6 +75,10 @@ export class AttributionReportingIssueDetailsView extends AffectedResourcesView
|
|
71
75
|
this.appendColumnTitle(header, i18nString(UIStrings.element));
|
72
76
|
this.appendColumnTitle(header, i18nString(UIStrings.request));
|
73
77
|
break;
|
78
|
+
case IssuesManager.AttributionReportingIssue.IssueCode.TooManyConcurrentRequests:
|
79
|
+
this.appendColumnTitle(header, i18nString(UIStrings.element));
|
80
|
+
this.appendColumnTitle(header, i18nString(UIStrings.maximumConcurrentRegistrations));
|
81
|
+
break;
|
74
82
|
}
|
75
83
|
|
76
84
|
this.affectedResources.appendChild(header);
|
@@ -107,6 +115,10 @@ export class AttributionReportingIssueDetailsView extends AffectedResourcesView
|
|
107
115
|
await this.#appendElementOrEmptyCell(element, issue);
|
108
116
|
this.#appendRequestOrEmptyCell(element, details.request);
|
109
117
|
break;
|
118
|
+
case IssuesManager.AttributionReportingIssue.IssueCode.TooManyConcurrentRequests:
|
119
|
+
await this.#appendElementOrEmptyCell(element, issue);
|
120
|
+
this.appendIssueDetailCell(element, details.invalidParameter || '');
|
121
|
+
break;
|
110
122
|
}
|
111
123
|
|
112
124
|
this.affectedResources.appendChild(element);
|
@@ -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 {
|
@@ -69,6 +64,7 @@ div.raw-headers-row {
|
|
69
64
|
font-weight: 500;
|
70
65
|
width: 160px;
|
71
66
|
flex-shrink: 0;
|
67
|
+
text-transform: capitalize;
|
72
68
|
}
|
73
69
|
|
74
70
|
.header-value {
|
@@ -175,3 +171,40 @@ div.raw-headers-row {
|
|
175
171
|
font-size: 90%;
|
176
172
|
color: var(--color-text-secondary);
|
177
173
|
}
|
174
|
+
|
175
|
+
.header-grid-container {
|
176
|
+
display: inline-grid;
|
177
|
+
grid-template-columns: 156px 50px 1fr;
|
178
|
+
grid-gap: 4px;
|
179
|
+
/* Make this fit into the same line as the summary marker */
|
180
|
+
width: calc(100% - 15px);
|
181
|
+
}
|
182
|
+
|
183
|
+
.header-grid-container div:last-child {
|
184
|
+
text-align: right;
|
185
|
+
}
|
186
|
+
|
187
|
+
.header .devtools-link {
|
188
|
+
color: var(--color-text-primary);
|
189
|
+
}
|
190
|
+
|
191
|
+
x-link .inline-icon { /* stylelint-disable-line selector-type-no-unknown */
|
192
|
+
padding-right: 3px;
|
193
|
+
}
|
194
|
+
|
195
|
+
.purple-dot {
|
196
|
+
filter: hue-rotate(160deg);
|
197
|
+
}
|
198
|
+
|
199
|
+
.-theme-with-dark-background .purple-dot,
|
200
|
+
:host-context(.-theme-with-dark-background) .purple-dot {
|
201
|
+
filter: invert(80%) hue-rotate(350deg);
|
202
|
+
}
|
203
|
+
|
204
|
+
summary label {
|
205
|
+
color: var(--color-text-secondary);
|
206
|
+
}
|
207
|
+
|
208
|
+
summary label:hover {
|
209
|
+
color: var(--color-text-primary);
|
210
|
+
}
|
@@ -6,9 +6,12 @@ import * as Common from '../../../core/common/common.js';
|
|
6
6
|
import * as Host from '../../../core/host/host.js';
|
7
7
|
import * as i18n from '../../../core/i18n/i18n.js';
|
8
8
|
import * as Platform from '../../../core/platform/platform.js';
|
9
|
+
import * as Root from '../../../core/root/root.js';
|
9
10
|
import * as SDK from '../../../core/sdk/sdk.js';
|
10
11
|
import * as Protocol from '../../../generated/protocol.js';
|
11
12
|
import * as IssuesManager from '../../../models/issues_manager/issues_manager.js';
|
13
|
+
import * as Persistence from '../../../models/persistence/persistence.js';
|
14
|
+
import * as Workspace from '../../../models/workspace/workspace.js';
|
12
15
|
import * as ClientVariations from '../../../third_party/chromium/client-variations/client-variations.js';
|
13
16
|
import * as Buttons from '../../../ui/components/buttons/buttons.js';
|
14
17
|
import * as ComponentHelpers from '../../../ui/components/helpers/helpers.js';
|
@@ -16,6 +19,7 @@ import * as IconButton from '../../../ui/components/icon_button/icon_button.js';
|
|
16
19
|
import * as Input from '../../../ui/components/input/input.js';
|
17
20
|
import * as UI from '../../../ui/legacy/legacy.js';
|
18
21
|
import * as LitHtml from '../../../ui/lit-html/lit-html.js';
|
22
|
+
import * as Sources from '../../sources/sources.js';
|
19
23
|
|
20
24
|
import requestHeadersViewStyles from './RequestHeadersView.css.js';
|
21
25
|
|
@@ -69,6 +73,11 @@ const UIStrings = {
|
|
69
73
|
*/
|
70
74
|
general: 'General',
|
71
75
|
/**
|
76
|
+
*@description Label for a link from the network panel's headers view to the file in which
|
77
|
+
* header overrides are defined in the sources panel.
|
78
|
+
*/
|
79
|
+
headerOverrides: 'Header overrides',
|
80
|
+
/**
|
72
81
|
*@description Text that is usually a hyperlink to more documentation
|
73
82
|
*/
|
74
83
|
learnMore: 'Learn more',
|
@@ -204,6 +213,7 @@ export class RequestHeadersComponent extends HTMLElement {
|
|
204
213
|
#showRequestHeadersText = false;
|
205
214
|
#showResponseHeadersTextFull = false;
|
206
215
|
#showRequestHeadersTextFull = false;
|
216
|
+
readonly #workspace = Workspace.Workspace.WorkspaceImpl.instance();
|
207
217
|
|
208
218
|
set data(data: RequestHeadersComponentData) {
|
209
219
|
this.#request = data.request;
|
@@ -212,6 +222,23 @@ export class RequestHeadersComponent extends HTMLElement {
|
|
212
222
|
|
213
223
|
connectedCallback(): void {
|
214
224
|
this.#shadow.adoptedStyleSheets = [requestHeadersViewStyles];
|
225
|
+
this.#workspace.addEventListener(
|
226
|
+
Workspace.Workspace.Events.UISourceCodeAdded, this.#uiSourceCodeAddedOrRemoved, this);
|
227
|
+
this.#workspace.addEventListener(
|
228
|
+
Workspace.Workspace.Events.UISourceCodeRemoved, this.#uiSourceCodeAddedOrRemoved, this);
|
229
|
+
}
|
230
|
+
|
231
|
+
disconnectedCallback(): void {
|
232
|
+
this.#workspace.removeEventListener(
|
233
|
+
Workspace.Workspace.Events.UISourceCodeAdded, this.#uiSourceCodeAddedOrRemoved, this);
|
234
|
+
this.#workspace.removeEventListener(
|
235
|
+
Workspace.Workspace.Events.UISourceCodeRemoved, this.#uiSourceCodeAddedOrRemoved, this);
|
236
|
+
}
|
237
|
+
|
238
|
+
#uiSourceCodeAddedOrRemoved(event: Common.EventTarget.EventTargetEvent<Workspace.UISourceCode.UISourceCode>): void {
|
239
|
+
if (this.#getHeaderOverridesFileUrl() === event.data.url()) {
|
240
|
+
this.#render();
|
241
|
+
}
|
215
242
|
}
|
216
243
|
|
217
244
|
#render(): void {
|
@@ -284,6 +311,10 @@ export class RequestHeadersComponent extends HTMLElement {
|
|
284
311
|
this.#render();
|
285
312
|
};
|
286
313
|
|
314
|
+
if (!mergedHeaders.length) {
|
315
|
+
return LitHtml.nothing;
|
316
|
+
}
|
317
|
+
|
287
318
|
// Disabled until https://crbug.com/1079231 is fixed.
|
288
319
|
// clang-format off
|
289
320
|
return html`
|
@@ -294,6 +325,7 @@ export class RequestHeadersComponent extends HTMLElement {
|
|
294
325
|
title: i18nString(UIStrings.responseHeaders),
|
295
326
|
headerCount: this.#request.sortedResponseHeaders.length,
|
296
327
|
checked: this.#request.responseHeadersText ? this.#showResponseHeadersText : undefined,
|
328
|
+
additionalContent: this.#renderHeaderOverridesLink(),
|
297
329
|
} as CategoryData}
|
298
330
|
aria-label=${i18nString(UIStrings.responseHeaders)}
|
299
331
|
>
|
@@ -306,6 +338,57 @@ export class RequestHeadersComponent extends HTMLElement {
|
|
306
338
|
// clang-format on
|
307
339
|
}
|
308
340
|
|
341
|
+
#renderHeaderOverridesLink(): LitHtml.LitTemplate {
|
342
|
+
const overrideable = Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.HEADER_OVERRIDES);
|
343
|
+
if (!overrideable || !this.#workspace.uiSourceCodeForURL(this.#getHeaderOverridesFileUrl())) {
|
344
|
+
return LitHtml.nothing;
|
345
|
+
}
|
346
|
+
|
347
|
+
const overridesSetting: Common.Settings.Setting<boolean> =
|
348
|
+
Common.Settings.Settings.instance().moduleSetting('persistenceNetworkOverridesEnabled');
|
349
|
+
// Disabled until https://crbug.com/1079231 is fixed.
|
350
|
+
// clang-format off
|
351
|
+
const fileIcon = overridesSetting.get() ? html`
|
352
|
+
<${IconButton.Icon.Icon.litTagName} class="inline-icon purple-dot" .data=${{
|
353
|
+
iconName: 'file-sync_icon',
|
354
|
+
width: '11px',
|
355
|
+
height: '13px',
|
356
|
+
} as IconButton.Icon.IconData}>
|
357
|
+
</${IconButton.Icon.Icon.litTagName}>` : html`
|
358
|
+
<${IconButton.Icon.Icon.litTagName} class="inline-icon" .data=${{
|
359
|
+
iconName: 'file_icon',
|
360
|
+
color: 'var(--color-text-primary)',
|
361
|
+
width: '12px',
|
362
|
+
height: '12px',
|
363
|
+
} as IconButton.Icon.IconData}>
|
364
|
+
</${IconButton.Icon.Icon.litTagName}>`;
|
365
|
+
// clang-format on
|
366
|
+
|
367
|
+
const revealHeadersFile = (event: Event): void => {
|
368
|
+
event.preventDefault();
|
369
|
+
const uiSourceCode = this.#workspace.uiSourceCodeForURL(this.#getHeaderOverridesFileUrl());
|
370
|
+
if (uiSourceCode) {
|
371
|
+
Sources.SourcesPanel.SourcesPanel.instance().showUISourceCode(uiSourceCode);
|
372
|
+
}
|
373
|
+
};
|
374
|
+
|
375
|
+
return html`
|
376
|
+
<x-link @click=${revealHeadersFile} class="link devtools-link">
|
377
|
+
${fileIcon}${i18nString(UIStrings.headerOverrides)}
|
378
|
+
</x-link>
|
379
|
+
`;
|
380
|
+
}
|
381
|
+
|
382
|
+
#getHeaderOverridesFileUrl(): Platform.DevToolsPath.UrlString {
|
383
|
+
if (!this.#request) {
|
384
|
+
return Platform.DevToolsPath.EmptyUrlString;
|
385
|
+
}
|
386
|
+
const fileUrl = Persistence.NetworkPersistenceManager.NetworkPersistenceManager.instance().fileUrlFromNetworkUrl(
|
387
|
+
this.#request.url(), /* ignoreInactive */ true);
|
388
|
+
return fileUrl.substring(0, fileUrl.lastIndexOf('/')) + '/' +
|
389
|
+
Persistence.NetworkPersistenceManager.HEADERS_FILENAME as Platform.DevToolsPath.UrlString;
|
390
|
+
}
|
391
|
+
|
309
392
|
#renderRequestHeaders(): LitHtml.LitTemplate {
|
310
393
|
if (!this.#request) {
|
311
394
|
return LitHtml.nothing;
|
@@ -316,6 +399,9 @@ export class RequestHeadersComponent extends HTMLElement {
|
|
316
399
|
return Platform.StringUtilities.compare(a.name.toLowerCase(), b.name.toLowerCase());
|
317
400
|
});
|
318
401
|
const requestHeadersText = this.#request.requestHeadersText();
|
402
|
+
if (!headers.length && requestHeadersText !== undefined) {
|
403
|
+
return LitHtml.nothing;
|
404
|
+
}
|
319
405
|
|
320
406
|
const toggleShowRaw = (): void => {
|
321
407
|
this.#showRequestHeadersText = !this.#showRequestHeadersText;
|
@@ -647,6 +733,7 @@ export interface CategoryData {
|
|
647
733
|
title: Common.UIString.LocalizedString;
|
648
734
|
headerCount?: number;
|
649
735
|
checked?: boolean;
|
736
|
+
additionalContent?: LitHtml.LitTemplate;
|
650
737
|
}
|
651
738
|
|
652
739
|
export class Category extends HTMLElement {
|
@@ -656,6 +743,7 @@ export class Category extends HTMLElement {
|
|
656
743
|
#title: Common.UIString.LocalizedString = Common.UIString.LocalizedEmptyString;
|
657
744
|
#headerCount?: number = undefined;
|
658
745
|
#checked: boolean|undefined = undefined;
|
746
|
+
#additionalContent: LitHtml.LitTemplate|undefined = undefined;
|
659
747
|
|
660
748
|
connectedCallback(): void {
|
661
749
|
this.#shadow.adoptedStyleSheets = [requestHeadersViewStyles, Input.checkboxStyles];
|
@@ -667,6 +755,7 @@ export class Category extends HTMLElement {
|
|
667
755
|
Common.Settings.Settings.instance().createSetting('request-info-' + data.name + '-category-expanded', true);
|
668
756
|
this.#headerCount = data.headerCount;
|
669
757
|
this.#checked = data.checked;
|
758
|
+
this.#additionalContent = data.additionalContent;
|
670
759
|
this.#render();
|
671
760
|
}
|
672
761
|
|
@@ -681,18 +770,19 @@ export class Category extends HTMLElement {
|
|
681
770
|
render(html`
|
682
771
|
<details ?open=${isOpen} @toggle=${this.#onToggle}>
|
683
772
|
<summary class="header" @keydown=${this.#onSummaryKeyDown}>
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
773
|
+
<div class="header-grid-container">
|
774
|
+
<div>
|
775
|
+
${this.#title}${this.#headerCount ?
|
776
|
+
html`<span class="header-count"> (${this.#headerCount})</span>` :
|
777
|
+
LitHtml.nothing
|
778
|
+
}
|
779
|
+
</div>
|
780
|
+
<div class="hide-when-closed">
|
781
|
+
${this.#checked !== undefined ? html`
|
782
|
+
<label><input type="checkbox" .checked=${this.#checked} @change=${this.#onCheckboxToggle} />${i18nString(UIStrings.raw)}</label>
|
783
|
+
` : LitHtml.nothing}
|
784
|
+
</div>
|
785
|
+
<div class="hide-when-closed">${this.#additionalContent}</div>
|
696
786
|
</summary>
|
697
787
|
<slot></slot>
|
698
788
|
</details>
|
@@ -4,7 +4,9 @@
|
|
4
4
|
|
5
5
|
import type * as Common from '../../core/common/common.js';
|
6
6
|
import * as i18n from '../../core/i18n/i18n.js';
|
7
|
+
import * as Bindings from '../../models/bindings/bindings.js';
|
7
8
|
import * as Persistence from '../../models/persistence/persistence.js';
|
9
|
+
import * as Root from '../../core/root/root.js';
|
8
10
|
import * as Workspace from '../../models/workspace/workspace.js';
|
9
11
|
import * as QuickOpen from '../../ui/legacy/components/quick_open/quick_open.js';
|
10
12
|
import * as UI from '../../ui/legacy/legacy.js';
|
@@ -62,6 +64,11 @@ export class FilteredUISourceCodeListProvider extends QuickOpen.FilteredListWidg
|
|
62
64
|
if (this.uiSourceCodeUrls.has(uiSourceCode.url())) {
|
63
65
|
return false;
|
64
66
|
}
|
67
|
+
if (Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.JUST_MY_CODE) &&
|
68
|
+
Bindings.IgnoreListManager.IgnoreListManager.instance().isUserOrSourceMapIgnoreListedUISourceCode(
|
69
|
+
uiSourceCode)) {
|
70
|
+
return false;
|
71
|
+
}
|
65
72
|
const binding = Persistence.Persistence.PersistenceImpl.instance().binding(uiSourceCode);
|
66
73
|
return !binding || binding.fileSystem === uiSourceCode;
|
67
74
|
}
|