blob: 0709c7916c89b720a4123c496b7e1690a4c64f89 [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 };
269 type GetTypeInfoRequest = {
270 method: LanguageExtensionPluginCommands.GetTypeInfo,
271 parameters: {expression: string, context: PublicAPI.Chrome.DevTools.RawLocation},
272 };
273 type GetFormatterRequest = {
274 method: LanguageExtensionPluginCommands.GetFormatter,
275 parameters: {
276 expressionOrField: string|{
277 base: PublicAPI.Chrome.DevTools.EvalBase,
278 field: Array<PublicAPI.Chrome.DevTools.FieldInfo>,
279 },
280 context: PublicAPI.Chrome.DevTools.RawLocation,
281 },
282 };
283 type GetInspectableAddressRequest = {
284 method: LanguageExtensionPluginCommands.GetInspectableAddress,
285 parameters: {
286 field: {
287 base: PublicAPI.Chrome.DevTools.EvalBase,
288 field: Array<PublicAPI.Chrome.DevTools.FieldInfo>,
289 },
290 },
291 };
292 type GetFunctionInfoRequest = {
293 method: LanguageExtensionPluginCommands.GetFunctionInfo,
294 parameters: {rawLocation: PublicAPI.Chrome.DevTools.RawLocation},
295 };
296 type GetInlinedFunctionRangesRequest = {
297 method: LanguageExtensionPluginCommands.GetInlinedFunctionRanges,
298 parameters: {rawLocation: PublicAPI.Chrome.DevTools.RawLocation},
299 };
300 type GetInlinedCalleesRangesRequest = {
301 method: LanguageExtensionPluginCommands.GetInlinedCalleesRanges,
302 parameters: {rawLocation: PublicAPI.Chrome.DevTools.RawLocation},
303 };
304 type GetMappedLinesRequest = {
305 method: LanguageExtensionPluginCommands.GetMappedLines,
306 parameters: {rawModuleId: string, sourceFileURL: string},
307 };
Philip Pfaffe6ed01262022-07-06 10:41:39308 type FormatValueRequest = {
309 method: LanguageExtensionPluginCommands.FormatValue,
310 parameters: {expression: string, context: PublicAPI.Chrome.DevTools.RawLocation, stopId: number},
311 };
312 type GetPropertiesRequest = {
313 method: LanguageExtensionPluginCommands.GetProperties,
314 parameters: {objectId: PublicAPI.Chrome.DevTools.RemoteObjectId},
315 };
316 type ReleaseObjectRequest = {
317 method: LanguageExtensionPluginCommands.ReleaseObject,
318 parameters: {objectId: PublicAPI.Chrome.DevTools.RemoteObjectId},
319 };
Philip Pfaffec5d160e2021-07-20 10:53:32320
Philip Pfaffe6ed01262022-07-06 10:41:39321 export type LanguageExtensionRequests =
322 AddRawModuleRequest|SourceLocationToRawLocationRequest|RawLocationToSourceLocationRequest|GetScopeInfoRequest|
323 ListVariablesInScopeRequest|RemoveRawModuleRequest|GetTypeInfoRequest|GetFormatterRequest|
324 GetInspectableAddressRequest|GetFunctionInfoRequest|GetInlinedFunctionRangesRequest|
325 GetInlinedCalleesRangesRequest|GetMappedLinesRequest|FormatValueRequest|GetPropertiesRequest|ReleaseObjectRequest;
Alex Rudenkoa3850822022-05-24 07:34:22326
327 type StringifyRequest = {
328 method: RecorderExtensionPluginCommands.Stringify,
329 parameters: {recording: Record<string, unknown>},
330 };
331
Alex Rudenko2aa04c02022-06-01 13:05:20332 type StringifyStepRequest = {
333 method: RecorderExtensionPluginCommands.StringifyStep,
334 parameters: {step: Record<string, unknown>},
335 };
336
Alex Rudenko0b8b8882023-01-17 12:21:49337 type ReplayRequest = {
338 method: RecorderExtensionPluginCommands.Replay,
339 parameters: {recording: Record<string, unknown>},
340 };
341
342 export type RecorderExtensionRequests = StringifyRequest|StringifyStepRequest|ReplayRequest;
Blink Reformat4c46d092018-04-07 15:32:37343}
344
Philip Pfaffe939605d2021-06-25 12:20:04345declare global {
346 interface Window {
347 injectedExtensionAPI:
348 (extensionInfo: ExtensionDescriptor, inspectedTabId: string, themeName: string, keysToForward: number[],
Philip Pfaffe7523faf2021-06-28 14:23:14349 testHook:
350 (extensionServer: APIImpl.ExtensionServerClient, extensionAPI: APIImpl.InspectorExtensionAPI) => unknown,
Alex Rudenkoa3850822022-05-24 07:34:22351 injectedScriptId: number, targetWindow?: Window) => void;
Philip Pfaffe939605d2021-06-25 12:20:04352 buildExtensionAPIInjectedScript(
353 extensionInfo: ExtensionDescriptor, inspectedTabId: string, themeName: string, keysToForward: number[],
Philip Pfaffed662bdf2021-06-25 13:30:32354 testHook: undefined|((extensionServer: unknown, extensionAPI: unknown) => unknown)): string;
Philip Pfaffe7523faf2021-06-28 14:23:14355 chrome: PublicAPI.Chrome.DevTools.Chrome;
356 webInspector?: APIImpl.InspectorExtensionAPI;
Philip Pfaffe939605d2021-06-25 12:20:04357 }
358}
359
360export type ExtensionDescriptor = {
361 startPage: string,
362 name: string,
363 exposeExperimentalAPIs: boolean,
364 exposeWebInspectorNamespace?: boolean,
Danil Somsikov28cfaf32022-09-27 15:36:55365 allowFileAccess?: boolean,
Philip Pfaffe939605d2021-06-25 12:20:04366};
367
Philip Pfaffe7523faf2021-06-28 14:23:14368namespace APIImpl {
369 export interface InspectorExtensionAPI {
370 languageServices: PublicAPI.Chrome.DevTools.LanguageExtensions;
Alex Rudenkoa3850822022-05-24 07:34:22371 recorder: PublicAPI.Chrome.DevTools.RecorderExtensions;
Philip Pfaffe1c827212021-06-25 12:33:20372 timeline: Timeline;
Philip Pfaffe7523faf2021-06-28 14:23:14373 network: PublicAPI.Chrome.DevTools.Network;
374 panels: PublicAPI.Chrome.DevTools.Panels;
375 inspectedWindow: PublicAPI.Chrome.DevTools.InspectedWindow;
376 }
377
378 export interface ExtensionServerClient {
379 _callbacks: {[key: string]: (response: unknown) => unknown};
380 _handlers: {[key: string]: (request: {arguments: unknown[]}) => unknown};
381 _lastRequestId: number;
382 _lastObjectId: number;
383 _port: MessagePort;
384
385 _onCallback(request: unknown): void;
386 _onMessage(event: MessageEvent<{command: string, requestId: number, arguments: unknown[]}>): void;
387 _registerCallback(callback: (response: unknown) => unknown): number;
388 registerHandler(command: string, handler: (request: {arguments: unknown[]}) => unknown): void;
389 unregisterHandler(command: string): void;
390 hasHandler(command: string): boolean;
Philip Pfaffe6ed01262022-07-06 10:41:39391 sendRequest<ResponseT>(
392 request: PrivateAPI.ServerRequests, callback?: ((response: ResponseT) => unknown), transfers?: unknown[]): void;
Philip Pfaffe7523faf2021-06-28 14:23:14393 nextObjectId(): string;
394 }
395
396 // We cannot use the stronger `unknown` type in place of `any` in the following type definition. The type is used as
397 // the right-hand side of `extends` in a few places, which doesn't narrow `unknown`. Without narrowing, overload
398 // resolution and meaningful type inference of arguments break, for example.
Tim van der Lippe269e9ae2021-12-14 13:33:28399 // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
Philip Pfaffe7523faf2021-06-28 14:23:14400 // eslint-disable-next-line @typescript-eslint/no-explicit-any
Tim van der Lippe269e9ae2021-12-14 13:33:28401 export type Callable = (...args: any) => void;
Philip Pfaffe7523faf2021-06-28 14:23:14402
403 export interface EventSink<ListenerT extends Callable> extends PublicAPI.Chrome.DevTools.EventSink<ListenerT> {
404 _type: string;
405 _listeners: ListenerT[];
406 _customDispatch: undefined|((this: EventSink<ListenerT>, request: {arguments: unknown[]}) => unknown);
407
408 _fire(..._vararg: Parameters<ListenerT>): void;
409 _dispatch(request: {arguments: unknown[]}): void;
410 }
Philip Pfaffe4b88c662021-06-25 12:30:47411
412 export interface Network extends PublicAPI.Chrome.DevTools.Network {
413 addRequestHeaders(headers: {[key: string]: string}): void;
414 }
415
416 export interface Request extends PublicAPI.Chrome.DevTools.Request, HAR.Log.EntryDTO {
417 _id: number;
418 }
Philip Pfaffe6fd04c42021-06-25 12:31:48419
420 export interface Panels extends PublicAPI.Chrome.DevTools.Panels {
421 get SearchAction(): {[key: string]: string};
422 applyStyleSheet(styleSheet: string): void;
423 setOpenResourceHandler(callback?: (resource: PublicAPI.Chrome.DevTools.Resource, lineNumber: number) => unknown):
424 void;
Paul Lewisada689f2022-01-11 12:03:40425 setThemeChangeHandler(callback?: (themeName: string) => unknown): void;
Philip Pfaffe6fd04c42021-06-25 12:31:48426 }
427
428 export interface ExtensionView extends PublicAPI.Chrome.DevTools.ExtensionView {
429 _id: string|null;
430 }
431
432 export interface ExtensionSidebarPane extends ExtensionView, PublicAPI.Chrome.DevTools.ExtensionSidebarPane {
433 setExpression(
434 expression: string, rootTitle?: string, evaluteOptions?: PrivateAPI.EvaluateOptions,
435 callback?: () => unknown): void;
436 }
437
438 export interface PanelWithSidebar extends ExtensionView, PublicAPI.Chrome.DevTools.PanelWithSidebar {
439 _hostPanelName: string;
440 }
441
442 export interface LanguageExtensions extends PublicAPI.Chrome.DevTools.LanguageExtensions {
443 _plugins: Map<PublicAPI.Chrome.DevTools.LanguageExtensionPlugin, MessagePort>;
444 }
445
Alex Rudenkoa3850822022-05-24 07:34:22446 export interface RecorderExtensions extends PublicAPI.Chrome.DevTools.RecorderExtensions {
447 _plugins: Map<PublicAPI.Chrome.DevTools.RecorderExtensionPlugin, MessagePort>;
448 }
449
Philip Pfaffe6fd04c42021-06-25 12:31:48450 export interface ExtensionPanel extends ExtensionView, PublicAPI.Chrome.DevTools.ExtensionPanel {
451 show(): void;
452 }
453
Alex Rudenko0b8b8882023-01-17 12:21:49454 export interface RecorderView extends ExtensionView, PublicAPI.Chrome.DevTools.RecorderView {}
455
Philip Pfaffe6fd04c42021-06-25 12:31:48456 export interface Button extends PublicAPI.Chrome.DevTools.Button {
457 _id: string;
458 }
459
Philip Pfaffe1c827212021-06-25 12:33:20460 export interface TraceSession {
461 _id: string;
462
463 complete(url?: string, timeOffset?: number): void;
464 }
465
466 export interface TraceProvider {
467 onRecordingStarted: EventSink<(session: TraceSession) => unknown>;
468 onRecordingStopped: EventSink<() => unknown>;
469 }
470
471 export interface Timeline {
472 addTraceProvider(categoryName: string, categoryTooltip: string): TraceProvider;
473 }
474
Philip Pfaffe6fd04c42021-06-25 12:31:48475 export type ResourceData = {url: string, type: string};
476 export interface Resource extends PublicAPI.Chrome.DevTools.Resource {
477 _type: string;
478 _url: string;
479
480 get type(): string;
481 }
Philip Pfaffe7523faf2021-06-28 14:23:14482}
Philip Pfaffe939605d2021-06-25 12:20:04483
Tim van der Lippe226fc222019-10-10 12:17:12484self.injectedExtensionAPI = function(
Philip Pfaffe7523faf2021-06-28 14:23:14485 extensionInfo: ExtensionDescriptor, inspectedTabId: string, themeName: string, keysToForward: number[],
486 testHook: (extensionServer: APIImpl.ExtensionServerClient, extensionAPI: APIImpl.InspectorExtensionAPI) => unknown,
Alex Rudenkoa3850822022-05-24 07:34:22487 injectedScriptId: number, targetWindowForTest?: Window): void {
Jan Schefflerd76b4162021-03-29 07:52:16488 const keysToForwardSet = new Set<number>(keysToForward);
Blink Reformat4c46d092018-04-07 15:32:37489 const chrome = window.chrome || {};
Jan Schefflerd76b4162021-03-29 07:52:16490
Blink Reformat4c46d092018-04-07 15:32:37491 const devtools_descriptor = Object.getOwnPropertyDescriptor(chrome, 'devtools');
Tim van der Lippe1d6e57a2019-09-30 11:55:34492 if (devtools_descriptor) {
Blink Reformat4c46d092018-04-07 15:32:37493 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34494 }
Blink Reformat4c46d092018-04-07 15:32:37495 let userAction = false;
Alex Rudenko0b8b8882023-01-17 12:21:49496 let userRecorderAction = false;
Blink Reformat4c46d092018-04-07 15:32:37497
498 // Here and below, all constructors are private to API implementation.
499 // For a public type Foo, if internal fields are present, these are on
500 // a private FooImpl type, an instance of FooImpl is used in a closure
501 // by Foo consutrctor to re-bind publicly exported members to an instance
502 // of Foo.
503
Philip Pfaffe7523faf2021-06-28 14:23:14504 function EventSinkImpl<ListenerT extends APIImpl.Callable>(
505 this: APIImpl.EventSink<ListenerT>, type: string,
506 customDispatch?: (this: APIImpl.EventSink<ListenerT>, request: {arguments: unknown[]}) => unknown): void {
Blink Reformat4c46d092018-04-07 15:32:37507 this._type = type;
508 this._listeners = [];
509 this._customDispatch = customDispatch;
510 }
511
512 EventSinkImpl.prototype = {
Philip Pfaffe7523faf2021-06-28 14:23:14513 addListener: function<ListenerT extends APIImpl.Callable>(this: APIImpl.EventSink<ListenerT>, callback: ListenerT):
514 void {
515 if (typeof callback !== 'function') {
516 throw 'addListener: callback is not a function';
517 }
518 if (this._listeners.length === 0) {
519 extensionServer.sendRequest({command: PrivateAPI.Commands.Subscribe, type: this._type});
520 }
521 this._listeners.push(callback);
522 extensionServer.registerHandler('notify-' + this._type, this._dispatch.bind(this));
523 },
Blink Reformat4c46d092018-04-07 15:32:37524
Philip Pfaffe7523faf2021-06-28 14:23:14525 removeListener: function<ListenerT extends APIImpl.Callable>(
526 this: APIImpl.EventSink<ListenerT>, callback: ListenerT): void {
Blink Reformat4c46d092018-04-07 15:32:37527 const listeners = this._listeners;
528
529 for (let i = 0; i < listeners.length; ++i) {
530 if (listeners[i] === callback) {
531 listeners.splice(i, 1);
532 break;
533 }
534 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34535 if (this._listeners.length === 0) {
Philip Pfaffe939605d2021-06-25 12:20:04536 extensionServer.sendRequest({command: PrivateAPI.Commands.Unsubscribe, type: this._type});
Tim van der Lippe1d6e57a2019-09-30 11:55:34537 }
Blink Reformat4c46d092018-04-07 15:32:37538 },
539
Philip Pfaffe7523faf2021-06-28 14:23:14540 _fire: function<ListenerT extends APIImpl.Callable>(
541 this: APIImpl.EventSink<ListenerT>, ..._vararg: Parameters<ListenerT>): void {
Blink Reformat4c46d092018-04-07 15:32:37542 const listeners = this._listeners.slice();
Tim van der Lippe1d6e57a2019-09-30 11:55:34543 for (let i = 0; i < listeners.length; ++i) {
Philip Pfaffe7523faf2021-06-28 14:23:14544 listeners[i].apply(null, Array.from(arguments));
Tim van der Lippe1d6e57a2019-09-30 11:55:34545 }
Blink Reformat4c46d092018-04-07 15:32:37546 },
547
Philip Pfaffe7523faf2021-06-28 14:23:14548 _dispatch: function<ListenerT extends APIImpl.Callable>(
549 this: APIImpl.EventSink<ListenerT>, request: {arguments: unknown[]}): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:34550 if (this._customDispatch) {
Blink Reformat4c46d092018-04-07 15:32:37551 this._customDispatch.call(this, request);
Tim van der Lippe1d6e57a2019-09-30 11:55:34552 } else {
Philip Pfaffe7523faf2021-06-28 14:23:14553 this._fire.apply(this, request.arguments as Parameters<ListenerT>);
Tim van der Lippe1d6e57a2019-09-30 11:55:34554 }
Jan Schefflerd76b4162021-03-29 07:52:16555 },
Blink Reformat4c46d092018-04-07 15:32:37556 };
557
Philip Pfaffe7523faf2021-06-28 14:23:14558 function Constructor<NewT extends APIImpl.Callable>(ctor: NewT): new (...args: Parameters<NewT>) =>
559 ThisParameterType<NewT> {
560 return ctor as unknown as new (...args: Parameters<NewT>) => ThisParameterType<NewT>;
561 }
562
Philip Pfaffe7523faf2021-06-28 14:23:14563 function InspectorExtensionAPI(this: APIImpl.InspectorExtensionAPI): void {
Philip Pfaffeddf60d22021-06-25 12:35:41564 this.inspectedWindow = new (Constructor(InspectedWindow))();
Philip Pfaffe6fd04c42021-06-25 12:31:48565 this.panels = new (Constructor(Panels))();
Philip Pfaffe4b88c662021-06-25 12:30:47566 this.network = new (Constructor(Network))();
Philip Pfaffe1c827212021-06-25 12:33:20567 this.timeline = new (Constructor(Timeline))();
Philip Pfaffec5d160e2021-07-20 10:53:32568 this.languageServices = new (Constructor(LanguageServicesAPI))();
Alex Rudenkoa3850822022-05-24 07:34:22569 this.recorder = new (Constructor(RecorderServicesAPI))();
Blink Reformat4c46d092018-04-07 15:32:37570 defineDeprecatedProperty(this, 'webInspector', 'resources', 'network');
571 }
572
Philip Pfaffe4b88c662021-06-25 12:30:47573 function Network(this: APIImpl.Network): void {
574 function dispatchRequestEvent(
575 this: APIImpl.EventSink<(request: PublicAPI.Chrome.DevTools.Request) => unknown>,
576 message: {arguments: unknown[]}): void {
577 const request = message.arguments[1] as APIImpl.Request & {__proto__: APIImpl.Request};
578
579 request.__proto__ = new (Constructor(Request))(message.arguments[0] as number);
Blink Reformat4c46d092018-04-07 15:32:37580 this._fire(request);
581 }
Philip Pfaffe4b88c662021-06-25 12:30:47582
583 this.onRequestFinished =
584 new (Constructor(EventSink))(PrivateAPI.Events.NetworkRequestFinished, dispatchRequestEvent);
Blink Reformat4c46d092018-04-07 15:32:37585 defineDeprecatedProperty(this, 'network', 'onFinished', 'onRequestFinished');
Philip Pfaffe4b88c662021-06-25 12:30:47586
587 this.onNavigated = new (Constructor(EventSink))(PrivateAPI.Events.InspectedURLChanged);
Blink Reformat4c46d092018-04-07 15:32:37588 }
589
Philip Pfaffe4b88c662021-06-25 12:30:47590 (Network.prototype as Pick<APIImpl.Network, 'getHAR'|'addRequestHeaders'>) = {
591 getHAR: function(this: PublicAPI.Chrome.DevTools.Network, callback?: (harLog: Object) => unknown): void {
592 function callbackWrapper(response: unknown): void {
593 const result =
594 response as ({entries: Array<HAR.Log.EntryDTO&{__proto__?: APIImpl.Request, _requestId?: number}>});
Blink Reformat4c46d092018-04-07 15:32:37595 const entries = (result && result.entries) || [];
596 for (let i = 0; i < entries.length; ++i) {
Philip Pfaffe4b88c662021-06-25 12:30:47597 entries[i].__proto__ = new (Constructor(Request))(entries[i]._requestId as number);
Blink Reformat4c46d092018-04-07 15:32:37598 delete entries[i]._requestId;
599 }
Philip Pfaffe4b88c662021-06-25 12:30:47600 callback && callback(result as Object);
Blink Reformat4c46d092018-04-07 15:32:37601 }
Philip Pfaffe939605d2021-06-25 12:20:04602 extensionServer.sendRequest({command: PrivateAPI.Commands.GetHAR}, callback && callbackWrapper);
Blink Reformat4c46d092018-04-07 15:32:37603 },
604
Philip Pfaffe4b88c662021-06-25 12:30:47605 addRequestHeaders: function(headers: {[key: string]: string}): void {
Blink Reformat4c46d092018-04-07 15:32:37606 extensionServer.sendRequest(
Philip Pfaffe939605d2021-06-25 12:20:04607 {command: PrivateAPI.Commands.AddRequestHeaders, headers: headers, extensionId: window.location.hostname});
Jan Schefflerd76b4162021-03-29 07:52:16608 },
Blink Reformat4c46d092018-04-07 15:32:37609 };
610
Philip Pfaffe4b88c662021-06-25 12:30:47611 function RequestImpl(this: APIImpl.Request, id: number): void {
Blink Reformat4c46d092018-04-07 15:32:37612 this._id = id;
613 }
614
Philip Pfaffe4b88c662021-06-25 12:30:47615 (RequestImpl.prototype as Pick<APIImpl.Request, 'getContent'>) = {
616 getContent: function(this: APIImpl.Request, callback?: (content: string, encoding: string) => unknown): void {
617 function callbackWrapper(response: unknown): void {
618 const {content, encoding} = response as {content: string, encoding: string};
619 callback && callback(content, encoding);
Blink Reformat4c46d092018-04-07 15:32:37620 }
Philip Pfaffe939605d2021-06-25 12:20:04621 extensionServer.sendRequest(
622 {command: PrivateAPI.Commands.GetRequestContent, id: this._id}, callback && callbackWrapper);
Jan Schefflerd76b4162021-03-29 07:52:16623 },
Blink Reformat4c46d092018-04-07 15:32:37624 };
625
Philip Pfaffe6fd04c42021-06-25 12:31:48626 function Panels(this: APIImpl.Panels): void {
627 const panels: {[key: string]: ElementsPanel|SourcesPanel} = {
Blink Reformat4c46d092018-04-07 15:32:37628 elements: new ElementsPanel(),
629 sources: new SourcesPanel(),
630 };
631
Philip Pfaffe6fd04c42021-06-25 12:31:48632 function panelGetter(name: string): ElementsPanel|SourcesPanel {
Blink Reformat4c46d092018-04-07 15:32:37633 return panels[name];
634 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34635 for (const panel in panels) {
Tim van der Lippeffa78622019-09-16 12:07:12636 Object.defineProperty(this, panel, {get: panelGetter.bind(null, panel), enumerable: true});
Tim van der Lippe1d6e57a2019-09-30 11:55:34637 }
Philip Pfaffe6fd04c42021-06-25 12:31:48638 this.applyStyleSheet = function(styleSheet: string): void {
Philip Pfaffe939605d2021-06-25 12:20:04639 extensionServer.sendRequest({command: PrivateAPI.Commands.ApplyStyleSheet, styleSheet: styleSheet});
Blink Reformat4c46d092018-04-07 15:32:37640 };
641 }
642
Paul Lewisada689f2022-01-11 12:03:40643 (Panels.prototype as
644 Pick<APIImpl.Panels, 'create'|'setOpenResourceHandler'|'openResource'|'SearchAction'|'setThemeChangeHandler'>) = {
Philip Pfaffe6fd04c42021-06-25 12:31:48645 create: function(
646 title: string, icon: string, page: string,
647 callback: (panel: PublicAPI.Chrome.DevTools.ExtensionPanel) => unknown): void {
Blink Reformat4c46d092018-04-07 15:32:37648 const id = 'extension-panel-' + extensionServer.nextObjectId();
Philip Pfaffe6fd04c42021-06-25 12:31:48649 extensionServer.sendRequest(
650 {command: PrivateAPI.Commands.CreatePanel, id, title, page},
Philip Pfaffe3abccb42021-09-14 09:18:37651 callback && ((): unknown => callback.call(this, new (Constructor(ExtensionPanel))(id))));
Blink Reformat4c46d092018-04-07 15:32:37652 },
653
Philip Pfaffe6fd04c42021-06-25 12:31:48654 setOpenResourceHandler: function(
655 callback: (resource: PublicAPI.Chrome.DevTools.Resource, lineNumber: number) => unknown): void {
Philip Pfaffe939605d2021-06-25 12:20:04656 const hadHandler = extensionServer.hasHandler(PrivateAPI.Events.OpenResource);
Blink Reformat4c46d092018-04-07 15:32:37657
Philip Pfaffe6fd04c42021-06-25 12:31:48658 function callbackWrapper(message: unknown): void {
Blink Reformat4c46d092018-04-07 15:32:37659 // Allow the panel to show itself when handling the event.
660 userAction = true;
661 try {
Philip Pfaffe6fd04c42021-06-25 12:31:48662 const {resource, lineNumber} = message as {resource: APIImpl.ResourceData, lineNumber: number};
Danil Somsikov56210832022-10-05 13:17:58663 if (canAccessResource(resource)) {
664 callback.call(null, new (Constructor(Resource))(resource), lineNumber);
665 }
Blink Reformat4c46d092018-04-07 15:32:37666 } finally {
667 userAction = false;
668 }
669 }
670
Tim van der Lippe1d6e57a2019-09-30 11:55:34671 if (!callback) {
Philip Pfaffe939605d2021-06-25 12:20:04672 extensionServer.unregisterHandler(PrivateAPI.Events.OpenResource);
Tim van der Lippe1d6e57a2019-09-30 11:55:34673 } else {
Philip Pfaffe939605d2021-06-25 12:20:04674 extensionServer.registerHandler(PrivateAPI.Events.OpenResource, callbackWrapper);
Tim van der Lippe1d6e57a2019-09-30 11:55:34675 }
Blink Reformat4c46d092018-04-07 15:32:37676
677 // 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:34678 if (hadHandler === !callback) {
Philip Pfaffe939605d2021-06-25 12:20:04679 extensionServer.sendRequest(
680 {command: PrivateAPI.Commands.SetOpenResourceHandler, 'handlerPresent': Boolean(callback)});
Tim van der Lippe1d6e57a2019-09-30 11:55:34681 }
Blink Reformat4c46d092018-04-07 15:32:37682 },
683
Paul Lewisada689f2022-01-11 12:03:40684 setThemeChangeHandler: function(callback: (themeName: string) => unknown): void {
685 const hadHandler = extensionServer.hasHandler(PrivateAPI.Events.ThemeChange);
686
687 function callbackWrapper(message: unknown): void {
688 const {themeName} = message as {themeName: string};
689 chrome.devtools.panels.themeName = themeName;
690 callback.call(null, themeName);
691 }
692
693 if (!callback) {
694 extensionServer.unregisterHandler(PrivateAPI.Events.ThemeChange);
695 } else {
696 extensionServer.registerHandler(PrivateAPI.Events.ThemeChange, callbackWrapper);
697 }
698
699 // Only send command if we either removed an existing handler or added handler and had none before.
700 if (hadHandler === !callback) {
701 extensionServer.sendRequest(
702 {command: PrivateAPI.Commands.SetThemeChangeHandler, 'handlerPresent': Boolean(callback)});
703 }
704 },
705
Philip Pfaffe140e5432021-09-13 16:34:23706 openResource: function(
Kateryna Prokopenko9964ab12022-03-23 16:41:49707 url: Platform.DevToolsPath.UrlString, lineNumber: number, columnNumber?: number,
708 _callback?: (response: unknown) => unknown): void {
Philip Pfaffe140e5432021-09-13 16:34:23709 const callbackArg = extractCallbackArgument(arguments);
710 // Handle older API:
711 const columnNumberArg = typeof columnNumber === 'number' ? columnNumber : 0;
712 extensionServer.sendRequest(
713 {command: PrivateAPI.Commands.OpenResource, url, lineNumber, columnNumber: columnNumberArg}, callbackArg);
Blink Reformat4c46d092018-04-07 15:32:37714 },
715
Philip Pfaffe6fd04c42021-06-25 12:31:48716 get SearchAction(): {[key: string]: string} {
Philip Pfaffe939605d2021-06-25 12:20:04717 return {
718 CancelSearch: PrivateAPI.Panels.SearchAction.CancelSearch,
719 PerformSearch: PrivateAPI.Panels.SearchAction.PerformSearch,
720 NextSearchResult: PrivateAPI.Panels.SearchAction.NextSearchResult,
721 PreviousSearchResult: PrivateAPI.Panels.SearchAction.PreviousSearchResult,
722 };
Jan Schefflerd76b4162021-03-29 07:52:16723 },
Blink Reformat4c46d092018-04-07 15:32:37724 };
725
Philip Pfaffe6fd04c42021-06-25 12:31:48726 function ExtensionViewImpl(this: APIImpl.ExtensionView, id: string|null): void {
Blink Reformat4c46d092018-04-07 15:32:37727 this._id = id;
728
Philip Pfaffe6fd04c42021-06-25 12:31:48729 function dispatchShowEvent(
730 this: APIImpl.EventSink<(window?: Window) => unknown>, message: {arguments: unknown[]}): void {
Blink Reformat4c46d092018-04-07 15:32:37731 const frameIndex = message.arguments[0];
Tim van der Lippe1d6e57a2019-09-30 11:55:34732 if (typeof frameIndex === 'number') {
Blink Reformat4c46d092018-04-07 15:32:37733 this._fire(window.parent.frames[frameIndex]);
Tim van der Lippe1d6e57a2019-09-30 11:55:34734 } else {
Blink Reformat4c46d092018-04-07 15:32:37735 this._fire();
Tim van der Lippe1d6e57a2019-09-30 11:55:34736 }
Blink Reformat4c46d092018-04-07 15:32:37737 }
738
739 if (id) {
Philip Pfaffe6fd04c42021-06-25 12:31:48740 this.onShown = new (Constructor(EventSink))(PrivateAPI.Events.ViewShown + id, dispatchShowEvent);
741
742 this.onHidden = new (Constructor(EventSink))(PrivateAPI.Events.ViewHidden + id);
Blink Reformat4c46d092018-04-07 15:32:37743 }
744 }
745
Philip Pfaffe6fd04c42021-06-25 12:31:48746 function PanelWithSidebarImpl(this: APIImpl.PanelWithSidebar, hostPanelName: string): void {
Blink Reformat4c46d092018-04-07 15:32:37747 ExtensionViewImpl.call(this, null);
748 this._hostPanelName = hostPanelName;
Philip Pfaffe6fd04c42021-06-25 12:31:48749
750 this.onSelectionChanged = new (Constructor(EventSink))(PrivateAPI.Events.PanelObjectSelected + hostPanelName);
Blink Reformat4c46d092018-04-07 15:32:37751 }
752
Philip Pfaffe6fd04c42021-06-25 12:31:48753 (PanelWithSidebarImpl.prototype as Pick<APIImpl.PanelWithSidebar, 'createSidebarPane'>&
754 {__proto__: APIImpl.ExtensionView}) = {
755 createSidebarPane: function(
756 this: APIImpl.PanelWithSidebar, title: string,
757 callback?: (pane: PublicAPI.Chrome.DevTools.ExtensionSidebarPane) => unknown): void {
Blink Reformat4c46d092018-04-07 15:32:37758 const id = 'extension-sidebar-' + extensionServer.nextObjectId();
Jan Schefflerd76b4162021-03-29 07:52:16759 function callbackWrapper(): void {
Philip Pfaffe6fd04c42021-06-25 12:31:48760 callback && callback(new (Constructor(ExtensionSidebarPane))(id));
Blink Reformat4c46d092018-04-07 15:32:37761 }
Philip Pfaffe7523faf2021-06-28 14:23:14762 extensionServer.sendRequest(
Philip Pfaffe6fd04c42021-06-25 12:31:48763 {command: PrivateAPI.Commands.CreateSidebarPane, panel: this._hostPanelName, id, title},
Philip Pfaffe7523faf2021-06-28 14:23:14764 callback && callbackWrapper);
Blink Reformat4c46d092018-04-07 15:32:37765 },
766
Jan Schefflerd76b4162021-03-29 07:52:16767 __proto__: ExtensionViewImpl.prototype,
Blink Reformat4c46d092018-04-07 15:32:37768 };
769
Alex Rudenkoa3850822022-05-24 07:34:22770 function RecorderServicesAPIImpl(this: APIImpl.RecorderExtensions): void {
771 this._plugins = new Map();
772 }
773
Alex Rudenko0b8b8882023-01-17 12:21:49774 async function registerRecorderExtensionPluginImpl(
775 this: APIImpl.RecorderExtensions, plugin: PublicAPI.Chrome.DevTools.RecorderExtensionPlugin, pluginName: string,
776 mediaType?: string): Promise<void> {
777 if (this._plugins.has(plugin)) {
778 throw new Error(`Tried to register plugin '${pluginName}' twice`);
779 }
780 const channel = new MessageChannel();
781 const port = channel.port1;
782 this._plugins.set(plugin, port);
783 port.onmessage = ({data}: MessageEvent<{requestId: number}&PrivateAPI.RecorderExtensionRequests>): void => {
784 const {requestId} = data;
785 dispatchMethodCall(data)
786 .then(result => port.postMessage({requestId, result}))
787 .catch(error => port.postMessage({requestId, error: {message: error.message}}));
788 };
789
790 async function dispatchMethodCall(request: PrivateAPI.RecorderExtensionRequests): Promise<unknown> {
791 switch (request.method) {
792 case PrivateAPI.RecorderExtensionPluginCommands.Stringify:
793 return (plugin as PublicAPI.Chrome.DevTools.RecorderExtensionExportPlugin)
794 .stringify(request.parameters.recording);
795 case PrivateAPI.RecorderExtensionPluginCommands.StringifyStep:
796 return (plugin as PublicAPI.Chrome.DevTools.RecorderExtensionExportPlugin)
797 .stringifyStep(request.parameters.step);
798 case PrivateAPI.RecorderExtensionPluginCommands.Replay:
799 try {
800 userAction = true;
801 userRecorderAction = true;
802 return (plugin as PublicAPI.Chrome.DevTools.RecorderExtensionReplayPlugin)
803 .replay(request.parameters.recording);
804 } finally {
805 userAction = false;
806 userRecorderAction = false;
807 }
808 default:
809 // @ts-expect-error
810 throw new Error(`'${request.method}' is not recognized`);
Alex Rudenkoa3850822022-05-24 07:34:22811 }
Alex Rudenko0b8b8882023-01-17 12:21:49812 }
Alex Rudenkoa3850822022-05-24 07:34:22813
Alex Rudenko0b8b8882023-01-17 12:21:49814 const capabilities: PrivateAPI.RecordingExtensionPluginCapability[] = [];
Alex Rudenkoa3850822022-05-24 07:34:22815
Alex Rudenko0b8b8882023-01-17 12:21:49816 if ('stringify' in plugin && 'stringifyStep' in plugin) {
817 capabilities.push('export');
818 }
Alex Rudenkoa3850822022-05-24 07:34:22819
Alex Rudenko0b8b8882023-01-17 12:21:49820 if ('replay' in plugin) {
821 capabilities.push('replay');
822 }
823
824 await new Promise<void>(resolve => {
825 extensionServer.sendRequest(
826 {
827 command: PrivateAPI.Commands.RegisterRecorderExtensionPlugin,
828 pluginName,
829 mediaType,
830 capabilities,
831 port: channel.port2,
832 },
833 () => resolve(), [channel.port2]);
834 });
835 }
836
837 (RecorderServicesAPIImpl.prototype as Pick<
838 APIImpl.RecorderExtensions,
839 'registerRecorderExtensionPlugin'|'unregisterRecorderExtensionPlugin'|'createView'>) = {
840 registerRecorderExtensionPlugin: registerRecorderExtensionPluginImpl,
Alex Rudenkoa3850822022-05-24 07:34:22841 unregisterRecorderExtensionPlugin: async function(
842 this: APIImpl.RecorderExtensions, plugin: PublicAPI.Chrome.DevTools.RecorderExtensionPlugin): Promise<void> {
843 const port = this._plugins.get(plugin);
844 if (!port) {
845 throw new Error('Tried to unregister a plugin that was not previously registered');
846 }
847 this._plugins.delete(plugin);
848 port.postMessage({event: PrivateAPI.RecorderExtensionPluginEvents.UnregisteredRecorderExtensionPlugin});
849 port.close();
850 },
Alex Rudenko0b8b8882023-01-17 12:21:49851 createView: async function(this: APIImpl.RecorderExtensions, title: string, pagePath: string):
852 Promise<PublicAPI.Chrome.DevTools.RecorderView> {
853 const id = 'recorder-extension-view-' + extensionServer.nextObjectId();
854 await new Promise(resolve => {
855 extensionServer.sendRequest(
856 {command: PrivateAPI.Commands.CreateRecorderView, id, title, pagePath}, resolve);
857 });
858 return new (Constructor(RecorderView))(id);
859 },
Alex Rudenkoa3850822022-05-24 07:34:22860 };
861
Philip Pfaffec5d160e2021-07-20 10:53:32862 function LanguageServicesAPIImpl(this: APIImpl.LanguageExtensions): void {
Philip Pfaffeedad8322020-07-20 10:24:25863 this._plugins = new Map();
864 }
865
Philip Pfaffe6ed01262022-07-06 10:41:39866 (LanguageServicesAPIImpl.prototype as PublicAPI.Chrome.DevTools.LanguageExtensions) = {
Philip Pfaffed662bdf2021-06-25 13:30:32867 registerLanguageExtensionPlugin: async function(
Philip Pfaffec5d160e2021-07-20 10:53:32868 this: APIImpl.LanguageExtensions, plugin: PublicAPI.Chrome.DevTools.LanguageExtensionPlugin, pluginName: string,
869 supportedScriptTypes: PublicAPI.Chrome.DevTools.SupportedScriptTypes): Promise<void> {
870 if (this._plugins.has(plugin)) {
871 throw new Error(`Tried to register plugin '${pluginName}' twice`);
872 }
873 const channel = new MessageChannel();
874 const port = channel.port1;
875 this._plugins.set(plugin, port);
876 port.onmessage = ({data}: MessageEvent<{requestId: number}&PrivateAPI.LanguageExtensionRequests>): void => {
877 const {requestId} = data;
878 console.time(`${requestId}: ${data.method}`);
879 dispatchMethodCall(data)
880 .then(result => port.postMessage({requestId, result}))
881 .catch(error => port.postMessage({requestId, error: {message: error.message}}))
882 .finally(() => console.timeEnd(`${requestId}: ${data.method}`));
883 };
Philip Pfaffeedad8322020-07-20 10:24:25884
Philip Pfaffec5d160e2021-07-20 10:53:32885 function dispatchMethodCall(request: PrivateAPI.LanguageExtensionRequests): Promise<unknown> {
886 switch (request.method) {
887 case PrivateAPI.LanguageExtensionPluginCommands.AddRawModule:
888 return plugin.addRawModule(
889 request.parameters.rawModuleId, request.parameters.symbolsURL, request.parameters.rawModule);
890 case PrivateAPI.LanguageExtensionPluginCommands.RemoveRawModule:
891 return plugin.removeRawModule(request.parameters.rawModuleId);
892 case PrivateAPI.LanguageExtensionPluginCommands.SourceLocationToRawLocation:
893 return plugin.sourceLocationToRawLocation(request.parameters.sourceLocation);
894 case PrivateAPI.LanguageExtensionPluginCommands.RawLocationToSourceLocation:
895 return plugin.rawLocationToSourceLocation(request.parameters.rawLocation);
896 case PrivateAPI.LanguageExtensionPluginCommands.GetScopeInfo:
897 return plugin.getScopeInfo(request.parameters.type);
898 case PrivateAPI.LanguageExtensionPluginCommands.ListVariablesInScope:
899 return plugin.listVariablesInScope(request.parameters.rawLocation);
900 case PrivateAPI.LanguageExtensionPluginCommands.GetTypeInfo:
901 return plugin.getTypeInfo(request.parameters.expression, request.parameters.context);
902 case PrivateAPI.LanguageExtensionPluginCommands.GetFormatter:
903 return plugin.getFormatter(request.parameters.expressionOrField, request.parameters.context);
904 case PrivateAPI.LanguageExtensionPluginCommands.GetInspectableAddress:
905 if ('getInspectableAddress' in plugin) {
906 return plugin.getInspectableAddress(request.parameters.field);
Kim-Anh Tran8fd7d6f2021-01-28 11:07:02907 }
Philip Pfaffec5d160e2021-07-20 10:53:32908 return Promise.resolve({js: ''});
909 case PrivateAPI.LanguageExtensionPluginCommands.GetFunctionInfo:
910 return plugin.getFunctionInfo(request.parameters.rawLocation);
911 case PrivateAPI.LanguageExtensionPluginCommands.GetInlinedFunctionRanges:
912 return plugin.getInlinedFunctionRanges(request.parameters.rawLocation);
913 case PrivateAPI.LanguageExtensionPluginCommands.GetInlinedCalleesRanges:
914 return plugin.getInlinedCalleesRanges(request.parameters.rawLocation);
915 case PrivateAPI.LanguageExtensionPluginCommands.GetMappedLines:
916 if ('getMappedLines' in plugin) {
917 return plugin.getMappedLines(request.parameters.rawModuleId, request.parameters.sourceFileURL);
918 }
919 return Promise.resolve(undefined);
Philip Pfaffe6ed01262022-07-06 10:41:39920 case PrivateAPI.LanguageExtensionPluginCommands.FormatValue:
Philip Pfaffe889342a2022-07-08 06:18:47921 if ('evaluate' in plugin && plugin.evaluate) {
Philip Pfaffe6ed01262022-07-06 10:41:39922 return plugin.evaluate(
923 request.parameters.expression, request.parameters.context, request.parameters.stopId);
924 }
925 return Promise.resolve(undefined);
926 case PrivateAPI.LanguageExtensionPluginCommands.GetProperties:
Philip Pfaffe889342a2022-07-08 06:18:47927 if ('getProperties' in plugin && plugin.getProperties) {
Philip Pfaffe6ed01262022-07-06 10:41:39928 return plugin.getProperties(request.parameters.objectId);
929 }
Philip Pfaffe889342a2022-07-08 06:18:47930 if (!('evaluate' in plugin &&
931 plugin.evaluate)) { // If evalute is defined but the remote objects methods aren't, that's a bug
Philip Pfaffe6ed01262022-07-06 10:41:39932 return Promise.resolve(undefined);
933 }
934 break;
935 case PrivateAPI.LanguageExtensionPluginCommands.ReleaseObject:
Philip Pfaffe889342a2022-07-08 06:18:47936 if ('releaseObject' in plugin && plugin.releaseObject) {
Philip Pfaffe6ed01262022-07-06 10:41:39937 return plugin.releaseObject(request.parameters.objectId);
938 }
Philip Pfaffe889342a2022-07-08 06:18:47939 if (!('evaluate' in plugin) &&
940 plugin.evaluate) { // If evalute is defined but the remote objects methods aren't, that's a bug
Philip Pfaffe6ed01262022-07-06 10:41:39941 return Promise.resolve(undefined);
942 }
943 break;
Philip Pfaffec5d160e2021-07-20 10:53:32944 }
Philip Pfaffec5d160e2021-07-20 10:53:32945 throw new Error(`Unknown language plugin method ${request.method}`);
946 }
Philip Pfaffeedad8322020-07-20 10:24:25947
Philip Pfaffec5d160e2021-07-20 10:53:32948 await new Promise<void>(resolve => {
949 extensionServer.sendRequest(
950 {
951 command: PrivateAPI.Commands.RegisterLanguageExtensionPlugin,
952 pluginName,
953 port: channel.port2,
954 supportedScriptTypes,
955 },
956 () => resolve(), [channel.port2]);
957 });
958 },
Benedikt Meurer929fc7c2020-11-20 14:21:06959
Philip Pfaffec5d160e2021-07-20 10:53:32960 unregisterLanguageExtensionPlugin: async function(
961 this: APIImpl.LanguageExtensions, plugin: PublicAPI.Chrome.DevTools.LanguageExtensionPlugin): Promise<void> {
Benedikt Meurer929fc7c2020-11-20 14:21:06962 const port = this._plugins.get(plugin);
963 if (!port) {
964 throw new Error('Tried to unregister a plugin that was not previously registered');
965 }
966 this._plugins.delete(plugin);
Philip Pfaffe939605d2021-06-25 12:20:04967 port.postMessage({event: PrivateAPI.LanguageExtensionPluginEvents.UnregisteredLanguageExtensionPlugin});
Benedikt Meurer929fc7c2020-11-20 14:21:06968 port.close();
Jan Schefflerd76b4162021-03-29 07:52:16969 },
Philip Pfaffe6ed01262022-07-06 10:41:39970
971 getWasmLinearMemory: async function(
972 this: APIImpl.LanguageExtensions, offset: number, length: number, stopId: number): Promise<ArrayBuffer> {
973 const result = await new Promise(
974 resolve => extensionServer.sendRequest(
975 {command: PrivateAPI.Commands.GetWasmLinearMemory, offset, length, stopId}, resolve));
976 if (Array.isArray(result)) {
977 return new Uint8Array(result).buffer;
978 }
979 return new ArrayBuffer(0);
980 },
981 getWasmLocal: async function(
982 this: APIImpl.LanguageExtensions, local: number, stopId: number): Promise<PublicAPI.Chrome.DevTools.WasmValue> {
983 return new Promise(
984 resolve => extensionServer.sendRequest({command: PrivateAPI.Commands.GetWasmLocal, local, stopId}, resolve));
985 },
986 getWasmGlobal: async function(this: APIImpl.LanguageExtensions, global: number, stopId: number):
987 Promise<PublicAPI.Chrome.DevTools.WasmValue> {
988 return new Promise(
989 resolve =>
990 extensionServer.sendRequest({command: PrivateAPI.Commands.GetWasmGlobal, global, stopId}, resolve));
991 },
992 getWasmOp: async function(this: APIImpl.LanguageExtensions, op: number, stopId: number):
993 Promise<PublicAPI.Chrome.DevTools.WasmValue> {
994 return new Promise(
995 resolve => extensionServer.sendRequest({command: PrivateAPI.Commands.GetWasmOp, op, stopId}, resolve));
996 },
Philip Pfaffeedad8322020-07-20 10:24:25997 };
998
Philip Pfaffe7523faf2021-06-28 14:23:14999 function declareInterfaceClass<ImplT extends APIImpl.Callable>(implConstructor: ImplT): (
1000 this: ThisParameterType<ImplT>, ...args: Parameters<ImplT>) => void {
1001 return function(this: ThisParameterType<ImplT>, ...args: Parameters<ImplT>): void {
Blink Reformat4c46d092018-04-07 15:32:371002 const impl = {__proto__: implConstructor.prototype};
Philip Pfaffe7523faf2021-06-28 14:23:141003 implConstructor.apply(impl, args);
1004 populateInterfaceClass(this as {[key: string]: unknown}, impl);
Blink Reformat4c46d092018-04-07 15:32:371005 };
1006 }
1007
Philip Pfaffe7523faf2021-06-28 14:23:141008 // eslint-disable-next-line @typescript-eslint/no-explicit-any
1009 function defineDeprecatedProperty(object: any, className: string, oldName: string, newName: string): void {
Blink Reformat4c46d092018-04-07 15:32:371010 let warningGiven = false;
Philip Pfaffe7523faf2021-06-28 14:23:141011 function getter(): unknown {
Blink Reformat4c46d092018-04-07 15:32:371012 if (!warningGiven) {
1013 console.warn(className + '.' + oldName + ' is deprecated. Use ' + className + '.' + newName + ' instead');
1014 warningGiven = true;
1015 }
1016 return object[newName];
1017 }
1018 object.__defineGetter__(oldName, getter);
1019 }
1020
Philip Pfaffe7523faf2021-06-28 14:23:141021 function extractCallbackArgument(args: IArguments): ((...args: unknown[]) => unknown)|undefined {
Blink Reformat4c46d092018-04-07 15:32:371022 const lastArgument = args[args.length - 1];
Philip Pfaffe7523faf2021-06-28 14:23:141023 return typeof lastArgument === 'function' ? lastArgument as (...args: unknown[]) => unknown : undefined;
Blink Reformat4c46d092018-04-07 15:32:371024 }
1025
Philip Pfaffeedad8322020-07-20 10:24:251026 const LanguageServicesAPI = declareInterfaceClass(LanguageServicesAPIImpl);
Alex Rudenkoa3850822022-05-24 07:34:221027 const RecorderServicesAPI = declareInterfaceClass(RecorderServicesAPIImpl);
Blink Reformat4c46d092018-04-07 15:32:371028 const Button = declareInterfaceClass(ButtonImpl);
1029 const EventSink = declareInterfaceClass(EventSinkImpl);
1030 const ExtensionPanel = declareInterfaceClass(ExtensionPanelImpl);
Alex Rudenko0b8b8882023-01-17 12:21:491031 const RecorderView = declareInterfaceClass(RecorderViewImpl);
Blink Reformat4c46d092018-04-07 15:32:371032 const ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl);
Tim van der Lippeffa78622019-09-16 12:07:121033 const PanelWithSidebarClass = declareInterfaceClass(PanelWithSidebarImpl);
Blink Reformat4c46d092018-04-07 15:32:371034 const Request = declareInterfaceClass(RequestImpl);
1035 const Resource = declareInterfaceClass(ResourceImpl);
1036 const TraceSession = declareInterfaceClass(TraceSessionImpl);
1037
Philip Pfaffe6fd04c42021-06-25 12:31:481038 class ElementsPanel extends (Constructor(PanelWithSidebarClass)) {
Tim van der Lippeffa78622019-09-16 12:07:121039 constructor() {
1040 super('elements');
1041 }
Blink Reformat4c46d092018-04-07 15:32:371042 }
1043
Philip Pfaffe6fd04c42021-06-25 12:31:481044 class SourcesPanel extends (Constructor(PanelWithSidebarClass)) {
Tim van der Lippeffa78622019-09-16 12:07:121045 constructor() {
1046 super('sources');
1047 }
Blink Reformat4c46d092018-04-07 15:32:371048 }
1049
Philip Pfaffe6fd04c42021-06-25 12:31:481050 function ExtensionPanelImpl(this: APIImpl.ExtensionPanel, id: string): void {
Blink Reformat4c46d092018-04-07 15:32:371051 ExtensionViewImpl.call(this, id);
Philip Pfaffe6fd04c42021-06-25 12:31:481052
1053 this.onSearch = new (Constructor(EventSink))(PrivateAPI.Events.PanelSearch + id);
Blink Reformat4c46d092018-04-07 15:32:371054 }
1055
Philip Pfaffe6fd04c42021-06-25 12:31:481056 (ExtensionPanelImpl.prototype as Pick<APIImpl.ExtensionPanel, 'createStatusBarButton'|'show'>&
1057 {__proto__: APIImpl.ExtensionView}) = {
1058 createStatusBarButton: function(
1059 this: APIImpl.ExtensionPanel, iconPath: string, tooltipText: string, disabled: boolean):
1060 PublicAPI.Chrome.DevTools.Button {
1061 const id = 'button-' + extensionServer.nextObjectId();
1062 extensionServer.sendRequest({
1063 command: PrivateAPI.Commands.CreateToolbarButton,
1064 panel: this._id as string,
1065 id: id,
1066 icon: iconPath,
1067 tooltip: tooltipText,
1068 disabled: Boolean(disabled),
1069 });
Blink Reformat4c46d092018-04-07 15:32:371070
Philip Pfaffe6fd04c42021-06-25 12:31:481071 return new (Constructor(Button))(id);
1072 },
1073
1074 show: function(this: APIImpl.ExtensionPanel): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341075 if (!userAction) {
Blink Reformat4c46d092018-04-07 15:32:371076 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341077 }
Blink Reformat4c46d092018-04-07 15:32:371078
Philip Pfaffe6fd04c42021-06-25 12:31:481079 extensionServer.sendRequest({command: PrivateAPI.Commands.ShowPanel, id: this._id as string});
Blink Reformat4c46d092018-04-07 15:32:371080 },
1081
Jan Schefflerd76b4162021-03-29 07:52:161082 __proto__: ExtensionViewImpl.prototype,
Blink Reformat4c46d092018-04-07 15:32:371083 };
1084
Alex Rudenko0b8b8882023-01-17 12:21:491085 function RecorderViewImpl(this: APIImpl.RecorderView, id: string): void {
1086 ExtensionViewImpl.call(this, id);
1087 }
1088
1089 (RecorderViewImpl.prototype as Pick<APIImpl.RecorderView, 'show'>& {__proto__: APIImpl.ExtensionView}) = {
1090 show: function(this: APIImpl.RecorderView): void {
1091 if (!userAction || !userRecorderAction) {
1092 return;
1093 }
1094
1095 extensionServer.sendRequest({command: PrivateAPI.Commands.ShowRecorderView, id: this._id as string});
1096 },
1097
1098 __proto__: ExtensionViewImpl.prototype,
1099 };
1100
Philip Pfaffe6fd04c42021-06-25 12:31:481101 function ExtensionSidebarPaneImpl(this: APIImpl.ExtensionSidebarPane, id: string): void {
Blink Reformat4c46d092018-04-07 15:32:371102 ExtensionViewImpl.call(this, id);
1103 }
1104
Philip Pfaffe6fd04c42021-06-25 12:31:481105 (ExtensionSidebarPaneImpl.prototype as
1106 Pick<APIImpl.ExtensionSidebarPane, 'setHeight'|'setExpression'|'setObject'|'setPage'>&
1107 {__proto__: APIImpl.ExtensionView}) = {
1108 setHeight: function(this: APIImpl.ExtensionSidebarPane, height: string): void {
1109 extensionServer.sendRequest(
1110 {command: PrivateAPI.Commands.SetSidebarHeight, id: this._id as string, height: height});
Blink Reformat4c46d092018-04-07 15:32:371111 },
1112
Philip Pfaffe6fd04c42021-06-25 12:31:481113 setExpression: function(
1114 this: APIImpl.ExtensionSidebarPane, expression: string, rootTitle: string,
1115 evaluateOptions?: PrivateAPI.EvaluateOptions, _callback?: () => unknown): void {
Philip Pfaffe7523faf2021-06-28 14:23:141116 extensionServer.sendRequest(
1117 {
1118 command: PrivateAPI.Commands.SetSidebarContent,
Philip Pfaffe6fd04c42021-06-25 12:31:481119 id: this._id as string,
Philip Pfaffe7523faf2021-06-28 14:23:141120 expression: expression,
1121 rootTitle: rootTitle,
1122 evaluateOnPage: true,
Philip Pfaffe6fd04c42021-06-25 12:31:481123 evaluateOptions: (typeof evaluateOptions === 'object' ? evaluateOptions : {}),
Philip Pfaffe7523faf2021-06-28 14:23:141124 },
1125 extractCallbackArgument(arguments));
Blink Reformat4c46d092018-04-07 15:32:371126 },
1127
Philip Pfaffe6fd04c42021-06-25 12:31:481128 setObject: function(
1129 this: APIImpl.ExtensionSidebarPane, jsonObject: string, rootTitle?: string, callback?: () => unknown): void {
Blink Reformat4c46d092018-04-07 15:32:371130 extensionServer.sendRequest(
Philip Pfaffe6fd04c42021-06-25 12:31:481131 {
1132 command: PrivateAPI.Commands.SetSidebarContent,
1133 id: this._id as string,
1134 expression: jsonObject,
1135 rootTitle: rootTitle,
1136 },
Philip Pfaffe939605d2021-06-25 12:20:041137 callback);
Blink Reformat4c46d092018-04-07 15:32:371138 },
1139
Philip Pfaffe6fd04c42021-06-25 12:31:481140 setPage: function(this: APIImpl.ExtensionSidebarPane, page: string): void {
1141 extensionServer.sendRequest({command: PrivateAPI.Commands.SetSidebarPage, id: this._id as string, page: page});
Blink Reformat4c46d092018-04-07 15:32:371142 },
1143
Jan Schefflerd76b4162021-03-29 07:52:161144 __proto__: ExtensionViewImpl.prototype,
Blink Reformat4c46d092018-04-07 15:32:371145 };
1146
Philip Pfaffe6fd04c42021-06-25 12:31:481147 function ButtonImpl(this: APIImpl.Button, id: string): void {
Blink Reformat4c46d092018-04-07 15:32:371148 this._id = id;
Philip Pfaffe6fd04c42021-06-25 12:31:481149
1150 this.onClicked = new (Constructor(EventSink))(PrivateAPI.Events.ButtonClicked + id);
Blink Reformat4c46d092018-04-07 15:32:371151 }
1152
Philip Pfaffe6fd04c42021-06-25 12:31:481153 (ButtonImpl.prototype as Pick<APIImpl.Button, 'update'>) = {
1154 update: function(this: APIImpl.Button, iconPath?: string, tooltipText?: string, disabled?: boolean): void {
Philip Pfaffe7523faf2021-06-28 14:23:141155 extensionServer.sendRequest({
Philip Pfaffe939605d2021-06-25 12:20:041156 command: PrivateAPI.Commands.UpdateButton,
Tim van der Lipped7cfd142021-01-07 12:17:241157 id: this._id,
1158 icon: iconPath,
1159 tooltip: tooltipText,
Jan Schefflerd76b4162021-03-29 07:52:161160 disabled: Boolean(disabled),
Philip Pfaffe7523faf2021-06-28 14:23:141161 });
Jan Schefflerd76b4162021-03-29 07:52:161162 },
Blink Reformat4c46d092018-04-07 15:32:371163 };
1164
Philip Pfaffe1c827212021-06-25 12:33:201165 function Timeline(this: APIImpl.Timeline): void {
Blink Reformat4c46d092018-04-07 15:32:371166 }
1167
Philip Pfaffe1c827212021-06-25 12:33:201168 (Timeline.prototype as Pick<APIImpl.Timeline, 'addTraceProvider'>) = {
1169 addTraceProvider: function(this: APIImpl.Timeline, categoryName: string, categoryTooltip: string):
1170 APIImpl.TraceProvider {
1171 const id = 'extension-trace-provider-' + extensionServer.nextObjectId();
1172 extensionServer.sendRequest({
1173 command: PrivateAPI.Commands.AddTraceProvider,
1174 id: id,
1175 categoryName: categoryName,
1176 categoryTooltip: categoryTooltip,
1177 });
1178
1179 return new (Constructor(TraceProvider))(id);
1180 },
Blink Reformat4c46d092018-04-07 15:32:371181 };
1182
Philip Pfaffe1c827212021-06-25 12:33:201183 function TraceSessionImpl(this: APIImpl.TraceSession, id: string): void {
Blink Reformat4c46d092018-04-07 15:32:371184 this._id = id;
1185 }
1186
Philip Pfaffe1c827212021-06-25 12:33:201187 (TraceSessionImpl.prototype as Pick<APIImpl.TraceSession, 'complete'>) = {
Kateryna Prokopenko6fa122c2022-05-06 08:54:471188 complete: function(this: APIImpl.TraceSession, url?: Platform.DevToolsPath.UrlString, timeOffset?: number): void {
Philip Pfaffe7523faf2021-06-28 14:23:141189 extensionServer.sendRequest({
Philip Pfaffe939605d2021-06-25 12:20:041190 command: PrivateAPI.Commands.CompleteTraceSession,
1191 id: this._id,
Kateryna Prokopenko6fa122c2022-05-06 08:54:471192 url: url || Platform.DevToolsPath.EmptyUrlString,
Philip Pfaffe939605d2021-06-25 12:20:041193 timeOffset: timeOffset || 0,
Philip Pfaffe7523faf2021-06-28 14:23:141194 });
Jan Schefflerd76b4162021-03-29 07:52:161195 },
Blink Reformat4c46d092018-04-07 15:32:371196 };
1197
Philip Pfaffe1c827212021-06-25 12:33:201198 function TraceProvider(this: APIImpl.TraceProvider, id: string): void {
1199 function dispatchRecordingStarted(
1200 this: APIImpl.EventSink<APIImpl.Callable>, message: {arguments: unknown[]}): void {
1201 const sessionId = message.arguments[0] as string;
1202
1203 this._fire(new (Constructor(TraceSession))(sessionId));
Blink Reformat4c46d092018-04-07 15:32:371204 }
1205
Philip Pfaffe1c827212021-06-25 12:33:201206 this.onRecordingStarted =
1207 new (Constructor(EventSink))(PrivateAPI.Events.RecordingStarted + id, dispatchRecordingStarted);
1208
1209 this.onRecordingStopped = new (Constructor(EventSink))(PrivateAPI.Events.RecordingStopped + id);
Blink Reformat4c46d092018-04-07 15:32:371210 }
1211
Danil Somsikov56210832022-10-05 13:17:581212 function canAccessResource(resource: APIImpl.ResourceData): boolean {
Danil Somsikov91694742023-03-13 08:45:131213 return extensionInfo.allowFileAccess || !resource.url.toLowerCase().startsWith('file:');
Danil Somsikov56210832022-10-05 13:17:581214 }
1215
Philip Pfaffeddf60d22021-06-25 12:35:411216 function InspectedWindow(this: PublicAPI.Chrome.DevTools.InspectedWindow): void {
1217 function dispatchResourceEvent(
1218 this: APIImpl.EventSink<(resource: APIImpl.Resource) => unknown>, message: {arguments: unknown[]}): void {
Danil Somsikov56210832022-10-05 13:17:581219 const resourceData = message.arguments[0] as APIImpl.ResourceData;
1220 if (!canAccessResource(resourceData)) {
1221 return;
1222 }
1223 this._fire(new (Constructor(Resource))(resourceData));
Blink Reformat4c46d092018-04-07 15:32:371224 }
1225
Philip Pfaffeddf60d22021-06-25 12:35:411226 function dispatchResourceContentEvent(
1227 this: APIImpl.EventSink<(resource: APIImpl.Resource, content: string) => unknown>,
1228 message: {arguments: unknown[]}): void {
Danil Somsikov56210832022-10-05 13:17:581229 const resourceData = message.arguments[0] as APIImpl.ResourceData;
1230 if (!canAccessResource(resourceData)) {
1231 return;
1232 }
1233 this._fire(new (Constructor(Resource))(resourceData), message.arguments[1] as string);
Blink Reformat4c46d092018-04-07 15:32:371234 }
1235
Philip Pfaffeddf60d22021-06-25 12:35:411236 this.onResourceAdded = new (Constructor(EventSink))(PrivateAPI.Events.ResourceAdded, dispatchResourceEvent);
Philip Pfaffe939605d2021-06-25 12:20:041237 this.onResourceContentCommitted =
Philip Pfaffeddf60d22021-06-25 12:35:411238 new (Constructor(EventSink))(PrivateAPI.Events.ResourceContentCommitted, dispatchResourceContentEvent);
Blink Reformat4c46d092018-04-07 15:32:371239 }
1240
Philip Pfaffeddf60d22021-06-25 12:35:411241 (InspectedWindow.prototype as Pick<PublicAPI.Chrome.DevTools.InspectedWindow, 'reload'|'eval'|'getResources'>) = {
1242 reload: function(optionsOrUserAgent: {
1243 ignoreCache?: boolean,
1244 injectedScript?: string,
1245 userAgent?: string,
1246 }): void {
Jan Schefflerd76b4162021-03-29 07:52:161247 let options: {
Philip Pfaffeddf60d22021-06-25 12:35:411248 ignoreCache?: boolean,
1249 injectedScript?: string,
1250 userAgent?: string,
Jan Schefflerd76b4162021-03-29 07:52:161251 }|null = null;
Blink Reformat4c46d092018-04-07 15:32:371252 if (typeof optionsOrUserAgent === 'object') {
1253 options = optionsOrUserAgent;
1254 } else if (typeof optionsOrUserAgent === 'string') {
1255 options = {userAgent: optionsOrUserAgent};
1256 console.warn(
1257 'Passing userAgent as string parameter to inspectedWindow.reload() is deprecated. ' +
1258 'Use inspectedWindow.reload({ userAgent: value}) instead.');
1259 }
Philip Pfaffe939605d2021-06-25 12:20:041260 extensionServer.sendRequest({command: PrivateAPI.Commands.Reload, options: options});
Blink Reformat4c46d092018-04-07 15:32:371261 },
1262
Philip Pfaffeddf60d22021-06-25 12:35:411263 eval: function(
1264 expression: string,
1265 evaluateOptions: {contextSecurityOrigin?: string, frameURL?: string, useContentScriptContext?: boolean}):
1266 Object |
Jan Schefflerd76b4162021-03-29 07:52:161267 null {
1268 const callback = extractCallbackArgument(arguments);
Philip Pfaffeddf60d22021-06-25 12:35:411269 function callbackWrapper(result: unknown): void {
1270 const {isError, isException, value} = result as {
1271 isError?: boolean,
1272 isException?: boolean, value: unknown,
1273 };
1274 if (isError || isException) {
Philip Pfaffe7523faf2021-06-28 14:23:141275 callback && callback(undefined, result);
Jan Schefflerd76b4162021-03-29 07:52:161276 } else {
Philip Pfaffeddf60d22021-06-25 12:35:411277 callback && callback(value);
Jan Schefflerd76b4162021-03-29 07:52:161278 }
1279 }
Philip Pfaffe7523faf2021-06-28 14:23:141280 extensionServer.sendRequest(
1281 {
1282 command: PrivateAPI.Commands.EvaluateOnInspectedPage,
1283 expression: expression,
1284 evaluateOptions: (typeof evaluateOptions === 'object' ? evaluateOptions : undefined),
1285 },
1286 callback && callbackWrapper);
Jan Schefflerd76b4162021-03-29 07:52:161287 return null;
1288 },
Blink Reformat4c46d092018-04-07 15:32:371289
Philip Pfaffeddf60d22021-06-25 12:35:411290 getResources: function(callback?: (resources: PublicAPI.Chrome.DevTools.Resource[]) => unknown): void {
1291 function wrapResource(resourceData: APIImpl.ResourceData): APIImpl.Resource {
1292 return new (Constructor(Resource))(resourceData);
Blink Reformat4c46d092018-04-07 15:32:371293 }
Philip Pfaffeddf60d22021-06-25 12:35:411294 function callbackWrapper(resources: unknown): void {
Danil Somsikov56210832022-10-05 13:17:581295 callback && callback((resources as APIImpl.ResourceData[]).map(wrapResource).filter(canAccessResource));
Blink Reformat4c46d092018-04-07 15:32:371296 }
Danil Somsikov56210832022-10-05 13:17:581297 extensionServer.sendRequest({command: PrivateAPI.Commands.GetPageResources}, callback && callbackWrapper);
Jan Schefflerd76b4162021-03-29 07:52:161298 },
Blink Reformat4c46d092018-04-07 15:32:371299 };
1300
Philip Pfaffe6fd04c42021-06-25 12:31:481301 function ResourceImpl(this: APIImpl.Resource, resourceData: APIImpl.ResourceData): void {
Danil Somsikov56210832022-10-05 13:17:581302 if (!canAccessResource) {
1303 throw new Error('Resource access not allowed');
1304 }
Blink Reformat4c46d092018-04-07 15:32:371305 this._url = resourceData.url;
1306 this._type = resourceData.type;
1307 }
1308
Philip Pfaffe6fd04c42021-06-25 12:31:481309 (ResourceImpl.prototype as Pick<APIImpl.Resource, 'url'|'type'|'getContent'|'setContent'>) = {
Jan Schefflerd76b4162021-03-29 07:52:161310 get url(): string {
Philip Pfaffe6fd04c42021-06-25 12:31:481311 return (this as APIImpl.Resource)._url;
Blink Reformat4c46d092018-04-07 15:32:371312 },
1313
Jan Schefflerd76b4162021-03-29 07:52:161314 get type(): string {
Philip Pfaffe6fd04c42021-06-25 12:31:481315 return (this as APIImpl.Resource)._type;
Blink Reformat4c46d092018-04-07 15:32:371316 },
1317
Philip Pfaffe6fd04c42021-06-25 12:31:481318 getContent: function(this: APIImpl.Resource, callback?: (content: string, encoding: string) => unknown): void {
1319 function callbackWrapper(response: unknown): void {
1320 const {content, encoding} = response as {content: string, encoding: string};
1321 callback && callback(content, encoding);
Blink Reformat4c46d092018-04-07 15:32:371322 }
1323
Philip Pfaffe939605d2021-06-25 12:20:041324 extensionServer.sendRequest(
1325 {command: PrivateAPI.Commands.GetResourceContent, url: this._url}, callback && callbackWrapper);
Blink Reformat4c46d092018-04-07 15:32:371326 },
1327
Philip Pfaffe6fd04c42021-06-25 12:31:481328 setContent: function(
1329 this: APIImpl.Resource, content: string, commit: boolean, callback: (error?: Object) => unknown): void {
Blink Reformat4c46d092018-04-07 15:32:371330 extensionServer.sendRequest(
Philip Pfaffe939605d2021-06-25 12:20:041331 {command: PrivateAPI.Commands.SetResourceContent, url: this._url, content: content, commit: commit},
Philip Pfaffe6fd04c42021-06-25 12:31:481332 callback as (response: unknown) => unknown);
Jan Schefflerd76b4162021-03-29 07:52:161333 },
Blink Reformat4c46d092018-04-07 15:32:371334 };
1335
Jan Schefflerd76b4162021-03-29 07:52:161336 function getTabId(): string {
Blink Reformat4c46d092018-04-07 15:32:371337 return inspectedTabId;
1338 }
1339
Philip Pfaffe7523faf2021-06-28 14:23:141340 let keyboardEventRequestQueue: KeyboardEventInit&{eventType: string}[] = [];
Jan Schefflerd76b4162021-03-29 07:52:161341 let forwardTimer: number|null = null;
Philip Pfaffe7523faf2021-06-28 14:23:141342 function forwardKeyboardEvent(event: KeyboardEvent): void {
Jan Schefflere7d7bb12019-10-24 09:18:521343 // Check if the event should be forwarded.
1344 // This is a workaround for crbug.com/923338.
1345 const focused = document.activeElement;
1346 if (focused) {
Benedikt Meurer5d508f62022-12-06 14:37:381347 const isInput =
1348 focused.nodeName === 'INPUT' || focused.nodeName === 'TEXTAREA' || (focused as HTMLElement).isContentEditable;
Jan Schefflere7d7bb12019-10-24 09:18:521349 if (isInput && !(event.ctrlKey || event.altKey || event.metaKey)) {
1350 return;
1351 }
1352 }
1353
Joel Einbinder67f28fb2018-08-02 00:33:471354 let modifiers = 0;
Tim van der Lippe1d6e57a2019-09-30 11:55:341355 if (event.shiftKey) {
Joel Einbinder67f28fb2018-08-02 00:33:471356 modifiers |= 1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341357 }
1358 if (event.ctrlKey) {
Joel Einbinder67f28fb2018-08-02 00:33:471359 modifiers |= 2;
Tim van der Lippe1d6e57a2019-09-30 11:55:341360 }
1361 if (event.altKey) {
Joel Einbinder67f28fb2018-08-02 00:33:471362 modifiers |= 4;
Tim van der Lippe1d6e57a2019-09-30 11:55:341363 }
1364 if (event.metaKey) {
Joel Einbinder67f28fb2018-08-02 00:33:471365 modifiers |= 8;
Tim van der Lippe1d6e57a2019-09-30 11:55:341366 }
Joel Einbinder67f28fb2018-08-02 00:33:471367 const num = (event.keyCode & 255) | (modifiers << 8);
Blink Reformat4c46d092018-04-07 15:32:371368 // We only care about global hotkeys, not about random text
Tim van der Lippe1d6e57a2019-09-30 11:55:341369 if (!keysToForwardSet.has(num)) {
Blink Reformat4c46d092018-04-07 15:32:371370 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341371 }
Joel Einbinder67f28fb2018-08-02 00:33:471372 event.preventDefault();
Blink Reformat4c46d092018-04-07 15:32:371373 const requestPayload = {
1374 eventType: event.type,
1375 ctrlKey: event.ctrlKey,
1376 altKey: event.altKey,
1377 metaKey: event.metaKey,
Joel Einbinder67f28fb2018-08-02 00:33:471378 shiftKey: event.shiftKey,
Philip Pfaffe7523faf2021-06-28 14:23:141379 // @ts-expect-error keyIdentifier is a deprecated non-standard property that typescript doesn't know about.
Blink Reformat4c46d092018-04-07 15:32:371380 keyIdentifier: event.keyIdentifier,
1381 key: event.key,
1382 code: event.code,
1383 location: event.location,
Jan Schefflerd76b4162021-03-29 07:52:161384 keyCode: event.keyCode,
Blink Reformat4c46d092018-04-07 15:32:371385 };
1386 keyboardEventRequestQueue.push(requestPayload);
Tim van der Lippe1d6e57a2019-09-30 11:55:341387 if (!forwardTimer) {
Tim van der Lippe6bcbe0f2022-01-11 13:10:311388 forwardTimer = window.setTimeout(forwardEventQueue, 0);
Tim van der Lippe1d6e57a2019-09-30 11:55:341389 }
Blink Reformat4c46d092018-04-07 15:32:371390 }
1391
Jan Schefflerd76b4162021-03-29 07:52:161392 function forwardEventQueue(): void {
Blink Reformat4c46d092018-04-07 15:32:371393 forwardTimer = null;
Philip Pfaffe7523faf2021-06-28 14:23:141394 extensionServer.sendRequest(
1395 {command: PrivateAPI.Commands.ForwardKeyboardEvent, entries: keyboardEventRequestQueue});
Blink Reformat4c46d092018-04-07 15:32:371396 keyboardEventRequestQueue = [];
1397 }
1398
1399 document.addEventListener('keydown', forwardKeyboardEvent, false);
Blink Reformat4c46d092018-04-07 15:32:371400
Alex Rudenkoa3850822022-05-24 07:34:221401 function ExtensionServerClient(this: APIImpl.ExtensionServerClient, targetWindow: Window): void {
Blink Reformat4c46d092018-04-07 15:32:371402 this._callbacks = {};
1403 this._handlers = {};
1404 this._lastRequestId = 0;
1405 this._lastObjectId = 0;
1406
1407 this.registerHandler('callback', this._onCallback.bind(this));
1408
1409 const channel = new MessageChannel();
1410 this._port = channel.port1;
1411 this._port.addEventListener('message', this._onMessage.bind(this), false);
1412 this._port.start();
1413
Alex Rudenkoa3850822022-05-24 07:34:221414 targetWindow.postMessage('registerExtension', '*', [channel.port2]);
Blink Reformat4c46d092018-04-07 15:32:371415 }
1416
Philip Pfaffe7523faf2021-06-28 14:23:141417 (ExtensionServerClient.prototype as Pick<
1418 APIImpl.ExtensionServerClient,
1419 'sendRequest'|'hasHandler'|'registerHandler'|'unregisterHandler'|'nextObjectId'|'_registerCallback'|
1420 '_onCallback'|'_onMessage'>) = {
Philip Pfaffe6ed01262022-07-06 10:41:391421 sendRequest: function<ResponseT>(
Philip Pfaffe7523faf2021-06-28 14:23:141422 this: APIImpl.ExtensionServerClient, message: PrivateAPI.ServerRequests,
Philip Pfaffe6ed01262022-07-06 10:41:391423 callback?: (response: ResponseT) => unknown, transfers?: Transferable[]): void {
Philip Pfaffe7523faf2021-06-28 14:23:141424 if (typeof callback === 'function') {
Philip Pfaffe6ed01262022-07-06 10:41:391425 (message as PrivateAPI.ExtensionServerRequestMessage).requestId =
1426 this._registerCallback(callback as (response: unknown) => unknown);
Philip Pfaffe7523faf2021-06-28 14:23:141427 }
1428 // @ts-expect-error
1429 this._port.postMessage(message, transfers);
1430 },
Blink Reformat4c46d092018-04-07 15:32:371431
Philip Pfaffe7523faf2021-06-28 14:23:141432 hasHandler: function(this: APIImpl.ExtensionServerClient, command: string): boolean {
Tim van der Lipped7cfd142021-01-07 12:17:241433 return Boolean(this._handlers[command]);
Blink Reformat4c46d092018-04-07 15:32:371434 },
1435
Philip Pfaffe7523faf2021-06-28 14:23:141436 registerHandler: function(
1437 this: APIImpl.ExtensionServerClient, command: string, handler: (request: {arguments: unknown[]}) => unknown):
1438 void {
1439 this._handlers[command] = handler;
1440 },
Blink Reformat4c46d092018-04-07 15:32:371441
Philip Pfaffe7523faf2021-06-28 14:23:141442 unregisterHandler: function(this: APIImpl.ExtensionServerClient, command: string): void {
Blink Reformat4c46d092018-04-07 15:32:371443 delete this._handlers[command];
1444 },
1445
Philip Pfaffe7523faf2021-06-28 14:23:141446 nextObjectId: function(this: APIImpl.ExtensionServerClient): string {
Blink Reformat4c46d092018-04-07 15:32:371447 return injectedScriptId.toString() + '_' + ++this._lastObjectId;
1448 },
1449
Philip Pfaffe7523faf2021-06-28 14:23:141450 _registerCallback: function(this: APIImpl.ExtensionServerClient, callback: (response: unknown) => unknown): number {
Blink Reformat4c46d092018-04-07 15:32:371451 const id = ++this._lastRequestId;
1452 this._callbacks[id] = callback;
1453 return id;
1454 },
1455
Philip Pfaffe7523faf2021-06-28 14:23:141456 _onCallback: function(this: APIImpl.ExtensionServerClient, request: {requestId: number, result: unknown}): void {
Blink Reformat4c46d092018-04-07 15:32:371457 if (request.requestId in this._callbacks) {
1458 const callback = this._callbacks[request.requestId];
1459 delete this._callbacks[request.requestId];
1460 callback(request.result);
1461 }
1462 },
1463
Philip Pfaffe7523faf2021-06-28 14:23:141464 _onMessage: function(
1465 this: APIImpl.ExtensionServerClient,
1466 event: MessageEvent<{command: string, requestId: number, arguments: unknown[]}>): void {
Blink Reformat4c46d092018-04-07 15:32:371467 const request = event.data;
1468 const handler = this._handlers[request.command];
Tim van der Lippe1d6e57a2019-09-30 11:55:341469 if (handler) {
Blink Reformat4c46d092018-04-07 15:32:371470 handler.call(this, request);
Tim van der Lippe1d6e57a2019-09-30 11:55:341471 }
Jan Schefflerd76b4162021-03-29 07:52:161472 },
Blink Reformat4c46d092018-04-07 15:32:371473 };
1474
Philip Pfaffe7523faf2021-06-28 14:23:141475 function populateInterfaceClass(interfaze: {[key: string]: unknown}, implementation: {[key: string]: unknown}): void {
Blink Reformat4c46d092018-04-07 15:32:371476 for (const member in implementation) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341477 if (member.charAt(0) === '_') {
Blink Reformat4c46d092018-04-07 15:32:371478 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341479 }
Jan Schefflerd76b4162021-03-29 07:52:161480 let descriptor: (PropertyDescriptor|undefined)|null = null;
Blink Reformat4c46d092018-04-07 15:32:371481 // Traverse prototype chain until we find the owner.
Philip Pfaffe7523faf2021-06-28 14:23:141482 for (let owner = implementation; owner && !descriptor; owner = owner.__proto__ as {[key: string]: unknown}) {
Blink Reformat4c46d092018-04-07 15:32:371483 descriptor = Object.getOwnPropertyDescriptor(owner, member);
Tim van der Lippe1d6e57a2019-09-30 11:55:341484 }
1485 if (!descriptor) {
Blink Reformat4c46d092018-04-07 15:32:371486 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341487 }
1488 if (typeof descriptor.value === 'function') {
Blink Reformat4c46d092018-04-07 15:32:371489 interfaze[member] = descriptor.value.bind(implementation);
Tim van der Lippe1d6e57a2019-09-30 11:55:341490 } else if (typeof descriptor.get === 'function') {
Philip Pfaffe7523faf2021-06-28 14:23:141491 // @ts-expect-error
Blink Reformat4c46d092018-04-07 15:32:371492 interfaze.__defineGetter__(member, descriptor.get.bind(implementation));
Tim van der Lippe1d6e57a2019-09-30 11:55:341493 } else {
Blink Reformat4c46d092018-04-07 15:32:371494 Object.defineProperty(interfaze, member, descriptor);
Tim van der Lippe1d6e57a2019-09-30 11:55:341495 }
Blink Reformat4c46d092018-04-07 15:32:371496 }
1497 }
1498
Alex Rudenkoa3850822022-05-24 07:34:221499 const extensionServer = new (Constructor(ExtensionServerClient))(targetWindowForTest || window.parent);
Philip Pfaffe7523faf2021-06-28 14:23:141500
1501 const coreAPI = new (Constructor(InspectorExtensionAPI))();
Blink Reformat4c46d092018-04-07 15:32:371502
1503 Object.defineProperty(chrome, 'devtools', {value: {}, enumerable: true});
1504
1505 // Only expose tabId on chrome.devtools.inspectedWindow, not webInspector.inspectedWindow.
Philip Pfaffe7523faf2021-06-28 14:23:141506 // @ts-expect-error
1507 chrome.devtools!.inspectedWindow = {};
1508 Object.defineProperty(chrome.devtools!.inspectedWindow, 'tabId', {get: getTabId});
1509 // @ts-expect-error
1510 chrome.devtools!.inspectedWindow.__proto__ = coreAPI.inspectedWindow;
1511 chrome.devtools!.network = coreAPI.network;
1512 chrome.devtools!.panels = coreAPI.panels;
1513 chrome.devtools!.panels.themeName = themeName;
1514 chrome.devtools!.languageServices = coreAPI.languageServices;
Alex Rudenkoa3850822022-05-24 07:34:221515 chrome.devtools!.recorder = coreAPI.recorder;
Blink Reformat4c46d092018-04-07 15:32:371516
1517 // default to expose experimental APIs for now.
1518 if (extensionInfo.exposeExperimentalAPIs !== false) {
1519 chrome.experimental = chrome.experimental || {};
1520 chrome.experimental.devtools = chrome.experimental.devtools || {};
1521
1522 const properties = Object.getOwnPropertyNames(coreAPI);
1523 for (let i = 0; i < properties.length; ++i) {
1524 const descriptor = Object.getOwnPropertyDescriptor(coreAPI, properties[i]);
Tim van der Lippe1d6e57a2019-09-30 11:55:341525 if (descriptor) {
Blink Reformat4c46d092018-04-07 15:32:371526 Object.defineProperty(chrome.experimental.devtools, properties[i], descriptor);
Tim van der Lippe1d6e57a2019-09-30 11:55:341527 }
Blink Reformat4c46d092018-04-07 15:32:371528 }
1529 chrome.experimental.devtools.inspectedWindow = chrome.devtools.inspectedWindow;
1530 }
1531
Tim van der Lippe1d6e57a2019-09-30 11:55:341532 if (extensionInfo.exposeWebInspectorNamespace) {
Blink Reformat4c46d092018-04-07 15:32:371533 window.webInspector = coreAPI;
Tim van der Lippe1d6e57a2019-09-30 11:55:341534 }
Blink Reformat4c46d092018-04-07 15:32:371535 testHook(extensionServer, coreAPI);
Tim van der Lippe226fc222019-10-10 12:17:121536};
Blink Reformat4c46d092018-04-07 15:32:371537
Jan Schefflerd76b4162021-03-29 07:52:161538self.buildExtensionAPIInjectedScript = function(
1539 extensionInfo: {
1540 startPage: string,
1541 name: string,
1542 exposeExperimentalAPIs: boolean,
1543 },
1544 inspectedTabId: string, themeName: string, keysToForward: number[],
Philip Pfaffe7523faf2021-06-28 14:23:141545 testHook:
1546 ((extensionServer: APIImpl.ExtensionServerClient, extensionAPI: APIImpl.InspectorExtensionAPI) => unknown)|
1547 undefined): string {
Philip Pfaffeedad8322020-07-20 10:24:251548 const argumentsJSON =
1549 [extensionInfo, inspectedTabId || null, themeName, keysToForward].map(_ => JSON.stringify(_)).join(',');
Tim van der Lippe1d6e57a2019-09-30 11:55:341550 if (!testHook) {
Jan Schefflerd76b4162021-03-29 07:52:161551 testHook = (): void => {};
Tim van der Lippe1d6e57a2019-09-30 11:55:341552 }
Philip Pfaffe939605d2021-06-25 12:20:041553 return '(function(injectedScriptId){ ' +
Tim van der Lippe226fc222019-10-10 12:17:121554 '(' + self.injectedExtensionAPI.toString() + ')(' + argumentsJSON + ',' + testHook + ', injectedScriptId);' +
Blink Reformat4c46d092018-04-07 15:32:371555 '})';
Tim van der Lippe29fab472019-08-15 14:46:481556};