Merge mozilla-central to mozilla-inbound
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Thu, 27 Nov 2014 17:03:44 +0100
changeset 242191 1b70fe4f38bab55e7a6c223f56d351566804676e
parent 242190 18953298cf06307dd002420c5b14f2a945aefaf0 (current diff)
parent 242177 92a21b9147bd62348099da6e900f2cfc56f00f0d (diff)
child 242192 41bf902163cfcd8dd744df45379cf5150471af9e
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to mozilla-inbound
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -417,16 +417,18 @@ pref("browser.search.update", true);
 pref("browser.search.update.log", false);
 
 // Check whether we need to perform engine updates every 6 hours
 pref("browser.search.update.interval", 21600);
 
 // enable search suggestions by default
 pref("browser.search.suggest.enabled", true);
 
+pref("browser.search.showOneOffButtons", true);
+
 #ifdef MOZ_OFFICIAL_BRANDING
 // {moz:official} expands to "official"
 pref("browser.search.official", true);
 #endif
 
 pref("browser.sessionhistory.max_entries", 50);
 
 // handle links targeting new windows
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -410,16 +410,25 @@ panel[noactions] > richlistbox > richlis
 #urlbar:not([actiontype="switchtab"]) > #urlbar-display-box {
   display: none;
 }
 
 #PopupAutoComplete {
   -moz-binding: url("chrome://browser/content/urlbarBindings.xml#browser-autocomplete-result-popup");
 }
 
