merge fx-team to mozilla-central a=merge
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Mon, 12 Jan 2015 13:01:26 +0100
changeset 223251 a41cce2dd4081306e06bb93b9c80bb125c9d1265
parent 223250 643589c3ef94ab60157309c3be7f1441c32503c2 (current diff)
parent 223076 a31444b37e976d88f8c4b3a516fcfa64428de9cb (diff)
child 223286 ee55ebb9d533fb55aa588a8966b63bd8e812a920
push id10769
push usercbook@mozilla.com
push dateMon, 12 Jan 2015 14:15:52 +0000
treeherderfx-team@0e9765732906 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone37.0a1
merge fx-team to mozilla-central a=merge
browser/base/content/urlbarBindings.xml
browser/components/search/content/search.xml
python/mozboot/mozboot/android-ndk-r8e.rb
--- a/b2g/chrome/content/touchcontrols.css
+++ b/b2g/chrome/content/touchcontrols.css
@@ -46,27 +46,31 @@
 .fullscreenButton {
   background: url("chrome://b2g/content/images/fullscreen-hdpi.png") no-repeat center;
 }
 
 .fullscreenButton[fullscreened="true"] {
   background: url("chrome://b2g/content/images/exitfullscreen-hdpi.png") no-repeat center;
 }
 
+.controlBar[fullscreen-unavailable] .fullscreenButton {
+  display: none;
+}
+
 .playButton {
   background: url("chrome://b2g/content/images/pause-hdpi.png") no-repeat center;
 }
 
 /*
  * Normally the button bar has fullscreen spacer play spacer mute, but if
  * this is an audio control rather than a video control, the fullscreen button
  * is hidden by videocontrols.xml, and that alters the position of the
  * play button.  This workaround moves it back to center.
  */
