blob: 0487b632dcfa1b82d3e06cadfeb827cb95ac7fe8 [file] [log] [blame]
Blink Reformat4c46d092018-04-07 15:32:371/*
2 * Copyright (C) 2011 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
Tim van der Lippea6110922020-01-09 15:38:3931import {ExtensionButton, ExtensionPanel, ExtensionSidebarPane} from './ExtensionPanel.js';
32import {ExtensionTraceProvider, TracingSession} from './ExtensionTraceProvider.js'; // eslint-disable-line no-unused-vars
33
Blink Reformat4c46d092018-04-07 15:32:3734/**
35 * @unrestricted
36 */
Tim van der Lippea6110922020-01-09 15:38:3937export class ExtensionServer extends Common.Object {
Blink Reformat4c46d092018-04-07 15:32:3738 /**
39 * @suppressGlobalPropertiesCheck
40 */
41 constructor() {
42 super();
43 this._clientObjects = {};
44 this._handlers = {};
45 this._subscribers = {};
46 this._subscriptionStartHandlers = {};
47 this._subscriptionStopHandlers = {};
48 this._extraHeaders = {};
49 this._requests = {};
50 this._lastRequestId = 0;
51 this._registeredExtensions = {};
Tim van der Lippe226fc222019-10-10 12:17:1252 this._status = new ExtensionStatus();
Tim van der Lippea6110922020-01-09 15:38:3953 /** @type {!Array<!ExtensionSidebarPane>} */
Blink Reformat4c46d092018-04-07 15:32:3754 this._sidebarPanes = [];
Tim van der Lippea6110922020-01-09 15:38:3955 /** @type {!Array<!ExtensionTraceProvider>} */
Blink Reformat4c46d092018-04-07 15:32:3756 this._traceProviders = [];
Tim van der Lippea6110922020-01-09 15:38:3957 /** @type {!Map<string, !TracingSession>} */
Blink Reformat4c46d092018-04-07 15:32:3758 this._traceSessions = new Map();
59
60 const commands = Extensions.extensionAPI.Commands;
61
62 this._registerHandler(commands.AddRequestHeaders, this._onAddRequestHeaders.bind(this));
63 this._registerHandler(commands.AddTraceProvider, this._onAddTraceProvider.bind(this));
64 this._registerHandler(commands.ApplyStyleSheet, this._onApplyStyleSheet.bind(this));
65 this._registerHandler(commands.CompleteTraceSession, this._onCompleteTraceSession.bind(this));
66 this._registerHandler(commands.CreatePanel, this._onCreatePanel.bind(this));
67 this._registerHandler(commands.CreateSidebarPane, this._onCreateSidebarPane.bind(this));
68 this._registerHandler(commands.CreateToolbarButton, this._onCreateToolbarButton.bind(this));
69 this._registerHandler(commands.EvaluateOnInspectedPage, this._onEvaluateOnInspectedPage.bind(this));
70 this._registerHandler(commands.ForwardKeyboardEvent, this._onForwardKeyboardEvent.bind(this));
71 this._registerHandler(commands.GetHAR, this._onGetHAR.bind(this));
72 this._registerHandler(commands.GetPageResources, this._onGetPageResources.bind(this));
73 this._registerHandler(commands.GetRequestContent, this._onGetRequestContent.bind(this));
74 this._registerHandler(commands.GetResourceContent, this._onGetResourceContent.bind(this));
75 this._registerHandler(commands.Reload, this._onReload.bind(this));
76 this._registerHandler(commands.SetOpenResourceHandler, this._onSetOpenResourceHandler.bind(this));
77 this._registerHandler(commands.SetResourceContent, this._onSetResourceContent.bind(this));
78 this._registerHandler(commands.SetSidebarHeight, this._onSetSidebarHeight.bind(this));
79 this._registerHandler(commands.SetSidebarContent, this._onSetSidebarContent.bind(this));
80 this._registerHandler(commands.SetSidebarPage, this._onSetSidebarPage.bind(this));
81 this._registerHandler(commands.ShowPanel, this._onShowPanel.bind(this));
82 this._registerHandler(commands.Subscribe, this._onSubscribe.bind(this));
83 this._registerHandler(commands.OpenResource, this._onOpenResource.bind(this));
84 this._registerHandler(commands.Unsubscribe, this._onUnsubscribe.bind(this));
85 this._registerHandler(commands.UpdateButton, this._onUpdateButton.bind(this));
86 window.addEventListener('message', this._onWindowMessage.bind(this), false); // Only for main window.
87
Tim van der Lippe647e33b2019-11-04 19:02:3188 /** @suppress {checkTypes} */
Tim van der Lippe8a0cc702019-11-05 17:53:1089 const existingTabId =
90 window.DevToolsAPI && window.DevToolsAPI.getInspectedTabId && window.DevToolsAPI.getInspectedTabId();
Tim van der Lippe647e33b2019-11-04 19:02:3191
92 if (existingTabId) {
93 this._setInspectedTabId({data: existingTabId});
94 }
Tim van der Lippe50cfa9b2019-10-01 10:40:5895 Host.InspectorFrontendHost.events.addEventListener(
Tim van der Lippe7b190162019-09-27 15:10:4496 Host.InspectorFrontendHostAPI.Events.SetInspectedTabId, this._setInspectedTabId, this);
Blink Reformat4c46d092018-04-07 15:32:3797
98 this._initExtensions();
99 }
100
101 initializeExtensions() {
Tim van der Lippe50cfa9b2019-10-01 10:40:58102 Host.InspectorFrontendHost.setAddExtensionCallback(this._addExtension.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37103 }
104
105 /**
106 * @return {boolean}
107 */
108 hasExtensions() {
109 return !!Object.keys(this._registeredExtensions).length;
110 }
111
112 /**
113 * @param {string} panelId
114 * @param {string} action
115 * @param {string=} searchString
116 */
117 notifySearchAction(panelId, action, searchString) {
118 this._postNotification(Extensions.extensionAPI.Events.PanelSearch + panelId, action, searchString);
119 }
120
121 /**
122 * @param {string} identifier
123 * @param {number=} frameIndex
124 */
125 notifyViewShown(identifier, frameIndex) {
126 this._postNotification(Extensions.extensionAPI.Events.ViewShown + identifier, frameIndex);
127 }
128
129 /**
130 * @param {string} identifier
131 */
132 notifyViewHidden(identifier) {
133 this._postNotification(Extensions.extensionAPI.Events.ViewHidden + identifier);
134 }
135
136 /**
137 * @param {string} identifier
138 */
139 notifyButtonClicked(identifier) {
140 this._postNotification(Extensions.extensionAPI.Events.ButtonClicked + identifier);
141 }
142
143 _inspectedURLChanged(event) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34144 if (event.data !== SDK.targetManager.mainTarget()) {
Blink Reformat4c46d092018-04-07 15:32:37145 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34146 }
Blink Reformat4c46d092018-04-07 15:32:37147 this._requests = {};
148 const url = event.data.inspectedURL();
149 this._postNotification(Extensions.extensionAPI.Events.InspectedURLChanged, url);
150 }
151
152 /**
153 * @param {string} providerId
154 * @param {string} sessionId
Tim van der Lippea6110922020-01-09 15:38:39155 * @param {!TracingSession} session
Blink Reformat4c46d092018-04-07 15:32:37156 */
157 startTraceRecording(providerId, sessionId, session) {
158 this._traceSessions.set(sessionId, session);
159 this._postNotification('trace-recording-started-' + providerId, sessionId);
160 }
161
162 /**
163 * @param {string} providerId
164 */
165 stopTraceRecording(providerId) {
166 this._postNotification('trace-recording-stopped-' + providerId);
167 }
168
169 /**
170 * @param {string} type
171 * @return {boolean}
172 */
173 hasSubscribers(type) {
174 return !!this._subscribers[type];
175 }
176
177 /**
178 * @param {string} type
179 * @param {...*} vararg
180 */
181 _postNotification(type, vararg) {
182 const subscribers = this._subscribers[type];
Tim van der Lippe1d6e57a2019-09-30 11:55:34183 if (!subscribers) {
Blink Reformat4c46d092018-04-07 15:32:37184 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34185 }
Blink Reformat4c46d092018-04-07 15:32:37186 const message = {command: 'notify-' + type, arguments: Array.prototype.slice.call(arguments, 1)};
Tim van der Lippe1d6e57a2019-09-30 11:55:34187 for (let i = 0; i < subscribers.length; ++i) {
Blink Reformat4c46d092018-04-07 15:32:37188 subscribers[i].postMessage(message);
Tim van der Lippe1d6e57a2019-09-30 11:55:34189 }
Blink Reformat4c46d092018-04-07 15:32:37190 }
191
192 _onSubscribe(message, port) {
193 const subscribers = this._subscribers[message.type];
194 if (subscribers) {
195 subscribers.push(port);
196 } else {
197 this._subscribers[message.type] = [port];
Tim van der Lippe1d6e57a2019-09-30 11:55:34198 if (this._subscriptionStartHandlers[message.type]) {
Blink Reformat4c46d092018-04-07 15:32:37199 this._subscriptionStartHandlers[message.type]();
Tim van der Lippe1d6e57a2019-09-30 11:55:34200 }
Blink Reformat4c46d092018-04-07 15:32:37201 }
202 }
203
204 _onUnsubscribe(message, port) {
205 const subscribers = this._subscribers[message.type];
Tim van der Lippe1d6e57a2019-09-30 11:55:34206 if (!subscribers) {
Blink Reformat4c46d092018-04-07 15:32:37207 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34208 }
Blink Reformat4c46d092018-04-07 15:32:37209 subscribers.remove(port);
210 if (!subscribers.length) {
211 delete this._subscribers[message.type];
Tim van der Lippe1d6e57a2019-09-30 11:55:34212 if (this._subscriptionStopHandlers[message.type]) {
Blink Reformat4c46d092018-04-07 15:32:37213 this._subscriptionStopHandlers[message.type]();
Tim van der Lippe1d6e57a2019-09-30 11:55:34214 }
Blink Reformat4c46d092018-04-07 15:32:37215 }
216 }
217
218 _onAddRequestHeaders(message) {
219 const id = message.extensionId;
Tim van der Lippe1d6e57a2019-09-30 11:55:34220 if (typeof id !== 'string') {
Blink Reformat4c46d092018-04-07 15:32:37221 return this._status.E_BADARGTYPE('extensionId', typeof id, 'string');
Tim van der Lippe1d6e57a2019-09-30 11:55:34222 }
Blink Reformat4c46d092018-04-07 15:32:37223 let extensionHeaders = this._extraHeaders[id];
224 if (!extensionHeaders) {
225 extensionHeaders = {};
226 this._extraHeaders[id] = extensionHeaders;
227 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34228 for (const name in message.headers) {
Blink Reformat4c46d092018-04-07 15:32:37229 extensionHeaders[name] = message.headers[name];
Tim van der Lippe1d6e57a2019-09-30 11:55:34230 }
Blink Reformat4c46d092018-04-07 15:32:37231 const allHeaders = /** @type {!Protocol.Network.Headers} */ ({});
232 for (const extension in this._extraHeaders) {
233 const headers = this._extraHeaders[extension];
234 for (const name in headers) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34235 if (typeof headers[name] === 'string') {
Blink Reformat4c46d092018-04-07 15:32:37236 allHeaders[name] = headers[name];
Tim van der Lippe1d6e57a2019-09-30 11:55:34237 }
Blink Reformat4c46d092018-04-07 15:32:37238 }
239 }
240
241 SDK.multitargetNetworkManager.setExtraHTTPHeaders(allHeaders);
242 }
243
244 /**
245 * @param {*} message
246 * @suppressGlobalPropertiesCheck
247 */
248 _onApplyStyleSheet(message) {
Tim van der Lippe99e59b82019-09-30 20:00:59249 if (!Root.Runtime.experiments.isEnabled('applyCustomStylesheet')) {
Blink Reformat4c46d092018-04-07 15:32:37250 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34251 }
Blink Reformat4c46d092018-04-07 15:32:37252 const styleSheet = createElement('style');
253 styleSheet.textContent = message.styleSheet;
254 document.head.appendChild(styleSheet);
255
256 UI.themeSupport.addCustomStylesheet(message.styleSheet);
257 // Add to all the shadow roots that have already been created
258 for (let node = document.body; node; node = node.traverseNextNode(document.body)) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34259 if (node instanceof ShadowRoot) {
Blink Reformat4c46d092018-04-07 15:32:37260 UI.themeSupport.injectCustomStyleSheets(node);
Tim van der Lippe1d6e57a2019-09-30 11:55:34261 }
Blink Reformat4c46d092018-04-07 15:32:37262 }
263 }
264
265 _onCreatePanel(message, port) {
266 const id = message.id;
267 // The ids are generated on the client API side and must be unique, so the check below
268 // shouldn't be hit unless someone is bypassing the API.
Tim van der Lippe1d6e57a2019-09-30 11:55:34269 if (id in this._clientObjects || UI.inspectorView.hasPanel(id)) {
Blink Reformat4c46d092018-04-07 15:32:37270 return this._status.E_EXISTS(id);
Tim van der Lippe1d6e57a2019-09-30 11:55:34271 }
Blink Reformat4c46d092018-04-07 15:32:37272
273 const page = this._expandResourcePath(port._extensionOrigin, message.page);
274 let persistentId = port._extensionOrigin + message.title;
275 persistentId = persistentId.replace(/\s/g, '');
Tim van der Lippea6110922020-01-09 15:38:39276 const panelView =
277 new ExtensionServerPanelView(persistentId, message.title, new ExtensionPanel(this, persistentId, id, page));
Blink Reformat4c46d092018-04-07 15:32:37278 this._clientObjects[id] = panelView;
279 UI.inspectorView.addPanel(panelView);
280 return this._status.OK();
281 }
282
283 _onShowPanel(message) {
284 let panelViewId = message.id;
285 const panelView = this._clientObjects[message.id];
Tim van der Lippe226fc222019-10-10 12:17:12286 if (panelView && panelView instanceof ExtensionServerPanelView) {
Blink Reformat4c46d092018-04-07 15:32:37287 panelViewId = panelView.viewId();
Tim van der Lippe1d6e57a2019-09-30 11:55:34288 }
Blink Reformat4c46d092018-04-07 15:32:37289 UI.inspectorView.showPanel(panelViewId);
290 }
291
292 _onCreateToolbarButton(message, port) {
293 const panelView = this._clientObjects[message.panel];
Tim van der Lippe226fc222019-10-10 12:17:12294 if (!panelView || !(panelView instanceof ExtensionServerPanelView)) {
Blink Reformat4c46d092018-04-07 15:32:37295 return this._status.E_NOTFOUND(message.panel);
Tim van der Lippe1d6e57a2019-09-30 11:55:34296 }
Tim van der Lippea6110922020-01-09 15:38:39297 const button = new ExtensionButton(
Blink Reformat4c46d092018-04-07 15:32:37298 this, message.id, this._expandResourcePath(port._extensionOrigin, message.icon), message.tooltip,
299 message.disabled);
300 this._clientObjects[message.id] = button;
301
302 panelView.widget().then(appendButton);
303
304 /**
305 * @param {!UI.Widget} panel
306 */
307 function appendButton(panel) {
Tim van der Lippea6110922020-01-09 15:38:39308 /** @type {!ExtensionPanel} panel*/ (panel).addToolbarItem(button.toolbarButton());
Blink Reformat4c46d092018-04-07 15:32:37309 }
310
311 return this._status.OK();
312 }
313
314 _onUpdateButton(message, port) {
315 const button = this._clientObjects[message.id];
Tim van der Lippea6110922020-01-09 15:38:39316 if (!button || !(button instanceof ExtensionButton)) {
Blink Reformat4c46d092018-04-07 15:32:37317 return this._status.E_NOTFOUND(message.id);
Tim van der Lippe1d6e57a2019-09-30 11:55:34318 }
Blink Reformat4c46d092018-04-07 15:32:37319 button.update(this._expandResourcePath(port._extensionOrigin, message.icon), message.tooltip, message.disabled);
320 return this._status.OK();
321 }
322
323 /**
324 * @param {!Object} message
325 */
326 _onCompleteTraceSession(message) {
327 const session = this._traceSessions.get(message.id);
Tim van der Lippe1d6e57a2019-09-30 11:55:34328 if (!session) {
Blink Reformat4c46d092018-04-07 15:32:37329 return this._status.E_NOTFOUND(message.id);
Tim van der Lippe1d6e57a2019-09-30 11:55:34330 }
Blink Reformat4c46d092018-04-07 15:32:37331 this._traceSessions.delete(message.id);
332 session.complete(message.url, message.timeOffset);
333 }
334
335 _onCreateSidebarPane(message) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34336 if (message.panel !== 'elements' && message.panel !== 'sources') {
Blink Reformat4c46d092018-04-07 15:32:37337 return this._status.E_NOTFOUND(message.panel);
Tim van der Lippe1d6e57a2019-09-30 11:55:34338 }
Blink Reformat4c46d092018-04-07 15:32:37339 const id = message.id;
Tim van der Lippea6110922020-01-09 15:38:39340 const sidebar = new ExtensionSidebarPane(this, message.panel, message.title, id);
Blink Reformat4c46d092018-04-07 15:32:37341 this._sidebarPanes.push(sidebar);
342 this._clientObjects[id] = sidebar;
Tim van der Lippe226fc222019-10-10 12:17:12343 this.dispatchEventToListeners(Events.SidebarPaneAdded, sidebar);
Blink Reformat4c46d092018-04-07 15:32:37344
345 return this._status.OK();
346 }
347
348 /**
Tim van der Lippea6110922020-01-09 15:38:39349 * @return {!Array.<!ExtensionSidebarPane>}
Blink Reformat4c46d092018-04-07 15:32:37350 */
351 sidebarPanes() {
352 return this._sidebarPanes;
353 }
354
355 _onSetSidebarHeight(message) {
356 const sidebar = this._clientObjects[message.id];
Tim van der Lippe1d6e57a2019-09-30 11:55:34357 if (!sidebar) {
Blink Reformat4c46d092018-04-07 15:32:37358 return this._status.E_NOTFOUND(message.id);
Tim van der Lippe1d6e57a2019-09-30 11:55:34359 }
Blink Reformat4c46d092018-04-07 15:32:37360 sidebar.setHeight(message.height);
361 return this._status.OK();
362 }
363
364 _onSetSidebarContent(message, port) {
365 const sidebar = this._clientObjects[message.id];
Tim van der Lippe1d6e57a2019-09-30 11:55:34366 if (!sidebar) {
Blink Reformat4c46d092018-04-07 15:32:37367 return this._status.E_NOTFOUND(message.id);
Tim van der Lippe1d6e57a2019-09-30 11:55:34368 }
Blink Reformat4c46d092018-04-07 15:32:37369
370 /**
Tim van der Lippe226fc222019-10-10 12:17:12371 * @this {ExtensionServer}
Blink Reformat4c46d092018-04-07 15:32:37372 */
373 function callback(error) {
374 const result = error ? this._status.E_FAILED(error) : this._status.OK();
375 this._dispatchCallback(message.requestId, port, result);
376 }
377 if (message.evaluateOnPage) {
378 return sidebar.setExpression(
379 message.expression, message.rootTitle, message.evaluateOptions, port._extensionOrigin, callback.bind(this));
380 }
381 sidebar.setObject(message.expression, message.rootTitle, callback.bind(this));
382 }
383
384 _onSetSidebarPage(message, port) {
385 const sidebar = this._clientObjects[message.id];
Tim van der Lippe1d6e57a2019-09-30 11:55:34386 if (!sidebar) {
Blink Reformat4c46d092018-04-07 15:32:37387 return this._status.E_NOTFOUND(message.id);
Tim van der Lippe1d6e57a2019-09-30 11:55:34388 }
Blink Reformat4c46d092018-04-07 15:32:37389 sidebar.setPage(this._expandResourcePath(port._extensionOrigin, message.page));
390 }
391
392 _onOpenResource(message) {
393 const uiSourceCode = Workspace.workspace.uiSourceCodeForURL(message.url);
394 if (uiSourceCode) {
395 Common.Revealer.reveal(uiSourceCode.uiLocation(message.lineNumber, 0));
396 return this._status.OK();
397 }
398
399 const resource = Bindings.resourceForURL(message.url);
400 if (resource) {
401 Common.Revealer.reveal(resource);
402 return this._status.OK();
403 }
404
Pavel Feldman18d13562018-07-31 03:31:18405 const request = SDK.networkLog.requestForURL(message.url);
Blink Reformat4c46d092018-04-07 15:32:37406 if (request) {
407 Common.Revealer.reveal(request);
408 return this._status.OK();
409 }
410
411 return this._status.E_NOTFOUND(message.url);
412 }
413
414 _onSetOpenResourceHandler(message, port) {
415 const name = this._registeredExtensions[port._extensionOrigin].name || ('Extension ' + port._extensionOrigin);
Tim van der Lippe1d6e57a2019-09-30 11:55:34416 if (message.handlerPresent) {
Blink Reformat4c46d092018-04-07 15:32:37417 Components.Linkifier.registerLinkHandler(name, this._handleOpenURL.bind(this, port));
Tim van der Lippe1d6e57a2019-09-30 11:55:34418 } else {
Blink Reformat4c46d092018-04-07 15:32:37419 Components.Linkifier.unregisterLinkHandler(name);
Tim van der Lippe1d6e57a2019-09-30 11:55:34420 }
Blink Reformat4c46d092018-04-07 15:32:37421 }
422
423 _handleOpenURL(port, contentProvider, lineNumber) {
424 port.postMessage(
425 {command: 'open-resource', resource: this._makeResource(contentProvider), lineNumber: lineNumber + 1});
426 }
427
428 _onReload(message) {
429 const options = /** @type {!ExtensionReloadOptions} */ (message.options || {});
430
431 SDK.multitargetNetworkManager.setUserAgentOverride(typeof options.userAgent === 'string' ? options.userAgent : '');
432 let injectedScript;
Tim van der Lippe1d6e57a2019-09-30 11:55:34433 if (options.injectedScript) {
Blink Reformat4c46d092018-04-07 15:32:37434 injectedScript = '(function(){' + options.injectedScript + '})()';
Tim van der Lippe1d6e57a2019-09-30 11:55:34435 }
Blink Reformat4c46d092018-04-07 15:32:37436 SDK.ResourceTreeModel.reloadAllPages(!!options.ignoreCache, injectedScript);
437 return this._status.OK();
438 }
439
440 _onEvaluateOnInspectedPage(message, port) {
441 /**
442 * @param {?Protocol.Error} error
443 * @param {?SDK.RemoteObject} object
444 * @param {boolean} wasThrown
Tim van der Lippe226fc222019-10-10 12:17:12445 * @this {ExtensionServer}
Blink Reformat4c46d092018-04-07 15:32:37446 */
447 function callback(error, object, wasThrown) {
448 let result;
Tim van der Lippe1d6e57a2019-09-30 11:55:34449 if (error || !object) {
Blink Reformat4c46d092018-04-07 15:32:37450 result = this._status.E_PROTOCOLERROR(error.toString());
Tim van der Lippe1d6e57a2019-09-30 11:55:34451 } else if (wasThrown) {
Blink Reformat4c46d092018-04-07 15:32:37452 result = {isException: true, value: object.description};
Tim van der Lippe1d6e57a2019-09-30 11:55:34453 } else {
Blink Reformat4c46d092018-04-07 15:32:37454 result = {value: object.value};
Tim van der Lippe1d6e57a2019-09-30 11:55:34455 }
Blink Reformat4c46d092018-04-07 15:32:37456
457 this._dispatchCallback(message.requestId, port, result);
458 }
459 return this.evaluate(
460 message.expression, true, true, message.evaluateOptions, port._extensionOrigin, callback.bind(this));
461 }
462
463 async _onGetHAR() {
Pavel Feldman18d13562018-07-31 03:31:18464 const requests = SDK.networkLog.requests();
465 const harLog = await SDK.HARLog.build(requests);
Tim van der Lippe1d6e57a2019-09-30 11:55:34466 for (let i = 0; i < harLog.entries.length; ++i) {
Blink Reformat4c46d092018-04-07 15:32:37467 harLog.entries[i]._requestId = this._requestId(requests[i]);
Tim van der Lippe1d6e57a2019-09-30 11:55:34468 }
Blink Reformat4c46d092018-04-07 15:32:37469 return harLog;
470 }
471
472 /**
473 * @param {!Common.ContentProvider} contentProvider
474 */
475 _makeResource(contentProvider) {
476 return {url: contentProvider.contentURL(), type: contentProvider.contentType().name()};
477 }
478
479 /**
480 * @return {!Array<!Common.ContentProvider>}
481 */
482 _onGetPageResources() {
483 /** @type {!Map<string, !Common.ContentProvider>} */
484 const resources = new Map();
485
486 /**
Tim van der Lippe226fc222019-10-10 12:17:12487 * @this {ExtensionServer}
Blink Reformat4c46d092018-04-07 15:32:37488 */
489 function pushResourceData(contentProvider) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34490 if (!resources.has(contentProvider.contentURL())) {
Blink Reformat4c46d092018-04-07 15:32:37491 resources.set(contentProvider.contentURL(), this._makeResource(contentProvider));
Tim van der Lippe1d6e57a2019-09-30 11:55:34492 }
Blink Reformat4c46d092018-04-07 15:32:37493 }
494 let uiSourceCodes = Workspace.workspace.uiSourceCodesForProjectType(Workspace.projectTypes.Network);
495 uiSourceCodes =
496 uiSourceCodes.concat(Workspace.workspace.uiSourceCodesForProjectType(Workspace.projectTypes.ContentScripts));
497 uiSourceCodes.forEach(pushResourceData.bind(this));
Tim van der Lippe1d6e57a2019-09-30 11:55:34498 for (const resourceTreeModel of SDK.targetManager.models(SDK.ResourceTreeModel)) {
Blink Reformat4c46d092018-04-07 15:32:37499 resourceTreeModel.forAllResources(pushResourceData.bind(this));
Tim van der Lippe1d6e57a2019-09-30 11:55:34500 }
Blink Reformat4c46d092018-04-07 15:32:37501 return resources.valuesArray();
502 }
503
504 /**
505 * @param {!Common.ContentProvider} contentProvider
506 * @param {!Object} message
507 * @param {!MessagePort} port
508 */
509 async _getResourceContent(contentProvider, message, port) {
Rob Paveza2eb8c142019-10-13 18:02:38510 const {content} = await contentProvider.requestContent();
Blink Reformat4c46d092018-04-07 15:32:37511 const encoded = await contentProvider.contentEncoded();
512 this._dispatchCallback(message.requestId, port, {encoding: encoded ? 'base64' : '', content: content});
513 }
514
515 _onGetRequestContent(message, port) {
516 const request = this._requestById(message.id);
Tim van der Lippe1d6e57a2019-09-30 11:55:34517 if (!request) {
Blink Reformat4c46d092018-04-07 15:32:37518 return this._status.E_NOTFOUND(message.id);
Tim van der Lippe1d6e57a2019-09-30 11:55:34519 }
Blink Reformat4c46d092018-04-07 15:32:37520 this._getResourceContent(request, message, port);
521 }
522
523 _onGetResourceContent(message, port) {
524 const url = /** @type {string} */ (message.url);
525 const contentProvider = Workspace.workspace.uiSourceCodeForURL(url) || Bindings.resourceForURL(url);
Tim van der Lippe1d6e57a2019-09-30 11:55:34526 if (!contentProvider) {
Blink Reformat4c46d092018-04-07 15:32:37527 return this._status.E_NOTFOUND(url);
Tim van der Lippe1d6e57a2019-09-30 11:55:34528 }
Blink Reformat4c46d092018-04-07 15:32:37529 this._getResourceContent(contentProvider, message, port);
530 }
531
532 _onSetResourceContent(message, port) {
533 /**
534 * @param {?Protocol.Error} error
Tim van der Lippe226fc222019-10-10 12:17:12535 * @this {ExtensionServer}
Blink Reformat4c46d092018-04-07 15:32:37536 */
537 function callbackWrapper(error) {
538 const response = error ? this._status.E_FAILED(error) : this._status.OK();
539 this._dispatchCallback(message.requestId, port, response);
540 }
541
542 const url = /** @type {string} */ (message.url);
543 const uiSourceCode = Workspace.workspace.uiSourceCodeForURL(url);
544 if (!uiSourceCode || !uiSourceCode.contentType().isDocumentOrScriptOrStyleSheet()) {
545 const resource = SDK.ResourceTreeModel.resourceForURL(url);
Tim van der Lippe1d6e57a2019-09-30 11:55:34546 if (!resource) {
Blink Reformat4c46d092018-04-07 15:32:37547 return this._status.E_NOTFOUND(url);
Tim van der Lippe1d6e57a2019-09-30 11:55:34548 }
Blink Reformat4c46d092018-04-07 15:32:37549 return this._status.E_NOTSUPPORTED('Resource is not editable');
550 }
551 uiSourceCode.setWorkingCopy(message.content);
Tim van der Lippe1d6e57a2019-09-30 11:55:34552 if (message.commit) {
Blink Reformat4c46d092018-04-07 15:32:37553 uiSourceCode.commitWorkingCopy();
Tim van der Lippe1d6e57a2019-09-30 11:55:34554 }
Blink Reformat4c46d092018-04-07 15:32:37555 callbackWrapper.call(this, null);
556 }
557
558 _requestId(request) {
559 if (!request._extensionRequestId) {
560 request._extensionRequestId = ++this._lastRequestId;
561 this._requests[request._extensionRequestId] = request;
562 }
563 return request._extensionRequestId;
564 }
565
566 _requestById(id) {
567 return this._requests[id];
568 }
569
570 /**
571 * @param {!Object} message
572 * @param {!MessagePort} port
573 */
574 _onAddTraceProvider(message, port) {
Tim van der Lippea6110922020-01-09 15:38:39575 const provider =
576 new ExtensionTraceProvider(port._extensionOrigin, message.id, message.categoryName, message.categoryTooltip);
Blink Reformat4c46d092018-04-07 15:32:37577 this._clientObjects[message.id] = provider;
578 this._traceProviders.push(provider);
Tim van der Lippe226fc222019-10-10 12:17:12579 this.dispatchEventToListeners(Events.TraceProviderAdded, provider);
Blink Reformat4c46d092018-04-07 15:32:37580 }
581
582 /**
Tim van der Lippea6110922020-01-09 15:38:39583 * @return {!Array<!ExtensionTraceProvider>}
Blink Reformat4c46d092018-04-07 15:32:37584 */
585 traceProviders() {
586 return this._traceProviders;
587 }
588
589 _onForwardKeyboardEvent(message) {
590 message.entries.forEach(handleEventEntry);
591
592 /**
593 * @param {*} entry
594 * @suppressGlobalPropertiesCheck
595 */
596 function handleEventEntry(entry) {
Blink Reformat4c46d092018-04-07 15:32:37597 // Fool around closure compiler -- it has its own notion of both KeyboardEvent constructor
598 // and initKeyboardEvent methods and overriding these in externs.js does not have effect.
599 const event = new window.KeyboardEvent(entry.eventType, {
600 key: entry.key,
601 code: entry.code,
602 keyCode: entry.keyCode,
603 location: entry.location,
604 ctrlKey: entry.ctrlKey,
605 altKey: entry.altKey,
606 shiftKey: entry.shiftKey,
607 metaKey: entry.metaKey
608 });
609 event.__keyCode = keyCodeForEntry(entry);
610 document.dispatchEvent(event);
611 }
612
613 function keyCodeForEntry(entry) {
614 let keyCode = entry.keyCode;
615 if (!keyCode) {
616 // This is required only for synthetic events (e.g. dispatched in tests).
Tim van der Lippe1d6e57a2019-09-30 11:55:34617 if (entry.key === 'Escape') {
Blink Reformat4c46d092018-04-07 15:32:37618 keyCode = 27;
Tim van der Lippe1d6e57a2019-09-30 11:55:34619 }
Blink Reformat4c46d092018-04-07 15:32:37620 }
621 return keyCode || 0;
622 }
623 }
624
625 _dispatchCallback(requestId, port, result) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34626 if (requestId) {
Blink Reformat4c46d092018-04-07 15:32:37627 port.postMessage({command: 'callback', requestId: requestId, result: result});
Tim van der Lippe1d6e57a2019-09-30 11:55:34628 }
Blink Reformat4c46d092018-04-07 15:32:37629 }
630
631 _initExtensions() {
632 this._registerAutosubscriptionHandler(
633 Extensions.extensionAPI.Events.ResourceAdded, Workspace.workspace, Workspace.Workspace.Events.UISourceCodeAdded,
634 this._notifyResourceAdded);
635 this._registerAutosubscriptionTargetManagerHandler(
636 Extensions.extensionAPI.Events.NetworkRequestFinished, SDK.NetworkManager,
637 SDK.NetworkManager.Events.RequestFinished, this._notifyRequestFinished);
638
639 /**
Tim van der Lippe226fc222019-10-10 12:17:12640 * @this {ExtensionServer}
Blink Reformat4c46d092018-04-07 15:32:37641 */
642 function onElementsSubscriptionStarted() {
643 UI.context.addFlavorChangeListener(SDK.DOMNode, this._notifyElementsSelectionChanged, this);
644 }
645
646 /**
Tim van der Lippe226fc222019-10-10 12:17:12647 * @this {ExtensionServer}
Blink Reformat4c46d092018-04-07 15:32:37648 */
649 function onElementsSubscriptionStopped() {
650 UI.context.removeFlavorChangeListener(SDK.DOMNode, this._notifyElementsSelectionChanged, this);
651 }
652
653 this._registerSubscriptionHandler(
654 Extensions.extensionAPI.Events.PanelObjectSelected + 'elements', onElementsSubscriptionStarted.bind(this),
655 onElementsSubscriptionStopped.bind(this));
656 this._registerResourceContentCommittedHandler(this._notifyUISourceCodeContentCommitted);
657
658 SDK.targetManager.addEventListener(SDK.TargetManager.Events.InspectedURLChanged, this._inspectedURLChanged, this);
Blink Reformat4c46d092018-04-07 15:32:37659 }
660
661 _notifyResourceAdded(event) {
662 const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
663 this._postNotification(Extensions.extensionAPI.Events.ResourceAdded, this._makeResource(uiSourceCode));
664 }
665
666 _notifyUISourceCodeContentCommitted(event) {
667 const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data.uiSourceCode);
668 const content = /** @type {string} */ (event.data.content);
669 this._postNotification(
670 Extensions.extensionAPI.Events.ResourceContentCommitted, this._makeResource(uiSourceCode), content);
671 }
672
673 async _notifyRequestFinished(event) {
674 const request = /** @type {!SDK.NetworkRequest} */ (event.data);
Pavel Feldman18d13562018-07-31 03:31:18675 const entry = await SDK.HARLog.Entry.build(request);
Blink Reformat4c46d092018-04-07 15:32:37676 this._postNotification(Extensions.extensionAPI.Events.NetworkRequestFinished, this._requestId(request), entry);
677 }
678
679 _notifyElementsSelectionChanged() {
680 this._postNotification(Extensions.extensionAPI.Events.PanelObjectSelected + 'elements');
681 }
682
683 /**
684 * @param {string} url
685 * @param {!TextUtils.TextRange} range
686 */
687 sourceSelectionChanged(url, range) {
688 this._postNotification(Extensions.extensionAPI.Events.PanelObjectSelected + 'sources', {
689 startLine: range.startLine,
690 startColumn: range.startColumn,
691 endLine: range.endLine,
692 endColumn: range.endColumn,
693 url: url,
694 });
695 }
696
697 /**
698 * @param {!Common.Event} event
699 */
Blink Reformat4c46d092018-04-07 15:32:37700 _setInspectedTabId(event) {
701 this._inspectedTabId = /** @type {string} */ (event.data);
702 }
703
704 /**
705 * @param {!ExtensionDescriptor} extensionInfo
706 * @suppressGlobalPropertiesCheck
707 */
708 _addExtension(extensionInfo) {
709 const urlOriginRegExp = new RegExp('([^:]+:\/\/[^/]*)\/'); // Can't use regexp literal here, MinJS chokes on it.
710 const startPage = extensionInfo.startPage;
711 const name = extensionInfo.name;
712
713 try {
714 const originMatch = urlOriginRegExp.exec(startPage);
715 if (!originMatch) {
716 console.error('Skipping extension with invalid URL: ' + startPage);
717 return false;
718 }
719 const extensionOrigin = originMatch[1];
720 if (!this._registeredExtensions[extensionOrigin]) {
721 // See ExtensionAPI.js for details.
Tim van der Lippe226fc222019-10-10 12:17:12722 const injectedAPI = self.buildExtensionAPIInjectedScript(
723 extensionInfo, this._inspectedTabId, UI.themeSupport.themeName(), UI.shortcutRegistry.globalShortcutKeys(),
Blink Reformat4c46d092018-04-07 15:32:37724 Extensions.extensionServer['_extensionAPITestHook']);
Tim van der Lippe50cfa9b2019-10-01 10:40:58725 Host.InspectorFrontendHost.setInjectedScriptForOrigin(extensionOrigin, injectedAPI);
Blink Reformat4c46d092018-04-07 15:32:37726 this._registeredExtensions[extensionOrigin] = {name: name};
727 }
728 const iframe = createElement('iframe');
729 iframe.src = startPage;
730 iframe.style.display = 'none';
731 document.body.appendChild(iframe); // Only for main window.
732 } catch (e) {
733 console.error('Failed to initialize extension ' + startPage + ':' + e);
734 return false;
735 }
736 return true;
737 }
738
739 _registerExtension(origin, port) {
740 if (!this._registeredExtensions.hasOwnProperty(origin)) {
741 if (origin !== window.location.origin) // Just ignore inspector frames.
Tim van der Lippe1d6e57a2019-09-30 11:55:34742 {
Blink Reformat4c46d092018-04-07 15:32:37743 console.error('Ignoring unauthorized client request from ' + origin);
Tim van der Lippe1d6e57a2019-09-30 11:55:34744 }
Blink Reformat4c46d092018-04-07 15:32:37745 return;
746 }
747 port._extensionOrigin = origin;
748 port.addEventListener('message', this._onmessage.bind(this), false);
749 port.start();
750 }
751
752 _onWindowMessage(event) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34753 if (event.data === 'registerExtension') {
Blink Reformat4c46d092018-04-07 15:32:37754 this._registerExtension(event.origin, event.ports[0]);
Tim van der Lippe1d6e57a2019-09-30 11:55:34755 }
Blink Reformat4c46d092018-04-07 15:32:37756 }
757
758 async _onmessage(event) {
759 const message = event.data;
760 let result;
761
Tim van der Lippe1d6e57a2019-09-30 11:55:34762 if (message.command in this._handlers) {
Blink Reformat4c46d092018-04-07 15:32:37763 result = await this._handlers[message.command](message, event.target);
Tim van der Lippe1d6e57a2019-09-30 11:55:34764 } else {
Blink Reformat4c46d092018-04-07 15:32:37765 result = this._status.E_NOTSUPPORTED(message.command);
Tim van der Lippe1d6e57a2019-09-30 11:55:34766 }
Blink Reformat4c46d092018-04-07 15:32:37767
Tim van der Lippe1d6e57a2019-09-30 11:55:34768 if (result && message.requestId) {
Blink Reformat4c46d092018-04-07 15:32:37769 this._dispatchCallback(message.requestId, event.target, result);
Tim van der Lippe1d6e57a2019-09-30 11:55:34770 }
Blink Reformat4c46d092018-04-07 15:32:37771 }
772
773 _registerHandler(command, callback) {
774 console.assert(command);
775 this._handlers[command] = callback;
776 }
777
778 _registerSubscriptionHandler(eventTopic, onSubscribeFirst, onUnsubscribeLast) {
779 this._subscriptionStartHandlers[eventTopic] = onSubscribeFirst;
780 this._subscriptionStopHandlers[eventTopic] = onUnsubscribeLast;
781 }
782
783 /**
784 * @param {string} eventTopic
785 * @param {!Object} eventTarget
Tim van der Lippeffa78622019-09-16 12:07:12786 * @param {symbol} frontendEventType
Blink Reformat4c46d092018-04-07 15:32:37787 * @param {function(!Common.Event)} handler
788 */
789 _registerAutosubscriptionHandler(eventTopic, eventTarget, frontendEventType, handler) {
790 this._registerSubscriptionHandler(
791 eventTopic, eventTarget.addEventListener.bind(eventTarget, frontendEventType, handler, this),
792 eventTarget.removeEventListener.bind(eventTarget, frontendEventType, handler, this));
793 }
794
795 /**
796 * @param {string} eventTopic
797 * @param {!Function} modelClass
Tim van der Lippeffa78622019-09-16 12:07:12798 * @param {symbol} frontendEventType
Blink Reformat4c46d092018-04-07 15:32:37799 * @param {function(!Common.Event)} handler
800 */
801 _registerAutosubscriptionTargetManagerHandler(eventTopic, modelClass, frontendEventType, handler) {
802 this._registerSubscriptionHandler(
803 eventTopic,
804 SDK.targetManager.addModelListener.bind(SDK.targetManager, modelClass, frontendEventType, handler, this),
805 SDK.targetManager.removeModelListener.bind(SDK.targetManager, modelClass, frontendEventType, handler, this));
806 }
807
808 _registerResourceContentCommittedHandler(handler) {
809 /**
Tim van der Lippe226fc222019-10-10 12:17:12810 * @this {ExtensionServer}
Blink Reformat4c46d092018-04-07 15:32:37811 */
812 function addFirstEventListener() {
813 Workspace.workspace.addEventListener(Workspace.Workspace.Events.WorkingCopyCommittedByUser, handler, this);
814 Workspace.workspace.setHasResourceContentTrackingExtensions(true);
815 }
816
817 /**
Tim van der Lippe226fc222019-10-10 12:17:12818 * @this {ExtensionServer}
Blink Reformat4c46d092018-04-07 15:32:37819 */
820 function removeLastEventListener() {
821 Workspace.workspace.setHasResourceContentTrackingExtensions(false);
822 Workspace.workspace.removeEventListener(Workspace.Workspace.Events.WorkingCopyCommittedByUser, handler, this);
823 }
824
825 this._registerSubscriptionHandler(
826 Extensions.extensionAPI.Events.ResourceContentCommitted, addFirstEventListener.bind(this),
827 removeLastEventListener.bind(this));
828 }
829
830 _expandResourcePath(extensionPath, resourcePath) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34831 if (!resourcePath) {
Blink Reformat4c46d092018-04-07 15:32:37832 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34833 }
Blink Reformat4c46d092018-04-07 15:32:37834 return extensionPath + this._normalizePath(resourcePath);
835 }
836
837 _normalizePath(path) {
838 const source = path.split('/');
839 const result = [];
840
841 for (let i = 0; i < source.length; ++i) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34842 if (source[i] === '.') {
Blink Reformat4c46d092018-04-07 15:32:37843 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34844 }
Blink Reformat4c46d092018-04-07 15:32:37845 // Ignore empty path components resulting from //, as well as a leading and traling slashes.
Tim van der Lippe1d6e57a2019-09-30 11:55:34846 if (source[i] === '') {
Blink Reformat4c46d092018-04-07 15:32:37847 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34848 }
849 if (source[i] === '..') {
Blink Reformat4c46d092018-04-07 15:32:37850 result.pop();
Tim van der Lippe1d6e57a2019-09-30 11:55:34851 } else {
Blink Reformat4c46d092018-04-07 15:32:37852 result.push(source[i]);
Tim van der Lippe1d6e57a2019-09-30 11:55:34853 }
Blink Reformat4c46d092018-04-07 15:32:37854 }
855 return '/' + result.join('/');
856 }
857
858 /**
859 * @param {string} expression
860 * @param {boolean} exposeCommandLineAPI
861 * @param {boolean} returnByValue
862 * @param {?Object} options
863 * @param {string} securityOrigin
864 * @param {function(?string, ?SDK.RemoteObject, boolean)} callback
865 * @return {!Extensions.ExtensionStatus.Record|undefined}
866 */
867 evaluate(expression, exposeCommandLineAPI, returnByValue, options, securityOrigin, callback) {
868 let context;
869
870 /**
871 * @param {string} url
872 * @return {boolean}
873 */
874 function resolveURLToFrame(url) {
875 let found;
876 function hasMatchingURL(frame) {
877 found = (frame.url === url) ? frame : null;
878 return found;
879 }
880 SDK.ResourceTreeModel.frames().some(hasMatchingURL);
881 return found;
882 }
883
884 options = options || {};
885 let frame;
886 if (options.frameURL) {
887 frame = resolveURLToFrame(options.frameURL);
888 } else {
889 const target = SDK.targetManager.mainTarget();
890 const resourceTreeModel = target && target.model(SDK.ResourceTreeModel);
891 frame = resourceTreeModel && resourceTreeModel.mainFrame;
892 }
893 if (!frame) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34894 if (options.frameURL) {
Blink Reformat4c46d092018-04-07 15:32:37895 console.warn('evaluate: there is no frame with URL ' + options.frameURL);
Tim van der Lippe1d6e57a2019-09-30 11:55:34896 } else {
Blink Reformat4c46d092018-04-07 15:32:37897 console.warn('evaluate: the main frame is not yet available');
Tim van der Lippe1d6e57a2019-09-30 11:55:34898 }
Blink Reformat4c46d092018-04-07 15:32:37899 return this._status.E_NOTFOUND(options.frameURL || '<top>');
900 }
901
902 let contextSecurityOrigin;
Tim van der Lippe1d6e57a2019-09-30 11:55:34903 if (options.useContentScriptContext) {
Blink Reformat4c46d092018-04-07 15:32:37904 contextSecurityOrigin = securityOrigin;
Tim van der Lippe1d6e57a2019-09-30 11:55:34905 } else if (options.scriptExecutionContext) {
Blink Reformat4c46d092018-04-07 15:32:37906 contextSecurityOrigin = options.scriptExecutionContext;
Tim van der Lippe1d6e57a2019-09-30 11:55:34907 }
Blink Reformat4c46d092018-04-07 15:32:37908
909 const runtimeModel = frame.resourceTreeModel().target().model(SDK.RuntimeModel);
910 const executionContexts = runtimeModel ? runtimeModel.executionContexts() : [];
911 if (contextSecurityOrigin) {
912 for (let i = 0; i < executionContexts.length; ++i) {
913 const executionContext = executionContexts[i];
914 if (executionContext.frameId === frame.id && executionContext.origin === contextSecurityOrigin &&
Tim van der Lippe1d6e57a2019-09-30 11:55:34915 !executionContext.isDefault) {
Blink Reformat4c46d092018-04-07 15:32:37916 context = executionContext;
Tim van der Lippe1d6e57a2019-09-30 11:55:34917 }
Blink Reformat4c46d092018-04-07 15:32:37918 }
919 if (!context) {
920 console.warn('The JavaScript context ' + contextSecurityOrigin + ' was not found in the frame ' + frame.url);
921 return this._status.E_NOTFOUND(contextSecurityOrigin);
922 }
923 } else {
924 for (let i = 0; i < executionContexts.length; ++i) {
925 const executionContext = executionContexts[i];
Tim van der Lippe1d6e57a2019-09-30 11:55:34926 if (executionContext.frameId === frame.id && executionContext.isDefault) {
Blink Reformat4c46d092018-04-07 15:32:37927 context = executionContext;
Tim van der Lippe1d6e57a2019-09-30 11:55:34928 }
Blink Reformat4c46d092018-04-07 15:32:37929 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34930 if (!context) {
Blink Reformat4c46d092018-04-07 15:32:37931 return this._status.E_FAILED(frame.url + ' has no execution context');
Tim van der Lippe1d6e57a2019-09-30 11:55:34932 }
Blink Reformat4c46d092018-04-07 15:32:37933 }
934
935 context
936 .evaluate(
937 {
938 expression: expression,
939 objectGroup: 'extension',
940 includeCommandLineAPI: exposeCommandLineAPI,
941 silent: true,
942 returnByValue: returnByValue,
943 generatePreview: false
944 },
945 /* userGesture */ false, /* awaitPromise */ false)
946 .then(onEvaluate);
947
948 /**
949 * @param {!SDK.RuntimeModel.EvaluationResult} result
950 */
951 function onEvaluate(result) {
952 if (result.error) {
953 callback(result.error, null, false);
954 return;
955 }
956 callback(null, result.object || null, !!result.exceptionDetails);
957 }
958 }
Tim van der Lippe226fc222019-10-10 12:17:12959}
Blink Reformat4c46d092018-04-07 15:32:37960
961/** @enum {symbol} */
Tim van der Lippe226fc222019-10-10 12:17:12962export const Events = {
Blink Reformat4c46d092018-04-07 15:32:37963 SidebarPaneAdded: Symbol('SidebarPaneAdded'),
964 TraceProviderAdded: Symbol('TraceProviderAdded')
965};
966
967/**
968 * @unrestricted
969 */
Tim van der Lippec96ccd92019-11-29 16:23:54970class ExtensionServerPanelView extends UI.SimpleView {
Blink Reformat4c46d092018-04-07 15:32:37971 /**
972 * @param {string} name
973 * @param {string} title
974 * @param {!UI.Panel} panel
975 */
976 constructor(name, title, panel) {
977 super(title);
978 this._name = name;
979 this._panel = panel;
980 }
981
982 /**
983 * @override
984 * @return {string}
985 */
986 viewId() {
987 return this._name;
988 }
989
990 /**
991 * @override
992 * @return {!Promise.<!UI.Widget>}
993 */
994 widget() {
995 return /** @type {!Promise.<!UI.Widget>} */ (Promise.resolve(this._panel));
996 }
Tim van der Lippe226fc222019-10-10 12:17:12997}
Blink Reformat4c46d092018-04-07 15:32:37998
999/**
1000 * @unrestricted
1001 */
Tim van der Lippe226fc222019-10-10 12:17:121002export class ExtensionStatus {
Blink Reformat4c46d092018-04-07 15:32:371003 constructor() {
1004 /**
1005 * @param {string} code
1006 * @param {string} description
1007 * @return {!Extensions.ExtensionStatus.Record}
1008 */
1009 function makeStatus(code, description) {
1010 const details = Array.prototype.slice.call(arguments, 2);
1011 const status = {code: code, description: description, details: details};
1012 if (code !== 'OK') {
1013 status.isError = true;
1014 console.error('Extension server error: ' + String.vsprintf(description, details));
1015 }
1016 return status;
1017 }
1018
1019 this.OK = makeStatus.bind(null, 'OK', 'OK');
1020 this.E_EXISTS = makeStatus.bind(null, 'E_EXISTS', 'Object already exists: %s');
1021 this.E_BADARG = makeStatus.bind(null, 'E_BADARG', 'Invalid argument %s: %s');
1022 this.E_BADARGTYPE = makeStatus.bind(null, 'E_BADARGTYPE', 'Invalid type for argument %s: got %s, expected %s');
1023 this.E_NOTFOUND = makeStatus.bind(null, 'E_NOTFOUND', 'Object not found: %s');
1024 this.E_NOTSUPPORTED = makeStatus.bind(null, 'E_NOTSUPPORTED', 'Object does not support requested operation: %s');
1025 this.E_PROTOCOLERROR = makeStatus.bind(null, 'E_PROTOCOLERROR', 'Inspector protocol error: %s');
1026 this.E_FAILED = makeStatus.bind(null, 'E_FAILED', 'Operation failed: %s');
1027 }
Tim van der Lippe226fc222019-10-10 12:17:121028}