Chromium Code Reviews| 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) { |