-.controlBar.audio-only .playButton {
+.controlBar[fullscreen-unavailable] .playButton {
   transform: translateX(28px);
 }
 
 .playButton[paused="true"] {
   background: url("chrome://b2g/content/images/play-hdpi.png") no-repeat center;
 }
 
 .castingButton {
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -436,17 +436,16 @@ panel[noactions] > richlistbox > richlis
 }
 
 #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;
 }
 
 /* Overlay a badge on top of the icon of additional open search providers
    in the search panel. */
 .addengine-item > .button-box > .button-icon {
   -moz-binding: url("chrome://browser/content/urlbarBindings.xml#addengine-icon");
   display: -moz-stack;
 }
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -1127,31 +1127,36 @@
         let engines = Services.search.getVisibleEngines()
                               .filter(e => e.name != currentEngineName &&
                                            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;
-
         // 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.
         const ENGINE_WIDTH = 49;
+        let panel = document.getElementById("PopupSearchAutoComplete");
+        // The panel width only spans to the textbox size, but we also want it
+        // to include the magnifier icon's width.
+        let ltr = getComputedStyle(this).direction == "ltr";
+        let magnifierWidth = parseInt(getComputedStyle(panel)[
+                               ltr ? "marginLeft" : "marginRight"
+                             ]) * -1;
+        let minWidth = parseInt(panel.width) + magnifierWidth;
+        if (engines.length) {
+          // Ensure the panel is wide enough to fit at least 3 engines.
+          minWidth = Math.max(minWidth, ENGINE_WIDTH * 3);
+        }
+        panel.setAttribute("style", "min-width: " + minWidth + "px");
 
-        let panel = document.getElementById("PopupSearchAutoComplete");
-        // The + 23 is because the panel width only spans to the textbox
-        // size, but we also want it to include the magnifier icon's width.
-        let minWidth = parseInt(panel.width) + 23;
-        // Ensure the panel is wide enough to fit at least 3 engines.
-        minWidth = Math.max(minWidth, ENGINE_WIDTH * 3);
-        panel.setAttribute("style", "min-width: " + minWidth + "px");
+        if (!engines.length)
+          return;
 
         let panelWidth = parseInt(panel.clientWidth);
         // The + 1 is because the last button doesn't have a right border.
         let enginesPerRow = Math.floor((panelWidth + 1) / ENGINE_WIDTH);
         let buttonWidth = Math.floor(panelWidth / enginesPerRow);
         // There will be an emtpy area of:
         //   panelWidth - enginesPerRow * buttonWidth  px
         // at the end of each row.
--- a/browser/components/loop/content/js/conversationViews.js
+++ b/browser/components/loop/content/js/conversationViews.js
@@ -15,16 +15,21 @@ loop.conversationViews = (function(mozL1
   var sharedUtils = loop.shared.utils;
   var sharedViews = loop.shared.views;
   var sharedMixins = loop.shared.mixins;
   var sharedModels = loop.shared.models;
 
   // This duplicates a similar function in contacts.jsx that isn't used in the
   // conversation window. If we get too many of these, we might want to consider
   // finding a logical place for them to be shared.
+
+  // XXXdmose this code is already out of sync with the code in contacts.jsx
+  // which, unlike this code, now has unit tests.  We should totally do the
+  // above.
+
   function _getPreferredEmail(contact) {
     // A contact may not contain email addresses, but only a phone number.
     if (!contact.email || contact.email.length === 0) {
       return { value: "" };
     }
     return contact.email.find(e => e.pref) || contact.email[0];
   }
 
@@ -756,16 +761,35 @@ loop.conversationViews = (function(mozL1
 
     _renderError: function() {
       if (!this.state.emailLinkError) {
         return;
       }
       return React.createElement("p", {className: "error"}, mozL10n.get("unable_retrieve_url"));
     },
 
+    _getTitleMessage: function() {
+      var callStateReason =
+        this.props.store.getStoreState("callStateReason");
+
+      if (callStateReason === "reject" || callStateReason === "busy" ||
+          callStateReason === "setup") {
+        var contactDisplayName = _getContactDisplayName(this.props.contact);
+        if (contactDisplayName.length) {
+          return mozL10n.get(
+            "contact_unavailable_title",
+            {"contactName": contactDisplayName});
+        }
+
+        return mozL10n.get("generic_contact_unavailable_title");
+      } else {
+        return mozL10n.get("generic_failure_title");
+      }
+    },
+
     retryCall: function() {
       this.props.dispatcher.dispatch(new sharedActions.RetryCall());
     },
 
     cancelCall: function() {
       this.props.dispatcher.dispatch(new sharedActions.CancelCall());
     },
 
@@ -779,17 +803,17 @@ loop.conversationViews = (function(mozL1
         roomOwner: navigator.mozLoop.userProfile.email,
         roomName: _getContactDisplayName(this.props.contact)
       }));
     },
 
     render: function() {
       return (
         React.createElement("div", {className: "call-window"}, 
-          React.createElement("h2", null, mozL10n.get("generic_failure_title")), 
+          React.createElement("h2", null,  this._getTitleMessage() ), 
 
           React.createElement("p", {className: "btn-label"}, mozL10n.get("generic_failure_with_reason2")), 
 
           this._renderError(), 
 
           React.createElement("div", {className: "btn-group call-action-group"}, 
             React.createElement("button", {className: "btn btn-cancel", 
                     onClick: this.cancelCall}, 
@@ -1043,16 +1067,17 @@ loop.conversationViews = (function(mozL1
     },
   });
 
   return {
     PendingConversationView: PendingConversationView,
     CallIdentifierView: CallIdentifierView,
     ConversationDetailView: ConversationDetailView,
     CallFailedView: CallFailedView,
+    _getContactDisplayName: _getContactDisplayName,
     GenericFailureView: GenericFailureView,
     IncomingCallView: IncomingCallView,
     IncomingConversationView: IncomingConversationView,
     OngoingConversationView: OngoingConversationView,
     OutgoingConversationView: OutgoingConversationView
   };
 
 })(document.mozL10n || navigator.mozL10n);
--- a/browser/components/loop/content/js/conversationViews.jsx
+++ b/browser/components/loop/content/js/conversationViews.jsx
@@ -15,16 +15,21 @@ loop.conversationViews = (function(mozL1
   var sharedUtils = loop.shared.utils;
   var sharedViews = loop.shared.views;
   var sharedMixins = loop.shared.mixins;
   var sharedModels = loop.shared.models;
 
   // This duplicates a similar function in contacts.jsx that isn't used in the
   // conversation window. If we get too many of these, we might want to consider
   // finding a logical place for them to be shared.
+
+  // XXXdmose this code is already out of sync with the code in contacts.jsx
+  // which, unlike this code, now has unit tests.  We should totally do the
+  // above.
+
   function _getPreferredEmail(contact) {
     // A contact may not contain email addresses, but only a phone number.
     if (!contact.email || contact.email.length === 0) {
       return { value: "" };
     }
     return contact.email.find(e => e.pref) || contact.email[0];
   }
 
@@ -756,16 +761,35 @@ loop.conversationViews = (function(mozL1
 
     _renderError: function() {
       if (!this.state.emailLinkError) {
         return;
       }
       return <p className="error">{mozL10n.get("unable_retrieve_url")}</p>;
     },
 
+    _getTitleMessage: function() {
+      var callStateReason =
+        this.props.store.getStoreState("callStateReason");
+
+      if (callStateReason === "reject" || callStateReason === "busy" ||
+          callStateReason === "setup") {
+        var contactDisplayName = _getContactDisplayName(this.props.contact);
+        if (contactDisplayName.length) {
+          return mozL10n.get(
+            "contact_unavailable_title",
+            {"contactName": contactDisplayName});
+        }
+
+        return mozL10n.get("generic_contact_unavailable_title");
+      } else {
+        return mozL10n.get("generic_failure_title");
+      }
+    },
+
     retryCall: function() {
       this.props.dispatcher.dispatch(new sharedActions.RetryCall());
     },
 
     cancelCall: function() {
       this.props.dispatcher.dispatch(new sharedActions.CancelCall());
     },
 
@@ -779,17 +803,17 @@ loop.conversationViews = (function(mozL1
         roomOwner: navigator.mozLoop.userProfile.email,
         roomName: _getContactDisplayName(this.props.contact)
       }));
     },
 
     render: function() {
       return (
         <div className="call-window">
-          <h2>{mozL10n.get("generic_failure_title")}</h2>
+          <h2>{ this._getTitleMessage() }</h2>
 
           <p className="btn-label">{mozL10n.get("generic_failure_with_reason2")}</p>
 
           {this._renderError()}
 
           <div className="btn-group call-action-group">
             <button className="btn btn-cancel"
                     onClick={this.cancelCall}>
@@ -1043,16 +1067,17 @@ loop.conversationViews = (function(mozL1
     },
   });
 
   return {
     PendingConversationView: PendingConversationView,
     CallIdentifierView: CallIdentifierView,
     ConversationDetailView: ConversationDetailView,
     CallFailedView: CallFailedView,
+    _getContactDisplayName: _getContactDisplayName,
     GenericFailureView: GenericFailureView,
     IncomingCallView: IncomingCallView,
     IncomingConversationView: IncomingConversationView,
     OngoingConversationView: OngoingConversationView,
     OutgoingConversationView: OutgoingConversationView
   };
 
 })(document.mozL10n || navigator.mozL10n);
--- a/browser/components/loop/content/shared/css/conversation.css
+++ b/browser/components/loop/content/shared/css/conversation.css
@@ -274,17 +274,17 @@
 }
 
 /* XXX Once we get the incoming call avatar, bug 1047435, the H2 should
  * disappear from our markup, and we should remove this rule entirely.
  */
 .call-window h2 {
   font-size: 1.5em;
   font-weight: normal;
-
+  text-align: center;
   /* compensate for reset.css overriding this; values borrowed from
      Firefox Mac html.css */
   margin: 0.83em 0;
 }
 
 .fx-embedded-call-button-spacer {
   display: flex;
   flex: 1;
--- a/browser/components/loop/test/desktop-local/conversationViews_test.js
+++ b/browser/components/loop/test/desktop-local/conversationViews_test.js
@@ -407,16 +407,71 @@ describe("loop.conversationViews", funct
       view = mountTestComponent({contact: contact});
 
       sinon.assert.calledOnce(navigator.mozLoop.getAudioBlob);
       sinon.assert.calledWithExactly(navigator.mozLoop.getAudioBlob,
                                      "failure", sinon.match.func);
       sinon.assert.calledOnce(fakeAudio.play);
       expect(fakeAudio.loop).to.equal(false);
     });
+
+    it("should show 'something went wrong' when the reason is 'media-fail'",
+      function () {
+        store.setStoreState({callStateReason: "media-fail"});
+
+        view = mountTestComponent({contact: contact});
+
+        sinon.assert.calledWith(document.mozL10n.get, "generic_failure_title");
+      });
+
+    it("should show 'contact unavailable' when the reason is 'reject'",
+      function () {
+        store.setStoreState({callStateReason: "reject"});
+
+        view = mountTestComponent({contact: contact});
+
+        sinon.assert.calledWithExactly(document.mozL10n.get,
+          "contact_unavailable_title",
+          {contactName: loop.conversationViews._getContactDisplayName(contact)});
+      });
+
+    it("should show 'contact unavailable' when the reason is 'busy'",
+      function () {
+        store.setStoreState({callStateReason: "busy"});
+
+        view = mountTestComponent({contact: contact});
+
+        sinon.assert.calledWithExactly(document.mozL10n.get,
+          "contact_unavailable_title",
+          {contactName: loop.conversationViews._getContactDisplayName(contact)});
+      });
+
+    it("should show 'contact unavailable' when the reason is 'setup'",
+      function () {
+        store.setStoreState({callStateReason: "setup"});
+
+        view = mountTestComponent({contact: contact});
+
+        sinon.assert.calledWithExactly(document.mozL10n.get,
+          "contact_unavailable_title",
+          {contactName: loop.conversationViews._getContactDisplayName(contact)});
+      });
+
+    it("should display a generic contact unavailable msg when the reason is" +
+       " 'busy' and no display name is available", function() {
+        store.setStoreState({callStateReason: "busy"});
+        var phoneOnlyContact = {
+          tel: [{"pref": true, type: "work", value: ""}]
+        };
+
+        view = mountTestComponent({contact: phoneOnlyContact});
+
+        sinon.assert.calledWith(document.mozL10n.get,
+          "generic_contact_unavailable_title");
+    });
   });
 
   describe("OngoingConversationView", function() {
     function mountTestComponent(props) {
       return TestUtils.renderIntoDocument(
         React.createElement(loop.conversationViews.OngoingConversationView, props));
     }
 
@@ -526,17 +581,20 @@ describe("loop.conversationViews", funct
       });
       feedbackStore = new loop.store.FeedbackStore(dispatcher, {
         feedbackClient: {}
       });
     });
 
     it("should render the CallFailedView when the call state is 'terminated'",
       function() {
-        store.setStoreState({callState: CALL_STATES.TERMINATED});
+        store.setStoreState({
+          callState: CALL_STATES.TERMINATED,
+          contact: contact
+        });
 
         view = mountTestComponent();
 
         TestUtils.findRenderedComponentWithType(view,
           loop.conversationViews.CallFailedView);
     });
 
     it("should render the PendingConversationView when the call state is 'gather'",
--- a/browser/components/loop/ui/ui-showcase.js
+++ b/browser/components/loop/ui/ui-showcase.js
@@ -69,16 +69,21 @@
     sdkDriver: {}
   });
   var roomStore = new loop.store.RoomStore(dispatcher, {
     mozLoop: navigator.mozLoop
   });
   var feedbackStore = new loop.store.FeedbackStore(dispatcher, {
     feedbackClient: stageFeedbackApiClient
   });
+  var conversationStore = new loop.store.ConversationStore(dispatcher, {
+    client: {},
+    mozLoop: navigator.mozLoop,
+    sdkDriver: {}
+  });
 
   // Local mocks
 
   var mockMozLoopRooms = _.extend({}, navigator.mozLoop);
   mockMozLoopRooms.roomsEnabled = true;
 
   var mockContact = {
     name: ["Mr Smith"],
@@ -371,23 +376,24 @@
               )
             )
           ), 
 
           React.createElement(Section, {name: "CallFailedView"}, 
             React.createElement(Example, {summary: "Call Failed", dashed: "true", 
                      style: {width: "260px", height: "265px"}}, 
               React.createElement("div", {className: "fx-embedded"}, 
-                React.createElement(CallFailedView, {dispatcher: dispatcher})
+                React.createElement(CallFailedView, {dispatcher: dispatcher, store: conversationStore})
               )
             ), 
             React.createElement(Example, {summary: "Call Failed — with call URL error", dashed: "true", 
                      style: {width: "260px", height: "265px"}}, 
               React.createElement("div", {className: "fx-embedded"}, 
-                React.createElement(CallFailedView, {dispatcher: dispatcher, emailLinkError: true})
+                React.createElement(CallFailedView, {dispatcher: dispatcher, emailLinkError: true, 
+                                store: conversationStore})
               )
             )
           ), 
 
           React.createElement(Section, {name: "StartConversationView"}, 
             React.createElement(Example, {summary: "Start conversation view", dashed: "true"}, 
               React.createElement("div", {className: "standalone"}, 
                 React.createElement(StartConversationView, {conversation: mockConversationModel, 
--- a/browser/components/loop/ui/ui-showcase.jsx
+++ b/browser/components/loop/ui/ui-showcase.jsx
@@ -69,16 +69,21 @@
     sdkDriver: {}
   });
   var roomStore = new loop.store.RoomStore(dispatcher, {
     mozLoop: navigator.mozLoop
   });
   var feedbackStore = new loop.store.FeedbackStore(dispatcher, {
     feedbackClient: stageFeedbackApiClient
   });
+  var conversationStore = new loop.store.ConversationStore(dispatcher, {
+    client: {},
+    mozLoop: navigator.mozLoop,
+    sdkDriver: {}
+  });
 
   // Local mocks
 
   var mockMozLoopRooms = _.extend({}, navigator.mozLoop);
   mockMozLoopRooms.roomsEnabled = true;
 
   var mockContact = {
     name: ["Mr Smith"],
@@ -371,23 +376,24 @@
               </div>
             </Example>
           </Section>
 
           <Section name="CallFailedView">
             <Example summary="Call Failed" dashed="true"
                      style={{width: "260px", height: "265px"}}>
               <div className="fx-embedded">
-                <CallFailedView dispatcher={dispatcher} />
+                <CallFailedView dispatcher={dispatcher} store={conversationStore} />
               </div>
             </Example>
             <Example summary="Call Failed — with call URL error" dashed="true"
                      style={{width: "260px", height: "265px"}}>
               <div className="fx-embedded">
-                <CallFailedView dispatcher={dispatcher} emailLinkError={true} />
+                <CallFailedView dispatcher={dispatcher} emailLinkError={true}
+                                store={conversationStore} />
               </div>
             </Example>
           </Section>
 
           <Section name="StartConversationView">
             <Example summary="Start conversation view" dashed="true">
               <div className="standalone">
                 <StartConversationView conversation={mockConversationModel}
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -2403,38 +2403,38 @@ let DefaultBrowserCheck = {
       if (event.target.id == "defaultBrowserNever") {
         ShellService.shouldCheckDefaultBrowser = false;
       }
       this.closePrompt();
     }
   },
 
   prompt: function(win) {
+    let useNotificationBar = Services.prefs.getBoolPref("browser.defaultbrowser.notificationbar");
+
     let brandBundle = win.document.getElementById("bundle_brand");
-    let shellBundle = win.document.getElementById("bundle_shell");
-
     let brandShortName = brandBundle.getString("brandShortName");
-    let promptMessage = shellBundle.getFormattedString("setDefaultBrowserMessage2",
-                                                       [brandShortName]);
 
-    let yesButton = shellBundle.getFormattedString("setDefaultBrowserConfirm.label",
+    let shellBundle = win.document.getElementById("bundle_shell");
+    let buttonPrefix = "setDefaultBrowser" + (useNotificationBar ? "" : "Alert");
+    let yesButton = shellBundle.getFormattedString(buttonPrefix + "Confirm.label",
                                                    [brandShortName]);
-
-    let notNowButton = shellBundle.getString("setDefaultBrowserNotNow.label");
-    let notNowButtonKey = shellBundle.getString("setDefaultBrowserNotNow.accesskey");
+    let notNowButton = shellBundle.getString(buttonPrefix + "NotNow.label");
 
-    let neverLabel = shellBundle.getString("setDefaultBrowserNever.label");
-    let neverKey = shellBundle.getString("setDefaultBrowserNever.accesskey");
-
-    let useNotificationBar = Services.prefs.getBoolPref("browser.defaultbrowser.notificationbar");
     if (useNotificationBar) {
+      let promptMessage = shellBundle.getFormattedString("setDefaultBrowserMessage2",
+                                                         [brandShortName]);
       let optionsMessage = shellBundle.getString("setDefaultBrowserOptions.label");
       let optionsKey = shellBundle.getString("setDefaultBrowserOptions.accesskey");
 
+      let neverLabel = shellBundle.getString("setDefaultBrowserNever.label");
+      let neverKey = shellBundle.getString("setDefaultBrowserNever.accesskey");
+
       let yesButtonKey = shellBundle.getString("setDefaultBrowserConfirm.accesskey");
+      let notNowButtonKey = shellBundle.getString("setDefaultBrowserNotNow.accesskey");
 
       let notificationBox = win.document.getElementById("high-priority-global-notificationbox");
 
       this._createPopup(win, {
         label: notNowButton,
         accesskey: notNowButtonKey
       }, {
         label: neverLabel,
@@ -2462,24 +2462,28 @@ let DefaultBrowserCheck = {
       const priority = notificationBox.PRIORITY_WARNING_HIGH;
       let callback = this._onNotificationEvent.bind(this);
       this._notification = notificationBox.appendNotification(promptMessage, "default-browser",
                                                               iconURL, priority, buttons,
                                                               callback);
     } else {
       // Modal prompt
       let promptTitle = shellBundle.getString("setDefaultBrowserTitle");
+      let promptMessage = shellBundle.getFormattedString("setDefaultBrowserMessage",
+                                                         [brandShortName]);
+      let dontAskLabel = shellBundle.getFormattedString("setDefaultBrowserDontAsk",
+                                                        [brandShortName]);
 
       let ps = Services.prompt;
       let dontAsk = { value: false };
       let buttonFlags = (ps.BUTTON_TITLE_IS_STRING * ps.BUTTON_POS_0) +
                         (ps.BUTTON_TITLE_IS_STRING * ps.BUTTON_POS_1) +
                         ps.BUTTON_POS_0_DEFAULT;
       let rv = ps.confirmEx(win, promptTitle, promptMessage, buttonFlags,
-                            yesButton, notNowButton, null, neverLabel, dontAsk);
+                            yesButton, notNowButton, null, dontAskLabel, dontAsk);
       if (rv == 0) {
         this.setAsDefault();
       } else if (dontAsk.value) {
         ShellService.shouldCheckDefaultBrowser = false;
       }
     }
   },
 
--- a/browser/components/preferences/colors.xul
+++ b/browser/components/preferences/colors.xul
@@ -75,21 +75,28 @@
         </hbox>
         <separator class="thin"/>
         <hbox align="center">
           <checkbox id="browserUnderlineAnchors" label="&underlineLinks.label;" accesskey="&underlineLinks.accesskey;"
                     preference="browser.underline_anchors"/>
         </hbox>
       </groupbox>
     </hbox>
+#ifdef XP_WIN
     <vbox align="start">
-      <label accesskey="&allowPagesToUseColors.accesskey;"
-             control="useDocumentColors">&allowPagesToUseColors.label;</label>
+#else
+    <vbox>
+#endif
+      <label accesskey="&overridePageColors.accesskey;"
+             control="useDocumentColors">&overridePageColors.label;</label>
       <menulist id="useDocumentColors" preference="browser.display.document_color_use">
         <menupopup>
-          <menuitem label="&allowPagesToUseColors.automatic.label;" value="0" id="documentColorAutomatic"/>
-          <menuitem label="&allowPagesToUseColors.always.label;"    value="1" id="documentColorAlways"/>
-          <menuitem label="&allowPagesToUseColors.never.label;"     value="2" id="documentColorNever"/>
+          <menuitem label="&overridePageColors.always.label;"
+                    value="2" id="documentColorAlways"/>
+          <menuitem label="&overridePageColors.auto.label;"
+                    value="0" id="documentColorAutomatic"/>
+          <menuitem label="&overridePageColors.never.label;"
+                    value="1" id="documentColorNever"/>
         </menupopup>
       </menulist>
     </vbox>
   </prefpane>
 </prefwindow>
--- a/browser/components/search/content/search.xml
+++ b/browser/components/search/content/search.xml
@@ -746,16 +746,21 @@
         if (Services.focus.getLastFocusMethod(window) == Services.focus.FLAG_BYMOUSE)
           return;
 
         this.openSuggestionsPanel();
       ]]></handler>
 
       <handler event="click" button="0">
       <![CDATA[
+        // Ignore clicks on the search go button.
+        if (event.originalTarget.getAttribute("anonid") == "search-go-button") {
+          return;
+        }
+
         // Open the suggestions whenever clicking on the search icon or if there
         // is text in the textbox.
         if (event.originalTarget.getAttribute("anonid") == "searchbar-search-button" ||
             this._textbox.value) {
           this.openSuggestionsPanel(true);
         }
       ]]></handler>
 
--- a/browser/components/search/test/browser_searchbar_openpopup.js
+++ b/browser/components/search/test/browser_searchbar_openpopup.js
@@ -1,13 +1,14 @@
 // Tests that the suggestion popup appears at the right times in response to
 // focus and clicks.
 
 const searchbar = document.getElementById("searchbar");
 const searchIcon = document.getAnonymousElementByAttribute(searchbar, "anonid", "searchbar-search-button");
+const goButton = document.getAnonymousElementByAttribute(searchbar, "anonid", "search-go-button");
 const textbox = searchbar._textbox;
 const searchPopup = document.getElementById("PopupSearchAutoComplete");
 
 function promiseNewEngine(basename) {
   return new Promise((resolve, reject) => {
     info("Waiting for engine to be added: " + basename);
     Services.search.init({
       onInitComplete: function() {
@@ -313,8 +314,24 @@ add_task(function* refocus_window_doesnt
   // Wait a few ticks to allow any focus handlers to show the popup if they are going to.
   yield new Promise(resolve => executeSoon(resolve));
   yield new Promise(resolve => executeSoon(resolve));
   yield new Promise(resolve => executeSoon(resolve));
 
   searchPopup.removeEventListener("popupshowing", listener, false);
   textbox.value = "";
 });
+
+// Clicking the search go button shouldn't open the popup
+add_no_popup_task(function* search_go_doesnt_open_popup() {
+  gBrowser.selectedTab = gBrowser.addTab();
+
+  gURLBar.focus();
+  textbox.value = "foo";
+  searchbar.inputChanged();
+
+  let promise = promiseOnLoad();
+  EventUtils.synthesizeMouseAtCenter(goButton, {});
+  yield promise;
+
+  textbox.value = "";
+  gBrowser.removeCurrentTab();
+});
--- a/browser/devtools/netmonitor/netmonitor-controller.js
+++ b/browser/devtools/netmonitor/netmonitor-controller.js
@@ -387,26 +387,16 @@ let NetMonitorController = {
    */
   get supportsCustomRequest() {
     return this.webConsoleClient &&
            (this.webConsoleClient.traits.customNetworkRequest ||
             !this._target.isApp);
   },
 
   /**
-   * Getter that tells if the server includes the transferred (compressed /
-   * encoded) response size.
-   * @type boolean
-   */
-  get supportsTransferredResponseSize() {
-    return this.webConsoleClient &&
-           this.webConsoleClient.traits.transferredResponseSize;
-  },
-
-  /**
    * Getter that tells if the server can do network performance statistics.
    * @type boolean
    */
   get supportsPerfStats() {
     return this.tabClient &&
            (this.tabClient.traits.reconfigure || !this._target.isApp);
   },
 
@@ -595,17 +585,16 @@ NetworkEventsHandler.prototype = {
           statusText: aPacket.response.statusText,
           headersSize: aPacket.response.headersSize
         });
         window.emit(EVENTS.STARTED_RECEIVING_RESPONSE, actor);
         break;
       case "responseContent":
         NetMonitorView.RequestsMenu.updateRequest(aPacket.from, {
           contentSize: aPacket.contentSize,
-          transferredSize: aPacket.transferredSize,
           mimeType: aPacket.mimeType
         });
         this.webConsoleClient.getResponseContent(actor, this._onResponseContent);
         window.emit(EVENTS.UPDATING_RESPONSE_CONTENT, actor);
         break;
       case "eventTimings":
         NetMonitorView.RequestsMenu.updateRequest(aPacket.from, {
           totalTime: aPacket.totalTime
--- a/browser/devtools/netmonitor/netmonitor-view.js
+++ b/browser/devtools/netmonitor/netmonitor-view.js
@@ -411,21 +411,16 @@ RequestsMenuView.prototype = Heritage.ex
       $("#requests-menu-network-summary-label").addEventListener("click", this._onContextPerfCommand, false);
       $("#network-statistics-back-button").addEventListener("command", this._onContextPerfCommand, false);
     } else {
       $("#notice-perf-message").hidden = true;
       $("#request-menu-context-perf").hidden = true;
       $("#requests-menu-network-summary-button").hidden = true;
       $("#requests-menu-network-summary-label").hidden = true;
     }
-
-    if (!NetMonitorController.supportsTransferredResponseSize) {
-      $("#requests-menu-transferred-header-box").hidden = true;
-      $("#requests-menu-item-template .requests-menu-transferred").hidden = true;
-    }
   },
 
   /**
    * Destruction function, called when the network monitor is closed.
    */
   destroy: function() {
     dumpn("Destroying the SourcesView");
 
@@ -799,18 +794,18 @@ RequestsMenuView.prototype = Heritage.ex
     flash: this.isFlash,
     other: this.isOther
   }),
 
   /**
    * Sorts all network requests in this container by a specified detail.
    *
    * @param string aType
-   *        Either "status", "method", "file", "domain", "type", "transferred",
-   *        "size" or "waterfall".
+   *        Either "status", "method", "file", "domain", "type", "size" or
+   *        "waterfall".
    */
   sortBy: function(aType = "waterfall") {
     let target = $("#requests-menu-" + aType + "-button");
     let headers = document.querySelectorAll(".requests-menu-header-button");
 
     for (let header of headers) {
       if (header != target) {
         header.removeAttribute("sorted");
@@ -861,23 +856,16 @@ RequestsMenuView.prototype = Heritage.ex
         break;
       case "type":
         if (direction == "ascending") {
           this.sortContents(this._byType);
         } else {
           this.sortContents((a, b) => !this._byType(a, b));
         }
         break;
-      case "transferred":
-        if (direction == "ascending") {
-          this.sortContents(this._byTransferred);
-        } else {
-          this.sortContents((a, b) => !this._byTransferred(a, b));
-        }
-        break;
       case "size":
         if (direction == "ascending") {
           this.sortContents(this._bySize);
         } else {
           this.sortContents((a, b) => !this._bySize(a, b));
         }
         break;
       case "waterfall":
@@ -1000,23 +988,18 @@ RequestsMenuView.prototype = Heritage.ex
   _byType: function({ attachment: first }, { attachment: second }) {
     let firstType = this._getAbbreviatedMimeType(first.mimeType).toLowerCase();
     let secondType = this._getAbbreviatedMimeType(second.mimeType).toLowerCase();
     return firstType == secondType
       ? first.startedMillis > second.startedMillis
       : firstType > secondType;
   },
 
-  _byTransferred: function({ attachment: first }, { attachment: second }) {
-    return first.transferredSize > second.transferredSize;
-  },
-
-  _bySize: function({ attachment: first }, { attachment: second }) {
-    return first.contentSize > second.contentSize;
-  },
+  _bySize: function({ attachment: first }, { attachment: second })
+    first.contentSize > second.contentSize,
 
   /**
    * Refreshes the status displayed in this container's footer, providing
    * concise information about all requests.
    */
   refreshSummary: function() {
     let visibleItems = this.visibleItems;
     let visibleRequestsCount = visibleItems.length;
@@ -1171,20 +1154,16 @@ RequestsMenuView.prototype = Heritage.ex
             break;
           case "headersSize":
             requestItem.attachment.headersSize = value;
             break;
           case "contentSize":
             requestItem.attachment.contentSize = value;
             this.updateMenuView(requestItem, key, value);
             break;
-          case "transferredSize":
-            requestItem.attachment.transferredSize = value;
-            this.updateMenuView(requestItem, key, value);
-            break;
           case "mimeType":
             requestItem.attachment.mimeType = value;
             this.updateMenuView(requestItem, key, value);
             break;
           case "responseContent":
             // If there's no mime type available when the response content
             // is received, assume text/plain as a fallback.
             if (!requestItem.attachment.mimeType) {
@@ -1323,30 +1302,16 @@ RequestsMenuView.prototype = Heritage.ex
         let kb = aValue / 1024;
         let size = L10N.numberWithDecimals(kb, CONTENT_SIZE_DECIMALS);
         let node = $(".requests-menu-size", target);
         let text = L10N.getFormatStr("networkMenu.sizeKB", size);
         node.setAttribute("value", text);
         node.setAttribute("tooltiptext", text);
         break;
       }
-      case "transferredSize": {
-        let text;
-        if (aValue === null) {
-          text = L10N.getStr("networkMenu.sizeUnavailable");
-        } else {
-          let kb = aValue / 1024;
-          let size = L10N.numberWithDecimals(kb, CONTENT_SIZE_DECIMALS);
-          text = L10N.getFormatStr("networkMenu.sizeKB", size);
-        }
-        let node = $(".requests-menu-transferred", target);
-        node.setAttribute("value", text);
-        node.setAttribute("tooltiptext", text);
-        break;
-      }
       case "mimeType": {
         let type = this._getAbbreviatedMimeType(aValue);
         let node = $(".requests-menu-type", target);
         let text = CONTENT_MIME_TYPE_ABBREVIATIONS[type] || type;
         node.setAttribute("value", text);
         node.setAttribute("tooltiptext", aValue);
         break;
       }
--- a/browser/devtools/netmonitor/netmonitor.xul
+++ b/browser/devtools/netmonitor/netmonitor.xul
@@ -96,26 +96,16 @@
                     align="center">
                 <button id="requests-menu-type-button"
                         class="requests-menu-header-button requests-menu-type"
                         data-key="type"
                         label="&netmonitorUI.toolbar.type;"
                         flex="1">
                 </button>
               </hbox>
-              <hbox id="requests-menu-transferred-header-box"
-                    class="requests-menu-header requests-menu-transferred"
-                    align="center">
-                <button id="requests-menu-transferred-button"
-                        class="requests-menu-header-button requests-menu-transferred"
-                        data-key="transferred"
-                        label="&netmonitorUI.toolbar.transferred;"
-                        flex="1">
-                </button>
-              </hbox>
               <hbox id="requests-menu-size-header-box"
                     class="requests-menu-header requests-menu-size"
                     align="center">
                 <button id="requests-menu-size-button"
                         class="requests-menu-header-button requests-menu-size"
                         data-key="size"
                         label="&netmonitorUI.toolbar.size;"
                         flex="1">
@@ -179,18 +169,16 @@
                 <label class="plain requests-menu-file"
                        crop="end"
                        flex="1"/>
               </hbox>
               <label class="plain requests-menu-subitem requests-menu-domain"
                      crop="end"/>
               <label class="plain requests-menu-subitem requests-menu-type"
                      crop="end"/>
-              <label class="plain requests-menu-subitem requests-menu-transferred"
-                     crop="end"/>
               <label class="plain requests-menu-subitem requests-menu-size"
                      crop="end"/>
               <hbox class="requests-menu-subitem requests-menu-waterfall"
                     align="center"
                     flex="1">
                 <hbox class="requests-menu-timings"
                       align="center">
                   <label class="plain requests-menu-timings-total"/>
--- a/browser/devtools/netmonitor/test/browser_net_simple-request-data.js
+++ b/browser/devtools/netmonitor/test/browser_net_simple-request-data.js
@@ -60,18 +60,16 @@ function test() {
         "The httpVersion should not yet be set.");
       is(requestItem.attachment.status, undefined,
         "The status should not yet be set.");
       is(requestItem.attachment.statusText, undefined,
         "The statusText should not yet be set.");
 
       is(requestItem.attachment.headersSize, undefined,
         "The headersSize should not yet be set.");
-      is(requestItem.attachment.transferredSize, undefined,
-        "The transferredSize should not yet be set.");
       is(requestItem.attachment.contentSize, undefined,
         "The contentSize should not yet be set.");
 
       is(requestItem.attachment.mimeType, undefined,
         "The mimeType should not yet be set.");
       is(requestItem.attachment.responseContent, undefined,
         "The responseContent should not yet be set.");
 
@@ -153,27 +151,24 @@ function test() {
         status: "200",
         statusText: "Och Aye"
       });
     });
 
     aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.UPDATING_RESPONSE_CONTENT, () => {
       let requestItem = RequestsMenu.getItemAtIndex(0);
 
-      is(requestItem.attachment.transferredSize, "12",
-        "The transferredSize attachment has an incorrect value.");
       is(requestItem.attachment.contentSize, "12",
         "The contentSize attachment has an incorrect value.");
       is(requestItem.attachment.mimeType, "text/plain; charset=utf-8",
         "The mimeType attachment has an incorrect value.");
 
       verifyRequestItemTarget(requestItem, "GET", SIMPLE_SJS, {
         type: "plain",
         fullMimeType: "text/plain; charset=utf-8",
-        transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
         size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
       });
     });
 
     aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.RECEIVED_RESPONSE_CONTENT, () => {
       let requestItem = RequestsMenu.getItemAtIndex(0);
 
       ok(requestItem.attachment.responseContent,
@@ -183,17 +178,16 @@ function test() {
       is(requestItem.attachment.responseContent.content.text, "Hello world!",
         "The responseContent attachment has an incorrect |content.text| property.");
       is(requestItem.attachment.responseContent.content.size, 12,
         "The responseContent attachment has an incorrect |content.size| property.");
 
       verifyRequestItemTarget(requestItem, "GET", SIMPLE_SJS, {
         type: "plain",
         fullMimeType: "text/plain; charset=utf-8",
-        transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
         size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
       });
     });
 
     aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.UPDATING_EVENT_TIMINGS, () => {
       let requestItem = RequestsMenu.getItemAtIndex(0);
 
       is(typeof requestItem.attachment.totalTime, "number",
--- a/browser/devtools/netmonitor/test/browser_net_sort-01.js
+++ b/browser/devtools/netmonitor/test/browser_net_sort-01.js
@@ -197,57 +197,52 @@ function test() {
         "The requests menu items aren't ordered correctly. Fifth item is misplaced.");
 
       verifyRequestItemTarget(RequestsMenu.getItemAtIndex(a),
         "GET", STATUS_CODES_SJS + "?sts=100", {
           status: 101,
           statusText: "Switching Protocols",
           type: "plain",
           fullMimeType: "text/plain; charset=utf-8",
-          transferred: L10N.getStr("networkMenu.sizeUnavailable"),
           size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0),
           time: true
         });
       verifyRequestItemTarget(RequestsMenu.getItemAtIndex(b),
         "GET", STATUS_CODES_SJS + "?sts=200", {
           status: 202,
           statusText: "Created",
           type: "plain",
           fullMimeType: "text/plain; charset=utf-8",
-          transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
           size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
           time: true
         });
       verifyRequestItemTarget(RequestsMenu.getItemAtIndex(c),
         "GET", STATUS_CODES_SJS + "?sts=300", {
           status: 303,
           statusText: "See Other",
           type: "plain",
           fullMimeType: "text/plain; charset=utf-8",
-          transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
           size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0),
           time: true
         });
       verifyRequestItemTarget(RequestsMenu.getItemAtIndex(d),
         "GET", STATUS_CODES_SJS + "?sts=400", {
           status: 404,
           statusText: "Not Found",
           type: "plain",
           fullMimeType: "text/plain; charset=utf-8",
-          transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
           size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
           time: true
         });
       verifyRequestItemTarget(RequestsMenu.getItemAtIndex(e),
         "GET", STATUS_CODES_SJS + "?sts=500", {
           status: 501,
           statusText: "Not Implemented",
           type: "plain",
           fullMimeType: "text/plain; charset=utf-8",
-          transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
           size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
           time: true
         });
 
       return promise.resolve(null);
     }
 
     aDebuggee.performRequests();
--- a/browser/devtools/netmonitor/test/browser_net_sort-02.js
+++ b/browser/devtools/netmonitor/test/browser_net_sort-02.js
@@ -98,34 +98,16 @@ function test() {
         })
         .then(() => {
           info("Testing type sort, ascending. Checking sort loops correctly.");
           EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-type-button"));
           testHeaders("type", "ascending");
           return testContents([0, 1, 2, 3, 4]);
         })
         .then(() => {
-          info("Testing transferred sort, ascending.");
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-transferred-button"));
-          testHeaders("transferred", "ascending");
-          return testContents([0, 1, 2, 3, 4]);
-        })
-        .then(() => {
-          info("Testing transferred sort, descending.");
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-transferred-button"));
-          testHeaders("transferred", "descending");
-          return testContents([4, 3, 2, 1, 0]);
-        })
-        .then(() => {
-          info("Testing transferred sort, ascending. Checking sort loops correctly.");
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-transferred-button"));
-          testHeaders("transferred", "ascending");
-          return testContents([0, 1, 2, 3, 4]);
-        })
-        .then(() => {
           info("Testing size sort, ascending.");
           EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-size-button"));
           testHeaders("size", "ascending");
           return testContents([0, 1, 2, 3, 4]);
         })
         .then(() => {
           info("Testing size sort, descending.");
           EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-size-button"));
@@ -212,61 +194,56 @@ function test() {
 
       verifyRequestItemTarget(RequestsMenu.getItemAtIndex(a),
         "GET1", SORTING_SJS + "?index=1", {
           fuzzyUrl: true,
           status: 101,
           statusText: "Meh",
           type: "1",
           fullMimeType: "text/1",
-          transferred: L10N.getStr("networkMenu.sizeUnavailable"),
           size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0),
           time: true
         });
       verifyRequestItemTarget(RequestsMenu.getItemAtIndex(b),
         "GET2", SORTING_SJS + "?index=2", {
           fuzzyUrl: true,
           status: 200,
           statusText: "Meh",
           type: "2",
           fullMimeType: "text/2",
-          transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
           size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
           time: true
         });
       verifyRequestItemTarget(RequestsMenu.getItemAtIndex(c),
         "GET3", SORTING_SJS + "?index=3", {
           fuzzyUrl: true,
           status: 300,
           statusText: "Meh",
           type: "3",
           fullMimeType: "text/3",
-          transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
           size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
           time: true
         });
       verifyRequestItemTarget(RequestsMenu.getItemAtIndex(d),
         "GET4", SORTING_SJS + "?index=4", {
           fuzzyUrl: true,
           status: 400,
           statusText: "Meh",
           type: "4",
           fullMimeType: "text/4",
-          transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.03),
           size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.03),
           time: true
         });
       verifyRequestItemTarget(RequestsMenu.getItemAtIndex(e),
         "GET5", SORTING_SJS + "?index=5", {
           fuzzyUrl: true,
           status: 500,
           statusText: "Meh",
           type: "5",
           fullMimeType: "text/5",
-          transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.04),
           size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.04),
           time: true
         });
 
       return promise.resolve(null);
     }
 
     aDebuggee.performRequests();
--- a/browser/devtools/netmonitor/test/browser_net_sort-03.js
+++ b/browser/devtools/netmonitor/test/browser_net_sort-03.js
@@ -125,69 +125,64 @@ function test() {
       for (let i = 0, len = aOrder.length / 5; i < len; i++) {
         verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i]),
           "GET1", SORTING_SJS + "?index=1", {
             fuzzyUrl: true,
             status: 101,
             statusText: "Meh",
             type: "1",
             fullMimeType: "text/1",
-            transferred: L10N.getStr("networkMenu.sizeUnavailable"),
             size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0),
             time: true
           });
       }
       for (let i = 0, len = aOrder.length / 5; i < len; i++) {
         verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len]),
           "GET2", SORTING_SJS + "?index=2", {
             fuzzyUrl: true,
             status: 200,
             statusText: "Meh",
             type: "2",
             fullMimeType: "text/2",
-            transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
             size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
             time: true
           });
       }
       for (let i = 0, len = aOrder.length / 5; i < len; i++) {
         verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 2]),
           "GET3", SORTING_SJS + "?index=3", {
             fuzzyUrl: true,
             status: 300,
             statusText: "Meh",
             type: "3",
             fullMimeType: "text/3",
-            transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
             size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
             time: true
           });
       }
       for (let i = 0, len = aOrder.length / 5; i < len; i++) {
         verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 3]),
           "GET4", SORTING_SJS + "?index=4", {
             fuzzyUrl: true,
             status: 400,
             statusText: "Meh",
             type: "4",
             fullMimeType: "text/4",
-            transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.03),
             size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.03),
             time: true
           });
       }
       for (let i = 0, len = aOrder.length / 5; i < len; i++) {
         verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 4]),
           "GET5", SORTING_SJS + "?index=5", {
             fuzzyUrl: true,
             status: 500,
             statusText: "Meh",
             type: "5",
             fullMimeType: "text/5",
-            transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.04),
             size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.04),
             time: true
           });
       }
 
       return promise.resolve(null);
     }
 
