diff options
Diffstat (limited to 'devtools')
180 files changed, 613 insertions, 14128 deletions
diff --git a/devtools/client/framework/devtools-browser.js b/devtools/client/framework/devtools-browser.js index 4d7176b4c..83a888ab9 100644 --- a/devtools/client/framework/devtools-browser.js +++ b/devtools/client/framework/devtools-browser.js @@ -123,23 +123,6 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = { win.DeveloperToolbar.show(false).catch(console.error); } - // Enable WebIDE? - let webIDEEnabled = Services.prefs.getBoolPref("devtools.webide.enabled"); - idEls = [ - "appmenu_webide", - "menu_webide" - ]; - idEls.forEach(function (idEl) { - toggleMenuItem(idEl, webIDEEnabled); - }); - - let showWebIDEWidget = Services.prefs.getBoolPref("devtools.webide.widget.enabled"); - if (webIDEEnabled && showWebIDEWidget) { - gDevToolsBrowser.installWebIDEWidget(); - } else { - gDevToolsBrowser.uninstallWebIDEWidget(); - } - // Enable Browser Toolbox? let chromeEnabled = Services.prefs.getBoolPref("devtools.chrome.enabled"); let devtoolsRemoteEnabled = Services.prefs.getBoolPref("devtools.debugger.remote-enabled"); @@ -347,9 +330,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = { viewId: "PanelUI-developer", shortcutId: "key_devToolboxMenuItem", tooltiptext: "developer-button.tooltiptext2", - defaultArea: AppConstants.MOZ_DEV_EDITION ? - CustomizableUI.AREA_NAVBAR : - CustomizableUI.AREA_PANEL, + defaultArea: CustomizableUI.AREA_PANEL, onViewShowing: function (aEvent) { // Populate the subview with whatever menuitems are in the developer // menu. We skip menu elements, because the menu panel has no way diff --git a/devtools/client/framework/gDevTools.jsm b/devtools/client/framework/gDevTools.jsm index d825c0eaa..6e0dc5e83 100644 --- a/devtools/client/framework/gDevTools.jsm +++ b/devtools/client/framework/gDevTools.jsm @@ -127,15 +127,8 @@ let gDevToolsBrowserMethods = [ "openConnectScreen", // Used by browser-sets.inc, command - // itself, webide widget - "openWebIDE", - - // Used by browser-sets.inc, command "openContentProcessToolbox", - // Used by webide.js - "moveWebIDEWidgetInNavbar", - // Used by browser.js "registerBrowserWindow", @@ -146,10 +139,6 @@ let gDevToolsBrowserMethods = [ "forgetBrowserWindow" ]; this.gDevToolsBrowser = { - // Used by webide.js - get isWebIDEInitialized() { - return browser.isWebIDEInitialized; - }, // Used by a test (should be removed) get _trackedBrowserWindows() { return browser._trackedBrowserWindows; diff --git a/devtools/client/jsonview/converter-child.js b/devtools/client/jsonview/converter-child.js index 61aa0c9a3..65327c395 100644 --- a/devtools/client/jsonview/converter-child.js +++ b/devtools/client/jsonview/converter-child.js @@ -23,10 +23,6 @@ const childProcessMessageManager = Cc["@mozilla.org/childprocessmessagemanager;1"] .getService(Ci.nsISyncMessageSender); -// Amount of space that will be allocated for the stream's backing-store. -// Must be power of 2. Used to copy the data stream in onStopRequest. -const SEGMENT_SIZE = Math.pow(2, 17); - const JSON_VIEW_MIME_TYPE = "application/vnd.mozilla.json.view"; const CONTRACT_ID = "@mozilla.org/streamconv;1?from=" + JSON_VIEW_MIME_TYPE + "&to=*/*"; @@ -61,9 +57,8 @@ let Converter = Class({ * 1. asyncConvertData captures the listener * 2. onStartRequest fires, initializes stuff, modifies the listener * to match our output type - * 3. onDataAvailable transcodes the data into a UTF-8 string - * 4. onStopRequest gets the collected data and converts it, - * spits it to the listener + * 3. onDataAvailable spits it back to the listener + * 4. onStopRequest spits it back to the listener * 5. convert does nothing, it's just the synchronous version * of asyncConvertData */ @@ -76,243 +71,221 @@ let Converter = Class({ }, onDataAvailable: function (request, context, inputStream, offset, count) { - // From https://developer.mozilla.org/en/Reading_textual_data - let is = Cc["@mozilla.org/intl/converter-input-stream;1"] - .createInstance(Ci.nsIConverterInputStream); - is.init(inputStream, this.charset, -1, - Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER); - - // Seed it with something positive - while (count) { - let str = {}; - let bytesRead = is.readString(count, str); - if (!bytesRead) { - break; - } - count -= bytesRead; - this.data += str.value; - } + this.listener.onDataAvailable(...arguments); }, onStartRequest: function (request, context) { - this.data = ""; - this.uri = request.QueryInterface(Ci.nsIChannel).URI.spec; + // Set the content type to HTML in order to parse the doctype, styles + // and scripts, but later a <plaintext> element will switch the tokenizer + // to the plaintext state in order to parse the JSON. + request.QueryInterface(Ci.nsIChannel); + request.contentType = "text/html"; - // Sets the charset if it is available. (For documents loaded from the - // filesystem, this is not set.) - this.charset = - request.QueryInterface(Ci.nsIChannel).contentCharset || "UTF-8"; + // JSON enforces UTF-8 charset (see bug 741776). + request.contentCharset = "UTF-8"; + + // Changing the content type breaks saving functionality. Fix it. + fixSave(request); - this.channel = request; - this.channel.contentType = "text/html"; - this.channel.contentCharset = "UTF-8"; // Because content might still have a reference to this window, // force setting it to a null principal to avoid it being same- // origin with (other) content. - this.channel.loadInfo.resetPrincipalsToNullPrincipal(); + request.loadInfo.resetPrincipalsToNullPrincipal(); - this.listener.onStartRequest(this.channel, context); - }, - - /** - * This should go something like this: - * 1. Make sure we have a unicode string. - * 2. Convert it to a Javascript object. - * 2.1 Removes the callback - * 3. Convert that to HTML? Or XUL? - * 4. Spit it back out at the listener - */ - onStopRequest: function (request, context, statusCode) { - let headers = { - response: [], - request: [] - }; + // Start the request. + this.listener.onStartRequest(request, context); + // Initialize stuff. let win = NetworkHelper.getWindowForRequest(request); + exportData(win, request); + win.addEventListener("DOMContentLoaded", event => { + win.addEventListener("contentMessage", onContentMessage, false, true); + }, {once: true}); + + // Insert the initial HTML code. + let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"] + .createInstance(Ci.nsIScriptableUnicodeConverter); + converter.charset = "UTF-8"; + let stream = converter.convertToInputStream(initialHTML(win.document)); + this.listener.onDataAvailable(request, context, stream, 0, stream.available()); + }, - let Locale = { - $STR: key => { - try { - return jsonViewStrings.GetStringFromName(key); - } catch (err) { - console.error(err); - return undefined; - } - } - }; - - JsonViewUtils.exportIntoContentScope(win, Locale, "Locale"); - - Events.once(win, "DOMContentLoaded", event => { - win.addEventListener("contentMessage", - this.onContentMessage.bind(this), false, true); - }); - - // The request doesn't have to be always nsIHttpChannel - // (e.g. in case of data: URLs) - if (request instanceof Ci.nsIHttpChannel) { - request.visitResponseHeaders({ - visitHeader: function (name, value) { - headers.response.push({name: name, value: value}); - } - }); - - request.visitRequestHeaders({ - visitHeader: function (name, value) { - headers.request.push({name: name, value: value}); - } - }); - } - - let outputDoc = ""; + onStopRequest: function (request, context, statusCode) { + this.listener.onStopRequest(request, context, statusCode); + this.listener = null; + } +}); +// Lets "save as" save the original JSON, not the viewer. +// To save with the proper extension we need the original content type, +// which has been replaced by application/vnd.mozilla.json.view +function fixSave(request) { + let originalType; + if (request instanceof Ci.nsIHttpChannel) { try { - headers = JSON.stringify(headers); - outputDoc = this.toHTML(this.data, headers, this.uri); - } catch (e) { - console.error("JSON Viewer ERROR " + e); - outputDoc = this.toErrorPage(e, this.data, this.uri); + let header = request.getResponseHeader("Content-Type"); + originalType = header.split(";")[0]; + } catch (err) { + // Handled below } - - let storage = Cc["@mozilla.org/storagestream;1"] - .createInstance(Ci.nsIStorageStream); - - storage.init(SEGMENT_SIZE, 0xffffffff, null); - let out = storage.getOutputStream(0); - - let binout = Cc["@mozilla.org/binaryoutputstream;1"] - .createInstance(Ci.nsIBinaryOutputStream); - - binout.setOutputStream(out); - binout.writeUtf8Z(outputDoc); - binout.close(); - - // We need to trim 4 bytes off the front (this could be underlying bug). - let trunc = 4; - let instream = storage.newInputStream(trunc); - - // Pass the data to the main content listener - this.listener.onDataAvailable(this.channel, context, instream, 0, - instream.available()); - - this.listener.onStopRequest(this.channel, context, statusCode); - - this.listener = null; - }, - - htmlEncode: function (t) { - return t !== null ? t.toString() - .replace(/&/g, "&") - .replace(/"/g, """) - .replace(/</g, "<") - .replace(/>/g, ">") : ""; - }, - - toHTML: function (json, headers, title) { - let themeClassName = "theme-" + JsonViewUtils.getCurrentTheme(); - let clientBaseUrl = "resource://devtools/client/"; - let baseUrl = clientBaseUrl + "jsonview/"; - let themeVarsUrl = clientBaseUrl + "themes/variables.css"; - let commonUrl = clientBaseUrl + "themes/common.css"; - let toolbarsUrl = clientBaseUrl + "themes/toolbars.css"; - - let os; - let platform = Services.appinfo.OS; - if (platform.startsWith("WINNT")) { - os = "win"; - } else if (platform.startsWith("Darwin")) { - os = "mac"; - } else { - os = "linux"; + } else { + let uri = request.QueryInterface(Ci.nsIChannel).URI.spec; + let match = uri.match(/^data:(.*?)[,;]/); + if (match) { + originalType = match[1]; } + } + const JSON_TYPES = ["application/json", "application/manifest+json"]; + if (!JSON_TYPES.includes(originalType)) { + originalType = JSON_TYPES[0]; + } + request.QueryInterface(Ci.nsIWritablePropertyBag); + request.setProperty("contentType", originalType); +} - return "<!DOCTYPE html>\n" + - "<html platform=\"" + os + "\" class=\"" + themeClassName + "\">" + - "<head><title>" + this.htmlEncode(title) + "</title>" + - "<base href=\"" + this.htmlEncode(baseUrl) + "\">" + - "<link rel=\"stylesheet\" type=\"text/css\" href=\"" + - themeVarsUrl + "\">" + - "<link rel=\"stylesheet\" type=\"text/css\" href=\"" + - commonUrl + "\">" + - "<link rel=\"stylesheet\" type=\"text/css\" href=\"" + - toolbarsUrl + "\">" + - "<link rel=\"stylesheet\" type=\"text/css\" href=\"css/main.css\">" + - "<script data-main=\"viewer-config\" src=\"lib/require.js\"></script>" + - "</head><body>" + - "<div id=\"content\"></div>" + - "<div id=\"json\">" + this.htmlEncode(json) + "</div>" + - "<div id=\"headers\">" + this.htmlEncode(headers) + "</div>" + - "</body></html>"; - }, - - toErrorPage: function (error, data, uri) { - // Escape unicode nulls - data = data.replace("\u0000", "\uFFFD"); +// Exports variables that will be accessed by the non-privileged scripts. +function exportData(win, request) { + let Locale = { + $STR: key => { + try { + return jsonViewStrings.GetStringFromName(key); + } catch (err) { + console.error(err); + return undefined; + } + } + }; + JsonViewUtils.exportIntoContentScope(win, Locale, "Locale"); + + let headers = { + response: [], + request: [] + }; + // The request doesn't have to be always nsIHttpChannel + // (e.g. in case of data: URLs) + if (request instanceof Ci.nsIHttpChannel) { + request.visitResponseHeaders({ + visitHeader: function (name, value) { + headers.response.push({name: name, value: value}); + } + }); + request.visitRequestHeaders({ + visitHeader: function (name, value) { + headers.request.push({name: name, value: value}); + } + }); + } + JsonViewUtils.exportIntoContentScope(win, headers, "headers"); +} - let errorInfo = error + ""; +// Serializes a qualifiedName and an optional set of attributes into an HTML +// start tag. Be aware qualifiedName and attribute names are not validated. +// Attribute values are escaped with escapingString algorithm in attribute mode +// (https://html.spec.whatwg.org/multipage/syntax.html#escapingString). +function startTag(qualifiedName, attributes = {}) { + return Object.entries(attributes).reduce(function (prev, [attr, value]) { + return prev + " " + attr + "=\"" + + value.replace(/&/g, "&") + .replace(/\u00a0/g, " ") + .replace(/"/g, """) + + "\""; + }, "<" + qualifiedName) + ">"; +} - let output = "<div id=\"error\">" + "error parsing"; - if (errorInfo.message) { - output += "<div class=\"errormessage\">" + errorInfo.message + "</div>"; - } +// Builds an HTML string that will be used to load stylesheets and scripts, +// and switch the parser to plaintext state. +function initialHTML(doc) { + let os; + let platform = Services.appinfo.OS; + if (platform.startsWith("WINNT")) { + os = "win"; + } else if (platform.startsWith("Darwin")) { + os = "mac"; + } else { + os = "linux"; + } - output += "</div><div id=\"json\">" + this.highlightError(data, - errorInfo.line, errorInfo.column) + "</div>"; + let base = doc.createElement("base"); + base.href = "resource://devtools/client/jsonview/"; + + let style = doc.createElement("link"); + style.rel = "stylesheet"; + style.type = "text/css"; + style.href = "css/main.css"; + + let script = doc.createElement("script"); + script.src = "lib/require.js"; + script.dataset.main = "viewer-config"; + script.defer = true; + + let head = doc.createElement("head"); + head.append(base, style, script); + + return "<!DOCTYPE html>\n" + + startTag("html", { + "platform": os, + "class": "theme-" + JsonViewUtils.getCurrentTheme(), + "dir": Services.locale.isAppLocaleRTL ? "rtl" : "ltr" + }) + + head.outerHTML + + startTag("body") + + startTag("div", {"id": "content"}) + + startTag("plaintext", {"id": "json"}); +} - return "<!DOCTYPE html>\n" + - "<html><head><title>" + this.htmlEncode(uri + " - Error") + "</title>" + - "<base href=\"" + this.htmlEncode(this.data.url()) + "\">" + - "</head><body>" + - output + - "</body></html>"; - }, +// Chrome <-> Content communication +function onContentMessage(e) { + // Do not handle events from different documents. + let win = this; + if (win != e.target) { + return; + } - // Chrome <-> Content communication + let value = e.detail.value; + switch (e.detail.type) { + case "copy": + copyString(win, value); + break; - onContentMessage: function (e) { - // Do not handle events from different documents. - let win = NetworkHelper.getWindowForRequest(this.channel); - if (win != e.target) { - return; - } + case "copy-headers": + copyHeaders(win, value); + break; - let value = e.detail.value; - switch (e.detail.type) { - case "copy": - Clipboard.set(value, "text"); - break; + case "save": + childProcessMessageManager.sendAsyncMessage( + "devtools:jsonview:save", value); + } +} - case "copy-headers": - this.copyHeaders(value); - break; +function copyHeaders(win, headers) { + let value = ""; + let eol = (Services.appinfo.OS !== "WINNT") ? "\n" : "\r\n"; - case "save": - childProcessMessageManager.sendAsyncMessage( - "devtools:jsonview:save", value); - } - }, + let responseHeaders = headers.response; + for (let i = 0; i < responseHeaders.length; i++) { + let header = responseHeaders[i]; + value += header.name + ": " + header.value + eol; + } - copyHeaders: function (headers) { - let value = ""; - let eol = (Services.appinfo.OS !== "WINNT") ? "\n" : "\r\n"; + value += eol; - let responseHeaders = headers.response; - for (let i = 0; i < responseHeaders.length; i++) { - let header = responseHeaders[i]; - value += header.name + ": " + header.value + eol; - } + let requestHeaders = headers.request; + for (let i = 0; i < requestHeaders.length; i++) { + let header = requestHeaders[i]; + value += header.name + ": " + header.value + eol; + } - value += eol; + copyString(win, value); +} - let requestHeaders = headers.request; - for (let i = 0; i < requestHeaders.length; i++) { - let header = requestHeaders[i]; - value += header.name + ": " + header.value + eol; - } +function copyString(win, string) { + win.document.addEventListener("copy", event => { + event.clipboardData.setData("text/plain", string); + event.preventDefault(); + }, {once: true}); - Clipboard.set(value, "text"); - } -}); + win.document.execCommand("copy", false, null); +} // Stream converter component definition let service = xpcom.Service({ diff --git a/devtools/client/jsonview/css/general.css b/devtools/client/jsonview/css/general.css index 0c68d65e7..d80720f4f 100644 --- a/devtools/client/jsonview/css/general.css +++ b/devtools/client/jsonview/css/general.css @@ -28,9 +28,9 @@ pre { font-family: var(--monospace-font-family); } -#json, -#headers { +#json { display: none; + white-space: pre-wrap; } /******************************************************************************/ diff --git a/devtools/client/jsonview/css/main.css b/devtools/client/jsonview/css/main.css index 04f3cb87c..c75d7cea0 100644 --- a/devtools/client/jsonview/css/main.css +++ b/devtools/client/jsonview/css/main.css @@ -3,7 +3,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -@import "resource://devtools/client/shared/components/reps/reps.css"; +@import "resource://devtools/client/themes/variables.css"; +@import "resource://devtools/client/themes/common.css"; +@import "resource://devtools/client/themes/toolbars.css"; @import "resource://devtools/client/shared/components/tree/tree-view.css"; @import "resource://devtools/client/shared/components/tabs/tabs.css"; diff --git a/devtools/client/jsonview/json-viewer.js b/devtools/client/jsonview/json-viewer.js index d96081da2..38cb6d7ec 100644 --- a/devtools/client/jsonview/json-viewer.js +++ b/devtools/client/jsonview/json-viewer.js @@ -12,28 +12,28 @@ define(function (require, exports, module) { const { MainTabbedArea } = createFactories(require("./components/main-tabbed-area")); const json = document.getElementById("json"); - const headers = document.getElementById("headers"); - - let jsonData; - - try { - jsonData = JSON.parse(json.textContent); - } catch (err) { - jsonData = err + ""; - } // Application state object. let input = { jsonText: json.textContent, jsonPretty: null, - json: jsonData, - headers: JSON.parse(headers.textContent), + headers: window.headers, tabActive: 0, prettified: false }; + // Remove BOM, if present. + if (input.jsonText.startsWith("\ufeff")) { + input.jsonText = input.jsonText.slice(1); + } + + try { + input.json = JSON.parse(input.jsonText); + } catch (err) { + input.json = err; + } + json.remove(); - headers.remove(); /** * Application actions/commands. This list implements all commands @@ -61,7 +61,7 @@ define(function (require, exports, module) { theApp.setState({jsonText: input.jsonText}); } else { if (!input.jsonPretty) { - input.jsonPretty = JSON.stringify(jsonData, null, " "); + input.jsonPretty = JSON.stringify(input.json, null, " "); } theApp.setState({jsonText: input.jsonPretty}); } diff --git a/devtools/client/jsonview/utils.js b/devtools/client/jsonview/utils.js index a70afdc68..6ab697c89 100644 --- a/devtools/client/jsonview/utils.js +++ b/devtools/client/jsonview/utils.js @@ -96,6 +96,8 @@ exports.exportIntoContentScope = function (win, obj, defineAs) { Cu.exportFunction(propValue, clone, { defineAs: propName }); + } else { + clone[propName] = Cu.cloneInto(propValue, win); } } }; diff --git a/devtools/client/locales/en-US/menus.properties b/devtools/client/locales/en-US/menus.properties index 66e158cbd..7030fe17d 100644 --- a/devtools/client/locales/en-US/menus.properties +++ b/devtools/client/locales/en-US/menus.properties @@ -54,11 +54,6 @@ devToolbarMenu.accesskey = v devToolbarMenu.key = VK_F2 devToolbarMenu.keytext = F2 -webide.label = WebIDE -webide.accesskey = W -webide.key = VK_F8 -webide.keytext = F8 - devToolboxMenuItem.label = Toggle Tools devToolboxMenuItem.accesskey = T devToolboxMenuItem.key = I diff --git a/devtools/client/locales/en-US/webide.dtd b/devtools/client/locales/en-US/webide.dtd deleted file mode 100644 index 554488f6d..000000000 --- a/devtools/client/locales/en-US/webide.dtd +++ /dev/null @@ -1,222 +0,0 @@ -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!ENTITY % brandDTD - SYSTEM "chrome://branding/locale/brand.dtd"> - %brandDTD; - -<!ENTITY windowTitle "&brandShortName; WebIDE"> - -<!ENTITY projectMenu_label "Project"> -<!ENTITY projectMenu_accesskey "P"> -<!ENTITY projectMenu_newApp_label "New App…"> -<!ENTITY projectMenu_newApp_accesskey "N"> -<!ENTITY projectMenu_importPackagedApp_label "Open Packaged App…"> -<!ENTITY projectMenu_importPackagedApp_accesskey "P"> -<!ENTITY projectMenu_importHostedApp_label "Open Hosted App…"> -<!ENTITY projectMenu_importHostedApp_accesskey "H"> -<!ENTITY projectMenu_selectApp_label "Open App…"> -<!ENTITY projectMenu_selectApp_accesskey "O"> -<!ENTITY projectMenu_play_label "Install and Run"> -<!ENTITY projectMenu_play_accesskey "I"> -<!ENTITY projectMenu_stop_label "Stop App"> -<!ENTITY projectMenu_stop_accesskey "S"> -<!ENTITY projectMenu_debug_label "Debug App"> -<!ENTITY projectMenu_debug_accesskey "D"> -<!ENTITY projectMenu_remove_label "Remove Project"> -<!ENTITY projectMenu_remove_accesskey "R"> -<!ENTITY projectMenu_showPrefs_label "Preferences"> -<!ENTITY projectMenu_showPrefs_accesskey "e"> -<!ENTITY projectMenu_manageComponents_label "Manage Extra Components"> -<!ENTITY projectMenu_manageComponents_accesskey "M"> -<!ENTITY projectMenu_refreshTabs_label "Refresh Tabs"> - -<!ENTITY runtimeMenu_label "Runtime"> -<!ENTITY runtimeMenu_accesskey "R"> -<!ENTITY runtimeMenu_disconnect_label "Disconnect"> -<!ENTITY runtimeMenu_disconnect_accesskey "D"> -<!ENTITY runtimeMenu_showPermissionTable_label "Permissions Table"> -<!ENTITY runtimeMenu_showPermissionTable_accesskey "P"> -<!ENTITY runtimeMenu_takeScreenshot_label "Screenshot"> -<!ENTITY runtimeMenu_takeScreenshot_accesskey "S"> -<!ENTITY runtimeMenu_showDetails_label "Runtime Info"> -<!ENTITY runtimeMenu_showDetails_accesskey "E"> -<!ENTITY runtimeMenu_showMonitor_label "Monitor"> -<!ENTITY runtimeMenu_showMonitor_accesskey "M"> -<!ENTITY runtimeMenu_showDevicePrefs_label "Device Preferences"> -<!ENTITY runtimeMenu_showDevicePrefs_accesskey "D"> -<!ENTITY runtimeMenu_showSettings_label "Device Settings"> -<!ENTITY runtimeMenu_showSettings_accesskey "s"> - -<!ENTITY viewMenu_label "View"> -<!ENTITY viewMenu_accesskey "V"> -<!ENTITY viewMenu_toggleEditor_label "Toggle Editor"> -<!ENTITY viewMenu_toggleEditor_accesskey "E"> -<!ENTITY viewMenu_zoomin_label "Zoom In"> -<!ENTITY viewMenu_zoomin_accesskey "I"> -<!ENTITY viewMenu_zoomout_label "Zoom Out"> -<!ENTITY viewMenu_zoomout_accesskey "O"> -<!ENTITY viewMenu_resetzoom_label "Reset Zoom"> -<!ENTITY viewMenu_resetzoom_accesskey "R"> - -<!ENTITY projectButton_label "Open App"> -<!ENTITY runtimeButton_label "Select Runtime"> - -<!-- We try to repicate browser' bindings: --> -<!-- quit app --> -<!ENTITY key_quit "W"> -<!-- open menu --> -<!ENTITY key_showProjectPanel "O"> -<!-- reload app --> -<!ENTITY key_play "R"> -<!-- show toolbox --> -<!ENTITY key_toggleToolbox "VK_F12"> -<!-- toggle sidebar --> -<!ENTITY key_toggleEditor "B"> -<!-- zoom --> -<!ENTITY key_zoomin "+"> -<!ENTITY key_zoomin2 "="> -<!ENTITY key_zoomout "-"> -<!ENTITY key_resetzoom "0"> - -<!ENTITY projectPanel_myProjects "My Projects"> -<!ENTITY projectPanel_runtimeApps "Runtime Apps"> -<!ENTITY projectPanel_tabs "Tabs"> -<!ENTITY runtimePanel_usb "USB Devices"> -<!ENTITY runtimePanel_wifi "Wi-Fi Devices"> -<!ENTITY runtimePanel_simulator "Simulators"> -<!ENTITY runtimePanel_other "Other"> -<!ENTITY runtimePanel_installsimulator "Install Simulator"> -<!ENTITY runtimePanel_noadbhelper "Install ADB Helper"> -<!ENTITY runtimePanel_nousbdevice "Can’t see your device?"> -<!ENTITY runtimePanel_refreshDevices_label "Refresh Devices"> - -<!-- Lense --> -<!ENTITY details_valid_header "valid"> -<!ENTITY details_warning_header "warnings"> -<!ENTITY details_error_header "errors"> -<!ENTITY details_description "Description"> -<!ENTITY details_location "Location"> -<!ENTITY details_manifestURL "App ID"> -<!ENTITY details_removeProject_button "Remove Project"> -<!ENTITY details_showPrepackageLog_button "Show Pre-package Log"> - -<!-- New App --> -<!ENTITY newAppWindowTitle "New App"> -<!ENTITY newAppHeader "Select template"> -<!ENTITY newAppLoadingTemplate "Loading templates…"> -<!ENTITY newAppProjectName "Project Name:"> - - -<!-- Decks --> - -<!ENTITY deck_close "Close"> - -<!-- Addons --> -<!ENTITY addons_title "Extra Components"> -<!ENTITY addons_aboutaddons "Open Add-ons Manager"> - -<!-- Prefs --> -<!ENTITY prefs_title "Preferences"> -<!ENTITY prefs_editor_title "Editor"> -<!ENTITY prefs_general_title "General"> -<!ENTITY prefs_restore "Restore Defaults"> -<!ENTITY prefs_manage_components "Manage Extra Components"> -<!ENTITY prefs_options_autoconnectruntime "Reconnect to previous runtime"> -<!ENTITY prefs_options_autoconnectruntime_tooltip "Reconnect to previous runtime when WebIDE starts"> -<!ENTITY prefs_options_rememberlastproject "Remember last project"> -<!ENTITY prefs_options_rememberlastproject_tooltip "Restore previous project when WebIDE starts"> -<!ENTITY prefs_options_templatesurl "Templates URL"> -<!ENTITY prefs_options_templatesurl_tooltip "Index of available templates"> -<!ENTITY prefs_options_showeditor "Show editor"> -<!ENTITY prefs_options_showeditor_tooltip "Show internal editor"> -<!ENTITY prefs_options_tabsize "Tab size"> -<!ENTITY prefs_options_expandtab "Soft tabs"> -<!ENTITY prefs_options_expandtab_tooltip "Use spaces instead of the tab character"> -<!ENTITY prefs_options_detectindentation "Autoindent"> -<!ENTITY prefs_options_detectindentation_tooltip "Guess indentation based on source content"> -<!ENTITY prefs_options_autocomplete "Autocomplete"> -<!ENTITY prefs_options_autocomplete_tooltip "Enable code autocompletion"> -<!ENTITY prefs_options_autoclosebrackets "Autoclose brackets"> -<!ENTITY prefs_options_autoclosebrackets_tooltip "Automatically insert closing brackets"> -<!ENTITY prefs_options_keybindings "Keybindings"> -<!ENTITY prefs_options_keybindings_default "Default"> -<!ENTITY prefs_options_autosavefiles "Autosave files"> -<!ENTITY prefs_options_autosavefiles_tooltip "Automatically save edited files before running project"> - -<!-- Permissions Table --> -<!ENTITY permissionstable_title "Permissions Table"> -<!ENTITY permissionstable_name_header "Name"> - -<!-- Runtime Details --> -<!ENTITY runtimedetails_title "Runtime Info"> -<!ENTITY runtimedetails_adbIsRoot "ADB is root: "> -<!ENTITY runtimedetails_summonADBRoot "root device"> -<!ENTITY runtimedetails_ADBRootWarning "(requires unlocked bootloader)"> -<!ENTITY runtimedetails_unrestrictedPrivileges "Unrestricted DevTools privileges: "> -<!ENTITY runtimedetails_requestPrivileges "request higher privileges"> -<!ENTITY runtimedetails_privilegesWarning "(Will reboot device. Requires root access.)"> - -<!-- Device Preferences and Settings --> -<!ENTITY device_typeboolean "Boolean"> -<!ENTITY device_typenumber "Integer"> -<!ENTITY device_typestring "String"> -<!ENTITY device_typeobject "Object"> -<!ENTITY device_typenone "Select a type"> - -<!-- Device Preferences --> -<!ENTITY devicepreference_title "Device Preferences"> -<!ENTITY devicepreference_search "Search preferences"> -<!ENTITY devicepreference_newname "New preference name"> -<!ENTITY devicepreference_newtext "Preference value"> -<!ENTITY devicepreference_addnew "Add new preference"> - -<!-- Device Settings --> -<!ENTITY devicesetting_title "Device Settings"> -<!ENTITY devicesetting_search "Search settings"> -<!ENTITY devicesetting_newname "New setting name"> -<!ENTITY devicesetting_newtext "Setting value"> -<!ENTITY devicesetting_addnew "Add new setting"> - -<!-- Monitor --> -<!ENTITY monitor_title "Monitor"> -<!ENTITY monitor_help "Help"> - -<!-- WiFi Authentication --> -<!-- LOCALIZATION NOTE (wifi_auth_header): The header displayed on the dialog - that instructs the user to transfer an authentication token to the - server. --> -<!ENTITY wifi_auth_header "Client Identification"> -<!-- LOCALIZATION NOTE (wifi_auth_scan_request): Instructions requesting the - user to transfer authentication info by scanning a QR code. --> -<!ENTITY wifi_auth_scan_request "The endpoint you are connecting to needs more information to authenticate this connection. Please scan the QR code below via the prompt on your other device."> -<!-- LOCALIZATION NOTE (wifi_auth_no_scanner): Link text to assist users with - devices that can't scan a QR code. --> -<!ENTITY wifi_auth_no_scanner "No QR scanner prompt?"> -<!-- LOCALIZATION NOTE (wifi_auth_yes_scanner): Link text to assist users with - devices that can scan a QR code. --> -<!ENTITY wifi_auth_yes_scanner "Have a QR scanner prompt?"> -<!-- LOCALIZATION NOTE (wifi_auth_token_request): Instructions requesting the - user to transfer authentication info by transferring a token. --> -<!ENTITY wifi_auth_token_request "If your other device asks for a token instead of scanning a QR code, please copy the value below to the other device:"> -<!ENTITY wifi_auth_qr_size_note "If the QR code appears too small for the connection to be successfully established, try zooming or enlarging the window."> - -<!-- Logs panel --> -<!ENTITY logs_title "Pre-packaging Command Logs"> - -<!-- Simulator Options --> -<!ENTITY simulator_title "Simulator Options"> -<!ENTITY simulator_remove "Delete Simulator"> -<!ENTITY simulator_reset "Restore Defaults"> -<!ENTITY simulator_name "Name"> -<!ENTITY simulator_software "Software"> -<!ENTITY simulator_version "Version"> -<!ENTITY simulator_profile "Profile"> -<!ENTITY simulator_hardware "Hardware"> -<!ENTITY simulator_device "Device"> -<!ENTITY simulator_screenSize "Screen"> -<!ENTITY simulator_pixelRatio "Pixel Ratio"> -<!ENTITY simulator_tv_data "TV Simulation"> -<!ENTITY simulator_tv_data_open "Config Data"> -<!ENTITY simulator_tv_data_open_button "Open Config Directory…"> diff --git a/devtools/client/locales/en-US/webide.properties b/devtools/client/locales/en-US/webide.properties deleted file mode 100644 index 154094906..000000000 --- a/devtools/client/locales/en-US/webide.properties +++ /dev/null @@ -1,92 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -title_noApp=WebIDE -title_app=WebIDE: %S - -runtimeButton_label=Select Runtime -projectButton_label=Open App - -mainProcess_label=Main Process - -local_runtime=Local Runtime -remote_runtime=Remote Runtime -remote_runtime_promptTitle=Remote Runtime -remote_runtime_promptMessage=hostname:port - -importPackagedApp_title=Select Directory -importHostedApp_title=Open Hosted App -importHostedApp_header=Enter Manifest URL - -selectCustomBinary_title=Select custom B2G binary -selectCustomProfile_title=Select custom Gaia profile - -notification_showTroubleShooting_label=Troubleshooting -notification_showTroubleShooting_accesskey=T - -# LOCALIZATION NOTE (project_tab_loading): This is shown as a temporary tab -# title for browser tab projects when the tab is still loading. -project_tab_loading=Loading… - -# These messages appear in a notification box when an error occur. - -error_cantInstallNotFullyConnected=Can’t install project. Not fully connected. -error_cantInstallValidationErrors=Can’t install project. Validation errors. -error_listRunningApps=Can’t get app list from device - -# Variable: name of the operation (in english) -error_operationTimeout=Operation timed out: %1$S -error_operationFail=Operation failed: %1$S - -# Variable: app name -error_cantConnectToApp=Can’t connect to app: %1$S - -# Variable: error message (in english) -error_cantFetchAddonsJSON=Can’t fetch the add-on list: %S - -error_appProjectsLoadFailed=Unable to load project list. This can occur if you’ve used this profile with a newer version of the browser. -error_folderCreationFailed=Unable to create project folder in the selected directory. - -# Variable: runtime app build ID (looks like this %Y%M%D format) and firefox build ID (same format) -error_runtimeVersionTooRecent=The connected runtime has a more recent build date (%1$S) than your desktop browser (%2$S) does. This is an unsupported setup and may cause DevTools to fail. Please update the browser. - -addons_stable=stable -addons_unstable=unstable -# LOCALIZATION NOTE (addons_simulator_label): This label is shown as the name of -# a given simulator version in the "Manage Simulators" pane. %1$S: Firefox OS -# version in the simulator, ex. 1.3. %2$S: Simulator stability label, ex. -# "stable" or "unstable". -addons_simulator_label=Firefox OS %1$S Simulator (%2$S) -addons_install_button=install -addons_uninstall_button=uninstall -addons_adb_label=ADB Helper Add-on -addons_adapters_label=Tools Adapters Add-on -addons_adb_warning=USB devices won’t be detected without this add-on -addons_status_unknown=? -addons_status_installed=Installed -addons_status_uninstalled=Not Installed -addons_status_preparing=preparing -addons_status_downloading=downloading -addons_status_installing=installing - -runtimedetails_checkno=no -runtimedetails_checkyes=yes -runtimedetails_checkunknown=unknown (requires ADB Helper 0.4.0 or later) -runtimedetails_notUSBDevice=Not a USB device - -# Validation status -status_tooltip=Validation status: %1$S -status_valid=VALID -status_warning=WARNINGS -status_error=ERRORS -status_unknown=UNKNOWN - -# Device preferences and settings -device_reset_default=Reset to default - -# Simulator options -simulator_custom_device=Custom -simulator_custom_binary=Custom B2G binary… -simulator_custom_profile=Custom Gaia profile… -simulator_default_profile=Use default diff --git a/devtools/client/menus.js b/devtools/client/menus.js index dbacb367d..23f024f04 100644 --- a/devtools/client/menus.js +++ b/devtools/client/menus.js @@ -86,17 +86,6 @@ exports.menuitems = [ }, checkbox: true }, - { id: "menu_webide", - l10nKey: "webide", - disabled: true, - oncommand() { - gDevToolsBrowser.openWebIDE(); - }, - key: { - id: "webide", - modifiers: "shift" - } - }, { id: "menu_browserToolbox", l10nKey: "browserToolboxMenu", disabled: true, diff --git a/devtools/client/moz.build b/devtools/client/moz.build index b55aa5380..9699ec726 100644 --- a/devtools/client/moz.build +++ b/devtools/client/moz.build @@ -34,7 +34,6 @@ DIRS += [ 'themes', 'webaudioeditor', 'webconsole', - 'webide', ] # Shim old theme paths used by DevTools add-ons diff --git a/devtools/client/preferences/devtools.js b/devtools/client/preferences/devtools.js index 2f6ca2104..e817b3a18 100644 --- a/devtools/client/preferences/devtools.js +++ b/devtools/client/preferences/devtools.js @@ -21,9 +21,6 @@ pref("devtools.loader.hotreload", false); pref("devtools.toolbar.enabled", true); pref("devtools.toolbar.visible", false); -// Enable DevTools WebIDE by default -pref("devtools.webide.enabled", true); - // Toolbox preferences pref("devtools.toolbox.footer.height", 250); pref("devtools.toolbox.sidebar.width", 500); @@ -234,11 +231,7 @@ pref("devtools.dom.enabled", false); pref("devtools.webaudioeditor.inspectorWidth", 300); // Default theme ("dark" or "light") -#ifdef MOZ_DEV_EDITION -sticky_pref("devtools.theme", "dark"); -#else sticky_pref("devtools.theme", "light"); -#endif // Web console filters pref("devtools.webconsole.filter.error", true); @@ -356,13 +349,8 @@ pref("devtools.editor.autocomplete", true); // version for each user. pref("devtools.telemetry.tools.opened.version", "{}"); -// Enable the JSON View tool (an inspector for application/json documents) on -// Nightly and Dev. Edition. -#ifdef RELEASE_OR_BETA -pref("devtools.jsonview.enabled", false); -#else +// Enable the JSON View tool (an inspector for application/json documents) pref("devtools.jsonview.enabled", true); -#endif // Enable the HTML responsive design mode for all channels. pref("devtools.responsive.html.enabled", true); diff --git a/devtools/client/projecteditor/lib/plugins/app-manager/app-project-editor.js b/devtools/client/projecteditor/lib/plugins/app-manager/app-project-editor.js deleted file mode 100644 index 9a66770b0..000000000 --- a/devtools/client/projecteditor/lib/plugins/app-manager/app-project-editor.js +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const { Cu } = require("chrome"); -const { Class } = require("sdk/core/heritage"); -const promise = require("promise"); -const { ItchEditor } = require("devtools/client/projecteditor/lib/editors"); - -var AppProjectEditor = Class({ - extends: ItchEditor, - - hidesToolbar: true, - - initialize: function (host) { - ItchEditor.prototype.initialize.apply(this, arguments); - this.appended = promise.resolve(); - this.host = host; - this.label = "app-manager"; - }, - - destroy: function () { - this.elt.remove(); - this.elt = null; - }, - - load: function (resource) { - let {appManagerOpts} = this.host.project; - - // Only load the frame the first time it is selected - if (!this.iframe || this.iframe.getAttribute("src") !== appManagerOpts.projectOverviewURL) { - - this.elt.textContent = ""; - let iframe = this.iframe = this.elt.ownerDocument.createElement("iframe"); - let iframeLoaded = this.iframeLoaded = promise.defer(); - - iframe.addEventListener("load", function onLoad() { - iframe.removeEventListener("load", onLoad); - iframeLoaded.resolve(); - }); - - iframe.setAttribute("flex", "1"); - iframe.setAttribute("src", appManagerOpts.projectOverviewURL); - this.elt.appendChild(iframe); - - } - - promise.all([this.iframeLoaded.promise, this.appended]).then(() => { - this.emit("load"); - }); - } -}); - -exports.AppProjectEditor = AppProjectEditor; diff --git a/devtools/client/projecteditor/lib/plugins/app-manager/moz.build b/devtools/client/projecteditor/lib/plugins/app-manager/moz.build deleted file mode 100644 index 8aae52725..000000000 --- a/devtools/client/projecteditor/lib/plugins/app-manager/moz.build +++ /dev/null @@ -1,10 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -DevToolsModules( - 'app-project-editor.js', - 'plugin.js', -) diff --git a/devtools/client/projecteditor/lib/plugins/app-manager/plugin.js b/devtools/client/projecteditor/lib/plugins/app-manager/plugin.js deleted file mode 100644 index 82bbab34b..000000000 --- a/devtools/client/projecteditor/lib/plugins/app-manager/plugin.js +++ /dev/null @@ -1,77 +0,0 @@ -const { Cu } = require("chrome"); -const { Class } = require("sdk/core/heritage"); -const { EventTarget } = require("sdk/event/target"); -const { emit } = require("sdk/event/core"); -const promise = require("promise"); -var { registerPlugin, Plugin } = require("devtools/client/projecteditor/lib/plugins/core"); -const { AppProjectEditor } = require("./app-project-editor"); -const OPTION_URL = "chrome://devtools/skin/images/tool-options.svg"; -const Services = require("Services"); -const Strings = Services.strings.createBundle("chrome://devtools/locale/webide.properties"); - -var AppManagerRenderer = Class({ - extends: Plugin, - - isAppManagerProject: function () { - return !!this.host.project.appManagerOpts; - }, - editorForResource: function (resource) { - if (!resource.parent && this.isAppManagerProject()) { - return AppProjectEditor; - } - }, - getUI: function (parent) { - let doc = parent.ownerDocument; - if (parent.childElementCount == 0) { - let image = doc.createElement("image"); - let optionImage = doc.createElement("image"); - let flexElement = doc.createElement("div"); - let nameLabel = doc.createElement("span"); - let statusElement = doc.createElement("div"); - - image.className = "project-image"; - optionImage.className = "project-options"; - optionImage.setAttribute("src", OPTION_URL); - nameLabel.className = "project-name-label"; - statusElement.className = "project-status"; - flexElement.className = "project-flex"; - - parent.appendChild(image); - parent.appendChild(nameLabel); - parent.appendChild(flexElement); - parent.appendChild(statusElement); - parent.appendChild(optionImage); - } - - return { - image: parent.querySelector(".project-image"), - nameLabel: parent.querySelector(".project-name-label"), - statusElement: parent.querySelector(".project-status") - }; - }, - onAnnotate: function (resource, editor, elt) { - if (resource.parent || !this.isAppManagerProject()) { - return; - } - - let {appManagerOpts} = this.host.project; - let doc = elt.ownerDocument; - - let {image, nameLabel, statusElement} = this.getUI(elt); - let name = appManagerOpts.name || resource.basename; - let url = appManagerOpts.iconUrl || "icon-sample.png"; - let status = appManagerOpts.validationStatus || "unknown"; - let tooltip = Strings.formatStringFromName("status_tooltip", - [Strings.GetStringFromName("status_" + status)], 1); - - nameLabel.textContent = name; - image.setAttribute("src", url); - statusElement.setAttribute("status", status); - statusElement.setAttribute("tooltiptext", tooltip); - - return true; - } -}); - -exports.AppManagerRenderer = AppManagerRenderer; -registerPlugin(AppManagerRenderer); diff --git a/devtools/client/projecteditor/lib/plugins/moz.build b/devtools/client/projecteditor/lib/plugins/moz.build index 17bff7ce0..99d864e13 100644 --- a/devtools/client/projecteditor/lib/plugins/moz.build +++ b/devtools/client/projecteditor/lib/plugins/moz.build @@ -5,7 +5,6 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. DIRS += [ - 'app-manager', 'delete', 'dirty', 'image-view', diff --git a/devtools/client/projecteditor/lib/projecteditor.js b/devtools/client/projecteditor/lib/projecteditor.js index a3ef06249..27127b0a0 100644 --- a/devtools/client/projecteditor/lib/projecteditor.js +++ b/devtools/client/projecteditor/lib/projecteditor.js @@ -31,7 +31,6 @@ require("devtools/client/projecteditor/lib/plugins/new/new"); require("devtools/client/projecteditor/lib/plugins/rename/rename"); require("devtools/client/projecteditor/lib/plugins/save/save"); require("devtools/client/projecteditor/lib/plugins/image-view/plugin"); -require("devtools/client/projecteditor/lib/plugins/app-manager/plugin"); require("devtools/client/projecteditor/lib/plugins/status-bar/plugin"); // Uncomment to enable logging. diff --git a/devtools/client/shared/telemetry.js b/devtools/client/shared/telemetry.js index 38a21cef6..547b1c07f 100644 --- a/devtools/client/shared/telemetry.js +++ b/devtools/client/shared/telemetry.js @@ -177,23 +177,6 @@ Telemetry.prototype = { histogram: "DEVTOOLS_ABOUTDEBUGGING_OPENED_COUNT", timerHistogram: "DEVTOOLS_ABOUTDEBUGGING_TIME_ACTIVE_SECONDS" }, - webide: { - histogram: "DEVTOOLS_WEBIDE_OPENED_COUNT", - timerHistogram: "DEVTOOLS_WEBIDE_TIME_ACTIVE_SECONDS" - }, - webideProjectEditor: { - histogram: "DEVTOOLS_WEBIDE_PROJECT_EDITOR_OPENED_COUNT", - timerHistogram: "DEVTOOLS_WEBIDE_PROJECT_EDITOR_TIME_ACTIVE_SECONDS" - }, - webideProjectEditorSave: { - histogram: "DEVTOOLS_WEBIDE_PROJECT_EDITOR_SAVE_COUNT", - }, - webideNewProject: { - histogram: "DEVTOOLS_WEBIDE_NEW_PROJECT_COUNT", - }, - webideImportProject: { - histogram: "DEVTOOLS_WEBIDE_IMPORT_PROJECT_COUNT", - }, custom: { histogram: "DEVTOOLS_CUSTOM_OPENED_COUNT", timerHistogram: "DEVTOOLS_CUSTOM_TIME_ACTIVE_SECONDS" diff --git a/devtools/client/webconsole/new-console-output/components/message-types/evaluation-result.js b/devtools/client/webconsole/new-console-output/components/message-types/evaluation-result.js index 992dc62cf..824bdb3fb 100644 --- a/devtools/client/webconsole/new-console-output/components/message-types/evaluation-result.js +++ b/devtools/client/webconsole/new-console-output/components/message-types/evaluation-result.js @@ -34,6 +34,7 @@ function EvaluationResult(props) { id: messageId, exceptionDocURL, frame, + notes, } = message; let messageBody; @@ -57,6 +58,7 @@ function EvaluationResult(props) { serviceContainer, exceptionDocURL, frame, + notes, }; return Message(childProps); } diff --git a/devtools/client/webconsole/new-console-output/components/message-types/page-error.js b/devtools/client/webconsole/new-console-output/components/message-types/page-error.js index 77ea75ff7..c68b850bd 100644 --- a/devtools/client/webconsole/new-console-output/components/message-types/page-error.js +++ b/devtools/client/webconsole/new-console-output/components/message-types/page-error.js @@ -44,6 +44,7 @@ function PageError(props) { stacktrace, frame, exceptionDocURL, + notes, } = message; const childProps = { @@ -62,6 +63,7 @@ function PageError(props) { stacktrace, serviceContainer, exceptionDocURL, + notes, }; return Message(childProps); } diff --git a/devtools/client/webconsole/new-console-output/components/message.js b/devtools/client/webconsole/new-console-output/components/message.js index f36bff7e4..1ffa4e12d 100644 --- a/devtools/client/webconsole/new-console-output/components/message.js +++ b/devtools/client/webconsole/new-console-output/components/message.js @@ -47,6 +47,10 @@ const Message = createClass({ onViewSourceInDebugger: PropTypes.func.isRequired, sourceMapService: PropTypes.any, }), + notes: PropTypes.arrayOf(PropTypes.shape({ + messageBody: PropTypes.string.isRequired, + frame: PropTypes.any, + })), }, getDefaultProps: function () { @@ -90,6 +94,7 @@ const Message = createClass({ serviceContainer, dispatch, exceptionDocURL, + notes, } = this.props; topLevelClasses.push("message", source, type, level); @@ -127,6 +132,29 @@ const Message = createClass({ }); } + let notesNodes; + if (notes) { + notesNodes = notes.map(note => dom.span( + { className: "message-flex-body error-note" }, + dom.span({ className: "message-body devtools-monospace" }, + "note: " + note.messageBody + ), + dom.span({ className: "message-location devtools-monospace" }, + note.frame ? FrameView({ + frame: note.frame, + onClick: serviceContainer + ? serviceContainer.onViewSourceInDebugger + : undefined, + showEmptyPathAsHost: true, + sourceMapService: serviceContainer + ? serviceContainer.sourceMapService + : undefined + }) : null + ))); + } else { + notesNodes = []; + } + const repeat = this.props.repeat ? MessageRepeat({repeat: this.props.repeat}) : null; // Configure the location. @@ -167,7 +195,8 @@ const Message = createClass({ repeat, location ), - attachment + attachment, + ...notesNodes ) ); } diff --git a/devtools/client/webconsole/new-console-output/selectors/messages.js b/devtools/client/webconsole/new-console-output/selectors/messages.js index c4b1aee28..e405be2f8 100644 --- a/devtools/client/webconsole/new-console-output/selectors/messages.js +++ b/devtools/client/webconsole/new-console-output/selectors/messages.js @@ -126,6 +126,15 @@ function matchSearchFilters(message, filters) { || (message.parameters !== null && message.parameters.join("").toLocaleLowerCase() .includes(text.toLocaleLowerCase())) + // Look for a match in notes. + || (Array.isArray(message.notes) && message.notes.some(note => + // Look for a match in location. + isTextInFrame(text, note.frame) + // Look for a match in messageBody. + || (note.messageBody !== null + && note.messageBody.toLocaleLowerCase() + .includes(text.toLocaleLowerCase())) + )) ); } diff --git a/devtools/client/webconsole/new-console-output/test/components/page-error.test.js b/devtools/client/webconsole/new-console-output/test/components/page-error.test.js index 93f3a9ea5..5bc5fe0f0 100644 --- a/devtools/client/webconsole/new-console-output/test/components/page-error.test.js +++ b/devtools/client/webconsole/new-console-output/test/components/page-error.test.js @@ -123,4 +123,118 @@ describe("PageError component:", () => { wrapper = render(PageError({ message, serviceContainer})); expect(wrapper.find(".indent").prop("style").width).toBe(`0`); }); + + it("has empty error notes", () => { + const message = stubPreparedMessages.get("ReferenceError: asdf is not defined"); + let wrapper = render(PageError({ message, serviceContainer })); + + const notes = wrapper.find(".error-note"); + + expect(notes.length).toBe(0); + }); + + it("can show an error note", () => { + const origMessage = stubPreparedMessages.get("ReferenceError: asdf is not defined"); + const message = origMessage.set("notes", [ + { + "messageBody": "test note", + "frame": { + "source": "http://example.com/test.js", + "line": 2, + "column": 6 + } + } + ]); + + let wrapper = render(PageError({ message, serviceContainer })); + + const notes = wrapper.find(".error-note"); + expect(notes.length).toBe(1); + + const note = notes.eq(0); + expect(note.find(".message-body").text()) + .toBe("note: test note"); + + // There should be the location. + const locationLink = note.find(`.message-location`); + expect(locationLink.length).toBe(1); + expect(locationLink.text()).toBe("test.js:2:6"); + }); + + it("can show multiple error notes", () => { + const origMessage = stubPreparedMessages.get("ReferenceError: asdf is not defined"); + const message = origMessage.set("notes", [ + { + "messageBody": "test note 1", + "frame": { + "source": "http://example.com/test1.js", + "line": 2, + "column": 6 + } + }, + { + "messageBody": "test note 2", + "frame": { + "source": "http://example.com/test2.js", + "line": 10, + "column": 18 + } + }, + { + "messageBody": "test note 3", + "frame": { + "source": "http://example.com/test3.js", + "line": 9, + "column": 4 + } + } + ]); + + let wrapper = render(PageError({ message, serviceContainer })); + + const notes = wrapper.find(".error-note"); + expect(notes.length).toBe(3); + + const note1 = notes.eq(0); + expect(note1.find(".message-body").text()) + .toBe("note: test note 1"); + + const locationLink1 = note1.find(`.message-location`); + expect(locationLink1.length).toBe(1); + expect(locationLink1.text()).toBe("test1.js:2:6"); + + const note2 = notes.eq(1); + expect(note2.find(".message-body").text()) + .toBe("note: test note 2"); + + const locationLink2 = note2.find(`.message-location`); + expect(locationLink2.length).toBe(1); + expect(locationLink2.text()).toBe("test2.js:10:18"); + + const note3 = notes.eq(2); + expect(note3.find(".message-body").text()) + .toBe("note: test note 3"); + + const locationLink3 = note3.find(`.message-location`); + expect(locationLink3.length).toBe(1); + expect(locationLink3.text()).toBe("test3.js:9:4"); + }); + + it("displays error notes", () => { + const message = stubPreparedMessages.get("SyntaxError: redeclaration of let a"); + + let wrapper = render(PageError({ message, serviceContainer })); + + const notes = wrapper.find(".error-note"); + expect(notes.length).toBe(1); + + const note = notes.eq(0); + expect(note.find(".message-body").text()) + .toBe("note: Previously declared at line 2, column 6"); + + // There should be the location. + const locationLink = note.find(`.message-location`); + expect(locationLink.length).toBe(1); + expect(locationLink.text()).toBe("test-console-api.html:2:6"); + }); }); diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/stub-snippets.js b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/stub-snippets.js index f79548e7b..f0f01a561 100644 --- a/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/stub-snippets.js +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/stub-snippets.js @@ -140,6 +140,10 @@ pageError.set("Reference Error", ` foo() `); +pageError.set("Redeclaration Error", ` + let a, a; +`); + module.exports = { consoleApi, evaluationResult, diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/consoleApi.js b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/consoleApi.js index d9662c4fd..bec3abd70 100644 --- a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/consoleApi.js +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/consoleApi.js @@ -11,8 +11,6 @@ const { ConsoleMessage, NetworkEventMessage } = require("devtools/client/webcons let stubPreparedMessages = new Map(); let stubPackets = new Map(); - - stubPreparedMessages.set("console.log('foobar', 'test')", new ConsoleMessage({ "id": "1", "allowRepeating": true, @@ -34,7 +32,8 @@ stubPreparedMessages.set("console.log('foobar', 'test')", new ConsoleMessage({ }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.log(undefined)", new ConsoleMessage({ @@ -50,7 +49,7 @@ stubPreparedMessages.set("console.log(undefined)", new ConsoleMessage({ } ], "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"undefined\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(undefined)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"undefined\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(undefined)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}", "stacktrace": null, "frame": { "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(undefined)", @@ -59,7 +58,8 @@ stubPreparedMessages.set("console.log(undefined)", new ConsoleMessage({ }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.warn('danger, will robinson!')", new ConsoleMessage({ @@ -73,7 +73,7 @@ stubPreparedMessages.set("console.warn('danger, will robinson!')", new ConsoleMe "danger, will robinson!" ], "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"warn\",\"level\":\"warn\",\"messageText\":null,\"parameters\":[\"danger, will robinson!\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.warn(%27danger%2C%20will%20robinson!%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"warn\",\"level\":\"warn\",\"messageText\":null,\"parameters\":[\"danger, will robinson!\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.warn(%27danger%2C%20will%20robinson!%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}", "stacktrace": null, "frame": { "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.warn(%27danger%2C%20will%20robinson!%27)", @@ -82,7 +82,8 @@ stubPreparedMessages.set("console.warn('danger, will robinson!')", new ConsoleMe }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.log(NaN)", new ConsoleMessage({ @@ -98,7 +99,7 @@ stubPreparedMessages.set("console.log(NaN)", new ConsoleMessage({ } ], "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"NaN\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(NaN)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"NaN\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(NaN)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}", "stacktrace": null, "frame": { "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(NaN)", @@ -107,7 +108,8 @@ stubPreparedMessages.set("console.log(NaN)", new ConsoleMessage({ }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.log(null)", new ConsoleMessage({ @@ -123,7 +125,7 @@ stubPreparedMessages.set("console.log(null)", new ConsoleMessage({ } ], "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"null\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(null)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"null\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(null)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}", "stacktrace": null, "frame": { "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(null)", @@ -132,7 +134,8 @@ stubPreparedMessages.set("console.log(null)", new ConsoleMessage({ }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.log('鼬')", new ConsoleMessage({ @@ -146,7 +149,7 @@ stubPreparedMessages.set("console.log('鼬')", new ConsoleMessage({ "鼬" ], "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"鼬\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%E9%BC%AC%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"鼬\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%E9%BC%AC%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}", "stacktrace": null, "frame": { "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%E9%BC%AC%27)", @@ -155,7 +158,8 @@ stubPreparedMessages.set("console.log('鼬')", new ConsoleMessage({ }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.clear()", new ConsoleMessage({ @@ -169,8 +173,7 @@ stubPreparedMessages.set("console.clear()", new ConsoleMessage({ "Console was cleared." ], "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"clear\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"Console was cleared.\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.clear()\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", - "stacktrace": null, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"clear\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"Console was cleared.\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.clear()\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}", "frame": { "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.clear()", "line": 1, @@ -178,7 +181,8 @@ stubPreparedMessages.set("console.clear()", new ConsoleMessage({ }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.count('bar')", new ConsoleMessage({ @@ -190,7 +194,7 @@ stubPreparedMessages.set("console.count('bar')", new ConsoleMessage({ "messageText": "bar: 1", "parameters": null, "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"debug\",\"messageText\":\"bar: 1\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.count(%27bar%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"debug\",\"messageText\":\"bar: 1\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.count(%27bar%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}", "stacktrace": null, "frame": { "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.count(%27bar%27)", @@ -199,7 +203,8 @@ stubPreparedMessages.set("console.count('bar')", new ConsoleMessage({ }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.assert(false, {message: 'foobar'})", new ConsoleMessage({ @@ -234,7 +239,7 @@ stubPreparedMessages.set("console.assert(false, {message: 'foobar'})", new Conso } ], "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"assert\",\"level\":\"error\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn8.child1/obj31\",\"class\":\"Object\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":1,\"preview\":{\"kind\":\"Object\",\"ownProperties\":{\"message\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"foobar\"}},\"ownPropertiesLength\":1,\"safeGetterValues\":{}}}],\"repeatId\":null,\"stacktrace\":[{\"columnNumber\":27,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.assert(false%2C%20%7Bmessage%3A%20%27foobar%27%7D)\",\"functionName\":\"triggerPacket\",\"language\":2,\"lineNumber\":1}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.assert(false%2C%20%7Bmessage%3A%20%27foobar%27%7D)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"assert\",\"level\":\"error\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn8.child1/obj31\",\"class\":\"Object\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":1,\"preview\":{\"kind\":\"Object\",\"ownProperties\":{\"message\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"foobar\"}},\"ownPropertiesLength\":1,\"safeGetterValues\":{}}}],\"repeatId\":null,\"stacktrace\":[{\"columnNumber\":27,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.assert(false%2C%20%7Bmessage%3A%20%27foobar%27%7D)\",\"functionName\":\"triggerPacket\",\"language\":2,\"lineNumber\":1}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.assert(false%2C%20%7Bmessage%3A%20%27foobar%27%7D)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}", "stacktrace": [ { "columnNumber": 27, @@ -251,7 +256,8 @@ stubPreparedMessages.set("console.assert(false, {message: 'foobar'})", new Conso }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.log('hello \nfrom \rthe \"string world!')", new ConsoleMessage({ @@ -265,7 +271,7 @@ stubPreparedMessages.set("console.log('hello \nfrom \rthe \"string world!')", ne "hello \nfrom \rthe \"string world!" ], "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"hello \\nfrom \\rthe \\\"string world!\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27hello%20%5Cnfrom%20%5Crthe%20%5C%22string%20world!%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"hello \\nfrom \\rthe \\\"string world!\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27hello%20%5Cnfrom%20%5Crthe%20%5C%22string%20world!%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}", "stacktrace": null, "frame": { "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27hello%20%5Cnfrom%20%5Crthe%20%5C%22string%20world!%27)", @@ -274,7 +280,8 @@ stubPreparedMessages.set("console.log('hello \nfrom \rthe \"string world!')", ne }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.log('úṇĩçödê țĕșť')", new ConsoleMessage({ @@ -288,7 +295,7 @@ stubPreparedMessages.set("console.log('úṇĩçödê țĕșť')", new ConsoleMe "úṇĩçödê țĕșť" ], "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"úṇĩçödê țĕșť\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%C3%BA%E1%B9%87%C4%A9%C3%A7%C3%B6d%C3%AA%20%C8%9B%C4%95%C8%99%C5%A5%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"úṇĩçödê țĕșť\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%C3%BA%E1%B9%87%C4%A9%C3%A7%C3%B6d%C3%AA%20%C8%9B%C4%95%C8%99%C5%A5%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}", "stacktrace": null, "frame": { "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%C3%BA%E1%B9%87%C4%A9%C3%A7%C3%B6d%C3%AA%20%C8%9B%C4%95%C8%99%C5%A5%27)", @@ -297,7 +304,8 @@ stubPreparedMessages.set("console.log('úṇĩçödê țĕșť')", new ConsoleMe }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.dirxml(window)", new ConsoleMessage({ @@ -315,7 +323,7 @@ stubPreparedMessages.set("console.dirxml(window)", new ConsoleMessage({ "extensible": true, "frozen": false, "sealed": false, - "ownPropertyLength": 804, + "ownPropertyLength": 815, "preview": { "kind": "ObjectWithURL", "url": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html" @@ -323,7 +331,7 @@ stubPreparedMessages.set("console.dirxml(window)", new ConsoleMessage({ } ], "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn11.child1/obj31\",\"class\":\"Window\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":804,\"preview\":{\"kind\":\"ObjectWithURL\",\"url\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html\"}}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.dirxml(window)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn11.child1/obj31\",\"class\":\"Window\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":804,\"preview\":{\"kind\":\"ObjectWithURL\",\"url\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html\"}}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.dirxml(window)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}", "stacktrace": null, "frame": { "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.dirxml(window)", @@ -332,7 +340,8 @@ stubPreparedMessages.set("console.dirxml(window)", new ConsoleMessage({ }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.trace()", new ConsoleMessage({ @@ -344,7 +353,7 @@ stubPreparedMessages.set("console.trace()", new ConsoleMessage({ "messageText": null, "parameters": [], "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"trace\",\"level\":\"log\",\"messageText\":null,\"parameters\":[],\"repeatId\":null,\"stacktrace\":[{\"columnNumber\":3,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"functionName\":\"testStacktraceFiltering\",\"language\":2,\"lineNumber\":3},{\"columnNumber\":3,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"functionName\":\"foo\",\"language\":2,\"lineNumber\":6},{\"columnNumber\":1,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"functionName\":\"triggerPacket\",\"language\":2,\"lineNumber\":9}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"line\":3,\"column\":3},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"trace\",\"level\":\"log\",\"messageText\":null,\"parameters\":[],\"repeatId\":null,\"stacktrace\":[{\"columnNumber\":3,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"functionName\":\"testStacktraceFiltering\",\"language\":2,\"lineNumber\":3},{\"columnNumber\":3,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"functionName\":\"foo\",\"language\":2,\"lineNumber\":6},{\"columnNumber\":1,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"functionName\":\"triggerPacket\",\"language\":2,\"lineNumber\":9}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"line\":3,\"column\":3},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}", "stacktrace": [ { "columnNumber": 3, @@ -375,7 +384,8 @@ stubPreparedMessages.set("console.trace()", new ConsoleMessage({ }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.time('bar')", new ConsoleMessage({ @@ -387,7 +397,7 @@ stubPreparedMessages.set("console.time('bar')", new ConsoleMessage({ "messageText": null, "parameters": null, "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"nullMessage\",\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"nullMessage\",\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}", "stacktrace": null, "frame": { "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)", @@ -396,7 +406,8 @@ stubPreparedMessages.set("console.time('bar')", new ConsoleMessage({ }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.timeEnd('bar')", new ConsoleMessage({ @@ -408,7 +419,7 @@ stubPreparedMessages.set("console.timeEnd('bar')", new ConsoleMessage({ "messageText": "bar: 1.36ms", "parameters": null, "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"timeEnd\",\"level\":\"log\",\"messageText\":\"bar: 1.36ms\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)\",\"line\":3,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"timeEnd\",\"level\":\"log\",\"messageText\":\"bar: 1.36ms\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)\",\"line\":3,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}", "stacktrace": null, "frame": { "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)", @@ -417,7 +428,8 @@ stubPreparedMessages.set("console.timeEnd('bar')", new ConsoleMessage({ }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.table('bar')", new ConsoleMessage({ @@ -431,7 +443,7 @@ stubPreparedMessages.set("console.table('bar')", new ConsoleMessage({ "bar" ], "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"bar\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%27bar%27)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"bar\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%27bar%27)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}", "stacktrace": null, "frame": { "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%27bar%27)", @@ -440,7 +452,8 @@ stubPreparedMessages.set("console.table('bar')", new ConsoleMessage({ }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.table(['a', 'b', 'c'])", new ConsoleMessage({ @@ -471,7 +484,7 @@ stubPreparedMessages.set("console.table(['a', 'b', 'c'])", new ConsoleMessage({ } ], "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"table\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn15.child1/obj31\",\"class\":\"Array\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":4,\"preview\":{\"kind\":\"ArrayLike\",\"length\":3,\"items\":[\"a\",\"b\",\"c\"]}}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%5B%27a%27%2C%20%27b%27%2C%20%27c%27%5D)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"table\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn15.child1/obj31\",\"class\":\"Array\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":4,\"preview\":{\"kind\":\"ArrayLike\",\"length\":3,\"items\":[\"a\",\"b\",\"c\"]}}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%5B%27a%27%2C%20%27b%27%2C%20%27c%27%5D)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}", "stacktrace": null, "frame": { "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%5B%27a%27%2C%20%27b%27%2C%20%27c%27%5D)", @@ -480,7 +493,8 @@ stubPreparedMessages.set("console.table(['a', 'b', 'c'])", new ConsoleMessage({ }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.group('bar')", new ConsoleMessage({ @@ -492,7 +506,7 @@ stubPreparedMessages.set("console.group('bar')", new ConsoleMessage({ "messageText": "bar", "parameters": null, "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"startGroup\",\"level\":\"log\",\"messageText\":\"bar\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group(%27bar%27)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"startGroup\",\"level\":\"log\",\"messageText\":\"bar\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group(%27bar%27)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}", "stacktrace": null, "frame": { "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group(%27bar%27)", @@ -501,7 +515,8 @@ stubPreparedMessages.set("console.group('bar')", new ConsoleMessage({ }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.groupEnd('bar')", new ConsoleMessage({ @@ -513,7 +528,7 @@ stubPreparedMessages.set("console.groupEnd('bar')", new ConsoleMessage({ "messageText": null, "parameters": null, "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"endGroup\",\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group(%27bar%27)\",\"line\":3,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"endGroup\",\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group(%27bar%27)\",\"line\":3,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}", "stacktrace": null, "frame": { "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group(%27bar%27)", @@ -522,7 +537,8 @@ stubPreparedMessages.set("console.groupEnd('bar')", new ConsoleMessage({ }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.groupCollapsed('foo')", new ConsoleMessage({ @@ -534,7 +550,7 @@ stubPreparedMessages.set("console.groupCollapsed('foo')", new ConsoleMessage({ "messageText": "foo", "parameters": null, "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"startGroupCollapsed\",\"level\":\"log\",\"messageText\":\"foo\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.groupCollapsed(%27foo%27)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"startGroupCollapsed\",\"level\":\"log\",\"messageText\":\"foo\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.groupCollapsed(%27foo%27)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}", "stacktrace": null, "frame": { "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.groupCollapsed(%27foo%27)", @@ -543,7 +559,8 @@ stubPreparedMessages.set("console.groupCollapsed('foo')", new ConsoleMessage({ }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.groupEnd('foo')", new ConsoleMessage({ @@ -555,7 +572,7 @@ stubPreparedMessages.set("console.groupEnd('foo')", new ConsoleMessage({ "messageText": null, "parameters": null, "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"endGroup\",\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.groupCollapsed(%27foo%27)\",\"line\":3,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"endGroup\",\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.groupCollapsed(%27foo%27)\",\"line\":3,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}", "stacktrace": null, "frame": { "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.groupCollapsed(%27foo%27)", @@ -564,7 +581,8 @@ stubPreparedMessages.set("console.groupEnd('foo')", new ConsoleMessage({ }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.group()", new ConsoleMessage({ @@ -576,7 +594,7 @@ stubPreparedMessages.set("console.group()", new ConsoleMessage({ "messageText": "<no group label>", "parameters": null, "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"startGroup\",\"level\":\"log\",\"messageText\":\"<no group label>\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group()\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"startGroup\",\"level\":\"log\",\"messageText\":\"<no group label>\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group()\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}", "stacktrace": null, "frame": { "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group()", @@ -585,7 +603,8 @@ stubPreparedMessages.set("console.group()", new ConsoleMessage({ }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.groupEnd()", new ConsoleMessage({ @@ -597,7 +616,7 @@ stubPreparedMessages.set("console.groupEnd()", new ConsoleMessage({ "messageText": null, "parameters": null, "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"endGroup\",\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group()\",\"line\":3,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"endGroup\",\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group()\",\"line\":3,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}", "stacktrace": null, "frame": { "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group()", @@ -606,7 +625,8 @@ stubPreparedMessages.set("console.groupEnd()", new ConsoleMessage({ }, "groupId": null, "exceptionDocURL": null, - "userProvidedStyles": [] + "userProvidedStyles": [], + "notes": null })); stubPreparedMessages.set("console.log(%cfoobar)", new ConsoleMessage({ @@ -621,7 +641,7 @@ stubPreparedMessages.set("console.log(%cfoobar)", new ConsoleMessage({ "bar" ], "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"foo\",\"bar\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%25cfoobar)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[\"color:blue;font-size:1.3em;background:url('http://example.com/test');position:absolute;top:10px\",\"color:red;background:url('http://example.com/test')\"]}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"foo\",\"bar\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%25cfoobar)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[\"color:blue;font-size:1.3em;background:url('http://example.com/test');position:absolute;top:10px\",\"color:red;background:url('http://example.com/test')\"],\"notes\":null}", "stacktrace": null, "frame": { "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%25cfoobar)", @@ -633,10 +653,10 @@ stubPreparedMessages.set("console.log(%cfoobar)", new ConsoleMessage({ "userProvidedStyles": [ "color:blue;font-size:1.3em;background:url('http://example.com/test');position:absolute;top:10px", "color:red;background:url('http://example.com/test')" - ] + ], + "notes": null })); - stubPackets.set("console.log('foobar', 'test')", { "from": "server1.conn0.child1/consoleActor2", "type": "consoleAPICall", @@ -1017,7 +1037,7 @@ stubPackets.set("console.dirxml(window)", { "extensible": true, "frozen": false, "sealed": false, - "ownPropertyLength": 804, + "ownPropertyLength": 815, "preview": { "kind": "ObjectWithURL", "url": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html" @@ -1451,8 +1471,7 @@ stubPackets.set("console.log(%cfoobar)", { } }); - module.exports = { stubPreparedMessages, stubPackets, -}
\ No newline at end of file +}; diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/evaluationResult.js b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/evaluationResult.js index 098086044..0682d9134 100644 --- a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/evaluationResult.js +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/evaluationResult.js @@ -11,8 +11,6 @@ const { ConsoleMessage, NetworkEventMessage } = require("devtools/client/webcons let stubPreparedMessages = new Map(); let stubPackets = new Map(); - - stubPreparedMessages.set("new Date(0)", new ConsoleMessage({ "id": "1", "allowRepeating": true, @@ -32,11 +30,12 @@ stubPreparedMessages.set("new Date(0)", new ConsoleMessage({ } }, "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"result\",\"level\":\"log\",\"parameters\":{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj30\",\"class\":\"Date\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":0,\"preview\":{\"timestamp\":0}},\"repeatId\":null,\"stacktrace\":null,\"frame\":null,\"groupId\":null,\"userProvidedStyles\":null}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"result\",\"level\":\"log\",\"parameters\":{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj30\",\"class\":\"Date\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":0,\"preview\":{\"timestamp\":0}},\"repeatId\":null,\"stacktrace\":null,\"frame\":null,\"groupId\":null,\"userProvidedStyles\":null,\"notes\":null}", "stacktrace": null, "frame": null, "groupId": null, - "userProvidedStyles": null + "userProvidedStyles": null, + "notes": null })); stubPreparedMessages.set("asdf()", new ConsoleMessage({ @@ -50,7 +49,7 @@ stubPreparedMessages.set("asdf()", new ConsoleMessage({ "type": "undefined" }, "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"result\",\"level\":\"error\",\"messageText\":\"ReferenceError: asdf is not defined\",\"parameters\":{\"type\":\"undefined\"},\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"debugger eval code\",\"line\":1,\"column\":1},\"groupId\":null,\"exceptionDocURL\":\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default\",\"userProvidedStyles\":null}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"result\",\"level\":\"error\",\"messageText\":\"ReferenceError: asdf is not defined\",\"parameters\":{\"type\":\"undefined\"},\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"debugger eval code\",\"line\":1,\"column\":1},\"groupId\":null,\"exceptionDocURL\":\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default\",\"userProvidedStyles\":null,\"notes\":null}", "stacktrace": null, "frame": { "source": "debugger eval code", @@ -59,7 +58,8 @@ stubPreparedMessages.set("asdf()", new ConsoleMessage({ }, "groupId": null, "exceptionDocURL": "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default", - "userProvidedStyles": null + "userProvidedStyles": null, + "notes": null })); stubPreparedMessages.set("1 + @", new ConsoleMessage({ @@ -73,7 +73,7 @@ stubPreparedMessages.set("1 + @", new ConsoleMessage({ "type": "undefined" }, "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"result\",\"level\":\"error\",\"messageText\":\"SyntaxError: illegal character\",\"parameters\":{\"type\":\"undefined\"},\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"debugger eval code\",\"line\":1,\"column\":4},\"groupId\":null,\"userProvidedStyles\":null}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"result\",\"level\":\"error\",\"messageText\":\"SyntaxError: illegal character\",\"parameters\":{\"type\":\"undefined\"},\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"debugger eval code\",\"line\":1,\"column\":4},\"groupId\":null,\"userProvidedStyles\":null,\"notes\":null}", "stacktrace": null, "frame": { "source": "debugger eval code", @@ -81,10 +81,10 @@ stubPreparedMessages.set("1 + @", new ConsoleMessage({ "column": 4 }, "groupId": null, - "userProvidedStyles": null + "userProvidedStyles": null, + "notes": null })); - stubPackets.set("new Date(0)", { "from": "server1.conn0.child1/consoleActor2", "input": "new Date(0)", @@ -103,7 +103,8 @@ stubPackets.set("new Date(0)", { "timestamp": 1476573073424, "exception": null, "frame": null, - "helperResult": null + "helperResult": null, + "notes": null }); stubPackets.set("asdf()", { @@ -138,7 +139,8 @@ stubPackets.set("asdf()", { "line": 1, "column": 1 }, - "helperResult": null + "helperResult": null, + "notes": null }); stubPackets.set("1 + @", { @@ -172,11 +174,11 @@ stubPackets.set("1 + @", { "line": 1, "column": 4 }, - "helperResult": null + "helperResult": null, + "notes": null }); - module.exports = { stubPreparedMessages, stubPackets, -}
\ No newline at end of file +}; diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/pageError.js b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/pageError.js index eda8e8b83..80147e7dd 100644 --- a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/pageError.js +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/pageError.js @@ -11,8 +11,6 @@ const { ConsoleMessage, NetworkEventMessage } = require("devtools/client/webcons let stubPreparedMessages = new Map(); let stubPackets = new Map(); - - stubPreparedMessages.set("ReferenceError: asdf is not defined", new ConsoleMessage({ "id": "1", "allowRepeating": true, @@ -22,7 +20,7 @@ stubPreparedMessages.set("ReferenceError: asdf is not defined", new ConsoleMessa "messageText": "ReferenceError: asdf is not defined", "parameters": null, "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"log\",\"level\":\"error\",\"messageText\":\"ReferenceError: asdf is not defined\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":[{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"lineNumber\":3,\"columnNumber\":5,\"functionName\":\"bar\"},{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"lineNumber\":6,\"columnNumber\":5,\"functionName\":\"foo\"},{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"lineNumber\":9,\"columnNumber\":3,\"functionName\":null}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"line\":3,\"column\":5},\"groupId\":null,\"exceptionDocURL\":\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default\"}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"log\",\"level\":\"error\",\"messageText\":\"ReferenceError: asdf is not defined\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":[{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"lineNumber\":3,\"columnNumber\":5,\"functionName\":\"bar\"},{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"lineNumber\":6,\"columnNumber\":5,\"functionName\":\"foo\"},{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"lineNumber\":9,\"columnNumber\":3,\"functionName\":null}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"line\":3,\"column\":5},\"groupId\":null,\"exceptionDocURL\":\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default\",\"userProvidedStyles\":null,\"notes\":null}", "stacktrace": [ { "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error", @@ -49,9 +47,53 @@ stubPreparedMessages.set("ReferenceError: asdf is not defined", new ConsoleMessa "column": 5 }, "groupId": null, - "exceptionDocURL": "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default" + "exceptionDocURL": "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default", + "userProvidedStyles": null, + "notes": null })); +stubPreparedMessages.set("SyntaxError: redeclaration of let a", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "javascript", + "type": "log", + "level": "error", + "messageText": "SyntaxError: redeclaration of let a", + "parameters": null, + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"log\",\"level\":\"error\",\"messageText\":\"SyntaxError: redeclaration of let a\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":[{\"filename\":\"chrome://mochikit/content/tests/BrowserTestUtils/content-task.js line 52 > eval\",\"lineNumber\":6,\"columnNumber\":9,\"functionName\":null},{\"filename\":\"chrome://mochikit/content/tests/BrowserTestUtils/content-task.js\",\"lineNumber\":53,\"columnNumber\":20,\"functionName\":null}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html\",\"line\":2,\"column\":9},\"groupId\":null,\"userProvidedStyles\":null,\"notes\":[{\"messageBody\":\"Previously declared at line 2, column 6\",\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html\",\"line\":2,\"column\":6}}]}", + "stacktrace": [ + { + "filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js line 52 > eval", + "lineNumber": 6, + "columnNumber": 9, + "functionName": null + }, + { + "filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js", + "lineNumber": 53, + "columnNumber": 20, + "functionName": null + } + ], + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html", + "line": 2, + "column": 9 + }, + "groupId": null, + "userProvidedStyles": null, + "notes": [ + { + "messageBody": "Previously declared at line 2, column 6", + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html", + "line": 2, + "column": 6 + } + } + ] +})); stubPackets.set("ReferenceError: asdf is not defined", { "from": "server1.conn0.child1/consoleActor2", @@ -91,12 +133,56 @@ stubPackets.set("ReferenceError: asdf is not defined", { "columnNumber": 3, "functionName": null } - ] + ], + "notes": null } }); +stubPackets.set("SyntaxError: redeclaration of let a", { + "from": "server1.conn0.child1/consoleActor2", + "type": "pageError", + "pageError": { + "errorMessage": "SyntaxError: redeclaration of let a", + "errorMessageName": "JSMSG_REDECLARED_VAR", + "sourceName": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html", + "lineText": " let a, a;\n", + "lineNumber": 2, + "columnNumber": 9, + "category": "content javascript", + "warning": false, + "error": false, + "exception": true, + "strict": false, + "info": false, + "private": false, + "stacktrace": [ + { + "filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js line 52 > eval", + "lineNumber": 6, + "columnNumber": 9, + "functionName": null + }, + { + "filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js", + "lineNumber": 53, + "columnNumber": 20, + "functionName": null + } + ], + "notes": [ + { + "messageBody": "Previously declared at line 2, column 6", + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html", + "line": 2, + "column": 6 + } + } + ] + } +}); module.exports = { stubPreparedMessages, stubPackets, -}
\ No newline at end of file +}; diff --git a/devtools/client/webconsole/new-console-output/types.js b/devtools/client/webconsole/new-console-output/types.js index 897ae5d3a..cb27aedab 100644 --- a/devtools/client/webconsole/new-console-output/types.js +++ b/devtools/client/webconsole/new-console-output/types.js @@ -38,6 +38,7 @@ exports.ConsoleMessage = Immutable.Record({ groupId: null, exceptionDocURL: null, userProvidedStyles: null, + notes: null, }); exports.NetworkEventMessage = Immutable.Record({ diff --git a/devtools/client/webconsole/new-console-output/utils/messages.js b/devtools/client/webconsole/new-console-output/utils/messages.js index f91209e9d..119bc7fba 100644 --- a/devtools/client/webconsole/new-console-output/utils/messages.js +++ b/devtools/client/webconsole/new-console-output/utils/messages.js @@ -165,6 +165,7 @@ function transformPacket(packet) { stacktrace: pageError.stacktrace ? pageError.stacktrace : null, frame, exceptionDocURL: pageError.exceptionDocURL, + notes: pageError.notes, }); } @@ -185,7 +186,8 @@ function transformPacket(packet) { exceptionMessage: messageText, exceptionDocURL, frame, - result: parameters + result: parameters, + notes, } = packet; const level = messageText ? MESSAGE_LEVEL.ERROR : MESSAGE_LEVEL.LOG; @@ -197,6 +199,7 @@ function transformPacket(packet) { parameters, exceptionDocURL, frame, + notes, }); } } diff --git a/devtools/client/webide/components/moz.build b/devtools/client/webide/components/moz.build deleted file mode 100644 index d4047c295..000000000 --- a/devtools/client/webide/components/moz.build +++ /dev/null @@ -1,10 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -EXTRA_COMPONENTS += [ - 'webideCli.js', - 'webideComponents.manifest', -] diff --git a/devtools/client/webide/components/webideCli.js b/devtools/client/webide/components/webideCli.js deleted file mode 100644 index 0f75da2c4..000000000 --- a/devtools/client/webide/components/webideCli.js +++ /dev/null @@ -1,58 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const Ci = Components.interfaces; -const Cu = Components.utils; - -const { XPCOMUtils } = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {}); - -XPCOMUtils.defineLazyModuleGetter(this, "Services", "resource://gre/modules/Services.jsm"); - -/** - * Handles --webide command line option. - */ - -function webideCli() { } - -webideCli.prototype = { - handle: function (cmdLine) { - if (!cmdLine.handleFlag("webide", false)) { - return; - } - - // If --webide is used remotely, we don't want to open - // a new tab. - // - // If --webide is used for a new Firefox instance, we - // want to open webide only. - cmdLine.preventDefault = true; - - let win = Services.wm.getMostRecentWindow("devtools:webide"); - if (win) { - win.focus(); - } else { - win = Services.ww.openWindow(null, - "chrome://webide/content/", - "webide", - "chrome,centerscreen,resizable,dialog=no", - null); - } - - if (cmdLine.state == Ci.nsICommandLine.STATE_INITIAL_LAUNCH) { - // If this is a new Firefox instance, and because we will only start - // webide, we need to notify "sessionstore-windows-restored" to trigger - // addons registration (for simulators and adb helper). - Services.obs.notifyObservers(null, "sessionstore-windows-restored", ""); - } - }, - - helpInfo: "", - - classID: Components.ID("{79b7b44e-de5e-4e4c-b7a2-044003c615d9}"), - QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler]), -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([webideCli]); diff --git a/devtools/client/webide/components/webideComponents.manifest b/devtools/client/webide/components/webideComponents.manifest deleted file mode 100644 index 03af9758c..000000000 --- a/devtools/client/webide/components/webideComponents.manifest +++ /dev/null @@ -1,4 +0,0 @@ -# webide components -component {79b7b44e-de5e-4e4c-b7a2-044003c615d9} webideCli.js -contract @mozilla.org/browser/webide-clh;1 {79b7b44e-de5e-4e4c-b7a2-044003c615d9} -category command-line-handler a-webide @mozilla.org/browser/webide-clh;1 diff --git a/devtools/client/webide/content/addons.js b/devtools/client/webide/content/addons.js deleted file mode 100644 index 3948b040f..000000000 --- a/devtools/client/webide/content/addons.js +++ /dev/null @@ -1,135 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -var Cu = Components.utils; -const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); -const Services = require("Services"); -const {gDevTools} = require("devtools/client/framework/devtools"); -const {GetAvailableAddons, ForgetAddonsList} = require("devtools/client/webide/modules/addons"); -const Strings = Services.strings.createBundle("chrome://devtools/locale/webide.properties"); - -window.addEventListener("load", function onLoad() { - window.removeEventListener("load", onLoad); - document.querySelector("#aboutaddons").onclick = function () { - let browserWin = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType); - if (browserWin && browserWin.BrowserOpenAddonsMgr) { - browserWin.BrowserOpenAddonsMgr("addons://list/extension"); - } - }; - document.querySelector("#close").onclick = CloseUI; - GetAvailableAddons().then(BuildUI, (e) => { - console.error(e); - window.alert(Strings.formatStringFromName("error_cantFetchAddonsJSON", [e], 1)); - }); -}, true); - -window.addEventListener("unload", function onUnload() { - window.removeEventListener("unload", onUnload); - ForgetAddonsList(); -}, true); - -function CloseUI() { - window.parent.UI.openProject(); -} - -function BuildUI(addons) { - BuildItem(addons.adb, "adb"); - BuildItem(addons.adapters, "adapters"); - for (let addon of addons.simulators) { - BuildItem(addon, "simulator"); - } -} - -function BuildItem(addon, type) { - - function onAddonUpdate(event, arg) { - switch (event) { - case "update": - progress.removeAttribute("value"); - li.setAttribute("status", addon.status); - status.textContent = Strings.GetStringFromName("addons_status_" + addon.status); - break; - case "failure": - window.parent.UI.reportError("error_operationFail", arg); - break; - case "progress": - if (arg == -1) { - progress.removeAttribute("value"); - } else { - progress.value = arg; - } - break; - } - } - - let events = ["update", "failure", "progress"]; - for (let e of events) { - addon.on(e, onAddonUpdate); - } - window.addEventListener("unload", function onUnload() { - window.removeEventListener("unload", onUnload); - for (let e of events) { - addon.off(e, onAddonUpdate); - } - }); - - let li = document.createElement("li"); - li.setAttribute("status", addon.status); - - let name = document.createElement("span"); - name.className = "name"; - - switch (type) { - case "adb": - li.setAttribute("addon", type); - name.textContent = Strings.GetStringFromName("addons_adb_label"); - break; - case "adapters": - li.setAttribute("addon", type); - try { - name.textContent = Strings.GetStringFromName("addons_adapters_label"); - } catch (e) { - // This code (bug 1081093) will be backported to Aurora, which doesn't - // contain this string. - name.textContent = "Tools Adapters Add-on"; - } - break; - case "simulator": - li.setAttribute("addon", "simulator-" + addon.version); - let stability = Strings.GetStringFromName("addons_" + addon.stability); - name.textContent = Strings.formatStringFromName("addons_simulator_label", [addon.version, stability], 2); - break; - } - - li.appendChild(name); - - let status = document.createElement("span"); - status.className = "status"; - status.textContent = Strings.GetStringFromName("addons_status_" + addon.status); - li.appendChild(status); - - let installButton = document.createElement("button"); - installButton.className = "install-button"; - installButton.onclick = () => addon.install(); - installButton.textContent = Strings.GetStringFromName("addons_install_button"); - li.appendChild(installButton); - - let uninstallButton = document.createElement("button"); - uninstallButton.className = "uninstall-button"; - uninstallButton.onclick = () => addon.uninstall(); - uninstallButton.textContent = Strings.GetStringFromName("addons_uninstall_button"); - li.appendChild(uninstallButton); - - let progress = document.createElement("progress"); - li.appendChild(progress); - - if (type == "adb") { - let warning = document.createElement("p"); - warning.textContent = Strings.GetStringFromName("addons_adb_warning"); - warning.className = "warning"; - li.appendChild(warning); - } - - document.querySelector("ul").appendChild(li); -} diff --git a/devtools/client/webide/content/addons.xhtml b/devtools/client/webide/content/addons.xhtml deleted file mode 100644 index 6f3bc1e7c..000000000 --- a/devtools/client/webide/content/addons.xhtml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!DOCTYPE html [ - <!ENTITY % webideDTD SYSTEM "chrome://devtools/locale/webide.dtd" > - %webideDTD; -]> - -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <meta charset="utf8"/> - <link rel="stylesheet" href="chrome://webide/skin/deck.css" type="text/css"/> - <link rel="stylesheet" href="chrome://webide/skin/addons.css" type="text/css"/> - <script type="application/javascript;version=1.8" src="chrome://webide/content/addons.js"></script> - </head> - <body> - - <div id="controls"> - <a id="aboutaddons">&addons_aboutaddons;</a> - <a id="close">&deck_close;</a> - </div> - - <h1>&addons_title;</h1> - - <ul></ul> - - </body> -</html> diff --git a/devtools/client/webide/content/details.js b/devtools/client/webide/content/details.js deleted file mode 100644 index 9097cd8c5..000000000 --- a/devtools/client/webide/content/details.js +++ /dev/null @@ -1,139 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -var Cu = Components.utils; -const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); -const Services = require("Services"); -const {AppManager} = require("devtools/client/webide/modules/app-manager"); -const {ProjectBuilding} = require("devtools/client/webide/modules/build"); - -window.addEventListener("load", function onLoad() { - window.removeEventListener("load", onLoad); - document.addEventListener("visibilitychange", updateUI, true); - AppManager.on("app-manager-update", onAppManagerUpdate); - updateUI(); -}, true); - -window.addEventListener("unload", function onUnload() { - window.removeEventListener("unload", onUnload); - AppManager.off("app-manager-update", onAppManagerUpdate); -}, true); - -function onAppManagerUpdate(event, what, details) { - if (what == "project" || - what == "project-validated") { - updateUI(); - } -} - -function resetUI() { - document.querySelector("#toolbar").classList.add("hidden"); - document.querySelector("#type").classList.add("hidden"); - document.querySelector("#descriptionHeader").classList.add("hidden"); - document.querySelector("#manifestURLHeader").classList.add("hidden"); - document.querySelector("#locationHeader").classList.add("hidden"); - - document.body.className = ""; - document.querySelector("#icon").src = ""; - document.querySelector("h1").textContent = ""; - document.querySelector("#description").textContent = ""; - document.querySelector("#type").textContent = ""; - document.querySelector("#manifestURL").textContent = ""; - document.querySelector("#location").textContent = ""; - - document.querySelector("#prePackageLog").hidden = true; - - document.querySelector("#errorslist").innerHTML = ""; - document.querySelector("#warningslist").innerHTML = ""; - -} - -function updateUI() { - resetUI(); - - let project = AppManager.selectedProject; - if (!project) { - return; - } - - if (project.type != "runtimeApp" && project.type != "mainProcess") { - document.querySelector("#toolbar").classList.remove("hidden"); - document.querySelector("#locationHeader").classList.remove("hidden"); - document.querySelector("#location").textContent = project.location; - } - - document.body.className = project.validationStatus; - document.querySelector("#icon").src = project.icon; - document.querySelector("h1").textContent = project.name; - - let manifest; - if (project.type == "runtimeApp") { - manifest = project.app.manifest; - } else { - manifest = project.manifest; - } - - if (manifest) { - if (manifest.description) { - document.querySelector("#descriptionHeader").classList.remove("hidden"); - document.querySelector("#description").textContent = manifest.description; - } - - document.querySelector("#type").classList.remove("hidden"); - - if (project.type == "runtimeApp") { - let manifestURL = AppManager.getProjectManifestURL(project); - document.querySelector("#type").textContent = manifest.type || "web"; - document.querySelector("#manifestURLHeader").classList.remove("hidden"); - document.querySelector("#manifestURL").textContent = manifestURL; - } else if (project.type == "mainProcess") { - document.querySelector("#type").textContent = project.name; - } else { - document.querySelector("#type").textContent = project.type + " " + (manifest.type || "web"); - } - - if (project.type == "packaged") { - let manifestURL = AppManager.getProjectManifestURL(project); - if (manifestURL) { - document.querySelector("#manifestURLHeader").classList.remove("hidden"); - document.querySelector("#manifestURL").textContent = manifestURL; - } - } - } - - if (project.type != "runtimeApp" && project.type != "mainProcess") { - ProjectBuilding.hasPrepackage(project).then(hasPrepackage => { - document.querySelector("#prePackageLog").hidden = !hasPrepackage; - }); - } - - let errorsNode = document.querySelector("#errorslist"); - let warningsNode = document.querySelector("#warningslist"); - - if (project.errors) { - for (let e of project.errors) { - let li = document.createElement("li"); - li.textContent = e; - errorsNode.appendChild(li); - } - } - - if (project.warnings) { - for (let w of project.warnings) { - let li = document.createElement("li"); - li.textContent = w; - warningsNode.appendChild(li); - } - } - - AppManager.update("details"); -} - -function showPrepackageLog() { - window.top.UI.selectDeckPanel("logs"); -} - -function removeProject() { - AppManager.removeSelectedProject(); -} diff --git a/devtools/client/webide/content/details.xhtml b/devtools/client/webide/content/details.xhtml deleted file mode 100644 index a04c37b0c..000000000 --- a/devtools/client/webide/content/details.xhtml +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!DOCTYPE html [ - <!ENTITY % webideDTD SYSTEM "chrome://devtools/locale/webide.dtd" > - %webideDTD; -]> - -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <meta charset="utf8"/> - <link rel="stylesheet" href="chrome://webide/skin/details.css" type="text/css"/> - <script type="application/javascript;version=1.8" src="chrome://webide/content/details.js"></script> - </head> - <body> - - <div id="toolbar"> - <button onclick="removeProject()">&details_removeProject_button;</button> - <p id="validation_status"> - <span class="valid">&details_valid_header;</span> - <span class="warning">&details_warning_header;</span> - <span class="error">&details_error_header;</span> - </p> - </div> - - <header> - <img id="icon"></img> - <div> - <h1></h1> - <p id="type"></p> - </div> - </header> - - <main> - <h3 id="descriptionHeader">&details_description;</h3> - <p id="description"></p> - - <h3 id="locationHeader">&details_location;</h3> - <p id="location"></p> - - <h3 id="manifestURLHeader">&details_manifestURL;</h3> - <p id="manifestURL"></p> - - <button id="prePackageLog" onclick="showPrepackageLog()" hidden="true">&details_showPrepackageLog_button;</button> - </main> - - <ul class="validation_messages" id="errorslist"></ul> - <ul class="validation_messages" id="warningslist"></ul> - - </body> -</html> diff --git a/devtools/client/webide/content/devicepreferences.js b/devtools/client/webide/content/devicepreferences.js deleted file mode 100644 index 14c020f12..000000000 --- a/devtools/client/webide/content/devicepreferences.js +++ /dev/null @@ -1,81 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -var Cu = Components.utils; -const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); -const {AppManager} = require("devtools/client/webide/modules/app-manager"); -const {Connection} = require("devtools/shared/client/connection-manager"); -const ConfigView = require("devtools/client/webide/modules/config-view"); - -var configView = new ConfigView(window); - -window.addEventListener("load", function onLoad() { - window.removeEventListener("load", onLoad); - AppManager.on("app-manager-update", OnAppManagerUpdate); - document.getElementById("close").onclick = CloseUI; - document.getElementById("device-fields").onchange = UpdateField; - document.getElementById("device-fields").onclick = CheckReset; - document.getElementById("search-bar").onkeyup = document.getElementById("search-bar").onclick = SearchField; - document.getElementById("custom-value").onclick = UpdateNewField; - document.getElementById("custom-value-type").onchange = ClearNewFields; - document.getElementById("add-custom-field").onkeyup = CheckNewFieldSubmit; - BuildUI(); -}, true); - -window.addEventListener("unload", function onUnload() { - window.removeEventListener("unload", onUnload); - AppManager.off("app-manager-update", OnAppManagerUpdate); -}); - -function CloseUI() { - window.parent.UI.openProject(); -} - -function OnAppManagerUpdate(event, what) { - if (what == "connection" || what == "runtime-global-actors") { - BuildUI(); - } -} - -function CheckNewFieldSubmit(event) { - configView.checkNewFieldSubmit(event); -} - -function UpdateNewField() { - configView.updateNewField(); -} - -function ClearNewFields() { - configView.clearNewFields(); -} - -function CheckReset(event) { - configView.checkReset(event); -} - -function UpdateField(event) { - configView.updateField(event); -} - -function SearchField(event) { - configView.search(event); -} - -var getAllPrefs; // Used by tests -function BuildUI() { - configView.resetTable(); - - if (AppManager.connection && - AppManager.connection.status == Connection.Status.CONNECTED && - AppManager.preferenceFront) { - configView.front = AppManager.preferenceFront; - configView.kind = "Pref"; - configView.includeTypeName = true; - - getAllPrefs = AppManager.preferenceFront.getAllPrefs() - .then(json => configView.generateDisplay(json)); - } else { - CloseUI(); - } -} diff --git a/devtools/client/webide/content/devicepreferences.xhtml b/devtools/client/webide/content/devicepreferences.xhtml deleted file mode 100644 index dafb6f15f..000000000 --- a/devtools/client/webide/content/devicepreferences.xhtml +++ /dev/null @@ -1,49 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!DOCTYPE html [ - <!ENTITY % webideDTD SYSTEM "chrome://devtools/locale/webide.dtd" > - %webideDTD; -]> - -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <meta charset="utf8"/> - <link rel="stylesheet" href="chrome://webide/skin/deck.css" type="text/css"/> - <link rel="stylesheet" href="chrome://webide/skin/config-view.css" type="text/css"/> - <script type="application/javascript;version=1.8" src="chrome://webide/content/devicepreferences.js"></script> - </head> - <body> - <header> - <div id="controls"> - <a id="close">&deck_close;</a> - </div> - <h1>&devicepreference_title;</h1> - <div id="search"> - <input type="text" id="search-bar" placeholder="&devicepreference_search;"/> - </div> - </header> - <table id="device-fields"> - <tr id="add-custom-field"> - <td> - <select id="custom-value-type"> - <option value="" selected="selected">&device_typenone;</option> - <option value="boolean">&device_typeboolean;</option> - <option value="number">&device_typenumber;</option> - <option value="string">&device_typestring;</option> - </select> - <input type="text" id="custom-value-name" placeholder="&devicepreference_newname;"/> - </td> - <td class="custom-input"> - <input type="text" id="custom-value-text" placeholder="&devicepreference_newtext;"/> - </td> - <td> - <button id="custom-value" class="new-editable">&devicepreference_addnew;</button> - </td> - </tr> - </table> - </body> -</html> diff --git a/devtools/client/webide/content/devicesettings.js b/devtools/client/webide/content/devicesettings.js deleted file mode 100644 index 987df5995..000000000 --- a/devtools/client/webide/content/devicesettings.js +++ /dev/null @@ -1,81 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -var Cu = Components.utils; -const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); -const {AppManager} = require("devtools/client/webide/modules/app-manager"); -const {Connection} = require("devtools/shared/client/connection-manager"); -const ConfigView = require("devtools/client/webide/modules/config-view"); - -var configView = new ConfigView(window); - -window.addEventListener("load", function onLoad() { - window.removeEventListener("load", onLoad); - AppManager.on("app-manager-update", OnAppManagerUpdate); - document.getElementById("close").onclick = CloseUI; - document.getElementById("device-fields").onchange = UpdateField; - document.getElementById("device-fields").onclick = CheckReset; - document.getElementById("search-bar").onkeyup = document.getElementById("search-bar").onclick = SearchField; - document.getElementById("custom-value").onclick = UpdateNewField; - document.getElementById("custom-value-type").onchange = ClearNewFields; - document.getElementById("add-custom-field").onkeyup = CheckNewFieldSubmit; - BuildUI(); -}, true); - -window.addEventListener("unload", function onUnload() { - window.removeEventListener("unload", onUnload); - AppManager.off("app-manager-update", OnAppManagerUpdate); -}); - -function CloseUI() { - window.parent.UI.openProject(); -} - -function OnAppManagerUpdate(event, what) { - if (what == "connection" || what == "runtime-global-actors") { - BuildUI(); - } -} - -function CheckNewFieldSubmit(event) { - configView.checkNewFieldSubmit(event); -} - -function UpdateNewField() { - configView.updateNewField(); -} - -function ClearNewFields() { - configView.clearNewFields(); -} - -function CheckReset(event) { - configView.checkReset(event); -} - -function UpdateField(event) { - configView.updateField(event); -} - -function SearchField(event) { - configView.search(event); -} - -var getAllSettings; // Used by tests -function BuildUI() { - configView.resetTable(); - - if (AppManager.connection && - AppManager.connection.status == Connection.Status.CONNECTED && - AppManager.settingsFront) { - configView.front = AppManager.settingsFront; - configView.kind = "Setting"; - configView.includeTypeName = false; - - getAllSettings = AppManager.settingsFront.getAllSettings() - .then(json => configView.generateDisplay(json)); - } else { - CloseUI(); - } -} diff --git a/devtools/client/webide/content/devicesettings.xhtml b/devtools/client/webide/content/devicesettings.xhtml deleted file mode 100644 index 0406c6f07..000000000 --- a/devtools/client/webide/content/devicesettings.xhtml +++ /dev/null @@ -1,50 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!DOCTYPE html [ - <!ENTITY % webideDTD SYSTEM "chrome://devtools/locale/webide.dtd" > - %webideDTD; -]> - -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <meta charset="utf8"/> - <link rel="stylesheet" href="chrome://webide/skin/deck.css" type="text/css"/> - <link rel="stylesheet" href="chrome://webide/skin/config-view.css" type="text/css"/> - <script type="application/javascript;version=1.8" src="chrome://webide/content/devicesettings.js"></script> - </head> - <body> - <header> - <div id="controls"> - <a id="close">&deck_close;</a> - </div> - <h1>&devicesetting_title;</h1> - <div id="search"> - <input type="text" id="search-bar" placeholder="&devicesetting_search;"/> - </div> - </header> - <table id="device-fields"> - <tr id="add-custom-field"> - <td> - <select id="custom-value-type"> - <option value="" selected="selected">&device_typenone;</option> - <option value="boolean">&device_typeboolean;</option> - <option value="number">&device_typenumber;</option> - <option value="string">&device_typestring;</option> - <option value="object">&device_typeobject;</option> - </select> - <input type="text" id="custom-value-name" placeholder="&devicesetting_newname;"/> - </td> - <td class="custom-input"> - <input type="text" id="custom-value-text" placeholder="&devicesetting_newtext;"/> - </td> - <td> - <button id="custom-value" class="new-editable">&devicesetting_addnew;</button> - </td> - </tr> - </table> - </body> -</html> diff --git a/devtools/client/webide/content/jar.mn b/devtools/client/webide/content/jar.mn deleted file mode 100644 index db79fdb51..000000000 --- a/devtools/client/webide/content/jar.mn +++ /dev/null @@ -1,38 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -webide.jar: -% content webide %content/ - content/webide.xul (webide.xul) - content/webide.js (webide.js) - content/newapp.xul (newapp.xul) - content/newapp.js (newapp.js) - content/details.xhtml (details.xhtml) - content/details.js (details.js) - content/addons.js (addons.js) - content/addons.xhtml (addons.xhtml) - content/permissionstable.js (permissionstable.js) - content/permissionstable.xhtml (permissionstable.xhtml) - content/runtimedetails.js (runtimedetails.js) - content/runtimedetails.xhtml (runtimedetails.xhtml) - content/prefs.js (prefs.js) - content/prefs.xhtml (prefs.xhtml) - content/monitor.xhtml (monitor.xhtml) - content/monitor.js (monitor.js) - content/devicepreferences.js (devicepreferences.js) - content/devicepreferences.xhtml (devicepreferences.xhtml) - content/devicesettings.js (devicesettings.js) - content/devicesettings.xhtml (devicesettings.xhtml) - content/wifi-auth.js (wifi-auth.js) - content/wifi-auth.xhtml (wifi-auth.xhtml) - content/logs.xhtml (logs.xhtml) - content/logs.js (logs.js) - content/project-listing.xhtml (project-listing.xhtml) - content/project-listing.js (project-listing.js) - content/project-panel.js (project-panel.js) - content/runtime-panel.js (runtime-panel.js) - content/runtime-listing.xhtml (runtime-listing.xhtml) - content/runtime-listing.js (runtime-listing.js) - content/simulator.js (simulator.js) - content/simulator.xhtml (simulator.xhtml) diff --git a/devtools/client/webide/content/logs.js b/devtools/client/webide/content/logs.js deleted file mode 100644 index 157d83b67..000000000 --- a/devtools/client/webide/content/logs.js +++ /dev/null @@ -1,70 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -var Cu = Components.utils; -const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); -const {AppManager} = require("devtools/client/webide/modules/app-manager"); - -window.addEventListener("load", function onLoad() { - window.removeEventListener("load", onLoad); - - Logs.init(); -}); - -window.addEventListener("unload", function onUnload() { - window.removeEventListener("unload", onUnload); - - Logs.uninit(); -}); - -const Logs = { - init: function () { - this.list = document.getElementById("logs"); - - Logs.onAppManagerUpdate = Logs.onAppManagerUpdate.bind(this); - AppManager.on("app-manager-update", Logs.onAppManagerUpdate); - - document.getElementById("close").onclick = Logs.close.bind(this); - }, - - uninit: function () { - AppManager.off("app-manager-update", Logs.onAppManagerUpdate); - }, - - onAppManagerUpdate: function (event, what, details) { - switch (what) { - case "pre-package": - this.prePackageLog(details); - break; - } - }, - - close: function () { - window.parent.UI.openProject(); - }, - - prePackageLog: function (msg, details) { - if (msg == "start") { - this.clear(); - } else if (msg == "succeed") { - setTimeout(function () { - Logs.close(); - }, 1000); - } else if (msg == "failed") { - this.log(details); - } else { - this.log(msg); - } - }, - - clear: function () { - this.list.innerHTML = ""; - }, - - log: function (msg) { - let line = document.createElement("li"); - line.textContent = msg; - this.list.appendChild(line); - } -}; diff --git a/devtools/client/webide/content/logs.xhtml b/devtools/client/webide/content/logs.xhtml deleted file mode 100644 index 8d003e509..000000000 --- a/devtools/client/webide/content/logs.xhtml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!DOCTYPE html [ - <!ENTITY % webideDTD SYSTEM "chrome://devtools/locale/webide.dtd" > - %webideDTD; -]> - -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <meta charset="utf8"/> - <link rel="stylesheet" href="chrome://webide/skin/deck.css" type="text/css"/> - <link rel="stylesheet" href="resource://devtools/client/themes/common.css" type="text/css"/> - <link rel="stylesheet" href="chrome://webide/skin/logs.css" type="text/css"/> - <script type="application/javascript;version=1.8" src="chrome://devtools/content/shared/theme-switching.js"></script> - <script type="application/javascript;version=1.8" src="logs.js"></script> - </head> - <body> - - <div id="controls"> - <a id="close">&deck_close;</a> - </div> - - <h1>&logs_title;</h1> - - <ul id="logs" class="devtools-monospace"> - </ul> - - </body> -</html> diff --git a/devtools/client/webide/content/monitor.js b/devtools/client/webide/content/monitor.js deleted file mode 100644 index a5d80d460..000000000 --- a/devtools/client/webide/content/monitor.js +++ /dev/null @@ -1,741 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -var Cu = Components.utils; -const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); -const Services = require("Services"); -const {AppManager} = require("devtools/client/webide/modules/app-manager"); -const {AppActorFront} = require("devtools/shared/apps/app-actor-front"); -const {Connection} = require("devtools/shared/client/connection-manager"); -const EventEmitter = require("devtools/shared/event-emitter"); - -window.addEventListener("load", function onLoad() { - window.removeEventListener("load", onLoad); - window.addEventListener("resize", Monitor.resize); - window.addEventListener("unload", Monitor.unload); - - document.querySelector("#close").onclick = () => { - window.parent.UI.openProject(); - }; - - Monitor.load(); -}); - - -/** - * The Monitor is a WebIDE tool used to display any kind of time-based data in - * the form of graphs. - * - * The data can come from a Firefox OS device, simulator, or from a WebSockets - * server running locally. - * - * The format of a data update is typically an object like: - * - * { graph: 'mygraph', curve: 'mycurve', value: 42, time: 1234 } - * - * or an array of such objects. For more details on the data format, see the - * `Graph.update(data)` method. - */ -var Monitor = { - - apps: new Map(), - graphs: new Map(), - front: null, - socket: null, - wstimeout: null, - b2ginfo: false, - b2gtimeout: null, - - /** - * Add new data to the graphs, create a new graph if necessary. - */ - update: function (data, fallback) { - if (Array.isArray(data)) { - data.forEach(d => Monitor.update(d, fallback)); - return; - } - - if (Monitor.b2ginfo && data.graph === "USS") { - // If we're polling b2g-info, ignore USS updates from the device's - // USSAgents (see Monitor.pollB2GInfo()). - return; - } - - if (fallback) { - for (let key in fallback) { - if (!data[key]) { - data[key] = fallback[key]; - } - } - } - - let graph = Monitor.graphs.get(data.graph); - if (!graph) { - let element = document.createElement("div"); - element.classList.add("graph"); - document.body.appendChild(element); - - graph = new Graph(data.graph, element); - Monitor.resize(); // a scrollbar might have dis/reappeared - Monitor.graphs.set(data.graph, graph); - } - graph.update(data); - }, - - /** - * Initialize the Monitor. - */ - load: function () { - AppManager.on("app-manager-update", Monitor.onAppManagerUpdate); - Monitor.connectToRuntime(); - Monitor.connectToWebSocket(); - }, - - /** - * Clean up the Monitor. - */ - unload: function () { - AppManager.off("app-manager-update", Monitor.onAppManagerUpdate); - Monitor.disconnectFromRuntime(); - Monitor.disconnectFromWebSocket(); - }, - - /** - * Resize all the graphs. - */ - resize: function () { - for (let graph of Monitor.graphs.values()) { - graph.resize(); - } - }, - - /** - * When WebIDE connects to a new runtime, start its data forwarders. - */ - onAppManagerUpdate: function (event, what, details) { - switch (what) { - case "runtime-global-actors": - Monitor.connectToRuntime(); - break; - case "connection": - if (AppManager.connection.status == Connection.Status.DISCONNECTED) { - Monitor.disconnectFromRuntime(); - } - break; - } - }, - - /** - * Use an AppActorFront on a runtime to watch track its apps. - */ - connectToRuntime: function () { - Monitor.pollB2GInfo(); - let client = AppManager.connection && AppManager.connection.client; - let resp = AppManager._listTabsResponse; - if (client && resp && !Monitor.front) { - Monitor.front = new AppActorFront(client, resp); - Monitor.front.watchApps(Monitor.onRuntimeAppEvent); - } - }, - - /** - * Destroy our AppActorFront. - */ - disconnectFromRuntime: function () { - Monitor.unpollB2GInfo(); - if (Monitor.front) { - Monitor.front.unwatchApps(Monitor.onRuntimeAppEvent); - Monitor.front = null; - } - }, - - /** - * Try connecting to a local websockets server and accept updates from it. - */ - connectToWebSocket: function () { - let webSocketURL = Services.prefs.getCharPref("devtools.webide.monitorWebSocketURL"); - try { - Monitor.socket = new WebSocket(webSocketURL); - Monitor.socket.onmessage = function (event) { - Monitor.update(JSON.parse(event.data)); - }; - Monitor.socket.onclose = function () { - Monitor.wstimeout = setTimeout(Monitor.connectToWebsocket, 1000); - }; - } catch (e) { - Monitor.wstimeout = setTimeout(Monitor.connectToWebsocket, 1000); - } - }, - - /** - * Used when cleaning up. - */ - disconnectFromWebSocket: function () { - clearTimeout(Monitor.wstimeout); - if (Monitor.socket) { - Monitor.socket.onclose = () => {}; - Monitor.socket.close(); - } - }, - - /** - * When an app starts on the runtime, start a monitor actor for its process. - */ - onRuntimeAppEvent: function (type, app) { - if (type !== "appOpen" && type !== "appClose") { - return; - } - - let client = AppManager.connection.client; - app.getForm().then(form => { - if (type === "appOpen") { - app.monitorClient = new MonitorClient(client, form); - app.monitorClient.start(); - app.monitorClient.on("update", Monitor.onRuntimeUpdate); - Monitor.apps.set(form.monitorActor, app); - } else { - let app = Monitor.apps.get(form.monitorActor); - if (app) { - app.monitorClient.stop(() => app.monitorClient.destroy()); - Monitor.apps.delete(form.monitorActor); - } - } - }); - }, - - /** - * Accept data updates from the monitor actors of a runtime. - */ - onRuntimeUpdate: function (type, packet) { - let fallback = {}, app = Monitor.apps.get(packet.from); - if (app) { - fallback.curve = app.manifest.name; - } - Monitor.update(packet.data, fallback); - }, - - /** - * Bug 1047355: If possible, parsing the output of `b2g-info` has several - * benefits over bug 1037465's multi-process USSAgent approach, notably: - * - Works for older Firefox OS devices (pre-2.1), - * - Doesn't need certified-apps debugging, - * - Polling time is synchronized for all processes. - * TODO: After bug 1043324 lands, consider removing this hack. - */ - pollB2GInfo: function () { - if (AppManager.selectedRuntime) { - let device = AppManager.selectedRuntime.device; - if (device && device.shell) { - device.shell("b2g-info").then(s => { - let lines = s.split("\n"); - let line = ""; - - // Find the header row to locate NAME and USS, looks like: - // ' NAME PID NICE USS PSS RSS VSIZE OOM_ADJ USER '. - while (line.indexOf("NAME") < 0) { - if (lines.length < 1) { - // Something is wrong with this output, don't trust b2g-info. - Monitor.unpollB2GInfo(); - return; - } - line = lines.shift(); - } - let namelength = line.indexOf("NAME") + "NAME".length; - let ussindex = line.slice(namelength).split(/\s+/).indexOf("USS"); - - // Get the NAME and USS in each following line, looks like: - // 'Homescreen 375 18 12.6 16.3 27.1 67.8 4 app_375'. - while (lines.length > 0 && lines[0].length > namelength) { - line = lines.shift(); - let name = line.slice(0, namelength); - let uss = line.slice(namelength).split(/\s+/)[ussindex]; - Monitor.update({ - curve: name.trim(), - value: 1024 * 1024 * parseFloat(uss) // Convert MB to bytes. - }, { - // Note: We use the fallback object to set the graph name to 'USS' - // so that Monitor.update() can ignore USSAgent updates. - graph: "USS" - }); - } - }); - } - } - Monitor.b2ginfo = true; - Monitor.b2gtimeout = setTimeout(Monitor.pollB2GInfo, 350); - }, - - /** - * Polling b2g-info doesn't work or is no longer needed. - */ - unpollB2GInfo: function () { - clearTimeout(Monitor.b2gtimeout); - Monitor.b2ginfo = false; - } - -}; - - -/** - * A MonitorClient is used as an actor client of a runtime's monitor actors, - * receiving its updates. - */ -function MonitorClient(client, form) { - this.client = client; - this.actor = form.monitorActor; - this.events = ["update"]; - - EventEmitter.decorate(this); - this.client.registerClient(this); -} -MonitorClient.prototype.destroy = function () { - this.client.unregisterClient(this); -}; -MonitorClient.prototype.start = function () { - this.client.request({ - to: this.actor, - type: "start" - }); -}; -MonitorClient.prototype.stop = function (callback) { - this.client.request({ - to: this.actor, - type: "stop" - }, callback); -}; - - -/** - * A Graph populates a container DOM element with an SVG graph and a legend. - */ -function Graph(name, element) { - this.name = name; - this.element = element; - this.curves = new Map(); - this.events = new Map(); - this.ignored = new Set(); - this.enabled = true; - this.request = null; - - this.x = d3.time.scale(); - this.y = d3.scale.linear(); - - this.xaxis = d3.svg.axis().scale(this.x).orient("bottom"); - this.yaxis = d3.svg.axis().scale(this.y).orient("left"); - - this.xformat = d3.time.format("%I:%M:%S"); - this.yformat = this.formatter(1); - this.yaxis.tickFormat(this.formatter(0)); - - this.line = d3.svg.line().interpolate("linear") - .x(function (d) { return this.x(d.time); }) - .y(function (d) { return this.y(d.value); }); - - this.color = d3.scale.category10(); - - this.svg = d3.select(element).append("svg").append("g") - .attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")"); - - this.xelement = this.svg.append("g").attr("class", "x axis").call(this.xaxis); - this.yelement = this.svg.append("g").attr("class", "y axis").call(this.yaxis); - - // RULERS on axes - let xruler = this.xruler = this.svg.select(".x.axis").append("g").attr("class", "x ruler"); - xruler.append("line").attr("y2", 6); - xruler.append("line").attr("stroke-dasharray", "1,1"); - xruler.append("text").attr("y", 9).attr("dy", ".71em"); - - let yruler = this.yruler = this.svg.select(".y.axis").append("g").attr("class", "y ruler"); - yruler.append("line").attr("x2", -6); - yruler.append("line").attr("stroke-dasharray", "1,1"); - yruler.append("text").attr("x", -9).attr("dy", ".32em"); - - let self = this; - - d3.select(element).select("svg") - .on("mousemove", function () { - let mouse = d3.mouse(this); - self.mousex = mouse[0] - self.margin.left, - self.mousey = mouse[1] - self.margin.top; - - xruler.attr("transform", "translate(" + self.mousex + ",0)"); - yruler.attr("transform", "translate(0," + self.mousey + ")"); - }); - /* .on('mouseout', function() { - self.xruler.attr('transform', 'translate(-500,0)'); - self.yruler.attr('transform', 'translate(0,-500)'); - });*/ - this.mousex = this.mousey = -500; - - let sidebar = d3.select(this.element).append("div").attr("class", "sidebar"); - let title = sidebar.append("label").attr("class", "graph-title"); - - title.append("input") - .attr("type", "checkbox") - .attr("checked", "true") - .on("click", function () { self.toggle(); }); - title.append("span").text(this.name); - - this.legend = sidebar.append("div").attr("class", "legend"); - - this.resize = this.resize.bind(this); - this.render = this.render.bind(this); - this.averages = this.averages.bind(this); - - setInterval(this.averages, 1000); - - this.resize(); -} - -Graph.prototype = { - - /** - * These margin are used to properly position the SVG graph items inside the - * container element. - */ - margin: { - top: 10, - right: 150, - bottom: 20, - left: 50 - }, - - /** - * A Graph can be collapsed by the user. - */ - toggle: function () { - if (this.enabled) { - this.element.classList.add("disabled"); - this.enabled = false; - } else { - this.element.classList.remove("disabled"); - this.enabled = true; - } - Monitor.resize(); - }, - - /** - * If the container element is resized (e.g. because the window was resized or - * a scrollbar dis/appeared), the graph needs to be resized as well. - */ - resize: function () { - let style = getComputedStyle(this.element), - height = parseFloat(style.height) - this.margin.top - this.margin.bottom, - width = parseFloat(style.width) - this.margin.left - this.margin.right; - - d3.select(this.element).select("svg") - .attr("width", width + this.margin.left) - .attr("height", height + this.margin.top + this.margin.bottom); - - this.x.range([0, width]); - this.y.range([height, 0]); - - this.xelement.attr("transform", "translate(0," + height + ")"); - this.xruler.select("line[stroke-dasharray]").attr("y2", -height); - this.yruler.select("line[stroke-dasharray]").attr("x2", width); - }, - - /** - * If the domain of the Graph's data changes (on the time axis and/or on the - * value axis), the axes' domains need to be updated and the graph items need - * to be rescaled in order to represent all the data. - */ - rescale: function () { - let gettime = v => { return v.time; }, - getvalue = v => { return v.value; }, - ignored = c => { return this.ignored.has(c.id); }; - - let xmin = null, xmax = null, ymin = null, ymax = null; - for (let curve of this.curves.values()) { - if (ignored(curve)) { - continue; - } - if (xmax == null || curve.xmax > xmax) { - xmax = curve.xmax; - } - if (xmin == null || curve.xmin < xmin) { - xmin = curve.xmin; - } - if (ymax == null || curve.ymax > ymax) { - ymax = curve.ymax; - } - if (ymin == null || curve.ymin < ymin) { - ymin = curve.ymin; - } - } - for (let event of this.events.values()) { - if (ignored(event)) { - continue; - } - if (xmax == null || event.xmax > xmax) { - xmax = event.xmax; - } - if (xmin == null || event.xmin < xmin) { - xmin = event.xmin; - } - } - - let oldxdomain = this.x.domain(); - if (xmin != null && xmax != null) { - this.x.domain([xmin, xmax]); - let newxdomain = this.x.domain(); - if (newxdomain[0] !== oldxdomain[0] || newxdomain[1] !== oldxdomain[1]) { - this.xelement.call(this.xaxis); - } - } - - let oldydomain = this.y.domain(); - if (ymin != null && ymax != null) { - this.y.domain([ymin, ymax]).nice(); - let newydomain = this.y.domain(); - if (newydomain[0] !== oldydomain[0] || newydomain[1] !== oldydomain[1]) { - this.yelement.call(this.yaxis); - } - } - }, - - /** - * Add new values to the graph. - */ - update: function (data) { - delete data.graph; - - let time = data.time || Date.now(); - delete data.time; - - let curve = data.curve; - delete data.curve; - - // Single curve value, e.g. { curve: 'memory', value: 42, time: 1234 }. - if ("value" in data) { - this.push(this.curves, curve, [{time: time, value: data.value}]); - delete data.value; - } - - // Several curve values, e.g. { curve: 'memory', values: [{value: 42, time: 1234}] }. - if ("values" in data) { - this.push(this.curves, curve, data.values); - delete data.values; - } - - // Punctual event, e.g. { event: 'gc', time: 1234 }, - // event with duration, e.g. { event: 'jank', duration: 425, time: 1234 }. - if ("event" in data) { - this.push(this.events, data.event, [{time: time, value: data.duration}]); - delete data.event; - delete data.duration; - } - - // Remaining keys are curves, e.g. { time: 1234, memory: 42, battery: 13, temperature: 45 }. - for (let key in data) { - this.push(this.curves, key, [{time: time, value: data[key]}]); - } - - // If no render is currently pending, request one. - if (this.enabled && !this.request) { - this.request = requestAnimationFrame(this.render); - } - }, - - /** - * Insert new data into the graph's data structures. - */ - push: function (collection, id, values) { - - // Note: collection is either `this.curves` or `this.events`. - let item = collection.get(id); - if (!item) { - item = { id: id, values: [], xmin: null, xmax: null, ymin: 0, ymax: null, average: 0 }; - collection.set(id, item); - } - - for (let v of values) { - let time = new Date(v.time), value = +v.value; - // Update the curve/event's domain values. - if (item.xmax == null || time > item.xmax) { - item.xmax = time; - } - if (item.xmin == null || time < item.xmin) { - item.xmin = time; - } - if (item.ymax == null || value > item.ymax) { - item.ymax = value; - } - if (item.ymin == null || value < item.ymin) { - item.ymin = value; - } - // Note: A curve's average is not computed here. Call `graph.averages()`. - item.values.push({ time: time, value: value }); - } - }, - - /** - * Render the SVG graph with curves, events, crosshair and legend. - */ - render: function () { - this.request = null; - this.rescale(); - - - // DATA - - let self = this, - getid = d => { return d.id; }, - gettime = d => { return d.time.getTime(); }, - getline = d => { return self.line(d.values); }, - getcolor = d => { return self.color(d.id); }, - getvalues = d => { return d.values; }, - ignored = d => { return self.ignored.has(d.id); }; - - // Convert our maps to arrays for d3. - let curvedata = [...this.curves.values()], - eventdata = [...this.events.values()], - data = curvedata.concat(eventdata); - - - // CURVES - - // Map curve data to curve elements. - let curves = this.svg.selectAll(".curve").data(curvedata, getid); - - // Create new curves (no element corresponding to the data). - curves.enter().append("g").attr("class", "curve").append("path") - .style("stroke", getcolor); - - // Delete old curves (elements corresponding to data not present anymore). - curves.exit().remove(); - - // Update all curves from data. - this.svg.selectAll(".curve").select("path") - .attr("d", d => { return ignored(d) ? "" : getline(d); }); - - let height = parseFloat(getComputedStyle(this.element).height) - this.margin.top - this.margin.bottom; - - - // EVENTS - - // Map event data to event elements. - let events = this.svg.selectAll(".event-slot").data(eventdata, getid); - - // Create new events. - events.enter().append("g").attr("class", "event-slot"); - - // Remove old events. - events.exit().remove(); - - // Get all occurences of an event, and map its data to them. - let lines = this.svg.selectAll(".event-slot") - .style("stroke", d => { return ignored(d) ? "none" : getcolor(d); }) - .selectAll(".event") - .data(getvalues, gettime); - - // Create new event occurrence. - lines.enter().append("line").attr("class", "event").attr("y2", height); - - // Delete old event occurrence. - lines.exit().remove(); - - // Update all event occurrences from data. - this.svg.selectAll(".event") - .attr("transform", d => { return "translate(" + self.x(d.time) + ",0)"; }); - - - // CROSSHAIR - - // TODO select curves and events, intersect with curves and show values/hovers - // e.g. look like http://code.shutterstock.com/rickshaw/examples/lines.html - - // Update crosshair labels on each axis. - this.xruler.select("text").text(self.xformat(self.x.invert(self.mousex))); - this.yruler.select("text").text(self.yformat(self.y.invert(self.mousey))); - - - // LEGEND - - // Map data to legend elements. - let legends = this.legend.selectAll("label").data(data, getid); - - // Update averages. - legends.attr("title", c => { return "Average: " + self.yformat(c.average); }); - - // Create new legends. - let newlegend = legends.enter().append("label"); - newlegend.append("input").attr("type", "checkbox").attr("checked", "true").on("click", function (c) { - if (ignored(c)) { - this.parentElement.classList.remove("disabled"); - self.ignored.delete(c.id); - } else { - this.parentElement.classList.add("disabled"); - self.ignored.add(c.id); - } - self.update({}); // if no re-render is pending, request one. - }); - newlegend.append("span").attr("class", "legend-color").style("background-color", getcolor); - newlegend.append("span").attr("class", "legend-id").text(getid); - - // Delete old legends. - legends.exit().remove(); - }, - - /** - * Returns a SI value formatter with a given precision. - */ - formatter: function (decimals) { - return value => { - // Don't use sub-unit SI prefixes (milli, micro, etc.). - if (Math.abs(value) < 1) return value.toFixed(decimals); - // SI prefix, e.g. 1234567 will give '1.2M' at precision 1. - let prefix = d3.formatPrefix(value); - return prefix.scale(value).toFixed(decimals) + prefix.symbol; - }; - }, - - /** - * Compute the average of each time series. - */ - averages: function () { - for (let c of this.curves.values()) { - let length = c.values.length; - if (length > 0) { - let total = 0; - c.values.forEach(v => total += v.value); - c.average = (total / length); - } - } - }, - - /** - * Bisect a time serie to find the data point immediately left of `time`. - */ - bisectTime: d3.bisector(d => d.time).left, - - /** - * Get all curve values at a given time. - */ - valuesAt: function (time) { - let values = { time: time }; - - for (let id of this.curves.keys()) { - let curve = this.curves.get(id); - - // Find the closest value just before `time`. - let i = this.bisectTime(curve.values, time); - if (i < 0) { - // Curve starts after `time`, use first value. - values[id] = curve.values[0].value; - } else if (i > curve.values.length - 2) { - // Curve ends before `time`, use last value. - values[id] = curve.values[curve.values.length - 1].value; - } else { - // Curve has two values around `time`, interpolate. - let v1 = curve.values[i], - v2 = curve.values[i + 1], - delta = (time - v1.time) / (v2.time - v1.time); - values[id] = v1.value + (v2.value - v1.time) * delta; - } - } - return values; - } - -}; diff --git a/devtools/client/webide/content/monitor.xhtml b/devtools/client/webide/content/monitor.xhtml deleted file mode 100644 index 552f3826c..000000000 --- a/devtools/client/webide/content/monitor.xhtml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!DOCTYPE html [ - <!ENTITY % webideDTD SYSTEM "chrome://devtools/locale/webide.dtd" > - %webideDTD; -]> - - -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <meta charset="utf8"/> - <link rel="stylesheet" href="chrome://webide/skin/deck.css" type="text/css"/> - <link rel="stylesheet" href="chrome://webide/skin/monitor.css" type="text/css"/> - <script src="chrome://devtools/content/shared/vendor/d3.js"></script> - <script type="application/javascript;version=1.8" src="monitor.js"></script> - </head> - <body> - - <div id="controls"> - <a href="https://developer.mozilla.org/docs/Tools/WebIDE/Monitor" target="_blank">&monitor_help;</a> - <a id="close">&deck_close;</a> - </div> - - <h1>&monitor_title;</h1> - - </body> -</html> diff --git a/devtools/client/webide/content/moz.build b/devtools/client/webide/content/moz.build deleted file mode 100644 index aac3a838c..000000000 --- a/devtools/client/webide/content/moz.build +++ /dev/null @@ -1,7 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -JAR_MANIFESTS += ['jar.mn'] diff --git a/devtools/client/webide/content/newapp.js b/devtools/client/webide/content/newapp.js deleted file mode 100644 index d47bfabec..000000000 --- a/devtools/client/webide/content/newapp.js +++ /dev/null @@ -1,175 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -var Cc = Components.classes; -var Cu = Components.utils; -var Ci = Components.interfaces; - -const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); -const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm"); -const Services = require("Services"); -const {FileUtils} = require("resource://gre/modules/FileUtils.jsm"); -const {AppProjects} = require("devtools/client/webide/modules/app-projects"); -const {AppManager} = require("devtools/client/webide/modules/app-manager"); -const {getJSON} = require("devtools/client/shared/getjson"); - -XPCOMUtils.defineLazyModuleGetter(this, "ZipUtils", "resource://gre/modules/ZipUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "Downloads", "resource://gre/modules/Downloads.jsm"); - -const TEMPLATES_URL = "devtools.webide.templatesURL"; - -var gTemplateList = null; - -// See bug 989619 -console.log = console.log.bind(console); -console.warn = console.warn.bind(console); -console.error = console.error.bind(console); - -window.addEventListener("load", function onLoad() { - window.removeEventListener("load", onLoad); - let projectNameNode = document.querySelector("#project-name"); - projectNameNode.addEventListener("input", canValidate, true); - getTemplatesJSON(); -}, true); - -function getTemplatesJSON() { - getJSON(TEMPLATES_URL).then(list => { - if (!Array.isArray(list)) { - throw new Error("JSON response not an array"); - } - if (list.length == 0) { - throw new Error("JSON response is an empty array"); - } - gTemplateList = list; - let templatelistNode = document.querySelector("#templatelist"); - templatelistNode.innerHTML = ""; - for (let template of list) { - let richlistitemNode = document.createElement("richlistitem"); - let imageNode = document.createElement("image"); - imageNode.setAttribute("src", template.icon); - let labelNode = document.createElement("label"); - labelNode.setAttribute("value", template.name); - let descriptionNode = document.createElement("description"); - descriptionNode.textContent = template.description; - let vboxNode = document.createElement("vbox"); - vboxNode.setAttribute("flex", "1"); - richlistitemNode.appendChild(imageNode); - vboxNode.appendChild(labelNode); - vboxNode.appendChild(descriptionNode); - richlistitemNode.appendChild(vboxNode); - templatelistNode.appendChild(richlistitemNode); - } - templatelistNode.selectedIndex = 0; - - /* Chrome mochitest support */ - let testOptions = window.arguments[0].testOptions; - if (testOptions) { - templatelistNode.selectedIndex = testOptions.index; - document.querySelector("#project-name").value = testOptions.name; - doOK(); - } - }, (e) => { - failAndBail("Can't download app templates: " + e); - }); -} - -function failAndBail(msg) { - let promptService = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService); - promptService.alert(window, "error", msg); - window.close(); -} - -function canValidate() { - let projectNameNode = document.querySelector("#project-name"); - let dialogNode = document.querySelector("dialog"); - if (projectNameNode.value.length > 0) { - dialogNode.removeAttribute("buttondisabledaccept"); - } else { - dialogNode.setAttribute("buttondisabledaccept", "true"); - } -} - -function doOK() { - let projectName = document.querySelector("#project-name").value; - - if (!projectName) { - console.error("No project name"); - return false; - } - - if (!gTemplateList) { - console.error("No template index"); - return false; - } - - let templatelistNode = document.querySelector("#templatelist"); - if (templatelistNode.selectedIndex < 0) { - console.error("No template selected"); - return false; - } - - let folder; - - /* Chrome mochitest support */ - let testOptions = window.arguments[0].testOptions; - if (testOptions) { - folder = testOptions.folder; - } else { - let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); - fp.init(window, "Select directory where to create app directory", Ci.nsIFilePicker.modeGetFolder); - let res = fp.show(); - if (res == Ci.nsIFilePicker.returnCancel) { - console.error("No directory selected"); - return false; - } - folder = fp.file; - } - - // Create subfolder with fs-friendly name of project - let subfolder = projectName.replace(/[\\/:*?"<>|]/g, "").toLowerCase(); - let win = Services.wm.getMostRecentWindow("devtools:webide"); - folder.append(subfolder); - - try { - folder.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); - } catch (e) { - win.UI.reportError("error_folderCreationFailed"); - window.close(); - return false; - } - - // Download boilerplate zip - let template = gTemplateList[templatelistNode.selectedIndex]; - let source = template.file; - let target = folder.clone(); - target.append(subfolder + ".zip"); - - let bail = (e) => { - console.error(e); - window.close(); - }; - - Downloads.fetch(source, target).then(() => { - ZipUtils.extractFiles(target, folder); - target.remove(false); - AppProjects.addPackaged(folder).then((project) => { - window.arguments[0].location = project.location; - AppManager.validateAndUpdateProject(project).then(() => { - if (project.manifest) { - project.manifest.name = projectName; - AppManager.writeManifest(project).then(() => { - AppManager.validateAndUpdateProject(project).then( - () => {window.close();}, bail); - }, bail); - } else { - bail("Manifest not found"); - } - }, bail); - }, bail); - }, bail); - - return false; -} diff --git a/devtools/client/webide/content/newapp.xul b/devtools/client/webide/content/newapp.xul deleted file mode 100644 index 7ff083519..000000000 --- a/devtools/client/webide/content/newapp.xul +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!DOCTYPE window [ - <!ENTITY % webideDTD SYSTEM "chrome://devtools/locale/webide.dtd" > - %webideDTD; -]> - -<?xml-stylesheet href="chrome://global/skin/global.css"?> -<?xml-stylesheet href="chrome://webide/skin/newapp.css"?> - -<dialog id="webide:newapp" title="&newAppWindowTitle;" - width="600" height="400" - buttons="accept,cancel" - ondialogaccept="return doOK();" - buttondisabledaccept="true" - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> - - <script type="application/javascript" src="newapp.js"></script> - <label class="header-name" value="&newAppHeader;"/> - - <richlistbox id="templatelist" flex="1"> - <description>&newAppLoadingTemplate;</description> - </richlistbox> - <vbox> - <label class="header-name" control="project-name" value="&newAppProjectName;"/> - <textbox id="project-name"/> - </vbox> - -</dialog> diff --git a/devtools/client/webide/content/permissionstable.js b/devtools/client/webide/content/permissionstable.js deleted file mode 100644 index 22c74bd0d..000000000 --- a/devtools/client/webide/content/permissionstable.js +++ /dev/null @@ -1,78 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -var Cu = Components.utils; -const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); -const Services = require("Services"); -const {AppManager} = require("devtools/client/webide/modules/app-manager"); -const {Connection} = require("devtools/shared/client/connection-manager"); - -window.addEventListener("load", function onLoad() { - window.removeEventListener("load", onLoad); - document.querySelector("#close").onclick = CloseUI; - AppManager.on("app-manager-update", OnAppManagerUpdate); - BuildUI(); -}, true); - -window.addEventListener("unload", function onUnload() { - window.removeEventListener("unload", onUnload); - AppManager.off("app-manager-update", OnAppManagerUpdate); -}); - -function CloseUI() { - window.parent.UI.openProject(); -} - -function OnAppManagerUpdate(event, what) { - if (what == "connection" || what == "runtime-global-actors") { - BuildUI(); - } -} - -function generateFields(json) { - let table = document.querySelector("table"); - let permissionsTable = json.rawPermissionsTable; - for (let name in permissionsTable) { - let tr = document.createElement("tr"); - tr.className = "line"; - let td = document.createElement("td"); - td.textContent = name; - tr.appendChild(td); - for (let type of ["app", "privileged", "certified"]) { - let td = document.createElement("td"); - if (permissionsTable[name][type] == json.ALLOW_ACTION) { - td.textContent = "✓"; - td.className = "permallow"; - } - if (permissionsTable[name][type] == json.PROMPT_ACTION) { - td.textContent = "!"; - td.className = "permprompt"; - } - if (permissionsTable[name][type] == json.DENY_ACTION) { - td.textContent = "✕"; - td.className = "permdeny"; - } - tr.appendChild(td); - } - table.appendChild(tr); - } -} - -var getRawPermissionsTablePromise; // Used by tests -function BuildUI() { - let table = document.querySelector("table"); - let lines = table.querySelectorAll(".line"); - for (let line of lines) { - line.remove(); - } - - if (AppManager.connection && - AppManager.connection.status == Connection.Status.CONNECTED && - AppManager.deviceFront) { - getRawPermissionsTablePromise = AppManager.deviceFront.getRawPermissionsTable() - .then(json => generateFields(json)); - } else { - CloseUI(); - } -} diff --git a/devtools/client/webide/content/permissionstable.xhtml b/devtools/client/webide/content/permissionstable.xhtml deleted file mode 100644 index 361cfece8..000000000 --- a/devtools/client/webide/content/permissionstable.xhtml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!DOCTYPE html [ - <!ENTITY % webideDTD SYSTEM "chrome://devtools/locale/webide.dtd" > - %webideDTD; -]> - -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <meta charset="utf8"/> - <link rel="stylesheet" href="chrome://webide/skin/deck.css" type="text/css"/> - <link rel="stylesheet" href="chrome://webide/skin/permissionstable.css" type="text/css"/> - <script type="application/javascript;version=1.8" src="chrome://webide/content/permissionstable.js"></script> - </head> - <body> - - <div id="controls"> - <a id="close">&deck_close;</a> - </div> - - <h1>&permissionstable_title;</h1> - - <table class="permissionstable"> - <tr> - <th>&permissionstable_name_header;</th> - <th>type:web</th> - <th>type:privileged</th> - <th>type:certified</th> - </tr> - </table> - </body> -</html> diff --git a/devtools/client/webide/content/prefs.js b/devtools/client/webide/content/prefs.js deleted file mode 100644 index 75f6233ba..000000000 --- a/devtools/client/webide/content/prefs.js +++ /dev/null @@ -1,108 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const Cu = Components.utils; -const {Services} = Cu.import("resource://gre/modules/Services.jsm", {}); - -window.addEventListener("load", function onLoad() { - window.removeEventListener("load", onLoad); - - // Listen to preference changes - let inputs = document.querySelectorAll("[data-pref]"); - for (let i of inputs) { - let pref = i.dataset.pref; - Services.prefs.addObserver(pref, FillForm, false); - i.addEventListener("change", SaveForm, false); - } - - // Buttons - document.querySelector("#close").onclick = CloseUI; - document.querySelector("#restore").onclick = RestoreDefaults; - document.querySelector("#manageComponents").onclick = ShowAddons; - - // Initialize the controls - FillForm(); - -}, true); - -window.addEventListener("unload", function onUnload() { - window.removeEventListener("unload", onUnload); - let inputs = document.querySelectorAll("[data-pref]"); - for (let i of inputs) { - let pref = i.dataset.pref; - i.removeEventListener("change", SaveForm, false); - Services.prefs.removeObserver(pref, FillForm, false); - } -}, true); - -function CloseUI() { - window.parent.UI.openProject(); -} - -function ShowAddons() { - window.parent.Cmds.showAddons(); -} - -function FillForm() { - let inputs = document.querySelectorAll("[data-pref]"); - for (let i of inputs) { - let pref = i.dataset.pref; - let val = GetPref(pref); - if (i.type == "checkbox") { - i.checked = val; - } else { - i.value = val; - } - } -} - -function SaveForm(e) { - let inputs = document.querySelectorAll("[data-pref]"); - for (let i of inputs) { - let pref = i.dataset.pref; - if (i.type == "checkbox") { - SetPref(pref, i.checked); - } else { - SetPref(pref, i.value); - } - } -} - -function GetPref(name) { - let type = Services.prefs.getPrefType(name); - switch (type) { - case Services.prefs.PREF_STRING: - return Services.prefs.getCharPref(name); - case Services.prefs.PREF_INT: - return Services.prefs.getIntPref(name); - case Services.prefs.PREF_BOOL: - return Services.prefs.getBoolPref(name); - default: - throw new Error("Unknown type"); - } -} - -function SetPref(name, value) { - let type = Services.prefs.getPrefType(name); - switch (type) { - case Services.prefs.PREF_STRING: - return Services.prefs.setCharPref(name, value); - case Services.prefs.PREF_INT: - return Services.prefs.setIntPref(name, value); - case Services.prefs.PREF_BOOL: - return Services.prefs.setBoolPref(name, value); - default: - throw new Error("Unknown type"); - } -} - -function RestoreDefaults() { - let inputs = document.querySelectorAll("[data-pref]"); - for (let i of inputs) { - let pref = i.dataset.pref; - Services.prefs.clearUserPref(pref); - } -} diff --git a/devtools/client/webide/content/prefs.xhtml b/devtools/client/webide/content/prefs.xhtml deleted file mode 100644 index 726ca772c..000000000 --- a/devtools/client/webide/content/prefs.xhtml +++ /dev/null @@ -1,112 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!DOCTYPE html [ - <!ENTITY % webideDTD SYSTEM "chrome://devtools/locale/webide.dtd" > - %webideDTD; -]> - -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <meta charset="utf8"/> - <link rel="stylesheet" href="chrome://webide/skin/deck.css" type="text/css"/> - <script type="application/javascript;version=1.8" src="chrome://webide/content/prefs.js"></script> - </head> - <body> - - <div id="controls"> - <a id="restore">&prefs_restore;</a> - <a id="manageComponents">&prefs_manage_components;</a> - <a id="close">&deck_close;</a> - </div> - - <h1>&prefs_title;</h1> - - <h2>&prefs_general_title;</h2> - - <ul> - <li> - <label title="&prefs_options_showeditor_tooltip;"> - <input type="checkbox" data-pref="devtools.webide.showProjectEditor"/> - <span>&prefs_options_showeditor;</span> - </label> - </li> - <li> - <label title="&prefs_options_rememberlastproject_tooltip;"> - <input type="checkbox" data-pref="devtools.webide.restoreLastProject"/> - <span>&prefs_options_rememberlastproject;</span> - </label> - </li> - <li> - <label title="&prefs_options_autoconnectruntime_tooltip;"> - <input type="checkbox" data-pref="devtools.webide.autoConnectRuntime"/> - <span>&prefs_options_autoconnectruntime;</span> - </label> - </li> - <li> - <label class="text-input" title="&prefs_options_templatesurl_tooltip;"> - <span>&prefs_options_templatesurl;</span> - <input data-pref="devtools.webide.templatesURL"/> - </label> - </li> - </ul> - - <h2>&prefs_editor_title;</h2> - - <ul> - <li> - <label><span>&prefs_options_tabsize;</span> - <select data-pref="devtools.editor.tabsize"> - <option value="2">2</option> - <option value="4">4</option> - <option value="8">8</option> - </select> - </label> - </li> - <li> - <label title="&prefs_options_expandtab_tooltip;"> - <input type="checkbox" data-pref="devtools.editor.expandtab"/> - <span>&prefs_options_expandtab;</span> - </label> - </li> - <li> - <label title="&prefs_options_detectindentation_tooltip;"> - <input type="checkbox" data-pref="devtools.editor.detectindentation"/> - <span>&prefs_options_detectindentation;</span> - </label> - </li> - <li> - <label title="&prefs_options_autocomplete_tooltip;"> - <input type="checkbox" data-pref="devtools.editor.autocomplete"/> - <span>&prefs_options_autocomplete;</span> - </label> - </li> - <li> - <label title="&prefs_options_autoclosebrackets_tooltip;"> - <input type="checkbox" data-pref="devtools.editor.autoclosebrackets"/> - <span>&prefs_options_autoclosebrackets;</span> - </label> - </li> - <li> - <label title="&prefs_options_autosavefiles_tooltip;"> - <input type="checkbox" data-pref="devtools.webide.autosaveFiles"/> - <span>&prefs_options_autosavefiles;</span> - </label> - </li> - <li> - <label><span>&prefs_options_keybindings;</span> - <select data-pref="devtools.editor.keymap"> - <option value="default">&prefs_options_keybindings_default;</option> - <option value="vim">Vim</option> - <option value="emacs">Emacs</option> - <option value="sublime">Sublime</option> - </select> - </label> - </li> - </ul> - - </body> -</html> diff --git a/devtools/client/webide/content/project-listing.js b/devtools/client/webide/content/project-listing.js deleted file mode 100644 index 5641f6c0c..000000000 --- a/devtools/client/webide/content/project-listing.js +++ /dev/null @@ -1,42 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* eslint-env browser */ - -var Cu = Components.utils; -const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); -const ProjectList = require("devtools/client/webide/modules/project-list"); - -var projectList = new ProjectList(window, window.parent); - -window.addEventListener("load", function onLoad() { - window.removeEventListener("load", onLoad, true); - document.getElementById("new-app").onclick = CreateNewApp; - document.getElementById("hosted-app").onclick = ImportHostedApp; - document.getElementById("packaged-app").onclick = ImportPackagedApp; - document.getElementById("refresh-tabs").onclick = RefreshTabs; - projectList.update(); - projectList.updateCommands(); -}, true); - -window.addEventListener("unload", function onUnload() { - window.removeEventListener("unload", onUnload); - projectList.destroy(); -}); - -function RefreshTabs() { - projectList.refreshTabs(); -} - -function CreateNewApp() { - projectList.newApp(); -} - -function ImportHostedApp() { - projectList.importHostedApp(); -} - -function ImportPackagedApp() { - projectList.importPackagedApp(); -} diff --git a/devtools/client/webide/content/project-listing.xhtml b/devtools/client/webide/content/project-listing.xhtml deleted file mode 100644 index 337befe5d..000000000 --- a/devtools/client/webide/content/project-listing.xhtml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!DOCTYPE html [ - <!ENTITY % webideDTD SYSTEM "chrome://devtools/locale/webide.dtd" > - %webideDTD; -]> - -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <meta charset="utf8"/> - <link rel="stylesheet" href="chrome://webide/skin/panel-listing.css" type="text/css"/> - <script type="application/javascript;version=1.8" src="chrome://webide/content/project-listing.js"></script> - </head> - <body> - <div id="project-panel"> - <div id="project-panel-box"> - <button class="panel-item project-panel-item-newapp" id="new-app">&projectMenu_newApp_label;</button> - <button class="panel-item project-panel-item-openpackaged" id="packaged-app">&projectMenu_importPackagedApp_label;</button> - <button class="panel-item project-panel-item-openhosted" id="hosted-app">&projectMenu_importHostedApp_label;</button> - <label class="panel-header">&projectPanel_myProjects;</label> - <div id="project-panel-projects"></div> - <label class="panel-header" id="panel-header-runtimeapps" hidden="true">&projectPanel_runtimeApps;</label> - <div id="project-panel-runtimeapps"/> - <label class="panel-header" id="panel-header-tabs" hidden="true">&projectPanel_tabs; - <button class="project-panel-item-refreshtabs refresh-icon" id="refresh-tabs" title="&projectMenu_refreshTabs_label;"></button> - </label> - <div id="project-panel-tabs"/> - </div> - </div> - </body> -</html> diff --git a/devtools/client/webide/content/project-panel.js b/devtools/client/webide/content/project-panel.js deleted file mode 100644 index 54eab8251..000000000 --- a/devtools/client/webide/content/project-panel.js +++ /dev/null @@ -1,11 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -var ProjectPanel = { - // TODO: Expand function to save toggle state. - toggleSidebar: function () { - document.querySelector("#project-listing-panel").setAttribute("sidebar-displayed", true); - document.querySelector("#project-listing-splitter").setAttribute("sidebar-displayed", true); - } -}; diff --git a/devtools/client/webide/content/runtime-listing.js b/devtools/client/webide/content/runtime-listing.js deleted file mode 100644 index 0a1a40a2a..000000000 --- a/devtools/client/webide/content/runtime-listing.js +++ /dev/null @@ -1,66 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -var Cu = Components.utils; -const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); -const RuntimeList = require("devtools/client/webide/modules/runtime-list"); - -var runtimeList = new RuntimeList(window, window.parent); - -window.addEventListener("load", function onLoad() { - window.removeEventListener("load", onLoad, true); - document.getElementById("runtime-screenshot").onclick = TakeScreenshot; - document.getElementById("runtime-permissions").onclick = ShowPermissionsTable; - document.getElementById("runtime-details").onclick = ShowRuntimeDetails; - document.getElementById("runtime-disconnect").onclick = DisconnectRuntime; - document.getElementById("runtime-preferences").onclick = ShowDevicePreferences; - document.getElementById("runtime-settings").onclick = ShowSettings; - document.getElementById("runtime-panel-installsimulator").onclick = ShowAddons; - document.getElementById("runtime-panel-noadbhelper").onclick = ShowAddons; - document.getElementById("runtime-panel-nousbdevice").onclick = ShowTroubleShooting; - document.getElementById("refresh-devices").onclick = RefreshScanners; - runtimeList.update(); - runtimeList.updateCommands(); -}, true); - -window.addEventListener("unload", function onUnload() { - window.removeEventListener("unload", onUnload); - runtimeList.destroy(); -}); - -function TakeScreenshot() { - runtimeList.takeScreenshot(); -} - -function ShowRuntimeDetails() { - runtimeList.showRuntimeDetails(); -} - -function ShowPermissionsTable() { - runtimeList.showPermissionsTable(); -} - -function ShowDevicePreferences() { - runtimeList.showDevicePreferences(); -} - -function ShowSettings() { - runtimeList.showSettings(); -} - -function RefreshScanners() { - runtimeList.refreshScanners(); -} - -function DisconnectRuntime() { - window.parent.Cmds.disconnectRuntime(); -} - -function ShowAddons() { - runtimeList.showAddons(); -} - -function ShowTroubleShooting() { - runtimeList.showTroubleShooting(); -} diff --git a/devtools/client/webide/content/runtime-listing.xhtml b/devtools/client/webide/content/runtime-listing.xhtml deleted file mode 100644 index f648fac12..000000000 --- a/devtools/client/webide/content/runtime-listing.xhtml +++ /dev/null @@ -1,45 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!DOCTYPE html [ - <!ENTITY % webideDTD SYSTEM "chrome://devtools/locale/webide.dtd" > - %webideDTD; -]> - -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <meta charset="utf8"/> - <link rel="stylesheet" href="chrome://webide/skin/panel-listing.css" type="text/css"/> - <script type="application/javascript;version=1.8" src="chrome://webide/content/runtime-listing.js"></script> - </head> - <body> - <div id="runtime-panel"> - <div id="runtime-panel-box"> - <label class="panel-header">&runtimePanel_usb; - <button class="runtime-panel-item-refreshdevices refresh-icon" id="refresh-devices" title="&runtimePanel_refreshDevices_label;"></button> - </label> - <button class="panel-item" id="runtime-panel-nousbdevice">&runtimePanel_nousbdevice;</button> - <button class="panel-item" id="runtime-panel-noadbhelper">&runtimePanel_noadbhelper;</button> - <div id="runtime-panel-usb"></div> - <label class="panel-header" id="runtime-header-wifi">&runtimePanel_wifi;</label> - <div id="runtime-panel-wifi"></div> - <label class="panel-header">&runtimePanel_simulator;</label> - <div id="runtime-panel-simulator"></div> - <button class="panel-item" id="runtime-panel-installsimulator">&runtimePanel_installsimulator;</button> - <label class="panel-header">&runtimePanel_other;</label> - <div id="runtime-panel-other"></div> - <div id="runtime-actions"> - <button class="panel-item" id="runtime-details">&runtimeMenu_showDetails_label;</button> - <button class="panel-item" id="runtime-permissions">&runtimeMenu_showPermissionTable_label;</button> - <button class="panel-item" id="runtime-preferences">&runtimeMenu_showDevicePrefs_label;</button> - <button class="panel-item" id="runtime-settings">&runtimeMenu_showSettings_label;</button> - <button class="panel-item" id="runtime-screenshot">&runtimeMenu_takeScreenshot_label;</button> - <button class="panel-item" id="runtime-disconnect">&runtimeMenu_disconnect_label;</button> - </div> - </div> - </div> - </body> -</html> diff --git a/devtools/client/webide/content/runtime-panel.js b/devtools/client/webide/content/runtime-panel.js deleted file mode 100644 index 3646fa15c..000000000 --- a/devtools/client/webide/content/runtime-panel.js +++ /dev/null @@ -1,11 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -var RuntimePanel = { - // TODO: Expand function to save toggle state. - toggleSidebar: function () { - document.querySelector("#runtime-listing-panel").setAttribute("sidebar-displayed", true); - document.querySelector("#runtime-listing-splitter").setAttribute("sidebar-displayed", true); - } -}; diff --git a/devtools/client/webide/content/runtimedetails.js b/devtools/client/webide/content/runtimedetails.js deleted file mode 100644 index dea423e81..000000000 --- a/devtools/client/webide/content/runtimedetails.js +++ /dev/null @@ -1,153 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -var Cu = Components.utils; -const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); -const Services = require("Services"); -const {AppManager} = require("devtools/client/webide/modules/app-manager"); -const {Connection} = require("devtools/shared/client/connection-manager"); -const {RuntimeTypes} = require("devtools/client/webide/modules/runtimes"); -const Strings = Services.strings.createBundle("chrome://devtools/locale/webide.properties"); - -const UNRESTRICTED_HELP_URL = "https://developer.mozilla.org/docs/Tools/WebIDE/Running_and_debugging_apps#Unrestricted_app_debugging_%28including_certified_apps_main_process_etc.%29"; - -window.addEventListener("load", function onLoad() { - window.removeEventListener("load", onLoad); - document.querySelector("#close").onclick = CloseUI; - document.querySelector("#devtools-check button").onclick = EnableCertApps; - document.querySelector("#adb-check button").onclick = RootADB; - document.querySelector("#unrestricted-privileges").onclick = function () { - window.parent.UI.openInBrowser(UNRESTRICTED_HELP_URL); - }; - AppManager.on("app-manager-update", OnAppManagerUpdate); - BuildUI(); - CheckLockState(); -}, true); - -window.addEventListener("unload", function onUnload() { - window.removeEventListener("unload", onUnload); - AppManager.off("app-manager-update", OnAppManagerUpdate); -}); - -function CloseUI() { - window.parent.UI.openProject(); -} - -function OnAppManagerUpdate(event, what) { - if (what == "connection" || what == "runtime-global-actors") { - BuildUI(); - CheckLockState(); - } -} - -function generateFields(json) { - let table = document.querySelector("table"); - for (let name in json) { - let tr = document.createElement("tr"); - let td = document.createElement("td"); - td.textContent = name; - tr.appendChild(td); - td = document.createElement("td"); - td.textContent = json[name]; - tr.appendChild(td); - table.appendChild(tr); - } -} - -var getDescriptionPromise; // Used by tests -function BuildUI() { - let table = document.querySelector("table"); - table.innerHTML = ""; - if (AppManager.connection && - AppManager.connection.status == Connection.Status.CONNECTED && - AppManager.deviceFront) { - getDescriptionPromise = AppManager.deviceFront.getDescription() - .then(json => generateFields(json)); - } else { - CloseUI(); - } -} - -function CheckLockState() { - let adbCheckResult = document.querySelector("#adb-check > .yesno"); - let devtoolsCheckResult = document.querySelector("#devtools-check > .yesno"); - let flipCertPerfButton = document.querySelector("#devtools-check button"); - let adbRootButton = document.querySelector("#adb-check button"); - let flipCertPerfAction = document.querySelector("#devtools-check > .action"); - let adbRootAction = document.querySelector("#adb-check > .action"); - - let sYes = Strings.GetStringFromName("runtimedetails_checkyes"); - let sNo = Strings.GetStringFromName("runtimedetails_checkno"); - let sUnknown = Strings.GetStringFromName("runtimedetails_checkunknown"); - let sNotUSB = Strings.GetStringFromName("runtimedetails_notUSBDevice"); - - flipCertPerfButton.setAttribute("disabled", "true"); - flipCertPerfAction.setAttribute("hidden", "true"); - adbRootAction.setAttribute("hidden", "true"); - - adbCheckResult.textContent = sUnknown; - devtoolsCheckResult.textContent = sUnknown; - - if (AppManager.connection && - AppManager.connection.status == Connection.Status.CONNECTED) { - - // ADB check - if (AppManager.selectedRuntime.type === RuntimeTypes.USB) { - let device = AppManager.selectedRuntime.device; - if (device && device.summonRoot) { - device.isRoot().then(isRoot => { - if (isRoot) { - adbCheckResult.textContent = sYes; - flipCertPerfButton.removeAttribute("disabled"); - } else { - adbCheckResult.textContent = sNo; - adbRootAction.removeAttribute("hidden"); - } - }, e => console.error(e)); - } else { - adbCheckResult.textContent = sUnknown; - } - } else { - adbCheckResult.textContent = sNotUSB; - } - - // forbid-certified-apps check - try { - let prefFront = AppManager.preferenceFront; - prefFront.getBoolPref("devtools.debugger.forbid-certified-apps").then(isForbidden => { - if (isForbidden) { - devtoolsCheckResult.textContent = sNo; - flipCertPerfAction.removeAttribute("hidden"); - } else { - devtoolsCheckResult.textContent = sYes; - } - }, e => console.error(e)); - } catch (e) { - // Exception. pref actor is only accessible if forbird-certified-apps is false - devtoolsCheckResult.textContent = sNo; - flipCertPerfAction.removeAttribute("hidden"); - } - - } - -} - -function EnableCertApps() { - let device = AppManager.selectedRuntime.device; - // TODO: Remove `network.disable.ipc.security` once bug 1125916 is fixed. - device.shell( - "stop b2g && " + - "cd /data/b2g/mozilla/*.default/ && " + - "echo 'user_pref(\"devtools.debugger.forbid-certified-apps\", false);' >> prefs.js && " + - "echo 'user_pref(\"dom.apps.developer_mode\", true);' >> prefs.js && " + - "echo 'user_pref(\"network.disable.ipc.security\", true);' >> prefs.js && " + - "echo 'user_pref(\"dom.webcomponents.enabled\", true);' >> prefs.js && " + - "start b2g" - ); -} - -function RootADB() { - let device = AppManager.selectedRuntime.device; - device.summonRoot().then(CheckLockState, (e) => console.error(e)); -} diff --git a/devtools/client/webide/content/runtimedetails.xhtml b/devtools/client/webide/content/runtimedetails.xhtml deleted file mode 100644 index b2f74728a..000000000 --- a/devtools/client/webide/content/runtimedetails.xhtml +++ /dev/null @@ -1,46 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!DOCTYPE html [ - <!ENTITY % webideDTD SYSTEM "chrome://devtools/locale/webide.dtd" > - %webideDTD; -]> - -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <meta charset="utf8"/> - <link rel="stylesheet" href="chrome://webide/skin/deck.css" type="text/css"/> - <link rel="stylesheet" href="chrome://webide/skin/runtimedetails.css" type="text/css"/> - <script type="application/javascript;version=1.8" src="chrome://webide/content/runtimedetails.js"></script> - </head> - <body> - - <div id="controls"> - <a id="close">&deck_close;</a> - </div> - - <h1>&runtimedetails_title;</h1> - - <div id="devicePrivileges"> - <p id="adb-check"> - &runtimedetails_adbIsRoot;<span class="yesno"></span> - <div class="action"> - <button>&runtimedetails_summonADBRoot;</button> - <em>&runtimedetails_ADBRootWarning;</em> - </div> - </p> - <p id="devtools-check"> - <a id="unrestricted-privileges">&runtimedetails_unrestrictedPrivileges;</a><span class="yesno"></span> - <div class="action"> - <button>&runtimedetails_requestPrivileges;</button> - <em>&runtimedetails_privilegesWarning;</em> - </div> - </p> - </div> - - <table></table> - </body> -</html> diff --git a/devtools/client/webide/content/simulator.js b/devtools/client/webide/content/simulator.js deleted file mode 100644 index ddc1cbed1..000000000 --- a/devtools/client/webide/content/simulator.js +++ /dev/null @@ -1,352 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -var Cu = Components.utils; -var Ci = Components.interfaces; - -const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {}); -const { getDevices, getDeviceString } = require("devtools/client/shared/devices"); -const { Simulators, Simulator } = require("devtools/client/webide/modules/simulators"); -const Services = require("Services"); -const EventEmitter = require("devtools/shared/event-emitter"); -const promise = require("promise"); -const utils = require("devtools/client/webide/modules/utils"); - -const Strings = Services.strings.createBundle("chrome://devtools/locale/webide.properties"); - -var SimulatorEditor = { - - // Available Firefox OS Simulator addons (key: `addon.id`). - _addons: {}, - - // Available device simulation profiles (key: `device.name`). - _devices: {}, - - // The names of supported simulation options. - _deviceOptions: [], - - // The <form> element used to edit Simulator options. - _form: null, - - // The Simulator object being edited. - _simulator: null, - - // Generate the dynamic form elements. - init() { - let promises = []; - - // Grab the <form> element. - let form = this._form; - if (!form) { - // This is the first time we run `init()`, bootstrap some things. - form = this._form = document.querySelector("#simulator-editor"); - form.addEventListener("change", this.update.bind(this)); - Simulators.on("configure", (e, simulator) => { this.edit(simulator); }); - // Extract the list of device simulation options we'll support. - let deviceFields = form.querySelectorAll("*[data-device]"); - this._deviceOptions = Array.map(deviceFields, field => field.name); - } - - // Append a new <option> to a <select> (or <optgroup>) element. - function opt(select, value, text) { - let option = document.createElement("option"); - option.value = value; - option.textContent = text; - select.appendChild(option); - } - - // Generate B2G version selector. - promises.push(Simulators.findSimulatorAddons().then(addons => { - this._addons = {}; - form.version.innerHTML = ""; - form.version.classList.remove("custom"); - addons.forEach(addon => { - this._addons[addon.id] = addon; - opt(form.version, addon.id, addon.name); - }); - opt(form.version, "custom", ""); - opt(form.version, "pick", Strings.GetStringFromName("simulator_custom_binary")); - })); - - // Generate profile selector. - form.profile.innerHTML = ""; - form.profile.classList.remove("custom"); - opt(form.profile, "default", Strings.GetStringFromName("simulator_default_profile")); - opt(form.profile, "custom", ""); - opt(form.profile, "pick", Strings.GetStringFromName("simulator_custom_profile")); - - // Generate example devices list. - form.device.innerHTML = ""; - form.device.classList.remove("custom"); - opt(form.device, "custom", Strings.GetStringFromName("simulator_custom_device")); - promises.push(getDevices().then(devices => { - devices.TYPES.forEach(type => { - let b2gDevices = devices[type].filter(d => d.firefoxOS); - if (b2gDevices.length < 1) { - return; - } - let optgroup = document.createElement("optgroup"); - optgroup.label = getDeviceString(type); - b2gDevices.forEach(device => { - this._devices[device.name] = device; - opt(optgroup, device.name, device.name); - }); - form.device.appendChild(optgroup); - }); - })); - - return promise.all(promises); - }, - - // Edit the configuration of an existing Simulator, or create a new one. - edit(simulator) { - // If no Simulator was given to edit, we're creating a new one. - if (!simulator) { - simulator = new Simulator(); // Default options. - Simulators.add(simulator); - } - - this._simulator = null; - - return this.init().then(() => { - this._simulator = simulator; - - // Update the form fields. - this._form.name.value = simulator.name; - - this.updateVersionSelector(); - this.updateProfileSelector(); - this.updateDeviceSelector(); - this.updateDeviceFields(); - - // Change visibility of 'TV Simulator Menu'. - let tvSimMenu = document.querySelector("#tv_simulator_menu"); - tvSimMenu.style.visibility = (this._simulator.type === "television") ? - "visible" : "hidden"; - - // Trigger any listener waiting for this update - let change = document.createEvent("HTMLEvents"); - change.initEvent("change", true, true); - this._form.dispatchEvent(change); - }); - }, - - // Open the directory of TV Simulator config. - showTVConfigDirectory() { - let profD = Services.dirsvc.get("ProfD", Ci.nsIFile); - profD.append("extensions"); - profD.append(this._simulator.addon.id); - profD.append("profile"); - profD.append("dummy"); - let profileDir = profD.path; - - // Show the profile directory. - let nsLocalFile = Components.Constructor("@mozilla.org/file/local;1", - "nsILocalFile", "initWithPath"); - new nsLocalFile(profileDir).reveal(); - }, - - // Close the configuration panel. - close() { - this._simulator = null; - window.parent.UI.openProject(); - }, - - // Restore the simulator to its default configuration. - restoreDefaults() { - let simulator = this._simulator; - this.version = simulator.addon.id; - this.profile = "default"; - simulator.restoreDefaults(); - Simulators.emitUpdated(); - return this.edit(simulator); - }, - - // Delete this simulator. - deleteSimulator() { - Simulators.remove(this._simulator); - this.close(); - }, - - // Select an available option, or set the "custom" option. - updateSelector(selector, value) { - selector.value = value; - if (selector.selectedIndex == -1) { - selector.value = "custom"; - selector.classList.add("custom"); - selector[selector.selectedIndex].textContent = value; - } - }, - - // VERSION: Can be an installed `addon.id` or a custom binary path. - - get version() { - return this._simulator.options.b2gBinary || this._simulator.addon.id; - }, - - set version(value) { - let form = this._form; - let simulator = this._simulator; - let oldVer = simulator.version; - if (this._addons[value]) { - // `value` is a simulator addon ID. - simulator.addon = this._addons[value]; - simulator.options.b2gBinary = null; - } else { - // `value` is a custom binary path. - simulator.options.b2gBinary = value; - // TODO (Bug 1146531) Indicate that a custom profile is now required. - } - // If `form.name` contains the old version, update its last occurrence. - if (form.name.value.includes(oldVer) && simulator.version !== oldVer) { - let regex = new RegExp("(.*)" + oldVer); - let name = form.name.value.replace(regex, "$1" + simulator.version); - simulator.options.name = form.name.value = Simulators.uniqueName(name); - } - }, - - updateVersionSelector() { - this.updateSelector(this._form.version, this.version); - }, - - // PROFILE. Can be "default" or a custom profile directory path. - - get profile() { - return this._simulator.options.gaiaProfile || "default"; - }, - - set profile(value) { - this._simulator.options.gaiaProfile = (value == "default" ? null : value); - }, - - updateProfileSelector() { - this.updateSelector(this._form.profile, this.profile); - }, - - // DEVICE. Can be an existing `device.name` or "custom". - - get device() { - let devices = this._devices; - let simulator = this._simulator; - - // Search for the name of a device matching current simulator options. - for (let name in devices) { - let match = true; - for (let option of this._deviceOptions) { - if (simulator.options[option] === devices[name][option]) { - continue; - } - match = false; - break; - } - if (match) { - return name; - } - } - return "custom"; - }, - - set device(name) { - let device = this._devices[name]; - if (!device) { - return; - } - let form = this._form; - let simulator = this._simulator; - this._deviceOptions.forEach(option => { - simulator.options[option] = form[option].value = device[option] || null; - }); - // TODO (Bug 1146531) Indicate when a custom profile is required (e.g. for - // tablet, TV…). - }, - - updateDeviceSelector() { - this.updateSelector(this._form.device, this.device); - }, - - // Erase any current values, trust only the `simulator.options`. - updateDeviceFields() { - let form = this._form; - let simulator = this._simulator; - this._deviceOptions.forEach(option => { - form[option].value = simulator.options[option]; - }); - }, - - // Handle a change in our form's fields. - update(event) { - let simulator = this._simulator; - if (!simulator) { - return; - } - let form = this._form; - let input = event.target; - switch (input.name) { - case "name": - simulator.options.name = input.value; - break; - case "version": - switch (input.value) { - case "pick": - let file = utils.getCustomBinary(window); - if (file) { - this.version = file.path; - } - // Whatever happens, don't stay on the "pick" option. - this.updateVersionSelector(); - break; - case "custom": - this.version = input[input.selectedIndex].textContent; - break; - default: - this.version = input.value; - } - break; - case "profile": - switch (input.value) { - case "pick": - let directory = utils.getCustomProfile(window); - if (directory) { - this.profile = directory.path; - } - // Whatever happens, don't stay on the "pick" option. - this.updateProfileSelector(); - break; - case "custom": - this.profile = input[input.selectedIndex].textContent; - break; - default: - this.profile = input.value; - } - break; - case "device": - this.device = input.value; - break; - default: - simulator.options[input.name] = input.value || null; - this.updateDeviceSelector(); - } - Simulators.emitUpdated(); - }, -}; - -window.addEventListener("load", function onLoad() { - document.querySelector("#close").onclick = e => { - SimulatorEditor.close(); - }; - document.querySelector("#reset").onclick = e => { - SimulatorEditor.restoreDefaults(); - }; - document.querySelector("#remove").onclick = e => { - SimulatorEditor.deleteSimulator(); - }; - - // We just loaded, so we probably missed the first configure request. - SimulatorEditor.edit(Simulators._lastConfiguredSimulator); - - document.querySelector("#open-tv-dummy-directory").onclick = e => { - SimulatorEditor.showTVConfigDirectory(); - e.preventDefault(); - }; -}); diff --git a/devtools/client/webide/content/simulator.xhtml b/devtools/client/webide/content/simulator.xhtml deleted file mode 100644 index 3ab916248..000000000 --- a/devtools/client/webide/content/simulator.xhtml +++ /dev/null @@ -1,99 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!DOCTYPE html [ - <!ENTITY % webideDTD SYSTEM "chrome://devtools/locale/webide.dtd" > - %webideDTD; -]> - -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <meta charset="utf8"/> - <link rel="stylesheet" href="chrome://webide/skin/deck.css" type="text/css"/> - <link rel="stylesheet" href="chrome://webide/skin/simulator.css" type="text/css"/> - <script type="application/javascript;version=1.8" src="chrome://webide/content/simulator.js"></script> - </head> - <body> - - <div id="controls"> - <a id="remove" class="hidden">&simulator_remove;</a> - <a id="reset">&simulator_reset;</a> - <a id="close">&deck_close;</a> - </div> - - <form id="simulator-editor"> - - <h1>&simulator_title;</h1> - - <h2>&simulator_software;</h2> - - <ul> - <li> - <label> - <span class="label">&simulator_name;</span> - <input type="text" name="name"/> - </label> - </li> - <li> - <label> - <span class="label">&simulator_version;</span> - <select name="version"/> - </label> - </li> - <li> - <label> - <span class="label">&simulator_profile;</span> - <select name="profile"/> - </label> - </li> - </ul> - - <h2>&simulator_hardware;</h2> - - <ul> - <li> - <label> - <span class="label">&simulator_device;</span> - <select name="device"/> - </label> - </li> - <li> - <label> - <span class="label">&simulator_screenSize;</span> - <input name="width" data-device="" type="number"/> - <span>×</span> - <input name="height" data-device="" type="number"/> - </label> - </li> - <li class="hidden"> - <label> - <span class="label">&simulator_pixelRatio;</span> - <input name="pixelRatio" data-device="" type="number" step="0.05"/> - </label> - </li> - </ul> - - <!-- This menu is shown when simulator type is television--> - <p id="tv_simulator_menu" style="visibility:hidden;"> - <h2>&simulator_tv_data;</h2> - - <ul> - <li> - <label> - <span class="label">&simulator_tv_data_open;</span> - <button id="open-tv-dummy-directory"> - &simulator_tv_data_open_button; - </button> - </label> - </li> - </ul> - - </p> - - </form> - - </body> -</html> diff --git a/devtools/client/webide/content/webide.js b/devtools/client/webide/content/webide.js deleted file mode 100644 index c222332e3..000000000 --- a/devtools/client/webide/content/webide.js +++ /dev/null @@ -1,1157 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -var Cc = Components.classes; -var Cu = Components.utils; -var Ci = Components.interfaces; - -const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); -const {gDevTools} = require("devtools/client/framework/devtools"); -const {gDevToolsBrowser} = require("devtools/client/framework/devtools-browser"); -const {Toolbox} = require("devtools/client/framework/toolbox"); -const Services = require("Services"); -const {AppProjects} = require("devtools/client/webide/modules/app-projects"); -const {Connection} = require("devtools/shared/client/connection-manager"); -const {AppManager} = require("devtools/client/webide/modules/app-manager"); -const EventEmitter = require("devtools/shared/event-emitter"); -const promise = require("promise"); -const ProjectEditor = require("devtools/client/projecteditor/lib/projecteditor"); -const {GetAvailableAddons} = require("devtools/client/webide/modules/addons"); -const {getJSON} = require("devtools/client/shared/getjson"); -const utils = require("devtools/client/webide/modules/utils"); -const Telemetry = require("devtools/client/shared/telemetry"); -const {RuntimeScanners} = require("devtools/client/webide/modules/runtimes"); -const {showDoorhanger} = require("devtools/client/shared/doorhanger"); -const {Simulators} = require("devtools/client/webide/modules/simulators"); -const {Task} = require("devtools/shared/task"); - -const Strings = Services.strings.createBundle("chrome://devtools/locale/webide.properties"); - -const HTML = "http://www.w3.org/1999/xhtml"; -const HELP_URL = "https://developer.mozilla.org/docs/Tools/WebIDE/Troubleshooting"; - -const MAX_ZOOM = 1.4; -const MIN_ZOOM = 0.6; - -const MS_PER_DAY = 86400000; - -[["AppManager", AppManager], - ["AppProjects", AppProjects], - ["Connection", Connection]].forEach(([key, value]) => { - Object.defineProperty(this, key, { - value: value, - enumerable: true, - writable: false - }); - }); - -// Download remote resources early -getJSON("devtools.webide.addonsURL"); -getJSON("devtools.webide.templatesURL"); -getJSON("devtools.devices.url"); - -// See bug 989619 -console.log = console.log.bind(console); -console.warn = console.warn.bind(console); -console.error = console.error.bind(console); - -window.addEventListener("load", function onLoad() { - window.removeEventListener("load", onLoad); - UI.init(); -}); - -window.addEventListener("unload", function onUnload() { - window.removeEventListener("unload", onUnload); - UI.destroy(); -}); - -var UI = { - init: function () { - this._telemetry = new Telemetry(); - this._telemetry.toolOpened("webide"); - - AppManager.init(); - - this.appManagerUpdate = this.appManagerUpdate.bind(this); - AppManager.on("app-manager-update", this.appManagerUpdate); - - Cmds.showProjectPanel(); - Cmds.showRuntimePanel(); - - this.updateCommands(); - - this.onfocus = this.onfocus.bind(this); - window.addEventListener("focus", this.onfocus, true); - - AppProjects.load().then(() => { - this.autoSelectProject(); - }, e => { - console.error(e); - this.reportError("error_appProjectsLoadFailed"); - }); - - // Auto install the ADB Addon Helper and Tools Adapters. Only once. - // If the user decides to uninstall any of this addon, we won't install it again. - let autoinstallADBHelper = Services.prefs.getBoolPref("devtools.webide.autoinstallADBHelper"); - let autoinstallFxdtAdapters = Services.prefs.getBoolPref("devtools.webide.autoinstallFxdtAdapters"); - if (autoinstallADBHelper) { - GetAvailableAddons().then(addons => { - addons.adb.install(); - }, console.error); - } - if (autoinstallFxdtAdapters) { - GetAvailableAddons().then(addons => { - addons.adapters.install(); - }, console.error); - } - Services.prefs.setBoolPref("devtools.webide.autoinstallADBHelper", false); - Services.prefs.setBoolPref("devtools.webide.autoinstallFxdtAdapters", false); - - if (Services.prefs.getBoolPref("devtools.webide.widget.autoinstall") && - !Services.prefs.getBoolPref("devtools.webide.widget.enabled")) { - Services.prefs.setBoolPref("devtools.webide.widget.enabled", true); - gDevToolsBrowser.moveWebIDEWidgetInNavbar(); - } - - this.setupDeck(); - - this.contentViewer = window.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShell) - .contentViewer; - this.contentViewer.fullZoom = Services.prefs.getCharPref("devtools.webide.zoom"); - - gDevToolsBrowser.isWebIDEInitialized.resolve(); - - this.configureSimulator = this.configureSimulator.bind(this); - Simulators.on("configure", this.configureSimulator); - }, - - destroy: function () { - window.removeEventListener("focus", this.onfocus, true); - AppManager.off("app-manager-update", this.appManagerUpdate); - AppManager.destroy(); - Simulators.off("configure", this.configureSimulator); - this.updateConnectionTelemetry(); - this._telemetry.toolClosed("webide"); - this._telemetry.toolClosed("webideProjectEditor"); - this._telemetry.destroy(); - }, - - canCloseProject: function () { - if (this.projecteditor) { - return this.projecteditor.confirmUnsaved(); - } - return true; - }, - - onfocus: function () { - // Because we can't track the activity in the folder project, - // we need to validate the project regularly. Let's assume that - // if a modification happened, it happened when the window was - // not focused. - if (AppManager.selectedProject && - AppManager.selectedProject.type != "mainProcess" && - AppManager.selectedProject.type != "runtimeApp" && - AppManager.selectedProject.type != "tab") { - AppManager.validateAndUpdateProject(AppManager.selectedProject); - } - - // Hook to display promotional Developer Edition doorhanger. Only displayed once. - // Hooked into the `onfocus` event because sometimes does not work - // when run at the end of `init`. ¯\(°_o)/¯ - showDoorhanger({ window, type: "deveditionpromo", anchor: document.querySelector("#deck") }); - }, - - appManagerUpdate: function (event, what, details) { - // Got a message from app-manager.js - // See AppManager.update() for descriptions of what these events mean. - switch (what) { - case "runtime-list": - this.autoConnectRuntime(); - break; - case "connection": - this.updateRuntimeButton(); - this.updateCommands(); - this.updateConnectionTelemetry(); - break; - case "before-project": - if (!this.canCloseProject()) { - details.cancel(); - } - break; - case "project": - this._updatePromise = Task.spawn(function* () { - UI.updateTitle(); - yield UI.destroyToolbox(); - UI.updateCommands(); - UI.openProject(); - yield UI.autoStartProject(); - UI.autoOpenToolbox(); - UI.saveLastSelectedProject(); - UI.updateRemoveProjectButton(); - }); - return; - case "project-started": - this.updateCommands(); - UI.autoOpenToolbox(); - break; - case "project-stopped": - UI.destroyToolbox(); - this.updateCommands(); - break; - case "runtime-global-actors": - // Check runtime version only on runtime-global-actors, - // as we expect to use device actor - this.checkRuntimeVersion(); - this.updateCommands(); - break; - case "runtime-details": - this.updateRuntimeButton(); - break; - case "runtime": - this.updateRuntimeButton(); - this.saveLastConnectedRuntime(); - break; - case "project-validated": - this.updateTitle(); - this.updateCommands(); - this.updateProjectEditorHeader(); - break; - case "install-progress": - this.updateProgress(Math.round(100 * details.bytesSent / details.totalBytes)); - break; - case "runtime-targets": - this.autoSelectProject(); - break; - case "pre-package": - this.prePackageLog(details); - break; - } - this._updatePromise = promise.resolve(); - }, - - configureSimulator: function (event, simulator) { - UI.selectDeckPanel("simulator"); - }, - - openInBrowser: function (url) { - // Open a URL in a Firefox window - let mainWindow = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType); - if (mainWindow) { - mainWindow.openUILinkIn(url, "tab"); - mainWindow.focus() - } else { - window.open(url); - } - }, - - updateTitle: function () { - let project = AppManager.selectedProject; - if (project) { - window.document.title = Strings.formatStringFromName("title_app", [project.name], 1); - } else { - window.document.title = Strings.GetStringFromName("title_noApp"); - } - }, - - /** ******** BUSY UI **********/ - - _busyTimeout: null, - _busyOperationDescription: null, - _busyPromise: null, - - updateProgress: function (percent) { - let progress = document.querySelector("#action-busy-determined"); - progress.mode = "determined"; - progress.value = percent; - this.setupBusyTimeout(); - }, - - busy: function () { - let win = document.querySelector("window"); - win.classList.add("busy"); - win.classList.add("busy-undetermined"); - this.updateCommands(); - this.update("busy"); - }, - - unbusy: function () { - let win = document.querySelector("window"); - win.classList.remove("busy"); - win.classList.remove("busy-determined"); - win.classList.remove("busy-undetermined"); - this.updateCommands(); - this.update("unbusy"); - this._busyPromise = null; - }, - - setupBusyTimeout: function () { - this.cancelBusyTimeout(); - this._busyTimeout = setTimeout(() => { - this.unbusy(); - UI.reportError("error_operationTimeout", this._busyOperationDescription); - }, Services.prefs.getIntPref("devtools.webide.busyTimeout")); - }, - - cancelBusyTimeout: function () { - clearTimeout(this._busyTimeout); - }, - - busyWithProgressUntil: function (promise, operationDescription) { - let busy = this.busyUntil(promise, operationDescription); - let win = document.querySelector("window"); - let progress = document.querySelector("#action-busy-determined"); - progress.mode = "undetermined"; - win.classList.add("busy-determined"); - win.classList.remove("busy-undetermined"); - return busy; - }, - - busyUntil: function (promise, operationDescription) { - // Freeze the UI until the promise is resolved. A timeout will unfreeze the - // UI, just in case the promise never gets resolved. - this._busyPromise = promise; - this._busyOperationDescription = operationDescription; - this.setupBusyTimeout(); - this.busy(); - promise.then(() => { - this.cancelBusyTimeout(); - this.unbusy(); - }, (e) => { - let message; - if (e && e.error && e.message) { - // Some errors come from fronts that are not based on protocol.js. - // Errors are not translated to strings. - message = operationDescription + " (" + e.error + "): " + e.message; - } else { - message = operationDescription + (e ? (": " + e) : ""); - } - this.cancelBusyTimeout(); - let operationCanceled = e && e.canceled; - if (!operationCanceled) { - UI.reportError("error_operationFail", message); - if (e) { - console.error(e); - } - } - this.unbusy(); - }); - return promise; - }, - - reportError: function (l10nProperty, ...l10nArgs) { - let text; - - if (l10nArgs.length > 0) { - text = Strings.formatStringFromName(l10nProperty, l10nArgs, l10nArgs.length); - } else { - text = Strings.GetStringFromName(l10nProperty); - } - - console.error(text); - - let buttons = [{ - label: Strings.GetStringFromName("notification_showTroubleShooting_label"), - accessKey: Strings.GetStringFromName("notification_showTroubleShooting_accesskey"), - callback: function () { - Cmds.showTroubleShooting(); - } - }]; - - let nbox = document.querySelector("#notificationbox"); - nbox.removeAllNotifications(true); - nbox.appendNotification(text, "webide:errornotification", null, - nbox.PRIORITY_WARNING_LOW, buttons); - }, - - dismissErrorNotification: function () { - let nbox = document.querySelector("#notificationbox"); - nbox.removeAllNotifications(true); - }, - - /** ******** COMMANDS **********/ - - /** - * This module emits various events when state changes occur. - * - * The events this module may emit include: - * busy: - * The window is currently busy and certain UI functions may be disabled. - * unbusy: - * The window is not busy and certain UI functions may be re-enabled. - */ - update: function (what, details) { - this.emit("webide-update", what, details); - }, - - updateCommands: function () { - // Action commands - let playCmd = document.querySelector("#cmd_play"); - let stopCmd = document.querySelector("#cmd_stop"); - let debugCmd = document.querySelector("#cmd_toggleToolbox"); - let playButton = document.querySelector("#action-button-play"); - let projectPanelCmd = document.querySelector("#cmd_showProjectPanel"); - - if (document.querySelector("window").classList.contains("busy")) { - playCmd.setAttribute("disabled", "true"); - stopCmd.setAttribute("disabled", "true"); - debugCmd.setAttribute("disabled", "true"); - projectPanelCmd.setAttribute("disabled", "true"); - return; - } - - if (!AppManager.selectedProject || !AppManager.connected) { - playCmd.setAttribute("disabled", "true"); - stopCmd.setAttribute("disabled", "true"); - debugCmd.setAttribute("disabled", "true"); - } else { - let isProjectRunning = AppManager.isProjectRunning(); - if (isProjectRunning) { - playButton.classList.add("reload"); - stopCmd.removeAttribute("disabled"); - debugCmd.removeAttribute("disabled"); - } else { - playButton.classList.remove("reload"); - stopCmd.setAttribute("disabled", "true"); - debugCmd.setAttribute("disabled", "true"); - } - - // If connected and a project is selected - if (AppManager.selectedProject.type == "runtimeApp") { - playCmd.removeAttribute("disabled"); - } else if (AppManager.selectedProject.type == "tab") { - playCmd.removeAttribute("disabled"); - stopCmd.setAttribute("disabled", "true"); - } else if (AppManager.selectedProject.type == "mainProcess") { - playCmd.setAttribute("disabled", "true"); - stopCmd.setAttribute("disabled", "true"); - } else { - if (AppManager.selectedProject.errorsCount == 0 && - AppManager.runtimeCanHandleApps()) { - playCmd.removeAttribute("disabled"); - } else { - playCmd.setAttribute("disabled", "true"); - } - } - } - - // Runtime commands - let monitorCmd = document.querySelector("#cmd_showMonitor"); - let screenshotCmd = document.querySelector("#cmd_takeScreenshot"); - let permissionsCmd = document.querySelector("#cmd_showPermissionsTable"); - let detailsCmd = document.querySelector("#cmd_showRuntimeDetails"); - let disconnectCmd = document.querySelector("#cmd_disconnectRuntime"); - let devicePrefsCmd = document.querySelector("#cmd_showDevicePrefs"); - let settingsCmd = document.querySelector("#cmd_showSettings"); - - if (AppManager.connected) { - if (AppManager.deviceFront) { - monitorCmd.removeAttribute("disabled"); - detailsCmd.removeAttribute("disabled"); - permissionsCmd.removeAttribute("disabled"); - screenshotCmd.removeAttribute("disabled"); - } - if (AppManager.preferenceFront) { - devicePrefsCmd.removeAttribute("disabled"); - } - if (AppManager.settingsFront) { - settingsCmd.removeAttribute("disabled"); - } - disconnectCmd.removeAttribute("disabled"); - } else { - monitorCmd.setAttribute("disabled", "true"); - detailsCmd.setAttribute("disabled", "true"); - permissionsCmd.setAttribute("disabled", "true"); - screenshotCmd.setAttribute("disabled", "true"); - disconnectCmd.setAttribute("disabled", "true"); - devicePrefsCmd.setAttribute("disabled", "true"); - settingsCmd.setAttribute("disabled", "true"); - } - - let runtimePanelButton = document.querySelector("#runtime-panel-button"); - - if (AppManager.connected) { - runtimePanelButton.setAttribute("active", "true"); - runtimePanelButton.removeAttribute("hidden"); - } else { - runtimePanelButton.removeAttribute("active"); - runtimePanelButton.setAttribute("hidden", "true"); - } - - projectPanelCmd.removeAttribute("disabled"); - }, - - updateRemoveProjectButton: function () { - // Remove command - let removeCmdNode = document.querySelector("#cmd_removeProject"); - if (AppManager.selectedProject) { - removeCmdNode.removeAttribute("disabled"); - } else { - removeCmdNode.setAttribute("disabled", "true"); - } - }, - - /** ******** RUNTIME **********/ - - get lastConnectedRuntime() { - return Services.prefs.getCharPref("devtools.webide.lastConnectedRuntime"); - }, - - set lastConnectedRuntime(runtime) { - Services.prefs.setCharPref("devtools.webide.lastConnectedRuntime", runtime); - }, - - autoConnectRuntime: function () { - // Automatically reconnect to the previously selected runtime, - // if available and has an ID and feature is enabled - if (AppManager.selectedRuntime || - !Services.prefs.getBoolPref("devtools.webide.autoConnectRuntime") || - !this.lastConnectedRuntime) { - return; - } - let [_, type, id] = this.lastConnectedRuntime.match(/^(\w+):(.+)$/); - - type = type.toLowerCase(); - - // Local connection is mapped to AppManager.runtimeList.other array - if (type == "local") { - type = "other"; - } - - // We support most runtimes except simulator, that needs to be manually - // launched - if (type == "usb" || type == "wifi" || type == "other") { - for (let runtime of AppManager.runtimeList[type]) { - // Some runtimes do not expose an id and don't support autoconnect (like - // remote connection) - if (runtime.id == id) { - // Only want one auto-connect attempt, so clear last runtime value - this.lastConnectedRuntime = ""; - this.connectToRuntime(runtime); - } - } - } - }, - - connectToRuntime: function (runtime) { - let name = runtime.name; - let promise = AppManager.connectToRuntime(runtime); - promise.then(() => this.initConnectionTelemetry()) - .catch(() => { - // Empty rejection handler to silence uncaught rejection warnings - // |busyUntil| will listen for rejections. - // Bug 1121100 may find a better way to silence these. - }); - promise = this.busyUntil(promise, "Connecting to " + name); - // Stop busy timeout for runtimes that take unknown or long amounts of time - // to connect. - if (runtime.prolongedConnection) { - this.cancelBusyTimeout(); - } - return promise; - }, - - updateRuntimeButton: function () { - let labelNode = document.querySelector("#runtime-panel-button > .panel-button-label"); - if (!AppManager.selectedRuntime) { - labelNode.setAttribute("value", Strings.GetStringFromName("runtimeButton_label")); - } else { - let name = AppManager.selectedRuntime.name; - labelNode.setAttribute("value", name); - } - }, - - saveLastConnectedRuntime: function () { - if (AppManager.selectedRuntime && - AppManager.selectedRuntime.id !== undefined) { - this.lastConnectedRuntime = AppManager.selectedRuntime.type + ":" + - AppManager.selectedRuntime.id; - } else { - this.lastConnectedRuntime = ""; - } - }, - - /** ******** ACTIONS **********/ - - _actionsToLog: new Set(), - - /** - * For each new connection, track whether play and debug were ever used. Only - * one value is collected for each button, even if they are used multiple - * times during a connection. - */ - initConnectionTelemetry: function () { - this._actionsToLog.add("play"); - this._actionsToLog.add("debug"); - }, - - /** - * Action occurred. Log that it happened, and remove it from the loggable - * set. - */ - onAction: function (action) { - if (!this._actionsToLog.has(action)) { - return; - } - this.logActionState(action, true); - this._actionsToLog.delete(action); - }, - - /** - * Connection status changed or we are shutting down. Record any loggable - * actions as having not occurred. - */ - updateConnectionTelemetry: function () { - for (let action of this._actionsToLog.values()) { - this.logActionState(action, false); - } - this._actionsToLog.clear(); - }, - - logActionState: function (action, state) { - let histogramId = "DEVTOOLS_WEBIDE_CONNECTION_" + - action.toUpperCase() + "_USED"; - this._telemetry.log(histogramId, state); - }, - - /** ******** PROJECTS **********/ - - // ProjectEditor & details screen - - destroyProjectEditor: function () { - if (this.projecteditor) { - this.projecteditor.destroy(); - this.projecteditor = null; - } - }, - - /** - * Called when selecting or deselecting the project editor panel. - */ - onChangeProjectEditorSelected: function () { - if (this.projecteditor) { - let panel = document.querySelector("#deck").selectedPanel; - if (panel && panel.id == "deck-panel-projecteditor") { - this.projecteditor.menuEnabled = true; - this._telemetry.toolOpened("webideProjectEditor"); - } else { - this.projecteditor.menuEnabled = false; - this._telemetry.toolClosed("webideProjectEditor"); - } - } - }, - - getProjectEditor: function () { - if (this.projecteditor) { - return this.projecteditor.loaded; - } - - let projecteditorIframe = document.querySelector("#deck-panel-projecteditor"); - this.projecteditor = ProjectEditor.ProjectEditor(projecteditorIframe, { - menubar: document.querySelector("#main-menubar"), - menuindex: 1 - }); - this.projecteditor.on("onEditorSave", () => { - AppManager.validateAndUpdateProject(AppManager.selectedProject); - this._telemetry.actionOccurred("webideProjectEditorSave"); - }); - return this.projecteditor.loaded; - }, - - updateProjectEditorHeader: function () { - let project = AppManager.selectedProject; - if (!project || !this.projecteditor) { - return; - } - let status = project.validationStatus || "unknown"; - if (status == "error warning") { - status = "error"; - } - this.getProjectEditor().then((projecteditor) => { - projecteditor.setProjectToAppPath(project.location, { - name: project.name, - iconUrl: project.icon, - projectOverviewURL: "chrome://webide/content/details.xhtml", - validationStatus: status - }).then(null, console.error); - }, console.error); - }, - - isProjectEditorEnabled: function () { - return Services.prefs.getBoolPref("devtools.webide.showProjectEditor"); - }, - - openProject: function () { - let project = AppManager.selectedProject; - - // Nothing to show - - if (!project) { - this.resetDeck(); - return; - } - - // Make sure the directory exist before we show Project Editor - - let forceDetailsOnly = false; - if (project.type == "packaged") { - forceDetailsOnly = !utils.doesFileExist(project.location); - } - - // Show only the details screen - - if (project.type != "packaged" || - !this.isProjectEditorEnabled() || - forceDetailsOnly) { - this.selectDeckPanel("details"); - return; - } - - // Show ProjectEditor - - this.getProjectEditor().then(() => { - this.updateProjectEditorHeader(); - }, console.error); - - this.selectDeckPanel("projecteditor"); - }, - - autoStartProject: Task.async(function* () { - let project = AppManager.selectedProject; - - if (!project) { - return; - } - if (!(project.type == "runtimeApp" || - project.type == "mainProcess" || - project.type == "tab")) { - return; // For something that is not an editable app, we're done. - } - - // Do not force opening apps that are already running, as they may have - // some activity being opened and don't want to dismiss them. - if (project.type == "runtimeApp" && !AppManager.isProjectRunning()) { - yield UI.busyUntil(AppManager.launchRuntimeApp(), "running app"); - } - }), - - autoOpenToolbox: Task.async(function* () { - let project = AppManager.selectedProject; - - if (!project) { - return; - } - if (!(project.type == "runtimeApp" || - project.type == "mainProcess" || - project.type == "tab")) { - return; // For something that is not an editable app, we're done. - } - - yield UI.createToolbox(); - }), - - importAndSelectApp: Task.async(function* (source) { - let isPackaged = !!source.path; - let project; - try { - project = yield AppProjects[isPackaged ? "addPackaged" : "addHosted"](source); - } catch (e) { - if (e === "Already added") { - // Select project that's already been added, - // and allow it to be revalidated and selected - project = AppProjects.get(isPackaged ? source.path : source); - } else { - throw e; - } - } - - // Select project - AppManager.selectedProject = project; - - this._telemetry.actionOccurred("webideImportProject"); - }), - - // Remember the last selected project on the runtime - saveLastSelectedProject: function () { - let shouldRestore = Services.prefs.getBoolPref("devtools.webide.restoreLastProject"); - if (!shouldRestore) { - return; - } - - // Ignore unselection of project on runtime disconnection - if (!AppManager.connected) { - return; - } - - let project = "", type = ""; - let selected = AppManager.selectedProject; - if (selected) { - if (selected.type == "runtimeApp") { - type = "runtimeApp"; - project = selected.app.manifestURL; - } else if (selected.type == "mainProcess") { - type = "mainProcess"; - } else if (selected.type == "packaged" || - selected.type == "hosted") { - type = "local"; - project = selected.location; - } - } - if (type) { - Services.prefs.setCharPref("devtools.webide.lastSelectedProject", - type + ":" + project); - } else { - Services.prefs.clearUserPref("devtools.webide.lastSelectedProject"); - } - }, - - autoSelectProject: function () { - if (AppManager.selectedProject) { - return; - } - let shouldRestore = Services.prefs.getBoolPref("devtools.webide.restoreLastProject"); - if (!shouldRestore) { - return; - } - let pref = Services.prefs.getCharPref("devtools.webide.lastSelectedProject"); - if (!pref) { - return; - } - let m = pref.match(/^(\w+):(.*)$/); - if (!m) { - return; - } - let [_, type, project] = m; - - if (type == "local") { - let lastProject = AppProjects.get(project); - if (lastProject) { - AppManager.selectedProject = lastProject; - } - } - - // For other project types, we need to be connected to the runtime - if (!AppManager.connected) { - return; - } - - if (type == "mainProcess" && AppManager.isMainProcessDebuggable()) { - AppManager.selectedProject = { - type: "mainProcess", - name: Strings.GetStringFromName("mainProcess_label"), - icon: AppManager.DEFAULT_PROJECT_ICON - }; - } else if (type == "runtimeApp") { - let app = AppManager.apps.get(project); - if (app) { - AppManager.selectedProject = { - type: "runtimeApp", - app: app.manifest, - icon: app.iconURL, - name: app.manifest.name - }; - } - } - }, - - /** ******** DECK **********/ - - setupDeck: function () { - let iframes = document.querySelectorAll("#deck > iframe"); - for (let iframe of iframes) { - iframe.tooltip = "aHTMLTooltip"; - } - }, - - resetFocus: function () { - document.commandDispatcher.focusedElement = document.documentElement; - }, - - selectDeckPanel: function (id) { - let deck = document.querySelector("#deck"); - if (deck.selectedPanel && deck.selectedPanel.id === "deck-panel-" + id) { - // This panel is already displayed. - return; - } - this.resetFocus(); - let panel = deck.querySelector("#deck-panel-" + id); - let lazysrc = panel.getAttribute("lazysrc"); - if (lazysrc) { - panel.removeAttribute("lazysrc"); - panel.setAttribute("src", lazysrc); - } - deck.selectedPanel = panel; - this.onChangeProjectEditorSelected(); - }, - - resetDeck: function () { - this.resetFocus(); - let deck = document.querySelector("#deck"); - deck.selectedPanel = null; - this.onChangeProjectEditorSelected(); - }, - - buildIDToDate(buildID) { - let fields = buildID.match(/(\d{4})(\d{2})(\d{2})/); - // Date expects 0 - 11 for months - return new Date(fields[1], Number.parseInt(fields[2]) - 1, fields[3]); - }, - - checkRuntimeVersion: Task.async(function* () { - if (AppManager.connected && AppManager.deviceFront) { - let desc = yield AppManager.deviceFront.getDescription(); - // Compare device and firefox build IDs - // and only compare by day (strip hours/minutes) to prevent - // warning against builds of the same day. - let deviceID = desc.appbuildid.substr(0, 8); - let localID = Services.appinfo.appBuildID.substr(0, 8); - let deviceDate = this.buildIDToDate(deviceID); - let localDate = this.buildIDToDate(localID); - // Allow device to be newer by up to a week. This accommodates those with - // local device builds, since their devices will almost always be newer - // than the client. - if (deviceDate - localDate > 7 * MS_PER_DAY) { - this.reportError("error_runtimeVersionTooRecent", deviceID, localID); - } - } - }), - - /** ******** TOOLBOX **********/ - - /** - * There are many ways to close a toolbox: - * * Close button inside the toolbox - * * Toggle toolbox wrench in WebIDE - * * Disconnect the current runtime gracefully - * * Yank cord out of device - * * Close or crash the app/tab - * We can't know for sure which one was used here, so reset the - * |toolboxPromise| since someone must be destroying it to reach here, - * and call our own close method. - */ - _onToolboxClosed: function (promise, iframe) { - // Only save toolbox size, disable wrench button, workaround focus issue... - // if we are closing the last toolbox: - // - toolboxPromise is nullified by destroyToolbox and is still null here - // if no other toolbox has been opened in between, - // - having two distinct promise means we are receiving closed event - // for a previous, non-current, toolbox. - if (!this.toolboxPromise || this.toolboxPromise === promise) { - this.toolboxPromise = null; - this.resetFocus(); - Services.prefs.setIntPref("devtools.toolbox.footer.height", iframe.height); - - let splitter = document.querySelector(".devtools-horizontal-splitter"); - splitter.setAttribute("hidden", "true"); - document.querySelector("#action-button-debug").removeAttribute("active"); - } - // We have to destroy the iframe, otherwise, the keybindings of webide don't work - // properly anymore. - iframe.remove(); - }, - - destroyToolbox: function () { - // Only have a live toolbox if |this.toolboxPromise| exists - if (this.toolboxPromise) { - let toolboxPromise = this.toolboxPromise; - this.toolboxPromise = null; - return toolboxPromise.then(toolbox => toolbox.destroy()); - } - return promise.resolve(); - }, - - createToolbox: function () { - // If |this.toolboxPromise| exists, there is already a live toolbox - if (this.toolboxPromise) { - return this.toolboxPromise; - } - - let iframe = document.createElement("iframe"); - iframe.id = "toolbox"; - - // Compute a uid on the iframe in order to identify toolbox iframe - // when receiving toolbox-close event - iframe.uid = new Date().getTime(); - - let height = Services.prefs.getIntPref("devtools.toolbox.footer.height"); - iframe.height = height; - - let promise = this.toolboxPromise = AppManager.getTarget().then(target => { - return this._showToolbox(target, iframe); - }).then(toolbox => { - // Destroy the toolbox on WebIDE side before - // toolbox.destroy's promise resolves. - toolbox.once("destroyed", this._onToolboxClosed.bind(this, promise, iframe)); - return toolbox; - }, console.error); - - return this.busyUntil(this.toolboxPromise, "opening toolbox"); - }, - - _showToolbox: function (target, iframe) { - let splitter = document.querySelector(".devtools-horizontal-splitter"); - splitter.removeAttribute("hidden"); - - document.querySelector("notificationbox").insertBefore(iframe, splitter.nextSibling); - let host = Toolbox.HostType.CUSTOM; - let options = { customIframe: iframe, zoom: false, uid: iframe.uid }; - - document.querySelector("#action-button-debug").setAttribute("active", "true"); - - return gDevTools.showToolbox(target, null, host, options); - }, - - prePackageLog: function (msg) { - if (msg == "start") { - UI.selectDeckPanel("logs"); - } - } -}; - -EventEmitter.decorate(UI); - -var Cmds = { - quit: function () { - if (UI.canCloseProject()) { - window.close(); - } - }, - - showProjectPanel: function () { - ProjectPanel.toggleSidebar(); - return promise.resolve(); - }, - - showRuntimePanel: function () { - RuntimeScanners.scan(); - RuntimePanel.toggleSidebar(); - }, - - disconnectRuntime: function () { - let disconnecting = Task.spawn(function* () { - yield UI.destroyToolbox(); - yield AppManager.disconnectRuntime(); - }); - return UI.busyUntil(disconnecting, "disconnecting from runtime"); - }, - - takeScreenshot: function () { - let url = AppManager.deviceFront.screenshotToDataURL(); - return UI.busyUntil(url.then(longstr => { - return longstr.string().then(dataURL => { - longstr.release().then(null, console.error); - UI.openInBrowser(dataURL); - }); - }), "taking screenshot"); - }, - - showPermissionsTable: function () { - UI.selectDeckPanel("permissionstable"); - }, - - showRuntimeDetails: function () { - UI.selectDeckPanel("runtimedetails"); - }, - - showDevicePrefs: function () { - UI.selectDeckPanel("devicepreferences"); - }, - - showSettings: function () { - UI.selectDeckPanel("devicesettings"); - }, - - showMonitor: function () { - UI.selectDeckPanel("monitor"); - }, - - play: Task.async(function* () { - let busy; - switch (AppManager.selectedProject.type) { - case "packaged": - let autosave = - Services.prefs.getBoolPref("devtools.webide.autosaveFiles"); - if (autosave && UI.projecteditor) { - yield UI.projecteditor.saveAllFiles(); - } - busy = UI.busyWithProgressUntil(AppManager.installAndRunProject(), - "installing and running app"); - break; - case "hosted": - busy = UI.busyUntil(AppManager.installAndRunProject(), - "installing and running app"); - break; - case "runtimeApp": - busy = UI.busyUntil(AppManager.launchOrReloadRuntimeApp(), "launching / reloading app"); - break; - case "tab": - busy = UI.busyUntil(AppManager.reloadTab(), "reloading tab"); - break; - } - if (!busy) { - return promise.reject(); - } - UI.onAction("play"); - return busy; - }), - - stop: function () { - return UI.busyUntil(AppManager.stopRunningApp(), "stopping app"); - }, - - toggleToolbox: function () { - UI.onAction("debug"); - if (UI.toolboxPromise) { - UI.destroyToolbox(); - return promise.resolve(); - } else { - return UI.createToolbox(); - } - }, - - removeProject: function () { - AppManager.removeSelectedProject(); - }, - - toggleEditors: function () { - let isNowEnabled = !UI.isProjectEditorEnabled(); - Services.prefs.setBoolPref("devtools.webide.showProjectEditor", isNowEnabled); - if (!isNowEnabled) { - UI.destroyProjectEditor(); - } - UI.openProject(); - }, - - showTroubleShooting: function () { - UI.openInBrowser(HELP_URL); - }, - - showAddons: function () { - UI.selectDeckPanel("addons"); - }, - - showPrefs: function () { - UI.selectDeckPanel("prefs"); - }, - - zoomIn: function () { - if (UI.contentViewer.fullZoom < MAX_ZOOM) { - UI.contentViewer.fullZoom += 0.1; - Services.prefs.setCharPref("devtools.webide.zoom", UI.contentViewer.fullZoom); - } - }, - - zoomOut: function () { - if (UI.contentViewer.fullZoom > MIN_ZOOM) { - UI.contentViewer.fullZoom -= 0.1; - Services.prefs.setCharPref("devtools.webide.zoom", UI.contentViewer.fullZoom); - } - }, - - resetZoom: function () { - UI.contentViewer.fullZoom = 1; - Services.prefs.setCharPref("devtools.webide.zoom", 1); - } -}; diff --git a/devtools/client/webide/content/webide.xul b/devtools/client/webide/content/webide.xul deleted file mode 100644 index a3e4355b9..000000000 --- a/devtools/client/webide/content/webide.xul +++ /dev/null @@ -1,178 +0,0 @@ -<?xml version="1.0"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!DOCTYPE window [ - <!ENTITY % webideDTD SYSTEM "chrome://devtools/locale/webide.dtd" > - %webideDTD; -]> - -<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?> - -<?xml-stylesheet href="chrome://global/skin/global.css"?> -<?xml-stylesheet href="resource://devtools/client/themes/common.css"?> -<?xml-stylesheet href="chrome://webide/skin/webide.css"?> - -<window id="webide" onclose="return UI.canCloseProject();" - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - xmlns:html="http://www.w3.org/1999/xhtml" - title="&windowTitle;" - windowtype="devtools:webide" - macanimationtype="document" - fullscreenbutton="true" - screenX="4" screenY="4" - width="800" height="600" - persist="screenX screenY width height sizemode"> - - <script type="application/javascript" src="chrome://global/content/globalOverlay.js"></script> - <script type="application/javascript" src="project-panel.js"></script> - <script type="application/javascript" src="runtime-panel.js"></script> - <script type="application/javascript" src="webide.js"></script> - - <commandset id="mainCommandSet"> - <commandset id="editMenuCommands"/> - <commandset id="webideCommands"> - <command id="cmd_quit" oncommand="Cmds.quit()"/> - <command id="cmd_newApp" oncommand="Cmds.newApp()" label="&projectMenu_newApp_label;"/> - <command id="cmd_importPackagedApp" oncommand="Cmds.importPackagedApp()" label="&projectMenu_importPackagedApp_label;"/> - <command id="cmd_importHostedApp" oncommand="Cmds.importHostedApp()" label="&projectMenu_importHostedApp_label;"/> - <command id="cmd_showDevicePrefs" label="&runtimeMenu_showDevicePrefs_label;" oncommand="Cmds.showDevicePrefs()"/> - <command id="cmd_showSettings" label="&runtimeMenu_showSettings_label;" oncommand="Cmds.showSettings()"/> - <command id="cmd_removeProject" oncommand="Cmds.removeProject()" label="&projectMenu_remove_label;"/> - <command id="cmd_showProjectPanel" oncommand="Cmds.showProjectPanel()"/> - <command id="cmd_showRuntimePanel" oncommand="Cmds.showRuntimePanel()"/> - <command id="cmd_disconnectRuntime" oncommand="Cmds.disconnectRuntime()" label="&runtimeMenu_disconnect_label;"/> - <command id="cmd_showMonitor" oncommand="Cmds.showMonitor()" label="&runtimeMenu_showMonitor_label;"/> - <command id="cmd_showPermissionsTable" oncommand="Cmds.showPermissionsTable()" label="&runtimeMenu_showPermissionTable_label;"/> - <command id="cmd_showRuntimeDetails" oncommand="Cmds.showRuntimeDetails()" label="&runtimeMenu_showDetails_label;"/> - <command id="cmd_takeScreenshot" oncommand="Cmds.takeScreenshot()" label="&runtimeMenu_takeScreenshot_label;"/> - <command id="cmd_toggleEditor" oncommand="Cmds.toggleEditors()" label="&viewMenu_toggleEditor_label;"/> - <command id="cmd_showAddons" oncommand="Cmds.showAddons()"/> - <command id="cmd_showPrefs" oncommand="Cmds.showPrefs()"/> - <command id="cmd_showTroubleShooting" oncommand="Cmds.showTroubleShooting()"/> - <command id="cmd_play" oncommand="Cmds.play()"/> - <command id="cmd_stop" oncommand="Cmds.stop()" label="&projectMenu_stop_label;"/> - <command id="cmd_toggleToolbox" oncommand="Cmds.toggleToolbox()"/> - <command id="cmd_zoomin" label="&viewMenu_zoomin_label;" oncommand="Cmds.zoomIn()"/> - <command id="cmd_zoomout" label="&viewMenu_zoomout_label;" oncommand="Cmds.zoomOut()"/> - <command id="cmd_resetzoom" label="&viewMenu_resetzoom_label;" oncommand="Cmds.resetZoom()"/> - </commandset> - </commandset> - - <menubar id="main-menubar"> - <menu id="menu-project" label="&projectMenu_label;" accesskey="&projectMenu_accesskey;"> - <menupopup id="menu-project-popup"> - <menuitem command="cmd_newApp" accesskey="&projectMenu_newApp_accesskey;"/> - <menuitem command="cmd_importPackagedApp" accesskey="&projectMenu_importPackagedApp_accesskey;"/> - <menuitem command="cmd_importHostedApp" accesskey="&projectMenu_importHostedApp_accesskey;"/> - <menuitem id="menuitem-show_projectPanel" command="cmd_showProjectPanel" key="key_showProjectPanel" label="&projectMenu_selectApp_label;" accesskey="&projectMenu_selectApp_accesskey;"/> - <menuseparator/> - <menuitem command="cmd_play" key="key_play" label="&projectMenu_play_label;" accesskey="&projectMenu_play_accesskey;"/> - <menuitem command="cmd_stop" accesskey="&projectMenu_stop_accesskey;"/> - <menuitem command="cmd_toggleToolbox" key="key_toggleToolbox" label="&projectMenu_debug_label;" accesskey="&projectMenu_debug_accesskey;"/> - <menuseparator/> - <menuitem command="cmd_removeProject" accesskey="&projectMenu_remove_accesskey;"/> - <menuseparator/> - <menuitem command="cmd_showPrefs" label="&projectMenu_showPrefs_label;" accesskey="&projectMenu_showPrefs_accesskey;"/> - <menuitem command="cmd_showAddons" label="&projectMenu_manageComponents_label;" accesskey="&projectMenu_manageComponents_accesskey;"/> - </menupopup> - </menu> - - <menu id="menu-runtime" label="&runtimeMenu_label;" accesskey="&runtimeMenu_accesskey;"> - <menupopup id="menu-runtime-popup"> - <menuitem command="cmd_showMonitor" accesskey="&runtimeMenu_showMonitor_accesskey;"/> - <menuitem command="cmd_takeScreenshot" accesskey="&runtimeMenu_takeScreenshot_accesskey;"/> - <menuitem command="cmd_showPermissionsTable" accesskey="&runtimeMenu_showPermissionTable_accesskey;"/> - <menuitem command="cmd_showRuntimeDetails" accesskey="&runtimeMenu_showDetails_accesskey;"/> - <menuitem command="cmd_showDevicePrefs" accesskey="&runtimeMenu_showDevicePrefs_accesskey;"/> - <menuitem command="cmd_showSettings" accesskey="&runtimeMenu_showSettings_accesskey;"/> - <menuseparator/> - <menuitem command="cmd_disconnectRuntime" accesskey="&runtimeMenu_disconnect_accesskey;"/> - </menupopup> - </menu> - - <menu id="menu-view" label="&viewMenu_label;" accesskey="&viewMenu_accesskey;"> - <menupopup id="menu-ViewPopup"> - <menuitem command="cmd_toggleEditor" key="key_toggleEditor" accesskey="&viewMenu_toggleEditor_accesskey;"/> - <menuseparator/> - <menuitem command="cmd_zoomin" key="key_zoomin" accesskey="&viewMenu_zoomin_accesskey;"/> - <menuitem command="cmd_zoomout" key="key_zoomout" accesskey="&viewMenu_zoomout_accesskey;"/> - <menuitem command="cmd_resetzoom" key="key_resetzoom" accesskey="&viewMenu_resetzoom_accesskey;"/> - </menupopup> - </menu> - - </menubar> - - <keyset id="mainKeyset"> - <key key="&key_quit;" id="key_quit" command="cmd_quit" modifiers="accel"/> - <key key="&key_showProjectPanel;" id="key_showProjectPanel" command="cmd_showProjectPanel" modifiers="accel"/> - <key key="&key_play;" id="key_play" command="cmd_play" modifiers="accel"/> - <key key="&key_toggleEditor;" id="key_toggleEditor" command="cmd_toggleEditor" modifiers="accel"/> - <key keycode="&key_toggleToolbox;" id="key_toggleToolbox" command="cmd_toggleToolbox"/> - <key key="&key_zoomin;" id="key_zoomin" command="cmd_zoomin" modifiers="accel"/> - <key key="&key_zoomin2;" id="key_zoomin2" command="cmd_zoomin" modifiers="accel"/> - <key key="&key_zoomout;" id="key_zoomout" command="cmd_zoomout" modifiers="accel"/> - <key key="&key_resetzoom;" id="key_resetzoom" command="cmd_resetzoom" modifiers="accel"/> - </keyset> - - <tooltip id="aHTMLTooltip" page="true"/> - - <toolbar id="main-toolbar"> - - <vbox flex="1"> - <hbox id="action-buttons-container" class="busy"> - <toolbarbutton id="action-button-play" class="action-button" command="cmd_play" tooltiptext="&projectMenu_play_label;"/> - <toolbarbutton id="action-button-stop" class="action-button" command="cmd_stop" tooltiptext="&projectMenu_stop_label;"/> - <toolbarbutton id="action-button-debug" class="action-button" command="cmd_toggleToolbox" tooltiptext="&projectMenu_debug_label;"/> - <hbox id="action-busy" align="center"> - <html:img id="action-busy-undetermined" src="chrome://webide/skin/throbber.svg"/> - <progressmeter id="action-busy-determined"/> - </hbox> - </hbox> - - <hbox id="panel-buttons-container"> - <spacer flex="1"/> - <toolbarbutton id="runtime-panel-button" class="panel-button"> - <image class="panel-button-image"/> - <label class="panel-button-label" value="&runtimeButton_label;"/> - </toolbarbutton> - </hbox> - - </vbox> - </toolbar> - - <notificationbox flex="1" id="notificationbox"> - <div flex="1" id="deck-panels"> - <vbox id="project-listing-panel" class="project-listing panel-list" flex="1"> - <div id="project-listing-wrapper" class="panel-list-wrapper"> - <iframe id="project-listing-panel-details" flex="1" src="project-listing.xhtml" tooltip="aHTMLTooltip"/> - </div> - </vbox> - <splitter class="devtools-side-splitter" id="project-listing-splitter"/> - <deck flex="1" id="deck" selectedIndex="-1"> - <iframe id="deck-panel-details" flex="1" src="details.xhtml"/> - <iframe id="deck-panel-projecteditor" flex="1"/> - <iframe id="deck-panel-addons" flex="1" src="addons.xhtml"/> - <iframe id="deck-panel-prefs" flex="1" src="prefs.xhtml"/> - <iframe id="deck-panel-permissionstable" flex="1" lazysrc="permissionstable.xhtml"/> - <iframe id="deck-panel-runtimedetails" flex="1" lazysrc="runtimedetails.xhtml"/> - <iframe id="deck-panel-monitor" flex="1" lazysrc="monitor.xhtml"/> - <iframe id="deck-panel-devicepreferences" flex="1" lazysrc="devicepreferences.xhtml"/> - <iframe id="deck-panel-devicesettings" flex="1" lazysrc="devicesettings.xhtml"/> - <iframe id="deck-panel-logs" flex="1" src="logs.xhtml"/> - <iframe id="deck-panel-simulator" flex="1" lazysrc="simulator.xhtml"/> - </deck> - <splitter class="devtools-side-splitter" id="runtime-listing-splitter"/> - <vbox id="runtime-listing-panel" class="runtime-listing panel-list" flex="1"> - <div id="runtime-listing-wrapper" class="panel-list-wrapper"> - <iframe id="runtime-listing-panel-details" flex="1" src="runtime-listing.xhtml" tooltip="aHTMLTooltip"/> - </div> - </vbox> - </div> - <splitter hidden="true" class="devtools-horizontal-splitter" orient="vertical"/> - <!-- toolbox iframe will be inserted here --> - </notificationbox> - -</window> diff --git a/devtools/client/webide/content/wifi-auth.js b/devtools/client/webide/content/wifi-auth.js deleted file mode 100644 index 5ae5d824c..000000000 --- a/devtools/client/webide/content/wifi-auth.js +++ /dev/null @@ -1,44 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -var Cu = Components.utils; -const { require } = - Cu.import("resource://devtools/shared/Loader.jsm", {}); -const Services = require("Services"); -const QR = require("devtools/shared/qrcode/index"); - -window.addEventListener("load", function onLoad() { - window.removeEventListener("load", onLoad); - document.getElementById("close").onclick = () => window.close(); - document.getElementById("no-scanner").onclick = showToken; - document.getElementById("yes-scanner").onclick = hideToken; - buildUI(); -}); - -function buildUI() { - let { oob } = window.arguments[0]; - createQR(oob); - createToken(oob); -} - -function createQR(oob) { - let oobData = JSON.stringify(oob); - let imgData = QR.encodeToDataURI(oobData, "L" /* low quality */); - document.querySelector("#qr-code img").src = imgData.src; -} - -function createToken(oob) { - let token = oob.sha256.replace(/:/g, "").toLowerCase() + oob.k; - document.querySelector("#token pre").textContent = token; -} - -function showToken() { - document.querySelector("body").setAttribute("token", "true"); -} - -function hideToken() { - document.querySelector("body").removeAttribute("token"); -} diff --git a/devtools/client/webide/content/wifi-auth.xhtml b/devtools/client/webide/content/wifi-auth.xhtml deleted file mode 100644 index cfeec3c96..000000000 --- a/devtools/client/webide/content/wifi-auth.xhtml +++ /dev/null @@ -1,45 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!DOCTYPE html [ - <!ENTITY % webideDTD SYSTEM "chrome://devtools/locale/webide.dtd" > - %webideDTD; -]> - -<html id="devtools:wifi-auth" xmlns="http://www.w3.org/1999/xhtml"> - <head> - <meta charset="utf8"/> - <link rel="stylesheet" href="chrome://webide/skin/deck.css" type="text/css"/> - <link rel="stylesheet" href="chrome://webide/skin/wifi-auth.css" type="text/css"/> - <script type="application/javascript;version=1.8" src="chrome://webide/content/wifi-auth.js"></script> - </head> - <body> - - <div id="controls"> - <a id="close">&deck_close;</a> - </div> - - <h3 id="header">&wifi_auth_header;</h3> - <div id="scan-request">&wifi_auth_scan_request;</div> - - <div id="qr-code"> - <div id="qr-code-wrapper"> - <img/> - </div> - <a id="no-scanner" class="toggle-scanner">&wifi_auth_no_scanner;</a> - <div id="qr-size-note"> - <h5>&wifi_auth_qr_size_note;</h5> - </div> - </div> - - <div id="token"> - <div>&wifi_auth_token_request;</div> - <pre id="token-value"/> - <a id="yes-scanner" class="toggle-scanner">&wifi_auth_yes_scanner;</a> - </div> - - </body> -</html> diff --git a/devtools/client/webide/modules/addons.js b/devtools/client/webide/modules/addons.js deleted file mode 100644 index 4dc09f1ca..000000000 --- a/devtools/client/webide/modules/addons.js +++ /dev/null @@ -1,197 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const promise = require("promise"); -const {AddonManager} = require("resource://gre/modules/AddonManager.jsm"); -const Services = require("Services"); -const {getJSON} = require("devtools/client/shared/getjson"); -const EventEmitter = require("devtools/shared/event-emitter"); - -const ADDONS_URL = "devtools.webide.addonsURL"; - -var SIMULATOR_LINK = Services.prefs.getCharPref("devtools.webide.simulatorAddonsURL"); -var ADB_LINK = Services.prefs.getCharPref("devtools.webide.adbAddonURL"); -var ADAPTERS_LINK = Services.prefs.getCharPref("devtools.webide.adaptersAddonURL"); -var SIMULATOR_ADDON_ID = Services.prefs.getCharPref("devtools.webide.simulatorAddonID"); -var ADB_ADDON_ID = Services.prefs.getCharPref("devtools.webide.adbAddonID"); -var ADAPTERS_ADDON_ID = Services.prefs.getCharPref("devtools.webide.adaptersAddonID"); - -var platform = Services.appShell.hiddenDOMWindow.navigator.platform; -var OS = ""; -if (platform.indexOf("Win") != -1) { - OS = "win32"; -} else if (platform.indexOf("Mac") != -1) { - OS = "mac64"; -} else if (platform.indexOf("Linux") != -1) { - if (platform.indexOf("x86_64") != -1) { - OS = "linux64"; - } else { - OS = "linux32"; - } -} - -var addonsListener = {}; -addonsListener.onEnabled = -addonsListener.onDisabled = -addonsListener.onInstalled = -addonsListener.onUninstalled = (updatedAddon) => { - GetAvailableAddons().then(addons => { - for (let a of [...addons.simulators, addons.adb, addons.adapters]) { - if (a.addonID == updatedAddon.id) { - a.updateInstallStatus(); - } - } - }); -}; -AddonManager.addAddonListener(addonsListener); - -var GetAvailableAddons_promise = null; -var GetAvailableAddons = exports.GetAvailableAddons = function () { - if (!GetAvailableAddons_promise) { - let deferred = promise.defer(); - GetAvailableAddons_promise = deferred.promise; - let addons = { - simulators: [], - adb: null - }; - getJSON(ADDONS_URL).then(json => { - for (let stability in json) { - for (let version of json[stability]) { - addons.simulators.push(new SimulatorAddon(stability, version)); - } - } - addons.adb = new ADBAddon(); - addons.adapters = new AdaptersAddon(); - deferred.resolve(addons); - }, e => { - GetAvailableAddons_promise = null; - deferred.reject(e); - }); - } - return GetAvailableAddons_promise; -}; - -exports.ForgetAddonsList = function () { - GetAvailableAddons_promise = null; -}; - -function Addon() {} -Addon.prototype = { - _status: "unknown", - set status(value) { - if (this._status != value) { - this._status = value; - this.emit("update"); - } - }, - get status() { - return this._status; - }, - - updateInstallStatus: function () { - AddonManager.getAddonByID(this.addonID, (addon) => { - if (addon && !addon.userDisabled) { - this.status = "installed"; - } else { - this.status = "uninstalled"; - } - }); - }, - - install: function () { - AddonManager.getAddonByID(this.addonID, (addon) => { - if (addon && !addon.userDisabled) { - this.status = "installed"; - return; - } - this.status = "preparing"; - if (addon && addon.userDisabled) { - addon.userDisabled = false; - } else { - AddonManager.getInstallForURL(this.xpiLink, (install) => { - install.addListener(this); - install.install(); - }, "application/x-xpinstall"); - } - }); - }, - - uninstall: function () { - AddonManager.getAddonByID(this.addonID, (addon) => { - addon.uninstall(); - }); - }, - - installFailureHandler: function (install, message) { - this.status = "uninstalled"; - this.emit("failure", message); - }, - - onDownloadStarted: function () { - this.status = "downloading"; - }, - - onInstallStarted: function () { - this.status = "installing"; - }, - - onDownloadProgress: function (install) { - if (install.maxProgress == -1) { - this.emit("progress", -1); - } else { - this.emit("progress", install.progress / install.maxProgress); - } - }, - - onInstallEnded: function ({addon}) { - addon.userDisabled = false; - }, - - onDownloadCancelled: function (install) { - this.installFailureHandler(install, "Download cancelled"); - }, - onDownloadFailed: function (install) { - this.installFailureHandler(install, "Download failed"); - }, - onInstallCancelled: function (install) { - this.installFailureHandler(install, "Install cancelled"); - }, - onInstallFailed: function (install) { - this.installFailureHandler(install, "Install failed"); - }, -}; - -function SimulatorAddon(stability, version) { - EventEmitter.decorate(this); - this.stability = stability; - this.version = version; - // This addon uses the string "linux" for "linux32" - let fixedOS = OS == "linux32" ? "linux" : OS; - this.xpiLink = SIMULATOR_LINK.replace(/#OS#/g, fixedOS) - .replace(/#VERSION#/g, version) - .replace(/#SLASHED_VERSION#/g, version.replace(/\./g, "_")); - this.addonID = SIMULATOR_ADDON_ID.replace(/#SLASHED_VERSION#/g, version.replace(/\./g, "_")); - this.updateInstallStatus(); -} -SimulatorAddon.prototype = Object.create(Addon.prototype); - -function ADBAddon() { - EventEmitter.decorate(this); - // This addon uses the string "linux" for "linux32" - let fixedOS = OS == "linux32" ? "linux" : OS; - this.xpiLink = ADB_LINK.replace(/#OS#/g, fixedOS); - this.addonID = ADB_ADDON_ID; - this.updateInstallStatus(); -} -ADBAddon.prototype = Object.create(Addon.prototype); - -function AdaptersAddon() { - EventEmitter.decorate(this); - this.xpiLink = ADAPTERS_LINK.replace(/#OS#/g, OS); - this.addonID = ADAPTERS_ADDON_ID; - this.updateInstallStatus(); -} -AdaptersAddon.prototype = Object.create(Addon.prototype); diff --git a/devtools/client/webide/modules/app-manager.js b/devtools/client/webide/modules/app-manager.js deleted file mode 100644 index 88dfcdd44..000000000 --- a/devtools/client/webide/modules/app-manager.js +++ /dev/null @@ -1,850 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const {Cu} = require("chrome"); - -const promise = require("promise"); -const {TargetFactory} = require("devtools/client/framework/target"); -const Services = require("Services"); -const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {}); -const EventEmitter = require("devtools/shared/event-emitter"); -const {TextEncoder, OS} = Cu.import("resource://gre/modules/osfile.jsm", {}); -const {AppProjects} = require("devtools/client/webide/modules/app-projects"); -const TabStore = require("devtools/client/webide/modules/tab-store"); -const {AppValidator} = require("devtools/client/webide/modules/app-validator"); -const {ConnectionManager, Connection} = require("devtools/shared/client/connection-manager"); -const {AppActorFront} = require("devtools/shared/apps/app-actor-front"); -const {getDeviceFront} = require("devtools/shared/fronts/device"); -const {getPreferenceFront} = require("devtools/shared/fronts/preference"); -const {getSettingsFront} = require("devtools/shared/fronts/settings"); -const {Task} = require("devtools/shared/task"); -const {RuntimeScanners, RuntimeTypes} = require("devtools/client/webide/modules/runtimes"); -const {NetUtil} = Cu.import("resource://gre/modules/NetUtil.jsm", {}); -const Telemetry = require("devtools/client/shared/telemetry"); -const {ProjectBuilding} = require("./build"); - -const Strings = Services.strings.createBundle("chrome://devtools/locale/webide.properties"); - -var AppManager = exports.AppManager = { - - DEFAULT_PROJECT_ICON: "chrome://webide/skin/default-app-icon.png", - DEFAULT_PROJECT_NAME: "--", - - _initialized: false, - - init: function () { - if (this._initialized) { - return; - } - this._initialized = true; - - let port = Services.prefs.getIntPref("devtools.debugger.remote-port"); - this.connection = ConnectionManager.createConnection("localhost", port); - this.onConnectionChanged = this.onConnectionChanged.bind(this); - this.connection.on(Connection.Events.STATUS_CHANGED, this.onConnectionChanged); - - this.tabStore = new TabStore(this.connection); - this.onTabList = this.onTabList.bind(this); - this.onTabNavigate = this.onTabNavigate.bind(this); - this.onTabClosed = this.onTabClosed.bind(this); - this.tabStore.on("tab-list", this.onTabList); - this.tabStore.on("navigate", this.onTabNavigate); - this.tabStore.on("closed", this.onTabClosed); - - this._clearRuntimeList(); - this._rebuildRuntimeList = this._rebuildRuntimeList.bind(this); - RuntimeScanners.on("runtime-list-updated", this._rebuildRuntimeList); - RuntimeScanners.enable(); - this._rebuildRuntimeList(); - - this.onInstallProgress = this.onInstallProgress.bind(this); - - this._telemetry = new Telemetry(); - }, - - destroy: function () { - if (!this._initialized) { - return; - } - this._initialized = false; - - this.selectedProject = null; - this.selectedRuntime = null; - RuntimeScanners.off("runtime-list-updated", this._rebuildRuntimeList); - RuntimeScanners.disable(); - this.runtimeList = null; - this.tabStore.off("tab-list", this.onTabList); - this.tabStore.off("navigate", this.onTabNavigate); - this.tabStore.off("closed", this.onTabClosed); - this.tabStore.destroy(); - this.tabStore = null; - this.connection.off(Connection.Events.STATUS_CHANGED, this.onConnectionChanged); - this._listTabsResponse = null; - this.connection.disconnect(); - this.connection = null; - }, - - /** - * This module emits various events when state changes occur. The basic event - * naming scheme is that event "X" means "X has changed" or "X is available". - * Some names are more detailed to clarify their precise meaning. - * - * The events this module may emit include: - * before-project: - * The selected project is about to change. The event includes a special - * |cancel| callback that will abort the project change if desired. - * connection: - * The connection status has changed (connected, disconnected, etc.) - * install-progress: - * A project being installed to a runtime has made further progress. This - * event contains additional details about exactly how far the process is - * when such information is available. - * project: - * The selected project has changed. - * project-started: - * The selected project started running on the connected runtime. - * project-stopped: - * The selected project stopped running on the connected runtime. - * project-removed: - * The selected project was removed from the project list. - * project-validated: - * The selected project just completed validation. As part of validation, - * many pieces of metadata about the project are refreshed, including its - * name, manifest details, etc. - * runtime: - * The selected runtime has changed. - * runtime-apps-icons: - * The list of URLs for the runtime app icons are available. - * runtime-global-actors: - * The list of global actors for the entire runtime (but not actors for a - * specific tab or app) are now available, so we can test for features - * like preferences and settings. - * runtime-details: - * The selected runtime's details have changed, such as its user-visible - * name. - * runtime-list: - * The list of available runtimes has changed, or any of the user-visible - * details (like names) for the non-selected runtimes has changed. - * runtime-telemetry: - * Detailed runtime telemetry has been recorded. Used by tests. - * runtime-targets: - * The list of remote runtime targets available from the currently - * connected runtime (such as tabs or apps) has changed, or any of the - * user-visible details (like names) for the non-selected runtime targets - * has changed. This event includes |type| in the details, to distinguish - * "apps" and "tabs". - */ - update: function (what, details) { - // Anything we want to forward to the UI - this.emit("app-manager-update", what, details); - }, - - reportError: function (l10nProperty, ...l10nArgs) { - let win = Services.wm.getMostRecentWindow("devtools:webide"); - if (win) { - win.UI.reportError(l10nProperty, ...l10nArgs); - } else { - let text; - if (l10nArgs.length > 0) { - text = Strings.formatStringFromName(l10nProperty, l10nArgs, l10nArgs.length); - } else { - text = Strings.GetStringFromName(l10nProperty); - } - console.error(text); - } - }, - - onConnectionChanged: function () { - console.log("Connection status changed: " + this.connection.status); - - if (this.connection.status == Connection.Status.DISCONNECTED) { - this.selectedRuntime = null; - } - - if (!this.connected) { - if (this._appsFront) { - this._appsFront.off("install-progress", this.onInstallProgress); - this._appsFront.unwatchApps(); - this._appsFront = null; - } - this._listTabsResponse = null; - } else { - this.connection.client.listTabs((response) => { - if (response.webappsActor) { - let front = new AppActorFront(this.connection.client, - response); - front.on("install-progress", this.onInstallProgress); - front.watchApps(() => this.checkIfProjectIsRunning()) - .then(() => { - // This can't be done earlier as many operations - // in the apps actor require watchApps to be called - // first. - this._appsFront = front; - this._listTabsResponse = response; - this._recordRuntimeInfo(); - this.update("runtime-global-actors"); - }) - .then(() => { - this.checkIfProjectIsRunning(); - this.update("runtime-targets", { type: "apps" }); - front.fetchIcons().then(() => this.update("runtime-apps-icons")); - }); - } else { - this._listTabsResponse = response; - this._recordRuntimeInfo(); - this.update("runtime-global-actors"); - } - }); - } - - this.update("connection"); - }, - - get connected() { - return this.connection && - this.connection.status == Connection.Status.CONNECTED; - }, - - get apps() { - if (this._appsFront) { - return this._appsFront.apps; - } else { - return new Map(); - } - }, - - onInstallProgress: function (event, details) { - this.update("install-progress", details); - }, - - isProjectRunning: function () { - if (this.selectedProject.type == "mainProcess" || - this.selectedProject.type == "tab") { - return true; - } - - let app = this._getProjectFront(this.selectedProject); - return app && app.running; - }, - - checkIfProjectIsRunning: function () { - if (this.selectedProject) { - if (this.isProjectRunning()) { - this.update("project-started"); - } else { - this.update("project-stopped"); - } - } - }, - - listTabs: function () { - return this.tabStore.listTabs(); - }, - - onTabList: function () { - this.update("runtime-targets", { type: "tabs" }); - }, - - // TODO: Merge this into TabProject as part of project-agnostic work - onTabNavigate: function () { - this.update("runtime-targets", { type: "tabs" }); - if (this.selectedProject.type !== "tab") { - return; - } - let tab = this.selectedProject.app = this.tabStore.selectedTab; - let uri = NetUtil.newURI(tab.url); - // Wanted to use nsIFaviconService here, but it only works for visited - // tabs, so that's no help for any remote tabs. Maybe some favicon wizard - // knows how to get high-res favicons easily, or we could offer actor - // support for this (bug 1061654). - tab.favicon = uri.prePath + "/favicon.ico"; - tab.name = tab.title || Strings.GetStringFromName("project_tab_loading"); - if (uri.scheme.startsWith("http")) { - tab.name = uri.host + ": " + tab.name; - } - this.selectedProject.location = tab.url; - this.selectedProject.name = tab.name; - this.selectedProject.icon = tab.favicon; - this.update("project-validated"); - }, - - onTabClosed: function () { - if (this.selectedProject.type !== "tab") { - return; - } - this.selectedProject = null; - }, - - reloadTab: function () { - if (this.selectedProject && this.selectedProject.type != "tab") { - return promise.reject("tried to reload non-tab project"); - } - return this.getTarget().then(target => { - target.activeTab.reload(); - }, console.error.bind(console)); - }, - - getTarget: function () { - if (this.selectedProject.type == "mainProcess") { - // Fx >=39 exposes a ChromeActor to debug the main process - if (this.connection.client.mainRoot.traits.allowChromeProcess) { - return this.connection.client.getProcess() - .then(aResponse => { - return TargetFactory.forRemoteTab({ - form: aResponse.form, - client: this.connection.client, - chrome: true - }); - }); - } else { - // Fx <39 exposes tab actors on the root actor - return TargetFactory.forRemoteTab({ - form: this._listTabsResponse, - client: this.connection.client, - chrome: true, - isTabActor: false - }); - } - } - - if (this.selectedProject.type == "tab") { - return this.tabStore.getTargetForTab(); - } - - let app = this._getProjectFront(this.selectedProject); - if (!app) { - return promise.reject("Can't find app front for selected project"); - } - - return Task.spawn(function* () { - // Once we asked the app to launch, the app isn't necessary completely loaded. - // launch request only ask the app to launch and immediatly returns. - // We have to keep trying to get app tab actors required to create its target. - - for (let i = 0; i < 10; i++) { - try { - return yield app.getTarget(); - } catch (e) {} - let deferred = promise.defer(); - setTimeout(deferred.resolve, 500); - yield deferred.promise; - } - - AppManager.reportError("error_cantConnectToApp", app.manifest.manifestURL); - throw new Error("can't connect to app"); - }); - }, - - getProjectManifestURL: function (project) { - let manifest = null; - if (project.type == "runtimeApp") { - manifest = project.app.manifestURL; - } - - if (project.type == "hosted") { - manifest = project.location; - } - - if (project.type == "packaged" && project.packagedAppOrigin) { - manifest = "app://" + project.packagedAppOrigin + "/manifest.webapp"; - } - - return manifest; - }, - - _getProjectFront: function (project) { - let manifest = this.getProjectManifestURL(project); - if (manifest && this._appsFront) { - return this._appsFront.apps.get(manifest); - } - return null; - }, - - _selectedProject: null, - set selectedProject(project) { - // A regular comparison doesn't work as we recreate a new object every time - let prev = this._selectedProject; - if (!prev && !project) { - return; - } else if (prev && project && prev.type === project.type) { - let type = project.type; - if (type === "runtimeApp") { - if (prev.app.manifestURL === project.app.manifestURL) { - return; - } - } else if (type === "tab") { - if (prev.app.actor === project.app.actor) { - return; - } - } else if (type === "packaged" || type === "hosted") { - if (prev.location === project.location) { - return; - } - } else if (type === "mainProcess") { - return; - } else { - throw new Error("Unsupported project type: " + type); - } - } - - let cancelled = false; - this.update("before-project", { cancel: () => { cancelled = true; } }); - if (cancelled) { - return; - } - - this._selectedProject = project; - - // Clear out tab store's selected state, if any - this.tabStore.selectedTab = null; - - if (project) { - if (project.type == "packaged" || - project.type == "hosted") { - this.validateAndUpdateProject(project); - } - if (project.type == "tab") { - this.tabStore.selectedTab = project.app; - } - } - - this.update("project"); - this.checkIfProjectIsRunning(); - }, - get selectedProject() { - return this._selectedProject; - }, - - removeSelectedProject: Task.async(function* () { - let location = this.selectedProject.location; - AppManager.selectedProject = null; - // If the user cancels the removeProject operation, don't remove the project - if (AppManager.selectedProject != null) { - return; - } - - yield AppProjects.remove(location); - AppManager.update("project-removed"); - }), - - packageProject: Task.async(function* (project) { - if (!project) { - return; - } - if (project.type == "packaged" || - project.type == "hosted") { - yield ProjectBuilding.build({ - project: project, - logger: this.update.bind(this, "pre-package") - }); - } - }), - - _selectedRuntime: null, - set selectedRuntime(value) { - this._selectedRuntime = value; - if (!value && this.selectedProject && - (this.selectedProject.type == "mainProcess" || - this.selectedProject.type == "runtimeApp" || - this.selectedProject.type == "tab")) { - this.selectedProject = null; - } - this.update("runtime"); - }, - - get selectedRuntime() { - return this._selectedRuntime; - }, - - connectToRuntime: function (runtime) { - - if (this.connected && this.selectedRuntime === runtime) { - // Already connected - return promise.resolve(); - } - - let deferred = promise.defer(); - - this.disconnectRuntime().then(() => { - this.selectedRuntime = runtime; - - let onConnectedOrDisconnected = () => { - this.connection.off(Connection.Events.CONNECTED, onConnectedOrDisconnected); - this.connection.off(Connection.Events.DISCONNECTED, onConnectedOrDisconnected); - if (this.connected) { - deferred.resolve(); - } else { - deferred.reject(); - } - }; - this.connection.on(Connection.Events.CONNECTED, onConnectedOrDisconnected); - this.connection.on(Connection.Events.DISCONNECTED, onConnectedOrDisconnected); - try { - // Reset the connection's state to defaults - this.connection.resetOptions(); - // Only watch for errors here. Final resolution occurs above, once - // we've reached the CONNECTED state. - this.selectedRuntime.connect(this.connection) - .then(null, e => deferred.reject(e)); - } catch (e) { - deferred.reject(e); - } - }, deferred.reject); - - // Record connection result in telemetry - let logResult = result => { - this._telemetry.log("DEVTOOLS_WEBIDE_CONNECTION_RESULT", result); - if (runtime.type) { - this._telemetry.log("DEVTOOLS_WEBIDE_" + runtime.type + - "_CONNECTION_RESULT", result); - } - }; - deferred.promise.then(() => logResult(true), () => logResult(false)); - - // If successful, record connection time in telemetry - deferred.promise.then(() => { - const timerId = "DEVTOOLS_WEBIDE_CONNECTION_TIME_SECONDS"; - this._telemetry.startTimer(timerId); - this.connection.once(Connection.Events.STATUS_CHANGED, () => { - this._telemetry.stopTimer(timerId); - }); - }).catch(() => { - // Empty rejection handler to silence uncaught rejection warnings - // |connectToRuntime| caller should listen for rejections. - // Bug 1121100 may find a better way to silence these. - }); - - return deferred.promise; - }, - - _recordRuntimeInfo: Task.async(function* () { - if (!this.connected) { - return; - } - let runtime = this.selectedRuntime; - this._telemetry.logKeyed("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_TYPE", - runtime.type || "UNKNOWN", true); - this._telemetry.logKeyed("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_ID", - runtime.id || "unknown", true); - if (!this.deviceFront) { - this.update("runtime-telemetry"); - return; - } - let d = yield this.deviceFront.getDescription(); - this._telemetry.logKeyed("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_PROCESSOR", - d.processor, true); - this._telemetry.logKeyed("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_OS", - d.os, true); - this._telemetry.logKeyed("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_PLATFORM_VERSION", - d.platformversion, true); - this._telemetry.logKeyed("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_APP_TYPE", - d.apptype, true); - this._telemetry.logKeyed("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_VERSION", - d.version, true); - this.update("runtime-telemetry"); - }), - - isMainProcessDebuggable: function () { - // Fx <39 exposes chrome tab actors on RootActor - // Fx >=39 exposes a dedicated actor via getProcess request - return this.connection.client && - this.connection.client.mainRoot && - this.connection.client.mainRoot.traits.allowChromeProcess || - (this._listTabsResponse && - this._listTabsResponse.consoleActor); - }, - - get deviceFront() { - if (!this._listTabsResponse) { - return null; - } - return getDeviceFront(this.connection.client, this._listTabsResponse); - }, - - get preferenceFront() { - if (!this._listTabsResponse) { - return null; - } - return getPreferenceFront(this.connection.client, this._listTabsResponse); - }, - - get settingsFront() { - if (!this._listTabsResponse) { - return null; - } - return getSettingsFront(this.connection.client, this._listTabsResponse); - }, - - disconnectRuntime: function () { - if (!this.connected) { - return promise.resolve(); - } - let deferred = promise.defer(); - this.connection.once(Connection.Events.DISCONNECTED, () => deferred.resolve()); - this.connection.disconnect(); - return deferred.promise; - }, - - launchRuntimeApp: function () { - if (this.selectedProject && this.selectedProject.type != "runtimeApp") { - return promise.reject("attempting to launch a non-runtime app"); - } - let app = this._getProjectFront(this.selectedProject); - return app.launch(); - }, - - launchOrReloadRuntimeApp: function () { - if (this.selectedProject && this.selectedProject.type != "runtimeApp") { - return promise.reject("attempting to launch / reload a non-runtime app"); - } - let app = this._getProjectFront(this.selectedProject); - if (!app.running) { - return app.launch(); - } else { - return app.reload(); - } - }, - - runtimeCanHandleApps: function () { - return !!this._appsFront; - }, - - installAndRunProject: function () { - let project = this.selectedProject; - - if (!project || (project.type != "packaged" && project.type != "hosted")) { - console.error("Can't install project. Unknown type of project."); - return promise.reject("Can't install"); - } - - if (!this._listTabsResponse) { - this.reportError("error_cantInstallNotFullyConnected"); - return promise.reject("Can't install"); - } - - if (!this._appsFront) { - console.error("Runtime doesn't have a webappsActor"); - return promise.reject("Can't install"); - } - - return Task.spawn(function* () { - let self = AppManager; - - // Package and validate project - yield self.packageProject(project); - yield self.validateAndUpdateProject(project); - - if (project.errorsCount > 0) { - self.reportError("error_cantInstallValidationErrors"); - return; - } - - let installPromise; - - if (project.type != "packaged" && project.type != "hosted") { - return promise.reject("Don't know how to install project"); - } - - let response; - if (project.type == "packaged") { - let packageDir = yield ProjectBuilding.getPackageDir(project); - console.log("Installing app from " + packageDir); - - response = yield self._appsFront.installPackaged(packageDir, - project.packagedAppOrigin); - - // If the packaged app specified a custom origin override, - // we need to update the local project origin - project.packagedAppOrigin = response.appId; - // And ensure the indexed db on disk is also updated - AppProjects.update(project); - } - - if (project.type == "hosted") { - let manifestURLObject = Services.io.newURI(project.location, null, null); - let origin = Services.io.newURI(manifestURLObject.prePath, null, null); - let appId = origin.host; - let metadata = { - origin: origin.spec, - manifestURL: project.location - }; - response = yield self._appsFront.installHosted(appId, - metadata, - project.manifest); - } - - // Addons don't have any document to load (yet?) - // So that there is no need to run them, installing is enough - if (project.manifest.manifest_version || project.manifest.role === "addon") { - return; - } - - let {app} = response; - if (!app.running) { - let deferred = promise.defer(); - self.on("app-manager-update", function onUpdate(event, what) { - if (what == "project-started") { - self.off("app-manager-update", onUpdate); - deferred.resolve(); - } - }); - yield app.launch(); - yield deferred.promise; - } else { - yield app.reload(); - } - }); - }, - - stopRunningApp: function () { - let app = this._getProjectFront(this.selectedProject); - return app.close(); - }, - - /* PROJECT VALIDATION */ - - validateAndUpdateProject: function (project) { - if (!project) { - return promise.reject(); - } - - return Task.spawn(function* () { - - let packageDir = yield ProjectBuilding.getPackageDir(project); - let validation = new AppValidator({ - type: project.type, - // Build process may place the manifest in a non-root directory - location: packageDir - }); - - yield validation.validate(); - - if (validation.manifest) { - let manifest = validation.manifest; - let iconPath; - if (manifest.icons) { - let size = Object.keys(manifest.icons).sort((a, b) => b - a)[0]; - if (size) { - iconPath = manifest.icons[size]; - } - } - if (!iconPath) { - project.icon = AppManager.DEFAULT_PROJECT_ICON; - } else { - if (project.type == "hosted") { - let manifestURL = Services.io.newURI(project.location, null, null); - let origin = Services.io.newURI(manifestURL.prePath, null, null); - project.icon = Services.io.newURI(iconPath, null, origin).spec; - } else if (project.type == "packaged") { - let projectFolder = FileUtils.File(packageDir); - let folderURI = Services.io.newFileURI(projectFolder).spec; - project.icon = folderURI + iconPath.replace(/^\/|\\/, ""); - } - } - project.manifest = validation.manifest; - - if ("name" in project.manifest) { - project.name = project.manifest.name; - } else { - project.name = AppManager.DEFAULT_PROJECT_NAME; - } - } else { - project.manifest = null; - project.icon = AppManager.DEFAULT_PROJECT_ICON; - project.name = AppManager.DEFAULT_PROJECT_NAME; - } - - project.validationStatus = "valid"; - - if (validation.warnings.length > 0) { - project.warningsCount = validation.warnings.length; - project.warnings = validation.warnings; - project.validationStatus = "warning"; - } else { - project.warnings = ""; - project.warningsCount = 0; - } - - if (validation.errors.length > 0) { - project.errorsCount = validation.errors.length; - project.errors = validation.errors; - project.validationStatus = "error"; - } else { - project.errors = ""; - project.errorsCount = 0; - } - - if (project.warningsCount && project.errorsCount) { - project.validationStatus = "error warning"; - } - - if (project.type === "hosted" && project.location !== validation.manifestURL) { - yield AppProjects.updateLocation(project, validation.manifestURL); - } else if (AppProjects.get(project.location)) { - yield AppProjects.update(project); - } - - if (AppManager.selectedProject === project) { - AppManager.update("project-validated"); - } - }); - }, - - /* RUNTIME LIST */ - - _clearRuntimeList: function () { - this.runtimeList = { - usb: [], - wifi: [], - simulator: [], - other: [] - }; - }, - - _rebuildRuntimeList: function () { - let runtimes = RuntimeScanners.listRuntimes(); - this._clearRuntimeList(); - - // Reorganize runtimes by type - for (let runtime of runtimes) { - switch (runtime.type) { - case RuntimeTypes.USB: - this.runtimeList.usb.push(runtime); - break; - case RuntimeTypes.WIFI: - this.runtimeList.wifi.push(runtime); - break; - case RuntimeTypes.SIMULATOR: - this.runtimeList.simulator.push(runtime); - break; - default: - this.runtimeList.other.push(runtime); - } - } - - this.update("runtime-details"); - this.update("runtime-list"); - }, - - /* MANIFEST UTILS */ - - writeManifest: function (project) { - if (project.type != "packaged") { - return promise.reject("Not a packaged app"); - } - - if (!project.manifest) { - project.manifest = {}; - } - - let folder = project.location; - let manifestPath = OS.Path.join(folder, "manifest.webapp"); - let text = JSON.stringify(project.manifest, null, 2); - let encoder = new TextEncoder(); - let array = encoder.encode(text); - return OS.File.writeAtomic(manifestPath, array, {tmpPath: manifestPath + ".tmp"}); - }, -}; - -EventEmitter.decorate(AppManager); diff --git a/devtools/client/webide/modules/app-projects.js b/devtools/client/webide/modules/app-projects.js deleted file mode 100644 index 691d09064..000000000 --- a/devtools/client/webide/modules/app-projects.js +++ /dev/null @@ -1,235 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const {Cc, Ci, Cu, Cr} = require("chrome"); -const promise = require("promise"); - -const EventEmitter = require("devtools/shared/event-emitter"); -const {generateUUID} = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator); -const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {}); - -/** - * IndexedDB wrapper that just save project objects - * - * The only constraint is that project objects have to have - * a unique `location` object. - */ - -const IDB = { - _db: null, - databaseName: "AppProjects", - - open: function () { - let deferred = promise.defer(); - - let request = indexedDB.open(IDB.databaseName, 5); - request.onerror = function (event) { - deferred.reject("Unable to open AppProjects indexedDB: " + - this.error.name + " - " + this.error.message); - }; - request.onupgradeneeded = function (event) { - let db = event.target.result; - db.createObjectStore("projects", { keyPath: "location" }); - }; - - request.onsuccess = function () { - let db = IDB._db = request.result; - let objectStore = db.transaction("projects").objectStore("projects"); - let projects = []; - let toRemove = []; - objectStore.openCursor().onsuccess = function (event) { - let cursor = event.target.result; - if (cursor) { - if (cursor.value.location) { - - // We need to make sure this object has a `.location` property. - // The UI depends on this property. - // This should not be needed as we make sure to register valid - // projects, but in the past (before bug 924568), we might have - // registered invalid objects. - - - // We also want to make sure the location is valid. - // If the location doesn't exist, we remove the project. - - try { - let file = FileUtils.File(cursor.value.location); - if (file.exists()) { - projects.push(cursor.value); - } else { - toRemove.push(cursor.value.location); - } - } catch (e) { - if (e.result == Cr.NS_ERROR_FILE_UNRECOGNIZED_PATH) { - // A URL - projects.push(cursor.value); - } - } - } - cursor.continue(); - } else { - let removePromises = []; - for (let location of toRemove) { - removePromises.push(IDB.remove(location)); - } - promise.all(removePromises).then(() => { - deferred.resolve(projects); - }); - } - }; - }; - - return deferred.promise; - }, - - add: function (project) { - let deferred = promise.defer(); - - if (!project.location) { - // We need to make sure this object has a `.location` property. - deferred.reject("Missing location property on project object."); - } else { - let transaction = IDB._db.transaction(["projects"], "readwrite"); - let objectStore = transaction.objectStore("projects"); - let request = objectStore.add(project); - request.onerror = function (event) { - deferred.reject("Unable to add project to the AppProjects indexedDB: " + - this.error.name + " - " + this.error.message); - }; - request.onsuccess = function () { - deferred.resolve(); - }; - } - - return deferred.promise; - }, - - update: function (project) { - let deferred = promise.defer(); - - var transaction = IDB._db.transaction(["projects"], "readwrite"); - var objectStore = transaction.objectStore("projects"); - var request = objectStore.put(project); - request.onerror = function (event) { - deferred.reject("Unable to update project to the AppProjects indexedDB: " + - this.error.name + " - " + this.error.message); - }; - request.onsuccess = function () { - deferred.resolve(); - }; - - return deferred.promise; - }, - - remove: function (location) { - let deferred = promise.defer(); - - let request = IDB._db.transaction(["projects"], "readwrite") - .objectStore("projects") - .delete(location); - request.onsuccess = function (event) { - deferred.resolve(); - }; - request.onerror = function () { - deferred.reject("Unable to delete project to the AppProjects indexedDB: " + - this.error.name + " - " + this.error.message); - }; - - return deferred.promise; - } -}; - -var loadDeferred = promise.defer(); - -loadDeferred.resolve(IDB.open().then(function (projects) { - AppProjects.projects = projects; - AppProjects.emit("ready", projects); -})); - -const AppProjects = { - load: function () { - return loadDeferred.promise; - }, - - addPackaged: function (folder) { - let file = FileUtils.File(folder.path); - if (!file.exists()) { - return promise.reject("path doesn't exist"); - } - let existingProject = this.get(folder.path); - if (existingProject) { - return promise.reject("Already added"); - } - let project = { - type: "packaged", - location: folder.path, - // We need a unique id, that is the app origin, - // in order to identify the app when being installed on the device. - // The packaged app local path is a valid id, but only on the client. - // This origin will be used to generate the true id of an app: - // its manifest URL. - // If the app ends up specifying an explicit origin in its manifest, - // we will override this random UUID on app install. - packagedAppOrigin: generateUUID().toString().slice(1, -1) - }; - return IDB.add(project).then(() => { - this.projects.push(project); - return project; - }); - }, - - addHosted: function (manifestURL) { - let existingProject = this.get(manifestURL); - if (existingProject) { - return promise.reject("Already added"); - } - let project = { - type: "hosted", - location: manifestURL - }; - return IDB.add(project).then(() => { - this.projects.push(project); - return project; - }); - }, - - update: function (project) { - return IDB.update(project); - }, - - updateLocation: function (project, newLocation) { - return IDB.remove(project.location) - .then(() => { - project.location = newLocation; - return IDB.add(project); - }); - }, - - remove: function (location) { - return IDB.remove(location).then(() => { - for (let i = 0; i < this.projects.length; i++) { - if (this.projects[i].location == location) { - this.projects.splice(i, 1); - return; - } - } - throw new Error("Unable to find project in AppProjects store"); - }); - }, - - get: function (location) { - for (let i = 0; i < this.projects.length; i++) { - if (this.projects[i].location == location) { - return this.projects[i]; - } - } - return null; - }, - - projects: [] -}; - -EventEmitter.decorate(AppProjects); - -exports.AppProjects = AppProjects; diff --git a/devtools/client/webide/modules/app-validator.js b/devtools/client/webide/modules/app-validator.js deleted file mode 100644 index 750720110..000000000 --- a/devtools/client/webide/modules/app-validator.js +++ /dev/null @@ -1,292 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -var {Ci, Cu, CC} = require("chrome"); -const promise = require("promise"); - -const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {}); -const Services = require("Services"); -const {Task} = require("devtools/shared/task"); -var XMLHttpRequest = CC("@mozilla.org/xmlextras/xmlhttprequest;1"); -var strings = Services.strings.createBundle("chrome://devtools/locale/app-manager.properties"); - -function AppValidator({ type, location }) { - this.type = type; - this.location = location; - this.errors = []; - this.warnings = []; -} - -AppValidator.prototype.error = function (message) { - this.errors.push(message); -}; - -AppValidator.prototype.warning = function (message) { - this.warnings.push(message); -}; - -AppValidator.prototype._getPackagedManifestFile = function () { - let manifestFile = FileUtils.File(this.location); - if (!manifestFile.exists()) { - this.error(strings.GetStringFromName("validator.nonExistingFolder")); - return null; - } - if (!manifestFile.isDirectory()) { - this.error(strings.GetStringFromName("validator.expectProjectFolder")); - return null; - } - - let appManifestFile = manifestFile.clone(); - appManifestFile.append("manifest.webapp"); - - let jsonManifestFile = manifestFile.clone(); - jsonManifestFile.append("manifest.json"); - - let hasAppManifest = appManifestFile.exists() && appManifestFile.isFile(); - let hasJsonManifest = jsonManifestFile.exists() && jsonManifestFile.isFile(); - - if (!hasAppManifest && !hasJsonManifest) { - this.error(strings.GetStringFromName("validator.noManifestFile")); - return null; - } - - return hasAppManifest ? appManifestFile : jsonManifestFile; -}; - -AppValidator.prototype._getPackagedManifestURL = function () { - let manifestFile = this._getPackagedManifestFile(); - if (!manifestFile) { - return null; - } - return Services.io.newFileURI(manifestFile).spec; -}; - -AppValidator.checkManifest = function (manifestURL) { - let deferred = promise.defer(); - let error; - - let req = new XMLHttpRequest(); - req.overrideMimeType("text/plain"); - - try { - req.open("GET", manifestURL, true); - req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE | Ci.nsIRequest.INHIBIT_CACHING; - } catch (e) { - error = strings.formatStringFromName("validator.invalidManifestURL", [manifestURL], 1); - deferred.reject(error); - return deferred.promise; - } - - req.onload = function () { - let manifest = null; - try { - manifest = JSON.parse(req.responseText); - } catch (e) { - error = strings.formatStringFromName("validator.invalidManifestJSON", [e, manifestURL], 2); - deferred.reject(error); - } - - deferred.resolve({manifest, manifestURL}); - }; - - req.onerror = function () { - error = strings.formatStringFromName("validator.noAccessManifestURL", [req.statusText, manifestURL], 2); - deferred.reject(error); - }; - - try { - req.send(null); - } catch (e) { - error = strings.formatStringFromName("validator.noAccessManifestURL", [e, manifestURL], 2); - deferred.reject(error); - } - - return deferred.promise; -}; - -AppValidator.findManifestAtOrigin = function (manifestURL) { - let fixedManifest = Services.io.newURI(manifestURL, null, null).prePath + "/manifest.webapp"; - return AppValidator.checkManifest(fixedManifest); -}; - -AppValidator.findManifestPath = function (manifestURL) { - let deferred = promise.defer(); - - if (manifestURL.endsWith("manifest.webapp")) { - deferred.reject(); - } else { - let fixedManifest = manifestURL + "/manifest.webapp"; - deferred.resolve(AppValidator.checkManifest(fixedManifest)); - } - - return deferred.promise; -}; - -AppValidator.checkAlternateManifest = function (manifestURL) { - return Task.spawn(function* () { - let result; - try { - result = yield AppValidator.findManifestPath(manifestURL); - } catch (e) { - result = yield AppValidator.findManifestAtOrigin(manifestURL); - } - - return result; - }); -}; - -AppValidator.prototype._fetchManifest = function (manifestURL) { - let deferred = promise.defer(); - this.manifestURL = manifestURL; - - AppValidator.checkManifest(manifestURL) - .then(({manifest, manifestURL}) => { - deferred.resolve(manifest); - }, error => { - AppValidator.checkAlternateManifest(manifestURL) - .then(({manifest, manifestURL}) => { - this.manifestURL = manifestURL; - deferred.resolve(manifest); - }, () => { - this.error(error); - deferred.resolve(null); - }); - }); - - return deferred.promise; -}; - -AppValidator.prototype._getManifest = function () { - let manifestURL; - if (this.type == "packaged") { - manifestURL = this._getPackagedManifestURL(); - if (!manifestURL) - return promise.resolve(null); - } else if (this.type == "hosted") { - manifestURL = this.location; - try { - Services.io.newURI(manifestURL, null, null); - } catch (e) { - this.error(strings.formatStringFromName("validator.invalidHostedManifestURL", [manifestURL, e.message], 2)); - return promise.resolve(null); - } - } else { - this.error(strings.formatStringFromName("validator.invalidProjectType", [this.type], 1)); - return promise.resolve(null); - } - return this._fetchManifest(manifestURL); -}; - -AppValidator.prototype.validateManifest = function (manifest) { - if (!manifest.name) { - this.error(strings.GetStringFromName("validator.missNameManifestProperty")); - } - - if (!manifest.icons || Object.keys(manifest.icons).length === 0) { - this.warning(strings.GetStringFromName("validator.missIconsManifestProperty")); - } else if (!manifest.icons["128"]) { - this.warning(strings.GetStringFromName("validator.missIconMarketplace2")); - } -}; - -AppValidator.prototype._getOriginURL = function () { - if (this.type == "packaged") { - let manifestURL = Services.io.newURI(this.manifestURL, null, null); - return Services.io.newURI(".", null, manifestURL).spec; - } else if (this.type == "hosted") { - return Services.io.newURI(this.location, null, null).prePath; - } -}; - -AppValidator.prototype.validateLaunchPath = function (manifest) { - let deferred = promise.defer(); - // The launch_path field has to start with a `/` - if (manifest.launch_path && manifest.launch_path[0] !== "/") { - this.error(strings.formatStringFromName("validator.nonAbsoluteLaunchPath", [manifest.launch_path], 1)); - deferred.resolve(); - return deferred.promise; - } - let origin = this._getOriginURL(); - let path; - if (this.type == "packaged") { - path = "." + (manifest.launch_path || "/index.html"); - } else if (this.type == "hosted") { - path = manifest.launch_path || "/"; - } - let indexURL; - try { - indexURL = Services.io.newURI(path, null, Services.io.newURI(origin, null, null)).spec; - } catch (e) { - this.error(strings.formatStringFromName("validator.accessFailedLaunchPath", [origin + path], 1)); - deferred.resolve(); - return deferred.promise; - } - - let req = new XMLHttpRequest(); - req.overrideMimeType("text/plain"); - try { - req.open("HEAD", indexURL, true); - req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE | Ci.nsIRequest.INHIBIT_CACHING; - } catch (e) { - this.error(strings.formatStringFromName("validator.accessFailedLaunchPath", [indexURL], 1)); - deferred.resolve(); - return deferred.promise; - } - req.onload = () => { - if (req.status >= 400) - this.error(strings.formatStringFromName("validator.accessFailedLaunchPathBadHttpCode", [indexURL, req.status], 2)); - deferred.resolve(); - }; - req.onerror = () => { - this.error(strings.formatStringFromName("validator.accessFailedLaunchPath", [indexURL], 1)); - deferred.resolve(); - }; - - try { - req.send(null); - } catch (e) { - this.error(strings.formatStringFromName("validator.accessFailedLaunchPath", [indexURL], 1)); - deferred.resolve(); - } - - return deferred.promise; -}; - -AppValidator.prototype.validateType = function (manifest) { - let appType = manifest.type || "web"; - if (["web", "privileged", "certified"].indexOf(appType) === -1) { - this.error(strings.formatStringFromName("validator.invalidAppType", [appType], 1)); - } else if (this.type == "hosted" && - ["certified", "privileged"].indexOf(appType) !== -1) { - this.error(strings.formatStringFromName("validator.invalidHostedPriviledges", [appType], 1)); - } - - // certified app are not fully supported on the simulator - if (appType === "certified") { - this.warning(strings.GetStringFromName("validator.noCertifiedSupport")); - } -}; - -AppValidator.prototype.validate = function () { - this.errors = []; - this.warnings = []; - return this._getManifest(). - then((manifest) => { - if (manifest) { - this.manifest = manifest; - - // Skip validations for add-ons - if (manifest.role === "addon" || manifest.manifest_version) { - return promise.resolve(); - } - - this.validateManifest(manifest); - this.validateType(manifest); - return this.validateLaunchPath(manifest); - } - }); -}; - -exports.AppValidator = AppValidator; diff --git a/devtools/client/webide/modules/build.js b/devtools/client/webide/modules/build.js deleted file mode 100644 index 34cbcc0b7..000000000 --- a/devtools/client/webide/modules/build.js +++ /dev/null @@ -1,199 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const {Cu, Cc, Ci} = require("chrome"); - -const promise = require("promise"); -const { Task } = require("devtools/shared/task"); -const { TextDecoder, OS } = Cu.import("resource://gre/modules/osfile.jsm", {}); -const Subprocess = require("sdk/system/child_process/subprocess"); - -const ProjectBuilding = exports.ProjectBuilding = { - fetchPackageManifest: Task.async(function* (project) { - let manifestPath = OS.Path.join(project.location, "package.json"); - let exists = yield OS.File.exists(manifestPath); - if (!exists) { - // No explicit manifest, try to generate one if possible - return this.generatePackageManifest(project); - } - - let data = yield OS.File.read(manifestPath); - data = new TextDecoder().decode(data); - let manifest; - try { - manifest = JSON.parse(data); - } catch (e) { - throw new Error("Error while reading WebIDE manifest at: '" + manifestPath + - "', invalid JSON: " + e.message); - } - return manifest; - }), - - /** - * For common frameworks in the community, attempt to detect the build - * settings if none are defined. This makes it much easier to get started - * with WebIDE. Later on, perhaps an add-on could define such things for - * different frameworks. - */ - generatePackageManifest: Task.async(function* (project) { - // Cordova - let cordovaConfigPath = OS.Path.join(project.location, "config.xml"); - let exists = yield OS.File.exists(cordovaConfigPath); - if (!exists) { - return; - } - let data = yield OS.File.read(cordovaConfigPath); - data = new TextDecoder().decode(data); - if (data.contains("cordova.apache.org")) { - return { - "webide": { - "prepackage": "cordova prepare", - "packageDir": "./platforms/firefoxos/www" - } - }; - } - }), - - hasPrepackage: Task.async(function* (project) { - let manifest = yield ProjectBuilding.fetchPackageManifest(project); - return manifest && manifest.webide && "prepackage" in manifest.webide; - }), - - // If the app depends on some build step, run it before pushing the app - build: Task.async(function* ({ project, logger }) { - if (!(yield this.hasPrepackage(project))) { - return; - } - - let manifest = yield ProjectBuilding.fetchPackageManifest(project); - - logger("start"); - try { - yield this._build(project, manifest, logger); - logger("succeed"); - } catch (e) { - logger("failed", e); - } - }), - - _build: Task.async(function* (project, manifest, logger) { - // Look for `webide` property - manifest = manifest.webide; - - let command, cwd, args = [], env = []; - - // Copy frequently used env vars - let envService = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment); - ["HOME", "PATH"].forEach(key => { - let value = envService.get(key); - if (value) { - env.push(key + "=" + value); - } - }); - - if (typeof (manifest.prepackage) === "string") { - command = manifest.prepackage.replace(/%project%/g, project.location); - } else if (manifest.prepackage.command) { - command = manifest.prepackage.command; - - args = manifest.prepackage.args || []; - args = args.map(a => a.replace(/%project%/g, project.location)); - - env = env.concat(manifest.prepackage.env || []); - env = env.map(a => a.replace(/%project%/g, project.location)); - - if (manifest.prepackage.cwd) { - // Normalize path for Windows support (converts / to \) - let path = OS.Path.normalize(manifest.prepackage.cwd); - // Note that Path.join also support absolute path and argument. - // So that if cwd is absolute, it will return cwd. - let rel = OS.Path.join(project.location, path); - let exists = yield OS.File.exists(rel); - if (exists) { - cwd = rel; - } - } - } else { - throw new Error("pre-package manifest is invalid, missing or invalid " + - "`prepackage` attribute"); - } - - if (!cwd) { - cwd = project.location; - } - - logger("Running pre-package hook '" + command + "' " + - args.join(" ") + - " with ENV=[" + env.join(", ") + "]" + - " at " + cwd); - - // Run the command through a shell command in order to support non absolute - // paths. - // On Windows `ComSpec` env variable is going to refer to cmd.exe, - // Otherwise, on Linux and Mac, SHELL env variable should refer to - // the user chosen shell program. - // (We do not check for OS, as on windows, with cygwin, ComSpec isn't set) - let shell = envService.get("ComSpec") || envService.get("SHELL"); - args.unshift(command); - - // For cmd.exe, we have to pass the `/C` option, - // but for unix shells we need -c. - // That to interpret next argument as a shell command. - if (envService.exists("ComSpec")) { - args.unshift("/C"); - } else { - args.unshift("-c"); - } - - // Subprocess changes CWD, we have to save and restore it. - let originalCwd = yield OS.File.getCurrentDirectory(); - try { - let defer = promise.defer(); - Subprocess.call({ - command: shell, - arguments: args, - environment: env, - workdir: cwd, - - stdout: data => - logger(data), - stderr: data => - logger(data), - - done: result => { - logger("Terminated with error code: " + result.exitCode); - if (result.exitCode == 0) { - defer.resolve(); - } else { - defer.reject("pre-package command failed with error code " + result.exitCode); - } - } - }); - defer.promise.then(() => { - OS.File.setCurrentDirectory(originalCwd); - }); - yield defer.promise; - } catch (e) { - throw new Error("Unable to run pre-package command '" + command + "' " + - args.join(" ") + ":\n" + (e.message || e)); - } - }), - - getPackageDir: Task.async(function* (project) { - let manifest = yield ProjectBuilding.fetchPackageManifest(project); - if (!manifest || !manifest.webide || !manifest.webide.packageDir) { - return project.location; - } - manifest = manifest.webide; - - let packageDir = OS.Path.join(project.location, manifest.packageDir); - // On Windows, replace / by \\ - packageDir = OS.Path.normalize(packageDir); - let exists = yield OS.File.exists(packageDir); - if (exists) { - return packageDir; - } - throw new Error("Unable to resolve application package directory: '" + manifest.packageDir + "'"); - }) -}; diff --git a/devtools/client/webide/modules/config-view.js b/devtools/client/webide/modules/config-view.js deleted file mode 100644 index 5fb07e235..000000000 --- a/devtools/client/webide/modules/config-view.js +++ /dev/null @@ -1,373 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const {Cu} = require("chrome"); - -const EventEmitter = require("devtools/shared/event-emitter"); -const Services = require("Services"); -const Strings = Services.strings.createBundle("chrome://devtools/locale/webide.properties"); - -var ConfigView; - -module.exports = ConfigView = function (window) { - EventEmitter.decorate(this); - this._doc = window.document; - this._keys = []; - return this; -}; - -ConfigView.prototype = { - _renderByType: function (input, name, value, customType) { - value = customType || typeof value; - - switch (value) { - case "boolean": - input.setAttribute("data-type", "boolean"); - input.setAttribute("type", "checkbox"); - break; - case "number": - input.setAttribute("data-type", "number"); - input.setAttribute("type", "number"); - break; - case "object": - input.setAttribute("data-type", "object"); - input.setAttribute("type", "text"); - break; - default: - input.setAttribute("data-type", "string"); - input.setAttribute("type", "text"); - break; - } - return input; - }, - - set front(front) { - this._front = front; - }, - - set keys(keys) { - this._keys = keys; - }, - - get keys() { - return this._keys; - }, - - set kind(kind) { - this._kind = kind; - }, - - set includeTypeName(include) { - this._includeTypeName = include; - }, - - search: function (event) { - if (event.target.value.length) { - let stringMatch = new RegExp(event.target.value, "i"); - - for (let i = 0; i < this._keys.length; i++) { - let key = this._keys[i]; - let row = this._doc.getElementById("row-" + key); - if (key.match(stringMatch)) { - row.classList.remove("hide"); - } else if (row) { - row.classList.add("hide"); - } - } - } else { - var trs = this._doc.getElementById("device-fields").querySelectorAll("tr"); - - for (let i = 0; i < trs.length; i++) { - trs[i].classList.remove("hide"); - } - } - }, - - generateDisplay: function (json) { - let deviceItems = Object.keys(json); - deviceItems.sort(); - this.keys = deviceItems; - for (let i = 0; i < this.keys.length; i++) { - let key = this.keys[i]; - this.generateField(key, json[key].value, json[key].hasUserValue); - } - }, - - generateField: function (name, value, hasUserValue, customType, newRow) { - let table = this._doc.querySelector("table"); - let sResetDefault = Strings.GetStringFromName("device_reset_default"); - - if (this._keys.indexOf(name) === -1) { - this._keys.push(name); - } - - let input = this._doc.createElement("input"); - let tr = this._doc.createElement("tr"); - tr.setAttribute("id", "row-" + name); - tr.classList.add("edit-row"); - let td = this._doc.createElement("td"); - td.classList.add("field-name"); - td.textContent = name; - tr.appendChild(td); - td = this._doc.createElement("td"); - input.classList.add("editable"); - input.setAttribute("id", name); - input = this._renderByType(input, name, value, customType); - - if (customType === "boolean" || input.type === "checkbox") { - input.checked = value; - } else { - if (typeof value === "object") { - value = JSON.stringify(value); - } - input.value = value; - } - - if (!(this._includeTypeName || isNaN(parseInt(value, 10)))) { - input.type = "number"; - } - - td.appendChild(input); - tr.appendChild(td); - td = this._doc.createElement("td"); - td.setAttribute("id", "td-" + name); - - let button = this._doc.createElement("button"); - button.setAttribute("data-id", name); - button.setAttribute("id", "btn-" + name); - button.classList.add("reset"); - button.textContent = sResetDefault; - td.appendChild(button); - - if (!hasUserValue) { - button.classList.add("hide"); - } - - tr.appendChild(td); - - // If this is a new field, add it to the top of the table. - if (newRow) { - let existing = table.querySelector("#" + name); - - if (!existing) { - table.insertBefore(tr, newRow); - } else { - existing.value = value; - } - } else { - table.appendChild(tr); - } - }, - - resetTable: function () { - let table = this._doc.querySelector("table"); - let trs = table.querySelectorAll("tr:not(#add-custom-field)"); - - for (var i = 0; i < trs.length; i++) { - table.removeChild(trs[i]); - } - - return table; - }, - - _getCallType: function (type, name) { - let frontName = "get"; - - if (this._includeTypeName) { - frontName += type; - } - - return this._front[frontName + this._kind](name); - }, - - _setCallType: function (type, name, value) { - let frontName = "set"; - - if (this._includeTypeName) { - frontName += type; - } - - return this._front[frontName + this._kind](name, value); - }, - - _saveByType: function (options) { - let fieldName = options.id; - let inputType = options.type; - let value = options.value; - let input = this._doc.getElementById(fieldName); - - switch (inputType) { - case "boolean": - this._setCallType("Bool", fieldName, input.checked); - break; - case "number": - this._setCallType("Int", fieldName, value); - break; - case "object": - try { - value = JSON.parse(value); - } catch (e) {} - this._setCallType("Object", fieldName, value); - break; - default: - this._setCallType("Char", fieldName, value); - break; - } - }, - - updateField: function (event) { - if (event.target) { - let inputType = event.target.getAttribute("data-type"); - let inputValue = event.target.checked || event.target.value; - - if (event.target.nodeName == "input" && - event.target.validity.valid && - event.target.classList.contains("editable")) { - let id = event.target.id; - if (inputType === "boolean") { - if (event.target.checked) { - inputValue = true; - } else { - inputValue = false; - } - } - - this._saveByType({ - id: id, - type: inputType, - value: inputValue - }); - this._doc.getElementById("btn-" + id).classList.remove("hide"); - } - } - }, - - _resetToDefault: function (name, input, button) { - this._front["clearUser" + this._kind](name); - let dataType = input.getAttribute("data-type"); - let tr = this._doc.getElementById("row-" + name); - - switch (dataType) { - case "boolean": - this._defaultField = this._getCallType("Bool", name); - this._defaultField.then(boolean => { - input.checked = boolean; - }, () => { - input.checked = false; - tr.parentNode.removeChild(tr); - }); - break; - case "number": - this._defaultField = this._getCallType("Int", name); - this._defaultField.then(number => { - input.value = number; - }, () => { - tr.parentNode.removeChild(tr); - }); - break; - case "object": - this._defaultField = this._getCallType("Object", name); - this._defaultField.then(object => { - input.value = JSON.stringify(object); - }, () => { - tr.parentNode.removeChild(tr); - }); - break; - default: - this._defaultField = this._getCallType("Char", name); - this._defaultField.then(string => { - input.value = string; - }, () => { - tr.parentNode.removeChild(tr); - }); - break; - } - - button.classList.add("hide"); - }, - - checkReset: function (event) { - if (event.target.classList.contains("reset")) { - let btnId = event.target.getAttribute("data-id"); - let input = this._doc.getElementById(btnId); - this._resetToDefault(btnId, input, event.target); - } - }, - - updateFieldType: function () { - let table = this._doc.querySelector("table"); - let customValueType = table.querySelector("#custom-value-type").value; - let customTextEl = table.querySelector("#custom-value-text"); - let customText = customTextEl.value; - - if (customValueType.length === 0) { - return false; - } - - switch (customValueType) { - case "boolean": - customTextEl.type = "checkbox"; - customText = customTextEl.checked; - break; - case "number": - customText = parseInt(customText, 10) || 0; - customTextEl.type = "number"; - break; - default: - customTextEl.type = "text"; - break; - } - - return customValueType; - }, - - clearNewFields: function () { - let table = this._doc.querySelector("table"); - let customTextEl = table.querySelector("#custom-value-text"); - if (customTextEl.checked) { - customTextEl.checked = false; - } else { - customTextEl.value = ""; - } - - this.updateFieldType(); - }, - - updateNewField: function () { - let table = this._doc.querySelector("table"); - let customValueType = this.updateFieldType(); - - if (!customValueType) { - return; - } - - let customRow = table.querySelector("tr:nth-of-type(2)"); - let customTextEl = table.querySelector("#custom-value-text"); - let customTextNameEl = table.querySelector("#custom-value-name"); - - if (customTextEl.validity.valid) { - let customText = customTextEl.value; - - if (customValueType === "boolean") { - customText = customTextEl.checked; - } - - let customTextName = customTextNameEl.value.replace(/[^A-Za-z0-9\.\-_]/gi, ""); - this.generateField(customTextName, customText, true, customValueType, customRow); - this._saveByType({ - id: customTextName, - type: customValueType, - value: customText - }); - customTextNameEl.value = ""; - this.clearNewFields(); - } - }, - - checkNewFieldSubmit: function (event) { - if (event.keyCode === 13) { - this._doc.getElementById("custom-value").click(); - } - } -}; diff --git a/devtools/client/webide/modules/moz.build b/devtools/client/webide/modules/moz.build deleted file mode 100644 index c4072b703..000000000 --- a/devtools/client/webide/modules/moz.build +++ /dev/null @@ -1,21 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -DevToolsModules( - 'addons.js', - 'app-manager.js', - 'app-projects.js', - 'app-validator.js', - 'build.js', - 'config-view.js', - 'project-list.js', - 'runtime-list.js', - 'runtimes.js', - 'simulator-process.js', - 'simulators.js', - 'tab-store.js', - 'utils.js' -) diff --git a/devtools/client/webide/modules/project-list.js b/devtools/client/webide/modules/project-list.js deleted file mode 100644 index 10766dd4f..000000000 --- a/devtools/client/webide/modules/project-list.js +++ /dev/null @@ -1,375 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const {Cu} = require("chrome"); - -const Services = require("Services"); -const {AppProjects} = require("devtools/client/webide/modules/app-projects"); -const {AppManager} = require("devtools/client/webide/modules/app-manager"); -const promise = require("promise"); -const EventEmitter = require("devtools/shared/event-emitter"); -const {Task} = require("devtools/shared/task"); -const utils = require("devtools/client/webide/modules/utils"); -const Telemetry = require("devtools/client/shared/telemetry"); - -const Strings = Services.strings.createBundle("chrome://devtools/locale/webide.properties"); - -var ProjectList; - -module.exports = ProjectList = function (win, parentWindow) { - EventEmitter.decorate(this); - this._doc = win.document; - this._UI = parentWindow.UI; - this._parentWindow = parentWindow; - this._telemetry = new Telemetry(); - this._panelNodeEl = "div"; - - this.onWebIDEUpdate = this.onWebIDEUpdate.bind(this); - this._UI.on("webide-update", this.onWebIDEUpdate); - - AppManager.init(); - this.appManagerUpdate = this.appManagerUpdate.bind(this); - AppManager.on("app-manager-update", this.appManagerUpdate); -}; - -ProjectList.prototype = { - get doc() { - return this._doc; - }, - - appManagerUpdate: function (event, what, details) { - // Got a message from app-manager.js - // See AppManager.update() for descriptions of what these events mean. - switch (what) { - case "project-removed": - case "runtime-apps-icons": - case "runtime-targets": - case "connection": - this.update(details); - break; - case "project": - this.updateCommands(); - this.update(details); - break; - } - }, - - onWebIDEUpdate: function (event, what, details) { - if (what == "busy" || what == "unbusy") { - this.updateCommands(); - } - }, - - /** - * testOptions: { chrome mochitest support - * folder: nsIFile, where to store the app - * index: Number, index of the app in the template list - * name: String name of the app - * } - */ - newApp: function (testOptions) { - let parentWindow = this._parentWindow; - let self = this; - return this._UI.busyUntil(Task.spawn(function* () { - // Open newapp.xul, which will feed ret.location - let ret = {location: null, testOptions: testOptions}; - parentWindow.openDialog("chrome://webide/content/newapp.xul", "newapp", "chrome,modal", ret); - if (!ret.location) - return; - - // Retrieve added project - let project = AppProjects.get(ret.location); - - // Select project - AppManager.selectedProject = project; - - self._telemetry.actionOccurred("webideNewProject"); - }), "creating new app"); - }, - - importPackagedApp: function (location) { - let parentWindow = this._parentWindow; - let UI = this._UI; - return UI.busyUntil(Task.spawn(function* () { - let directory = utils.getPackagedDirectory(parentWindow, location); - - if (!directory) { - // User cancelled directory selection - return; - } - - yield UI.importAndSelectApp(directory); - }), "importing packaged app"); - }, - - importHostedApp: function (location) { - let parentWindow = this._parentWindow; - let UI = this._UI; - return UI.busyUntil(Task.spawn(function* () { - let url = utils.getHostedURL(parentWindow, location); - - if (!url) { - return; - } - - yield UI.importAndSelectApp(url); - }), "importing hosted app"); - }, - - /** - * opts: { - * panel: Object, currenl project panel node - * name: String, name of the project - * icon: String path of the project icon - * } - */ - _renderProjectItem: function (opts) { - let span = opts.panel.querySelector("span") || this._doc.createElement("span"); - span.textContent = opts.name; - let icon = opts.panel.querySelector("img") || this._doc.createElement("img"); - icon.className = "project-image"; - icon.setAttribute("src", opts.icon); - opts.panel.appendChild(icon); - opts.panel.appendChild(span); - opts.panel.setAttribute("title", opts.name); - }, - - refreshTabs: function () { - if (AppManager.connected) { - return AppManager.listTabs().then(() => { - this.updateTabs(); - }).catch(console.error); - } - }, - - updateTabs: function () { - let tabsHeaderNode = this._doc.querySelector("#panel-header-tabs"); - let tabsNode = this._doc.querySelector("#project-panel-tabs"); - - while (tabsNode.hasChildNodes()) { - tabsNode.firstChild.remove(); - } - - if (!AppManager.connected) { - tabsHeaderNode.setAttribute("hidden", "true"); - return; - } - - let tabs = AppManager.tabStore.tabs; - - tabsHeaderNode.removeAttribute("hidden"); - - for (let i = 0; i < tabs.length; i++) { - let tab = tabs[i]; - let URL = this._parentWindow.URL; - let url; - try { - url = new URL(tab.url); - } catch (e) { - // Don't try to handle invalid URLs, especially from Valence. - continue; - } - // Wanted to use nsIFaviconService here, but it only works for visited - // tabs, so that's no help for any remote tabs. Maybe some favicon wizard - // knows how to get high-res favicons easily, or we could offer actor - // support for this (bug 1061654). - if (url.origin) { - tab.favicon = url.origin + "/favicon.ico"; - } - tab.name = tab.title || Strings.GetStringFromName("project_tab_loading"); - if (url.protocol.startsWith("http")) { - tab.name = url.hostname + ": " + tab.name; - } - let panelItemNode = this._doc.createElement(this._panelNodeEl); - panelItemNode.className = "panel-item"; - tabsNode.appendChild(panelItemNode); - this._renderProjectItem({ - panel: panelItemNode, - name: tab.name, - icon: tab.favicon || AppManager.DEFAULT_PROJECT_ICON - }); - panelItemNode.addEventListener("click", () => { - AppManager.selectedProject = { - type: "tab", - app: tab, - icon: tab.favicon || AppManager.DEFAULT_PROJECT_ICON, - location: tab.url, - name: tab.name - }; - }, true); - } - - return promise.resolve(); - }, - - updateApps: function () { - let doc = this._doc; - let runtimeappsHeaderNode = doc.querySelector("#panel-header-runtimeapps"); - let sortedApps = []; - for (let [manifestURL, app] of AppManager.apps) { - sortedApps.push(app); - } - sortedApps = sortedApps.sort((a, b) => { - return a.manifest.name > b.manifest.name; - }); - let mainProcess = AppManager.isMainProcessDebuggable(); - if (AppManager.connected && (sortedApps.length > 0 || mainProcess)) { - runtimeappsHeaderNode.removeAttribute("hidden"); - } else { - runtimeappsHeaderNode.setAttribute("hidden", "true"); - } - - let runtimeAppsNode = doc.querySelector("#project-panel-runtimeapps"); - while (runtimeAppsNode.hasChildNodes()) { - runtimeAppsNode.firstChild.remove(); - } - - if (mainProcess) { - let panelItemNode = doc.createElement(this._panelNodeEl); - panelItemNode.className = "panel-item"; - this._renderProjectItem({ - panel: panelItemNode, - name: Strings.GetStringFromName("mainProcess_label"), - icon: AppManager.DEFAULT_PROJECT_ICON - }); - runtimeAppsNode.appendChild(panelItemNode); - panelItemNode.addEventListener("click", () => { - AppManager.selectedProject = { - type: "mainProcess", - name: Strings.GetStringFromName("mainProcess_label"), - icon: AppManager.DEFAULT_PROJECT_ICON - }; - }, true); - } - - for (let i = 0; i < sortedApps.length; i++) { - let app = sortedApps[i]; - let panelItemNode = doc.createElement(this._panelNodeEl); - panelItemNode.className = "panel-item"; - this._renderProjectItem({ - panel: panelItemNode, - name: app.manifest.name, - icon: app.iconURL || AppManager.DEFAULT_PROJECT_ICON - }); - runtimeAppsNode.appendChild(panelItemNode); - panelItemNode.addEventListener("click", () => { - AppManager.selectedProject = { - type: "runtimeApp", - app: app.manifest, - icon: app.iconURL || AppManager.DEFAULT_PROJECT_ICON, - name: app.manifest.name - }; - }, true); - } - - return promise.resolve(); - }, - - updateCommands: function () { - let doc = this._doc; - let newAppCmd; - let packagedAppCmd; - let hostedAppCmd; - - newAppCmd = doc.querySelector("#new-app"); - packagedAppCmd = doc.querySelector("#packaged-app"); - hostedAppCmd = doc.querySelector("#hosted-app"); - - if (!newAppCmd || !packagedAppCmd || !hostedAppCmd) { - return; - } - - if (this._parentWindow.document.querySelector("window").classList.contains("busy")) { - newAppCmd.setAttribute("disabled", "true"); - packagedAppCmd.setAttribute("disabled", "true"); - hostedAppCmd.setAttribute("disabled", "true"); - return; - } - - newAppCmd.removeAttribute("disabled"); - packagedAppCmd.removeAttribute("disabled"); - hostedAppCmd.removeAttribute("disabled"); - }, - - /** - * Trigger an update of the project and remote runtime list. - * @param options object (optional) - * An |options| object containing a type of |apps| or |tabs| will limit - * what is updated to only those sections. - */ - update: function (options) { - let deferred = promise.defer(); - - if (options && options.type === "apps") { - return this.updateApps(); - } else if (options && options.type === "tabs") { - return this.updateTabs(); - } - - let doc = this._doc; - let projectsNode = doc.querySelector("#project-panel-projects"); - - while (projectsNode.hasChildNodes()) { - projectsNode.firstChild.remove(); - } - - AppProjects.load().then(() => { - let projects = AppProjects.projects; - for (let i = 0; i < projects.length; i++) { - let project = projects[i]; - let panelItemNode = doc.createElement(this._panelNodeEl); - panelItemNode.className = "panel-item"; - projectsNode.appendChild(panelItemNode); - if (!project.validationStatus) { - // The result of the validation process (storing names, icons, …) is not stored in - // the IndexedDB database when App Manager v1 is used. - // We need to run the validation again and update the name and icon of the app. - AppManager.validateAndUpdateProject(project).then(() => { - this._renderProjectItem({ - panel: panelItemNode, - name: project.name, - icon: project.icon - }); - }); - } else { - this._renderProjectItem({ - panel: panelItemNode, - name: project.name || AppManager.DEFAULT_PROJECT_NAME, - icon: project.icon || AppManager.DEFAULT_PROJECT_ICON - }); - } - panelItemNode.addEventListener("click", () => { - AppManager.selectedProject = project; - }, true); - } - - deferred.resolve(); - }, deferred.reject); - - // List remote apps and the main process, if they exist - this.updateApps(); - - // Build the tab list right now, so it's fast... - this.updateTabs(); - - // But re-list them and rebuild, in case any tabs navigated since the last - // time they were listed. - if (AppManager.connected) { - AppManager.listTabs().then(() => { - this.updateTabs(); - }).catch(console.error); - } - - return deferred.promise; - }, - - destroy: function () { - this._doc = null; - AppManager.off("app-manager-update", this.appManagerUpdate); - this._UI.off("webide-update", this.onWebIDEUpdate); - this._UI = null; - this._parentWindow = null; - this._panelNodeEl = null; - } -}; diff --git a/devtools/client/webide/modules/runtime-list.js b/devtools/client/webide/modules/runtime-list.js deleted file mode 100644 index 295dd1705..000000000 --- a/devtools/client/webide/modules/runtime-list.js +++ /dev/null @@ -1,207 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const Services = require("Services"); -const {AppManager} = require("devtools/client/webide/modules/app-manager"); -const EventEmitter = require("devtools/shared/event-emitter"); -const {RuntimeScanners, WiFiScanner} = require("devtools/client/webide/modules/runtimes"); -const {Devices} = require("resource://devtools/shared/apps/Devices.jsm"); -const {Task} = require("devtools/shared/task"); -const utils = require("devtools/client/webide/modules/utils"); - -const Strings = Services.strings.createBundle("chrome://devtools/locale/webide.properties"); - -var RuntimeList; - -module.exports = RuntimeList = function (window, parentWindow) { - EventEmitter.decorate(this); - this._doc = window.document; - this._UI = parentWindow.UI; - this._Cmds = parentWindow.Cmds; - this._parentWindow = parentWindow; - this._panelNodeEl = "button"; - this._panelBoxEl = "div"; - - this.onWebIDEUpdate = this.onWebIDEUpdate.bind(this); - this._UI.on("webide-update", this.onWebIDEUpdate); - - AppManager.init(); - this.appManagerUpdate = this.appManagerUpdate.bind(this); - AppManager.on("app-manager-update", this.appManagerUpdate); -}; - -RuntimeList.prototype = { - get doc() { - return this._doc; - }, - - appManagerUpdate: function (event, what, details) { - // Got a message from app-manager.js - // See AppManager.update() for descriptions of what these events mean. - switch (what) { - case "runtime-list": - this.update(); - break; - case "connection": - case "runtime-global-actors": - this.updateCommands(); - break; - } - }, - - onWebIDEUpdate: function (event, what, details) { - if (what == "busy" || what == "unbusy") { - this.updateCommands(); - } - }, - - takeScreenshot: function () { - this._Cmds.takeScreenshot(); - }, - - showRuntimeDetails: function () { - this._Cmds.showRuntimeDetails(); - }, - - showPermissionsTable: function () { - this._Cmds.showPermissionsTable(); - }, - - showDevicePreferences: function () { - this._Cmds.showDevicePrefs(); - }, - - showSettings: function () { - this._Cmds.showSettings(); - }, - - showTroubleShooting: function () { - this._Cmds.showTroubleShooting(); - }, - - showAddons: function () { - this._Cmds.showAddons(); - }, - - refreshScanners: function () { - RuntimeScanners.scan(); - }, - - updateCommands: function () { - let doc = this._doc; - - // Runtime commands - let screenshotCmd = doc.querySelector("#runtime-screenshot"); - let permissionsCmd = doc.querySelector("#runtime-permissions"); - let detailsCmd = doc.querySelector("#runtime-details"); - let disconnectCmd = doc.querySelector("#runtime-disconnect"); - let devicePrefsCmd = doc.querySelector("#runtime-preferences"); - let settingsCmd = doc.querySelector("#runtime-settings"); - - if (AppManager.connected) { - if (AppManager.deviceFront) { - detailsCmd.removeAttribute("disabled"); - permissionsCmd.removeAttribute("disabled"); - screenshotCmd.removeAttribute("disabled"); - } - if (AppManager.preferenceFront) { - devicePrefsCmd.removeAttribute("disabled"); - } - if (AppManager.settingsFront) { - settingsCmd.removeAttribute("disabled"); - } - disconnectCmd.removeAttribute("disabled"); - } else { - detailsCmd.setAttribute("disabled", "true"); - permissionsCmd.setAttribute("disabled", "true"); - screenshotCmd.setAttribute("disabled", "true"); - disconnectCmd.setAttribute("disabled", "true"); - devicePrefsCmd.setAttribute("disabled", "true"); - settingsCmd.setAttribute("disabled", "true"); - } - }, - - update: function () { - let doc = this._doc; - let wifiHeaderNode = doc.querySelector("#runtime-header-wifi"); - - if (WiFiScanner.allowed) { - wifiHeaderNode.removeAttribute("hidden"); - } else { - wifiHeaderNode.setAttribute("hidden", "true"); - } - - let usbListNode = doc.querySelector("#runtime-panel-usb"); - let wifiListNode = doc.querySelector("#runtime-panel-wifi"); - let simulatorListNode = doc.querySelector("#runtime-panel-simulator"); - let otherListNode = doc.querySelector("#runtime-panel-other"); - let noHelperNode = doc.querySelector("#runtime-panel-noadbhelper"); - let noUSBNode = doc.querySelector("#runtime-panel-nousbdevice"); - - if (Devices.helperAddonInstalled) { - noHelperNode.setAttribute("hidden", "true"); - } else { - noHelperNode.removeAttribute("hidden"); - } - - let runtimeList = AppManager.runtimeList; - - if (!runtimeList) { - return; - } - - if (runtimeList.usb.length === 0 && Devices.helperAddonInstalled) { - noUSBNode.removeAttribute("hidden"); - } else { - noUSBNode.setAttribute("hidden", "true"); - } - - for (let [type, parent] of [ - ["usb", usbListNode], - ["wifi", wifiListNode], - ["simulator", simulatorListNode], - ["other", otherListNode], - ]) { - while (parent.hasChildNodes()) { - parent.firstChild.remove(); - } - for (let runtime of runtimeList[type]) { - let r = runtime; - let panelItemNode = doc.createElement(this._panelBoxEl); - panelItemNode.className = "panel-item-complex"; - - let connectButton = doc.createElement(this._panelNodeEl); - connectButton.className = "panel-item runtime-panel-item-" + type; - connectButton.textContent = r.name; - - connectButton.addEventListener("click", () => { - this._UI.dismissErrorNotification(); - this._UI.connectToRuntime(r); - }, true); - panelItemNode.appendChild(connectButton); - - if (r.configure) { - let configButton = doc.createElement(this._panelNodeEl); - configButton.className = "configure-button"; - configButton.addEventListener("click", r.configure.bind(r), true); - panelItemNode.appendChild(configButton); - } - - parent.appendChild(panelItemNode); - } - } - }, - - destroy: function () { - this._doc = null; - AppManager.off("app-manager-update", this.appManagerUpdate); - this._UI.off("webide-update", this.onWebIDEUpdate); - this._UI = null; - this._Cmds = null; - this._parentWindow = null; - this._panelNodeEl = null; - } -}; diff --git a/devtools/client/webide/modules/runtimes.js b/devtools/client/webide/modules/runtimes.js deleted file mode 100644 index a23337359..000000000 --- a/devtools/client/webide/modules/runtimes.js +++ /dev/null @@ -1,673 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const {Ci} = require("chrome"); -const Services = require("Services"); -const {Devices} = require("resource://devtools/shared/apps/Devices.jsm"); -const {Connection} = require("devtools/shared/client/connection-manager"); -const {DebuggerServer} = require("devtools/server/main"); -const {Simulators} = require("devtools/client/webide/modules/simulators"); -const discovery = require("devtools/shared/discovery/discovery"); -const EventEmitter = require("devtools/shared/event-emitter"); -const promise = require("promise"); -loader.lazyRequireGetter(this, "AuthenticationResult", - "devtools/shared/security/auth", true); -loader.lazyRequireGetter(this, "DevToolsUtils", - "devtools/shared/DevToolsUtils"); - -const Strings = Services.strings.createBundle("chrome://devtools/locale/webide.properties"); - -/** - * Runtime and Scanner API - * - * |RuntimeScanners| maintains a set of |Scanner| objects that produce one or - * more |Runtime|s to connect to. Add-ons can extend the set of known runtimes - * by registering additional |Scanner|s that emit them. - * - * Each |Scanner| must support the following API: - * - * enable() - * Bind any event handlers and start any background work the scanner needs to - * maintain an updated set of |Runtime|s. - * Called when the first consumer (such as WebIDE) actively interested in - * maintaining the |Runtime| list enables the registry. - * disable() - * Unbind any event handlers and stop any background work the scanner needs to - * maintain an updated set of |Runtime|s. - * Called when the last consumer (such as WebIDE) actively interested in - * maintaining the |Runtime| list disables the registry. - * emits "runtime-list-updated" - * If the set of runtimes a |Scanner| manages has changed, it must emit this - * event to notify consumers of changes. - * scan() - * Actively refreshes the list of runtimes the scanner knows about. If your - * scanner uses an active scanning approach (as opposed to listening for - * events when changes occur), the bulk of the work would be done here. - * @return Promise - * Should be resolved when scanning is complete. If scanning has no - * well-defined end point, you can resolve immediately, as long as - * update event is emitted later when changes are noticed. - * listRuntimes() - * Return the current list of runtimes known to the |Scanner| instance. - * @return Iterable - * - * Each |Runtime| must support the following API: - * - * |type| field - * The |type| must be one of the values from the |RuntimeTypes| object. This - * is used for Telemetry and to support displaying sets of |Runtime|s - * categorized by type. - * |id| field - * An identifier that is unique in the set of all runtimes with the same - * |type|. WebIDE tries to save the last used runtime via type + id, and - * tries to locate it again in the next session, so this value should attempt - * to be stable across Firefox sessions. - * |name| field - * A user-visible label to identify the runtime that will be displayed in a - * runtime list. - * |prolongedConnection| field - * A boolean value which should be |true| if the connection process is - * expected to take a unknown or large amount of time. A UI may use this as a - * hint to skip timeouts or other time-based code paths. - * connect() - * Configure the passed |connection| object with any settings need to - * successfully connect to the runtime, and call the |connection|'s connect() - * method. - * @param Connection connection - * A |Connection| object from the DevTools |ConnectionManager|. - * @return Promise - * Resolved once you've called the |connection|'s connect() method. - * configure() OPTIONAL - * Show a configuration screen if the runtime is configurable. - */ - -/* SCANNER REGISTRY */ - -var RuntimeScanners = { - - _enabledCount: 0, - _scanners: new Set(), - - get enabled() { - return !!this._enabledCount; - }, - - add(scanner) { - if (this.enabled) { - // Enable any scanner added while globally enabled - this._enableScanner(scanner); - } - this._scanners.add(scanner); - this._emitUpdated(); - }, - - remove(scanner) { - this._scanners.delete(scanner); - if (this.enabled) { - // Disable any scanner removed while globally enabled - this._disableScanner(scanner); - } - this._emitUpdated(); - }, - - has(scanner) { - return this._scanners.has(scanner); - }, - - scan() { - if (!this.enabled) { - return promise.resolve(); - } - - if (this._scanPromise) { - return this._scanPromise; - } - - let promises = []; - - for (let scanner of this._scanners) { - promises.push(scanner.scan()); - } - - this._scanPromise = promise.all(promises); - - // Reset pending promise - this._scanPromise.then(() => { - this._scanPromise = null; - }, () => { - this._scanPromise = null; - }); - - return this._scanPromise; - }, - - listRuntimes: function* () { - for (let scanner of this._scanners) { - for (let runtime of scanner.listRuntimes()) { - yield runtime; - } - } - }, - - _emitUpdated() { - this.emit("runtime-list-updated"); - }, - - enable() { - if (this._enabledCount++ !== 0) { - // Already enabled scanners during a previous call - return; - } - this._emitUpdated = this._emitUpdated.bind(this); - for (let scanner of this._scanners) { - this._enableScanner(scanner); - } - }, - - _enableScanner(scanner) { - scanner.enable(); - scanner.on("runtime-list-updated", this._emitUpdated); - }, - - disable() { - if (--this._enabledCount !== 0) { - // Already disabled scanners during a previous call - return; - } - for (let scanner of this._scanners) { - this._disableScanner(scanner); - } - }, - - _disableScanner(scanner) { - scanner.off("runtime-list-updated", this._emitUpdated); - scanner.disable(); - }, - -}; - -EventEmitter.decorate(RuntimeScanners); - -exports.RuntimeScanners = RuntimeScanners; - -/* SCANNERS */ - -var SimulatorScanner = { - - _runtimes: [], - - enable() { - this._updateRuntimes = this._updateRuntimes.bind(this); - Simulators.on("updated", this._updateRuntimes); - this._updateRuntimes(); - }, - - disable() { - Simulators.off("updated", this._updateRuntimes); - }, - - _emitUpdated() { - this.emit("runtime-list-updated"); - }, - - _updateRuntimes() { - Simulators.findSimulators().then(simulators => { - this._runtimes = []; - for (let simulator of simulators) { - this._runtimes.push(new SimulatorRuntime(simulator)); - } - this._emitUpdated(); - }); - }, - - scan() { - return promise.resolve(); - }, - - listRuntimes: function () { - return this._runtimes; - } - -}; - -EventEmitter.decorate(SimulatorScanner); -RuntimeScanners.add(SimulatorScanner); - -/** - * TODO: Remove this comaptibility layer in the future (bug 1085393) - * This runtime exists to support the ADB Helper add-on below version 0.7.0. - * - * This scanner will list all ADB devices as runtimes, even if they may or may - * not actually connect (since the |DeprecatedUSBRuntime| assumes a Firefox OS - * device). - */ -var DeprecatedAdbScanner = { - - _runtimes: [], - - enable() { - this._updateRuntimes = this._updateRuntimes.bind(this); - Devices.on("register", this._updateRuntimes); - Devices.on("unregister", this._updateRuntimes); - Devices.on("addon-status-updated", this._updateRuntimes); - this._updateRuntimes(); - }, - - disable() { - Devices.off("register", this._updateRuntimes); - Devices.off("unregister", this._updateRuntimes); - Devices.off("addon-status-updated", this._updateRuntimes); - }, - - _emitUpdated() { - this.emit("runtime-list-updated"); - }, - - _updateRuntimes() { - this._runtimes = []; - for (let id of Devices.available()) { - let runtime = new DeprecatedUSBRuntime(id); - this._runtimes.push(runtime); - runtime.updateNameFromADB().then(() => { - this._emitUpdated(); - }, () => {}); - } - this._emitUpdated(); - }, - - scan() { - return promise.resolve(); - }, - - listRuntimes: function () { - return this._runtimes; - } - -}; - -EventEmitter.decorate(DeprecatedAdbScanner); -RuntimeScanners.add(DeprecatedAdbScanner); - -// ADB Helper 0.7.0 and later will replace this scanner on startup -exports.DeprecatedAdbScanner = DeprecatedAdbScanner; - -/** - * This is a lazy ADB scanner shim which only tells the ADB Helper to start and - * stop as needed. The real scanner that lists devices lives in ADB Helper. - * ADB Helper 0.8.0 and later wait until these signals are received before - * starting ADB polling. For earlier versions, they have no effect. - */ -var LazyAdbScanner = { - - enable() { - Devices.emit("adb-start-polling"); - }, - - disable() { - Devices.emit("adb-stop-polling"); - }, - - scan() { - return promise.resolve(); - }, - - listRuntimes: function () { - return []; - } - -}; - -EventEmitter.decorate(LazyAdbScanner); -RuntimeScanners.add(LazyAdbScanner); - -var WiFiScanner = { - - _runtimes: [], - - init() { - this.updateRegistration(); - Services.prefs.addObserver(this.ALLOWED_PREF, this, false); - }, - - enable() { - this._updateRuntimes = this._updateRuntimes.bind(this); - discovery.on("devtools-device-added", this._updateRuntimes); - discovery.on("devtools-device-updated", this._updateRuntimes); - discovery.on("devtools-device-removed", this._updateRuntimes); - this._updateRuntimes(); - }, - - disable() { - discovery.off("devtools-device-added", this._updateRuntimes); - discovery.off("devtools-device-updated", this._updateRuntimes); - discovery.off("devtools-device-removed", this._updateRuntimes); - }, - - _emitUpdated() { - this.emit("runtime-list-updated"); - }, - - _updateRuntimes() { - this._runtimes = []; - for (let device of discovery.getRemoteDevicesWithService("devtools")) { - this._runtimes.push(new WiFiRuntime(device)); - } - this._emitUpdated(); - }, - - scan() { - discovery.scan(); - return promise.resolve(); - }, - - listRuntimes: function () { - return this._runtimes; - }, - - ALLOWED_PREF: "devtools.remote.wifi.scan", - - get allowed() { - return Services.prefs.getBoolPref(this.ALLOWED_PREF); - }, - - updateRegistration() { - if (this.allowed) { - RuntimeScanners.add(WiFiScanner); - } else { - RuntimeScanners.remove(WiFiScanner); - } - this._emitUpdated(); - }, - - observe(subject, topic, data) { - if (data !== WiFiScanner.ALLOWED_PREF) { - return; - } - WiFiScanner.updateRegistration(); - } - -}; - -EventEmitter.decorate(WiFiScanner); -WiFiScanner.init(); - -exports.WiFiScanner = WiFiScanner; - -var StaticScanner = { - enable() {}, - disable() {}, - scan() { return promise.resolve(); }, - listRuntimes() { - let runtimes = [gRemoteRuntime]; - if (Services.prefs.getBoolPref("devtools.webide.enableLocalRuntime")) { - runtimes.push(gLocalRuntime); - } - return runtimes; - } -}; - -EventEmitter.decorate(StaticScanner); -RuntimeScanners.add(StaticScanner); - -/* RUNTIMES */ - -// These type strings are used for logging events to Telemetry. -// You must update Histograms.json if new types are added. -var RuntimeTypes = exports.RuntimeTypes = { - USB: "USB", - WIFI: "WIFI", - SIMULATOR: "SIMULATOR", - REMOTE: "REMOTE", - LOCAL: "LOCAL", - OTHER: "OTHER" -}; - -/** - * TODO: Remove this comaptibility layer in the future (bug 1085393) - * This runtime exists to support the ADB Helper add-on below version 0.7.0. - * - * This runtime assumes it is connecting to a Firefox OS device. - */ -function DeprecatedUSBRuntime(id) { - this._id = id; -} - -DeprecatedUSBRuntime.prototype = { - type: RuntimeTypes.USB, - get device() { - return Devices.getByName(this._id); - }, - connect: function (connection) { - if (!this.device) { - return promise.reject(new Error("Can't find device: " + this.name)); - } - return this.device.connect().then((port) => { - connection.host = "localhost"; - connection.port = port; - connection.connect(); - }); - }, - get id() { - return this._id; - }, - get name() { - return this._productModel || this._id; - }, - updateNameFromADB: function () { - if (this._productModel) { - return promise.reject(); - } - let deferred = promise.defer(); - if (this.device && this.device.shell) { - this.device.shell("getprop ro.product.model").then(stdout => { - this._productModel = stdout; - deferred.resolve(); - }, () => {}); - } else { - this._productModel = null; - deferred.reject(); - } - return deferred.promise; - }, -}; - -// For testing use only -exports._DeprecatedUSBRuntime = DeprecatedUSBRuntime; - -function WiFiRuntime(deviceName) { - this.deviceName = deviceName; -} - -WiFiRuntime.prototype = { - type: RuntimeTypes.WIFI, - // Mark runtime as taking a long time to connect - prolongedConnection: true, - connect: function (connection) { - let service = discovery.getRemoteService("devtools", this.deviceName); - if (!service) { - return promise.reject(new Error("Can't find device: " + this.name)); - } - connection.advertisement = service; - connection.authenticator.sendOOB = this.sendOOB; - // Disable the default connection timeout, since QR scanning can take an - // unknown amount of time. This prevents spurious errors (even after - // eventual success) from being shown. - connection.timeoutDelay = 0; - connection.connect(); - return promise.resolve(); - }, - get id() { - return this.deviceName; - }, - get name() { - return this.deviceName; - }, - - /** - * During OOB_CERT authentication, a notification dialog like this is used to - * to display a token which the user must transfer through some mechanism to the - * server to authenticate the devices. - * - * This implementation presents the token as text for the user to transfer - * manually. For a mobile device, you should override this implementation with - * something more convenient, such as displaying a QR code. - * - * This method receives an object containing: - * @param host string - * The host name or IP address of the debugger server. - * @param port number - * The port number of the debugger server. - * @param cert object (optional) - * The server's cert details. - * @param authResult AuthenticationResult - * Authentication result sent from the server. - * @param oob object (optional) - * The token data to be transferred during OOB_CERT step 8: - * * sha256: hash(ClientCert) - * * k : K(random 128-bit number) - * @return object containing: - * * close: Function to hide the notification - */ - sendOOB(session) { - const WINDOW_ID = "devtools:wifi-auth"; - let { authResult } = session; - // Only show in the PENDING state - if (authResult != AuthenticationResult.PENDING) { - throw new Error("Expected PENDING result, got " + authResult); - } - - // Listen for the window our prompt opens, so we can close it programatically - let promptWindow; - let windowListener = { - onOpenWindow(xulWindow) { - let win = xulWindow.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindow); - win.addEventListener("load", function listener() { - win.removeEventListener("load", listener, false); - if (win.document.documentElement.getAttribute("id") != WINDOW_ID) { - return; - } - // Found the window - promptWindow = win; - Services.wm.removeListener(windowListener); - }, false); - }, - onCloseWindow() {}, - onWindowTitleChange() {} - }; - Services.wm.addListener(windowListener); - - // |openDialog| is typically a blocking API, so |executeSoon| to get around this - DevToolsUtils.executeSoon(() => { - // Height determines the size of the QR code. Force a minimum size to - // improve scanability. - const MIN_HEIGHT = 600; - let win = Services.wm.getMostRecentWindow("devtools:webide"); - let width = win.outerWidth * 0.8; - let height = Math.max(win.outerHeight * 0.5, MIN_HEIGHT); - win.openDialog("chrome://webide/content/wifi-auth.xhtml", - WINDOW_ID, - "modal=yes,width=" + width + ",height=" + height, session); - }); - - return { - close() { - if (!promptWindow) { - return; - } - promptWindow.close(); - promptWindow = null; - } - }; - } -}; - -// For testing use only -exports._WiFiRuntime = WiFiRuntime; - -function SimulatorRuntime(simulator) { - this.simulator = simulator; -} - -SimulatorRuntime.prototype = { - type: RuntimeTypes.SIMULATOR, - connect: function (connection) { - return this.simulator.launch().then(port => { - connection.host = "localhost"; - connection.port = port; - connection.keepConnecting = true; - connection.once(Connection.Events.DISCONNECTED, e => this.simulator.kill()); - connection.connect(); - }); - }, - configure() { - Simulators.emit("configure", this.simulator); - }, - get id() { - return this.simulator.id; - }, - get name() { - return this.simulator.name; - }, -}; - -// For testing use only -exports._SimulatorRuntime = SimulatorRuntime; - -var gLocalRuntime = { - type: RuntimeTypes.LOCAL, - connect: function (connection) { - if (!DebuggerServer.initialized) { - DebuggerServer.init(); - DebuggerServer.addBrowserActors(); - } - DebuggerServer.allowChromeProcess = true; - connection.host = null; // Force Pipe transport - connection.port = null; - connection.connect(); - return promise.resolve(); - }, - get id() { - return "local"; - }, - get name() { - return Strings.GetStringFromName("local_runtime"); - }, -}; - -// For testing use only -exports._gLocalRuntime = gLocalRuntime; - -var gRemoteRuntime = { - type: RuntimeTypes.REMOTE, - connect: function (connection) { - let win = Services.wm.getMostRecentWindow("devtools:webide"); - if (!win) { - return promise.reject(new Error("No WebIDE window found")); - } - let ret = {value: connection.host + ":" + connection.port}; - let title = Strings.GetStringFromName("remote_runtime_promptTitle"); - let message = Strings.GetStringFromName("remote_runtime_promptMessage"); - let ok = Services.prompt.prompt(win, title, message, ret, null, {}); - let [host, port] = ret.value.split(":"); - if (!ok) { - return promise.reject({canceled: true}); - } - if (!host || !port) { - return promise.reject(new Error("Invalid host or port")); - } - connection.host = host; - connection.port = port; - connection.connect(); - return promise.resolve(); - }, - get name() { - return Strings.GetStringFromName("remote_runtime"); - }, -}; - -// For testing use only -exports._gRemoteRuntime = gRemoteRuntime; diff --git a/devtools/client/webide/modules/simulator-process.js b/devtools/client/webide/modules/simulator-process.js deleted file mode 100644 index 7d0b57cc6..000000000 --- a/devtools/client/webide/modules/simulator-process.js +++ /dev/null @@ -1,325 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -"use strict"; - -const { Cc, Ci, Cu } = require("chrome"); - -const Environment = require("sdk/system/environment").env; -const EventEmitter = require("devtools/shared/event-emitter"); -const promise = require("promise"); -const Subprocess = require("sdk/system/child_process/subprocess"); -const Services = require("Services"); - -loader.lazyGetter(this, "OS", () => { - const Runtime = require("sdk/system/runtime"); - switch (Runtime.OS) { - case "Darwin": - return "mac64"; - case "Linux": - if (Runtime.XPCOMABI.indexOf("x86_64") === 0) { - return "linux64"; - } else { - return "linux32"; - } - case "WINNT": - return "win32"; - default: - return ""; - } -}); - -function SimulatorProcess() {} -SimulatorProcess.prototype = { - - // Check if B2G is running. - get isRunning() { - return !!this.process; - }, - - // Start the process and connect the debugger client. - run() { - - // Resolve B2G binary. - let b2g = this.b2gBinary; - if (!b2g || !b2g.exists()) { - throw Error("B2G executable not found."); - } - - // Ensure Gaia profile exists. - let gaia = this.gaiaProfile; - if (!gaia || !gaia.exists()) { - throw Error("Gaia profile directory not found."); - } - - this.once("stdout", function () { - if (OS == "mac64") { - console.debug("WORKAROUND run osascript to show b2g-desktop window on OS=='mac64'"); - // Escape double quotes and escape characters for use in AppleScript. - let path = b2g.path.replace(/\\/g, "\\\\").replace(/\"/g, '\\"'); - - Subprocess.call({ - command: "/usr/bin/osascript", - arguments: ["-e", 'tell application "' + path + '" to activate'], - }); - } - }); - - let logHandler = (e, data) => this.log(e, data.trim()); - this.on("stdout", logHandler); - this.on("stderr", logHandler); - this.once("exit", () => { - this.off("stdout", logHandler); - this.off("stderr", logHandler); - }); - - let environment; - if (OS.indexOf("linux") > -1) { - environment = ["TMPDIR=" + Services.dirsvc.get("TmpD", Ci.nsIFile).path]; - ["DISPLAY", "XAUTHORITY"].forEach(key => { - if (key in Environment) { - environment.push(key + "=" + Environment[key]); - } - }); - } - - // Spawn a B2G instance. - this.process = Subprocess.call({ - command: b2g, - arguments: this.args, - environment: environment, - stdout: data => this.emit("stdout", data), - stderr: data => this.emit("stderr", data), - // On B2G instance exit, reset tracked process, remote debugger port and - // shuttingDown flag, then finally emit an exit event. - done: result => { - console.log("B2G terminated with " + result.exitCode); - this.process = null; - this.emit("exit", result.exitCode); - } - }); - }, - - // Request a B2G instance kill. - kill() { - let deferred = promise.defer(); - if (this.process) { - this.once("exit", (e, exitCode) => { - this.shuttingDown = false; - deferred.resolve(exitCode); - }); - if (!this.shuttingDown) { - this.shuttingDown = true; - this.emit("kill", null); - this.process.kill(); - } - return deferred.promise; - } else { - return promise.resolve(undefined); - } - }, - - // Maybe log output messages. - log(level, message) { - if (!Services.prefs.getBoolPref("devtools.webide.logSimulatorOutput")) { - return; - } - if (level === "stderr" || level === "error") { - console.error(message); - return; - } - console.log(message); - }, - - // Compute B2G CLI arguments. - get args() { - let args = []; - - // Gaia profile. - args.push("-profile", this.gaiaProfile.path); - - // Debugger server port. - let port = parseInt(this.options.port); - args.push("-start-debugger-server", "" + port); - - // Screen size. - let width = parseInt(this.options.width); - let height = parseInt(this.options.height); - if (width && height) { - args.push("-screen", width + "x" + height); - } - - // Ignore eventual zombie instances of b2g that are left over. - args.push("-no-remote"); - - // If we are running a simulator based on Mulet, - // we have to override the default chrome URL - // in order to prevent the Browser UI to appear. - if (this.b2gBinary.leafName.includes("firefox")) { - args.push("-chrome", "chrome://b2g/content/shell.html"); - } - - return args; - }, -}; - -EventEmitter.decorate(SimulatorProcess.prototype); - - -function CustomSimulatorProcess(options) { - this.options = options; -} - -var CSPp = CustomSimulatorProcess.prototype = Object.create(SimulatorProcess.prototype); - -// Compute B2G binary file handle. -Object.defineProperty(CSPp, "b2gBinary", { - get: function () { - let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile); - file.initWithPath(this.options.b2gBinary); - return file; - } -}); - -// Compute Gaia profile file handle. -Object.defineProperty(CSPp, "gaiaProfile", { - get: function () { - let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile); - file.initWithPath(this.options.gaiaProfile); - return file; - } -}); - -exports.CustomSimulatorProcess = CustomSimulatorProcess; - - -function AddonSimulatorProcess(addon, options) { - this.addon = addon; - this.options = options; -} - -var ASPp = AddonSimulatorProcess.prototype = Object.create(SimulatorProcess.prototype); - -// Compute B2G binary file handle. -Object.defineProperty(ASPp, "b2gBinary", { - get: function () { - let file; - try { - let pref = "extensions." + this.addon.id + ".customRuntime"; - file = Services.prefs.getComplexValue(pref, Ci.nsIFile); - } catch (e) {} - - if (!file) { - file = this.addon.getResourceURI().QueryInterface(Ci.nsIFileURL).file; - file.append("b2g"); - let binaries = { - win32: "b2g-bin.exe", - mac64: "B2G.app/Contents/MacOS/b2g-bin", - linux32: "b2g-bin", - linux64: "b2g-bin", - }; - binaries[OS].split("/").forEach(node => file.append(node)); - } - // If the binary doesn't exists, it may be because of a simulator - // based on mulet, which has a different binary name. - if (!file.exists()) { - file = this.addon.getResourceURI().QueryInterface(Ci.nsIFileURL).file; - file.append("firefox"); - let binaries = { - win32: "firefox.exe", - mac64: "FirefoxNightly.app/Contents/MacOS/firefox-bin", - linux32: "firefox-bin", - linux64: "firefox-bin", - }; - binaries[OS].split("/").forEach(node => file.append(node)); - } - return file; - } -}); - -// Compute Gaia profile file handle. -Object.defineProperty(ASPp, "gaiaProfile", { - get: function () { - let file; - - // Custom profile from simulator configuration. - if (this.options.gaiaProfile) { - file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile); - file.initWithPath(this.options.gaiaProfile); - return file; - } - - // Custom profile from addon prefs. - try { - let pref = "extensions." + this.addon.id + ".gaiaProfile"; - file = Services.prefs.getComplexValue(pref, Ci.nsIFile); - return file; - } catch (e) {} - - // Default profile from addon. - file = this.addon.getResourceURI().QueryInterface(Ci.nsIFileURL).file; - file.append("profile"); - return file; - } -}); - -exports.AddonSimulatorProcess = AddonSimulatorProcess; - - -function OldAddonSimulatorProcess(addon, options) { - this.addon = addon; - this.options = options; -} - -var OASPp = OldAddonSimulatorProcess.prototype = Object.create(AddonSimulatorProcess.prototype); - -// Compute B2G binary file handle. -Object.defineProperty(OASPp, "b2gBinary", { - get: function () { - let file; - try { - let pref = "extensions." + this.addon.id + ".customRuntime"; - file = Services.prefs.getComplexValue(pref, Ci.nsIFile); - } catch (e) {} - - if (!file) { - file = this.addon.getResourceURI().QueryInterface(Ci.nsIFileURL).file; - let version = this.addon.name.match(/\d+\.\d+/)[0].replace(/\./, "_"); - file.append("resources"); - file.append("fxos_" + version + "_simulator"); - file.append("data"); - file.append(OS == "linux32" ? "linux" : OS); - let binaries = { - win32: "b2g/b2g-bin.exe", - mac64: "B2G.app/Contents/MacOS/b2g-bin", - linux32: "b2g/b2g-bin", - linux64: "b2g/b2g-bin", - }; - binaries[OS].split("/").forEach(node => file.append(node)); - } - return file; - } -}); - -// Compute B2G CLI arguments. -Object.defineProperty(OASPp, "args", { - get: function () { - let args = []; - - // Gaia profile. - args.push("-profile", this.gaiaProfile.path); - - // Debugger server port. - let port = parseInt(this.options.port); - args.push("-dbgport", "" + port); - - // Ignore eventual zombie instances of b2g that are left over. - args.push("-no-remote"); - - return args; - } -}); - -exports.OldAddonSimulatorProcess = OldAddonSimulatorProcess; diff --git a/devtools/client/webide/modules/simulators.js b/devtools/client/webide/modules/simulators.js deleted file mode 100644 index f09df9e05..000000000 --- a/devtools/client/webide/modules/simulators.js +++ /dev/null @@ -1,368 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const { AddonManager } = require("resource://gre/modules/AddonManager.jsm"); -const { Task } = require("devtools/shared/task"); -loader.lazyRequireGetter(this, "ConnectionManager", "devtools/shared/client/connection-manager", true); -loader.lazyRequireGetter(this, "AddonSimulatorProcess", "devtools/client/webide/modules/simulator-process", true); -loader.lazyRequireGetter(this, "OldAddonSimulatorProcess", "devtools/client/webide/modules/simulator-process", true); -loader.lazyRequireGetter(this, "CustomSimulatorProcess", "devtools/client/webide/modules/simulator-process", true); -const asyncStorage = require("devtools/shared/async-storage"); -const EventEmitter = require("devtools/shared/event-emitter"); -const promise = require("promise"); -const Services = require("Services"); - -const SimulatorRegExp = new RegExp(Services.prefs.getCharPref("devtools.webide.simulatorAddonRegExp")); -const LocaleCompare = (a, b) => { - return a.name.toLowerCase().localeCompare(b.name.toLowerCase()); -}; - -var Simulators = { - - // The list of simulator configurations. - _simulators: [], - - /** - * Load a previously saved list of configurations (only once). - * - * @return Promise. - */ - _load() { - if (this._loadingPromise) { - return this._loadingPromise; - } - - this._loadingPromise = Task.spawn(function* () { - let jobs = []; - - let value = yield asyncStorage.getItem("simulators"); - if (Array.isArray(value)) { - value.forEach(options => { - let simulator = new Simulator(options); - Simulators.add(simulator, true); - - // If the simulator had a reference to an addon, fix it. - if (options.addonID) { - let deferred = promise.defer(); - AddonManager.getAddonByID(options.addonID, addon => { - simulator.addon = addon; - delete simulator.options.addonID; - deferred.resolve(); - }); - jobs.push(deferred.promise); - } - }); - } - - yield promise.all(jobs); - yield Simulators._addUnusedAddons(); - Simulators.emitUpdated(); - return Simulators._simulators; - }); - - return this._loadingPromise; - }, - - /** - * Add default simulators to the list for each new (unused) addon. - * - * @return Promise. - */ - _addUnusedAddons: Task.async(function* () { - let jobs = []; - - let addons = yield Simulators.findSimulatorAddons(); - addons.forEach(addon => { - jobs.push(Simulators.addIfUnusedAddon(addon, true)); - }); - - yield promise.all(jobs); - }), - - /** - * Save the current list of configurations. - * - * @return Promise. - */ - _save: Task.async(function* () { - yield this._load(); - - let value = Simulators._simulators.map(simulator => { - let options = JSON.parse(JSON.stringify(simulator.options)); - if (simulator.addon != null) { - options.addonID = simulator.addon.id; - } - return options; - }); - - yield asyncStorage.setItem("simulators", value); - }), - - /** - * List all available simulators. - * - * @return Promised simulator list. - */ - findSimulators: Task.async(function* () { - yield this._load(); - return Simulators._simulators; - }), - - /** - * List all installed simulator addons. - * - * @return Promised addon list. - */ - findSimulatorAddons() { - let deferred = promise.defer(); - AddonManager.getAllAddons(all => { - let addons = []; - for (let addon of all) { - if (Simulators.isSimulatorAddon(addon)) { - addons.push(addon); - } - } - // Sort simulator addons by name. - addons.sort(LocaleCompare); - deferred.resolve(addons); - }); - return deferred.promise; - }, - - /** - * Add a new simulator for `addon` if no other simulator uses it. - */ - addIfUnusedAddon(addon, silently = false) { - let simulators = this._simulators; - let matching = simulators.filter(s => s.addon && s.addon.id == addon.id); - if (matching.length > 0) { - return promise.resolve(); - } - let options = {}; - options.name = addon.name.replace(" Simulator", ""); - // Some addons specify a simulator type at the end of their version string, - // e.g. "2_5_tv". - let type = this.simulatorAddonVersion(addon).split("_")[2]; - if (type) { - // "tv" is shorthand for type "television". - options.type = (type === "tv" ? "television" : type); - } - return this.add(new Simulator(options, addon), silently); - }, - - // TODO (Bug 1146521) Maybe find a better way to deal with removed addons? - removeIfUsingAddon(addon) { - let simulators = this._simulators; - let remaining = simulators.filter(s => !s.addon || s.addon.id != addon.id); - this._simulators = remaining; - if (remaining.length !== simulators.length) { - this.emitUpdated(); - } - }, - - /** - * Add a new simulator to the list. Caution: `simulator.name` may be modified. - * - * @return Promise to added simulator. - */ - add(simulator, silently = false) { - let simulators = this._simulators; - let uniqueName = this.uniqueName(simulator.options.name); - simulator.options.name = uniqueName; - simulators.push(simulator); - if (!silently) { - this.emitUpdated(); - } - return promise.resolve(simulator); - }, - - /** - * Remove a simulator from the list. - */ - remove(simulator) { - let simulators = this._simulators; - let remaining = simulators.filter(s => s !== simulator); - this._simulators = remaining; - if (remaining.length !== simulators.length) { - this.emitUpdated(); - } - }, - - /** - * Get a unique name for a simulator (may add a suffix, e.g. "MyName (1)"). - */ - uniqueName(name) { - let simulators = this._simulators; - - let names = {}; - simulators.forEach(simulator => names[simulator.name] = true); - - // Strip any previous suffix, add a new suffix if necessary. - let stripped = name.replace(/ \(\d+\)$/, ""); - let unique = stripped; - for (let i = 1; names[unique]; i++) { - unique = stripped + " (" + i + ")"; - } - return unique; - }, - - /** - * Compare an addon's ID against the expected form of a simulator addon ID, - * and try to extract its version if there is a match. - * - * Note: If a simulator addon is recognized, but no version can be extracted - * (e.g. custom RegExp pref value), we return "Unknown" to keep the returned - * value 'truthy'. - */ - simulatorAddonVersion(addon) { - let match = SimulatorRegExp.exec(addon.id); - if (!match) { - return null; - } - let version = match[1]; - return version || "Unknown"; - }, - - /** - * Detect simulator addons, including "unofficial" ones. - */ - isSimulatorAddon(addon) { - return !!this.simulatorAddonVersion(addon); - }, - - emitUpdated() { - this.emit("updated", { length: this._simulators.length }); - this._simulators.sort(LocaleCompare); - this._save(); - }, - - onConfigure(e, simulator) { - this._lastConfiguredSimulator = simulator; - }, - - onInstalled(addon) { - if (this.isSimulatorAddon(addon)) { - this.addIfUnusedAddon(addon); - } - }, - - onEnabled(addon) { - if (this.isSimulatorAddon(addon)) { - this.addIfUnusedAddon(addon); - } - }, - - onDisabled(addon) { - if (this.isSimulatorAddon(addon)) { - this.removeIfUsingAddon(addon); - } - }, - - onUninstalled(addon) { - if (this.isSimulatorAddon(addon)) { - this.removeIfUsingAddon(addon); - } - }, -}; -exports.Simulators = Simulators; -AddonManager.addAddonListener(Simulators); -EventEmitter.decorate(Simulators); -Simulators.on("configure", Simulators.onConfigure.bind(Simulators)); - -function Simulator(options = {}, addon = null) { - this.addon = addon; - this.options = options; - - // Fill `this.options` with default values where needed. - let defaults = this.defaults; - for (let option in defaults) { - if (this.options[option] == null) { - this.options[option] = defaults[option]; - } - } -} -Simulator.prototype = { - - // Default simulation options. - _defaults: { - // Based on the Firefox OS Flame. - phone: { - width: 320, - height: 570, - pixelRatio: 1.5 - }, - // Based on a 720p HD TV. - television: { - width: 1280, - height: 720, - pixelRatio: 1, - } - }, - _defaultType: "phone", - - restoreDefaults() { - let defaults = this.defaults; - let options = this.options; - for (let option in defaults) { - options[option] = defaults[option]; - } - }, - - launch() { - // Close already opened simulation. - if (this.process) { - return this.kill().then(this.launch.bind(this)); - } - - this.options.port = ConnectionManager.getFreeTCPPort(); - - // Choose simulator process type. - if (this.options.b2gBinary) { - // Custom binary. - this.process = new CustomSimulatorProcess(this.options); - } else if (this.version > "1.3") { - // Recent simulator addon. - this.process = new AddonSimulatorProcess(this.addon, this.options); - } else { - // Old simulator addon. - this.process = new OldAddonSimulatorProcess(this.addon, this.options); - } - this.process.run(); - - return promise.resolve(this.options.port); - }, - - kill() { - let process = this.process; - if (!process) { - return promise.resolve(); - } - this.process = null; - return process.kill(); - }, - - get defaults() { - let defaults = this._defaults; - return defaults[this.type] || defaults[this._defaultType]; - }, - - get id() { - return this.name; - }, - - get name() { - return this.options.name; - }, - - get type() { - return this.options.type || this._defaultType; - }, - - get version() { - return this.options.b2gBinary ? "Custom" : this.addon.name.match(/\d+\.\d+/)[0]; - }, -}; -exports.Simulator = Simulator; diff --git a/devtools/client/webide/modules/tab-store.js b/devtools/client/webide/modules/tab-store.js deleted file mode 100644 index 0fed366cc..000000000 --- a/devtools/client/webide/modules/tab-store.js +++ /dev/null @@ -1,178 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const { Cu } = require("chrome"); - -const { TargetFactory } = require("devtools/client/framework/target"); -const EventEmitter = require("devtools/shared/event-emitter"); -const { Connection } = require("devtools/shared/client/connection-manager"); -const promise = require("promise"); -const { Task } = require("devtools/shared/task"); - -const _knownTabStores = new WeakMap(); - -var TabStore; - -module.exports = TabStore = function (connection) { - // If we already know about this connection, - // let's re-use the existing store. - if (_knownTabStores.has(connection)) { - return _knownTabStores.get(connection); - } - - _knownTabStores.set(connection, this); - - EventEmitter.decorate(this); - - this._resetStore(); - - this.destroy = this.destroy.bind(this); - this._onStatusChanged = this._onStatusChanged.bind(this); - - this._connection = connection; - this._connection.once(Connection.Events.DESTROYED, this.destroy); - this._connection.on(Connection.Events.STATUS_CHANGED, this._onStatusChanged); - this._onTabListChanged = this._onTabListChanged.bind(this); - this._onTabNavigated = this._onTabNavigated.bind(this); - this._onStatusChanged(); - return this; -}; - -TabStore.prototype = { - - destroy: function () { - if (this._connection) { - // While this.destroy is bound using .once() above, that event may not - // have occurred when the TabStore client calls destroy, so we - // manually remove it here. - this._connection.off(Connection.Events.DESTROYED, this.destroy); - this._connection.off(Connection.Events.STATUS_CHANGED, this._onStatusChanged); - _knownTabStores.delete(this._connection); - this._connection = null; - } - }, - - _resetStore: function () { - this.response = null; - this.tabs = []; - this._selectedTab = null; - this._selectedTabTargetPromise = null; - }, - - _onStatusChanged: function () { - if (this._connection.status == Connection.Status.CONNECTED) { - // Watch for changes to remote browser tabs - this._connection.client.addListener("tabListChanged", - this._onTabListChanged); - this._connection.client.addListener("tabNavigated", - this._onTabNavigated); - this.listTabs(); - } else { - if (this._connection.client) { - this._connection.client.removeListener("tabListChanged", - this._onTabListChanged); - this._connection.client.removeListener("tabNavigated", - this._onTabNavigated); - } - this._resetStore(); - } - }, - - _onTabListChanged: function () { - this.listTabs().then(() => this.emit("tab-list")) - .catch(console.error); - }, - - _onTabNavigated: function (e, { from, title, url }) { - if (!this._selectedTab || from !== this._selectedTab.actor) { - return; - } - this._selectedTab.url = url; - this._selectedTab.title = title; - this.emit("navigate"); - }, - - listTabs: function () { - if (!this._connection || !this._connection.client) { - return promise.reject(new Error("Can't listTabs, not connected.")); - } - let deferred = promise.defer(); - this._connection.client.listTabs(response => { - if (response.error) { - this._connection.disconnect(); - deferred.reject(response.error); - return; - } - let tabsChanged = JSON.stringify(this.tabs) !== JSON.stringify(response.tabs); - this.response = response; - this.tabs = response.tabs; - this._checkSelectedTab(); - if (tabsChanged) { - this.emit("tab-list"); - } - deferred.resolve(response); - }); - return deferred.promise; - }, - - // TODO: Tab "selection" should really take place by creating a TabProject - // which is the selected project. This should be done as part of the - // project-agnostic work. - _selectedTab: null, - _selectedTabTargetPromise: null, - get selectedTab() { - return this._selectedTab; - }, - set selectedTab(tab) { - if (this._selectedTab === tab) { - return; - } - this._selectedTab = tab; - this._selectedTabTargetPromise = null; - // Attach to the tab to follow navigation events - if (this._selectedTab) { - this.getTargetForTab(); - } - }, - - _checkSelectedTab: function () { - if (!this._selectedTab) { - return; - } - let alive = this.tabs.some(tab => { - return tab.actor === this._selectedTab.actor; - }); - if (!alive) { - this._selectedTab = null; - this._selectedTabTargetPromise = null; - this.emit("closed"); - } - }, - - getTargetForTab: function () { - if (this._selectedTabTargetPromise) { - return this._selectedTabTargetPromise; - } - let store = this; - this._selectedTabTargetPromise = Task.spawn(function* () { - // If you connect to a tab, then detach from it, the root actor may have - // de-listed the actors that belong to the tab. This breaks the toolbox - // if you try to connect to the same tab again. To work around this - // issue, we force a "listTabs" request before connecting to a tab. - yield store.listTabs(); - return TargetFactory.forRemoteTab({ - form: store._selectedTab, - client: store._connection.client, - chrome: false - }); - }); - this._selectedTabTargetPromise.then(target => { - target.once("close", () => { - this._selectedTabTargetPromise = null; - }); - }); - return this._selectedTabTargetPromise; - }, - -}; diff --git a/devtools/client/webide/modules/utils.js b/devtools/client/webide/modules/utils.js deleted file mode 100644 index 7a19c7044..000000000 --- a/devtools/client/webide/modules/utils.js +++ /dev/null @@ -1,68 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const { Cc, Cu, Ci } = require("chrome"); -const { FileUtils } = Cu.import("resource://gre/modules/FileUtils.jsm", {}); -const Services = require("Services"); -const Strings = Services.strings.createBundle("chrome://devtools/locale/webide.properties"); - -function doesFileExist(location) { - let file = new FileUtils.File(location); - return file.exists(); -} -exports.doesFileExist = doesFileExist; - -function _getFile(location, ...pickerParams) { - if (location) { - return new FileUtils.File(location); - } - let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); - fp.init(...pickerParams); - let res = fp.show(); - if (res == Ci.nsIFilePicker.returnCancel) { - return null; - } - return fp.file; -} - -function getCustomBinary(window, location) { - return _getFile(location, window, Strings.GetStringFromName("selectCustomBinary_title"), Ci.nsIFilePicker.modeOpen); -} -exports.getCustomBinary = getCustomBinary; - -function getCustomProfile(window, location) { - return _getFile(location, window, Strings.GetStringFromName("selectCustomProfile_title"), Ci.nsIFilePicker.modeGetFolder); -} -exports.getCustomProfile = getCustomProfile; - -function getPackagedDirectory(window, location) { - return _getFile(location, window, Strings.GetStringFromName("importPackagedApp_title"), Ci.nsIFilePicker.modeGetFolder); -} -exports.getPackagedDirectory = getPackagedDirectory; - -function getHostedURL(window, location) { - let ret = { value: null }; - - if (!location) { - Services.prompt.prompt(window, - Strings.GetStringFromName("importHostedApp_title"), - Strings.GetStringFromName("importHostedApp_header"), - ret, null, {}); - location = ret.value; - } - - if (!location) { - return null; - } - - // Clean location string and add "http://" if missing - location = location.trim(); - try { // Will fail if no scheme - Services.io.extractScheme(location); - } catch (e) { - location = "http://" + location; - } - return location; -} -exports.getHostedURL = getHostedURL; diff --git a/devtools/client/webide/moz.build b/devtools/client/webide/moz.build deleted file mode 100644 index c5dcb07a9..000000000 --- a/devtools/client/webide/moz.build +++ /dev/null @@ -1,23 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -DIRS += [ - 'content', - 'components', - 'modules', - 'themes', -] - -BROWSER_CHROME_MANIFESTS += [ - 'test/browser.ini' -] -MOCHITEST_CHROME_MANIFESTS += [ - 'test/chrome.ini' -] - -JS_PREFERENCE_PP_FILES += [ - 'webide-prefs.js', -] diff --git a/devtools/client/webide/test/.eslintrc.js b/devtools/client/webide/test/.eslintrc.js deleted file mode 100644 index 8d15a76d9..000000000 --- a/devtools/client/webide/test/.eslintrc.js +++ /dev/null @@ -1,6 +0,0 @@ -"use strict"; - -module.exports = { - // Extend from the shared list of defined globals for mochitests. - "extends": "../../../.eslintrc.mochitests.js" -}; diff --git a/devtools/client/webide/test/addons/adbhelper-linux.xpi b/devtools/client/webide/test/addons/adbhelper-linux.xpi Binary files differdeleted file mode 100644 index b56cc03e3..000000000 --- a/devtools/client/webide/test/addons/adbhelper-linux.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/adbhelper-linux64.xpi b/devtools/client/webide/test/addons/adbhelper-linux64.xpi Binary files differdeleted file mode 100644 index b56cc03e3..000000000 --- a/devtools/client/webide/test/addons/adbhelper-linux64.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/adbhelper-mac64.xpi b/devtools/client/webide/test/addons/adbhelper-mac64.xpi Binary files differdeleted file mode 100644 index b56cc03e3..000000000 --- a/devtools/client/webide/test/addons/adbhelper-mac64.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/adbhelper-win32.xpi b/devtools/client/webide/test/addons/adbhelper-win32.xpi Binary files differdeleted file mode 100644 index b56cc03e3..000000000 --- a/devtools/client/webide/test/addons/adbhelper-win32.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/fxdt-adapters-linux32.xpi b/devtools/client/webide/test/addons/fxdt-adapters-linux32.xpi Binary files differdeleted file mode 100644 index 5a512ae3d..000000000 --- a/devtools/client/webide/test/addons/fxdt-adapters-linux32.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/fxdt-adapters-linux64.xpi b/devtools/client/webide/test/addons/fxdt-adapters-linux64.xpi Binary files differdeleted file mode 100644 index 5a512ae3d..000000000 --- a/devtools/client/webide/test/addons/fxdt-adapters-linux64.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/fxdt-adapters-mac64.xpi b/devtools/client/webide/test/addons/fxdt-adapters-mac64.xpi Binary files differdeleted file mode 100644 index 5a512ae3d..000000000 --- a/devtools/client/webide/test/addons/fxdt-adapters-mac64.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/fxdt-adapters-win32.xpi b/devtools/client/webide/test/addons/fxdt-adapters-win32.xpi Binary files differdeleted file mode 100644 index 5a512ae3d..000000000 --- a/devtools/client/webide/test/addons/fxdt-adapters-win32.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/fxos_1_0_simulator-linux.xpi b/devtools/client/webide/test/addons/fxos_1_0_simulator-linux.xpi Binary files differdeleted file mode 100644 index 238c97562..000000000 --- a/devtools/client/webide/test/addons/fxos_1_0_simulator-linux.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/fxos_1_0_simulator-linux64.xpi b/devtools/client/webide/test/addons/fxos_1_0_simulator-linux64.xpi Binary files differdeleted file mode 100644 index 2f86c4d4d..000000000 --- a/devtools/client/webide/test/addons/fxos_1_0_simulator-linux64.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/fxos_1_0_simulator-mac64.xpi b/devtools/client/webide/test/addons/fxos_1_0_simulator-mac64.xpi Binary files differdeleted file mode 100644 index 6da2fcbad..000000000 --- a/devtools/client/webide/test/addons/fxos_1_0_simulator-mac64.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/fxos_1_0_simulator-win32.xpi b/devtools/client/webide/test/addons/fxos_1_0_simulator-win32.xpi Binary files differdeleted file mode 100644 index 546deacaf..000000000 --- a/devtools/client/webide/test/addons/fxos_1_0_simulator-win32.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/fxos_2_0_simulator-linux.xpi b/devtools/client/webide/test/addons/fxos_2_0_simulator-linux.xpi Binary files differdeleted file mode 100644 index e2335e3a0..000000000 --- a/devtools/client/webide/test/addons/fxos_2_0_simulator-linux.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/fxos_2_0_simulator-linux64.xpi b/devtools/client/webide/test/addons/fxos_2_0_simulator-linux64.xpi Binary files differdeleted file mode 100644 index 75fe209ea..000000000 --- a/devtools/client/webide/test/addons/fxos_2_0_simulator-linux64.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/fxos_2_0_simulator-mac64.xpi b/devtools/client/webide/test/addons/fxos_2_0_simulator-mac64.xpi Binary files differdeleted file mode 100644 index 58749f724..000000000 --- a/devtools/client/webide/test/addons/fxos_2_0_simulator-mac64.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/fxos_2_0_simulator-win32.xpi b/devtools/client/webide/test/addons/fxos_2_0_simulator-win32.xpi Binary files differdeleted file mode 100644 index 60cffd46e..000000000 --- a/devtools/client/webide/test/addons/fxos_2_0_simulator-win32.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/fxos_3_0_simulator-linux.xpi b/devtools/client/webide/test/addons/fxos_3_0_simulator-linux.xpi Binary files differdeleted file mode 100644 index c54cae3aa..000000000 --- a/devtools/client/webide/test/addons/fxos_3_0_simulator-linux.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/fxos_3_0_simulator-linux64.xpi b/devtools/client/webide/test/addons/fxos_3_0_simulator-linux64.xpi Binary files differdeleted file mode 100644 index 9a650a888..000000000 --- a/devtools/client/webide/test/addons/fxos_3_0_simulator-linux64.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/fxos_3_0_simulator-mac64.xpi b/devtools/client/webide/test/addons/fxos_3_0_simulator-mac64.xpi Binary files differdeleted file mode 100644 index d13dd78de..000000000 --- a/devtools/client/webide/test/addons/fxos_3_0_simulator-mac64.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/fxos_3_0_simulator-win32.xpi b/devtools/client/webide/test/addons/fxos_3_0_simulator-win32.xpi Binary files differdeleted file mode 100644 index 92d5cc394..000000000 --- a/devtools/client/webide/test/addons/fxos_3_0_simulator-win32.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/fxos_3_0_tv_simulator-linux.xpi b/devtools/client/webide/test/addons/fxos_3_0_tv_simulator-linux.xpi Binary files differdeleted file mode 100644 index 7a2a432ff..000000000 --- a/devtools/client/webide/test/addons/fxos_3_0_tv_simulator-linux.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/fxos_3_0_tv_simulator-linux64.xpi b/devtools/client/webide/test/addons/fxos_3_0_tv_simulator-linux64.xpi Binary files differdeleted file mode 100644 index d38932195..000000000 --- a/devtools/client/webide/test/addons/fxos_3_0_tv_simulator-linux64.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/fxos_3_0_tv_simulator-mac64.xpi b/devtools/client/webide/test/addons/fxos_3_0_tv_simulator-mac64.xpi Binary files differdeleted file mode 100644 index 48e271d54..000000000 --- a/devtools/client/webide/test/addons/fxos_3_0_tv_simulator-mac64.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/fxos_3_0_tv_simulator-win32.xpi b/devtools/client/webide/test/addons/fxos_3_0_tv_simulator-win32.xpi Binary files differdeleted file mode 100644 index 4c8bb2f10..000000000 --- a/devtools/client/webide/test/addons/fxos_3_0_tv_simulator-win32.xpi +++ /dev/null diff --git a/devtools/client/webide/test/addons/simulators.json b/devtools/client/webide/test/addons/simulators.json deleted file mode 100644 index 31d71b4da..000000000 --- a/devtools/client/webide/test/addons/simulators.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "stable": ["1.0", "2.0"], - "unstable": ["3.0", "3.0_tv"] -} diff --git a/devtools/client/webide/test/app.zip b/devtools/client/webide/test/app.zip Binary files differdeleted file mode 100644 index 8a706a3c9..000000000 --- a/devtools/client/webide/test/app.zip +++ /dev/null diff --git a/devtools/client/webide/test/app/index.html b/devtools/client/webide/test/app/index.html deleted file mode 100644 index 3ef4a25e2..000000000 --- a/devtools/client/webide/test/app/index.html +++ /dev/null @@ -1,6 +0,0 @@ -<!doctype html> -<html> -<head><title></title></head> -<body> -</body> -</html> diff --git a/devtools/client/webide/test/app/manifest.webapp b/devtools/client/webide/test/app/manifest.webapp deleted file mode 100644 index 4a198b1ca..000000000 --- a/devtools/client/webide/test/app/manifest.webapp +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "A name (in app directory)", - "description": "desc", - "launch_path": "/index.html" -} diff --git a/devtools/client/webide/test/browser.ini b/devtools/client/webide/test/browser.ini deleted file mode 100644 index 7d6e2de72..000000000 --- a/devtools/client/webide/test/browser.ini +++ /dev/null @@ -1,12 +0,0 @@ -[DEFAULT] -tags = devtools -subsuite = devtools -support-files = - addons/simulators.json - doc_tabs.html - head.js - templates.json - -[browser_tabs.js] -skip-if = e10s # Bug 1072167 - browser_tabs.js test fails under e10s -[browser_widget.js] diff --git a/devtools/client/webide/test/browser_tabs.js b/devtools/client/webide/test/browser_tabs.js deleted file mode 100644 index 541c6b363..000000000 --- a/devtools/client/webide/test/browser_tabs.js +++ /dev/null @@ -1,84 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -const TEST_URI = "http://example.com/browser/devtools/client/webide/test/doc_tabs.html"; - -function test() { - waitForExplicitFinish(); - requestCompleteLog(); - - Task.spawn(function* () { - // Since we test the connections set below, destroy the server in case it - // was left open. - DebuggerServer.destroy(); - DebuggerServer.init(); - DebuggerServer.addBrowserActors(); - - let tab = yield addTab(TEST_URI); - - let win = yield openWebIDE(); - let docProject = getProjectDocument(win); - let docRuntime = getRuntimeDocument(win); - - yield connectToLocal(win, docRuntime); - - is(Object.keys(DebuggerServer._connections).length, 1, "Locally connected"); - - yield selectTabProject(win, docProject); - - ok(win.UI.toolboxPromise, "Toolbox promise exists"); - yield win.UI.toolboxPromise; - - let project = win.AppManager.selectedProject; - is(project.location, TEST_URI, "Location is correct"); - is(project.name, "example.com: Test Tab", "Name is correct"); - - // Ensure tab list changes are noticed - let tabsNode = docProject.querySelector("#project-panel-tabs"); - is(tabsNode.querySelectorAll(".panel-item").length, 2, "2 tabs available"); - yield removeTab(tab); - yield waitForUpdate(win, "project"); - yield waitForUpdate(win, "runtime-targets"); - is(tabsNode.querySelectorAll(".panel-item").length, 1, "1 tab available"); - - tab = yield addTab(TEST_URI); - - is(tabsNode.querySelectorAll(".panel-item").length, 2, "2 tabs available"); - - yield removeTab(tab); - - is(tabsNode.querySelectorAll(".panel-item").length, 2, "2 tabs available"); - - docProject.querySelector("#refresh-tabs").click(); - - yield waitForUpdate(win, "runtime-targets"); - - is(tabsNode.querySelectorAll(".panel-item").length, 1, "1 tab available"); - - yield win.Cmds.disconnectRuntime(); - yield closeWebIDE(win); - - DebuggerServer.destroy(); - }).then(finish, handleError); -} - -function connectToLocal(win, docRuntime) { - let deferred = promise.defer(); - win.AppManager.connection.once( - win.Connection.Events.CONNECTED, - () => deferred.resolve()); - docRuntime.querySelectorAll(".runtime-panel-item-other")[1].click(); - return deferred.promise; -} - -function selectTabProject(win, docProject) { - return Task.spawn(function* () { - yield waitForUpdate(win, "runtime-targets"); - let tabsNode = docProject.querySelector("#project-panel-tabs"); - let tabNode = tabsNode.querySelectorAll(".panel-item")[1]; - let project = waitForUpdate(win, "project"); - tabNode.click(); - yield project; - }); -} diff --git a/devtools/client/webide/test/browser_widget.js b/devtools/client/webide/test/browser_widget.js deleted file mode 100644 index 7cfb2782b..000000000 --- a/devtools/client/webide/test/browser_widget.js +++ /dev/null @@ -1,15 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -function test() { - waitForExplicitFinish(); - Task.spawn(function* () { - let win = yield openWebIDE(); - ok(document.querySelector("#webide-button"), "Found WebIDE button"); - Services.prefs.setBoolPref("devtools.webide.widget.enabled", false); - ok(!document.querySelector("#webide-button"), "WebIDE button uninstalled"); - yield closeWebIDE(win); - Services.prefs.clearUserPref("devtools.webide.widget.enabled"); - }).then(finish, handleError); -} diff --git a/devtools/client/webide/test/build_app1/package.json b/devtools/client/webide/test/build_app1/package.json deleted file mode 100644 index c6ae833e1..000000000 --- a/devtools/client/webide/test/build_app1/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "webide": { - "prepackage": "echo \"{\\\"name\\\":\\\"hello\\\"}\" > manifest.webapp" - } -} diff --git a/devtools/client/webide/test/build_app2/manifest.webapp b/devtools/client/webide/test/build_app2/manifest.webapp deleted file mode 100644 index 0967ef424..000000000 --- a/devtools/client/webide/test/build_app2/manifest.webapp +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/devtools/client/webide/test/build_app2/package.json b/devtools/client/webide/test/build_app2/package.json deleted file mode 100644 index 5b7101620..000000000 --- a/devtools/client/webide/test/build_app2/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "webide": { - "prepackage": { - "command": "echo \"{\\\"name\\\":\\\"$NAME\\\"}\" > manifest.webapp", - "cwd": "./stage", - "env": ["NAME=world"] - }, - "packageDir": "./stage" - } -} diff --git a/devtools/client/webide/test/build_app2/stage/empty-directory b/devtools/client/webide/test/build_app2/stage/empty-directory deleted file mode 100644 index e69de29bb..000000000 --- a/devtools/client/webide/test/build_app2/stage/empty-directory +++ /dev/null diff --git a/devtools/client/webide/test/build_app_windows1/package.json b/devtools/client/webide/test/build_app_windows1/package.json deleted file mode 100644 index 036d2d767..000000000 --- a/devtools/client/webide/test/build_app_windows1/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "webide": { - "prepackage": "echo {\"name\":\"hello\"} > manifest.webapp" - } -} diff --git a/devtools/client/webide/test/build_app_windows2/manifest.webapp b/devtools/client/webide/test/build_app_windows2/manifest.webapp deleted file mode 100644 index 0967ef424..000000000 --- a/devtools/client/webide/test/build_app_windows2/manifest.webapp +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/devtools/client/webide/test/build_app_windows2/package.json b/devtools/client/webide/test/build_app_windows2/package.json deleted file mode 100644 index 83caf82ab..000000000 --- a/devtools/client/webide/test/build_app_windows2/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "webide": { - "prepackage": { - "command": "echo {\"name\":\"%NAME%\"} > manifest.webapp", - "cwd": "./stage", - "env": ["NAME=world"] - }, - "packageDir": "./stage" - } -} diff --git a/devtools/client/webide/test/build_app_windows2/stage/empty-directory b/devtools/client/webide/test/build_app_windows2/stage/empty-directory deleted file mode 100644 index e69de29bb..000000000 --- a/devtools/client/webide/test/build_app_windows2/stage/empty-directory +++ /dev/null diff --git a/devtools/client/webide/test/chrome.ini b/devtools/client/webide/test/chrome.ini deleted file mode 100644 index b492ccd9b..000000000 --- a/devtools/client/webide/test/chrome.ini +++ /dev/null @@ -1,71 +0,0 @@ -[DEFAULT] -tags = devtools -support-files = - app/index.html - app/manifest.webapp - app.zip - addons/simulators.json - addons/fxos_1_0_simulator-linux.xpi - addons/fxos_1_0_simulator-linux64.xpi - addons/fxos_1_0_simulator-win32.xpi - addons/fxos_1_0_simulator-mac64.xpi - addons/fxos_2_0_simulator-linux.xpi - addons/fxos_2_0_simulator-linux64.xpi - addons/fxos_2_0_simulator-win32.xpi - addons/fxos_2_0_simulator-mac64.xpi - addons/fxos_3_0_simulator-linux.xpi - addons/fxos_3_0_simulator-linux64.xpi - addons/fxos_3_0_simulator-win32.xpi - addons/fxos_3_0_simulator-mac64.xpi - addons/fxos_3_0_tv_simulator-linux.xpi - addons/fxos_3_0_tv_simulator-linux64.xpi - addons/fxos_3_0_tv_simulator-win32.xpi - addons/fxos_3_0_tv_simulator-mac64.xpi - addons/adbhelper-linux.xpi - addons/adbhelper-linux64.xpi - addons/adbhelper-win32.xpi - addons/adbhelper-mac64.xpi - addons/fxdt-adapters-linux32.xpi - addons/fxdt-adapters-linux64.xpi - addons/fxdt-adapters-win32.xpi - addons/fxdt-adapters-mac64.xpi - build_app1/package.json - build_app2/manifest.webapp - build_app2/package.json - build_app2/stage/empty-directory - build_app_windows1/package.json - build_app_windows2/manifest.webapp - build_app_windows2/package.json - build_app_windows2/stage/empty-directory - device_front_shared.js - head.js - hosted_app.manifest - templates.json - ../../shared/test/browser_devices.json - validator/* - -[test_basic.html] -[test_newapp.html] -skip-if = (os == "win" && os_version == "10.0") # Bug 1197053 -[test_import.html] -skip-if = (os == "linux") # Bug 1024734 -[test_duplicate_import.html] -[test_runtime.html] -[test_manifestUpdate.html] -[test_addons.html] -skip-if = true # Bug 1201392 - Update add-ons after migration -[test_device_runtime.html] -[test_device_permissions.html] -[test_autoconnect_runtime.html] -[test_autoselect_project.html] -[test_telemetry.html] -skip-if = true # Bug 1201392 - Update add-ons after migration -[test_device_preferences.html] -[test_device_settings.html] -[test_fullscreenToolbox.html] -[test_zoom.html] -[test_build.html] -[test_simulators.html] -skip-if = true # Bug 1281138 - intermittent failures -[test_toolbox.html] -[test_app_validator.html] diff --git a/devtools/client/webide/test/device_front_shared.js b/devtools/client/webide/test/device_front_shared.js deleted file mode 100644 index 0ddb5df21..000000000 --- a/devtools/client/webide/test/device_front_shared.js +++ /dev/null @@ -1,219 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -var customName; -var customValue; -var customValueType; -var customBtn; -var newField; -var change; -var doc; -var iframe; -var resetBtn; -var found = false; - -function setDocument(frame) { - iframe = frame; - doc = iframe.contentWindow.document; -} - -function fieldChange(fields, id) { - // Trigger existing field change - for (let field of fields) { - if (field.id == id) { - let button = doc.getElementById("btn-" + id); - found = true; - ok(button.classList.contains("hide"), "Default field detected"); - field.value = "custom"; - field.click(); - ok(!button.classList.contains("hide"), "Custom field detected"); - break; - } - } - ok(found, "Found " + id + " line"); -} - -function addNewField() { - found = false; - customName = doc.querySelector("#custom-value-name"); - customValue = doc.querySelector("#custom-value-text"); - customValueType = doc.querySelector("#custom-value-type"); - customBtn = doc.querySelector("#custom-value"); - change = doc.createEvent("HTMLEvents"); - change.initEvent("change", false, true); - - // Add a new custom string - customValueType.value = "string"; - customValueType.dispatchEvent(change); - customName.value = "new-string-field!"; - customValue.value = "test"; - customBtn.click(); - let newField = doc.querySelector("#new-string-field"); - if (newField) { - found = true; - is(newField.type, "text", "Custom type is a string"); - is(newField.value, "test", "Custom string new value is correct"); - } - ok(found, "Found new string field line"); - is(customName.value, "", "Custom string name reset"); - is(customValue.value, "", "Custom string value reset"); -} - -function addNewFieldWithEnter() { - // Add a new custom value with the <enter> key - found = false; - customName.value = "new-string-field-two"; - customValue.value = "test"; - let newAddField = doc.querySelector("#add-custom-field"); - let enter = doc.createEvent("KeyboardEvent"); - enter.initKeyEvent( - "keyup", true, true, null, false, false, false, false, 13, 0); - newAddField.dispatchEvent(enter); - newField = doc.querySelector("#new-string-field-two"); - if (newField) { - found = true; - is(newField.type, "text", "Custom type is a string"); - is(newField.value, "test", "Custom string new value is correct"); - } - ok(found, "Found new string field line"); - is(customName.value, "", "Custom string name reset"); - is(customValue.value, "", "Custom string value reset"); -} - -function editExistingField() { - // Edit existing custom string preference - newField.value = "test2"; - newField.click(); - is(newField.value, "test2", "Custom string existing value is correct"); -} - -function addNewFieldInteger() { - // Add a new custom integer preference with a valid integer - customValueType.value = "number"; - customValueType.dispatchEvent(change); - customName.value = "new-integer-field"; - customValue.value = 1; - found = false; - - customBtn.click(); - newField = doc.querySelector("#new-integer-field"); - if (newField) { - found = true; - is(newField.type, "number", "Custom type is a number"); - is(newField.value, "1", "Custom integer value is correct"); - } - ok(found, "Found new integer field line"); - is(customName.value, "", "Custom integer name reset"); - is(customValue.value, "", "Custom integer value reset"); -} - -var editFieldInteger = Task.async(function* () { - // Edit existing custom integer preference - newField.value = 3; - newField.click(); - is(newField.value, "3", "Custom integer existing value is correct"); - - // Reset a custom field - let resetBtn = doc.querySelector("#btn-new-integer-field"); - resetBtn.click(); - - try { - yield iframe.contentWindow.configView._defaultField; - } catch (err) { - let fieldRow = doc.querySelector("#row-new-integer-field"); - if (!fieldRow) { - found = false; - } - ok(!found, "Custom field removed"); - } -}); - -var resetExistingField = Task.async(function* (id) { - let existing = doc.getElementById(id); - existing.click(); - is(existing.checked, true, "Existing boolean value is correct"); - resetBtn = doc.getElementById("btn-" + id); - resetBtn.click(); - - yield iframe.contentWindow.configView._defaultField; - - ok(resetBtn.classList.contains("hide"), true, "Reset button hidden"); - is(existing.checked, true, "Existing field reset"); -}); - -var resetNewField = Task.async(function* (id) { - let custom = doc.getElementById(id); - custom.click(); - is(custom.value, "test", "New string value is correct"); - resetBtn = doc.getElementById("btn-" + id); - resetBtn.click(); - - yield iframe.contentWindow.configView._defaultField; - - ok(resetBtn.classList.contains("hide"), true, "Reset button hidden"); -}); - -function addNewFieldBoolean() { - customValueType.value = "boolean"; - customValueType.dispatchEvent(change); - customName.value = "new-boolean-field"; - customValue.checked = true; - found = false; - customBtn.click(); - newField = doc.querySelector("#new-boolean-field"); - if (newField) { - found = true; - is(newField.type, "checkbox", "Custom type is a checkbox"); - is(newField.checked, true, "Custom boolean value is correctly true"); - } - ok(found, "Found new boolean field line"); - - // Mouse event trigger - var mouseClick = new MouseEvent("click", { - canBubble: true, - cancelable: true, - view: doc.parent, - }); - - found = false; - customValueType.value = "boolean"; - customValueType.dispatchEvent(change); - customName.value = "new-boolean-field2"; - customValue.dispatchEvent(mouseClick); - customBtn.dispatchEvent(mouseClick); - newField = doc.querySelector("#new-boolean-field2"); - if (newField) { - found = true; - is(newField.checked, true, "Custom boolean value is correctly false"); - } - ok(found, "Found new second boolean field line"); - - is(customName.value, "", "Custom boolean name reset"); - is(customValue.checked, false, "Custom boolean value reset"); - - newField.click(); - is(newField.checked, false, "Custom boolean existing value is correct"); -} - -function searchFields(deck, keyword) { - // Search for a non-existent field - let searchField = doc.querySelector("#search-bar"); - searchField.value = "![o_O]!"; - searchField.click(); - - let fieldsTotal = doc.querySelectorAll("tr.edit-row").length; - let hiddenFields = doc.querySelectorAll("tr.hide"); - is(hiddenFields.length, fieldsTotal, "Search keyword not found"); - - // Search for existing fields - searchField.value = keyword; - searchField.click(); - hiddenFields = doc.querySelectorAll("tr.hide"); - isnot(hiddenFields.length, fieldsTotal, "Search keyword found"); - - doc.querySelector("#close").click(); - - ok(!deck.selectedPanel, "No panel selected"); -} diff --git a/devtools/client/webide/test/doc_tabs.html b/devtools/client/webide/test/doc_tabs.html deleted file mode 100644 index 4901289fc..000000000 --- a/devtools/client/webide/test/doc_tabs.html +++ /dev/null @@ -1,15 +0,0 @@ -<!-- Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ --> -<!doctype html> - -<html> - <head> - <meta charset="utf-8"/> - <title>Test Tab</title> - </head> - - <body> - Test Tab - </body> - -</html> diff --git a/devtools/client/webide/test/head.js b/devtools/client/webide/test/head.js deleted file mode 100644 index c0171c730..000000000 --- a/devtools/client/webide/test/head.js +++ /dev/null @@ -1,248 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -var {utils: Cu, classes: Cc, interfaces: Ci} = Components; - -const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {}); -const { FileUtils } = require("resource://gre/modules/FileUtils.jsm"); -const { gDevTools } = require("devtools/client/framework/devtools"); -const promise = require("promise"); -const Services = require("Services"); -const { Task } = require("devtools/shared/task"); -const { AppProjects } = require("devtools/client/webide/modules/app-projects"); -const DevToolsUtils = require("devtools/shared/DevToolsUtils"); -const { DebuggerServer } = require("devtools/server/main"); -const flags = require("devtools/shared/flags"); -flags.testing = true; - -var TEST_BASE; -if (window.location === "chrome://browser/content/browser.xul") { - TEST_BASE = "chrome://mochitests/content/browser/devtools/client/webide/test/"; -} else { - TEST_BASE = "chrome://mochitests/content/chrome/devtools/client/webide/test/"; -} - -Services.prefs.setBoolPref("devtools.webide.enabled", true); -Services.prefs.setBoolPref("devtools.webide.enableLocalRuntime", true); - -Services.prefs.setCharPref("devtools.webide.addonsURL", TEST_BASE + "addons/simulators.json"); -Services.prefs.setCharPref("devtools.webide.simulatorAddonsURL", TEST_BASE + "addons/fxos_#SLASHED_VERSION#_simulator-#OS#.xpi"); -Services.prefs.setCharPref("devtools.webide.adbAddonURL", TEST_BASE + "addons/adbhelper-#OS#.xpi"); -Services.prefs.setCharPref("devtools.webide.adaptersAddonURL", TEST_BASE + "addons/fxdt-adapters-#OS#.xpi"); -Services.prefs.setCharPref("devtools.webide.templatesURL", TEST_BASE + "templates.json"); -Services.prefs.setCharPref("devtools.devices.url", TEST_BASE + "browser_devices.json"); - -var registerCleanupFunction = registerCleanupFunction || - SimpleTest.registerCleanupFunction; -registerCleanupFunction(() => { - flags.testing = false; - Services.prefs.clearUserPref("devtools.webide.enabled"); - Services.prefs.clearUserPref("devtools.webide.enableLocalRuntime"); - Services.prefs.clearUserPref("devtools.webide.autoinstallADBHelper"); - Services.prefs.clearUserPref("devtools.webide.autoinstallFxdtAdapters"); - Services.prefs.clearUserPref("devtools.webide.busyTimeout"); - Services.prefs.clearUserPref("devtools.webide.lastSelectedProject"); - Services.prefs.clearUserPref("devtools.webide.lastConnectedRuntime"); -}); - -var openWebIDE = Task.async(function* (autoInstallAddons) { - info("opening WebIDE"); - - Services.prefs.setBoolPref("devtools.webide.autoinstallADBHelper", !!autoInstallAddons); - Services.prefs.setBoolPref("devtools.webide.autoinstallFxdtAdapters", !!autoInstallAddons); - - let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].getService(Ci.nsIWindowWatcher); - let win = ww.openWindow(null, "chrome://webide/content/", "webide", "chrome,centerscreen,resizable", null); - - yield new Promise(resolve => { - win.addEventListener("load", function onLoad() { - win.removeEventListener("load", onLoad); - SimpleTest.requestCompleteLog(); - SimpleTest.executeSoon(resolve); - }); - }); - - info("WebIDE open"); - - return win; -}); - -function closeWebIDE(win) { - info("Closing WebIDE"); - - let deferred = promise.defer(); - - Services.prefs.clearUserPref("devtools.webide.widget.enabled"); - - win.addEventListener("unload", function onUnload() { - win.removeEventListener("unload", onUnload); - info("WebIDE closed"); - SimpleTest.executeSoon(() => { - deferred.resolve(); - }); - }); - - win.close(); - - return deferred.promise; -} - -function removeAllProjects() { - return Task.spawn(function* () { - yield AppProjects.load(); - // use a new array so we're not iterating over the same - // underlying array that's being modified by AppProjects - let projects = AppProjects.projects.map(p => p.location); - for (let i = 0; i < projects.length; i++) { - yield AppProjects.remove(projects[i]); - } - }); -} - -function nextTick() { - let deferred = promise.defer(); - SimpleTest.executeSoon(() => { - deferred.resolve(); - }); - - return deferred.promise; -} - -function waitForUpdate(win, update) { - info("Wait: " + update); - let deferred = promise.defer(); - win.AppManager.on("app-manager-update", function onUpdate(e, what) { - info("Got: " + what); - if (what !== update) { - return; - } - win.AppManager.off("app-manager-update", onUpdate); - deferred.resolve(win.UI._updatePromise); - }); - return deferred.promise; -} - -function waitForTime(time) { - let deferred = promise.defer(); - setTimeout(() => { - deferred.resolve(); - }, time); - return deferred.promise; -} - -function documentIsLoaded(doc) { - let deferred = promise.defer(); - if (doc.readyState == "complete") { - deferred.resolve(); - } else { - doc.addEventListener("readystatechange", function onChange() { - if (doc.readyState == "complete") { - doc.removeEventListener("readystatechange", onChange); - deferred.resolve(); - } - }); - } - return deferred.promise; -} - -function lazyIframeIsLoaded(iframe) { - let deferred = promise.defer(); - iframe.addEventListener("load", function onLoad() { - iframe.removeEventListener("load", onLoad, true); - deferred.resolve(nextTick()); - }, true); - return deferred.promise; -} - -function addTab(aUrl, aWindow) { - info("Adding tab: " + aUrl); - - let deferred = promise.defer(); - let targetWindow = aWindow || window; - let targetBrowser = targetWindow.gBrowser; - - targetWindow.focus(); - let tab = targetBrowser.selectedTab = targetBrowser.addTab(aUrl); - let linkedBrowser = tab.linkedBrowser; - - BrowserTestUtils.browserLoaded(linkedBrowser).then(function () { - info("Tab added and finished loading: " + aUrl); - deferred.resolve(tab); - }); - - return deferred.promise; -} - -function removeTab(aTab, aWindow) { - info("Removing tab."); - - let deferred = promise.defer(); - let targetWindow = aWindow || window; - let targetBrowser = targetWindow.gBrowser; - let tabContainer = targetBrowser.tabContainer; - - tabContainer.addEventListener("TabClose", function onClose(aEvent) { - tabContainer.removeEventListener("TabClose", onClose, false); - info("Tab removed and finished closing."); - deferred.resolve(); - }, false); - - targetBrowser.removeTab(aTab); - return deferred.promise; -} - -function getRuntimeDocument(win) { - return win.document.querySelector("#runtime-listing-panel-details").contentDocument; -} - -function getProjectDocument(win) { - return win.document.querySelector("#project-listing-panel-details").contentDocument; -} - -function getRuntimeWindow(win) { - return win.document.querySelector("#runtime-listing-panel-details").contentWindow; -} - -function getProjectWindow(win) { - return win.document.querySelector("#project-listing-panel-details").contentWindow; -} - -function connectToLocalRuntime(win) { - info("Loading local runtime."); - - let panelNode; - let runtimePanel; - - runtimePanel = getRuntimeDocument(win); - - panelNode = runtimePanel.querySelector("#runtime-panel"); - let items = panelNode.querySelectorAll(".runtime-panel-item-other"); - is(items.length, 2, "Found 2 custom runtime buttons"); - - let updated = waitForUpdate(win, "runtime-global-actors"); - items[1].click(); - return updated; -} - -function handleError(aError) { - ok(false, "Got an error: " + aError.message + "\n" + aError.stack); - finish(); -} - -function waitForConnectionChange(expectedState, count = 1) { - return new Promise(resolve => { - let onConnectionChange = (_, state) => { - if (state != expectedState) { - return; - } - if (--count != 0) { - return; - } - DebuggerServer.off("connectionchange", onConnectionChange); - resolve(); - }; - DebuggerServer.on("connectionchange", onConnectionChange); - }); -} diff --git a/devtools/client/webide/test/hosted_app.manifest b/devtools/client/webide/test/hosted_app.manifest deleted file mode 100644 index ab5069978..000000000 --- a/devtools/client/webide/test/hosted_app.manifest +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "hosted manifest name property" -} diff --git a/devtools/client/webide/test/templates.json b/devtools/client/webide/test/templates.json deleted file mode 100644 index e6ffa3efe..000000000 --- a/devtools/client/webide/test/templates.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "file": "chrome://mochitests/content/chrome/devtools/client/webide/test/app.zip?1", - "icon": "ximgx1", - "name": "app name 1", - "description": "app description 1" - }, - { - "file": "chrome://mochitests/content/chrome/devtools/client/webide/test/app.zip?2", - "icon": "ximgx2", - "name": "app name 2", - "description": "app description 2" - } -] diff --git a/devtools/client/webide/test/test_addons.html b/devtools/client/webide/test/test_addons.html deleted file mode 100644 index 5a1bc7504..000000000 --- a/devtools/client/webide/test/test_addons.html +++ /dev/null @@ -1,176 +0,0 @@ -<!DOCTYPE html> - -<html> - - <head> - <meta charset="utf8"> - <title></title> - - <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script> - <script type="application/javascript;version=1.8" src="head.js"></script> - <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> - </head> - - <body> - - <script type="application/javascript;version=1.8"> - window.onload = function() { - SimpleTest.waitForExplicitFinish(); - - const {GetAvailableAddons} = require("devtools/client/webide/modules/addons"); - const {Devices} = Cu.import("resource://devtools/shared/apps/Devices.jsm"); - const {Simulators} = require("devtools/client/webide/modules/simulators"); - - let adbAddonsInstalled = promise.defer(); - Devices.on("addon-status-updated", function onUpdate1() { - Devices.off("addon-status-updated", onUpdate1); - adbAddonsInstalled.resolve(); - }); - - function getVersion(name) { - return name.match(/(\d+\.\d+)/)[0]; - } - - function onSimulatorInstalled(name) { - let deferred = promise.defer(); - Simulators.on("updated", function onUpdate() { - Simulators.findSimulatorAddons().then(addons => { - for (let addon of addons) { - if (name == addon.name.replace(" Simulator", "")) { - Simulators.off("updated", onUpdate); - nextTick().then(deferred.resolve); - return; - } - } - }); - }); - return deferred.promise; - } - - function installSimulatorFromUI(doc, name) { - let li = doc.querySelector('[addon="simulator-' + getVersion(name) + '"]'); - li.querySelector(".install-button").click(); - return onSimulatorInstalled(name); - } - - function uninstallSimulatorFromUI(doc, name) { - let deferred = promise.defer(); - Simulators.on("updated", function onUpdate() { - nextTick().then(() => { - let li = doc.querySelector('[status="uninstalled"][addon="simulator-' + getVersion(name) + '"]'); - if (li) { - Simulators.off("updated", onUpdate); - deferred.resolve(); - } else { - deferred.reject("Can't find item"); - } - }); - }); - let li = doc.querySelector('[status="installed"][addon="simulator-' + getVersion(name) + '"]'); - li.querySelector(".uninstall-button").click(); - return deferred.promise; - } - - function uninstallADBFromUI(doc) { - let deferred = promise.defer(); - Devices.on("addon-status-updated", function onUpdate() { - nextTick().then(() => { - let li = doc.querySelector('[status="uninstalled"][addon="adb"]'); - if (li) { - Devices.off("addon-status-updated", onUpdate); - deferred.resolve(); - } else { - deferred.reject("Can't find item"); - } - }) - }); - let li = doc.querySelector('[status="installed"][addon="adb"]'); - li.querySelector(".uninstall-button").click(); - return deferred.promise; - } - - Task.spawn(function*() { - - ok(!Devices.helperAddonInstalled, "Helper not installed"); - - let win = yield openWebIDE(true); - let docRuntime = getRuntimeDocument(win); - - yield adbAddonsInstalled.promise; - - ok(Devices.helperAddonInstalled, "Helper has been auto-installed"); - - yield nextTick(); - - let addons = yield GetAvailableAddons(); - - is(addons.simulators.length, 3, "3 simulator addons to install"); - - let sim10 = addons.simulators.filter(a => a.version == "1.0")[0]; - sim10.install(); - - yield onSimulatorInstalled("Firefox OS 1.0"); - - win.Cmds.showAddons(); - - let frame = win.document.querySelector("#deck-panel-addons"); - let addonDoc = frame.contentWindow.document; - let lis; - - lis = addonDoc.querySelectorAll("li"); - is(lis.length, 5, "5 addons listed"); - - lis = addonDoc.querySelectorAll('li[status="installed"]'); - is(lis.length, 3, "3 addons installed"); - - lis = addonDoc.querySelectorAll('li[status="uninstalled"]'); - is(lis.length, 2, "2 addons uninstalled"); - - info("Uninstalling Simulator 2.0"); - - yield installSimulatorFromUI(addonDoc, "Firefox OS 2.0"); - - info("Uninstalling Simulator 3.0"); - - yield installSimulatorFromUI(addonDoc, "Firefox OS 3.0"); - - yield nextTick(); - - let panelNode = docRuntime.querySelector("#runtime-panel"); - let items; - - items = panelNode.querySelectorAll(".runtime-panel-item-usb"); - is(items.length, 1, "Found one runtime button"); - - items = panelNode.querySelectorAll(".runtime-panel-item-simulator"); - is(items.length, 3, "Found 3 simulators button"); - - yield uninstallSimulatorFromUI(addonDoc, "Firefox OS 1.0"); - yield uninstallSimulatorFromUI(addonDoc, "Firefox OS 2.0"); - yield uninstallSimulatorFromUI(addonDoc, "Firefox OS 3.0"); - - items = panelNode.querySelectorAll(".runtime-panel-item-simulator"); - is(items.length, 0, "No simulator listed"); - - let w = addonDoc.querySelector(".warning"); - let display = addonDoc.defaultView.getComputedStyle(w).display - is(display, "none", "Warning about missing ADB hidden"); - - yield uninstallADBFromUI(addonDoc, "adb"); - - items = panelNode.querySelectorAll(".runtime-panel-item-usb"); - is(items.length, 0, "No usb runtime listed"); - - display = addonDoc.defaultView.getComputedStyle(w).display - is(display, "block", "Warning about missing ADB present"); - - yield closeWebIDE(win); - - SimpleTest.finish(); - - }); - } - </script> - </body> -</html> diff --git a/devtools/client/webide/test/test_app_validator.html b/devtools/client/webide/test/test_app_validator.html deleted file mode 100644 index 60ed29aac..000000000 --- a/devtools/client/webide/test/test_app_validator.html +++ /dev/null @@ -1,205 +0,0 @@ -<!DOCTYPE html> - -<html> - - <head> - <meta charset="utf8"> - <title></title> - - <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script> - <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> - </head> - - <body> - - <script type="application/javascript;version=1.8"> - const Cu = Components.utils; - const Cc = Components.classes; - const Ci = Components.interfaces; - Cu.import("resource://testing-common/httpd.js"); - const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); - - const {AppValidator} = require("devtools/client/webide/modules/app-validator"); - const Services = require("Services"); - const nsFile = Components.Constructor("@mozilla.org/file/local;1", - "nsILocalFile", "initWithPath"); - const cr = Cc["@mozilla.org/chrome/chrome-registry;1"] - .getService(Ci.nsIChromeRegistry); - const strings = Services.strings.createBundle("chrome://devtools/locale/app-manager.properties"); - let httpserver, origin; - - window.onload = function() { - SimpleTest.waitForExplicitFinish(); - - httpserver = new HttpServer(); - httpserver.start(-1); - origin = "http://localhost:" + httpserver.identity.primaryPort + "/"; - - next(); - } - - function createHosted(path, manifestFile="/manifest.webapp") { - let dirPath = getTestFilePath("validator/" + path); - httpserver.registerDirectory("/", nsFile(dirPath)); - return new AppValidator({ - type: "hosted", - location: origin + manifestFile - }); - } - - function createPackaged(path) { - let dirPath = getTestFilePath("validator/" + path); - return new AppValidator({ - type: "packaged", - location: dirPath - }); - } - - function next() { - let test = tests.shift(); - if (test) { - try { - test(); - } catch(e) { - console.error("exception", String(e), e, e.stack); - } - } else { - httpserver.stop(function() { - SimpleTest.finish(); - }); - } - } - - let tests = [ - // Test a 100% valid example - function () { - let validator = createHosted("valid"); - validator.validate().then(() => { - is(validator.errors.length, 0, "valid app got no error"); - is(validator.warnings.length, 0, "valid app got no warning"); - - next(); - }); - }, - - function () { - let validator = createPackaged("valid"); - validator.validate().then(() => { - is(validator.errors.length, 0, "valid packaged app got no error"); - is(validator.warnings.length, 0, "valid packaged app got no warning"); - - next(); - }); - }, - - // Test a launch path that returns a 404 - function () { - let validator = createHosted("wrong-launch-path"); - validator.validate().then(() => { - is(validator.errors.length, 1, "app with non-existant launch path got an error"); - is(validator.errors[0], strings.formatStringFromName("validator.accessFailedLaunchPathBadHttpCode", [origin + "wrong-path.html", 404], 2), - "with the right error message"); - is(validator.warnings.length, 0, "but no warning"); - next(); - }); - }, - function () { - let validator = createPackaged("wrong-launch-path"); - validator.validate().then(() => { - is(validator.errors.length, 1, "app with wrong path got an error"); - let file = nsFile(validator.location); - file.append("wrong-path.html"); - let url = Services.io.newFileURI(file); - is(validator.errors[0], strings.formatStringFromName("validator.accessFailedLaunchPath", [url.spec], 1), - "with the expected message"); - is(validator.warnings.length, 0, "but no warning"); - - next(); - }); - }, - - // Test when using a non-absolute path for launch_path - function () { - let validator = createHosted("non-absolute-path"); - validator.validate().then(() => { - is(validator.errors.length, 1, "app with non absolute path got an error"); - is(validator.errors[0], strings.formatStringFromName("validator.nonAbsoluteLaunchPath", ["non-absolute.html"], 1), - "with expected message"); - is(validator.warnings.length, 0, "but no warning"); - next(); - }); - }, - function () { - let validator = createPackaged("non-absolute-path"); - validator.validate().then(() => { - is(validator.errors.length, 1, "app with non absolute path got an error"); - is(validator.errors[0], strings.formatStringFromName("validator.nonAbsoluteLaunchPath", ["non-absolute.html"], 1), - "with expected message"); - is(validator.warnings.length, 0, "but no warning"); - next(); - }); - }, - - // Test multiple failures (missing name [error] and icon [warning]) - function () { - let validator = createHosted("no-name-or-icon"); - validator.validate().then(() => { - checkNoNameOrIcon(validator); - }); - }, - function () { - let validator = createPackaged("no-name-or-icon"); - validator.validate().then(() => { - checkNoNameOrIcon(validator); - }); - }, - - // Test a regular URL instead of a direct link to the manifest - function () { - let validator = createHosted("valid", "/"); - validator.validate().then(() => { - is(validator.warnings.length, 0, "manifest found got no warning"); - is(validator.errors.length, 0, "manifest found got no error"); - - next(); - }); - }, - - // Test finding a manifest at origin's root - function () { - let validator = createHosted("valid", "/unexisting-dir"); - validator.validate().then(() => { - is(validator.warnings.length, 0, "manifest found at origin root got no warning"); - is(validator.errors.length, 0, "manifest found at origin root got no error"); - - next(); - }); - }, - - // Test priorization of manifest.webapp at provided location instead of a manifest located at origin's root - function() { - let validator = createHosted("valid", "/alsoValid"); - validator.validate().then(() => { - is(validator.manifest.name, "valid at subfolder", "manifest at subfolder was used"); - - next(); - }); - } - ]; - - function checkNoNameOrIcon(validator) { - is(validator.errors.length, 1, "app with no name has an error"); - is(validator.errors[0], - strings.GetStringFromName("validator.missNameManifestProperty"), - "with expected message"); - is(validator.warnings.length, 1, "app with no icon has a warning"); - is(validator.warnings[0], - strings.GetStringFromName("validator.missIconsManifestProperty"), - "with expected message"); - next(); - } - - </script> - </body> -</html> diff --git a/devtools/client/webide/test/test_autoconnect_runtime.html b/devtools/client/webide/test/test_autoconnect_runtime.html deleted file mode 100644 index 3de00473a..000000000 --- a/devtools/client/webide/test/test_autoconnect_runtime.html +++ /dev/null @@ -1,94 +0,0 @@ -<!DOCTYPE html> - -<html> - - <head> - <meta charset="utf8"> - <title></title> - - <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script> - <script type="application/javascript;version=1.8" src="head.js"></script> - <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> - </head> - - <body> - - <script type="application/javascript;version=1.8"> - window.onload = function() { - SimpleTest.waitForExplicitFinish(); - - Task.spawn(function*() { - if (!DebuggerServer.initialized) { - DebuggerServer.init(); - DebuggerServer.addBrowserActors(); - } - - let win = yield openWebIDE(); - let docRuntime = getRuntimeDocument(win); - - let fakeRuntime = { - type: "USB", - connect: function(connection) { - is(connection, win.AppManager.connection, "connection is valid"); - connection.host = null; // force connectPipe - connection.connect(); - return promise.resolve(); - }, - - get id() { - return "fakeRuntime"; - }, - - get name() { - return "fakeRuntime"; - } - }; - win.AppManager.runtimeList.usb.push(fakeRuntime); - win.AppManager.update("runtime-list"); - - let panelNode = docRuntime.querySelector("#runtime-panel"); - let items = panelNode.querySelectorAll(".runtime-panel-item-usb"); - is(items.length, 1, "Found one runtime button"); - - let connectionsChanged = waitForConnectionChange("opened", 2); - items[0].click(); - - ok(win.document.querySelector("window").className, "busy", "UI is busy"); - yield win.UI._busyPromise; - - yield connectionsChanged; - is(Object.keys(DebuggerServer._connections).length, 2, "Connected"); - - connectionsChanged = waitForConnectionChange("closed", 2); - - yield nextTick(); - yield closeWebIDE(win); - - yield connectionsChanged; - is(Object.keys(DebuggerServer._connections).length, 0, "Disconnected"); - - connectionsChanged = waitForConnectionChange("opened", 2); - - win = yield openWebIDE(); - - win.AppManager.runtimeList.usb.push(fakeRuntime); - win.AppManager.update("runtime-list"); - - yield waitForUpdate(win, "runtime-targets"); - - yield connectionsChanged; - is(Object.keys(DebuggerServer._connections).length, 2, "Automatically reconnected"); - - yield win.Cmds.disconnectRuntime(); - - yield closeWebIDE(win); - - DebuggerServer.destroy(); - - SimpleTest.finish(); - }); - } - </script> - </body> -</html> diff --git a/devtools/client/webide/test/test_autoselect_project.html b/devtools/client/webide/test/test_autoselect_project.html deleted file mode 100644 index cd5793559..000000000 --- a/devtools/client/webide/test/test_autoselect_project.html +++ /dev/null @@ -1,110 +0,0 @@ -<!DOCTYPE html> - -<html> - - <head> - <meta charset="utf8"> - <title></title> - - <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script> - <script type="application/javascript;version=1.8" src="head.js"></script> - <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> - </head> - - <body> - - <script type="application/javascript;version=1.8"> - window.onload = function() { - SimpleTest.waitForExplicitFinish(); - - Task.spawn(function* () { - if (!DebuggerServer.initialized) { - DebuggerServer.init(); - DebuggerServer.addBrowserActors(); - } - - let win = yield openWebIDE(); - let docRuntime = getRuntimeDocument(win); - let docProject = getProjectDocument(win); - - let panelNode = docRuntime.querySelector("#runtime-panel"); - let items = panelNode.querySelectorAll(".runtime-panel-item-other"); - is(items.length, 2, "Found 2 runtime buttons"); - - // Connect to local runtime - let connectionsChanged = waitForConnectionChange("opened", 2); - items[1].click(); - - yield waitForUpdate(win, "runtime-targets"); - - yield connectionsChanged; - is(Object.keys(DebuggerServer._connections).length, 2, "Locally connected"); - - ok(win.AppManager.isMainProcessDebuggable(), "Main process available"); - - // Select main process - yield win.Cmds.showProjectPanel(); - yield waitForUpdate(win, "runtime-targets"); - SimpleTest.executeSoon(() => { - docProject.querySelectorAll("#project-panel-runtimeapps .panel-item")[0].click(); - }); - - yield waitForUpdate(win, "project"); - - let lastProject = Services.prefs.getCharPref("devtools.webide.lastSelectedProject"); - is(lastProject, "mainProcess:", "Last project is main process"); - - connectionsChanged = waitForConnectionChange("closed", 2); - - yield nextTick(); - yield closeWebIDE(win); - - yield connectionsChanged; - is(Object.keys(DebuggerServer._connections).length, 0, "Disconnected"); - - connectionsChanged = waitForConnectionChange("opened", 2); - - // Re-open, should reselect main process after connection - win = yield openWebIDE(); - - docRuntime = getRuntimeDocument(win); - - panelNode = docRuntime.querySelector("#runtime-panel"); - items = panelNode.querySelectorAll(".runtime-panel-item-other"); - is(items.length, 2, "Found 2 runtime buttons"); - - // Connect to local runtime - items[1].click(); - - yield waitForUpdate(win, "runtime-targets"); - - yield connectionsChanged; - is(Object.keys(DebuggerServer._connections).length, 2, "Locally connected"); - ok(win.AppManager.isMainProcessDebuggable(), "Main process available"); - is(win.AppManager.selectedProject.type, "mainProcess", "Main process reselected"); - - // Wait for the toolbox to be fully loaded - yield win.UI.toolboxPromise; - - // If we happen to pass a project object targeting the same context, - // here, the main process, the `selectedProject` attribute shouldn't be updated - // so that no `project` event would fire. - let oldProject = win.AppManager.selectedProject; - win.AppManager.selectedProject = { - type: "mainProcess" - }; - is(win.AppManager.selectedProject, oldProject, "AppManager.selectedProject shouldn't be updated if we selected the same project"); - - yield win.Cmds.disconnectRuntime(); - - yield closeWebIDE(win); - - DebuggerServer.destroy(); - - SimpleTest.finish(); - }); - } - </script> - </body> -</html> diff --git a/devtools/client/webide/test/test_basic.html b/devtools/client/webide/test/test_basic.html deleted file mode 100644 index e619a0f06..000000000 --- a/devtools/client/webide/test/test_basic.html +++ /dev/null @@ -1,55 +0,0 @@ -<!DOCTYPE html> - -<html> - - <head> - <meta charset="utf8"> - <title></title> - - <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script> - <script type="application/javascript;version=1.8" src="head.js"></script> - <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> - </head> - - <body> - - <script type="application/javascript;version=1.8"> - window.onload = function() { - SimpleTest.waitForExplicitFinish(); - - Task.spawn(function* () { - let win = yield openWebIDE(); - - const {gDevToolsBrowser} = require("devtools/client/framework/devtools-browser"); - yield gDevToolsBrowser.isWebIDEInitialized.promise; - ok(true, "WebIDE was initialized"); - - ok(win, "Found a window"); - ok(win.AppManager, "App Manager accessible"); - let appmgr = win.AppManager; - ok(appmgr.connection, "App Manager connection ready"); - ok(appmgr.runtimeList, "Runtime list ready"); - - // test error reporting - let nbox = win.document.querySelector("#notificationbox"); - let notification = nbox.getNotificationWithValue("webide:errornotification"); - ok(!notification, "No notification yet"); - let deferred = promise.defer(); - nextTick().then(() => { - deferred.reject("BOOM!"); - }); - try { - yield win.UI.busyUntil(deferred.promise, "xx"); - } catch(e) {/* This *will* fail */} - notification = nbox.getNotificationWithValue("webide:errornotification"); - ok(notification, "Error has been reported"); - - yield closeWebIDE(win); - - SimpleTest.finish(); - }); - } - </script> - </body> -</html> diff --git a/devtools/client/webide/test/test_build.html b/devtools/client/webide/test/test_build.html deleted file mode 100644 index ffb01998c..000000000 --- a/devtools/client/webide/test/test_build.html +++ /dev/null @@ -1,128 +0,0 @@ -<!DOCTYPE html> - -<html> - - <head> - <meta charset="utf8"> - <title></title> - - <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script> - <script type="application/javascript;version=1.8" src="head.js"></script> - <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> - </head> - - <body> - - <script type="application/javascript;version=1.8"> - window.onload = function() { - SimpleTest.waitForExplicitFinish(); - - let {TextDecoder, OS} = Cu.import("resource://gre/modules/osfile.jsm", {}); - let {ProjectBuilding} = require("devtools/client/webide/modules/build"); - - Task.spawn(function* () { - let win = yield openWebIDE(); - let winProject = getProjectWindow(win); - let AppManager = win.AppManager; - - function isProjectMarkedAsValid() { - let details = win.frames[0]; - return !details.document.body.classList.contains("error"); - } - - // # Test first package.json like this: `{webide: {prepackage: "command line string"}}` - let platform = Services.appShell.hiddenDOMWindow.navigator.platform; - let testSuffix = ""; - if (platform.indexOf("Win") != -1) { - testSuffix = "_windows"; - } - - let packagedAppLocation = getTestFilePath("build_app" + testSuffix + "1"); - - let onValidated = waitForUpdate(win, "project-validated"); - let onDetails = waitForUpdate(win, "details"); - yield winProject.projectList.importPackagedApp(packagedAppLocation); - yield onValidated; - yield onDetails; - - let project = win.AppManager.selectedProject; - - ok(!project.manifest, "manifest includes name"); - is(project.name, "--", "Display name uses manifest name"); - - let loggedMessages = []; - let logger = function (msg) { - loggedMessages.push(msg); - } - - yield ProjectBuilding.build({ - project, - logger - }); - let packageDir = yield ProjectBuilding.getPackageDir(project); - is(packageDir, packagedAppLocation, "no custom packagedir"); - is(loggedMessages[0], "start", "log messages are correct"); - ok(loggedMessages[1].indexOf("Running pre-package hook") != -1, "log messages are correct"); - is(loggedMessages[2], "Terminated with error code: 0", "log messages are correct"); - is(loggedMessages[3], "succeed", "log messages are correct"); - - // Trigger validation - yield AppManager.validateAndUpdateProject(AppManager.selectedProject); - yield nextTick(); - - ok("name" in project.manifest, "manifest includes name"); - is(project.name, "hello", "Display name uses manifest name"); - is(project.manifest.name, project.name, "Display name uses manifest name"); - - yield OS.File.remove(OS.Path.join(packagedAppLocation, "manifest.webapp")); - - // # Now test a full featured package.json - packagedAppLocation = getTestFilePath("build_app" + testSuffix + "2"); - - onValidated = waitForUpdate(win, "project-validated"); - onDetails = waitForUpdate(win, "details"); - yield winProject.projectList.importPackagedApp(packagedAppLocation); - yield onValidated; - yield onDetails; - - project = win.AppManager.selectedProject; - - loggedMessages = []; - yield ProjectBuilding.build({ - project, - logger - }); - packageDir = yield ProjectBuilding.getPackageDir(project); - is(OS.Path.normalize(packageDir), - OS.Path.join(packagedAppLocation, "stage"), "custom packagedir"); - is(loggedMessages[0], "start", "log messages are correct"); - ok(loggedMessages[1].indexOf("Running pre-package hook") != -1, "log messages are correct"); - is(loggedMessages[2], "Terminated with error code: 0", "log messages are correct"); - is(loggedMessages[3], "succeed", "log messages are correct"); - - // Switch to the package dir in order to verify the generated webapp.manifest - onValidated = waitForUpdate(win, "project-validated"); - onDetails = waitForUpdate(win, "details"); - yield winProject.projectList.importPackagedApp(packageDir); - yield onValidated; - yield onDetails; - - project = win.AppManager.selectedProject; - - ok("name" in project.manifest, "manifest includes name"); - is(project.name, "world", "Display name uses manifest name"); - is(project.manifest.name, project.name, "Display name uses manifest name"); - - yield closeWebIDE(win); - - yield removeAllProjects(); - - SimpleTest.finish(); - }); - } - - - </script> - </body> -</html> diff --git a/devtools/client/webide/test/test_device_permissions.html b/devtools/client/webide/test/test_device_permissions.html deleted file mode 100644 index eadd9f595..000000000 --- a/devtools/client/webide/test/test_device_permissions.html +++ /dev/null @@ -1,81 +0,0 @@ -<!DOCTYPE html> - -<html> - - <head> - <meta charset="utf8"> - <title></title> - - <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script> - <script type="application/javascript;version=1.8" src="head.js"></script> - <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> - </head> - - <body> - - <script type="application/javascript;version=1.8"> - window.onload = function() { - SimpleTest.waitForExplicitFinish(); - - Task.spawn(function* () { - if (!DebuggerServer.initialized) { - DebuggerServer.init(); - DebuggerServer.addBrowserActors(); - } - - let win = yield openWebIDE(); - - let permIframe = win.document.querySelector("#deck-panel-permissionstable"); - let docRuntime = getRuntimeDocument(win); - let winRuntime = getRuntimeWindow(win); - - yield connectToLocalRuntime(win); - - let perm = docRuntime.querySelector("#runtime-permissions"); - - ok(!perm.hasAttribute("disabled"), "perm cmd enabled"); - - let deck = win.document.querySelector("#deck"); - - winRuntime.runtimeList.showPermissionsTable(); - is(deck.selectedPanel, permIframe, "permission iframe selected"); - - yield nextTick(); - - yield lazyIframeIsLoaded(permIframe); - - yield permIframe.contentWindow.getRawPermissionsTablePromise; - - doc = permIframe.contentWindow.document; - trs = doc.querySelectorAll(".line"); - found = false; - for (let tr of trs) { - let [name,v1,v2,v3] = tr.querySelectorAll("td"); - if (name.textContent == "geolocation") { - found = true; - is(v1.className, "permprompt", "geolocation perm is valid"); - is(v2.className, "permprompt", "geolocation perm is valid"); - is(v3.className, "permprompt", "geolocation perm is valid"); - break; - } - } - ok(found, "Found geolocation line"); - - doc.querySelector("#close").click(); - - ok(!deck.selectedPanel, "No panel selected"); - - DebuggerServer.destroy(); - - yield closeWebIDE(win); - - SimpleTest.finish(); - }).then(null, e => { - ok(false, "Exception: " + e); - SimpleTest.finish(); - }); - } - </script> - </body> -</html> diff --git a/devtools/client/webide/test/test_device_preferences.html b/devtools/client/webide/test/test_device_preferences.html deleted file mode 100644 index c79db7f79..000000000 --- a/devtools/client/webide/test/test_device_preferences.html +++ /dev/null @@ -1,87 +0,0 @@ -<!DOCTYPE html> - -<html> - - <head> - <meta charset="utf8"> - <title></title> - <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script> - <script type="application/javascript;version=1.8" src="head.js"></script> - <script type="application/javascript;version=1.8" src="device_front_shared.js"></script> - <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> - </head> - - <body> - - <script type="application/javascript;version=1.8"> - window.onload = function() { - SimpleTest.waitForExplicitFinish(); - - Task.spawn(function* () { - if (!DebuggerServer.initialized) { - DebuggerServer.init(); - DebuggerServer.addBrowserActors(); - } - - let win = yield openWebIDE(); - - let prefIframe = win.document.querySelector("#deck-panel-devicepreferences"); - let docRuntime = getRuntimeDocument(win); - - win.AppManager.update("runtime-list"); - - yield connectToLocalRuntime(win); - - let prefs = docRuntime.querySelector("#runtime-preferences"); - - ok(!prefs.hasAttribute("disabled"), "device prefs cmd enabled"); - - let deck = win.document.querySelector("#deck"); - - win.Cmds.showDevicePrefs(); - is(deck.selectedPanel, prefIframe, "device preferences iframe selected"); - - yield nextTick(); - - yield lazyIframeIsLoaded(prefIframe); - - yield prefIframe.contentWindow.getAllPrefs; - - setDocument(prefIframe); - - let fields = doc.querySelectorAll(".editable"); - - addNewField(); - - let preference = "accessibility.accesskeycausesactivation"; - - fieldChange(fields, preference); - - addNewFieldWithEnter(); - - editExistingField(); - - addNewFieldInteger(); - - yield editFieldInteger(); - - yield resetExistingField("accessibility.accesskeycausesactivation"); - - addNewFieldBoolean(); - - searchFields(deck, "debugger"); - - DebuggerServer.destroy(); - - yield closeWebIDE(win); - - SimpleTest.finish(); - }).then(null, e => { - ok(false, "Exception: " + e); - SimpleTest.finish(); - }); - } - </script> - </body> -</html> diff --git a/devtools/client/webide/test/test_device_runtime.html b/devtools/client/webide/test/test_device_runtime.html deleted file mode 100644 index 0ac42b472..000000000 --- a/devtools/client/webide/test/test_device_runtime.html +++ /dev/null @@ -1,81 +0,0 @@ -<!DOCTYPE html> - -<html> - - <head> - <meta charset="utf8"> - <title></title> - - <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script> - <script type="application/javascript;version=1.8" src="head.js"></script> - <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> - </head> - - <body> - - <script type="application/javascript;version=1.8"> - window.onload = function() { - SimpleTest.waitForExplicitFinish(); - - Task.spawn(function* () { - if (!DebuggerServer.initialized) { - DebuggerServer.init(); - DebuggerServer.addBrowserActors(); - } - - let win = yield openWebIDE(); - - let detailsIframe = win.document.querySelector("#deck-panel-runtimedetails"); - - yield connectToLocalRuntime(win); - - let details = win.document.querySelector("#cmd_showRuntimeDetails"); - - ok(!details.hasAttribute("disabled"), "info cmd enabled"); - - let deck = win.document.querySelector("#deck"); - - win.Cmds.showRuntimeDetails(); - is(deck.selectedPanel, detailsIframe, "info iframe selected"); - - yield nextTick(); - - yield lazyIframeIsLoaded(detailsIframe); - - yield detailsIframe.contentWindow.getDescriptionPromise; - - // device info and permissions content is checked in other tests - // We just test one value to make sure we get something - - let doc = detailsIframe.contentWindow.document; - let trs = doc.querySelectorAll("tr"); - let found = false; - - for (let tr of trs) { - let [name,val] = tr.querySelectorAll("td"); - if (name.textContent == "appid") { - found = true; - is(val.textContent, Services.appinfo.ID, "appid has the right value"); - break; - } - } - ok(found, "Found appid line"); - - doc.querySelector("#close").click(); - - ok(!deck.selectedPanel, "No panel selected"); - - DebuggerServer.destroy(); - - yield closeWebIDE(win); - - SimpleTest.finish(); - }).then(null, e => { - ok(false, "Exception: " + e); - SimpleTest.finish(); - }); - } - </script> - </body> -</html> diff --git a/devtools/client/webide/test/test_device_settings.html b/devtools/client/webide/test/test_device_settings.html deleted file mode 100644 index ec8e7943b..000000000 --- a/devtools/client/webide/test/test_device_settings.html +++ /dev/null @@ -1,87 +0,0 @@ -<!DOCTYPE html> - -<html> - - <head> - <meta charset="utf8"> - <title></title> - <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script> - <script type="application/javascript;version=1.8" src="head.js"></script> - <script type="application/javascript;version=1.8" src="device_front_shared.js"></script> - <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> - </head> - - <body> - - <script type="application/javascript;version=1.8"> - window.onload = function() { - SimpleTest.waitForExplicitFinish(); - - Task.spawn(function*() { - if (SpecialPowers.isMainProcess()) { - Cu.import("resource://gre/modules/SettingsRequestManager.jsm"); - } - - if (!DebuggerServer.initialized) { - DebuggerServer.init(); - DebuggerServer.addBrowserActors(); - } - - let win = yield openWebIDE(); - - let settingIframe = win.document.querySelector("#deck-panel-devicesettings"); - let docRuntime = getRuntimeDocument(win); - - win.AppManager.update("runtime-list"); - - yield connectToLocalRuntime(win); - - let settings = docRuntime.querySelector("#runtime-settings"); - - ok(!settings.hasAttribute("disabled"), "device settings cmd enabled"); - - let deck = win.document.querySelector("#deck"); - - win.Cmds.showSettings(); - is(deck.selectedPanel, settingIframe, "device settings iframe selected"); - - yield nextTick(); - - yield lazyIframeIsLoaded(settingIframe); - - yield settingIframe.contentWindow.getAllSettings; - - setDocument(settingIframe); - - let fields = doc.querySelectorAll(".editable"); - - addNewField(); - - addNewFieldWithEnter(); - - editExistingField(); - - addNewFieldInteger(); - - yield editFieldInteger(); - - yield resetNewField("new-string-field"); - - addNewFieldBoolean(); - - searchFields(deck, "new-boolean-field2"); - - DebuggerServer.destroy(); - - yield closeWebIDE(win); - - SimpleTest.finish(); - }).then(null, e => { - ok(false, "Exception: " + e); - SimpleTest.finish(); - }); - } - </script> - </body> -</html> diff --git a/devtools/client/webide/test/test_duplicate_import.html b/devtools/client/webide/test/test_duplicate_import.html deleted file mode 100644 index ef01e23e4..000000000 --- a/devtools/client/webide/test/test_duplicate_import.html +++ /dev/null @@ -1,77 +0,0 @@ -<!DOCTYPE html> - -<html> - - <head> - <meta charset="utf8"> - <title></title> - - <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script> - <script type="application/javascript;version=1.8" src="head.js"></script> - <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> - </head> - - <body> - <script type="application/javascript;version=1.8"> - window.onload = function() { - SimpleTest.waitForExplicitFinish(); - - Task.spawn(function*() { - let win = yield openWebIDE(); - let docProject = getProjectDocument(win); - let winProject = getProjectWindow(win); - let packagedAppLocation = getTestFilePath("app"); - let hostedAppManifest = TEST_BASE + "hosted_app.manifest"; - - yield win.AppProjects.load(); - is(win.AppProjects.projects.length, 0, "IDB is empty"); - - let onValidated = waitForUpdate(win, "project-validated"); - let onDetails = waitForUpdate(win, "details"); - yield winProject.projectList.importPackagedApp(packagedAppLocation); - yield onValidated; - yield onDetails; - - yield winProject.projectList.importHostedApp(hostedAppManifest); - yield waitForUpdate(win, "project-validated"); - yield nextTick(); - - onValidated = waitForUpdate(win, "project-validated"); - onDetails = waitForUpdate(win, "details"); - yield winProject.projectList.importPackagedApp(packagedAppLocation); - yield onValidated; - yield onDetails; - - let project = win.AppManager.selectedProject; - is(project.location, packagedAppLocation, "Correctly reselected existing packaged app."); - yield nextTick(); - - info("to call importHostedApp(" + hostedAppManifest + ") again"); - yield winProject.projectList.importHostedApp(hostedAppManifest); - yield waitForUpdate(win, "project-validated"); - project = win.AppManager.selectedProject; - is(project.location, hostedAppManifest, "Correctly reselected existing hosted app."); - yield nextTick(); - - let panelNode = docProject.querySelector("#project-panel"); - let items = panelNode.querySelectorAll(".panel-item"); - // 3 controls, + 2 projects - is(items.length, 5, "5 projects in panel"); - is(items[3].querySelector("span").textContent, "A name (in app directory)", "Panel text is correct"); - is(items[4].querySelector("span").textContent, "hosted manifest name property", "Panel text is correct"); - - yield closeWebIDE(win); - - yield removeAllProjects(); - - SimpleTest.finish(); - }).then(null, e => { - ok(false, "Exception: " + e); - SimpleTest.finish(); - }); - } - </script> - </body> -</html> - diff --git a/devtools/client/webide/test/test_fullscreenToolbox.html b/devtools/client/webide/test/test_fullscreenToolbox.html deleted file mode 100644 index 6ae0c4446..000000000 --- a/devtools/client/webide/test/test_fullscreenToolbox.html +++ /dev/null @@ -1,67 +0,0 @@ -<!DOCTYPE html> - -<html> - - <head> - <meta charset="utf8"> - <title></title> - - <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script> - <script type="application/javascript;version=1.8" src="head.js"></script> - <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> - </head> - - <body> - - <script type="application/javascript;version=1.8"> - function connectToLocal(win, docRuntime) { - let deferred = promise.defer(); - win.AppManager.connection.once( - win.Connection.Events.CONNECTED, - () => deferred.resolve()); - docRuntime.querySelectorAll(".runtime-panel-item-other")[1].click(); - return deferred.promise; - } - - window.onload = function() { - SimpleTest.waitForExplicitFinish(); - - Task.spawn(function* () { - let win = yield openWebIDE(); - let docProject = getProjectDocument(win); - let docRuntime = getRuntimeDocument(win); - win.AppManager.update("runtime-list"); - - yield connectToLocal(win, docRuntime); - - // Select main process - yield waitForUpdate(win, "runtime-targets"); - SimpleTest.executeSoon(() => { - docProject.querySelectorAll("#project-panel-runtimeapps .panel-item")[0].click(); - }); - - yield waitForUpdate(win, "project"); - - ok(win.UI.toolboxPromise, "Toolbox promise exists"); - yield win.UI.toolboxPromise; - - let nbox = win.document.querySelector("#notificationbox"); - ok(!nbox.hasAttribute("toolboxfullscreen"), "Toolbox is not fullscreen"); - - win.Cmds.showRuntimeDetails(); - - ok(!nbox.hasAttribute("toolboxfullscreen"), "Toolbox is not fullscreen"); - - yield win.Cmds.disconnectRuntime(); - - yield closeWebIDE(win); - - DebuggerServer.destroy(); - - SimpleTest.finish(); - }); - } - </script> - </body> -</html> diff --git a/devtools/client/webide/test/test_import.html b/devtools/client/webide/test/test_import.html deleted file mode 100644 index 830198cca..000000000 --- a/devtools/client/webide/test/test_import.html +++ /dev/null @@ -1,82 +0,0 @@ -<!DOCTYPE html> - -<html> - - <head> - <meta charset="utf8"> - <title></title> - - <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script> - <script type="application/javascript;version=1.8" src="head.js"></script> - <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> - </head> - - <body> - <script type="application/javascript;version=1.8"> - window.onload = function() { - SimpleTest.waitForExplicitFinish(); - - Task.spawn(function*() { - let win = yield openWebIDE(); - let docProject = getProjectDocument(win); - let winProject = getProjectWindow(win); - let packagedAppLocation = getTestFilePath("app"); - - yield win.AppProjects.load(); - is(win.AppProjects.projects.length, 0, "IDB is empty"); - - info("to call importPackagedApp(" + packagedAppLocation + ")"); - ok(!win.UI._busyPromise, "UI is not busy"); - - let onValidated = waitForUpdate(win, "project-validated"); - let onDetails = waitForUpdate(win, "details"); - yield winProject.projectList.importPackagedApp(packagedAppLocation); - yield onValidated; - yield onDetails; - - let project = win.AppManager.selectedProject; - is(project.location, packagedAppLocation, "Location is valid"); - is(project.name, "A name (in app directory)", "name field has been updated"); - is(project.manifest.launch_path, "/index.html", "manifest found. launch_path valid."); - is(project.manifest.description, "desc", "manifest found. description valid"); - - yield nextTick(); - - let hostedAppManifest = TEST_BASE + "hosted_app.manifest"; - yield winProject.projectList.importHostedApp(hostedAppManifest); - yield waitForUpdate(win, "project-validated"); - - project = win.AppManager.selectedProject; - is(project.location, hostedAppManifest, "Location is valid"); - is(project.name, "hosted manifest name property", "name field has been updated"); - - yield nextTick(); - - hostedAppManifest = TEST_BASE + "/app"; - yield winProject.projectList.importHostedApp(hostedAppManifest); - yield waitForUpdate(win, "project-validated"); - - project = win.AppManager.selectedProject; - ok(project.location.endsWith('manifest.webapp'), "The manifest was found and the project was updated"); - - let panelNode = docProject.querySelector("#project-panel"); - let items = panelNode.querySelectorAll(".panel-item"); - // 4 controls, + 2 projects - is(items.length, 6, "6 projects in panel"); - is(items[3].querySelector("span").textContent, "A name (in app directory)", "Panel text is correct"); - is(items[4].querySelector("span").textContent, "hosted manifest name property", "Panel text is correct"); - - yield closeWebIDE(win); - - yield removeAllProjects(); - - SimpleTest.finish(); - }).then(null, e => { - ok(false, "Exception: " + e); - SimpleTest.finish(); - }); - } - </script> - </body> -</html> diff --git a/devtools/client/webide/test/test_manifestUpdate.html b/devtools/client/webide/test/test_manifestUpdate.html deleted file mode 100644 index 66f9affd0..000000000 --- a/devtools/client/webide/test/test_manifestUpdate.html +++ /dev/null @@ -1,98 +0,0 @@ -<!DOCTYPE html> - -<html> - - <head> - <meta charset="utf8"> - <title></title> - - <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script> - <script type="application/javascript;version=1.8" src="head.js"></script> - <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> - </head> - - <body> - - <script type="application/javascript;version=1.8"> - window.onload = function() { - SimpleTest.waitForExplicitFinish(); - - let {TextDecoder, OS} = Cu.import("resource://gre/modules/osfile.jsm", {}); - - Task.spawn(function* () { - let win = yield openWebIDE(); - let winProject = getProjectWindow(win); - let AppManager = win.AppManager; - - function isProjectMarkedAsValid() { - let details = win.frames[1]; - return !details.document.body.classList.contains("error"); - } - - let packagedAppLocation = getTestFilePath("app"); - - let onValidated = waitForUpdate(win, "project-validated"); - let onDetails = waitForUpdate(win, "details"); - yield winProject.projectList.importPackagedApp(packagedAppLocation); - yield onValidated; - yield onDetails; - - let project = win.AppManager.selectedProject; - - ok("name" in project.manifest, "manifest includes name"); - is(project.name, project.manifest.name, "Display name uses manifest name"); - ok(isProjectMarkedAsValid(), "project is marked as valid"); - - // Change the name - let originalName = project.manifest.name; - - project.manifest.name = "xxx"; - - // Write to disk - yield AppManager.writeManifest(project); - - // Read file - let manifestPath = OS.Path.join(packagedAppLocation, "manifest.webapp"); - let Decoder = new TextDecoder(); - let data = yield OS.File.read(manifestPath); - data = new TextDecoder().decode(data); - let json = JSON.parse(data); - is(json.name, "xxx", "manifest written on disc"); - - // Make the manifest invalid on disk - delete json.name; - let Encoder = new TextEncoder(); - data = Encoder.encode(JSON.stringify(json)); - yield OS.File.writeAtomic(manifestPath, data , {tmpPath: manifestPath + ".tmp"}); - - // Trigger validation - yield AppManager.validateAndUpdateProject(AppManager.selectedProject); - yield nextTick(); - - ok(!("name" in project.manifest), "manifest has been updated"); - is(project.name, "--", "Placeholder is used for display name"); - ok(!isProjectMarkedAsValid(), "project is marked as invalid"); - - // Make the manifest valid on disk - project.manifest.name = originalName; - yield AppManager.writeManifest(project); - - // Trigger validation - yield AppManager.validateAndUpdateProject(AppManager.selectedProject); - yield nextTick(); - - ok("name" in project.manifest, "manifest includes name"); - is(project.name, originalName, "Display name uses original manifest name"); - ok(isProjectMarkedAsValid(), "project is marked as valid"); - - yield closeWebIDE(win); - - yield removeAllProjects(); - - SimpleTest.finish(); - }); - } - </script> - </body> -</html> diff --git a/devtools/client/webide/test/test_newapp.html b/devtools/client/webide/test/test_newapp.html deleted file mode 100644 index 45374f268..000000000 --- a/devtools/client/webide/test/test_newapp.html +++ /dev/null @@ -1,46 +0,0 @@ -<!DOCTYPE html> - -<html> - - <head> - <meta charset="utf8"> - <title></title> - - <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script> - <script type="application/javascript;version=1.8" src="head.js"></script> - <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> - </head> - - <body> - - <script type="application/javascript;version=1.8"> - window.onload = function() { - SimpleTest.waitForExplicitFinish(); - - Task.spawn(function* () { - let win = yield openWebIDE(); - let winProject = getProjectWindow(win); - let tmpDir = FileUtils.getDir("TmpD", []); - yield winProject.projectList.newApp({ - index: 0, - name: "webideTmpApp", - folder: tmpDir - }); - - let project = win.AppManager.selectedProject; - tmpDir = FileUtils.getDir("TmpD", ["webidetmpapp"]); - ok(tmpDir.isDirectory(), "Directory created"); - is(project.location, tmpDir.path, "Location is valid (and lowercase)"); - is(project.name, "webideTmpApp", "name field has been updated"); - - // Clean up - tmpDir.remove(true); - yield closeWebIDE(win); - yield removeAllProjects(); - SimpleTest.finish(); - }); - } - </script> - </body> -</html> diff --git a/devtools/client/webide/test/test_runtime.html b/devtools/client/webide/test/test_runtime.html deleted file mode 100644 index 9b16ef82d..000000000 --- a/devtools/client/webide/test/test_runtime.html +++ /dev/null @@ -1,203 +0,0 @@ -<!DOCTYPE html> - -<html> - - <head> - <meta charset="utf8"> - <title></title> - - <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script> - <script type="application/javascript;version=1.8" src="head.js"></script> - <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> - </head> - - <body> - - <script type="application/javascript;version=1.8"> - window.onload = function() { - SimpleTest.waitForExplicitFinish(); - - let win; - - SimpleTest.registerCleanupFunction(() => { - Task.spawn(function*() { - if (win) { - yield closeWebIDE(win); - } - DebuggerServer.destroy(); - yield removeAllProjects(); - }); - }); - - Task.spawn(function*() { - function isPlayActive() { - return !win.document.querySelector("#cmd_play").hasAttribute("disabled"); - } - - function isStopActive() { - return !win.document.querySelector("#cmd_stop").hasAttribute("disabled"); - } - - if (!DebuggerServer.initialized) { - DebuggerServer.init(); - DebuggerServer.addBrowserActors(); - } - - win = yield openWebIDE(); - let docRuntime = getRuntimeDocument(win); - let docProject = getProjectDocument(win); - let winProject = getProjectWindow(win); - - let packagedAppLocation = getTestFilePath("app"); - - let onValidated = waitForUpdate(win, "project-validated"); - let onDetails = waitForUpdate(win, "details"); - yield winProject.projectList.importPackagedApp(packagedAppLocation); - yield onValidated; - yield onDetails; - - win.AppManager.runtimeList.usb.push({ - connect: function(connection) { - is(connection, win.AppManager.connection, "connection is valid"); - connection.host = null; // force connectPipe - connection.connect(); - return promise.resolve(); - }, - - get name() { - return "fakeRuntime"; - } - }); - - win.AppManager.runtimeList.usb.push({ - connect: function(connection) { - let deferred = promise.defer(); - return deferred.promise; - }, - - get name() { - return "infiniteRuntime"; - } - }); - - win.AppManager.runtimeList.usb.push({ - connect: function(connection) { - let deferred = promise.defer(); - return deferred.promise; - }, - - prolongedConnection: true, - - get name() { - return "prolongedRuntime"; - } - }); - - win.AppManager.update("runtime-list"); - - let panelNode = docRuntime.querySelector("#runtime-panel"); - let items = panelNode.querySelectorAll(".runtime-panel-item-usb"); - is(items.length, 3, "Found 3 runtime buttons"); - - let connectionsChanged = waitForConnectionChange("opened", 2); - items[0].click(); - - ok(win.document.querySelector("window").className, "busy", "UI is busy"); - yield win.UI._busyPromise; - - yield connectionsChanged; - is(Object.keys(DebuggerServer._connections).length, 2, "Connected"); - - yield waitForUpdate(win, "runtime-global-actors"); - - // Play button always disabled now, webapps actor removed - ok(!isPlayActive(), "play button is disabled"); - ok(!isStopActive(), "stop button is disabled"); - let oldProject = win.AppManager.selectedProject; - win.AppManager.selectedProject = null; - - yield nextTick(); - - ok(!isPlayActive(), "play button is disabled"); - ok(!isStopActive(), "stop button is disabled"); - win.AppManager._selectedProject = oldProject; - win.UI.updateCommands(); - - yield nextTick(); - - ok(!isPlayActive(), "play button is enabled"); - ok(!isStopActive(), "stop button is disabled"); - - connectionsChanged = waitForConnectionChange("closed", 2); - yield win.Cmds.disconnectRuntime(); - - yield connectionsChanged; - is(Object.keys(DebuggerServer._connections).length, 0, "Disconnected"); - - ok(win.AppManager.selectedProject, "A project is still selected"); - ok(!isPlayActive(), "play button is disabled"); - ok(!isStopActive(), "stop button is disabled"); - - connectionsChanged = waitForConnectionChange("opened", 2); - docRuntime.querySelectorAll(".runtime-panel-item-other")[1].click(); - - yield waitForUpdate(win, "runtime-targets"); - - yield connectionsChanged; - is(Object.keys(DebuggerServer._connections).length, 2, "Locally connected"); - - ok(win.AppManager.isMainProcessDebuggable(), "Main process available"); - - // Select main process - SimpleTest.executeSoon(() => { - docProject.querySelectorAll("#project-panel-runtimeapps .panel-item")[0].click(); - }); - - yield waitForUpdate(win, "project"); - - // Toolbox opens automatically for main process / runtime apps - ok(win.UI.toolboxPromise, "Toolbox promise exists"); - yield win.UI.toolboxPromise; - - yield win.Cmds.disconnectRuntime(); - - Services.prefs.setIntPref("devtools.webide.busyTimeout", 100); - - // Wait for error message since connection never completes - let errorDeferred = promise.defer(); - win.UI.reportError = errorName => { - if (errorName === "error_operationTimeout") { - errorDeferred.resolve(); - } - }; - - // Click the infinite runtime - items[1].click(); - ok(win.document.querySelector("window").className, "busy", "UI is busy"); - yield errorDeferred.promise; - - // Check for unexpected error message since this is prolonged - let noErrorDeferred = promise.defer(); - win.UI.reportError = errorName => { - if (errorName === "error_operationTimeout") { - noErrorDeferred.reject(); - } - }; - - // Click the prolonged runtime - items[2].click(); - ok(win.document.querySelector("window").className, "busy", "UI is busy"); - - setTimeout(() => { - noErrorDeferred.resolve(); - }, 1000); - - yield noErrorDeferred.promise; - - SimpleTest.finish(); - }); - } - </script> - </body> -</html> diff --git a/devtools/client/webide/test/test_simulators.html b/devtools/client/webide/test/test_simulators.html deleted file mode 100644 index 204881512..000000000 --- a/devtools/client/webide/test/test_simulators.html +++ /dev/null @@ -1,426 +0,0 @@ -<!DOCTYPE html> - -<html> - - <head> - <meta charset="utf8"> - <title></title> - - <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script> - <script type="application/javascript;version=1.8" src="head.js"></script> - <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> - </head> - - <body> - - <script type="application/javascript;version=1.8"> - window.onload = function() { - SimpleTest.waitForExplicitFinish(); - - const asyncStorage = require("devtools/shared/async-storage"); - const EventEmitter = require("devtools/shared/event-emitter"); - const { GetAvailableAddons } = require("devtools/client/webide/modules/addons"); - const { getDevices } = require("devtools/client/shared/devices"); - const { Simulator, Simulators } = require("devtools/client/webide/modules/simulators"); - const { AddonSimulatorProcess, - OldAddonSimulatorProcess, - CustomSimulatorProcess } = require("devtools/client/webide/modules/simulator-process"); - - function addonStatus(addon, status) { - if (addon.status == status) { - return promise.resolve(); - } - let deferred = promise.defer(); - addon.on("update", function onUpdate() { - if (addon.status == status) { - addon.off("update", onUpdate); - nextTick().then(() => deferred.resolve()); - } - }); - return deferred.promise; - } - - function waitForUpdate(length) { - info(`Wait for update with length ${length}`); - let deferred = promise.defer(); - let handler = (_, data) => { - if (data.length != length) { - return; - } - info(`Got update with length ${length}`); - Simulators.off("updated", handler); - deferred.resolve(); - }; - Simulators.on("updated", handler); - return deferred.promise; - } - - Task.spawn(function* () { - let win = yield openWebIDE(false); - - yield Simulators._load(); - - let docRuntime = getRuntimeDocument(win); - let find = win.document.querySelector.bind(docRuntime); - let findAll = win.document.querySelectorAll.bind(docRuntime); - - let simulatorList = find("#runtime-panel-simulator"); - let simulatorPanel = win.document.querySelector("#deck-panel-simulator"); - - // Hack SimulatorProcesses to spy on simulation parameters. - - let runPromise; - function fakeRun() { - runPromise.resolve({ - path: this.b2gBinary.path, - args: this.args - }); - // Don't actually try to connect to the fake simulator. - throw new Error("Aborting on purpose before connection."); - } - - AddonSimulatorProcess.prototype.run = fakeRun; - OldAddonSimulatorProcess.prototype.run = fakeRun; - CustomSimulatorProcess.prototype.run = fakeRun; - - function runSimulator(i) { - runPromise = promise.defer(); - findAll(".runtime-panel-item-simulator")[i].click(); - return runPromise.promise; - } - - // Install fake "Firefox OS 1.0" simulator addon. - - let addons = yield GetAvailableAddons(); - - let sim10 = addons.simulators.filter(a => a.version == "1.0")[0]; - - sim10.install(); - - let updated = waitForUpdate(1); - yield addonStatus(sim10, "installed"); - yield updated; - // Wait for next tick to ensure UI elements are updated - yield nextTick(); - - is(findAll(".runtime-panel-item-simulator").length, 1, "One simulator in runtime panel"); - - // Install fake "Firefox OS 2.0" simulator addon. - - let sim20 = addons.simulators.filter(a => a.version == "2.0")[0]; - - sim20.install(); - - updated = waitForUpdate(2); - yield addonStatus(sim20, "installed"); - yield updated; - // Wait for next tick to ensure UI elements are updated - yield nextTick(); - - is(findAll(".runtime-panel-item-simulator").length, 2, "Two simulators in runtime panel"); - - // Dry run a simulator to verify that its parameters look right. - - let params = yield runSimulator(0); - - ok(params.path.includes(sim10.addonID) && params.path.includes("b2g-bin"), "Simulator binary path looks right"); - - let pid = params.args.indexOf("-profile"); - ok(pid > -1, "Simulator process arguments have --profile"); - - let profilePath = params.args[pid + 1]; - ok(profilePath.includes(sim10.addonID) && profilePath.includes("profile"), "Simulator profile path looks right"); - - ok(params.args.indexOf("-dbgport") > -1 || params.args.indexOf("-start-debugger-server") > -1, "Simulator process arguments have a debugger port"); - - ok(params.args.indexOf("-no-remote") > -1, "Simulator process arguments have --no-remote"); - - // Wait for next tick to ensure UI elements are updated - yield nextTick(); - - // Configure the fake 1.0 simulator. - - simulatorList.querySelectorAll(".configure-button")[0].click(); - is(win.document.querySelector("#deck").selectedPanel, simulatorPanel, "Simulator deck panel is selected"); - - yield lazyIframeIsLoaded(simulatorPanel); - - let doc = simulatorPanel.contentWindow.document; - let form = doc.querySelector("#simulator-editor"); - - let formReady = new Promise((resolve, reject) => { - form.addEventListener("change", () => { - resolve(); - }); - }); - - let change = doc.createEvent("HTMLEvents"); - change.initEvent("change", true, true); - - function set(input, value) { - input.value = value; - input.dispatchEvent(change); - return nextTick(); - } - - let MockFilePicker = SpecialPowers.MockFilePicker; - MockFilePicker.init(simulatorPanel.contentWindow); - - yield formReady; - - // Test `name`. - - is(form.name.value, find(".runtime-panel-item-simulator").textContent, "Original simulator name"); - - let customName = "CustomFox "; - yield set(form.name, customName + "1.0"); - - is(find(".runtime-panel-item-simulator").textContent, form.name.value, "Updated simulator name"); - - // Test `version`. - - is(form.version.value, sim10.addonID, "Original simulator version"); - ok(!form.version.classList.contains("custom"), "Version selector is not customized"); - - yield set(form.version, sim20.addonID); - - ok(!form.version.classList.contains("custom"), "Version selector is not customized after addon change"); - is(form.name.value, customName + "2.0", "Simulator name was updated to new version"); - - // Pick custom binary, but act like the user aborted the file picker. - - MockFilePicker.returnFiles = []; - yield set(form.version, "pick"); - - is(form.version.value, sim20.addonID, "Version selector reverted to last valid choice after customization abort"); - ok(!form.version.classList.contains("custom"), "Version selector is not customized after customization abort"); - - // Pick custom binary, and actually follow through. (success, verify value = "custom" and textContent = custom path) - - MockFilePicker.useAnyFile(); - yield set(form.version, "pick"); - - let fakeBinary = MockFilePicker.returnFiles[0]; - - ok(form.version.value == "custom", "Version selector was set to a new custom binary"); - ok(form.version.classList.contains("custom"), "Version selector is now customized"); - is(form.version.selectedOptions[0].textContent, fakeBinary.path, "Custom option textContent is correct"); - - yield set(form.version, sim10.addonID); - - ok(form.version.classList.contains("custom"), "Version selector remains customized after change back to addon"); - is(form.name.value, customName + "1.0", "Simulator name was updated to new version"); - - yield set(form.version, "custom"); - - ok(form.version.value == "custom", "Version selector is back to custom"); - - // Test `profile`. - - is(form.profile.value, "default", "Default simulator profile"); - ok(!form.profile.classList.contains("custom"), "Profile selector is not customized"); - - MockFilePicker.returnFiles = []; - yield set(form.profile, "pick"); - - is(form.profile.value, "default", "Profile selector reverted to last valid choice after customization abort"); - ok(!form.profile.classList.contains("custom"), "Profile selector is not customized after customization abort"); - - let fakeProfile = FileUtils.getDir("TmpD", []); - - MockFilePicker.returnFiles = [ fakeProfile ]; - yield set(form.profile, "pick"); - - ok(form.profile.value == "custom", "Profile selector was set to a new custom directory"); - ok(form.profile.classList.contains("custom"), "Profile selector is now customized"); - is(form.profile.selectedOptions[0].textContent, fakeProfile.path, "Custom option textContent is correct"); - - yield set(form.profile, "default"); - - is(form.profile.value, "default", "Profile selector back to default"); - ok(form.profile.classList.contains("custom"), "Profile selector remains customized after change back to default"); - - yield set(form.profile, "custom"); - - is(form.profile.value, "custom", "Profile selector back to custom"); - - params = yield runSimulator(0); - - is(params.path, fakeBinary.path, "Simulator process uses custom binary path"); - - pid = params.args.indexOf("-profile"); - is(params.args[pid + 1], fakeProfile.path, "Simulator process uses custom profile directory"); - - yield set(form.version, sim10.addonID); - - is(form.name.value, customName + "1.0", "Simulator restored to 1.0"); - - params = yield runSimulator(0); - - pid = params.args.indexOf("-profile"); - is(params.args[pid + 1], fakeProfile.path, "Simulator process still uses custom profile directory"); - - yield set(form.version, "custom"); - - // Test `device`. - - let defaults = Simulator.prototype._defaults; - - for (let param in defaults.phone) { - is(form[param].value, String(defaults.phone[param]), "Default phone value for device " + param); - } - - let width = 5000, height = 4000; - yield set(form.width, width); - yield set(form.height, height); - - is(form.device.value, "custom", "Device selector is custom"); - - params = yield runSimulator(0); - - let sid = params.args.indexOf("-screen"); - ok(sid > -1, "Simulator process arguments have --screen"); - ok(params.args[sid + 1].includes(width + "x" + height), "Simulator screen resolution looks right"); - - yield set(form.version, sim10.addonID); - - // Configure the fake 2.0 simulator. - - simulatorList.querySelectorAll(".configure-button")[1].click(); - // Wait for next tick to ensure UI elements are updated - yield nextTick(); - - // Test `name`. - - is(form.name.value, findAll(".runtime-panel-item-simulator")[1].textContent, "Original simulator name"); - - yield set(form.name, customName + "2.0"); - - is(findAll(".runtime-panel-item-simulator")[1].textContent, form.name.value, "Updated simulator name"); - - yield set(form.version, sim10.addonID); - - ok(form.name.value !== customName + "1.0", "Conflicting simulator name was deduplicated"); - - is(form.name.value, findAll(".runtime-panel-item-simulator")[1].textContent, "Deduplicated simulator name stayed consistent"); - - yield set(form.version, sim20.addonID); - - is(form.name.value, customName + "2.0", "Name deduplication was undone when possible"); - - // Test `device`. - - for (let param in defaults.phone) { - is(form[param].value, String(defaults.phone[param]), "Default phone value for device " + param); - } - - let devices = yield getDevices(); - devices = devices[devices.TYPES[0]]; - let device = devices[devices.length - 1]; - - yield set(form.device, device.name); - - is(form.device.value, device.name, "Device selector was changed"); - is(form.width.value, String(device.width), "New device width is correct"); - is(form.height.value, String(device.height), "New device height is correct"); - - params = yield runSimulator(1); - - sid = params.args.indexOf("-screen"); - ok(params.args[sid + 1].includes(device.width + "x" + device.height), "Simulator screen resolution looks right"); - - // Test Simulator Menu. - is(doc.querySelector("#tv_simulator_menu").style.visibility, "hidden", "OpenTVDummyDirectory Button is not hidden"); - - // Restore default simulator options. - - doc.querySelector("#reset").click(); - // Wait for next tick to ensure UI elements are updated - yield nextTick(); - - for (let param in defaults.phone) { - is(form[param].value, String(defaults.phone[param]), "Default phone value for device " + param); - } - - // Install and configure the fake "Firefox OS 3.0 TV" simulator addon. - - let sim30tv = addons.simulators.filter(a => a.version == "3.0_tv")[0]; - - sim30tv.install(); - - updated = waitForUpdate(3); - yield addonStatus(sim30tv, "installed"); - yield updated; - // Wait for next tick to ensure UI elements are updated - yield nextTick(); - - is(findAll(".runtime-panel-item-simulator").length, 3, "Three simulators in runtime panel"); - - simulatorList.querySelectorAll(".configure-button")[2].click(); - // Wait for next tick to ensure UI elements are updated - yield nextTick(); - - for (let param in defaults.television) { - is(form[param].value, String(defaults.television[param]), "Default TV value for device " + param); - } - - // Test Simulator Menu - is(doc.querySelector("#tv_simulator_menu").style.visibility, "visible", "OpenTVDummyDirectory Button is not visible"); - - // Force reload the list of simulators. - - Simulators._loadingPromise = null; - Simulators._simulators = []; - yield Simulators._load(); - // Wait for next tick to ensure UI elements are updated - yield nextTick(); - - is(findAll(".runtime-panel-item-simulator").length, 3, "Three simulators saved and reloaded " + Simulators._simulators.map(s => s.name).join(',')); - - // Uninstall the 3.0 TV and 2.0 addons, and watch their Simulator objects disappear. - - sim30tv.uninstall(); - - yield addonStatus(sim30tv, "uninstalled"); - - is(findAll(".runtime-panel-item-simulator").length, 2, "Two simulators left in runtime panel"); - - sim20.uninstall(); - - yield addonStatus(sim20, "uninstalled"); - - is(findAll(".runtime-panel-item-simulator").length, 1, "One simulator left in runtime panel"); - - // Remove 1.0 simulator. - - simulatorList.querySelectorAll(".configure-button")[0].click(); - // Wait for next tick to ensure UI elements are updated - yield nextTick(); - - doc.querySelector("#remove").click(); - // Wait for next tick to ensure UI elements are updated - yield nextTick(); - - is(findAll(".runtime-panel-item-simulator").length, 0, "Last simulator was removed"); - - yield asyncStorage.removeItem("simulators"); - - sim10.uninstall(); - - MockFilePicker.cleanup(); - - doc.querySelector("#close").click(); - - ok(!win.document.querySelector("#deck").selectedPanel, "No panel selected"); - - yield closeWebIDE(win); - - SimpleTest.finish(); - - }); - } - - </script> - </body> -</html> diff --git a/devtools/client/webide/test/test_telemetry.html b/devtools/client/webide/test/test_telemetry.html deleted file mode 100644 index 225ddb89b..000000000 --- a/devtools/client/webide/test/test_telemetry.html +++ /dev/null @@ -1,325 +0,0 @@ -<!DOCTYPE html> - -<html> - - <head> - <meta charset="utf8"> - <title></title> - - <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script> - <script type="application/javascript;version=1.8" src="head.js"></script> - <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> - </head> - - <body> - - <script type="application/javascript;version=1.8"> - const Telemetry = require("devtools/client/shared/telemetry"); - const { _DeprecatedUSBRuntime, _WiFiRuntime, _SimulatorRuntime, - _gRemoteRuntime, _gLocalRuntime, RuntimeTypes } - = require("devtools/client/webide/modules/runtimes"); - - // Because we need to gather stats for the period of time that a tool has - // been opened we make use of setTimeout() to create tool active times. - const TOOL_DELAY = 200; - - function patchTelemetry() { - Telemetry.prototype.telemetryInfo = {}; - Telemetry.prototype._oldlog = Telemetry.prototype.log; - Telemetry.prototype.log = function(histogramId, value) { - if (histogramId) { - if (!this.telemetryInfo[histogramId]) { - this.telemetryInfo[histogramId] = []; - } - this.telemetryInfo[histogramId].push(value); - } - } - Telemetry.prototype._oldlogKeyed = Telemetry.prototype.logKeyed; - Telemetry.prototype.logKeyed = function(histogramId, key, value) { - // This simple reduction is enough to test WebIDE's usage - this.log(`${histogramId}|${key}`, value); - } - } - - function resetTelemetry() { - Telemetry.prototype.log = Telemetry.prototype._oldlog; - Telemetry.prototype.logKeyed = Telemetry.prototype._oldlogKeyed; - delete Telemetry.prototype._oldlog; - delete Telemetry.prototype._oldlogKeyed; - delete Telemetry.prototype.telemetryInfo; - } - - function cycleWebIDE() { - return Task.spawn(function*() { - let win = yield openWebIDE(); - // Wait a bit, so we're open for a non-zero time - yield waitForTime(TOOL_DELAY); - yield closeWebIDE(win); - }); - } - - function addFakeRuntimes(win) { - // We use the real runtimes here (and switch out some functionality) - // so we can ensure that logging happens as it would in real use. - - let usb = new _DeprecatedUSBRuntime("fakeUSB"); - // Use local pipe instead - usb.connect = function(connection) { - ok(connection, win.AppManager.connection, "connection is valid"); - connection.host = null; // force connectPipe - connection.connect(); - return promise.resolve(); - }; - win.AppManager.runtimeList.usb.push(usb); - - let wifi = new _WiFiRuntime("fakeWiFi"); - // Use local pipe instead - wifi.connect = function(connection) { - ok(connection, win.AppManager.connection, "connection is valid"); - connection.host = null; // force connectPipe - connection.connect(); - return promise.resolve(); - }; - win.AppManager.runtimeList.wifi.push(wifi); - - let sim = new _SimulatorRuntime({ id: "fakeSimulator" }); - // Use local pipe instead - sim.connect = function(connection) { - ok(connection, win.AppManager.connection, "connection is valid"); - connection.host = null; // force connectPipe - connection.connect(); - return promise.resolve(); - }; - Object.defineProperty(sim, "name", { - get() { - return this.version; - } - }); - win.AppManager.runtimeList.simulator.push(sim); - - let remote = _gRemoteRuntime; - // Use local pipe instead - remote.connect = function(connection) { - ok(connection, win.AppManager.connection, "connection is valid"); - connection.host = null; // force connectPipe - connection.connect(); - return promise.resolve(); - }; - let local = _gLocalRuntime; - - let other = Object.create(_gLocalRuntime); - other.type = RuntimeTypes.OTHER; - - win.AppManager.runtimeList.other = [remote, local, other]; - - win.AppManager.update("runtime-list"); - } - - function addTestApp(win) { - return Task.spawn(function*() { - let packagedAppLocation = getTestFilePath("../app"); - let winProject = getProjectWindow(win); - let onValidated = waitForUpdate(win, "project-validated"); - let onDetails = waitForUpdate(win, "details"); - yield winProject.projectList.importPackagedApp(packagedAppLocation); - yield onValidated; - yield onDetails; - }); - } - - function startConnection(win, docRuntime, type, index) { - let panelNode = docRuntime.querySelector("#runtime-panel"); - let items = panelNode.querySelectorAll(".runtime-panel-item-" + type); - if (index === undefined) { - is(items.length, 1, "Found one runtime button"); - } - - let deferred = promise.defer(); - win.AppManager.connection.once( - win.Connection.Events.CONNECTED, - () => deferred.resolve()); - - items[index || 0].click(); - - return deferred.promise; - } - - function waitUntilConnected(win) { - return Task.spawn(function*() { - ok(win.document.querySelector("window").className, "busy", "UI is busy"); - yield win.UI._busyPromise; - is(Object.keys(DebuggerServer._connections).length, 1, "Connected"); - // Logging runtime info needs to use the device actor - yield waitForUpdate(win, "runtime-global-actors"); - // Ensure detailed telemetry is recorded - yield waitForUpdate(win, "runtime-telemetry"); - }); - } - - function connectToRuntime(win, docRuntime, type, index) { - return Task.spawn(function*() { - startConnection(win, docRuntime, type, index); - yield waitUntilConnected(win); - }); - } - - function checkResults() { - let result = Telemetry.prototype.telemetryInfo; - for (let [histId, value] of Iterator(result)) { - if (histId === "DEVTOOLS_WEBIDE_IMPORT_PROJECT_BOOLEAN") { - ok(value.length === 1 && !!value[0], - histId + " has 1 successful entry"); - } else if (histId === - "DEVTOOLS_WEBIDE_PROJECT_EDITOR_OPENED_COUNT") { - ok(value.length === 1 && !!value[0], - histId + " has 1 successful entry"); - } else if (histId === "DEVTOOLS_WEBIDE_OPENED_COUNT") { - ok(value.length > 1, histId + " has more than one entry"); - - let okay = value.every(function(element) { - return !!element; - }); - - ok(okay, "All " + histId + " entries are true"); - } else if (histId.endsWith("WEBIDE_TIME_ACTIVE_SECONDS")) { - ok(value.length > 1, histId + " has more than one entry"); - - let okay = value.every(function(element) { - return element > 0; - }); - - ok(okay, "All " + histId + " entries have time > 0"); - } else if (histId.endsWith("EDITOR_TIME_ACTIVE_SECONDS")) { - ok(value.length === 1 && value[0] > 0, - histId + " has 1 entry with time > 0"); - } else if (histId === "DEVTOOLS_WEBIDE_CONNECTION_RESULT") { - ok(value.length === 6, histId + " has 6 connection results"); - - let okay = value.every(function(element) { - return !!element; - }); - - ok(okay, "All " + histId + " connections succeeded"); - } else if (histId.endsWith("CONNECTION_RESULT")) { - ok(value.length === 1 && !!value[0], - histId + " has 1 successful connection"); - } else if (histId === "DEVTOOLS_WEBIDE_CONNECTION_TIME_SECONDS") { - ok(value.length === 6, histId + " has 6 connection results"); - - let okay = value.every(function(element) { - return element > 0; - }); - - ok(okay, "All " + histId + " connections have time > 0"); - } else if (histId.endsWith("USED")) { - ok(value.length === 6, histId + " has 6 connection actions"); - - let okay = value.every(function(element) { - return !element; - }); - - ok(okay, "All " + histId + " actions were skipped"); - } else if (histId === "DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_TYPE|USB") { - is(value.length, 1, histId + " has 1 connection results"); - } else if (histId === "DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_TYPE|WIFI") { - is(value.length, 1, histId + " has 1 connection results"); - } else if (histId === "DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_TYPE|SIMULATOR") { - is(value.length, 1, histId + " has 1 connection results"); - } else if (histId === "DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_TYPE|REMOTE") { - is(value.length, 1, histId + " has 1 connection results"); - } else if (histId === "DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_TYPE|LOCAL") { - is(value.length, 1, histId + " has 1 connection results"); - } else if (histId === "DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_TYPE|OTHER") { - is(value.length, 1, histId + " has 1 connection results"); - } else if (histId === "DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_ID|fakeUSB") { - is(value.length, 1, histId + " has 1 connection results"); - } else if (histId === "DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_ID|fakeWiFi") { - is(value.length, 1, histId + " has 1 connection results"); - } else if (histId === "DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_ID|fakeSimulator") { - is(value.length, 1, histId + " has 1 connection results"); - } else if (histId === "DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_ID|unknown") { - is(value.length, 1, histId + " has 1 connection results"); - } else if (histId === "DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_ID|local") { - is(value.length, 2, histId + " has 2 connection results"); - } else if (histId.startsWith("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_PROCESSOR")) { - let processor = histId.split("|")[1]; - is(processor, Services.appinfo.XPCOMABI.split("-")[0], "Found runtime processor"); - is(value.length, 6, histId + " has 6 connection results"); - } else if (histId.startsWith("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_OS")) { - let os = histId.split("|")[1]; - is(os, Services.appinfo.OS, "Found runtime OS"); - is(value.length, 6, histId + " has 6 connection results"); - } else if (histId.startsWith("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_PLATFORM_VERSION")) { - let platformversion = histId.split("|")[1]; - is(platformversion, Services.appinfo.platformVersion, "Found runtime platform version"); - is(value.length, 6, histId + " has 6 connection results"); - } else if (histId.startsWith("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_APP_TYPE")) { - let apptype = histId.split("|")[1]; - is(apptype, "firefox", "Found runtime app type"); - is(value.length, 6, histId + " has 6 connection results"); - } else if (histId.startsWith("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_VERSION")) { - let version = histId.split("|")[1]; - is(version, Services.appinfo.version, "Found runtime version"); - is(value.length, 6, histId + " has 6 connection results"); - } else { - ok(false, "Unexpected " + histId + " was logged"); - } - } - } - - window.onload = function() { - SimpleTest.testInChaosMode(); - SimpleTest.waitForExplicitFinish(); - - let win; - - SimpleTest.registerCleanupFunction(() => { - return Task.spawn(function*() { - if (win) { - yield closeWebIDE(win); - } - DebuggerServer.destroy(); - yield removeAllProjects(); - resetTelemetry(); - }); - }); - - Task.spawn(function*() { - if (!DebuggerServer.initialized) { - DebuggerServer.init(); - DebuggerServer.addBrowserActors(); - } - - patchTelemetry(); - - // Cycle once, so we can test for multiple opens - yield cycleWebIDE(); - - win = yield openWebIDE(); - let docRuntime = getRuntimeDocument(win); - - // Wait a bit, so we're open for a non-zero time - yield waitForTime(TOOL_DELAY); - addFakeRuntimes(win); - yield addTestApp(win); - - // Each one should log a connection result and non-zero connection - // time - yield connectToRuntime(win, docRuntime, "usb"); - yield connectToRuntime(win, docRuntime, "wifi"); - yield connectToRuntime(win, docRuntime, "simulator"); - yield connectToRuntime(win, docRuntime, "other", 0 /* remote */); - yield connectToRuntime(win, docRuntime, "other", 1 /* local */); - yield connectToRuntime(win, docRuntime, "other", 2 /* other */); - yield closeWebIDE(win); - win = null; - - checkResults(); - - SimpleTest.finish(); - }); - } - </script> - </body> -</html> diff --git a/devtools/client/webide/test/test_toolbox.html b/devtools/client/webide/test/test_toolbox.html deleted file mode 100644 index 71ac2706c..000000000 --- a/devtools/client/webide/test/test_toolbox.html +++ /dev/null @@ -1,93 +0,0 @@ -<!DOCTYPE html> - -<html> - - <head> - <meta charset="utf8"> - <title></title> - - <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script> - <script type="application/javascript;version=1.8" src="head.js"></script> - <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> - </head> - - <body> - - <script type="application/javascript;version=1.8"> - window.onload = function() { - SimpleTest.waitForExplicitFinish(); - - let win; - - SimpleTest.registerCleanupFunction(() => { - Task.spawn(function*() { - if (win) { - yield closeWebIDE(win); - } - DebuggerServer.destroy(); - yield removeAllProjects(); - }); - }); - - Task.spawn(function*() { - if (!DebuggerServer.initialized) { - DebuggerServer.init(); - DebuggerServer.addBrowserActors(); - } - - win = yield openWebIDE(); - let docRuntime = getRuntimeDocument(win); - let docProject = getProjectDocument(win); - - win.AppManager.update("runtime-list"); - - let deferred = promise.defer(); - win.AppManager.connection.once( - win.Connection.Events.CONNECTED, - () => deferred.resolve()); - - docRuntime.querySelectorAll(".runtime-panel-item-other")[1].click(); - - ok(win.document.querySelector("window").className, "busy", "UI is busy"); - yield win.UI._busyPromise; - - is(Object.keys(DebuggerServer._connections).length, 1, "Connected"); - - yield waitForUpdate(win, "runtime-global-actors"); - - ok(win.AppManager.isMainProcessDebuggable(), "Main process available"); - - // Select main process - SimpleTest.executeSoon(() => { - docProject.querySelectorAll("#project-panel-runtimeapps .panel-item")[0].click(); - }); - - yield waitForUpdate(win, "project"); - - // Toolbox opens automatically for main process / runtime apps - ok(win.UI.toolboxPromise, "Toolbox promise exists"); - let toolbox = yield win.UI.toolboxPromise; - - yield toolbox.destroy(); - - ok(!win.UI.toolboxPromise, "Toolbox promise should be unset once toolbox.destroy()'s promise resolves"); - - // Reopen the toolbox right after to check races and also - // opening a toolbox more than just once against the same target - yield win.Cmds.toggleToolbox(); - - ok(win.UI.toolboxPromise, "Toolbox promise exists"); - - yield win.UI.destroyToolbox(); - - ok(!win.UI.toolboxPromise, "Toolbox promise is also nullified the second times"); - - yield win.Cmds.disconnectRuntime(); - - SimpleTest.finish(); - }); - } - </script> - </body> -</html> diff --git a/devtools/client/webide/test/test_zoom.html b/devtools/client/webide/test/test_zoom.html deleted file mode 100644 index 4ad3885d2..000000000 --- a/devtools/client/webide/test/test_zoom.html +++ /dev/null @@ -1,77 +0,0 @@ -<!DOCTYPE html> - -<html> - - <head> - <meta charset="utf8"> - <title></title> - - <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script> - <script type="application/javascript;version=1.8" src="head.js"></script> - <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> - </head> - - <body> - - <script type="application/javascript;version=1.8"> - window.onload = function() { - SimpleTest.waitForExplicitFinish(); - - Task.spawn(function* () { - let win = yield openWebIDE(); - let viewer = win.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShell) - .contentViewer; - - win.Cmds.zoomOut(); - win.Cmds.zoomOut(); - win.Cmds.zoomOut(); - win.Cmds.zoomOut(); - win.Cmds.zoomOut(); - win.Cmds.zoomOut(); - win.Cmds.zoomOut(); - - let roundZoom = Math.round(10 * viewer.fullZoom) / 10; - is(roundZoom, 0.6, "Reach min zoom"); - - win.Cmds.zoomIn(); - win.Cmds.zoomIn(); - win.Cmds.zoomIn(); - win.Cmds.zoomIn(); - win.Cmds.zoomIn(); - win.Cmds.zoomIn(); - win.Cmds.zoomIn(); - win.Cmds.zoomIn(); - win.Cmds.zoomIn(); - win.Cmds.zoomIn(); - win.Cmds.zoomIn(); - win.Cmds.zoomIn(); - - roundZoom = Math.round(10 * viewer.fullZoom) / 10; - is(roundZoom, 1.4, "Reach max zoom"); - - yield closeWebIDE(win); - - win = yield openWebIDE(); - viewer = win.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShell) - .contentViewer; - - roundZoom = Math.round(10 * viewer.fullZoom) / 10; - is(roundZoom, 1.4, "Zoom restored"); - - win.Cmds.resetZoom(); - - is(viewer.fullZoom, 1, "Zoom reset"); - - yield closeWebIDE(win); - - SimpleTest.finish(); - }); - } - </script> - </body> -</html> diff --git a/devtools/client/webide/test/validator/no-name-or-icon/home.html b/devtools/client/webide/test/validator/no-name-or-icon/home.html deleted file mode 100644 index e69de29bb..000000000 --- a/devtools/client/webide/test/validator/no-name-or-icon/home.html +++ /dev/null diff --git a/devtools/client/webide/test/validator/no-name-or-icon/manifest.webapp b/devtools/client/webide/test/validator/no-name-or-icon/manifest.webapp deleted file mode 100644 index 149e3fb79..000000000 --- a/devtools/client/webide/test/validator/no-name-or-icon/manifest.webapp +++ /dev/null @@ -1,3 +0,0 @@ -{ - "launch_path": "/home.html" -} diff --git a/devtools/client/webide/test/validator/non-absolute-path/manifest.webapp b/devtools/client/webide/test/validator/non-absolute-path/manifest.webapp deleted file mode 100644 index 64744067f..000000000 --- a/devtools/client/webide/test/validator/non-absolute-path/manifest.webapp +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "non-absolute path", - "icons": { - "128": "/icon.png" - }, - "launch_path": "non-absolute.html" -} diff --git a/devtools/client/webide/test/validator/valid/alsoValid/manifest.webapp b/devtools/client/webide/test/validator/valid/alsoValid/manifest.webapp deleted file mode 100644 index 20bd97bba..000000000 --- a/devtools/client/webide/test/validator/valid/alsoValid/manifest.webapp +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "valid at subfolder", - "launch_path": "/home.html", - "icons": { - "128": "/icon.png" - } -} diff --git a/devtools/client/webide/test/validator/valid/home.html b/devtools/client/webide/test/validator/valid/home.html deleted file mode 100644 index e69de29bb..000000000 --- a/devtools/client/webide/test/validator/valid/home.html +++ /dev/null diff --git a/devtools/client/webide/test/validator/valid/icon.png b/devtools/client/webide/test/validator/valid/icon.png deleted file mode 100644 index e69de29bb..000000000 --- a/devtools/client/webide/test/validator/valid/icon.png +++ /dev/null diff --git a/devtools/client/webide/test/validator/valid/manifest.webapp b/devtools/client/webide/test/validator/valid/manifest.webapp deleted file mode 100644 index 2c22a1567..000000000 --- a/devtools/client/webide/test/validator/valid/manifest.webapp +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "valid", - "launch_path": "/home.html", - "icons": { - "128": "/icon.png" - } -} diff --git a/devtools/client/webide/test/validator/wrong-launch-path/icon.png b/devtools/client/webide/test/validator/wrong-launch-path/icon.png deleted file mode 100644 index e69de29bb..000000000 --- a/devtools/client/webide/test/validator/wrong-launch-path/icon.png +++ /dev/null diff --git a/devtools/client/webide/test/validator/wrong-launch-path/manifest.webapp b/devtools/client/webide/test/validator/wrong-launch-path/manifest.webapp deleted file mode 100644 index 08057bae1..000000000 --- a/devtools/client/webide/test/validator/wrong-launch-path/manifest.webapp +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "valid", - "launch_path": "/wrong-path.html", - "icons": { - "128": "/icon.png" - } -} diff --git a/devtools/client/webide/themes/addons.css b/devtools/client/webide/themes/addons.css deleted file mode 100644 index 1ae41f2d9..000000000 --- a/devtools/client/webide/themes/addons.css +++ /dev/null @@ -1,79 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -button { - line-height: 20px; - font-size: 1em; - height: 30px; - max-height: 30px; - min-width: 120px; - padding: 3px; - color: #737980; - border: 1px solid rgba(23,50,77,.4); - border-radius: 5px; - background-color: #f1f1f1; - background-image: linear-gradient(#fff, rgba(255,255,255,.1)); - box-shadow: 0 1px 1px 0 #fff, inset 0 2px 2px 0 #fff; - text-shadow: 0 1px 1px #fefffe; - -moz-appearance: none; - -moz-border-top-colors: none !important; - -moz-border-right-colors: none !important; - -moz-border-bottom-colors: none !important; - -moz-border-left-colors: none !important; -} - -button:hover { - background-image: linear-gradient(#fff, rgba(255,255,255,.6)); - cursor: pointer; -} - -button:hover:active { - background-image: linear-gradient(rgba(255,255,255,.1), rgba(255,255,255,.6)); -} - -progress { - height: 30px; - vertical-align: middle; - padding: 0; - width: 120px; -} - -li { - margin: 20px 0; -} - -.name { - display: inline-block; - min-width: 280px; -} - -.status { - display: inline-block; - min-width: 120px; -} - -.warning { - color: #F06; - margin: 0; - font-size: 0.9em; -} - -li[status="unknown"], -li > .uninstall-button, -li > .install-button, -li > progress { - display: none; -} - -li[status="installed"] > .uninstall-button, -li[status="uninstalled"] > .install-button, -li[status="preparing"] > progress, -li[status="downloading"] > progress, -li[status="installing"] > progress { - display: inline; -} - -li:not([status="uninstalled"]) > .warning { - display: none; -} diff --git a/devtools/client/webide/themes/config-view.css b/devtools/client/webide/themes/config-view.css deleted file mode 100644 index 019e735df..000000000 --- a/devtools/client/webide/themes/config-view.css +++ /dev/null @@ -1,80 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -html, body { - background: white; -} - -.action { - display: inline; -} - -.action[hidden] { - display: none; -} - -#device-fields { - font-family: sans-serif; - padding-left: 6px; - width: 100%; - table-layout: auto; - margin-top: 110px; -} - -#custom-value-name { - width: 50%; -} - -header { - background-color: rgba(255, 255, 255, 0.8); - border-bottom: 1px solid #EEE; - position: fixed; - top: 0; - left: 0; - right: 0; - height: 90px; - padding: 10px 20px; -} - -#device-fields td { - background-color: #F9F9F9; - border-bottom: 1px solid #CCC; - border-right: 1px solid #FFF; - font-size: 0.75em; -} - -#device-fields td:first-child { - max-width: 250px; - min-width: 150px; -} - -#device-fields td.preference-name, #device-fields td.setting-name { - width: 50%; - min-width: 400px; - word-break: break-all; -} - -#device-fields button { - display: inline-block; - font-family: sans-serif; - font-size: 0.7rem; - white-space: nowrap; -} - -#device-fields tr.hide, #device-fields button.hide { - display: none; -} - -#device-fields .custom-input { - width: 130px; -} - -#search { - margin-bottom: 20px; - width: 100%; -} - -#search-bar { - width: 80%; -} diff --git a/devtools/client/webide/themes/deck.css b/devtools/client/webide/themes/deck.css deleted file mode 100644 index 30537f612..000000000 --- a/devtools/client/webide/themes/deck.css +++ /dev/null @@ -1,91 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -html { - font: message-box; - font-size: 0.9em; - font-weight: normal; - margin: 0; - height: 100%; - color: #737980; - background-color: #ededed; -} - -body { - margin: 0; - padding: 20px; - background-image: linear-gradient(#fff, #ededed 100px); -} - -.text-input { - display: flex; -} - -.text-input input { - flex: 0.5; - margin-left: 5px; -} - -h1 { - font-size: 2em; - font-weight: lighter; - line-height: 1.2; - margin: 0; - margin-bottom: .5em; -} - -#controls { - float: right; - position: relative; - top: -10px; - right: -10px; -} - -#controls > a { - color: #4C9ED9; - font-size: small; - cursor: pointer; - border-bottom: 1px dotted; - margin-left: 10px; -} - -table { - font-family: monospace; - border-collapse: collapse; -} - -th, td { - padding: 5px; - border: 1px solid #eee; -} - -th { - min-width: 100px; -} - -th:first-of-type, td:first-of-type { - text-align: left; -} - -li { - list-style: none; - padding: 2px; -} - -li > label:hover { - background-color: rgba(0,0,0,0.02); -} - -li > label > span { - display: inline-block; -} - -input, select { - box-sizing: border-box; -} - -select { - padding-top: 2px; - padding-bottom: 2px; -} diff --git a/devtools/client/webide/themes/default-app-icon.png b/devtools/client/webide/themes/default-app-icon.png Binary files differdeleted file mode 100644 index f186d9c62..000000000 --- a/devtools/client/webide/themes/default-app-icon.png +++ /dev/null diff --git a/devtools/client/webide/themes/details.css b/devtools/client/webide/themes/details.css deleted file mode 100644 index dc73d5357..000000000 --- a/devtools/client/webide/themes/details.css +++ /dev/null @@ -1,138 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -body { - margin: 0; - background-color: white; - font: message-box; -} - -.hidden { - display: none; -} - -h1, h3, p { - margin: 0; -} - -#toolbar { - background-color: #D8D8D8; - border-bottom: 1px solid #AAA; -} - -#toolbar > button { - -moz-appearance: none; - background-color: transparent; - border-width: 0 1px 0 0; - border-color: #AAA; - border-style: solid; - margin: 0; - padding: 0 12px; - font-family: inherit; - font-weight: bold; - height: 24px; -} - -#toolbar > button:hover { - background-color: #CCC; - cursor: pointer; -} - -#validation_status { - float: right; - text-transform: uppercase; - font-size: 10px; - line-height: 24px; - padding: 0 12px; - color: white; -} - - -header { - padding: 20px 0; -} - -header > div { - vertical-align: top; - display: flex; - flex-direction: column; -} - -#icon { - height: 48px; - width: 48px; - float: left; - margin: 0 20px; -} - -h1, #type { - line-height: 24px; - height: 24px; /* avoid collapsing if empty */ - display: block; -} - -h1 { - font-size: 20px; - overflow-x: hidden; - white-space: nowrap; - text-overflow: ellipsis; -} - -#type { - font-size: 10px; - text-transform: uppercase; - color: #777; -} - -main { - padding-left: 88px; -} - -h3 { - color: #999; - font-size: 10px; - font-weight: normal; -} - -main > p { - margin-bottom: 20px; -} - -.validation_messages { - margin-left: 74px; - list-style: none; - border-left: 4px solid transparent; - padding: 0 10px;; -} - - -body.valid #validation_status { - background-color: #81D135; -} - -body.warning #validation_status { - background-color: #FFAC00; -} - -body.error #validation_status { - background-color: #ED4C62; -} - -#warningslist { - border-color: #FFAC00 -} - -#errorslist { - border-color: #ED4C62; -} - -#validation_status > span { - display: none; -} - -body.valid #validation_status > .valid, -body.warning #validation_status > .warning, -body.error #validation_status > .error { - display: inline; -} diff --git a/devtools/client/webide/themes/icons.png b/devtools/client/webide/themes/icons.png Binary files differdeleted file mode 100644 index 5e1dd5c64..000000000 --- a/devtools/client/webide/themes/icons.png +++ /dev/null diff --git a/devtools/client/webide/themes/jar.mn b/devtools/client/webide/themes/jar.mn deleted file mode 100644 index 4235278da..000000000 --- a/devtools/client/webide/themes/jar.mn +++ /dev/null @@ -1,24 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -webide.jar: -% skin webide classic/1.0 %skin/ -* skin/webide.css (webide.css) - skin/icons.png (icons.png) - skin/details.css (details.css) - skin/newapp.css (newapp.css) - skin/throbber.svg (throbber.svg) - skin/deck.css (deck.css) - skin/addons.css (addons.css) - skin/runtimedetails.css (runtimedetails.css) - skin/permissionstable.css (permissionstable.css) - skin/monitor.css (monitor.css) - skin/config-view.css (config-view.css) - skin/wifi-auth.css (wifi-auth.css) - skin/logs.css (logs.css) - skin/panel-listing.css (panel-listing.css) - skin/simulator.css (simulator.css) - skin/rocket.svg (rocket.svg) - skin/noise.png (noise.png) - skin/default-app-icon.png (default-app-icon.png) diff --git a/devtools/client/webide/themes/logs.css b/devtools/client/webide/themes/logs.css deleted file mode 100644 index 446b6e41c..000000000 --- a/devtools/client/webide/themes/logs.css +++ /dev/null @@ -1,18 +0,0 @@ -html, body { - background: var(--theme-body-background); - color: var(--theme-body-color); -} - -h1 { - font-size: 1.2em; -} - -ul { - padding: 0; - font-size: 1em; -} - -li { - list-style: none; - margin: 0; -} diff --git a/devtools/client/webide/themes/monitor.css b/devtools/client/webide/themes/monitor.css deleted file mode 100644 index ba4b298ed..000000000 --- a/devtools/client/webide/themes/monitor.css +++ /dev/null @@ -1,86 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Graph */ -.graph { - height: 500px; - width: 100%; - padding-top: 20px; - padding-bottom: 20px; - margin-bottom: 30px; - background-color: white; -} -.graph > svg, .sidebar { - display: inline-block; - vertical-align: top; -} -.disabled { - opacity: 0.5; -} -.graph.disabled { - height: 30px; -} -.graph.disabled > svg { - visibility: hidden; -} -.curve path, .event-slot line { - fill: none; - stroke-width: 1.5px; -} -.axis line { - fill: none; - stroke: #000; - shape-rendering: crispEdges; -} -.axis path { - fill: none; - stroke: black; - stroke-width: 1px; - shape-rendering: crispEdges; -} -.tick text, .x.ruler text, .y.ruler text { - font-size: 0.9em; -} -.x.ruler text { - text-anchor: middle; -} -.y.ruler text { - text-anchor: end; -} - -/* Sidebar */ -.sidebar { - width: 150px; - overflow-x: hidden; -} -.sidebar label { - cursor: pointer; - display: block; -} -.sidebar span:not(.color) { - vertical-align: 13%; -} -.sidebar input { - visibility: hidden; -} -.sidebar input:hover { - visibility: visible; -} -.graph-title { - margin-top: 5px; - font-size: 1.2em; -} -.legend-color { - display: inline-block; - height: 10px; - width: 10px; - margin-left: 1px; - margin-right: 3px; -} -.legend-id { - font-size: .9em; -} -.graph.disabled > .sidebar > .legend { - display: none; -} diff --git a/devtools/client/webide/themes/moz.build b/devtools/client/webide/themes/moz.build deleted file mode 100644 index aac3a838c..000000000 --- a/devtools/client/webide/themes/moz.build +++ /dev/null @@ -1,7 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -JAR_MANIFESTS += ['jar.mn'] diff --git a/devtools/client/webide/themes/newapp.css b/devtools/client/webide/themes/newapp.css deleted file mode 100644 index 0b351a40a..000000000 --- a/devtools/client/webide/themes/newapp.css +++ /dev/null @@ -1,54 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -dialog { - -moz-appearance: none; - background-image: linear-gradient(rgb(255, 255, 255), rgb(237, 237, 237) 100px); - font-family: "Clear Sans", sans-serif; - color: #424E5A; - overflow-y: scroll; -} - -.header-name { - font-size: 1.5rem; - font-weight: normal; - margin: 15px 0; -} - -richlistbox { - -moz-appearance: none; - overflow-y: auto; - border: 1px solid #424E5A; -} - -richlistitem { - padding: 6px 0; -} - -richlistitem:not([selected="true"]):hover { - background-color: rgba(0,0,0,0.04); -} - -richlistitem > vbox > label { - margin: 0; - font-size: 1.1em; -} - -richlistbox > description { - margin: 8px; -} - -richlistitem { - -moz-box-align: start; -} - -richlistitem > image { - height: 24px; - width: 24px; - margin: 0 6px; -} - -textbox { - font-size: 1.2rem; -} diff --git a/devtools/client/webide/themes/noise.png b/devtools/client/webide/themes/noise.png Binary files differdeleted file mode 100644 index b3c42acae..000000000 --- a/devtools/client/webide/themes/noise.png +++ /dev/null diff --git a/devtools/client/webide/themes/panel-listing.css b/devtools/client/webide/themes/panel-listing.css deleted file mode 100644 index 06e51211c..000000000 --- a/devtools/client/webide/themes/panel-listing.css +++ /dev/null @@ -1,150 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -html { - font: message-box; - font-size: 11px; - font-weight: 400; -} - -label, -.panel-item, -#project-panel-projects, -#runtime-panel-projects { - display: block; - float: left; - width: 100%; - text-align: left; -} - -.project-image, -.panel-item span { - display: inline-block; - float: left; - line-height: 20px; -} - -.project-image { - margin-right: 10px; - max-height: 20px; -} - -.panel-header { - color: #ACACAC; - text-transform: uppercase; - line-height: 200%; - margin: 5px 5px 0 5px; - font-weight: 700; - width: 100%; -} - -.panel-header:first-child { - margin-top: 0; -} - -.panel-header[hidden], .panel-item[hidden] { - display: none; -} - -#runtime-panel-simulator, -.panel-item-complex { - clear: both; - position: relative; -} - -.panel-item span { - display: block; - float: left; - overflow: hidden; - text-overflow: ellipsis; - width: 75%; - white-space: nowrap; -} - -.panel-item { - -moz-appearance: none; - -moz-box-align: center; - padding: 3%; - display: block; - width: 94%; - cursor: pointer; - border-top: 1px solid transparent; - border-left: 0; - border-bottom: 1px solid #CCC; - border-right: 0; - background-color: transparent; -} - -button.panel-item { - background-position: 5px 5px; - background-repeat: no-repeat; - background-size: 14px 14px; - padding-left: 25px; - width: 100%; -} - -.panel-item:disabled { - background-color: #FFF; - color: #5A5A5A; - opacity: 0.5; - cursor: default; -} - -.refresh-icon { - background-image: url("chrome://devtools/skin/images/reload.svg"); - height: 14px; - width: 14px; - border: 0; - opacity: 0.6; - display: inline-block; - margin: 3px; - float: right; -} - -.panel-item:not(:disabled):hover, -button.panel-item:not(:disabled):hover { - background-color: #CCF0FD; - border-top: 1px solid #EDEDED; -} - -.configure-button { - display: inline-block; - height: 30px; - width: 30px; - background-color: transparent; - background-image: -moz-image-rect(url("icons.png"), 104, 462, 129, 438); - background-position: center center; - background-repeat: no-repeat; - background-size: 14px 14px; - position: absolute; - top: -2px; - right: 0; - border: 0; -} - -.configure-button:hover { - cursor: pointer; -} - -.project-panel-item-openpackaged { background-image: -moz-image-rect(url("icons.png"), 260, 438, 286, 412); } -.runtime-panel-item-simulator { background-image: -moz-image-rect(url("icons.png"), 0, 438, 26, 412); } -.runtime-panel-item-other { background-image: -moz-image-rect(url("icons.png"), 26, 438, 52, 412); } -#runtime-permissions { background-image: -moz-image-rect(url("icons.png"), 105, 438, 131, 412); } -#runtime-screenshot { background-image: -moz-image-rect(url("icons.png"), 131, 438, 156, 412); } - -#runtime-preferences, -#runtime-settings { background-image: -moz-image-rect(url("icons.png"), 105, 464, 131, 438); } - -#runtime-panel-nousbdevice, -#runtime-details { background-image: -moz-image-rect(url("icons.png"), 156, 438, 182, 412); } - -.runtime-panel-item-usb, -#runtime-disconnect { background-image: -moz-image-rect(url("icons.png"), 52, 438, 78, 412); } - -.runtime-panel-item-wifi, -.project-panel-item-openhosted { background-image: -moz-image-rect(url("icons.png"), 208, 438, 234, 412); } - -.project-panel-item-newapp, -#runtime-panel-noadbhelper, -#runtime-panel-installsimulator { background-image: -moz-image-rect(url("icons.png"), 234, 438, 260, 412); } diff --git a/devtools/client/webide/themes/permissionstable.css b/devtools/client/webide/themes/permissionstable.css deleted file mode 100644 index 3a45e0d74..000000000 --- a/devtools/client/webide/themes/permissionstable.css +++ /dev/null @@ -1,23 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -html, body { - background: white; -} - -.permissionstable td { - text-align: center; -} - -.permallow { - color: rgb(152,207,57); -} - -.permprompt { - color: rgb(0,158,237); -} - -.permdeny { - color: rgb(204,73,8); -} diff --git a/devtools/client/webide/themes/rocket.svg b/devtools/client/webide/themes/rocket.svg deleted file mode 100644 index a0cca5c21..000000000 --- a/devtools/client/webide/themes/rocket.svg +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> -<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24"> - <g opacity="0.1"> - <path fill="#fff" d="M12,2.3c-1.127,0-3.333,3.721-4.084,7.411l-2.535,2.535v6.619l1.767,0l2.464-2.464 c0.252,0.264,0.529,0.486,0.827,0.662h3.118c0.299-0.175,0.579-0.397,0.831-0.662l2.464,2.464l1.767,0v-6.619l-2.535-2.535 C15.333,6.021,13.127,2.3,12,2.3z M12.003,6.181c0.393,0,1.084,1.103,1.515,2.423c-0.466-0.087-0.963-0.135-1.481-0.135 c-0.545,0-1.066,0.054-1.553,0.15C10.914,7.292,11.608,6.181,12.003,6.181z"/> - <path fill="#fff" d="M12.792,18.755c0,0.778-0.603,1.408-0.805,1.408c-0.201,0-0.805-0.631-0.805-1.408 c0-0.301,0.055-0.579,0.147-0.809h-0.932c-0.109,0.403-0.171,0.854-0.171,1.33c0,1.714,1.33,3.104,1.774,3.104 s1.774-1.389,1.774-3.103c0-0.477-0.062-0.927-0.171-1.331l-0.957,0C12.738,18.175,12.792,18.453,12.792,18.755z"/> - <path fill="#414042" d="M12,2c-1.127,0-3.333,3.721-4.084,7.411l-2.535,2.535v6.619l1.767,0l2.464-2.464 c0.252,0.264,0.529,0.486,0.827,0.662h3.118c0.299-0.175,0.579-0.397,0.831-0.662l2.464,2.464l1.767,0v-6.619l-2.535-2.535 C15.333,5.721,13.127,2,12,2z M12.003,5.881c0.393,0,1.084,1.103,1.515,2.423c-0.466-0.087-0.963-0.135-1.481-0.135 c-0.545,0-1.066,0.054-1.553,0.15C10.914,6.992,11.608,5.881,12.003,5.881z"/> - <path fill="#414042" d="M12.792,18.455c0,0.778-0.603,1.408-0.805,1.408c-0.201,0-0.805-0.631-0.805-1.408 c0-0.301,0.055-0.579,0.147-0.809h-0.932c-0.109,0.403-0.171,0.854-0.171,1.33c0,1.714,1.33,3.104,1.774,3.104 s1.774-1.389,1.774-3.103c0-0.477-0.062-0.927-0.171-1.331l-0.957,0C12.738,17.875,12.792,18.153,12.792,18.455z"/> - </g> -</svg> diff --git a/devtools/client/webide/themes/runtimedetails.css b/devtools/client/webide/themes/runtimedetails.css deleted file mode 100644 index 91ced5bff..000000000 --- a/devtools/client/webide/themes/runtimedetails.css +++ /dev/null @@ -1,25 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -html, body { - background: white; -} - -#devicePrivileges { - font-family: monospace; - padding-left: 6px; -} - -#devtools-check > a { - color: #4C9ED9; - cursor: pointer; -} - -.action { - display: inline; -} - -.action[hidden] { - display: none; -} diff --git a/devtools/client/webide/themes/simulator.css b/devtools/client/webide/themes/simulator.css deleted file mode 100644 index 036cfcdb4..000000000 --- a/devtools/client/webide/themes/simulator.css +++ /dev/null @@ -1,41 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -select:not(.custom) > option[value="custom"] { - display: none; -} - -select, input[type="text"] { - width: 13rem; -} - -input[name="name"] { - height: 1.8rem; -} - -input[type="number"] { - width: 6rem; -} - -input[type="text"], input[type="number"] { - padding-left: 0.2rem; -} - -li > label:hover { - background-color: transparent; -} - -ul { - padding-left: 0; -} - -.label { - width: 6rem; - padding: 0.2rem; - text-align: right; -} - -.hidden { - display: none; -} diff --git a/devtools/client/webide/themes/throbber.svg b/devtools/client/webide/themes/throbber.svg deleted file mode 100644 index d89fb3851..000000000 --- a/devtools/client/webide/themes/throbber.svg +++ /dev/null @@ -1,22 +0,0 @@ -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<svg xmlns="http://www.w3.org/2000/svg" - width="24" height="24" viewBox="0 0 64 64"> - <g> - <rect x="30" y="4" width="4" height="15" transform="rotate(0, 32, 32)" fill="#BBB"/> - <rect x="30" y="4" width="4" height="15" transform="rotate(30, 32, 32)" fill="#AAA"/> - <rect x="30" y="4" width="4" height="15" transform="rotate(60, 32, 32)" fill="#999"/> - <rect x="30" y="4" width="4" height="15" transform="rotate(90, 32, 32)" fill="#888"/> - <rect x="30" y="4" width="4" height="15" transform="rotate(120, 32, 32)" fill="#777"/> - <rect x="30" y="4" width="4" height="15" transform="rotate(150, 32, 32)" fill="#666"/> - <rect x="30" y="4" width="4" height="15" transform="rotate(180, 32, 32)" fill="#555"/> - <rect x="30" y="4" width="4" height="15" transform="rotate(210, 32, 32)" fill="#444"/> - <rect x="30" y="4" width="4" height="15" transform="rotate(240, 32, 32)" fill="#333"/> - <rect x="30" y="4" width="4" height="15" transform="rotate(270, 32, 32)" fill="#222"/> - <rect x="30" y="4" width="4" height="15" transform="rotate(300, 32, 32)" fill="#111"/> - <rect x="30" y="4" width="4" height="15" transform="rotate(330, 32, 32)" fill="#000"/> - <animateTransform attributeName="transform" type="rotate" calcMode="discrete" values="0 32 32;30 32 32;60 32 32;90 32 32;120 32 32;150 32 32;180 32 32;210 32 32;240 32 32;270 32 32;300 32 32;330 32 32" dur="0.8s" repeatCount="indefinite"/> - </g> -</svg> diff --git a/devtools/client/webide/themes/webide.css b/devtools/client/webide/themes/webide.css deleted file mode 100644 index 0dea91a5f..000000000 --- a/devtools/client/webide/themes/webide.css +++ /dev/null @@ -1,149 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * - * Icons.png: - * - * actions icons: 100x100. Starts at 0x0. - * menu icons: 26x26. Starts at 312x0. - * anchors icons: 27x16. Starts at 364x0. - * - */ - -#main-toolbar { - padding: 0 12px; -} - -#action-buttons-container { - -moz-box-pack: center; - height: 50px; -} - -#panel-buttons-container { - height: 50px; - margin-top: -50px; - pointer-events: none; -} - -#panel-buttons-container > .panel-button { - pointer-events: auto; -} - -#action-busy-undetermined { - height: 24px; - width: 24px; -} - -window.busy .action-button, -window:not(.busy) #action-busy, -window.busy-undetermined #action-busy-determined, -window.busy-determined #action-busy-undetermined { - display: none; -} - -/* Panel buttons - runtime */ - -#runtime-panel-button > .panel-button-image { - list-style-image: url('icons.png'); - -moz-image-region: rect(78px,438px,104px,412px); - width: 13px; - height: 13px; -} - -#runtime-panel-button[active="true"] > .panel-button-image { - -moz-image-region: rect(78px,464px,104px,438px); -} - -/* Action buttons */ - -.action-button { - -moz-appearance: none; - border-width: 0; - margin: 0; - padding: 0; - list-style-image: url('icons.png'); -} - -.action-button[disabled="true"] { - opacity: 0.4; -} - -.action-button > .toolbarbutton-icon { - width: 40px; - height: 40px; -} - -.action-button > .toolbarbutton-text { - display: none; -} - -#action-button-play { -moz-image-region: rect(0,100px,100px,0) } -#action-button-stop { -moz-image-region: rect(0,200px,100px,100px) } -#action-button-debug { -moz-image-region: rect(0,300px,100px,200px) } - -#action-button-play:not([disabled="true"]):hover { -moz-image-region: rect(200px,100px,300px,0) } -#action-button-stop:not([disabled="true"]):hover { -moz-image-region: rect(200px,200px,300px,100px) } -#action-button-debug:not([disabled="true"]):not([active="true"]):hover { -moz-image-region: rect(200px,300px,300px,200px) } - -#action-button-play.reload { -moz-image-region: rect(0,400px,100px,303px) } -#action-button-play.reload:hover { -moz-image-region: rect(200px,400px,300px,303px) } - -#action-button-debug[active="true"] { -moz-image-region: rect(100px,300px,200px,200px) } - -/* Panels */ - -.panel-list { - display: none; - position: relative; - max-width: 190px; - overflow: hidden; -} - -#project-listing-panel { - max-width: 165px; -} - -.panel-list-wrapper { - height: 100%; - width: 100%; - min-width: 100px; - position: absolute; - top: 0; - bottom: 0; - right: 0; - left: 0; -} - -.panel-list-wrapper > iframe { - height: inherit; - width: 100%; - position: absolute; - top: 0; - bottom: 0; - right: 0; - left: 0; -} - -[sidebar-displayed] { - display: block; -} - -/* Main view */ - -#deck { - background-color: rgb(225, 225, 225); - background-image: url('rocket.svg'), url('noise.png'); - background-repeat: no-repeat, repeat; - background-size: 35%, auto; - background-position: center center, top left; -%ifndef XP_MACOSX - border-top: 1px solid #AAA; -%endif -} - -.devtools-horizontal-splitter { - position: relative; - border-bottom: 1px solid #aaa; -} diff --git a/devtools/client/webide/themes/wifi-auth.css b/devtools/client/webide/themes/wifi-auth.css deleted file mode 100644 index de6afc94e..000000000 --- a/devtools/client/webide/themes/wifi-auth.css +++ /dev/null @@ -1,64 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -html, body { - background: white; -} - -body { - display: flex; - flex-direction: column; - height: 90%; -} - -div { - margin-bottom: 1em; -} - -#qr-code { - flex: 1; - display: flex; - flex-direction: column; - align-items: center; -} - -#qr-code-wrapper { - flex: 1; - width: 100%; - margin: 2em 0; - text-align: center; -} - -#qr-code img { - height: 100%; -} - -.toggle-scanner { - color: #4C9ED9; - font-size: small; - cursor: pointer; - border-bottom: 1px dotted; -} - -#token { - display: none; -} - -body[token] > #token { - display: flex; - flex-direction: column; -} - -body[token] > #qr-code { - display: none; -} - -#token pre, -#token a { - align-self: center; -} - -#qr-size-note { - text-align: center -} diff --git a/devtools/client/webide/webide-prefs.js b/devtools/client/webide/webide-prefs.js deleted file mode 100644 index 94871171d..000000000 --- a/devtools/client/webide/webide-prefs.js +++ /dev/null @@ -1,35 +0,0 @@ -# -*- indent-tabs-mode: nil; js-indent-level: 2 -*- -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -pref("devtools.webide.showProjectEditor", true); -pref("devtools.webide.templatesURL", "https://code.cdn.mozilla.net/templates/list.json"); -pref("devtools.webide.autoinstallADBHelper", true); -pref("devtools.webide.autoinstallFxdtAdapters", true); -pref("devtools.webide.autoConnectRuntime", true); -pref("devtools.webide.restoreLastProject", true); -pref("devtools.webide.enableLocalRuntime", false); -pref("devtools.webide.addonsURL", "https://ftp.mozilla.org/pub/mozilla.org/labs/fxos-simulator/index.json"); -pref("devtools.webide.simulatorAddonsURL", "https://ftp.mozilla.org/pub/mozilla.org/labs/fxos-simulator/#VERSION#/#OS#/fxos_#SLASHED_VERSION#_simulator-#OS#-latest.xpi"); -pref("devtools.webide.simulatorAddonID", "fxos_#SLASHED_VERSION#_simulator@mozilla.org"); -pref("devtools.webide.simulatorAddonRegExp", "fxos_(.*)_simulator@mozilla\\.org$"); -pref("devtools.webide.adbAddonURL", "https://ftp.mozilla.org/pub/mozilla.org/labs/fxos-simulator/adb-helper/#OS#/adbhelper-#OS#-latest.xpi"); -pref("devtools.webide.adbAddonID", "adbhelper@mozilla.org"); -pref("devtools.webide.adaptersAddonURL", "https://ftp.mozilla.org/pub/mozilla.org/labs/valence/#OS#/valence-#OS#-latest.xpi"); -pref("devtools.webide.adaptersAddonID", "fxdevtools-adapters@mozilla.org"); -pref("devtools.webide.monitorWebSocketURL", "ws://localhost:9000"); -pref("devtools.webide.lastConnectedRuntime", ""); -pref("devtools.webide.lastSelectedProject", ""); -pref("devtools.webide.logSimulatorOutput", false); -pref("devtools.webide.widget.autoinstall", true); -#ifdef MOZ_DEV_EDITION -pref("devtools.webide.widget.enabled", true); -pref("devtools.webide.widget.inNavbarByDefault", true); -#else -pref("devtools.webide.widget.enabled", false); -pref("devtools.webide.widget.inNavbarByDefault", false); -#endif -pref("devtools.webide.zoom", "1"); -pref("devtools.webide.busyTimeout", 10000); -pref("devtools.webide.autosaveFiles", true); diff --git a/devtools/server/actors/webconsole.js b/devtools/server/actors/webconsole.js index a1eba84ed..66715bd34 100644 --- a/devtools/server/actors/webconsole.js +++ b/devtools/server/actors/webconsole.js @@ -888,7 +888,8 @@ WebConsoleActor.prototype = let evalResult = evalInfo.result; let helperResult = evalInfo.helperResult; - let result, errorDocURL, errorMessage, errorGrip = null, frame = null; + let result, errorDocURL, errorMessage, errorNotes = null, errorGrip = null, + frame = null; if (evalResult) { if ("return" in evalResult) { result = evalResult.return; @@ -943,6 +944,23 @@ WebConsoleActor.prototype = }; } } catch (ex) {} + + try { + let notes = error.errorNotes; + if (notes && notes.length) { + errorNotes = []; + for (let note of notes) { + errorNotes.push({ + messageBody: this._createStringGrip(note.message), + frame: { + source: note.fileName, + line: note.lineNumber, + column: note.columnNumber, + } + }); + } + } + } catch (ex) {} } } @@ -967,6 +985,7 @@ WebConsoleActor.prototype = exceptionDocURL: errorDocURL, frame, helperResult: helperResult, + notes: errorNotes, }; }, @@ -1500,6 +1519,23 @@ WebConsoleActor.prototype = lineText = lineText.substr(0, DebuggerServer.LONG_STRING_INITIAL_LENGTH); } + let notesArray = null; + let notes = aPageError.notes; + if (notes && notes.length) { + notesArray = []; + for (let i = 0, len = notes.length; i < len; i++) { + let note = notes.queryElementAt(i, Ci.nsIScriptErrorNote); + notesArray.push({ + messageBody: this._createStringGrip(note.errorMessage), + frame: { + source: note.sourceName, + line: note.lineNumber, + column: note.columnNumber, + } + }); + } + } + return { errorMessage: this._createStringGrip(aPageError.errorMessage), errorMessageName: aPageError.errorMessageName, @@ -1516,7 +1552,8 @@ WebConsoleActor.prototype = strict: !!(aPageError.flags & aPageError.strictFlag), info: !!(aPageError.flags & aPageError.infoFlag), private: aPageError.isFromPrivateWindow, - stacktrace: stack + stacktrace: stack, + notes: notesArray, }; }, diff --git a/devtools/shared/webconsole/test/test_page_errors.html b/devtools/shared/webconsole/test/test_page_errors.html index 78138856e..b4c0fe885 100644 --- a/devtools/shared/webconsole/test/test_page_errors.html +++ b/devtools/shared/webconsole/test/test_page_errors.html @@ -112,6 +112,24 @@ function doPageErrors() warning: true, exception: false, }, + "let a, a;": { + errorMessage: /redeclaration of/, + errorMessageName: "JSMSG_REDECLARED_VAR", + sourceName: /test_page_errors/, + category: "chrome javascript", + timeStamp: /^\d+$/, + error: false, + warning: false, + exception: true, + notes: [ + { + messageBody: /Previously declared at line/, + frame: { + source: /test_page_errors/, + } + } + ] + }, }; let container = document.createElement("script"); |