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

Side by Side 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: Modify override dropdown to apply to console completions & transpile 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 apiPrivate.panels.SearchAction = { 43 apiPrivate.panels.SearchAction = {
44 CancelSearch: "cancelSearch", 44 CancelSearch: "cancelSearch",
45 PerformSearch: "performSearch", 45 PerformSearch: "performSearch",
46 NextSearchResult: "nextSearchResult", 46 NextSearchResult: "nextSearchResult",
47 PreviousSearchResult: "previousSearchResult" 47 PreviousSearchResult: "previousSearchResult"
48 }; 48 };
49 49
50 apiPrivate.Events = { 50 apiPrivate.Events = {
51 AuditStarted: "audit-started-", 51 AuditStarted: "audit-started-",
52 ButtonClicked: "button-clicked-", 52 ButtonClicked: "button-clicked-",
53 ContextMenuClicked: "context-menu-clicked-",
53 PanelObjectSelected: "panel-objectSelected-", 54 PanelObjectSelected: "panel-objectSelected-",
54 NetworkRequestFinished: "network-request-finished", 55 NetworkRequestFinished: "network-request-finished",
55 OpenResource: "open-resource", 56 OpenResource: "open-resource",
56 PanelSearch: "panel-search-", 57 PanelSearch: "panel-search-",
57 ResourceAdded: "resource-added", 58 ResourceAdded: "resource-added",
59 ResourceContentEdited: "resource-content-edited",
58 ResourceContentCommitted: "resource-content-committed", 60 ResourceContentCommitted: "resource-content-committed",
61 ResourceLineMessagesChanged: "resource-line-messages-changed",
59 ViewShown: "view-shown-", 62 ViewShown: "view-shown-",
60 ViewHidden: "view-hidden-" 63 ViewHidden: "view-hidden-"
61 }; 64 };
62 65
63 apiPrivate.Commands = { 66 apiPrivate.Commands = {
64 AddAuditCategory: "addAuditCategory", 67 AddAuditCategory: "addAuditCategory",
65 AddAuditResult: "addAuditResult", 68 AddAuditResult: "addAuditResult",
66 AddRequestHeaders: "addRequestHeaders", 69 AddRequestHeaders: "addRequestHeaders",
67 ApplyStyleSheet: "applyStyleSheet", 70 ApplyStyleSheet: "applyStyleSheet",
68 CreatePanel: "createPanel", 71 CreatePanel: "createPanel",
69 CreateSidebarPane: "createSidebarPane", 72 CreateSidebarPane: "createSidebarPane",
70 CreateToolbarButton: "createToolbarButton", 73 CreateToolbarButton: "createToolbarButton",
74 DisplaySearchResults: "displaySearchResults",
71 EvaluateOnInspectedPage: "evaluateOnInspectedPage", 75 EvaluateOnInspectedPage: "evaluateOnInspectedPage",
72 ForwardKeyboardEvent: "_forwardKeyboardEvent", 76 ForwardKeyboardEvent: "_forwardKeyboardEvent",
73 GetHAR: "getHAR", 77 GetHAR: "getHAR",
74 GetPageResources: "getPageResources", 78 GetPageResources: "getPageResources",
75 GetRequestContent: "getRequestContent", 79 GetRequestContent: "getRequestContent",
76 GetResourceContent: "getResourceContent", 80 GetResourceContent: "getResourceContent",
81 GetResourceLineMessages: "getResourceLineMessages",
77 InspectedURLChanged: "inspectedURLChanged", 82 InspectedURLChanged: "inspectedURLChanged",
78 OpenResource: "openResource", 83 OpenResource: "openResource",
84 RegisterLanguageService: "registerLanguageService",
85 RegisterMimeRecognizer: "registerMimeRecognizer",
79 Reload: "Reload", 86 Reload: "Reload",
80 Subscribe: "subscribe", 87 Subscribe: "subscribe",
81 SetOpenResourceHandler: "setOpenResourceHandler", 88 SetOpenResourceHandler: "setOpenResourceHandler",
82 SetResourceContent: "setResourceContent", 89 SetResourceContent: "setResourceContent",
90 SetResourceLineMessages: "setResourceLineMessages",
83 SetSidebarContent: "setSidebarContent", 91 SetSidebarContent: "setSidebarContent",
84 SetSidebarHeight: "setSidebarHeight", 92 SetSidebarHeight: "setSidebarHeight",
85 SetSidebarPage: "setSidebarPage", 93 SetSidebarPage: "setSidebarPage",
86 ShowPanel: "showPanel", 94 ShowPanel: "showPanel",
87 StopAuditCategoryRun: "stopAuditCategoryRun", 95 StopAuditCategoryRun: "stopAuditCategoryRun",
88 Unsubscribe: "unsubscribe", 96 Unsubscribe: "unsubscribe",
89 UpdateAuditProgress: "updateAuditProgress", 97 UpdateAuditProgress: "updateAuditProgress",
90 UpdateButton: "updateButton" 98 UpdateButton: "updateButton"
91 }; 99 };
92 } 100 }
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 177
170 /** 178 /**
171 * @constructor 179 * @constructor
172 */ 180 */
173 function InspectorExtensionAPI() 181 function InspectorExtensionAPI()
174 { 182 {
175 this.audits = new Audits(); 183 this.audits = new Audits();
176 this.inspectedWindow = new InspectedWindow(); 184 this.inspectedWindow = new InspectedWindow();
177 this.panels = new Panels(); 185 this.panels = new Panels();
178 this.network = new Network(); 186 this.network = new Network();
187 this.language = new Language();
179 defineDeprecatedProperty(this, "webInspector", "resources", "network"); 188 defineDeprecatedProperty(this, "webInspector", "resources", "network");
180 } 189 }
181 190
182 /** 191 /**
192 * @interface
193 */
194 function ServiceProvider(){}
195 ServiceProvider.prototype = {
196 /**
197 * @param {string} text
198 * @param {{source: string, line: number, column: number}=} location
199 * @return {!Promise<string>}
200 */
201 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.
202 /**
203 * @param {{source: string, line: number, column: number}} location
204 * @return {!Promise<!Array<{text: string, callback: function(), category: ( string|undefined)}>>}
205 */
206 populateContextMenu: function(location){ return Promise.reject(); },
207
208 /**
209 * @param {{source: string, line: number, column: number}} location
210 * @param {string} prefix
211 * @return {!Promise<!Array<{text: string, icon: (string|undefined), details : function(): !Promise<{detail: string, description: string}>}>>}
212 */
213 completions: function(location, prefix) { return Promise.reject(); },
214
215 /**
216 * @param {string} content
217 * @param {{line: number, column: number}} cursor
218 * @param {string=} prefix
219 * @param {{source: string, line: number, column: number}=} context
220 * @return {!Promise<!Array<{text: string, icon: (string|undefined), details : function(): !Promise<{detail: string, description: string}>}>>}
221 */
222 debuggerCompletions: function(content, cursor, prefix, context) { return Pro mise.reject(); }
223 }
224
225 /**
226 * @constructor
227 */
228 function Language() {
229 }
230 Language.prototype = {
231 /**
232 * @param {string} match
233 * @param {string} mime
234 * @param {boolean=} matchName
235 */
236 registerMimeRecognizer: function(match, mime, matchName) {
237 extensionServer.sendRequest({command: commands.RegisterMimeRecognizer, m atch: match, mime: mime, matchName: matchName});
238 },
239
240 /**
241 * @param {string} name
242 * @param {!Array<string>} mimes
243 * @param {!ServiceProvider} service
244 * @param {?=} simplemode
245 */
246 register: function(name, mimes, service, simplemode) {
247 var capabilities = Object.keys(service);
248 if (Object.getPrototypeOf(service) !== Object.getPrototypeOf({})) { //ha ndle classes
249 var serviceWalker = service;
250 while ((serviceWalker = Object.getPrototypeOf(serviceWalker)) && ser viceWalker !== Object.getPrototypeOf({})) {
251 capabilities = capabilities.concat(Object.getOwnPropertyNames(se rviceWalker));
252 }
253 }
254 capabilities = Array.from(/** @type {!Iterator<string>} */(new Set(capab ilities.filter(f => (f !== "constructor") && (typeof service[f] === "function")) )));
255
256 extensionServer.sendRequest({
257 command: commands.RegisterLanguageService,
258 name: name,
259 mimes: mimes,
260 capabilities: capabilities,
261 simplemode: simplemode
262 });
263
264 extensionServer.registerHandler("transpile-"+name, function(request) {
265 if (!service.transpile) {
266 return extensionServer.sendRequest({command: "callback", request Id: request.requestId, result: request.input});
267 }
268 service.transpile(request.input, request.location).then(function(tra nspiled) {
269 extensionServer.sendRequest({command: "callback", requestId: req uest.requestId, result: transpiled});
270 })
271 .catch(function(err) {
272 extensionServer.sendRequest({command: "callback", requestId: req uest.requestId});
273 console.error(err);
274 });
275 });
276
277 extensionServer.registerHandler("populateContextMenu-"+name, function(re quest) {
278 if (!service.populateContextMenu) {
279 return extensionServer.sendRequest({command: "callback", request Id: request.requestId});
280 }
281 var eventName ="notify-"+apiPrivate.Events.ContextMenuClicked;
282 service.populateContextMenu(request.location).then(function(options) {
283 var opts = options.map(function(item, i) { return {text: item.te xt, id: i, category: item.category} });
284 extensionServer.sendRequest({command: "callback", requestId: req uest.requestId, result: opts});
285
286 if (extensionServer.hasHandler(eventName)) {
287 extensionServer.unregisterHandler(eventName);
288 }
289 extensionServer.registerHandler(eventName, handleClick);
290
291 function handleClick(event) {
292 extensionServer.unregisterHandler(eventName);
293 if (options[event.id] && options[event.id].callback) {
294 options[event.id].callback();
295 }
296 }
297 })
298 .catch(function(err) {
299 extensionServer.sendRequest({command: "callback", requestId: req uest.requestId});
300 console.error(err);
301 });
302 });
303
304 function handleCompletionsResponse(request) {
305 var commandName = "completionDetails-"+name;
306 return function(completions) {
307 var comps = completions.map(function(item, i) { return {text: it em.text, icon: item.icon, id: i} });
308
309 extensionServer.sendRequest({command: "callback", requestId: req uest.requestId, result: comps});
310
311 if (extensionServer.hasHandler(commandName)) {
312 extensionServer.unregisterHandler(commandName);
313 }
314 extensionServer.registerHandler(commandName, handlerHover);
315
316 function handlerHover(event) {
317 if (completions[event.id] && completions[event.id].details) {
318 completions[event.id].details().then(function(details) {
319 extensionServer.sendRequest({command: "callback", re questId: event.requestId, result: details});
320 }).catch(function(err) {
321 extensionServer.sendRequest({command: "callback", re questId: event.requestId});
322 console.error(err);
323 });
324 } else {
325 extensionServer.sendRequest({command: "callback", reques tId: event.requestId});
326 }
327 }
328 }
329 }
330
331 extensionServer.registerHandler("completions-"+name, function(request) {
332 if (!service.completions) {
333 return extensionServer.sendRequest({command: "callback", request Id: request.requestId});
334 }
335 service.completions(request.location, request.prefix)
336 .then(handleCompletionsResponse(request))
337 .catch(function(err) {
338 extensionServer.sendRequest({command: "callback", requestId: req uest.requestId});
339 console.error(err);
340 });
341 });
342
343 extensionServer.registerHandler("debuggerCompletions-"+name, function(re quest) {
344 if (!service.debuggerCompletions) {
345 return extensionServer.sendRequest({command: "callback", request Id: request.requestId});
346 }
347 service.debuggerCompletions(request.content, request.cursor, request .prefix, request.context)
348 .then(handleCompletionsResponse(request))
349 .catch(function(err) {
350 extensionServer.sendRequest({command: "callback", requestId: req uest.requestId});
351 console.error(err);
352 });
353 });
354 }
355 }
356
357 /**
183 * @constructor 358 * @constructor
184 */ 359 */
185 function Network() 360 function Network()
186 { 361 {
187 /** 362 /**
188 * @this {EventSinkImpl} 363 * @this {EventSinkImpl}
189 */ 364 */
190 function dispatchRequestEvent(message) 365 function dispatchRequestEvent(message)
191 { 366 {
192 var request = message.arguments[1]; 367 var request = message.arguments[1];
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 /** 595 /**
421 * @constructor 596 * @constructor
422 * @extends {PanelWithSidebar} 597 * @extends {PanelWithSidebar}
423 */ 598 */
424 function SourcesPanel() 599 function SourcesPanel()
425 { 600 {
426 PanelWithSidebar.call(this, "sources"); 601 PanelWithSidebar.call(this, "sources");
427 } 602 }
428 603
429 SourcesPanel.prototype = { 604 SourcesPanel.prototype = {
605 displaySearchResults: function(results) {
606 extensionServer.sendRequest({command: commands.DisplaySearchResults, res ults: results});
607 },
430 __proto__: PanelWithSidebar.prototype 608 __proto__: PanelWithSidebar.prototype
431 } 609 }
432 610
433 /** 611 /**
434 * @constructor 612 * @constructor
435 * @extends {ExtensionViewImpl} 613 * @extends {ExtensionViewImpl}
436 */ 614 */
437 function ExtensionPanelImpl(id) 615 function ExtensionPanelImpl(id)
438 { 616 {
439 ExtensionViewImpl.call(this, id); 617 ExtensionViewImpl.call(this, id);
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 } 877 }
700 878
701 /** 879 /**
702 * @this {EventSinkImpl} 880 * @this {EventSinkImpl}
703 */ 881 */
704 function dispatchResourceContentEvent(message) 882 function dispatchResourceContentEvent(message)
705 { 883 {
706 this._fire(new Resource(message.arguments[0]), message.arguments[1]); 884 this._fire(new Resource(message.arguments[0]), message.arguments[1]);
707 } 885 }
708 886
887 /**
888 * @this {EventSinkImpl}
889 */
890 function dispatchResourceEditEvent(message)
891 {
892 this._fire(new Resource(message.arguments[0]), message.arguments[1], mes sage.arguments[2]);
893 }
894
895 /**
896 * @this {EventSinkImpl}
897 */
898 function dispatchResourceLineMessagesChanged(message) {
899 this._fire(new Resource(message.arguments[0]), message.arguments[1]);
900 }
901
709 this.onResourceAdded = new EventSink(events.ResourceAdded, dispatchResourceE vent); 902 this.onResourceAdded = new EventSink(events.ResourceAdded, dispatchResourceE vent);
710 this.onResourceContentCommitted = new EventSink(events.ResourceContentCommit ted, dispatchResourceContentEvent); 903 this.onResourceContentCommitted = new EventSink(events.ResourceContentCommit ted, dispatchResourceContentEvent);
904 this.onResourceContentEdited = new EventSink(events.ResourceContentEdited, d ispatchResourceEditEvent);
905 this.onResourceLineMessagesChanged = new EventSink(events.ResourceLineMessag esChanged, dispatchResourceLineMessagesChanged);
711 } 906 }
712 907
713 InspectedWindow.prototype = { 908 InspectedWindow.prototype = {
714 reload: function(optionsOrUserAgent) 909 reload: function(optionsOrUserAgent)
715 { 910 {
716 var options = null; 911 var options = null;
717 if (typeof optionsOrUserAgent === "object") { 912 if (typeof optionsOrUserAgent === "object") {
718 options = optionsOrUserAgent; 913 options = optionsOrUserAgent;
719 } else if (typeof optionsOrUserAgent === "string") { 914 } else if (typeof optionsOrUserAgent === "string") {
720 options = { userAgent: optionsOrUserAgent }; 915 options = { userAgent: optionsOrUserAgent };
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 { 982 {
788 callback(response.content, response.encoding); 983 callback(response.content, response.encoding);
789 } 984 }
790 985
791 extensionServer.sendRequest({ command: commands.GetResourceContent, url: this._url }, callback && callbackWrapper); 986 extensionServer.sendRequest({ command: commands.GetResourceContent, url: this._url }, callback && callbackWrapper);
792 }, 987 },
793 988
794 setContent: function(content, commit, callback) 989 setContent: function(content, commit, callback)
795 { 990 {
796 extensionServer.sendRequest({ command: commands.SetResourceContent, url: this._url, content: content, commit: commit }, callback); 991 extensionServer.sendRequest({ command: commands.SetResourceContent, url: this._url, content: content, commit: commit }, callback);
992 },
993
994 getLineMessages: function(callback) {
995 extensionServer.sendRequest({ command: commands.GetResourceLineMessages, url: this._url }, callback);
996 },
997
998 setLineMessages: function(messages, callback) {
999 extensionServer.sendRequest({ command: commands.SetResourceLineMessages, url: this._url, messages: messages }, callback);
797 } 1000 }
798 } 1001 }
799 1002
800 var keyboardEventRequestQueue = []; 1003 var keyboardEventRequestQueue = [];
801 var forwardTimer = null; 1004 var forwardTimer = null;
802 1005
803 function forwardKeyboardEvent(event) 1006 function forwardKeyboardEvent(event)
804 { 1007 {
805 const Esc = "U+001B"; 1008 const Esc = "U+001B";
806 // We only care about global hotkeys, not about random text 1009 // We only care about global hotkeys, not about random text
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 // extensions) 1162 // extensions)
960 var devtools_descriptor = Object.getOwnPropertyDescriptor(chrome, "devtools" ); 1163 var devtools_descriptor = Object.getOwnPropertyDescriptor(chrome, "devtools" );
961 if (!devtools_descriptor || devtools_descriptor.get) 1164 if (!devtools_descriptor || devtools_descriptor.get)
962 Object.defineProperty(chrome, "devtools", { value: {}, enumerable: true }); 1165 Object.defineProperty(chrome, "devtools", { value: {}, enumerable: true });
963 // Only expose tabId on chrome.devtools.inspectedWindow, not webInspector.in spectedWindow. 1166 // Only expose tabId on chrome.devtools.inspectedWindow, not webInspector.in spectedWindow.
964 chrome.devtools.inspectedWindow = {}; 1167 chrome.devtools.inspectedWindow = {};
965 chrome.devtools.inspectedWindow.__defineGetter__("tabId", getTabId); 1168 chrome.devtools.inspectedWindow.__defineGetter__("tabId", getTabId);
966 chrome.devtools.inspectedWindow.__proto__ = coreAPI.inspectedWindow; 1169 chrome.devtools.inspectedWindow.__proto__ = coreAPI.inspectedWindow;
967 chrome.devtools.network = coreAPI.network; 1170 chrome.devtools.network = coreAPI.network;
968 chrome.devtools.panels = coreAPI.panels; 1171 chrome.devtools.panels = coreAPI.panels;
1172 chrome.devtools.language = coreAPI.language;
969 1173
970 // default to expose experimental APIs for now. 1174 // default to expose experimental APIs for now.
971 if (extensionInfo.exposeExperimentalAPIs !== false) { 1175 if (extensionInfo.exposeExperimentalAPIs !== false) {
972 chrome.experimental = chrome.experimental || {}; 1176 chrome.experimental = chrome.experimental || {};
973 chrome.experimental.devtools = chrome.experimental.devtools || {}; 1177 chrome.experimental.devtools = chrome.experimental.devtools || {};
974 1178
975 var properties = Object.getOwnPropertyNames(coreAPI); 1179 var properties = Object.getOwnPropertyNames(coreAPI);
976 for (var i = 0; i < properties.length; ++i) { 1180 for (var i = 0; i < properties.length; ++i) {
977 var descriptor = Object.getOwnPropertyDescriptor(coreAPI, properties [i]); 1181 var descriptor = Object.getOwnPropertyDescriptor(coreAPI, properties [i]);
978 Object.defineProperty(chrome.experimental.devtools, properties[i], d escriptor); 1182 Object.defineProperty(chrome.experimental.devtools, properties[i], d escriptor);
(...skipping 25 matching lines...) Expand all
1004 { 1208 {
1005 return "(function(injectedScriptId){ " + 1209 return "(function(injectedScriptId){ " +
1006 "var extensionServer;" + 1210 "var extensionServer;" +
1007 defineCommonExtensionSymbols.toString() + ";" + 1211 defineCommonExtensionSymbols.toString() + ";" +
1008 injectedExtensionAPI.toString() + ";" + 1212 injectedExtensionAPI.toString() + ";" +
1009 buildPlatformExtensionAPI(extensionInfo, inspectedTabId) + ";" + 1213 buildPlatformExtensionAPI(extensionInfo, inspectedTabId) + ";" +
1010 "platformExtensionAPI(injectedExtensionAPI(injectedScriptId));" + 1214 "platformExtensionAPI(injectedExtensionAPI(injectedScriptId));" +
1011 "return {};" + 1215 "return {};" +
1012 "})"; 1216 "})";
1013 } 1217 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698