Bug 817537 - Connection screen polish. r=vporof
authorPaul Rouget <paul@mozilla.com>
Tue, 18 Dec 2012 08:54:00 +0100
changeset 116640 59e6f831b60bf9f6df599850c3d23028e16a0c4c
parent 116639 6b168eb45722e7082cbbdba612674abf2e615181
child 116641 bb4bce1a33484a42cd062faa2cfed50967f6bc84
push idunknown
push userunknown
push dateunknown
reviewersvporof
bugs817537
milestone20.0a1
Bug 817537 - Connection screen polish. r=vporof
browser/base/content/browser-appmenu.inc
browser/base/content/browser-menubar.inc
browser/base/content/browser-sets.inc
browser/base/content/browser.js
browser/devtools/framework/connect/connect.css
browser/devtools/framework/connect/connect.js
browser/devtools/framework/connect/connect.xhtml
browser/locales/en-US/chrome/browser/devtools/connection-screen.dtd
browser/locales/en-US/chrome/browser/devtools/connection-screen.properties
browser/locales/jar.mn
browser/themes/gnomestripe/devtools/common.css
browser/themes/pinstripe/devtools/common.css
browser/themes/winstripe/devtools/common.css
--- a/browser/base/content/browser-appmenu.inc
+++ b/browser/base/content/browser-appmenu.inc
@@ -160,17 +160,16 @@
           <menuitem id="appmenu_responsiveUI"
                     observes="devtoolsMenuBroadcaster_ResponsiveUI"/>
           <menuitem id="appmenu_scratchpad"
                     observes="devtoolsMenuBroadcaster_Scratchpad"/>
           <menuitem id="appmenu_pageSource"
                     observes="devtoolsMenuBroadcaster_PageSource"/>
           <menuitem id="appmenu_errorConsole"
                     observes="devtoolsMenuBroadcaster_ErrorConsole"/>
-          <menuseparator id="appmenu_devToolsConnectSeparator"/>
           <menuitem id="appmenu_devtools_connect"
                     observes="devtoolsMenuBroadcaster_connect"/>
           <menuseparator id="appmenu_devToolsEndSeparator"/>
           <menuitem id="appmenu_getMoreDevtools"
                     observes="devtoolsMenuBroadcaster_GetMoreTools"/>
           <menuseparator/>
 #define ID_PREFIX appmenu_developer_
 #define OMIT_ACCESSKEYS
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -579,17 +579,16 @@
                             observes="devtoolsMenuBroadcaster_Scratchpad"
                             accesskey="&scratchpad.accesskey;"/>
                   <menuitem id="menu_pageSource"
                             observes="devtoolsMenuBroadcaster_PageSource"
                             accesskey="&pageSourceCmd.accesskey;"/>
                   <menuitem id="javascriptConsole"
                             observes="devtoolsMenuBroadcaster_ErrorConsole"
                             accesskey="&errorConsoleCmd.accesskey;"/>
-                  <menuseparator id="menu_devToolsConnectSeparator"/>
                   <menuitem id="menu_devtools_connect"
                             observes="devtoolsMenuBroadcaster_connect"/>
                   <menuseparator id="devToolsEndSeparator"/>
                   <menuitem id="getMoreDevtools"
                             observes="devtoolsMenuBroadcaster_GetMoreTools"
                             accesskey="&getMoreDevtoolsCmd.accesskey;"/>
                 </menupopup>
               </menu>
--- a/browser/base/content/browser-sets.inc
+++ b/browser/base/content/browser-sets.inc
@@ -92,17 +92,17 @@
     <command id="Tools:DevToolbox" oncommand="gDevToolsBrowser.toggleToolboxCommand(gBrowser);"/>
     <command id="Tools:DevToolbar" oncommand="DeveloperToolbar.toggle();" disabled="true" hidden="true"/>
     <command id="Tools:DevToolbarFocus" oncommand="DeveloperToolbar.focusToggle();" disabled="true"/>
     <command id="Tools:ChromeDebugger" oncommand="DebuggerUI.toggleChromeDebugger();" disabled="true" hidden="true"/>
     <command id="Tools:Scratchpad" oncommand="Scratchpad.openScratchpad();" disabled="true" hidden="true"/>
     <command id="Tools:ResponsiveUI" oncommand="ResponsiveUI.toggle();" disabled="true" hidden="true"/>
     <command id="Tools:Addons" oncommand="BrowserOpenAddonsMgr();"/>
     <command id="Tools:ErrorConsole" oncommand="toJavaScriptConsole()" disabled="true" hidden="true"/>
