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..d9938d9e0279a34c49e10b1250f1e3a88444718e 100644 |
--- a/Source/devtools/front_end/extensions/ExtensionAPI.js |
+++ b/Source/devtools/front_end/extensions/ExtensionAPI.js |
@@ -50,12 +50,15 @@ 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", |
+ ResourceLineMessagesChanged: "resource-line-messages-changed", |
ViewShown: "view-shown-", |
ViewHidden: "view-hidden-" |
}; |
@@ -68,18 +71,23 @@ function defineCommonExtensionSymbols(apiPrivate) |
CreatePanel: "createPanel", |
CreateSidebarPane: "createSidebarPane", |
CreateToolbarButton: "createToolbarButton", |
+ DisplaySearchResults: "displaySearchResults", |
EvaluateOnInspectedPage: "evaluateOnInspectedPage", |
ForwardKeyboardEvent: "_forwardKeyboardEvent", |
GetHAR: "getHAR", |
GetPageResources: "getPageResources", |
GetRequestContent: "getRequestContent", |
GetResourceContent: "getResourceContent", |
+ GetResourceLineMessages: "getResourceLineMessages", |
InspectedURLChanged: "inspectedURLChanged", |
OpenResource: "openResource", |
+ RegisterLanguageService: "registerLanguageService", |
+ RegisterMimeRecognizer: "registerMimeRecognizer", |
Reload: "Reload", |
Subscribe: "subscribe", |
SetOpenResourceHandler: "setOpenResourceHandler", |
SetResourceContent: "setResourceContent", |
+ SetResourceLineMessages: "setResourceLineMessages", |
SetSidebarContent: "setSidebarContent", |
SetSidebarHeight: "setSidebarHeight", |
SetSidebarPage: "setSidebarPage", |
@@ -176,10 +184,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(); }, |
pfeldman
2015/08/13 21:15:46
We are using callbacks to be consistent with chrom
wes
2015/08/14 00:55:05
Are we? Before this patch there were absolutely no
pfeldman
2015/08/17 21:15:51
Ok, I misunderstood its purpose then.
|
+ /** |
+ * @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} match |
+ * @param {string} mime |
+ * @param {boolean=} matchName |
+ */ |
+ registerMimeRecognizer: function(match, mime, matchName) { |
+ extensionServer.sendRequest({command: commands.RegisterMimeRecognizer, match: match, mime: mime, matchName: matchName}); |
+ }, |
+ |
+ /** |
+ * @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 +602,9 @@ function SourcesPanel() |
} |
SourcesPanel.prototype = { |
+ displaySearchResults: function(results) { |
+ extensionServer.sendRequest({command: commands.DisplaySearchResults, results: results}); |
+ }, |
__proto__: PanelWithSidebar.prototype |
} |
@@ -706,8 +884,25 @@ 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 {EventSinkImpl} |
+ */ |
+ function dispatchResourceLineMessagesChanged(message) { |
+ this._fire(new Resource(message.arguments[0]), message.arguments[1]); |
+ } |
+ |
this.onResourceAdded = new EventSink(events.ResourceAdded, dispatchResourceEvent); |
this.onResourceContentCommitted = new EventSink(events.ResourceContentCommitted, dispatchResourceContentEvent); |
+ this.onResourceContentEdited = new EventSink(events.ResourceContentEdited, dispatchResourceEditEvent); |
+ this.onResourceLineMessagesChanged = new EventSink(events.ResourceLineMessagesChanged, dispatchResourceLineMessagesChanged); |
} |
InspectedWindow.prototype = { |
@@ -794,6 +989,14 @@ ResourceImpl.prototype = { |
setContent: function(content, commit, callback) |
{ |
extensionServer.sendRequest({ command: commands.SetResourceContent, url: this._url, content: content, commit: commit }, callback); |
+ }, |
+ |
+ getLineMessages: function(callback) { |
+ extensionServer.sendRequest({ command: commands.GetResourceLineMessages, url: this._url }, callback); |
+ }, |
+ |
+ setLineMessages: function(messages, callback) { |
+ extensionServer.sendRequest({ command: commands.SetResourceLineMessages, url: this._url, messages: messages }, callback); |
} |
} |
@@ -966,6 +1169,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) { |