+#PopupSearchAutoComplete {
+  -moz-binding: url("chrome://browser/content/urlbarBindings.xml#browser-search-autocomplete-result-popup");
+  margin-left: -23px;
+}
+
+searchbar[oneoffui] {
+  -moz-binding: url("chrome://browser/content/search/search.xml#searchbar-flare") !important;
+}
+
 #PopupAutoCompleteRichResult {
   -moz-binding: url("chrome://browser/content/urlbarBindings.xml#urlbar-rich-result-popup");
 }
 
 #urlbar[pageproxystate="invalid"] > #urlbar-icons > .urlbar-icon,
 #urlbar[pageproxystate="invalid"][focused="true"] > #urlbar-go-button ~ toolbarbutton,
 #urlbar[pageproxystate="valid"] > #urlbar-go-button,
 #urlbar:not([focused="true"]) > #urlbar-go-button {
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3299,36 +3299,30 @@ const BrowserSearch = {
       return;
 
     // Check to see whether we've already added an engine with this title
     if (browser.engines) {
       if (browser.engines.some(function (e) e.title == engine.title))
         return;
     }
 
-    // Append the URI and an appropriate title to the browser data.
-    // Use documentURIObject in the check for shouldLoadFavIcon so that we
-    // do the right thing with about:-style error pages.  Bug 453442
-    var iconURL = null;
-    if (gBrowser.shouldLoadFavIcon(uri))
-      iconURL = uri.prePath + "/favicon.ico";
-
     var hidden = false;
     // If this engine (identified by title) is already in the list, add it
     // to the list of hidden engines rather than to the main list.
     // XXX This will need to be changed when engines are identified by URL;
     // see bug 335102.
     if (Services.search.getEngineByName(engine.title))
       hidden = true;
 
     var engines = (hidden ? browser.hiddenEngines : browser.engines) || [];
 
     engines.push({ uri: engine.href,
                    title: engine.title,
-                   icon: iconURL });
+                   get icon() { return browser.mIconURL; }
+                 });
 
     if (hidden)
       browser.hiddenEngines = engines;
     else
       browser.engines = engines;
   },
 
   /**
@@ -7816,9 +7810,8 @@ let PanicButtonNotifier = {
       Cu.reportError(ex);
     }
   },
   close: function() {
     let popup = document.getElementById("panic-button-success-notification");
     popup.hidePopup();
   },
 };
-
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -135,16 +135,19 @@
                oncommand="gotoHistoryIndex(event); event.stopPropagation();"
                onclick="checkForMiddleClick(this, event);"/>
     <tooltip id="aHTMLTooltip" page="true"/>
     <tooltip id="remoteBrowserTooltip"/>
 
     <!-- for search and content formfill/pw manager -->
     <panel type="autocomplete" id="PopupAutoComplete" noautofocus="true" hidden="true"/>
 
+    <!-- for search with one-off buttons -->
+    <panel type="autocomplete" id="PopupSearchAutoComplete" noautofocus="true" hidden="true"/>
+
     <!-- for url bar autocomplete -->
     <panel type="autocomplete-richlistbox" id="PopupAutoCompleteRichResult" noautofocus="true" hidden="true"/>
 
     <!-- for select dropdowns -->
     <menupopup id="ContentSelectDropdown" rolluponmousewheel="true" hidden="true"/>
 
     <!-- for invalid form error message -->
     <panel id="invalid-form-popup" type="arrow" orient="vertical" noautofocus="true" hidden="true" level="parent">
--- a/browser/base/content/test/general/browser_lastAccessedTab.js
+++ b/browser/base/content/test/general/browser_lastAccessedTab.js
@@ -1,35 +1,40 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 let originalTab;
 let newTab;
 
+function isCurrent(tab, msg) {
+  const tolerance = 1;
+  const difference = Math.abs(Date.now() - tab.lastAccessed);
+  ok(difference <= tolerance, msg + " (difference: " + difference + ")");
+}
+
 function test() {
   waitForExplicitFinish();
 
   originalTab = gBrowser.selectedTab;
   setTimeout(step2, 100);
 }
 
 function step2() {
-  is(originalTab.lastAccessed, Date.now(), "selected tab has the current timestamp");
+  isCurrent(originalTab, "selected tab has the current timestamp");
   newTab = gBrowser.addTab("about:blank", {skipAnimation: true});
   setTimeout(step3, 100);
 }
 
 function step3() {
   ok(newTab.lastAccessed < Date.now(), "new tab hasn't been selected so far");
   gBrowser.selectedTab = newTab;
-  is(newTab.lastAccessed, Date.now(), "new tab has the current timestamp after being selected");
+  isCurrent(newTab, "new tab has the current timestamp after being selected");
   setTimeout(step4, 100);
 }
 
 function step4() {
   ok(originalTab.lastAccessed < Date.now(),
      "original tab has old timestamp after being deselected");
-  is(newTab.lastAccessed, Date.now(),
-     "new tab has the current timestamp since it's still selected");
+  isCurrent(newTab, "new tab has the current timestamp since it's still selected");
 
   gBrowser.removeTab(newTab);
   finish();
 }
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -946,16 +946,279 @@
             var where = whereToOpenLink(aEvent, false, true);
             searchBar.doSearch(search, where);
           }
         ]]></body>
       </method>
     </implementation>
   </binding>
 
+  <!-- Note: this binding is applied to the autocomplete popup used in the Search bar -->
+  <binding id="browser-search-autocomplete-result-popup" extends="chrome://browser/content/urlbarBindings.xml#browser-autocomplete-result-popup">
+    <resources>
+      <stylesheet src="chrome://browser/skin/searchbar.css"/>
+    </resources>
+    <content ignorekeys="true" level="top" consumeoutsideclicks="false">
+      <xul:hbox xbl:inherits="collapsed=showonlysettings"
+                class="search-panel-header search-panel-current-engine">
+        <xul:image class="searchbar-engine-image" xbl:inherits="src"/>
+        <xul:label anonid="searchbar-engine-name" flex="1" crop="end"/>
+      </xul:hbox>
+      <xul:tree anonid="tree" flex="1"
+                class="autocomplete-tree plain search-panel-tree"
+                hidecolumnpicker="true" seltype="single">
+        <xul:treecols anonid="treecols">
+          <xul:treecol id="treecolAutoCompleteValue" class="autocomplete-treecol" flex="1" overflow="true"/>
+        </xul:treecols>
+        <xul:treechildren class="autocomplete-treebody"/>
+      </xul:tree>
+      <xul:hbox anonid="search-panel-one-offs-header"
+                class="search-panel-header search-panel-current-input"
+                xbl:inherits="hidden=showonlysettings">
+        <xul:label anonid="searchbar-oneoffheader-before" value="&searchFor.label;"/>
+        <xul:label anonid="searchbar-oneoffheader-searchtext" flex="1" crop="end" class="search-panel-input-value"/>
+        <xul:label anonid="searchbar-oneoffheader-after" flex="10000" value="&searchWith.label;"/>
+      </xul:hbox>
+      <xul:description anonid="search-panel-one-offs"
+                       class="search-panel-one-offs"
+                       xbl:inherits="hidden=showonlysettings"/>
+      <xul:vbox anonid="add-engines"/>
+      <xul:button anonid="search-settings"
+                  xbl:inherits="showonlysettings"
+                  oncommand="openPreferences('paneSearch')"
+                  class="search-setting-button search-panel-header"
+                  label="&changeSearchSettings.button;"/>
+    </content>
+    <handlers>
+      <handler event="popupshowing"><![CDATA[
+        // First handle deciding if we are showing the reduced version of the
+        // popup containing only the preferences button. We do this if the
+        // glass icon has been clicked if the text field is empty.
+        let searchbar = document.getElementById("searchbar");
+        let tree = document.getAnonymousElementByAttribute(this, "anonid",
+                                                           "tree")
+        if (searchbar.hasAttribute("showonlysettings")) {
+          searchbar.removeAttribute("showonlysettings");
+          this.setAttribute("showonlysettings", "true");
+
+          // Setting this with an xbl-inherited attribute gets overridden the
+          // second time the user clicks the glass icon for some reason...
+          tree.collapsed = true;
+        }
+        else {
+          this.removeAttribute("showonlysettings");
+          tree.collapsed = false;
+        }
+
+        // Show the current default engine in the top header of the panel.
+        let currentEngine = Services.search.currentEngine;
+        let uri = currentEngine.iconURI;
+        if (uri) {
+          uri = uri.spec;
+          this.setAttribute("src", PlacesUtils.getImageURLForResolution(window, uri));
+        }
+        else {
+          // If the default has just been changed to a provider without icon,
+          // avoid showing the icon of the previous default provider.
+          this.removeAttribute("src");
+        }
+
+        const kBundleURI = "chrome://browser/locale/search.properties";
+        let bundle = Services.strings.createBundle(kBundleURI);
+        let headerText = bundle.formatStringFromName("searchHeader",
+                                                     [currentEngine.name], 1);
+        document.getAnonymousElementByAttribute(this, "anonid", "searchbar-engine-name")
+                .setAttribute("value", headerText);
+
+        // Update the 'Search for <keywords> with:" header.
+        let headerSearchText =
+          document.getAnonymousElementByAttribute(this, "anonid",
+                                                  "searchbar-oneoffheader-searchtext");
+        let textbox = searchbar.textbox;
+        let self = this;
+        let keyPressHandler = function() {
+          headerSearchText.setAttribute("value", textbox.value);
+          if (textbox.value)
+            self.removeAttribute("showonlysettings");
+        };
+        textbox.addEventListener("keyup", keyPressHandler);
+        this.addEventListener("popuphiding", function hiding() {
+          textbox.removeEventListener("keyup", keyPressHandler);
+          this.removeEventListener("popuphiding", hiding);
+        });
+        keyPressHandler();
+
+        // Handle opensearch items. This needs to be done before building the
+        // list of one off providers, as that code will return early if all the
+        // alternative engines are hidden.
+        let addEngineList =
+          document.getAnonymousElementByAttribute(this, "anonid", "add-engines");
+        while (addEngineList.firstChild)
+          addEngineList.firstChild.remove();
+
+        const kXULNS =
+          "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+
+        let addEngines = getBrowser().mCurrentBrowser.engines;
+        if (addEngines && addEngines.length > 0) {
+          const kBundleURI = "chrome://browser/locale/search.properties";
+          let bundle = Services.strings.createBundle(kBundleURI);
+          for (let engine of addEngines) {
+            let button = document.createElementNS(kXULNS, "button");
+            let label = bundle.formatStringFromName("cmd_addFoundEngine",
+                                                    [engine.title], 1);
+            button.setAttribute("class", "addengine-item");
+            button.setAttribute("label", label);
+            button.setAttribute("pack", "start");
+
+            button.setAttribute("crop", "end");
+            button.setAttribute("tooltiptext", engine.uri);
+            button.setAttribute("uri", engine.uri);
+            if (engine.icon) {
+              let uri = PlacesUtils.getImageURLForResolution(window, engine.icon);
+              button.setAttribute("image", uri);
+            }
+            button.setAttribute("title", engine.title);
+            addEngineList.appendChild(button);
+          }
+        }
+
+        // Finally, build the list of one-off buttons.
+        let list = document.getAnonymousElementByAttribute(this, "anonid",
+                                                           "search-panel-one-offs")
+        while (list.firstChild)
+          list.firstChild.remove();
+
+        let hiddenList;
+        try {
+          let pref =
+            Services.prefs.getCharPref("browser.search.hiddenOneOffs");
+          hiddenList = pref ? pref.split(",") : [];
+        } catch(e) {
+          hiddenList = [];
+        }
+
+        let engines = Services.search.getVisibleEngines()
+                              .filter(e => e.name != currentEngine.name &&
+                                           hiddenList.indexOf(e.name) == -1);
+
+        let header = document.getAnonymousElementByAttribute(this, "anonid",
+                                                             "search-panel-one-offs-header")
+        header.collapsed = list.collapsed = !engines.length;
+
+        if (!engines.length)
+          return;
+
+        let panel = document.getElementById("PopupSearchAutoComplete");
+        let minWidth = parseInt(panel.width) + 23;
+        panel.setAttribute("style", "min-width: " + minWidth + "px");
+
+        // 49px is the min-width of each search engine button,
+        // adapt this const when changing the css.
+        // It's actually 48px + 1px of right border.
+        // The + 1 is because the last button doesn't have a right border.
+        let panelWidth = parseInt(panel.clientWidth);
+        let enginesPerRow = Math.floor((panelWidth + 1) / 49);
+        let buttonWidth = Math.floor(panelWidth / enginesPerRow);
+        // There will be an emtpy area of:
+        //   panelWidth - enginesPerRow * buttonWidth  px
+        // at the end of each row.
+
+        // If the <description> tag with the list of search engines doesn't have
+        // a fixed height, the panel will be sized incorrectly, causing the bottom
+        // of the suggestion <tree> to be hidden.
+        let rowCount = Math.ceil(engines.length / enginesPerRow);
+        let height = rowCount * 33; // 32px per row, 1px border.
+        list.setAttribute("height", height + "px");
+
+        let dummyItems = enginesPerRow - (engines.length % enginesPerRow || enginesPerRow);
+        for (let i = 0; i < engines.length; ++i) {
+          let engine = engines[i];
+          let button = document.createElementNS(kXULNS, "button");
+          button.setAttribute("label", engine.name);
+          let uri = "chrome://browser/skin/search-engine-placeholder.png";
+          if (engine.iconURI) {
+            uri = PlacesUtils.getImageURLForResolution(window, engine.iconURI.spec);
+          }
+          button.setAttribute("image", uri);
+          button.setAttribute("class", "searchbar-engine-one-off-item");
+          button.setAttribute("tooltiptext", engine.name);
+          button.setAttribute("width", buttonWidth);
+          button.engine = engine;
+
+          if ((i + 1) % enginesPerRow == 0)
+            button.classList.add("last-of-row");
+
+          if (i >= engines.length + dummyItems - enginesPerRow)
+            button.classList.add("last-row");
+
+          list.appendChild(button);
+        }
+
+        while (dummyItems) {
+          let button = document.createElementNS(kXULNS, "button");
+          button.setAttribute("class", "searchbar-engine-one-off-item dummy last-row");
+          button.setAttribute("width", buttonWidth);
+
+          if (!--dummyItems)
+            button.classList.add("last-of-row");
+
+          list.appendChild(button);
+        }
+      ]]></handler>
+
+      <handler event="mousedown"><![CDATA[
+        // Required to receive click events from the buttons on Linux.
+        event.preventDefault();
+      ]]></handler>
+
+      <handler event="mouseover"><![CDATA[
+        let target = event.originalTarget;
+        if (target.localName == "button" &&
+            target.classList.contains("searchbar-engine-one-off-item") &&
+            !target.classList.contains("dummy")) {
+          let list = document.getAnonymousElementByAttribute(this, "anonid",
+                                                             "search-panel-one-offs")
+          for (let button = list.firstChild; button; button = button.nextSibling)
+            button.removeAttribute("selected");
+        }
+      ]]></handler>
+
+      <handler event="click"><![CDATA[
+        if (event.button == 2)
+          return; // ignore right clicks.
+
+        let button = event.originalTarget;
+        if (button.localName != "button" || !button.engine)
+          return;
+
+        let searchbar = document.getElementById("searchbar");
+        searchbar.handleSearchCommand(event, button.engine);
+      ]]></handler>
+
+      <handler event="command"><![CDATA[
+        let target = event.originalTarget;
+        if (target.classList.contains("addengine-item")) {
+          // On success, hide and reshow the panel to show the new engine.
+          let installCallback = {
+            onSuccess: function(engine) {
+              event.target.hidePopup();
+              BrowserSearch.searchBar.openSuggestionsPanel();
+            }
+          }
+          Services.search.addEngine(target.getAttribute("uri"),
+                                    Ci.nsISearchEngine.DATA_XML,
+                                    target.getAttribute("src"), false,
+                                    installCallback);
+        }
+      ]]></handler>
+    </handlers>
+  </binding>
+
+
   <binding id="urlbar-rich-result-popup" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete-rich-result-popup">
     <implementation>
       <field name="_maxResults">0</field>
 
       <field name="_bundle" readonly="true">
         Cc["@mozilla.org/intl/stringbundle;1"].
           getService(Ci.nsIStringBundleService).
           createBundle("chrome://browser/locale/places/places.properties");
--- a/browser/components/customizableui/test/browser_940307_panel_click_closure_handling.js
+++ b/browser/components/customizableui/test/browser_940307_panel_click_closure_handling.js
@@ -62,38 +62,51 @@ add_task(function() {
 add_task(function*() {
   let searchbar = document.getElementById("searchbar");
   gCustomizeMode.addToPanel(searchbar);
   let placement = CustomizableUI.getPlacementOfWidget("search-container");
   is(placement.area, CustomizableUI.AREA_PANEL, "Should be in panel");
   yield PanelUI.show();
   yield waitForCondition(() => "value" in searchbar && searchbar.value === "");
 
+  // Focusing a non-empty searchbox will cause us to open the
+  // autocomplete panel and search for suggestions, which would
+  // trigger network requests. Temporarily disable suggestions.
+  let suggestEnabled =
+    Services.prefs.getBoolPref("browser.search.suggest.enabled");
+  Services.prefs.setBoolPref("browser.search.suggest.enabled", false);
+
   searchbar.value = "foo";
   searchbar.focus();
   // Reaching into this context menu is pretty evil, but hey... it's a test.
   let textbox = document.getAnonymousElementByAttribute(searchbar.textbox, "anonid", "textbox-input-box");
   let contextmenu = document.getAnonymousElementByAttribute(textbox, "anonid", "input-box-contextmenu");
   let contextMenuShown = promisePanelElementShown(window, contextmenu);
   EventUtils.synthesizeMouseAtCenter(searchbar, {type: "contextmenu", button: 2});
   yield contextMenuShown;
 
   ok(isPanelUIOpen(), "Panel should still be open");
 
   let selectAll = contextmenu.querySelector("[cmd='cmd_selectAll']");
   let contextMenuHidden = promisePanelElementHidden(window, contextmenu);
   EventUtils.synthesizeMouseAtCenter(selectAll, {});
   yield contextMenuHidden;
 
+  // Hide the suggestion panel.
+  searchbar.textbox.popup.hidePopup();
+
   ok(isPanelUIOpen(), "Panel should still be open");
 
   let hiddenPanelPromise = promisePanelHidden(window);
   EventUtils.synthesizeKey("VK_ESCAPE", {});
   yield hiddenPanelPromise;
   ok(!isPanelUIOpen(), "Panel should no longer be open");
+
+  Services.prefs.setBoolPref("browser.search.suggest.enabled", suggestEnabled);
+  CustomizableUI.reset();
 });
 
 add_task(function*() {
   button = document.createElement("toolbarbutton");
   button.id = "browser_946166_button_disabled";
   button.setAttribute("disabled", "true");
   button.setAttribute("label", "Button");
   PanelUI.contents.appendChild(button);
@@ -116,9 +129,8 @@ registerCleanupFunction(function() {
   }
   // Sadly this isn't task.jsm-enabled, so we can't wait for this to happen. But we should
   // definitely close it here and hope it won't interfere with other tests.
   // Of course, all the tests are meant to do this themselves, but if they fail...
   if (isPanelUIOpen()) {
     PanelUI.hide();
   }
 });
-
--- a/browser/components/loop/content/js/panel.js
+++ b/browser/components/loop/content/js/panel.js
@@ -582,18 +582,20 @@ loop.panel = (function(_, mozL10n) {
       });
 
       return (
         React.DOM.div({className: roomClasses, onMouseLeave: this.handleMouseLeave}, 
           React.DOM.h2(null, 
             React.DOM.span({className: "room-notification"}), 
             room.roomName, 
             React.DOM.button({className: copyButtonClasses, 
+              title: mozL10n.get("rooms_list_copy_url_tooltip"), 
               onClick: this.handleCopyButtonClick}), 
             React.DOM.button({className: "delete-link", 
+              title: mozL10n.get("rooms_list_delete_tooltip"), 
               onClick: this.handleDeleteButtonClick})
           ), 
           React.DOM.p(null, 
             React.DOM.a({href: "#", onClick: this.handleClickRoomUrl}, 
               room.roomUrl
             )
           )
         )
--- a/browser/components/loop/content/js/panel.jsx
+++ b/browser/components/loop/content/js/panel.jsx
@@ -582,18 +582,20 @@ loop.panel = (function(_, mozL10n) {
       });
 
       return (
         <div className={roomClasses} onMouseLeave={this.handleMouseLeave}>
           <h2>
             <span className="room-notification" />
             {room.roomName}
             <button className={copyButtonClasses}
+              title={mozL10n.get("rooms_list_copy_url_tooltip")}
               onClick={this.handleCopyButtonClick} />
             <button className="delete-link"
+              title={mozL10n.get("rooms_list_delete_tooltip")}
               onClick={this.handleDeleteButtonClick} />
           </h2>
           <p>
             <a href="#" onClick={this.handleClickRoomUrl}>
               {room.roomUrl}
             </a>
           </p>
         </div>
--- a/browser/components/loop/content/js/roomViews.js
+++ b/browser/components/loop/content/js/roomViews.js
@@ -246,17 +246,17 @@ loop.roomViews = (function(mozL10n) {
     render: function() {
       if (this.state.roomName) {
         this.setTitle(this.state.roomName);
       }
 
       var localStreamClasses = React.addons.classSet({
         local: true,
         "local-stream": true,
-        "local-stream-audio": !this.state.videoMuted,
+        "local-stream-audio": this.state.videoMuted,
         "room-preview": this.state.roomState !== ROOM_STATES.HAS_PARTICIPANTS
       });
 
       switch(this.state.roomState) {
         case ROOM_STATES.FAILED:
         case ROOM_STATES.FULL: {
           // Note: While rooms are set to hold a maximum of 2 participants, the
           //       FULL case should never happen on desktop.
--- a/browser/components/loop/content/js/roomViews.jsx
+++ b/browser/components/loop/content/js/roomViews.jsx
@@ -246,17 +246,17 @@ loop.roomViews = (function(mozL10n) {
     render: function() {
       if (this.state.roomName) {
         this.setTitle(this.state.roomName);
       }
 
       var localStreamClasses = React.addons.classSet({
         local: true,
         "local-stream": true,
-        "local-stream-audio": !this.state.videoMuted,
+        "local-stream-audio": this.state.videoMuted,
         "room-preview": this.state.roomState !== ROOM_STATES.HAS_PARTICIPANTS
       });
 
       switch(this.state.roomState) {
         case ROOM_STATES.FAILED:
         case ROOM_STATES.FULL: {
           // Note: While rooms are set to hold a maximum of 2 participants, the
           //       FULL case should never happen on desktop.
--- a/browser/components/loop/standalone/content/js/standaloneRoomViews.js
+++ b/browser/components/loop/standalone/content/js/standaloneRoomViews.js
@@ -337,17 +337,17 @@ loop.standaloneRoomViews = (function(moz
              this.state.roomState === ROOM_STATES.HAS_PARTICIPANTS;
     },
 
     render: function() {
       var localStreamClasses = React.addons.classSet({
         hide: !this._roomIsActive(),
         local: true,
         "local-stream": true,
-        "local-stream-audio": false
+        "local-stream-audio": this.state.videoMuted
       });
 
       return (
         React.DOM.div({className: "room-conversation-wrapper"}, 
           StandaloneRoomHeader(null), 
           StandaloneRoomInfoArea({roomState: this.state.roomState, 
                                   failureReason: this.state.failureReason, 
                                   joinRoom: this.joinRoom, 
--- a/browser/components/loop/standalone/content/js/standaloneRoomViews.jsx
+++ b/browser/components/loop/standalone/content/js/standaloneRoomViews.jsx
@@ -337,17 +337,17 @@ loop.standaloneRoomViews = (function(moz
              this.state.roomState === ROOM_STATES.HAS_PARTICIPANTS;
     },
 
     render: function() {
       var localStreamClasses = React.addons.classSet({
         hide: !this._roomIsActive(),
         local: true,
         "local-stream": true,
-        "local-stream-audio": false
+        "local-stream-audio": this.state.videoMuted
       });
 
       return (
         <div className="room-conversation-wrapper">
           <StandaloneRoomHeader />
           <StandaloneRoomInfoArea roomState={this.state.roomState}
                                   failureReason={this.state.failureReason}
                                   joinRoom={this.joinRoom}
--- a/browser/components/loop/test/desktop-local/roomViews_test.js
+++ b/browser/components/loop/test/desktop-local/roomViews_test.js
@@ -325,10 +325,25 @@ describe("loop.roomViews", function () {
           activeRoomStore.setStoreState({roomState: ROOM_STATES.ENDED});
 
           view = mountTestComponent();
 
           TestUtils.findRenderedComponentWithType(view,
             loop.shared.views.FeedbackView);
         });
     });
+
+    describe("Mute", function() {
+      it("should render local media as audio-only if video is muted",
+        function() {
+          activeRoomStore.setStoreState({
+            roomState: ROOM_STATES.SESSION_CONNECTED,
+            videoMuted: true
+          });
+
+          view = mountTestComponent();
+
+          expect(view.getDOMNode().querySelector(".local-stream-audio"))
+            .not.eql(null);
+        });
+    });
   });
 });
--- a/browser/components/loop/test/standalone/standaloneRoomViews_test.js
+++ b/browser/components/loop/test/standalone/standaloneRoomViews_test.js
@@ -306,11 +306,24 @@ describe("loop.standaloneRoomViews", fun
 
             sandbox.clock.tick(
               loop.shared.views.WINDOW_AUTOCLOSE_TIMEOUT_IN_SECONDS * 1000 + 1000);
 
             sinon.assert.calledOnce(dispatch);
             sinon.assert.calledWithExactly(dispatch, new sharedActions.FeedbackComplete());
           });
       });
+
+      describe("Mute", function() {
+        it("should render local media as audio-only if video is muted",
+          function() {
+            activeRoomStore.setStoreState({
+              roomState: ROOM_STATES.SESSION_CONNECTED,
+              videoMuted: true
+            });
+
+            expect(view.getDOMNode().querySelector(".local-stream-audio"))
+              .not.eql(null);
+          });
+      });
     });
   });
 });
--- a/browser/components/preferences/in-content/jar.mn
+++ b/browser/components/preferences/in-content/jar.mn
@@ -9,8 +9,10 @@ browser.jar:
 
 *  content/browser/preferences/in-content/main.js
 *  content/browser/preferences/in-content/privacy.js
 *  content/browser/preferences/in-content/advanced.js
 *  content/browser/preferences/in-content/applications.js
    content/browser/preferences/in-content/content.js
    content/browser/preferences/in-content/sync.js
    content/browser/preferences/in-content/security.js
+   content/browser/preferences/in-content/search.css
+   content/browser/preferences/in-content/search.js
--- a/browser/components/preferences/in-content/preferences.js
+++ b/browser/components/preferences/in-content/preferences.js
@@ -19,16 +19,17 @@ addEventListener("DOMContentLoaded", fun
   init_all();
 });
 
 function init_all() {
   document.documentElement.instantApply = true;
 
   gSubDialog.init();
   gMainPane.init();
+  gSearchPane.init();
   gPrivacyPane.init();
   gAdvancedPane.init();
   gApplicationsPane.init();
   gContentPane.init();
   gSyncPane.init();
   gSecurityPane.init();
 
   var initFinished = new CustomEvent("Initialized", {
--- a/browser/components/preferences/in-content/preferences.xul
+++ b/browser/components/preferences/in-content/preferences.xul
@@ -9,24 +9,26 @@
 
 <?xml-stylesheet href="chrome://browser/skin/preferences/preferences.css"?>
 <?xml-stylesheet href="chrome://global/skin/in-content/common.css"?>
 <?xml-stylesheet
   href="chrome://browser/skin/preferences/in-content/preferences.css"?>
 <?xml-stylesheet
   href="chrome://browser/content/preferences/handlers.css"?>
 <?xml-stylesheet href="chrome://browser/skin/preferences/applications.css"?>
+<?xml-stylesheet href="chrome://browser/content/preferences/in-content/search.css"?>
 
 <!DOCTYPE page [
 <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
 <!ENTITY % globalPreferencesDTD SYSTEM "chrome://global/locale/preferences.dtd">
 <!ENTITY % preferencesDTD SYSTEM
   "chrome://browser/locale/preferences/preferences.dtd">
 <!ENTITY % privacyDTD SYSTEM "chrome://browser/locale/preferences/privacy.dtd">
 <!ENTITY % tabsDTD SYSTEM "chrome://browser/locale/preferences/tabs.dtd">
+<!ENTITY % searchDTD SYSTEM "chrome://browser/locale/preferences/search.dtd">
 <!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
 <!ENTITY % syncDTD SYSTEM "chrome://browser/locale/preferences/sync.dtd">
 <!ENTITY % securityDTD SYSTEM
   "chrome://browser/locale/preferences/security.dtd">
 <!ENTITY % sanitizeDTD SYSTEM "chrome://browser/locale/sanitize.dtd">
 <!ENTITY % mainDTD SYSTEM "chrome://browser/locale/preferences/main.dtd">
 <!ENTITY % aboutHomeDTD SYSTEM "chrome://browser/locale/aboutHome.dtd">
 <!ENTITY % contentDTD SYSTEM "chrome://browser/locale/preferences/content.dtd">
@@ -34,16 +36,17 @@
   "chrome://browser/locale/preferences/applications.dtd">
 <!ENTITY % advancedDTD SYSTEM
   "chrome://browser/locale/preferences/advanced.dtd">
 %brandDTD;
 %globalPreferencesDTD;
 %preferencesDTD;
 %privacyDTD;
 %tabsDTD;
+%searchDTD;
 %syncBrandDTD;
 %syncDTD;
 %securityDTD;
 %sanitizeDTD;
 %mainDTD;
 %aboutHomeDTD;
 %contentDTD;
 %applicationsDTD;
@@ -91,16 +94,26 @@
                     value="paneGeneral"
                     helpTopic="prefs-main"
                     tooltiptext="&paneGeneral.title;"
                     align="center">
         <image class="category-icon"/>
         <label class="category-name" flex="1">&paneGeneral.title;</label>
       </richlistitem>
 
+      <richlistitem id="category-search"
+                    class="category"
+                    value="paneSearch"
+                    helpTopic="prefs-main"
+                    tooltiptext="&paneSearch.title;"
+                    align="center">
+        <image class="category-icon"/>
+        <label class="category-name" flex="1">&paneSearch.title;</label>
+      </richlistitem>
+
       <richlistitem id="category-content"
                     class="category"
                     value="paneContent"
                     helpTopic="prefs-content"
                     tooltiptext="&paneContent.title;"
                     align="center">
         <image class="category-icon"/>
         <label class="category-name" flex="1">&paneContent.title;</label>
@@ -157,16 +170,17 @@
         <image class="category-icon"/>
         <label class="category-name" flex="1">&paneAdvanced.title;</label>
       </richlistitem>
     </richlistbox>
 
     <vbox class="main-content" flex="1">
       <prefpane id="mainPrefPane">
 #include main.xul
+#include search.xul
 #include privacy.xul
 #include advanced.xul
 #include applications.xul
 #include content.xul
 #include security.xul
 #ifdef MOZ_SERVICES_SYNC
 #include sync.xul
 #endif
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/in-content/search.css
@@ -0,0 +1,20 @@
+/* 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/. */
+
+#oneClickProvidersList richlistitem {
+  -moz-binding: url("chrome://global/content/bindings/checkbox.xml#checkbox");
+}
+
+.searchengine-menuitem > .menu-iconic-left {
+  display: -moz-box
+}
+
+.checkbox-label-box {
+  -moz-box-align: center;
+}
+
+.checkbox-icon {
+  -moz-margin-end: 8px;
+  max-width: 16px;
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/in-content/search.js
@@ -0,0 +1,75 @@
+/* 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/. */
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+var gSearchPane = {
+
+  init: function ()
+  {
+    if (!Services.prefs.getBoolPref("browser.search.showOneOffButtons")) {
+      document.getElementById("category-search").hidden = true;
+      if (document.location.hash == "#search")
+        document.location.hash = "";
+      return;
+    }
+
+    let list = document.getElementById("defaultEngine");
+    let currentEngine = Services.search.currentEngine.name;
+    Services.search.getVisibleEngines().forEach(e => {
+      let item = list.appendItem(e.name);
+      item.setAttribute("class", "menuitem-iconic searchengine-menuitem menuitem-with-favicon");
+      if (e.iconURI)
+        item.setAttribute("image", e.iconURI.spec);
+      item.engine = e;
+      if (e.name == currentEngine)
+        list.selectedItem = item;
+    });
+
+    this.displayOneClickEnginesList();
+
+    document.getElementById("oneClickProvidersList")
+            .addEventListener("CheckboxStateChange", gSearchPane.saveOneClickEnginesList);
+  },
+
+  displayOneClickEnginesList: function () {
+    let richlistbox = document.getElementById("oneClickProvidersList");
+    let pref = document.getElementById("browser.search.hiddenOneOffs").value;
+    let hiddenList = pref ? pref.split(",") : [];
+
+    while (richlistbox.firstChild)
+      richlistbox.firstChild.remove();
+
+    let currentEngine = Services.search.currentEngine.name;
+    Services.search.getVisibleEngines().forEach(e => {
+      if (e.name == currentEngine)
+        return;
+
+      let item = document.createElement("richlistitem");
+      item.setAttribute("label", e.name);
+      if (hiddenList.indexOf(e.name) == -1)
+        item.setAttribute("checked", "true");
+      if (e.iconURI)
+        item.setAttribute("src", e.iconURI.spec);
+      richlistbox.appendChild(item);
+    });
+  },
+
+  saveOneClickEnginesList: function () {
+    let richlistbox = document.getElementById("oneClickProvidersList");
+    let hiddenList = [];
+    for (let child of richlistbox.childNodes) {
+      if (!child.checked)
+        hiddenList.push(child.getAttribute("label"));
+    }
+    document.getElementById("browser.search.hiddenOneOffs").value =
+      hiddenList.join(",");
+  },
+
+  setDefaultEngine: function () {
+    Services.search.currentEngine =
+      document.getElementById("defaultEngine").selectedItem.engine;
+    this.displayOneClickEnginesList();
+  }
+};
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/in-content/search.xul
@@ -0,0 +1,47 @@
+    <preferences id="searchPreferences">
+
+      <!-- Suggest -->
+      <preference id="browser.search.suggest.enabled"
+                  name="browser.search.suggest.enabled"
+                  type="bool"/>
+
+      <!-- One off providers -->
+      <preference id="browser.search.hiddenOneOffs"
+                  name="browser.search.hiddenOneOffs"
+                  type="string"/>
+
+    </preferences>
+
+    <script type="application/javascript"
+            src="chrome://browser/content/preferences/in-content/search.js"/>
+
+    <hbox id="header-search"
+          class="header"
+          hidden="true"
+          data-category="paneSearch">
+      <label class="header-name">&paneSearch.title;</label>
+    </hbox>
+
+    <!-- Default Search Engine -->
+    <groupbox id="defaultEngineGroup" align="start" data-category="paneSearch">
+      <caption label="&defaultSearchEngine.label;"/>
+      <label>&chooseYourDefaultSearchEngine.label;</label>
+      <menulist id="defaultEngine" oncommand="gSearchPane.setDefaultEngine();">
+        <menupopup/>
+      </menulist>
+      <checkbox id="suggestionsInSearchFieldsCheckbox"
+                label="&provideSearchSuggestions.label;"
+                accesskey="&provideSearchSuggestions.accesskey;"
+                preference="browser.search.suggest.enabled"/>
+    </groupbox>
+
+    <groupbox id="oneClickSearchProvidersGroup" data-category="paneSearch">
+      <caption label="&oneClickSearchEngines.label;"/>
+      <label>&chooseWhichOneToDisplay.label;</label>
+
+      <richlistbox id="oneClickProvidersList"/>
+      <hbox pack="end">
+        <label id="addEngines" class="text-link" value="&addMoreSearchEngines.label;"
+               onclick="if (event.button == 0) { Services.wm.getMostRecentWindow('navigator:browser').BrowserSearch.loadAddEngines(); }"/>
+      </hbox>
+    </groupbox>
--- a/browser/components/preferences/jar.mn
+++ b/browser/components/preferences/jar.mn
@@ -26,24 +26,28 @@ browser.jar:
     content/browser/preferences/handlers.css
 *   content/browser/preferences/languages.xul
     content/browser/preferences/languages.js
 *   content/browser/preferences/main.xul
 *   content/browser/preferences/main.js
 *   content/browser/preferences/permissions.xul
 *   content/browser/preferences/permissions.js
 *   content/browser/preferences/preferences.xul
+    content/browser/preferences/preferences.js
     content/browser/preferences/privacy.xul
 *   content/browser/preferences/privacy.js
     content/browser/preferences/sanitize.xul
     content/browser/preferences/sanitize.js
     content/browser/preferences/security.xul
     content/browser/preferences/security.js
     content/browser/preferences/selectBookmark.xul
     content/browser/preferences/selectBookmark.js
 #ifdef MOZ_SERVICES_SYNC
     content/browser/preferences/sync.xul
     content/browser/preferences/sync.js
 #endif
+    content/browser/preferences/search.xul
+    content/browser/preferences/search.css
+    content/browser/preferences/search.js
 *   content/browser/preferences/tabs.xul
 *   content/browser/preferences/tabs.js
 *   content/browser/preferences/translation.xul
     content/browser/preferences/translation.js
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/preferences.js
@@ -0,0 +1,19 @@
+/* - 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";
+
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+if (!Services.prefs.getBoolPref("browser.search.showOneOffButtons")) {
+  addEventListener("load", function onLoad() {
+    removeEventListener("load", onLoad);
+    let pane =
+      document.getAnonymousElementByAttribute(document.documentElement,
+                                              "pane", "paneSearch");
+    pane.hidden = true;
+    if (pane.selected)
+      document.documentElement.showPane(document.getElementById("paneMain"));
+  });
+}
--- a/browser/components/preferences/preferences.xul
+++ b/browser/components/preferences/preferences.xul
@@ -11,16 +11,17 @@
 
 <!-- XXX This should be in applications.xul, but bug 393953 means putting it
    - there causes the Applications pane not to work the first time you open
    - the Preferences dialog in a browsing session, so we work around the problem
    - by putting it here instead.
    -->
 <?xml-stylesheet href="chrome://browser/content/preferences/handlers.css"?>
 <?xml-stylesheet href="chrome://browser/skin/preferences/applications.css"?>
+<?xml-stylesheet href="chrome://browser/content/preferences/search.css"?>
 
 <!DOCTYPE prefwindow [
 <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
 <!ENTITY % preferencesDTD SYSTEM "chrome://browser/locale/preferences/preferences.dtd">
 %brandDTD;
 %preferencesDTD;
 ]>
 
@@ -61,29 +62,33 @@
     <stringbundle id="bundleBrand" src="chrome://branding/locale/brand.properties"/>
     <stringbundle id="bundlePreferences"
                   src="chrome://browser/locale/preferences/preferences.properties"/>
 
     <prefpane id="paneMain" label="&paneGeneral.title;"
               src="chrome://browser/content/preferences/main.xul"/>
     <prefpane id="paneTabs" label="&paneTabs.title;"
               src="chrome://browser/content/preferences/tabs.xul"/>
+    <prefpane id="paneSearch" label="&paneSearch.title;"
+              src="chrome://browser/content/preferences/search.xul"/>
     <prefpane id="paneContent" label="&paneContent.title;"
               src="chrome://browser/content/preferences/content.xul"/>
     <prefpane id="paneApplications" label="&paneApplications.title;"
               src="chrome://browser/content/preferences/applications.xul"/>
     <prefpane id="panePrivacy" label="&panePrivacy.title;"
               src="chrome://browser/content/preferences/privacy.xul"/>
     <prefpane id="paneSecurity" label="&paneSecurity.title;"
               src="chrome://browser/content/preferences/security.xul"/>
 #ifdef MOZ_SERVICES_SYNC
     <prefpane id="paneSync" label="&paneSync.title;"
               src="chrome://browser/content/preferences/sync.xul"/>
 #endif
     <prefpane id="paneAdvanced" label="&paneAdvanced.title;"
               src="chrome://browser/content/preferences/advanced.xul"/>
 
+    <script type="application/javascript"
+            src="chrome://browser/content/preferences/preferences.js"/>
 #ifdef XP_MACOSX
 #include ../../base/content/browserMountPoints.inc
 #endif
 
 </prefwindow>
 
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/search.css
@@ -0,0 +1,29 @@
+/* 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/. */
+
+#oneClickProvidersList richlistitem {
+  -moz-binding: url("chrome://global/content/bindings/checkbox.xml#checkbox");
+  -moz-padding-start: 5px;
+  height: 22px; /* setting the height of checkboxes is required to let the
+                   window auto-sizing code work. */
+}
+
+#oneClickProvidersList {
+  height: 178px;
+}
+
+.searchengine-menuitem > .menu-iconic-left {
+  display: -moz-box
+}
+
+.checkbox-label-box {
+  -moz-box-align: center;
+  -moz-appearance: none;
+  border: none;
+}
+
+.checkbox-icon {
+  margin: 3px 3px;
+  max-width: 16px;
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/search.js
@@ -0,0 +1,68 @@
+/* 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/. */
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+var gSearchPane = {
+
+  init: function ()
+  {
+    let list = document.getElementById("defaultEngine");
+    let currentEngine = Services.search.currentEngine.name;
+    Services.search.getVisibleEngines().forEach(e => {
+      let item = list.appendItem(e.name);
+      item.setAttribute("class", "menuitem-iconic searchengine-menuitem menuitem-with-favicon");
+      if (e.iconURI)
+        item.setAttribute("image", e.iconURI.spec);
+      item.engine = e;
+      if (e.name == currentEngine)
+        list.selectedItem = item;
+    });
+
+    this.displayOneClickEnginesList();
+
+    document.getElementById("oneClickProvidersList")
+            .addEventListener("CheckboxStateChange", gSearchPane.saveOneClickEnginesList);
+  },
+
+  displayOneClickEnginesList: function () {
+    let richlistbox = document.getElementById("oneClickProvidersList");
+    let pref = document.getElementById("browser.search.hiddenOneOffs").value;
+    let hiddenList = pref ? pref.split(",") : [];
+
+    while (richlistbox.firstChild)
+      richlistbox.firstChild.remove();
+
+    let currentEngine = Services.search.currentEngine.name;
+    Services.search.getVisibleEngines().forEach(e => {
+      if (e.name == currentEngine)
+        return;
+
+      let item = document.createElement("richlistitem");
+      item.setAttribute("label", e.name);
+      if (hiddenList.indexOf(e.name) == -1)
+        item.setAttribute("checked", "true");
+      if (e.iconURI)
+        item.setAttribute("src", e.iconURI.spec);
+      richlistbox.appendChild(item);
+    });
+  },
+
+  saveOneClickEnginesList: function () {
+    let richlistbox = document.getElementById("oneClickProvidersList");
+    let hiddenList = [];
+    for (let child of richlistbox.childNodes) {
+      if (!child.checked)
+        hiddenList.push(child.getAttribute("label"));
+    }
+    document.getElementById("browser.search.hiddenOneOffs").value =
+      hiddenList.join(",");
+  },
+
+  setDefaultEngine: function () {
+    Services.search.currentEngine =
+      document.getElementById("defaultEngine").selectedItem.engine;
+    this.displayOneClickEnginesList();
+  }
+};
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/search.xul
@@ -0,0 +1,63 @@
+<?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 overlay [
+  <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
+  <!ENTITY % searchDTD SYSTEM "chrome://browser/locale/preferences/search.dtd">
+  %brandDTD;
+  %searchDTD;
+]>
+
+<overlay id="SearchPaneOverlay"
+         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+         xmlns:html="http://www.w3.org/1999/xhtml">
+
+  <prefpane id="paneSearch" helpTopic="prefs-search"
+            onpaneload="gSearchPane.init();">
+
+    <preferences id="searchPreferences">
+
+      <!-- Suggest -->
+      <preference id="browser.search.suggest.enabled"
+                  name="browser.search.suggest.enabled"
+                  type="bool"/>
+
+      <!-- One off providers -->
+      <preference id="browser.search.hiddenOneOffs"
+                  name="browser.search.hiddenOneOffs"
+                  type="string"/>
+
+    </preferences>
+
+    <script type="application/javascript" src="chrome://browser/content/preferences/search.js"/>
+
+    <!-- Default Search Engine -->
+    <groupbox id="defaultEngineGroup" align="start">
+      <caption label="&defaultSearchEngine.label;"/>
+      <label>&chooseYourDefaultSearchEngine.label;</label>
+      <menulist id="defaultEngine" oncommand="gSearchPane.setDefaultEngine();">
+        <menupopup/>
+      </menulist>
+      <checkbox id="suggestionsInSearchFieldsCheckbox"
+                label="&provideSearchSuggestions.label;"
+                accesskey="&provideSearchSuggestions.accesskey;"
+                preference="browser.search.suggest.enabled"/>
+    </groupbox>
+
+    <groupbox id="oneClickSearchProvidersGroup">
+      <caption label="&oneClickSearchEngines.label;"/>
+      <label>&chooseWhichOneToDisplay.label;</label>
+
+      <richlistbox id="oneClickProvidersList"/>
+      <hbox pack="end" style="margin-bottom: 1em">
+        <label id="addEngines" class="text-link" value="&addMoreSearchEngines.label;"
+               onclick="if (event.button == 0) { Services.wm.getMostRecentWindow('navigator:browser').BrowserSearch.loadAddEngines(); }"/>
+      </hbox>
+    </groupbox>
+
+  </prefpane>
+
+</overlay>
--- a/browser/components/search/content/search.xml
+++ b/browser/components/search/content/search.xml
@@ -68,16 +68,22 @@
                      onclick="handleSearchCommand(event);"
                      tooltiptext="&searchEndCap.label;"/>
         </xul:hbox>
       </xul:textbox>
     </content>
 
     <implementation implements="nsIObserver">
       <constructor><![CDATA[
+        if (!this.hasAttribute("oneoffui") &&
+            Services.prefs.getBoolPref("browser.search.showOneOffButtons")) {
+          this.setAttribute("oneoffui", "true");
+          return;
+        }
+
         if (this.parentNode.parentNode.localName == "toolbarpaletteitem")
           return;
         // Make sure we rebuild the popup in onpopupshowing
         this._needToBuildPopup = true;
 
         var os =
                Components.classes["@mozilla.org/observer-service;1"]
                          .getService(Components.interfaces.nsIObserverService);
@@ -95,29 +101,35 @@
             this.updateDisplay();
           } else {
             Components.utils.reportError("Cannot initialize search service, bailing out: " + aStatus);
           }
         }).bind(this));
       ]]></constructor>
 
       <destructor><![CDATA[
+        this.destroy();
+      ]]></destructor>
+
+      <method name="destroy">
+        <body><![CDATA[
         if (this._initialized) {
           this._initialized = false;
 
           var os = Components.classes["@mozilla.org/observer-service;1"]
                              .getService(Components.interfaces.nsIObserverService);
           os.removeObserver(this, "browser-search-engine-modified");
         }
 
         // Make sure to break the cycle from _textbox to us. Otherwise we leak
         // the world. But make sure it's actually pointing to us.
         if (this._textbox.mController.input == this)
           this._textbox.mController.input = null;
-      ]]></destructor>
+        ]]></body>
+      </method>
 
       <field name="_stringBundle">document.getAnonymousElementByAttribute(this,
           "anonid", "searchbar-stringbundle");</field>
       <field name="_textbox">document.getAnonymousElementByAttribute(this,
           "anonid", "searchbar-textbox");</field>
       <field name="_popup">document.getAnonymousElementByAttribute(this,
           "anonid", "searchbar-popup");</field>
       <field name="_ss">null</field>