-    <command id="Tools:DevToolsConnect" oncommand="gDevToolsBrowser.openConnectScreen(gBrowser)"/>
+    <command id="Tools:DevToolsConnect" oncommand="gDevToolsBrowser.openConnectScreen(gBrowser)" disabled="true" hidden="true"/>
     <command id="Tools:Sanitize"
      oncommand="Cc['@mozilla.org/browser/browserglue;1'].getService(Ci.nsIBrowserGlue).sanitize(window);"/>
     <command id="Tools:PrivateBrowsing"
 #ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
       oncommand="OpenBrowserWindow({private: true});"/>
 #else
       oncommand="gPrivateBrowsingUI.toggleMode();"/>
 #endif
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1439,16 +1439,24 @@ var gBrowserInit = {
     // Enable Scratchpad in the UI, if the preference allows this.
     let scratchpadEnabled = gPrefService.getBoolPref(Scratchpad.prefEnabledName);
     if (scratchpadEnabled) {
       let cmd = document.getElementById("Tools:Scratchpad");
       cmd.removeAttribute("disabled");
       cmd.removeAttribute("hidden");
     }
 
+    // Enable DevTools connection screen, if the preference allows this.
+    let devtoolsRemoteEnabled = gPrefService.getBoolPref("devtools.debugger.remote-enabled");
+    if (devtoolsRemoteEnabled) {
+      let cmd = document.getElementById("Tools:DevToolsConnect");
+      cmd.removeAttribute("disabled");
+      cmd.removeAttribute("hidden");
+    }
+
 #ifdef MENUBAR_CAN_AUTOHIDE
     // If the user (or the locale) hasn't enabled the top-level "Character
     // Encoding" menu via the "browser.menu.showCharacterEncoding" preference,
     // hide it.
     if ("true" != gPrefService.getComplexValue("browser.menu.showCharacterEncoding",
                                                Ci.nsIPrefLocalizedString).data)
       document.getElementById("appmenu_charsetMenu").hidden = true;
 #endif
--- a/browser/devtools/framework/connect/connect.css
+++ b/browser/devtools/framework/connect/connect.css
@@ -1,19 +1,30 @@
 html {
-  background: url("chrome://browser/skin/newtab/noise.png");
+  background-color: #111;
+  background-image: url("chrome://browser/skin/newtab/noise.png");
 }
 
 body {
-  font-family: Arial;
+  font-family: Arial, sans-serif;
+  color: white;
+  max-width: 600px;
+  margin: 30px auto 0;
+  box-shadow: 0 2px 3px black;
+  background-color: #3C3E40;
+}
+
+h1 {
+  margin: 0;
   padding: 20px;
-  border-radius: 3px;
-  max-width: 600px;
-  min-height: 400px;
-  margin: 10px auto 0;
+  background-color: rgba(0,0,0,0.12);
+  background-image: radial-gradient(ellipse farthest-corner at center top , rgb(159, 223, 255), rgba(101, 203, 255, 0.3)), radial-gradient(ellipse farthest-side at center top , rgba(101, 203, 255, 0.4), rgba(101, 203, 255, 0));
+  background-size: 100% 2px, 100% 5px;
+  background-repeat: no-repeat;
+  border-bottom: 1px solid rgba(0,0,0,0.1);
 }
 
 label {
   display: block;
   margin: 10px;
   font-size: 0;
 }
 
@@ -24,28 +35,31 @@ label > span {
   text-align: right;
   margin-right: 10px;
 }
 
 #submit {
   margin-left: 160px;
 }
 
-
-#actors, #connection-form {
-  margin: 20px;
+input:invalid {
+  box-shadow: 0 0 2px 2px #F06;
 }
 
