chrome-devtools-frontend 1.0.1700561 → 1.0.1701636
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/front_end/core/root/Runtime.ts +5 -0
- package/front_end/core/sdk/CSSPropertyParserMatchers.ts +16 -11
- package/front_end/core/sdk/NetworkManager.ts +7 -0
- package/front_end/core/sdk/SecurityOrigin.ts +1 -0
- package/front_end/core/sdk/SourceMap.ts +12 -1
- package/front_end/core/sdk/SourceMapCache.ts +12 -0
- package/front_end/core/sdk/SourceMapManager.ts +17 -8
- package/front_end/core/sdk/SourceMapScopeChainEntry.ts +2 -19
- package/front_end/core/sdk/SourceMapScopesInfo.ts +21 -0
- package/front_end/entrypoints/formatter_worker/ScopeParser.ts +7 -3
- package/front_end/entrypoints/formatter_worker/Substitute.ts +90 -26
- package/front_end/entrypoints/formatter_worker/formatter_worker-entrypoint.ts +1 -1
- package/front_end/entrypoints/main/ExecutionContextSelector.ts +17 -4
- package/front_end/generated/InspectorBackendCommands.ts +1 -3
- package/front_end/generated/protocol-mapping.d.ts +0 -8
- package/front_end/generated/protocol-proxy-api.d.ts +0 -6
- package/front_end/generated/protocol.ts +4 -22
- package/front_end/models/ai_assistance/debug.ts +10 -2
- package/front_end/models/comment_manager/CD4ABridge.ts +2 -2
- package/front_end/models/comment_manager/CommentManager.ts +3 -0
- package/front_end/models/formatter/FormatterWorkerPool.ts +2 -2
- package/front_end/models/javascript_metadata/NativeFunctions.ts +7 -2
- package/front_end/models/source_map_scopes/NamesResolver.ts +42 -39
- package/front_end/panels/accessibility/AccessibilityAnnouncementRecordingView.ts +70 -1
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +1 -1
- package/front_end/panels/common/CommentsOverlayWidget.ts +29 -2
- package/front_end/panels/common/ExtensionServer.ts +18 -8
- package/front_end/panels/console/ConsolePrompt.ts +1 -1
- package/front_end/panels/console/ConsoleViewMessage.ts +1 -1
- package/front_end/panels/elements/ClassesPaneWidget.ts +2 -1
- package/front_end/panels/elements/DOMTreeContextMenu.ts +1 -1
- package/front_end/panels/elements/{ElementsTreeOutline.ts → DOMTreeWidget.ts} +34 -24
- package/front_end/panels/elements/ElementsPanel.ts +1 -1
- package/front_end/panels/elements/ElementsTreeElement.ts +1 -1
- package/front_end/panels/elements/ShortcutTreeElement.ts +1 -1
- package/front_end/panels/elements/StylePropertyTreeElement.ts +1 -1
- package/front_end/panels/elements/StylesSidebarPane.ts +4 -6
- package/front_end/panels/elements/TopLayerContainer.ts +1 -1
- package/front_end/panels/elements/elements.ts +4 -3
- package/front_end/panels/profiler/HeapDetachedElementsDataGrid.ts +1 -1
- package/front_end/panels/profiler/HeapProfileView.ts +8 -6
- package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +8 -1
- package/front_end/panels/profiler/HeapSnapshotView.ts +6 -4
- package/front_end/panels/security/SecurityPanel.ts +87 -99
- package/front_end/panels/sensors/SensorsView.ts +87 -0
- package/front_end/panels/sensors/sensors-meta.ts +69 -1
- package/front_end/panels/settings/keybindsSettingsTab.css +1 -1
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/legacy/Treeoutline.ts +2 -1
- package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +1 -1
- package/front_end/ui/legacy/treeoutline.css +2 -2
- package/front_end/ui/visual_logging/KnownContextValues.ts +7 -0
- package/package.json +1 -1
|
@@ -75,7 +75,7 @@ import {ImagePreviewPopover} from './ImagePreviewPopover.js';
|
|
|
75
75
|
import {ShortcutTreeElement} from './ShortcutTreeElement.js';
|
|
76
76
|
import {TopLayerContainer} from './TopLayerContainer.js';
|
|
77
77
|
|
|
78
|
-
const {html, nothing, render, Directives: {classMap, repeat, styleMap}} = Lit;
|
|
78
|
+
const {html, nothing, render, Directives: {classMap, ifDefined, repeat, styleMap}} = Lit;
|
|
79
79
|
|
|
80
80
|
const UIStrings = {
|
|
81
81
|
/**
|
|
@@ -101,7 +101,7 @@ const UIStrings = {
|
|
|
101
101
|
*/
|
|
102
102
|
reveal: 'reveal',
|
|
103
103
|
} as const;
|
|
104
|
-
const str_ = i18n.i18n.registerUIStrings('panels/elements/
|
|
104
|
+
const str_ = i18n.i18n.registerUIStrings('panels/elements/DOMTreeWidget.ts', UIStrings);
|
|
105
105
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
106
106
|
const elementsTreeOutlineByDOMModel = new WeakMap<SDK.DOMModel.DOMModel, ElementsTreeOutline>();
|
|
107
107
|
|
|
@@ -919,6 +919,8 @@ export const DECLARATIVE_VIEW: View = (input: ViewInput, _output: ViewOutput, ta
|
|
|
919
919
|
// clang-format off
|
|
920
920
|
return html`
|
|
921
921
|
<li role="treeitem"
|
|
922
|
+
data-backend-node-id=${ifDefined(node.backendNodeId())}
|
|
923
|
+
data-target-id=${ifDefined(node.domModel().target().id())}
|
|
922
924
|
selectable=${input.selectEnabled ? 'true' : 'false'}
|
|
923
925
|
?selected=${isSelected && !input.selectedClosingTag}
|
|
924
926
|
class=${classes}
|
|
@@ -997,6 +999,8 @@ export const DECLARATIVE_VIEW: View = (input: ViewInput, _output: ViewOutput, ta
|
|
|
997
999
|
${node instanceof SDK.DOMModel.DOMDocument ? renderTopLayerContainer(node, depth + 1) : nothing}
|
|
998
1000
|
${needsClosingTag ? html`
|
|
999
1001
|
<li role="treeitem"
|
|
1002
|
+
data-backend-node-id=${ifDefined(node.backendNodeId())}
|
|
1003
|
+
data-target-id=${ifDefined(node.domModel().target().id())}
|
|
1000
1004
|
selectable=${input.selectEnabled ? 'true' : 'false'}
|
|
1001
1005
|
?selected=${isSelected && Boolean(input.selectedClosingTag)}
|
|
1002
1006
|
class=${classMap({
|
|
@@ -1348,7 +1352,7 @@ export class DOMTreeWidget extends UI.Widget.Widget {
|
|
|
1348
1352
|
element?: HTMLElement,
|
|
1349
1353
|
[changeTracker]:
|
|
1350
1354
|
UI.Widget.WidgetDependencies<typeof DOMTreeWidget>|[ChangeTracker.ChangeTracker.ChangeTracker?] = [],
|
|
1351
|
-
view: View =
|
|
1355
|
+
view: View = DECLARATIVE_VIEW,
|
|
1352
1356
|
) {
|
|
1353
1357
|
super(element, {
|
|
1354
1358
|
useShadowDom: false,
|
|
@@ -1358,12 +1362,12 @@ export class DOMTreeWidget extends UI.Widget.Widget {
|
|
|
1358
1362
|
this.#changeTracker = changeTracker;
|
|
1359
1363
|
this.#showHTMLCommentsSetting.addChangeListener(this.#onShowHTMLCommentsChange, this);
|
|
1360
1364
|
if (Common.Settings.Settings.instance().moduleSetting('highlight-node-on-hover-in-overlay').get()) {
|
|
1361
|
-
SDK.TargetManager.TargetManager.instance().addModelListener(
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
SDK.TargetManager.TargetManager.instance().addModelListener(
|
|
1365
|
-
|
|
1366
|
-
|
|
1365
|
+
SDK.TargetManager.TargetManager.instance().addModelListener(SDK.OverlayModel.OverlayModel,
|
|
1366
|
+
SDK.OverlayModel.Events.HIGHLIGHT_NODE_REQUESTED,
|
|
1367
|
+
this.#highlightNode, this, {scoped: true});
|
|
1368
|
+
SDK.TargetManager.TargetManager.instance().addModelListener(SDK.OverlayModel.OverlayModel,
|
|
1369
|
+
SDK.OverlayModel.Events.INSPECT_MODE_WILL_BE_TOGGLED,
|
|
1370
|
+
this.#clearHighlightedNode, this, {scoped: true});
|
|
1367
1371
|
}
|
|
1368
1372
|
this.#setupPopovers();
|
|
1369
1373
|
}
|
|
@@ -2245,7 +2249,7 @@ export class DOMTreeWidget extends UI.Widget.Widget {
|
|
|
2245
2249
|
this.onDocumentUpdated(domModel);
|
|
2246
2250
|
} else {
|
|
2247
2251
|
void domModel.requestDocument().then(document => {
|
|
2248
|
-
if (document && this.isShowing()) {
|
|
2252
|
+
if (document && this.isShowing() && this.#wiredDOMModels.has(domModel)) {
|
|
2249
2253
|
this.rootDOMNode = document;
|
|
2250
2254
|
this.onDocumentUpdated(domModel);
|
|
2251
2255
|
}
|
|
@@ -2269,6 +2273,12 @@ export class DOMTreeWidget extends UI.Widget.Widget {
|
|
|
2269
2273
|
this.#wiredDOMModels.delete(domModel);
|
|
2270
2274
|
this.#unwireDOMModel(domModel);
|
|
2271
2275
|
}
|
|
2276
|
+
if (this.#rootDOMNode?.domModel() === domModel) {
|
|
2277
|
+
this.#rootDOMNode = null;
|
|
2278
|
+
this.#selectedDOMNode = null;
|
|
2279
|
+
this.#expandedNodes.clear();
|
|
2280
|
+
this.#updateRecords.clear();
|
|
2281
|
+
}
|
|
2272
2282
|
this.performUpdate();
|
|
2273
2283
|
return;
|
|
2274
2284
|
}
|
|
@@ -3141,7 +3151,7 @@ export class DOMTreeWidget extends UI.Widget.Widget {
|
|
|
3141
3151
|
this.onDocumentUpdated(domModel);
|
|
3142
3152
|
} else if (this.#view === DECLARATIVE_VIEW) {
|
|
3143
3153
|
void domModel.requestDocument().then(document => {
|
|
3144
|
-
if (document && this.isShowing()) {
|
|
3154
|
+
if (document && this.isShowing() && this.#wiredDOMModels.has(domModel)) {
|
|
3145
3155
|
this.rootDOMNode = document;
|
|
3146
3156
|
this.onDocumentUpdated(domModel);
|
|
3147
3157
|
}
|
|
@@ -3472,8 +3482,8 @@ export class ElementsTreeOutline extends ElementsTreeOutlineBase {
|
|
|
3472
3482
|
}
|
|
3473
3483
|
|
|
3474
3484
|
selectedNodeChanged(focus: boolean): void {
|
|
3475
|
-
this.dispatchEventToListeners(
|
|
3476
|
-
|
|
3485
|
+
this.dispatchEventToListeners(ElementsTreeOutline.Events.SelectedNodeChanged,
|
|
3486
|
+
{node: this.selectedDOMNodeInternal, focus});
|
|
3477
3487
|
}
|
|
3478
3488
|
|
|
3479
3489
|
private fireElementsTreeUpdated(nodes: SDK.DOMModel.DOMNode[]): void {
|
|
@@ -3787,8 +3797,8 @@ export class ElementsTreeOutline extends ElementsTreeOutlineBase {
|
|
|
3787
3797
|
domModel.addEventListener(SDK.DOMModel.Events.DocumentURLChanged, this.documentURLChanged, this);
|
|
3788
3798
|
domModel.addEventListener(SDK.DOMModel.Events.ChildNodeCountUpdated, this.childNodeCountUpdated, this);
|
|
3789
3799
|
domModel.addEventListener(SDK.DOMModel.Events.DistributedNodesChanged, this.distributedNodesChanged, this);
|
|
3790
|
-
domModel.addEventListener(
|
|
3791
|
-
|
|
3800
|
+
domModel.addEventListener(SDK.DOMModel.Events.AffectedByStartingStylesFlagUpdated,
|
|
3801
|
+
this.affectedByStartingStylesFlagUpdated, this);
|
|
3792
3802
|
domModel.addEventListener(SDK.DOMModel.Events.AdoptedStyleSheetsModified, this.adoptedStyleSheetsModified, this);
|
|
3793
3803
|
}
|
|
3794
3804
|
|
|
@@ -3803,8 +3813,8 @@ export class ElementsTreeOutline extends ElementsTreeOutlineBase {
|
|
|
3803
3813
|
domModel.removeEventListener(SDK.DOMModel.Events.DocumentURLChanged, this.documentURLChanged, this);
|
|
3804
3814
|
domModel.removeEventListener(SDK.DOMModel.Events.ChildNodeCountUpdated, this.childNodeCountUpdated, this);
|
|
3805
3815
|
domModel.removeEventListener(SDK.DOMModel.Events.DistributedNodesChanged, this.distributedNodesChanged, this);
|
|
3806
|
-
domModel.removeEventListener(
|
|
3807
|
-
|
|
3816
|
+
domModel.removeEventListener(SDK.DOMModel.Events.AffectedByStartingStylesFlagUpdated,
|
|
3817
|
+
this.affectedByStartingStylesFlagUpdated, this);
|
|
3808
3818
|
domModel.removeEventListener(SDK.DOMModel.Events.AdoptedStyleSheetsModified, this.adoptedStyleSheetsModified, this);
|
|
3809
3819
|
elementsTreeOutlineByDOMModel.delete(domModel);
|
|
3810
3820
|
}
|
|
@@ -4026,8 +4036,8 @@ export class ElementsTreeOutline extends ElementsTreeOutlineBase {
|
|
|
4026
4036
|
return false;
|
|
4027
4037
|
}
|
|
4028
4038
|
|
|
4029
|
-
private createElementTreeElement(node: SDK.DOMModel.DOMNode|SDK.DOMModel.AdoptedStyleSheet[],
|
|
4030
|
-
|
|
4039
|
+
private createElementTreeElement(node: SDK.DOMModel.DOMNode|SDK.DOMModel.AdoptedStyleSheet[],
|
|
4040
|
+
isClosingTag?: boolean): UI.TreeOutline.TreeElement {
|
|
4031
4041
|
if (node instanceof Array) {
|
|
4032
4042
|
return new AdoptedStyleSheetSetTreeElement(node);
|
|
4033
4043
|
}
|
|
@@ -4202,9 +4212,9 @@ export class ElementsTreeOutline extends ElementsTreeOutlineBase {
|
|
|
4202
4212
|
this.#updateChildren(treeElement);
|
|
4203
4213
|
}
|
|
4204
4214
|
|
|
4205
|
-
insertChildElement(
|
|
4206
|
-
|
|
4207
|
-
|
|
4215
|
+
insertChildElement(treeElement: ElementsTreeElement|TopLayerContainer,
|
|
4216
|
+
child: SDK.DOMModel.DOMNode|SDK.DOMModel.AdoptedStyleSheet[], index: number,
|
|
4217
|
+
isClosingTag?: boolean): UI.TreeOutline.TreeElement {
|
|
4208
4218
|
const newElement = this.createElementTreeElement(child, isClosingTag);
|
|
4209
4219
|
treeElement.insertChild(newElement, index);
|
|
4210
4220
|
return newElement;
|
|
@@ -4237,8 +4247,8 @@ export class ElementsTreeOutline extends ElementsTreeOutlineBase {
|
|
|
4237
4247
|
|
|
4238
4248
|
// Remove any tree elements that no longer have this node as their parent and save
|
|
4239
4249
|
// all existing elements that could be reused. This also removes closing tag element.
|
|
4240
|
-
const existingTreeElements = new Map<
|
|
4241
|
-
|
|
4250
|
+
const existingTreeElements = new Map<SDK.DOMModel.DOMNode|SDK.DOMModel.AdoptedStyleSheet[],
|
|
4251
|
+
UI.TreeOutline.TreeElement&ElementsTreeElement>();
|
|
4242
4252
|
for (let i = treeElement.childCount() - 1; i >= 0; --i) {
|
|
4243
4253
|
const existingTreeElement = treeElement.childAt(i);
|
|
4244
4254
|
if (!(existingTreeElement instanceof ElementsTreeElement)) {
|
|
@@ -51,8 +51,8 @@ import {AccessibilityTreeView} from './AccessibilityTreeView.js';
|
|
|
51
51
|
import {ColorSwatchPopoverIcon} from './ColorSwatchPopoverIcon.js';
|
|
52
52
|
import * as ElementsComponents from './components/components.js';
|
|
53
53
|
import {ComputedStyleWidget} from './ComputedStyleWidget.js';
|
|
54
|
+
import {DOMTreeWidget, type ElementsTreeOutline} from './DOMTreeWidget.js';
|
|
54
55
|
import elementsPanelStyles from './elementsPanel.css.js';
|
|
55
|
-
import {DOMTreeWidget, type ElementsTreeOutline} from './ElementsTreeOutline.js';
|
|
56
56
|
import {LayoutPane} from './LayoutPane.js';
|
|
57
57
|
import type {MarkerDecorator} from './MarkerDecorator.js';
|
|
58
58
|
import {MetricsSidebarPane} from './MetricsSidebarPane.js';
|
|
@@ -67,10 +67,10 @@ import * as Media from '../media/media.js';
|
|
|
67
67
|
|
|
68
68
|
import * as ElementsComponents from './components/components.js';
|
|
69
69
|
import {cssPath} from './DOMPath.js';
|
|
70
|
+
import {type ElementsTreeOutline, MappedCharToEntity} from './DOMTreeWidget.js';
|
|
70
71
|
import {getElementIssueDetails} from './ElementIssueUtils.js';
|
|
71
72
|
import {ElementsPanel} from './ElementsPanel.js';
|
|
72
73
|
import * as ElementStatePaneWidget from './ElementStatePaneWidget.js';
|
|
73
|
-
import {type ElementsTreeOutline, MappedCharToEntity} from './ElementsTreeOutline.js';
|
|
74
74
|
import {ImagePreviewPopover} from './ImagePreviewPopover.js';
|
|
75
75
|
import {getRegisteredDecorators, type MarkerDecorator, type MarkerDecoratorRegistration} from './MarkerDecorator.js';
|
|
76
76
|
|
|
@@ -40,8 +40,8 @@ import * as Lit from '../../ui/lit/lit.js';
|
|
|
40
40
|
import * as VisualElements from '../../ui/visual_logging/visual_logging.js';
|
|
41
41
|
|
|
42
42
|
import * as ElementsComponents from './components/components.js';
|
|
43
|
+
import {ElementsTreeOutline} from './DOMTreeWidget.js';
|
|
43
44
|
import {adornerRef, ElementsTreeElement, handleAdornerKeydown} from './ElementsTreeElement.js';
|
|
44
|
-
import {ElementsTreeOutline} from './ElementsTreeOutline.js';
|
|
45
45
|
|
|
46
46
|
const {html, render} = Lit;
|
|
47
47
|
|
|
@@ -2044,7 +2044,7 @@ export class AnchorFunctionRenderer extends AnchorFunctionRendererBase {
|
|
|
2044
2044
|
|
|
2045
2045
|
override render(match: SDK.CSSPropertyParserMatchers.AnchorFunctionMatch, context: RenderingContext): Node[] {
|
|
2046
2046
|
const content = document.createElement('span');
|
|
2047
|
-
if (match.node.name
|
|
2047
|
+
if (match.node.name !== 'CallExpression') {
|
|
2048
2048
|
// Link an anchor double-dashed ident to its matching anchor element.
|
|
2049
2049
|
void AnchorFunctionRenderer.decorateAnchorForAnchorLink(this.#stylesContainer, content, {identifier: match.text});
|
|
2050
2050
|
} else {
|
|
@@ -729,9 +729,6 @@ export class StylesSidebarPane extends StylesSidebarPaneBase implements StylesCo
|
|
|
729
729
|
}
|
|
730
730
|
|
|
731
731
|
setEditingStyle(editing: boolean): void {
|
|
732
|
-
if (editing) {
|
|
733
|
-
this.isSuppressingResets = false;
|
|
734
|
-
}
|
|
735
732
|
if (this.isEditingStyle === editing) {
|
|
736
733
|
return;
|
|
737
734
|
}
|
|
@@ -816,12 +813,13 @@ export class StylesSidebarPane extends StylesSidebarPaneBase implements StylesCo
|
|
|
816
813
|
#scheduleResetUpdateIfNotEditing(): void {
|
|
817
814
|
this.scheduleResetUpdateIfNotEditingCalledForTest();
|
|
818
815
|
|
|
819
|
-
if
|
|
816
|
+
// Don't schedule if editing; the edit completion will handle the update.
|
|
817
|
+
if (this.userOperation || this.isEditingStyle) {
|
|
820
818
|
return;
|
|
821
819
|
}
|
|
822
820
|
|
|
823
|
-
|
|
824
|
-
|
|
821
|
+
if (this.isSuppressingResets) {
|
|
822
|
+
this.isSuppressingResets = false;
|
|
825
823
|
return;
|
|
826
824
|
}
|
|
827
825
|
|
|
@@ -6,7 +6,7 @@ import type * as Common from '../../core/common/common.js';
|
|
|
6
6
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
7
7
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
8
8
|
|
|
9
|
-
import type {ElementsTreeOutline} from './
|
|
9
|
+
import type {ElementsTreeOutline} from './DOMTreeWidget.js';
|
|
10
10
|
import {ShortcutTreeElement} from './ShortcutTreeElement.js';
|
|
11
11
|
|
|
12
12
|
export class TopLayerContainer extends UI.TreeOutline.TreeElement {
|
|
@@ -10,7 +10,7 @@ import './ElementsSidebarPane.js';
|
|
|
10
10
|
import './ElementsTreeElement.js';
|
|
11
11
|
import './AdoptedStyleSheetTreeElement.js';
|
|
12
12
|
import './TopLayerContainer.js';
|
|
13
|
-
import './
|
|
13
|
+
import './DOMTreeWidget.js';
|
|
14
14
|
import './ImagePreviewPopover.js';
|
|
15
15
|
import './EventListenersWidget.js';
|
|
16
16
|
import './MarkerDecorator.js';
|
|
@@ -42,11 +42,11 @@ import * as CSSSpecificityBreakdown from './CSSSpecificityBreakdown.js';
|
|
|
42
42
|
import * as CSSValueTraceView from './CSSValueTraceView.js';
|
|
43
43
|
import * as DOMPath from './DOMPath.js';
|
|
44
44
|
import * as DOMTreeContextMenu from './DOMTreeContextMenu.js';
|
|
45
|
+
import * as DOMTreeWidget from './DOMTreeWidget.js';
|
|
45
46
|
import * as ElementsPanel from './ElementsPanel.js';
|
|
46
47
|
import * as ElementsSidebarPane from './ElementsSidebarPane.js';
|
|
47
48
|
import * as ElementStatePaneWidget from './ElementStatePaneWidget.js';
|
|
48
49
|
import * as ElementsTreeElement from './ElementsTreeElement.js';
|
|
49
|
-
import * as ElementsTreeOutline from './ElementsTreeOutline.js';
|
|
50
50
|
import * as EventListenersWidget from './EventListenersWidget.js';
|
|
51
51
|
import * as ImagePreviewPopover from './ImagePreviewPopover.js';
|
|
52
52
|
import * as InspectElementModeController from './InspectElementModeController.js';
|
|
@@ -80,11 +80,12 @@ export {
|
|
|
80
80
|
CSSValueTraceView,
|
|
81
81
|
DOMPath,
|
|
82
82
|
DOMTreeContextMenu,
|
|
83
|
+
DOMTreeWidget,
|
|
84
|
+
DOMTreeWidget as ElementsTreeOutline,
|
|
83
85
|
ElementsPanel,
|
|
84
86
|
ElementsSidebarPane,
|
|
85
87
|
ElementStatePaneWidget,
|
|
86
88
|
ElementsTreeElement,
|
|
87
|
-
ElementsTreeOutline,
|
|
88
89
|
EventListenersWidget,
|
|
89
90
|
ImagePreviewPopover,
|
|
90
91
|
InspectElementModeController,
|
|
@@ -64,7 +64,7 @@ const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLElement|
|
|
|
64
64
|
<tr jslog=${VisualLogging.tableRow('detached-element')}>
|
|
65
65
|
<td>
|
|
66
66
|
<devtools-widget
|
|
67
|
-
${widget(Elements.
|
|
67
|
+
${widget(Elements.DOMTreeWidget.DOMTreeWidget, {
|
|
68
68
|
omitRootDOMNode: false,
|
|
69
69
|
selectEnabled: true,
|
|
70
70
|
hideGutter: true,
|
|
@@ -1067,12 +1067,14 @@ export class SamplingHeapProfileType extends SamplingHeapProfileTypeBase {
|
|
|
1067
1067
|
}
|
|
1068
1068
|
|
|
1069
1069
|
override customContent(): Element|null {
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1070
|
+
if (!this.customContentInternal) {
|
|
1071
|
+
const checkboxSetting = SettingsUI.SettingsUI.createSettingCheckbox(
|
|
1072
|
+
i18nString(UIStrings.samplingHeapProfilerTimeline), this.#recordTimelineSetting);
|
|
1073
|
+
this.customContentInternal = checkboxSetting;
|
|
1074
|
+
checkboxSetting.setAttribute(
|
|
1075
|
+
'jslog', `${VisualLogging.toggle('record-sampling-heap-profiler-timeline').track({click: true})}`);
|
|
1076
|
+
}
|
|
1077
|
+
return this.customContentInternal;
|
|
1076
1078
|
}
|
|
1077
1079
|
|
|
1078
1080
|
override setCustomContentEnabled(enable: boolean): void {
|
|
@@ -532,19 +532,26 @@ export class HeapSnapshotViewportDataGrid extends HeapSnapshotSortableDataGrid {
|
|
|
532
532
|
const scrollTop = this.scrollContainer.scrollTop;
|
|
533
533
|
const scrollBottom = scrollTop + this.scrollContainer.offsetHeight;
|
|
534
534
|
if (height >= scrollTop && height < scrollBottom) {
|
|
535
|
+
if (!node.dataGrid) {
|
|
536
|
+
this.updateVisibleNodes(false);
|
|
537
|
+
}
|
|
535
538
|
return Promise.resolve(node);
|
|
536
539
|
}
|
|
537
540
|
|
|
538
541
|
const scrollGap = 40;
|
|
539
542
|
this.scrollContainer.scrollTop = Math.max(0, height - scrollGap);
|
|
543
|
+
this.updateVisibleNodes(false);
|
|
540
544
|
return new Promise(resolve => {
|
|
541
|
-
|
|
545
|
+
if (this.scrollToResolveCallback) {
|
|
546
|
+
this.scrollToResolveCallback();
|
|
547
|
+
}
|
|
542
548
|
this.scrollToResolveCallback = resolve.bind(null, node);
|
|
543
549
|
// Still resolve the promise if it does not scroll for some reason.
|
|
544
550
|
this.scrollContainer.window().requestAnimationFrame(() => {
|
|
545
551
|
if (!this.scrollToResolveCallback) {
|
|
546
552
|
return;
|
|
547
553
|
}
|
|
554
|
+
this.updateVisibleNodes(false);
|
|
548
555
|
this.scrollToResolveCallback();
|
|
549
556
|
this.scrollToResolveCallback = null;
|
|
550
557
|
});
|
|
@@ -1640,10 +1640,12 @@ export class TrackingHeapSnapshotProfileType extends TrackingHeapSnapshotProfile
|
|
|
1640
1640
|
}
|
|
1641
1641
|
|
|
1642
1642
|
override customContent(): Element|null {
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1643
|
+
if (!this.customContentInternal) {
|
|
1644
|
+
const checkboxSetting = SettingsUI.SettingsUI.createSettingCheckbox(
|
|
1645
|
+
i18nString(UIStrings.recordAllocationStacksExtra), this.recordAllocationStacksSettingInternal);
|
|
1646
|
+
this.customContentInternal = checkboxSetting;
|
|
1647
|
+
}
|
|
1648
|
+
return this.customContentInternal;
|
|
1647
1649
|
}
|
|
1648
1650
|
|
|
1649
1651
|
override setCustomContentEnabled(enable: boolean): void {
|
|
@@ -13,7 +13,7 @@ import * as NetworkForward from '../../panels/network/forward/forward.js';
|
|
|
13
13
|
import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
14
14
|
import {createIcon, type Icon} from '../../ui/kit/kit.js';
|
|
15
15
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
16
|
-
import {Directives, html, nothing, render, type TemplateResult} from '../../ui/lit/lit.js';
|
|
16
|
+
import {Directives, html, type LitTemplate, nothing, render, type TemplateResult} from '../../ui/lit/lit.js';
|
|
17
17
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
18
18
|
|
|
19
19
|
import lockIconStyles from './lockIcon.css.js';
|
|
@@ -1347,10 +1347,10 @@ interface DetailsTableRow {
|
|
|
1347
1347
|
value: string|TemplateResult;
|
|
1348
1348
|
}
|
|
1349
1349
|
|
|
1350
|
-
function renderDetailsTable(rows: DetailsTableRow[]): TemplateResult {
|
|
1350
|
+
function renderDetailsTable(rows: DetailsTableRow[], additionalClasses: Directives.ClassInfo = {}): TemplateResult {
|
|
1351
1351
|
// clang-format off
|
|
1352
1352
|
return html`
|
|
1353
|
-
<table class
|
|
1353
|
+
<table class=${Directives.classMap({'details-table': true, ...additionalClasses})}>
|
|
1354
1354
|
${rows.map(row => html`
|
|
1355
1355
|
<tr class="details-table-row">
|
|
1356
1356
|
<td>${row.key ?? nothing}</td>
|
|
@@ -1492,6 +1492,74 @@ function renderCertificateSection(input: CertificateSectionInput): TemplateResul
|
|
|
1492
1492
|
// clang-format on
|
|
1493
1493
|
}
|
|
1494
1494
|
|
|
1495
|
+
interface CertificateTransparencySectionInput {
|
|
1496
|
+
securityDetails: Protocol.Network.SecurityDetails;
|
|
1497
|
+
isDetailsShown: boolean;
|
|
1498
|
+
onToggleDetails: () => void;
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
function renderSctSummary(scts: Protocol.Network.SignedCertificateTimestamp[], isShown: boolean): TemplateResult {
|
|
1502
|
+
const rows = scts.map(sct => ({
|
|
1503
|
+
key: i18nString(UIStrings.sct),
|
|
1504
|
+
value: `${sct.logDescription} (${sct.origin}, ${sct.status})`,
|
|
1505
|
+
}));
|
|
1506
|
+
return renderDetailsTable(rows, {'sct-summary': true, hidden: !isShown});
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
function renderSctDetails(scts: Protocol.Network.SignedCertificateTimestamp[], isShown: boolean): TemplateResult {
|
|
1510
|
+
// clang-format off
|
|
1511
|
+
return html`
|
|
1512
|
+
<div class=${Directives.classMap({'sct-details': true, hidden: !isShown})}>
|
|
1513
|
+
${scts.map(sct => renderDetailsTable([
|
|
1514
|
+
{key: i18nString(UIStrings.logName), value: sct.logDescription},
|
|
1515
|
+
{key: i18nString(UIStrings.logId), value: sct.logId.replace(/(.{2})/g, '$1 ')},
|
|
1516
|
+
{key: i18nString(UIStrings.validationStatus), value: sct.status},
|
|
1517
|
+
{key: i18nString(UIStrings.source), value: sct.origin},
|
|
1518
|
+
{key: i18nString(UIStrings.issuedAt), value: new Date(sct.timestamp).toUTCString()},
|
|
1519
|
+
{key: i18nString(UIStrings.hashAlgorithm), value: sct.hashAlgorithm},
|
|
1520
|
+
{key: i18nString(UIStrings.signatureAlgorithm), value: sct.signatureAlgorithm},
|
|
1521
|
+
{key: i18nString(UIStrings.signatureData), value: sct.signatureData.replace(/(.{2})/g, '$1 ')},
|
|
1522
|
+
]))}
|
|
1523
|
+
</div>`;
|
|
1524
|
+
// clang-format on
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
function renderCertificateTransparencyNote(compliance: Protocol.Network.CertificateTransparencyCompliance):
|
|
1528
|
+
LitTemplate {
|
|
1529
|
+
if (compliance === Protocol.Network.CertificateTransparencyCompliance.Unknown) {
|
|
1530
|
+
return nothing;
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
const note = compliance === Protocol.Network.CertificateTransparencyCompliance.Compliant ?
|
|
1534
|
+
i18nString(UIStrings.thisRequestCompliesWithChromes) :
|
|
1535
|
+
i18nString(UIStrings.thisRequestDoesNotComplyWith);
|
|
1536
|
+
|
|
1537
|
+
return html`<div class="origin-view-section-notes">${note}</div>`;
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
function renderCertificateTransparencySection(input: CertificateTransparencySectionInput): TemplateResult {
|
|
1541
|
+
const {securityDetails, isDetailsShown, onToggleDetails} = input;
|
|
1542
|
+
const scts = securityDetails.signedCertificateTimestampList;
|
|
1543
|
+
const toggleButtonText =
|
|
1544
|
+
isDetailsShown ? i18nString(UIStrings.hideFullDetails) : i18nString(UIStrings.showFullDetails);
|
|
1545
|
+
|
|
1546
|
+
// clang-format off
|
|
1547
|
+
return html`
|
|
1548
|
+
<div class="origin-view-section-title" role="heading" aria-level="2">${i18nString(UIStrings.certificateTransparency)}</div>
|
|
1549
|
+
${renderSctSummary(scts, !isDetailsShown)}
|
|
1550
|
+
${renderSctDetails(scts, isDetailsShown)}
|
|
1551
|
+
${scts.length ? html`
|
|
1552
|
+
<devtools-button
|
|
1553
|
+
class="details-toggle"
|
|
1554
|
+
.variant=${Buttons.Button.Variant.OUTLINED}
|
|
1555
|
+
.accessibleLabel=${toggleButtonText}
|
|
1556
|
+
.accessibleExpanded=${isDetailsShown}
|
|
1557
|
+
.jslogContext=${'security.toggle-scts-details'}
|
|
1558
|
+
@click=${onToggleDetails}>${toggleButtonText}</devtools-button>` : nothing}
|
|
1559
|
+
${renderCertificateTransparencyNote(securityDetails.certificateTransparencyCompliance)}`;
|
|
1560
|
+
// clang-format on
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1495
1563
|
export class SecurityOriginView extends UI.Widget.VBox {
|
|
1496
1564
|
readonly #origin: Platform.DevToolsPath.UrlString;
|
|
1497
1565
|
readonly #titleSection: HTMLElement;
|
|
@@ -1516,80 +1584,10 @@ export class SecurityOriginView extends UI.Widget.VBox {
|
|
|
1516
1584
|
|
|
1517
1585
|
const sctListLength = originState.securityDetails.signedCertificateTimestampList.length;
|
|
1518
1586
|
const ctCompliance = originState.securityDetails.certificateTransparencyCompliance;
|
|
1519
|
-
|
|
1520
|
-
if (sctListLength || ctCompliance !== Protocol.Network.CertificateTransparencyCompliance.Unknown) {
|
|
1521
|
-
// Create the Certificate Transparency section outside the callback, so that it appears in the right place.
|
|
1522
|
-
sctSection = this.element.createChild('div', 'origin-view-section');
|
|
1523
|
-
const sctDiv = sctSection.createChild('div', 'origin-view-section-title');
|
|
1524
|
-
sctDiv.textContent = i18nString(UIStrings.certificateTransparency);
|
|
1525
|
-
UI.ARIAUtils.markAsHeading(sctDiv, 2);
|
|
1526
|
-
}
|
|
1527
|
-
|
|
1528
|
-
if (!sctSection) {
|
|
1587
|
+
if (!sctListLength && ctCompliance === Protocol.Network.CertificateTransparencyCompliance.Unknown) {
|
|
1529
1588
|
return;
|
|
1530
1589
|
}
|
|
1531
|
-
|
|
1532
|
-
// Show summary of SCT(s) of Certificate Transparency.
|
|
1533
|
-
const sctSummaryTable = new SecurityDetailsTable();
|
|
1534
|
-
sctSummaryTable.element().classList.add('sct-summary');
|
|
1535
|
-
sctSection.appendChild(sctSummaryTable.element());
|
|
1536
|
-
for (let i = 0; i < sctListLength; i++) {
|
|
1537
|
-
const sct = originState.securityDetails.signedCertificateTimestampList[i];
|
|
1538
|
-
sctSummaryTable.addRow(
|
|
1539
|
-
i18nString(UIStrings.sct), sct.logDescription + ' (' + sct.origin + ', ' + sct.status + ')');
|
|
1540
|
-
}
|
|
1541
|
-
|
|
1542
|
-
// Show detailed SCT(s) of Certificate Transparency.
|
|
1543
|
-
const sctTableWrapper = sctSection.createChild('div', 'sct-details');
|
|
1544
|
-
sctTableWrapper.classList.add('hidden');
|
|
1545
|
-
for (let i = 0; i < sctListLength; i++) {
|
|
1546
|
-
const sctTable = new SecurityDetailsTable();
|
|
1547
|
-
sctTableWrapper.appendChild(sctTable.element());
|
|
1548
|
-
const sct = originState.securityDetails.signedCertificateTimestampList[i];
|
|
1549
|
-
sctTable.addRow(i18nString(UIStrings.logName), sct.logDescription);
|
|
1550
|
-
sctTable.addRow(i18nString(UIStrings.logId), sct.logId.replace(/(.{2})/g, '$1 '));
|
|
1551
|
-
sctTable.addRow(i18nString(UIStrings.validationStatus), sct.status);
|
|
1552
|
-
sctTable.addRow(i18nString(UIStrings.source), sct.origin);
|
|
1553
|
-
sctTable.addRow(i18nString(UIStrings.issuedAt), new Date(sct.timestamp).toUTCString());
|
|
1554
|
-
sctTable.addRow(i18nString(UIStrings.hashAlgorithm), sct.hashAlgorithm);
|
|
1555
|
-
sctTable.addRow(i18nString(UIStrings.signatureAlgorithm), sct.signatureAlgorithm);
|
|
1556
|
-
sctTable.addRow(i18nString(UIStrings.signatureData), sct.signatureData.replace(/(.{2})/g, '$1 '));
|
|
1557
|
-
}
|
|
1558
|
-
|
|
1559
|
-
// Add link to toggle between displaying of the summary of the SCT(s) and the detailed SCT(s).
|
|
1560
|
-
if (sctListLength) {
|
|
1561
|
-
function toggleSctDetailsDisplay(): void {
|
|
1562
|
-
let buttonText;
|
|
1563
|
-
const isDetailsShown = !sctTableWrapper.classList.contains('hidden');
|
|
1564
|
-
if (isDetailsShown) {
|
|
1565
|
-
buttonText = i18nString(UIStrings.showFullDetails);
|
|
1566
|
-
} else {
|
|
1567
|
-
buttonText = i18nString(UIStrings.hideFullDetails);
|
|
1568
|
-
}
|
|
1569
|
-
toggleSctsDetailsLink.textContent = buttonText;
|
|
1570
|
-
UI.ARIAUtils.setLabel(toggleSctsDetailsLink, buttonText);
|
|
1571
|
-
UI.ARIAUtils.setExpanded(toggleSctsDetailsLink, !isDetailsShown);
|
|
1572
|
-
sctSummaryTable.element().classList.toggle('hidden');
|
|
1573
|
-
sctTableWrapper.classList.toggle('hidden');
|
|
1574
|
-
}
|
|
1575
|
-
const toggleSctsDetailsLink = UI.UIUtils.createTextButton(
|
|
1576
|
-
i18nString(UIStrings.showFullDetails), toggleSctDetailsDisplay,
|
|
1577
|
-
{className: 'details-toggle', jslogContext: 'security.toggle-scts-details'});
|
|
1578
|
-
sctSection.appendChild(toggleSctsDetailsLink);
|
|
1579
|
-
}
|
|
1580
|
-
|
|
1581
|
-
switch (ctCompliance) {
|
|
1582
|
-
case Protocol.Network.CertificateTransparencyCompliance.Compliant:
|
|
1583
|
-
sctSection.createChild('div', 'origin-view-section-notes').textContent =
|
|
1584
|
-
i18nString(UIStrings.thisRequestCompliesWithChromes);
|
|
1585
|
-
break;
|
|
1586
|
-
case Protocol.Network.CertificateTransparencyCompliance.NotCompliant:
|
|
1587
|
-
sctSection.createChild('div', 'origin-view-section-notes').textContent =
|
|
1588
|
-
i18nString(UIStrings.thisRequestDoesNotComplyWith);
|
|
1589
|
-
break;
|
|
1590
|
-
case Protocol.Network.CertificateTransparencyCompliance.Unknown:
|
|
1591
|
-
break;
|
|
1592
|
-
}
|
|
1590
|
+
this.#createCertificateTransparencySection(originState.securityDetails);
|
|
1593
1591
|
|
|
1594
1592
|
const noteSection = this.element.createChild('div', 'origin-view-section origin-view-notes');
|
|
1595
1593
|
if (originState.loadedFromCache) {
|
|
@@ -1640,6 +1638,20 @@ export class SecurityOriginView extends UI.Widget.VBox {
|
|
|
1640
1638
|
updateCertificateSection();
|
|
1641
1639
|
}
|
|
1642
1640
|
|
|
1641
|
+
#createCertificateTransparencySection(securityDetails: Protocol.Network.SecurityDetails): void {
|
|
1642
|
+
const section = this.element.createChild('div', 'origin-view-section certificate-transparency-section');
|
|
1643
|
+
let isDetailsShown = false;
|
|
1644
|
+
const onToggleDetails = (): void => {
|
|
1645
|
+
isDetailsShown = !isDetailsShown;
|
|
1646
|
+
updateSection();
|
|
1647
|
+
};
|
|
1648
|
+
const updateSection = (): void => {
|
|
1649
|
+
// eslint-disable-next-line @devtools/no-lit-render-outside-of-view
|
|
1650
|
+
render(renderCertificateTransparencySection({securityDetails, isDetailsShown, onToggleDetails}), section);
|
|
1651
|
+
};
|
|
1652
|
+
updateSection();
|
|
1653
|
+
}
|
|
1654
|
+
|
|
1643
1655
|
#showCertificateViewer = async(event: Event): Promise<void> => {
|
|
1644
1656
|
event.consume();
|
|
1645
1657
|
const names = await SDK.NetworkManager.MultitargetNetworkManager.instance().getCertificate(this.#origin);
|
|
@@ -1667,30 +1679,6 @@ export class SecurityOriginView extends UI.Widget.VBox {
|
|
|
1667
1679
|
};
|
|
1668
1680
|
}
|
|
1669
1681
|
|
|
1670
|
-
export class SecurityDetailsTable {
|
|
1671
|
-
readonly #element: HTMLTableElement;
|
|
1672
|
-
|
|
1673
|
-
constructor() {
|
|
1674
|
-
this.#element = document.createElement('table');
|
|
1675
|
-
this.#element.classList.add('details-table');
|
|
1676
|
-
}
|
|
1677
|
-
|
|
1678
|
-
element(): HTMLTableElement {
|
|
1679
|
-
return this.#element;
|
|
1680
|
-
}
|
|
1681
|
-
|
|
1682
|
-
addRow(key: string, value: string|Node): void {
|
|
1683
|
-
const row = this.#element.createChild('tr', 'details-table-row');
|
|
1684
|
-
row.createChild('td').textContent = key;
|
|
1685
|
-
|
|
1686
|
-
const valueCell = row.createChild('td');
|
|
1687
|
-
if (typeof value === 'string') {
|
|
1688
|
-
valueCell.textContent = value;
|
|
1689
|
-
} else {
|
|
1690
|
-
valueCell.appendChild(value);
|
|
1691
|
-
}
|
|
1692
|
-
}
|
|
1693
|
-
}
|
|
1694
1682
|
export interface OriginState {
|
|
1695
1683
|
securityState: Protocol.Security.SecurityState;
|
|
1696
1684
|
securityDetails: Protocol.Network.SecurityDetails|null;
|