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

Unified Diff: Source/devtools/front_end/extensions/ExtensionAPI.js

Issue 1264133002: Devtools: [WIP] Implement enhanced devtools extension language APIs Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Small cleanups - prefer URIs to contentURLs, revert protocol unifications, remove lambdas Created 5 years, 4 months 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
« no previous file with comments | « Source/devtools/front_end/es6.js ('k') | Source/devtools/front_end/extensions/ExtensionServer.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/devtools/front_end/extensions/ExtensionAPI.js
diff --git a/Source/devtools/front_end/extensions/ExtensionAPI.js b/Source/devtools/front_end/extensions/ExtensionAPI.js
index 9eb5179f1a4556952a491fe500344287bc9d3499..46fb9cd94d066e8f80f50e5fa316175dc32d77b6 100644
--- a/Source/devtools/front_end/extensions/ExtensionAPI.js
+++ b/Source/devtools/front_end/extensions/ExtensionAPI.js
@@ -50,11 +50,13 @@ function defineCommonExtensionSymbols(apiPrivate)
apiPrivate.Events = {
AuditStarted: "audit-started-",
ButtonClicked: "button-clicked-",
+ ContextMenuClicked: "context-menu-clicked-",
PanelObjectSelected: "panel-objectSelected-",
NetworkRequestFinished: "network-request-finished",
OpenResource: "open-resource",
PanelSearch: "panel-search-",
ResourceAdded: "resource-added",
+ ResourceContentEdited: "resource-content-edited",
ResourceContentCommitted: "resource-content-committed",
ViewShown: "view-shown-",
ViewHidden: "view-hidden-"
@@ -68,6 +70,7 @@ function defineCommonExtensionSymbols(apiPrivate)
CreatePanel: "createPanel",
CreateSidebarPane: "createSidebarPane",
CreateToolbarButton: "createToolbarButton",
+ DisplaySearchResults: "displaySearchResults",
EvaluateOnInspectedPage: "evaluateOnInspectedPage",
ForwardKeyboardEvent: "_forwardKeyboardEvent",
GetHAR: "getHAR",
@@ -75,11 +78,14 @@ function defineCommonExtensionSymbols(apiPrivate)
GetRequestContent: "getRequestContent",
GetResourceContent: "getResourceContent",
InspectedURLChanged: "inspectedURLChanged",
+ NewMimeType: "newMimeType",
OpenResource: "openResource",
+ RegisterLanguageService: "registerLanguageService",
Reload: "Reload",
Subscribe: "subscribe",
SetOpenResourceHandler: "setOpenResourceHandler",
SetResourceContent: "setResourceContent",
+ SetResourceLineMessages: "setResourceLineMessages",
SetSidebarContent: "setSidebarContent",
SetSidebarHeight: "setSidebarHeight",
SetSidebarPage: "setSidebarPage",
@@ -176,10 +182,177 @@ function InspectorExtensionAPI()
this.inspectedWindow = new InspectedWindow();
this.panels = new Panels();
this.network = new Network();
+ this.language = new Language();
defineDeprecatedProperty(this, "webInspector", "resources", "network");
}
/**
+ * @interface
+ */
+function ServiceProvider(){}
+ServiceProvider.prototype = {
+ /**
+ * @param {string} text
+ * @param {{source: string, line: number, column: number}=} location
+ * @return {!Promise<string>}
+ */
+ transpile: function(text, location){ return Promise.reject(); },
+ /**
+ * @param {{source: string, line: number, column: number}} location
+ * @return {!Promise<!Array<{text: string, callback: function(), category: (string|undefined)}>>}
+ */
+ populateContextMenu: function(location){ return Promise.reject(); },
+
+ /**
+ * @param {{source: string, line: number, column: number}} location
+ * @param {string} prefix
+ * @return {!Promise<!Array<{text: string, icon: (string|undefined), details: function(): !Promise<{detail: string, description: string}>}>>}
+ */
+ completions: function(location, prefix) { return Promise.reject(); },
+
+ /**
+ * @param {string} content
+ * @param {{line: number, column: number}} cursor
+ * @param {string=} prefix
+ * @param {{source: string, line: number, column: number}=} context
+ * @return {!Promise<!Array<{text: string, icon: (string|undefined), details: function(): !Promise<{detail: string, description: string}>}>>}
+ */
+ debuggerCompletions: function(content, cursor, prefix, context) { return Promise.reject(); }
+}
+
+/**
+ * @constructor
+ */
+function Language() {
+}
+Language.prototype = {
+ /**
+ * @param {string} extensionOrName
+ * @param {string} mime
+ * @param {boolean=} byName
+ */
+ newMimeType: function(extensionOrName, mime, byName) {
+ extensionServer.sendRequest({command: commands.NewMimeType, extensionOrName: extensionOrName, mime: mime, byName: byName});
+ },
+
+ /**
+ * @param {string} name
+ * @param {!Array<string>} mimes
+ * @param {!ServiceProvider} service
+ * @param {?=} simplemode
+ */
+ register: function(name, mimes, service, simplemode) {
+ var capabilities = Object.keys(service);
+ if (Object.getPrototypeOf(service) !== Object.getPrototypeOf({})) { //handle classes
+ var serviceWalker = service;
+ while ((serviceWalker = Object.getPrototypeOf(serviceWalker)) && serviceWalker !== Object.getPrototypeOf({})) {
+ capabilities = capabilities.concat(Object.getOwnPropertyNames(serviceWalker));
+ }
+ }
+ capabilities = Array.from(/** @type {!Iterator<string>} */(new Set(capabilities.filter(f => (f !== "constructor") && (typeof service[f] === "function")))));
+
+ extensionServer.sendRequest({
+ command: commands.RegisterLanguageService,
+ name: name,
+ mimes: mimes,
+ capabilities: capabilities,
+ simplemode: simplemode
+ });
+
+ extensionServer.registerHandler("transpile-"+name, function(request) {
+ if (!service.transpile) {
+ return extensionServer.sendRequest({command: "callback", requestId: request.requestId, result: request.input});
+ }
+ service.transpile(request.input, request.location).then(function(transpiled) {
+ extensionServer.sendRequest({command: "callback", requestId: request.requestId, result: transpiled});
+ })
+ .catch(function(err) {
+ extensionServer.sendRequest({command: "callback", requestId: request.requestId});
+ console.error(err);
+ });
+ });
+
+ extensionServer.registerHandler("populateContextMenu-"+name, function(request) {
+ if (!service.populateContextMenu) {
+ return extensionServer.sendRequest({command: "callback", requestId: request.requestId});
+ }
+ var eventName ="notify-"+apiPrivate.Events.ContextMenuClicked;
+ service.populateContextMenu(request.location).then(function(options) {
+ var opts = options.map(function(item, i) { return {text: item.text, id: i, category: item.category} });
+ extensionServer.sendRequest({command: "callback", requestId: request.requestId, result: opts});
+
+ if (extensionServer.hasHandler(eventName)) {
+ extensionServer.unregisterHandler(eventName);
+ }
+ extensionServer.registerHandler(eventName, handleClick);
+
+ function handleClick(event) {
+ extensionServer.unregisterHandler(eventName);
+ if (options[event.id] && options[event.id].callback) {
+ options[event.id].callback();
+ }
+ }
+ })
+ .catch(function(err) {
+ extensionServer.sendRequest({command: "callback", requestId: request.requestId});
+ console.error(err);
+ });
+ });
+
+ function handleCompletionsResponse(request) {
+ var commandName = "completionDetails-"+name;
+ return function(completions) {
+ var comps = completions.map(function(item, i) { return {text: item.text, icon: item.icon, id: i} });
+
+ extensionServer.sendRequest({command: "callback", requestId: request.requestId, result: comps});
+
+ if (extensionServer.hasHandler(commandName)) {
+ extensionServer.unregisterHandler(commandName);
+ }
+ extensionServer.registerHandler(commandName, handlerHover);
+
+ function handlerHover(event) {
+ if (completions[event.id] && completions[event.id].details) {
+ completions[event.id].details().then(function(details) {
+ extensionServer.sendRequest({command: "callback", requestId: event.requestId, result: details});
+ }).catch(function(err) {
+ extensionServer.sendRequest({command: "callback", requestId: event.requestId});
+ console.error(err);
+ });
+ } else {
+ extensionServer.sendRequest({command: "callback", requestId: event.requestId});
+ }
+ }
+ }
+ }
+
+ extensionServer.registerHandler("completions-"+name, function(request) {
+ if (!service.completions) {
+ return extensionServer.sendRequest({command: "callback", requestId: request.requestId});
+ }
+ service.completions(request.location, request.prefix)
+ .then(handleCompletionsResponse(request))
+ .catch(function(err) {
+ extensionServer.sendRequest({command: "callback", requestId: request.requestId});
+ console.error(err);
+ });
+ });
+
+ extensionServer.registerHandler("debuggerCompletions-"+name, function(request) {
+ if (!service.debuggerCompletions) {
+ return extensionServer.sendRequest({command: "callback", requestId: request.requestId});
+ }
+ service.debuggerCompletions(request.content, request.cursor, request.prefix, request.context)
+ .then(handleCompletionsResponse(request))
+ .catch(function(err) {
+ extensionServer.sendRequest({command: "callback", requestId: request.requestId});
+ console.error(err);
+ });
+ });
+ }
+}
+
+/**
* @constructor
*/
function Network()
@@ -427,6 +600,9 @@ function SourcesPanel()
}
SourcesPanel.prototype = {
+ displaySearchResults: function(results) {
+ extensionServer.sendRequest({command: commands.DisplaySearchResults, results: results});
+ },
__proto__: PanelWithSidebar.prototype
}
@@ -706,8 +882,17 @@ function InspectedWindow()
this._fire(new Resource(message.arguments[0]), message.arguments[1]);
}
+ /**
+ * @this {EventSinkImpl}
+ */
+ function dispatchResourceEditEvent(message)
+ {
+ this._fire(new Resource(message.arguments[0]), message.arguments[1], message.arguments[2]);
+ }
+
this.onResourceAdded = new EventSink(events.ResourceAdded, dispatchResourceEvent);
this.onResourceContentCommitted = new EventSink(events.ResourceContentCommitted, dispatchResourceContentEvent);
+ this.onResourceContentEdited = new EventSink(events.ResourceContentEdited, dispatchResourceEditEvent);
}
InspectedWindow.prototype = {
@@ -794,6 +979,10 @@ ResourceImpl.prototype = {
setContent: function(content, commit, callback)
{
extensionServer.sendRequest({ command: commands.SetResourceContent, url: this._url, content: content, commit: commit }, callback);
+ },
+
+ setLineMessages: function(messages, callback) {
+ extensionServer.sendRequest({ command: commands.SetResourceLineMessages, url: this._url, messages: messages }, callback);
}
}
@@ -966,6 +1155,7 @@ function platformExtensionAPI(coreAPI)
chrome.devtools.inspectedWindow.__proto__ = coreAPI.inspectedWindow;
chrome.devtools.network = coreAPI.network;
chrome.devtools.panels = coreAPI.panels;
+ chrome.devtools.language = coreAPI.language;
// default to expose experimental APIs for now.
if (extensionInfo.exposeExperimentalAPIs !== false) {
« no previous file with comments | « Source/devtools/front_end/es6.js ('k') | Source/devtools/front_end/extensions/ExtensionServer.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698