-input {
-  border: 1px solid grey;
+section {
+  min-height: 160px;
+  margin: 60px 20px;
+  display: none; /* By default, hidden */
 }
 
-#connection-form,
-#connecting,
-#actors-list {
+.error-message {
+  color: red;
+}
+
+.error-message:not(.active) {
   display: none;
 }
 
 body:not(.actors-mode):not(.connecting) > #connection-form {
   display: block;
 }
 
 body.actors-mode > #actors-list {
@@ -55,33 +69,40 @@ body.actors-mode > #actors-list {
 body.connecting > #connecting {
   display: block;
 }
 
 #connecting {
   text-align: center;
 }
 
-#throbber {
-  height: 7px; width: 7px;
-  border-radius: 50%;
-  background: black;
-  display: inline-block;
-  animation-duration: 0.6s;
-  animation-name: anim;
-  animation-direction: alternate;
-  animation-iteration-count: infinite;
-  animation-timing-function: linear;
+#connecting > p > img {
+  vertical-align: top;
 }
-@keyframes anim {to {
-    transform: scale(0.5) rotate(0.1deg);
-}}
 
 #actors {
   padding-left: 0;
   font-size: 0.9rem;
 }
 
 #actors > a {
   display: block;
   margin: 5px;
   padding: 5px;
+  color: white;
 }
+
+.remote-process {
+  font-style: italic;
+  opacity: 0.8;
+}
+
+footer {
+  padding: 10px;
+  background-color: rgba(0,0,0,0.12);
+  border-top: 1px solid rgba(0,0,0,0.1);
+  font-size: small;
+}
+
+footer > a,
+footer > a:visited {
+  color: white;
+}
--- a/browser/devtools/framework/connect/connect.js
+++ b/browser/devtools/framework/connect/connect.js
@@ -5,96 +5,163 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const Cu = Components.utils;
 Cu.import("resource:///modules/devtools/Target.jsm");
 Cu.import("resource:///modules/devtools/Toolbox.jsm");
 Cu.import("resource:///modules/devtools/gDevTools.jsm");
+Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/devtools/dbg-client.jsm");
 
 let gClient;
+let gConnectionTimeout;
 