@@ -299,17 +311,22 @@
 
       <method name="updateDisplay">
         <body><![CDATA[
           var uri = this.currentEngine.iconURI;
           this.setIcon(this, uri ? uri.spec : "");
 
           var name = this.currentEngine.name;
           var text = this._stringBundle.getFormattedString("searchtip", [name]);
-          this._textbox.placeholder = name;
+
+          if (Services.prefs.getBoolPref("browser.search.showOneOffButtons"))
+            this._textbox.placeholder = this._stringBundle.getString("searchPlaceholder");
+          else
+            this._textbox.placeholder = name;
+
           this._textbox.label = text;
           this._textbox.tooltipText = text;
         ]]></body>
       </method>
 
       <!-- Rebuilds the dynamic portion of the popup menu (i.e., the menu items
            for new search engines that can be added to the available list).  This
            is called each time the popup is shown.
@@ -444,56 +461,59 @@
 
           aEvent.preventDefault();
           aEvent.stopPropagation();
         ]]></body>
       </method>
 
       <method name="handleSearchCommand">
         <parameter name="aEvent"/>
+        <parameter name="aEngine"/>
         <body><![CDATA[
           var textBox = this._textbox;
           var textValue = textBox.value;
 
           var where = "current";
           if (aEvent && aEvent.originalTarget.getAttribute("anonid") == "search-go-button") {
             if (aEvent.button == 2)
               return;
             where = whereToOpenLink(aEvent, false, true);
           }
           else {
             var newTabPref = textBox._prefBranch.getBoolPref("browser.search.openintab");
             if ((aEvent && aEvent.altKey) ^ newTabPref)
               where = "tab";
           }
 
-          this.doSearch(textValue, where);
+          this.doSearch(textValue, where, aEngine);
         ]]></body>
       </method>
 
       <method name="doSearch">
         <parameter name="aData"/>
         <parameter name="aWhere"/>