--- a/browser/devtools/netmonitor/test/browser_net_timeline_ticks.js
+++ b/browser/devtools/netmonitor/test/browser_net_timeline_ticks.js
@@ -7,22 +7,16 @@
 
 function test() {
   initNetMonitor(SIMPLE_URL).then(([aTab, aDebuggee, aMonitor]) => {
     info("Starting test... ");
 
     let { document, L10N, NetMonitorView } = aMonitor.panelWin;
     let { RequestsMenu } = NetMonitorView;
 
-    // Disable transferred size column support for this test.
-    // Without this, the waterfall only has enough room for one division, which
-    // would remove most of the value of this test.
-    document.querySelector("#requests-menu-transferred-header-box").hidden = true;
-    document.querySelector("#requests-menu-item-template .requests-menu-transferred").hidden = true;
-
     RequestsMenu.lazyUpdate = false;
 
     ok(document.querySelector("#requests-menu-waterfall-label"),
       "An timeline label should be displayed when the frontend is opened.");
     ok(document.querySelectorAll(".requests-menu-timings-division").length == 0,
       "No tick labels should be displayed when the frontend is opened.");
 
     ok(!RequestsMenu._canvas,
--- a/browser/devtools/netmonitor/test/head.js
+++ b/browser/devtools/netmonitor/test/head.js
@@ -259,17 +259,17 @@ function verifyRequestItemTarget(aReques
 
   let requestsMenu = aRequestItem.ownerView;
   let widgetIndex = requestsMenu.indexOfItem(aRequestItem);
   let visibleIndex = requestsMenu.visibleItems.indexOf(aRequestItem);
 
   info("Widget index of item: " + widgetIndex);
   info("Visible index of item: " + visibleIndex);
 
-  let { fuzzyUrl, status, statusText, type, fullMimeType, transferred, size, time } = aData;
+  let { fuzzyUrl, status, statusText, type, fullMimeType, size, time } = aData;
   let { attachment, target } = aRequestItem
 
   let uri = Services.io.newURI(aUrl, null, null).QueryInterface(Ci.nsIURL);
   let name = uri.fileName || "/";
   let query = uri.query;
   let hostPort = uri.hostPort;
 
   if (fuzzyUrl) {
@@ -314,24 +314,16 @@ function verifyRequestItemTarget(aReques
   if (type !== undefined) {
     let value = target.querySelector(".requests-menu-type").getAttribute("value");
     let tooltip = target.querySelector(".requests-menu-type").getAttribute("tooltiptext");
     info("Displayed type: " + value);
     info("Tooltip type: " + tooltip);
     is(value, type, "The displayed type is incorrect.");
     is(tooltip, fullMimeType, "The tooltip type is incorrect.");
   }
-  if (transferred !== undefined) {
-    let value = target.querySelector(".requests-menu-transferred").getAttribute("value");
-    let tooltip = target.querySelector(".requests-menu-transferred").getAttribute("tooltiptext");
-    info("Displayed transferred size: " + value);
-    info("Tooltip transferred size: " + tooltip);
-    is(value, transferred, "The displayed transferred size is incorrect.");
-    is(tooltip, transferred, "The tooltip transferred size is incorrect.");
-  }
   if (size !== undefined) {
     let value = target.querySelector(".requests-menu-size").getAttribute("value");
     let tooltip = target.querySelector(".requests-menu-size").getAttribute("tooltiptext");
     info("Displayed size: " + value);
     info("Tooltip size: " + tooltip);
     is(value, size, "The displayed size is incorrect.");
     is(tooltip, size, "The tooltip size is incorrect.");
   }
--- a/browser/locales/en-US/chrome/browser/devtools/netmonitor.dtd
+++ b/browser/locales/en-US/chrome/browser/devtools/netmonitor.dtd
@@ -37,24 +37,18 @@
 <!-- LOCALIZATION NOTE (netmonitorUI.toolbar.domain): This is the label displayed
   -  in the network table toolbar, above the "domain" column. -->
 <!ENTITY netmonitorUI.toolbar.domain      "Domain">
 
 <!-- LOCALIZATION NOTE (netmonitorUI.toolbar.type): This is the label displayed
   -  in the network table toolbar, above the "type" column. -->
 <!ENTITY netmonitorUI.toolbar.type        "Type">
 
-<!-- LOCALIZATION NOTE (netmonitorUI.toolbar.transferred): This is the label displayed
-  -  in the network table toolbar, above the "transferred" column, which is the
-  -  compressed / encoded size. -->
-<!ENTITY netmonitorUI.toolbar.transferred "Transferred">
-
 <!-- LOCALIZATION NOTE (netmonitorUI.toolbar.size): This is the label displayed
-  -  in the network table toolbar, above the "size" column, which is the
-  -  uncompressed / decoded size. -->
+  -  in the network table toolbar, above the "size" column. -->
 <!ENTITY netmonitorUI.toolbar.size        "Size">
 
 <!-- LOCALIZATION NOTE (netmonitorUI.toolbar.waterfall): This is the label displayed
   -  in the network table toolbar, above the "waterfall" column. -->
 <!ENTITY netmonitorUI.toolbar.waterfall   "Timeline">
 
 <!-- LOCALIZATION NOTE (debuggerUI.tab.headers): This is the label displayed
   -  in the network details pane identifying the headers tab. -->
--- a/browser/locales/en-US/chrome/browser/devtools/netmonitor.properties
+++ b/browser/locales/en-US/chrome/browser/devtools/netmonitor.properties
@@ -124,21 +124,16 @@ networkMenu.empty=No requests
 # information about all requests. Parameters: #1 is the number of requests,
 # #2 is the size, #3 is the number of seconds.
 networkMenu.summary=One request, #2 KB, #3 s;#1 requests, #2 KB, #3 s
 
 # LOCALIZATION NOTE (networkMenu.sizeKB): This is the label displayed
 # in the network menu specifying the size of a request (in kilobytes).
 networkMenu.sizeKB=%S KB
 
-# LOCALIZATION NOTE (networkMenu.sizeUnavailable): This is the label displayed
-# in the network menu specifying the transferred size of a request is
-# unavailable.
-networkMenu.sizeUnavailable=—
-
 # LOCALIZATION NOTE (networkMenu.totalMS): This is the label displayed
 # in the network menu specifying the time for a request to finish (in milliseconds).
 networkMenu.totalMS=→ %S ms
 
 # LOCALIZATION NOTE (networkMenu.millisecond): This is the label displayed
 # in the network menu specifying timing interval divisions (in milliseconds).
 networkMenu.millisecond=%S ms
 
--- a/browser/locales/en-US/chrome/browser/loop/loop.properties
+++ b/browser/locales/en-US/chrome/browser/loop/loop.properties
@@ -220,16 +220,22 @@ call_progress_connecting_description=Connecting…
 ## when the other client is actually ringing.
 ## https://people.mozilla.org/~dhenein/labs/loop-mvp-spec/#call-outgoing
 call_progress_ringing_description=Ringing…
 
 peer_ended_conversation2=The person you were calling has ended the conversation.
 conversation_has_ended=Your conversation has ended.
 restart_call=Rejoin
 
+## LOCALIZATION NOTE (contact_unavailable_title): The title displayed
+## when a contact is unavailable. Don't translate the part between {{..}}
+## because this will be replaced by the contact's name.
+contact_unavailable_title={{contactName}} is unavailable.
+generic_contact_unavailable_title=This person is unavailable.
+
 generic_failure_title=Something went wrong.
 generic_failure_with_reason2=You can try again or email a link to be reached at later.
 generic_failure_no_reason2=Would you like to try again?
 
 ## LOCALIZATION NOTE (contact_offline_title): Title for
 ## https://people.mozilla.org/~dhenein/labs/loop-mvp-spec/#link-prompt
 ## displayed when the contact is offline.
 contact_offline_title=This person is not online
--- a/browser/locales/en-US/chrome/browser/preferences/colors.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/colors.dtd
@@ -1,22 +1,22 @@
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 <!ENTITY  colorsDialog.title              "Colors">
 <!ENTITY  window.width                    "38em">
 <!ENTITY  window.macWidth                 "41em">
 
-<!ENTITY  allowPagesToUseColors.label           "Allow pages to choose their own colors, instead of my selections above:">
-<!ENTITY  allowPagesToUseColors.accesskey       "A">
+<!ENTITY  overridePageColors.label        "Override the colors specified by the page with my selections above:">
+<!ENTITY  overridePageColors.accesskey    "O">
 
-<!ENTITY  allowPagesToUseColors.automatic.label "Automatic">
-<!ENTITY  allowPagesToUseColors.always.label    "Always">
-<!ENTITY  allowPagesToUseColors.never.label     "Never">
+<!ENTITY  overridePageColors.always.label "Always">
+<!ENTITY  overridePageColors.auto.label   "Only with High Contrast themes">
+<!ENTITY  overridePageColors.never.label  "Never">
 
 <!ENTITY  color                           "Text and Background">
 <!ENTITY  textColor.label                 "Text:">
 <!ENTITY  textColor.accesskey             "T">
 <!ENTITY  backgroundColor.label           "Background:">
 <!ENTITY  backgroundColor.accesskey       "B">
 <!ENTITY  useSystemColors.label           "Use system colors">
 <!ENTITY  useSystemColors.accesskey       "s">
--- a/browser/locales/en-US/chrome/browser/shellservice.properties
+++ b/browser/locales/en-US/chrome/browser/shellservice.properties
@@ -12,18 +12,20 @@ setDefaultBrowserConfirm.label     = Use
 setDefaultBrowserConfirm.accesskey = U
 setDefaultBrowserOptions.label     = Options
 setDefaultBrowserOptions.accesskey = O
 setDefaultBrowserNotNow.label      = Not now
 setDefaultBrowserNotNow.accesskey  = N
 setDefaultBrowserNever.label       = Don't ask me again
 setDefaultBrowserNever.accesskey   = D
 
-# LOCALIZATION NOTE (setDefaultBrowserTitle, setDefaultBrowserMessage, setDefaultBrowserDontAsk):
+# LOCALIZATION NOTE (setDefaultBrowserTitle, setDefaultBrowserMessage, setDefaultBrowserDontAsk, setDefaultBrowserAlertConfirm.label, setDefaultBrowserAlertNotNow.label):
 # These strings are used as an alternative to the ones above, in a modal dialog.
 # %S will be replaced by brandShortName
 setDefaultBrowserTitle=Default Browser
 setDefaultBrowserMessage=%S is not currently set as your default browser. Would you like to make it your default browser?
 setDefaultBrowserDontAsk=Always perform this check when starting %S.
+setDefaultBrowserAlertConfirm.label=Use %S as my default browser
+setDefaultBrowserAlertNotNow.label=Not now
 
 desktopBackgroundLeafNameWin=Desktop Background.bmp
 DesktopBackgroundDownloading=Saving Picture…
 DesktopBackgroundSet=Set Desktop Background
--- a/browser/metro/theme/touchcontrols.css
+++ b/browser/metro/theme/touchcontrols.css
@@ -40,27 +40,31 @@
 .fullscreenButton {
   background: url("chrome://browser/skin/images/fullscreen-hdpi.png") no-repeat center;
 }
 
 .fullscreenButton[fullscreened="true"] {
   background: url("chrome://browser/skin/images/exitfullscreen-hdpi.png") no-repeat center;
 }
 
+.controlBar[fullscreen-unavailable] .fullscreenButton {
+  display: none;
+}
+
 .playButton {
   background: url("chrome://browser/skin/images/pause-hdpi.png") no-repeat center;
 }
 
 /*
  * Normally the button bar has fullscreen spacer play spacer mute, but if
  * this is an audio control rather than a video control, the fullscreen button
  * is hidden by videocontrols.xml, and that alters the position of the
  * play button.  This workaround moves it back to center.
  */
-.controlBar.audio-only .playButton {
+.controlBar[fullscreen-unavailable] .playButton {
   transform: translateX(28px);
 }
 
 .playButton[paused="true"] {
   background: url("chrome://browser/skin/images/play-hdpi.png") no-repeat center;
 }
 
 .castingButton {
--- a/browser/themes/linux/searchbar.css
+++ b/browser/themes/linux/searchbar.css
@@ -1,12 +1,16 @@
 /* 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/. */
 
+#PopupSearchAutoComplete {
+  -moz-margin-start: -24px;
+}
+
 .searchbar-textbox {
   min-height: 22px;
   background-color: -moz-field;
 }
 
 .autocomplete-textbox-container {
   -moz-box-align: stretch;
 }
@@ -19,17 +23,16 @@
   font-weight: bold;
 }
 
 /* Engine button */
 .searchbar-engine-image {
   height: 16px;
   width: 16px;
   list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
-  -moz-margin-start: 2px;
 }
 
 .searchbar-engine-button {
   -moz-appearance: none;
   min-width: 0;
   margin: 0;
   border: 0;
   -moz-box-align: center;
@@ -67,24 +70,22 @@ menuitem[cmd="cmd_clearhistory"][disable
   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;
+  -moz-margin-start: 2px;
 }
 
 .searchbar-search-button[addengines="true"] {
   list-style-image: url("chrome://browser/skin/search-indicator-badge-add.png");
 }
 
 .searchbar-search-button:hover {
   -moz-image-region: rect(0, 40px, 20px, 20px);
@@ -235,17 +236,17 @@ searchbar[oneoffui] .searchbar-engine-bu
   border-top: none !important;
 }
 
 .search-panel-tree > .autocomplete-treebody::-moz-tree-cell-text {
   -moz-padding-start: 4px;
 }
 
 .search-panel-tree > .autocomplete-treebody::-moz-tree-image {
-  -moz-padding-start: 6px;
+  -moz-padding-start: 5px;
   width: 14px;
   height: 14px;
 }
 
 .search-panel-tree > .autocomplete-treebody::-moz-tree-image(fromhistory) {
   list-style-image: url("chrome://browser/skin/search-history-icon.svg#search-history-icon");
 }
 
--- a/browser/themes/osx/searchbar.css
+++ b/browser/themes/osx/searchbar.css
@@ -1,12 +1,16 @@
 /* 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/. */
 
+#PopupSearchAutoComplete {
+  -moz-margin-start: -23px;
+}
+
 .searchbar-dropmarker-image {
   --searchbar-dropmarker-url: url("chrome://browser/skin/searchbar-dropmarker.png");
   --searchbar-dropmarker-2x-url: url("chrome://browser/skin/searchbar-dropmarker@2x.png");
 }
 
 .searchbar-textbox {
   border-radius: 10000px;
 }
@@ -44,28 +48,27 @@
 
 .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;
+  -moz-margin-start: 3px;
+  -moz-margin-end: 1px;
 }
 
 .searchbar-search-button[addengines="true"] {
   list-style-image: url("chrome://browser/skin/search-indicator-badge-add.png");
 }
 
 .searchbar-search-button:hover {
   -moz-image-region: rect(0, 40px, 20px, 20px);
--- a/browser/themes/shared/devtools/netmonitor.inc.css
+++ b/browser/themes/shared/devtools/netmonitor.inc.css
@@ -161,21 +161,16 @@
   width: 4em;
 }
 
 .requests-menu-size {
   text-align: center;
   width: 8em;
 }
 
-.requests-menu-transferred {
-  text-align: center;
-  width: 8em;
-}
-
 /* Network requests table: status codes */
 
 box.requests-menu-status {
   background: #fff;
   width: 10px;
   -moz-margin-start: 5px;
   -moz-margin-end: 5px;
   border-radius: 10px;
--- a/browser/themes/windows/searchbar.css
+++ b/browser/themes/windows/searchbar.css
@@ -1,12 +1,16 @@
 /* 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/. */
 
+#PopupSearchAutoComplete {
+  -moz-margin-start: -25px;
+}
+
 .searchbar-dropmarker-image {
   --searchbar-dropmarker-url: url("chrome://browser/skin/searchbar-dropdown-arrow.png");
 }
 
 .autocomplete-textbox-container {
   -moz-box-align: stretch;
 }
 
@@ -16,17 +20,16 @@
 
 /* ::::: searchbar-engine-button ::::: */
 
 .searchbar-engine-image {
   height: 16px;
   width: 16px;
   list-style-image: url("chrome://global/skin/icons/folder-item.png");
   -moz-image-region: rect(0px, 16px, 16px, 0px);
-  -moz-margin-start: 2px;
 }
 
 .searchbar-engine-button {
   -moz-appearance: none;
   min-width: 0;
   margin: 0;
   padding: 0;
   -moz-padding-end: 2px;
@@ -78,24 +81,24 @@
 .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;
+  margin-top: 1px;
+  margin-bottom: 1px;
+  -moz-margin-start: 4px;
 }
 
 .searchbar-search-button[addengines="true"] {
   list-style-image: url("chrome://browser/skin/search-indicator-badge-add.png");
 }
 
 .searchbar-search-button:hover {
   -moz-image-region: rect(0, 40px, 20px, 20px);
--- a/mobile/android/base/tests/BaseTest.java
+++ b/mobile/android/base/tests/BaseTest.java
@@ -854,44 +854,44 @@ abstract class BaseTest extends BaseRobo
             pageShowExpecter.blockForEvent();
             pageShowExpecter.unregisterListener();
         }
 
         public void forward() {
             Actions.EventExpecter pageShowExpecter = mActions.expectGeckoEvent("Content:PageShow");
 
             if (devType.equals("tablet")) {
-                Element fwdBtn = mDriver.findElement(getActivity(), R.id.forward);
-                fwdBtn.click();
+                mSolo.waitForView(R.id.forward);
+                mSolo.clickOnView(mSolo.getView(R.id.forward));
             } else {
                 mActions.sendSpecialKey(Actions.SpecialKey.MENU);
                 waitForText("^New Tab$");
                 if (!osVersion.equals("2.x")) {
-                    Element fwdBtn = mDriver.findElement(getActivity(), R.id.forward);
-                    fwdBtn.click();
+                    mSolo.waitForView(R.id.forward);
+                    mSolo.clickOnView(mSolo.getView(R.id.forward));
                 } else {
                     mSolo.clickOnText("^Forward$");
                 }
                 ensureMenuClosed();
             }
 
             pageShowExpecter.blockForEvent();
             pageShowExpecter.unregisterListener();
         }
 
         public void reload() {
             if (devType.equals("tablet")) {
-                Element reloadBtn = mDriver.findElement(getActivity(), R.id.reload);
-                reloadBtn.click();
+                mSolo.waitForView(R.id.reload);
+                mSolo.clickOnView(mSolo.getView(R.id.reload));
             } else {
                 mActions.sendSpecialKey(Actions.SpecialKey.MENU);
                 waitForText("^New Tab$");
                 if (!osVersion.equals("2.x")) {
-                    Element reloadBtn = mDriver.findElement(getActivity(), R.id.reload);
-                    reloadBtn.click();
+                    mSolo.waitForView(R.id.reload);
+                    mSolo.clickOnView(mSolo.getView(R.id.reload));
                 } else {
                     mSolo.clickOnText("^Reload$");
                 }
                 ensureMenuClosed();
             }
         }
 
         // DEPRECATED!
--- a/mobile/android/chrome/content/aboutPasswords.js
+++ b/mobile/android/chrome/content/aboutPasswords.js
@@ -27,56 +27,80 @@ function copyStringAndToast(string, noti
     gChromeWin.NativeWindow.toast.show(notifyString, "short");
   } catch (e) {
     debug("Error copying from about:passwords");
     gChromeWin.NativeWindow.toast.show(gStringBundle.GetStringFromName("passwordsDetails.copyFailed"), "short");
   }
 }
 
 let Passwords = {
+  _logins: [],
+
+  _getLogins: function() {
+    let logins;
+    try {
+      logins = Services.logins.getAllLogins();
+    } catch(e) {
+      // Master password was not entered
+      debug("Master password permissions error: " + e);
+      logins = [];
+    }
+
+    logins.sort((a, b) => a.hostname.localeCompare(b.hostname));
+    return this._logins = logins;
+  },
+
   init: function () {
     window.addEventListener("popstate", this , false);
 
     Services.obs.addObserver(this, "passwordmgr-storage-changed", false);
 
-    this._loadList();
+    this._loadList(this._getLogins());
 
     document.getElementById("copyusername-btn").addEventListener("click", this._copyUsername.bind(this), false);
     document.getElementById("copypassword-btn").addEventListener("click", this._copyPassword.bind(this), false);
     document.getElementById("details-header").addEventListener("click", this._openLink.bind(this), false);
 
+    let filterInput = document.getElementById("filter-input");
+    let filterContainer = document.getElementById("filter-input-container");
+
+    filterInput.addEventListener("input", this._filter.bind(this), false);
+    filterInput.addEventListener("blur", (event) => {
+      filterContainer.setAttribute("hidden", true);
+    });
+
+    document.getElementById("filter-button").addEventListener("click", (event) => {
+      filterContainer.removeAttribute("hidden");
+      filterInput.focus();
+    }, false);
+
+    document.getElementById("filter-clear").addEventListener("click", (event) => {
+      filterInput.blur();
+      filterInput.value = "";
+      this._loadList(this._logins);
+    }, false);
+
     this._showList();
   },
 
   uninit: function () {
     Services.obs.removeObserver(this, "passwordmgr-storage-changed");
     window.removeEventListener("popstate", this, false);
   },
 
-  _loadList: function () {
-    let logins;
-    try {
-      logins = Services.logins.getAllLogins();
-    } catch(e) {
-      // Master password was not entered
-      debug("Master password permissions error: " + e);
-      return;
-    }
+  _loadList: function (logins) {
+    let list = document.getElementById("logins-list");
+    let newList = list.cloneNode(false);
 
-    logins.forEach(login => login.QueryInterface(Ci.nsILoginMetaInfo));
-
-    logins.sort((a, b) => a.hostname.localeCompare(b.hostname));
-
-    // Clear all content before filling the logins
-    let list = document.getElementById("logins-list");
-    list.innerHTML = "";
     logins.forEach(login => {
       let item = this._createItemForLogin(login);
-      list.appendChild(item);
+      newList.appendChild(item);
     });
+
+    list.parentNode.replaceChild(newList, list);
   },
 
   _showList: function () {
     // Hide the detail page and show the list
     let details = document.getElementById("login-details");
     details.setAttribute("hidden", "true");
     let list = document.getElementById("logins-list");
     list.removeAttribute("hidden");
@@ -153,17 +177,17 @@ let Passwords = {
       }
     }
   },
 
   observe: function (subject, topic, data) {
     switch(topic) {
       case "passwordmgr-storage-changed": {
         // Reload passwords content.
-        this._loadList();
+        this._loadList(this._getLogins());
         break;
       }
     }
   },
 
   _showDetails: function (listItem) {
     let detailItem = document.querySelector("#login-details > .login-item");
     let login = detailItem.login = listItem.login;
@@ -212,13 +236,33 @@ let Passwords = {
     let login = detailItem.login;
     copyStringAndToast(login.password, gStringBundle.GetStringFromName("passwordsDetails.passwordCopied"));
   },
 
   _openLink: function (clickEvent) {
     let url = clickEvent.currentTarget.getAttribute("link");
     let BrowserApp = gChromeWin.BrowserApp;
     BrowserApp.addTab(url, { selected: true, parentId: BrowserApp.selectedTab.id });
+  },
+
+  _filter: function(event) {
+    let value = event.target.value;
+    let logins = this._logins.filter((login) => {
+      if (login.hostname.toLowerCase().indexOf(value) != -1) {
+        return true;
+      }
+      if (login.username &&
+          login.username.toLowerCase().indexOf(value) != -1) {
+        return true;
+      }
+      if (login.httpRealm &&
+          login.httpRealm.toLowerCase().indexOf(value) != -1) {
+        return true;
+      }
+      return false;
+    });
+
+    this._loadList(logins);
   }
 };
 
 window.addEventListener("load", Passwords.init.bind(Passwords), false);
 window.addEventListener("unload", Passwords.uninit.bind(Passwords), false);
--- a/mobile/android/chrome/content/aboutPasswords.xhtml
+++ b/mobile/android/chrome/content/aboutPasswords.xhtml
@@ -18,16 +18,19 @@
     <link rel="icon" type="image/png" sizes="64x64" href="chrome://branding/content/favicon64.png" />
     <link rel="stylesheet" href="chrome://browser/skin/aboutBase.css" type="text/css"/>
     <link rel="stylesheet" href="chrome://browser/skin/aboutPasswords.css" type="text/css"/>
     <script type="application/javascript;version=1.8" src="chrome://browser/content/aboutPasswords.js"></script>
   </head>
   <body dir="&locale.dir;">
     <div id="passwords-header" class="header">
       <div>&aboutPasswords.title;</div>
+      <ul class="toolbar-buttons">
+        <li id="filter-button"></li>
+      </ul>
     </div>
     <div id="logins-list" class="list" hidden="true">
     </div>
     <div id="login-details" class="list" hidden="true">
       <div class="login-item list-item">
         <img class="icon"/>
         <div id="details-header" class="inner">
           <div class="details">
@@ -38,10 +41,14 @@
           <div id="detail-age"></div>
         </div>
         <div class="buttons">
           <button id="copyusername-btn">&aboutPasswords.copyUsername;</button>
           <button id="copypassword-btn">&aboutPasswords.copyPassword;</button>
         </div>
       </div>
     </div>
+    <div id="filter-input-container" hidden="true">
+      <input id="filter-input" type="search"/>
+      <div id="filter-clear"></div>
+    </div>
   </body>
 </html>
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -11,23 +11,24 @@ let Cu = Components.utils;
 let Cr = Components.results;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/AddonManager.jsm");
 Cu.import('resource://gre/modules/Payment.jsm');
 Cu.import("resource://gre/modules/NotificationDB.jsm");
 Cu.import("resource://gre/modules/SpatialNavigation.jsm");
-// TODO: Lazy load this based on a message...?
-Cu.import("resource://gre/modules/DownloadNotifications.jsm");
 
 #ifdef ACCESSIBILITY
 Cu.import("resource://gre/modules/accessibility/AccessFu.jsm");
 #endif
 
+XPCOMUtils.defineLazyModuleGetter(this, "DownloadNotifications",
+                                  "resource://gre/modules/DownloadNotifications.jsm");
+
 XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
                                   "resource://gre/modules/FileUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "JNI",
                                   "resource://gre/modules/JNI.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "UITelemetry",
                                   "resource://gre/modules/UITelemetry.jsm");
@@ -367,16 +368,17 @@ var BrowserApp = {
         Services.obs.notifyObservers(window, "browser-delayed-startup-finished", "");
         Messaging.sendRequest({ type: "Gecko:DelayedStartup" });
 
         // Queue up some other performance-impacting initializations
         Services.tm.mainThread.dispatch(function() {
           Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
 
           CastingApps.init();
+          DownloadNotifications.init();
 
           // Delay this a minute because there's no rush
           setTimeout(() => {
             BrowserApp.gmpInstallManager = new GMPInstallManager();
             BrowserApp.gmpInstallManager.simpleCheckAndInstall().then(null, () => {});
           }, 1000 * 60);
         }, Ci.nsIThread.DISPATCH_NORMAL);
 
@@ -461,17 +463,16 @@ var BrowserApp = {
     }, false);
 
     // When a restricted key is pressed in DOM full-screen mode, we should display
     // the "Press ESC to exit" warning message.
     window.addEventListener("MozShowFullScreenWarning", showFullScreenWarning, true);
 
     NativeWindow.init();
     LightWeightThemeWebInstaller.init();
-    DownloadNotifications.init();
     FormAssistant.init();
     IndexedDB.init();
     HealthReportStatusListener.init();
     XPInstallObserver.init();
     CharacterEncoding.init();
     ActivityObserver.init();
     // TODO: replace with Android implementation of WebappOSUtils.isLaunchable.
     Cu.import("resource://gre/modules/Webapps.jsm");
--- a/mobile/android/themes/core/aboutPasswords.css
+++ b/mobile/android/themes/core/aboutPasswords.css
@@ -1,11 +1,15 @@
 /* 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/. */
+
+%filter substitution
+%include defines.inc
+
 .hidden {
   display: none;
 }
 
 .details {
   width: 100%;
 }
 
@@ -25,8 +29,76 @@
   overflow: hidden;
   flex: 1;
 }
 
 .realm {
   /* hostname is not localized, so keep the margin on the left side */
   margin-left: .67em;
 }
+
+.toolbar-buttons {
+  list-style: none;
+}
+
+.toolbar-buttons > li {
+  background-position: center;
+  background-size: 32px 32px;
+  background-repeat: no-repeat;
+  height: 32px;
+  width: 32px;
+  margin: 0 15px;
+}
+
+#filter-input-container {
+  position: fixed;
+  bottom: 0;
+  width: 100%;
+  padding: 10px 0;
+  display: flex;
+  background: @color_about_background@;
+  border-top: 2px solid @color_about_item_border@;
+}
+
+#filter-input-container[hidden] {
+  display: none;
+}
+
+#filter-input {
+  flex: 1;
+  padding: 5px;
+  -moz-margin-start: 10px;
+  border-radius: 3px;
+}
+
+#filter-button {
+  background-image: url("resource://android/res/drawable-mdpi-v4/ab_search.png");
+}
+
+#filter-clear {
+  background-image: url("resource://android/res/drawable-mdpi-v4/close_edit_mode_light.png");
+  background-position: center;
+  background-size: 12px 12px;
+  background-repeat: no-repeat;
+  height: 32px;
+  width: 32px;
+  margin: 0 5px;
+}
+
+@media screen and (min-resolution: 1.25dppx) {
+  #filter-button {
+    background-image: url("resource://android/res/drawable-hdpi-v4/ab_search.png");
+  }
+
+  #filter-clear {
+    background-image: url("resource://android/res/drawable-hdpi-v4/close_edit_mode_light.png");
+  }
+}
+
+@media screen and (min-resolution: 2dppx) {
+  #filter-button {
+    background-image: url("resource://android/res/drawable-xhdpi-v4/ab_search.png");
+  }
+
+  #filter-clear {
+    background-image: url("resource://android/res/drawable-hdpi-v4/close_edit_mode_light.png");
+  }
+}
--- a/mobile/android/themes/core/jar.mn
+++ b/mobile/android/themes/core/jar.mn
@@ -31,17 +31,17 @@ chrome.jar:
 % override chrome://global/skin/about.css chrome://browser/skin/about.css
 % override chrome://global/skin/aboutMemory.css chrome://browser/skin/aboutMemory.css
 % override chrome://global/skin/aboutReader.css chrome://browser/skin/aboutReader.css
 % override chrome://global/skin/aboutSupport.css chrome://browser/skin/aboutSupport.css
 % override chrome://global/skin/media/videocontrols.css chrome://browser/skin/touchcontrols.css
 % override chrome://global/skin/netError.css chrome://browser/skin/netError.css
 
 #ifdef NIGHTLY_BUILD
