| Index: third_party/WebKit/Source/devtools/front_end/extensions/ExtensionServer.js
|
| diff --git a/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionServer.js b/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionServer.js
|
| index 2ececcf1cdf91e5f78fadbc65056e3ee34df475f..e45a540066b50940878959d180d75d0cbbe6eba9 100644
|
| --- a/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionServer.js
|
| +++ b/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionServer.js
|
| @@ -27,14 +27,15 @@
|
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| */
|
| -
|
| /**
|
| - * @constructor
|
| - * @extends {WebInspector.Object}
|
| - * @suppressGlobalPropertiesCheck
|
| + * @unrestricted
|
| */
|
| -WebInspector.ExtensionServer = function()
|
| -{
|
| +WebInspector.ExtensionServer = class extends WebInspector.Object {
|
| + /**
|
| + * @suppressGlobalPropertiesCheck
|
| + */
|
| + constructor() {
|
| + super();
|
| this._clientObjects = {};
|
| this._handlers = {};
|
| this._subscribers = {};
|
| @@ -81,1043 +82,962 @@ WebInspector.ExtensionServer = function()
|
| this._registerHandler(commands.Unsubscribe, this._onUnsubscribe.bind(this));
|
| this._registerHandler(commands.UpdateButton, this._onUpdateButton.bind(this));
|
| this._registerHandler(commands.UpdateAuditProgress, this._onUpdateAuditProgress.bind(this));
|
| - window.addEventListener("message", this._onWindowMessage.bind(this), false); // Only for main window.
|
| + window.addEventListener('message', this._onWindowMessage.bind(this), false); // Only for main window.
|
|
|
| - InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.AddExtensions, this._addExtensions, this);
|
| - InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.SetInspectedTabId, this._setInspectedTabId, this);
|
| + InspectorFrontendHost.events.addEventListener(
|
| + InspectorFrontendHostAPI.Events.AddExtensions, this._addExtensions, this);
|
| + InspectorFrontendHost.events.addEventListener(
|
| + InspectorFrontendHostAPI.Events.SetInspectedTabId, this._setInspectedTabId, this);
|
|
|
| this._initExtensions();
|
| -};
|
| -
|
| -/** @enum {symbol} */
|
| -WebInspector.ExtensionServer.Events = {
|
| - SidebarPaneAdded: Symbol("SidebarPaneAdded"),
|
| - AuditCategoryAdded: Symbol("AuditCategoryAdded")
|
| -};
|
| + }
|
|
|
| -WebInspector.ExtensionServer.prototype = {
|
| - initializeExtensions: function()
|
| - {
|
| - this._initializeCommandIssued = true;
|
| - if (this._pendingExtensionInfos) {
|
| - this._pendingExtensionInfos.forEach(this._addExtension, this);
|
| - delete this._pendingExtensionInfos;
|
| - }
|
| - },
|
| + initializeExtensions() {
|
| + this._initializeCommandIssued = true;
|
| + if (this._pendingExtensionInfos) {
|
| + this._pendingExtensionInfos.forEach(this._addExtension, this);
|
| + delete this._pendingExtensionInfos;
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * @return {boolean}
|
| + */
|
| + hasExtensions() {
|
| + return !!Object.keys(this._registeredExtensions).length;
|
| + }
|
| +
|
| + /**
|
| + * @param {string} panelId
|
| + * @param {string} action
|
| + * @param {string=} searchString
|
| + */
|
| + notifySearchAction(panelId, action, searchString) {
|
| + this._postNotification(WebInspector.extensionAPI.Events.PanelSearch + panelId, action, searchString);
|
| + }
|
| +
|
| + /**
|
| + * @param {string} identifier
|
| + * @param {number=} frameIndex
|
| + */
|
| + notifyViewShown(identifier, frameIndex) {
|
| + this._postNotification(WebInspector.extensionAPI.Events.ViewShown + identifier, frameIndex);
|
| + }
|
| +
|
| + /**
|
| + * @param {string} identifier
|
| + */
|
| + notifyViewHidden(identifier) {
|
| + this._postNotification(WebInspector.extensionAPI.Events.ViewHidden + identifier);
|
| + }
|
| +
|
| + /**
|
| + * @param {string} identifier
|
| + */
|
| + notifyButtonClicked(identifier) {
|
| + this._postNotification(WebInspector.extensionAPI.Events.ButtonClicked + identifier);
|
| + }
|
| +
|
| + _inspectedURLChanged(event) {
|
| + if (event.data !== WebInspector.targetManager.mainTarget())
|
| + return;
|
| + this._requests = {};
|
| + var url = event.data.inspectedURL();
|
| + this._postNotification(WebInspector.extensionAPI.Events.InspectedURLChanged, url);
|
| + }
|
| +
|
| + /**
|
| + * @param {string} categoryId
|
| + * @param {!WebInspector.ExtensionAuditCategoryResults} auditResults
|
| + */
|
| + startAuditRun(categoryId, auditResults) {
|
| + this._clientObjects[auditResults.id()] = auditResults;
|
| + this._postNotification('audit-started-' + categoryId, auditResults.id());
|
| + }
|
| +
|
| + /**
|
| + * @param {!WebInspector.ExtensionAuditCategoryResults} auditResults
|
| + */
|
| + stopAuditRun(auditResults) {
|
| + delete this._clientObjects[auditResults.id()];
|
| + }
|
| +
|
| + /**
|
| + * @param {string} traceProviderId
|
| + */
|
| + startTraceRecording(traceProviderId) {
|
| + this._postNotification('trace-recording-started-' + traceProviderId);
|
| + }
|
| +
|
| + /**
|
| + * @param {string} traceProviderId
|
| + */
|
| + stopTraceRecording(traceProviderId) {
|
| + this._postNotification('trace-recording-stopped-' + traceProviderId);
|
| + }
|
| +
|
| + /**
|
| + * @param {string} type
|
| + * @return {boolean}
|
| + */
|
| + hasSubscribers(type) {
|
| + return !!this._subscribers[type];
|
| + }
|
| +
|
| + /**
|
| + * @param {string} type
|
| + * @param {...*} vararg
|
| + */
|
| + _postNotification(type, vararg) {
|
| + var subscribers = this._subscribers[type];
|
| + if (!subscribers)
|
| + return;
|
| + var message = {command: 'notify-' + type, arguments: Array.prototype.slice.call(arguments, 1)};
|
| + for (var i = 0; i < subscribers.length; ++i)
|
| + subscribers[i].postMessage(message);
|
| + }
|
| +
|
| + _onSubscribe(message, port) {
|
| + var subscribers = this._subscribers[message.type];
|
| + if (subscribers)
|
| + subscribers.push(port);
|
| + else {
|
| + this._subscribers[message.type] = [port];
|
| + if (this._subscriptionStartHandlers[message.type])
|
| + this._subscriptionStartHandlers[message.type]();
|
| + }
|
| + }
|
| +
|
| + _onUnsubscribe(message, port) {
|
| + var subscribers = this._subscribers[message.type];
|
| + if (!subscribers)
|
| + return;
|
| + subscribers.remove(port);
|
| + if (!subscribers.length) {
|
| + delete this._subscribers[message.type];
|
| + if (this._subscriptionStopHandlers[message.type])
|
| + this._subscriptionStopHandlers[message.type]();
|
| + }
|
| + }
|
| +
|
| + _onAddRequestHeaders(message) {
|
| + var id = message.extensionId;
|
| + if (typeof id !== 'string')
|
| + return this._status.E_BADARGTYPE('extensionId', typeof id, 'string');
|
| + var extensionHeaders = this._extraHeaders[id];
|
| + if (!extensionHeaders) {
|
| + extensionHeaders = {};
|
| + this._extraHeaders[id] = extensionHeaders;
|
| + }
|
| + for (var name in message.headers)
|
| + extensionHeaders[name] = message.headers[name];
|
| + var allHeaders = /** @type {!NetworkAgent.Headers} */ ({});
|
| + for (var extension in this._extraHeaders) {
|
| + var headers = this._extraHeaders[extension];
|
| + for (name in headers) {
|
| + if (typeof headers[name] === 'string')
|
| + allHeaders[name] = headers[name];
|
| + }
|
| + }
|
|
|
| - /**
|
| - * @return {boolean}
|
| - */
|
| - hasExtensions: function()
|
| - {
|
| - return !!Object.keys(this._registeredExtensions).length;
|
| - },
|
| + WebInspector.multitargetNetworkManager.setExtraHTTPHeaders(allHeaders);
|
| + }
|
| +
|
| + /**
|
| + * @param {*} message
|
| + * @suppressGlobalPropertiesCheck
|
| + */
|
| + _onApplyStyleSheet(message) {
|
| + if (!Runtime.experiments.isEnabled('applyCustomStylesheet'))
|
| + return;
|
| + var styleSheet = createElement('style');
|
| + styleSheet.textContent = message.styleSheet;
|
| + document.head.appendChild(styleSheet);
|
| + }
|
| +
|
| + _onCreatePanel(message, port) {
|
| + var id = message.id;
|
| + // The ids are generated on the client API side and must be unique, so the check below
|
| + // shouldn't be hit unless someone is bypassing the API.
|
| + if (id in this._clientObjects || WebInspector.inspectorView.hasPanel(id))
|
| + return this._status.E_EXISTS(id);
|
| +
|
| + var page = this._expandResourcePath(port._extensionOrigin, message.page);
|
| + var persistentId = port._extensionOrigin + message.title;
|
| + persistentId = persistentId.replace(/\s/g, '');
|
| + var panelView = new WebInspector.ExtensionServerPanelView(
|
| + persistentId, message.title, new WebInspector.ExtensionPanel(this, persistentId, id, page));
|
| + this._clientObjects[id] = panelView;
|
| + WebInspector.inspectorView.addPanel(panelView);
|
| + return this._status.OK();
|
| + }
|
| +
|
| + _onShowPanel(message) {
|
| + var panelViewId = message.id;
|
| + var panelView = this._clientObjects[message.id];
|
| + if (panelView && panelView instanceof WebInspector.ExtensionServerPanelView)
|
| + panelViewId = panelView.viewId();
|
| + WebInspector.inspectorView.showPanel(panelViewId);
|
| + }
|
| +
|
| + _onCreateToolbarButton(message, port) {
|
| + var panelView = this._clientObjects[message.panel];
|
| + if (!panelView || !(panelView instanceof WebInspector.ExtensionServerPanelView))
|
| + return this._status.E_NOTFOUND(message.panel);
|
| + var button = new WebInspector.ExtensionButton(
|
| + this, message.id, this._expandResourcePath(port._extensionOrigin, message.icon), message.tooltip,
|
| + message.disabled);
|
| + this._clientObjects[message.id] = button;
|
| +
|
| + panelView.widget().then(appendButton);
|
|
|
| /**
|
| - * @param {string} panelId
|
| - * @param {string} action
|
| - * @param {string=} searchString
|
| + * @param {!WebInspector.Widget} panel
|
| */
|
| - notifySearchAction: function(panelId, action, searchString)
|
| - {
|
| - this._postNotification(WebInspector.extensionAPI.Events.PanelSearch + panelId, action, searchString);
|
| - },
|
| + function appendButton(panel) {
|
| + /** @type {!WebInspector.ExtensionPanel} panel*/ (panel).addToolbarItem(button.toolbarButton());
|
| + }
|
|
|
| - /**
|
| - * @param {string} identifier
|
| - * @param {number=} frameIndex
|
| - */
|
| - notifyViewShown: function(identifier, frameIndex)
|
| - {
|
| - this._postNotification(WebInspector.extensionAPI.Events.ViewShown + identifier, frameIndex);
|
| - },
|
| + return this._status.OK();
|
| + }
|
| +
|
| + _onUpdateButton(message, port) {
|
| + var button = this._clientObjects[message.id];
|
| + if (!button || !(button instanceof WebInspector.ExtensionButton))
|
| + return this._status.E_NOTFOUND(message.id);
|
| + button.update(this._expandResourcePath(port._extensionOrigin, message.icon), message.tooltip, message.disabled);
|
| + return this._status.OK();
|
| + }
|
| +
|
| + _onCreateSidebarPane(message) {
|
| + if (message.panel !== 'elements' && message.panel !== 'sources')
|
| + return this._status.E_NOTFOUND(message.panel);
|
| + var id = message.id;
|
| + var sidebar = new WebInspector.ExtensionSidebarPane(this, message.panel, message.title, id);
|
| + this._sidebarPanes.push(sidebar);
|
| + this._clientObjects[id] = sidebar;
|
| + this.dispatchEventToListeners(WebInspector.ExtensionServer.Events.SidebarPaneAdded, sidebar);
|
| +
|
| + return this._status.OK();
|
| + }
|
| +
|
| + /**
|
| + * @return {!Array.<!WebInspector.ExtensionSidebarPane>}
|
| + */
|
| + sidebarPanes() {
|
| + return this._sidebarPanes;
|
| + }
|
| +
|
| + _onSetSidebarHeight(message) {
|
| + var sidebar = this._clientObjects[message.id];
|
| + if (!sidebar)
|
| + return this._status.E_NOTFOUND(message.id);
|
| + sidebar.setHeight(message.height);
|
| + return this._status.OK();
|
| + }
|
| +
|
| + _onSetSidebarContent(message, port) {
|
| + var sidebar = this._clientObjects[message.id];
|
| + if (!sidebar)
|
| + return this._status.E_NOTFOUND(message.id);
|
|
|
| /**
|
| - * @param {string} identifier
|
| + * @this {WebInspector.ExtensionServer}
|
| */
|
| - notifyViewHidden: function(identifier)
|
| - {
|
| - this._postNotification(WebInspector.extensionAPI.Events.ViewHidden + identifier);
|
| - },
|
| + function callback(error) {
|
| + var result = error ? this._status.E_FAILED(error) : this._status.OK();
|
| + this._dispatchCallback(message.requestId, port, result);
|
| + }
|
| + if (message.evaluateOnPage)
|
| + return sidebar.setExpression(
|
| + message.expression, message.rootTitle, message.evaluateOptions, port._extensionOrigin, callback.bind(this));
|
| + sidebar.setObject(message.expression, message.rootTitle, callback.bind(this));
|
| + }
|
| +
|
| + _onSetSidebarPage(message, port) {
|
| + var sidebar = this._clientObjects[message.id];
|
| + if (!sidebar)
|
| + return this._status.E_NOTFOUND(message.id);
|
| + sidebar.setPage(this._expandResourcePath(port._extensionOrigin, message.page));
|
| + }
|
| +
|
| + _onOpenResource(message) {
|
| + var uiSourceCode = WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(message.url);
|
| + if (uiSourceCode) {
|
| + WebInspector.Revealer.reveal(uiSourceCode.uiLocation(message.lineNumber, 0));
|
| + return this._status.OK();
|
| + }
|
|
|
| - /**
|
| - * @param {string} identifier
|
| - */
|
| - notifyButtonClicked: function(identifier)
|
| - {
|
| - this._postNotification(WebInspector.extensionAPI.Events.ButtonClicked + identifier);
|
| - },
|
| -
|
| - _inspectedURLChanged: function(event)
|
| - {
|
| - if (event.data !== WebInspector.targetManager.mainTarget())
|
| - return;
|
| - this._requests = {};
|
| - var url = event.data.inspectedURL();
|
| - this._postNotification(WebInspector.extensionAPI.Events.InspectedURLChanged, url);
|
| - },
|
| + var resource = WebInspector.resourceForURL(message.url);
|
| + if (resource) {
|
| + WebInspector.Revealer.reveal(resource);
|
| + return this._status.OK();
|
| + }
|
|
|
| - /**
|
| - * @param {string} categoryId
|
| - * @param {!WebInspector.ExtensionAuditCategoryResults} auditResults
|
| - */
|
| - startAuditRun: function(categoryId, auditResults)
|
| - {
|
| - this._clientObjects[auditResults.id()] = auditResults;
|
| - this._postNotification("audit-started-" + categoryId, auditResults.id());
|
| - },
|
| + var request = WebInspector.NetworkLog.requestForURL(message.url);
|
| + if (request) {
|
| + WebInspector.Revealer.reveal(request);
|
| + return this._status.OK();
|
| + }
|
|
|
| + return this._status.E_NOTFOUND(message.url);
|
| + }
|
| +
|
| + _onSetOpenResourceHandler(message, port) {
|
| + var name = this._registeredExtensions[port._extensionOrigin].name || ('Extension ' + port._extensionOrigin);
|
| + if (message.handlerPresent)
|
| + WebInspector.openAnchorLocationRegistry.registerHandler(name, this._handleOpenURL.bind(this, port));
|
| + else
|
| + WebInspector.openAnchorLocationRegistry.unregisterHandler(name);
|
| + }
|
| +
|
| + _handleOpenURL(port, details) {
|
| + var url = /** @type {string} */ (details.url);
|
| + var contentProvider = WebInspector.workspace.uiSourceCodeForURL(url) || WebInspector.resourceForURL(url);
|
| + if (!contentProvider)
|
| + return false;
|
| +
|
| + var lineNumber = details.lineNumber;
|
| + if (typeof lineNumber === 'number')
|
| + lineNumber += 1;
|
| + port.postMessage({command: 'open-resource', resource: this._makeResource(contentProvider), lineNumber: lineNumber});
|
| + return true;
|
| + }
|
| +
|
| + _onReload(message) {
|
| + var options = /** @type {!ExtensionReloadOptions} */ (message.options || {});
|
| +
|
| + WebInspector.multitargetNetworkManager.setUserAgentOverride(
|
| + typeof options.userAgent === 'string' ? options.userAgent : '');
|
| + var injectedScript;
|
| + if (options.injectedScript)
|
| + injectedScript = '(function(){' + options.injectedScript + '})()';
|
| + WebInspector.targetManager.reloadPage(!!options.ignoreCache, injectedScript);
|
| + return this._status.OK();
|
| + }
|
| +
|
| + _onEvaluateOnInspectedPage(message, port) {
|
| /**
|
| - * @param {!WebInspector.ExtensionAuditCategoryResults} auditResults
|
| + * @param {?Protocol.Error} error
|
| + * @param {?WebInspector.RemoteObject} remoteObject
|
| + * @param {boolean=} wasThrown
|
| + * @this {WebInspector.ExtensionServer}
|
| */
|
| - stopAuditRun: function(auditResults)
|
| - {
|
| - delete this._clientObjects[auditResults.id()];
|
| - },
|
| + function callback(error, remoteObject, wasThrown) {
|
| + var result;
|
| + if (error || !remoteObject)
|
| + result = this._status.E_PROTOCOLERROR(error.toString());
|
| + else if (wasThrown)
|
| + result = {isException: true, value: remoteObject.description};
|
| + else
|
| + result = {value: remoteObject.value};
|
| +
|
| + this._dispatchCallback(message.requestId, port, result);
|
| + }
|
| + return this.evaluate(
|
| + message.expression, true, true, message.evaluateOptions, port._extensionOrigin, callback.bind(this));
|
| + }
|
| +
|
| + _onGetHAR() {
|
| + var requests = WebInspector.NetworkLog.requests();
|
| + var harLog = (new WebInspector.HARLog(requests)).build();
|
| + for (var i = 0; i < harLog.entries.length; ++i)
|
| + harLog.entries[i]._requestId = this._requestId(requests[i]);
|
| + return harLog;
|
| + }
|
| +
|
| + /**
|
| + * @param {!WebInspector.ContentProvider} contentProvider
|
| + */
|
| + _makeResource(contentProvider) {
|
| + return {url: contentProvider.contentURL(), type: contentProvider.contentType().name()};
|
| + }
|
| +
|
| + /**
|
| + * @return {!Array<!WebInspector.ContentProvider>}
|
| + */
|
| + _onGetPageResources() {
|
| + /** @type {!Map<string, !WebInspector.ContentProvider>} */
|
| + var resources = new Map();
|
|
|
| /**
|
| - * @param {string} traceProviderId
|
| + * @this {WebInspector.ExtensionServer}
|
| */
|
| - startTraceRecording: function(traceProviderId)
|
| - {
|
| - this._postNotification("trace-recording-started-" + traceProviderId);
|
| - },
|
| -
|
| - /**
|
| - * @param {string} traceProviderId
|
| - */
|
| - stopTraceRecording: function(traceProviderId)
|
| - {
|
| - this._postNotification("trace-recording-stopped-" + traceProviderId);
|
| - },
|
| -
|
| + function pushResourceData(contentProvider) {
|
| + if (!resources.has(contentProvider.contentURL()))
|
| + resources.set(contentProvider.contentURL(), this._makeResource(contentProvider));
|
| + }
|
| + var uiSourceCodes = WebInspector.workspace.uiSourceCodesForProjectType(WebInspector.projectTypes.Network);
|
| + uiSourceCodes = uiSourceCodes.concat(
|
| + WebInspector.workspace.uiSourceCodesForProjectType(WebInspector.projectTypes.ContentScripts));
|
| + uiSourceCodes.forEach(pushResourceData.bind(this));
|
| + for (var target of WebInspector.targetManager.targets(WebInspector.Target.Capability.DOM))
|
| + WebInspector.ResourceTreeModel.fromTarget(target).forAllResources(pushResourceData.bind(this));
|
| + return resources.valuesArray();
|
| + }
|
| +
|
| + /**
|
| + * @param {!WebInspector.ContentProvider} contentProvider
|
| + * @param {!Object} message
|
| + * @param {!MessagePort} port
|
| + */
|
| + _getResourceContent(contentProvider, message, port) {
|
| /**
|
| - * @param {string} type
|
| - * @return {boolean}
|
| + * @param {?string} content
|
| + * @this {WebInspector.ExtensionServer}
|
| */
|
| - hasSubscribers: function(type)
|
| - {
|
| - return !!this._subscribers[type];
|
| - },
|
| + function onContentAvailable(content) {
|
| + var contentEncoded = false;
|
| + if (contentProvider instanceof WebInspector.Resource)
|
| + contentEncoded = contentProvider.contentEncoded;
|
| + if (contentProvider instanceof WebInspector.NetworkRequest)
|
| + contentEncoded = contentProvider.contentEncoded;
|
| + var response = {encoding: contentEncoded && content ? 'base64' : '', content: content};
|
| + this._dispatchCallback(message.requestId, port, response);
|
| + }
|
|
|
| + contentProvider.requestContent().then(onContentAvailable.bind(this));
|
| + }
|
| +
|
| + _onGetRequestContent(message, port) {
|
| + var request = this._requestById(message.id);
|
| + if (!request)
|
| + return this._status.E_NOTFOUND(message.id);
|
| + this._getResourceContent(request, message, port);
|
| + }
|
| +
|
| + _onGetResourceContent(message, port) {
|
| + var url = /** @type {string} */ (message.url);
|
| + var contentProvider = WebInspector.workspace.uiSourceCodeForURL(url) || WebInspector.resourceForURL(url);
|
| + if (!contentProvider)
|
| + return this._status.E_NOTFOUND(url);
|
| + this._getResourceContent(contentProvider, message, port);
|
| + }
|
| +
|
| + _onSetResourceContent(message, port) {
|
| /**
|
| - * @param {string} type
|
| - * @param {...*} vararg
|
| + * @param {?Protocol.Error} error
|
| + * @this {WebInspector.ExtensionServer}
|
| */
|
| - _postNotification: function(type, vararg)
|
| - {
|
| - var subscribers = this._subscribers[type];
|
| - if (!subscribers)
|
| - return;
|
| - var message = {
|
| - command: "notify-" + type,
|
| - arguments: Array.prototype.slice.call(arguments, 1)
|
| - };
|
| - for (var i = 0; i < subscribers.length; ++i)
|
| - subscribers[i].postMessage(message);
|
| - },
|
| -
|
| - _onSubscribe: function(message, port)
|
| - {
|
| - var subscribers = this._subscribers[message.type];
|
| - if (subscribers)
|
| - subscribers.push(port);
|
| - else {
|
| - this._subscribers[message.type] = [ port ];
|
| - if (this._subscriptionStartHandlers[message.type])
|
| - this._subscriptionStartHandlers[message.type]();
|
| - }
|
| - },
|
| -
|
| - _onUnsubscribe: function(message, port)
|
| - {
|
| - var subscribers = this._subscribers[message.type];
|
| - if (!subscribers)
|
| - return;
|
| - subscribers.remove(port);
|
| - if (!subscribers.length) {
|
| - delete this._subscribers[message.type];
|
| - if (this._subscriptionStopHandlers[message.type])
|
| - this._subscriptionStopHandlers[message.type]();
|
| - }
|
| - },
|
| -
|
| - _onAddRequestHeaders: function(message)
|
| - {
|
| - var id = message.extensionId;
|
| - if (typeof id !== "string")
|
| - return this._status.E_BADARGTYPE("extensionId", typeof id, "string");
|
| - var extensionHeaders = this._extraHeaders[id];
|
| - if (!extensionHeaders) {
|
| - extensionHeaders = {};
|
| - this._extraHeaders[id] = extensionHeaders;
|
| - }
|
| - for (var name in message.headers)
|
| - extensionHeaders[name] = message.headers[name];
|
| - var allHeaders = /** @type {!NetworkAgent.Headers} */ ({});
|
| - for (var extension in this._extraHeaders) {
|
| - var headers = this._extraHeaders[extension];
|
| - for (name in headers) {
|
| - if (typeof headers[name] === "string")
|
| - allHeaders[name] = headers[name];
|
| - }
|
| - }
|
| + function callbackWrapper(error) {
|
| + var response = error ? this._status.E_FAILED(error) : this._status.OK();
|
| + this._dispatchCallback(message.requestId, port, response);
|
| + }
|
|
|
| - WebInspector.multitargetNetworkManager.setExtraHTTPHeaders(allHeaders);
|
| - },
|
| + var url = /** @type {string} */ (message.url);
|
| + var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(url);
|
| + if (!uiSourceCode || !uiSourceCode.contentType().isDocumentOrScriptOrStyleSheet()) {
|
| + var resource = WebInspector.ResourceTreeModel.resourceForURL(url);
|
| + if (!resource)
|
| + return this._status.E_NOTFOUND(url);
|
| + return this._status.E_NOTSUPPORTED('Resource is not editable');
|
| + }
|
| + uiSourceCode.setWorkingCopy(message.content);
|
| + if (message.commit)
|
| + uiSourceCode.commitWorkingCopy();
|
| + callbackWrapper.call(this, null);
|
| + }
|
| +
|
| + _requestId(request) {
|
| + if (!request._extensionRequestId) {
|
| + request._extensionRequestId = ++this._lastRequestId;
|
| + this._requests[request._extensionRequestId] = request;
|
| + }
|
| + return request._extensionRequestId;
|
| + }
|
| +
|
| + _requestById(id) {
|
| + return this._requests[id];
|
| + }
|
| +
|
| + _onAddAuditCategory(message, port) {
|
| + var category = new WebInspector.ExtensionAuditCategory(
|
| + port._extensionOrigin, message.id, message.displayName, message.resultCount);
|
| + this._clientObjects[message.id] = category;
|
| + this._auditCategories.push(category);
|
| + this.dispatchEventToListeners(WebInspector.ExtensionServer.Events.AuditCategoryAdded, category);
|
| + }
|
| +
|
| + /**
|
| + * @param {!Object} message
|
| + * @param {!MessagePort} port
|
| + */
|
| + _onAddTraceProvider(message, port) {
|
| + var provider = new WebInspector.ExtensionTraceProvider(
|
| + port._extensionOrigin, message.id, message.categoryName, message.categoryTooltip);
|
| + this._clientObjects[message.id] = provider;
|
| + this._traceProviders.push(provider);
|
| + }
|
| +
|
| + /**
|
| + * @return {!Array<!WebInspector.ExtensionTraceProvider>}
|
| + */
|
| + traceProviders() {
|
| + return this._traceProviders;
|
| + }
|
| +
|
| + /**
|
| + * @return {!Array.<!WebInspector.ExtensionAuditCategory>}
|
| + */
|
| + auditCategories() {
|
| + return this._auditCategories;
|
| + }
|
| +
|
| + _onAddAuditResult(message) {
|
| + var auditResult = /** {!WebInspector.ExtensionAuditCategoryResults} */ (this._clientObjects[message.resultId]);
|
| + if (!auditResult)
|
| + return this._status.E_NOTFOUND(message.resultId);
|
| + try {
|
| + auditResult.addResult(message.displayName, message.description, message.severity, message.details);
|
| + } catch (e) {
|
| + return e;
|
| + }
|
| + return this._status.OK();
|
| + }
|
| +
|
| + _onUpdateAuditProgress(message) {
|
| + var auditResult = /** {!WebInspector.ExtensionAuditCategoryResults} */ (this._clientObjects[message.resultId]);
|
| + if (!auditResult)
|
| + return this._status.E_NOTFOUND(message.resultId);
|
| + auditResult.updateProgress(Math.min(Math.max(0, message.progress), 1));
|
| + }
|
| +
|
| + _onStopAuditCategoryRun(message) {
|
| + var auditRun = /** {!WebInspector.ExtensionAuditCategoryResults} */ (this._clientObjects[message.resultId]);
|
| + if (!auditRun)
|
| + return this._status.E_NOTFOUND(message.resultId);
|
| + auditRun.done();
|
| + }
|
| +
|
| + _onForwardKeyboardEvent(message) {
|
| + message.entries.forEach(handleEventEntry);
|
|
|
| /**
|
| - * @param {*} message
|
| + * @param {*} entry
|
| * @suppressGlobalPropertiesCheck
|
| */
|
| - _onApplyStyleSheet: function(message)
|
| - {
|
| - if (!Runtime.experiments.isEnabled("applyCustomStylesheet"))
|
| - return;
|
| - var styleSheet = createElement("style");
|
| - styleSheet.textContent = message.styleSheet;
|
| - document.head.appendChild(styleSheet);
|
| - },
|
| -
|
| - _onCreatePanel: function(message, port)
|
| - {
|
| - var id = message.id;
|
| - // The ids are generated on the client API side and must be unique, so the check below
|
| - // shouldn't be hit unless someone is bypassing the API.
|
| - if (id in this._clientObjects || WebInspector.inspectorView.hasPanel(id))
|
| - return this._status.E_EXISTS(id);
|
| -
|
| - var page = this._expandResourcePath(port._extensionOrigin, message.page);
|
| - var persistentId = port._extensionOrigin + message.title;
|
| - persistentId = persistentId.replace(/\s/g, "");
|
| - var panelView = new WebInspector.ExtensionServerPanelView(persistentId, message.title, new WebInspector.ExtensionPanel(this, persistentId, id, page));
|
| - this._clientObjects[id] = panelView;
|
| - WebInspector.inspectorView.addPanel(panelView);
|
| - return this._status.OK();
|
| - },
|
| -
|
| - _onShowPanel: function(message)
|
| - {
|
| - var panelViewId = message.id;
|
| - var panelView = this._clientObjects[message.id];
|
| - if (panelView && panelView instanceof WebInspector.ExtensionServerPanelView)
|
| - panelViewId = panelView.viewId();
|
| - WebInspector.inspectorView.showPanel(panelViewId);
|
| - },
|
| -
|
| - _onCreateToolbarButton: function(message, port)
|
| - {
|
| - var panelView = this._clientObjects[message.panel];
|
| - if (!panelView || !(panelView instanceof WebInspector.ExtensionServerPanelView))
|
| - return this._status.E_NOTFOUND(message.panel);
|
| - var button = new WebInspector.ExtensionButton(this, message.id, this._expandResourcePath(port._extensionOrigin, message.icon), message.tooltip, message.disabled);
|
| - this._clientObjects[message.id] = button;
|
| -
|
| - panelView.widget().then(appendButton);
|
| -
|
| - /**
|
| - * @param {!WebInspector.Widget} panel
|
| - */
|
| - function appendButton(panel)
|
| - {
|
| - /** @type {!WebInspector.ExtensionPanel} panel*/ (panel).addToolbarItem(button.toolbarButton());
|
| - }
|
| -
|
| - return this._status.OK();
|
| - },
|
| -
|
| - _onUpdateButton: function(message, port)
|
| - {
|
| - var button = this._clientObjects[message.id];
|
| - if (!button || !(button instanceof WebInspector.ExtensionButton))
|
| - return this._status.E_NOTFOUND(message.id);
|
| - button.update(this._expandResourcePath(port._extensionOrigin, message.icon), message.tooltip, message.disabled);
|
| - return this._status.OK();
|
| - },
|
| -
|
| - _onCreateSidebarPane: function(message)
|
| - {
|
| - if (message.panel !== "elements" && message.panel !== "sources")
|
| - return this._status.E_NOTFOUND(message.panel);
|
| - var id = message.id;
|
| - var sidebar = new WebInspector.ExtensionSidebarPane(this, message.panel, message.title, id);
|
| - this._sidebarPanes.push(sidebar);
|
| - this._clientObjects[id] = sidebar;
|
| - this.dispatchEventToListeners(WebInspector.ExtensionServer.Events.SidebarPaneAdded, sidebar);
|
| -
|
| - return this._status.OK();
|
| - },
|
| -
|
| - /**
|
| - * @return {!Array.<!WebInspector.ExtensionSidebarPane>}
|
| - */
|
| - sidebarPanes: function()
|
| - {
|
| - return this._sidebarPanes;
|
| - },
|
| -
|
| - _onSetSidebarHeight: function(message)
|
| - {
|
| - var sidebar = this._clientObjects[message.id];
|
| - if (!sidebar)
|
| - return this._status.E_NOTFOUND(message.id);
|
| - sidebar.setHeight(message.height);
|
| - return this._status.OK();
|
| - },
|
| -
|
| - _onSetSidebarContent: function(message, port)
|
| - {
|
| - var sidebar = this._clientObjects[message.id];
|
| - if (!sidebar)
|
| - return this._status.E_NOTFOUND(message.id);
|
| -
|
| - /**
|
| - * @this {WebInspector.ExtensionServer}
|
| - */
|
| - function callback(error)
|
| - {
|
| - var result = error ? this._status.E_FAILED(error) : this._status.OK();
|
| - this._dispatchCallback(message.requestId, port, result);
|
| - }
|
| - if (message.evaluateOnPage)
|
| - return sidebar.setExpression(message.expression, message.rootTitle, message.evaluateOptions, port._extensionOrigin, callback.bind(this));
|
| - sidebar.setObject(message.expression, message.rootTitle, callback.bind(this));
|
| - },
|
| -
|
| - _onSetSidebarPage: function(message, port)
|
| - {
|
| - var sidebar = this._clientObjects[message.id];
|
| - if (!sidebar)
|
| - return this._status.E_NOTFOUND(message.id);
|
| - sidebar.setPage(this._expandResourcePath(port._extensionOrigin, message.page));
|
| - },
|
| -
|
| - _onOpenResource: function(message)
|
| - {
|
| - var uiSourceCode = WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(message.url);
|
| - if (uiSourceCode) {
|
| - WebInspector.Revealer.reveal(uiSourceCode.uiLocation(message.lineNumber, 0));
|
| - return this._status.OK();
|
| - }
|
| -
|
| - var resource = WebInspector.resourceForURL(message.url);
|
| - if (resource) {
|
| - WebInspector.Revealer.reveal(resource);
|
| - return this._status.OK();
|
| - }
|
| + function handleEventEntry(entry) {
|
| + if (!entry.ctrlKey && !entry.altKey && !entry.metaKey && !/^F\d+$/.test(entry.key) && entry.key !== 'Escape')
|
| + return;
|
| + // Fool around closure compiler -- it has its own notion of both KeyboardEvent constructor
|
| + // and initKeyboardEvent methods and overriding these in externs.js does not have effect.
|
| + var event = new window.KeyboardEvent(entry.eventType, {
|
| + key: entry.key,
|
| + code: entry.code,
|
| + keyCode: entry.keyCode,
|
| + location: entry.location,
|
| + ctrlKey: entry.ctrlKey,
|
| + altKey: entry.altKey,
|
| + shiftKey: entry.shiftKey,
|
| + metaKey: entry.metaKey
|
| + });
|
| + event.__keyCode = keyCodeForEntry(entry);
|
| + document.dispatchEvent(event);
|
| + }
|
|
|
| - var request = WebInspector.NetworkLog.requestForURL(message.url);
|
| - if (request) {
|
| - WebInspector.Revealer.reveal(request);
|
| - return this._status.OK();
|
| - }
|
| + function keyCodeForEntry(entry) {
|
| + var keyCode = entry.keyCode;
|
| + if (!keyCode) {
|
| + // This is required only for synthetic events (e.g. dispatched in tests).
|
| + if (entry.key === 'Escape')
|
| + keyCode = 27;
|
| + }
|
| + return keyCode || 0;
|
| + }
|
| + }
|
|
|
| - return this._status.E_NOTFOUND(message.url);
|
| - },
|
| + _dispatchCallback(requestId, port, result) {
|
| + if (requestId)
|
| + port.postMessage({command: 'callback', requestId: requestId, result: result});
|
| + }
|
|
|
| - _onSetOpenResourceHandler: function(message, port)
|
| - {
|
| - var name = this._registeredExtensions[port._extensionOrigin].name || ("Extension " + port._extensionOrigin);
|
| - if (message.handlerPresent)
|
| - WebInspector.openAnchorLocationRegistry.registerHandler(name, this._handleOpenURL.bind(this, port));
|
| - else
|
| - WebInspector.openAnchorLocationRegistry.unregisterHandler(name);
|
| - },
|
| -
|
| - _handleOpenURL: function(port, details)
|
| - {
|
| - var url = /** @type {string} */ (details.url);
|
| - var contentProvider = WebInspector.workspace.uiSourceCodeForURL(url) || WebInspector.resourceForURL(url);
|
| - if (!contentProvider)
|
| - return false;
|
| -
|
| - var lineNumber = details.lineNumber;
|
| - if (typeof lineNumber === "number")
|
| - lineNumber += 1;
|
| - port.postMessage({
|
| - command: "open-resource",
|
| - resource: this._makeResource(contentProvider),
|
| - lineNumber: lineNumber
|
| - });
|
| - return true;
|
| - },
|
| -
|
| - _onReload: function(message)
|
| - {
|
| - var options = /** @type {!ExtensionReloadOptions} */ (message.options || {});
|
| -
|
| - WebInspector.multitargetNetworkManager.setUserAgentOverride(typeof options.userAgent === "string" ? options.userAgent : "");
|
| - var injectedScript;
|
| - if (options.injectedScript)
|
| - injectedScript = "(function(){" + options.injectedScript + "})()";
|
| - WebInspector.targetManager.reloadPage(!!options.ignoreCache, injectedScript);
|
| - return this._status.OK();
|
| - },
|
| -
|
| - _onEvaluateOnInspectedPage: function(message, port)
|
| - {
|
| - /**
|
| - * @param {?Protocol.Error} error
|
| - * @param {?WebInspector.RemoteObject} remoteObject
|
| - * @param {boolean=} wasThrown
|
| - * @this {WebInspector.ExtensionServer}
|
| - */
|
| - function callback(error, remoteObject, wasThrown)
|
| - {
|
| - var result;
|
| - if (error || !remoteObject)
|
| - result = this._status.E_PROTOCOLERROR(error.toString());
|
| - else if (wasThrown)
|
| - result = { isException: true, value: remoteObject.description };
|
| - else
|
| - result = { value: remoteObject.value };
|
| -
|
| - this._dispatchCallback(message.requestId, port, result);
|
| - }
|
| - return this.evaluate(message.expression, true, true, message.evaluateOptions, port._extensionOrigin, callback.bind(this));
|
| - },
|
| -
|
| - _onGetHAR: function()
|
| - {
|
| - var requests = WebInspector.NetworkLog.requests();
|
| - var harLog = (new WebInspector.HARLog(requests)).build();
|
| - for (var i = 0; i < harLog.entries.length; ++i)
|
| - harLog.entries[i]._requestId = this._requestId(requests[i]);
|
| - return harLog;
|
| - },
|
| + _initExtensions() {
|
| + this._registerAutosubscriptionHandler(
|
| + WebInspector.extensionAPI.Events.ResourceAdded, WebInspector.workspace,
|
| + WebInspector.Workspace.Events.UISourceCodeAdded, this._notifyResourceAdded);
|
| + this._registerAutosubscriptionTargetManagerHandler(
|
| + WebInspector.extensionAPI.Events.NetworkRequestFinished, WebInspector.NetworkManager,
|
| + WebInspector.NetworkManager.Events.RequestFinished, this._notifyRequestFinished);
|
|
|
| /**
|
| - * @param {!WebInspector.ContentProvider} contentProvider
|
| + * @this {WebInspector.ExtensionServer}
|
| */
|
| - _makeResource: function(contentProvider)
|
| - {
|
| - return {
|
| - url: contentProvider.contentURL(),
|
| - type: contentProvider.contentType().name()
|
| - };
|
| - },
|
| + function onElementsSubscriptionStarted() {
|
| + WebInspector.context.addFlavorChangeListener(WebInspector.DOMNode, this._notifyElementsSelectionChanged, this);
|
| + }
|
|
|
| /**
|
| - * @return {!Array<!WebInspector.ContentProvider>}
|
| + * @this {WebInspector.ExtensionServer}
|
| */
|
| - _onGetPageResources: function()
|
| - {
|
| - /** @type {!Map<string, !WebInspector.ContentProvider>} */
|
| - var resources = new Map();
|
| -
|
| - /**
|
| - * @this {WebInspector.ExtensionServer}
|
| - */
|
| - function pushResourceData(contentProvider)
|
| - {
|
| - if (!resources.has(contentProvider.contentURL()))
|
| - resources.set(contentProvider.contentURL(), this._makeResource(contentProvider));
|
| - }
|
| - var uiSourceCodes = WebInspector.workspace.uiSourceCodesForProjectType(WebInspector.projectTypes.Network);
|
| - uiSourceCodes = uiSourceCodes.concat(WebInspector.workspace.uiSourceCodesForProjectType(WebInspector.projectTypes.ContentScripts));
|
| - uiSourceCodes.forEach(pushResourceData.bind(this));
|
| - for (var target of WebInspector.targetManager.targets(WebInspector.Target.Capability.DOM))
|
| - WebInspector.ResourceTreeModel.fromTarget(target).forAllResources(pushResourceData.bind(this));
|
| - return resources.valuesArray();
|
| - },
|
| + function onElementsSubscriptionStopped() {
|
| + WebInspector.context.removeFlavorChangeListener(WebInspector.DOMNode, this._notifyElementsSelectionChanged, this);
|
| + }
|
|
|
| + this._registerSubscriptionHandler(
|
| + WebInspector.extensionAPI.Events.PanelObjectSelected + 'elements', onElementsSubscriptionStarted.bind(this),
|
| + onElementsSubscriptionStopped.bind(this));
|
| + this._registerResourceContentCommittedHandler(this._notifyUISourceCodeContentCommitted);
|
| +
|
| + WebInspector.targetManager.addEventListener(
|
| + WebInspector.TargetManager.Events.InspectedURLChanged, this._inspectedURLChanged, this);
|
| +
|
| + InspectorExtensionRegistry.getExtensionsAsync();
|
| + }
|
| +
|
| + _notifyResourceAdded(event) {
|
| + var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
|
| + this._postNotification(WebInspector.extensionAPI.Events.ResourceAdded, this._makeResource(uiSourceCode));
|
| + }
|
| +
|
| + _notifyUISourceCodeContentCommitted(event) {
|
| + var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data.uiSourceCode);
|
| + var content = /** @type {string} */ (event.data.content);
|
| + this._postNotification(
|
| + WebInspector.extensionAPI.Events.ResourceContentCommitted, this._makeResource(uiSourceCode), content);
|
| + }
|
| +
|
| + _notifyRequestFinished(event) {
|
| + var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
|
| + this._postNotification(
|
| + WebInspector.extensionAPI.Events.NetworkRequestFinished, this._requestId(request),
|
| + (new WebInspector.HAREntry(request)).build());
|
| + }
|
| +
|
| + _notifyElementsSelectionChanged() {
|
| + this._postNotification(WebInspector.extensionAPI.Events.PanelObjectSelected + 'elements');
|
| + }
|
| +
|
| + /**
|
| + * @param {!WebInspector.Event} event
|
| + */
|
| + _addExtensions(event) {
|
| + if (WebInspector.extensionServer._overridePlatformExtensionAPIForTest)
|
| + window.buildPlatformExtensionAPI = WebInspector.extensionServer._overridePlatformExtensionAPIForTest;
|
| +
|
| + var extensionInfos = /** @type {!Array.<!ExtensionDescriptor>} */ (event.data);
|
| + if (this._initializeCommandIssued)
|
| + extensionInfos.forEach(this._addExtension, this);
|
| + else
|
| + this._pendingExtensionInfos = extensionInfos;
|
| + }
|
| +
|
| + /**
|
| + * @param {!WebInspector.Event} event
|
| + */
|
| + _setInspectedTabId(event) {
|
| + this._inspectedTabId = /** @type {string} */ (event.data);
|
| + }
|
| +
|
| + /**
|
| + * @param {!ExtensionDescriptor} extensionInfo
|
| + * @suppressGlobalPropertiesCheck
|
| + */
|
| + _addExtension(extensionInfo) {
|
| + const urlOriginRegExp = new RegExp('([^:]+:\/\/[^/]*)\/'); // Can't use regexp literal here, MinJS chokes on it.
|
| + var startPage = extensionInfo.startPage;
|
| + var name = extensionInfo.name;
|
| +
|
| + try {
|
| + var originMatch = urlOriginRegExp.exec(startPage);
|
| + if (!originMatch) {
|
| + console.error('Skipping extension with invalid URL: ' + startPage);
|
| + return false;
|
| + }
|
| + var extensionOrigin = originMatch[1];
|
| + if (!this._registeredExtensions[extensionOrigin]) {
|
| + // See ExtensionAPI.js for details.
|
| + var injectedAPI = buildExtensionAPIInjectedScript(
|
| + extensionInfo, this._inspectedTabId, WebInspector.themeSupport.themeName(),
|
| + WebInspector.extensionServer['_extensionAPITestHook']);
|
| + InspectorFrontendHost.setInjectedScriptForOrigin(extensionOrigin, injectedAPI);
|
| + this._registeredExtensions[extensionOrigin] = {name: name};
|
| + }
|
| + var iframe = createElement('iframe');
|
| + iframe.src = startPage;
|
| + iframe.style.display = 'none';
|
| + document.body.appendChild(iframe); // Only for main window.
|
| + } catch (e) {
|
| + console.error('Failed to initialize extension ' + startPage + ':' + e);
|
| + return false;
|
| + }
|
| + return true;
|
| + }
|
| +
|
| + _registerExtension(origin, port) {
|
| + if (!this._registeredExtensions.hasOwnProperty(origin)) {
|
| + if (origin !== window.location.origin) // Just ignore inspector frames.
|
| + console.error('Ignoring unauthorized client request from ' + origin);
|
| + return;
|
| + }
|
| + port._extensionOrigin = origin;
|
| + port.addEventListener('message', this._onmessage.bind(this), false);
|
| + port.start();
|
| + }
|
| +
|
| + _onWindowMessage(event) {
|
| + if (event.data === 'registerExtension')
|
| + this._registerExtension(event.origin, event.ports[0]);
|
| + }
|
| +
|
| + _onmessage(event) {
|
| + var message = event.data;
|
| + var result;
|
| +
|
| + if (message.command in this._handlers)
|
| + result = this._handlers[message.command](message, event.target);
|
| + else
|
| + result = this._status.E_NOTSUPPORTED(message.command);
|
| +
|
| + if (result && message.requestId)
|
| + this._dispatchCallback(message.requestId, event.target, result);
|
| + }
|
| +
|
| + _registerHandler(command, callback) {
|
| + console.assert(command);
|
| + this._handlers[command] = callback;
|
| + }
|
| +
|
| + _registerSubscriptionHandler(eventTopic, onSubscribeFirst, onUnsubscribeLast) {
|
| + this._subscriptionStartHandlers[eventTopic] = onSubscribeFirst;
|
| + this._subscriptionStopHandlers[eventTopic] = onUnsubscribeLast;
|
| + }
|
| +
|
| + /**
|
| + * @param {string} eventTopic
|
| + * @param {!Object} eventTarget
|
| + * @param {string} frontendEventType
|
| + * @param {function(!WebInspector.Event)} handler
|
| + */
|
| + _registerAutosubscriptionHandler(eventTopic, eventTarget, frontendEventType, handler) {
|
| + this._registerSubscriptionHandler(
|
| + eventTopic, eventTarget.addEventListener.bind(eventTarget, frontendEventType, handler, this),
|
| + eventTarget.removeEventListener.bind(eventTarget, frontendEventType, handler, this));
|
| + }
|
| +
|
| + /**
|
| + * @param {string} eventTopic
|
| + * @param {!Function} modelClass
|
| + * @param {string} frontendEventType
|
| + * @param {function(!WebInspector.Event)} handler
|
| + */
|
| + _registerAutosubscriptionTargetManagerHandler(eventTopic, modelClass, frontendEventType, handler) {
|
| + this._registerSubscriptionHandler(
|
| + eventTopic, WebInspector.targetManager.addModelListener.bind(
|
| + WebInspector.targetManager, modelClass, frontendEventType, handler, this),
|
| + WebInspector.targetManager.removeModelListener.bind(
|
| + WebInspector.targetManager, modelClass, frontendEventType, handler, this));
|
| + }
|
| +
|
| + _registerResourceContentCommittedHandler(handler) {
|
| /**
|
| - * @param {!WebInspector.ContentProvider} contentProvider
|
| - * @param {!Object} message
|
| - * @param {!MessagePort} port
|
| + * @this {WebInspector.ExtensionServer}
|
| */
|
| - _getResourceContent: function(contentProvider, message, port)
|
| - {
|
| - /**
|
| - * @param {?string} content
|
| - * @this {WebInspector.ExtensionServer}
|
| - */
|
| - function onContentAvailable(content)
|
| - {
|
| - var contentEncoded = false;
|
| - if (contentProvider instanceof WebInspector.Resource)
|
| - contentEncoded = contentProvider.contentEncoded;
|
| - if (contentProvider instanceof WebInspector.NetworkRequest)
|
| - contentEncoded = contentProvider.contentEncoded;
|
| - var response = {
|
| - encoding: contentEncoded && content ? "base64" : "",
|
| - content: content
|
| - };
|
| - this._dispatchCallback(message.requestId, port, response);
|
| - }
|
| -
|
| - contentProvider.requestContent().then(onContentAvailable.bind(this));
|
| - },
|
| -
|
| - _onGetRequestContent: function(message, port)
|
| - {
|
| - var request = this._requestById(message.id);
|
| - if (!request)
|
| - return this._status.E_NOTFOUND(message.id);
|
| - this._getResourceContent(request, message, port);
|
| - },
|
| -
|
| - _onGetResourceContent: function(message, port)
|
| - {
|
| - var url = /** @type {string} */ (message.url);
|
| - var contentProvider = WebInspector.workspace.uiSourceCodeForURL(url) || WebInspector.resourceForURL(url);
|
| - if (!contentProvider)
|
| - return this._status.E_NOTFOUND(url);
|
| - this._getResourceContent(contentProvider, message, port);
|
| - },
|
| -
|
| - _onSetResourceContent: function(message, port)
|
| - {
|
| - /**
|
| - * @param {?Protocol.Error} error
|
| - * @this {WebInspector.ExtensionServer}
|
| - */
|
| - function callbackWrapper(error)
|
| - {
|
| - var response = error ? this._status.E_FAILED(error) : this._status.OK();
|
| - this._dispatchCallback(message.requestId, port, response);
|
| - }
|
| -
|
| - var url = /** @type {string} */ (message.url);
|
| - var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(url);
|
| - if (!uiSourceCode || !uiSourceCode.contentType().isDocumentOrScriptOrStyleSheet()) {
|
| - var resource = WebInspector.ResourceTreeModel.resourceForURL(url);
|
| - if (!resource)
|
| - return this._status.E_NOTFOUND(url);
|
| - return this._status.E_NOTSUPPORTED("Resource is not editable");
|
| - }
|
| - uiSourceCode.setWorkingCopy(message.content);
|
| - if (message.commit)
|
| - uiSourceCode.commitWorkingCopy();
|
| - callbackWrapper.call(this, null);
|
| - },
|
| -
|
| - _requestId: function(request)
|
| - {
|
| - if (!request._extensionRequestId) {
|
| - request._extensionRequestId = ++this._lastRequestId;
|
| - this._requests[request._extensionRequestId] = request;
|
| - }
|
| - return request._extensionRequestId;
|
| - },
|
| -
|
| - _requestById: function(id)
|
| - {
|
| - return this._requests[id];
|
| - },
|
| -
|
| - _onAddAuditCategory: function(message, port)
|
| - {
|
| - var category = new WebInspector.ExtensionAuditCategory(port._extensionOrigin, message.id, message.displayName, message.resultCount);
|
| - this._clientObjects[message.id] = category;
|
| - this._auditCategories.push(category);
|
| - this.dispatchEventToListeners(WebInspector.ExtensionServer.Events.AuditCategoryAdded, category);
|
| - },
|
| + function addFirstEventListener() {
|
| + WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.WorkingCopyCommittedByUser, handler, this);
|
| + WebInspector.workspace.setHasResourceContentTrackingExtensions(true);
|
| + }
|
|
|
| /**
|
| - * @param {!Object} message
|
| - * @param {!MessagePort} port
|
| + * @this {WebInspector.ExtensionServer}
|
| */
|
| - _onAddTraceProvider: function(message, port)
|
| - {
|
| - var provider = new WebInspector.ExtensionTraceProvider(port._extensionOrigin, message.id, message.categoryName, message.categoryTooltip);
|
| - this._clientObjects[message.id] = provider;
|
| - this._traceProviders.push(provider);
|
| - },
|
| + function removeLastEventListener() {
|
| + WebInspector.workspace.setHasResourceContentTrackingExtensions(false);
|
| + WebInspector.workspace.removeEventListener(
|
| + WebInspector.Workspace.Events.WorkingCopyCommittedByUser, handler, this);
|
| + }
|
|
|
| - /**
|
| - * @return {!Array<!WebInspector.ExtensionTraceProvider>}
|
| - */
|
| - traceProviders: function()
|
| - {
|
| - return this._traceProviders;
|
| - },
|
| + this._registerSubscriptionHandler(
|
| + WebInspector.extensionAPI.Events.ResourceContentCommitted, addFirstEventListener.bind(this),
|
| + removeLastEventListener.bind(this));
|
| + }
|
| +
|
| + _expandResourcePath(extensionPath, resourcePath) {
|
| + if (!resourcePath)
|
| + return;
|
| + return extensionPath + this._normalizePath(resourcePath);
|
| + }
|
| +
|
| + _normalizePath(path) {
|
| + var source = path.split('/');
|
| + var result = [];
|
| +
|
| + for (var i = 0; i < source.length; ++i) {
|
| + if (source[i] === '.')
|
| + continue;
|
| + // Ignore empty path components resulting from //, as well as a leading and traling slashes.
|
| + if (source[i] === '')
|
| + continue;
|
| + if (source[i] === '..')
|
| + result.pop();
|
| + else
|
| + result.push(source[i]);
|
| + }
|
| + return '/' + result.join('/');
|
| + }
|
| +
|
| + /**
|
| + * @param {string} expression
|
| + * @param {boolean} exposeCommandLineAPI
|
| + * @param {boolean} returnByValue
|
| + * @param {?Object} options
|
| + * @param {string} securityOrigin
|
| + * @param {function(?string, ?WebInspector.RemoteObject, boolean=)} callback
|
| + * @return {!WebInspector.ExtensionStatus.Record|undefined}
|
| + */
|
| + evaluate(expression, exposeCommandLineAPI, returnByValue, options, securityOrigin, callback) {
|
| + var contextId;
|
|
|
| /**
|
| - * @return {!Array.<!WebInspector.ExtensionAuditCategory>}
|
| + * @param {string} url
|
| + * @return {boolean}
|
| */
|
| - auditCategories: function()
|
| - {
|
| - return this._auditCategories;
|
| - },
|
| -
|
| - _onAddAuditResult: function(message)
|
| - {
|
| - var auditResult = /** {!WebInspector.ExtensionAuditCategoryResults} */ (this._clientObjects[message.resultId]);
|
| - if (!auditResult)
|
| - return this._status.E_NOTFOUND(message.resultId);
|
| - try {
|
| - auditResult.addResult(message.displayName, message.description, message.severity, message.details);
|
| - } catch (e) {
|
| - return e;
|
| - }
|
| - return this._status.OK();
|
| - },
|
| -
|
| - _onUpdateAuditProgress: function(message)
|
| - {
|
| - var auditResult = /** {!WebInspector.ExtensionAuditCategoryResults} */ (this._clientObjects[message.resultId]);
|
| - if (!auditResult)
|
| - return this._status.E_NOTFOUND(message.resultId);
|
| - auditResult.updateProgress(Math.min(Math.max(0, message.progress), 1));
|
| - },
|
| -
|
| - _onStopAuditCategoryRun: function(message)
|
| - {
|
| - var auditRun = /** {!WebInspector.ExtensionAuditCategoryResults} */ (this._clientObjects[message.resultId]);
|
| - if (!auditRun)
|
| - return this._status.E_NOTFOUND(message.resultId);
|
| - auditRun.done();
|
| - },
|
| -
|
| - _onForwardKeyboardEvent: function(message)
|
| - {
|
| - message.entries.forEach(handleEventEntry);
|
| -
|
| - /**
|
| - * @param {*} entry
|
| - * @suppressGlobalPropertiesCheck
|
| - */
|
| - function handleEventEntry(entry)
|
| - {
|
| - if (!entry.ctrlKey && !entry.altKey && !entry.metaKey && !/^F\d+$/.test(entry.key) && entry.key !== "Escape")
|
| - return;
|
| - // Fool around closure compiler -- it has its own notion of both KeyboardEvent constructor
|
| - // and initKeyboardEvent methods and overriding these in externs.js does not have effect.
|
| - var event = new window.KeyboardEvent(entry.eventType, {
|
| - key: entry.key,
|
| - code: entry.code,
|
| - keyCode: entry.keyCode,
|
| - location: entry.location,
|
| - ctrlKey: entry.ctrlKey,
|
| - altKey: entry.altKey,
|
| - shiftKey: entry.shiftKey,
|
| - metaKey: entry.metaKey
|
| - });
|
| - event.__keyCode = keyCodeForEntry(entry);
|
| - document.dispatchEvent(event);
|
| - }
|
| -
|
| - function keyCodeForEntry(entry)
|
| - {
|
| - var keyCode = entry.keyCode;
|
| - if (!keyCode) {
|
| - // This is required only for synthetic events (e.g. dispatched in tests).
|
| - if (entry.key === "Escape")
|
| - keyCode = 27;
|
| - }
|
| - return keyCode || 0;
|
| - }
|
| - },
|
| -
|
| - _dispatchCallback: function(requestId, port, result)
|
| - {
|
| - if (requestId)
|
| - port.postMessage({ command: "callback", requestId: requestId, result: result });
|
| - },
|
| -
|
| - _initExtensions: function()
|
| - {
|
| - this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ResourceAdded,
|
| - WebInspector.workspace, WebInspector.Workspace.Events.UISourceCodeAdded, this._notifyResourceAdded);
|
| - this._registerAutosubscriptionTargetManagerHandler(WebInspector.extensionAPI.Events.NetworkRequestFinished,
|
| - WebInspector.NetworkManager, WebInspector.NetworkManager.Events.RequestFinished, this._notifyRequestFinished);
|
| -
|
| - /**
|
| - * @this {WebInspector.ExtensionServer}
|
| - */
|
| - function onElementsSubscriptionStarted()
|
| - {
|
| - WebInspector.context.addFlavorChangeListener(WebInspector.DOMNode, this._notifyElementsSelectionChanged, this);
|
| - }
|
| -
|
| - /**
|
| - * @this {WebInspector.ExtensionServer}
|
| - */
|
| - function onElementsSubscriptionStopped()
|
| - {
|
| - WebInspector.context.removeFlavorChangeListener(WebInspector.DOMNode, this._notifyElementsSelectionChanged, this);
|
| - }
|
| -
|
| - this._registerSubscriptionHandler(WebInspector.extensionAPI.Events.PanelObjectSelected + "elements",
|
| - onElementsSubscriptionStarted.bind(this), onElementsSubscriptionStopped.bind(this));
|
| - this._registerResourceContentCommittedHandler(this._notifyUISourceCodeContentCommitted);
|
| -
|
| - WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.InspectedURLChanged,
|
| - this._inspectedURLChanged, this);
|
| -
|
| - InspectorExtensionRegistry.getExtensionsAsync();
|
| - },
|
| -
|
| - _notifyResourceAdded: function(event)
|
| - {
|
| - var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
|
| - this._postNotification(WebInspector.extensionAPI.Events.ResourceAdded, this._makeResource(uiSourceCode));
|
| - },
|
| -
|
| - _notifyUISourceCodeContentCommitted: function(event)
|
| - {
|
| - var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data.uiSourceCode);
|
| - var content = /** @type {string} */ (event.data.content);
|
| - this._postNotification(WebInspector.extensionAPI.Events.ResourceContentCommitted, this._makeResource(uiSourceCode), content);
|
| - },
|
| -
|
| - _notifyRequestFinished: function(event)
|
| - {
|
| - var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
|
| - this._postNotification(WebInspector.extensionAPI.Events.NetworkRequestFinished, this._requestId(request), (new WebInspector.HAREntry(request)).build());
|
| - },
|
| -
|
| - _notifyElementsSelectionChanged: function()
|
| - {
|
| - this._postNotification(WebInspector.extensionAPI.Events.PanelObjectSelected + "elements");
|
| - },
|
| + function resolveURLToFrame(url) {
|
| + var found;
|
| + function hasMatchingURL(frame) {
|
| + found = (frame.url === url) ? frame : null;
|
| + return found;
|
| + }
|
| + WebInspector.ResourceTreeModel.frames().some(hasMatchingURL);
|
| + return found;
|
| + }
|
|
|
| - /**
|
| - * @param {!WebInspector.Event} event
|
| - */
|
| - _addExtensions: function(event)
|
| - {
|
| - if (WebInspector.extensionServer._overridePlatformExtensionAPIForTest)
|
| - window.buildPlatformExtensionAPI = WebInspector.extensionServer._overridePlatformExtensionAPIForTest;
|
| -
|
| - var extensionInfos = /** @type {!Array.<!ExtensionDescriptor>} */ (event.data);
|
| - if (this._initializeCommandIssued)
|
| - extensionInfos.forEach(this._addExtension, this);
|
| + if (typeof options === 'object') {
|
| + var frame;
|
| + if (options.frameURL) {
|
| + frame = resolveURLToFrame(options.frameURL);
|
| + } else {
|
| + var target = WebInspector.targetManager.mainTarget();
|
| + var resourceTreeModel = target && WebInspector.ResourceTreeModel.fromTarget(target);
|
| + frame = resourceTreeModel && resourceTreeModel.mainFrame;
|
| + }
|
| + if (!frame) {
|
| + if (options.frameURL)
|
| + console.warn('evaluate: there is no frame with URL ' + options.frameURL);
|
| else
|
| - this._pendingExtensionInfos = extensionInfos;
|
| - },
|
| -
|
| - /**
|
| - * @param {!WebInspector.Event} event
|
| - */
|
| - _setInspectedTabId: function(event)
|
| - {
|
| - this._inspectedTabId = /** @type {string} */ (event.data);
|
| - },
|
| -
|
| - /**
|
| - * @param {!ExtensionDescriptor} extensionInfo
|
| - * @suppressGlobalPropertiesCheck
|
| - */
|
| - _addExtension: function(extensionInfo)
|
| - {
|
| - const urlOriginRegExp = new RegExp("([^:]+:\/\/[^/]*)\/"); // Can't use regexp literal here, MinJS chokes on it.
|
| - var startPage = extensionInfo.startPage;
|
| - var name = extensionInfo.name;
|
| -
|
| - try {
|
| - var originMatch = urlOriginRegExp.exec(startPage);
|
| - if (!originMatch) {
|
| - console.error("Skipping extension with invalid URL: " + startPage);
|
| - return false;
|
| - }
|
| - var extensionOrigin = originMatch[1];
|
| - if (!this._registeredExtensions[extensionOrigin]) {
|
| - // See ExtensionAPI.js for details.
|
| - var injectedAPI = buildExtensionAPIInjectedScript(extensionInfo, this._inspectedTabId, WebInspector.themeSupport.themeName(), WebInspector.extensionServer["_extensionAPITestHook"]);
|
| - InspectorFrontendHost.setInjectedScriptForOrigin(extensionOrigin, injectedAPI);
|
| - this._registeredExtensions[extensionOrigin] = { name: name };
|
| - }
|
| - var iframe = createElement("iframe");
|
| - iframe.src = startPage;
|
| - iframe.style.display = "none";
|
| - document.body.appendChild(iframe); // Only for main window.
|
| - } catch (e) {
|
| - console.error("Failed to initialize extension " + startPage + ":" + e);
|
| - return false;
|
| + console.warn('evaluate: the main frame is not yet available');
|
| + return this._status.E_NOTFOUND(options.frameURL || '<top>');
|
| + }
|
| +
|
| + var contextSecurityOrigin;
|
| + if (options.useContentScriptContext)
|
| + contextSecurityOrigin = securityOrigin;
|
| + else if (options.scriptExecutionContext)
|
| + contextSecurityOrigin = options.scriptExecutionContext;
|
| +
|
| + var context;
|
| + var executionContexts = frame.target().runtimeModel.executionContexts();
|
| + if (contextSecurityOrigin) {
|
| + for (var i = 0; i < executionContexts.length; ++i) {
|
| + var executionContext = executionContexts[i];
|
| + if (executionContext.frameId === frame.id && executionContext.origin === contextSecurityOrigin &&
|
| + !executionContext.isDefault)
|
| + context = executionContext;
|
| }
|
| - return true;
|
| - },
|
| -
|
| - _registerExtension: function(origin, port)
|
| - {
|
| - if (!this._registeredExtensions.hasOwnProperty(origin)) {
|
| - if (origin !== window.location.origin) // Just ignore inspector frames.
|
| - console.error("Ignoring unauthorized client request from " + origin);
|
| - return;
|
| + if (!context) {
|
| + console.warn('The JavaScript context ' + contextSecurityOrigin + ' was not found in the frame ' + frame.url);
|
| + return this._status.E_NOTFOUND(contextSecurityOrigin);
|
| }
|
| - port._extensionOrigin = origin;
|
| - port.addEventListener("message", this._onmessage.bind(this), false);
|
| - port.start();
|
| - },
|
| -
|
| - _onWindowMessage: function(event)
|
| - {
|
| - if (event.data === "registerExtension")
|
| - this._registerExtension(event.origin, event.ports[0]);
|
| - },
|
| -
|
| - _onmessage: function(event)
|
| - {
|
| - var message = event.data;
|
| - var result;
|
| -
|
| - if (message.command in this._handlers)
|
| - result = this._handlers[message.command](message, event.target);
|
| - else
|
| - result = this._status.E_NOTSUPPORTED(message.command);
|
| -
|
| - if (result && message.requestId)
|
| - this._dispatchCallback(message.requestId, event.target, result);
|
| - },
|
| -
|
| - _registerHandler: function(command, callback)
|
| - {
|
| - console.assert(command);
|
| - this._handlers[command] = callback;
|
| - },
|
| -
|
| - _registerSubscriptionHandler: function(eventTopic, onSubscribeFirst, onUnsubscribeLast)
|
| - {
|
| - this._subscriptionStartHandlers[eventTopic] = onSubscribeFirst;
|
| - this._subscriptionStopHandlers[eventTopic] = onUnsubscribeLast;
|
| - },
|
| -
|
| - /**
|
| - * @param {string} eventTopic
|
| - * @param {!Object} eventTarget
|
| - * @param {string} frontendEventType
|
| - * @param {function(!WebInspector.Event)} handler
|
| - */
|
| - _registerAutosubscriptionHandler: function(eventTopic, eventTarget, frontendEventType, handler)
|
| - {
|
| - this._registerSubscriptionHandler(eventTopic,
|
| - eventTarget.addEventListener.bind(eventTarget, frontendEventType, handler, this),
|
| - eventTarget.removeEventListener.bind(eventTarget, frontendEventType, handler, this));
|
| - },
|
| -
|
| - /**
|
| - * @param {string} eventTopic
|
| - * @param {!Function} modelClass
|
| - * @param {string} frontendEventType
|
| - * @param {function(!WebInspector.Event)} handler
|
| - */
|
| - _registerAutosubscriptionTargetManagerHandler: function(eventTopic, modelClass, frontendEventType, handler)
|
| - {
|
| - this._registerSubscriptionHandler(eventTopic,
|
| - WebInspector.targetManager.addModelListener.bind(WebInspector.targetManager, modelClass, frontendEventType, handler, this),
|
| - WebInspector.targetManager.removeModelListener.bind(WebInspector.targetManager, modelClass, frontendEventType, handler, this));
|
| - },
|
| -
|
| - _registerResourceContentCommittedHandler: function(handler)
|
| - {
|
| - /**
|
| - * @this {WebInspector.ExtensionServer}
|
| - */
|
| - function addFirstEventListener()
|
| - {
|
| - WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.WorkingCopyCommittedByUser, handler, this);
|
| - WebInspector.workspace.setHasResourceContentTrackingExtensions(true);
|
| + } else {
|
| + for (var i = 0; i < executionContexts.length; ++i) {
|
| + var executionContext = executionContexts[i];
|
| + if (executionContext.frameId === frame.id && executionContext.isDefault)
|
| + context = executionContext;
|
| }
|
| + if (!context)
|
| + return this._status.E_FAILED(frame.url + ' has no execution context');
|
| + }
|
|
|
| - /**
|
| - * @this {WebInspector.ExtensionServer}
|
| - */
|
| - function removeLastEventListener()
|
| - {
|
| - WebInspector.workspace.setHasResourceContentTrackingExtensions(false);
|
| - WebInspector.workspace.removeEventListener(WebInspector.Workspace.Events.WorkingCopyCommittedByUser, handler, this);
|
| - }
|
| + contextId = context.id;
|
| + }
|
| + var target = target ? target : WebInspector.targetManager.mainTarget();
|
| + if (!target)
|
| + return;
|
|
|
| - this._registerSubscriptionHandler(WebInspector.extensionAPI.Events.ResourceContentCommitted,
|
| - addFirstEventListener.bind(this),
|
| - removeLastEventListener.bind(this));
|
| - },
|
| -
|
| - _expandResourcePath: function(extensionPath, resourcePath)
|
| - {
|
| - if (!resourcePath)
|
| - return;
|
| - return extensionPath + this._normalizePath(resourcePath);
|
| - },
|
| -
|
| - _normalizePath: function(path)
|
| - {
|
| - var source = path.split("/");
|
| - var result = [];
|
| -
|
| - for (var i = 0; i < source.length; ++i) {
|
| - if (source[i] === ".")
|
| - continue;
|
| - // Ignore empty path components resulting from //, as well as a leading and traling slashes.
|
| - if (source[i] === "")
|
| - continue;
|
| - if (source[i] === "..")
|
| - result.pop();
|
| - else
|
| - result.push(source[i]);
|
| - }
|
| - return "/" + result.join("/");
|
| - },
|
| + target.runtimeAgent().evaluate(
|
| + expression, 'extension', exposeCommandLineAPI, true, contextId, returnByValue, false, false, false, onEvalute);
|
|
|
| /**
|
| - * @param {string} expression
|
| - * @param {boolean} exposeCommandLineAPI
|
| - * @param {boolean} returnByValue
|
| - * @param {?Object} options
|
| - * @param {string} securityOrigin
|
| - * @param {function(?string, ?WebInspector.RemoteObject, boolean=)} callback
|
| - * @return {!WebInspector.ExtensionStatus.Record|undefined}
|
| + * @param {?Protocol.Error} error
|
| + * @param {!RuntimeAgent.RemoteObject} result
|
| + * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails
|
| */
|
| - evaluate: function(expression, exposeCommandLineAPI, returnByValue, options, securityOrigin, callback)
|
| - {
|
| - var contextId;
|
| -
|
| - /**
|
| - * @param {string} url
|
| - * @return {boolean}
|
| - */
|
| - function resolveURLToFrame(url)
|
| - {
|
| - var found;
|
| - function hasMatchingURL(frame)
|
| - {
|
| - found = (frame.url === url) ? frame : null;
|
| - return found;
|
| - }
|
| - WebInspector.ResourceTreeModel.frames().some(hasMatchingURL);
|
| - return found;
|
| - }
|
| -
|
| - if (typeof options === "object") {
|
| - var frame;
|
| - if (options.frameURL) {
|
| - frame = resolveURLToFrame(options.frameURL);
|
| - } else {
|
| - var target = WebInspector.targetManager.mainTarget();
|
| - var resourceTreeModel = target && WebInspector.ResourceTreeModel.fromTarget(target);
|
| - frame = resourceTreeModel && resourceTreeModel.mainFrame;
|
| - }
|
| - if (!frame) {
|
| - if (options.frameURL)
|
| - console.warn("evaluate: there is no frame with URL " + options.frameURL);
|
| - else
|
| - console.warn("evaluate: the main frame is not yet available");
|
| - return this._status.E_NOTFOUND(options.frameURL || "<top>");
|
| - }
|
| -
|
| - var contextSecurityOrigin;
|
| - if (options.useContentScriptContext)
|
| - contextSecurityOrigin = securityOrigin;
|
| - else if (options.scriptExecutionContext)
|
| - contextSecurityOrigin = options.scriptExecutionContext;
|
| -
|
| - var context;
|
| - var executionContexts = frame.target().runtimeModel.executionContexts();
|
| - if (contextSecurityOrigin) {
|
| - for (var i = 0; i < executionContexts.length; ++i) {
|
| - var executionContext = executionContexts[i];
|
| - if (executionContext.frameId === frame.id && executionContext.origin === contextSecurityOrigin && !executionContext.isDefault)
|
| - context = executionContext;
|
| -
|
| - }
|
| - if (!context) {
|
| - console.warn("The JavaScript context " + contextSecurityOrigin + " was not found in the frame " + frame.url);
|
| - return this._status.E_NOTFOUND(contextSecurityOrigin);
|
| - }
|
| - } else {
|
| - for (var i = 0; i < executionContexts.length; ++i) {
|
| - var executionContext = executionContexts[i];
|
| - if (executionContext.frameId === frame.id && executionContext.isDefault)
|
| - context = executionContext;
|
| -
|
| - }
|
| - if (!context)
|
| - return this._status.E_FAILED(frame.url + " has no execution context");
|
| - }
|
| -
|
| - contextId = context.id;
|
| - }
|
| - var target = target ? target : WebInspector.targetManager.mainTarget();
|
| - if (!target)
|
| - return;
|
| -
|
| - target.runtimeAgent().evaluate(expression, "extension", exposeCommandLineAPI, true, contextId, returnByValue, false, false, false, onEvalute);
|
| -
|
| - /**
|
| - * @param {?Protocol.Error} error
|
| - * @param {!RuntimeAgent.RemoteObject} result
|
| - * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails
|
| - */
|
| - function onEvalute(error, result, exceptionDetails)
|
| - {
|
| - if (error) {
|
| - callback(error, null, !!exceptionDetails);
|
| - return;
|
| - }
|
| - callback(error, target.runtimeModel.createRemoteObject(result), !!exceptionDetails);
|
| - }
|
| - },
|
| + function onEvalute(error, result, exceptionDetails) {
|
| + if (error) {
|
| + callback(error, null, !!exceptionDetails);
|
| + return;
|
| + }
|
| + callback(error, target.runtimeModel.createRemoteObject(result), !!exceptionDetails);
|
| + }
|
| + }
|
| +};
|
|
|
| - __proto__: WebInspector.Object.prototype
|
| +/** @enum {symbol} */
|
| +WebInspector.ExtensionServer.Events = {
|
| + SidebarPaneAdded: Symbol('SidebarPaneAdded'),
|
| + AuditCategoryAdded: Symbol('AuditCategoryAdded')
|
| };
|
|
|
| /**
|
| - * @constructor
|
| - * @param {string} name
|
| - * @param {string} title
|
| - * @param {!WebInspector.Panel} panel
|
| - * @extends {WebInspector.SimpleView}
|
| + * @unrestricted
|
| */
|
| -WebInspector.ExtensionServerPanelView = function(name, title, panel)
|
| -{
|
| - WebInspector.SimpleView.call(this, title);
|
| +WebInspector.ExtensionServerPanelView = class extends WebInspector.SimpleView {
|
| + /**
|
| + * @param {string} name
|
| + * @param {string} title
|
| + * @param {!WebInspector.Panel} panel
|
| + */
|
| + constructor(name, title, panel) {
|
| + super(title);
|
| this._name = name;
|
| this._panel = panel;
|
| -};
|
| -
|
| -WebInspector.ExtensionServerPanelView.prototype = {
|
| - /**
|
| - * @override
|
| - * @return {string}
|
| - */
|
| - viewId: function()
|
| - {
|
| - return this._name;
|
| - },
|
| -
|
| - /**
|
| - * @override
|
| - * @return {!Promise.<!WebInspector.Widget>}
|
| - */
|
| - widget: function()
|
| - {
|
| - return /** @type {!Promise.<!WebInspector.Widget>} */ (Promise.resolve(this._panel));
|
| - },
|
| -
|
| - __proto__: WebInspector.SimpleView.prototype
|
| + }
|
| +
|
| + /**
|
| + * @override
|
| + * @return {string}
|
| + */
|
| + viewId() {
|
| + return this._name;
|
| + }
|
| +
|
| + /**
|
| + * @override
|
| + * @return {!Promise.<!WebInspector.Widget>}
|
| + */
|
| + widget() {
|
| + return /** @type {!Promise.<!WebInspector.Widget>} */ (Promise.resolve(this._panel));
|
| + }
|
| };
|
|
|
| /**
|
| - * @constructor
|
| + * @unrestricted
|
| */
|
| -WebInspector.ExtensionStatus = function()
|
| -{
|
| +WebInspector.ExtensionStatus = class {
|
| + constructor() {
|
| /**
|
| * @param {string} code
|
| * @param {string} description
|
| * @return {!WebInspector.ExtensionStatus.Record}
|
| */
|
| - function makeStatus(code, description)
|
| - {
|
| - var details = Array.prototype.slice.call(arguments, 2);
|
| - var status = { code: code, description: description, details: details };
|
| - if (code !== "OK") {
|
| - status.isError = true;
|
| - console.log("Extension server error: " + String.vsprintf(description, details));
|
| - }
|
| - return status;
|
| + function makeStatus(code, description) {
|
| + var details = Array.prototype.slice.call(arguments, 2);
|
| + var status = {code: code, description: description, details: details};
|
| + if (code !== 'OK') {
|
| + status.isError = true;
|
| + console.log('Extension server error: ' + String.vsprintf(description, details));
|
| + }
|
| + return status;
|
| }
|
|
|
| - this.OK = makeStatus.bind(null, "OK", "OK");
|
| - this.E_EXISTS = makeStatus.bind(null, "E_EXISTS", "Object already exists: %s");
|
| - this.E_BADARG = makeStatus.bind(null, "E_BADARG", "Invalid argument %s: %s");
|
| - this.E_BADARGTYPE = makeStatus.bind(null, "E_BADARGTYPE", "Invalid type for argument %s: got %s, expected %s");
|
| - this.E_NOTFOUND = makeStatus.bind(null, "E_NOTFOUND", "Object not found: %s");
|
| - this.E_NOTSUPPORTED = makeStatus.bind(null, "E_NOTSUPPORTED", "Object does not support requested operation: %s");
|
| - this.E_PROTOCOLERROR = makeStatus.bind(null, "E_PROTOCOLERROR", "Inspector protocol error: %s");
|
| - this.E_FAILED = makeStatus.bind(null, "E_FAILED", "Operation failed: %s");
|
| + this.OK = makeStatus.bind(null, 'OK', 'OK');
|
| + this.E_EXISTS = makeStatus.bind(null, 'E_EXISTS', 'Object already exists: %s');
|
| + this.E_BADARG = makeStatus.bind(null, 'E_BADARG', 'Invalid argument %s: %s');
|
| + this.E_BADARGTYPE = makeStatus.bind(null, 'E_BADARGTYPE', 'Invalid type for argument %s: got %s, expected %s');
|
| + this.E_NOTFOUND = makeStatus.bind(null, 'E_NOTFOUND', 'Object not found: %s');
|
| + this.E_NOTSUPPORTED = makeStatus.bind(null, 'E_NOTSUPPORTED', 'Object does not support requested operation: %s');
|
| + this.E_PROTOCOLERROR = makeStatus.bind(null, 'E_PROTOCOLERROR', 'Inspector protocol error: %s');
|
| + this.E_FAILED = makeStatus.bind(null, 'E_FAILED', 'Operation failed: %s');
|
| + }
|
| };
|
|
|
| /**
|
|
|