Merge m-c to m-i
authorPhil Ringnalda <philringnalda@gmail.com>
Sat, 08 Mar 2014 17:50:53 -0800
changeset 190887 e9e0d0ae787b7480bef0c003a9de6b6aa1a2bbaf
parent 190886 c7d86e2ddfea761bb11d1808cfec784a33e3565c (current diff)
parent 190874 21f293fc8d34737fe2816c286364e779fd8674fb (diff)
child 190888 e2ca2e77c0ef19cd723a1f1d18964ac059479681
push id474
push userasasaki@mozilla.com
push dateMon, 02 Jun 2014 21:01:02 +0000
treeherdermozilla-release@967f4cf1b31c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone30.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to m-i
--- a/addon-sdk/source/lib/sdk/lang/functional.js
+++ b/addon-sdk/source/lib/sdk/lang/functional.js
@@ -8,17 +8,17 @@
 
 "use strict";
 
 module.metadata = {
   "stability": "unstable"
 };
 
 const { deprecateFunction } = require("../util/deprecate");
-const { setImmediate, setTimeout } = require("../timers");
+const { setImmediate, setTimeout, clearTimeout } = require("../timers");
 
 const arity = f => f.arity || f.length;
 
 const name = f => f.displayName || f.name;
 
 const derive = (f, source) => {
   f.displayName = name(source);
   f.arity = arity(source);
@@ -356,8 +356,45 @@ const debounce = function debounce (fn, 
     if (!timeout) {
       timeout = setTimeout(later, wait);
     }
 
     return result;
   };
 };
 exports.debounce = debounce;
