blob: d6f7e96b90e2ed2499b8fa78065e1dc3fdf7b7bc [file] [log] [blame]
Blink Reformat4c46d092018-04-07 15:32:371/*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
Kateryna Prokopenko6fa122c2022-05-06 08:54:4731import * as Platform from '../../core/platform/platform.js';
Philip Pfaffe7523faf2021-06-28 14:23:1432import type * as PublicAPI from '../../../extension-api/ExtensionAPI'; // eslint-disable-line rulesdir/es_modules_import
Philip Pfaffe4b88c662021-06-25 12:30:4733import type * as HAR from '../har/har.js';
Philip Pfaffe7523faf2021-06-28 14:23:1434
Philip Pfaffeddf60d22021-06-25 12:35:4135/* eslint-disable @typescript-eslint/naming-convention,@typescript-eslint/no-non-null-assertion */
Philip Pfaffe939605d2021-06-25 12:20:0436export namespace PrivateAPI {
37 export namespace Panels {
38 export const enum SearchAction {
39 CancelSearch = 'cancelSearch',
40 PerformSearch = 'performSearch',
41 NextSearchResult = 'nextSearchResult',
42 PreviousSearchResult = 'previousSearchResult',
43 }
Tim van der Lippe1d6e57a2019-09-30 11:55:3444 }
Blink Reformat4c46d092018-04-07 15:32:3745
Philip Pfaffe939605d2021-06-25 12:20:0446 export const enum Events {
47 ButtonClicked = 'button-clicked-',
48 PanelObjectSelected = 'panel-objectSelected-',
49 InspectedURLChanged = 'inspected-url-changed',
50 NetworkRequestFinished = 'network-request-finished',
51 OpenResource = 'open-resource',
52 PanelSearch = 'panel-search-',
53 RecordingStarted = 'trace-recording-started-',
54 RecordingStopped = 'trace-recording-stopped-',
55 ResourceAdded = 'resource-added',
56 ResourceContentCommitted = 'resource-content-committed',
57 ViewShown = 'view-shown-',
58 ViewHidden = 'view-hidden,',
Paul Lewisada689f2022-01-11 12:03:4059 ThemeChange = 'host-theme-change',
Philip Pfaffe939605d2021-06-25 12:20:0460 }
Blink Reformat4c46d092018-04-07 15:32:3761
Philip Pfaffe939605d2021-06-25 12:20:0462 export const enum Commands {
63 AddRequestHeaders = 'addRequestHeaders',
64 AddTraceProvider = 'addTraceProvider',
65 ApplyStyleSheet = 'applyStyleSheet',
66 CompleteTraceSession = 'completeTra.eSession',
67 CreatePanel = 'createPanel',
68 CreateSidebarPane = 'createSidebarPane',
69 CreateToolbarButton = 'createToolbarButton',
70 EvaluateOnInspectedPage = 'evaluateOnInspectedPage',
71 ForwardKeyboardEvent = '_forwardKeyboardEvent',
72 GetHAR = 'getHAR',
73 GetPageResources = 'getPageResources',
74 GetRequestContent = 'getRequestContent',
75 GetResourceContent = 'getResourceContent',
76 OpenResource = 'openResource',
77 Reload = 'Reload',
78 Subscribe = 'subscribe',
79 SetOpenResourceHandler = 'setOpenResourceHandler',
Paul Lewisada689f2022-01-11 12:03:4080 SetThemeChangeHandler = 'setThemeChangeHandler',
Philip Pfaffe939605d2021-06-25 12:20:0481 SetResourceContent = 'setResourceContent',
82 SetSidebarContent = 'setSidebarContent',
83 SetSidebarHeight = 'setSidebarHeight',
84 SetSidebarPage = 'setSidebarPage',
85 ShowPanel = 'showPanel',
86 Unsubscribe = 'unsubscribe',
87 UpdateButton = 'updateButton',
88 RegisterLanguageExtensionPlugin = 'registerLanguageExtensionPlugin',
Philip Pfaffe6ed01262022-07-06 10:41:3989 GetWasmLinearMemory = 'getWasmLinearMemory',
90 GetWasmLocal = 'getWasmLocal',
91 GetWasmGlobal = 'getWasmGlobal',
92 GetWasmOp = 'getWasmOp',
Alex Rudenkoa3850822022-05-24 07:34:2293 RegisterRecorderExtensionPlugin = 'registerRecorderExtensionPlugin',
Alex Rudenko0b8b8882023-01-17 12:21:4994 CreateRecorderView = 'createRecorderView',
95 ShowRecorderView = 'showRecorderView',
Philip Pfaffe939605d2021-06-25 12:20:0496 }
Philip Pfaffeedad8322020-07-20 10:24:2597
Philip Pfaffe939605d2021-06-25 12:20:0498 export const enum LanguageExtensionPluginCommands {
99 AddRawModule = 'addRawModule',
100 RemoveRawModule = 'removeRawModule',
101 SourceLocationToRawLocation = 'sourceLocationToRawLocation',
102 RawLocationToSourceLocation = 'rawLocationToSourceLocation',
103 GetScopeInfo = 'getScopeInfo',
104 ListVariablesInScope = 'listVariablesInScope',
105 GetTypeInfo = 'getTypeInfo',
106 GetFormatter = 'getFormatter',
107 GetInspectableAddress = 'getInspectableAddress',
108 GetFunctionInfo = 'getFunctionInfo',
109 GetInlinedFunctionRanges = 'getInlinedFunctionRanges',
110 GetInlinedCalleesRanges = 'getInlinedCalleesRanges',
111 GetMappedLines = 'getMappedLines',
Philip Pfaffe6ed01262022-07-06 10:41:39112 FormatValue = 'formatValue',
113 GetProperties = 'getProperties',
114 ReleaseObject = 'releaseObject',
Philip Pfaffe939605d2021-06-25 12:20:04115 }
Benedikt Meurer929fc7c2020-11-20 14:21:06116
Philip Pfaffe939605d2021-06-25 12:20:04117 export const enum LanguageExtensionPluginEvents {
118 UnregisteredLanguageExtensionPlugin = 'unregisteredLanguageExtensionPlugin',
119 }
Philip Pfaffed662bdf2021-06-25 13:30:32120
Alex Rudenkoa3850822022-05-24 07:34:22121 export const enum RecorderExtensionPluginCommands {
122 Stringify = 'stringify',
Alex Rudenko2aa04c02022-06-01 13:05:20123 StringifyStep = 'stringifyStep',
Alex Rudenko0b8b8882023-01-17 12:21:49124 Replay = 'replay',
Alex Rudenkoa3850822022-05-24 07:34:22125 }
126
127 export const enum RecorderExtensionPluginEvents {
128 UnregisteredRecorderExtensionPlugin = 'unregisteredRecorderExtensionPlugin',
129 }
130
Philip Pfaffed662bdf2021-06-25 13:30:32131 export interface EvaluateOptions {
132 frameURL?: string;
133 useContentScriptContext?: boolean;
134 scriptExecutionContext?: string;
135 }
136
Philip Pfaffed662bdf2021-06-25 13:30:32137 type RegisterLanguageExtensionPluginRequest = {
138 command: Commands.RegisterLanguageExtensionPlugin,
139 pluginName: string,
140 port: MessagePort,
Philip Pfaffe7523faf2021-06-28 14:23:14141 supportedScriptTypes: PublicAPI.Chrome.DevTools.SupportedScriptTypes,
Philip Pfaffed662bdf2021-06-25 13:30:32142 };
Alex Rudenko0b8b8882023-01-17 12:21:49143 export type RecordingExtensionPluginCapability = 'export'|'replay';
Alex Rudenkoa3850822022-05-24 07:34:22144 type RegisterRecorderExtensionPluginRequest = {
145 command: Commands.RegisterRecorderExtensionPlugin,
146 pluginName: string,
Alex Rudenko0b8b8882023-01-17 12:21:49147 mediaType?: string, capabilities: RecordingExtensionPluginCapability[], port: MessagePort,
148 };
149 type CreateRecorderViewRequest = {
150 command: Commands.CreateRecorderView,
151 id: string,
152 title: string,
153 pagePath: string,
154 };
155 type ShowRecorderViewRequest = {
156 command: Commands.ShowRecorderView,
157 id: string,
Alex Rudenkoa3850822022-05-24 07:34:22158 };
Philip Pfaffed662bdf2021-06-25 13:30:32159 type SubscribeRequest = {command: Commands.Subscribe, type: string};
160 type UnsubscribeRequest = {command: Commands.Unsubscribe, type: string};
161 type AddRequestHeadersRequest = {
162 command: Commands.AddRequestHeaders,
163 extensionId: string,
164 headers: {[key: string]: string},
165 };
166 type ApplyStyleSheetRequest = {command: Commands.ApplyStyleSheet, styleSheet: string};
167 type CreatePanelRequest = {command: Commands.CreatePanel, id: string, title: string, page: string};
168 type ShowPanelRequest = {command: Commands.ShowPanel, id: string};
169 type CreateToolbarButtonRequest = {
170 command: Commands.CreateToolbarButton,
171 id: string,
172 icon: string,
173 panel: string,
174 tooltip?: string,
175 disabled?: boolean,
176 };
177 type UpdateButtonRequest =
178 {command: Commands.UpdateButton, id: string, icon?: string, tooltip?: string, disabled?: boolean};
179 type CompleteTraceSessionRequest =
Kateryna Prokopenko6fa122c2022-05-06 08:54:47180 {command: Commands.CompleteTraceSession, id: string, url: Platform.DevToolsPath.UrlString, timeOffset: number};
Philip Pfaffed662bdf2021-06-25 13:30:32181 type CreateSidebarPaneRequest = {command: Commands.CreateSidebarPane, id: string, panel: string, title: string};
182 type SetSidebarHeightRequest = {command: Commands.SetSidebarHeight, id: string, height: string};
183 type SetSidebarContentRequest = {
184 command: Commands.SetSidebarContent,
185 id: string,
186 evaluateOnPage?: boolean, expression: string,
187 rootTitle?: string,
188 evaluateOptions?: EvaluateOptions,
189 };
190 type SetSidebarPageRequest = {command: Commands.SetSidebarPage, id: string, page: string};
Kateryna Prokopenko9964ab12022-03-23 16:41:49191 type OpenResourceRequest =
192 {command: Commands.OpenResource, url: Platform.DevToolsPath.UrlString, lineNumber: number, columnNumber: number};
Philip Pfaffed662bdf2021-06-25 13:30:32193 type SetOpenResourceHandlerRequest = {command: Commands.SetOpenResourceHandler, handlerPresent: boolean};
Paul Lewisada689f2022-01-11 12:03:40194 type SetThemeChangeHandlerRequest = {command: Commands.SetThemeChangeHandler, handlerPresent: boolean};
Philip Pfaffed662bdf2021-06-25 13:30:32195 type ReloadRequest = {
196 command: Commands.Reload,
197 options: null|{
198 userAgent?: string,
199 injectedScript?: string,
200 ignoreCache?: boolean,
201 },
202 };
203 type EvaluateOnInspectedPageRequest = {
204 command: Commands.EvaluateOnInspectedPage,
205 expression: string,
206 evaluateOptions?: EvaluateOptions,
207 };
208 type GetRequestContentRequest = {command: Commands.GetRequestContent, id: number};
209 type GetResourceContentRequest = {command: Commands.GetResourceContent, url: string};
210 type SetResourceContentRequest =
211 {command: Commands.SetResourceContent, url: string, content: string, commit: boolean};
212 type AddTraceProviderRequest =
213 {command: Commands.AddTraceProvider, id: string, categoryName: string, categoryTooltip: string};
214 type ForwardKeyboardEventRequest = {
215 command: Commands.ForwardKeyboardEvent,
216 entries: Array<KeyboardEventInit&{eventType: string}>,
217 };
218 type GetHARRequest = {command: Commands.GetHAR};
Danil Somsikov56210832022-10-05 13:17:58219 type GetPageResourcesRequest = {command: Commands.GetPageResources};
Philip Pfaffe6ed01262022-07-06 10:41:39220 type GetWasmLinearMemoryRequest = {
221 command: Commands.GetWasmLinearMemory,
222 offset: number,
223 length: number,
224 stopId: unknown,
225 };
226 type GetWasmLocalRequest = {
227 command: Commands.GetWasmLocal,
228 local: number,
229 stopId: unknown,
230 };
231 type GetWasmGlobalRequest = {
232 command: Commands.GetWasmGlobal,
233 global: number,
234 stopId: unknown,
235 };
236 type GetWasmOpRequest = {command: Commands.GetWasmOp, op: number, stopId: unknown};
Philip Pfaffed662bdf2021-06-25 13:30:32237
Alex Rudenko0b8b8882023-01-17 12:21:49238 export type ServerRequests = ShowRecorderViewRequest|CreateRecorderViewRequest|RegisterRecorderExtensionPluginRequest|
239 RegisterLanguageExtensionPluginRequest|SubscribeRequest|UnsubscribeRequest|AddRequestHeadersRequest|
240 ApplyStyleSheetRequest|CreatePanelRequest|ShowPanelRequest|CreateToolbarButtonRequest|UpdateButtonRequest|
241 CompleteTraceSessionRequest|CreateSidebarPaneRequest|SetSidebarHeightRequest|SetSidebarContentRequest|
242 SetSidebarPageRequest|OpenResourceRequest|SetOpenResourceHandlerRequest|SetThemeChangeHandlerRequest|
243 ReloadRequest|EvaluateOnInspectedPageRequest|GetRequestContentRequest|GetResourceContentRequest|
244 SetResourceContentRequest|AddTraceProviderRequest|ForwardKeyboardEventRequest|GetHARRequest|
245 GetPageResourcesRequest|GetWasmLinearMemoryRequest|GetWasmLocalRequest|GetWasmGlobalRequest|GetWasmOpRequest;
Philip Pfaffed662bdf2021-06-25 13:30:32246 export type ExtensionServerRequestMessage = PrivateAPI.ServerRequests&{requestId?: number};
Philip Pfaffec5d160e2021-07-20 10:53:32247
248 type AddRawModuleRequest = {
249 method: LanguageExtensionPluginCommands.AddRawModule,
250 parameters: {rawModuleId: string, symbolsURL: string|undefined, rawModule: PublicAPI.Chrome.DevTools.RawModule},
251 };
252 type SourceLocationToRawLocationRequest = {
253 method: LanguageExtensionPluginCommands.SourceLocationToRawLocation,
254 parameters: {sourceLocation: PublicAPI.Chrome.DevTools.SourceLocation},
255 };
256 type RawLocationToSourceLocationRequest = {
257 method: LanguageExtensionPluginCommands.RawLocationToSourceLocation,
258 parameters: {rawLocation: PublicAPI.Chrome.DevTools.RawLocation},
259 };
260 type GetScopeInfoRequest = {method: LanguageExtensionPluginCommands.GetScopeInfo, parameters: {type: string}};
261 type ListVariablesInScopeRequest = {
262 method: LanguageExtensionPluginCommands.ListVariablesInScope,
263 parameters: {rawLocation: PublicAPI.Chrome.DevTools.RawLocation},
264 };
265 type RemoveRawModuleRequest = {
266 method: LanguageExtensionPluginCommands.RemoveRawModule,
267 parameters: {rawModuleId: string},
268 };
Philip Pfaffec5d160e2021-07-20 10:53:32269 type GetFunctionInfoRequest = {
270 method: LanguageExtensionPluginCommands.GetFunctionInfo,
271 parameters: {rawLocation: PublicAPI.Chrome.DevTools.RawLocation},
272 };
273 type GetInlinedFunctionRangesRequest = {
274 method: LanguageExtensionPluginCommands.GetInlinedFunctionRanges,
275 parameters: {rawLocation: PublicAPI.Chrome.DevTools.RawLocation},
276 };
277 type GetInlinedCalleesRangesRequest = {
278 method: LanguageExtensionPluginCommands.GetInlinedCalleesRanges,
279 parameters: {rawLocation: PublicAPI.Chrome.DevTools.RawLocation},
280 };
281 type GetMappedLinesRequest = {
282 method: LanguageExtensionPluginCommands.GetMappedLines,
283 parameters: {rawModuleId: string, sourceFileURL: string},
284 };
Philip Pfaffe6ed01262022-07-06 10:41:39285 type FormatValueRequest = {
286 method: LanguageExtensionPluginCommands.FormatValue,
287 parameters: {expression: string, context: PublicAPI.Chrome.DevTools.RawLocation, stopId: number},
288 };
289 type GetPropertiesRequest = {
290 method: LanguageExtensionPluginCommands.GetProperties,
291 parameters: {objectId: PublicAPI.Chrome.DevTools.RemoteObjectId},
292 };
293 type ReleaseObjectRequest = {
294 method: LanguageExtensionPluginCommands.ReleaseObject,
295 parameters: {objectId: PublicAPI.Chrome.DevTools.RemoteObjectId},
296 };
Philip Pfaffec5d160e2021-07-20 10:53:32297
Philip Pfaffe6ed01262022-07-06 10:41:39298 export type LanguageExtensionRequests =
299 AddRawModuleRequest|SourceLocationToRawLocationRequest|RawLocationToSourceLocationRequest|GetScopeInfoRequest|
Philip Pfaffe8a3d59b2023-05-04 11:26:00300 ListVariablesInScopeRequest|RemoveRawModuleRequest|GetFunctionInfoRequest|GetInlinedFunctionRangesRequest|
Philip Pfaffe6ed01262022-07-06 10:41:39301 GetInlinedCalleesRangesRequest|GetMappedLinesRequest|FormatValueRequest|GetPropertiesRequest|ReleaseObjectRequest;
Alex Rudenkoa3850822022-05-24 07:34:22302
303 type StringifyRequest = {
304 method: RecorderExtensionPluginCommands.Stringify,
305 parameters: {recording: Record<string, unknown>},
306 };
307
Alex Rudenko2aa04c02022-06-01 13:05:20308 type StringifyStepRequest = {
309 method: RecorderExtensionPluginCommands.StringifyStep,
310 parameters: {step: Record<string, unknown>},
311 };
312
Alex Rudenko0b8b8882023-01-17 12:21:49313 type ReplayRequest = {
314 method: RecorderExtensionPluginCommands.Replay,
315 parameters: {recording: Record<string, unknown>},
316 };
317
318 export type RecorderExtensionRequests = StringifyRequest|StringifyStepRequest|ReplayRequest;
Blink Reformat4c46d092018-04-07 15:32:37319}
320
Philip Pfaffe939605d2021-06-25 12:20:04321declare global {
322 interface Window {
323 injectedExtensionAPI:
324 (extensionInfo: ExtensionDescriptor, inspectedTabId: string, themeName: string, keysToForward: number[],
Philip Pfaffe7523faf2021-06-28 14:23:14325 testHook:
326 (extensionServer: APIImpl.ExtensionServerClient, extensionAPI: APIImpl.InspectorExtensionAPI) => unknown,
Alex Rudenkoa3850822022-05-24 07:34:22327 injectedScriptId: number, targetWindow?: Window) => void;
Philip Pfaffe939605d2021-06-25 12:20:04328 buildExtensionAPIInjectedScript(
329 extensionInfo: ExtensionDescriptor, inspectedTabId: string, themeName: string, keysToForward: number[],
Philip Pfaffed662bdf2021-06-25 13:30:32330 testHook: undefined|((extensionServer: unknown, extensionAPI: unknown) => unknown)): string;
Philip Pfaffe7523faf2021-06-28 14:23:14331 chrome: PublicAPI.Chrome.DevTools.Chrome;
332 webInspector?: APIImpl.InspectorExtensionAPI;
Philip Pfaffe939605d2021-06-25 12:20:04333 }
334}
335
336export type ExtensionDescriptor = {
337 startPage: string,
338 name: string,
339 exposeExperimentalAPIs: boolean,
340 exposeWebInspectorNamespace?: boolean,
Danil Somsikov28cfaf32022-09-27 15:36:55341 allowFileAccess?: boolean,
Philip Pfaffe939605d2021-06-25 12:20:04342};
343
Philip Pfaffe7523faf2021-06-28 14:23:14344namespace APIImpl {
345 export interface InspectorExtensionAPI {
346 languageServices: PublicAPI.Chrome.DevTools.LanguageExtensions;
Alex Rudenkoa3850822022-05-24 07:34:22347 recorder: PublicAPI.Chrome.DevTools.RecorderExtensions;
Philip Pfaffe1c827212021-06-25 12:33:20348 timeline: Timeline;
Philip Pfaffe7523faf2021-06-28 14:23:14349 network: PublicAPI.Chrome.DevTools.Network;
350 panels: PublicAPI.Chrome.DevTools.Panels;
351 inspectedWindow: PublicAPI.Chrome.DevTools.InspectedWindow;
352 }
353
354 export interface ExtensionServerClient {
355 _callbacks: {[key: string]: (response: unknown) => unknown};
356 _handlers: {[key: string]: (request: {arguments: unknown[]}) => unknown};
357 _lastRequestId: number;
358 _lastObjectId: number;
359 _port: MessagePort;
360
361 _onCallback(request: unknown): void;
362 _onMessage(event: MessageEvent<{command: string, requestId: number, arguments: unknown[]}>): void;
363 _registerCallback(callback: (response: unknown) => unknown): number;
364 registerHandler(command: string, handler: (request: {arguments: unknown[]}) => unknown): void;
365 unregisterHandler(command: string): void;
366 hasHandler(command: string): boolean;
Philip Pfaffe6ed01262022-07-06 10:41:39367 sendRequest<ResponseT>(
368 request: PrivateAPI.ServerRequests, callback?: ((response: ResponseT) => unknown), transfers?: unknown[]): void;
Philip Pfaffe7523faf2021-06-28 14:23:14369 nextObjectId(): string;
370 }
371
372 // We cannot use the stronger `unknown` type in place of `any` in the following type definition. The type is used as
373 // the right-hand side of `extends` in a few places, which doesn't narrow `unknown`. Without narrowing, overload
374 // resolution and meaningful type inference of arguments break, for example.
Tim van der Lippe269e9ae2021-12-14 13:33:28375 // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
Philip Pfaffe7523faf2021-06-28 14:23:14376 // eslint-disable-next-line @typescript-eslint/no-explicit-any
Tim van der Lippe269e9ae2021-12-14 13:33:28377 export type Callable = (...args: any) => void;
Philip Pfaffe7523faf2021-06-28 14:23:14378
379 export interface EventSink<ListenerT extends Callable> extends PublicAPI.Chrome.DevTools.EventSink<ListenerT> {
380 _type: string;
381 _listeners: ListenerT[];
382 _customDispatch: undefined|((this: EventSink<ListenerT>, request: {arguments: unknown[]}) => unknown);
383
384 _fire(..._vararg: Parameters<ListenerT>): void;
385 _dispatch(request: {arguments: unknown[]}): void;
386 }
Philip Pfaffe4b88c662021-06-25 12:30:47387
388 export interface Network extends PublicAPI.Chrome.DevTools.Network {
389 addRequestHeaders(headers: {[key: string]: string}): void;
390 }
391
392 export interface Request extends PublicAPI.Chrome.DevTools.Request, HAR.Log.EntryDTO {
393 _id: number;
394 }
Philip Pfaffe6fd04c42021-06-25 12:31:48395
396 export interface Panels extends PublicAPI.Chrome.DevTools.Panels {
397 get SearchAction(): {[key: string]: string};
398 applyStyleSheet(styleSheet: string): void;
399 setOpenResourceHandler(callback?: (resource: PublicAPI.Chrome.DevTools.Resource, lineNumber: number) => unknown):
400 void;
Paul Lewisada689f2022-01-11 12:03:40401 setThemeChangeHandler(callback?: (themeName: string) => unknown): void;
Philip Pfaffe6fd04c42021-06-25 12:31:48402 }
403
404 export interface ExtensionView extends PublicAPI.Chrome.DevTools.ExtensionView {
405 _id: string|null;
406 }
407
408 export interface ExtensionSidebarPane extends ExtensionView, PublicAPI.Chrome.DevTools.ExtensionSidebarPane {
409 setExpression(
410 expression: string, rootTitle?: string, evaluteOptions?: PrivateAPI.EvaluateOptions,
411 callback?: () => unknown): void;
412 }
413
414 export interface PanelWithSidebar extends ExtensionView, PublicAPI.Chrome.DevTools.PanelWithSidebar {
415 _hostPanelName: string;
416 }
417
418 export interface LanguageExtensions extends PublicAPI.Chrome.DevTools.LanguageExtensions {
419 _plugins: Map<PublicAPI.Chrome.DevTools.LanguageExtensionPlugin, MessagePort>;
420 }
421
Alex Rudenkoa3850822022-05-24 07:34:22422 export interface RecorderExtensions extends PublicAPI.Chrome.DevTools.RecorderExtensions {
423 _plugins: Map<PublicAPI.Chrome.DevTools.RecorderExtensionPlugin, MessagePort>;
424 }
425
Philip Pfaffe6fd04c42021-06-25 12:31:48426 export interface ExtensionPanel extends ExtensionView, PublicAPI.Chrome.DevTools.ExtensionPanel {
427 show(): void;
428 }
429
Alex Rudenko0b8b8882023-01-17 12:21:49430 export interface RecorderView extends ExtensionView, PublicAPI.Chrome.DevTools.RecorderView {}
431
Philip Pfaffe6fd04c42021-06-25 12:31:48432 export interface Button extends PublicAPI.Chrome.DevTools.Button {
433 _id: string;
434 }
435
Philip Pfaffe1c827212021-06-25 12:33:20436 export interface TraceSession {
437 _id: string;
438
439 complete(url?: string, timeOffset?: number): void;
440 }
441
442 export interface TraceProvider {
443 onRecordingStarted: EventSink<(session: TraceSession) => unknown>;
444 onRecordingStopped: EventSink<() => unknown>;
445 }
446
447 export interface Timeline {
448 addTraceProvider(categoryName: string, categoryTooltip: string): TraceProvider;
449 }
450
Philip Pfaffe6fd04c42021-06-25 12:31:48451 export type ResourceData = {url: string, type: string};
452 export interface Resource extends PublicAPI.Chrome.DevTools.Resource {
453 _type: string;
454 _url: string;
455
456 get type(): string;
457 }
Philip Pfaffe7523faf2021-06-28 14:23:14458}
Philip Pfaffe939605d2021-06-25 12:20:04459
Tim van der Lippe226fc222019-10-10 12:17:12460self.injectedExtensionAPI = function(
Philip Pfaffe7523faf2021-06-28 14:23:14461 extensionInfo: ExtensionDescriptor, inspectedTabId: string, themeName: string, keysToForward: number[],
462 testHook: (extensionServer: APIImpl.ExtensionServerClient, extensionAPI: APIImpl.InspectorExtensionAPI) => unknown,
Alex Rudenkoa3850822022-05-24 07:34:22463 injectedScriptId: number, targetWindowForTest?: Window): void {
Jan Schefflerd76b4162021-03-29 07:52:16464 const keysToForwardSet = new Set<number>(keysToForward);
Blink Reformat4c46d092018-04-07 15:32:37465 const chrome = window.chrome || {};
Jan Schefflerd76b4162021-03-29 07:52:16466
Blink Reformat4c46d092018-04-07 15:32:37467 const devtools_descriptor = Object.getOwnPropertyDescriptor(chrome, 'devtools');
Tim van der Lippe1d6e57a2019-09-30 11:55:34468 if (devtools_descriptor) {
Blink Reformat4c46d092018-04-07 15:32:37469 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34470 }
Blink Reformat4c46d092018-04-07 15:32:37471 let userAction = false;
Alex Rudenko0b8b8882023-01-17 12:21:49472 let userRecorderAction = false;
Blink Reformat4c46d092018-04-07 15:32:37473
474 // Here and below, all constructors are private to API implementation.
475 // For a public type Foo, if internal fields are present, these are on
476 // a private FooImpl type, an instance of FooImpl is used in a closure
477 // by Foo consutrctor to re-bind publicly exported members to an instance
478 // of Foo.
479
Philip Pfaffe7523faf2021-06-28 14:23:14480 function EventSinkImpl<ListenerT extends APIImpl.Callable>(
481 this: APIImpl.EventSink<ListenerT>, type: string,
482 customDispatch?: (this: APIImpl.EventSink<ListenerT>, request: {arguments: unknown[]}) => unknown): void {
Blink Reformat4c46d092018-04-07 15:32:37483 this._type = type;
484 this._listeners = [];
485 this._customDispatch = customDispatch;
486 }
487
488 EventSinkImpl.prototype = {
Philip Pfaffe7523faf2021-06-28 14:23:14489 addListener: function<ListenerT extends APIImpl.Callable>(this: APIImpl.EventSink<ListenerT>, callback: ListenerT):
490 void {
491 if (typeof callback !== 'function') {
492 throw 'addListener: callback is not a function';
493 }
494 if (this._listeners.length === 0) {
495 extensionServer.sendRequest({command: PrivateAPI.Commands.Subscribe, type: this._type});
496 }
497 this._listeners.push(callback);
498 extensionServer.registerHandler('notify-' + this._type, this._dispatch.bind(this));
499 },
Blink Reformat4c46d092018-04-07 15:32:37500
Philip Pfaffe7523faf2021-06-28 14:23:14501 removeListener: function<ListenerT extends APIImpl.Callable>(
502 this: APIImpl.EventSink<ListenerT>, callback: ListenerT): void {
Blink Reformat4c46d092018-04-07 15:32:37503 const listeners = this._listeners;
504
505 for (let i = 0; i < listeners.length; ++i) {
506 if (listeners[i] === callback) {
507 listeners.splice(i, 1);
508 break;
509 }
510 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34511 if (this._listeners.length === 0) {
Philip Pfaffe939605d2021-06-25 12:20:04512 extensionServer.sendRequest({command: PrivateAPI.Commands.Unsubscribe, type: this._type});
Tim van der Lippe1d6e57a2019-09-30 11:55:34513 }
Blink Reformat4c46d092018-04-07 15:32:37514 },
515
Philip Pfaffe7523faf2021-06-28 14:23:14516 _fire: function<ListenerT extends APIImpl.Callable>(
517 this: APIImpl.EventSink<ListenerT>, ..._vararg: Parameters<ListenerT>): void {
Blink Reformat4c46d092018-04-07 15:32:37518 const listeners = this._listeners.slice();
Tim van der Lippe1d6e57a2019-09-30 11:55:34519 for (let i = 0; i < listeners.length; ++i) {
Philip Pfaffe7523faf2021-06-28 14:23:14520 listeners[i].apply(null, Array.from(arguments));
Tim van der Lippe1d6e57a2019-09-30 11:55:34521 }
Blink Reformat4c46d092018-04-07 15:32:37522 },
523
Philip Pfaffe7523faf2021-06-28 14:23:14524 _dispatch: function<ListenerT extends APIImpl.Callable>(
525 this: APIImpl.EventSink<ListenerT>, request: {arguments: unknown[]}): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:34526 if (this._customDispatch) {
Blink Reformat4c46d092018-04-07 15:32:37527 this._customDispatch.call(this, request);
Tim van der Lippe1d6e57a2019-09-30 11:55:34528 } else {
Philip Pfaffe7523faf2021-06-28 14:23:14529 this._fire.apply(this, request.arguments as Parameters<ListenerT>);
Tim van der Lippe1d6e57a2019-09-30 11:55:34530 }
Jan Schefflerd76b4162021-03-29 07:52:16531 },
Blink Reformat4c46d092018-04-07 15:32:37532 };
533
Philip Pfaffe7523faf2021-06-28 14:23:14534 function Constructor<NewT extends APIImpl.Callable>(ctor: NewT): new (...args: Parameters<NewT>) =>
535 ThisParameterType<NewT> {
536 return ctor as unknown as new (...args: Parameters<NewT>) => ThisParameterType<NewT>;
537 }
538
Philip Pfaffe7523faf2021-06-28 14:23:14539 function InspectorExtensionAPI(this: APIImpl.InspectorExtensionAPI): void {
Philip Pfaffeddf60d22021-06-25 12:35:41540 this.inspectedWindow = new (Constructor(InspectedWindow))();
Philip Pfaffe6fd04c42021-06-25 12:31:48541 this.panels = new (Constructor(Panels))();
Philip Pfaffe4b88c662021-06-25 12:30:47542 this.network = new (Constructor(Network))();
Philip Pfaffe1c827212021-06-25 12:33:20543 this.timeline = new (Constructor(Timeline))();
Philip Pfaffec5d160e2021-07-20 10:53:32544 this.languageServices = new (Constructor(LanguageServicesAPI))();
Alex Rudenkoa3850822022-05-24 07:34:22545 this.recorder = new (Constructor(RecorderServicesAPI))();
Blink Reformat4c46d092018-04-07 15:32:37546 defineDeprecatedProperty(this, 'webInspector', 'resources', 'network');
547 }
548
Philip Pfaffe4b88c662021-06-25 12:30:47549 function Network(this: APIImpl.Network): void {
550 function dispatchRequestEvent(
551 this: APIImpl.EventSink<(request: PublicAPI.Chrome.DevTools.Request) => unknown>,
552 message: {arguments: unknown[]}): void {
553 const request = message.arguments[1] as APIImpl.Request & {__proto__: APIImpl.Request};
554
555 request.__proto__ = new (Constructor(Request))(message.arguments[0] as number);
Blink Reformat4c46d092018-04-07 15:32:37556 this._fire(request);
557 }
Philip Pfaffe4b88c662021-06-25 12:30:47558
559 this.onRequestFinished =
560 new (Constructor(EventSink))(PrivateAPI.Events.NetworkRequestFinished, dispatchRequestEvent);
Blink Reformat4c46d092018-04-07 15:32:37561 defineDeprecatedProperty(this, 'network', 'onFinished', 'onRequestFinished');
Philip Pfaffe4b88c662021-06-25 12:30:47562
563 this.onNavigated = new (Constructor(EventSink))(PrivateAPI.Events.InspectedURLChanged);
Blink Reformat4c46d092018-04-07 15:32:37564 }
565
Philip Pfaffe4b88c662021-06-25 12:30:47566 (Network.prototype as Pick<APIImpl.Network, 'getHAR'|'addRequestHeaders'>) = {
567 getHAR: function(this: PublicAPI.Chrome.DevTools.Network, callback?: (harLog: Object) => unknown): void {
568 function callbackWrapper(response: unknown): void {
569 const result =
570 response as ({entries: Array<HAR.Log.EntryDTO&{__proto__?: APIImpl.Request, _requestId?: number}>});
Blink Reformat4c46d092018-04-07 15:32:37571 const entries = (result && result.entries) || [];
572 for (let i = 0; i < entries.length; ++i) {
Philip Pfaffe4b88c662021-06-25 12:30:47573 entries[i].__proto__ = new (Constructor(Request))(entries[i]._requestId as number);
Blink Reformat4c46d092018-04-07 15:32:37574 delete entries[i]._requestId;
575 }
Philip Pfaffe4b88c662021-06-25 12:30:47576 callback && callback(result as Object);
Blink Reformat4c46d092018-04-07 15:32:37577 }
Philip Pfaffe939605d2021-06-25 12:20:04578 extensionServer.sendRequest({command: PrivateAPI.Commands.GetHAR}, callback && callbackWrapper);
Blink Reformat4c46d092018-04-07 15:32:37579 },
580
Philip Pfaffe4b88c662021-06-25 12:30:47581 addRequestHeaders: function(headers: {[key: string]: string}): void {
Blink Reformat4c46d092018-04-07 15:32:37582 extensionServer.sendRequest(
Philip Pfaffe939605d2021-06-25 12:20:04583 {command: PrivateAPI.Commands.AddRequestHeaders, headers: headers, extensionId: window.location.hostname});
Jan Schefflerd76b4162021-03-29 07:52:16584 },
Blink Reformat4c46d092018-04-07 15:32:37585 };
586
Philip Pfaffe4b88c662021-06-25 12:30:47587 function RequestImpl(this: APIImpl.Request, id: number): void {
Blink Reformat4c46d092018-04-07 15:32:37588 this._id = id;
589 }
590
Philip Pfaffe4b88c662021-06-25 12:30:47591 (RequestImpl.prototype as Pick<APIImpl.Request, 'getContent'>) = {
592 getContent: function(this: APIImpl.Request, callback?: (content: string, encoding: string) => unknown): void {
593 function callbackWrapper(response: unknown): void {
594 const {content, encoding} = response as {content: string, encoding: string};
595 callback && callback(content, encoding);
Blink Reformat4c46d092018-04-07 15:32:37596 }
Philip Pfaffe939605d2021-06-25 12:20:04597 extensionServer.sendRequest(
598 {command: PrivateAPI.Commands.GetRequestContent, id: this._id}, callback && callbackWrapper);
Jan Schefflerd76b4162021-03-29 07:52:16599 },
Blink Reformat4c46d092018-04-07 15:32:37600 };
601
Philip Pfaffe6fd04c42021-06-25 12:31:48602 function Panels(this: APIImpl.Panels): void {
603 const panels: {[key: string]: ElementsPanel|SourcesPanel} = {
Blink Reformat4c46d092018-04-07 15:32:37604 elements: new ElementsPanel(),
605 sources: new SourcesPanel(),
606 };
607
Philip Pfaffe6fd04c42021-06-25 12:31:48608 function panelGetter(name: string): ElementsPanel|SourcesPanel {
Blink Reformat4c46d092018-04-07 15:32:37609 return panels[name];
610 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34611 for (const panel in panels) {
Tim van der Lippeffa78622019-09-16 12:07:12612 Object.defineProperty(this, panel, {get: panelGetter.bind(null, panel), enumerable: true});
Tim van der Lippe1d6e57a2019-09-30 11:55:34613 }
Philip Pfaffe6fd04c42021-06-25 12:31:48614 this.applyStyleSheet = function(styleSheet: string): void {
Philip Pfaffe939605d2021-06-25 12:20:04615 extensionServer.sendRequest({command: PrivateAPI.Commands.ApplyStyleSheet, styleSheet: styleSheet});
Blink Reformat4c46d092018-04-07 15:32:37616 };
617 }
618
Paul Lewisada689f2022-01-11 12:03:40619 (Panels.prototype as
620 Pick<APIImpl.Panels, 'create'|'setOpenResourceHandler'|'openResource'|'SearchAction'|'setThemeChangeHandler'>) = {
Philip Pfaffe6fd04c42021-06-25 12:31:48621 create: function(
622 title: string, icon: string, page: string,
623 callback: (panel: PublicAPI.Chrome.DevTools.ExtensionPanel) => unknown): void {
Blink Reformat4c46d092018-04-07 15:32:37624 const id = 'extension-panel-' + extensionServer.nextObjectId();
Philip Pfaffe6fd04c42021-06-25 12:31:48625 extensionServer.sendRequest(
626 {command: PrivateAPI.Commands.CreatePanel, id, title, page},
Philip Pfaffe3abccb42021-09-14 09:18:37627 callback && ((): unknown => callback.call(this, new (Constructor(ExtensionPanel))(id))));
Blink Reformat4c46d092018-04-07 15:32:37628 },
629
Philip Pfaffe6fd04c42021-06-25 12:31:48630 setOpenResourceHandler: function(
631 callback: (resource: PublicAPI.Chrome.DevTools.Resource, lineNumber: number) => unknown): void {
Philip Pfaffe939605d2021-06-25 12:20:04632 const hadHandler = extensionServer.hasHandler(PrivateAPI.Events.OpenResource);
Blink Reformat4c46d092018-04-07 15:32:37633
Philip Pfaffe6fd04c42021-06-25 12:31:48634 function callbackWrapper(message: unknown): void {
Blink Reformat4c46d092018-04-07 15:32:37635 // Allow the panel to show itself when handling the event.
636 userAction = true;
637 try {
Philip Pfaffe6fd04c42021-06-25 12:31:48638 const {resource, lineNumber} = message as {resource: APIImpl.ResourceData, lineNumber: number};
Danil Somsikov56210832022-10-05 13:17:58639 if (canAccessResource(resource)) {
640 callback.call(null, new (Constructor(Resource))(resource), lineNumber);
641 }
Blink Reformat4c46d092018-04-07 15:32:37642 } finally {
643 userAction = false;
644 }
645 }
646
Tim van der Lippe1d6e57a2019-09-30 11:55:34647 if (!callback) {
Philip Pfaffe939605d2021-06-25 12:20:04648 extensionServer.unregisterHandler(PrivateAPI.Events.OpenResource);
Tim van der Lippe1d6e57a2019-09-30 11:55:34649 } else {
Philip Pfaffe939605d2021-06-25 12:20:04650 extensionServer.registerHandler(PrivateAPI.Events.OpenResource, callbackWrapper);
Tim van der Lippe1d6e57a2019-09-30 11:55:34651 }
Blink Reformat4c46d092018-04-07 15:32:37652
653 // Only send command if we either removed an existing handler or added handler and had none before.
Tim van der Lippe1d6e57a2019-09-30 11:55:34654 if (hadHandler === !callback) {
Philip Pfaffe939605d2021-06-25 12:20:04655 extensionServer.sendRequest(
656 {command: PrivateAPI.Commands.SetOpenResourceHandler, 'handlerPresent': Boolean(callback)});
Tim van der Lippe1d6e57a2019-09-30 11:55:34657 }
Blink Reformat4c46d092018-04-07 15:32:37658 },
659
Paul Lewisada689f2022-01-11 12:03:40660 setThemeChangeHandler: function(callback: (themeName: string) => unknown): void {
661 const hadHandler = extensionServer.hasHandler(PrivateAPI.Events.ThemeChange);
662
663 function callbackWrapper(message: unknown): void {
664 const {themeName} = message as {themeName: string};
665 chrome.devtools.panels.themeName = themeName;
666 callback.call(null, themeName);
667 }
668
669 if (!callback) {
670 extensionServer.unregisterHandler(PrivateAPI.Events.ThemeChange);
671 } else {
672 extensionServer.registerHandler(PrivateAPI.Events.ThemeChange, callbackWrapper);
673 }
674
675 // Only send command if we either removed an existing handler or added handler and had none before.
676 if (hadHandler === !callback) {
677 extensionServer.sendRequest(
678 {command: PrivateAPI.Commands.SetThemeChangeHandler, 'handlerPresent': Boolean(callback)});
679 }
680 },
681
Philip Pfaffe140e5432021-09-13 16:34:23682 openResource: function(
Kateryna Prokopenko9964ab12022-03-23 16:41:49683 url: Platform.DevToolsPath.UrlString, lineNumber: number, columnNumber?: number,
684 _callback?: (response: unknown) => unknown): void {
Philip Pfaffe140e5432021-09-13 16:34:23685 const callbackArg = extractCallbackArgument(arguments);
686 // Handle older API:
687 const columnNumberArg = typeof columnNumber === 'number' ? columnNumber : 0;
688 extensionServer.sendRequest(
689 {command: PrivateAPI.Commands.OpenResource, url, lineNumber, columnNumber: columnNumberArg}, callbackArg);
Blink Reformat4c46d092018-04-07 15:32:37690 },
691
Philip Pfaffe6fd04c42021-06-25 12:31:48692 get SearchAction(): {[key: string]: string} {
Philip Pfaffe939605d2021-06-25 12:20:04693 return {
694 CancelSearch: PrivateAPI.Panels.SearchAction.CancelSearch,
695 PerformSearch: PrivateAPI.Panels.SearchAction.PerformSearch,
696 NextSearchResult: PrivateAPI.Panels.SearchAction.NextSearchResult,
697 PreviousSearchResult: PrivateAPI.Panels.SearchAction.PreviousSearchResult,
698 };
Jan Schefflerd76b4162021-03-29 07:52:16699 },
Blink Reformat4c46d092018-04-07 15:32:37700 };
701
Philip Pfaffe6fd04c42021-06-25 12:31:48702 function ExtensionViewImpl(this: APIImpl.ExtensionView, id: string|null): void {
Blink Reformat4c46d092018-04-07 15:32:37703 this._id = id;
704
Philip Pfaffe6fd04c42021-06-25 12:31:48705 function dispatchShowEvent(
706 this: APIImpl.EventSink<(window?: Window) => unknown>, message: {arguments: unknown[]}): void {
Blink Reformat4c46d092018-04-07 15:32:37707 const frameIndex = message.arguments[0];
Tim van der Lippe1d6e57a2019-09-30 11:55:34708 if (typeof frameIndex === 'number') {
Blink Reformat4c46d092018-04-07 15:32:37709 this._fire(window.parent.frames[frameIndex]);
Tim van der Lippe1d6e57a2019-09-30 11:55:34710 } else {
Blink Reformat4c46d092018-04-07 15:32:37711 this._fire();
Tim van der Lippe1d6e57a2019-09-30 11:55:34712 }
Blink Reformat4c46d092018-04-07 15:32:37713 }
714
715 if (id) {
Philip Pfaffe6fd04c42021-06-25 12:31:48716 this.onShown = new (Constructor(EventSink))(PrivateAPI.Events.ViewShown + id, dispatchShowEvent);
717
718 this.onHidden = new (Constructor(EventSink))(PrivateAPI.Events.ViewHidden + id);
Blink Reformat4c46d092018-04-07 15:32:37719 }
720 }
721
Philip Pfaffe6fd04c42021-06-25 12:31:48722 function PanelWithSidebarImpl(this: APIImpl.PanelWithSidebar, hostPanelName: string): void {
Blink Reformat4c46d092018-04-07 15:32:37723 ExtensionViewImpl.call(this, null);
724 this._hostPanelName = hostPanelName;
Philip Pfaffe6fd04c42021-06-25 12:31:48725
726 this.onSelectionChanged = new (Constructor(EventSink))(PrivateAPI.Events.PanelObjectSelected + hostPanelName);
Blink Reformat4c46d092018-04-07 15:32:37727 }
728
Philip Pfaffe6fd04c42021-06-25 12:31:48729 (PanelWithSidebarImpl.prototype as Pick<APIImpl.PanelWithSidebar, 'createSidebarPane'>&
730 {__proto__: APIImpl.ExtensionView}) = {
731 createSidebarPane: function(
732 this: APIImpl.PanelWithSidebar, title: string,
733 callback?: (pane: PublicAPI.Chrome.DevTools.ExtensionSidebarPane) => unknown): void {
Blink Reformat4c46d092018-04-07 15:32:37734 const id = 'extension-sidebar-' + extensionServer.nextObjectId();
Jan Schefflerd76b4162021-03-29 07:52:16735 function callbackWrapper(): void {
Philip Pfaffe6fd04c42021-06-25 12:31:48736 callback && callback(new (Constructor(ExtensionSidebarPane))(id));
Blink Reformat4c46d092018-04-07 15:32:37737 }
Philip Pfaffe7523faf2021-06-28 14:23:14738 extensionServer.sendRequest(
Philip Pfaffe6fd04c42021-06-25 12:31:48739 {command: PrivateAPI.Commands.CreateSidebarPane, panel: this._hostPanelName, id, title},
Philip Pfaffe7523faf2021-06-28 14:23:14740 callback && callbackWrapper);
Blink Reformat4c46d092018-04-07 15:32:37741 },
742
Jan Schefflerd76b4162021-03-29 07:52:16743 __proto__: ExtensionViewImpl.prototype,
Blink Reformat4c46d092018-04-07 15:32:37744 };
745
Alex Rudenkoa3850822022-05-24 07:34:22746 function RecorderServicesAPIImpl(this: APIImpl.RecorderExtensions): void {
747 this._plugins = new Map();
748 }
749
Alex Rudenko0b8b8882023-01-17 12:21:49750 async function registerRecorderExtensionPluginImpl(
751 this: APIImpl.RecorderExtensions, plugin: PublicAPI.Chrome.DevTools.RecorderExtensionPlugin, pluginName: string,
752 mediaType?: string): Promise<void> {
753 if (this._plugins.has(plugin)) {
754 throw new Error(`Tried to register plugin '${pluginName}' twice`);
755 }
756 const channel = new MessageChannel();
757 const port = channel.port1;
758 this._plugins.set(plugin, port);
759 port.onmessage = ({data}: MessageEvent<{requestId: number}&PrivateAPI.RecorderExtensionRequests>): void => {
760 const {requestId} = data;
761 dispatchMethodCall(data)
762 .then(result => port.postMessage({requestId, result}))
763 .catch(error => port.postMessage({requestId, error: {message: error.message}}));
764 };
765
766 async function dispatchMethodCall(request: PrivateAPI.RecorderExtensionRequests): Promise<unknown> {
767 switch (request.method) {
768 case PrivateAPI.RecorderExtensionPluginCommands.Stringify:
769 return (plugin as PublicAPI.Chrome.DevTools.RecorderExtensionExportPlugin)
770 .stringify(request.parameters.recording);
771 case PrivateAPI.RecorderExtensionPluginCommands.StringifyStep:
772 return (plugin as PublicAPI.Chrome.DevTools.RecorderExtensionExportPlugin)
773 .stringifyStep(request.parameters.step);
774 case PrivateAPI.RecorderExtensionPluginCommands.Replay:
775 try {
776 userAction = true;
777 userRecorderAction = true;
778 return (plugin as PublicAPI.Chrome.DevTools.RecorderExtensionReplayPlugin)
779 .replay(request.parameters.recording);
780 } finally {
781 userAction = false;
782 userRecorderAction = false;
783 }
784 default:
785 // @ts-expect-error
786 throw new Error(`'${request.method}' is not recognized`);
Alex Rudenkoa3850822022-05-24 07:34:22787 }
Alex Rudenko0b8b8882023-01-17 12:21:49788 }
Alex Rudenkoa3850822022-05-24 07:34:22789
Alex Rudenko0b8b8882023-01-17 12:21:49790 const capabilities: PrivateAPI.RecordingExtensionPluginCapability[] = [];
Alex Rudenkoa3850822022-05-24 07:34:22791
Alex Rudenko0b8b8882023-01-17 12:21:49792 if ('stringify' in plugin && 'stringifyStep' in plugin) {
793 capabilities.push('export');
794 }
Alex Rudenkoa3850822022-05-24 07:34:22795
Alex Rudenko0b8b8882023-01-17 12:21:49796 if ('replay' in plugin) {
797 capabilities.push('replay');
798 }
799
800 await new Promise<void>(resolve => {
801 extensionServer.sendRequest(
802 {
803 command: PrivateAPI.Commands.RegisterRecorderExtensionPlugin,
804 pluginName,
805 mediaType,
806 capabilities,
807 port: channel.port2,
808 },
809 () => resolve(), [channel.port2]);
810 });
811 }
812
813 (RecorderServicesAPIImpl.prototype as Pick<
814 APIImpl.RecorderExtensions,
815 'registerRecorderExtensionPlugin'|'unregisterRecorderExtensionPlugin'|'createView'>) = {
816 registerRecorderExtensionPlugin: registerRecorderExtensionPluginImpl,
Alex Rudenkoa3850822022-05-24 07:34:22817 unregisterRecorderExtensionPlugin: async function(
818 this: APIImpl.RecorderExtensions, plugin: PublicAPI.Chrome.DevTools.RecorderExtensionPlugin): Promise<void> {
819 const port = this._plugins.get(plugin);
820 if (!port) {
821 throw new Error('Tried to unregister a plugin that was not previously registered');
822 }
823 this._plugins.delete(plugin);
824 port.postMessage({event: PrivateAPI.RecorderExtensionPluginEvents.UnregisteredRecorderExtensionPlugin});
825 port.close();
826 },
Alex Rudenko0b8b8882023-01-17 12:21:49827 createView: async function(this: APIImpl.RecorderExtensions, title: string, pagePath: string):
828 Promise<PublicAPI.Chrome.DevTools.RecorderView> {
829 const id = 'recorder-extension-view-' + extensionServer.nextObjectId();
830 await new Promise(resolve => {
831 extensionServer.sendRequest(
832 {command: PrivateAPI.Commands.CreateRecorderView, id, title, pagePath}, resolve);
833 });
834 return new (Constructor(RecorderView))(id);
835 },
Alex Rudenkoa3850822022-05-24 07:34:22836 };
837
Philip Pfaffec5d160e2021-07-20 10:53:32838 function LanguageServicesAPIImpl(this: APIImpl.LanguageExtensions): void {
Philip Pfaffeedad8322020-07-20 10:24:25839 this._plugins = new Map();
840 }
841
Philip Pfaffe6ed01262022-07-06 10:41:39842 (LanguageServicesAPIImpl.prototype as PublicAPI.Chrome.DevTools.LanguageExtensions) = {
Philip Pfaffed662bdf2021-06-25 13:30:32843 registerLanguageExtensionPlugin: async function(
Philip Pfaffec5d160e2021-07-20 10:53:32844 this: APIImpl.LanguageExtensions, plugin: PublicAPI.Chrome.DevTools.LanguageExtensionPlugin, pluginName: string,
845 supportedScriptTypes: PublicAPI.Chrome.DevTools.SupportedScriptTypes): Promise<void> {
846 if (this._plugins.has(plugin)) {
847 throw new Error(`Tried to register plugin '${pluginName}' twice`);
848 }
849 const channel = new MessageChannel();
850 const port = channel.port1;
851 this._plugins.set(plugin, port);
852 port.onmessage = ({data}: MessageEvent<{requestId: number}&PrivateAPI.LanguageExtensionRequests>): void => {
853 const {requestId} = data;
854 console.time(`${requestId}: ${data.method}`);
855 dispatchMethodCall(data)
856 .then(result => port.postMessage({requestId, result}))
857 .catch(error => port.postMessage({requestId, error: {message: error.message}}))
858 .finally(() => console.timeEnd(`${requestId}: ${data.method}`));
859 };
Philip Pfaffeedad8322020-07-20 10:24:25860
Philip Pfaffec5d160e2021-07-20 10:53:32861 function dispatchMethodCall(request: PrivateAPI.LanguageExtensionRequests): Promise<unknown> {
862 switch (request.method) {
863 case PrivateAPI.LanguageExtensionPluginCommands.AddRawModule:
864 return plugin.addRawModule(
865 request.parameters.rawModuleId, request.parameters.symbolsURL, request.parameters.rawModule);
866 case PrivateAPI.LanguageExtensionPluginCommands.RemoveRawModule:
867 return plugin.removeRawModule(request.parameters.rawModuleId);
868 case PrivateAPI.LanguageExtensionPluginCommands.SourceLocationToRawLocation:
869 return plugin.sourceLocationToRawLocation(request.parameters.sourceLocation);
870 case PrivateAPI.LanguageExtensionPluginCommands.RawLocationToSourceLocation:
871 return plugin.rawLocationToSourceLocation(request.parameters.rawLocation);
872 case PrivateAPI.LanguageExtensionPluginCommands.GetScopeInfo:
873 return plugin.getScopeInfo(request.parameters.type);
874 case PrivateAPI.LanguageExtensionPluginCommands.ListVariablesInScope:
875 return plugin.listVariablesInScope(request.parameters.rawLocation);
Philip Pfaffec5d160e2021-07-20 10:53:32876 case PrivateAPI.LanguageExtensionPluginCommands.GetFunctionInfo:
877 return plugin.getFunctionInfo(request.parameters.rawLocation);
878 case PrivateAPI.LanguageExtensionPluginCommands.GetInlinedFunctionRanges:
879 return plugin.getInlinedFunctionRanges(request.parameters.rawLocation);
880 case PrivateAPI.LanguageExtensionPluginCommands.GetInlinedCalleesRanges:
881 return plugin.getInlinedCalleesRanges(request.parameters.rawLocation);
882 case PrivateAPI.LanguageExtensionPluginCommands.GetMappedLines:
883 if ('getMappedLines' in plugin) {
884 return plugin.getMappedLines(request.parameters.rawModuleId, request.parameters.sourceFileURL);
885 }
886 return Promise.resolve(undefined);
Philip Pfaffe6ed01262022-07-06 10:41:39887 case PrivateAPI.LanguageExtensionPluginCommands.FormatValue:
Philip Pfaffe889342a2022-07-08 06:18:47888 if ('evaluate' in plugin && plugin.evaluate) {
Philip Pfaffe6ed01262022-07-06 10:41:39889 return plugin.evaluate(
890 request.parameters.expression, request.parameters.context, request.parameters.stopId);
891 }
892 return Promise.resolve(undefined);
893 case PrivateAPI.LanguageExtensionPluginCommands.GetProperties:
Philip Pfaffe889342a2022-07-08 06:18:47894 if ('getProperties' in plugin && plugin.getProperties) {
Philip Pfaffe6ed01262022-07-06 10:41:39895 return plugin.getProperties(request.parameters.objectId);
896 }
Philip Pfaffe889342a2022-07-08 06:18:47897 if (!('evaluate' in plugin &&
898 plugin.evaluate)) { // If evalute is defined but the remote objects methods aren't, that's a bug
Philip Pfaffe6ed01262022-07-06 10:41:39899 return Promise.resolve(undefined);
900 }
901 break;
902 case PrivateAPI.LanguageExtensionPluginCommands.ReleaseObject:
Philip Pfaffe889342a2022-07-08 06:18:47903 if ('releaseObject' in plugin && plugin.releaseObject) {
Philip Pfaffe6ed01262022-07-06 10:41:39904 return plugin.releaseObject(request.parameters.objectId);
905 }
Philip Pfaffe6ed01262022-07-06 10:41:39906 break;
Philip Pfaffec5d160e2021-07-20 10:53:32907 }
Philip Pfaffec5d160e2021-07-20 10:53:32908 throw new Error(`Unknown language plugin method ${request.method}`);
909 }
Philip Pfaffeedad8322020-07-20 10:24:25910
Philip Pfaffec5d160e2021-07-20 10:53:32911 await new Promise<void>(resolve => {
912 extensionServer.sendRequest(
913 {
914 command: PrivateAPI.Commands.RegisterLanguageExtensionPlugin,
915 pluginName,
916 port: channel.port2,
917 supportedScriptTypes,
918 },
919 () => resolve(), [channel.port2]);
920 });
921 },
Benedikt Meurer929fc7c2020-11-20 14:21:06922
Philip Pfaffec5d160e2021-07-20 10:53:32923 unregisterLanguageExtensionPlugin: async function(
924 this: APIImpl.LanguageExtensions, plugin: PublicAPI.Chrome.DevTools.LanguageExtensionPlugin): Promise<void> {
Benedikt Meurer929fc7c2020-11-20 14:21:06925 const port = this._plugins.get(plugin);
926 if (!port) {
927 throw new Error('Tried to unregister a plugin that was not previously registered');
928 }
929 this._plugins.delete(plugin);
Philip Pfaffe939605d2021-06-25 12:20:04930 port.postMessage({event: PrivateAPI.LanguageExtensionPluginEvents.UnregisteredLanguageExtensionPlugin});
Benedikt Meurer929fc7c2020-11-20 14:21:06931 port.close();
Jan Schefflerd76b4162021-03-29 07:52:16932 },
Philip Pfaffe6ed01262022-07-06 10:41:39933
934 getWasmLinearMemory: async function(
935 this: APIImpl.LanguageExtensions, offset: number, length: number, stopId: number): Promise<ArrayBuffer> {
936 const result = await new Promise(
937 resolve => extensionServer.sendRequest(
938 {command: PrivateAPI.Commands.GetWasmLinearMemory, offset, length, stopId}, resolve));
939 if (Array.isArray(result)) {
940 return new Uint8Array(result).buffer;
941 }
942 return new ArrayBuffer(0);
943 },
944 getWasmLocal: async function(
945 this: APIImpl.LanguageExtensions, local: number, stopId: number): Promise<PublicAPI.Chrome.DevTools.WasmValue> {
946 return new Promise(
947 resolve => extensionServer.sendRequest({command: PrivateAPI.Commands.GetWasmLocal, local, stopId}, resolve));
948 },
949 getWasmGlobal: async function(this: APIImpl.LanguageExtensions, global: number, stopId: number):
950 Promise<PublicAPI.Chrome.DevTools.WasmValue> {
951 return new Promise(
952 resolve =>
953 extensionServer.sendRequest({command: PrivateAPI.Commands.GetWasmGlobal, global, stopId}, resolve));
954 },
955 getWasmOp: async function(this: APIImpl.LanguageExtensions, op: number, stopId: number):
956 Promise<PublicAPI.Chrome.DevTools.WasmValue> {
957 return new Promise(
958 resolve => extensionServer.sendRequest({command: PrivateAPI.Commands.GetWasmOp, op, stopId}, resolve));
959 },
Philip Pfaffeedad8322020-07-20 10:24:25960 };
961
Philip Pfaffe7523faf2021-06-28 14:23:14962 function declareInterfaceClass<ImplT extends APIImpl.Callable>(implConstructor: ImplT): (
963 this: ThisParameterType<ImplT>, ...args: Parameters<ImplT>) => void {
964 return function(this: ThisParameterType<ImplT>, ...args: Parameters<ImplT>): void {
Blink Reformat4c46d092018-04-07 15:32:37965 const impl = {__proto__: implConstructor.prototype};
Philip Pfaffe7523faf2021-06-28 14:23:14966 implConstructor.apply(impl, args);
967 populateInterfaceClass(this as {[key: string]: unknown}, impl);
Blink Reformat4c46d092018-04-07 15:32:37968 };
969 }
970
Philip Pfaffe7523faf2021-06-28 14:23:14971 // eslint-disable-next-line @typescript-eslint/no-explicit-any
972 function defineDeprecatedProperty(object: any, className: string, oldName: string, newName: string): void {
Blink Reformat4c46d092018-04-07 15:32:37973 let warningGiven = false;
Philip Pfaffe7523faf2021-06-28 14:23:14974 function getter(): unknown {
Blink Reformat4c46d092018-04-07 15:32:37975 if (!warningGiven) {
976 console.warn(className + '.' + oldName + ' is deprecated. Use ' + className + '.' + newName + ' instead');
977 warningGiven = true;
978 }
979 return object[newName];
980 }
981 object.__defineGetter__(oldName, getter);
982 }
983
Philip Pfaffe7523faf2021-06-28 14:23:14984 function extractCallbackArgument(args: IArguments): ((...args: unknown[]) => unknown)|undefined {
Blink Reformat4c46d092018-04-07 15:32:37985 const lastArgument = args[args.length - 1];
Philip Pfaffe7523faf2021-06-28 14:23:14986 return typeof lastArgument === 'function' ? lastArgument as (...args: unknown[]) => unknown : undefined;
Blink Reformat4c46d092018-04-07 15:32:37987 }
988
Philip Pfaffeedad8322020-07-20 10:24:25989 const LanguageServicesAPI = declareInterfaceClass(LanguageServicesAPIImpl);
Alex Rudenkoa3850822022-05-24 07:34:22990 const RecorderServicesAPI = declareInterfaceClass(RecorderServicesAPIImpl);
Blink Reformat4c46d092018-04-07 15:32:37991 const Button = declareInterfaceClass(ButtonImpl);
992 const EventSink = declareInterfaceClass(EventSinkImpl);
993 const ExtensionPanel = declareInterfaceClass(ExtensionPanelImpl);
Alex Rudenko0b8b8882023-01-17 12:21:49994 const RecorderView = declareInterfaceClass(RecorderViewImpl);
Blink Reformat4c46d092018-04-07 15:32:37995 const ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl);
Tim van der Lippeffa78622019-09-16 12:07:12996 const PanelWithSidebarClass = declareInterfaceClass(PanelWithSidebarImpl);
Blink Reformat4c46d092018-04-07 15:32:37997 const Request = declareInterfaceClass(RequestImpl);
998 const Resource = declareInterfaceClass(ResourceImpl);
999 const TraceSession = declareInterfaceClass(TraceSessionImpl);
1000
Philip Pfaffe6fd04c42021-06-25 12:31:481001 class ElementsPanel extends (Constructor(PanelWithSidebarClass)) {
Tim van der Lippeffa78622019-09-16 12:07:121002 constructor() {
1003 super('elements');
1004 }
Blink Reformat4c46d092018-04-07 15:32:371005 }
1006
Philip Pfaffe6fd04c42021-06-25 12:31:481007 class SourcesPanel extends (Constructor(PanelWithSidebarClass)) {
Tim van der Lippeffa78622019-09-16 12:07:121008 constructor() {
1009 super('sources');
1010 }
Blink Reformat4c46d092018-04-07 15:32:371011 }
1012
Philip Pfaffe6fd04c42021-06-25 12:31:481013 function ExtensionPanelImpl(this: APIImpl.ExtensionPanel, id: string): void {
Blink Reformat4c46d092018-04-07 15:32:371014 ExtensionViewImpl.call(this, id);
Philip Pfaffe6fd04c42021-06-25 12:31:481015
1016 this.onSearch = new (Constructor(EventSink))(PrivateAPI.Events.PanelSearch + id);
Blink Reformat4c46d092018-04-07 15:32:371017 }
1018
Philip Pfaffe6fd04c42021-06-25 12:31:481019 (ExtensionPanelImpl.prototype as Pick<APIImpl.ExtensionPanel, 'createStatusBarButton'|'show'>&
1020 {__proto__: APIImpl.ExtensionView}) = {
1021 createStatusBarButton: function(
1022 this: APIImpl.ExtensionPanel, iconPath: string, tooltipText: string, disabled: boolean):
1023 PublicAPI.Chrome.DevTools.Button {
1024 const id = 'button-' + extensionServer.nextObjectId();
1025 extensionServer.sendRequest({
1026 command: PrivateAPI.Commands.CreateToolbarButton,
1027 panel: this._id as string,
1028 id: id,
1029 icon: iconPath,
1030 tooltip: tooltipText,
1031 disabled: Boolean(disabled),
1032 });
Blink Reformat4c46d092018-04-07 15:32:371033
Philip Pfaffe6fd04c42021-06-25 12:31:481034 return new (Constructor(Button))(id);
1035 },
1036
1037 show: function(this: APIImpl.ExtensionPanel): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341038 if (!userAction) {
Blink Reformat4c46d092018-04-07 15:32:371039 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341040 }
Blink Reformat4c46d092018-04-07 15:32:371041
Philip Pfaffe6fd04c42021-06-25 12:31:481042 extensionServer.sendRequest({command: PrivateAPI.Commands.ShowPanel, id: this._id as string});
Blink Reformat4c46d092018-04-07 15:32:371043 },
1044
Jan Schefflerd76b4162021-03-29 07:52:161045 __proto__: ExtensionViewImpl.prototype,
Blink Reformat4c46d092018-04-07 15:32:371046 };
1047
Alex Rudenko0b8b8882023-01-17 12:21:491048 function RecorderViewImpl(this: APIImpl.RecorderView, id: string): void {
1049 ExtensionViewImpl.call(this, id);
1050 }
1051
1052 (RecorderViewImpl.prototype as Pick<APIImpl.RecorderView, 'show'>& {__proto__: APIImpl.ExtensionView}) = {
1053 show: function(this: APIImpl.RecorderView): void {
1054 if (!userAction || !userRecorderAction) {
1055 return;
1056 }
1057
1058 extensionServer.sendRequest({command: PrivateAPI.Commands.ShowRecorderView, id: this._id as string});
1059 },
1060
1061 __proto__: ExtensionViewImpl.prototype,
1062 };
1063
Philip Pfaffe6fd04c42021-06-25 12:31:481064 function ExtensionSidebarPaneImpl(this: APIImpl.ExtensionSidebarPane, id: string): void {
Blink Reformat4c46d092018-04-07 15:32:371065 ExtensionViewImpl.call(this, id);
1066 }
1067
Philip Pfaffe6fd04c42021-06-25 12:31:481068 (ExtensionSidebarPaneImpl.prototype as
1069 Pick<APIImpl.ExtensionSidebarPane, 'setHeight'|'setExpression'|'setObject'|'setPage'>&
1070 {__proto__: APIImpl.ExtensionView}) = {
1071 setHeight: function(this: APIImpl.ExtensionSidebarPane, height: string): void {
1072 extensionServer.sendRequest(
1073 {command: PrivateAPI.Commands.SetSidebarHeight, id: this._id as string, height: height});
Blink Reformat4c46d092018-04-07 15:32:371074 },
1075
Philip Pfaffe6fd04c42021-06-25 12:31:481076 setExpression: function(
1077 this: APIImpl.ExtensionSidebarPane, expression: string, rootTitle: string,
1078 evaluateOptions?: PrivateAPI.EvaluateOptions, _callback?: () => unknown): void {
Philip Pfaffe7523faf2021-06-28 14:23:141079 extensionServer.sendRequest(
1080 {
1081 command: PrivateAPI.Commands.SetSidebarContent,
Philip Pfaffe6fd04c42021-06-25 12:31:481082 id: this._id as string,
Philip Pfaffe7523faf2021-06-28 14:23:141083 expression: expression,
1084 rootTitle: rootTitle,
1085 evaluateOnPage: true,
Philip Pfaffe6fd04c42021-06-25 12:31:481086 evaluateOptions: (typeof evaluateOptions === 'object' ? evaluateOptions : {}),
Philip Pfaffe7523faf2021-06-28 14:23:141087 },
1088 extractCallbackArgument(arguments));
Blink Reformat4c46d092018-04-07 15:32:371089 },
1090
Philip Pfaffe6fd04c42021-06-25 12:31:481091 setObject: function(
1092 this: APIImpl.ExtensionSidebarPane, jsonObject: string, rootTitle?: string, callback?: () => unknown): void {
Blink Reformat4c46d092018-04-07 15:32:371093 extensionServer.sendRequest(
Philip Pfaffe6fd04c42021-06-25 12:31:481094 {
1095 command: PrivateAPI.Commands.SetSidebarContent,
1096 id: this._id as string,
1097 expression: jsonObject,
1098 rootTitle: rootTitle,
1099 },
Philip Pfaffe939605d2021-06-25 12:20:041100 callback);
Blink Reformat4c46d092018-04-07 15:32:371101 },
1102
Philip Pfaffe6fd04c42021-06-25 12:31:481103 setPage: function(this: APIImpl.ExtensionSidebarPane, page: string): void {
1104 extensionServer.sendRequest({command: PrivateAPI.Commands.SetSidebarPage, id: this._id as string, page: page});
Blink Reformat4c46d092018-04-07 15:32:371105 },
1106
Jan Schefflerd76b4162021-03-29 07:52:161107 __proto__: ExtensionViewImpl.prototype,
Blink Reformat4c46d092018-04-07 15:32:371108 };
1109
Philip Pfaffe6fd04c42021-06-25 12:31:481110 function ButtonImpl(this: APIImpl.Button, id: string): void {
Blink Reformat4c46d092018-04-07 15:32:371111 this._id = id;
Philip Pfaffe6fd04c42021-06-25 12:31:481112
1113 this.onClicked = new (Constructor(EventSink))(PrivateAPI.Events.ButtonClicked + id);
Blink Reformat4c46d092018-04-07 15:32:371114 }
1115
Philip Pfaffe6fd04c42021-06-25 12:31:481116 (ButtonImpl.prototype as Pick<APIImpl.Button, 'update'>) = {
1117 update: function(this: APIImpl.Button, iconPath?: string, tooltipText?: string, disabled?: boolean): void {
Philip Pfaffe7523faf2021-06-28 14:23:141118 extensionServer.sendRequest({
Philip Pfaffe939605d2021-06-25 12:20:041119 command: PrivateAPI.Commands.UpdateButton,
Tim van der Lipped7cfd142021-01-07 12:17:241120 id: this._id,
1121 icon: iconPath,
1122 tooltip: tooltipText,
Jan Schefflerd76b4162021-03-29 07:52:161123 disabled: Boolean(disabled),
Philip Pfaffe7523faf2021-06-28 14:23:141124 });
Jan Schefflerd76b4162021-03-29 07:52:161125 },
Blink Reformat4c46d092018-04-07 15:32:371126 };
1127
Philip Pfaffe1c827212021-06-25 12:33:201128 function Timeline(this: APIImpl.Timeline): void {
Blink Reformat4c46d092018-04-07 15:32:371129 }
1130
Philip Pfaffe1c827212021-06-25 12:33:201131 (Timeline.prototype as Pick<APIImpl.Timeline, 'addTraceProvider'>) = {
1132 addTraceProvider: function(this: APIImpl.Timeline, categoryName: string, categoryTooltip: string):
1133 APIImpl.TraceProvider {
1134 const id = 'extension-trace-provider-' + extensionServer.nextObjectId();
1135 extensionServer.sendRequest({
1136 command: PrivateAPI.Commands.AddTraceProvider,
1137 id: id,
1138 categoryName: categoryName,
1139 categoryTooltip: categoryTooltip,
1140 });
1141
1142 return new (Constructor(TraceProvider))(id);
1143 },
Blink Reformat4c46d092018-04-07 15:32:371144 };
1145
Philip Pfaffe1c827212021-06-25 12:33:201146 function TraceSessionImpl(this: APIImpl.TraceSession, id: string): void {
Blink Reformat4c46d092018-04-07 15:32:371147 this._id = id;
1148 }
1149
Philip Pfaffe1c827212021-06-25 12:33:201150 (TraceSessionImpl.prototype as Pick<APIImpl.TraceSession, 'complete'>) = {
Kateryna Prokopenko6fa122c2022-05-06 08:54:471151 complete: function(this: APIImpl.TraceSession, url?: Platform.DevToolsPath.UrlString, timeOffset?: number): void {
Philip Pfaffe7523faf2021-06-28 14:23:141152 extensionServer.sendRequest({
Philip Pfaffe939605d2021-06-25 12:20:041153 command: PrivateAPI.Commands.CompleteTraceSession,
1154 id: this._id,
Kateryna Prokopenko6fa122c2022-05-06 08:54:471155 url: url || Platform.DevToolsPath.EmptyUrlString,
Philip Pfaffe939605d2021-06-25 12:20:041156 timeOffset: timeOffset || 0,
Philip Pfaffe7523faf2021-06-28 14:23:141157 });
Jan Schefflerd76b4162021-03-29 07:52:161158 },
Blink Reformat4c46d092018-04-07 15:32:371159 };
1160
Philip Pfaffe1c827212021-06-25 12:33:201161 function TraceProvider(this: APIImpl.TraceProvider, id: string): void {
1162 function dispatchRecordingStarted(
1163 this: APIImpl.EventSink<APIImpl.Callable>, message: {arguments: unknown[]}): void {
1164 const sessionId = message.arguments[0] as string;
1165
1166 this._fire(new (Constructor(TraceSession))(sessionId));
Blink Reformat4c46d092018-04-07 15:32:371167 }
1168
Philip Pfaffe1c827212021-06-25 12:33:201169 this.onRecordingStarted =
1170 new (Constructor(EventSink))(PrivateAPI.Events.RecordingStarted + id, dispatchRecordingStarted);
1171
1172 this.onRecordingStopped = new (Constructor(EventSink))(PrivateAPI.Events.RecordingStopped + id);
Blink Reformat4c46d092018-04-07 15:32:371173 }
1174
Danil Somsikov56210832022-10-05 13:17:581175 function canAccessResource(resource: APIImpl.ResourceData): boolean {
Danil Somsikovb2e37052023-03-24 12:50:431176 try {
1177 return extensionInfo.allowFileAccess || (new URL(resource.url)).protocol !== 'file:';
1178 } catch (e) {
1179 return false;
1180 }
Danil Somsikov56210832022-10-05 13:17:581181 }
1182
Philip Pfaffeddf60d22021-06-25 12:35:411183 function InspectedWindow(this: PublicAPI.Chrome.DevTools.InspectedWindow): void {
1184 function dispatchResourceEvent(
1185 this: APIImpl.EventSink<(resource: APIImpl.Resource) => unknown>, message: {arguments: unknown[]}): void {
Danil Somsikov56210832022-10-05 13:17:581186 const resourceData = message.arguments[0] as APIImpl.ResourceData;
1187 if (!canAccessResource(resourceData)) {
1188 return;
1189 }
1190 this._fire(new (Constructor(Resource))(resourceData));
Blink Reformat4c46d092018-04-07 15:32:371191 }
1192
Philip Pfaffeddf60d22021-06-25 12:35:411193 function dispatchResourceContentEvent(
1194 this: APIImpl.EventSink<(resource: APIImpl.Resource, content: string) => unknown>,
1195 message: {arguments: unknown[]}): void {
Danil Somsikov56210832022-10-05 13:17:581196 const resourceData = message.arguments[0] as APIImpl.ResourceData;
1197 if (!canAccessResource(resourceData)) {
1198 return;
1199 }
1200 this._fire(new (Constructor(Resource))(resourceData), message.arguments[1] as string);
Blink Reformat4c46d092018-04-07 15:32:371201 }
1202
Philip Pfaffeddf60d22021-06-25 12:35:411203 this.onResourceAdded = new (Constructor(EventSink))(PrivateAPI.Events.ResourceAdded, dispatchResourceEvent);
Philip Pfaffe939605d2021-06-25 12:20:041204 this.onResourceContentCommitted =
Philip Pfaffeddf60d22021-06-25 12:35:411205 new (Constructor(EventSink))(PrivateAPI.Events.ResourceContentCommitted, dispatchResourceContentEvent);
Blink Reformat4c46d092018-04-07 15:32:371206 }
1207
Philip Pfaffeddf60d22021-06-25 12:35:411208 (InspectedWindow.prototype as Pick<PublicAPI.Chrome.DevTools.InspectedWindow, 'reload'|'eval'|'getResources'>) = {
1209 reload: function(optionsOrUserAgent: {
1210 ignoreCache?: boolean,
1211 injectedScript?: string,
1212 userAgent?: string,
1213 }): void {
Jan Schefflerd76b4162021-03-29 07:52:161214 let options: {
Philip Pfaffeddf60d22021-06-25 12:35:411215 ignoreCache?: boolean,
1216 injectedScript?: string,
1217 userAgent?: string,
Jan Schefflerd76b4162021-03-29 07:52:161218 }|null = null;
Blink Reformat4c46d092018-04-07 15:32:371219 if (typeof optionsOrUserAgent === 'object') {
1220 options = optionsOrUserAgent;
1221 } else if (typeof optionsOrUserAgent === 'string') {
1222 options = {userAgent: optionsOrUserAgent};
1223 console.warn(
1224 'Passing userAgent as string parameter to inspectedWindow.reload() is deprecated. ' +
1225 'Use inspectedWindow.reload({ userAgent: value}) instead.');
1226 }
Philip Pfaffe939605d2021-06-25 12:20:041227 extensionServer.sendRequest({command: PrivateAPI.Commands.Reload, options: options});
Blink Reformat4c46d092018-04-07 15:32:371228 },
1229
Philip Pfaffeddf60d22021-06-25 12:35:411230 eval: function(
1231 expression: string,
Benedikt Meurer6428bce2023-09-15 10:47:331232 evaluateOptions: {scriptExecutionContext?: string, frameURL?: string, useContentScriptContext?: boolean}):
Philip Pfaffeddf60d22021-06-25 12:35:411233 Object |
Jan Schefflerd76b4162021-03-29 07:52:161234 null {
1235 const callback = extractCallbackArgument(arguments);
Philip Pfaffeddf60d22021-06-25 12:35:411236 function callbackWrapper(result: unknown): void {
1237 const {isError, isException, value} = result as {
1238 isError?: boolean,
1239 isException?: boolean, value: unknown,
1240 };
1241 if (isError || isException) {
Philip Pfaffe7523faf2021-06-28 14:23:141242 callback && callback(undefined, result);
Jan Schefflerd76b4162021-03-29 07:52:161243 } else {
Philip Pfaffeddf60d22021-06-25 12:35:411244 callback && callback(value);
Jan Schefflerd76b4162021-03-29 07:52:161245 }
1246 }
Philip Pfaffe7523faf2021-06-28 14:23:141247 extensionServer.sendRequest(
1248 {
1249 command: PrivateAPI.Commands.EvaluateOnInspectedPage,
1250 expression: expression,
1251 evaluateOptions: (typeof evaluateOptions === 'object' ? evaluateOptions : undefined),
1252 },
1253 callback && callbackWrapper);
Jan Schefflerd76b4162021-03-29 07:52:161254 return null;
1255 },
Blink Reformat4c46d092018-04-07 15:32:371256
Philip Pfaffeddf60d22021-06-25 12:35:411257 getResources: function(callback?: (resources: PublicAPI.Chrome.DevTools.Resource[]) => unknown): void {
1258 function wrapResource(resourceData: APIImpl.ResourceData): APIImpl.Resource {
1259 return new (Constructor(Resource))(resourceData);
Blink Reformat4c46d092018-04-07 15:32:371260 }
Philip Pfaffeddf60d22021-06-25 12:35:411261 function callbackWrapper(resources: unknown): void {
Danil Somsikovf8035f02023-07-17 14:05:411262 callback && callback((resources as APIImpl.ResourceData[]).filter(canAccessResource).map(wrapResource));
Blink Reformat4c46d092018-04-07 15:32:371263 }
Danil Somsikov56210832022-10-05 13:17:581264 extensionServer.sendRequest({command: PrivateAPI.Commands.GetPageResources}, callback && callbackWrapper);
Jan Schefflerd76b4162021-03-29 07:52:161265 },
Blink Reformat4c46d092018-04-07 15:32:371266 };
1267
Philip Pfaffe6fd04c42021-06-25 12:31:481268 function ResourceImpl(this: APIImpl.Resource, resourceData: APIImpl.ResourceData): void {
Danil Somsikovf8035f02023-07-17 14:05:411269 if (!canAccessResource(resourceData)) {
Danil Somsikov56210832022-10-05 13:17:581270 throw new Error('Resource access not allowed');
1271 }
Blink Reformat4c46d092018-04-07 15:32:371272 this._url = resourceData.url;
1273 this._type = resourceData.type;
1274 }
1275
Philip Pfaffe6fd04c42021-06-25 12:31:481276 (ResourceImpl.prototype as Pick<APIImpl.Resource, 'url'|'type'|'getContent'|'setContent'>) = {
Jan Schefflerd76b4162021-03-29 07:52:161277 get url(): string {
Philip Pfaffe6fd04c42021-06-25 12:31:481278 return (this as APIImpl.Resource)._url;
Blink Reformat4c46d092018-04-07 15:32:371279 },
1280
Jan Schefflerd76b4162021-03-29 07:52:161281 get type(): string {
Philip Pfaffe6fd04c42021-06-25 12:31:481282 return (this as APIImpl.Resource)._type;
Blink Reformat4c46d092018-04-07 15:32:371283 },
1284
Philip Pfaffe6fd04c42021-06-25 12:31:481285 getContent: function(this: APIImpl.Resource, callback?: (content: string, encoding: string) => unknown): void {
1286 function callbackWrapper(response: unknown): void {
1287 const {content, encoding} = response as {content: string, encoding: string};
1288 callback && callback(content, encoding);
Blink Reformat4c46d092018-04-07 15:32:371289 }
1290
Philip Pfaffe939605d2021-06-25 12:20:041291 extensionServer.sendRequest(
1292 {command: PrivateAPI.Commands.GetResourceContent, url: this._url}, callback && callbackWrapper);
Blink Reformat4c46d092018-04-07 15:32:371293 },
1294
Philip Pfaffe6fd04c42021-06-25 12:31:481295 setContent: function(
1296 this: APIImpl.Resource, content: string, commit: boolean, callback: (error?: Object) => unknown): void {
Blink Reformat4c46d092018-04-07 15:32:371297 extensionServer.sendRequest(
Philip Pfaffe939605d2021-06-25 12:20:041298 {command: PrivateAPI.Commands.SetResourceContent, url: this._url, content: content, commit: commit},
Philip Pfaffe6fd04c42021-06-25 12:31:481299 callback as (response: unknown) => unknown);
Jan Schefflerd76b4162021-03-29 07:52:161300 },
Blink Reformat4c46d092018-04-07 15:32:371301 };
1302
Jan Schefflerd76b4162021-03-29 07:52:161303 function getTabId(): string {
Blink Reformat4c46d092018-04-07 15:32:371304 return inspectedTabId;
1305 }
1306
Philip Pfaffe7523faf2021-06-28 14:23:141307 let keyboardEventRequestQueue: KeyboardEventInit&{eventType: string}[] = [];
Jan Schefflerd76b4162021-03-29 07:52:161308 let forwardTimer: number|null = null;
Philip Pfaffe7523faf2021-06-28 14:23:141309 function forwardKeyboardEvent(event: KeyboardEvent): void {
Jan Schefflere7d7bb12019-10-24 09:18:521310 // Check if the event should be forwarded.
1311 // This is a workaround for crbug.com/923338.
1312 const focused = document.activeElement;
1313 if (focused) {
Benedikt Meurer5d508f62022-12-06 14:37:381314 const isInput =
1315 focused.nodeName === 'INPUT' || focused.nodeName === 'TEXTAREA' || (focused as HTMLElement).isContentEditable;
Jan Schefflere7d7bb12019-10-24 09:18:521316 if (isInput && !(event.ctrlKey || event.altKey || event.metaKey)) {
1317 return;
1318 }
1319 }
1320
Joel Einbinder67f28fb2018-08-02 00:33:471321 let modifiers = 0;
Tim van der Lippe1d6e57a2019-09-30 11:55:341322 if (event.shiftKey) {
Joel Einbinder67f28fb2018-08-02 00:33:471323 modifiers |= 1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341324 }
1325 if (event.ctrlKey) {
Joel Einbinder67f28fb2018-08-02 00:33:471326 modifiers |= 2;
Tim van der Lippe1d6e57a2019-09-30 11:55:341327 }
1328 if (event.altKey) {
Joel Einbinder67f28fb2018-08-02 00:33:471329 modifiers |= 4;
Tim van der Lippe1d6e57a2019-09-30 11:55:341330 }
1331 if (event.metaKey) {
Joel Einbinder67f28fb2018-08-02 00:33:471332 modifiers |= 8;
Tim van der Lippe1d6e57a2019-09-30 11:55:341333 }
Joel Einbinder67f28fb2018-08-02 00:33:471334 const num = (event.keyCode & 255) | (modifiers << 8);
Blink Reformat4c46d092018-04-07 15:32:371335 // We only care about global hotkeys, not about random text
Tim van der Lippe1d6e57a2019-09-30 11:55:341336 if (!keysToForwardSet.has(num)) {
Blink Reformat4c46d092018-04-07 15:32:371337 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341338 }
Joel Einbinder67f28fb2018-08-02 00:33:471339 event.preventDefault();
Blink Reformat4c46d092018-04-07 15:32:371340 const requestPayload = {
1341 eventType: event.type,
1342 ctrlKey: event.ctrlKey,
1343 altKey: event.altKey,
1344 metaKey: event.metaKey,
Joel Einbinder67f28fb2018-08-02 00:33:471345 shiftKey: event.shiftKey,
Philip Pfaffe7523faf2021-06-28 14:23:141346 // @ts-expect-error keyIdentifier is a deprecated non-standard property that typescript doesn't know about.
Blink Reformat4c46d092018-04-07 15:32:371347 keyIdentifier: event.keyIdentifier,
1348 key: event.key,
1349 code: event.code,
1350 location: event.location,
Jan Schefflerd76b4162021-03-29 07:52:161351 keyCode: event.keyCode,
Blink Reformat4c46d092018-04-07 15:32:371352 };
1353 keyboardEventRequestQueue.push(requestPayload);
Tim van der Lippe1d6e57a2019-09-30 11:55:341354 if (!forwardTimer) {
Tim van der Lippe6bcbe0f2022-01-11 13:10:311355 forwardTimer = window.setTimeout(forwardEventQueue, 0);
Tim van der Lippe1d6e57a2019-09-30 11:55:341356 }
Blink Reformat4c46d092018-04-07 15:32:371357 }
1358
Jan Schefflerd76b4162021-03-29 07:52:161359 function forwardEventQueue(): void {
Blink Reformat4c46d092018-04-07 15:32:371360 forwardTimer = null;
Philip Pfaffe7523faf2021-06-28 14:23:141361 extensionServer.sendRequest(
1362 {command: PrivateAPI.Commands.ForwardKeyboardEvent, entries: keyboardEventRequestQueue});
Blink Reformat4c46d092018-04-07 15:32:371363 keyboardEventRequestQueue = [];
1364 }
1365
1366 document.addEventListener('keydown', forwardKeyboardEvent, false);
Blink Reformat4c46d092018-04-07 15:32:371367
Alex Rudenkoa3850822022-05-24 07:34:221368 function ExtensionServerClient(this: APIImpl.ExtensionServerClient, targetWindow: Window): void {
Blink Reformat4c46d092018-04-07 15:32:371369 this._callbacks = {};
1370 this._handlers = {};
1371 this._lastRequestId = 0;
1372 this._lastObjectId = 0;
1373
1374 this.registerHandler('callback', this._onCallback.bind(this));
1375
1376 const channel = new MessageChannel();
1377 this._port = channel.port1;
1378 this._port.addEventListener('message', this._onMessage.bind(this), false);
1379 this._port.start();
1380
Alex Rudenkoa3850822022-05-24 07:34:221381 targetWindow.postMessage('registerExtension', '*', [channel.port2]);
Blink Reformat4c46d092018-04-07 15:32:371382 }
1383
Philip Pfaffe7523faf2021-06-28 14:23:141384 (ExtensionServerClient.prototype as Pick<
1385 APIImpl.ExtensionServerClient,
1386 'sendRequest'|'hasHandler'|'registerHandler'|'unregisterHandler'|'nextObjectId'|'_registerCallback'|
1387 '_onCallback'|'_onMessage'>) = {
Philip Pfaffe6ed01262022-07-06 10:41:391388 sendRequest: function<ResponseT>(
Philip Pfaffe7523faf2021-06-28 14:23:141389 this: APIImpl.ExtensionServerClient, message: PrivateAPI.ServerRequests,
Philip Pfaffe6ed01262022-07-06 10:41:391390 callback?: (response: ResponseT) => unknown, transfers?: Transferable[]): void {
Philip Pfaffe7523faf2021-06-28 14:23:141391 if (typeof callback === 'function') {
Philip Pfaffe6ed01262022-07-06 10:41:391392 (message as PrivateAPI.ExtensionServerRequestMessage).requestId =
1393 this._registerCallback(callback as (response: unknown) => unknown);
Philip Pfaffe7523faf2021-06-28 14:23:141394 }
1395 // @ts-expect-error
1396 this._port.postMessage(message, transfers);
1397 },
Blink Reformat4c46d092018-04-07 15:32:371398
Philip Pfaffe7523faf2021-06-28 14:23:141399 hasHandler: function(this: APIImpl.ExtensionServerClient, command: string): boolean {
Tim van der Lipped7cfd142021-01-07 12:17:241400 return Boolean(this._handlers[command]);
Blink Reformat4c46d092018-04-07 15:32:371401 },
1402
Philip Pfaffe7523faf2021-06-28 14:23:141403 registerHandler: function(
1404 this: APIImpl.ExtensionServerClient, command: string, handler: (request: {arguments: unknown[]}) => unknown):
1405 void {
1406 this._handlers[command] = handler;
1407 },
Blink Reformat4c46d092018-04-07 15:32:371408
Philip Pfaffe7523faf2021-06-28 14:23:141409 unregisterHandler: function(this: APIImpl.ExtensionServerClient, command: string): void {
Blink Reformat4c46d092018-04-07 15:32:371410 delete this._handlers[command];
1411 },
1412
Philip Pfaffe7523faf2021-06-28 14:23:141413 nextObjectId: function(this: APIImpl.ExtensionServerClient): string {
Blink Reformat4c46d092018-04-07 15:32:371414 return injectedScriptId.toString() + '_' + ++this._lastObjectId;
1415 },
1416
Philip Pfaffe7523faf2021-06-28 14:23:141417 _registerCallback: function(this: APIImpl.ExtensionServerClient, callback: (response: unknown) => unknown): number {
Blink Reformat4c46d092018-04-07 15:32:371418 const id = ++this._lastRequestId;
1419 this._callbacks[id] = callback;
1420 return id;
1421 },
1422
Philip Pfaffe7523faf2021-06-28 14:23:141423 _onCallback: function(this: APIImpl.ExtensionServerClient, request: {requestId: number, result: unknown}): void {
Blink Reformat4c46d092018-04-07 15:32:371424 if (request.requestId in this._callbacks) {
1425 const callback = this._callbacks[request.requestId];
1426 delete this._callbacks[request.requestId];
1427 callback(request.result);
1428 }
1429 },
1430
Philip Pfaffe7523faf2021-06-28 14:23:141431 _onMessage: function(
1432 this: APIImpl.ExtensionServerClient,
1433 event: MessageEvent<{command: string, requestId: number, arguments: unknown[]}>): void {
Blink Reformat4c46d092018-04-07 15:32:371434 const request = event.data;
1435 const handler = this._handlers[request.command];
Tim van der Lippe1d6e57a2019-09-30 11:55:341436 if (handler) {
Blink Reformat4c46d092018-04-07 15:32:371437 handler.call(this, request);
Tim van der Lippe1d6e57a2019-09-30 11:55:341438 }
Jan Schefflerd76b4162021-03-29 07:52:161439 },
Blink Reformat4c46d092018-04-07 15:32:371440 };
1441
Philip Pfaffe7523faf2021-06-28 14:23:141442 function populateInterfaceClass(interfaze: {[key: string]: unknown}, implementation: {[key: string]: unknown}): void {
Blink Reformat4c46d092018-04-07 15:32:371443 for (const member in implementation) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341444 if (member.charAt(0) === '_') {
Blink Reformat4c46d092018-04-07 15:32:371445 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341446 }
Jan Schefflerd76b4162021-03-29 07:52:161447 let descriptor: (PropertyDescriptor|undefined)|null = null;
Blink Reformat4c46d092018-04-07 15:32:371448 // Traverse prototype chain until we find the owner.
Philip Pfaffe7523faf2021-06-28 14:23:141449 for (let owner = implementation; owner && !descriptor; owner = owner.__proto__ as {[key: string]: unknown}) {
Blink Reformat4c46d092018-04-07 15:32:371450 descriptor = Object.getOwnPropertyDescriptor(owner, member);
Tim van der Lippe1d6e57a2019-09-30 11:55:341451 }
1452 if (!descriptor) {
Blink Reformat4c46d092018-04-07 15:32:371453 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341454 }
1455 if (typeof descriptor.value === 'function') {
Blink Reformat4c46d092018-04-07 15:32:371456 interfaze[member] = descriptor.value.bind(implementation);
Tim van der Lippe1d6e57a2019-09-30 11:55:341457 } else if (typeof descriptor.get === 'function') {
Philip Pfaffe7523faf2021-06-28 14:23:141458 // @ts-expect-error
Blink Reformat4c46d092018-04-07 15:32:371459 interfaze.__defineGetter__(member, descriptor.get.bind(implementation));
Tim van der Lippe1d6e57a2019-09-30 11:55:341460 } else {
Blink Reformat4c46d092018-04-07 15:32:371461 Object.defineProperty(interfaze, member, descriptor);
Tim van der Lippe1d6e57a2019-09-30 11:55:341462 }
Blink Reformat4c46d092018-04-07 15:32:371463 }
1464 }
1465
Alex Rudenkoa3850822022-05-24 07:34:221466 const extensionServer = new (Constructor(ExtensionServerClient))(targetWindowForTest || window.parent);
Philip Pfaffe7523faf2021-06-28 14:23:141467
1468 const coreAPI = new (Constructor(InspectorExtensionAPI))();
Blink Reformat4c46d092018-04-07 15:32:371469
1470 Object.defineProperty(chrome, 'devtools', {value: {}, enumerable: true});
1471
1472 // Only expose tabId on chrome.devtools.inspectedWindow, not webInspector.inspectedWindow.
Philip Pfaffe7523faf2021-06-28 14:23:141473 // @ts-expect-error
1474 chrome.devtools!.inspectedWindow = {};
1475 Object.defineProperty(chrome.devtools!.inspectedWindow, 'tabId', {get: getTabId});
1476 // @ts-expect-error
1477 chrome.devtools!.inspectedWindow.__proto__ = coreAPI.inspectedWindow;
1478 chrome.devtools!.network = coreAPI.network;
1479 chrome.devtools!.panels = coreAPI.panels;
1480 chrome.devtools!.panels.themeName = themeName;
1481 chrome.devtools!.languageServices = coreAPI.languageServices;
Alex Rudenkoa3850822022-05-24 07:34:221482 chrome.devtools!.recorder = coreAPI.recorder;
Blink Reformat4c46d092018-04-07 15:32:371483
1484 // default to expose experimental APIs for now.
1485 if (extensionInfo.exposeExperimentalAPIs !== false) {
1486 chrome.experimental = chrome.experimental || {};
1487 chrome.experimental.devtools = chrome.experimental.devtools || {};
1488
1489 const properties = Object.getOwnPropertyNames(coreAPI);
1490 for (let i = 0; i < properties.length; ++i) {
1491 const descriptor = Object.getOwnPropertyDescriptor(coreAPI, properties[i]);
Tim van der Lippe1d6e57a2019-09-30 11:55:341492 if (descriptor) {
Blink Reformat4c46d092018-04-07 15:32:371493 Object.defineProperty(chrome.experimental.devtools, properties[i], descriptor);
Tim van der Lippe1d6e57a2019-09-30 11:55:341494 }
Blink Reformat4c46d092018-04-07 15:32:371495 }
1496 chrome.experimental.devtools.inspectedWindow = chrome.devtools.inspectedWindow;
1497 }
1498
Tim van der Lippe1d6e57a2019-09-30 11:55:341499 if (extensionInfo.exposeWebInspectorNamespace) {
Blink Reformat4c46d092018-04-07 15:32:371500 window.webInspector = coreAPI;
Tim van der Lippe1d6e57a2019-09-30 11:55:341501 }
Blink Reformat4c46d092018-04-07 15:32:371502 testHook(extensionServer, coreAPI);
Tim van der Lippe226fc222019-10-10 12:17:121503};
Blink Reformat4c46d092018-04-07 15:32:371504
Jan Schefflerd76b4162021-03-29 07:52:161505self.buildExtensionAPIInjectedScript = function(
1506 extensionInfo: {
1507 startPage: string,
1508 name: string,
1509 exposeExperimentalAPIs: boolean,
1510 },
1511 inspectedTabId: string, themeName: string, keysToForward: number[],
Philip Pfaffe7523faf2021-06-28 14:23:141512 testHook:
1513 ((extensionServer: APIImpl.ExtensionServerClient, extensionAPI: APIImpl.InspectorExtensionAPI) => unknown)|
1514 undefined): string {
Philip Pfaffeedad8322020-07-20 10:24:251515 const argumentsJSON =
1516 [extensionInfo, inspectedTabId || null, themeName, keysToForward].map(_ => JSON.stringify(_)).join(',');
Tim van der Lippe1d6e57a2019-09-30 11:55:341517 if (!testHook) {
Jan Schefflerd76b4162021-03-29 07:52:161518 testHook = (): void => {};
Tim van der Lippe1d6e57a2019-09-30 11:55:341519 }
Philip Pfaffe939605d2021-06-25 12:20:041520 return '(function(injectedScriptId){ ' +
Tim van der Lippe226fc222019-10-10 12:17:121521 '(' + self.injectedExtensionAPI.toString() + ')(' + argumentsJSON + ',' + testHook + ', injectedScriptId);' +
Blink Reformat4c46d092018-04-07 15:32:371522 '})';
Tim van der Lippe29fab472019-08-15 14:46:481523};