-function submit() {
-  document.body.classList.add("connecting");
+XPCOMUtils.defineLazyGetter(window, 'l10n', function () {
+  return Services.strings.createBundle('chrome://browser/locale/devtools/connection-screen.properties');
+});
 
-  let host = document.getElementById("host").value;
-  let port = document.getElementById("port").value;
-  if (!host) {
-    host = Services.prefs.getCharPref("devtools.debugger.remote-host");
-  } else {
-    Services.prefs.setCharPref("devtools.debugger.remote-host", host);
+/**
+ * Once DOM is ready, we prefil the host/port inputs with
+ * pref-stored values.
+ */
+window.addEventListener("DOMContentLoaded", function onDOMReady() {
+  window.removeEventListener("DOMContentLoaded", onDOMReady, true);
+  let host = Services.prefs.getCharPref("devtools.debugger.remote-host");
+  let port = Services.prefs.getIntPref("devtools.debugger.remote-port");
+
+  if (host) {
+    document.getElementById("host").value = host;
   }
-  if (!port) {
-    port = Services.prefs.getIntPref("devtools.debugger.remote-port");
-  } else {
-    Services.prefs.setIntPref("devtools.debugger.remote-port", port);
+
+  if (port) {
+    document.getElementById("port").value = port;
   }
 
-  let transport = debuggerSocketConnect(host, port);
-  let client = gClient = new DebuggerClient(transport);
+}, true);
 
-  client.connect(function(aType, aTraits) {
-    client.listTabs(function(aResponse) {
-      document.body.classList.remove("connecting");
-      document.body.classList.add("actors-mode");
+/**
+ * Called when the "connect" button is clicked.
+ */
+function submit() {
+  // Show the "connecting" screen
+  document.body.classList.add("connecting");
 
-      let parent = document.getElementById("actors");
-      let focusSet = false;
+  // Save the host/port values
+  let host = document.getElementById("host").value;
+  Services.prefs.setCharPref("devtools.debugger.remote-host", host);
+
+  let port = document.getElementById("port").value;
+  Services.prefs.setIntPref("devtools.debugger.remote-port", port);
 
-      // Add Global Process debugging...
-      let globals = JSON.parse(JSON.stringify(aResponse));
-      delete globals.tabs;
-      delete globals.selected;
-      // ...only if there are appropriate actors (a 'from' property will always
-      // be there).
-      if (Object.keys(globals).length > 1) {
-        let a = document.createElement("a");
-        a.onclick = function() {
-          connect(globals, true);
-        }
+  // Initiate the connection
+  let transport = debuggerSocketConnect(host, port);
+  gClient = new DebuggerClient(transport);
+  let delay = Services.prefs.getIntPref("devtools.debugger.remote-timeout");
+  gConnectionTimeout = setTimeout(handleConnectionTimeout, delay);
+  gClient.connect(onConnectionReady);
+}
 
-        a.title = a.textContent = "Remote process";
-        a.href = "#";
+/**
+ * Connection is ready. List actors and build buttons.
+ */
+function onConnectionReady(aType, aTraits) {
+  clearTimeout(gConnectionTimeout);
+  gClient.listTabs(function(aResponse) {
+    document.body.classList.remove("connecting");
+    document.body.classList.add("actors-mode");
 
-        parent.appendChild(a);
-      }
+    let parent = document.getElementById("actors");
 
-      // Add one entry for each open tab.
-      if (aResponse.tabs.length > 0) {
-        let header = document.createElement("div");
-        header.innerHTML = "Tabs:";
-        parent.appendChild(header);
-      }
-      for (let i = 0; i < aResponse.tabs.length; i++) {
-        let tab = aResponse.tabs[i];
+    // Add Global Process debugging...
+    let globals = JSON.parse(JSON.stringify(aResponse));
+    delete globals.tabs;
+    delete globals.selected;
+    // ...only if there are appropriate actors (a 'from' property will always
+    // be there).
 
-        let a = document.createElement("a");
-        a.onclick = function() {
-          connect(tab);
-        }
+    // Add one entry for each open tab.
+    for (let i = 0; i < aResponse.tabs.length; i++) {
+      buildLink(aResponse.tabs[i], parent, i == aResponse.selected);
+    }
+
+    // Build the Remote Process button
+    if (Object.keys(globals).length > 1) {
+      let a = document.createElement("a");
+      a.onclick = function() {
+        openToolbox(globals, true);
 
-        a.title = a.textContent = tab.title;
-        a.href = "#";
-
-        if (i == aResponse.selected) {
-          a.title += " [*]";
-          a.textContent = a.title;
-        }
+      }
+      a.title = a.textContent = window.l10n.GetStringFromName("remoteProcess");
+      a.className = "remote-process";
+      a.href = "#";
+      parent.appendChild(a);
+    }
+    // Move the selected tab on top
+    let selectedLink = parent.querySelector("a.selected");
+    if (selectedLink) {
+      parent.insertBefore(selectedLink, parent.firstChild);
+    }
 
-        parent.appendChild(a);
+    // Ensure the first link is focused
+    let firstLink = parent.querySelector("a:first-of-type");
+    if (firstLink) {
+      firstLink.focus();
+    }
 
-        if (!focusSet) {
-          a.focus();
-          focusSet = true;
-        }
-      }
-    });
   });
 }
 
-function connect(form, chrome=false) {
+/**
+ * Build one button for an actor.
+ */
+function buildLink(tab, parent, selected) {
+  let a = document.createElement("a");
+  a.onclick = function() {
+    openToolbox(tab);
+  }
+
+  a.textContent = tab.title;
+  a.title = tab.url;
+  if (!a.textContent) {
+    a.textContent = tab.url;
+  }
+  a.href = "#";
+
+  if (selected) {
+    a.classList.add("selected");
+  }
+
+  parent.appendChild(a);
+}
+
+/**
+ * An error occured. Let's show it and return to the first screen.
+ */
+function showError(type) {
+  document.body.className = "error";
+  let activeError = document.querySelector(".error-message.active");
+  if (activeError) {
+    activeError.classList.remove("active");
+  }
+  activeError = document.querySelector(".error-" + type);
+  if (activeError) {
+    activeError.classList.add("active");
+  }
+}
+
+/**
+ * Connection timeout.
+ */
+function handleConnectionTimeout() {
+  showError("timeout");
+}
+
+/**
+ * The user clicked on one of the buttons.
+ * Opens the toolbox.
+ */
+function openToolbox(form, chrome=false) {
   let target = TargetFactory.forRemote(form, gClient, chrome);
   gDevTools.showToolbox(target, "webconsole", Toolbox.HostType.WINDOW);
-  window.close();
 }
--- a/browser/devtools/framework/connect/connect.xhtml
+++ b/browser/devtools/framework/connect/connect.xhtml
@@ -7,39 +7,42 @@
 <!ENTITY % connectionDTD SYSTEM "chrome://browser/locale/devtools/connection-screen.dtd" >
  %connectionDTD;
 ]>
 
 <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
   <head>
     <title>&title;</title>
+    <link rel="stylesheet" href="chrome://browser/skin/devtools/common.css" type="text/css"/>
     <link rel="stylesheet" href="chrome://browser/content/devtools/connect.css" type="text/css"/>
     <script type="application/javascript;version=1.8" src="connect.js"></script>
   </head>
   <body>
-    <p>
-    </p>
+    <h1>&header;</h1>
     <section id="connection-form">
-      <form onsubmit="window.submit()" action="#">
+      <form validate="validate" onsubmit="window.submit()" action="#">
         <label>
           <span>&host;</span>
-          <input id="host" type="text" placeholder="localhost"></input>
+          <input required="required" class="devtools-textinput" id="host" type="text"></input>
         </label>
         <label>
           <span>&port;</span>
-          <input id="port" type="number" placeholder="6000"></input>
+          <input required="required" class="devtools-textinput" id="port" type="number" pattern="\d+"></input>
         </label>
         <label>
-          <input id="submit" type="submit" value="&connect;"></input>
+          <input class="devtools-toolbarbutton" id="submit" type="submit" value="&connect;"></input>
         </label>
       </form>
+      <p class="error-message error-timeout">&errorTimeout;</p>
+      <p class="error-message error-refused">&errorRefused;</p>
+      <p class="error-message error-unexpected">&errorUnexpected;</p>
     </section>
     <section id="actors-list">
       <p>&availability;</p>
       <ul id="actors"></ul>
     </section>
     <section id="connecting">
-      <p>&connecting;</p>
-      <div id="throbber"></div>
+      <p><img src="chrome://browser/skin/tabbrowser/loading.png"></img> &connecting;</p>
     </section>
+    <footer>&help;</footer>
   </body>
 </html>
--- a/browser/locales/en-US/chrome/browser/devtools/connection-screen.dtd
+++ b/browser/locales/en-US/chrome/browser/devtools/connection-screen.dtd
@@ -1,15 +1,22 @@
 <!-- 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/. -->
 
-<!-- LOCALIZATION NOTE : FILE This file contains the Remove Connection strings.
-  - The Remote Connection window can be start by running the command:
-  - `devtools connect`
+<!-- LOCALIZATION NOTE : FILE This file contains the Remote Connection strings.
+  - The Remote Connection window can reached from the "connect…" menuitem
+  - in the Web Developer menu.
   - -->
 
 <!ENTITY title      "Connect">
+<!ENTITY header     "Connect to remote device">
 <!ENTITY host       "Host:">
 <!ENTITY port       "Port:">
 <!ENTITY connect    "Connect">
 <!ENTITY connecting "Connecting…">
 <!ENTITY availability "Available remote objects:">
+<!ENTITY remoteProcess "remote process">
+<!ENTITY connectionError "Error:">
+<!ENTITY errorTimeout "Error: connection timeout.">
+<!ENTITY errorRefused "Error: connection refused.">
+<!ENTITY errorUnexpected "Unexpected error.">
+<!ENTITY help "Firefox Developer Tools can debug remote devices (Firefox for Android and Firefox OS for example). Make sure that you have turned on the 'Debugger Server' option on the remote device. See <a target='_' href='https://developer.mozilla.org/en-US/docs/Tools/Debugger#Remote_Debugging'>documentation</a>.">
new file mode 100644
--- /dev/null
+++ b/browser/locales/en-US/chrome/browser/devtools/connection-screen.properties
@@ -0,0 +1,9 @@
+# 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/.
+
+# LOCALIZATION NOTE : FILE This file contains the Remote Connection strings.
+# The Remote Connection window can reached from the "connect…" menuitem
+# in the Web Developer menu.
+
+remoteProcess=Remote Process
--- a/browser/locales/jar.mn
+++ b/browser/locales/jar.mn
@@ -36,16 +36,17 @@
     locale/browser/devtools/sourceeditor.properties   (%chrome/browser/devtools/sourceeditor.properties)
     locale/browser/devtools/sourceeditor.dtd          (%chrome/browser/devtools/sourceeditor.dtd)
     locale/browser/devtools/profiler.properties       (%chrome/browser/devtools/profiler.properties)
     locale/browser/devtools/layoutview.dtd            (%chrome/browser/devtools/layoutview.dtd)
     locale/browser/devtools/responsiveUI.properties   (%chrome/browser/devtools/responsiveUI.properties)
     locale/browser/devtools/toolbox.dtd            (%chrome/browser/devtools/toolbox.dtd)
     locale/browser/devtools/inspector.dtd          (%chrome/browser/devtools/inspector.dtd)
     locale/browser/devtools/connection-screen.dtd  (%chrome/browser/devtools/connection-screen.dtd)
+    locale/browser/devtools/connection-screen.properties (%chrome/browser/devtools/connection-screen.properties)
     locale/browser/newTab.dtd                      (%chrome/browser/newTab.dtd)
     locale/browser/newTab.properties               (%chrome/browser/newTab.properties)
     locale/browser/openLocation.dtd                (%chrome/browser/openLocation.dtd)
     locale/browser/openLocation.properties         (%chrome/browser/openLocation.properties)
     locale/browser/pageInfo.dtd                    (%chrome/browser/pageInfo.dtd)
     locale/browser/pageInfo.properties             (%chrome/browser/pageInfo.properties)
     locale/browser/quitDialog.properties           (%chrome/browser/quitDialog.properties)
     locale/browser/safeMode.dtd                    (%chrome/browser/safeMode.dtd)
--- a/browser/themes/gnomestripe/devtools/common.css
+++ b/browser/themes/gnomestripe/devtools/common.css
@@ -123,35 +123,41 @@
 .devtools-toolbarbutton[type=menu] > .toolbarbutton-menu-dropmarker,
 .devtools-toolbarbutton[type=menu-button] > .toolbarbutton-menubutton-dropmarker {
   -moz-appearance: none !important;
   list-style-image: url("chrome://browser/skin/devtools/dropmarker.png");
   -moz-box-align: center;
   margin: 0 3px;
 }
 
-/* Search input */
+/* Text input */
 
+.devtools-textinput,
 .devtools-searchinput {
   -moz-appearance: none;
   margin: 0 3px;
   border: 1px solid hsla(210,8%,5%,.6);
   border-radius: 2px;
   background-color: transparent;
-  background-image: url(magnifying-glass.png), -moz-linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
-  background-repeat: no-repeat;
-  background-position: 4px center, top left, top left;
+  background-image: -moz-linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
+  padding: 3px;
+  box-shadow: 0 1px 1px hsla(210,8%,5%,.3) inset,
+              0 0 0 1px hsla(210,16%,76%,.1) inset,
+              0 1px 0 hsla(210,16%,76%,.15);
+  color: inherit;
+}
+
+.devtools-searchinput {
   padding-top: 0;
   padding-bottom: 0;
   -moz-padding-start: 18px;
   -moz-padding-end: 12px;
-  box-shadow: 0 1px 1px hsla(210,8%,5%,.3) inset,
-              0 0 0 1px hsla(210,16%,76%,.1) inset,
-              0 1px 0 hsla(210,16%,76%,.15);
-  color: inherit;
+  background-image: url(magnifying-glass.png), -moz-linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
+  background-position: 4px center, top left, top left;
+  background-repeat: no-repeat;
 }
 
 .devtools-searchinput:-moz-locale-dir(rtl) {
   background-position: calc(100% - 4px) center, top left, top left;
 }
 
 .devtools-searchinput > .textbox-input-box > .textbox-search-icons {
   display: none;
--- a/browser/themes/pinstripe/devtools/common.css
+++ b/browser/themes/pinstripe/devtools/common.css
@@ -129,35 +129,41 @@
 .devtools-toolbarbutton[type=menu] > .toolbarbutton-menu-dropmarker,
 .devtools-toolbarbutton[type=menu-button] > .toolbarbutton-menubutton-dropmarker {
   -moz-appearance: none !important;
   list-style-image: url("chrome://browser/skin/devtools/dropmarker.png");
   margin: 0 3px;
   border: 0;
 }
 
-/* Search input */
+/* Text input */
 
+.devtools-textinput,
 .devtools-searchinput {
   -moz-appearance: none;
   margin: 0 3px;
   background-color: transparent;
   border: 1px solid hsla(210,8%,5%,.6);
   border-radius: 20px;
+  background-image: -moz-linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
+  padding: 3px;
+  box-shadow: 0 1px 1px hsla(210,8%,5%,.3) inset,
+              0 0 0 1px hsla(210,16%,76%,.1) inset,
+              0 1px 0 hsla(210,16%,76%,.15);
+  color: inherit;
+}
+
+.devtools-searchinput {
   background-image: url(magnifying-glass.png), -moz-linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
   background-repeat: no-repeat;
   background-position: 4px center, top left, top left;
   padding-top: 0;
   padding-bottom: 0;
   -moz-padding-start: 18px;
   -moz-padding-end: 12px;
-  box-shadow: 0 1px 1px hsla(210,8%,5%,.3) inset,
-              0 0 0 1px hsla(210,16%,76%,.1) inset,
-              0 1px 0 hsla(210,16%,76%,.15);
-  color: inherit;
 }
 
 .devtools-searchinput:-moz-locale-dir(rtl) {
   background-position: calc(100% - 4px) center, top left, top left;
 }
 
 .devtools-searchinput > .textbox-input-box > .textbox-search-icons {
   display: none;
--- a/browser/themes/winstripe/devtools/common.css
+++ b/browser/themes/winstripe/devtools/common.css
@@ -127,36 +127,42 @@
 
 .devtools-toolbarbutton[type=menu] > .toolbarbutton-menu-dropmarker,
 .devtools-toolbarbutton[type=menu-button] > .toolbarbutton-menubutton-dropmarker {
   -moz-appearance: none !important;
   list-style-image: url("chrome://browser/skin/devtools/dropmarker.png");
   -moz-box-align: center;
 }
 
-/* Search input */
+/* Text input */
 
+.devtools-textinput,
 .devtools-searchinput {
   -moz-appearance: none;
   margin: 0 3px;
   border: 1px solid hsla(211,68%,6%,.6);
   box-shadow: inset 0 1px 0 hsla(211,68%,6%,.05), 0 0 0 1px hsla(210,40%,83%,.1);
   border-radius: 2px;
   background-color: transparent;
+  background-image: -moz-linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
+  padding: 3px;
+  transition-property: background-color, border-color, box-shadow;
+  transition-duration: 150ms;
+  transition-timing-function: ease;
+  color: inherit;
+}
+
+.devtools-searchinput {
   background-image: url(magnifying-glass.png), -moz-linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
   background-repeat: no-repeat;
   background-position: 4px center, top left, top left;
   padding-top: 0;
   padding-bottom: 0;
   -moz-padding-start: 18px;
   -moz-padding-end: 12px;
-  transition-property: background-color, border-color, box-shadow;
-  transition-duration: 150ms;
-  transition-timing-function: ease;
-  color: inherit;
 }
 
 .devtools-searchinput[focused] {
   border-color: hsl(200,70%,40%) hsl(200,75%,37%) hsl(200,80%,35%);
   background-origin: padding-box;
   background-clip: padding-box;
   box-shadow: inset 0 0 0 1px hsla(211,68%,6%,.1);
 }