+
+/**
+ * From underscore's `_.throttle`
+ * http://underscorejs.org
+ * (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Underscore may be freely distributed under the MIT license.
+ */
+const throttle = function throttle (func, wait, options) {
+  let context, args, result;
+  let timeout = null;
+  let previous = 0;
+  options || (options = {});
+  let later = function() {
+    previous = options.leading === false ? 0 : Date.now();
+    timeout = null;
+    result = func.apply(context, args);
+    context = args = null;
+  };
+  return function() {
+    let now = Date.now();
+    if (!previous && options.leading === false) previous = now;
+    let remaining = wait - (now - previous);
+    context = this;
+    args = arguments;
+    if (remaining <= 0) {
+      clearTimeout(timeout);
+      timeout = null;
+      previous = now;
+      result = func.apply(context, args);
+      context = args = null;
+    } else if (!timeout && options.trailing !== false) {
+      timeout = setTimeout(later, remaining);
+    }
+    return result;
+  };
+};
+exports.throttle = throttle;
--- a/addon-sdk/source/python-lib/cuddlefish/__init__.py
+++ b/addon-sdk/source/python-lib/cuddlefish/__init__.py
@@ -91,18 +91,18 @@ parser_groups = (
                                 default=1,
                                 cmds=['test', 'testex', 'testpkgs',
                                       'testall'])),
         (("-f", "--filter",), dict(dest="filter",
                                    help=("only run tests whose filenames "
                                          "match FILENAME and optionally "
                                          "match TESTNAME, both regexps"),
                                    metavar="FILENAME[:TESTNAME]",
-                                   default=None,
-                                   cmds=['test', 'testex', 'testpkgs',
+                                   default='',
+                                   cmds=['test', 'testex', 'testaddons', 'testpkgs',
                                          'testall'])),
         (("-g", "--use-config",), dict(dest="config",
                                        help="use named config from local.json",
                                        metavar=None,
                                        default="default",
                                        cmds=['test', 'run', 'xpi', 'testex',
                                              'testpkgs', 'testall'])),
         (("", "--templatedir",), dict(dest="templatedir",
@@ -416,16 +416,19 @@ def test_cfx(env_root, verbose):
 
 def test_all_testaddons(env_root, defaults):
     addons_dir = os.path.join(env_root, "test", "addons")
     addons = [dirname for dirname in os.listdir(addons_dir)
                 if os.path.isdir(os.path.join(addons_dir, dirname))]
     addons.sort()
     fail = False
     for dirname in addons:
+        if (not defaults['filter'].split(":")[0] in dirname):
+            continue
+
         print >>sys.stderr, "Testing %s..." % dirname
         sys.stderr.flush()
         try:
             run(arguments=["run",
                            "--pkgdir",
                            os.path.join(addons_dir, dirname)],
                 defaults=defaults,
                 env_root=env_root)
@@ -440,16 +443,19 @@ def test_all_testaddons(env_root, defaul
 
 def test_all_examples(env_root, defaults):
     examples_dir = os.path.join(env_root, "examples")
     examples = [dirname for dirname in os.listdir(examples_dir)
                 if os.path.isdir(os.path.join(examples_dir, dirname))]
     examples.sort()
     fail = False
     for dirname in examples:
+        if (not defaults['filter'].split(":")[0] in dirname):
+            continue
+
         print >>sys.stderr, "Testing %s..." % dirname
         sys.stderr.flush()
         try:
             run(arguments=["test",
                            "--pkgdir",
                            os.path.join(examples_dir, dirname)],
                 defaults=defaults,
                 env_root=env_root)
@@ -814,22 +820,22 @@ def run(arguments=sys.argv[1:], target_c
 
     if target_cfg.get('preferences'):
         harness_options['preferences'] = target_cfg.get('preferences')
 
     # Do not add entries for SDK modules
     harness_options['manifest'] = manifest.get_harness_options_manifest(False)
 
     # Gives an hint to tell if sdk modules are bundled or not
-    harness_options['is-sdk-bundled'] = options.bundle_sdk
+    harness_options['is-sdk-bundled'] = options.bundle_sdk or options.no_strip_xpi
 
     if options.force_use_bundled_sdk:
-        if not options.bundle_sdk:
-            print >>sys.stderr, ("--force-use-bundled-sdk and --strip-sdk "
-                                 "can't be used at the same time.")
+        if not harness_options['is-sdk-bundled']:
+            print >>sys.stderr, ("--force-use-bundled-sdk "
+                                 "can't be used if sdk isn't bundled.")
             sys.exit(1)
         if options.overload_modules:
             print >>sys.stderr, ("--force-use-bundled-sdk and --overload-modules "
                                  "can't be used at the same time.")
             sys.exit(1)
         # Pass a flag in order to force using sdk modules shipped in the xpi
         harness_options['force-use-bundled-sdk'] = True
 
--- a/addon-sdk/source/python-lib/cuddlefish/runner.py
+++ b/addon-sdk/source/python-lib/cuddlefish/runner.py
@@ -188,21 +188,26 @@ class RemoteFennecRunner(mozrunner.Runne
         print "Launching mobile application with intent name " + self._intent_name
 
         # First try to kill firefox if it is already running
         pid = self.getProcessPID(self._intent_name)
         if pid != None:
             print "Killing running Firefox instance ..."
             subprocess.call([self._adb_path, "shell",
                              "am force-stop " + self._intent_name])
-            time.sleep(2)
-            if self.getProcessPID(self._intent_name) != None:
-                raise Exception("Unable to automatically kill running Firefox" +
-                                " instance. Please close it manually before " +
-                                "executing cfx.")
+            time.sleep(7)
+            # It appears recently that the PID still exists even after
+            # Fennec closes, so removing this error still allows the tests
+            # to pass as the new Fennec instance is able to start.
+            # Leaving error in but commented out for now.
+            #
+            #if self.getProcessPID(self._intent_name) != None:
+            #    raise Exception("Unable to automatically kill running Firefox" +
+            #                    " instance. Please close it manually before " +
+            #                    "executing cfx.")
 
         print "Pushing the addon to your device"
 
         # Create a clean empty profile on the sd card
         subprocess.call([self._adb_path, "shell", "rm -r " + FENNEC_REMOTE_PATH])
         subprocess.call([self._adb_path, "shell", "mkdir " + FENNEC_REMOTE_PATH])
 
         # Push the profile folder created by mozrunner to the device
--- a/addon-sdk/source/test/addons/places/tests/test-places-events.js
+++ b/addon-sdk/source/test/addons/places/tests/test-places-events.js
@@ -11,16 +11,18 @@ module.metadata = {
 
 const { Cc, Ci } = require('chrome');
 const { defer, all } = require('sdk/core/promise');
 const { filter } = require('sdk/event/utils');
 const { on, off } = require('sdk/event/core');
 const { events } = require('sdk/places/events');
 const { setTimeout } = require('sdk/timers');
 const { before, after } = require('sdk/test/utils');
+const bmsrv = Cc['@mozilla.org/browser/nav-bookmarks-service;1'].
+                getService(Ci.nsINavBookmarksService);
 const {
   search
 } = require('sdk/places/history');
 const {
   invalidResolve, invalidReject, createTree, createBookmark,
   compareWithHost, addVisits, resetPlaces, createBookmarkItem,
   removeVisits
 } = require('../places-helper');
@@ -47,16 +49,21 @@ exports['test bookmark-item-added'] = fu
 };
 
 exports['test bookmark-item-changed'] = function (assert, done) {
   let id;
   let complete = makeCompleted(done);
   function handler ({type, data}) {
     if (type !== 'bookmark-item-changed') return;
     if (data.id !== id) return;
+    // Abort if the 'bookmark-item-changed' event isn't for the `title` property,
+    // as sometimes the event can be for the `url` property.
+    // Intermittent failure, bug 969616
+    if (data.property !== 'title') return;
+
     assert.equal(type, 'bookmark-item-changed',
       'correct type in bookmark-item-changed event');
     assert.equal(data.type, 'bookmark',
       'correct data in bookmark-item-changed event');
     assert.equal(data.property, 'title',
       'correct property in bookmark-item-changed event');
     assert.equal(data.value, 'bookmark-changed-title-2',
       'correct value in bookmark-item-changed event');
@@ -73,41 +80,45 @@ exports['test bookmark-item-changed'] = 
     item.title = 'bookmark-changed-title-2';
     return saveP(item);
   }).then(complete);
 };
 
 exports['test bookmark-item-moved'] = function (assert, done) {
   let id;
   let complete = makeCompleted(done);
+  let previousIndex, previousParentId;
+
   function handler ({type, data}) {
     if (type !== 'bookmark-item-moved') return;
     if (data.id !== id) return;
     assert.equal(type, 'bookmark-item-moved',
       'correct type in bookmark-item-moved event');
     assert.equal(data.type, 'bookmark',
       'correct data in bookmark-item-moved event');
     assert.ok(data.id === id, 'correct id in bookmark-item-moved event');
-    assert.equal(data.previousParentId, UNSORTED.id,
+    assert.equal(data.previousParentId, previousParentId,
       'correct previousParentId');
-    assert.equal(data.currentParentId, MENU.id,
+    assert.equal(data.currentParentId, bmsrv.getFolderIdForItem(id),
       'correct currentParentId');
-    assert.equal(data.previousIndex, 0, 'correct previousIndex');
-    assert.equal(data.currentIndex, 0, 'correct currentIndex');
+    assert.equal(data.previousIndex, previousIndex, 'correct previousIndex');
+    assert.equal(data.currentIndex, bmsrv.getItemIndex(id), 'correct currentIndex');
 
     events.off('data', handler);
     complete();
   }
   events.on('data', handler);
 
   createBookmarkItem({
     title: 'bookmark-moved-title',
     group: UNSORTED
   }).then(item => {
     id = item.id;
+    previousIndex = bmsrv.getItemIndex(id);
+    previousParentId = bmsrv.getFolderIdForItem(id);
     item.group = MENU;
     return saveP(item);
   }).then(complete);
 };
 
 exports['test bookmark-item-removed'] = function (assert, done) {
   let id;
   let complete = makeCompleted(done);
--- a/addon-sdk/source/test/test-content-worker.js
+++ b/addon-sdk/source/test/test-content-worker.js
@@ -869,16 +869,57 @@ exports["test:worker events"] = WorkerTe
       }
     });
     // `attach` event is called synchronously during instantiation,
     // so we can't listen to that, TODO FIX?
     //  worker.on('attach', obj => console.log('attach', obj));
   }
 );
 
+exports["test:onDetach in contentScript on destroy"] = WorkerTest(
+  "data:text/html;charset=utf-8,foo#detach",
+  function(assert, browser, done) {
+    let worker = Worker({
+      window: browser.contentWindow,
+      contentScript: 'new ' + function WorkerScope() {
+        self.port.on('detach', function(reason) {
+          window.location.hash += '!' + reason;
+        })
+      },
+    });
+    browser.contentWindow.addEventListener('hashchange', _ => { 
+      assert.equal(browser.contentWindow.location.hash, '#detach!', 
+                   "location.href is as expected");
+      done();
+    })
+    worker.destroy();
+  }
+);
+
+exports["test:onDetach in contentScript on unload"] = WorkerTest(
+  "data:text/html;charset=utf-8,foo#detach",
+  function(assert, browser, done) {
+    let { loader } = LoaderWithHookedConsole(module);
+    let worker = loader.require("sdk/content/worker").Worker({
+      window: browser.contentWindow,
+      contentScript: 'new ' + function WorkerScope() {
+        self.port.on('detach', function(reason) {
+          window.location.hash += '!' + reason;
+        })
+      },
+    });
+    browser.contentWindow.addEventListener('hashchange', _ => { 
+      assert.equal(browser.contentWindow.location.hash, '#detach!shutdown', 
+                   "location.href is as expected");
+      done();
+    })
+    loader.unload('shutdown');
+  }
+);
+
 exports["test:console method log functions properly"] = WorkerTest(
   DEFAULT_CONTENT_URL,
   function(assert, browser, done) {
     let logs = [];
 
     let clean = message =>
           message.trim().
           replace(/[\r\n]/g, " ").
--- a/addon-sdk/source/test/test-functional.js
+++ b/addon-sdk/source/test/test-functional.js
@@ -1,17 +1,18 @@
 /* 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 { setTimeout } = require('sdk/timers');
 const utils = require('sdk/lang/functional');
 const { invoke, defer, partial, compose, memoize, once, is, isnt,
-        delay, wrap, curry, chainable, field, query, isInstance, debounce } = utils;
+  delay, wrap, curry, chainable, field, query, isInstance, debounce, throttle
+} = utils;
 const { LoaderWithHookedConsole } = require('sdk/test/loader');
 
 exports['test forwardApply'] = function(assert) {
   function sum(b, c) { return this.a + b + c; }
   assert.equal(invoke(sum, [2, 3], { a: 1 }), 6,
                'passed arguments and pseoude-variable are used');
 
   assert.equal(invoke(sum.bind({ a: 2 }), [2, 3], { a: 1 }), 7,
@@ -430,9 +431,32 @@ exports["test debounce"] = (assert, done
     assert.equal(counter, 1, "function called after wait time");
     fn();
     setTimeout(() => {
       assert.equal(counter, 2, "function able to be called again after wait");
       done();
     }, 150);
   }, 200);
 };
+
+exports["test throttle"] = (assert, done) => {
+  let called = 0;
+  let attempt = 0;
+  let throttledFn = throttle(() => called++, 100);
+  let fn = () => ++attempt && throttledFn();
+
+  new Array(11).join(0).split("").forEach((_, i) => {
+    setTimeout(fn, 20 * (i+1));
+  });
+
+  setTimeout(() => {
+    assert.equal(called, 1, "function called atleast once during first throttle period");
+    assert.ok(attempt >= 2, "function attempted to be called several times during first period");
+  }, 50);
+
+  setTimeout(() => {
+    assert.equal(called, 3, "function called again during second throttle period");
+    assert.equal(attempt, 10, "function attempted to be called several times during second period");
+    done();
+  }, 300);
+};
+
 require('test').run(exports);
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1393524054000">
+<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1394054454000">
   <emItems>
       <emItem  blockID="i454" id="sqlmoz@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                                 <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
               </prefs>
@@ -84,16 +84,22 @@
               </prefs>
     </emItem>
       <emItem  blockID="i105" id="{95ff02bc-ffc6-45f0-a5c8-619b8226a9de}">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
+      <emItem  blockID="i20" id="{AB2CE124-6272-4b12-94A9-7303C7397BD1}">
+                        <versionRange  minVersion="0.1" maxVersion="5.2.0.7164" severity="1">
+                    </versionRange>
+                    <prefs>
+              </prefs>
+    </emItem>
       <emItem  blockID="i506" id="/^ext@bettersurfplus/">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i400" id="{dd6b651f-dfb9-4142-b0bd-09912ad22674}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
@@ -171,18 +177,18 @@
               </prefs>
     </emItem>
       <emItem  blockID="i40" id="{28387537-e3f9-4ed7-860c-11e69af4a8a0}">
                         <versionRange  minVersion="0.1" maxVersion="4.3.1.00" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
-      <emItem  blockID="i20" id="{AB2CE124-6272-4b12-94A9-7303C7397BD1}">
-                        <versionRange  minVersion="0.1" maxVersion="5.2.0.7164" severity="1">
+      <emItem  blockID="i566" id="{77BEC163-D389-42c1-91A4-C758846296A5}">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i498" id="hoverst@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
@@ -1369,17 +1375,17 @@
               </prefs>
     </emItem>
       <emItem  blockID="i544" id="/^(93abedcf-8e3a-4d02-b761-d1441e437c09@243f129d-aee2-42c2-bcd1-48858e1c22fd\.com|9acfc440-ac2d-417a-a64c-f6f14653b712@09f9a966-9258-4b12-af32-da29bdcc28c5\.com|58ad0086-1cfb-48bb-8ad2-33a8905572bc@5715d2be-69b9-4930-8f7e-64bdeb961cfd\.com)$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
-      <emItem  blockID="i224" id="{336D0C35-8A85-403a-B9D2-65C292C39087}">
+      <emItem  blockID="i564" id="/^(firefox@vebergreat\.net|EFGLQA@78ETGYN-0W7FN789T87\.COM|{52b0f3db-f988-4788-b9dc-861d016f4487})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i61" id="youtube@youtube3.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
@@ -1530,16 +1536,22 @@
               </prefs>
     </emItem>
       <emItem  blockID="i282" id="{33e0daa6-3af3-d8b5-6752-10e949c61516}">
                         <versionRange  minVersion="0" maxVersion="1.1.999" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
+      <emItem  blockID="i224" id="{336D0C35-8A85-403a-B9D2-65C292C39087}">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
+                    </versionRange>
+                    <prefs>
+              </prefs>
+    </emItem>
       <emItem  blockID="i452" id="{77beece6-3997-403a-92fa-0055bfcf88e5}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i45" id="{22119944-ED35-4ab1-910B-E619EA06A115}">
                         <versionRange  minVersion="0.1" maxVersion="7.6.1">
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -283,17 +283,17 @@ toolbarpaletteitem > #personal-bookmarks
   direction: rtl;
 }
 
 #panelMenu_bookmarksMenu > .bookmark-item {
   max-width: none;
 }
 
 #urlbar-container {
-  min-width: 28ch;
+  min-width: 50ch;
 }
 
 #search-container {
   min-width: 25ch;
 }
 
 #urlbar,
 .searchbar-textbox {
@@ -385,30 +385,47 @@ panel[noactions] > richlistbox > richlis
 #urlbar[pageproxystate="invalid"] > #identity-box {
   pointer-events: none;
 }
 
 #identity-icon-labels {
   max-width: 18em;
 }
 @media (max-width: 700px) {
+  #urlbar-container {
+    min-width: 45ch;
+  }
   #identity-icon-labels {
     max-width: 70px;
   }
 }
 @media (max-width: 600px) {
+  #urlbar-container {
+    min-width: 40ch;
+  }
   #identity-icon-labels {
     max-width: 60px;
   }
 }
 @media (max-width: 500px) {
+  #urlbar-container {
+    min-width: 35ch;
+  }
   #identity-icon-labels {
     max-width: 50px;
   }
 }
+@media (max-width: 400px) {
+  #urlbar-container {
+    min-width: 28ch;
+  }
+  #identity-icon-labels {
+    max-width: 40px;
+  }
+}
 
 #identity-icon-country-label {
   direction: ltr;
 }
 
 #identity-box.verifiedIdentity > #identity-icon-labels > #identity-icon-label {
   -moz-margin-end: 0.25em !important;
 }
--- a/browser/components/customizableui/content/panelUI.inc.xul
+++ b/browser/components/customizableui/content/panelUI.inc.xul
@@ -200,28 +200,16 @@
               label="&customizeMenu.addToPanel.label;"/>
   </menupopup>
 
   <menupopup id="customizationPanelContextMenu">
     <menuitem command="cmd_CustomizeToolbars"
               accesskey="&customizeMenu.addMoreItems.accesskey;"
               label="&customizeMenu.addMoreItems.label;"/>
   </menupopup>
-  <svg:svg height="0">
-    <svg:defs>
-      <svg:linearGradient gradientUnits="objectBoundingBox" id="menuPanelButtonTextFadeOut" x2="0" y2="1">
-        <svg:stop stop-color="white" offset=".66"/>
-        <svg:stop stop-color="rgb(128,128,128)" offset=".72"/>
-        <svg:stop stop-color="black" offset=".9"/>
-      </svg:linearGradient>
-      <svg:mask id="menuPanelButtonTextFadeOutMask" maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox" x="0" y="0" width="100%" height="100%">
-        <svg:rect width="1" height="1" fill="url(#menuPanelButtonTextFadeOut)"/>
-      </svg:mask>
-    </svg:defs>
-  </svg:svg>
 </panel>
 
 <panel id="widget-overflow"
        role="group"
        type="arrow"
        noautofocus="true"
        context="toolbar-context-menu"
        position="bottomcenter topright"
--- a/browser/components/customizableui/content/panelUI.xml
+++ b/browser/components/customizableui/content/panelUI.xml
@@ -268,28 +268,23 @@
           }
           switch (aEvent.type) {
             case "click":
               if (aEvent.originalTarget == this._clickCapturer) {
                 this.showMainView();
               }
               break;
             case "overflow":
-              switch (aEvent.target.localName) {
-                case "vbox":
-                  // Resize the right view on the next tick.
-                  if (this.showingSubView) {
-                    setTimeout(this._syncContainerWithSubView.bind(this), 0);
-                  } else if (!this.transitioning) {
-                    setTimeout(this._syncContainerWithMainView.bind(this), 0);
-                  }
-                  break;
-                case "toolbarbutton":
-                  aEvent.target.setAttribute("fadelabel", "true");
-                  break;
+              if (aEvent.target.localName == "vbox") {
+                // Resize the right view on the next tick.
+                if (this.showingSubView) {
+                  setTimeout(this._syncContainerWithSubView.bind(this), 0);
+                } else if (!this.transitioning) {
+                  setTimeout(this._syncContainerWithMainView.bind(this), 0);
+                }
               }
               break;
             case "popupshowing":
               this.setAttribute("panelopen", "true");
               // Bug 941196 - The panel can get taller when opening a subview. Disabling
               // autoPositioning means that the panel won't jump around if an opened
               // subview causes the panel to exceed the dimensions of the screen in the
               // direction that the panel originally opened in. This property resets
--- a/browser/themes/shared/customizableui/panelUIOverlay.inc.css
+++ b/browser/themes/shared/customizableui/panelUIOverlay.inc.css
@@ -116,21 +116,24 @@
 #PanelUI-popup > .panel-arrowcontainer > .panel-arrowcontent,
 .cui-widget-panel > .panel-arrowcontainer > .panel-arrowcontent > .popup-internal-box {
   padding: 0;
 }
 
 .panelUI-grid .toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-multiline-text,
 .panelUI-grid .toolbarbutton-1 > .toolbarbutton-multiline-text {
   -moz-hyphens: auto;
+  line-height: 1.1;
+  max-height: 2.2em;
 }
 
-.panelUI-grid:not([customize-transitioning]) .toolbarbutton-1[fadelabel] > .toolbarbutton-menubutton-button > .toolbarbutton-multiline-text,
-.panelUI-grid:not([customize-transitioning]) .toolbarbutton-1[fadelabel] > .toolbarbutton-multiline-text {
-  mask: url(chrome://browser/content/browser.xul#menuPanelButtonTextFadeOutMask);
+.panelUI-grid:not([customize-transitioning]) .toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-multiline-text,
+.panelUI-grid:not([customize-transitioning]) .toolbarbutton-1 > .toolbarbutton-multiline-text {
+  position: absolute;
+  clip: rect(auto, auto, 2.2em, auto);
 }
 
 .panelUI-grid .toolbarbutton-1 > .toolbarbutton-text,
 .panelUI-grid .toolbarbutton-1 > .toolbarbutton-multiline-text {
   text-align: center;
   margin: 2px 0 0;
 }
 
@@ -189,17 +192,17 @@ panelview:not([mainview]) .toolbarbutton
 }
 
 toolbaritem[cui-areatype="menu-panel"][sdkstylewidget="true"]:not(.panel-wide-item),
 .panelUI-grid .toolbarbutton-1,
 .panel-customization-placeholder-child {
   -moz-appearance: none;
   -moz-box-orient: vertical;
   width: calc(@menuPanelButtonWidth@);
-  height: calc(40px + 4em);
+  height: calc(51px + 2.2em);
 }
 
 /* Help SDK buttons fit in. */
 toolbarpaletteitem[place="palette"] > toolbarbutton[sdk-button="true"] > .toolbarbutton-icon,
 toolbarbutton[sdk-button="true"][cui-areatype="menu-panel"] > .toolbarbutton-icon {
   height: 32px;
   width: 32px;
 }
@@ -208,29 +211,21 @@ toolbarbutton[sdk-button="true"][cui-are
   -moz-appearance: none;
   -moz-box-orient: vertical;
 }
 
 .panelUI-grid .toolbarbutton-1 > .toolbarbutton-menubutton-button {
   -moz-appearance: none;
   -moz-box-orient: vertical;
   width: calc(@menuPanelButtonWidth@ - 2px);
-  height: calc(38px + 4em);
+  height: calc(49px + 2.2em);
   margin-top: 3px; /* Hack needed to get type=menu-button to properly align vertically. */
   border: 0;
 }
 
-toolbaritem[cui-areatype="menu-panel"][sdkstylewidget="true"]:not(.panel-wide-item),
-.panelUI-grid .toolbarbutton-1:not([type="menu-button"]),
-.panelUI-grid .toolbarbutton-1 > .toolbarbutton-menubutton-button,
-.customization-palette .toolbarbutton-1,
-.panel-customization-placeholder-child {
-  overflow: hidden;
-}
-
 .panel-customization-placeholder-child {
   margin: 6px 0 0;
   padding: 2px 6px;
   border: 1px solid transparent;
 }
 
 .panelUI-grid .toolbarbutton-1[type="menu"] {
   background-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow.png");
@@ -245,18 +240,18 @@ toolbaritem[cui-areatype="menu-panel"][s
 .panelUI-grid .toolbarbutton-1 > .toolbarbutton-menu-dropmarker {
   display: none;
 }
 
 .panelUI-grid .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
   -moz-box-align: center;
   width: 16px;
   -moz-margin-start: -16px;
-  height: 40px;
-  margin-bottom: 4em;
+  height: 51px;
+  margin-bottom: 2.2em;
   padding: 0;
 }
 
 .panelUI-grid .toolbarbutton-1:not([buttonover])@buttonStateHover@ > .toolbarbutton-menubutton-dropmarker {
   background-color: hsla(210,4%,10%,.1) !important;
   border-radius: 0 0 0 2px;
 }
 
--- a/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -828,13 +828,15 @@ pref("browser.webapps.updateInterval", 8
 // The URL of the service that checks for updates.
 // This currently points to the development server.
 // To test updates, set this to http://apk-update-checker.paas.allizom.org,
 // which is a test server that always reports all apps as having updates.
 pref("browser.webapps.updateCheckUrl", "http://dapk.net/app_updates");
 
 #endif
 
-// Whether or not to only sync home provider data when the user is on wifi.
-pref("home.sync.wifiOnly", false);
+// The mode of home provider syncing.
+// 0: Sync always
+// 1: Sync only when on wifi
+pref("home.sync.updateMode", 0);
 
 // How frequently to check if we should sync home provider data.
 pref("home.sync.checkIntervalSecs", 3600);
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -88,16 +88,20 @@
 <!ENTITY pref_developer_remotedebugging_docs "Learn more">
 <!ENTITY pref_remember_signons "Remember passwords">
 
 <!ENTITY pref_category_home "Home">
 <!ENTITY pref_category_home_panels "Panels">
 <!ENTITY pref_home_add_panel "Add panel">
 <!ENTITY home_add_panel_title "Add new panel">
 <!ENTITY home_add_panel_empty "Sorry, we couldn\'t find any panels for you to add.">
+<!ENTITY pref_category_home_content_settings "Content settings">
+<!ENTITY pref_home_updates "Automatic updates">
+<!ENTITY pref_home_updates_enabled "Enabled">
+<!ENTITY pref_home_updates_wifi "Only over Wi-Fi">
 
 <!-- Localization note: These are shown in the left sidebar on tablets -->
 <!ENTITY pref_header_customize "Customize">
 <!ENTITY pref_header_display "Display">
 <!ENTITY pref_header_privacy_short "Privacy">
 <!ENTITY pref_header_help "Help">
 <!ENTITY pref_header_vendor "&vendorShortName;">
 <!ENTITY pref_header_devtools "Developer tools">
--- a/mobile/android/base/resources/values/arrays.xml
+++ b/mobile/android/base/resources/values/arrays.xml
@@ -1,15 +1,23 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 
 <resources>
+    <string-array name="pref_home_updates_entries">
+        <item>@string/pref_home_updates_enabled</item>
+        <item>@string/pref_home_updates_wifi</item>
+    </string-array>
+    <string-array name="pref_home_updates_values">
+        <item>0</item>
+        <item>1</item>
+    </string-array>
     <string-array name="pref_plugins_entries">
         <item>@string/pref_plugins_enabled</item>
         <item>@string/pref_plugins_tap_to_play</item>
         <item>@string/pref_plugins_disabled</item>
     </string-array>
     <string-array name="pref_plugins_values">
         <item>1</item>
         <item>2</item>
--- a/mobile/android/base/resources/xml/preferences_home.xml
+++ b/mobile/android/base/resources/xml/preferences_home.xml
@@ -12,9 +12,19 @@
         android:title="@string/pref_category_home_panels">
 
         <Preference android:key="android.not_a_preference.home.add_panel"
                     android:title="@string/pref_home_add_panel"
                     android:icon="@drawable/icon_new_home_panel" />
 
     </org.mozilla.gecko.preferences.PanelsPreferenceCategory>
 
+    <PreferenceCategory android:title="@string/pref_category_home_content_settings">
+
+        <ListPreference android:key="home.sync.updateMode"
+                        android:title="@string/pref_home_updates"
+                        android:entries="@array/pref_home_updates_entries"
+                        android:entryValues="@array/pref_home_updates_values"
+                        android:persistent="false" />
+
+    </PreferenceCategory>
+
 </PreferenceScreen>
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -111,16 +111,20 @@
   <string name="pref_developer_remotedebugging">&pref_developer_remotedebugging;</string>
   <string name="pref_developer_remotedebugging_docs">&pref_developer_remotedebugging_docs;</string>
 
   <string name="pref_category_home">&pref_category_home;</string>
   <string name="pref_category_home_panels">&pref_category_home_panels;</string>
   <string name="pref_home_add_panel">&pref_home_add_panel;</string>
   <string name="home_add_panel_title">&home_add_panel_title;</string>
   <string name="home_add_panel_empty">&home_add_panel_empty;</string>
+  <string name="pref_category_home_content_settings">&pref_category_home_content_settings;</string>
+  <string name="pref_home_updates">&pref_home_updates;</string>
+  <string name="pref_home_updates_enabled">&pref_home_updates_enabled;</string>
+  <string name="pref_home_updates_wifi">&pref_home_updates_wifi;</string>
 
   <string name="pref_header_customize">&pref_header_customize;</string>
   <string name="pref_header_display">&pref_header_display;</string>
   <string name="pref_header_privacy_short">&pref_header_privacy_short;</string>
   <string name="pref_header_vendor">&pref_header_vendor;</string>
   <string name="pref_header_devtools">&pref_header_devtools;</string>
 
   <string name="pref_remember_signons">&pref_remember_signons;</string>
--- a/mobile/android/base/tests/testSettingsMenuItems.java
+++ b/mobile/android/base/tests/testSettingsMenuItems.java
@@ -21,84 +21,98 @@ public class testSettingsMenuItems exten
      * The following String[][] (arrays) match the menu hierarchy for each section.
      * Each String[] (array) represents the menu items/choices in the following order:
      *
      * itemTitle { defaultValue [options] }
      *
      * where defaultValue is optional, and there can be multiple options.
      *
      * These menu items are the ones that are always present - to test menu items that differ
-     * based on build (e.g., release vs. nightly), add the items in <code>addConditionalSettings</code>. 
+     * based on build (e.g., release vs. nightly), add the items in <code>addConditionalSettings</code>.
      */
 
     // Customize menu items.
+    String[] PATH_CUSTOMIZE = { "Customize" };
     String[][] OPTIONS_CUSTOMIZE = {
-        { "Home", "", "Panels" },
+        { "Home" },
         { "Search", "", "Show search suggestions", "Installed search engines"},
         { "Tabs", "Don't restore after quitting " + BRAND_NAME, "Always restore", "Don't restore after quitting " + BRAND_NAME },
         { "Import from Android", "", "Bookmarks", "History", "Import" },
     };
 
+    // Home panel menu items.
+    String[] PATH_HOME = { "Customize", "Home" };
+    String[][] OPTIONS_HOME = {
+      { "Panels" },
+      { "Automatic updates", "Enabled", "Enabled", "Only over Wi-Fi" },
+    };
+
     // Display menu items.
+    String[] PATH_DISPLAY = { "Display" };
     String[][] OPTIONS_DISPLAY = {
         { "Text size" },
         { "Title bar", "Show page title", "Show page title", "Show page address" },
         { "Advanced" },
         { "Character encoding", "Don't show menu", "Show menu", "Don't show menu" },
         { "Plugins", "Tap to play", "Enabled", "Tap to play", "Disabled" },
     };
 
     // Privacy menu items.
+    String[] PATH_PRIVACY = { "Privacy" };
     String[][] OPTIONS_PRIVACY = {
         { "Tracking", "Do not tell sites anything about my tracking preferences", "Tell sites that I do not want to be tracked", "Tell sites that I want to be tracked", "Do not tell sites anything about my tracking preferences" },
         { "Cookies", "Enabled", "Enabled, excluding 3rd party", "Disabled" },
         { "Remember passwords" },
         { "Use master password" },
         { "Clear private data", "", "Browsing & download history", "Downloaded files", "Form & search history", "Cookies & active logins", "Saved passwords", "Cache", "Offline website data", "Site settings", "Clear data" },
     };
 
+    // Mozilla/vendor menu items.
+    String[] PATH_MOZILLA = { "Mozilla" };
     String[][] OPTIONS_MOZILLA = {
         { "About " + BRAND_NAME },
         { "FAQs" },
         { "Give feedback" },
         { "Show product announcements" },
         { "Data choices" },
         { BRAND_NAME + " Health Report", "Shares data with Mozilla about your browser health and helps you understand your browser performance" },
         { "View my Health Report" },
     };
 
     /*
      * This sets up a hierarchy of settings to test.
      *
-     * The keys are the top-level settings categories, and each value is a
-     * List of menu items contained within each category.
+     * The keys are String arrays representing the path through menu items
+     * (the single-item arrays being top-level categories), and each value
+     * is a List of menu items contained within each category.
      *
      * Each menu item is itself an array as follows:
      *  - item title
      *  - default string value of item (optional)
      *  - string values of options that are displayed once clicked (optional).
      */
-    public void setupSettingsMap(Map<String, List<String[]>> settingsMap) {
-        settingsMap.put("Customize", new ArrayList<String[]>(Arrays.asList(OPTIONS_CUSTOMIZE)));
-        settingsMap.put("Display", new ArrayList<String[]>(Arrays.asList(OPTIONS_DISPLAY)));
-        settingsMap.put("Privacy", new ArrayList<String[]>(Arrays.asList(OPTIONS_PRIVACY)));
-        settingsMap.put("Mozilla", new ArrayList<String[]>(Arrays.asList(OPTIONS_MOZILLA)));
+    public void setupSettingsMap(Map<String[], List<String[]>> settingsMap) {
+        settingsMap.put(PATH_CUSTOMIZE, new ArrayList<String[]>(Arrays.asList(OPTIONS_CUSTOMIZE)));
+        settingsMap.put(PATH_HOME, new ArrayList<String[]>(Arrays.asList(OPTIONS_HOME)));
+        settingsMap.put(PATH_DISPLAY, new ArrayList<String[]>(Arrays.asList(OPTIONS_DISPLAY)));
+        settingsMap.put(PATH_PRIVACY, new ArrayList<String[]>(Arrays.asList(OPTIONS_PRIVACY)));
+        settingsMap.put(PATH_MOZILLA, new ArrayList<String[]>(Arrays.asList(OPTIONS_MOZILLA)));
     }
 
     @Override
     protected int getTestType() {
         return TEST_MOCHITEST;
     }
 
     public void testSettingsMenuItems() {
         blockForGeckoReady();
         mMidWidth = mDriver.getGeckoWidth()/2;
         mMidHeight = mDriver.getGeckoHeight()/2;
 
-        Map<String, List<String[]>> settingsMenuItems = new HashMap<String, List<String[]>>();
+        Map<String[], List<String[]>> settingsMenuItems = new HashMap<String[], List<String[]>>();
         setupSettingsMap(settingsMenuItems);
 
         // Set special handling for Settings items that are conditionally built.
         addConditionalSettings(settingsMenuItems);
 
         selectMenuItem("Settings");
         waitForText("Settings");
 
@@ -132,57 +146,63 @@ public class testSettingsMenuItems exten
         }
         mAsserter.ok(mSolo.waitForText("Sync"), "Waiting for Sync option", "The Sync option is present");
     }
 
     /**
      * Check for conditions for building certain settings, and add them to be tested
      * if they are present.
      */
-    public void addConditionalSettings(Map<String, List<String[]>> settingsMap) {
+    public void addConditionalSettings(Map<String[], List<String[]>> settingsMap) {
         // Preferences dependent on RELEASE_BUILD
         if (!AppConstants.RELEASE_BUILD) {
             // Text reflow - only built if *not* release build
             String[] textReflowUi = { "Text reflow" };
-            settingsMap.get("Display").add(textReflowUi);
+            settingsMap.get(PATH_DISPLAY).add(textReflowUi);
 
             // Anonymous cell tower/wifi collection - only built if *not* release build
             String[] networkReportingUi = { "Mozilla location services", "Help improve geolocation services for the Open Web by letting " + BRAND_NAME + " collect and send anonymous cellular tower data" };
-            settingsMap.get("Mozilla").add(networkReportingUi);
+            settingsMap.get(PATH_MOZILLA).add(networkReportingUi);
 
         }
 
         // Automatic updates
         if (AppConstants.MOZ_UPDATER) {
             String[] autoUpdateUi = { "Download updates automatically", "Only over Wi-Fi", "Always", "Only over Wi-Fi", "Never" };
-            settingsMap.get("Customize").add(autoUpdateUi);
+            settingsMap.get(PATH_CUSTOMIZE).add(autoUpdateUi);
         }
 
         // Crash reporter
         if (AppConstants.MOZ_CRASHREPORTER) {
             String[] crashReporterUi = { "Crash Reporter", BRAND_NAME + " submits crash reports to help Mozilla make your browser more stable and secure" };
-            settingsMap.get("Mozilla").add(crashReporterUi);
+            settingsMap.get(PATH_MOZILLA).add(crashReporterUi);
         }
 
         // Telemetry
         if (AppConstants.MOZ_TELEMETRY_REPORTING) {
             String[] telemetryUi = { "Telemetry", "Shares performance, usage, hardware and customization data about your browser with Mozilla to help us make " + BRAND_NAME + " better" };
-            settingsMap.get("Mozilla").add(telemetryUi);
+            settingsMap.get(PATH_MOZILLA).add(telemetryUi);
         }
     }
 
-    public void checkMenuHierarchy(Map<String, List<String[]>> settingsMap) {
+    public void checkMenuHierarchy(Map<String[], List<String[]>> settingsMap) {
         // Check the items within each category.
-        for (Entry<String, List<String[]>> e : settingsMap.entrySet()) {
-            String section = "^" + e.getKey() + "$";
+        String section = null;
+        for (Entry<String[], List<String[]>> e : settingsMap.entrySet()) {
+            final String[] menuPath = e.getKey();
+
+            for (String menuItem : menuPath) {
+                section = "^" + menuItem + "$";
+
+                waitForEnabledText(section);
+                mSolo.clickOnText(section);
+            }
+
             List<String[]> sectionItems = e.getValue();
 
-            waitForEnabledText(section);
-            mSolo.clickOnText(section);
-
             // Check each item of the section.
             for (String[] item : sectionItems) {
                 int itemLen = item.length;
 
                 // Each item must at least have a title.
                 mAsserter.ok(item.length > 0, "Section-item", "Each item must at least have a title");
 
                 // Check item title.
@@ -204,29 +224,36 @@ public class testSettingsMenuItems exten
                     mSolo.clickOnText(itemTitle);
                     for (int i = 2; i < itemLen; i++) {
                         String itemChoice = "^" + item[i] + "$";
                         foundText = waitExtraForText(itemChoice);
                         mAsserter.ok(foundText, "Waiting for settings item choice " + itemChoice
                                      + " in section " + section,
                                      "The " + itemChoice + " choice is present in section " + section);
                     }
+
                     // Leave submenu after checking.
                     if (waitForText("^Cancel$")) {
                         mSolo.clickOnText("^Cancel$");
                     } else {
                         // Some submenus aren't dialogs, but are nested screens; exit using "back".
                         mActions.sendSpecialKey(Actions.SpecialKey.BACK);
                     }
                 }
             }
-            // Navigate back a screen if on a phone.
+
+            // Navigate back if on a phone. Tablets shouldn't do this because they use headers and fragments.
             if (mDevice.type.equals("phone")) {
-                // Click back to return to previous menu. Tablets shouldn't do this because they use headers and fragments.
-                mActions.sendSpecialKey(Actions.SpecialKey.BACK);
+                int menuDepth = menuPath.length;
+                while (menuDepth > 0) {
+                    mActions.sendSpecialKey(Actions.SpecialKey.BACK);
+                    menuDepth--;
+                    // Sleep so subsequent back actions aren't lost.
+                    mSolo.sleep(50);
+                }
             }
         }
     }
 
     // Solo.waitForText usually scrolls down in a view when text is not visible.
     // In this test, Solo.waitForText scrolling does not work, so we use this
     // hack to do the same thing.
     private boolean waitExtraForText(String txt) {
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -1182,16 +1182,17 @@ var BrowserApp = {
       // Since the Java UI uses the type to determine which ui elements
       // to show and how to handle them, we need to normalize these
       // preferences to the correct type.
       switch (prefName) {
         // (string) index for determining which multiple choice value to display.
         case "browser.chrome.titlebarMode":
         case "network.cookie.cookieBehavior":
         case "font.size.inflation.minTwips":
+        case "home.sync.updateMode":
           pref.type = "string";
           pref.value = pref.value.toString();
           break;
       }
 
       prefs.push(pref);
     }
 
@@ -1253,16 +1254,17 @@ var BrowserApp = {
         return;
 #endif
       // When sending to Java, we normalized special preferences that use
       // integers and strings to represent booleans. Here, we convert them back
       // to their actual types so we can store them.
       case "browser.chrome.titlebarMode":
       case "network.cookie.cookieBehavior":
       case "font.size.inflation.minTwips":
+      case "home.sync.updateMode":
         json.type = "int";
         json.value = parseInt(json.value);
         break;
     }
 
     // Pref name translation.
     switch (json.name) {
 #ifdef MOZ_TELEMETRY_REPORTING
--- a/mobile/android/modules/HomeProvider.jsm
+++ b/mobile/android/modules/HomeProvider.jsm
@@ -23,17 +23,17 @@ Cu.import("resource://gre/modules/XPCOMU
  */
 const SCHEMA_VERSION = 2;
 
 XPCOMUtils.defineLazyGetter(this, "DB_PATH", function() {
   return OS.Path.join(OS.Constants.Path.profileDir, "home.sqlite");
 });
 
 const PREF_STORAGE_LAST_SYNC_TIME_PREFIX = "home.storage.lastSyncTime.";
-const PREF_SYNC_WIFI_ONLY = "home.sync.wifiOnly";
+const PREF_SYNC_UPDATE_MODE = "home.sync.updateMode";
 const PREF_SYNC_CHECK_INTERVAL_SECS = "home.sync.checkIntervalSecs";
 
 XPCOMUtils.defineLazyGetter(this, "gSyncCheckIntervalSecs", function() {
   return Services.prefs.getIntPref(PREF_SYNC_CHECK_INTERVAL_SECS);
 });
 
 XPCOMUtils.defineLazyServiceGetter(this,
   "gUpdateTimerManager", "@mozilla.org/updates/timer-manager;1", "nsIUpdateTimerManager");
@@ -130,17 +130,17 @@ this.HomeProvider = Object.freeze({
    *
    * @param datasetId Unique identifier for the dataset to sync.
    * @param callback Function to call when it's time to sync, called with datasetId as a parameter.
    *
    * @return boolean Whether or not we were able to sync.
    */
   requestSync: function(datasetId, callback) {
     // Make sure it's a good time to sync.
-    if (Services.prefs.getBoolPref(PREF_SYNC_WIFI_ONLY) && !isUsingWifi()) {
+    if ((Services.prefs.getIntPref(PREF_SYNC_UPDATE_MODE) === 1) && !isUsingWifi()) {
       Cu.reportError("HomeProvider: Failed to sync because device is not on a local network");
       return false;
     }
 
     callback(datasetId);
     return true;
   },
 
--- a/security/manager/boot/src/nsSTSPreloadList.errors
+++ b/security/manager/boot/src/nsSTSPreloadList.errors
@@ -17,28 +17,28 @@ calyxinstitute.org: [Exception... "Compo
 carlolly.co.uk: did not receive HSTS header
 cert.se: max-age too low: 2628001
 checkout.google.com: did not receive HSTS header (error ignored - included regardless)
 chrome-devtools-frontend.appspot.com: did not receive HSTS header (error ignored - included regardless)
 chrome.google.com: did not receive HSTS header (error ignored - included regardless)
 cloud.google.com: did not receive HSTS header (error ignored - included regardless)
 code.google.com: did not receive HSTS header (error ignored - included regardless)
 codereview.chromium.org: did not receive HSTS header (error ignored - included regardless)
-conformal.com: could not connect to host
 crate.io: did not receive HSTS header
 crowdcurity.com: did not receive HSTS header
 crypto.is: did not receive HSTS header
 csawctf.poly.edu: did not receive HSTS header
 dl.google.com: did not receive HSTS header (error ignored - included regardless)
 docs.google.com: did not receive HSTS header (error ignored - included regardless)
 drive.google.com: did not receive HSTS header (error ignored - included regardless)
 dropcam.com: did not receive HSTS header
 email.lookout.com: could not connect to host
 emailprivacytester.com: did not receive HSTS header
 encrypted.google.com: did not receive HSTS header (error ignored - included regardless)
+errors.zenpayroll.com: could not connect to host
 espra.com: could not connect to host
 fatzebra.com.au: did not receive HSTS header
 fj.simple.com: did not receive HSTS header
 get.zenpayroll.com: did not receive HSTS header
 glass.google.com: did not receive HSTS header (error ignored - included regardless)
 gmail.com: did not receive HSTS header
 gocardless.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-hsts-000000000000000/getHSTSPreloadList.js :: processStsHeader :: line 125"  data: no]
 googlemail.com: did not receive HSTS header
--- a/security/manager/boot/src/nsSTSPreloadList.inc
+++ b/security/manager/boot/src/nsSTSPreloadList.inc
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*****************************************************************************/
 /* This is an automatically generated file. If you're not                    */
 /* nsSiteSecurityService.cpp, you shouldn't be #including it.     */
 /*****************************************************************************/
 
 #include <stdint.h>
-const PRTime gPreloadListExpirationTime = INT64_C(1404558396496000);
+const PRTime gPreloadListExpirationTime = INT64_C(1405167392459000);
 
 class nsSTSPreload
 {
   public:
     const char *mHost;
     const bool mIncludeSubdomains;
 };