chrome-devtools-frontend 1.0.1643855 → 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/front_end/core/host/UserMetrics.ts +3 -2
- package/front_end/core/sdk/CSSPropertyParserMatchers.ts +2 -3
- package/front_end/core/sdk/NetworkRequest.ts +0 -1
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +37 -0
- package/front_end/generated/SupportedCSSProperties.js +4 -2
- package/front_end/models/ai_assistance/AiAgent2.ts +23 -13
- package/front_end/models/ai_assistance/README.md +5 -4
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +15 -0
- package/front_end/models/ai_assistance/agents/README.md +57 -0
- package/front_end/models/ai_assistance/agents/StylingAgent.ts +26 -3
- package/front_end/models/ai_assistance/tools/ExecuteJavaScript.ts +9 -12
- 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 +74 -11
- package/front_end/models/ai_assistance/tools/ToolRegistry.ts +21 -5
- package/front_end/models/heap_snapshot/HeapSnapshotModel.ts +18 -2
- package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +4 -0
- package/front_end/models/stack_trace/DetailedErrorStackParser.ts +17 -4
- package/front_end/models/stack_trace/StackTraceModel.ts +34 -1
- 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/ai_assistance/AiAssistancePanel.ts +8 -2
- package/front_end/panels/ai_assistance/ai_assistance-meta.ts +16 -0
- package/front_end/panels/application/ApplicationPanelSidebar.ts +44 -0
- 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/console/ConsoleView.ts +6 -1
- package/front_end/panels/console/ConsoleViewMessage.ts +46 -213
- package/front_end/panels/console/SymbolizedErrorWidget.ts +4 -1
- 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/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/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/visual_logging/KnownContextValues.ts +5 -0
- package/package.json +1 -1
|
@@ -94,6 +94,18 @@ import {TrustTokensTreeElement} from './TrustTokensTreeElement.js';
|
|
|
94
94
|
import {WebMCPTreeElement} from './WebMCPTreeElement.js';
|
|
95
95
|
|
|
96
96
|
const UIStrings = {
|
|
97
|
+
/**
|
|
98
|
+
* @description Text of a context menu item to start a chat with AI
|
|
99
|
+
*/
|
|
100
|
+
startAChat: 'Start a chat',
|
|
101
|
+
/**
|
|
102
|
+
* @description Text of a context menu item to explain contents of a local/session storage bucket with AI
|
|
103
|
+
*/
|
|
104
|
+
explainStorage: 'Explain storage',
|
|
105
|
+
/**
|
|
106
|
+
* @description Text of a context menu item to explain web cookies with AI
|
|
107
|
+
*/
|
|
108
|
+
explainCookies: 'Explain cookies',
|
|
97
109
|
/**
|
|
98
110
|
* @description Text in Application Panel Sidebar of the Application panel
|
|
99
111
|
*/
|
|
@@ -1792,6 +1804,22 @@ export class DOMStorageTreeElement extends ApplicationPanelTreeElement {
|
|
|
1792
1804
|
const contextMenu = new UI.ContextMenu.ContextMenu(event);
|
|
1793
1805
|
contextMenu.defaultSection().appendItem(
|
|
1794
1806
|
i18nString(UIStrings.clear), () => this.domStorage.clear(), {jslogContext: 'clear'});
|
|
1807
|
+
|
|
1808
|
+
const storageItem = this.#getStorageItem();
|
|
1809
|
+
if (storageItem) {
|
|
1810
|
+
const openAiAssistanceId = 'ai-assistance.application-panel-context';
|
|
1811
|
+
if (UI.ActionRegistry.ActionRegistry.instance().hasAction(openAiAssistanceId)) {
|
|
1812
|
+
UI.Context.Context.instance().setFlavor(AiAssistance.StorageItem.StorageItem, storageItem);
|
|
1813
|
+
const action = UI.ActionRegistry.ActionRegistry.instance().getAction(openAiAssistanceId);
|
|
1814
|
+
const submenu = contextMenu.footerSection().appendSubMenuItem(action.title(), false, openAiAssistanceId);
|
|
1815
|
+
submenu.defaultSection().appendAction(openAiAssistanceId, i18nString(UIStrings.startAChat));
|
|
1816
|
+
submenu.defaultSection().appendItem(
|
|
1817
|
+
i18nString(UIStrings.explainStorage),
|
|
1818
|
+
() => action.execute({prompt: 'What is the purpose of this storage bucket?'}),
|
|
1819
|
+
{disabled: !action.enabled(), jslogContext: openAiAssistanceId + '.storage'});
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1822
|
+
|
|
1795
1823
|
void contextMenu.show();
|
|
1796
1824
|
}
|
|
1797
1825
|
}
|
|
@@ -1900,6 +1928,22 @@ export class CookieTreeElement extends ApplicationPanelTreeElement {
|
|
|
1900
1928
|
contextMenu.defaultSection().appendItem(
|
|
1901
1929
|
i18nString(UIStrings.clear), () => this.resourcesPanel.clearCookies(this.target, this.#cookieDomain),
|
|
1902
1930
|
{jslogContext: 'clear'});
|
|
1931
|
+
|
|
1932
|
+
const storageItem = this.#getStorageItem();
|
|
1933
|
+
if (storageItem) {
|
|
1934
|
+
const openAiAssistanceId = 'ai-assistance.application-panel-context';
|
|
1935
|
+
if (UI.ActionRegistry.ActionRegistry.instance().hasAction(openAiAssistanceId)) {
|
|
1936
|
+
UI.Context.Context.instance().setFlavor(AiAssistance.StorageItem.StorageItem, storageItem);
|
|
1937
|
+
const action = UI.ActionRegistry.ActionRegistry.instance().getAction(openAiAssistanceId);
|
|
1938
|
+
const submenu = contextMenu.footerSection().appendSubMenuItem(action.title(), false, openAiAssistanceId);
|
|
1939
|
+
submenu.defaultSection().appendAction(openAiAssistanceId, i18nString(UIStrings.startAChat));
|
|
1940
|
+
submenu.defaultSection().appendItem(
|
|
1941
|
+
i18nString(UIStrings.explainCookies),
|
|
1942
|
+
() => action.execute({prompt: 'What is the purpose of these cookies?'}),
|
|
1943
|
+
{disabled: !action.enabled(), jslogContext: openAiAssistanceId + '.cookies'});
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1946
|
+
|
|
1903
1947
|
void contextMenu.show();
|
|
1904
1948
|
}
|
|
1905
1949
|
|
|
@@ -228,8 +228,8 @@ export class ServiceWorkersView extends UI.Widget.VBox implements
|
|
|
228
228
|
othersView.show(othersDiv);
|
|
229
229
|
const othersSection = othersView.appendSection(i18nString(UIStrings.serviceWorkersFromOtherOrigins));
|
|
230
230
|
const othersSectionRow = othersSection.appendRow();
|
|
231
|
-
const seeOthers = Link.create(
|
|
232
|
-
|
|
231
|
+
const seeOthers = Link.create('chrome://serviceworker-internals', i18nString(UIStrings.seeAllRegistrations),
|
|
232
|
+
undefined, 'view-all', 0, /* allowPrivileged=*/ true);
|
|
233
233
|
othersSectionRow.appendChild(seeOthers);
|
|
234
234
|
|
|
235
235
|
this.toolbar.appendToolbarItem(
|
|
@@ -341,7 +341,7 @@ function maybeRenderReasonContext(explanation: Protocol.Page.BackForwardCacheNot
|
|
|
341
341
|
const link = 'chrome://extensions/?id=' + explanation.context as Platform.DevToolsPath.UrlString;
|
|
342
342
|
// clang-format off
|
|
343
343
|
return html`${i18nString(UIStrings.blockingExtensionId)}
|
|
344
|
-
<devtools-link .href=${link}>${explanation.context}</devtools-link>`;
|
|
344
|
+
<devtools-link .href=${link} allow-privileged>${explanation.context}</devtools-link>`;
|
|
345
345
|
// clang-format on
|
|
346
346
|
}
|
|
347
347
|
return nothing;
|
|
@@ -393,7 +393,6 @@ function maybeRenderJavaScriptDetails(details: Protocol.Page.BackForwardCacheBlo
|
|
|
393
393
|
options: {
|
|
394
394
|
columnNumber: detail.columnNumber,
|
|
395
395
|
showColumnNumber: true,
|
|
396
|
-
inlineFrameIndex: 0,
|
|
397
396
|
maxLength: maxLengthForDisplayedURLs,
|
|
398
397
|
}
|
|
399
398
|
})}`));
|
|
@@ -75,6 +75,7 @@ import {
|
|
|
75
75
|
getMessageForElement,
|
|
76
76
|
} from './ConsoleViewMessage.js';
|
|
77
77
|
import {ConsoleViewport, type ConsoleViewportElement, type ConsoleViewportProvider} from './ConsoleViewport.js';
|
|
78
|
+
import symbolizedErrorWidgetStyles from './symbolizedErrorWidget.css.js';
|
|
78
79
|
|
|
79
80
|
const UIStrings = {
|
|
80
81
|
/**
|
|
@@ -356,7 +357,11 @@ export class ConsoleView extends UI.Widget.VBox implements
|
|
|
356
357
|
constructor(viewportThrottlerTimeout: number) {
|
|
357
358
|
super();
|
|
358
359
|
this.setMinimumSize(0, 35);
|
|
359
|
-
|
|
360
|
+
// We register the SymbolizedErrorWidget styles here because many web and e2e
|
|
361
|
+
// tests use `deepTextContent`, which would also include <style> tags if they
|
|
362
|
+
// were injected directly into the widget's shadow DOM.
|
|
363
|
+
this.registerRequiredCSS(consoleViewStyles, symbolizedErrorWidgetStyles, objectValueStyles,
|
|
364
|
+
CodeHighlighter.codeHighlighterStyles);
|
|
360
365
|
|
|
361
366
|
this.#searchableView = new UI.SearchableView.SearchableView(this, null);
|
|
362
367
|
this.#searchableView.element.classList.add('console-searchable-view');
|
|
@@ -34,7 +34,6 @@
|
|
|
34
34
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
35
35
|
*/
|
|
36
36
|
|
|
37
|
-
import type {Chrome} from '../../../extension-api/ExtensionAPI.js';
|
|
38
37
|
import * as Common from '../../core/common/common.js';
|
|
39
38
|
import * as Host from '../../core/host/host.js';
|
|
40
39
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
@@ -45,7 +44,6 @@ import * as AiAssistanceModel from '../../models/ai_assistance/ai_assistance.js'
|
|
|
45
44
|
import * as Bindings from '../../models/bindings/bindings.js';
|
|
46
45
|
import type * as IssuesManager from '../../models/issues_manager/issues_manager.js';
|
|
47
46
|
import * as Logs from '../../models/logs/logs.js';
|
|
48
|
-
import * as StackTrace from '../../models/stack_trace/stack_trace.js';
|
|
49
47
|
import * as TextUtils from '../../models/text_utils/text_utils.js';
|
|
50
48
|
import * as Workspace from '../../models/workspace/workspace.js';
|
|
51
49
|
import * as CodeHighlighter from '../../ui/components/code_highlighter/code_highlighter.js';
|
|
@@ -66,6 +64,7 @@ import {format, updateStyle} from './ConsoleFormat.js';
|
|
|
66
64
|
import {ConsoleInsightTeaser} from './ConsoleInsightTeaser.js';
|
|
67
65
|
import consoleViewStyles from './consoleView.css.js';
|
|
68
66
|
import type {ConsoleViewportElement} from './ConsoleViewport.js';
|
|
67
|
+
import {SymbolizedErrorWidget} from './SymbolizedErrorWidget.js';
|
|
69
68
|
|
|
70
69
|
const UIStrings = {
|
|
71
70
|
/**
|
|
@@ -449,7 +448,14 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
|
|
|
449
448
|
if (this.message.parameters?.length === 1) {
|
|
450
449
|
const parameter = this.message.parameters[0];
|
|
451
450
|
if (typeof parameter !== 'string' && parameter.type === 'string') {
|
|
452
|
-
|
|
451
|
+
const value = parameter.value as string;
|
|
452
|
+
const runtimeModel = this.message.runtimeModel();
|
|
453
|
+
if (runtimeModel && Bindings.SymbolizedError.isErrorLike(value)) {
|
|
454
|
+
const remoteObj = parameter instanceof SDK.RemoteObject.RemoteObject ?
|
|
455
|
+
parameter :
|
|
456
|
+
runtimeModel.createRemoteObject(parameter);
|
|
457
|
+
messageElement = this.renderSymbolizedError(remoteObj);
|
|
458
|
+
}
|
|
453
459
|
}
|
|
454
460
|
}
|
|
455
461
|
const args = this.message.parameters || [messageText];
|
|
@@ -570,23 +576,21 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
|
|
|
570
576
|
const userMetric = this.#getLinkifierMetric();
|
|
571
577
|
if (stackFrameWithBreakpoint) {
|
|
572
578
|
return this.linkifier.maybeLinkifyConsoleCallFrame(runtimeModel.target(), stackFrameWithBreakpoint, {
|
|
573
|
-
inlineFrameIndex: 0,
|
|
574
579
|
revealBreakpoint: true,
|
|
575
580
|
userMetric,
|
|
576
581
|
});
|
|
577
582
|
}
|
|
578
583
|
if (scriptId) {
|
|
579
|
-
return this.linkifier.linkifyScriptLocation(
|
|
580
|
-
|
|
581
|
-
|
|
584
|
+
return this.linkifier.linkifyScriptLocation(runtimeModel.target(), scriptId,
|
|
585
|
+
url || Platform.DevToolsPath.EmptyUrlString, line,
|
|
586
|
+
{columnNumber: column, userMetric});
|
|
582
587
|
}
|
|
583
588
|
if (stackTrace?.callFrames.length) {
|
|
584
589
|
return this.linkifier.linkifyStackTraceTopFrame(runtimeModel.target(), stackTrace);
|
|
585
590
|
}
|
|
586
591
|
if (url && url !== 'undefined') {
|
|
587
|
-
return this.linkifier.linkifyScriptLocation(
|
|
588
|
-
|
|
589
|
-
{columnNumber: column, inlineFrameIndex: 0, userMetric});
|
|
592
|
+
return this.linkifier.linkifyScriptLocation(runtimeModel.target(), /* scriptId */ null, url, line,
|
|
593
|
+
{columnNumber: column, userMetric});
|
|
590
594
|
}
|
|
591
595
|
return null;
|
|
592
596
|
};
|
|
@@ -695,17 +699,19 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
|
|
|
695
699
|
stackTracePreview.options = {widthConstrained: true};
|
|
696
700
|
if (stackTraceTarget && stackTrace) {
|
|
697
701
|
const selectableChildIndex = this.selectableChildren.length;
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
702
|
+
const stackTracePromise = Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance()
|
|
703
|
+
.createStackTraceFromProtocolRuntime(stackTrace, stackTraceTarget)
|
|
704
|
+
.then(stackTrace => {
|
|
705
|
+
stackTracePreview.stackTrace = stackTrace;
|
|
706
|
+
return stackTracePreview.updateComplete;
|
|
707
|
+
})
|
|
708
|
+
.then(() => {
|
|
709
|
+
const selectableLinks = stackTracePreview.linkElements.map(
|
|
710
|
+
(element: HTMLElement) => ({element, forceSelect: () => element.focus()}));
|
|
711
|
+
this.selectableChildren.splice(selectableChildIndex, 0, ...selectableLinks);
|
|
712
|
+
});
|
|
713
|
+
this.#formatErrorStackPromiseForTest =
|
|
714
|
+
Promise.all([this.#formatErrorStackPromiseForTest, stackTracePromise]).then(() => {});
|
|
709
715
|
}
|
|
710
716
|
stackTracePreview.markAsRoot();
|
|
711
717
|
stackTracePreview.show(stackTraceElement);
|
|
@@ -771,7 +777,7 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
|
|
|
771
777
|
let element;
|
|
772
778
|
switch (outputType) {
|
|
773
779
|
case 'error':
|
|
774
|
-
element = this.
|
|
780
|
+
element = this.renderSymbolizedError(output);
|
|
775
781
|
break;
|
|
776
782
|
case 'function':
|
|
777
783
|
element = this.formatParameterAsFunction(output, includePreview);
|
|
@@ -980,42 +986,28 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
|
|
|
980
986
|
return result;
|
|
981
987
|
}
|
|
982
988
|
|
|
983
|
-
private
|
|
984
|
-
const
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
// linking.
|
|
989
|
-
const formatErrorStack =
|
|
990
|
-
async(errorObj: SDK.RemoteObject.RemoteObject, includeCausedByPrefix: boolean): Promise<void> => {
|
|
991
|
-
const error = SDK.RemoteObject.RemoteError.objectAsError(errorObj);
|
|
992
|
-
const [details, cause] = await Promise.all([error.exceptionDetails(), error.cause()]);
|
|
993
|
-
let errorElement = this.tryFormatAsError(error.errorStack, details);
|
|
994
|
-
if (!errorElement) {
|
|
995
|
-
errorElement = document.createElement('span');
|
|
996
|
-
appendOrShow(errorElement, this.linkifyStringAsFragment(error.errorStack));
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
if (includeCausedByPrefix) {
|
|
1000
|
-
const causeElement = document.createElement('div');
|
|
1001
|
-
causeElement.append('Caused by: ', errorElement);
|
|
1002
|
-
result.appendChild(causeElement);
|
|
1003
|
-
} else {
|
|
1004
|
-
result.appendChild(errorElement);
|
|
1005
|
-
}
|
|
989
|
+
private renderSymbolizedError(errorRemoteObject: SDK.RemoteObject.RemoteObject): HTMLElement {
|
|
990
|
+
const container = document.createElement('span');
|
|
991
|
+
const widget = new SymbolizedErrorWidget();
|
|
992
|
+
widget.ignoreListManager = Workspace.IgnoreListManager.IgnoreListManager.instance();
|
|
993
|
+
const selectableChildIndex = this.selectableChildren.length;
|
|
1006
994
|
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
result.append(stringCauseElement);
|
|
995
|
+
const format = async(): Promise<void> => {
|
|
996
|
+
const error = await Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance().createSymbolizedError(
|
|
997
|
+
errorRemoteObject, this.message.exceptionDetails);
|
|
998
|
+
if (error) {
|
|
999
|
+
widget.error = error;
|
|
1013
1000
|
}
|
|
1001
|
+
await widget.updateComplete;
|
|
1002
|
+
const selectableLinks =
|
|
1003
|
+
widget.linkElements.map((element: HTMLElement) => ({element, forceSelect: () => element.focus()}));
|
|
1004
|
+
this.selectableChildren.splice(selectableChildIndex, 0, ...selectableLinks);
|
|
1014
1005
|
};
|
|
1015
1006
|
|
|
1016
|
-
this.#formatErrorStackPromiseForTest =
|
|
1017
|
-
|
|
1018
|
-
|
|
1007
|
+
this.#formatErrorStackPromiseForTest = Promise.all([this.#formatErrorStackPromiseForTest, format()]).then(() => {});
|
|
1008
|
+
widget.markAsRoot();
|
|
1009
|
+
widget.show(container);
|
|
1010
|
+
return container;
|
|
1019
1011
|
}
|
|
1020
1012
|
|
|
1021
1013
|
private formatAsArrayEntry(output: SDK.RemoteObject.RemoteObject): DocumentFragment {
|
|
@@ -1781,165 +1773,6 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
|
|
|
1781
1773
|
return this.searchHighlightNodes[index];
|
|
1782
1774
|
}
|
|
1783
1775
|
|
|
1784
|
-
private async getInlineFrames(
|
|
1785
|
-
debuggerModel: SDK.DebuggerModel.DebuggerModel, url: Platform.DevToolsPath.UrlString,
|
|
1786
|
-
lineNumber: number|undefined, columnNumber: number|undefined): Promise<{frames: Chrome.DevTools.FunctionInfo[]}> {
|
|
1787
|
-
const debuggerWorkspaceBinding = Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance();
|
|
1788
|
-
const projects = Workspace.Workspace.WorkspaceImpl.instance().projects();
|
|
1789
|
-
const uiSourceCodes = projects.map(project => project.uiSourceCodeForURL(url)).flat().filter(f => !!f);
|
|
1790
|
-
const scripts =
|
|
1791
|
-
uiSourceCodes.map(uiSourceCode => debuggerWorkspaceBinding.scriptsForUISourceCode(uiSourceCode)).flat();
|
|
1792
|
-
if (scripts.length) {
|
|
1793
|
-
const location =
|
|
1794
|
-
new SDK.DebuggerModel.Location(debuggerModel, scripts[0].scriptId, lineNumber || 0, columnNumber);
|
|
1795
|
-
const functionInfo = await debuggerWorkspaceBinding.pluginManager.getFunctionInfo(scripts[0], location);
|
|
1796
|
-
return functionInfo && 'frames' in functionInfo ? functionInfo : {frames: []};
|
|
1797
|
-
}
|
|
1798
|
-
|
|
1799
|
-
return {frames: []};
|
|
1800
|
-
}
|
|
1801
|
-
|
|
1802
|
-
// Expand inline stack frames in the formatted error in the stackTrace element, inserting new elements before the
|
|
1803
|
-
// insertBefore anchor.
|
|
1804
|
-
private async expandInlineStackFrames(
|
|
1805
|
-
debuggerModel: SDK.DebuggerModel.DebuggerModel, prefix: string, suffix: string,
|
|
1806
|
-
url: Platform.DevToolsPath.UrlString, lineNumber: number|undefined, columnNumber: number|undefined,
|
|
1807
|
-
stackTrace: HTMLElement, insertBefore: HTMLElement): Promise<boolean> {
|
|
1808
|
-
const {frames} = await this.getInlineFrames(debuggerModel, url, lineNumber, columnNumber);
|
|
1809
|
-
if (!frames.length) {
|
|
1810
|
-
return false;
|
|
1811
|
-
}
|
|
1812
|
-
|
|
1813
|
-
for (let f = 0; f < frames.length; ++f) {
|
|
1814
|
-
const {name} = frames[f];
|
|
1815
|
-
const formattedLine = document.createElement('span');
|
|
1816
|
-
appendOrShow(formattedLine, this.linkifyStringAsFragment(`${prefix} ${name} (`));
|
|
1817
|
-
const scriptLocationLink = this.linkifier.linkifyScriptLocation(
|
|
1818
|
-
debuggerModel.target(), null, url, lineNumber, {columnNumber, inlineFrameIndex: f});
|
|
1819
|
-
scriptLocationLink.tabIndex = -1;
|
|
1820
|
-
this.selectableChildren.push({element: scriptLocationLink, forceSelect: () => scriptLocationLink.focus()});
|
|
1821
|
-
formattedLine.appendChild(scriptLocationLink);
|
|
1822
|
-
appendOrShow(formattedLine, this.linkifyStringAsFragment(suffix));
|
|
1823
|
-
formattedLine.classList.add('formatted-stack-frame');
|
|
1824
|
-
stackTrace.insertBefore(formattedLine, insertBefore);
|
|
1825
|
-
}
|
|
1826
|
-
return true;
|
|
1827
|
-
}
|
|
1828
|
-
|
|
1829
|
-
private createScriptLocationLinkForSyntaxError(
|
|
1830
|
-
debuggerModel: SDK.DebuggerModel.DebuggerModel, exceptionDetails: Protocol.Runtime.ExceptionDetails): HTMLElement
|
|
1831
|
-
|undefined {
|
|
1832
|
-
const {scriptId, lineNumber, columnNumber} = exceptionDetails;
|
|
1833
|
-
if (!scriptId) {
|
|
1834
|
-
return;
|
|
1835
|
-
}
|
|
1836
|
-
|
|
1837
|
-
// SyntaxErrors might not populate the URL field. Try to resolve it via scriptId.
|
|
1838
|
-
const url =
|
|
1839
|
-
exceptionDetails.url as Platform.DevToolsPath.UrlString || debuggerModel.scriptForId(scriptId)?.sourceURL;
|
|
1840
|
-
if (!url) {
|
|
1841
|
-
return;
|
|
1842
|
-
}
|
|
1843
|
-
|
|
1844
|
-
const scriptLocationLink = this.linkifier.linkifyScriptLocation(
|
|
1845
|
-
debuggerModel.target(), exceptionDetails.scriptId || null, url, lineNumber, {
|
|
1846
|
-
columnNumber,
|
|
1847
|
-
inlineFrameIndex: 0,
|
|
1848
|
-
showColumnNumber: true,
|
|
1849
|
-
});
|
|
1850
|
-
scriptLocationLink.tabIndex = -1;
|
|
1851
|
-
return scriptLocationLink;
|
|
1852
|
-
}
|
|
1853
|
-
|
|
1854
|
-
private tryFormatAsError(string: string, exceptionDetails?: Protocol.Runtime.ExceptionDetails): HTMLElement|null {
|
|
1855
|
-
const runtimeModel = this.message.runtimeModel();
|
|
1856
|
-
if (!runtimeModel) {
|
|
1857
|
-
return null;
|
|
1858
|
-
}
|
|
1859
|
-
|
|
1860
|
-
const issueSummary = exceptionDetails?.exceptionMetaData?.issueSummary;
|
|
1861
|
-
if (typeof issueSummary === 'string') {
|
|
1862
|
-
string = StackTrace.ErrorStackParser.concatErrorDescriptionAndIssueSummary(string, issueSummary);
|
|
1863
|
-
}
|
|
1864
|
-
|
|
1865
|
-
const linkInfos = StackTrace.ErrorStackParser.parseSourcePositionsFromErrorStack(runtimeModel, string);
|
|
1866
|
-
if (!linkInfos?.length) {
|
|
1867
|
-
return null;
|
|
1868
|
-
}
|
|
1869
|
-
if (exceptionDetails?.stackTrace) {
|
|
1870
|
-
StackTrace.ErrorStackParser.augmentErrorStackWithScriptIds(linkInfos, exceptionDetails.stackTrace);
|
|
1871
|
-
}
|
|
1872
|
-
|
|
1873
|
-
const debuggerModel = runtimeModel.debuggerModel();
|
|
1874
|
-
const formattedResult = document.createElement('span');
|
|
1875
|
-
|
|
1876
|
-
for (let i = 0; i < linkInfos.length; ++i) {
|
|
1877
|
-
const newline = i < linkInfos.length - 1 ? '\n' : '';
|
|
1878
|
-
const {line, link, isCallFrame} = linkInfos[i];
|
|
1879
|
-
// Syntax errors don't have a stack frame that points to the source position
|
|
1880
|
-
// where the error occurred. We use the source location from the
|
|
1881
|
-
// exceptionDetails and append it to the end of the message instead.
|
|
1882
|
-
if (!link && exceptionDetails && line.startsWith('SyntaxError')) {
|
|
1883
|
-
appendOrShow(formattedResult, this.linkifyStringAsFragment(line));
|
|
1884
|
-
const maybeScriptLocation = this.createScriptLocationLinkForSyntaxError(debuggerModel, exceptionDetails);
|
|
1885
|
-
if (maybeScriptLocation) {
|
|
1886
|
-
formattedResult.append(' (at ');
|
|
1887
|
-
formattedResult.appendChild(maybeScriptLocation);
|
|
1888
|
-
formattedResult.append(')');
|
|
1889
|
-
}
|
|
1890
|
-
formattedResult.append(newline);
|
|
1891
|
-
continue;
|
|
1892
|
-
}
|
|
1893
|
-
if (!isCallFrame) {
|
|
1894
|
-
appendOrShow(formattedResult, this.linkifyStringAsFragment(`${line}${newline}`));
|
|
1895
|
-
continue;
|
|
1896
|
-
}
|
|
1897
|
-
const formattedLine = document.createElement('span');
|
|
1898
|
-
if (!link) {
|
|
1899
|
-
appendOrShow(formattedLine, this.linkifyStringAsFragment(`${line}${newline}`));
|
|
1900
|
-
formattedLine.classList.add('formatted-builtin-stack-frame');
|
|
1901
|
-
formattedResult.appendChild(formattedLine);
|
|
1902
|
-
continue;
|
|
1903
|
-
}
|
|
1904
|
-
const suffix = `${link.suffix}${newline}`;
|
|
1905
|
-
appendOrShow(formattedLine, this.linkifyStringAsFragment(link.prefix));
|
|
1906
|
-
const scriptLocationLink = this.linkifier.linkifyScriptLocation(
|
|
1907
|
-
debuggerModel.target(), link.scriptId || null, link.url, link.lineNumber, {
|
|
1908
|
-
columnNumber: link.columnNumber,
|
|
1909
|
-
inlineFrameIndex: 0,
|
|
1910
|
-
showColumnNumber: true,
|
|
1911
|
-
});
|
|
1912
|
-
scriptLocationLink.tabIndex = -1;
|
|
1913
|
-
this.selectableChildren.push({element: scriptLocationLink, forceSelect: () => scriptLocationLink.focus()});
|
|
1914
|
-
formattedLine.appendChild(scriptLocationLink);
|
|
1915
|
-
appendOrShow(formattedLine, this.linkifyStringAsFragment(suffix));
|
|
1916
|
-
formattedLine.classList.add('formatted-stack-frame');
|
|
1917
|
-
formattedResult.appendChild(formattedLine);
|
|
1918
|
-
|
|
1919
|
-
if (!link.enclosedInBraces) {
|
|
1920
|
-
continue;
|
|
1921
|
-
}
|
|
1922
|
-
|
|
1923
|
-
const prefixWithoutFunction = link.prefix.substring(0, link.prefix.lastIndexOf(' ', link.prefix.length - 3));
|
|
1924
|
-
|
|
1925
|
-
// If we were able to parse the function name from the stack trace line, try to replace it with an expansion of
|
|
1926
|
-
// any inline frames.
|
|
1927
|
-
const selectableChildIndex = this.selectableChildren.length - 1;
|
|
1928
|
-
void this
|
|
1929
|
-
.expandInlineStackFrames(
|
|
1930
|
-
debuggerModel, prefixWithoutFunction, suffix, link.url, link.lineNumber, link.columnNumber,
|
|
1931
|
-
formattedResult, formattedLine)
|
|
1932
|
-
.then(modified => {
|
|
1933
|
-
if (modified) {
|
|
1934
|
-
formattedResult.removeChild(formattedLine);
|
|
1935
|
-
this.selectableChildren.splice(selectableChildIndex, 1);
|
|
1936
|
-
}
|
|
1937
|
-
});
|
|
1938
|
-
}
|
|
1939
|
-
|
|
1940
|
-
return formattedResult;
|
|
1941
|
-
}
|
|
1942
|
-
|
|
1943
1776
|
static linkifyWithCustomLinkifier(
|
|
1944
1777
|
string: string,
|
|
1945
1778
|
linkifier: (arg0: string, arg1: Platform.DevToolsPath.UrlString, arg2?: number, arg3?: number) => Node):
|
|
@@ -122,7 +122,6 @@ const DEFAULT_VIEW = (input: ViewInput, _output: object, target: HTMLElement): v
|
|
|
122
122
|
|
|
123
123
|
const linkOptions: Components.Linkifier.LinkifyOptions = {
|
|
124
124
|
showColumnNumber: true,
|
|
125
|
-
inlineFrameIndex: 0,
|
|
126
125
|
maxLength: UI.UIUtils.MaxLengthForDisplayedURLsInConsole,
|
|
127
126
|
ignoreListManager: input.ignoreListManager,
|
|
128
127
|
};
|
|
@@ -171,6 +170,10 @@ export class SymbolizedErrorWidget extends UI.Widget.Widget {
|
|
|
171
170
|
this.#view = view;
|
|
172
171
|
}
|
|
173
172
|
|
|
173
|
+
get linkElements(): readonly HTMLElement[] {
|
|
174
|
+
return [...this.contentElement.querySelectorAll<HTMLElement>('.devtools-link')];
|
|
175
|
+
}
|
|
176
|
+
|
|
174
177
|
set ignoreListManager(ignoreListManager: Workspace.IgnoreListManager.IgnoreListManager) {
|
|
175
178
|
this.#ignoreListManager = ignoreListManager;
|
|
176
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);
|