Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(862)

Unified Diff: third_party/WebKit/Source/devtools/front_end/extensions/ExtensionServer.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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');
+ }
};
/**

Powered by Google App Engine
This is Rietveld 408576698