chrome-devtools-frontend 1.0.1643099 → 1.0.1645245
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/eslint.config.mjs +3 -1
- package/extension-api/ExtensionAPI.d.ts +83 -12
- package/front_end/core/host/UserMetrics.ts +3 -3
- package/front_end/core/root/ExperimentNames.ts +0 -1
- package/front_end/core/sdk/CSSPropertyParserMatchers.ts +2 -3
- package/front_end/core/sdk/ConsoleModel.ts +4 -0
- package/front_end/core/sdk/NetworkRequest.ts +12 -1
- package/front_end/core/sdk/SourceMap.ts +15 -18
- package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +0 -2
- package/front_end/entrypoints/greendev_floaty/greendev_floaty.ts +0 -2
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +37 -0
- package/front_end/entrypoints/main/MainImpl.ts +0 -6
- package/front_end/generated/SupportedCSSProperties.js +4 -2
- package/front_end/models/ai_assistance/AiAgent2.ts +23 -12
- package/front_end/models/ai_assistance/README.md +5 -4
- package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +22 -16
- package/front_end/models/ai_assistance/agents/AiAgent.ts +19 -6
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +5 -5
- package/front_end/models/ai_assistance/agents/ExecuteJavascript.ts +1 -94
- package/front_end/models/ai_assistance/agents/NetworkAgent.ts +25 -0
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +37 -0
- package/front_end/models/ai_assistance/agents/README.md +57 -0
- package/front_end/models/ai_assistance/agents/StorageAgent.ts +54 -1
- package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +1 -2
- package/front_end/models/ai_assistance/agents/StylingAgent.ts +31 -3
- package/front_end/models/ai_assistance/tools/ExecuteJavaScript.ts +12 -21
- package/front_end/models/ai_assistance/tools/GetStyles.ts +19 -12
- package/front_end/models/ai_assistance/tools/README.md +45 -0
- package/front_end/models/ai_assistance/tools/Tool.ts +78 -9
- package/front_end/models/ai_assistance/tools/ToolRegistry.ts +21 -5
- package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +6 -9
- package/front_end/models/bindings/DefaultScriptMapping.ts +2 -1
- package/front_end/models/bindings/SymbolizedError.ts +45 -35
- package/front_end/models/extensions/ExtensionAPI.ts +138 -47
- package/front_end/models/har/Importer.ts +1 -0
- package/front_end/models/heap_snapshot/HeapSnapshotModel.ts +18 -2
- package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +4 -0
- package/front_end/models/source_map_scopes/FunctionCodeResolver.ts +12 -2
- package/front_end/models/stack_trace/DetailedErrorStackParser.ts +58 -52
- package/front_end/models/stack_trace/StackTrace.ts +7 -0
- package/front_end/models/stack_trace/StackTraceImpl.ts +13 -4
- package/front_end/models/stack_trace/StackTraceModel.ts +43 -9
- package/front_end/models/trace/Styles.ts +29 -7
- package/front_end/models/trace/handlers/PageLoadMetricsHandler.ts +33 -4
- package/front_end/models/trace/helpers/Timing.ts +10 -0
- package/front_end/models/trace/types/TraceEvents.ts +22 -2
- package/front_end/panels/accessibility/AccessibilitySidebarView.ts +2 -1
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +9 -2
- package/front_end/panels/ai_assistance/ai_assistance-meta.ts +16 -0
- package/front_end/panels/application/ApplicationPanelSidebar.ts +83 -0
- package/front_end/panels/application/ApplicationPanelTreeElement.ts +39 -0
- package/front_end/panels/application/CookieItemsView.ts +2 -2
- package/front_end/panels/application/ServiceWorkersView.ts +2 -2
- package/front_end/panels/application/WebMCPView.ts +0 -1
- package/front_end/panels/application/components/BackForwardCacheView.ts +1 -2
- package/front_end/panels/application/resourcesSidebar.css +11 -0
- package/front_end/panels/console/ConsoleView.ts +6 -1
- package/front_end/panels/console/ConsoleViewMessage.ts +46 -213
- package/front_end/panels/console/SymbolizedErrorWidget.ts +14 -8
- package/front_end/panels/elements/AdoptedStyleSheetTreeElement.ts +0 -1
- package/front_end/panels/elements/ElementsTreeElement.ts +0 -2
- package/front_end/panels/elements/PropertyRenderer.ts +0 -1
- package/front_end/panels/elements/StylesSidebarPane.ts +9 -2
- package/front_end/panels/issues/AffectedResourcesView.ts +1 -1
- package/front_end/panels/issues/AffectedSourcesView.ts +1 -1
- package/front_end/panels/lighthouse/LighthouseReportRenderer.ts +0 -1
- package/front_end/panels/mobile_throttling/ThrottlingSettingsTab.ts +10 -0
- package/front_end/panels/network/NetworkDataGridNode.ts +1 -2
- package/front_end/panels/network/NetworkLogView.ts +34 -7
- package/front_end/panels/profiler/HeapProfileView.ts +0 -1
- package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +0 -1
- package/front_end/panels/profiler/HeapSnapshotView.ts +1 -1
- package/front_end/panels/settings/components/SyncSection.ts +1 -1
- package/front_end/panels/settings/emulation/DevicesSettingsTab.ts +1 -0
- package/front_end/panels/sources/SourcesPanel.ts +2 -1
- package/front_end/panels/timeline/TimelineFlameChartView.ts +5 -4
- package/front_end/panels/timeline/TimelinePanel.ts +7 -0
- package/front_end/panels/timeline/TimelineUIUtils.ts +13 -14
- package/front_end/panels/timeline/TimingsTrackAppender.ts +7 -5
- package/front_end/panels/timeline/components/LayoutShiftDetails.ts +0 -1
- package/front_end/panels/timeline/components/NetworkRequestDetails.ts +0 -2
- package/front_end/panels/timeline/components/insights/ForcedReflow.ts +0 -1
- package/front_end/panels/timeline/components/insights/NodeLink.ts +0 -1
- package/front_end/panels/timeline/overlays/OverlaysImpl.ts +2 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/helpers/OpenInNewTab.ts +3 -3
- package/front_end/ui/kit/link/Link.ts +16 -2
- package/front_end/ui/legacy/InspectorDrawerView.ts +14 -5
- package/front_end/ui/legacy/InspectorView.ts +4 -1
- package/front_end/ui/legacy/PlusButton.ts +6 -1
- package/front_end/ui/legacy/StackedPane.ts +229 -0
- package/front_end/ui/legacy/ViewManager.ts +59 -169
- package/front_end/ui/legacy/Widget.ts +19 -1
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +95 -31
- package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +0 -1
- package/front_end/ui/legacy/components/utils/Linkifier.ts +2 -16
- package/front_end/ui/legacy/legacy.ts +3 -1
- package/front_end/ui/visual_logging/KnownContextValues.ts +5 -0
- package/package.json +1 -1
|
@@ -28,8 +28,8 @@ function renderHeader(content: Lit.LitTemplate|Node|UI.Widget.Widget, isCause: b
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
function formatName(frame: StackTrace.StackTrace.ParsedErrorStackFrame): string {
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
const isInline = frame.isInline;
|
|
32
|
+
let name = isInline ? (frame.name || '') : (frame.rawName || frame.name || '');
|
|
33
33
|
const shouldAppendMethodAlias = !isInline && frame.methodName && name && name !== frame.methodName &&
|
|
34
34
|
!name.endsWith('.' + frame.methodName) && !name.endsWith(' ' + frame.methodName);
|
|
35
35
|
if (shouldAppendMethodAlias) {
|
|
@@ -105,10 +105,6 @@ function renderFrameSuffix(frame: StackTrace.StackTrace.ParsedErrorStackFrame):
|
|
|
105
105
|
|
|
106
106
|
const DEFAULT_VIEW = (input: ViewInput, _output: object, target: HTMLElement): void => {
|
|
107
107
|
const renderError = (error: Bindings.SymbolizedError.SymbolizedError, isCause: boolean): Lit.LitTemplate => {
|
|
108
|
-
if (error instanceof Bindings.SymbolizedError.SymbolizedSyntaxError) {
|
|
109
|
-
console.error('SymbolizedErrorWidget received an unsupported error type:', error);
|
|
110
|
-
return Lit.nothing;
|
|
111
|
-
}
|
|
112
108
|
if (error instanceof Bindings.SymbolizedError.UnparsableError) {
|
|
113
109
|
const fragment = ConsoleViewMessage.linkifyWithCustomLinkifier(
|
|
114
110
|
error.errorStack,
|
|
@@ -126,11 +122,17 @@ const DEFAULT_VIEW = (input: ViewInput, _output: object, target: HTMLElement): v
|
|
|
126
122
|
|
|
127
123
|
const linkOptions: Components.Linkifier.LinkifyOptions = {
|
|
128
124
|
showColumnNumber: true,
|
|
129
|
-
inlineFrameIndex: 0,
|
|
130
125
|
maxLength: UI.UIUtils.MaxLengthForDisplayedURLsInConsole,
|
|
131
126
|
ignoreListManager: input.ignoreListManager,
|
|
132
127
|
};
|
|
133
|
-
|
|
128
|
+
|
|
129
|
+
let headerContent = html`${error.message}`;
|
|
130
|
+
if (error.syntaxErrorLocation) {
|
|
131
|
+
const linkElement = Components.Linkifier.Linkifier.linkifyUILocation(error.syntaxErrorLocation, linkOptions);
|
|
132
|
+
linkElement.tabIndex = -1;
|
|
133
|
+
headerContent = html`${error.message} (at ${linkElement})`;
|
|
134
|
+
}
|
|
135
|
+
|
|
134
136
|
const header = renderHeader(headerContent, isCause);
|
|
135
137
|
const syncFrames = error.stackTrace.syncFragment.frames;
|
|
136
138
|
// clang-format off
|
|
@@ -168,6 +170,10 @@ export class SymbolizedErrorWidget extends UI.Widget.Widget {
|
|
|
168
170
|
this.#view = view;
|
|
169
171
|
}
|
|
170
172
|
|
|
173
|
+
get linkElements(): readonly HTMLElement[] {
|
|
174
|
+
return [...this.contentElement.querySelectorAll<HTMLElement>('.devtools-link')];
|
|
175
|
+
}
|
|
176
|
+
|
|
171
177
|
set ignoreListManager(ignoreListManager: Workspace.IgnoreListManager.IgnoreListManager) {
|
|
172
178
|
this.#ignoreListManager = ignoreListManager;
|
|
173
179
|
this.requestUpdate();
|
|
@@ -644,7 +644,6 @@ function renderTitle(
|
|
|
644
644
|
text,
|
|
645
645
|
preventClick: true,
|
|
646
646
|
showColumnNumber: false,
|
|
647
|
-
inlineFrameIndex: 0,
|
|
648
647
|
})}</span>)</span>`;
|
|
649
648
|
}
|
|
650
649
|
|
|
@@ -733,7 +732,6 @@ function renderLinkifiedValue(value: string, node: SDK.DOMModel.DOMNode): Lit.Te
|
|
|
733
732
|
text: value,
|
|
734
733
|
preventClick: true,
|
|
735
734
|
showColumnNumber: false,
|
|
736
|
-
inlineFrameIndex: 0,
|
|
737
735
|
onRef: link => {
|
|
738
736
|
ImagePreviewPopover.setImageUrl(link, rewrittenHref);
|
|
739
737
|
}
|
|
@@ -556,7 +556,6 @@ export class URLRenderer extends rendererBase(SDK.CSSPropertyParserMatchers.URLM
|
|
|
556
556
|
// at the same time, which complicates both StylesSidebarPane and StylePropertyTreeElement.
|
|
557
557
|
bypassURLTrimming: true,
|
|
558
558
|
showColumnNumber: false,
|
|
559
|
-
inlineFrameIndex: 0,
|
|
560
559
|
}),
|
|
561
560
|
hrefUrl || url);
|
|
562
561
|
container.appendChild(link);
|
|
@@ -235,6 +235,7 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
|
|
|
235
235
|
#shouldRenderLazily = false;
|
|
236
236
|
#lazyRenderObserver?: IntersectionObserver;
|
|
237
237
|
#lazyRenderCallbacks = new WeakMap<Element, () => void>();
|
|
238
|
+
#updateId = 0;
|
|
238
239
|
|
|
239
240
|
constructor(computedStyleModel: ComputedStyle.ComputedStyleModel.ComputedStyleModel) {
|
|
240
241
|
super(computedStyleModel, {delegatesFocus: true, useShadowDom: true, classes: ['flex-none']});
|
|
@@ -616,9 +617,15 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
|
|
|
616
617
|
this.dispatchEventToListeners(Events.INITIAL_UPDATE_COMPLETED);
|
|
617
618
|
}
|
|
618
619
|
|
|
619
|
-
this
|
|
620
|
+
this.#updateId += 1;
|
|
621
|
+
const currentUpdateId = this.#updateId;
|
|
620
622
|
|
|
621
|
-
|
|
623
|
+
void UI.Widget.Widget.allUpdatesComplete.then(() => {
|
|
624
|
+
if (this.#updateId === currentUpdateId) {
|
|
625
|
+
this.nodeStylesUpdatedForTest((this.node() as SDK.DOMModel.DOMNode), true);
|
|
626
|
+
this.dispatchEventToListeners(Events.STYLES_UPDATE_COMPLETED, {hasMatchedStyles: this.hasMatchedStyles});
|
|
627
|
+
}
|
|
628
|
+
});
|
|
622
629
|
}
|
|
623
630
|
|
|
624
631
|
#getRegisteredPropertyDetails(matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles, variableName: string):
|
|
@@ -252,7 +252,7 @@ export abstract class AffectedResourcesView extends UI.TreeOutline.TreeElement {
|
|
|
252
252
|
const linkifier = new Components.Linkifier.Linkifier(UI.UIUtils.MaxLengthForDisplayedURLsInConsole);
|
|
253
253
|
const sourceAnchor = linkifier.linkifyScriptLocation(
|
|
254
254
|
target || null, sourceLocation.scriptId || null, sourceLocation.url as Platform.DevToolsPath.UrlString,
|
|
255
|
-
sourceLocation.lineNumber, {columnNumber: sourceLocation.columnNumber
|
|
255
|
+
sourceLocation.lineNumber, {columnNumber: sourceLocation.columnNumber});
|
|
256
256
|
sourceAnchor.setAttribute('jslog', `${VisualLogging.link('source-location').track({click: true})}`);
|
|
257
257
|
sourceCodeLocation.appendChild(sourceAnchor);
|
|
258
258
|
}
|
|
@@ -39,7 +39,7 @@ export class AffectedSourcesView extends AffectedResourcesView {
|
|
|
39
39
|
const cellElement = document.createElement('td');
|
|
40
40
|
// TODO(chromium:1072331): Check feasibility of plumping through scriptId for `linkifyScriptLocation`
|
|
41
41
|
// to support source maps and formatted scripts.
|
|
42
|
-
const linkifierURLOptions = {columnNumber, lineNumber, tabStop: true, showColumnNumber: false
|
|
42
|
+
const linkifierURLOptions = {columnNumber, lineNumber, tabStop: true, showColumnNumber: false};
|
|
43
43
|
// An element created with linkifyURL can subscribe to the events
|
|
44
44
|
// 'click' neither 'keydown' if that key is the 'Enter' key.
|
|
45
45
|
// Also, this element has a context menu, so we should be able to
|
|
@@ -180,10 +180,20 @@ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
|
180
180
|
/**
|
|
181
181
|
* This promise resolves after the first compute pressure record is observed.
|
|
182
182
|
* The object it returns is always up-to-date with the most recent record observed.
|
|
183
|
+
*
|
|
184
|
+
* Note: The returned value measures the host machine's compute pressure. When
|
|
185
|
+
* debugging a remote device, this may trigger irrelevant high-pressure warnings.
|
|
183
186
|
*/
|
|
184
187
|
function createComputePressurePromise(): Promise<{state: string}> {
|
|
185
188
|
const result = {state: ''};
|
|
186
189
|
|
|
190
|
+
// @ts-expect-error typescript/lib version needs to be updated.
|
|
191
|
+
if (typeof PressureObserver === 'undefined') {
|
|
192
|
+
// The Compute Pressure API is used only for showing warnings to the user.
|
|
193
|
+
// If it's unavailable, resolve immediately to proceed without warnings.
|
|
194
|
+
return Promise.resolve(result);
|
|
195
|
+
}
|
|
196
|
+
|
|
187
197
|
return new Promise(resolve => {
|
|
188
198
|
// @ts-expect-error typescript/lib version needs to be updated.
|
|
189
199
|
const observer = new PressureObserver(records => {
|
|
@@ -1515,8 +1515,7 @@ export class NetworkRequestNode extends NetworkNode {
|
|
|
1515
1515
|
this.linkifiedInitiatorAnchor = linkifier.linkifyStackTraceTopFrame(target, initiator.stack);
|
|
1516
1516
|
} else {
|
|
1517
1517
|
this.linkifiedInitiatorAnchor = linkifier.linkifyScriptLocation(
|
|
1518
|
-
target, initiator.scriptId, initiator.url, initiator.lineNumber,
|
|
1519
|
-
{columnNumber: initiator.columnNumber, inlineFrameIndex: 0});
|
|
1518
|
+
target, initiator.scriptId, initiator.url, initiator.lineNumber, {columnNumber: initiator.columnNumber});
|
|
1520
1519
|
}
|
|
1521
1520
|
UI.Tooltip.Tooltip.install((this.linkifiedInitiatorAnchor), '');
|
|
1522
1521
|
cell.appendChild(this.linkifiedInitiatorAnchor);
|
|
@@ -505,6 +505,11 @@ const UIStrings = {
|
|
|
505
505
|
* @description Context menu item in Network panel to assess security headers of a request via AI.
|
|
506
506
|
*/
|
|
507
507
|
assessSecurityHeaders: 'Assess security headers',
|
|
508
|
+
/**
|
|
509
|
+
* @description A comment in a generated command indicating that the URL scheme is unsupported. The placeholder is the comment prefix (e.g. '//' or '#').
|
|
510
|
+
* @example {//} PH1
|
|
511
|
+
*/
|
|
512
|
+
unsupportedUrlScheme: '{PH1} Unsupported URL scheme',
|
|
508
513
|
} as const;
|
|
509
514
|
const str_ = i18n.i18n.registerUIStrings('panels/network/NetworkLogView.ts', UIStrings);
|
|
510
515
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
@@ -557,6 +562,8 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
557
562
|
private readonly textFilterSetting: Common.Settings.Setting<string>;
|
|
558
563
|
private networkRequestToNode: WeakMap<SDK.NetworkRequest.NetworkRequest, NetworkRequestNode>;
|
|
559
564
|
|
|
565
|
+
static #allowedSchemes = new Set(['http:', 'https:', 'ws:', 'wss:', 'data:']);
|
|
566
|
+
|
|
560
567
|
constructor(
|
|
561
568
|
filterBar: UI.FilterBar.FilterBar, progressBarContainer: Element,
|
|
562
569
|
networkLogLargeRowsSetting: Common.Settings.Setting<boolean>) {
|
|
@@ -2319,6 +2326,18 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
2319
2326
|
return requests.filter(request => !request.isBlobRequest());
|
|
2320
2327
|
}
|
|
2321
2328
|
|
|
2329
|
+
static #getValidClipboardUrl(url: string): Platform.DevToolsPath.UrlString|null {
|
|
2330
|
+
try {
|
|
2331
|
+
const parsedUrl = new URL(url);
|
|
2332
|
+
if (!NetworkLogView.#allowedSchemes.has(parsedUrl.protocol)) {
|
|
2333
|
+
return null;
|
|
2334
|
+
}
|
|
2335
|
+
return url as Platform.DevToolsPath.UrlString;
|
|
2336
|
+
} catch {
|
|
2337
|
+
return null;
|
|
2338
|
+
}
|
|
2339
|
+
}
|
|
2340
|
+
|
|
2322
2341
|
private async generateFetchCall(request: SDK.NetworkRequest.NetworkRequest, style: FetchStyle): Promise<string> {
|
|
2323
2342
|
const ignoredHeaders = new Set<string>([
|
|
2324
2343
|
// Internal headers
|
|
@@ -2355,7 +2374,11 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
2355
2374
|
|
|
2356
2375
|
const credentialHeaders = new Set<string>(['cookie', 'authorization']);
|
|
2357
2376
|
|
|
2358
|
-
const
|
|
2377
|
+
const validUrl = NetworkLogView.#getValidClipboardUrl(request.url());
|
|
2378
|
+
if (!validUrl) {
|
|
2379
|
+
return i18nString(UIStrings.unsupportedUrlScheme, {PH1: '//'});
|
|
2380
|
+
}
|
|
2381
|
+
const url = JSON.stringify(validUrl);
|
|
2359
2382
|
|
|
2360
2383
|
const requestHeaders = request.requestHeaders();
|
|
2361
2384
|
const headerData: Headers = requestHeaders.reduce((result, header) => {
|
|
@@ -2507,11 +2530,11 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
2507
2530
|
// (it may be different from the inspected page platform).
|
|
2508
2531
|
const escapeString = platform === 'win' ? escapeStringWin : escapeStringPosix;
|
|
2509
2532
|
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
command.push('--url ' + escapeString(
|
|
2533
|
+
const validUrl = NetworkLogView.#getValidClipboardUrl(request.url());
|
|
2534
|
+
if (!validUrl) {
|
|
2535
|
+
return i18nString(UIStrings.unsupportedUrlScheme, {PH1: '#'});
|
|
2536
|
+
}
|
|
2537
|
+
command.push('--url ' + escapeString(validUrl).replace(/[[{}\]]/g, '\\$&'));
|
|
2515
2538
|
|
|
2516
2539
|
let inferredMethod = 'GET';
|
|
2517
2540
|
const data = [];
|
|
@@ -2617,7 +2640,11 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
2617
2640
|
return null;
|
|
2618
2641
|
}
|
|
2619
2642
|
|
|
2620
|
-
|
|
2643
|
+
const validUrl = NetworkLogView.#getValidClipboardUrl(request.url());
|
|
2644
|
+
if (!validUrl) {
|
|
2645
|
+
return i18nString(UIStrings.unsupportedUrlScheme, {PH1: '#'});
|
|
2646
|
+
}
|
|
2647
|
+
command.push('-Uri ' + escapeString(validUrl));
|
|
2621
2648
|
|
|
2622
2649
|
if (request.requestMethod !== 'GET') {
|
|
2623
2650
|
command.push('-Method ' + escapeString(request.requestMethod));
|
|
@@ -628,7 +628,6 @@ export class NodeFormatter implements Formatter {
|
|
|
628
628
|
const target = heapProfilerModel ? heapProfilerModel.target() : null;
|
|
629
629
|
const options = {
|
|
630
630
|
className: 'profile-node-file',
|
|
631
|
-
inlineFrameIndex: 0,
|
|
632
631
|
};
|
|
633
632
|
return this.profileView.linkifier().maybeLinkifyConsoleCallFrame(target, node.profileNode.callFrame, options);
|
|
634
633
|
}
|
|
@@ -1467,7 +1467,6 @@ export class AllocationGridNode extends HeapSnapshotGridNode {
|
|
|
1467
1467
|
String(allocationNode.scriptId) as Protocol.Runtime.ScriptId,
|
|
1468
1468
|
allocationNode.scriptName as Platform.DevToolsPath.UrlString, allocationNode.line - 1, {
|
|
1469
1469
|
columnNumber: allocationNode.column - 1,
|
|
1470
|
-
inlineFrameIndex: 0,
|
|
1471
1470
|
className: 'profile-node-file',
|
|
1472
1471
|
});
|
|
1473
1472
|
urlElement.style.maxWidth = '75%';
|
|
@@ -1949,7 +1949,7 @@ export class HeapAllocationStackView extends UI.Widget.Widget {
|
|
|
1949
1949
|
continue;
|
|
1950
1950
|
}
|
|
1951
1951
|
const target = this.heapProfilerModel ? this.heapProfilerModel.target() : null;
|
|
1952
|
-
const options = {columnNumber: frame.column - 1
|
|
1952
|
+
const options = {columnNumber: frame.column - 1};
|
|
1953
1953
|
const urlElement = this.linkifier.linkifyScriptLocation(
|
|
1954
1954
|
target, String(frame.scriptId) as Protocol.Runtime.ScriptId,
|
|
1955
1955
|
frame.scriptName as Platform.DevToolsPath.UrlString, frame.line - 1, options);
|
|
@@ -346,7 +346,7 @@ export class SyncSection extends UI.Widget.Widget {
|
|
|
346
346
|
// TODO: investigate if /advance link is alive
|
|
347
347
|
const warningLink =
|
|
348
348
|
this.#syncInfo.isSyncActive ? 'chrome://settings/syncSetup/advanced' : 'chrome://settings/syncSetup';
|
|
349
|
-
UIHelpers.openInNewTab(warningLink);
|
|
349
|
+
UIHelpers.openInNewTab(warningLink, /* allowPrivileged=*/ true);
|
|
350
350
|
event.consume();
|
|
351
351
|
}
|
|
352
352
|
|
|
@@ -177,6 +177,7 @@ export class DevicesSettingsTab extends UI.Widget.VBox implements
|
|
|
177
177
|
device.horizontal.height = 400;
|
|
178
178
|
device.vertical.width = 400;
|
|
179
179
|
device.vertical.height = 700;
|
|
180
|
+
device.userAgent = navigator.userAgent;
|
|
180
181
|
this.#customDeviceList.addNewItem(this.emulatedDevicesList.custom().length, device);
|
|
181
182
|
}
|
|
182
183
|
|
|
@@ -221,7 +221,7 @@ export class SourcesPanel extends UI.Panel.Panel implements
|
|
|
221
221
|
#paused?: boolean;
|
|
222
222
|
private switchToPausedTargetTimeout?: number;
|
|
223
223
|
private executionLineLocation?: Bindings.DebuggerWorkspaceBinding.Location|null;
|
|
224
|
-
private sidebarPaneStack?: UI.
|
|
224
|
+
private sidebarPaneStack?: UI.ViewManager.StackLocation;
|
|
225
225
|
private tabbedLocationHeader?: Element|null;
|
|
226
226
|
private extensionSidebarPanesContainer?: UI.View.ViewLocation;
|
|
227
227
|
sidebarPaneView?: UI.Widget.VBox|UI.SplitWidget.SplitWidget;
|
|
@@ -477,6 +477,7 @@ export class SourcesPanel extends UI.Panel.Panel implements
|
|
|
477
477
|
|
|
478
478
|
toggleDebuggerSidebar(): void {
|
|
479
479
|
this.splitWidget.toggleSidebar();
|
|
480
|
+
this.sidebarPaneStack?.notifyVisibilityChanged(this.splitWidget.sidebarIsShowing());
|
|
480
481
|
}
|
|
481
482
|
|
|
482
483
|
private debuggerPaused(event: Common.EventTarget.EventTargetEvent<SDK.DebuggerModel.DebuggerModel>): void {
|
|
@@ -69,9 +69,10 @@ export const SORT_ORDER_PAGE_LOAD_MARKERS: Readonly<Record<string, number>> = {
|
|
|
69
69
|
[Trace.Types.Events.Name.SOFT_NAVIGATION_START]: 1,
|
|
70
70
|
[Trace.Types.Events.Name.MARK_LOAD]: 2,
|
|
71
71
|
[Trace.Types.Events.Name.MARK_FCP]: 3,
|
|
72
|
-
[Trace.Types.Events.Name.
|
|
73
|
-
[Trace.Types.Events.Name.
|
|
74
|
-
[Trace.Types.Events.Name.
|
|
72
|
+
[Trace.Types.Events.Name.MARK_SOFT_FCP]: 4,
|
|
73
|
+
[Trace.Types.Events.Name.MARK_DOM_CONTENT]: 5,
|
|
74
|
+
[Trace.Types.Events.Name.MARK_LCP_CANDIDATE]: 6,
|
|
75
|
+
[Trace.Types.Events.Name.MARK_LCP_CANDIDATE_FOR_SOFT_NAVIGATION]: 7,
|
|
75
76
|
};
|
|
76
77
|
|
|
77
78
|
// Threshold to match up overlay markers that are off by a tiny amount so they aren't rendered
|
|
@@ -676,7 +677,7 @@ export class TimelineFlameChartView extends Common.ObjectWrapper.eventMixin<Even
|
|
|
676
677
|
event.name === Trace.Types.Events.Name.SOFT_NAVIGATION_START ||
|
|
677
678
|
event.name === Trace.Types.Events.Name.MARK_LCP_CANDIDATE ||
|
|
678
679
|
event.name === Trace.Types.Events.Name.MARK_LCP_CANDIDATE_FOR_SOFT_NAVIGATION ||
|
|
679
|
-
event.name === Trace.Types.Events.Name.MARK_FCP ||
|
|
680
|
+
event.name === Trace.Types.Events.Name.MARK_FCP || event.name === Trace.Types.Events.Name.MARK_SOFT_FCP ||
|
|
680
681
|
event.name === Trace.Types.Events.Name.MARK_DOM_CONTENT ||
|
|
681
682
|
event.name === Trace.Types.Events.Name.MARK_LOAD);
|
|
682
683
|
|
|
@@ -2435,6 +2435,13 @@ export class TimelinePanel extends Common.ObjectWrapper.eventMixin<EventTypes, t
|
|
|
2435
2435
|
async loadingStarted(): Promise<void> {
|
|
2436
2436
|
this.#changeView({mode: 'STATUS_PANE_OVERLAY'});
|
|
2437
2437
|
|
|
2438
|
+
// If recording was stopped automatically (e.g. page reload or AI-triggered trace),
|
|
2439
|
+
// we must transition to STOP_PENDING so that loadingComplete() knows the resulting
|
|
2440
|
+
// trace is a fresh recording.
|
|
2441
|
+
if (this.state === State.RECORDING) {
|
|
2442
|
+
this.setState(State.STOP_PENDING);
|
|
2443
|
+
}
|
|
2444
|
+
|
|
2438
2445
|
if (this.statusDialog) {
|
|
2439
2446
|
this.statusDialog.remove();
|
|
2440
2447
|
}
|
|
@@ -668,7 +668,6 @@ export class TimelineUIUtils {
|
|
|
668
668
|
const options = {
|
|
669
669
|
tabStop: true,
|
|
670
670
|
showColumnNumber: false,
|
|
671
|
-
inlineFrameIndex: 0,
|
|
672
671
|
};
|
|
673
672
|
details = LegacyComponents.Linkifier.Linkifier.linkifyURL(url, options);
|
|
674
673
|
}
|
|
@@ -763,7 +762,6 @@ export class TimelineUIUtils {
|
|
|
763
762
|
lineNumber,
|
|
764
763
|
columnNumber,
|
|
765
764
|
showColumnNumber: true,
|
|
766
|
-
inlineFrameIndex: 0,
|
|
767
765
|
className: 'timeline-details',
|
|
768
766
|
tabStop: true,
|
|
769
767
|
omitOrigin,
|
|
@@ -788,14 +786,13 @@ export class TimelineUIUtils {
|
|
|
788
786
|
const options = {
|
|
789
787
|
className: 'timeline-details',
|
|
790
788
|
tabStop: true,
|
|
791
|
-
inlineFrameIndex: 0,
|
|
792
789
|
showColumnNumber: true,
|
|
793
790
|
columnNumber: frame.columnNumber,
|
|
794
791
|
lineNumber: frame.lineNumber,
|
|
795
792
|
maxLength,
|
|
796
793
|
};
|
|
797
794
|
if (isFreshOrEnhanced) {
|
|
798
|
-
return linkifier.maybeLinkifyConsoleCallFrame(target, frame, {showColumnNumber: true
|
|
795
|
+
return linkifier.maybeLinkifyConsoleCallFrame(target, frame, {showColumnNumber: true});
|
|
799
796
|
}
|
|
800
797
|
return LegacyComponents.Linkifier.Linkifier.linkifyURL(frame.url as Platform.DevToolsPath.UrlString, options);
|
|
801
798
|
}
|
|
@@ -809,17 +806,21 @@ export class TimelineUIUtils {
|
|
|
809
806
|
name = 'Largest Contentful Paint';
|
|
810
807
|
break;
|
|
811
808
|
case Trace.Types.Events.Name.MARK_LCP_CANDIDATE_FOR_SOFT_NAVIGATION:
|
|
812
|
-
link = 'https://developer.chrome.com/docs/web-platform/soft-navigations
|
|
809
|
+
link = 'https://developer.chrome.com/docs/web-platform/soft-navigations';
|
|
813
810
|
name = 'Soft Largest Contentful Paint';
|
|
814
811
|
break;
|
|
815
812
|
case Trace.Types.Events.Name.SOFT_NAVIGATION_START:
|
|
816
|
-
link = 'https://developer.chrome.com/docs/web-platform/soft-navigations
|
|
813
|
+
link = 'https://developer.chrome.com/docs/web-platform/soft-navigations';
|
|
817
814
|
name = 'Soft Navigations';
|
|
818
815
|
break;
|
|
819
816
|
case Trace.Types.Events.Name.MARK_FCP:
|
|
820
817
|
link = 'https://web.dev/first-contentful-paint/';
|
|
821
818
|
name = 'First Contentful Paint';
|
|
822
819
|
break;
|
|
820
|
+
case Trace.Types.Events.Name.MARK_SOFT_FCP:
|
|
821
|
+
link = 'https://developer.chrome.com/docs/web-platform/soft-navigations';
|
|
822
|
+
name = 'Soft First Contentful Paint';
|
|
823
|
+
break;
|
|
823
824
|
default:
|
|
824
825
|
break;
|
|
825
826
|
}
|
|
@@ -963,7 +964,7 @@ export class TimelineUIUtils {
|
|
|
963
964
|
|
|
964
965
|
// Add timestamp to user timings, including custom extensibility markers
|
|
965
966
|
if (Trace.Helpers.Trace.eventHasCategory(event, Trace.Types.Events.Categories.UserTiming) ||
|
|
966
|
-
Trace.Types.Extensions.isSyntheticExtensionEntry(event)) {
|
|
967
|
+
Trace.Types.Extensions.isSyntheticExtensionEntry(event) || Trace.Types.Events.isSoftNavigationStart(event)) {
|
|
967
968
|
const adjustedEventTimeStamp = timeStampForEventAdjustedForClosestNavigationIfPossible(
|
|
968
969
|
event,
|
|
969
970
|
parsedTrace,
|
|
@@ -1228,7 +1229,6 @@ export class TimelineUIUtils {
|
|
|
1228
1229
|
const options = {
|
|
1229
1230
|
tabStop: true,
|
|
1230
1231
|
showColumnNumber: false,
|
|
1231
|
-
inlineFrameIndex: 0,
|
|
1232
1232
|
};
|
|
1233
1233
|
contentHelper.appendElementRow(
|
|
1234
1234
|
i18nString(UIStrings.imageUrl), LegacyComponents.Linkifier.Linkifier.linkifyURL(url, options));
|
|
@@ -1242,7 +1242,6 @@ export class TimelineUIUtils {
|
|
|
1242
1242
|
const options = {
|
|
1243
1243
|
tabStop: true,
|
|
1244
1244
|
showColumnNumber: false,
|
|
1245
|
-
inlineFrameIndex: 0,
|
|
1246
1245
|
};
|
|
1247
1246
|
contentHelper.appendElementRow(
|
|
1248
1247
|
i18nString(UIStrings.stylesheetUrl), LegacyComponents.Linkifier.Linkifier.linkifyURL(url, options));
|
|
@@ -1444,6 +1443,7 @@ export class TimelineUIUtils {
|
|
|
1444
1443
|
|
|
1445
1444
|
case Trace.Types.Events.Name.MARK_FIRST_PAINT:
|
|
1446
1445
|
case Trace.Types.Events.Name.MARK_FCP:
|
|
1446
|
+
case Trace.Types.Events.Name.MARK_SOFT_FCP:
|
|
1447
1447
|
case Trace.Types.Events.Name.MARK_LOAD:
|
|
1448
1448
|
case Trace.Types.Events.Name.MARK_DOM_CONTENT: {
|
|
1449
1449
|
const adjustedEventTimeStamp = timeStampForEventAdjustedForClosestNavigationIfPossible(
|
|
@@ -2074,7 +2074,7 @@ export class TimelineUIUtils {
|
|
|
2074
2074
|
tall = true;
|
|
2075
2075
|
break;
|
|
2076
2076
|
case Trace.Types.Events.Name.SOFT_NAVIGATION_START:
|
|
2077
|
-
color = 'var(--
|
|
2077
|
+
color = 'var(--color-text-primary)';
|
|
2078
2078
|
tall = true;
|
|
2079
2079
|
break;
|
|
2080
2080
|
case Trace.Types.Events.Name.FRAME_STARTED_LOADING:
|
|
@@ -2094,6 +2094,7 @@ export class TimelineUIUtils {
|
|
|
2094
2094
|
tall = true;
|
|
2095
2095
|
break;
|
|
2096
2096
|
case Trace.Types.Events.Name.MARK_FCP:
|
|
2097
|
+
case Trace.Types.Events.Name.MARK_SOFT_FCP:
|
|
2097
2098
|
color = 'var(--sys-color-green-bright)';
|
|
2098
2099
|
tall = true;
|
|
2099
2100
|
break;
|
|
@@ -2299,7 +2300,6 @@ export class TimelineDetailsContentHelper {
|
|
|
2299
2300
|
tabStop: true,
|
|
2300
2301
|
columnNumber: startColumn,
|
|
2301
2302
|
showColumnNumber: true,
|
|
2302
|
-
inlineFrameIndex: 0,
|
|
2303
2303
|
text,
|
|
2304
2304
|
omitOrigin,
|
|
2305
2305
|
};
|
|
@@ -2316,8 +2316,7 @@ export class TimelineDetailsContentHelper {
|
|
|
2316
2316
|
return;
|
|
2317
2317
|
}
|
|
2318
2318
|
const locationContent = document.createElement('span');
|
|
2319
|
-
const link = this.#linkifier.maybeLinkifyScriptLocation(
|
|
2320
|
-
this.target, null, url, startLine, {tabStop: true, inlineFrameIndex: 0});
|
|
2319
|
+
const link = this.#linkifier.maybeLinkifyScriptLocation(this.target, null, url, startLine, {tabStop: true});
|
|
2321
2320
|
if (!link) {
|
|
2322
2321
|
return;
|
|
2323
2322
|
}
|
|
@@ -2407,7 +2406,7 @@ export function isMarkerEvent(parsedTrace: Trace.TraceModel.ParsedTrace, event:
|
|
|
2407
2406
|
return true;
|
|
2408
2407
|
}
|
|
2409
2408
|
|
|
2410
|
-
if (Trace.Types.Events.
|
|
2409
|
+
if (Trace.Types.Events.isAnyFirstContentfulPaint(event) || Trace.Types.Events.isFirstPaint(event)) {
|
|
2411
2410
|
return event.args.frame === parsedTrace.data.Meta.mainFrameId;
|
|
2412
2411
|
}
|
|
2413
2412
|
|
|
@@ -37,12 +37,14 @@ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
|
37
37
|
*/
|
|
38
38
|
export const SORT_ORDER_PAGE_LOAD_MARKERS: Readonly<Record<string, number>> = {
|
|
39
39
|
[Trace.Types.Events.Name.NAVIGATION_START]: 0,
|
|
40
|
-
[Trace.Types.Events.Name.
|
|
41
|
-
[Trace.Types.Events.Name.MARK_FCP]: 2,
|
|
40
|
+
[Trace.Types.Events.Name.SOFT_NAVIGATION_START]: 1,
|
|
42
41
|
[Trace.Types.Events.Name.MARK_FIRST_PAINT]: 2,
|
|
43
|
-
[Trace.Types.Events.Name.
|
|
44
|
-
[Trace.Types.Events.Name.
|
|
45
|
-
[Trace.Types.Events.Name.
|
|
42
|
+
[Trace.Types.Events.Name.MARK_FCP]: 3,
|
|
43
|
+
[Trace.Types.Events.Name.MARK_SOFT_FCP]: 4,
|
|
44
|
+
[Trace.Types.Events.Name.MARK_DOM_CONTENT]: 5,
|
|
45
|
+
[Trace.Types.Events.Name.MARK_LOAD]: 6,
|
|
46
|
+
[Trace.Types.Events.Name.MARK_LCP_CANDIDATE]: 7,
|
|
47
|
+
[Trace.Types.Events.Name.MARK_LCP_CANDIDATE_FOR_SOFT_NAVIGATION]: 8,
|
|
46
48
|
};
|
|
47
49
|
|
|
48
50
|
export class TimingsTrackAppender implements TrackAppender {
|
|
@@ -436,7 +436,6 @@ function linkifyURL(url: Platform.DevToolsPath.UrlString): HTMLElement {
|
|
|
436
436
|
return LegacyComponents.Linkifier.Linkifier.linkifyURL(url, {
|
|
437
437
|
tabStop: true,
|
|
438
438
|
showColumnNumber: false,
|
|
439
|
-
inlineFrameIndex: 0,
|
|
440
439
|
maxLength: MAX_URL_LENGTH,
|
|
441
440
|
});
|
|
442
441
|
}
|
|
@@ -267,7 +267,6 @@ function renderURL(request: Trace.Types.Events.SyntheticNetworkRequest): Lit.Tem
|
|
|
267
267
|
const options: LegacyComponents.Linkifier.LinkifyURLOptions = {
|
|
268
268
|
tabStop: true,
|
|
269
269
|
showColumnNumber: false,
|
|
270
|
-
inlineFrameIndex: 0,
|
|
271
270
|
maxLength: MAX_URL_LENGTH,
|
|
272
271
|
};
|
|
273
272
|
const linkifiedURL = LegacyComponents.Linkifier.Linkifier.linkifyURL(
|
|
@@ -439,7 +438,6 @@ function renderInitiatedBy(
|
|
|
439
438
|
const options: LegacyComponents.Linkifier.LinkifyOptions = {
|
|
440
439
|
tabStop: true,
|
|
441
440
|
showColumnNumber: true,
|
|
442
|
-
inlineFrameIndex: 0,
|
|
443
441
|
};
|
|
444
442
|
// If we have a stack trace, that is the most reliable way to get the initiator data and display a link to the source.
|
|
445
443
|
if (hasStackTrace) {
|
|
@@ -39,7 +39,6 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
39
39
|
const options = {
|
|
40
40
|
tabStop: true,
|
|
41
41
|
showColumnNumber: false,
|
|
42
|
-
inlineFrameIndex: 0,
|
|
43
42
|
maxLength: MAX_URL_LENGTH,
|
|
44
43
|
};
|
|
45
44
|
const linkEl = LegacyComponents.Linkifier.Linkifier.linkifyURL(fallbackUrl, options);
|
|
@@ -1627,6 +1627,8 @@ export class Overlays extends EventTarget {
|
|
|
1627
1627
|
markers: HTMLElement, marker: HTMLElement): void {
|
|
1628
1628
|
if (Trace.Types.Events.isSoftNavigationStart(event)) {
|
|
1629
1629
|
name = 'Soft Nav';
|
|
1630
|
+
} else if (Trace.Types.Events.isSoftFirstContentfulPaint(event)) {
|
|
1631
|
+
name = 'Soft FCP';
|
|
1630
1632
|
} else if (Trace.Types.Events.isSoftLargestContentfulPaintCandidate(event)) {
|
|
1631
1633
|
name = 'Soft LCP';
|
|
1632
1634
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Name: Dependencies sourced from the upstream `chromium` repository
|
|
2
2
|
URL: Internal
|
|
3
3
|
Version: N/A
|
|
4
|
-
Revision:
|
|
4
|
+
Revision: db882e11eb73564831cdf0a63b661a81332df665
|
|
5
5
|
Update Mechanism: Manual (https://crbug.com/428069060)
|
|
6
6
|
License: BSD-3-Clause
|
|
7
7
|
License File: LICENSE
|
|
@@ -57,15 +57,15 @@ import * as SDK from '../../core/sdk/sdk.js';
|
|
|
57
57
|
* @throws TypeError if `url` is not a valid URL.
|
|
58
58
|
* @see https://en.wikipedia.org/wiki/UTM_parameters
|
|
59
59
|
*/
|
|
60
|
-
export function openInNewTab(url: URL|string): void {
|
|
60
|
+
export function openInNewTab(url: URL|string, allowPrivileged?: boolean): void {
|
|
61
61
|
url = new URL(url);
|
|
62
62
|
if (Common.ParsedURL.schemeIs(url, 'javascript:')) {
|
|
63
63
|
return;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
// Navigating to a chrome:// link via a normal anchor doesn't work, so we "navigate"
|
|
67
|
-
// there using CDP.
|
|
68
|
-
if (Common.ParsedURL.schemeIs(url, 'chrome:')) {
|
|
67
|
+
// there using CDP if explicitly requested.
|
|
68
|
+
if (allowPrivileged && Common.ParsedURL.schemeIs(url, 'chrome:')) {
|
|
69
69
|
const rootTarget = SDK.TargetManager.TargetManager.instance().rootTarget();
|
|
70
70
|
if (rootTarget === null) {
|
|
71
71
|
return;
|
|
@@ -60,7 +60,7 @@ export class Link extends HTMLElement {
|
|
|
60
60
|
return;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
UIHelpers.openInNewTab(href);
|
|
63
|
+
UIHelpers.openInNewTab(href, this.allowPrivileged);
|
|
64
64
|
|
|
65
65
|
event.consume();
|
|
66
66
|
}
|
|
@@ -73,6 +73,18 @@ export class Link extends HTMLElement {
|
|
|
73
73
|
this.setAttribute('href', href);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
get allowPrivileged(): boolean {
|
|
77
|
+
return this.hasAttribute('allow-privileged');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
set allowPrivileged(allowPrivileged: boolean) {
|
|
81
|
+
if (allowPrivileged) {
|
|
82
|
+
this.setAttribute('allow-privileged', '');
|
|
83
|
+
} else {
|
|
84
|
+
this.removeAttribute('allow-privileged');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
76
88
|
get jslogContext(): string|null {
|
|
77
89
|
return this.getAttribute('jslogcontext');
|
|
78
90
|
}
|
|
@@ -98,7 +110,7 @@ export class Link extends HTMLElement {
|
|
|
98
110
|
oldValue: string|null,
|
|
99
111
|
newValue: string|null,
|
|
100
112
|
): void {
|
|
101
|
-
if (oldValue
|
|
113
|
+
if (oldValue === newValue) {
|
|
102
114
|
return;
|
|
103
115
|
}
|
|
104
116
|
if (name === 'jslogcontext') {
|
|
@@ -145,9 +157,11 @@ export class Link extends HTMLElement {
|
|
|
145
157
|
className?: string,
|
|
146
158
|
jsLogContext?: string,
|
|
147
159
|
tabindex = 0,
|
|
160
|
+
allowPrivileged = false,
|
|
148
161
|
): Link {
|
|
149
162
|
const link = new Link();
|
|
150
163
|
link.href = url as Platform.DevToolsPath.UrlString;
|
|
164
|
+
link.allowPrivileged = allowPrivileged;
|
|
151
165
|
linkText = linkText ?? url;
|
|
152
166
|
link.textContent = Platform.StringUtilities.trimMiddle(linkText, 150);
|
|
153
167
|
|