chrome-devtools-frontend 1.0.1699061 → 1.0.1701636
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/front_end/core/root/Runtime.ts +5 -0
- package/front_end/core/sdk/CSSPropertyParserMatchers.ts +16 -11
- package/front_end/core/sdk/NetworkManager.ts +7 -0
- package/front_end/core/sdk/SecurityOrigin.ts +1 -0
- package/front_end/core/sdk/ServiceWorkerCacheModel.ts +3 -0
- package/front_end/core/sdk/SourceMap.ts +12 -1
- package/front_end/core/sdk/SourceMapCache.ts +12 -0
- package/front_end/core/sdk/SourceMapManager.ts +17 -8
- package/front_end/core/sdk/SourceMapScopeChainEntry.ts +2 -19
- package/front_end/core/sdk/SourceMapScopesInfo.ts +21 -0
- package/front_end/core/sdk/StorageBucketsModel.ts +2 -0
- package/front_end/entrypoints/formatter_worker/ScopeParser.ts +7 -3
- package/front_end/entrypoints/formatter_worker/Substitute.ts +90 -26
- package/front_end/entrypoints/formatter_worker/formatter_worker-entrypoint.ts +1 -1
- package/front_end/entrypoints/main/ExecutionContextSelector.ts +17 -4
- package/front_end/entrypoints/main/GlobalAiButton.ts +2 -6
- package/front_end/entrypoints/main/MainImpl.ts +8 -1
- package/front_end/generated/InspectorBackendCommands.ts +13 -5
- package/front_end/generated/SupportedCSSProperties.ts +14 -0
- package/front_end/generated/protocol-mapping.d.ts +48 -9
- package/front_end/generated/protocol-proxy-api.d.ts +37 -7
- package/front_end/generated/protocol.ts +135 -22
- package/front_end/models/ai_assistance/debug.ts +10 -2
- package/front_end/models/bindings/NetworkProject.ts +30 -0
- package/front_end/models/bindings/ResourceScriptMapping.ts +62 -0
- package/front_end/models/change_tracker/ChangeTracker.ts +1 -1
- package/front_end/models/comment_manager/CD4ABridge.ts +4 -4
- package/front_end/models/comment_manager/CommentManager.ts +21 -0
- package/front_end/models/extensions/ExtensionAPI.ts +4 -2
- package/front_end/models/formatter/FormatterWorkerPool.ts +2 -2
- package/front_end/models/issues_manager/CookieIssue.ts +0 -2
- package/front_end/models/javascript_metadata/NativeFunctions.ts +7 -2
- package/front_end/models/persistence/NetworkPersistenceManager.ts +29 -4
- package/front_end/models/source_map_scopes/NamesResolver.ts +65 -40
- package/front_end/models/source_map_scopes/ScopeChainModel.ts +21 -1
- package/front_end/panels/accessibility/AccessibilityAnnouncementRecordingView.ts +70 -1
- package/front_end/panels/ai_assistance/ai_assistance-meta.ts +5 -8
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +1 -1
- package/front_end/panels/application/AppManifestView.ts +128 -134
- package/front_end/panels/application/CrashReportContextView.ts +5 -5
- package/front_end/panels/application/DeviceBoundSessionsTreeElement.ts +17 -17
- package/front_end/panels/application/DeviceBoundSessionsView.ts +136 -137
- package/front_end/panels/application/IndexedDBModel.ts +3 -0
- package/front_end/panels/application/OriginTrialTreeView.ts +18 -23
- package/front_end/panels/application/ReportingApiTreeElement.ts +3 -3
- package/front_end/panels/application/ReportingApiView.ts +6 -14
- package/front_end/panels/application/application-meta.ts +7 -7
- package/front_end/panels/common/CommentThreadWidget.ts +19 -6
- package/front_end/panels/common/CommentsOverlayWidget.ts +143 -10
- package/front_end/panels/common/CommentsStatusBarPill.ts +13 -1
- package/front_end/panels/common/ExtensionServer.ts +61 -42
- package/front_end/panels/common/GeminiRebrandPromoDialog.ts +1 -1
- package/front_end/panels/common/commentThreadWidget.css +18 -0
- package/front_end/panels/common/common-meta.ts +4 -1
- package/front_end/panels/console/ConsolePrompt.ts +1 -1
- package/front_end/panels/console/ConsoleViewMessage.ts +1 -1
- package/front_end/panels/elements/ClassesPaneWidget.ts +2 -1
- package/front_end/panels/elements/DOMTreeContextMenu.ts +1 -1
- package/front_end/panels/elements/{ElementsTreeOutline.ts → DOMTreeWidget.ts} +45 -31
- package/front_end/panels/elements/ElementsPanel.ts +1 -1
- package/front_end/panels/elements/ElementsTreeElement.ts +3 -1
- package/front_end/panels/elements/ShortcutTreeElement.ts +1 -1
- package/front_end/panels/elements/StylePropertyTreeElement.ts +1 -1
- package/front_end/panels/elements/StylesSidebarPane.ts +4 -6
- package/front_end/panels/elements/TopLayerContainer.ts +1 -1
- package/front_end/panels/elements/elements.ts +4 -3
- package/front_end/panels/elements/elementsTreeOutline.css +4 -0
- package/front_end/panels/event_listeners/EventListenersView.ts +9 -4
- package/front_end/panels/issues/IssuesPane.ts +34 -22
- package/front_end/panels/network/RequestPayloadView.ts +17 -15
- package/front_end/panels/profiler/HeapDetachedElementsDataGrid.ts +1 -1
- package/front_end/panels/profiler/HeapProfileView.ts +8 -6
- package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +8 -1
- package/front_end/panels/profiler/HeapSnapshotView.ts +6 -4
- package/front_end/panels/recorder/RecordingView.ts +32 -53
- package/front_end/panels/recorder/controlButton.css +6 -0
- package/front_end/panels/recorder/recordingView.css +11 -2
- package/front_end/panels/security/SecurityPanel.ts +87 -99
- package/front_end/panels/sensors/SensorsView.ts +87 -0
- package/front_end/panels/sensors/sensors-meta.ts +69 -1
- package/front_end/panels/settings/keybindsSettingsTab.css +1 -1
- package/front_end/panels/sources/DebuggerPlugin.ts +136 -55
- package/front_end/panels/sources/ScopeChainSidebarPane.ts +17 -15
- package/front_end/panels/timeline/components/IgnoreListSetting.ts +0 -2
- package/front_end/panels/timeline/components/LiveMetricsView.ts +59 -64
- package/front_end/panels/timeline/components/liveMetricsView.css +1 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/lighthouse/README.chromium +2 -2
- package/front_end/third_party/lighthouse/lighthouse-dt-bundle.js +1580 -1524
- package/front_end/third_party/lighthouse/locales/ar-XB.json +111 -72
- package/front_end/third_party/lighthouse/locales/ar.json +113 -74
- package/front_end/third_party/lighthouse/locales/bg.json +112 -73
- package/front_end/third_party/lighthouse/locales/ca.json +112 -73
- package/front_end/third_party/lighthouse/locales/cs.json +112 -73
- package/front_end/third_party/lighthouse/locales/da.json +112 -73
- package/front_end/third_party/lighthouse/locales/de.json +112 -73
- package/front_end/third_party/lighthouse/locales/el.json +112 -73
- package/front_end/third_party/lighthouse/locales/en-GB.json +111 -72
- package/front_end/third_party/lighthouse/locales/en-US.json +102 -66
- package/front_end/third_party/lighthouse/locales/en-XA.json +111 -72
- package/front_end/third_party/lighthouse/locales/en-XL.json +102 -66
- package/front_end/third_party/lighthouse/locales/es-419.json +112 -73
- package/front_end/third_party/lighthouse/locales/es.json +112 -73
- package/front_end/third_party/lighthouse/locales/fi.json +112 -73
- package/front_end/third_party/lighthouse/locales/fil.json +112 -73
- package/front_end/third_party/lighthouse/locales/fr.json +112 -73
- package/front_end/third_party/lighthouse/locales/he.json +112 -73
- package/front_end/third_party/lighthouse/locales/hi.json +112 -73
- package/front_end/third_party/lighthouse/locales/hr.json +112 -73
- package/front_end/third_party/lighthouse/locales/hu.json +112 -73
- package/front_end/third_party/lighthouse/locales/id.json +112 -73
- package/front_end/third_party/lighthouse/locales/it.json +113 -74
- package/front_end/third_party/lighthouse/locales/ja.json +112 -73
- package/front_end/third_party/lighthouse/locales/ko.json +112 -73
- package/front_end/third_party/lighthouse/locales/lt.json +112 -73
- package/front_end/third_party/lighthouse/locales/lv.json +112 -73
- package/front_end/third_party/lighthouse/locales/nl.json +112 -73
- package/front_end/third_party/lighthouse/locales/no.json +112 -73
- package/front_end/third_party/lighthouse/locales/pl.json +112 -73
- package/front_end/third_party/lighthouse/locales/pt-PT.json +112 -73
- package/front_end/third_party/lighthouse/locales/pt.json +112 -73
- package/front_end/third_party/lighthouse/locales/ro.json +112 -73
- package/front_end/third_party/lighthouse/locales/ru.json +112 -73
- package/front_end/third_party/lighthouse/locales/sk.json +112 -73
- package/front_end/third_party/lighthouse/locales/sl.json +112 -73
- package/front_end/third_party/lighthouse/locales/sr-Latn.json +112 -73
- package/front_end/third_party/lighthouse/locales/sr.json +112 -73
- package/front_end/third_party/lighthouse/locales/sv.json +124 -85
- package/front_end/third_party/lighthouse/locales/ta.json +112 -73
- package/front_end/third_party/lighthouse/locales/te.json +112 -73
- package/front_end/third_party/lighthouse/locales/th.json +112 -73
- package/front_end/third_party/lighthouse/locales/tr.json +113 -74
- package/front_end/third_party/lighthouse/locales/uk.json +112 -73
- package/front_end/third_party/lighthouse/locales/vi.json +112 -73
- package/front_end/third_party/lighthouse/locales/zh-HK.json +112 -73
- package/front_end/third_party/lighthouse/locales/zh-TW.json +113 -74
- package/front_end/third_party/lighthouse/locales/zh.json +113 -74
- package/front_end/third_party/lighthouse/report/bundle.d.ts +4 -4
- package/front_end/third_party/lighthouse/report/bundle.js +10 -3
- package/front_end/third_party/lighthouse/report-assets/report-generator.mjs +2 -2
- package/front_end/third_party/lit/lit.ts +3 -0
- package/front_end/third_party/lit/package.json +3 -0
- package/front_end/third_party/lit/rebuild.sh +3 -2
- package/front_end/ui/comments/CommentAnchorResolver.ts +8 -2
- package/front_end/ui/comments/CommentOverlayManager.ts +2 -1
- package/front_end/ui/legacy/InspectorView.ts +4 -3
- package/front_end/ui/legacy/TabbedPane.ts +121 -80
- package/front_end/ui/legacy/Treeoutline.ts +37 -7
- package/front_end/ui/legacy/UIUtils.ts +7 -0
- package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +1 -1
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +135 -146
- package/front_end/ui/legacy/treeoutline.css +2 -2
- package/front_end/ui/lit/lit.ts +1 -1
- package/front_end/ui/visual_logging/KnownContextValues.ts +11 -0
- package/inspector_overlay/highlight_anchor.ts +197 -0
- package/inspector_overlay/tool_highlight.ts +8 -0
- package/package.json +1 -1
|
@@ -549,6 +549,10 @@ interface DevToolsNetworkBackendLinking {
|
|
|
549
549
|
enabled: boolean;
|
|
550
550
|
}
|
|
551
551
|
|
|
552
|
+
interface DevToolsAiNaturalLanguageInterface {
|
|
553
|
+
enabled: boolean;
|
|
554
|
+
}
|
|
555
|
+
|
|
552
556
|
/**
|
|
553
557
|
* The host configuration that we expect from the DevTools back-end.
|
|
554
558
|
*
|
|
@@ -579,6 +583,7 @@ export type HostConfig = Platform.TypeScriptUtilities.RecursivePartial<{
|
|
|
579
583
|
devToolsAiCodeGeneration: HostConfigAiCodeGeneration,
|
|
580
584
|
devToolsAiCodeCompletionStyles: HostConfigAiCodeCompletionStyles,
|
|
581
585
|
devToolsVeLogging: HostConfigVeLogging,
|
|
586
|
+
devToolsAiNaturalLanguageInterface: DevToolsAiNaturalLanguageInterface,
|
|
582
587
|
/**
|
|
583
588
|
* OffTheRecord here indicates that the user's profile is either incognito,
|
|
584
589
|
* or guest mode, rather than a "normal" profile.
|
|
@@ -56,6 +56,15 @@ export class BaseVariableMatch implements Match {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
// TODO(b/533783988): Remove ValueName handling once https://code.haverbeke.berlin/lezer/css/issues/36 is fixed and rolled.
|
|
60
|
+
function isVariableNameNode(node: CodeMirror.SyntaxNode|null|undefined, ast: SyntaxTree): boolean {
|
|
61
|
+
if (node?.name !== 'VariableName' && node?.name !== 'ValueName') {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
const text = ast.text(node);
|
|
65
|
+
return text.length > 2 && text.startsWith('--');
|
|
66
|
+
}
|
|
67
|
+
|
|
59
68
|
const BaseVariableMatcherBase: MatcherClass<BaseVariableMatch> = matcherBase(BaseVariableMatch);
|
|
60
69
|
// This matcher provides matching for var() functions and basic computedText support. Computed text is resolved by a
|
|
61
70
|
// callback. This matcher is intended to be used directly only in environments where CSSMatchedStyles is not available.
|
|
@@ -83,15 +92,11 @@ export class BaseVariableMatcher extends BaseVariableMatcherBase {
|
|
|
83
92
|
const nameNode = args[0][0];
|
|
84
93
|
const fallback = args.length === 2 ? args[1] : undefined;
|
|
85
94
|
|
|
86
|
-
if (nameNode
|
|
95
|
+
if (!isVariableNameNode(nameNode, matching.ast)) {
|
|
87
96
|
return null;
|
|
88
97
|
}
|
|
89
98
|
|
|
90
99
|
const varName = matching.ast.text(nameNode);
|
|
91
|
-
if (!varName.startsWith('--')) {
|
|
92
|
-
return null;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
100
|
return new BaseVariableMatch(
|
|
96
101
|
matching.ast.text(node), node, varName, fallback, matching, this.#computedTextCallback);
|
|
97
102
|
}
|
|
@@ -903,7 +908,7 @@ export class LinkableNameMatcher extends LinkableNameMatcherBase {
|
|
|
903
908
|
propertyName === LinkableNameProperties.POSITION_TRY_FALLBACKS;
|
|
904
909
|
// We only mark top level nodes or nodes that are inside `var()` expressions as linkable names.
|
|
905
910
|
if (!propertyName || (node.name !== 'ValueName' && node.name !== 'VariableName') ||
|
|
906
|
-
!isAParentDeclarationOrVarCall || (
|
|
911
|
+
!isAParentDeclarationOrVarCall || (shouldMatchOnlyVariableName && !isVariableNameNode(node, matching.ast))) {
|
|
907
912
|
return null;
|
|
908
913
|
}
|
|
909
914
|
|
|
@@ -1117,8 +1122,8 @@ export class CustomFunctionMatcher extends CustomFunctionMatcherBase {
|
|
|
1117
1122
|
if (node.name !== 'CallExpression') {
|
|
1118
1123
|
return null;
|
|
1119
1124
|
}
|
|
1120
|
-
const callee = matching.ast.text(node.getChild('VariableName'));
|
|
1121
|
-
if (!callee
|
|
1125
|
+
const callee = matching.ast.text(node.getChild('VariableName') ?? node.getChild('Callee'));
|
|
1126
|
+
if (!callee || callee.length <= 2 || !callee.startsWith('--')) {
|
|
1122
1127
|
return null;
|
|
1123
1128
|
}
|
|
1124
1129
|
const args = ASTUtils.callArgs(node);
|
|
@@ -1295,7 +1300,7 @@ export class AnchorFunctionMatcher extends AnchorFunctionMatcherBase {
|
|
|
1295
1300
|
}
|
|
1296
1301
|
|
|
1297
1302
|
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): AnchorFunctionMatch|null {
|
|
1298
|
-
if (node.
|
|
1303
|
+
if (isVariableNameNode(node, matching.ast)) {
|
|
1299
1304
|
// Double-dashed anchor reference to be rendered with a link to its matching anchor.
|
|
1300
1305
|
let parent = node.parent;
|
|
1301
1306
|
if (parent?.name !== 'ArgList') {
|
|
@@ -1316,7 +1321,7 @@ export class AnchorFunctionMatcher extends AnchorFunctionMatcherBase {
|
|
|
1316
1321
|
if (calleeText === 'anchor' && args.length <= 2) {
|
|
1317
1322
|
return null;
|
|
1318
1323
|
}
|
|
1319
|
-
if (args.find(arg => arg.
|
|
1324
|
+
if (args.find(arg => isVariableNameNode(arg, matching.ast))) {
|
|
1320
1325
|
// We have an explicit anchor reference, no need to render swatch.
|
|
1321
1326
|
return null;
|
|
1322
1327
|
}
|
|
@@ -1339,7 +1344,7 @@ export class PositionAnchorMatcher extends PositionAnchorMatcherBase {
|
|
|
1339
1344
|
}
|
|
1340
1345
|
|
|
1341
1346
|
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): PositionAnchorMatch|null {
|
|
1342
|
-
if (node.
|
|
1347
|
+
if (!isVariableNameNode(node, matching.ast)) {
|
|
1343
1348
|
return null;
|
|
1344
1349
|
}
|
|
1345
1350
|
|
|
@@ -2629,6 +2629,13 @@ export class InterceptedRequest {
|
|
|
2629
2629
|
this.networkRequest.setCookieHeaders =
|
|
2630
2630
|
InterceptedRequest.mergeSetCookieHeaders(originalSetCookieHeaders, setCookieHeadersFromOverrides);
|
|
2631
2631
|
this.networkRequest.hasOverriddenContent = isBodyOverridden;
|
|
2632
|
+
if (isBodyOverridden) {
|
|
2633
|
+
this.networkRequest.setContentDataProvider(async () => {
|
|
2634
|
+
const {mimeType, charset} = this.getMimeTypeAndCharset();
|
|
2635
|
+
return new TextUtils.ContentData.ContentData(body, /* isBase64= */ true,
|
|
2636
|
+
mimeType ?? 'application/octet-stream', charset ?? undefined);
|
|
2637
|
+
});
|
|
2638
|
+
}
|
|
2632
2639
|
}
|
|
2633
2640
|
|
|
2634
2641
|
void this.#fetchAgent.invoke_fulfillRequest({requestId: this.requestId, responseCode, body, responseHeaders});
|
|
@@ -279,6 +279,9 @@ export class ServiceWorkerCacheModel extends SDKModel<EventTypes> implements Pro
|
|
|
279
279
|
storageBucketDeleted(_event: Protocol.Storage.StorageBucketDeletedEvent): void {
|
|
280
280
|
}
|
|
281
281
|
|
|
282
|
+
privateVerificationTokensUpdated(): void {
|
|
283
|
+
}
|
|
284
|
+
|
|
282
285
|
setThrottlerSchedulesAsSoonAsPossibleForTest(): void {
|
|
283
286
|
this.#scheduleAsSoonAsPossible = true;
|
|
284
287
|
}
|
|
@@ -7,7 +7,7 @@ import * as Common from '../common/common.js';
|
|
|
7
7
|
import * as Platform from '../platform/platform.js';
|
|
8
8
|
import * as TextUtils from '../text_utils/text_utils.js';
|
|
9
9
|
|
|
10
|
-
import type {CallFrame, ScopeChainEntry} from './DebuggerModel.js';
|
|
10
|
+
import type {CallFrame, Location, ScopeChainEntry} from './DebuggerModel.js';
|
|
11
11
|
import {scopeTreeForScript} from './ScopeTreeCache.js';
|
|
12
12
|
import type {Script} from './Script.js';
|
|
13
13
|
import {buildOriginalScopes, decodePastaRanges, type NamedFunctionRange} from './SourceMapFunctionRanges.js';
|
|
@@ -843,6 +843,17 @@ export class SourceMap {
|
|
|
843
843
|
return this.#scopesInfo.resolveMappedScopeChain(frame);
|
|
844
844
|
}
|
|
845
845
|
|
|
846
|
+
resolveMappedVariablesAtPosition(location: Location,
|
|
847
|
+
ignoreInnerBlockScopes = false): Array<Map<string, string|null>>|null {
|
|
848
|
+
this.#ensureSourceMapProcessed();
|
|
849
|
+
if (this.#provenance === SourceMapProvenance.USER || !this.#scopesInfo?.hasVariablesAndBindings()) {
|
|
850
|
+
return null;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
return this.#scopesInfo.resolveMappedVariablesAtPosition(location.lineNumber, location.columnNumber,
|
|
854
|
+
ignoreInnerBlockScopes);
|
|
855
|
+
}
|
|
856
|
+
|
|
846
857
|
findOriginalFunctionName(position: ScopesCodec.Position): string|null {
|
|
847
858
|
this.#ensureSourceMapProcessed();
|
|
848
859
|
return this.#scopesInfo?.findOriginalFunctionName(position) ?? null;
|
|
@@ -28,11 +28,17 @@ export class SourceMapCache {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
async set(debugId: DebugId, securityOrigin: Platform.DevToolsPath.UrlString, sourceMap: SourceMapV3): Promise<void> {
|
|
31
|
+
if (!securityOrigin || securityOrigin === 'file://') {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
31
34
|
const cache = await this.#cache();
|
|
32
35
|
await cache?.put(SourceMapCache.#urlForDebugId(debugId, securityOrigin), new Response(JSON.stringify(sourceMap)));
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
async get(debugId: DebugId, securityOrigin: Platform.DevToolsPath.UrlString): Promise<SourceMapV3|null> {
|
|
39
|
+
if (!securityOrigin || securityOrigin === 'file://') {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
36
42
|
const cache = await this.#cache();
|
|
37
43
|
const response = await cache?.match(SourceMapCache.#urlForDebugId(debugId, securityOrigin));
|
|
38
44
|
return (await response?.json() as SourceMapV3 | undefined) ?? null;
|
|
@@ -65,10 +71,16 @@ const IN_MEMORY_INSTANCE = new (class implements Pick<SourceMapCache, 'get'|'set
|
|
|
65
71
|
readonly #cache = new Map<string, SourceMapV3>();
|
|
66
72
|
|
|
67
73
|
async set(debugId: DebugId, securityOrigin: Platform.DevToolsPath.UrlString, sourceMap: SourceMapV3): Promise<void> {
|
|
74
|
+
if (!securityOrigin || securityOrigin === 'file://') {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
68
77
|
this.#cache.set(`${debugId}|${securityOrigin}`, sourceMap);
|
|
69
78
|
}
|
|
70
79
|
|
|
71
80
|
async get(debugId: DebugId, securityOrigin: Platform.DevToolsPath.UrlString): Promise<SourceMapV3|null> {
|
|
81
|
+
if (!securityOrigin || securityOrigin === 'file://') {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
72
84
|
return this.#cache.get(`${debugId}|${securityOrigin}`) ?? null;
|
|
73
85
|
}
|
|
74
86
|
|
|
@@ -7,6 +7,7 @@ import * as Platform from '../platform/platform.js';
|
|
|
7
7
|
|
|
8
8
|
import type {FrameAssociated} from './FrameAssociated.js';
|
|
9
9
|
import {PageResourceLoader, type PageResourceLoadInitiator, type ResourceLoader} from './PageResourceLoader.js';
|
|
10
|
+
import {SecurityOrigin} from './SecurityOrigin.js';
|
|
10
11
|
import {type DebugId, parseSourceMap, SourceMap, type SourceMapProvenance, type SourceMapV3} from './SourceMap.js';
|
|
11
12
|
import {SourceMapCache} from './SourceMapCache.js';
|
|
12
13
|
import {type Target, Type} from './Target.js';
|
|
@@ -215,14 +216,24 @@ export class SourceMapManager<T extends FrameAssociated> extends Common.ObjectWr
|
|
|
215
216
|
}
|
|
216
217
|
}
|
|
217
218
|
|
|
219
|
+
function getCacheOrigin(initiator: PageResourceLoadInitiator): Platform.DevToolsPath.UrlString|null {
|
|
220
|
+
if (!initiator.initiatorUrl) {
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
const securityOrigin = SecurityOrigin.create(initiator.initiatorUrl);
|
|
224
|
+
if (securityOrigin.isOpaque() || (securityOrigin.isFile() && securityOrigin.siteId() === 'file:///')) {
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
return securityOrigin.siteId() as Platform.DevToolsPath.UrlString;
|
|
228
|
+
}
|
|
229
|
+
|
|
218
230
|
async function loadSourceMap(resourceLoader: ResourceLoader, sourceMapCache: SourceMapCache,
|
|
219
231
|
url: Platform.DevToolsPath.UrlString, debugId: DebugId|null,
|
|
220
232
|
initiator: PageResourceLoadInitiator): Promise<SourceMapV3> {
|
|
221
233
|
try {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
const cachedSourceMap = await sourceMapCache.get(debugId, securityOrigin);
|
|
234
|
+
const cacheOrigin = debugId ? getCacheOrigin(initiator) : null;
|
|
235
|
+
if (debugId && cacheOrigin) {
|
|
236
|
+
const cachedSourceMap = await sourceMapCache.get(debugId, cacheOrigin);
|
|
226
237
|
if (cachedSourceMap) {
|
|
227
238
|
return cachedSourceMap;
|
|
228
239
|
}
|
|
@@ -230,11 +241,9 @@ async function loadSourceMap(resourceLoader: ResourceLoader, sourceMapCache: Sou
|
|
|
230
241
|
|
|
231
242
|
const {content} = await resourceLoader.loadResource(url, initiator);
|
|
232
243
|
const sourceMap = parseSourceMap(content);
|
|
233
|
-
if (debugId && 'debugId' in sourceMap && sourceMap.debugId === debugId) {
|
|
244
|
+
if (debugId && cacheOrigin && 'debugId' in sourceMap && sourceMap.debugId === debugId) {
|
|
234
245
|
// In case something goes wrong with updating the cache, we still want to use the source map.
|
|
235
|
-
|
|
236
|
-
Platform.DevToolsPath.EmptyUrlString;
|
|
237
|
-
await sourceMapCache.set(sourceMap.debugId as DebugId, securityOrigin, sourceMap).catch();
|
|
246
|
+
await sourceMapCache.set(sourceMap.debugId as DebugId, cacheOrigin, sourceMap).catch();
|
|
238
247
|
}
|
|
239
248
|
return sourceMap;
|
|
240
249
|
} catch (cause) {
|
|
@@ -8,7 +8,7 @@ import * as i18n from '../i18n/i18n.js';
|
|
|
8
8
|
|
|
9
9
|
import type {CallFrame, LocationRange, ScopeChainEntry} from './DebuggerModel.js';
|
|
10
10
|
import {type GetPropertiesResult, type RemoteObject, RemoteObjectImpl, RemoteObjectProperty} from './RemoteObject.js';
|
|
11
|
-
import {
|
|
11
|
+
import {findExpression} from './SourceMapScopesInfo.js';
|
|
12
12
|
|
|
13
13
|
const UIStrings = {
|
|
14
14
|
/**
|
|
@@ -263,25 +263,8 @@ class SourceMapScopeRemoteObject extends RemoteObjectImpl {
|
|
|
263
263
|
|
|
264
264
|
/** @returns null if the variable is unavailable at the current paused location */
|
|
265
265
|
#findExpression(index: number): string|null {
|
|
266
|
-
if (!this.#range) {
|
|
267
|
-
return null;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
const expressionOrSubRanges = this.#range.values[index];
|
|
271
|
-
if (typeof expressionOrSubRanges === 'string') {
|
|
272
|
-
return expressionOrSubRanges;
|
|
273
|
-
}
|
|
274
|
-
if (!expressionOrSubRanges) {
|
|
275
|
-
return null;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
266
|
const pausedPosition = this.#callFrame.location();
|
|
279
|
-
|
|
280
|
-
if (contains({start: range.from, end: range.to}, pausedPosition.lineNumber, pausedPosition.columnNumber)) {
|
|
281
|
-
return range.value ?? null;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
return null;
|
|
267
|
+
return findExpression(this.#range, index, pausedPosition?.lineNumber, pausedPosition?.columnNumber);
|
|
285
268
|
}
|
|
286
269
|
|
|
287
270
|
static #unavailableProperty(name: string): RemoteObjectProperty {
|
|
@@ -406,6 +406,20 @@ export class SourceMapScopesInfo {
|
|
|
406
406
|
return rangeChain;
|
|
407
407
|
}
|
|
408
408
|
|
|
409
|
+
resolveMappedVariablesAtPosition(line: number, column: number,
|
|
410
|
+
ignoreInnerBlockScopes = false): Array<Map<string, string|null>>|null {
|
|
411
|
+
const rangeChain = this.#findGeneratedRangeChain(line, column);
|
|
412
|
+
const startScope = rangeChain.at(-1)?.originalScope;
|
|
413
|
+
const innerMostScope =
|
|
414
|
+
(startScope && ignoreInnerBlockScopes && this.#findFunctionScopeInOriginalScopeChain(startScope)) || startScope;
|
|
415
|
+
const result: Array<Map<string, string|null>> = [];
|
|
416
|
+
for (let scope = innerMostScope; scope; scope = scope.parent) {
|
|
417
|
+
const range = rangeChain.findLast(r => r.originalScope === scope);
|
|
418
|
+
result.push(new Map(scope.variables.map((v, i) => [v, findExpression(range, i, line, column)])));
|
|
419
|
+
}
|
|
420
|
+
return innerMostScope ? result : null;
|
|
421
|
+
}
|
|
422
|
+
|
|
409
423
|
/**
|
|
410
424
|
* Returns the authored function name of the function containing the provided generated position.
|
|
411
425
|
*/
|
|
@@ -570,6 +584,13 @@ export interface TranslatedFrame {
|
|
|
570
584
|
url?: Platform.DevToolsPath.UrlString;
|
|
571
585
|
}
|
|
572
586
|
|
|
587
|
+
export function findExpression(range: ScopesCodec.GeneratedRange|undefined, index: number, line = 0,
|
|
588
|
+
column = 0): string|null {
|
|
589
|
+
const val = range?.values[index];
|
|
590
|
+
return (typeof val === 'string' ? val : val?.find(r => contains({start: r.from, end: r.to}, line, column))?.value) ??
|
|
591
|
+
null;
|
|
592
|
+
}
|
|
593
|
+
|
|
573
594
|
export function contains(
|
|
574
595
|
range: Pick<ScopesCodec.GeneratedRange, 'start'|'end'>, line: number, column: number): boolean {
|
|
575
596
|
if (range.start.line > line || (range.start.line === line && range.start.column > column)) {
|
|
@@ -154,6 +154,8 @@ export class StorageBucketsModel extends SDKModel<EventTypes> implements Protoco
|
|
|
154
154
|
cacheStorageContentUpdated(_event: Protocol.Storage.CacheStorageContentUpdatedEvent): void {
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
privateVerificationTokensUpdated(): void {
|
|
158
|
+
}
|
|
157
159
|
}
|
|
158
160
|
|
|
159
161
|
SDKModel.register(StorageBucketsModel, {capabilities: Capability.STORAGE, autostart: false});
|
|
@@ -11,9 +11,13 @@ export function parseScopes(expression: string, sourceType: 'module'|'script' =
|
|
|
11
11
|
// Parse the expression and find variables and scopes.
|
|
12
12
|
let root: Acorn.ESTree.Node|null = null;
|
|
13
13
|
try {
|
|
14
|
-
root = Acorn.parse(
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
root = Acorn.parse(expression, {
|
|
15
|
+
ecmaVersion: ECMA_VERSION,
|
|
16
|
+
allowAwaitOutsideFunction: true,
|
|
17
|
+
checkPrivateFields: false,
|
|
18
|
+
ranges: false,
|
|
19
|
+
sourceType,
|
|
20
|
+
}) as Acorn.ESTree.Node;
|
|
17
21
|
} catch {
|
|
18
22
|
return null;
|
|
19
23
|
}
|
|
@@ -6,10 +6,10 @@ import * as Acorn from '../../third_party/acorn/acorn.js';
|
|
|
6
6
|
import {DefinitionKind} from '../formatter_actions/formatter_actions.js';
|
|
7
7
|
|
|
8
8
|
import {ECMA_VERSION} from './AcornTokenizer.js';
|
|
9
|
-
import {ScopeVariableAnalysis} from './ScopeParser.js';
|
|
9
|
+
import {ScopeVariableAnalysis, type VariableUses} from './ScopeParser.js';
|
|
10
10
|
|
|
11
|
-
export function substituteExpression(expression: string,
|
|
12
|
-
const replacements = computeSubstitution(expression,
|
|
11
|
+
export function substituteExpression(expression: string, nameMaps: Array<Map<string, string|null>>): string {
|
|
12
|
+
const replacements = computeSubstitution(expression, nameMaps);
|
|
13
13
|
return applySubstitution(expression, replacements);
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -20,13 +20,44 @@ interface Replacement {
|
|
|
20
20
|
isShorthandAssignmentProperty: boolean;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
function parseBindingExpression(expression: string): {
|
|
24
|
+
replacement: string,
|
|
25
|
+
freeVariables: string[],
|
|
26
|
+
allNames: Set<string>,
|
|
27
|
+
} {
|
|
28
|
+
const options = {
|
|
29
|
+
ecmaVersion: ECMA_VERSION,
|
|
30
|
+
allowAwaitOutsideFunction: true,
|
|
31
|
+
allowImportExportEverywhere: true,
|
|
32
|
+
checkPrivateFields: false,
|
|
33
|
+
ranges: false,
|
|
34
|
+
} as const;
|
|
35
|
+
const root = Acorn.parse(`(${expression})`, options);
|
|
36
|
+
const exprAt = Acorn.Parser.parseExpressionAt(expression, 0, options);
|
|
37
|
+
if (root.body.length !== 1 || root.body[0].type !== 'ExpressionStatement') {
|
|
38
|
+
throw new SyntaxError(`Invalid binding expression '${expression}'`);
|
|
39
|
+
}
|
|
40
|
+
const expr = root.body[0].expression;
|
|
41
|
+
if (exprAt.start !== expr.start - 1 || exprAt.end !== expr.end - 1) {
|
|
42
|
+
throw new SyntaxError(`Invalid binding expression '${expression}'`);
|
|
43
|
+
}
|
|
44
|
+
const analysis = new ScopeVariableAnalysis(root as Acorn.ESTree.Node, `(${expression})`);
|
|
45
|
+
analysis.run();
|
|
46
|
+
const needsParens = expr.type !== 'Identifier' && expr.type !== 'MemberExpression' && expr.type !== 'ThisExpression';
|
|
47
|
+
return {
|
|
48
|
+
replacement: needsParens ? `(${expression})` : expression,
|
|
49
|
+
freeVariables: [...analysis.getFreeVariables().keys()],
|
|
50
|
+
allNames: analysis.getAllNames(),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
23
54
|
/**
|
|
24
55
|
* Given an |expression| and a mapping from names to new names, the |computeSubstitution|
|
|
25
56
|
* function returns a list of replacements sorted by the offset. The function throws if
|
|
26
57
|
* it cannot parse the expression or the substitution is impossible to perform (for example
|
|
27
58
|
* if the substitution target is 'this' within a function, it would become bound there).
|
|
28
59
|
**/
|
|
29
|
-
function computeSubstitution(expression: string,
|
|
60
|
+
function computeSubstitution(expression: string, nameMaps: Array<Map<string, string|null>>): Replacement[] {
|
|
30
61
|
// Parse the expression and find variables and scopes.
|
|
31
62
|
const root = Acorn.parse(expression, {
|
|
32
63
|
ecmaVersion: ECMA_VERSION,
|
|
@@ -42,10 +73,33 @@ function computeSubstitution(expression: string, nameMap: Map<string, string|nul
|
|
|
42
73
|
|
|
43
74
|
// Prepare the machinery for generating fresh names (to avoid variable captures).
|
|
44
75
|
const allNames = scopeVariables.getAllNames();
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
76
|
+
const nameMap = new Map<string, string|null>();
|
|
77
|
+
const parsedBindings = new Map<string, ReturnType<typeof parseBindingExpression>>();
|
|
78
|
+
const shadowedNames = new Set<string>();
|
|
79
|
+
for (const scopeMap of nameMaps) {
|
|
80
|
+
const scopeNames = new Set<string>();
|
|
81
|
+
for (const [name, rename] of scopeMap.entries()) {
|
|
82
|
+
let parsed: ReturnType<typeof parseBindingExpression>|undefined;
|
|
83
|
+
if (rename !== null) {
|
|
84
|
+
try {
|
|
85
|
+
parsed = parseBindingExpression(rename);
|
|
86
|
+
parsed.allNames.forEach(id => allNames.add(id));
|
|
87
|
+
parsed.freeVariables.forEach(id => scopeNames.add(id));
|
|
88
|
+
} catch (error) {
|
|
89
|
+
if (!nameMap.has(name) && freeVariables.has(name)) {
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (!nameMap.has(name)) {
|
|
95
|
+
const isShadowed = parsed?.freeVariables.some(id => shadowedNames.has(id));
|
|
96
|
+
nameMap.set(name, isShadowed ? null : rename);
|
|
97
|
+
if (parsed && !isShadowed) {
|
|
98
|
+
parsedBindings.set(name, parsed);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
48
101
|
}
|
|
102
|
+
scopeNames.forEach(id => shadowedNames.add(id));
|
|
49
103
|
}
|
|
50
104
|
function getNewName(base: string): string {
|
|
51
105
|
let i = 1;
|
|
@@ -58,6 +112,7 @@ function computeSubstitution(expression: string, nameMap: Map<string, string|nul
|
|
|
58
112
|
}
|
|
59
113
|
|
|
60
114
|
// Perform the substitutions.
|
|
115
|
+
const capturedBinders = new Map<VariableUses, string>();
|
|
61
116
|
for (const [name, rename] of nameMap.entries()) {
|
|
62
117
|
const defUse = freeVariables.get(name);
|
|
63
118
|
if (!defUse) {
|
|
@@ -68,34 +123,43 @@ function computeSubstitution(expression: string, nameMap: Map<string, string|nul
|
|
|
68
123
|
throw new Error(`Cannot substitute '${name}' as the underlying variable '${rename}' is unavailable`);
|
|
69
124
|
}
|
|
70
125
|
|
|
71
|
-
const
|
|
126
|
+
const parsed = parsedBindings.get(name);
|
|
127
|
+
if (!parsed) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
const freeIds = [...parsed.freeVariables];
|
|
72
131
|
for (const use of defUse) {
|
|
73
132
|
result.push({
|
|
74
133
|
from: name,
|
|
75
|
-
to:
|
|
134
|
+
to: parsed.replacement,
|
|
76
135
|
offset: use.offset,
|
|
77
136
|
isShorthandAssignmentProperty: use.isShorthandAssignmentProperty,
|
|
78
137
|
});
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (binder.definitionKind === DefinitionKind.FIXED) {
|
|
84
|
-
// If the identifier is bound to a fixed name, such as 'this',
|
|
85
|
-
// then refuse to do the substitution.
|
|
86
|
-
throw new Error(`Cannot avoid capture of '${rename}'`);
|
|
87
|
-
}
|
|
88
|
-
const newName = getNewName(rename);
|
|
89
|
-
for (const use of binder.uses) {
|
|
90
|
-
result.push({
|
|
91
|
-
from: rename,
|
|
92
|
-
to: newName,
|
|
93
|
-
offset: use.offset,
|
|
94
|
-
isShorthandAssignmentProperty: use.isShorthandAssignmentProperty,
|
|
95
|
-
});
|
|
138
|
+
for (const freeId of freeIds) {
|
|
139
|
+
for (const binder of use.scope.findBinders(freeId)) {
|
|
140
|
+
capturedBinders.set(binder, freeId);
|
|
141
|
+
}
|
|
96
142
|
}
|
|
97
143
|
}
|
|
98
144
|
}
|
|
145
|
+
|
|
146
|
+
// If there is a capturing binder, rename the bound variable.
|
|
147
|
+
for (const [binder, freeId] of capturedBinders.entries()) {
|
|
148
|
+
if (binder.definitionKind === DefinitionKind.FIXED) {
|
|
149
|
+
// If the identifier is bound to a fixed name, such as 'this',
|
|
150
|
+
// then refuse to do the substitution.
|
|
151
|
+
throw new Error(`Cannot avoid capture of '${freeId}'`);
|
|
152
|
+
}
|
|
153
|
+
const newName = getNewName(freeId);
|
|
154
|
+
for (const use of binder.uses) {
|
|
155
|
+
result.push({
|
|
156
|
+
from: freeId,
|
|
157
|
+
to: newName,
|
|
158
|
+
offset: use.offset,
|
|
159
|
+
isShorthandAssignmentProperty: use.isShorthandAssignmentProperty,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
99
163
|
result.sort((l, r) => l.offset - r.offset);
|
|
100
164
|
return result;
|
|
101
165
|
}
|
|
@@ -13,7 +13,7 @@ Platform.HostRuntime.HOST_RUNTIME.workerScope.onmessage = function(event): void
|
|
|
13
13
|
indentString: string,
|
|
14
14
|
content: string,
|
|
15
15
|
mimeType: string,
|
|
16
|
-
mapping: Map<string, string|null
|
|
16
|
+
mapping: Array<Map<string, string|null>>,
|
|
17
17
|
sourceType: 'module'|'script',
|
|
18
18
|
} = event.data.params;
|
|
19
19
|
if (!method) {
|
|
@@ -37,7 +37,7 @@ export class ExecutionContextSelector implements SDK.TargetManager.SDKModelObser
|
|
|
37
37
|
|
|
38
38
|
function deferred(this: ExecutionContextSelector): void {
|
|
39
39
|
// We always want the second context for the service worker targets.
|
|
40
|
-
if (!this.#context.flavor(SDK.Target.Target)) {
|
|
40
|
+
if (!this.#context.flavor(SDK.Target.Target) && !runtimeModel.target().targetInfo()?.subtype) {
|
|
41
41
|
this.#context.setFlavor(SDK.Target.Target, runtimeModel.target());
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -51,7 +51,8 @@ export class ExecutionContextSelector implements SDK.TargetManager.SDKModelObser
|
|
|
51
51
|
|
|
52
52
|
const models = this.#targetManager.models(SDK.RuntimeModel.RuntimeModel);
|
|
53
53
|
if (this.#context.flavor(SDK.Target.Target) === runtimeModel.target() && models.length) {
|
|
54
|
-
|
|
54
|
+
const nextModel = models.find(m => !m.target().targetInfo()?.subtype);
|
|
55
|
+
this.#context.setFlavor(SDK.Target.Target, nextModel ? nextModel.target() : null);
|
|
55
56
|
}
|
|
56
57
|
}
|
|
57
58
|
|
|
@@ -100,7 +101,8 @@ export class ExecutionContextSelector implements SDK.TargetManager.SDKModelObser
|
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
#shouldSwitchToContext(executionContext: SDK.RuntimeModel.ExecutionContext): boolean {
|
|
103
|
-
if (executionContext.target().targetInfo()?.subtype
|
|
104
|
+
if (executionContext.target().targetInfo()?.subtype &&
|
|
105
|
+
this.#context.flavor(SDK.Target.Target) !== executionContext.target()) {
|
|
104
106
|
return false;
|
|
105
107
|
}
|
|
106
108
|
if (this.#lastSelectedContextId && this.#lastSelectedContextId === this.#contextPersistentId(executionContext)) {
|
|
@@ -164,7 +166,10 @@ export class ExecutionContextSelector implements SDK.TargetManager.SDKModelObser
|
|
|
164
166
|
}
|
|
165
167
|
|
|
166
168
|
#switchContextIfNecessary(executionContext: SDK.RuntimeModel.ExecutionContext): boolean {
|
|
167
|
-
if (!this.#context.flavor(SDK.RuntimeModel.ExecutionContext)
|
|
169
|
+
if ((!this.#context.flavor(SDK.RuntimeModel.ExecutionContext) &&
|
|
170
|
+
(!executionContext.target().targetInfo()?.subtype ||
|
|
171
|
+
this.#context.flavor(SDK.Target.Target) === executionContext.target())) ||
|
|
172
|
+
this.#shouldSwitchToContext(executionContext)) {
|
|
168
173
|
this.#ignoreContextChanged = true;
|
|
169
174
|
this.#context.setFlavor(SDK.RuntimeModel.ExecutionContext, executionContext);
|
|
170
175
|
this.#ignoreContextChanged = false;
|
|
@@ -177,6 +182,10 @@ export class ExecutionContextSelector implements SDK.TargetManager.SDKModelObser
|
|
|
177
182
|
const runtimeModels = this.#targetManager.models(SDK.RuntimeModel.RuntimeModel);
|
|
178
183
|
let newContext: SDK.RuntimeModel.ExecutionContext|null = null;
|
|
179
184
|
for (let i = 0; i < runtimeModels.length && !newContext; ++i) {
|
|
185
|
+
if (runtimeModels[i].target().targetInfo()?.subtype &&
|
|
186
|
+
this.#context.flavor(SDK.Target.Target) !== runtimeModels[i].target()) {
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
180
189
|
const executionContexts = runtimeModels[i].executionContexts();
|
|
181
190
|
for (const executionContext of executionContexts) {
|
|
182
191
|
if (this.#isDefaultContext(executionContext)) {
|
|
@@ -187,6 +196,10 @@ export class ExecutionContextSelector implements SDK.TargetManager.SDKModelObser
|
|
|
187
196
|
}
|
|
188
197
|
if (!newContext) {
|
|
189
198
|
for (let i = 0; i < runtimeModels.length && !newContext; ++i) {
|
|
199
|
+
if (runtimeModels[i].target().targetInfo()?.subtype &&
|
|
200
|
+
this.#context.flavor(SDK.Target.Target) !== runtimeModels[i].target()) {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
190
203
|
const executionContexts = runtimeModels[i].executionContexts();
|
|
191
204
|
if (executionContexts.length) {
|
|
192
205
|
newContext = executionContexts[0];
|
|
@@ -23,14 +23,10 @@ const UIStrings = {
|
|
|
23
23
|
* @description Tooltip for the AI assistance button in the main DevTools toolbar.
|
|
24
24
|
*/
|
|
25
25
|
openAiAssistance: 'Open AI assistance panel',
|
|
26
|
-
/**
|
|
27
|
-
* @description Text label for the Gemini button in the main DevTools toolbar when expanded.
|
|
28
|
-
*/
|
|
29
|
-
gemini: 'Gemini',
|
|
30
26
|
/**
|
|
31
27
|
* @description Tooltip for the Gemini button in the main DevTools toolbar.
|
|
32
28
|
*/
|
|
33
|
-
openGemini: 'Open Gemini panel',
|
|
29
|
+
openGemini: 'Open `Gemini` panel',
|
|
34
30
|
} as const;
|
|
35
31
|
const str_ = i18n.i18n.registerUIStrings('entrypoints/main/GlobalAiButton.ts', UIStrings);
|
|
36
32
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
@@ -65,7 +61,7 @@ export const DEFAULT_VIEW = (input: ViewInput, output: undefined, target: HTMLEl
|
|
|
65
61
|
});
|
|
66
62
|
|
|
67
63
|
const strings = AIAssistance.AiUtils.isGeminiBranding() ?
|
|
68
|
-
{title: i18nString(UIStrings.openGemini), label:
|
|
64
|
+
{title: i18nString(UIStrings.openGemini), label: i18n.i18n.lockedString('Gemini')} :
|
|
69
65
|
{title: i18nString(UIStrings.openAiAssistance), label: i18nString(UIStrings.aiAssistance)};
|
|
70
66
|
const icon = AIAssistance.AiUtils.getIconName();
|
|
71
67
|
|
|
@@ -44,6 +44,7 @@ import * as SDK from '../../core/sdk/sdk.js';
|
|
|
44
44
|
import * as Foundation from '../../foundation/foundation.js';
|
|
45
45
|
import * as AiAssistanceModel from '../../models/ai_assistance/ai_assistance.js';
|
|
46
46
|
import * as Badges from '../../models/badges/badges.js';
|
|
47
|
+
import * as CommentManager from '../../models/comment_manager/comment_manager.js';
|
|
47
48
|
import * as CrUXManager from '../../models/crux-manager/crux-manager.js';
|
|
48
49
|
import * as Persistence from '../../models/persistence/persistence.js';
|
|
49
50
|
import * as Workspace from '../../models/workspace/workspace.js';
|
|
@@ -554,7 +555,13 @@ export class MainImpl {
|
|
|
554
555
|
inspectorView.displaySelectOverrideFolderInfobar(event.data);
|
|
555
556
|
});
|
|
556
557
|
await inspectorView.createToolbars();
|
|
557
|
-
inspectorView.renderStatusBar();
|
|
558
|
+
inspectorView.renderStatusBar(this.#universe.commentManager.isAgentAttached());
|
|
559
|
+
this.#universe.commentManager.addEventListener(
|
|
560
|
+
CommentManager.CommentManager.Events.AGENT_ATTACHED_CHANGED,
|
|
561
|
+
event => {
|
|
562
|
+
inspectorView.renderStatusBar(event.data);
|
|
563
|
+
},
|
|
564
|
+
);
|
|
558
565
|
Host.InspectorFrontendHost.InspectorFrontendHostInstance.loadCompleted();
|
|
559
566
|
|
|
560
567
|
// Initialize elements for the live announcer functionality for a11y.
|