chrome-devtools-frontend 1.0.1643855 → 1.0.1646286
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/.agents/skills/devtools-source-maps/SKILL.md +124 -0
- package/docs/README.md +1 -0
- package/docs/using_source_maps.md +159 -0
- package/front_end/core/host/AidaClientTypes.ts +2 -0
- package/front_end/core/host/UserMetrics.ts +5 -3
- package/front_end/core/root/Runtime.ts +10 -0
- package/front_end/core/sdk/CSSPropertyParserMatchers.ts +2 -3
- package/front_end/core/sdk/DebuggerModel.ts +7 -9
- package/front_end/core/sdk/NetworkRequest.ts +0 -25
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +37 -0
- package/front_end/generated/InspectorBackendCommands.ts +2 -2
- package/front_end/generated/SupportedCSSProperties.js +79 -2
- package/front_end/generated/protocol.ts +0 -5
- package/front_end/models/ai_assistance/AiAgent2.ts +52 -15
- package/front_end/models/ai_assistance/AiConversation.ts +4 -2
- package/front_end/models/ai_assistance/AiOrigins.ts +63 -2
- package/front_end/models/ai_assistance/README.md +20 -8
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +2 -2
- package/front_end/models/ai_assistance/agents/FileAgent.ts +9 -42
- package/front_end/models/ai_assistance/agents/NetworkAgent.snapshot.txt +2 -2
- package/front_end/models/ai_assistance/agents/NetworkAgent.ts +9 -133
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +25 -2
- package/front_end/models/ai_assistance/agents/README.md +64 -0
- package/front_end/models/ai_assistance/agents/StylingAgent.ts +26 -3
- package/front_end/models/ai_assistance/ai_assistance.ts +4 -0
- package/front_end/models/ai_assistance/contexts/FileContext.ts +45 -0
- package/front_end/models/ai_assistance/contexts/RequestContext.snapshot.txt +48 -0
- package/front_end/models/ai_assistance/contexts/RequestContext.ts +116 -0
- package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +2 -1
- 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/NetworkRequestsHandler.ts +15 -11
- 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/models/web_mcp/WebMCPModel.ts +8 -48
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +21 -15
- package/front_end/panels/ai_assistance/ai_assistance-meta.ts +16 -0
- package/front_end/panels/ai_assistance/components/ChatInput.ts +4 -4
- package/front_end/panels/application/ApplicationPanelSidebar.ts +69 -0
- package/front_end/panels/application/ServiceWorkersView.ts +2 -2
- package/front_end/panels/application/WebMCPView.ts +40 -71
- package/front_end/panels/application/components/AdsView.ts +31 -28
- package/front_end/panels/application/components/BackForwardCacheView.ts +1 -2
- package/front_end/panels/application/components/adsView.css +6 -0
- package/front_end/panels/common/ExtensionServer.ts +5 -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 +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/profiler/IsolateSelector.ts +4 -2
- package/front_end/panels/profiler/ProfileLauncherView.ts +194 -126
- package/front_end/panels/profiler/ProfilesPanel.ts +1 -3
- 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 +6 -0
- package/package.json +1 -1
|
@@ -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);
|
|
@@ -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);
|
|
@@ -66,8 +66,10 @@ export class IsolateSelector extends UI.Widget.VBox implements UI.ListControl.Li
|
|
|
66
66
|
totalValueDiv: HTMLElement;
|
|
67
67
|
readonly totalTrendDiv: HTMLElement;
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
// `devtools-widget` passes its host element into widget constructors.
|
|
70
|
+
// Accept and forward it so this widget attaches to that host element.
|
|
71
|
+
constructor(element?: HTMLElement) {
|
|
72
|
+
super(element);
|
|
71
73
|
|
|
72
74
|
this.items = new UI.ListModel.ListModel();
|
|
73
75
|
this.list = new UI.ListControl.ListControl(this.items, this, UI.ListControl.ListMode.NonViewport);
|