+        <parameter name="aEngine"/>
         <body><![CDATA[
           var textBox = this._textbox;
         
           // Save the current value in the form history
           if (aData && !PrivateBrowsingUtils.isWindowPrivate(window)) {
             this.FormHistory.update(
               { op : "bump",
                 fieldname : textBox.getAttribute("autocompletesearchparam"),
                 value : aData },
               { handleError : function(aError) {
                   Components.utils.reportError("Saving search to form history failed: " + aError.message);
               }});
           }
-          
+
+          let engine = aEngine || this.currentEngine;
+          var submission = engine.getSubmission(aData, null, "searchbar");
+          BrowserSearch.recordSearchInHealthReport(engine, "searchbar");
           // null parameter below specifies HTML response for search
-          var submission = this.currentEngine.getSubmission(aData, null, "searchbar");
-          BrowserSearch.recordSearchInHealthReport(this.currentEngine, "searchbar");
           openUILinkIn(submission.uri.spec, aWhere, null, submission.postData);
         ]]></body>
       </method>
     </implementation>
 
     <handlers>
       <handler event="command"><![CDATA[
         const target = event.originalTarget;
@@ -531,16 +551,134 @@
       <![CDATA[
         // Speculatively connect to the current engine's search URI (and
         // suggest URI, if different) to reduce request latency
         this.currentEngine.speculativeConnect({window: window});
       ]]></handler>
     </handlers>
   </binding>
 
+  <binding id="searchbar-flare" extends="chrome://browser/content/search/search.xml#searchbar">
+    <resources>
+      <stylesheet src="chrome://browser/content/search/searchbarBindings.css"/>
+      <stylesheet src="chrome://browser/skin/searchbar.css"/>
+    </resources>
+    <content>
+      <xul:stringbundle src="chrome://browser/locale/search.properties"
+                        anonid="searchbar-stringbundle"/>
+      <!--
+      There is a dependency between "maxrows" attribute and
+      "SuggestAutoComplete._historyLimit" (nsSearchSuggestions.js). Changing
+      one of them requires changing the other one.
+      -->
+      <xul:textbox class="searchbar-textbox"
+                   anonid="searchbar-textbox"
+                   type="autocomplete"
+                   flex="1"
+                   autocompletepopup="PopupSearchAutoComplete"
+                   autocompletesearch="search-autocomplete"
+                   autocompletesearchparam="searchbar-history"
+                   maxrows="10"
+                   completeselectedindex="true"
+                   tabscrolling="true"
+                   xbl:inherits="disabled,disableautocomplete,searchengine,src,newlines">
+        <!--
+        Empty <box> to properly position the icon within the autocomplete
+        binding's anonymous children (the autocomplete binding positions <box>
+        children differently)
+        -->
+        <xul:box>
+          <xul:hbox class="searchbar-search-button-container">
+            <xul:image class="searchbar-search-button"
+                       anonid="searchbar-search-button"
+                       tooltiptext="&searchEndCap.label;"/>
+          </xul:hbox>
+          <xul:button class="searchbar-engine-button"
+                      type="menu"
+                      anonid="searchbar-engine-button">
+            <xul:image class="searchbar-engine-image" xbl:inherits="src"/>
+            <xul:image class="searchbar-dropmarker-image"/>
+            <xul:menupopup class="searchbar-popup"
+                           anonid="searchbar-popup">
+              <xul:menuseparator/>
+              <xul:menuitem class="open-engine-manager"
+                            anonid="open-engine-manager"
+                            label="&cmd_engineManager.label;"
+                            oncommand="openManager(event);"/>
+            </xul:menupopup>
+          </xul:button>
+        </xul:box>
+        <xul:hbox class="search-go-container">
+          <xul:image class="search-go-button" hidden="true"
+                     anonid="search-go-button"
+                     onclick="handleSearchCommand(event);"
+                     tooltiptext="&searchEndCap.label;"/>
+        </xul:hbox>
+      </xul:textbox>
+    </content>
+    <implementation>
+      <destructor><![CDATA[
+        // For some reason the destructor of the base binding is called
+        // automatically when the window is closed, but now when the node
+        // is removed from the DOM.
+        this.destroy();
+      ]]></destructor>
+
+      <method name="selectEngine">
+        <body><![CDATA[
+          // Override this method to avoid accidentally changing the default
+          // engine using the keyboard shortcuts of the old UI.
+        ]]></body>
+      </method>
+
+      <method name="updateGoButtonVisibility">
+        <body><![CDATA[
+          document.getAnonymousElementByAttribute(this, "anonid",
+                                                  "search-go-button")
+                  .hidden = !this._textbox.value;
+        ]]></body>
+      </method>
+
+      <method name="openSuggestionsPanel">
+        <parameter name="aShowOnlySettingsIfEmpty"/>
+        <body><![CDATA[
+          if (this._textbox.open)
+            return;
+
+          this._textbox.showHistoryPopup();
+
+          if (this._textbox.value) {
+            // showHistoryPopup does a startSearch("") call, ensure the
+            // controller handles the text from the input box instead:
+            this._textbox.mController.handleText();
+          }
+          else if (aShowOnlySettingsIfEmpty) {
+            this.setAttribute("showonlysettings", "true");
+          }
+        ]]></body>
+      </method>
+    </implementation>
+    <handlers>
+      <handler event="input" action="this.updateGoButtonVisibility();"/>
+      <handler event="drop" action="this.updateGoButtonVisibility();"/>
+      <handler event="focus">
+      <![CDATA[
+        if (this._textbox.value)
+          this.openSuggestionsPanel();
+      ]]></handler>
+
+      <handler event="click">
+      <![CDATA[
+        if (event.originalTarget.getAttribute("anonid") == "searchbar-search-button")
+          this.openSuggestionsPanel(true);
+      ]]></handler>
+
+    </handlers>
+  </binding>
+
   <binding id="searchbar-textbox"
       extends="chrome://global/content/bindings/autocomplete.xml#autocomplete">
     <implementation implements="nsIObserver">
       <constructor><![CDATA[
         const kXULNS =
           "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 
         if (document.getBindingParent(this).parentNode.parentNode.localName ==
@@ -726,21 +864,164 @@
         </body>
       </method>
 
       <!-- override |onTextEntered| in autocomplete.xml -->
       <method name="onTextEntered">
         <parameter name="aEvent"/>
         <body><![CDATA[
           var evt = aEvent || this.mEnterEvent;
-          document.getBindingParent(this).handleSearchCommand(evt);
+
+          let engine;
+          let oneOff = this.getSelectedOneOff();
+          if (oneOff)
+            engine = oneOff.engine;
+          document.getBindingParent(this).handleSearchCommand(evt, engine);
+
           this.mEnterEvent = null;
         ]]></body>
       </method>
 
+      <method name="getSelectedOneOff">
+        <body><![CDATA[
+          let list = document.getAnonymousElementByAttribute(this.popup, "anonid",
+                                                             "search-panel-one-offs");
+          if (!list)
+            return null;
+
+          for (let button = list.firstChild; button; button = button.nextSibling) {
+            if (button.hasAttribute("selected"))
+              return button;
+          }
+
+          return null;
+        ]]></body>
+      </method>
+
+
+      <method name="handleKeyboardNavigation">
+        <parameter name="aEvent"/>
+        <body><![CDATA[
+          // XXXFlorian This method could likely be shortened with a helper
+          // handling moving the selection within the one-off list and
+          // returning a boolean indicating if the event should be stopped.
+
+          let popup = this.popup;
+          if (!popup.popupOpen)
+            return;
+
+          if (aEvent.keyCode == KeyEvent.DOM_VK_DOWN &&
+              popup.hasAttribute("showonlysettings")) {
+            // If the suggestion tree is collapsed, don't let the down arrow
+            // key event reach the tree.
+            aEvent.preventDefault();
+            aEvent.stopPropagation();
+            return;
+          }
+
+          let list = document.getAnonymousElementByAttribute(popup, "anonid",
+                                                             "search-panel-one-offs");
+          if (!list)
+            return;
+
+          let selectedButton = this.getSelectedOneOff();
+
+          // If the last suggestion is selected, DOWN selects the first one-off.
+          if (aEvent.keyCode == KeyEvent.DOM_VK_DOWN &&
+              popup.selectedIndex + 1 == popup.view.rowCount) {
+            if (selectedButton)
+              selectedButton.removeAttribute("selected");
+            selectedButton = list.firstChild;
+            if (selectedButton)
+              selectedButton.setAttribute("selected", "true");
+          }
+
+          // If no suggestion is selected and a one-off is selected,
+          // UP and DOWN cycle through one-off buttons.
+          if (popup.selectedIndex == -1 && selectedButton &&
+              (aEvent.keyCode == KeyEvent.DOM_VK_DOWN ||
+               aEvent.keyCode == KeyEvent.DOM_VK_UP)) {
+            selectedButton.removeAttribute("selected");
+            if (aEvent.keyCode == KeyEvent.DOM_VK_DOWN)
+              selectedButton = selectedButton.nextSibling;
+            else
+              selectedButton = selectedButton.previousSibling;
+            if (selectedButton && selectedButton.classList.contains("dummy"))
+              selectedButton = null;
+
+            if (selectedButton) {
+              selectedButton.setAttribute("selected", "true");
+
+              aEvent.preventDefault();
+              aEvent.stopPropagation();
+            }
+            else {
+              // Set the selectedIndex to something that will make
+              // handleKeyNavigation (called by autocomplete.xml's onKeyPress
+              // method) reset the text field value to what the user typed.
+              if (aEvent.keyCode == KeyEvent.DOM_VK_UP)
+                popup.selectedIndex = popup.view.rowCount;
+              else
+                popup.selectedIndex = popup.view.rowCount - 1;
+            }
+          }
+
+          // If nothing is selected, UP selects the last one-off button.
+          if (aEvent.keyCode == KeyEvent.DOM_VK_UP &&
+              popup.selectedIndex == -1 && !selectedButton) {
+            selectedButton = list.lastChild;
+            while (selectedButton.classList.contains("dummy"))
+              selectedButton = selectedButton.previousSibling;
+            selectedButton.setAttribute("selected", "true");
+
+            aEvent.preventDefault();
+            aEvent.stopPropagation();
+          }
+
+          if (aEvent.keyCode == KeyEvent.DOM_VK_TAB) {
+            if (selectedButton) {
+              // TAB cycles though the list of one-off buttons.
+              selectedButton.removeAttribute("selected");
+              if (aEvent.shiftKey)
+                selectedButton = selectedButton.previousSibling;
+              else
+                selectedButton = selectedButton.nextSibling;
+
+              // Avoid selecting dummy buttons.
+              if (selectedButton && selectedButton.classList.contains("dummy"))
+                selectedButton = null;
+
+              // If we are out of the list, revert the text field to what the user typed.
+              if (!selectedButton) {
+                // Set the selectedIndex to something that will make
+                // handleKeyNavigation (called by autocomplete.xml's onKeyPress
+                // method) reset the text field value to what the user typed.
+                popup.selectedIndex = aEvent.shiftKey ? 0 : popup.view.rowCount - 1;
+                return;
+              }
+            }
+            else {
+              // If no selection, select the first or last one-off button.
+              if (aEvent.shiftKey) {
+                selectedButton = list.lastChild;
+                while (selectedButton.classList.contains("dummy"))
+                  selectedButton = selectedButton.previousSibling;
+              }
+              else {
+                selectedButton = list.firstChild;
+              }
+            }
+            selectedButton.setAttribute("selected", "true");
+
+            aEvent.preventDefault();
+            aEvent.stopPropagation();
+          }
+        ]]></body>
+      </method>
+
       <!-- nsIController -->
       <field name="searchbarController" readonly="true"><![CDATA[({
         _self: this,
         supportsCommand: function(aCommand) {
           return aCommand == "cmd_clearhistory" ||
                  aCommand == "cmd_togglesuggest";
         },
 
@@ -767,16 +1048,19 @@
             default:
               // do nothing with unrecognized command
           }
         }
       })]]></field>
     </implementation>
 
     <handlers>
+      <handler event="keypress" phase="capturing"
+               action="return this.handleKeyboardNavigation(event);"/>
+
       <handler event="keypress" keycode="VK_UP" modifiers="accel"
                phase="capturing"
                action="document.getBindingParent(this).selectEngine(event, false);"/>
 
       <handler event="keypress" keycode="VK_DOWN" modifiers="accel"
                phase="capturing"
                action="document.getBindingParent(this).selectEngine(event, true);"/>
 
--- a/browser/components/search/test/browser_405664.js
+++ b/browser/components/search/test/browser_405664.js
@@ -1,12 +1,15 @@
 function test() {
   var searchBar = BrowserSearch.searchBar;
   ok(searchBar, "got search bar");
-  
+
+  if (searchBar.getAttribute("oneoffui"))
+    return; // The oneoffui removes the menu that's being tested here.
+
   searchBar.focus();
 
   var pbo = searchBar._popup.popupBoxObject;
   ok(pbo, "popup is PopupBoxObject");
 
   EventUtils.synthesizeKey("VK_UP", { altKey: true });
   is(pbo.popupState, "showing", "popup is opening after Alt+Up");
 
--- a/browser/components/search/test/browser_426329.js
+++ b/browser/components/search/test/browser_426329.js
@@ -136,16 +136,17 @@ function* prepareTest() {
   yield windowFocused.promise;
 
   let deferred = Promise.defer();
   if (document.activeElement != searchBar) {
     searchBar.addEventListener("focus", function onFocus() {
       searchBar.removeEventListener("focus", onFocus);
       deferred.resolve();
     });
+    gURLBar.focus();
     searchBar.focus();
   } else {
     deferred.resolve();
   }
   return deferred.promise;
 }
 
 add_task(function testSetupEngine() {
@@ -223,56 +224,55 @@ add_task(function testShiftMiddleClick()
         "Shift+MiddleClick loaded results in new tab");
   isnot(event.originalTarget, gBrowser.contentDocument,
         "Shift+MiddleClick loaded results in background tab");
   is(event.originalTarget.URL, expectedURL(searchBar.value), "testShiftMiddleClick opened correct search page");
 });
 
 add_task(function testDropText() {
   yield prepareTest();
-  let promisePreventPopup = promiseEvent(searchBar, "popupshowing", true);
   // drop on the search button so that we don't need to worry about the
   // default handlers for textboxes.
-  ChromeUtils.synthesizeDrop(searchBar.searchButton, searchBar.searchButton, [[ {type: "text/plain", data: "Some Text" } ]], "copy", window);
-  yield promisePreventPopup;
+  let searchButton = document.getAnonymousElementByAttribute(searchBar, "anonid", "searchbar-search-button");
+  ChromeUtils.synthesizeDrop(searchButton, searchButton, [[ {type: "text/plain", data: "Some Text" } ]], "copy", window);
   let event = yield promiseOnLoad();
   is(event.originalTarget.URL, expectedURL(searchBar.value), "testDropText opened correct search page");
   is(searchBar.value, "Some Text", "drop text/plain on searchbar");
 });
 
 add_task(function testDropInternalText() {
   yield prepareTest();
-  let promisePreventPopup = promiseEvent(searchBar, "popupshowing", true);
-  ChromeUtils.synthesizeDrop(searchBar.searchButton, searchBar.searchButton, [[ {type: "text/x-moz-text-internal", data: "More Text" } ]], "copy", window);
-  yield promisePreventPopup;
+  let searchButton = document.getAnonymousElementByAttribute(searchBar, "anonid", "searchbar-search-button");
+  ChromeUtils.synthesizeDrop(searchButton, searchButton, [[ {type: "text/x-moz-text-internal", data: "More Text" } ]], "copy", window);
   let event = yield promiseOnLoad();
   is(event.originalTarget.URL, expectedURL(searchBar.value), "testDropInternalText opened correct search page");
   is(searchBar.value, "More Text", "drop text/x-moz-text-internal on searchbar");
 
   // testDropLink implicitly depended on testDropInternalText, so these two tests
   // were merged so that if testDropInternalText failed it wouldn't cause testDropLink
   // to fail unexplainably.
   yield prepareTest();
-  promisePreventPopup = promiseEvent(searchBar, "popupshowing", true);
   ChromeUtils.synthesizeDrop(searchBar.searchButton, searchBar.searchButton, [[ {type: "text/uri-list", data: "http://www.mozilla.org" } ]], "copy", window);
-  yield promisePreventPopup;
   is(searchBar.value, "More Text", "drop text/uri-list on searchbar shouldn't change anything");
 });
 
 add_task(function testRightClick() {
   preTabNo = gBrowser.tabs.length;
   content.location.href = "about:blank";
   simulateClick({ button: 2 }, searchButton);
   let deferred = Promise.defer();
   setTimeout(function() {
     is(gBrowser.tabs.length, preTabNo, "RightClick did not open new tab");
     is(gBrowser.currentURI.spec, "about:blank", "RightClick did nothing");
     deferred.resolve();
   }, 5000);
   yield deferred.promise;
+  // The click in the searchbox focuses it, which opens the suggestion
+  // panel. Clean up after ourselves.
+  searchBar.textbox.popup.hidePopup();
 });
 
 add_task(function testSearchHistory() {
   var textbox = searchBar._textbox;
   for (var i = 0; i < searchEntries.length; i++) {
     let count = yield countEntries(textbox.getAttribute("autocompletesearchparam"), searchEntries[i]);
     ok(count > 0, "form history entry '" + searchEntries[i] + "' should exist");
   }
@@ -297,9 +297,8 @@ add_task(function testClearHistory() {
 add_task(function asyncCleanup() {
   searchBar.value = "";
   while (gBrowser.tabs.length != 1) {
     gBrowser.removeTab(gBrowser.tabs[0], {animate: false});
   }
   content.location.href = "about:blank";
   yield promiseRemoveEngine();
 });
-
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -410,16 +410,23 @@ These should match what Safari and other
   is a fundamental keybinding and we are maintaining a XP binding so that it is easy
   for people to switch to Linux.
 
  -->
 <!ENTITY searchFocus.commandkey       "k">
 <!ENTITY searchFocus.commandkey2      "e">
 <!ENTITY searchFocusUnix.commandkey   "j">
 
+<!-- LOCALIZATION NOTE (searchFor.label, searchWith.label):
+     These two strings are used to build the header above the list of one-click
+     search providers:  "Search for <used typed keywords> with:" -->
+<!ENTITY searchFor.label              "Search for ">
+<!ENTITY searchWith.label             " with:">
+<!ENTITY changeSearchSettings.button  "Change Search Settings">
+
 <!ENTITY tabView.commandkey           "e">
 
 <!ENTITY openLinkCmdInTab.label       "Open Link in New Tab">
 <!ENTITY openLinkCmdInTab.accesskey   "T">
 <!ENTITY openLinkCmd.label            "Open Link in New Window">
 <!ENTITY openLinkCmd.accesskey        "W">
 <!ENTITY openLinkInPrivateWindowCmd.label "Open Link in New Private Window">
 <!ENTITY openLinkInPrivateWindowCmd.accesskey "P">
--- a/browser/locales/en-US/chrome/browser/loop/loop.properties
+++ b/browser/locales/en-US/chrome/browser/loop/loop.properties
@@ -301,17 +301,17 @@ rooms_list_copy_url_tooltip=Copy Link
 ## http://developer.mozilla.org/en/docs/Localization_and_Plurals
 ## We prefer to have no number in the string, but if you need it for your
 ## language please use {{num}}.
 rooms_list_current_conversations=Current conversation;Current conversations
 rooms_list_delete_tooltip=Delete conversation
 rooms_list_deleteConfirmation_label=Are you sure?
 rooms_list_no_current_conversations=No current conversations
 rooms_name_this_room_label=Name this conversation
-rooms_name_this_room_tooltip=Click to edit the room name
+rooms_name_this_room_tooltip2=Click to edit the conversation name
 rooms_name_change_failed_label=Conversation cannot be renamed
 rooms_new_room_button_label=Start a conversation
 rooms_only_occupant_label=You're the first one here.
 rooms_panel_title=Choose a conversation or start a new one
 rooms_room_full_label=There are already two people in this conversation.
 rooms_room_full_call_to_action_nonFx_label=Download {{brandShortname}} to start your own
 rooms_room_full_call_to_action_label=Learn more about {{clientShortname}} »
 rooms_room_joined_label=Someone has joined the conversation!
--- a/browser/locales/en-US/chrome/browser/preferences/preferences.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/preferences.dtd
@@ -10,16 +10,17 @@
 <!-- When making changes to prefWindow.styleWin test both Windows Classic and
      Luna since widget heights are different based on the OS theme -->
 <!ENTITY  prefWinMinSize.styleWin2      "width: 42em; min-height: 37.5em;">
 <!ENTITY  prefWinMinSize.styleMac       "width: 47em; min-height: 40em;">
 <!ENTITY  prefWinMinSize.styleGNOME     "width: 45.5em; min-height: 40.5em;">
 
 <!ENTITY  paneGeneral.title       "General">
 <!ENTITY  paneTabs.title          "Tabs">
+<!ENTITY  paneSearch.title        "Search">
 <!ENTITY  paneContent.title       "Content">
 <!ENTITY  paneApplications.title  "Applications">
 <!ENTITY  panePrivacy.title       "Privacy">
 <!ENTITY  paneSecurity.title      "Security">
 <!ENTITY  paneAdvanced.title      "Advanced">
 
 <!-- LOCALIZATION NOTE (paneSync.title): This should match syncBrand.shortName.label in ../syncBrand.dtd -->
 <!ENTITY  paneSync.title          "Sync">
new file mode 100644
--- /dev/null
+++ b/browser/locales/en-US/chrome/browser/preferences/search.dtd
@@ -0,0 +1,17 @@
+<!-- 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 defaultSearchEngine.label             "Default Search Engine">
+
+<!ENTITY chooseYourDefaultSearchEngine.label   "Choose your default search engine. &brandShortName; uses it in the location bar, search bar, and start page.">
+
+<!ENTITY provideSearchSuggestions.label        "Provide search suggestions">
+<!ENTITY provideSearchSuggestions.accesskey    "s">
+
+
+<!ENTITY oneClickSearchEngines.label           "One-click search engines">
+
+<!ENTITY chooseWhichOneToDisplay.label         "The search bar lets you search alternate engines directly. Choose which ones to display.">
+
+<!ENTITY addMoreSearchEngines.label            "Add more search engines…">
--- a/browser/locales/en-US/chrome/browser/search.properties
+++ b/browser/locales/en-US/chrome/browser/search.properties
@@ -1,14 +1,23 @@
 # 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/.
 
 searchtip=Search using %S
 
+# LOCALIZATION NOTE (searchPlaceholder): this is shown in the searchbox when
+# the user hasn't typed anything yet.
+searchPlaceholder=Search
+
+# LOCALIZATION NOTE (searchHeader): this is displayed at the top of the panel
+# showing search suggestions.
+# %S is replaced with the name of the current default search engine.
+searchHeader=%S Search
+
 # LOCALIZATION NOTE (cmd_pasteAndSearch): "Search" is a verb, this is the
 # search bar equivalent to the url bar's "Paste & Go"
 cmd_pasteAndSearch=Paste & Search
 
 cmd_clearHistory=Clear Search History
 cmd_clearHistory_accesskey=H
 
 cmd_showSuggestions=Show Suggestions
--- a/browser/locales/jar.mn
+++ b/browser/locales/jar.mn
@@ -126,16 +126,17 @@
     locale/browser/preferences/preferences.dtd        (%chrome/browser/preferences/preferences.dtd)
     locale/browser/preferences/preferences.properties (%chrome/browser/preferences/preferences.properties)
     locale/browser/preferences/privacy.dtd            (%chrome/browser/preferences/privacy.dtd)
     locale/browser/preferences/security.dtd           (%chrome/browser/preferences/security.dtd)
 #ifdef MOZ_SERVICES_SYNC
     locale/browser/preferences/sync.dtd               (%chrome/browser/preferences/sync.dtd)
 #endif
     locale/browser/preferences/tabs.dtd               (%chrome/browser/preferences/tabs.dtd)
+    locale/browser/preferences/search.dtd             (%chrome/browser/preferences/search.dtd)
     locale/browser/preferences/translation.dtd        (%chrome/browser/preferences/translation.dtd)
 #ifdef MOZ_SERVICES_SYNC
     locale/browser/syncBrand.dtd                (%chrome/browser/syncBrand.dtd)
     locale/browser/syncSetup.dtd                (%chrome/browser/syncSetup.dtd)
     locale/browser/syncSetup.properties         (%chrome/browser/syncSetup.properties)
     locale/browser/syncGenericChange.properties         (%chrome/browser/syncGenericChange.properties)
     locale/browser/syncKey.dtd                  (%chrome/browser/syncKey.dtd)
     locale/browser/syncQuota.dtd                (%chrome/browser/syncQuota.dtd)
--- a/browser/modules/UITour.jsm
+++ b/browser/modules/UITour.jsm
@@ -123,22 +123,59 @@ this.UITour = {
     ["quit",        {query: "#PanelUI-quit"}],
     ["search",      {
       query: "#searchbar",
       widgetName: "search-container",
     }],
     ["searchProvider", {
       query: (aDocument) => {
         let searchbar = aDocument.getElementById("searchbar");
+        if (searchbar.hasAttribute("oneoffui")) {
+          return null;
+        }
         return aDocument.getAnonymousElementByAttribute(searchbar,
                                                         "anonid",
                                                         "searchbar-engine-button");
       },
       widgetName: "search-container",
     }],
+    ["searchIcon", {
+      query: (aDocument) => {
+        let searchbar = aDocument.getElementById("searchbar");
+        if (!searchbar.hasAttribute("oneoffui")) {
+          return null;
+        }
+        return aDocument.getAnonymousElementByAttribute(searchbar,
+                                                        "anonid",
+                                                        "searchbar-search-button");
+      },
+      widgetName: "search-container",
+    }],
+    ["searchPrefsLink", {
+      query: (aDocument) => {
+        let element = null;
+        let searchbar = aDocument.getElementById("searchbar");
+        if (searchbar.hasAttribute("oneoffui")) {
+          let popup = aDocument.getElementById("PopupSearchAutoComplete");
+          if (popup.state != "open")
+            return null;
+          element = aDocument.getAnonymousElementByAttribute(popup,
+                                                             "anonid",
+                                                             "search-settings");
+        } else {
+          element = aDocument.getAnonymousElementByAttribute(searchbar,
+                                                             "anonid",
+                                                             "open-engine-manager");
+        }
+        if (!element || !UITour.isElementVisible(element)) {
+          return null;
+        }
+        return element;
+      },
+    }],
     ["selectedTabIcon", {
       query: (aDocument) => {
         let selectedtab = aDocument.defaultView.gBrowser.selectedTab;
         let element = aDocument.getAnonymousElementByAttribute(selectedtab,
                                                                "anonid",
                                                                "tab-icon-image");
         if (!element || !UITour.isElementVisible(element)) {
           return null;
--- a/browser/modules/test/browser_UITour.js
+++ b/browser/modules/test/browser_UITour.js
@@ -216,18 +216,23 @@ let tests = [
     gContentAPI.showHighlight("urlbar");
     waitForElementToBeVisible(highlight, checkDefaultEffect, "Highlight should be shown after showHighlight()");
   },
   function test_highlight_search_engine(done) {
     let highlight = document.getElementById("UITourHighlight");
     gContentAPI.showHighlight("urlbar");
     waitForElementToBeVisible(highlight, () => {
 
+      let searchbar = document.getElementById("searchbar");
+      if (searchbar.getAttribute("oneoffui")) {
+        done();
+        return; // The oneoffui removes the menu that's being tested here.
+      }
+
       gContentAPI.showMenu("searchEngines", function() {
-        let searchbar = document.getElementById("searchbar");
         isnot(searchbar, null, "Should have found searchbar");
         let searchPopup = document.getAnonymousElementByAttribute(searchbar,
                                                                    "anonid",
                                                                    "searchbar-popup");
         isnot(searchPopup, null, "Should have found search popup");
 
         function getEngineNode(identifier) {
           let engineNode = null;
--- a/browser/modules/test/browser_UITour_availableTargets.js
+++ b/browser/modules/test/browser_UITour_availableTargets.js
@@ -36,17 +36,17 @@ let tests = [
         "help",
         "home",
         "loop",
         "devtools",
         "pinnedTab",
         "privateWindow",
         "quit",
         "search",
-        "searchProvider",
+        "searchIcon",
         "urlbar",
         ...searchEngineTargets(),
         ...(hasWebIDE ? ["webide"] : [])
       ]);
 
       ok(UITour.availableTargetsCache.has(window),
          "Targets should now be cached");
       done();
@@ -67,17 +67,17 @@ let tests = [
         "help",
         "loop",
         "devtools",
         "home",
         "pinnedTab",
         "privateWindow",
         "quit",
         "search",
-        "searchProvider",
+        "searchIcon",
         "urlbar",
         ...searchEngineTargets(),
         ...(hasWebIDE ? ["webide"] : [])
       ]);
 
       ok(UITour.availableTargetsCache.has(window),
          "Targets should now be cached again");
       CustomizableUI.reset();
@@ -87,17 +87,17 @@ let tests = [
     });
   },
 
   function test_availableTargets_exceptionFromGetTarget(done) {
     // The query function for the "search" target will throw if it's not found.
     // Make sure the callback still fires with the other available targets.
     CustomizableUI.removeWidgetFromArea("search-container");
     gContentAPI.getConfiguration("availableTargets", (data) => {
-      // Default minus "search" and "searchProvider"
+      // Default minus "search" and "searchProvider" and "searchIcon"
       ok_targets(data, [
         "accountStatus",
         "addons",
         "appMenu",
         "backForward",
         "bookmarks",
         "customize",
         "help",
--- a/browser/modules/test/browser_UITour_panel_close_annotation.js
+++ b/browser/modules/test/browser_UITour_panel_close_annotation.js
@@ -55,17 +55,17 @@ let tests = [
         ok(tooltip.state == "showing" || tooltip.state == "open", "The info panel should have remained open");
         done();
       }, "Highlight should have disappeared when panel closed");
     }, "Highlight should be shown after showHighlight() for fixed panel items");
   },
 
   function test_highlight_panel_click_find(done) {
     gContentAPI.showHighlight("help");
-    gContentAPI.showInfo("searchProvider", "test title", "test text");
+    gContentAPI.showInfo("searchIcon", "test title", "test text");
     waitForElementToBeVisible(highlight, function checkPanelIsOpen() {
       isnot(PanelUI.panel.state, "closed", "Panel should have opened");
 
       // Click the find button which should close the panel.
       let findButton = document.getElementById("find-button");
       EventUtils.synthesizeMouseAtCenter(findButton, {});
       waitForElementToBeHidden(highlight, function checkPanelIsClosed() {
         isnot(PanelUI.panel.state, "open",
--- a/browser/themes/linux/jar.mn
+++ b/browser/themes/linux/jar.mn
@@ -57,16 +57,21 @@ browser.jar:
   skin/classic/browser/pageInfo.png
   skin/classic/browser/page-livemarks.png
   skin/classic/browser/pointerLock-16.png
   skin/classic/browser/pointerLock-64.png
   skin/classic/browser/Privacy-16.png
   skin/classic/browser/privatebrowsing-mask.png
   skin/classic/browser/reload-stop-go.png
   skin/classic/browser/searchbar.css
+  skin/classic/browser/search-pref.png                      (../shared/search/search-pref.png)
+  skin/classic/browser/search-indicator.png                 (../shared/search/search-indicator.png)
+  skin/classic/browser/search-indicator-add-engine.png      (../shared/search/search-indicator-add-engine.png)
+  skin/classic/browser/search-engine-placeholder.png        (../shared/search/search-engine-placeholder.png)
+  skin/classic/browser/badge-add-engine.png                 (../shared/search/badge-add-engine.png)
   skin/classic/browser/Secure.png
   skin/classic/browser/Security-broken.png
   skin/classic/browser/setDesktopBackground.css
   skin/classic/browser/slowStartup-16.png
   skin/classic/browser/theme-switcher-icon.png
   skin/classic/browser/Toolbar.png
   skin/classic/browser/Toolbar-inverted.png
   skin/classic/browser/Toolbar-small.png
--- a/browser/themes/linux/preferences/preferences.css
+++ b/browser/themes/linux/preferences/preferences.css
@@ -15,16 +15,24 @@
 radio[pane=paneMain] {
   -moz-image-region: rect(0px, 32px,  32px, 0px)
 }
 
 radio[pane=paneTabs] {
   -moz-image-region: rect(0px, 64px, 32px, 32px)
 }
 
+#BrowserPreferences radio[pane=paneSearch] {
+  list-style-image: url("chrome://browser/skin/search-pref.png");
+}
+
+.checkbox-check {
+  -moz-appearance: checkbox;
+}
+
 radio[pane=paneContent] {
   -moz-image-region: rect(0px, 96px,  32px, 64px)
 }
 
 radio[pane=paneApplications] {
   -moz-image-region: rect(0px, 128px,  32px, 96px)
 }
 
--- a/browser/themes/linux/searchbar.css
+++ b/browser/themes/linux/searchbar.css
@@ -62,8 +62,183 @@
 menuitem[cmd="cmd_clearhistory"] {
   list-style-image: url("moz-icon://stock/gtk-clear?size=menu");
 }
 
 menuitem[cmd="cmd_clearhistory"][disabled] {
   list-style-image: url("moz-icon://stock/gtk-clear?size=menu&state=disabled");
 }
 
+
+
+
+.searchbar-search-button-container {
+  -moz-box-align: center;
+  padding: 2px 3px;
+  -moz-padding-end: 2px;
+}
+
+.searchbar-search-button {
+  list-style-image: url("chrome://browser/skin/search-indicator.png");
+  -moz-image-region: rect(0, 20px, 20px, 0);
+  margin: -2px -2px;
+}
+
+.searchbar-search-button:hover {
+  -moz-image-region: rect(0, 40px, 20px, 20px);
+}
+
+.searchbar-search-button:hover:active {
+  -moz-image-region: rect(0, 60px, 20px, 40px);
+}
+
+searchbar[oneoffui] .search-go-button {
+  list-style-image: url("chrome://browser/skin/reload-stop-go.png");
+  -moz-image-region: rect(0, 42px, 14px, 28px);
+}
+
+searchbar[oneoffui] .search-go-button:hover {
+  -moz-image-region: rect(14px, 42px, 28px, 28px);
+}
+
+searchbar[oneoffui] .search-go-button:hover:active {
+  -moz-image-region: rect(28px, 42px, 42px, 28px);
+}
+
+searchbar[oneoffui] .search-go-button:-moz-locale-dir(rtl) > .toolbarbutton-icon {
+  transform: scaleX(-1);
+}
+
+
+.search-panel-current-engine {
+  border-top: none !important;
+  border-bottom: 1px solid #ccc;
+  -moz-box-align: center;
+}
+
+.search-panel-header {
+  font-weight: normal;
+  background-color: rgb(245, 245, 245);
+  border-top: 1px solid #ccc;
+  margin: 0 1px;
+  padding: 3px 5px;
+  color: #666;
+}
+
+.search-panel-current-input > label {
+  margin: 0 0 !important;
+}
+
+.search-panel-input-value {
+  color: black;
+}
+
+.search-panel-one-offs {
+  margin: 0 0 !important;
+  border-top: 1px solid #ccc;
+}
+
+.searchbar-engine-one-off-item {
+  -moz-appearance: none;
+  display: inline-block;
+  border: none;
+  min-width: 48px;
+  height: 32px;
+  margin: 0 0;
+  padding: 0 0;
+  background: none;
+  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAWCAYAAAABxvaqAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gofECQNNVW2/AAAABBJREFUGFdjOHPmzH8GehEA/KpKg9YTf4AAAAAASUVORK5CYII=');
+  background-repeat: no-repeat;
+  background-position: right center;
+}
+
+.searchbar-engine-one-off-item:not(.last-row) {
+  box-sizing: padding-box;
+  border-bottom: 1px solid #ccc;
+}
+
+.searchbar-engine-one-off-item.last-of-row {
+  background-image: none;
+}
+
+.searchbar-engine-one-off-item:hover:not(.dummy),
+.searchbar-engine-one-off-item[selected] {
+  background-color: Highlight;
+  background-image: none;
+}
+
+.searchbar-engine-one-off-item > .button-box {
+  border: none;
+  padding: 0 0;
+}
+
+.searchbar-engine-one-off-item > .button-box > .button-text {
+  display: none;
+}
+
+.searchbar-engine-one-off-item > .button-box > .button-icon {
+  display: -moz-box;
+  -moz-margin-end: 0;
+  width: 16px;
+  height: 16px;
+}
+
+.addengine-item {
+  -moz-appearance: none;
+  border: none;
+  height: 32px;
+  margin: 0 0;
+  padding: 0 10px;
+}
+
+.addengine-item > .button-box {
+  -moz-box-pack: start;
+}
+
+.addengine-item:first-of-type {
+  border-top: 1px solid #ccc;
+}
+
+.addengine-item:hover {
+  background-color: Highlight;
+  color: HighlightText;
+}
+
+.addengine-item > .button-box > .button-icon {
+  width: 16px;
+}
+
+.addengine-item > .button-box > .button-text {
+  -moz-box-flex: 1;
+  text-align: start;
+  -moz-padding-start: 10px;
+}
+
+.addengine-item:not([image]) {
+  list-style-image: url("chrome://browser/skin/search-engine-placeholder.png");
+}
+
+searchbar[oneoffui] .searchbar-engine-button {
+  display: none;
+}
+
+.search-panel-tree > .autocomplete-treebody::-moz-tree-cell {
+  -moz-padding-start: 16px;
+  border-top: none !important;
+}
+
+searchbar[oneoffui] .searchbar-engine-image {
+  -moz-margin-start: -1px;
+}
+
+.search-setting-button {
+  -moz-appearance: none;
+  border-bottom: none;
+  border-left: none;
+  border-right: none;
+  -moz-border-top-colors: none;
+  min-height: 32px;
+}
+
+.search-setting-button:hover {
+  background-color: #d3d3d3;
+  border-top-color: #bdbebe;
+}
--- a/browser/themes/osx/jar.mn
+++ b/browser/themes/osx/jar.mn
@@ -95,16 +95,25 @@ browser.jar:
   skin/classic/browser/privatebrowsing-mask-short@2x.png
   skin/classic/browser/reload-stop-go.png
   skin/classic/browser/reload-stop-go@2x.png
   skin/classic/browser/searchbar-dropmarker.png
   skin/classic/browser/searchbar-dropmarker@2x.png
   skin/classic/browser/searchbar.css
   skin/classic/browser/Search.png
   skin/classic/browser/Search@2x.png
+  skin/classic/browser/search-pref.png                         (../shared/search/search-pref.png)
+  skin/classic/browser/search-indicator.png                    (../shared/search/search-indicator.png)
+  skin/classic/browser/search-indicator@2x.png                 (../shared/search/search-indicator@2x.png)
+  skin/classic/browser/search-indicator-add-engine.png         (../shared/search/search-indicator-add-engine.png)
+  skin/classic/browser/search-indicator-add-engine@2x.png      (../shared/search/search-indicator-add-engine@2x.png)
+  skin/classic/browser/search-engine-placeholder.png           (../shared/search/search-engine-placeholder.png)
+  skin/classic/browser/search-engine-placeholder@2x.png        (../shared/search/search-engine-placeholder@2x.png)
+  skin/classic/browser/badge-add-engine.png                    (../shared/search/badge-add-engine.png)
+  skin/classic/browser/badge-add-engine@2x.png                 (../shared/search/badge-add-engine@2x.png)
   skin/classic/browser/Secure-Glyph.png
   skin/classic/browser/Secure-Glyph@2x.png
   skin/classic/browser/slowStartup-16.png
   skin/classic/browser/theme-switcher-icon.png
   skin/classic/browser/theme-switcher-icon@2x.png
   skin/classic/browser/Toolbar.png
   skin/classic/browser/Toolbar@2x.png
   skin/classic/browser/Toolbar-inverted.png
--- a/browser/themes/osx/preferences/preferences.css
+++ b/browser/themes/osx/preferences/preferences.css
@@ -27,16 +27,22 @@ radio[pane=paneMain] {
 } 
 
 /* ----- TABS BUTTON ----- */
 
 radio[pane=paneTabs] {
   -moz-image-region: rect(0px, 64px, 32px, 32px);
 }
 
+/* ----- SEARCH BUTTON ----- */
+
+radio[pane=paneSearch] {
+  list-style-image: url("chrome://browser/skin/search-pref.png");
+}
+
 /* ----- CONTENT BUTTON ----- */
 
 radio[pane=paneContent] {
   -moz-image-region: rect(0px, 96px, 32px, 64px);
 }
 
 /* ----- APPLICATIONS BUTTON ----- */
 
--- a/browser/themes/osx/searchbar.css
+++ b/browser/themes/osx/searchbar.css
@@ -42,27 +42,221 @@
   -moz-margin-start: 2px;
 }
 
 .search-go-container {
   -moz-box-align: center;
   -moz-padding-end: 6px;
 }
 
+.searchbar-search-button-container {
+  -moz-box-align: center;
+  -moz-padding-start: 6px;
+  -moz-padding-end: 4px;
+}
+
 .search-go-button {
   list-style-image: url("chrome://browser/skin/Search.png");
 }
 
+.searchbar-search-button {
+  list-style-image: url("chrome://browser/skin/search-indicator.png");
+  -moz-image-region: rect(0, 20px, 20px, 0);
+  margin: 0 -3px;
+}
+
+.searchbar-search-button:hover {
+  -moz-image-region: rect(0, 40px, 20px, 20px);
+}
+
+.searchbar-search-button:hover:active {
+  -moz-image-region: rect(0, 60px, 20px, 40px);
+}
+
+searchbar[oneoffui] .search-go-button {
+  list-style-image: url("chrome://browser/skin/reload-stop-go.png");
+  -moz-image-region: rect(0, 42px, 14px, 28px);
+}
+
+searchbar[oneoffui] .search-go-button:hover:active {
+  -moz-image-region: rect(14px, 42px, 28px, 28px);
+}
+
+searchbar[oneoffui] .search-go-button:-moz-locale-dir(rtl) > .toolbarbutton-icon {
+  transform: scaleX(-1);
+}
+
 @media (min-resolution: 2dppx) {
   .searchbar-engine-image {
     list-style-image: url("chrome://mozapps/skin/places/defaultFavicon@2x.png");
   }
 
   .searchbar-dropmarker-image {
     list-style-image: var(--searchbar-dropmarker-2x-url);
     width: 7px;
   }
 
   .search-go-button {
     list-style-image: url("chrome://browser/skin/Search@2x.png");
     width: 14px;
   }
+
+  .searchbar-search-button {
+    list-style-image: url("chrome://browser/skin/search-indicator@2x.png");
+    width: 20px;
+    -moz-image-region: rect(0, 40px, 40px, 0);
+  }
+
+  .searchbar-search-button:hover {
+    -moz-image-region: rect(0, 80px, 40px, 40px);
+  }
+
+  .searchbar-search-button:hover:active {
+    -moz-image-region: rect(0, 120px, 40px, 80px);
+  }
+
+  searchbar[oneoffui] .search-go-button {
+    list-style-image: url("chrome://browser/skin/reload-stop-go@2x.png");
+    -moz-image-region: rect(0, 84px, 28px, 56px);
+    width: 14px;
+  }
+
+  searchbar[oneoffui] .search-go-button:hover:active {
+    list-style-image: url("chrome://browser/skin/reload-stop-go@2x.png");
+    -moz-image-region: rect(28px, 84px, 56px, 56px);
+    width: 14px;
+  }
 }
+
+.search-panel-current-engine {
+  border-top: none !important;
+  border-bottom: 1px solid #ccc;
+  border-radius: 4px 4px 0 0;
+}
+
+.search-panel-header {
+  font-size: 10px;
+  font-weight: normal;
+  background-color: rgb(245, 245, 245);
+  border-top: 1px solid #ccc;
+  margin: 0;
+  padding: 3px 6px;
+  color: #666;
+}
+
+.search-panel-current-input > label {
+  margin: 0 0 !important;
+}
+
+.search-panel-input-value {
+  color: black;
+}
+
+.search-panel-one-offs {
+  border-top: 1px solid #ccc;
+  margin-bottom: 0 !important;
+}
+
+.searchbar-engine-one-off-item {
+  -moz-appearance: none;
+  display: inline-block;
+  min-width: 48px;
+  height: 32px;
+  margin: 0 0;
+  padding: 0 0;
+  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAWCAYAAAABxvaqAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gofECQNNVW2/AAAABBJREFUGFdjOHPmzH8GehEA/KpKg9YTf4AAAAAASUVORK5CYII=');
+  background-repeat: no-repeat;
+  background-position: right center;
+}
+
+.searchbar-engine-one-off-item:not(.last-row) {
+  box-sizing: padding-box;
+  border-bottom: 1px solid #ccc;
+}
+
+.searchbar-engine-one-off-item.last-of-row {
+  background-image: none;
+}
+
+.searchbar-engine-one-off-item:hover:not(.dummy),
+.searchbar-engine-one-off-item[selected] {
+  background-color: Highlight;
+  background-image: none;
+}
+
+.searchbar-engine-one-off-item > .button-box > .button-text {
+  display: none;
+}
+
+.searchbar-engine-one-off-item > .button-box > .button-icon {
+  -moz-margin-start: 0;
+  width: 16px;
+  height: 16px;
+}
+
+.addengine-item {
+  -moz-appearance: none;
+  font-size: 10px;
+  height: 32px;
+  margin: 0 0;
+  padding: 0 10px;
+}
+
+.addengine-item > .button-box {
+  -moz-box-pack: start;
+}
+
+.addengine-item:first-of-type {
+  border-top: 1px solid #ccc;
+}
+
+.addengine-item:hover {
+  background-color: Highlight;
+  color: HighlightText;
+}
+
+.addengine-item > .button-box > .button-icon {
+  width: 16px;
+}
+
+.addengine-item > .button-box > .button-text {
+  -moz-box-flex: 1;
+  text-align: start;
+  -moz-padding-start: 10px;
+}
+
+.addengine-item:not([image]) {
+  list-style-image: url("chrome://browser/skin/search-engine-placeholder.png");
+}
+
+@media (min-resolution: 2dppx) {
+  .addengine-item:not([image]) {
+    list-style-image: url("chrome://browser/skin/search-engine-placeholder@2x.png");
+  }
+}
+
+searchbar[oneoffui] .searchbar-engine-button {
+  display: none;
+}
+
+.search-panel-tree > .autocomplete-treebody::-moz-tree-cell {
+  -moz-padding-start: 22px;
+  border-top: none !important;
+}
+
+#PopupSearchAutoComplete {
+  border-radius: 4px;
+}
+
+.search-setting-button {
+  -moz-appearance: none;
+  border-radius: 0 0 4px 4px;
+  min-height: 32px;
+}
+
+.search-setting-button[showonlysettings] {
+  border-radius: 4px;
+}
+
+.search-setting-button:hover {
+  background-color: #d3d3d3;
+  border-top-color: #bdbebe;
+}
index a833dde7c5fa4787e2681219ae198021ed6628e1..e42a3f71aa79195061e0f82a3f6f5932937e5bbd
GIT binary patch
literal 4749
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
btNwog_Hb;Lkmbvc00000NkvXXu0mjf9c4Sg
index e890cd9e6746f9541323f1ddb3be33a8ed164343..eea84f566aae0c17455f3b81bd29f73fd7d593ce
GIT binary patch
literal 11707
zc$^hkbyU<%8~rUycej*)q_ngw-LQ0b2`H(u^it9i(%taVUDBO`N=kQ2N-eM--~2Ik
z&YUyPoIB6GcP0|5p@@e~jST<*p0bjhHUNO&&wXA@^yiw=rz+sNq53Fq_)*8z{-c+b
zhaDho>uPPsp!~tg!A{%G%GTR`)J_5bxXqO1q;+9`PRuZ1WP{|ZSD~cDN(_WPa6*Pg
zhE6msLO;VE1_`Y?cv$IFZ~-aksPK<;PcR%M3I(M=SF0#W34<)@D_iFm<_@Ik6mx&O
zuh-|(Re0KC*X2t6_l5?CsVrn;`s{1d*1S>ORx=_KfQ^!Lh;#x;<`QPIvD;TNpBZTI
z3mdc^g%K<>XwmvS4L~sgWYNj~&qA_ui9NV|j;LpeAEP36OWz5PiUj4y7i<ND!2ee)
z);BbW@9pl=0cMte!jWQR9wly^%TLQca;4TNw>CLrqJ>@Cc2e?WfYv?$xFH5qMn*@y
z33GjwiGH!ZHCw2cuF%MlFuL$)cQr(`<Xh}9@9^CFzUJht@ZFfcshA)G&4P1XG1jD*
z+`&7LQ9q@Q;hT1iN_7eZ1x`7(ll$N0Hno^oj66)mjT?fz%f$DmvPcKZK>90$%N0`L
zVV;!q+AC0@R5SN=2*UftjR*P-?69JyOJ#74F=G<?Up{|ROXS&mh6sRd0Un%&B9toI
zW*`Wxzm>_uG}#2XPIJn*0u1yva_D=x{Xj;8@6F$$@r^FcED`A&zp+YW<LOAkORBK)
zKPz}D^{?5r&%DH`(9O5QuRjdd^`CdzOaH^eb``Ato<b_l{x<xg`!Jk7AmV}MD3lj4
zc3mE(bJxTmpz{NNk8%zqS0N<@FpKFsJ{`?P@iO?L#0(d@M*keLpMEo~|6q<Tnhrah
z`A;#=!bufQXz4VG00U<h#3oo{Q8Tf4CsRRZbDyp6kWYxyS+^&9o~UV}Iw3Dwg1yjz
z5Uw+a-V|;V4pSA-@H$sez=xK0jI*m!^~^Uc<mDgMTBM$C3%RzfXl>UU3m!(ccA43C
zWyA54uWcy6<XnbO+Q;LM*T;)S%oQ4T$i3Xazd_eBP2EOXpabwSqNz1}hmt<WH(xVm
zv0wA;oh=Eic8nx2IR(U*-rgK9{wCZylhnUf34QtzT=@`<aKc2b1_Q4buyL2FEU}jA
zi$1U|e}fs`EVb1+{w@il6aRcH<-!?Ao>d9Pz~@39H%#S#oajkV(E2VX?sr?(0xCQr
zw<QQu`Z8zejYf(C_WX%^#i_^p3|mE)^K}0Nm3H5<X<prtNVLp7CE`FuOxku7;^_P(
zqrfRkC$DUsy@tQO;4F+~@@eZ8VX$##C7oGUrCR0x^OasI2PHl`^l1lkk)qLN_$#|e
zXw=JstQfRRU>)nS<MN02An)~;C9Maa;GFahkDW2>V<OZs$T|mbywt)&7qhfMAn!zi
z`a?S3qS(jAwc}iY6n%#I5p19pgFWof`@u9NK7RWB#rCMC%x#>~ur+R$1(tJ#0%+VD
z;EGb%?-y-A@V3@?J_GDS0a;3f7+%wgiheivj!%LP`68TaW&0J7ccwsFc6?OR9Y7)j
zKROvh{>T=8wdHrA%Ve7##6J$7IQ{k&iLKIdXlMCvI8W+PIxuZ{>CV91n}sAi#qDr*
z0RZA=yM6v0asY*QU2K8U>z7Uv-*%7jwu9iA03jehC$B#cp?4C_v})g9Unj{6X~SH5
zA7uF=>Bh$Gy<N+&Hr4gXk}$r^QzXyhS%E}@<qpr_C#NJ%gV&G!1X6ye%EfC%*Y!W=
zn`+Yz$@4leda1M7Z%BeuZrB4;ZwliYNWG0)%_<)Rdir%%w=p_a5YMr^Ug_|@{Ky1c
z%~MJtxZqUnmoSpR5e#n-@PKi?tSOR!6!qM_vgTpp(GB)h6V|S+g?hbs>(_d~qWuum
zI&3l>7pt%ZA!MR)b`$Xy{HY;nB@g5^%j#DeCIkm?dCA_XGSp(3t2v|dE-71c0+?TV
zBpB&9uv|+uvRwv{lkPvK%xa79;uN)Q(apBzOk7VYbt)+qlAGE`dvYXwhqge0PBR3Y
zgJlpS!oMuG>IteZXlP7)A8yY(v1p4w*Yjb%DL~@k^xcQEOcT!k_=VG^rT{>0>YeAS
z@59XD_t#r-Qmk+<sf=^7q49fyx3_t&#>U1pw5ymi@c*=&oDPLBHLv^mGAFi)AYG1+
z_y62o#xZTriLgUN5(2Ld7D5Q#E<p8Dl5oGo)SUlXWt0j^pU1not8H;-h=^_drIFbE
z2I#T5>%RWu%;GjFuaEsg%oZ)NQy^Y73v+9OB=j(a4c^o4+Wpv^vW?Y>0u03SvZa)U
z682oI#UKyiPO^~U1!x+@G25nIg??;-^K?@WJa=d7+#;q=9sQX_I#B`3FHsC^94dE|
zDDc5n4T&-~Hg-Y5#<@(_u0;|8w-%8UbQ<)LH!yzghYyc7d9gy@>0vKlMNC}xXZTl5
z<3I^YEomhjhQ?!QgaaV?(zJ@J^kE=&`lJcnFl0q$TG|3}h+jtf!$$g*CrJ`x>dFY4
zI|q`KUq--=8O#On-=xjnZDU!|k{gO(u2X}I));OuHva3-T)813d8I*`ER;bHFu;fP
zP-FRcu>Cl(`B(j~ek!`Y>Zh2|EwE2dPtVR<w@~O7hK*uPd{}D!pf$Pc!J`ilf>gV6
zZG-k0t{;g^7dI?diNNDKXPQ!vf)0r569GNU;U8f*-fA`P&eu-6A1=muwbyU6IYZEg
z`9dDB0PJlL5E{6-@UH+>+Yt`=^GpK1mbJ%8=(4YG>%XZ8JlZ|>3u%VVHfWN6mL`n(
z#?y6cJ+;vvz7~F38uJ%p?+JyVWTE&9g~2l+Z!-@{vj?4MV4Gc`$O~2m;%+F<-Jdu5
z+g(YFEiAd1m#`o`>LPGkRKL(hOYbrr>)mOZq;E5)IndWS`*YXI!j?{-eZ>UDBpn1b
z-02AibL`3d?RuT}OKU8|ZaqU(W^o*Q4U_QtbPbutGZcpgK)+jIBAfVhmMMKJ(DA6{
zlJ#Px|1F+Xjee0)e^Te4EmKW>oxLuau}hGb>FXK5s`QD=1Oy>sJA5jaLCH@m@bs=K
zBU(O4|BR}IXfPco2llxENh)>?92^-KP-pzaj7NN?4FqLON#2-x!F%4^`59W02qJZt
zQ45&<i(d3+IuQJV#^yhnA!HN#Hxq(wx%^}DN$V4?dR+@)S3MNpE1!VAkZ1eg1@NKo
z#-OeyD)n;H{m1X5_rvGDBD4artmal0>}YxJ)S399eSdA4rGVQNJZeFPqblOz(dc(~
z#XdpCPjb10tBMfle`Ig6e0xS@!uXHY`vkCt8q&5Z9%LgsnMcLFr3<UL-g`^Mv^!w;
z^k6CsST-*DQxkQh71N@4&;Tg6MvBs-ntWPM72iJ{eSR4?MSaYYvQ?XuSI?y*s8!{X
z%%R5*pjc2gh1b;{{t!QnNxcA};Q+PpRhx0vbn%ne{WM(|rH&q2Bq*<S39yt$N68Lr
zra0`=LP0HSe%quNM<>iM)Ji_AV>FEh4B1Xf{rk=M&No=AJKylS*=40Ya@|`&K|yD1
zi}FP@g6c4u^F67n!gq_!29VKVJ<1pURyy*(q-VPX0y(nj^!yohYQ>2nUYY4xmV~qe
zPhMx=!*C&jAk6tr{14TrD@SLds3DsDvG>vO`zBn!-La=c<KyyezU7;)3DiURrgQ(D
zr=vpN{P~9aCm~RxVaw;vqW$B6|M4IUg6p%P!8R4EPu|SHk^03T_fYeQ-a8d`<)1ov
z?oU0sXdEyCf+hYHaQIQ_U|r|xe^8w2vKKE#C9W(M#}_4KW4M=Wf2ShL?jk;NcB61&
zeZ=Yw`U}801kT~Z&VebqTBU`A_{za<Es)A@o7vpmh`--=r=*a6>|LT_CCtR}^b63A
zW&lVz$1PP^3--v1Xzum*qn*=poeoj!+;EXXsVO=A)8ri9^D-j>snJj&n#?UF3}RSs
zKdO%Ig)E~4wdTDte5hGZ!>)W6!QqE|ys3$Ptb7;7(m0T6n`W-X<TaxYQ(e%9fYb&~
z9oL6H)AVHG75m5SlXR5RyhF*E_5P??bX7)-BZwuKOk80tWm}gF9y}b4e8wq_ndeXp
z)s0((Tyi+b?|o#O=ic?)O|G<eV%!unCR|D}c}?W{>{YHGKV{wi62lrs@m_p1?-rhM
zz@yX-NJXz)_kd&M4%L4|K85>E{7<0C<yyx#2uv+Ib|{Ff7wS9aNI8NE4DcUoVP;EO
z6_w?`T(#QKROw_s>c@P8yKToHbBCl%;h~;#j3(!%ww-w`(a>^dSZv3=j1I4hG46#v
z6!V^SQIOXXGHatl{)2V3QR-5u*BAO_1MqZ6I~wNw^}hjtSKU)&abU?m@n7)u)II_<
z=#3g}B4l5|ltiX1@#L)FP4Or>&73<-AJ`F!1FUPkkFY2$TxsaKpy&6bUZ0^1X~Ykp
z|1=hO;PXoK++m*PG6n;9FfDx2Oy}RRp9~OXd_jZ9d9Gjh^bO-E<R>A#)mOdIS0xO2
zM*5k6PNG$OIRE#W&rubIdrW+V=j}=iS@)UwJ6dflyUx4IJpz_Or68oDRT49Tos?8<
z{TLNsKyco!E~5g}u62NR|JhWTR$+VnPVR^YNjcTT@$7{Iez;p`5F}5#{|jE`FAj|R
z&wS={XAM{e3GyreF9~g@CFo?;nuP*2sQt%#OO!|B^GOA(f<?L6>k|O-ja5Af)T0u#
zz*2Zk1r(T}!x<!Us}=m=7lvpRRh+lJJfUYGLv#Wr<r(MI4)2xxfi7W@JzR8;4An;*
z-^2e(%lkIPx6zSW@=ZjIy%bNX`uhP%n6ED3zu$8lu>n6#3$J_UX#`hL+2x^;J)VcQ
zGl3HQ>2E3Vq+zQey0-+2w~uwhbVp;#!%^?;<_tSv=e%NHWn?f7W>PwcyzTj3SkSbU
zoO3)V8XjRu!9bujze{yd%B;X?p)+r3KaO9bp=ZB@ZdilS>bV9A>DQ=rk1N@=i<H#y
z5d-hqsRMXEe5u9HXHyXx*?gt29$d^_&S!{vhYOUAp4Nz+F$0*3wO0M=_QB!WZOu&5
zOkg<nA{x+=)Lyeq06;dI`IEk<TTfgUFyK`Qu?43;A6At6OCGHX{VIN4yiaXs7VX0)
z=jZ3ef{3FoSmh_&_C<vgrjH)6{kGN%&)#8mwM>2FwDj$Wnh4jD9=61&w4DyU27iim
z7-|0)JD&2Xk*<v2Y3Ggp?712Yg|y){LC#!h8=n6BR*`erI6xQyy?B(#A7`*c#Z*9m
zQe?A2gVd6mMle!}47<&xZA>SuPT5z>oQB7lTv1^E5tg6~A!!r<z_l?fVt|wlu-ps=
z;BEs5fqzPzX|Wk|M|TPZSil5b3=P20q_~sTm>n$St>QPfcJTXMw^>1}6q_nJZwm-c
zp4~4rH{RiHdG`>OCuk3M?MgXLSZ9fsfl|h|>4Wu?_o+<G2yza@Qt~YaLFS}>UFbdT
z;<in%fE$dLVZpbTm@s`WEf!+i_0Q*y@*nYWOATU%ut*1u+gZ(M{PVQ?-swf(K8xXM
z?D5A?GAY7lvmP?GNLm+SRpQ@GV?rPPG!otOrb>u`b0SqJP=cZ`?IfK(NiGj3c&+)j
z1dm(gLC>5L(oNShC}5^OUD3$x$1~jdUIDI6VgU0g`Hl88FB2QRVNON)6LHiP3J|<T
z2mgW(>qP~sQ!aqNAoy%gk^~%cpu|;3*1WQFB_V;w_!_AE<An_r#aNAUb?)W(wlkow
zF0RQ5q}2_L^w)mIkLcQZYX%0`>O5LYPhYSpvB;}3!1w4*WGN2r1`_IpsNx+gJGtO_
z_@UNqG?%1*GliVzqLpZQ3jE8-v)(z}UmZ;8(9Fy!()(ZGa*UIc{Gu_Vu}YrJ_+v_J
zyqhP<Qnj+%pwlC3(M(8Kc1F(_OGA3^L+5P&XoB$k5&YJca3ZRcwh}33_Wd)rBT9x0
zJ6VlZp~8!i2fB)*0@r!Rzv>cK+hPm*{JLjA-?tH~E3|kzzCTkBQgI`4I+Gh}#?S7V
z&9P8KGA6=X`}UPwv3j<bv{*A~2c0Yd;2Dr{(a<pA$qs^-udC8QP%9s*?T3}mf4zeb
z$%%)IV*$XU=1b;(UDtcZY8-bemjbhYm)kCzpl@ha&;k7?XaBkjyKzOoLkx7-n<Wgw
zygd?}ievFRAEnzG*~-s?dg+#dvekjr{ZnCG!g5R(E`~}=Rrgo{E<t^#j7>TQE~T2e
zZ(C&1hau>5;~#oCjeex0&hNpyO5hm750ehbk7905FThfZ9H<zUe#_++@l)J?a=*=4
zt5^CGZL+%%>EK(Q=Hp64Ew0{chIak?Oc*SXEHok$*em`rxLB<%X=oZm?<4+0nZ1z=
zfP6`zo;j)+&Pu?xx1vS^&XO|0O1qRG$g>RAne4#H1$tDVk9fdG?r^{jJy<mMl~K~V
zTDuf`!W`vrQ4&2%*p2`Ye-U2MJ{P&kD`u{Fe~E=kSm2gOlIP16)p|JZk;xXFJ*LMh
zB#LgVKc0K0{k4M0=_f6=VPg2ieXKtMR68$_X7KZMj)YFi5-USB!QG>-3pl?uta7G9
zG8_V*7cci~*etA>QVx{3f3u*9lq6%T{hVs@kA4<L&pS0SH%~n0pJv}V03XJIlS%$6
zM?xD<o!_c;B?`lqiPnd2Xm`)!Z#8nEiLc_<OR%e`k#|#pVwgNV5ex>Ixv<U1cay!^
z*!GMJ`+1QHDn5(#cIo(%fTs5W^692qjP=_%`6bM43JfLtC<&xt<<J4gxLo1@!0CdX
ztypJesPPIi&OnL7ND_V47V-8`T31JN)W}p^@oL2Y$V-!A4-}6YGLRnxJJNAu{Y3@N
z-b>Ayy~4oWl&|)EJ*IC%$(hIWzA0WtMc)4o)(~J*RVFOrXp}KUbP{^*<@B8t_9mv9
zJs0Q5yWYMtN0%*muzk>>1?!?|AsX$3s)b{U%2Ot1E7ZDHzE~R`tj!!S#Bg)dsE4$o
zJoyOavs)0(Fp<mWIxzQy+O=Ym%nvaM-cIxcfnBXadIS;<yOEEllZJi%fCsZ{e(+z_
z5wB(dSBxSL)|AcXL{!2aD}+F#aou0@g){YMZ3Dclxx!8qVlct*tL0HpUQTy+xh2ze
z1_og1W<V9W0s!CX01$kYiI?e)GI=XIJ`RBBoMM=Agvs*E)rlHPj#;j>f0B*4#oEZl
ztEfUNsR}<LRpaG6)21x)%KV4HGt;V`+Bo4HLJpQqD;28do7!LA8Be`wfZ@+*F#kXf
zD$(^slaK}kdtJUHN?N41rmw8=ymif7z=-=$qe1lB*jP##;dO`z?>be$RBJpZc^aRi
z54r5R;Fs#@_f@Gj85IE5*(q>HB>cc`1km`>lh>1xSSU5-<Ts-?X*fXIcz&<gF(d1l
zKPxXKRM{DPfj_GBZ3<(`qJ;$g0tLA8Q?Y)l{c;=BoTi3;l>g1Dq75x4YzLaNw9M85
z2}Si~4KYjN)Pt-7kQ$MHbnt*~1_7W}d*Es%62sD<x8kb*M*x#<<Sh!o=*E)!`?4<Y
zFBrR~W^$pd)SeD!qN)FGFSfdW^(X7JVqU^+Aj7^RTX-)txW?L&hwq4jyFbXrTpH#?
zm@T{4$5Ap3_NL8L#-bd3!M<<R|D~x8`j+k#jc&PS23<yh=4WYPfg~_rNAyx*dg*`~
z0|P@C9I>LJl6m9MdswtXlQI2PZO)N^%JijCS{pQ;^z(V;Rm87R+=1fK@tbhD+m_MM
z(Z()c9Vf7joyba@hO+;Oe2N4X?8>)p)>FZ1K<Vo%j8;@Y-mQCUVyKgWt;-$TN@V=V
z>fefpF?U+-iTr#IEIsZF`svz@$uK~YB`G4oU=WsNHzVvsU@lW>@5v|B;0<hlS~osT
zuS97lnnD_1qXbXvf|NXYWcVD4SXq6!1)Sm}WGm%U`XB}a$=(1eU{9c}=|j+?W_199
zH2Ig(_3S|20)S+=TWbZ65gr%WlMyKS=eZyiRL7T~U!EkZYzA+=?w;QVeOyFwo%>;3
z*^&g97EN0hv|4U;_g89*{tQSU;<xfu$hCQ!h=iYn)l019KVtJ>wnyL0I?Y#`nbhy^
z1TYXiNt|j%M?|~}E!y|<mLk1W?8x<CIVdah9R~pG4iI2H@mP5)&8h12ms^t<p7`@!
z`9ppC>-+1nlIF_q^L+R?U4@ko2Rf|$%#G0$3YTnJ56F%myzx?=jHhGKXWn&l@+h6O
z*u;O*jgGIRwhJkCCnN5Fi_A_G=5Z<9jd6S>hMG4fc%;sZEB)VYqa0l(QBy#WsdthW
zGHz?nO7$2<1*{9H@j6fS1bgBFBEmS}8-r<lUcd0$r0(CPG@;F(`w~SMZk7}QHWU`V
zD{Xd-0eK9uh{az3+xbCh?)4j=udCZ59}1dBqrO;o8H@)$=FSuA8{X3akRQPw=>Puz
z{E-^UqH*$5=AF_&v4^MyM<-5jpKN0;@dBoN({`jD`^{QlpyCB_(c5grgUuD%Ar%c}
zWyh%APVK(}0R&rJKK6h5w6mCQ?La^dA)!Qq%j&IkF3|RJ-@#5^KEaZYfRS*cN&lnk
zYK}0wq4}Hsc|t<&31O|8s~zVcP1kpUW+bmrSAVK1>?!x0H^+K2t<IrDZTlJMZF876
z!WI#G(=Q|mMcJn=sQSnQC9afTjjY;6Q}n+d6d&`g587HahCG7@tS1$Z^{90qJ&sL5
z1X#-90trgL%rw7+bx7hqhI~Q+L~gi}7HC_StNQx;P2d@bZv_Pf#@ByWzSI0YG5F~U
z6YByXMMS`YUXe!Ju&2*ZP%-5IITX8-{HKaEjggzi>G-~122aoVdI9-`ClLT~SuF;s
zsZe5d{=E2<523iYSI!}`%vYmlF)DP{&Y}U=Q*)jtfxze=Nz74leQ{IlX`1H}>ztgO
zVXB$MZ}(*EeLNF0?f;Z)-C&~;^a!}{{r4Xoe7}rLq@c=ybWhF{gZfyV(dJ>Q)+ZoI
zpm#y(k`Id(PIYAWu2;<U9%bXrn3+5zNPE<l_35%>8l6s$z;*AZYIf~AJ7sa~8A~DP
zo#e!hjkWb50DG(DH@W3idquJC88&Gk=OS&shi?D^$f1D(3epT0ZwI~V8@q2eqn!*l
zY8xnkeYnb3vGOPj*6%<M!IdC!;;E-2gVBfC2c?;SPf6_Nu^3&_S4()$sqf?GQS50n
zQB*kaSyol&?ggG-3!+%1^;$Y9rP(fenIkFr*(WZSTzcE4&j!=_v$fzA3rAwmvaFWd
zBoFl_tyvNpe#KHMUcj#WqHNGPol5fSc2RZ<Zr9GwYHFrwUOs@qVbPVIti(cTL(c&N
zs5x`A&&0Z$Ht`^v!jvD9tA<GaUh03`W4=wWzp7+BO4rr0`6L-LT8x|4#f3o>F>3q4
zw)5oy{kbHK`O=3*>Q_m~*Y|NLGKwyFQsf*RXx&rZ;`Hl3e`#P2Zu<j$I1DfIRI<fB
zW%RLS?d^&O#X<n@qH3<a6rL~VSU?OA6bk6{9rfQIa8Xt|2wr;un1U@Rq=lE+&q?Y%
zX5TRe9gKl2MN4$R^-;y`j<XZ_gg6;J@xlRkmBQPLZ%-0sfp~{+to<jijzlW*5E@fY
zCoOBNs=P+M_edNdUY_8r)4<R}*9fJ?ve^%h?Ii!<Jv*%~IHwOYCWKbMHrIN6xc*lK
zej5zeU+m?NVh^i{;Oddc@8$l8>rS+>&)r3N1TRhHcruhB5ufUr0K&B`s{?%fjb~>;
zU-8k$1U;yaHSV&`f}zbP;i4qjxT?}!dL$5c<~`S-Gz|<&b|u37Ay!kx108I56cpz$
z`4NqcW|&U!k78c<)TRC2FK?wQ1GF{OX(4x4S*VKnFe|XVL(2?iMC1ABh#d!u>Xrsp
zZA;#^9a91wyo>SYHp5>(prGYC22W6wXk_2>aOKSYvHwn24+bo+a1ZVmuXb5{tWalR
zh)m1J7b%Dn0ssn9d-;@kasvjotGqRHhz5WDH2<n6wT;ZX(wEWC>Gwg%TK#ls^3L6}
zI>EE5QTtT&Bmu<#ky3U=0mm0HZ2vw>P^7z~@b<d+m!E`SK$XkS`N)O#D~eo;1Yz|r
z4g}~AcC|0e)7D+o1rx}{j}PuUs2jVJATk+TFG!!HxUY4TIbiciwh;lG0Q}VhdQB<T
z->rx!+PpX&b^8Ec2~oozTLb5}Px0$7W3npTp732yRBybgJDmT^0ERxPOn<MI9+szR
zT?NaOK-C44?_S>8DqZj?438s&2*RbFZf#H=P`9mI;$a`jA9F(;;%&iz9Exz3thX{P
z3j??<cTv@>5>pS7IUSeo0*6}w>pQ6yE<uD)iUu2As2I~1uMg6oXHs+l;A5W{MvQJJ
z^q^;LA1krpw*b(G&C%DF`=!YTy|+)&@e@7edk0Iom|qub$v%4j|Bx_TyVSddJJTxu
z@&XKgCCyz}*cT*z&-)Y;Fnhi!!J-}s6L*|;m<ovM)Hx_~S<|YEOTs<3Sk=U`_3jP|
z^HDJDzy=sn?AfBBqjGvwgH7GN4((bdjiF!sc+RRbr)56x-_Vzz$mYM^U@k7^3PQ@e
z|4`}d8)~}g=`Rp_y8YASJRg?)77v*%p!1{vSn}FOuxX0W1DYxg9CN?_!w+~rof|iG
zdgixD3R*9?_rGTPCQ_<PF)rO0q$o&RU#l&D{u}2j;TC-ezdkmO{rYlh)eq@{j&NZ@
zC<>6Nl<|02QPV7UE%qBX-3rf)z@W9ttcdjj188-WHdO&2^gr^hpRks1I4W%ZTg@7y
z8RcjYBcH!U146Z9cYAZc{0sOSk0{%F#nqk5Agk-F>5M3HbEFAV)|Qo#p=L7Wi^Rnf
zcq%-Zt!;MQ%hIH(7Qw3jIWNN2Vpbki#jvf&iUts>3JknFPVa>m%mlJ^eiM085B*dy
zU??N6#nOi7o|XMXvhGf%A1w1A1pwk>F}aNsBHY3}G9HE`<>DUfB<zu2_dYMvP>!HN
z#lN`UfwA?6bl7>QsF-a?3($c_%g=Pxe2~ko&)q*M@$CuO#zc#4-)J0$hlL6GUoSeG
z8rR#7LP^opg1tm(<}D(orq-1;7~|nu{uVMaGB`Qw3Xerz<-$XvJohLl%>X2!KHt#T
zW@pm4aUsctVf)vnsqo529gfiakjc+4!0=h1iHQuSPX(06^A-f429&h~K$U`CF$!&q
zG|cx#P;#`L<2f347)j`wjz354e(+9zr18NG%q&me>pvMR)Q0A9&PklJ#%)-;Zl{(v
zw%)6iQ(;?Bl%6H%cDVVe@R{xIXhUpYZ66c*Gb!Jr^$GgJ;&mOIRUOSfx&m&ZBXNFR
zOaLnX8V7WLQUjTPycg76pz;dSud5&J&SFf@kPmxHI22IKB6!Jis^f=|jiJPt#(Tob
zXAw-wWS(%(LrHm~k;c2>7&`lfksXP?`=SHPa{pSNkuC%!IiW0-Uc`1JKIcX4MwWt~
zi+W5XKBhpIto%z4<iB~vHT_6Ca#9e49zSYB+1f7smC(XMTa;Z(ot(_Z{0>5G!*js<
zU)}K_j)rs(F|aN(2E>C?omtbwhPJ>*bb<m=9subcCpc9ydpceJgY6+54UMXBq8uIE
zvh2a~fJ7bH<+jl$oDbWTfqD3W0FVS^rm&G&knpoRXqve7`;n58eD|{(7c`0}Z7uCl
zsm2?(&t8Nx;}{`48HI>Tj4|i&Uecwr)1?BC-?It^yKkYeQg>5RQ_p6n!}@5`s5`Pg
ziSK2V8itx5=@KjF&+ZJ|Gn4PA6EYsXkh>tbPS~ldHY&hJ6$uf*`zDym#(^wM>bG&8
zy(H%_9J9FpWkKyriFiR)Q7hqtVU=U<^O!eJ!d1BVE)cILkhyQHrRl>`vuGSRvCyY-
z`ADGH`HpjVuIv7=f+mhipaf?d;eB>R)95{S=p$F#{ymysp9WwEft00m+v`b$vyC?_
zmqe(@u;!m})=KLnPO<j_GB(9Ic!Zcj8J{Xqfo*F(>o-M%DQaoSIPsLIINfAvOHW}G
z=B-3H{GX@=-$7Y7owCmZ6|<H=W3bRg@DNR+xz)Ba>iC(1cP<G4|L%jn<4dm^ap>wK
zmx5Wf#}qn@2k_EZ60TEq{8bjEJF`RlJMseGiUf1fZN4H3q(49FC$O06`__}&#Kw0}
z?B4=F3`;f=IZYGLB*Ll?{J*Xq8NlWd^P4OeZPq<SXQ$d(ZaDL_T`F1xfC710CE<hm
z{ShY$d|fEW(n$AjW65-e9x}m;iec~|1PV%Kq~XVBqtW-VpwTnz^ZXBY$|fcKYdqGL
z`02N?*t!p)EK>9e3mE%I%8}D?x!bqY=DW=Md>J4Af%U-uHS&<a?Zw88ioig8>L)@7
zVebX)EB0%-lr1^sjp1{FxNT3SriVci$A_7aa2qrflk^tGF#rxb0^Bd%+OGc{&K@1A
zBy$u8rF+^Ajjx5hf@{`ucpm6<TOilBPnCw$hHcBK9}zdM7_RHWcd%!zM>ps=^H0N4
zuBuPzNVEJ;oy{;V<{xyv>4)b#zHb*98Hu+L%*LTdt2^MUcw}#D+en(C*<e3u%m>v?
zO0vZTD}G>3D;bND_8V?mK?N3xv2B95#z-goJ_tq1zZFiwP~<}5&sV0t)<*%zaCGIZ
z5Gwaa($%^k2+V9Ca~tvZ`zdSI_wh<(ZTs*!B_j)|!cGpQIFA3mFMgk9|IQn-oM=OZ
zqK|DJJHOc1LO$0Yn;O&@TosjvZ$IX7o$X0}wcPgR#|L^aF$WTth$Mb68Ku0u^Flo(
z*w_mBxKX5yg1SCQaE6ZZi=RkZ1psv0RP9k`*>v8o#k6(t8~gpjwbG@eO}f!Jc(DfO
z1{grW>w#gE-ZTSgG+R4+u@B0E!yxk?l9Un{@@xLj#F4CUfblw6zAv^I=FLL4&8S^g
zB$D%+DFCdG#vIS_+cV_ftth8jokA4MJItY(y|UWdXAs~yGfD+Pq%du<-FV@sXzkOA
zs?Rc7#Ha0Z=6e)4+aL>PJqPQ~ike5^sg(8hmWUtgDn5D4mXGMk%OM^;E4)oPKjN1E
zI1tuPm|>EK(@U$+i#t4aE3!@-0|M`t`+1(cO5N0AANM8SOX$U4QoaS?PgGQ+4P5g<
z{OkKMY*eU+K41{LU^yy4^elAC74mUk#k8neeqJqo$Ts^ffXVV{dd7T@0`rI^D5?5K
z;+U1!9OuSDhvv(~I6kqQt|L;&YwOxm1OUjFRg#-e`0Abjs<y<|Pb9p>T`zrU2OFa;
zo(M64at*s2=sgZ4tu+>ISqJf_-BE2RIm5v%p(GxQF22sD=xXWtV1u*QPARTeB!KDH
zObj5e=UPlJ;Heg}^Vm_Aojo`sw-8%-=2T_e<Rpvb=^_yA0jXRb^ZedRDSkkz;r=U7
zH?3+gbi@Uh&Ccj=$osL5c;$psM~JuF$RlFJ^>LpRxAF=%a0(@^#mX!Pt9AE9mI<*u
zR-FPPDLtsi!y|o=_-7yp6zYRGN|uVbar9G5;sBuikt1miefO*R4q0ReR7Y3Rz0~5t
z_vfXeU&{*Qz~f2mI=Cvwj>7O!3Y_51bQ?BqM9c1bP^Cm_TEi35e|q7`fgM54FG6Wm
z4XO?EI@EFXnbksp<9uXm=<8|Ao<Vn5SxORbMRi)o_W}S=u@5r&5?gaoC`C`wJmh?B
z@S9YXG<AKzN{n>@PhoI1P}Gq_CW5iH*?D^DIP02zy^dc%Kp><O>${$z{audjHS3`b
z+N?c+<Q3FwKQy&=<d2%ED>!CmZF;YP6?;W@W9t(4<C63?&Rl;_1}LXPsfH`|>sObt
zEw0#_Y&J3$!>Sbv2EY;xrR>Z%O$JtWZvx`k6`IH_vl|A-Z-pnDG`~-m=2`x7#$Cig
z%$BA%0<OHq&{~os9B^fK_r6*2S{sQfE3&3d2$iIEF;T@Fx(>e5#od><ZDN&_?93o&
zaFi_y)$}f5p7dLsCxowYfAk;gg|sR%f^LKMNv>DQyaO>R{jz__@V!IEOkTc)YZWT2
z;F{Y}G?rGlJ&0CH{OQdXW|s)s#Jv&{3Cd{+W*)LIGM@Q4|J1*~sJT<9E&3l1oGS`l
z#RHQyjLcKA`3H@apPA~Zeb4(t#JP4-DHbi^SAR0mP{$%g$oQE*M@P1SBmM5UgnT|r
zQiYeYx_alAXp`#AH@|PGcbXnr=EG>b`JMoP-qVRstVeCnx4gH5^EHK`AqZ|b%^9Rs
z+^k#iXJl#y%7IfkG*UvXcx5<A#;MO0heg`*O?*!sUL`?+miqI3AUTLi#z6Q?7VCG`
zR0&=}Ju*SNekOw6$`CzIOrliQM>X-OABRU<opmb$i*qAtzD*khmuQL_p?D;SIxb2^
zxhi}xmBZY~hNIB*DI=8VZIvrEzxB`+!F+WYRxQaQ7ySLVpK|0@9qD%8P1my;y}8d-
zKMyp<z=710&V5o%B{OCAEoWKmFB_m!|D+G|z<TG;9r#NZ{A8YcGrME+`*yi}S)b}U
zar4$VKci0@JCzcMfiMK^$dQ&L?IEI4E&@{k1`|B@_jpnDoxu#}kWHaM;pGv1UXu}a
zZsW#xcwYNPQR;m!7YP0w#X?V#ZrB4`#57s!Mc!!>SN;2OqcxMyS*c0-Uq@jwottvU
zgl(vKBtx}mB8FyJtn=fyH$?Z$bhD6I6N(AaY=A)JZV|yDb$_XhRY>3po)K@TSD7X?
zzpcvSk|`cb1lZM*MslQmw6(R-$G*7sGym5W!P)&4vuB=C(Zo{sM8?pHefKD4(E4*f
zG(?JUXihdwYpK(u#pT1%Y=uEI;-Haso(4Y3l2i~?nWig~KHyU*aa3Vj67^s~HD?#O
zJZ!zJK-xmZ!D8_t-1&9gG4^T%|4$fqcZ{HlfHxv-%!j;>KgK$g9W&~>7bV#yM^D85
zZ~9w2r%eZ^${kG=l{b;U5uSw(dblQd6WclLNmBl$NWmkDAmnf1bL~@R{nmry<Tq`o
zGlt{2RT*PZoZ6RhimZKbre(v(n)D%ZPk%bu`qbB~hO;|-`qAF{k;6G={gW<%Xbh;%
zcRNWN#sSL3Y4UWFYw|{Rttl49RF$HYOy4H}$gXnj^N{1Ouv`Nl$%4rinsOJL`l9c%
zV&!7Rzx$>Q1Cn-oN%eaelRB^<f^6r+2lKqX2r{}nyT>v}b&>jnv4&+uU3m(!D?GT!
z>3vVqUYFdxR{mjs?9W6y?hBdGiRf}#<FX$9<N+&VK6myM1a$#f2L-!tjl%ta(9|_Q
zD)7<`_t(nzT~gqw`n7*8^K>09=2L+occAvSns14IdX@z#?W{Uz6f#=KB5tThX*4<f
zIBirXhBOYJ%My)vVjj=oNYwZ{Y%?dVl9}reYQc5bz4Vz146k~!7zHf1J5le_QFy=`
z6tl7gJ~Fxjq3@6#tzAoVy3)UQ@|5(r4g<4H7ugp(vJQ}A_uQ+jrhePNb5WMpkgJxl
G4E`TjRR3TA
--- a/browser/themes/shared/incontentprefs/preferences.inc.css
+++ b/browser/themes/shared/incontentprefs/preferences.inc.css
@@ -28,16 +28,20 @@ treecol {
 .category-icon {
   list-style-image: url("chrome://browser/skin/preferences/in-content/icons.png");
 }
 
 #category-general > .category-icon {
   -moz-image-region: rect(0, 24px, 24px, 0);
 }
 
+#category-search > .category-icon {
+  -moz-image-region: rect(0, 194px, 24px, 168px);
+}
+
 #category-content > .category-icon {
   -moz-image-region: rect(0, 48px, 24px, 24px);
 }
 
 #category-application > .category-icon {
   -moz-image-region: rect(0, 72px, 24px, 48px);
 }
 
@@ -61,16 +65,20 @@ treecol {
   .category-icon {
     list-style-image: url("chrome://browser/skin/preferences/in-content/icons@2x.png");
   }
 
   #category-general > .category-icon {
     -moz-image-region: rect(0, 48px, 48px, 0);
   }
 
+  #category-search > .category-icon {
+    -moz-image-region: rect(0, 384px, 48px, 336px);
+  }
+
   #category-content > .category-icon {
     -moz-image-region: rect(0, 96px, 48px, 48px);
   }
 
   #category-application > .category-icon {
     -moz-image-region: rect(0, 144px, 48px, 96px);
   }
 
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..226b7bf2b4c11ecc60006121eefda07edff3d57a
GIT binary patch
literal 425
zc$@*L0apHrP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0004SNkl<Zc-pm)
zOG^TA6vZbfh^UW{VMXa8BZU@OE&2{Ed(gXxh;pHe9$%tWRBkG?{b+BJ62b}+Y9}~l
z7-K@KXa@0ij|=Jl*J@)2eq8RkXU;IA{ELXFm)U1hjDd+A{$CGPGaFgsg#y|-t;Ppv
z@z#M^*x}>O)cjPi`S2d0<vSP6$806Q#~rzH54+z!Q?zvBqPgq#BG9*;?@mGvd7;2C
zjNoo!g=V8|0+8(OCDw@Z2SPzEm&<r#eKdX9DgeozFV;_-f0aLhW+FD4xM-o@ggbKi
zeBKlaOw-JIu6k(f%qjrMo+s)i&g(*fuInNHqmM?9n*<=)Lk@YNKn;ZlGat`1bz-OC
zu%!q~*l|Y=d7+@TuAx4e)B^YVIZYnfX-I7>0Y2`?A+N~l=<I6Nw5K56uod^x!f7{+
zs8-Cv4j*^qlyc(MD#o(C;~!6_(}(y`_}iG+;p2{+B1`@p#>zMtCnk3IN~QG$pfj!?
T>A^eA00000NkvXXu0mjf=M%?R
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..abf084aade08cd6c9a71f9c375ddbb54ab5f9d45
GIT binary patch
literal 888
zc$@)v1Bd*HP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80009&Nkl<Zc-qaE
zOGs2v9L6JDOoE$M5$aUd%n+sFqzelKt5x)%+Lc+FuPlkMhXs{Ui)d3~FoTqo*3Ly_
zr8b#fANeR#6QPk19n;dnF*S9Z?!WU5e*_nE@0m%m4}N%^^Zmc`IUX+eE+e8PWx+3o
z(6E0=PzB&K3C;@~f+4{y;A;o3nHIGGn-c{J$xFe^Ulm}JL0}W8NS*SIlQQyz?7i7^
zr7MZfypN{5b}QZJ-i^<&=JT*ro;3tqfDJ1JO-S<mo}sECJDqEfqf>1bE#MJeo0yp<
zRui(M3-Ds7pc&IYW(MhI_a1}?1ZFVHYDQ)t1&T2>Hakq0I}$0U)f^O<MFy)_ssJB2
z6<_<U?n894#q1ZBrUx1P?@*B~Q=lI1$}e`xerwW%rR%F4v=OUbs{nq+z%@DNrn4<p
z%5E}g!qW923z@7KtpWvb)DD+XR^tX;SW;eOvI_hb@Or(qaNO(3pv;E#y0E0YMLp>R
zi9PDH3Veg<Ld$l_P@;5UNqLb8VGq9rR8{rBl%-hcL|xQ8L25w;G9m1tTOdc-Olfb{
z%@d>+WMtNv^$U1Bo>7?co0BNDX00wPDQ{k50zufrZvnU4-3HU$jx;*%SfdL|%6q3H
zl_0UlJHG`!Ih{6`90L#O*ejzhEGaKCA*Zv~?zh1G2PJ!9n)HlOR?Q|#sWxiD()A$=
znGp8Sx)rZ>kB@(V@!97hI$9a22}{?9EC|`yL#x1wN2O)yIIOeYX}Z*~i;`bP_=TnE
z$*<o@$U<gm+2aiCp;Z8wT`pHSCcaMfQSR%ll>8zhC~|A!d>IfjkuCE)5Eg5V-}ZB2
z;v)t}rUvMuvV)F14-W{;jQ(;Fge+ttTc!Xo?%RJLiA(st!l%83lwP%w4p)S00uQ{H
zfslbLWCrp~xLja~*<wxT?;j}VhY4|#-BjIILbqE}=(HoAk}He=*Z2%;J`YR9EdS*e
zWJ(ucLU_=MgDFmMCrJukK5$mf2nqJR0Ieet1g>7Yez3Evs}OfgaZCNKs_GoTH9o@{
zJn%A+$XJXwqcA?fR!Pj5S?pIcU=XYlm;}*+SisjNUNcDK{68<JOUfS%8?^s6T8KIT
O0000<MNUMnLSTYKT#^_7
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..bff355bf486d4000cebfab154431e87e26329ace
GIT binary patch
literal 252
zc$@+J00aMtP)<h;3K|Lk000e1NJLTq000mG000mO1ONa4wfZ;e0002PNkl<Zcma)(
z!3u&v5Qg_8^eXDJrU!+7B5(BoRwwHT>L}S$*kOY*T&7uO#U-TLk70ku4;@!EEQFY&
z!IQag3ZVqq0%R~C4}%3}gAkwsO>jgYLT)cBYRPa_zLHrXLT_(t+Ec-$eWgdFkl5JL
z&Na83F_I`WHW(^gYsuLY8inrb6FMjG46LlUG@X1w%PW`z-N<mA=|SZv)NV+h(pOT2
z82yy8k<X0XL4C58J^%BlfBq~XLW(P1xTEG25B)a>2WL>o01H$A0000<MNUMnLSTaK
C^<`rK
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1565fc55df874fb19bed45f6063df110c8651a1d
GIT binary patch
literal 461
zc$@*v0W$uHP)<h;3K|Lk000e1NJLTq001BW001Be1ONa4*>kdg0004$Nkl<Zcmb`I
z-wx6+6vlfA2A+cQ0=&$8B<B<O0g}Kg>`pKBVw#Y-H-I}Bf1(K(S0SHgF{Z_}a|@o|
z&3fAXvaYAC@&yKn@CGUN_#y0(N-L7As#8yC%y0ocT%<=g3wn5k5^SJEj9y4ELI$=V
zgZ2p~*nutCVe+>?qX0WlK)ZrIzSzzsGoE-8j$BI%esc7!AhsRvSkjGBGVl}s5sYB$
z>s4%+a3LhzQX-@<(7y#U`|%~o&xA!<l<dl{m{)?KEt@sTZEe_wWX3>g4HY7rIFd|i
z!xEAw!cU|ywapvJMQzZ6<UJ&qDx_@$CL~A|4o^+tpiqMDPuz6*iA4DzShZh9D{!aa
z7SdZGk*6xYa@jD2^fC3GhHe;sBY6%fQg<02Hq)Iyd8js%a1JY`wvfU!DI&L&yDP3$
zDJ#su?h3n^6f{hG#YcBLkDUXho#KPre(fG<IoOdLFP=P9|J$){(a2kVybfP&@jq6?
zgswKr7&BZ!58pAzIDEOf4Db@bCloM3Ay1Hu_j>;Y4|t<Bx=lO>00000NkvXXu0mjf
D#0AC-
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..bff355bf486d4000cebfab154431e87e26329ace
GIT binary patch
literal 252
zc$@+J00aMtP)<h;3K|Lk000e1NJLTq000mG000mO1ONa4wfZ;e0002PNkl<Zcma)(
z!3u&v5Qg_8^eXDJrU!+7B5(BoRwwHT>L}S$*kOY*T&7uO#U-TLk70ku4;@!EEQFY&
z!IQag3ZVqq0%R~C4}%3}gAkwsO>jgYLT)cBYRPa_zLHrXLT_(t+Ec-$eWgdFkl5JL
z&Na83F_I`WHW(^gYsuLY8inrb6FMjG46LlUG@X1w%PW`z-N<mA=|SZv)NV+h(pOT2
z82yy8k<X0XL4C58J^%BlfBq~XLW(P1xTEG25B)a>2WL>o01H$A0000<MNUMnLSTaK
C^<`rK
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1565fc55df874fb19bed45f6063df110c8651a1d
GIT binary patch
literal 461
zc$@*v0W$uHP)<h;3K|Lk000e1NJLTq001BW001Be1ONa4*>kdg0004$Nkl<Zcmb`I
z-wx6+6vlfA2A+cQ0=&$8B<B<O0g}Kg>`pKBVw#Y-H-I}Bf1(K(S0SHgF{Z_}a|@o|
z&3fAXvaYAC@&yKn@CGUN_#y0(N-L7As#8yC%y0ocT%<=g3wn5k5^SJEj9y4ELI$=V
zgZ2p~*nutCVe+>?qX0WlK)ZrIzSzzsGoE-8j$BI%esc7!AhsRvSkjGBGVl}s5sYB$
z>s4%+a3LhzQX-@<(7y#U`|%~o&xA!<l<dl{m{)?KEt@sTZEe_wWX3>g4HY7rIFd|i
z!xEAw!cU|ywapvJMQzZ6<UJ&qDx_@$CL~A|4o^+tpiqMDPuz6*iA4DzShZh9D{!aa
z7SdZGk*6xYa@jD2^fC3GhHe;sBY6%fQg<02Hq)Iyd8js%a1JY`wvfU!DI&L&yDP3$
zDJ#su?h3n^6f{hG#YcBLkDUXho#KPre(fG<IoOdLFP=P9|J$){(a2kVybfP&@jq6?
zgswKr7&BZ!58pAzIDEOf4Db@bCloM3Ay1Hu_j>;Y4|t<Bx=lO>00000NkvXXu0mjf
D#0AC-
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a4eab0d7a3da705e9a941494bbf7b17737b90f2b
GIT binary patch
literal 344
zc$@)P0jK_nP)<h;3K|Lk000e1NJLTq002Ay000yS1ONa4dkU7K0003WNkl<Zcmd_p
zElWf}6o>I=i?Tt3FKfMDz~~zm-C}XK>U;yEHbIM^K@j_P!C-T(YV$5y{QyUe7YsHn
z3bSy+GQ&ARxMBbKfgcQW8q~BghI<_jSOQ+S<c{o0XD3G2*Z?4$as<55qy?ODoMD}v
zm|cX!Hhn(W<q25lih?fv1nca?>J)xplQjkmx59u&+6ma%iPb6m#U}+igc+t2aJu^)
z{V`&8d3cs73)XIeZvZCwQP}AI>#66cXi=%-=!S5ITi)4;=_=P0?9ofW&Q3C2{+xs+
z3jkEKc}>vHPK-`r2wnDB2A;X$g!wG(?8N9IJi4&Ry{7q5Iy*^p5w3w&I7c6H4mNFf
qqMZRpdW#FpmCjDIQ@DnWA^ZocG`dx^C;jdK0000<MNUMnLSTZw^p`jQ
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..2722c1697eabd39ba83fc2ade1361ef4b4f2a2d5
GIT binary patch
literal 694
zc$@*Y0!jUeP)<h;3K|Lk000e1NJLTq004LZ001Zm1ONa4pX2tf0007gNkl<ZcmeI$
zziZre9LMp;_nT5T1t))j2mUCf5f>eTAl-GiAU0f6ijG2uN@~<>Qb8-IiGtuCaK^O6
zrn+U)>81{%ZD}g<6(LRzSwvcnb3Bp{#W$DtaB%mSZhFFtH}`=%Q&Uq@Q)8@B`1+_<
zw7ujJ_w2gvnjhRXvR-npIaIGYX}?a}sweIDn<d|mI5)Z11bX4Yoyv#aS1Iv{6@B99
zCHI<yUX7tuD=KiqN8a$JkKF<+TN5{iz2d^1dEbFOZ~4{$P&w@@4}t}kh4qqqO-io@
z=p6MK_}iRy0{{bEFWUp3dLTSExz{B1Y5?<E;GA0y`q??~gx3X(Wv>|A1~+Xe(X|8G
z0>-&_1i*`6%Rq^NYu>>NqT)S1ciw($&gb`_2Jk4j<9=>~$3(?@T(E73ZA<yRgM;sZ
zN|tz!zEgGp+;K`jy;lt01y8%5W8g0VBlPyXYH#={zgG_a1<b2Zs<pv&QSqMP9fr5b
z?v;bLz;PXv&Ugk~6)<9N+fwoEOY4<`H~k5|^qhm9_XXH>MZn0tHLD=MR}Nmk>uvC`
zpDd~Y)Xw_RL!j$lL37EyRzk1*wRFic;I=I{aYEa(0Qye5EUcH@YZ7`#FtmbYaLl_(
zGrr;flH=Vg{{VQ+n#b+;yDKi30ey=$g!Php%^`cW1J*Y^<%~^#==;ZxtIj&^J&XEa
zM%RL{x#V8!kiF`psLq0J_$mRt<X#i%)xy>{;#Y~7OYXHoy_(6ITr*jdYYsJeHhJ=F
z^5ogb;P~W=ekEaYYOhuHBCmAd#lGkRNqWh>X4uOaOy`6f67`aMP1!34PlDRSm=2x*
c)4>zqKY1*LB2Lf?TmS$707*qoM6N<$f^ElIuK)l5
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1d50804b35d29d786da83988168a612b087e3126
GIT binary patch
literal 1350
zc$@)71-bf(P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU$=t)FDR9M5smw8NFRTPKOHVqXq0s$fg
z*%w*D680U!9%8EkrIux2(3VayaYzhfp^S9erh>?z37D|Yu*^sT$Pxu)XND+P7J;w{
z5=M;p$0UUWJHEM|Lmq}Gqlq(&H~Dhkym#(Bzjw~L_rB55QL_<3)Z(9-0T2MB08E+`
z`kujA3c$&O5)%`PJ3BiEmY0`zcXoCZ2weY!_wX6mgaAgG7GSNfuYaq%yL(tBlPSR|
z+1lD78yg#BZEfucyx!d0RQB}rj2amkv0#jirUV$GbE#CigpOBNR~4lnRnBHIS<-9i
zZ%eK-Zcg4{vBxVvt$w_?xTsiJSs~-&<I6Y(qoxS~!4Tfz?d@$Mkx1pKX*p8HTkrI8
zd1cj2E$#Qd=;<$PZf(E+;8A&P{(E-@Cc$QDX^FJ8wGCs+)D>U=dF4WADSW$>H?t)<
zxomM`^XEm6=e}qCviB?V@bEAb!E1rA_2FGEuV;2{PBA|}PsPW_bN_1;j$438BpO^_
zUnln;md;(vxY<$L*jBK)waxhL>C;p&ym}J6*VH8BwX}-9ot>Q}b#--vIEOj{Ql_V;
zcNZ2GNKz_eEWdzTI`z$W8Q|y&7+pS%`T2#+M<14nam>)r&@RrQj({9kVhRvJq7#z7
zuB@uNy(8Ow6%6830qID1|4v~Q)&Uf*0_RXm0Oo#ja*{;GUiq>?AWq-kKZpc_a8=0V
z@~DD>0zL{D9UVP{IkMDB0XW}<iO6e7X<wB*C}Tc(vL6Tr{;HUmn26``c(s@U*f(S_
zN3vQ)SYKa1I5ILqitd(7r(Vx4-uU51KQQoAMM+5sqpeLeJ~J~z_<TMVVW2u^ieYSQ
zEO%^djOy#_Q(S%{ReU2iFALJ(0?uCfD_k!3bvB#*2{>2anDFp$T!x0~9&EuiH8sN^
z05%tqJmqRyQ+j4rhCm?n+uPf7Kw#7H$<578&dbZ=gJb#B)D)?xs2IhuIvQw(dU|@d
znwy)KAg7pDMfu14$!um$Rcu`R2MGxY#VposKCJl>aIBC>B&4^um$bCB$ZTzG^I^OT
zpsTJ3YZOslUOwE>(V^_>>LLRJ1GwkoQab{#`}_NqWo2b!0)apV+cyykg)(z<^Lu7y
zX79or7V3&PI*vm_L%C4pgN==iKexBH|1K7b4;va9WOy$)I2dytYGY%Q56@-Q)zyT_
zWFA12l%AfRg_;m?EF_Tr2+0AmajDVwjtkBO-<-i<9K^-N5jYbF^puyESAnKP{9C(d
zVq(G$3ky?5MMaUAm>2@934016p*0Z}PEJlmAt51DWMm{kA<@y%*i-KA?%EUK=;+7^
z3=E_o8YChjf}j}aDK|Ga?TK)3aNq<41W*tSf<j<}!k%(<b>(PHgq@uo$Jf`Ff@lyF
zLPI$_JD)D%3_hzZU}NHVdwWy<{{AE=DCh`G52opFBF^ZKg@v`XH3ya><>TW+{QUd~
zM1|mQQ&Ur1))%$$&&I;a%8KLR;eq=Cfu7jg+kd952>dC+($bOxMMyzyp!1i3^QQ_p
z%fd7^HcqDB{JhE{g!T+@4!A&{YR}Q=0ngLu123pR|Ad|1iSfGh^K-Nhl>(lnjb8+e
zftP?wbl5BbE5H`8Q-LjQV@Z#>M9*PN&#6oM_+KJ$K~)6)00Jt#Y3STaegFUf07*qo
IM6N<$f(rU|WdHyG
--- a/browser/themes/windows/jar.mn
+++ b/browser/themes/windows/jar.mn
@@ -72,16 +72,21 @@ browser.jar:
         skin/classic/browser/Privacy-32.png
         skin/classic/browser/Privacy-48.png
         skin/classic/browser/privatebrowsing-mask-tabstrip-XPVista7.png
         skin/classic/browser/privatebrowsing-mask-titlebar-XPVista7.png
         skin/classic/browser/privatebrowsing-mask-titlebar-XPVista7-tall.png
         skin/classic/browser/reload-stop-go.png
         skin/classic/browser/searchbar.css
         skin/classic/browser/searchbar-dropdown-arrow.png
+        skin/classic/browser/search-pref.png                         (../shared/search/search-pref.png)
+        skin/classic/browser/search-indicator.png                    (../shared/search/search-indicator.png)
+        skin/classic/browser/search-indicator-add-engine.png         (../shared/search/search-indicator-add-engine.png)
+        skin/classic/browser/search-engine-placeholder.png           (../shared/search/search-engine-placeholder.png)
+        skin/classic/browser/badge-add-engine.png                    (../shared/search/badge-add-engine.png)
         skin/classic/browser/Secure24.png
         skin/classic/browser/setDesktopBackground.css
         skin/classic/browser/slowStartup-16.png
         skin/classic/browser/theme-switcher-icon.png
         skin/classic/browser/Toolbar.png                             (Toolbar-XP.png)
         skin/classic/browser/Toolbar-inverted.png
         skin/classic/browser/Toolbar-lunaSilver.png
         skin/classic/browser/toolbarbutton-dropdown-arrow.png        (toolbarbutton-dropdown-arrow-XPVista7.png)
@@ -506,16 +511,21 @@ browser.jar:
         skin/classic/aero/browser/privatebrowsing-mask-tabstrip.png
         skin/classic/aero/browser/privatebrowsing-mask-tabstrip-XPVista7.png
         skin/classic/aero/browser/privatebrowsing-mask-titlebar.png
         skin/classic/aero/browser/privatebrowsing-mask-titlebar-XPVista7.png
         skin/classic/aero/browser/privatebrowsing-mask-titlebar-XPVista7-tall.png
         skin/classic/aero/browser/reload-stop-go.png
         skin/classic/aero/browser/searchbar.css
         skin/classic/aero/browser/searchbar-dropdown-arrow.png       (searchbar-dropdown-arrow-aero.png)
+        skin/classic/aero/browser/search-pref.png                    (../shared/search/search-pref.png)
+        skin/classic/aero/browser/search-indicator.png               (../shared/search/search-indicator.png)
+        skin/classic/aero/browser/search-indicator-add-engine.png    (../shared/search/search-indicator-add-engine.png)
+        skin/classic/aero/browser/search-engine-placeholder.png      (../shared/search/search-engine-placeholder.png)
+        skin/classic/aero/browser/badge-add-engine.png               (../shared/search/badge-add-engine.png)
         skin/classic/aero/browser/Secure24.png                       (Secure24-aero.png)
         skin/classic/aero/browser/setDesktopBackground.css
         skin/classic/aero/browser/slowStartup-16.png
         skin/classic/aero/browser/theme-switcher-icon.png
         skin/classic/aero/browser/theme-switcher-icon-aero.png
         skin/classic/aero/browser/Toolbar.png
         skin/classic/aero/browser/Toolbar-inverted.png
         skin/classic/aero/browser/Toolbar-aero.png
--- a/browser/themes/windows/preferences/preferences.css
+++ b/browser/themes/windows/preferences/preferences.css
@@ -14,16 +14,20 @@
 radio[pane=paneMain] {
   -moz-image-region: rect(0, 32px,  32px, 0);
 }
 
 radio[pane=paneTabs] {
   -moz-image-region: rect(0, 64px, 32px, 32px);
 }
 
+#BrowserPreferences radio[pane=paneSearch] {
+  list-style-image: url("chrome://browser/skin/search-pref.png");
+}
+
 radio[pane=paneContent] {
   -moz-image-region: rect(0, 96px,  32px, 64px);
 }
 
 radio[pane=paneApplications] {
   -moz-image-region: rect(0, 128px,  32px, 96px);
 }
 
--- a/browser/themes/windows/searchbar.css
+++ b/browser/themes/windows/searchbar.css
@@ -73,8 +73,181 @@
 
 .search-go-button:hover:active {
   -moz-image-region: rect(0px, 48px, 16px, 32px);
 }
 
 .searchbar-engine-menuitem[selected="true"] > .menu-iconic-text {
   font-weight: bold;
 }
+
+
+
+.searchbar-search-button-container {
+  -moz-box-align: center;
+  padding: 3px 4px;
+  -moz-padding-end: 2px;
+}
+
+.searchbar-search-button {
+  list-style-image: url("chrome://browser/skin/search-indicator.png");
+  -moz-image-region: rect(0, 20px, 20px, 0);
+  margin: -2px -2px;
+}
+
+.searchbar-search-button:hover {
+  -moz-image-region: rect(0, 40px, 20px, 20px);
+}
+
+.searchbar-search-button:hover:active {
+  -moz-image-region: rect(0, 60px, 20px, 40px);
+}
+
+searchbar[oneoffui] .search-go-button {
+  list-style-image: url("chrome://browser/skin/reload-stop-go.png");
+  -moz-image-region: rect(0, 42px, 14px, 28px);
+}
+
+searchbar[oneoffui] .search-go-button:hover {
+  -moz-image-region: rect(14px, 42px, 28px, 28px);
+}
+
+searchbar[oneoffui] .search-go-button:hover:active {
+  -moz-image-region: rect(28px, 42px, 42px, 28px);
+}
+
+searchbar[oneoffui] .search-go-button:-moz-locale-dir(rtl) > .toolbarbutton-icon {
+  transform: scaleX(-1);
+}
+
+
+.search-panel-current-engine {
+  border-top: none !important;
+  border-bottom: 1px solid #ccc;
+  -moz-box-align: center;
+}
+
+.search-panel-header {
+  font-weight: normal;
+  background-color: rgb(245, 245, 245);
+  border-top: 1px solid #ccc;
+  margin: 0;
+  padding: 3px 6px;
+  color: #666;
+}
+
+.search-panel-current-input > label {
+  margin: 0 0 !important;
+}
+
+.search-panel-input-value {
+  color: black;
+}
+
+.search-panel-one-offs {
+  margin: 0 0 !important;
+  border-top: 1px solid #ccc;
+}
+
+.searchbar-engine-one-off-item {
+  -moz-appearance: none;
+  display: inline-block;
+  border: none;
+  min-width: 48px;
+  height: 32px;
+  margin: 0 0;
+  padding: 0 0;
+  background: none;
+  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAWCAYAAAABxvaqAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gofECQNNVW2/AAAABBJREFUGFdjOHPmzH8GehEA/KpKg9YTf4AAAAAASUVORK5CYII=');
+  background-repeat: no-repeat;
+  background-position: right center;
+}
+
+.searchbar-engine-one-off-item:not(.last-row) {
+  box-sizing: padding-box;
+  border-bottom: 1px solid #ccc;
+}
+
+.searchbar-engine-one-off-item.last-of-row {
+  background-image: none;
+}
+
+.searchbar-engine-one-off-item:hover:not(.dummy),
+.searchbar-engine-one-off-item[selected] {
+  background-color: Highlight;
+  background-image: none;
+}
+
+.searchbar-engine-one-off-item > .button-box {
+  border: none;
+  padding: 0 0;
+}
+
+.searchbar-engine-one-off-item > .button-box > .button-text {
+  display: none;
+}
+
+.searchbar-engine-one-off-item > .button-box > .button-icon {
+  width: 16px;
+  height: 16px;
+}
+
+.addengine-item {
+  -moz-appearance: none;
+  border: none;
+  height: 32px;
+  margin: 0 0;
+  padding: 0 10px;
+}
+
+.addengine-item > .button-box {
+  -moz-box-pack: start;
+}
+
+.addengine-item:first-of-type {
+  border-top: 1px solid #ccc;
+}
+
+.addengine-item:hover {
+  background-color: Highlight;
+  color: HighlightText;
+}
+
+.addengine-item > .button-box > .button-icon {
+  width: 16px;
+}
+
+.addengine-item > .button-box > .button-text {
+  -moz-box-flex: 1;
+  text-align: start;
+  -moz-padding-start: 10px;
+}
+
+.addengine-item:not([image]) {
+  list-style-image: url("chrome://browser/skin/search-engine-placeholder.png");
+}
+
+searchbar[oneoffui] .searchbar-engine-button {
+  display: none;
+}
+
+.search-panel-tree > .autocomplete-treebody::-moz-tree-cell {
+  -moz-padding-start: 15px;
+  border-top: none !important;
+}
+
+searchbar[oneoffui] .searchbar-engine-image {
+  -moz-margin-start: -1px;
+}
+
+.search-setting-button {
+  -moz-appearance: none;
+  border-bottom: none;
+  border-left: none;
+  border-right: none;
+  -moz-border-top-colors: none;
+  min-height: 32px;
+}
+
+.search-setting-button:hover {
+  background-color: #d3d3d3;
+  border-top-color: #bdbebe;
+}
--- a/toolkit/components/search/SearchSuggestionController.jsm
+++ b/toolkit/components/search/SearchSuggestionController.jsm
@@ -45,20 +45,22 @@ this.SearchSuggestionController = functi
   this._callback = callback;
 };
 
 this.SearchSuggestionController.prototype = {
   /**
    * The maximum number of local form history results to return. This limit is
    * only enforced if remote results are also returned.
    */
-  maxLocalResults: 7,
+  maxLocalResults: 5,
 
   /**
    * The maximum number of remote search engine results to return.
+   * We'll actually only display at most
+   * maxRemoteResults - <displayed local results count> remote results.
    */
   maxRemoteResults: 10,
 
   /**
    * The maximum time (ms) to wait before giving up on a remote suggestions.
    */
   remoteTimeout: REMOTE_TIMEOUT,
 
@@ -311,17 +313,23 @@ this.SearchSuggestionController.prototyp
     }
   },
 
   /**
    * @param {Array} suggestResults - an array of result objects from different sources (local or remote)
    * @return {Object}
    */
   _dedupeAndReturnResults: function(suggestResults) {
-    NS_ASSERT(this._searchString !== null, "this._searchString shouldn't be null when returning results");
+    if (this._searchString === null) {
+      // _searchString can be null if stop() was called and remote suggestions
+      // were disabled (stopping if we are fetching remote suggestions will
+      // cause a promise rejection before we reach _dedupeAndReturnResults).
+      return null;
+    }
+
     let results = {
       term: this._searchString,
       remote: [],
       local: [],
       formHistoryResult: null,
     };
 
     for (let result of suggestResults) {
@@ -348,17 +356,18 @@ this.SearchSuggestionController.prototyp
         let dupIndex = results.remote.indexOf(term);
         if (dupIndex != -1) {
           results.remote.splice(dupIndex, 1);
         }
       }
     }
 
     // Trim the number of results to the maximum requested (now that we've pruned dupes).
-    results.remote = results.remote.slice(0, this.maxRemoteResults);
+    results.remote =
+      results.remote.slice(0, this.maxRemoteResults - results.local.length);
 
     if (this._callback) {
       this._callback(results);
     }
     this._reset();
 
     return results;
   },
--- a/toolkit/components/search/nsSearchSuggestions.js
+++ b/toolkit/components/search/nsSearchSuggestions.js
@@ -68,16 +68,23 @@ SuggestAutoComplete.prototype = {
       // "comments" column values for suggestions starts as empty strings
       let comments = new Array(results.remote.length).fill("", 1);
       comments[0] = this._suggestionLabel;
       // now put the history results above the suggestions
       finalResults = finalResults.concat(results.remote);
       finalComments = finalComments.concat(comments);
     }
 
+    // If no result, add the search term so that the panel of the new UI is shown anyway.
+    if (!finalResults.length &&
+        Services.prefs.getBoolPref("browser.search.showOneOffButtons")) {
+      finalResults.push(results.term);
+      finalComments.push("");
+    }
+
     // Notify the FE of our new results
     this.onResultsReady(results.term, finalResults, finalComments, results.formHistoryResult);
   },
 
   /**
    * Notifies the front end of new results.
    * @param searchString  the user's query string
    * @param results       an array of results to the search
--- a/toolkit/components/search/tests/xpcshell/test_searchSuggest.js
+++ b/toolkit/components/search/tests/xpcshell/test_searchSuggest.js
@@ -256,18 +256,18 @@ add_task(function* both_identical_with_m
   controller.maxLocalResults = 7;
   controller.maxRemoteResults = 10;
   let result = yield controller.fetch("letter ", false, getEngine);
   do_check_eq(result.term, "letter ");
   do_check_eq(result.local.length, 7);
   for (let i = 0; i < controller.maxLocalResults; i++) {
     do_check_eq(result.local[i], "letter " + String.fromCharCode("A".charCodeAt() + i));
   }
-  do_check_eq(result.remote.length, 10);
-  for (let i = 0; i < controller.maxRemoteResults; i++) {
+  do_check_eq(result.local.length + result.remote.length, 10);
+  for (let i = 0; i < result.remote.length; i++) {
     do_check_eq(result.remote[i],
                 "letter " + String.fromCharCode("A".charCodeAt() + controller.maxLocalResults + i));
   }
 });
 
 add_task(function* noremote_maxLocal() {
   let controller = new SearchSuggestionController();
   controller.maxLocalResults = 2; // (should be ignored because no remote results)
@@ -279,34 +279,34 @@ add_task(function* noremote_maxLocal() {
     do_check_eq(result.local[i], "letter " + String.fromCharCode("A".charCodeAt() + i));
   }
   do_check_eq(result.remote.length, 0);
 });
 
 add_task(function* someremote_maxLocal() {
   let controller = new SearchSuggestionController();
   controller.maxLocalResults = 2;
-  controller.maxRemoteResults = 2;
+  controller.maxRemoteResults = 4;
   let result = yield controller.fetch("letter ", false, getEngine);
   do_check_eq(result.term, "letter ");
   do_check_eq(result.local.length, 2);
   for (let i = 0; i < result.local.length; i++) {
     do_check_eq(result.local[i], "letter " + String.fromCharCode("A".charCodeAt() + i));
   }
   do_check_eq(result.remote.length, 2);
   // "A" and "B" will have been de-duped, start at C for remote results
   for (let i = 0; i < result.remote.length; i++) {
     do_check_eq(result.remote[i], "letter " + String.fromCharCode("C".charCodeAt() + i));
   }
 });
 
 add_task(function* one_of_each() {
   let controller = new SearchSuggestionController();
   controller.maxLocalResults = 1;
-  controller.maxRemoteResults = 1;
+  controller.maxRemoteResults = 2;
   let result = yield controller.fetch("letter ", false, getEngine);
   do_check_eq(result.term, "letter ");
   do_check_eq(result.local.length, 1);
   do_check_eq(result.local[0], "letter A");
   do_check_eq(result.remote.length, 1);
   do_check_eq(result.remote[0], "letter B");
 });
 
@@ -339,17 +339,17 @@ add_task(function* local_result_returned
   do_check_eq(result.remote.length, 0);
   Services.prefs.setBoolPref("browser.search.suggest.enabled", true);
 });
 
 add_task(function* one_of_each_disabled_before_creation_enabled_after_creation_of_controller() {
   Services.prefs.setBoolPref("browser.search.suggest.enabled", false);
   let controller = new SearchSuggestionController();
   controller.maxLocalResults = 1;
-  controller.maxRemoteResults = 1;
+  controller.maxRemoteResults = 2;
   Services.prefs.setBoolPref("browser.search.suggest.enabled", true);
   let result = yield controller.fetch("letter ", false, getEngine);
   do_check_eq(result.term, "letter ");
   do_check_eq(result.local.length, 1);
   do_check_eq(result.local[0], "letter A");
   do_check_eq(result.remote.length, 1);
   do_check_eq(result.remote[0], "letter B");
 });
--- a/toolkit/themes/shared/in-content/common.inc.css
+++ b/toolkit/themes/shared/in-content/common.inc.css
@@ -172,16 +172,20 @@ xul|colorpicker[type="button"] {
 }
 
 xul|button > xul|*.button-box,
 xul|menulist > xul|*.menulist-label-box {
   padding-right: 10px !important;
   padding-left: 10px !important;
 }
 
+xul|menulist > xul|*.menulist-label-box > xul|*.menulist-icon {
+  -moz-margin-end: 5px;
+}
+
 xul|button[type="menu"] > xul|*.button-box > xul|*.button-menu-dropmarker {
   -moz-appearance: none;
   margin: 1px 0;
   -moz-margin-start: 10px;
   padding: 0;
   width: 10px;
   height: 16px;
   border: none;
@@ -422,16 +426,20 @@ xul|*.checkbox-label-box {
 @media (min-resolution: 2dppx) {
   xul|*.checkbox-check[checked] {
     background-size: 12px 12px, auto;
     background-image: url("chrome://global/skin/in-content/check@2x.png"),
                       linear-gradient(#fff, rgba(255,255,255,0.8)) !important;
   }
 }
 
+xul|richlistitem > xul|*.checkbox-check {
+  margin: 3px 6px;
+}
+
 xul|*.radio-check {
   -moz-appearance: none;
   width: 23px;
   height: 23px;
   border: 1px solid #c1c1c1;
   border-radius: 50%;
   -moz-margin-end: 10px;
   background-color: #f1f1f1;