1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 // DevToolsAPI ----------------------------------------------------------------
12 function DevToolsAPIImpl()
20 * @type {!Object.<number, function(?Object)>}
25 DevToolsAPIImpl.prototype = {
28 * @param {?Object} arg
30 embedderMessageAck: function(id, arg)
32 var callback = this._callbacks[id];
33 delete this._callbacks[id];
39 * @param {string} method
40 * @param {!Array.<*>} args
41 * @param {?function(?Object)} callback
43 sendMessageToEmbedder: function(method, args, callback)
45 var callId = ++this._lastCallId;
47 this._callbacks[callId] = callback;
48 var message = { "id": callId, "method": method };
50 message.params = args;
51 DevToolsHost.sendMessageToEmbedder(JSON.stringify(message));
55 * @param {string} method
56 * @param {!Array.<*>} args
58 _dispatchOnInspectorFrontendAPI: function(method, args)
60 var api = window["InspectorFrontendAPI"];
61 api[method].apply(api, args);
64 // API methods below this line --------------------------------------------
67 * @param {!Array.<!ExtensionDescriptor>} extensions
69 addExtensions: function(extensions)
71 // Support for legacy front-ends (<M41).
72 if (window["WebInspector"].addExtensions)
73 window["WebInspector"].addExtensions(extensions);
75 this._dispatchOnInspectorFrontendAPI("addExtensions", [extensions]);
81 appendedToURL: function(url)
83 this._dispatchOnInspectorFrontendAPI("appendedToURL", [url]);
89 canceledSaveURL: function(url)
91 this._dispatchOnInspectorFrontendAPI("canceledSaveURL", [url]);
94 contextMenuCleared: function()
96 this._dispatchOnInspectorFrontendAPI("contextMenuCleared", []);
102 contextMenuItemSelected: function(id)
104 this._dispatchOnInspectorFrontendAPI("contextMenuItemSelected", [id]);
108 * @param {number} count
110 deviceCountUpdated: function(count)
112 this._dispatchOnInspectorFrontendAPI("deviceCountUpdated", [count]);
116 * @param {boolean} discoverUsbDevices
117 * @param {boolean} portForwardingEnabled
118 * @param {!Adb.PortForwardingConfig} portForwardingConfig
120 devicesDiscoveryConfigChanged: function(discoverUsbDevices, portForwardingEnabled, portForwardingConfig)
122 this._dispatchOnInspectorFrontendAPI("devicesDiscoveryConfigChanged", [discoverUsbDevices, portForwardingEnabled, portForwardingConfig]);
126 * @param {!Array.<!Adb.Device>} devices
128 devicesUpdated: function(devices)
130 this._dispatchOnInspectorFrontendAPI("devicesUpdated", [devices]);
134 * @param {string} message
136 dispatchMessage: function(message)
138 this._dispatchOnInspectorFrontendAPI("dispatchMessage", [message]);
142 * @param {string} messageChunk
143 * @param {number} messageSize
145 dispatchMessageChunk: function(messageChunk, messageSize)
147 this._dispatchOnInspectorFrontendAPI("dispatchMessageChunk", [messageChunk, messageSize]);
150 enterInspectElementMode: function()
152 this._dispatchOnInspectorFrontendAPI("enterInspectElementMode", []);
156 * @param {!Array.<!{fileSystemName: string, rootURL: string, fileSystemPath: string}>} fileSystems
158 fileSystemsLoaded: function(fileSystems)
160 this._dispatchOnInspectorFrontendAPI("fileSystemsLoaded", [fileSystems]);
164 * @param {string} fileSystemPath
166 fileSystemRemoved: function(fileSystemPath)
168 this._dispatchOnInspectorFrontendAPI("fileSystemRemoved", [fileSystemPath]);
172 * @param {string} errorMessage
173 * @param {!{fileSystemName: string, rootURL: string, fileSystemPath: string}} fileSystem
175 fileSystemAdded: function(errorMessage, fileSystem)
177 this._dispatchOnInspectorFrontendAPI("fileSystemAdded", [errorMessage, fileSystem]);
181 * @param {number} requestId
182 * @param {string} fileSystemPath
183 * @param {number} totalWork
185 indexingTotalWorkCalculated: function(requestId, fileSystemPath, totalWork)
187 this._dispatchOnInspectorFrontendAPI("indexingTotalWorkCalculated", [requestId, fileSystemPath, totalWork]);
191 * @param {number} requestId
192 * @param {string} fileSystemPath
193 * @param {number} worked
195 indexingWorked: function(requestId, fileSystemPath, worked)
197 this._dispatchOnInspectorFrontendAPI("indexingWorked", [requestId, fileSystemPath, worked]);
201 * @param {number} requestId
202 * @param {string} fileSystemPath
204 indexingDone: function(requestId, fileSystemPath)
206 this._dispatchOnInspectorFrontendAPI("indexingDone", [requestId, fileSystemPath]);
210 * @param {{type: string, keyIdentifier: string, keyCode: number, modifiers: number}} event
212 keyEventUnhandled: function(event)
214 this._dispatchOnInspectorFrontendAPI("keyEventUnhandled", [event]);
218 * @param {boolean} hard
220 reloadInspectedPage: function(hard)
222 this._dispatchOnInspectorFrontendAPI("reloadInspectedPage", [hard]);
226 * @param {string} url
227 * @param {number} lineNumber
228 * @param {number} columnNumber
230 revealSourceLine: function(url, lineNumber, columnNumber)
232 this._dispatchOnInspectorFrontendAPI("revealSourceLine", [url, lineNumber, columnNumber]);
236 * @param {string} url
238 savedURL: function(url)
240 this._dispatchOnInspectorFrontendAPI("savedURL", [url]);
244 * @param {number} requestId
245 * @param {string} fileSystemPath
246 * @param {!Array.<string>} files
248 searchCompleted: function(requestId, fileSystemPath, files)
250 this._dispatchOnInspectorFrontendAPI("searchCompleted", [requestId, fileSystemPath, files]);
254 * @param {string} tabId
256 setInspectedTabId: function(tabId)
258 // Support for legacy front-ends (<M41).
259 if (window["WebInspector"].setInspectedTabId)
260 window["WebInspector"].setInspectedTabId(tabId);
262 this._dispatchOnInspectorFrontendAPI("setInspectedTabId", [tabId]);
266 * @param {boolean} useSoftMenu
268 setUseSoftMenu: function(useSoftMenu)
270 this._dispatchOnInspectorFrontendAPI("setUseSoftMenu", [useSoftMenu]);
273 showConsole: function()
275 this._dispatchOnInspectorFrontendAPI("showConsole", []);
280 * @param {string} chunk
282 streamWrite: function(id, chunk)
284 this._dispatchOnInspectorFrontendAPI("streamWrite", [id, chunk]);
287 frontendAPIAttached: function()
289 this._dispatchOnInspectorFrontendAPI("frontendAPIAttached", []);
292 frontendAPIDetached: function()
294 this._dispatchOnInspectorFrontendAPI("frontendAPIDetached", []);
298 * @param {string} command
300 dispatchFrontendAPIMessage: function(command)
302 this._dispatchOnInspectorFrontendAPI("dispatchFrontendAPIMessage", [command]);
306 var DevToolsAPI = new DevToolsAPIImpl();
307 window.DevToolsAPI = DevToolsAPI;
309 // InspectorFrontendHostImpl --------------------------------------------------
313 * @implements {InspectorFrontendHostAPI}
315 function InspectorFrontendHostImpl()
319 InspectorFrontendHostImpl.prototype = {
324 getSelectionBackgroundColor: function()
326 return DevToolsHost.getSelectionBackgroundColor();
333 getSelectionForegroundColor: function()
335 return DevToolsHost.getSelectionForegroundColor();
344 return DevToolsHost.platform();
350 loadCompleted: function()
352 DevToolsAPI.sendMessageToEmbedder("loadCompleted", [], null);
358 bringToFront: function()
360 DevToolsAPI.sendMessageToEmbedder("bringToFront", [], null);
366 closeWindow: function()
368 DevToolsAPI.sendMessageToEmbedder("closeWindow", [], null);
373 * @param {boolean} isDocked
374 * @param {function()} callback
376 setIsDocked: function(isDocked, callback)
378 DevToolsAPI.sendMessageToEmbedder("setIsDocked", [isDocked], callback);
382 * Requests inspected page to be placed atop of the inspector frontend with specified bounds.
384 * @param {{x: number, y: number, width: number, height: number}} bounds
386 setInspectedPageBounds: function(bounds)
388 DevToolsAPI.sendMessageToEmbedder("setInspectedPageBounds", [bounds], null);
394 inspectElementCompleted: function()
396 DevToolsAPI.sendMessageToEmbedder("inspectElementCompleted", [], null);
401 * @param {string} url
402 * @param {string} headers
403 * @param {number} streamId
404 * @param {function(!InspectorFrontendHostAPI.LoadNetworkResourceResult)} callback
406 loadNetworkResource: function(url, headers, streamId, callback)
408 DevToolsAPI.sendMessageToEmbedder("loadNetworkResource", [url, headers, streamId], /** @type {function(?Object)} */ (callback));
413 * @param {function(!Object<string, string>)} callback
415 getPreferences: function(callback)
417 DevToolsAPI.sendMessageToEmbedder("getPreferences", [], /** @type {function(?Object)} */ (callback));
422 * @param {string} name
423 * @param {string} value
425 setPreference: function(name, value)
427 DevToolsAPI.sendMessageToEmbedder("setPreference", [name, value], null);
432 * @param {string} name
434 removePreference: function(name)
436 DevToolsAPI.sendMessageToEmbedder("removePreference", [name], null);
442 clearPreferences: function()
444 DevToolsAPI.sendMessageToEmbedder("clearPreferences", [], null);
449 * @param {string} origin
450 * @param {string} script
452 setInjectedScriptForOrigin: function(origin, script)
454 DevToolsHost.setInjectedScriptForOrigin(origin, script);
459 * @param {string} url
461 inspectedURLChanged: function(url)
463 DevToolsAPI.sendMessageToEmbedder("inspectedURLChanged", [url], null);
468 * @param {string} text
470 copyText: function(text)
472 DevToolsHost.copyText(text);
477 * @param {string} url
479 openInNewTab: function(url)
481 DevToolsAPI.sendMessageToEmbedder("openInNewTab", [url], null);
486 * @param {string} url
487 * @param {string} content
488 * @param {boolean} forceSaveAs
490 save: function(url, content, forceSaveAs)
492 DevToolsAPI.sendMessageToEmbedder("save", [url, content, forceSaveAs], null);
497 * @param {string} url
498 * @param {string} content
500 append: function(url, content)
502 DevToolsAPI.sendMessageToEmbedder("append", [url, content], null);
507 * @param {string} message
509 sendMessageToBackend: function(message)
511 DevToolsHost.sendMessageToBackend(message);
516 * @param {string} actionName
517 * @param {number} actionCode
518 * @param {number} bucketSize
520 recordEnumeratedHistogram: function(actionName, actionCode, bucketSize)
522 DevToolsAPI.sendMessageToEmbedder("recordEnumeratedHistogram", [actionName, actionCode, bucketSize], null);
527 * @param {string} message
529 sendFrontendAPINotification: function(message)
531 DevToolsAPI.sendMessageToEmbedder("sendFrontendAPINotification", [message], null);
537 requestFileSystems: function()
539 DevToolsAPI.sendMessageToEmbedder("requestFileSystems", [], null);
545 addFileSystem: function()
547 DevToolsAPI.sendMessageToEmbedder("addFileSystem", [], null);
552 * @param {string} fileSystemPath
554 removeFileSystem: function(fileSystemPath)
556 DevToolsAPI.sendMessageToEmbedder("removeFileSystem", [fileSystemPath], null);
561 * @param {string} fileSystemId
562 * @param {string} registeredName
563 * @return {?DOMFileSystem}
565 isolatedFileSystem: function(fileSystemId, registeredName)
567 return DevToolsHost.isolatedFileSystem(fileSystemId, registeredName);
572 * @param {!FileSystem} fileSystem
574 upgradeDraggedFileSystemPermissions: function(fileSystem)
576 DevToolsHost.upgradeDraggedFileSystemPermissions(fileSystem);
581 * @param {number} requestId
582 * @param {string} fileSystemPath
584 indexPath: function(requestId, fileSystemPath)
586 DevToolsAPI.sendMessageToEmbedder("indexPath", [requestId, fileSystemPath], null);
591 * @param {number} requestId
593 stopIndexing: function(requestId)
595 DevToolsAPI.sendMessageToEmbedder("stopIndexing", [requestId], null);
600 * @param {number} requestId
601 * @param {string} fileSystemPath
602 * @param {string} query
604 searchInPath: function(requestId, fileSystemPath, query)
606 DevToolsAPI.sendMessageToEmbedder("searchInPath", [requestId, fileSystemPath, query], null);
613 zoomFactor: function()
615 return DevToolsHost.zoomFactor();
623 DevToolsAPI.sendMessageToEmbedder("zoomIn", [], null);
631 DevToolsAPI.sendMessageToEmbedder("zoomOut", [], null);
637 resetZoom: function()
639 DevToolsAPI.sendMessageToEmbedder("resetZoom", [], null);
644 * @param {string} shortcuts
646 setWhitelistedShortcuts: function(shortcuts)
648 DevToolsAPI.sendMessageToEmbedder("setWhitelistedShortcuts", [shortcuts], null);
655 isUnderTest: function()
657 return DevToolsHost.isUnderTest();
662 * @param {boolean} discoverUsbDevices
663 * @param {boolean} portForwardingEnabled
664 * @param {!Adb.PortForwardingConfig} portForwardingConfig
666 setDevicesDiscoveryConfig: function(discoverUsbDevices, portForwardingEnabled, portForwardingConfig)
668 DevToolsAPI.sendMessageToEmbedder("setDevicesDiscoveryConfig", [discoverUsbDevices, portForwardingEnabled, JSON.stringify(portForwardingConfig)], null);
673 * @param {boolean} enabled
675 setDevicesUpdatesEnabled: function(enabled)
677 DevToolsAPI.sendMessageToEmbedder("setDevicesUpdatesEnabled", [enabled], null);
682 * @param {string} pageId
683 * @param {string} action
685 performActionOnRemotePage: function(pageId, action)
687 DevToolsAPI.sendMessageToEmbedder("performActionOnRemotePage", [pageId, action], null);
694 * @param {!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>} items
695 * @param {!Document} document
697 showContextMenuAtPoint: function(x, y, items, document)
699 DevToolsHost.showContextMenuAtPoint(x, y, items, document);
706 isHostedMode: function()
708 return DevToolsHost.isHostedMode();
711 // Backward-compatible methods below this line --------------------------------------------
714 * Support for legacy front-ends (<M41).
723 * Support for legacy front-ends (<M38).
724 * @param {number} zoomFactor
726 setZoomFactor: function(zoomFactor)
731 * Support for legacy front-ends (<M34).
733 sendMessageToEmbedder: function()
738 * Support for legacy front-ends (<M34).
739 * @param {string} dockSide
741 requestSetDockSide: function(dockSide)
743 DevToolsAPI.sendMessageToEmbedder("setIsDocked", [dockSide !== "undocked"], null);
747 * Support for legacy front-ends (<M34).
750 supportsFileSystems: function()
756 * Support for legacy front-ends (<M28).
759 canInspectWorkers: function()
765 * Support for legacy front-ends (<M28).
768 canSaveAs: function()
774 * Support for legacy front-ends (<M28).
783 * Support for legacy front-ends (<M28).
790 * Support for legacy front-ends (<M28).
793 hiddenPanels: function()
799 * Support for legacy front-ends (<M28).
802 localizedStringsURL: function()
808 * Support for legacy front-ends (<M28).
809 * @param {string} url
816 * Support for legacy front-ends (<M44).
817 * @param {number} actionCode
819 recordActionTaken: function(actionCode)
821 this.recordEnumeratedHistogram("DevTools.ActionTaken", actionCode, 100);
825 * Support for legacy front-ends (<M44).
826 * @param {number} panelCode
828 recordPanelShown: function(panelCode)
830 this.recordEnumeratedHistogram("DevTools.PanelShown", panelCode, 20);
834 window.InspectorFrontendHost = new InspectorFrontendHostImpl();
836 // DevToolsApp ---------------------------------------------------------------
839 * @suppressGlobalPropertiesCheck
841 function installBackwardsCompatibility()
843 if (window.location.search.indexOf("remoteFrontend") === -1)
847 * @this {CSSStyleDeclaration}
849 function getValue(property)
851 // Note that |property| comes from another context, so we can't use === here.
852 if (property == "padding-left") {
855 * @suppressReceiverCheck
858 getFloatValue: function() { return this.__paddingLeft; },
859 __paddingLeft: parseFloat(this.paddingLeft)
862 throw new Error("getPropertyCSSValue is undefined");
865 // Support for legacy (<M41) frontends. Remove in M45.
866 window.CSSStyleDeclaration.prototype.getPropertyCSSValue = getValue;
868 function CSSPrimitiveValue()
871 CSSPrimitiveValue.CSS_PX = 5;
872 window.CSSPrimitiveValue = CSSPrimitiveValue;
874 // Support for legacy (<M44) frontends. Remove in M48.
875 var styleElement = window.document.createElement("style");
876 styleElement.type = "text/css";
877 styleElement.textContent = "html /deep/ * { min-width: 0; min-height: 0; }";
878 window.document.head.appendChild(styleElement);
881 function windowLoaded()
883 window.removeEventListener("DOMContentLoaded", windowLoaded, false);
884 installBackwardsCompatibility();
887 if (window.document.head && (window.document.readyState === "complete" || window.document.readyState === "interactive"))
888 installBackwardsCompatibility();
890 window.addEventListener("DOMContentLoaded", windowLoaded, false);
892 // UITests ------------------------------------------------------------------
894 if (window.domAutomationController) {
897 uiTests._tryRun = function()
899 if (uiTests._testSuite && uiTests._pendingTestName) {
900 var name = uiTests._pendingTestName;
901 delete uiTests._pendingTestName;
902 uiTests._testSuite.runTest(name);
906 uiTests.runTest = function(name)
908 uiTests._pendingTestName = name;
912 uiTests.testSuiteReady = function(testSuiteConstructor, testBase)
914 uiTests._testSuite = testSuiteConstructor(window.domAutomationController);
918 window.uiTests = uiTests;