blob: b570322e82f913f0f518ccbd1ff9da7f6a73be45 [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
Philip Pfaffe7523faf2021-06-28 14:23:1431import type * as PublicAPI from '../../../extension-api/ExtensionAPI'; // eslint-disable-line rulesdir/es_modules_import
32
33/* eslint-disable @typescript-eslint/no-explicit-any,@typescript-eslint/naming-convention,@typescript-eslint/no-non-null-assertion */
Philip Pfaffe939605d2021-06-25 12:20:0434export namespace PrivateAPI {
35 export namespace Panels {
36 export const enum SearchAction {
37 CancelSearch = 'cancelSearch',
38 PerformSearch = 'performSearch',
39 NextSearchResult = 'nextSearchResult',
40 PreviousSearchResult = 'previousSearchResult',
41 }
Tim van der Lippe1d6e57a2019-09-30 11:55:3442 }
Blink Reformat4c46d092018-04-07 15:32:3743
Philip Pfaffe939605d2021-06-25 12:20:0444 export const enum Events {
45 ButtonClicked = 'button-clicked-',
46 PanelObjectSelected = 'panel-objectSelected-',
47 InspectedURLChanged = 'inspected-url-changed',
48 NetworkRequestFinished = 'network-request-finished',
49 OpenResource = 'open-resource',
50 PanelSearch = 'panel-search-',
51 RecordingStarted = 'trace-recording-started-',
52 RecordingStopped = 'trace-recording-stopped-',
53 ResourceAdded = 'resource-added',
54 ResourceContentCommitted = 'resource-content-committed',
55 ViewShown = 'view-shown-',
56 ViewHidden = 'view-hidden,',
57 }
Blink Reformat4c46d092018-04-07 15:32:3758
Philip Pfaffe939605d2021-06-25 12:20:0459 export const enum Commands {
60 AddRequestHeaders = 'addRequestHeaders',
61 AddTraceProvider = 'addTraceProvider',
62 ApplyStyleSheet = 'applyStyleSheet',
63 CompleteTraceSession = 'completeTra.eSession',
64 CreatePanel = 'createPanel',
65 CreateSidebarPane = 'createSidebarPane',
66 CreateToolbarButton = 'createToolbarButton',
67 EvaluateOnInspectedPage = 'evaluateOnInspectedPage',
68 ForwardKeyboardEvent = '_forwardKeyboardEvent',
69 GetHAR = 'getHAR',
70 GetPageResources = 'getPageResources',
71 GetRequestContent = 'getRequestContent',
72 GetResourceContent = 'getResourceContent',
73 OpenResource = 'openResource',
74 Reload = 'Reload',
75 Subscribe = 'subscribe',
76 SetOpenResourceHandler = 'setOpenResourceHandler',
77 SetResourceContent = 'setResourceContent',
78 SetSidebarContent = 'setSidebarContent',
79 SetSidebarHeight = 'setSidebarHeight',
80 SetSidebarPage = 'setSidebarPage',
81 ShowPanel = 'showPanel',
82 Unsubscribe = 'unsubscribe',
83 UpdateButton = 'updateButton',
84 RegisterLanguageExtensionPlugin = 'registerLanguageExtensionPlugin',
85 }
Philip Pfaffeedad8322020-07-20 10:24:2586
Philip Pfaffe939605d2021-06-25 12:20:0487 export const enum LanguageExtensionPluginCommands {
88 AddRawModule = 'addRawModule',
89 RemoveRawModule = 'removeRawModule',
90 SourceLocationToRawLocation = 'sourceLocationToRawLocation',
91 RawLocationToSourceLocation = 'rawLocationToSourceLocation',
92 GetScopeInfo = 'getScopeInfo',
93 ListVariablesInScope = 'listVariablesInScope',
94 GetTypeInfo = 'getTypeInfo',
95 GetFormatter = 'getFormatter',
96 GetInspectableAddress = 'getInspectableAddress',
97 GetFunctionInfo = 'getFunctionInfo',
98 GetInlinedFunctionRanges = 'getInlinedFunctionRanges',
99 GetInlinedCalleesRanges = 'getInlinedCalleesRanges',
100 GetMappedLines = 'getMappedLines',
101 }
Benedikt Meurer929fc7c2020-11-20 14:21:06102
Philip Pfaffe939605d2021-06-25 12:20:04103 export const enum LanguageExtensionPluginEvents {
104 UnregisteredLanguageExtensionPlugin = 'unregisteredLanguageExtensionPlugin',
105 }
Philip Pfaffed662bdf2021-06-25 13:30:32106
107 export interface EvaluateOptions {
108 frameURL?: string;
109 useContentScriptContext?: boolean;
110 scriptExecutionContext?: string;
111 }
112
Philip Pfaffed662bdf2021-06-25 13:30:32113 type RegisterLanguageExtensionPluginRequest = {
114 command: Commands.RegisterLanguageExtensionPlugin,
115 pluginName: string,
116 port: MessagePort,
Philip Pfaffe7523faf2021-06-28 14:23:14117 supportedScriptTypes: PublicAPI.Chrome.DevTools.SupportedScriptTypes,
Philip Pfaffed662bdf2021-06-25 13:30:32118 };
119 type SubscribeRequest = {command: Commands.Subscribe, type: string};
120 type UnsubscribeRequest = {command: Commands.Unsubscribe, type: string};
121 type AddRequestHeadersRequest = {
122 command: Commands.AddRequestHeaders,
123 extensionId: string,
124 headers: {[key: string]: string},
125 };
126 type ApplyStyleSheetRequest = {command: Commands.ApplyStyleSheet, styleSheet: string};
127 type CreatePanelRequest = {command: Commands.CreatePanel, id: string, title: string, page: string};
128 type ShowPanelRequest = {command: Commands.ShowPanel, id: string};
129 type CreateToolbarButtonRequest = {
130 command: Commands.CreateToolbarButton,
131 id: string,
132 icon: string,
133 panel: string,
134 tooltip?: string,
135 disabled?: boolean,
136 };
137 type UpdateButtonRequest =
138 {command: Commands.UpdateButton, id: string, icon?: string, tooltip?: string, disabled?: boolean};
139 type CompleteTraceSessionRequest =
140 {command: Commands.CompleteTraceSession, id: string, url: string, timeOffset: number};
141 type CreateSidebarPaneRequest = {command: Commands.CreateSidebarPane, id: string, panel: string, title: string};
142 type SetSidebarHeightRequest = {command: Commands.SetSidebarHeight, id: string, height: string};
143 type SetSidebarContentRequest = {
144 command: Commands.SetSidebarContent,
145 id: string,
146 evaluateOnPage?: boolean, expression: string,
147 rootTitle?: string,
148 evaluateOptions?: EvaluateOptions,
149 };
150 type SetSidebarPageRequest = {command: Commands.SetSidebarPage, id: string, page: string};
151 type OpenResourceRequest = {command: Commands.OpenResource, url: string, lineNumber: number};
152 type SetOpenResourceHandlerRequest = {command: Commands.SetOpenResourceHandler, handlerPresent: boolean};
153 type ReloadRequest = {
154 command: Commands.Reload,
155 options: null|{
156 userAgent?: string,
157 injectedScript?: string,
158 ignoreCache?: boolean,
159 },
160 };
161 type EvaluateOnInspectedPageRequest = {
162 command: Commands.EvaluateOnInspectedPage,
163 expression: string,
164 evaluateOptions?: EvaluateOptions,
165 };
166 type GetRequestContentRequest = {command: Commands.GetRequestContent, id: number};
167 type GetResourceContentRequest = {command: Commands.GetResourceContent, url: string};
168 type SetResourceContentRequest =
169 {command: Commands.SetResourceContent, url: string, content: string, commit: boolean};
170 type AddTraceProviderRequest =
171 {command: Commands.AddTraceProvider, id: string, categoryName: string, categoryTooltip: string};
172 type ForwardKeyboardEventRequest = {
173 command: Commands.ForwardKeyboardEvent,
174 entries: Array<KeyboardEventInit&{eventType: string}>,
175 };
176 type GetHARRequest = {command: Commands.GetHAR};
177 type GetPageResourcesRequest = {command: Commands.GetPageResources};
178
179 export type ServerRequests = RegisterLanguageExtensionPluginRequest|SubscribeRequest|UnsubscribeRequest|
180 AddRequestHeadersRequest|ApplyStyleSheetRequest|CreatePanelRequest|ShowPanelRequest|CreateToolbarButtonRequest|
181 UpdateButtonRequest|CompleteTraceSessionRequest|CreateSidebarPaneRequest|SetSidebarHeightRequest|
182 SetSidebarContentRequest|SetSidebarPageRequest|OpenResourceRequest|SetOpenResourceHandlerRequest|ReloadRequest|
183 EvaluateOnInspectedPageRequest|GetRequestContentRequest|GetResourceContentRequest|SetResourceContentRequest|
184 AddTraceProviderRequest|ForwardKeyboardEventRequest|GetHARRequest|GetPageResourcesRequest;
185 export type ExtensionServerRequestMessage = PrivateAPI.ServerRequests&{requestId?: number};
Blink Reformat4c46d092018-04-07 15:32:37186}
187
Philip Pfaffe939605d2021-06-25 12:20:04188declare global {
189 interface Window {
190 injectedExtensionAPI:
191 (extensionInfo: ExtensionDescriptor, inspectedTabId: string, themeName: string, keysToForward: number[],
Philip Pfaffe7523faf2021-06-28 14:23:14192 testHook:
193 (extensionServer: APIImpl.ExtensionServerClient, extensionAPI: APIImpl.InspectorExtensionAPI) => unknown,
194 injectedScriptId: number) => void;
Philip Pfaffe939605d2021-06-25 12:20:04195 buildExtensionAPIInjectedScript(
196 extensionInfo: ExtensionDescriptor, inspectedTabId: string, themeName: string, keysToForward: number[],
Philip Pfaffed662bdf2021-06-25 13:30:32197 testHook: undefined|((extensionServer: unknown, extensionAPI: unknown) => unknown)): string;
Philip Pfaffe7523faf2021-06-28 14:23:14198 chrome: PublicAPI.Chrome.DevTools.Chrome;
199 webInspector?: APIImpl.InspectorExtensionAPI;
Philip Pfaffe939605d2021-06-25 12:20:04200 }
201}
202
203export type ExtensionDescriptor = {
204 startPage: string,
205 name: string,
206 exposeExperimentalAPIs: boolean,
207 exposeWebInspectorNamespace?: boolean,
208};
209
Philip Pfaffe7523faf2021-06-28 14:23:14210namespace APIImpl {
211 export interface InspectorExtensionAPI {
212 languageServices: PublicAPI.Chrome.DevTools.LanguageExtensions;
213 network: PublicAPI.Chrome.DevTools.Network;
214 panels: PublicAPI.Chrome.DevTools.Panels;
215 inspectedWindow: PublicAPI.Chrome.DevTools.InspectedWindow;
216 }
217
218 export interface ExtensionServerClient {
219 _callbacks: {[key: string]: (response: unknown) => unknown};
220 _handlers: {[key: string]: (request: {arguments: unknown[]}) => unknown};
221 _lastRequestId: number;
222 _lastObjectId: number;
223 _port: MessagePort;
224
225 _onCallback(request: unknown): void;
226 _onMessage(event: MessageEvent<{command: string, requestId: number, arguments: unknown[]}>): void;
227 _registerCallback(callback: (response: unknown) => unknown): number;
228 registerHandler(command: string, handler: (request: {arguments: unknown[]}) => unknown): void;
229 unregisterHandler(command: string): void;
230 hasHandler(command: string): boolean;
231 sendRequest(request: PrivateAPI.ServerRequests, callback?: ((response: unknown) => unknown), transfers?: unknown[]):
232 void;
233 nextObjectId(): string;
234 }
235
236 // We cannot use the stronger `unknown` type in place of `any` in the following type definition. The type is used as
237 // the right-hand side of `extends` in a few places, which doesn't narrow `unknown`. Without narrowing, overload
238 // resolution and meaningful type inference of arguments break, for example.
239 // eslint-disable-next-line @typescript-eslint/no-explicit-any
240 export type Callable = (...args: any) => any;
241
242 export interface EventSink<ListenerT extends Callable> extends PublicAPI.Chrome.DevTools.EventSink<ListenerT> {
243 _type: string;
244 _listeners: ListenerT[];
245 _customDispatch: undefined|((this: EventSink<ListenerT>, request: {arguments: unknown[]}) => unknown);
246
247 _fire(..._vararg: Parameters<ListenerT>): void;
248 _dispatch(request: {arguments: unknown[]}): void;
249 }
250}
Philip Pfaffe939605d2021-06-25 12:20:04251
Tim van der Lippe226fc222019-10-10 12:17:12252self.injectedExtensionAPI = function(
Philip Pfaffe7523faf2021-06-28 14:23:14253 extensionInfo: ExtensionDescriptor, inspectedTabId: string, themeName: string, keysToForward: number[],
254 testHook: (extensionServer: APIImpl.ExtensionServerClient, extensionAPI: APIImpl.InspectorExtensionAPI) => unknown,
255 injectedScriptId: number): void {
Jan Schefflerd76b4162021-03-29 07:52:16256 const keysToForwardSet = new Set<number>(keysToForward);
Blink Reformat4c46d092018-04-07 15:32:37257 const chrome = window.chrome || {};
Jan Schefflerd76b4162021-03-29 07:52:16258
Blink Reformat4c46d092018-04-07 15:32:37259 const devtools_descriptor = Object.getOwnPropertyDescriptor(chrome, 'devtools');
Tim van der Lippe1d6e57a2019-09-30 11:55:34260 if (devtools_descriptor) {
Blink Reformat4c46d092018-04-07 15:32:37261 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34262 }
Blink Reformat4c46d092018-04-07 15:32:37263 let userAction = false;
264
265 // Here and below, all constructors are private to API implementation.
266 // For a public type Foo, if internal fields are present, these are on
267 // a private FooImpl type, an instance of FooImpl is used in a closure
268 // by Foo consutrctor to re-bind publicly exported members to an instance
269 // of Foo.
270
Philip Pfaffe7523faf2021-06-28 14:23:14271 function EventSinkImpl<ListenerT extends APIImpl.Callable>(
272 this: APIImpl.EventSink<ListenerT>, type: string,
273 customDispatch?: (this: APIImpl.EventSink<ListenerT>, request: {arguments: unknown[]}) => unknown): void {
Blink Reformat4c46d092018-04-07 15:32:37274 this._type = type;
275 this._listeners = [];
276 this._customDispatch = customDispatch;
277 }
278
279 EventSinkImpl.prototype = {
Philip Pfaffe7523faf2021-06-28 14:23:14280 addListener: function<ListenerT extends APIImpl.Callable>(this: APIImpl.EventSink<ListenerT>, callback: ListenerT):
281 void {
282 if (typeof callback !== 'function') {
283 throw 'addListener: callback is not a function';
284 }
285 if (this._listeners.length === 0) {
286 extensionServer.sendRequest({command: PrivateAPI.Commands.Subscribe, type: this._type});
287 }
288 this._listeners.push(callback);
289 extensionServer.registerHandler('notify-' + this._type, this._dispatch.bind(this));
290 },
Blink Reformat4c46d092018-04-07 15:32:37291
Jan Schefflerd76b4162021-03-29 07:52:16292
Philip Pfaffe7523faf2021-06-28 14:23:14293 removeListener: function<ListenerT extends APIImpl.Callable>(
294 this: APIImpl.EventSink<ListenerT>, callback: ListenerT): void {
Blink Reformat4c46d092018-04-07 15:32:37295 const listeners = this._listeners;
296
297 for (let i = 0; i < listeners.length; ++i) {
298 if (listeners[i] === callback) {
299 listeners.splice(i, 1);
300 break;
301 }
302 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34303 if (this._listeners.length === 0) {
Philip Pfaffe939605d2021-06-25 12:20:04304 extensionServer.sendRequest({command: PrivateAPI.Commands.Unsubscribe, type: this._type});
Tim van der Lippe1d6e57a2019-09-30 11:55:34305 }
Blink Reformat4c46d092018-04-07 15:32:37306 },
307
Jan Schefflerd76b4162021-03-29 07:52:16308
Philip Pfaffe7523faf2021-06-28 14:23:14309 _fire: function<ListenerT extends APIImpl.Callable>(
310 this: APIImpl.EventSink<ListenerT>, ..._vararg: Parameters<ListenerT>): void {
Blink Reformat4c46d092018-04-07 15:32:37311 const listeners = this._listeners.slice();
Tim van der Lippe1d6e57a2019-09-30 11:55:34312 for (let i = 0; i < listeners.length; ++i) {
Philip Pfaffe7523faf2021-06-28 14:23:14313 listeners[i].apply(null, Array.from(arguments));
Tim van der Lippe1d6e57a2019-09-30 11:55:34314 }
Blink Reformat4c46d092018-04-07 15:32:37315 },
316
Jan Schefflerd76b4162021-03-29 07:52:16317
Philip Pfaffe7523faf2021-06-28 14:23:14318 _dispatch: function<ListenerT extends APIImpl.Callable>(
319 this: APIImpl.EventSink<ListenerT>, request: {arguments: unknown[]}): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:34320 if (this._customDispatch) {
Blink Reformat4c46d092018-04-07 15:32:37321 this._customDispatch.call(this, request);
Tim van der Lippe1d6e57a2019-09-30 11:55:34322 } else {
Philip Pfaffe7523faf2021-06-28 14:23:14323 this._fire.apply(this, request.arguments as Parameters<ListenerT>);
Tim van der Lippe1d6e57a2019-09-30 11:55:34324 }
Jan Schefflerd76b4162021-03-29 07:52:16325 },
Blink Reformat4c46d092018-04-07 15:32:37326 };
327
Philip Pfaffe7523faf2021-06-28 14:23:14328 function Constructor<NewT extends APIImpl.Callable>(ctor: NewT): new (...args: Parameters<NewT>) =>
329 ThisParameterType<NewT> {
330 return ctor as unknown as new (...args: Parameters<NewT>) => ThisParameterType<NewT>;
331 }
332
Blink Reformat4c46d092018-04-07 15:32:37333 /**
334 * @constructor
335 */
Jan Schefflerd76b4162021-03-29 07:52:16336
Philip Pfaffe7523faf2021-06-28 14:23:14337 function InspectorExtensionAPI(this: APIImpl.InspectorExtensionAPI): void {
Philip Pfaffe939605d2021-06-25 12:20:04338 // @ts-ignore
Blink Reformat4c46d092018-04-07 15:32:37339 this.inspectedWindow = new InspectedWindow();
Philip Pfaffe939605d2021-06-25 12:20:04340 // @ts-ignore
Blink Reformat4c46d092018-04-07 15:32:37341 this.panels = new Panels();
Philip Pfaffe939605d2021-06-25 12:20:04342 // @ts-ignore
Blink Reformat4c46d092018-04-07 15:32:37343 this.network = new Network();
Philip Pfaffe939605d2021-06-25 12:20:04344 // @ts-ignore
Blink Reformat4c46d092018-04-07 15:32:37345 this.timeline = new Timeline();
Philip Pfaffe939605d2021-06-25 12:20:04346 // @ts-ignore
Philip Pfaffeedad8322020-07-20 10:24:25347 this.languageServices = new LanguageServicesAPI();
Blink Reformat4c46d092018-04-07 15:32:37348 defineDeprecatedProperty(this, 'webInspector', 'resources', 'network');
349 }
350
351 /**
352 * @constructor
353 */
Jan Schefflerd76b4162021-03-29 07:52:16354
Philip Pfaffe939605d2021-06-25 12:20:04355 function Network(this: any): void {
356 function dispatchRequestEvent(this: any, message: any): void {
Blink Reformat4c46d092018-04-07 15:32:37357 const request = message.arguments[1];
Philip Pfaffe939605d2021-06-25 12:20:04358 // @ts-ignore
Blink Reformat4c46d092018-04-07 15:32:37359 request.__proto__ = new Request(message.arguments[0]);
360 this._fire(request);
361 }
Philip Pfaffe939605d2021-06-25 12:20:04362 // @ts-ignore
363 this.onRequestFinished = new EventSink(PrivateAPI.Events.NetworkRequestFinished, dispatchRequestEvent);
Blink Reformat4c46d092018-04-07 15:32:37364 defineDeprecatedProperty(this, 'network', 'onFinished', 'onRequestFinished');
Philip Pfaffe939605d2021-06-25 12:20:04365 // @ts-ignore
366 this.onNavigated = new EventSink(PrivateAPI.Events.InspectedURLChanged);
Blink Reformat4c46d092018-04-07 15:32:37367 }
368
369 Network.prototype = {
Jan Schefflerd76b4162021-03-29 07:52:16370 getHAR: function(callback: any): void {
371 function callbackWrapper(result: any): void {
Blink Reformat4c46d092018-04-07 15:32:37372 const entries = (result && result.entries) || [];
373 for (let i = 0; i < entries.length; ++i) {
Philip Pfaffe939605d2021-06-25 12:20:04374 // @ts-ignore
Blink Reformat4c46d092018-04-07 15:32:37375 entries[i].__proto__ = new Request(entries[i]._requestId);
376 delete entries[i]._requestId;
377 }
378 callback(result);
379 }
Philip Pfaffe939605d2021-06-25 12:20:04380 extensionServer.sendRequest({command: PrivateAPI.Commands.GetHAR}, callback && callbackWrapper);
Blink Reformat4c46d092018-04-07 15:32:37381 },
382
Jan Schefflerd76b4162021-03-29 07:52:16383 addRequestHeaders: function(headers: any): void {
Blink Reformat4c46d092018-04-07 15:32:37384 extensionServer.sendRequest(
Philip Pfaffe939605d2021-06-25 12:20:04385 {command: PrivateAPI.Commands.AddRequestHeaders, headers: headers, extensionId: window.location.hostname});
Jan Schefflerd76b4162021-03-29 07:52:16386 },
Blink Reformat4c46d092018-04-07 15:32:37387 };
388
Philip Pfaffe939605d2021-06-25 12:20:04389 function RequestImpl(this: any, id: any): void {
Blink Reformat4c46d092018-04-07 15:32:37390 this._id = id;
391 }
392
393 RequestImpl.prototype = {
Jan Schefflerd76b4162021-03-29 07:52:16394 getContent: function(callback: any): void {
395 function callbackWrapper(response: any): void {
Blink Reformat4c46d092018-04-07 15:32:37396 callback(response.content, response.encoding);
397 }
Philip Pfaffe939605d2021-06-25 12:20:04398 extensionServer.sendRequest(
399 {command: PrivateAPI.Commands.GetRequestContent, id: this._id}, callback && callbackWrapper);
Jan Schefflerd76b4162021-03-29 07:52:16400 },
Blink Reformat4c46d092018-04-07 15:32:37401 };
402
403 /**
404 * @constructor
405 */
Philip Pfaffe939605d2021-06-25 12:20:04406 function Panels(this: any): void {
407 const panels: {[key: string]: any} = {
Blink Reformat4c46d092018-04-07 15:32:37408 elements: new ElementsPanel(),
409 sources: new SourcesPanel(),
410 };
411
Jan Schefflerd76b4162021-03-29 07:52:16412 function panelGetter(name: any): any {
Blink Reformat4c46d092018-04-07 15:32:37413 return panels[name];
414 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34415 for (const panel in panels) {
Tim van der Lippeffa78622019-09-16 12:07:12416 Object.defineProperty(this, panel, {get: panelGetter.bind(null, panel), enumerable: true});
Tim van der Lippe1d6e57a2019-09-30 11:55:34417 }
Jan Schefflerd76b4162021-03-29 07:52:16418 this.applyStyleSheet = function(styleSheet: any): void {
Philip Pfaffe939605d2021-06-25 12:20:04419 extensionServer.sendRequest({command: PrivateAPI.Commands.ApplyStyleSheet, styleSheet: styleSheet});
Blink Reformat4c46d092018-04-07 15:32:37420 };
421 }
422
423 Panels.prototype = {
Jan Schefflerd76b4162021-03-29 07:52:16424 create: function(title: any, icon: any, page: any, callback: any): void {
Blink Reformat4c46d092018-04-07 15:32:37425 const id = 'extension-panel-' + extensionServer.nextObjectId();
Philip Pfaffe939605d2021-06-25 12:20:04426 const request = {command: PrivateAPI.Commands.CreatePanel, id: id, title: title, icon: icon, page: page};
427 // @ts-ignore
Blink Reformat4c46d092018-04-07 15:32:37428 extensionServer.sendRequest(request, callback && callback.bind(this, new ExtensionPanel(id)));
429 },
430
Jan Schefflerd76b4162021-03-29 07:52:16431 setOpenResourceHandler: function(callback: any): void {
Philip Pfaffe939605d2021-06-25 12:20:04432 const hadHandler = extensionServer.hasHandler(PrivateAPI.Events.OpenResource);
Blink Reformat4c46d092018-04-07 15:32:37433
Jan Schefflerd76b4162021-03-29 07:52:16434 function callbackWrapper(message: any): void {
Blink Reformat4c46d092018-04-07 15:32:37435 // Allow the panel to show itself when handling the event.
436 userAction = true;
437 try {
Philip Pfaffe939605d2021-06-25 12:20:04438 // @ts-ignore
Blink Reformat4c46d092018-04-07 15:32:37439 callback.call(null, new Resource(message.resource), message.lineNumber);
440 } finally {
441 userAction = false;
442 }
443 }
444
Tim van der Lippe1d6e57a2019-09-30 11:55:34445 if (!callback) {
Philip Pfaffe939605d2021-06-25 12:20:04446 extensionServer.unregisterHandler(PrivateAPI.Events.OpenResource);
Tim van der Lippe1d6e57a2019-09-30 11:55:34447 } else {
Philip Pfaffe939605d2021-06-25 12:20:04448 extensionServer.registerHandler(PrivateAPI.Events.OpenResource, callbackWrapper);
Tim van der Lippe1d6e57a2019-09-30 11:55:34449 }
Blink Reformat4c46d092018-04-07 15:32:37450
451 // 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:34452 if (hadHandler === !callback) {
Philip Pfaffe939605d2021-06-25 12:20:04453 extensionServer.sendRequest(
454 {command: PrivateAPI.Commands.SetOpenResourceHandler, 'handlerPresent': Boolean(callback)});
Tim van der Lippe1d6e57a2019-09-30 11:55:34455 }
Blink Reformat4c46d092018-04-07 15:32:37456 },
457
Jan Schefflerd76b4162021-03-29 07:52:16458 openResource: function(url: any, lineNumber: any, callback: any): void {
Philip Pfaffe939605d2021-06-25 12:20:04459 extensionServer.sendRequest(
460 {command: PrivateAPI.Commands.OpenResource, 'url': url, 'lineNumber': lineNumber}, callback);
Blink Reformat4c46d092018-04-07 15:32:37461 },
462
Jan Schefflerd76b4162021-03-29 07:52:16463 get SearchAction(): any {
Philip Pfaffe939605d2021-06-25 12:20:04464 return {
465 CancelSearch: PrivateAPI.Panels.SearchAction.CancelSearch,
466 PerformSearch: PrivateAPI.Panels.SearchAction.PerformSearch,
467 NextSearchResult: PrivateAPI.Panels.SearchAction.NextSearchResult,
468 PreviousSearchResult: PrivateAPI.Panels.SearchAction.PreviousSearchResult,
469 };
Jan Schefflerd76b4162021-03-29 07:52:16470 },
Blink Reformat4c46d092018-04-07 15:32:37471 };
472
473 /**
474 * @constructor
475 */
Philip Pfaffe939605d2021-06-25 12:20:04476 function ExtensionViewImpl(this: any, id: any): void {
Blink Reformat4c46d092018-04-07 15:32:37477 this._id = id;
478
Philip Pfaffe939605d2021-06-25 12:20:04479 function dispatchShowEvent(this: any, message: any): void {
Blink Reformat4c46d092018-04-07 15:32:37480 const frameIndex = message.arguments[0];
Tim van der Lippe1d6e57a2019-09-30 11:55:34481 if (typeof frameIndex === 'number') {
Blink Reformat4c46d092018-04-07 15:32:37482 this._fire(window.parent.frames[frameIndex]);
Tim van der Lippe1d6e57a2019-09-30 11:55:34483 } else {
Blink Reformat4c46d092018-04-07 15:32:37484 this._fire();
Tim van der Lippe1d6e57a2019-09-30 11:55:34485 }
Blink Reformat4c46d092018-04-07 15:32:37486 }
487
488 if (id) {
Philip Pfaffe939605d2021-06-25 12:20:04489 // @ts-ignore
490 this.onShown = new EventSink(PrivateAPI.Events.ViewShown + id, dispatchShowEvent);
491 // @ts-ignore
492 this.onHidden = new EventSink(PrivateAPI.Events.ViewHidden + id);
Blink Reformat4c46d092018-04-07 15:32:37493 }
494 }
495
496 /**
497 * @constructor
498 * @extends {ExtensionViewImpl}
Blink Reformat4c46d092018-04-07 15:32:37499 */
Philip Pfaffe939605d2021-06-25 12:20:04500 function PanelWithSidebarImpl(this: any, hostPanelName: string): void {
Blink Reformat4c46d092018-04-07 15:32:37501 ExtensionViewImpl.call(this, null);
502 this._hostPanelName = hostPanelName;
Philip Pfaffe939605d2021-06-25 12:20:04503 // @ts-ignore
504 this.onSelectionChanged = new EventSink(PrivateAPI.Events.PanelObjectSelected + hostPanelName);
Blink Reformat4c46d092018-04-07 15:32:37505 }
506
507 PanelWithSidebarImpl.prototype = {
Jan Schefflerd76b4162021-03-29 07:52:16508 createSidebarPane: function(title: any, callback: any): void {
Blink Reformat4c46d092018-04-07 15:32:37509 const id = 'extension-sidebar-' + extensionServer.nextObjectId();
Jan Schefflerd76b4162021-03-29 07:52:16510 function callbackWrapper(): void {
Philip Pfaffe939605d2021-06-25 12:20:04511 // @ts-ignore
Blink Reformat4c46d092018-04-07 15:32:37512 callback(new ExtensionSidebarPane(id));
513 }
Philip Pfaffe7523faf2021-06-28 14:23:14514 extensionServer.sendRequest(
515 {command: PrivateAPI.Commands.CreateSidebarPane, panel: this._hostPanelName, id: id, title: title},
516 callback && callbackWrapper);
Blink Reformat4c46d092018-04-07 15:32:37517 },
518
Jan Schefflerd76b4162021-03-29 07:52:16519 __proto__: ExtensionViewImpl.prototype,
Blink Reformat4c46d092018-04-07 15:32:37520 };
521
Philip Pfaffeedad8322020-07-20 10:24:25522 /**
523 * @constructor
524 */
Philip Pfaffe939605d2021-06-25 12:20:04525 function LanguageServicesAPIImpl(this: any): void {
Benedikt Meurer929fc7c2020-11-20 14:21:06526 /** @type {!Map<*, !MessagePort>} */
Philip Pfaffeedad8322020-07-20 10:24:25527 this._plugins = new Map();
528 }
529
530 LanguageServicesAPIImpl.prototype = {
Philip Pfaffed662bdf2021-06-25 13:30:32531 registerLanguageExtensionPlugin: async function(
Philip Pfaffe7523faf2021-06-28 14:23:14532 plugin: any, pluginName: string, supportedScriptTypes: PublicAPI.Chrome.DevTools.SupportedScriptTypes):
533 Promise<void> {
534 if (this._plugins.has(plugin)) {
535 throw new Error(`Tried to register plugin '${pluginName}' twice`);
536 }
537 const channel = new MessageChannel();
538 const port = channel.port1;
539 this._plugins.set(plugin, port);
540 port.onmessage = ({data: {requestId, method, parameters}}: MessageEvent<any>): void => {
541 console.time(`${requestId}: ${method}`);
542 dispatchMethodCall(method, parameters)
543 .then(result => port.postMessage({requestId, result}))
544 .catch(error => port.postMessage({requestId, error: {message: error.message}}))
545 .finally(() => console.timeEnd(`${requestId}: ${method}`));
546 };
Philip Pfaffeedad8322020-07-20 10:24:25547
Philip Pfaffe7523faf2021-06-28 14:23:14548 function dispatchMethodCall(method: string, parameters: any): Promise<any> {
549 switch (method) {
550 case PrivateAPI.LanguageExtensionPluginCommands.AddRawModule:
551 return plugin.addRawModule(parameters.rawModuleId, parameters.symbolsURL, parameters.rawModule);
552 case PrivateAPI.LanguageExtensionPluginCommands.RemoveRawModule:
553 return plugin.removeRawModule(parameters.rawModuleId);
554 case PrivateAPI.LanguageExtensionPluginCommands.SourceLocationToRawLocation:
555 return plugin.sourceLocationToRawLocation(parameters.sourceLocation);
556 case PrivateAPI.LanguageExtensionPluginCommands.RawLocationToSourceLocation:
557 return plugin.rawLocationToSourceLocation(parameters.rawLocation);
558 case PrivateAPI.LanguageExtensionPluginCommands.GetScopeInfo:
559 return plugin.getScopeInfo(parameters.type);
560 case PrivateAPI.LanguageExtensionPluginCommands.ListVariablesInScope:
561 return plugin.listVariablesInScope(parameters.rawLocation);
562 case PrivateAPI.LanguageExtensionPluginCommands.GetTypeInfo:
563 return plugin.getTypeInfo(parameters.expression, parameters.context);
564 case PrivateAPI.LanguageExtensionPluginCommands.GetFormatter:
565 return plugin.getFormatter(parameters.expressionOrField, parameters.context);
566 case PrivateAPI.LanguageExtensionPluginCommands.GetInspectableAddress:
567 if ('getInspectableAddress' in plugin) {
568 return plugin.getInspectableAddress(parameters.field);
569 }
570 return Promise.resolve({js: ''});
571 case PrivateAPI.LanguageExtensionPluginCommands.GetFunctionInfo:
572 return plugin.getFunctionInfo(parameters.rawLocation);
573 case PrivateAPI.LanguageExtensionPluginCommands.GetInlinedFunctionRanges:
574 return plugin.getInlinedFunctionRanges(parameters.rawLocation);
575 case PrivateAPI.LanguageExtensionPluginCommands.GetInlinedCalleesRanges:
576 return plugin.getInlinedCalleesRanges(parameters.rawLocation);
577 case PrivateAPI.LanguageExtensionPluginCommands.GetMappedLines:
578 if ('getMappedLines' in plugin) {
579 return plugin.getMappedLines(parameters.rawModuleId, parameters.sourceFileURL);
580 }
581 return Promise.resolve(undefined);
Kim-Anh Tran8fd7d6f2021-01-28 11:07:02582 }
Philip Pfaffe7523faf2021-06-28 14:23:14583 throw new Error(`Unknown language plugin method ${method}`);
584 }
Philip Pfaffeedad8322020-07-20 10:24:25585
Philip Pfaffe7523faf2021-06-28 14:23:14586 await new Promise<void>(resolve => {
587 extensionServer.sendRequest(
588 {
589 command: PrivateAPI.Commands.RegisterLanguageExtensionPlugin,
590 pluginName,
591 port: channel.port2,
592 supportedScriptTypes,
593 },
594 () => resolve(), [channel.port2]);
595 });
596 },
Benedikt Meurer929fc7c2020-11-20 14:21:06597
Jan Schefflerd76b4162021-03-29 07:52:16598 unregisterLanguageExtensionPlugin: async function(plugin: any): Promise<void> {
Benedikt Meurer929fc7c2020-11-20 14:21:06599 const port = this._plugins.get(plugin);
600 if (!port) {
601 throw new Error('Tried to unregister a plugin that was not previously registered');
602 }
603 this._plugins.delete(plugin);
Philip Pfaffe939605d2021-06-25 12:20:04604 port.postMessage({event: PrivateAPI.LanguageExtensionPluginEvents.UnregisteredLanguageExtensionPlugin});
Benedikt Meurer929fc7c2020-11-20 14:21:06605 port.close();
Jan Schefflerd76b4162021-03-29 07:52:16606 },
Philip Pfaffeedad8322020-07-20 10:24:25607 };
608
Philip Pfaffe7523faf2021-06-28 14:23:14609 function declareInterfaceClass<ImplT extends APIImpl.Callable>(implConstructor: ImplT): (
610 this: ThisParameterType<ImplT>, ...args: Parameters<ImplT>) => void {
611 return function(this: ThisParameterType<ImplT>, ...args: Parameters<ImplT>): void {
Blink Reformat4c46d092018-04-07 15:32:37612 const impl = {__proto__: implConstructor.prototype};
Philip Pfaffe7523faf2021-06-28 14:23:14613 implConstructor.apply(impl, args);
614 populateInterfaceClass(this as {[key: string]: unknown}, impl);
Blink Reformat4c46d092018-04-07 15:32:37615 };
616 }
617
Philip Pfaffe7523faf2021-06-28 14:23:14618 // eslint-disable-next-line @typescript-eslint/no-explicit-any
619 function defineDeprecatedProperty(object: any, className: string, oldName: string, newName: string): void {
Blink Reformat4c46d092018-04-07 15:32:37620 let warningGiven = false;
Philip Pfaffe7523faf2021-06-28 14:23:14621 function getter(): unknown {
Blink Reformat4c46d092018-04-07 15:32:37622 if (!warningGiven) {
623 console.warn(className + '.' + oldName + ' is deprecated. Use ' + className + '.' + newName + ' instead');
624 warningGiven = true;
625 }
626 return object[newName];
627 }
628 object.__defineGetter__(oldName, getter);
629 }
630
Philip Pfaffe7523faf2021-06-28 14:23:14631 function extractCallbackArgument(args: IArguments): ((...args: unknown[]) => unknown)|undefined {
Blink Reformat4c46d092018-04-07 15:32:37632 const lastArgument = args[args.length - 1];
Philip Pfaffe7523faf2021-06-28 14:23:14633 return typeof lastArgument === 'function' ? lastArgument as (...args: unknown[]) => unknown : undefined;
Blink Reformat4c46d092018-04-07 15:32:37634 }
635
Philip Pfaffeedad8322020-07-20 10:24:25636 const LanguageServicesAPI = declareInterfaceClass(LanguageServicesAPIImpl);
Blink Reformat4c46d092018-04-07 15:32:37637 const Button = declareInterfaceClass(ButtonImpl);
638 const EventSink = declareInterfaceClass(EventSinkImpl);
639 const ExtensionPanel = declareInterfaceClass(ExtensionPanelImpl);
640 const ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl);
Tim van der Lippeffa78622019-09-16 12:07:12641 /**
642 * @constructor
643 * @param {string} hostPanelName
644 */
645 const PanelWithSidebarClass = declareInterfaceClass(PanelWithSidebarImpl);
Blink Reformat4c46d092018-04-07 15:32:37646 const Request = declareInterfaceClass(RequestImpl);
647 const Resource = declareInterfaceClass(ResourceImpl);
648 const TraceSession = declareInterfaceClass(TraceSessionImpl);
649
Philip Pfaffe939605d2021-06-25 12:20:04650 // @ts-ignore
Tim van der Lippeffa78622019-09-16 12:07:12651 class ElementsPanel extends PanelWithSidebarClass {
652 constructor() {
653 super('elements');
654 }
Blink Reformat4c46d092018-04-07 15:32:37655 }
656
Philip Pfaffe939605d2021-06-25 12:20:04657 // @ts-ignore
Tim van der Lippeffa78622019-09-16 12:07:12658 class SourcesPanel extends PanelWithSidebarClass {
659 constructor() {
660 super('sources');
661 }
Blink Reformat4c46d092018-04-07 15:32:37662 }
663
Blink Reformat4c46d092018-04-07 15:32:37664 /**
665 * @constructor
666 * @extends {ExtensionViewImpl}
667 */
Philip Pfaffe939605d2021-06-25 12:20:04668 function ExtensionPanelImpl(this: any, id: any): void {
Blink Reformat4c46d092018-04-07 15:32:37669 ExtensionViewImpl.call(this, id);
Philip Pfaffe939605d2021-06-25 12:20:04670 // @ts-ignore
671 this.onSearch = new EventSink(PrivateAPI.Events.PanelSearch + id);
Blink Reformat4c46d092018-04-07 15:32:37672 }
673
674 ExtensionPanelImpl.prototype = {
Jan Schefflerd76b4162021-03-29 07:52:16675 createStatusBarButton: function(iconPath: any, tooltipText: any, disabled: any): Object {
Blink Reformat4c46d092018-04-07 15:32:37676 const id = 'button-' + extensionServer.nextObjectId();
Philip Pfaffe7523faf2021-06-28 14:23:14677 extensionServer.sendRequest({
Philip Pfaffe939605d2021-06-25 12:20:04678 command: PrivateAPI.Commands.CreateToolbarButton,
Blink Reformat4c46d092018-04-07 15:32:37679 panel: this._id,
680 id: id,
681 icon: iconPath,
682 tooltip: tooltipText,
Jan Schefflerd76b4162021-03-29 07:52:16683 disabled: Boolean(disabled),
Philip Pfaffe7523faf2021-06-28 14:23:14684 });
Philip Pfaffe939605d2021-06-25 12:20:04685 // @ts-ignore
Blink Reformat4c46d092018-04-07 15:32:37686 return new Button(id);
687 },
688
Jan Schefflerd76b4162021-03-29 07:52:16689 show: function(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:34690 if (!userAction) {
Blink Reformat4c46d092018-04-07 15:32:37691 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34692 }
Blink Reformat4c46d092018-04-07 15:32:37693
Philip Pfaffe7523faf2021-06-28 14:23:14694 extensionServer.sendRequest({command: PrivateAPI.Commands.ShowPanel, id: this._id});
Blink Reformat4c46d092018-04-07 15:32:37695 },
696
Jan Schefflerd76b4162021-03-29 07:52:16697 __proto__: ExtensionViewImpl.prototype,
Blink Reformat4c46d092018-04-07 15:32:37698 };
699
700 /**
701 * @constructor
702 * @extends {ExtensionViewImpl}
703 */
Philip Pfaffe939605d2021-06-25 12:20:04704 function ExtensionSidebarPaneImpl(this: any, id: any): void {
Blink Reformat4c46d092018-04-07 15:32:37705 ExtensionViewImpl.call(this, id);
706 }
707
708 ExtensionSidebarPaneImpl.prototype = {
Jan Schefflerd76b4162021-03-29 07:52:16709 setHeight: function(height: any): void {
Philip Pfaffe939605d2021-06-25 12:20:04710 extensionServer.sendRequest({command: PrivateAPI.Commands.SetSidebarHeight, id: this._id, height: height});
Blink Reformat4c46d092018-04-07 15:32:37711 },
712
Jan Schefflerd76b4162021-03-29 07:52:16713 setExpression: function(expression: any, rootTitle: any, evaluateOptions: any): void {
Philip Pfaffe7523faf2021-06-28 14:23:14714 extensionServer.sendRequest(
715 {
716 command: PrivateAPI.Commands.SetSidebarContent,
717 id: this._id,
718 expression: expression,
719 rootTitle: rootTitle,
720 evaluateOnPage: true,
721 evaluateOptions: (typeof evaluateOptions === 'object' ? evaluateOptions : undefined),
722 },
723 extractCallbackArgument(arguments));
Blink Reformat4c46d092018-04-07 15:32:37724 },
725
Jan Schefflerd76b4162021-03-29 07:52:16726 setObject: function(jsonObject: any, rootTitle: any, callback: any): void {
Blink Reformat4c46d092018-04-07 15:32:37727 extensionServer.sendRequest(
Philip Pfaffe939605d2021-06-25 12:20:04728 {command: PrivateAPI.Commands.SetSidebarContent, id: this._id, expression: jsonObject, rootTitle: rootTitle},
729 callback);
Blink Reformat4c46d092018-04-07 15:32:37730 },
731
Jan Schefflerd76b4162021-03-29 07:52:16732 setPage: function(page: any): void {
Philip Pfaffe939605d2021-06-25 12:20:04733 extensionServer.sendRequest({command: PrivateAPI.Commands.SetSidebarPage, id: this._id, page: page});
Blink Reformat4c46d092018-04-07 15:32:37734 },
735
Jan Schefflerd76b4162021-03-29 07:52:16736 __proto__: ExtensionViewImpl.prototype,
Blink Reformat4c46d092018-04-07 15:32:37737 };
738
739 /**
740 * @constructor
741 */
Philip Pfaffe939605d2021-06-25 12:20:04742 function ButtonImpl(this: any, id: any): void {
Blink Reformat4c46d092018-04-07 15:32:37743 this._id = id;
Philip Pfaffe939605d2021-06-25 12:20:04744 // @ts-ignore
745 this.onClicked = new EventSink(PrivateAPI.Events.ButtonClicked + id);
Blink Reformat4c46d092018-04-07 15:32:37746 }
747
748 ButtonImpl.prototype = {
Jan Schefflerd76b4162021-03-29 07:52:16749 update: function(iconPath: any, tooltipText: any, disabled: any): void {
Philip Pfaffe7523faf2021-06-28 14:23:14750 extensionServer.sendRequest({
Philip Pfaffe939605d2021-06-25 12:20:04751 command: PrivateAPI.Commands.UpdateButton,
Tim van der Lipped7cfd142021-01-07 12:17:24752 id: this._id,
753 icon: iconPath,
754 tooltip: tooltipText,
Jan Schefflerd76b4162021-03-29 07:52:16755 disabled: Boolean(disabled),
Philip Pfaffe7523faf2021-06-28 14:23:14756 });
Jan Schefflerd76b4162021-03-29 07:52:16757 },
Blink Reformat4c46d092018-04-07 15:32:37758 };
759
760 /**
761 * @constructor
762 */
Jan Schefflerd76b4162021-03-29 07:52:16763 function Timeline(): void {
Blink Reformat4c46d092018-04-07 15:32:37764 }
765
766 Timeline.prototype = {
Philip Pfaffe939605d2021-06-25 12:20:04767 // @ts-ignore
Jan Schefflerd76b4162021-03-29 07:52:16768 addTraceProvider: function(categoryName: string, categoryTooltip: string): TraceProvider {
Blink Reformat4c46d092018-04-07 15:32:37769 const id = 'extension-trace-provider-' + extensionServer.nextObjectId();
Philip Pfaffe939605d2021-06-25 12:20:04770 extensionServer.sendRequest({
771 command: PrivateAPI.Commands.AddTraceProvider,
772 id: id,
773 categoryName: categoryName,
774 categoryTooltip: categoryTooltip,
775 });
776 // @ts-ignore
Blink Reformat4c46d092018-04-07 15:32:37777 return new TraceProvider(id);
Jan Schefflerd76b4162021-03-29 07:52:16778 },
Blink Reformat4c46d092018-04-07 15:32:37779 };
780
781 /**
782 * @constructor
Blink Reformat4c46d092018-04-07 15:32:37783 */
Philip Pfaffe939605d2021-06-25 12:20:04784 function TraceSessionImpl(this: any, id: string): void {
Blink Reformat4c46d092018-04-07 15:32:37785 this._id = id;
786 }
787
788 TraceSessionImpl.prototype = {
Jan Schefflerd76b4162021-03-29 07:52:16789 complete: function(url?: string, timeOffset?: number): void {
Philip Pfaffe7523faf2021-06-28 14:23:14790 extensionServer.sendRequest({
Philip Pfaffe939605d2021-06-25 12:20:04791 command: PrivateAPI.Commands.CompleteTraceSession,
792 id: this._id,
793 url: url || '',
794 timeOffset: timeOffset || 0,
Philip Pfaffe7523faf2021-06-28 14:23:14795 });
Jan Schefflerd76b4162021-03-29 07:52:16796 },
Blink Reformat4c46d092018-04-07 15:32:37797 };
798
799 /**
800 * @constructor
Blink Reformat4c46d092018-04-07 15:32:37801 */
Jan Schefflerd76b4162021-03-29 07:52:16802 function TraceProvider(id: string): void {
Philip Pfaffe939605d2021-06-25 12:20:04803 function dispatchRecordingStarted(this: any, message: any): void {
Blink Reformat4c46d092018-04-07 15:32:37804 const sessionId = message.arguments[0];
Philip Pfaffe939605d2021-06-25 12:20:04805 // @ts-ignore
Blink Reformat4c46d092018-04-07 15:32:37806 this._fire(new TraceSession(sessionId));
807 }
808
Philip Pfaffe939605d2021-06-25 12:20:04809 // @ts-ignore
810 this.onRecordingStarted = new EventSink(PrivateAPI.Events.RecordingStarted + id, dispatchRecordingStarted);
811 // @ts-ignore
812 this.onRecordingStopped = new EventSink(PrivateAPI.Events.RecordingStopped + id);
Blink Reformat4c46d092018-04-07 15:32:37813 }
814
815 /**
816 * @constructor
817 */
Philip Pfaffe939605d2021-06-25 12:20:04818 function InspectedWindow(this: any): void {
819 function dispatchResourceEvent(this: any, message: any): void {
820 // @ts-ignore
Blink Reformat4c46d092018-04-07 15:32:37821 this._fire(new Resource(message.arguments[0]));
822 }
823
Philip Pfaffe939605d2021-06-25 12:20:04824 function dispatchResourceContentEvent(this: any, message: any): void {
825 // @ts-ignore
Blink Reformat4c46d092018-04-07 15:32:37826 this._fire(new Resource(message.arguments[0]), message.arguments[1]);
827 }
828
Philip Pfaffe939605d2021-06-25 12:20:04829 // @ts-ignore
830 this.onResourceAdded = new EventSink(PrivateAPI.Events.ResourceAdded, dispatchResourceEvent);
831 this.onResourceContentCommitted =
832 // @ts-ignore
833 new EventSink(PrivateAPI.Events.ResourceContentCommitted, dispatchResourceContentEvent);
Blink Reformat4c46d092018-04-07 15:32:37834 }
835
836 InspectedWindow.prototype = {
Jan Schefflerd76b4162021-03-29 07:52:16837 reload: function(optionsOrUserAgent: any): void {
838 let options: {
839 userAgent: string,
840 }|null = null;
Blink Reformat4c46d092018-04-07 15:32:37841 if (typeof optionsOrUserAgent === 'object') {
842 options = optionsOrUserAgent;
843 } else if (typeof optionsOrUserAgent === 'string') {
844 options = {userAgent: optionsOrUserAgent};
845 console.warn(
846 'Passing userAgent as string parameter to inspectedWindow.reload() is deprecated. ' +
847 'Use inspectedWindow.reload({ userAgent: value}) instead.');
848 }
Philip Pfaffe939605d2021-06-25 12:20:04849 extensionServer.sendRequest({command: PrivateAPI.Commands.Reload, options: options});
Blink Reformat4c46d092018-04-07 15:32:37850 },
851
Jan Schefflerd76b4162021-03-29 07:52:16852 eval: function(expression: any, evaluateOptions: any): Object |
853 null {
854 const callback = extractCallbackArgument(arguments);
855 function callbackWrapper(result: any): void {
856 if (result.isError || result.isException) {
Philip Pfaffe7523faf2021-06-28 14:23:14857 callback && callback(undefined, result);
Jan Schefflerd76b4162021-03-29 07:52:16858 } else {
Philip Pfaffe7523faf2021-06-28 14:23:14859 callback && callback(result.value);
Jan Schefflerd76b4162021-03-29 07:52:16860 }
861 }
Philip Pfaffe7523faf2021-06-28 14:23:14862 extensionServer.sendRequest(
863 {
864 command: PrivateAPI.Commands.EvaluateOnInspectedPage,
865 expression: expression,
866 evaluateOptions: (typeof evaluateOptions === 'object' ? evaluateOptions : undefined),
867 },
868 callback && callbackWrapper);
Jan Schefflerd76b4162021-03-29 07:52:16869 return null;
870 },
Blink Reformat4c46d092018-04-07 15:32:37871
Jan Schefflerd76b4162021-03-29 07:52:16872 getResources: function(callback: any): void {
873 function wrapResource(resourceData: any): any {
Philip Pfaffe939605d2021-06-25 12:20:04874 // @ts-ignore
Blink Reformat4c46d092018-04-07 15:32:37875 return new Resource(resourceData);
876 }
Jan Schefflerd76b4162021-03-29 07:52:16877 function callbackWrapper(resources: any): void {
Blink Reformat4c46d092018-04-07 15:32:37878 callback(resources.map(wrapResource));
879 }
Philip Pfaffe939605d2021-06-25 12:20:04880 extensionServer.sendRequest({command: PrivateAPI.Commands.GetPageResources}, callback && callbackWrapper);
Jan Schefflerd76b4162021-03-29 07:52:16881 },
Blink Reformat4c46d092018-04-07 15:32:37882 };
883
884 /**
885 * @constructor
886 */
Philip Pfaffe939605d2021-06-25 12:20:04887 function ResourceImpl(this: any, resourceData: any): void {
Blink Reformat4c46d092018-04-07 15:32:37888 this._url = resourceData.url;
889 this._type = resourceData.type;
890 }
891
892 ResourceImpl.prototype = {
Jan Schefflerd76b4162021-03-29 07:52:16893 get url(): string {
Blink Reformat4c46d092018-04-07 15:32:37894 return this._url;
895 },
896
Jan Schefflerd76b4162021-03-29 07:52:16897 get type(): string {
Blink Reformat4c46d092018-04-07 15:32:37898 return this._type;
899 },
900
Jan Schefflerd76b4162021-03-29 07:52:16901 getContent: function(callback: any): void {
902 function callbackWrapper(response: any): void {
Blink Reformat4c46d092018-04-07 15:32:37903 callback(response.content, response.encoding);
904 }
905
Philip Pfaffe939605d2021-06-25 12:20:04906 extensionServer.sendRequest(
907 {command: PrivateAPI.Commands.GetResourceContent, url: this._url}, callback && callbackWrapper);
Blink Reformat4c46d092018-04-07 15:32:37908 },
909
Jan Schefflerd76b4162021-03-29 07:52:16910 setContent: function(content: any, commit: any, callback: any): void {
Blink Reformat4c46d092018-04-07 15:32:37911 extensionServer.sendRequest(
Philip Pfaffe939605d2021-06-25 12:20:04912 {command: PrivateAPI.Commands.SetResourceContent, url: this._url, content: content, commit: commit},
913 callback);
Jan Schefflerd76b4162021-03-29 07:52:16914 },
Blink Reformat4c46d092018-04-07 15:32:37915 };
916
Jan Schefflerd76b4162021-03-29 07:52:16917 function getTabId(): string {
Blink Reformat4c46d092018-04-07 15:32:37918 return inspectedTabId;
919 }
920
Philip Pfaffe7523faf2021-06-28 14:23:14921 let keyboardEventRequestQueue: KeyboardEventInit&{eventType: string}[] = [];
Jan Schefflerd76b4162021-03-29 07:52:16922 let forwardTimer: number|null = null;
Philip Pfaffe7523faf2021-06-28 14:23:14923 function forwardKeyboardEvent(event: KeyboardEvent): void {
Jan Schefflere7d7bb12019-10-24 09:18:52924 // Check if the event should be forwarded.
925 // This is a workaround for crbug.com/923338.
926 const focused = document.activeElement;
927 if (focused) {
928 const isInput = focused.nodeName === 'INPUT' || focused.nodeName === 'TEXTAREA';
929 if (isInput && !(event.ctrlKey || event.altKey || event.metaKey)) {
930 return;
931 }
932 }
933
Joel Einbinder67f28fb2018-08-02 00:33:47934 let modifiers = 0;
Tim van der Lippe1d6e57a2019-09-30 11:55:34935 if (event.shiftKey) {
Joel Einbinder67f28fb2018-08-02 00:33:47936 modifiers |= 1;
Tim van der Lippe1d6e57a2019-09-30 11:55:34937 }
938 if (event.ctrlKey) {
Joel Einbinder67f28fb2018-08-02 00:33:47939 modifiers |= 2;
Tim van der Lippe1d6e57a2019-09-30 11:55:34940 }
941 if (event.altKey) {
Joel Einbinder67f28fb2018-08-02 00:33:47942 modifiers |= 4;
Tim van der Lippe1d6e57a2019-09-30 11:55:34943 }
944 if (event.metaKey) {
Joel Einbinder67f28fb2018-08-02 00:33:47945 modifiers |= 8;
Tim van der Lippe1d6e57a2019-09-30 11:55:34946 }
Joel Einbinder67f28fb2018-08-02 00:33:47947 const num = (event.keyCode & 255) | (modifiers << 8);
Blink Reformat4c46d092018-04-07 15:32:37948 // We only care about global hotkeys, not about random text
Tim van der Lippe1d6e57a2019-09-30 11:55:34949 if (!keysToForwardSet.has(num)) {
Blink Reformat4c46d092018-04-07 15:32:37950 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34951 }
Joel Einbinder67f28fb2018-08-02 00:33:47952 event.preventDefault();
Blink Reformat4c46d092018-04-07 15:32:37953 const requestPayload = {
954 eventType: event.type,
955 ctrlKey: event.ctrlKey,
956 altKey: event.altKey,
957 metaKey: event.metaKey,
Joel Einbinder67f28fb2018-08-02 00:33:47958 shiftKey: event.shiftKey,
Philip Pfaffe7523faf2021-06-28 14:23:14959 // @ts-expect-error keyIdentifier is a deprecated non-standard property that typescript doesn't know about.
Blink Reformat4c46d092018-04-07 15:32:37960 keyIdentifier: event.keyIdentifier,
961 key: event.key,
962 code: event.code,
963 location: event.location,
Jan Schefflerd76b4162021-03-29 07:52:16964 keyCode: event.keyCode,
Blink Reformat4c46d092018-04-07 15:32:37965 };
966 keyboardEventRequestQueue.push(requestPayload);
Tim van der Lippe1d6e57a2019-09-30 11:55:34967 if (!forwardTimer) {
Blink Reformat4c46d092018-04-07 15:32:37968 forwardTimer = setTimeout(forwardEventQueue, 0);
Tim van der Lippe1d6e57a2019-09-30 11:55:34969 }
Blink Reformat4c46d092018-04-07 15:32:37970 }
971
Jan Schefflerd76b4162021-03-29 07:52:16972 function forwardEventQueue(): void {
Blink Reformat4c46d092018-04-07 15:32:37973 forwardTimer = null;
Philip Pfaffe7523faf2021-06-28 14:23:14974 extensionServer.sendRequest(
975 {command: PrivateAPI.Commands.ForwardKeyboardEvent, entries: keyboardEventRequestQueue});
Blink Reformat4c46d092018-04-07 15:32:37976 keyboardEventRequestQueue = [];
977 }
978
979 document.addEventListener('keydown', forwardKeyboardEvent, false);
Blink Reformat4c46d092018-04-07 15:32:37980
981 /**
982 * @constructor
983 */
Philip Pfaffe7523faf2021-06-28 14:23:14984 function ExtensionServerClient(this: APIImpl.ExtensionServerClient): void {
Blink Reformat4c46d092018-04-07 15:32:37985 this._callbacks = {};
986 this._handlers = {};
987 this._lastRequestId = 0;
988 this._lastObjectId = 0;
989
990 this.registerHandler('callback', this._onCallback.bind(this));
991
992 const channel = new MessageChannel();
993 this._port = channel.port1;
994 this._port.addEventListener('message', this._onMessage.bind(this), false);
995 this._port.start();
996
997 window.parent.postMessage('registerExtension', '*', [channel.port2]);
998 }
999
Philip Pfaffe7523faf2021-06-28 14:23:141000 (ExtensionServerClient.prototype as Pick<
1001 APIImpl.ExtensionServerClient,
1002 'sendRequest'|'hasHandler'|'registerHandler'|'unregisterHandler'|'nextObjectId'|'_registerCallback'|
1003 '_onCallback'|'_onMessage'>) = {
1004 sendRequest: function(
1005 this: APIImpl.ExtensionServerClient, message: PrivateAPI.ServerRequests,
1006 callback?: (response: unknown) => unknown, transfers?: Transferable[]): void {
1007 if (typeof callback === 'function') {
1008 (message as PrivateAPI.ExtensionServerRequestMessage).requestId = this._registerCallback(callback);
1009 }
1010 // @ts-expect-error
1011 this._port.postMessage(message, transfers);
1012 },
Blink Reformat4c46d092018-04-07 15:32:371013
Philip Pfaffe7523faf2021-06-28 14:23:141014 hasHandler: function(this: APIImpl.ExtensionServerClient, command: string): boolean {
Tim van der Lipped7cfd142021-01-07 12:17:241015 return Boolean(this._handlers[command]);
Blink Reformat4c46d092018-04-07 15:32:371016 },
1017
Philip Pfaffe7523faf2021-06-28 14:23:141018 registerHandler: function(
1019 this: APIImpl.ExtensionServerClient, command: string, handler: (request: {arguments: unknown[]}) => unknown):
1020 void {
1021 this._handlers[command] = handler;
1022 },
Blink Reformat4c46d092018-04-07 15:32:371023
Philip Pfaffe7523faf2021-06-28 14:23:141024 unregisterHandler: function(this: APIImpl.ExtensionServerClient, command: string): void {
Blink Reformat4c46d092018-04-07 15:32:371025 delete this._handlers[command];
1026 },
1027
Philip Pfaffe7523faf2021-06-28 14:23:141028 nextObjectId: function(this: APIImpl.ExtensionServerClient): string {
Blink Reformat4c46d092018-04-07 15:32:371029 return injectedScriptId.toString() + '_' + ++this._lastObjectId;
1030 },
1031
Philip Pfaffe7523faf2021-06-28 14:23:141032 _registerCallback: function(this: APIImpl.ExtensionServerClient, callback: (response: unknown) => unknown): number {
Blink Reformat4c46d092018-04-07 15:32:371033 const id = ++this._lastRequestId;
1034 this._callbacks[id] = callback;
1035 return id;
1036 },
1037
Philip Pfaffe7523faf2021-06-28 14:23:141038 _onCallback: function(this: APIImpl.ExtensionServerClient, request: {requestId: number, result: unknown}): void {
Blink Reformat4c46d092018-04-07 15:32:371039 if (request.requestId in this._callbacks) {
1040 const callback = this._callbacks[request.requestId];
1041 delete this._callbacks[request.requestId];
1042 callback(request.result);
1043 }
1044 },
1045
Philip Pfaffe7523faf2021-06-28 14:23:141046 _onMessage: function(
1047 this: APIImpl.ExtensionServerClient,
1048 event: MessageEvent<{command: string, requestId: number, arguments: unknown[]}>): void {
Blink Reformat4c46d092018-04-07 15:32:371049 const request = event.data;
1050 const handler = this._handlers[request.command];
Tim van der Lippe1d6e57a2019-09-30 11:55:341051 if (handler) {
Blink Reformat4c46d092018-04-07 15:32:371052 handler.call(this, request);
Tim van der Lippe1d6e57a2019-09-30 11:55:341053 }
Jan Schefflerd76b4162021-03-29 07:52:161054 },
Blink Reformat4c46d092018-04-07 15:32:371055 };
1056
Philip Pfaffe7523faf2021-06-28 14:23:141057 function populateInterfaceClass(interfaze: {[key: string]: unknown}, implementation: {[key: string]: unknown}): void {
Blink Reformat4c46d092018-04-07 15:32:371058 for (const member in implementation) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341059 if (member.charAt(0) === '_') {
Blink Reformat4c46d092018-04-07 15:32:371060 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341061 }
Jan Schefflerd76b4162021-03-29 07:52:161062 let descriptor: (PropertyDescriptor|undefined)|null = null;
Blink Reformat4c46d092018-04-07 15:32:371063 // Traverse prototype chain until we find the owner.
Philip Pfaffe7523faf2021-06-28 14:23:141064 for (let owner = implementation; owner && !descriptor; owner = owner.__proto__ as {[key: string]: unknown}) {
Blink Reformat4c46d092018-04-07 15:32:371065 descriptor = Object.getOwnPropertyDescriptor(owner, member);
Tim van der Lippe1d6e57a2019-09-30 11:55:341066 }
1067 if (!descriptor) {
Blink Reformat4c46d092018-04-07 15:32:371068 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341069 }
1070 if (typeof descriptor.value === 'function') {
Blink Reformat4c46d092018-04-07 15:32:371071 interfaze[member] = descriptor.value.bind(implementation);
Tim van der Lippe1d6e57a2019-09-30 11:55:341072 } else if (typeof descriptor.get === 'function') {
Philip Pfaffe7523faf2021-06-28 14:23:141073 // @ts-expect-error
Blink Reformat4c46d092018-04-07 15:32:371074 interfaze.__defineGetter__(member, descriptor.get.bind(implementation));
Tim van der Lippe1d6e57a2019-09-30 11:55:341075 } else {
Blink Reformat4c46d092018-04-07 15:32:371076 Object.defineProperty(interfaze, member, descriptor);
Tim van der Lippe1d6e57a2019-09-30 11:55:341077 }
Blink Reformat4c46d092018-04-07 15:32:371078 }
1079 }
1080
Philip Pfaffe7523faf2021-06-28 14:23:141081
1082 const extensionServer = new (Constructor(ExtensionServerClient))();
1083
1084 const coreAPI = new (Constructor(InspectorExtensionAPI))();
Blink Reformat4c46d092018-04-07 15:32:371085
1086 Object.defineProperty(chrome, 'devtools', {value: {}, enumerable: true});
1087
1088 // Only expose tabId on chrome.devtools.inspectedWindow, not webInspector.inspectedWindow.
Philip Pfaffe7523faf2021-06-28 14:23:141089 // @ts-expect-error
1090 chrome.devtools!.inspectedWindow = {};
1091 Object.defineProperty(chrome.devtools!.inspectedWindow, 'tabId', {get: getTabId});
1092 // @ts-expect-error
1093 chrome.devtools!.inspectedWindow.__proto__ = coreAPI.inspectedWindow;
1094 chrome.devtools!.network = coreAPI.network;
1095 chrome.devtools!.panels = coreAPI.panels;
1096 chrome.devtools!.panels.themeName = themeName;
1097 chrome.devtools!.languageServices = coreAPI.languageServices;
Blink Reformat4c46d092018-04-07 15:32:371098
1099 // default to expose experimental APIs for now.
1100 if (extensionInfo.exposeExperimentalAPIs !== false) {
1101 chrome.experimental = chrome.experimental || {};
1102 chrome.experimental.devtools = chrome.experimental.devtools || {};
1103
1104 const properties = Object.getOwnPropertyNames(coreAPI);
1105 for (let i = 0; i < properties.length; ++i) {
1106 const descriptor = Object.getOwnPropertyDescriptor(coreAPI, properties[i]);
Tim van der Lippe1d6e57a2019-09-30 11:55:341107 if (descriptor) {
Blink Reformat4c46d092018-04-07 15:32:371108 Object.defineProperty(chrome.experimental.devtools, properties[i], descriptor);
Tim van der Lippe1d6e57a2019-09-30 11:55:341109 }
Blink Reformat4c46d092018-04-07 15:32:371110 }
1111 chrome.experimental.devtools.inspectedWindow = chrome.devtools.inspectedWindow;
1112 }
1113
Tim van der Lippe1d6e57a2019-09-30 11:55:341114 if (extensionInfo.exposeWebInspectorNamespace) {
Blink Reformat4c46d092018-04-07 15:32:371115 window.webInspector = coreAPI;
Tim van der Lippe1d6e57a2019-09-30 11:55:341116 }
Blink Reformat4c46d092018-04-07 15:32:371117 testHook(extensionServer, coreAPI);
Tim van der Lippe226fc222019-10-10 12:17:121118};
Blink Reformat4c46d092018-04-07 15:32:371119
Jan Schefflerd76b4162021-03-29 07:52:161120self.buildExtensionAPIInjectedScript = function(
1121 extensionInfo: {
1122 startPage: string,
1123 name: string,
1124 exposeExperimentalAPIs: boolean,
1125 },
1126 inspectedTabId: string, themeName: string, keysToForward: number[],
Philip Pfaffe7523faf2021-06-28 14:23:141127 testHook:
1128 ((extensionServer: APIImpl.ExtensionServerClient, extensionAPI: APIImpl.InspectorExtensionAPI) => unknown)|
1129 undefined): string {
Philip Pfaffeedad8322020-07-20 10:24:251130 const argumentsJSON =
1131 [extensionInfo, inspectedTabId || null, themeName, keysToForward].map(_ => JSON.stringify(_)).join(',');
Tim van der Lippe1d6e57a2019-09-30 11:55:341132 if (!testHook) {
Jan Schefflerd76b4162021-03-29 07:52:161133 testHook = (): void => {};
Tim van der Lippe1d6e57a2019-09-30 11:55:341134 }
Philip Pfaffe939605d2021-06-25 12:20:041135 return '(function(injectedScriptId){ ' +
Tim van der Lippe226fc222019-10-10 12:17:121136 '(' + self.injectedExtensionAPI.toString() + ')(' + argumentsJSON + ',' + testHook + ', injectedScriptId);' +
Blink Reformat4c46d092018-04-07 15:32:371137 '})';
Tim van der Lippe29fab472019-08-15 14:46:481138};