-  skin/aboutPasswords.css                   (aboutPasswords.css)
+* skin/aboutPasswords.css                   (aboutPasswords.css)
 #endif
 
   skin/images/search.png                    (images/search.png)
   skin/images/lock.png                      (images/lock.png)
   skin/images/textfield.png                 (images/textfield.png)
 
   skin/images/5stars.png                    (images/5stars.png)
   skin/images/addons-32.png                 (images/addons-32.png)
--- a/mobile/android/themes/core/touchcontrols.css
+++ b/mobile/android/themes/core/touchcontrols.css
@@ -75,16 +75,20 @@
   background-color: transparent;
   background: url("chrome://browser/skin/images/fullscreen-hdpi.png") no-repeat center;
 }
 
 .fullscreenButton[fullscreened] {
   background: url("chrome://browser/skin/images/exitfullscreen-hdpi.png") no-repeat center;
 }
 
+.controlBar[fullscreen-unavailable] .fullscreenButton {
+  display: none;
+}
+
 /* bars */
 .scrubberStack {
   width: 100%;
   min-height: 32px;
   max-height: 32px;
   padding: 0px 8px;
   margin: 0px;
 }
--- a/python/mozboot/bin/bootstrap.py
+++ b/python/mozboot/bin/bootstrap.py
@@ -27,17 +27,17 @@ from optparse import OptionParser
 
 # The next two variables define where in the repository the Python files
 # reside. This is used to remotely download file content when it isn't
 # available locally.
 REPOSITORY_PATH_PREFIX = 'python/mozboot'
 
 REPOSITORY_PATHS = [
     'mozboot/__init__.py',
-    'mozboot/android-ndk-r8e.rb',
+    'mozboot/android-ndk.rb',
     'mozboot/android.py',
     'mozboot/base.py',
     'mozboot/bootstrap.py',
     'mozboot/centos.py',
     'mozboot/debian.py',
     'mozboot/fedora.py',
     'mozboot/freebsd.py',
     'mozboot/gentoo.py',
rename from python/mozboot/mozboot/android-ndk-r8e.rb
rename to python/mozboot/mozboot/android-ndk.rb
--- a/python/mozboot/mozboot/android-ndk-r8e.rb
+++ b/python/mozboot/mozboot/android-ndk.rb
@@ -1,10 +1,14 @@
 require "formula"
 
+# This is an antiquated version pinned to NDK revision r8e.  That's
+# the revision Mozilla's automation currently uses.  We could push
+# this to https://github.com/Homebrew/homebrew-versions if there's a
+# problem shipping it locally.
 class AndroidNdk < Formula
   homepage "http://developer.android.com/sdk/ndk/index.html"
 
   if MacOS.prefer_64_bit?
     url "http://dl.google.com/android/ndk/android-ndk-r8e-darwin-x86_64.tar.bz2"
     sha1 "8c8f0d7df5f160c3ef82f2f4836cbcaf18aabf68"
   else
     url "http://dl.google.com/android/ndk/android-ndk-r8e-darwin-x86.tar.bz2"
--- a/python/mozboot/mozboot/osx.py
+++ b/python/mozboot/mozboot/osx.py
@@ -319,21 +319,26 @@ class OSXBootstrapper(BaseBootstrapper):
             print(PACKAGE_MANAGER_OLD_CLANG % ('Homebrew',))
 
             subprocess.check_call([self.brew, '-v', 'install', 'llvm',
                 '--with-clang', '--all-targets'])
 
     def ensure_homebrew_mobile_android_packages(self):
         import android
 
+        # If we're run from a downloaded bootstrap.py, then android-ndk.rb is
+        # fetched into a temporary directory.  This finds that directory.
+        import inspect
+        path_to_android = os.path.abspath(os.path.dirname(inspect.getfile(android)))
+
         # We don't need wget because we install the Android SDK and NDK from
         # packages.  If we used the android.py module, we'd need wget.
         packages = [
             ('android-sdk', 'android-sdk'),
-            ('android-ndk', 'android-ndk-r8e.rb'), # This is a locally provided brew formula!
+            ('android-ndk', os.path.join(path_to_android, 'android-ndk.rb')), # This is a locally provided brew formula!
             ('ant', 'ant'),
             ('brew-cask', 'caskroom/cask/brew-cask'), # For installing Java later.
         ]
         self._ensure_homebrew_packages(packages)
 
         casks = [
             ('java', 'java'),
         ]
--- a/toolkit/content/tests/widgets/test_videocontrols_audio.html
+++ b/toolkit/content/tests/widgets/test_videocontrols_audio.html
@@ -32,18 +32,18 @@
       if (result) {
         return result;
       }
     }
     return false;
   }
 
   function loadedmetadata(event) {
-    var fullscreenButton = findElementByAttribute(video, 'class', 'fullscreenButton');
-    is(fullscreenButton.hidden, true, 'Fullscreen button is hidden');
+    var controlBar = findElementByAttribute(video, "class", "controlBar");
+    is(controlBar.getAttribute("fullscreen-unavailable"), "true", "Fullscreen button is hidden");
     SimpleTest.finish();
   }
 
   var video = document.getElementById("video");
 
   SpecialPowers.pushPrefEnv({"set": [["media.cache_size", 40000]]}, startTest);
   function startTest() {
     // Kick off test once audio has loaded.
--- a/toolkit/content/widgets/videocontrols.css
+++ b/toolkit/content/widgets/videocontrols.css
@@ -16,16 +16,20 @@
 
 .playButton,
 .muteButton,
 .scrubber .scale-slider,
 .volumeControl .scale-slider {
   -moz-user-focus: none;
 }
 
+.controlBar[fullscreen-unavailable] > .fullscreenButton {
+  display: none;
+}
+
 .mediaControlsFrame {
   direction: ltr;
   /* Prevent unwanted style inheritance. See bug 554717. */
   text-align: left;
   list-style-image: none !important;
   font: normal normal normal 100%/normal sans-serif !important;
   text-decoration: none !important;
 }
--- a/toolkit/content/widgets/videocontrols.xml
+++ b/toolkit/content/widgets/videocontrols.xml
@@ -338,22 +338,17 @@
 
                 firstFrameShown : false,
                 timeUpdateCount : 0,
                 maxCurrentTimeSeen : 0,
                 _isAudioOnly : false,
                 get isAudioOnly() { return this._isAudioOnly; },
                 set isAudioOnly(val) {
                     this._isAudioOnly = val;
-                    if (this._isAudioOnly) {
-                        this.controlBar.setAttribute("audio-only", true);
-                    } else {
-                        this.controlBar.removeAttribute("audio-only");
-                    }
-                    this.adjustControlSize();
+                    this.setFullscreenButtonState();
 
                     if (!this.isTopLevelSyntheticDocument)
                         return;
                     if (this._isAudioOnly) {
                         this.video.style.height = this._controlBarHeight + "px";
                         this.video.style.width = "66%";
                     } else {
                         this.video.style.removeProperty("height");
@@ -1060,19 +1055,22 @@
                 toggleFullscreen : function () {
                     this.isVideoInFullScreen() ?
                         document.mozCancelFullScreen() :
                         this.video.mozRequestFullScreen();
                 },
 
                 setFullscreenButtonState : function () {
                     if (this.isAudioOnly || !document.mozFullScreenEnabled) {
-                        this.fullscreenButton.hidden = true;
+                        this.controlBar.setAttribute("fullscreen-unavailable", true);
+                        this.adjustControlSize();
                         return;
                     }
+                    this.controlBar.removeAttribute("fullscreen-unavailable");
+                    this.adjustControlSize();
 
                     var attrName = this.isVideoInFullScreen() ? "exitfullscreenlabel" : "enterfullscreenlabel";
                     var value = this.fullscreenButton.getAttribute(attrName);
                     this.fullscreenButton.setAttribute("aria-label", value);
 
                     if (this.isVideoInFullScreen())
                         this.fullscreenButton.setAttribute("fullscreened", "true");
                     else
@@ -1387,25 +1385,26 @@
                     let minScrubberWidth = 25;
                     let minWidthAllControls = this._playButtonWidth +
                                               minScrubberWidth +
                                               this._durationLabelWidth +
                                               this._muteButtonWidth +
                                               this._volumeControlWidth +
                                               this._fullscreenButtonWidth;
 
-                    let isAudioOnly = this.isAudioOnly;
-                    if (isAudioOnly) {
+                    let isFullscreenUnavailable = this.controlBar.hasAttribute("fullscreen-unavailable");
+                    if (isFullscreenUnavailable) {
                         // When the fullscreen button is hidden we add margin-end to the volume stack.
                         minWidthAllControls -= this._fullscreenButtonWidth - this._volumeStackMarginEnd;
                     }
 
                     let minHeightForControlBar = this._controlBarHeight;
                     let minWidthOnlyPlayPause = this._playButtonWidth + this._muteButtonWidth;
 
+                    let isAudioOnly = this.isAudioOnly;
                     let videoHeight = isAudioOnly ? minHeightForControlBar : this.video.clientHeight;
                     let videoWidth = isAudioOnly ? minWidthAllControls : this.video.clientWidth;
 
                     // Adapt the size of the controls to the size of the video
                     if (this.video.readyState >= this.video.HAVE_METADATA) {
                       if (!this.isAudioOnly && this.video.videoWidth && this.video.videoHeight) {
                         var rect = this.video.getBoundingClientRect();
                         var widthRatio = rect.width / this.video.videoWidth;
--- a/toolkit/devtools/server/actors/webconsole.js
+++ b/toolkit/devtools/server/actors/webconsole.js
@@ -78,17 +78,16 @@ function WebConsoleActor(aConnection, aP
   this._onObserverNotification = this._onObserverNotification.bind(this);
   if (this.parentActor.isRootActor) {
     Services.obs.addObserver(this._onObserverNotification,
                              "last-pb-context-exited", false);
   }
 
   this.traits = {
     customNetworkRequest: !this._parentIsContentActor,
-    transferredResponseSize: true,
     evaluateJSAsync: true
   };
 }
 
 WebConsoleActor.l10n = new WebConsoleUtils.l10n("chrome://global/locale/console.properties");
 
 WebConsoleActor.prototype =
 {
@@ -1971,17 +1970,16 @@ NetworkEventActor.prototype =
     }
 
     let packet = {
       from: this.actorID,
       type: "networkEventUpdate",
       updateType: "responseContent",
       mimeType: aContent.mimeType,
       contentSize: aContent.text.length,
-      transferredSize: aContent.transferredSize,
       discardResponseBody: aDiscardedResponseBody,
     };
 
     this.conn.send(packet);
   },
 
   /**
    * Add network event timing information.
--- a/toolkit/devtools/webconsole/network-monitor.js
+++ b/toolkit/devtools/webconsole/network-monitor.js
@@ -1,15 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
-const {Cc, Ci, Cu, Cr} = require("chrome");
+const {Cc, Ci, Cu} = require("chrome");
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 loader.lazyGetter(this, "NetworkHelper", () => require("devtools/toolkit/webconsole/network-helper"));
 loader.lazyImporter(this, "Services", "resource://gre/modules/Services.jsm");
 loader.lazyImporter(this, "DevToolsUtils", "resource://gre/modules/devtools/DevToolsUtils.jsm");
 loader.lazyImporter(this, "NetUtil", "resource://gre/modules/NetUtil.jsm");
 loader.lazyImporter(this, "PrivateBrowsingUtils", "resource://gre/modules/PrivateBrowsingUtils.jsm");
@@ -52,72 +52,32 @@ const RESPONSE_BODY_LIMIT = 1048576; // 
  *        for more information.
  */
 function NetworkResponseListener(aOwner, aHttpActivity)
 {
   this.owner = aOwner;
   this.receivedData = "";
   this.httpActivity = aHttpActivity;
   this.bodySize = 0;
-  let channel = this.httpActivity.channel;
-  this._wrappedNotificationCallbacks = channel.notificationCallbacks;
-  channel.notificationCallbacks = this;
 }
 exports.NetworkResponseListener = NetworkResponseListener;
 
 NetworkResponseListener.prototype = {
   QueryInterface:
     XPCOMUtils.generateQI([Ci.nsIStreamListener, Ci.nsIInputStreamCallback,
-                           Ci.nsIRequestObserver, Ci.nsIInterfaceRequestor,
-                           Ci.nsISupports]),
-
-  // nsIInterfaceRequestor implementation
-
-  /**
-   * This object implements nsIProgressEventSink, but also needs to forward
-   * interface requests to the notification callbacks of other objects.
-   */
-  getInterface(iid) {
-    if (iid.equals(Ci.nsIProgressEventSink)) {
-      return this;
-    }
-    if (this._wrappedNotificationCallbacks) {
-      return this._wrappedNotificationCallbacks.getInterface(iid);
-    }
-    throw Cr.NS_ERROR_NO_INTERFACE;
-  },
-
-  /**
-   * Forward notifications for interfaces this object implements, in case other
-   * objects also implemented them.
-   */
-  _forwardNotification(iid, method, args) {
-    if (!this._wrappedNotificationCallbacks) {
-      return;
-    }
-    try {
-      let impl = this._wrappedNotificationCallbacks.getInterface(iid);
-      impl[method].apply(impl, args);
-    } catch(e if e.result == Cr.NS_ERROR_NO_INTERFACE) {}
-  },
+                           Ci.nsIRequestObserver, Ci.nsISupports]),
 
   /**
    * This NetworkResponseListener tracks the NetworkMonitor.openResponses object
    * to find the associated uncached headers.
    * @private
    */
   _foundOpenResponse: false,
 
   /**
-   * If the channel already had notificationCallbacks, hold them here internally
-   * so that we can forward getInterface requests to that object.
-   */
-  _wrappedNotificationCallbacks: null,
-
-  /**
    * The response listener owner.
    */
   owner: null,
 
   /**
    * The response will be written into the outputStream of this nsIPipe.
    * Both ends of the pipe must be blocking.
    */
@@ -129,26 +89,21 @@ NetworkResponseListener.prototype = {
   httpActivity: null,
 
   /**
    * Stores the received data as a string.
    */
   receivedData: null,
 
   /**
-   * The uncompressed, decoded response body size.
+   * The network response body size.
    */
   bodySize: null,
 
   /**
-   * Response body size on the wire, potentially compressed / encoded.
-   */
-  transferredSize: null,
-
-  /**
    * The nsIRequest we are started for.
    */
   request: null,
 
   /**
    * Set the async listener for the given nsIAsyncInputStream. This allows us to
    * wait asynchronously for any data coming from the stream.
    *
@@ -217,33 +172,16 @@ NetworkResponseListener.prototype = {
    * https://developer.mozilla.org/En/NsIRequestObserver
    */
   onStopRequest: function NRL_onStopRequest()
   {
     this._findOpenResponse();
     this.sink.outputStream.close();
   },
 
-  // nsIProgressEventSink implementation
-
-  /**
-   * Handle progress event as data is transferred.  This is used to record the
-   * size on the wire, which may be compressed / encoded.
-   */
-  onProgress: function(request, context, progress, progressMax) {
-    this.transferredSize = progress;
-    // Need to forward as well to keep things like Download Manager's progress
-    // bar working properly.
-    this._forwardNotification(Ci.nsIProgressEventSink, 'onProgress', arguments);
-  },
-
-  onStatus: function () {
-    this._forwardNotification(Ci.nsIProgressEventSink, 'onStatus', arguments);
-  },
-
   /**
    * Find the open response object associated to the current request. The
    * NetworkMonitor._httpResponseExaminer() method saves the response headers in
    * NetworkMonitor.openResponses. This method takes the data from the open
    * response object and puts it into the HTTP activity object, then sends it to
    * the remote Web Console instance.
    *
    * @private
@@ -316,17 +254,16 @@ NetworkResponseListener.prototype = {
   _onComplete: function NRL__onComplete(aData)
   {
     let response = {
       mimeType: "",
       text: aData || "",
     };
 
     response.size = response.text.length;
-    response.transferredSize = this.transferredSize;
 
     try {
       response.mimeType = this.request.contentType;
     }
     catch (ex) { }
 
     if (!response.mimeType || !NetworkHelper.isTextMimeType(response.mimeType)) {
       response.encoding = "base64";
@@ -337,17 +274,16 @@ NetworkResponseListener.prototype = {
       response.mimeType += "; charset=" + this.request.contentCharset;
     }
 
     this.receivedData = "";
 
     this.httpActivity.owner.
       addResponseContent(response, this.httpActivity.discardResponseBody);
 
-    this._wrappedNotificationCallbacks = null;
     this.httpActivity.channel = null;
     this.httpActivity.owner = null;
     this.httpActivity = null;
     this.sink = null;
     this.inputStream = null;
     this.request = null;
     this.owner = null;
   },
--- a/toolkit/themes/osx/global/media/videocontrols.css
+++ b/toolkit/themes/osx/global/media/videocontrols.css
@@ -87,17 +87,17 @@
   background-image: url(chrome://global/skin/media/volume-empty.png);
 }
 
 .volumeForeground {
   background-image: url(chrome://global/skin/media/volume-full.png);
   background-clip: content-box;
 }
 
-.controlBar[audio-only] > .volumeStack {
+.controlBar[fullscreen-unavailable] > .volumeStack {
   /* This value is duplicated in the videocontrols.xml adjustControlSize function. */
   -moz-margin-end: 8px;
 }
 
 .volumeControl .scale-thumb {
   min-width: 0;
   opacity: 0;
 }
--- a/toolkit/themes/windows/global/media/videocontrols.css
+++ b/toolkit/themes/windows/global/media/videocontrols.css
@@ -87,17 +87,17 @@
   background-image: url(chrome://global/skin/media/volume-empty.png);
 }
 
 .volumeForeground {
   background-image: url(chrome://global/skin/media/volume-full.png);
   background-clip: content-box;
 }
 
-.controlBar[audio-only] > .volumeStack {
+.controlBar[fullscreen-unavailable] > .volumeStack {
   /* This value is duplicated in the videocontrols.xml adjustControlSize function. */
   -moz-margin-end: 8px;
 }
 
 .volumeControl .scale-thumb {
   min-width: 0;
   opacity: 0;
 }