Merge m-c to oak DONTBUILD
authorRobert Strong <robert.bugzilla@gmail.com>
Wed, 07 Sep 2016 23:38:02 -0700
changeset 491569 58f5a5a63533c60b333fdec9c3e6756bc744c964
parent 491568 5d13049e45a36f65374c4ca8746b54543b07fe3a (current diff)
parent 411433 77940cbf0c2a9f52c209fbbde5b2e7d4c74a1501 (diff)
child 491570 dfe9df2a3d995e680bac37d2b0f218967bb49822
push id47343
push userbmo:dothayer@mozilla.com
push dateWed, 01 Mar 2017 22:58:58 +0000
milestone51.0a1
Merge m-c to oak DONTBUILD
CLOBBER
b2g/app/b2g.js
b2g/installer/package-manifest.in
browser/app/nsBrowserApp.cpp
browser/app/profile/firefox.js
browser/base/content/browser.js
browser/components/contextualidentity/test/browser/browser_newtabButton.js
browser/components/originattributes/test/browser/browser_dummy.js
browser/components/preferences/in-content/advanced.js
browser/components/search/test/browser_eBay.js
browser/components/search/test/browser_eBay_behavior.js
browser/installer/package-manifest.in
browser/locales/en-US/searchplugins/eBay.xml
dom/alarm/AlarmDB.jsm
dom/alarm/AlarmHalService.cpp
dom/alarm/AlarmHalService.h
dom/alarm/AlarmService.jsm
dom/alarm/AlarmsManager.js
dom/alarm/AlarmsManager.manifest
dom/alarm/moz.build
dom/alarm/nsIAlarmHalService.idl
dom/alarm/test/chrome.ini
dom/alarm/test/file_empty.html
dom/alarm/test/mochitest.ini
dom/alarm/test/system_message_chrome_script.js
dom/alarm/test/test_alarm_add_data.html
dom/alarm/test/test_alarm_add_date.html
dom/alarm/test/test_alarm_add_respectTimezone.html
dom/alarm/test/test_alarm_change_system_clock.js
dom/alarm/test/test_alarm_non_permitted_app.html
dom/alarm/test/test_alarm_permitted_app.html
dom/alarm/test/test_alarm_remove.html
dom/alarm/test/test_bug1015540.html
dom/alarm/test/test_bug1037079.html
dom/alarm/test/test_bug1090896.html
dom/alarm/test/xpcshell.ini
dom/animation/Animation.cpp
dom/animation/Animation.h
dom/bindings/parser/tests/test_array.py
dom/bindings/parser/tests/test_array_of_interface.py
dom/bluetooth/common/BluetoothUtils.cpp
dom/permission/tests/test_alarms.html
dom/promise/PromiseNativeHandler.cpp
dom/security/test/general/file_block_importscript_wrong_mime_allowed.js
dom/security/test/general/file_block_importscript_wrong_mime_blocked.js
dom/simplepush/Push.js
dom/simplepush/Push.manifest
dom/simplepush/PushService.jsm
dom/simplepush/PushServiceLauncher.js
dom/simplepush/moz.build
dom/simplepush/test/mochitest.ini
dom/simplepush/test/test_permissions.html
dom/simplepush/test/test_prefs.html
dom/simplepush/test/test_register.html
dom/webidl/AlarmsManager.webidl
dom/webidl/SimplePushManager.webidl
hal/tests/browser.ini
hal/tests/browser_alarms.js
hal/tests/moz.build
js/src/jit-test/tests/asm.js/gating.js
js/src/jit-test/tests/wasm/basic-bce.js
js/src/jit-test/tests/wasm/basic-const.js
js/src/jit-test/tests/wasm/basic-control-flow.js
js/src/jit-test/tests/wasm/basic-float.js
js/src/jit-test/tests/wasm/basic-grow-memory.js
js/src/jit-test/tests/wasm/basic-integer.js
js/src/jit-test/tests/wasm/basic-memory.js
js/src/jit-test/tests/wasm/random-control-flow.js
media/libstagefright/binding/mp4parse/build.rs
media/libstagefright/binding/mp4parse/src/capi.rs
old-configure.in
security/sandbox/chromium/base/atomicops_internals_arm_gcc.h
security/sandbox/chromium/base/atomicops_internals_x86_gcc.h
security/sandbox/chromium/base/basictypes.h
security/sandbox/chromium/base/float_util.h
security/sandbox/chromium/base/port.h
security/sandbox/chromium/base/safe_strerror_posix.cc
security/sandbox/chromium/base/safe_strerror_posix.h
security/sandbox/chromium/sandbox/linux/seccomp-bpf/basicblock.cc
security/sandbox/chromium/sandbox/linux/seccomp-bpf/basicblock.h
security/sandbox/chromium/sandbox/linux/seccomp-bpf/codegen.cc
security/sandbox/chromium/sandbox/linux/seccomp-bpf/codegen.h
security/sandbox/chromium/sandbox/linux/seccomp-bpf/codegen_unittest.cc
security/sandbox/chromium/sandbox/linux/seccomp-bpf/errorcode.cc
security/sandbox/chromium/sandbox/linux/seccomp-bpf/errorcode.h
security/sandbox/chromium/sandbox/linux/seccomp-bpf/errorcode_unittest.cc
security/sandbox/chromium/sandbox/linux/seccomp-bpf/instruction.h
security/sandbox/chromium/sandbox/linux/seccomp-bpf/linux_seccomp.h
security/sandbox/chromium/sandbox/linux/seccomp-bpf/syscall_iterator.cc
security/sandbox/chromium/sandbox/linux/seccomp-bpf/syscall_iterator.h
security/sandbox/chromium/sandbox/linux/seccomp-bpf/syscall_iterator_unittest.cc
security/sandbox/chromium/sandbox/linux/seccomp-bpf/verifier.cc
security/sandbox/chromium/sandbox/linux/seccomp-bpf/verifier.h
security/sandbox/chromium/sandbox/linux/services/android_arm_ucontext.h
security/sandbox/chromium/sandbox/linux/services/android_futex.h
security/sandbox/chromium/sandbox/linux/services/android_i386_ucontext.h
security/sandbox/chromium/sandbox/linux/services/android_ucontext.h
security/sandbox/chromium/sandbox/linux/services/android_x86_64_ucontext.h
security/sandbox/chromium/sandbox/linux/services/arm_linux_syscalls.h
security/sandbox/chromium/sandbox/linux/services/linux_syscalls.h
security/sandbox/chromium/sandbox/linux/services/x86_32_linux_syscalls.h
security/sandbox/chromium/sandbox/linux/services/x86_64_linux_syscalls.h
security/sandbox/chromium/sandbox/win/src/handle_table.cc
security/sandbox/chromium/sandbox/win/src/handle_table.h
security/sandbox/chromium/sandbox/win/src/shared_handles.cc
security/sandbox/chromium/sandbox/win/src/shared_handles.h
taskcluster/scripts/builder/build-l10n.sh
testing/machine-configuration.json
testing/mochitest/mochitest_options.py
testing/mochitest/runtests.py
testing/web-platform/meta/2dcontext/drawing-images-to-the-canvas/2d.drawImage.incomplete.emptysrc.html.ini
testing/web-platform/meta/2dcontext/drawing-images-to-the-canvas/2d.drawImage.incomplete.nosrc.html.ini
testing/web-platform/meta/2dcontext/drawing-images-to-the-canvas/2d.drawImage.incomplete.removedsrc.html.ini
testing/web-platform/meta/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_10.html.ini
testing/web-platform/meta/2dcontext/image-smoothing/imagesmoothing.html.ini
testing/web-platform/meta/fetch/api/basic/scheme-data.html.ini
testing/web-platform/meta/html/semantics/scripting-1/the-script-element/fetch-src/empty-with-base.html.ini
testing/web-platform/meta/html/semantics/scripting-1/the-script-element/fetch-src/empty.html.ini
testing/web-platform/meta/old-tests/submission/Opera/script_scheduling/137.html.ini
toolkit/components/passwordmgr/content/passwordManagerExceptions.js
toolkit/components/passwordmgr/content/passwordManagerExceptions.xul
toolkit/components/places/UnifiedComplete.manifest
toolkit/components/telemetry/Histograms.json
toolkit/library/dummydll/dummydll.cpp
toolkit/library/dummydll/moz.build
toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
toolkit/xre/nsAppRunner.cpp
xpcom/build/XPCOMInit.cpp
--- a/.gitignore
+++ b/.gitignore
@@ -114,8 +114,11 @@ testing/talos/bin/
 testing/talos/include/
 testing/talos/lib/
 testing/talos/talos/tests/tp5n.zip
 testing/talos/talos/tests/tp5n
 testing/talos/talos/tests/devtools/damp.manifest.develop
 
 # Ignore files created when running a reftest.
 lextab.py
+
+# tup database
+/.tup
--- a/.hgignore
+++ b/.hgignore
@@ -124,8 +124,11 @@ GPATH
 ^testing/talos/include/
 ^testing/talos/lib/
 ^testing/talos/talos/tests/tp5n.zip
 ^testing/talos/talos/tests/tp5n
 ^testing/talos/talos/tests/devtools/damp.manifest.develop
 
 # Ignore files created when running a reftest.
 ^lextab.py$
+
+# tup database
+^\.tup
--- a/.taskcluster.yml
+++ b/.taskcluster.yml
@@ -80,17 +80,17 @@ tasks:
           level-{{level}}-hg-shared: /home/worker/hg-shared
           level-{{level}}-checkouts: /home/worker/checkouts
 
         features:
           taskclusterProxy: true
 
         # Note: This task is built server side without the context or tooling that
         # exist in tree so we must hard code the version
-        image: 'taskcluster/decision:0.1.5'
+        image: 'taskcluster/decision:0.1.6'
 
         maxRunTime: 1800
 
         # TODO use mozilla-unified for the base repository once the tc-vcs
         # tar.gz archives are created or tc-vcs isn't being used.
         command:
           - /home/worker/bin/run-task
           - '--vcs-checkout=/home/worker/checkouts/gecko'
--- a/CLOBBER
+++ b/CLOBBER
@@ -17,9 +17,9 @@
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
 # Are you updating CLOBBER because you think it's needed for your WebIDL
 # changes to stick? As of bug 928195, this shouldn't be necessary! Please
 # don't change CLOBBER for WebIDL changes any more.
 
-Bug 1299332 for the relanding of Bug 1299276.
+Bug 1287426 - Clobber required because of Linux Chromium sandbox file moves.
--- a/Makefile.in
+++ b/Makefile.in
@@ -166,16 +166,20 @@ install-manifests: $(addprefix install-,
 # config/faster/rules.mk)
 ifneq (,$(filter FasterMake+RecursiveMake,$(BUILD_BACKENDS)))
 install-manifests: faster
 .PHONY: faster
 faster: install-dist/idl
 	$(MAKE) -C faster FASTER_RECURSIVE_MAKE=1
 endif
 
+.PHONY: tup
+tup: install-manifests buildid.h
+	@$(TUP)
+
 # process_install_manifest needs to be invoked with --no-remove when building
 # js as standalone because automated builds are building nspr separately and
 # that would remove the resulting files.
 # Eventually, a standalone js build would just be able to build nspr itself,
 # removing the need for the former.
 ifdef JS_STANDALONE
 NO_REMOVE=1
 endif
--- a/accessible/base/Logging.cpp
+++ b/accessible/base/Logging.cpp
@@ -85,20 +85,17 @@ EnableLogging(const char* aModulesStr)
     if (*token == ',')
       token++; // skip ',' char
   }
 }
 
 static void
 LogDocURI(nsIDocument* aDocumentNode)
 {
-  nsIURI* uri = aDocumentNode->GetDocumentURI();
-  nsAutoCString spec;
-  uri->GetSpec(spec);
-  printf("uri: %s", spec.get());
+  printf("uri: %s", aDocumentNode->GetDocumentURI()->GetSpecOrDefault().get());
 }
 
 static void
 LogDocShellState(nsIDocument* aDocumentNode)
 {
   printf("docshell busy: ");
 
   nsAutoCString docShellBusy;
--- a/accessible/base/nsTextEquivUtils.cpp
+++ b/accessible/base/nsTextEquivUtils.cpp
@@ -122,17 +122,17 @@ nsTextEquivUtils::AppendTextEquivFromTex
     if (parentContent) {
       nsIFrame *frame = parentContent->GetPrimaryFrame();
       if (frame) {
         // If this text is inside a block level frame (as opposed to span
         // level), we need to add spaces around that block's text, so we don't
         // get words jammed together in final name.
         const nsStyleDisplay* display = frame->StyleDisplay();
         if (display->IsBlockOutsideStyle() ||
-            display->mDisplay == NS_STYLE_DISPLAY_TABLE_CELL) {
+            display->mDisplay == StyleDisplay::TableCell) {
           isHTMLBlock = true;
           if (!aString->IsEmpty()) {
             aString->Append(char16_t(' '));
           }
         }
       }
     }
     
--- a/accessible/tests/mochitest/text/test_atcaretoffset.html
+++ b/accessible/tests/mochitest/text/test_atcaretoffset.html
@@ -409,36 +409,28 @@
       // 10 11 12 13 14 15
 
       traverseTextByLines(gQueue, "textarea",
                           [ [ "aword", "\n", 0, 5, { words: [ 0, 5 ] } ],
                             [ "two ", "", 6, 10, { words: [ 6, 9 ] } ],
                             [ "words", "", 10, 15, { words: [ 10, 15 ] } ]
                           ] );
 
-      var line2 = [ // " my "
-        [ "TextBeforeOffset", BOUNDARY_WORD_END, kTodo, kTodo, kTodo ],
-        [ "TextAfterOffset", BOUNDARY_WORD_END, kTodo, kTodo, kTodo ]
-      ];
-      var line4 = [ // "riend"
-        [ "TextBeforeOffset", BOUNDARY_WORD_END, kTodo, kTodo, kTodo ],
-        [ "TextAfterOffset", BOUNDARY_WORD_END, kTodo, kTodo, kTodo ]
-      ];
-      var line5 = [ // " t "
+      var line4 = [ // "riend "
         [ "TextBeforeOffset", BOUNDARY_WORD_END, kTodo, kTodo, kTodo ],
         [ "TextAfterOffset", BOUNDARY_WORD_END, kTodo, kTodo, kTodo ]
       ];
       traverseTextByLines(gQueue, "ta_wrapped", 
                           [ [ "hi ", "", 0, 3, { words: [ 0, 2 ] } ],
-                            [ "hello", "", 3, 8, { words: [ 3, 8 ] } ],
-                            [ " my ", "", 8, 12, { words: [ 9, 11 ], lsf: line2 } ],
+                            [ "hello ", "", 3, 9, { words: [ 3, 8 ] } ],
+                            [ "my ", "", 9, 12, { words: [ 9, 11 ] } ],
                             [ "longf", "", 12, 17, { words: [ 12, 17 ] } ],
-                            [ "riend", "", 17, 22, { words: [ 17, 22 ], lsf: line4 } ],
-                            [ " t ", "", 22, 25, { words: [ 23, 24 ], lsf: line5 } ],
-                            [ "sq t", "", 25, 29, { words: [ 25, 27, 28, 29 ] } ]
+                            [ "riend ", "", 17, 23, { words: [ 17, 22 ], lsf: line4 } ],
+                            [ "t sq ", "", 23, 28, { words: [ 23, 24, 25, 27 ] } ],
+                            [ "t", "", 28, 29, { words: [ 28, 29 ] } ]
                           ] );
 
       gQueue.invoke(); // will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
--- a/accessible/tests/mochitest/tree/test_tabbrowser.xul
+++ b/accessible/tests/mochitest/tree/test_tabbrowser.xul
@@ -85,25 +85,16 @@
             {
               // xul:toolbarbutton ("Close current tab")
               role: ROLE_PUSHBUTTON,
               children: []
             }
             );
         } else {
           SimpleTest.ok(true, "Testing Firefox tabbrowser UI.");
-          let newTabChildren = [];
-          if (SpecialPowers.getBoolPref("privacy.userContext.enabled")) {
-            newTabChildren = [
-              {
-                role: ROLE_MENUPOPUP,
-                children: []
-              }
-            ];
-          }
 
           // NB: The (3) buttons are not visible, unless manually hovered,
           //     probably due to size reduction in this test.
           tabsAccTree.children.splice(0, 0,
             {
               // xul:tab ("about:")
               role: ROLE_PAGETAB,
               children: [
@@ -123,17 +114,17 @@
                   role: ROLE_PUSHBUTTON,
                   children: []
                 }
               ]
             },
             {
               // xul:toolbarbutton ("Open a new tab")
               role: ROLE_PUSHBUTTON,
-              children: newTabChildren
+              children: []
             }
             // "List all tabs" dropdown
             // XXX: This child(?) is not present in this test.
             //      I'm not sure why (though probably expected).
             );
         }
 
         testAccessibleTree(tabBrowser().tabContainer, tabsAccTree);
--- a/accessible/xul/XULTreeAccessible.cpp
+++ b/accessible/xul/XULTreeAccessible.cpp
@@ -119,17 +119,16 @@ XULTreeAccessible::Value(nsString& aValu
 
   // Return the value is the first selected child.
   nsCOMPtr<nsITreeSelection> selection;
   mTreeView->GetSelection(getter_AddRefs(selection));
   if (!selection)
     return;
 
   int32_t currentIndex;
-  nsCOMPtr<nsIDOMElement> selectItem;
   selection->GetCurrentIndex(&currentIndex);
   if (currentIndex >= 0) {
     nsCOMPtr<nsITreeColumn> keyCol;
 
     nsCOMPtr<nsITreeColumns> cols;
     mTree->GetColumns(getter_AddRefs(cols));
     if (cols)
       cols->GetKeyColumn(getter_AddRefs(keyCol));
--- a/addon-sdk/source/test/windows/test-firefox-windows.js
+++ b/addon-sdk/source/test/windows/test-firefox-windows.js
@@ -284,20 +284,20 @@ exports.testActiveWindow = function*(ass
     onFocus(rawWindow3).then(resolve);
     window3.activate();
     assert.pass("activating window3");
   });
 
   assert.equal(windows.activeWindow.title, window3.title, "Correct active window - 3");
 
   yield close(rawWindow2);
-  assert.equal(rawWindow2.closed, true, 'window 2 is closed');
+  yield close(rawWindow3);
 
-  yield close(rawWindow3);
-  assert.equal(rawWindow3.closed, true, 'window 3 is closed');
+  assert.equal(windows.length, 1, "Correct number of browser windows");
+  assert.equal(window.closed, false, "Original window is still open");
 };
 
 exports.testTrackWindows = function(assert, done) {
   let windows = [];
   let actions = [];
 
   let expects = [
     "activate 0", "global activate 0", "deactivate 0", "global deactivate 0",
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -398,53 +398,16 @@ pref("network.gonk.ms-release-mms-connec
 // Shortnumber matching needed for e.g. Brazil:
 // 03187654321 can be found with 87654321
 pref("dom.phonenumber.substringmatching.BR", 8);
 pref("dom.phonenumber.substringmatching.CO", 10);
 pref("dom.phonenumber.substringmatching.VE", 7);
 pref("dom.phonenumber.substringmatching.CL", 8);
 pref("dom.phonenumber.substringmatching.PE", 7);
 
-// WebAlarms
-pref("dom.mozAlarms.enabled", true);
-
-// SimplePush
-pref("services.push.enabled", true);
-// Debugging enabled.
-pref("services.push.debug", false);
-// Is the network connection allowed to be up?
-// This preference should be used in UX to enable/disable push.
-pref("services.push.connection.enabled", true);
-// serverURL to be assigned by services team
-pref("services.push.serverURL", "wss://push.services.mozilla.com/");
-pref("services.push.userAgentID", "");
-// Exponential back-off start is 5 seconds like in HTTP/1.1.
-// Maximum back-off is pingInterval.
-pref("services.push.retryBaseInterval", 5000);
-// Interval at which to ping PushServer to check connection status. In
-// milliseconds. If no reply is received within requestTimeout, the connection
-// is considered closed.
-pref("services.push.pingInterval", 1800000); // 30 minutes
-// How long before a DOMRequest errors as timeout
-pref("services.push.requestTimeout", 10000);
-pref("services.push.pingInterval.default", 180000);// 3 min
-pref("services.push.pingInterval.mobile", 180000); // 3 min
-pref("services.push.pingInterval.wifi", 180000);  // 3 min
-// Adaptive ping
-pref("services.push.adaptive.enabled", true);
-pref("services.push.adaptive.lastGoodPingInterval", 180000);// 3 min
-pref("services.push.adaptive.lastGoodPingInterval.mobile", 180000);// 3 min
-pref("services.push.adaptive.lastGoodPingInterval.wifi", 180000);// 3 min
-// Valid gap between the biggest good ping and the bad ping
-pref("services.push.adaptive.gap", 60000); // 1 minute
-// We limit the ping to this maximum value
-pref("services.push.adaptive.upperLimit", 1740000); // 29 min
-// enable udp wakeup support
-pref("services.push.udp.wakeupEnabled", true);
-
 // NetworkStats
 #ifdef MOZ_WIDGET_GONK
 pref("dom.mozNetworkStats.enabled", true);
 pref("dom.webapps.firstRunWithSIM", true);
 #endif
 
 // ResourceStats
 #ifdef MOZ_WIDGET_GONK
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -2,17 +2,16 @@
 /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
 /* 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/. */
 
 window.performance.mark('gecko-shell-loadstart');
 
 Cu.import('resource://gre/modules/ContactService.jsm');
-Cu.import('resource://gre/modules/AlarmService.jsm');
 Cu.import('resource://gre/modules/NotificationDB.jsm');
 Cu.import("resource://gre/modules/AppsUtils.jsm");
 Cu.import('resource://gre/modules/UserAgentOverrides.jsm');
 Cu.import('resource://gre/modules/Keyboard.jsm');
 Cu.import('resource://gre/modules/ErrorPage.jsm');
 Cu.import('resource://gre/modules/AlertsHelper.jsm');
 Cu.import('resource://gre/modules/SystemUpdateService.jsm');
 
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -11,17 +11,17 @@
   <project name="gaia" path="gaia" remote="b2g" revision="90240f7a2e66ae8873e1f1b0e5f1d80a98c2c2db"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="99003a6e7ecee880330a3fb8b5e49fefdb762374"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
   <project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>
   <project name="platform_system_libpdu" path="system/libpdu" remote="b2g" revision="f1a61fa8f97cc0a1ac4eca160acc222981b21d90"/>
   <project name="platform_system_sensorsd" path="system/sensorsd" remote="b2g" revision="3618678c472320de386f5ddc27897992d0e148a8"/>
   <!-- B2G specific things. -->
-  <project name="platform_build" path="build" remote="b2g" revision="aee7ff3dba262a037559d360b62af429b62cb876">
+  <project name="platform_build" path="build" remote="b2g" revision="76946dd709234cf4bdb860672ec66d6af8f2ea3c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
--- a/b2g/confvars.sh
+++ b/b2g/confvars.sh
@@ -31,17 +31,16 @@ fi
 MOZ_USE_NATIVE_POPUP_WINDOWS=1
 
 MOZ_XULRUNNER=
 
 MOZ_APP_ID={3c2e2abc-06d4-11e1-ac3b-374f68613e61}
 
 MOZ_TIME_MANAGER=1
 
-MOZ_SIMPLEPUSH=1
 MOZ_TOOLKIT_SEARCH=
 MOZ_B2G=1
 
 MOZ_JSDOWNLOADS=1
 
 MOZ_BUNDLED_FONTS=1
 
 export JS_GC_SMALL_CHUNK_SIZE=1
--- a/b2g/dev/config/tooltool-manifests/linux64/hazard.manifest
+++ b/b2g/dev/config/tooltool-manifests/linux64/hazard.manifest
@@ -19,21 +19,22 @@
 "algorithm" : "sha512",
 "filename" : "gtk3.tar.xz",
 "setup" : "setup.sh",
 "unpack" : true,
 "digest" : "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
 "size" : 12072532
 },
 {
-"size" : 89319524,
-"digest" : "5383d843c9f28abf0a6d254e9d975d96972d2c86d627ca836fa8e272a5d53230603b387d7d1499c49df7f84b1bb946946e800a85c88d968bdbe81c755fcb02e1",
-"algorithm" : "sha512",
-"filename" : "rustc.tar.xz",
-"unpack" : true
+"version": "rustc 1.11.0 (9b21dcd6a 2016-08-15) repack",
+"size": 131489924,
+"digest": "59f7463a0da38f324daa4ffc2678d78afb4fe0df13248c1d215bcb996ec05e8521155563cde9a8b719a9b98c5feeaf97cc9e8d52c9b95f6b44728870d908d5b6",
+"algorithm": "sha512",
+"filename": "rustc.tar.xz",
+"unpack": true
 },
 {
 "algorithm" : "sha512",
 "filename" : "sccache.tar.bz2",
 "unpack" : true,
 "digest" : "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
 "size" : 167175
 },
--- a/b2g/dev/config/tooltool-manifests/linux64/releng.manifest
+++ b/b2g/dev/config/tooltool-manifests/linux64/releng.manifest
@@ -11,27 +11,27 @@
 "size": 12072532,
 "digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
 "algorithm": "sha512",
 "filename": "gtk3.tar.xz",
 "setup": "setup.sh",
 "unpack": true
 },
 {
-"version": "gecko rustc 1.10.0 (cfcb716cf 2016-07-03)",
-"size": 102276708,
-"digest": "8cc9ea8347fc7e6e6fdb15a8fd1faae977f1235a426b879b3f9128ec91d8f2b6268297ce80bf4eceb47738bd40bfeda13f143dc3fe85f1434b13adfbc095ab90",
+"version": "rustc 1.11.0 (9b21dcd6a 2016-08-15) repack",
+"size": 131489924,
+"digest": "59f7463a0da38f324daa4ffc2678d78afb4fe0df13248c1d215bcb996ec05e8521155563cde9a8b719a9b98c5feeaf97cc9e8d52c9b95f6b44728870d908d5b6",
 "algorithm": "sha512",
 "filename": "rustc.tar.xz",
 "unpack": true
 },
 {
-"version": "cargo 0.13.0-nightly (664125b 2016-07-19)",
-"size": 3123796,
-"digest": "4b9d2bcb8488b6649ba6c748e19d33bfceb25c7566e882fc7e00322392e424a5a9c5878c11c61d57cdaecf67bcc110842c6eff95e49736e8f3c83d9ce1677122",
+"version": "cargo 0.13.0-nightly (e713e7f 2016-08-31)",
+"size": 3245716,
+"digest": "d5bb0d88ce7bb1b5a316d7a8ca6341672f5ee8008fa7754511bf53fabd54c0770e95397232896d6087547891f1143f6968d8b1e106e39800b43defeb0025c7c0",
 "algorithm": "sha512",
 "filename": "cargo.tar.xz",
 "unpack": true
 },
 {
 "size": 167175,
 "digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
 "algorithm": "sha512",
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -165,17 +165,16 @@
 #ifdef MOZ_B2G_BT
 @RESPATH@/components/dom_bluetooth.xpt
 #endif
 #ifdef MOZ_B2G_CAMERA
 @RESPATH@/components/dom_camera.xpt
 #endif
 @RESPATH@/components/dom_canvas.xpt
 @RESPATH@/components/dom_contacts.xpt
-@RESPATH@/components/dom_alarm.xpt
 @RESPATH@/components/dom_core.xpt
 @RESPATH@/components/dom_css.xpt
 @RESPATH@/components/dom_events.xpt
 @RESPATH@/components/dom_geolocation.xpt
 @RESPATH@/components/dom_media.xpt
 @RESPATH@/components/dom_network.xpt
 #ifdef MOZ_SECUREELEMENT
 @RESPATH@/components/dom_secureelement.xpt
@@ -358,18 +357,16 @@
 @RESPATH@/components/PhoneNumberService.js
 @RESPATH@/components/PhoneNumberService.manifest
 @RESPATH@/components/NotificationStorage.js
 @RESPATH@/components/NotificationStorage.manifest
 @RESPATH@/components/PermissionSettings.js
 @RESPATH@/components/PermissionSettings.manifest
 @RESPATH@/components/PermissionPromptService.js
 @RESPATH@/components/PermissionPromptService.manifest
-@RESPATH@/components/AlarmsManager.js
-@RESPATH@/components/AlarmsManager.manifest
 @RESPATH@/components/FeedProcessor.manifest
 @RESPATH@/components/FeedProcessor.js
 @RESPATH@/components/PackagedAppUtils.manifest
 @RESPATH@/components/PackagedAppUtils.js
 @RESPATH@/components/BrowserFeeds.manifest
 @RESPATH@/components/FeedConverter.js
 @RESPATH@/components/FeedWriter.js
 @RESPATH@/components/WebContentConverter.js
@@ -599,21 +596,17 @@
 @RESPATH@/components/XULStore.js
 @RESPATH@/components/XULStore.manifest
 @RESPATH@/components/Webapps.js
 @RESPATH@/components/Webapps.manifest
 @RESPATH@/components/AppsService.js
 @RESPATH@/components/AppsService.manifest
 @RESPATH@/components/Push.js
 @RESPATH@/components/Push.manifest
-#ifdef MOZ_SIMPLEPUSH
-@RESPATH@/components/PushServiceLauncher.js
-#else
 @RESPATH@/components/PushComponents.js
-#endif
 
 @RESPATH@/components/nsDOMIdentity.js
 @RESPATH@/components/nsIDService.js
 @RESPATH@/components/Identity.manifest
 
 @RESPATH@/components/SystemMessageInternal.js
 @RESPATH@/components/SystemMessageManager.js
 @RESPATH@/components/SystemMessageCache.js
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -521,16 +521,18 @@ pref("privacy.cpd.openWindows",         
 // 6 - Last 24 hours
 pref("privacy.sanitize.timeSpan", 1);
 pref("privacy.sanitize.sanitizeOnShutdown", false);
 
 pref("privacy.sanitize.migrateFx3Prefs",    false);
 
 pref("privacy.panicButton.enabled",         true);
 
+pref("privacy.firstparty.isolate",          false);
+
 pref("network.proxy.share_proxy_settings",  false); // use the same proxy settings for all protocols
 
 // simple gestures support
 pref("browser.gesture.swipe.left", "Browser:BackOrBackDuplicate");
 pref("browser.gesture.swipe.right", "Browser:ForwardOrForwardDuplicate");
 pref("browser.gesture.swipe.up", "cmd_scrollTop");
 pref("browser.gesture.swipe.down", "cmd_scrollBottom");
 #ifdef XP_MACOSX
--- a/browser/base/content/aboutDialog.js
+++ b/browser/base/content/aboutDialog.js
@@ -1,12 +1,14 @@
 /* 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";
+
 // Services = object with smart getters for common XPCOM services
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/AppConstants.jsm");
 
 function init(aEvent)
 {
   if (aEvent.target != document)
     return;
@@ -34,29 +36,40 @@ function init(aEvent)
       }
     }
   }
   catch (e) {
     // Pref is unset
   }
 
   // Include the build ID and display warning if this is an "a#" (nightly or aurora) build
+  let versionField = document.getElementById("version");
   let version = Services.appinfo.version;
   if (/a\d+$/.test(version)) {
     let buildID = Services.appinfo.appBuildID;
-    let buildDate = buildID.slice(0, 4) + "-" + buildID.slice(4, 6) + "-" + buildID.slice(6, 8);
-    document.getElementById("version").textContent += " (" + buildDate + ")";
+    let year = buildID.slice(0, 4);
+    let month = buildID.slice(4, 6);
+    let day = buildID.slice(6, 8);
+    versionField.textContent += ` (${year}-${month}-${day})`;
+
     document.getElementById("experimental").hidden = false;
     document.getElementById("communityDesc").hidden = true;
   }
 
+  // Append "(32-bit)" or "(64-bit)" build architecture to the version number:
+  let bundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
+  let archResource = Services.appinfo.is64Bit
+                     ? "aboutDialog.architecture.sixtyFourBit"
+                     : "aboutDialog.architecture.thirtyTwoBit";
+  let arch = bundle.GetStringFromName(archResource);
+  versionField.textContent += ` (${arch})`;
+
   if (AppConstants.MOZ_UPDATER) {
     gAppUpdater = new appUpdater();
 
-    let defaults = Services.prefs.getDefaultBranch("");
     let channelLabel = document.getElementById("currentChannel");
     let currentChannelText = document.getElementById("currentChannelText");
     channelLabel.value = UpdateUtils.UpdateChannel;
     if (/^release($|\-)/.test(channelLabel.value))
         currentChannelText.hidden = true;
   }
 
   if (AppConstants.platform == "macosx") {
--- a/browser/base/content/abouthome/aboutHome.css
+++ b/browser/base/content/abouthome/aboutHome.css
@@ -102,42 +102,41 @@ a {
 #searchText[keepfocus],
 #searchText:focus,
 #searchText[autofocus] {
   border-color: hsla(206,100%,60%,.6) hsla(206,76%,52%,.6) hsla(204,100%,40%,.6);
 }
 
 #searchSubmit {
   margin-inline-start: -1px;
+  color: transparent;
   background: url("chrome://browser/skin/search-arrow-go.svg#search-arrow-go") center center no-repeat, linear-gradient(hsla(0,0%,100%,.8), hsla(0,0%,100%,.1)) padding-box;
   padding: 0;
   border: 1px solid;
   border-color: hsla(210,54%,20%,.15) hsla(210,54%,20%,.17) hsla(210,54%,20%,.2);
   border-radius: 0 2px 2px 0;
   border-inline-start: 1px solid transparent;
   box-shadow: 0 0 2px hsla(0,0%,100%,.5) inset,
               0 1px 0 hsla(0,0%,100%,.2);
-  color: inherit;
   cursor: pointer;
   transition-property: background-color, border-color, box-shadow;
   transition-duration: 150ms;
   width: 50px;
 }
 
 #searchSubmit:dir(rtl) {
   border-radius: 2px 0 0 2px;
   background-image: url("chrome://browser/skin/search-arrow-go.svg#search-arrow-go-rtl"), linear-gradient(hsla(0,0%,100%,.8), hsla(0,0%,100%,.1));
 }
 
 #searchText:focus + #searchSubmit,
 #searchText[keepfocus] + #searchSubmit,
 #searchText + #searchSubmit:hover,
 #searchText[autofocus] + #searchSubmit {
   border-color: #59b5fc #45a3e7 #3294d5;
-  color: white;
 }
 
 #searchText:focus + #searchSubmit,
 #searchText[keepfocus] + #searchSubmit,
 #searchText[autofocus] + #searchSubmit {
   background-image: url("chrome://browser/skin/search-arrow-go.svg#search-arrow-go-inverted"), linear-gradient(#4cb1ff, #1793e5);
   box-shadow: 0 1px 0 hsla(0,0%,100%,.2) inset,
               0 0 0 1px hsla(0,0%,100%,.1) inset,
--- a/browser/base/content/abouthome/aboutHome.xhtml
+++ b/browser/base/content/abouthome/aboutHome.xhtml
@@ -39,18 +39,18 @@
     <div id="topSection">
       <div id="brandLogo"></div>
 
       <div id="searchIconAndTextContainer">
         <div id="searchIcon"/>
         <input type="text" name="q" value="" id="searchText" maxlength="256"
                aria-label="&contentSearchInput.label;" autofocus="autofocus"
                dir="auto"/>
-        <input id="searchSubmit" type="button" value="" onclick="onSearchSubmit(event)"
-               aria-label="&contentSearchSubmit.label;"/>
+        <input id="searchSubmit" type="button" value="&#x25b6;" onclick="onSearchSubmit(event)"
+               title="&contentSearchSubmit.tooltip;"/>
       </div>
 
       <div id="snippetContainer">
         <div id="defaultSnippets" hidden="true">
           <span id="defaultSnippet1">&abouthome.defaultSnippet1.v1;</span>
           <span id="defaultSnippet2">&abouthome.defaultSnippet2.v1;</span>
         </div>
         <span id="rightsSnippet" hidden="true">&abouthome.rightsSnippet;</span>
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -114,26 +114,16 @@ tabbrowser {
 #TabsToolbar[customizing="true"] > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .tabs-newtab-button {
   visibility: collapse;
 }
 
 #tabbrowser-tabs:not([overflow="true"])[using-closing-tabs-spacer] ~ #alltabs-button {
   visibility: hidden; /* temporary space to keep a tab's close button under the cursor */
 }
 
-.tabs-newtab-button > .toolbarbutton-menu-dropmarker,
-#new-tab-button > .toolbarbutton-menu-dropmarker {
-  display: none;
-}
-
-.tabs-newtab-button > .toolbarbutton-icon,
-#new-tab-button > .toolbarbutton-icon {
-  margin-inline-end: 0;
-}
-
 .tabbrowser-tab {
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tab");
 }
 
 .tabbrowser-tab:not([pinned]) {
   -moz-box-flex: 100;
   max-width: 210px;
   min-width: 100px;
@@ -182,17 +172,16 @@ tabbrowser {
   z-index: 2;
   pointer-events: none; /* avoid blocking dragover events on scroll buttons */
 }
 
 .tabbrowser-tabs[movingtab] > .tabbrowser-tab[fadein]:not([selected]) {
   transition: transform 200ms ease-out;
 }
 
-.new-tab-popup,
 #alltabs-popup {
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-alltabs-popup");
 }
 
 toolbar[printpreview="true"] {
   -moz-binding: url("chrome://global/content/printPreviewBindings.xml#printpreviewtoolbar");
 }
 
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -256,102 +256,92 @@ function UpdateBackForwardCommands(aWebN
   }
 }
 
 /**
  * Click-and-Hold implementation for the Back and Forward buttons
  * XXXmano: should this live in toolbarbutton.xml?
  */
 function SetClickAndHoldHandlers() {
+  var timer;
+
+  function openMenu(aButton) {
+    cancelHold(aButton);
+    aButton.firstChild.hidden = false;
+    aButton.open = true;
+  }
+
+  function mousedownHandler(aEvent) {
+    if (aEvent.button != 0 ||
+        aEvent.currentTarget.open ||
+        aEvent.currentTarget.disabled)
+      return;
+
+    // Prevent the menupopup from opening immediately
+    aEvent.currentTarget.firstChild.hidden = true;
+
+    aEvent.currentTarget.addEventListener("mouseout", mouseoutHandler, false);
+    aEvent.currentTarget.addEventListener("mouseup", mouseupHandler, false);
+    timer = setTimeout(openMenu, 500, aEvent.currentTarget);
+  }
+
+  function mouseoutHandler(aEvent) {
+    let buttonRect = aEvent.currentTarget.getBoundingClientRect();
+    if (aEvent.clientX >= buttonRect.left &&
+        aEvent.clientX <= buttonRect.right &&
+        aEvent.clientY >= buttonRect.bottom)
+      openMenu(aEvent.currentTarget);
+    else
+      cancelHold(aEvent.currentTarget);
+  }
+
+  function mouseupHandler(aEvent) {
+    cancelHold(aEvent.currentTarget);
+  }
+
+  function cancelHold(aButton) {
+    clearTimeout(timer);
+    aButton.removeEventListener("mouseout", mouseoutHandler, false);
+    aButton.removeEventListener("mouseup", mouseupHandler, false);
+  }
+
+  function clickHandler(aEvent) {
+    if (aEvent.button == 0 &&
+        aEvent.target == aEvent.currentTarget &&
+        !aEvent.currentTarget.open &&
+        !aEvent.currentTarget.disabled) {
+      let cmdEvent = document.createEvent("xulcommandevent");
+      cmdEvent.initCommandEvent("command", true, true, window, 0,
+                                aEvent.ctrlKey, aEvent.altKey, aEvent.shiftKey,
+                                aEvent.metaKey, null);
+      aEvent.currentTarget.dispatchEvent(cmdEvent);
+    }
+  }
+
+  function _addClickAndHoldListenersOnElement(aElm) {
+    aElm.addEventListener("mousedown", mousedownHandler, true);
+    aElm.addEventListener("click", clickHandler, true);
+  }
+
   // Bug 414797: Clone the back/forward buttons' context menu into both buttons.
   let popup = document.getElementById("backForwardMenu").cloneNode(true);
   popup.removeAttribute("id");
   // Prevent the back/forward buttons' context attributes from being inherited.
   popup.setAttribute("context", "");
 
   let backButton = document.getElementById("back-button");
   backButton.setAttribute("type", "menu");
   backButton.appendChild(popup);
-  addClickAndHoldListenersOnElement(backButton);
+  _addClickAndHoldListenersOnElement(backButton);
 
   let forwardButton = document.getElementById("forward-button");
   popup = popup.cloneNode(true);
   forwardButton.setAttribute("type", "menu");
   forwardButton.appendChild(popup);
-  addClickAndHoldListenersOnElement(forwardButton);
-}
-
-let holdTimersMap = new Map();
-function holdMousedownHandler(aEvent) {
-  if (aEvent.button != 0 ||
-      aEvent.currentTarget.open ||
-      aEvent.currentTarget.disabled)
-    return;
-
-  // Prevent the menupopup from opening immediately
-  aEvent.currentTarget.firstChild.hidden = true;
-
-  aEvent.currentTarget.addEventListener("mouseout", holdMouseoutHandler, false);
-  aEvent.currentTarget.addEventListener("mouseup", holdMouseupHandler, false);
-  holdTimersMap.set(aEvent.currentTarget, setTimeout(holdOpenMenu, 500, aEvent.currentTarget));
-}
-
-function holdClickHandler(aEvent) {
-  if (aEvent.button == 0 &&
-      aEvent.target == aEvent.currentTarget &&
-      !aEvent.currentTarget.open &&
-      !aEvent.currentTarget.disabled) {
-    let cmdEvent = document.createEvent("xulcommandevent");
-    cmdEvent.initCommandEvent("command", true, true, window, 0,
-                              aEvent.ctrlKey, aEvent.altKey, aEvent.shiftKey,
-                              aEvent.metaKey, null);
-    aEvent.currentTarget.dispatchEvent(cmdEvent);
-  }
-  // This is here to cancel the XUL default event
-  // dom.click() triggers a command even if there is a click handler
-  // however this can now be prevented with preventDefault().
-  aEvent.preventDefault();
-}
-
-function holdOpenMenu(aButton) {
-  cancelHold(aButton);
-  aButton.firstChild.hidden = false;
-  aButton.open = true;
-}
-
-function holdMouseoutHandler(aEvent) {
-  let buttonRect = aEvent.currentTarget.getBoundingClientRect();
-  if (aEvent.clientX >= buttonRect.left &&
-      aEvent.clientX <= buttonRect.right &&
-      aEvent.clientY >= buttonRect.bottom)
-    holdOpenMenu(aEvent.currentTarget);
-  else
-    cancelHold(aEvent.currentTarget);
-}
-
-function holdMouseupHandler(aEvent) {
-  cancelHold(aEvent.currentTarget);
-}
-
-function cancelHold(aButton) {
-  clearTimeout(holdTimersMap.get(aButton));
-  aButton.removeEventListener("mouseout", holdMouseoutHandler, false);
-  aButton.removeEventListener("mouseup", holdMouseupHandler, false);
-}
-
-function removeClickAndHoldListenersOnElement(aElm) {
-  aElm.removeEventListener("mousedown", holdMousedownHandler, true);
-  aElm.removeEventListener("click", holdClickHandler, true);
-}
-
-function addClickAndHoldListenersOnElement(aElm) {
-  holdTimersMap.delete(aElm);
-
-  aElm.addEventListener("mousedown", holdMousedownHandler, true);
-  aElm.addEventListener("click", holdClickHandler, true);
+  _addClickAndHoldListenersOnElement(forwardButton);
 }
 
 const gSessionHistoryObserver = {
   observe: function(subject, topic, data)
   {
     if (topic != "browser:purge-session-history")
       return;
 
@@ -696,17 +686,17 @@ function gKeywordURIFixup({ target: brow
   // because we need to be sure this last dot is the *only* dot, too.
   // More generally, this is used for the pref and should stay in sync with
   // the code in nsDefaultURIFixup::KeywordURIFixup .
   if (asciiHost.indexOf('.') == asciiHost.length - 1) {
     asciiHost = asciiHost.slice(0, -1);
   }
 
   // Ignore number-only things entirely (no decimal IPs for you!)
-  if (/^\d+$/.test(asciiHost))
+  if (/^\d+$/.test(fixupInfo.originalInput.trim()))
     return;
 
   let onLookupComplete = (request, record, status) => {
     let browser = weakBrowser.get();
     if (!Components.isSuccessCode(status) || !browser)
       return;
 
     let currentURI = browser.currentURI;
@@ -7386,16 +7376,18 @@ var gIdentityHandler = {
     let stateLabel = document.createElement("label");
     stateLabel.setAttribute("flex", "1");
     stateLabel.setAttribute("class", "identity-popup-permission-state-label");
     stateLabel.textContent = SitePermissions.getStateLabel(
       aPermission.id, aPermission.state, aPermission.inUse || false);
 
     let button = document.createElement("button");
     button.setAttribute("class", "identity-popup-permission-remove-button");
+    let tooltiptext = gNavigatorBundle.getString("permissions.remove.tooltip");
+    button.setAttribute("tooltiptext", tooltiptext);
     button.addEventListener("command", () => {
       this._permissionList.removeChild(container);
       if (aPermission.inUse &&
           ["camera", "microphone", "screen"].includes(aPermission.id)) {
         let windowId = this._sharingState.windowId;
         if (aPermission.id == "screen") {
           windowId = "screen:" + windowId;
         } else {
@@ -7414,16 +7406,33 @@ var gIdentityHandler = {
           }
         }
         let mm = gBrowser.selectedBrowser.messageManager;
         mm.sendAsyncMessage("webrtc:StopSharing", windowId);
       }
       SitePermissions.remove(gBrowser.currentURI, aPermission.id);
       this._permissionJustRemoved = true;
       this.updatePermissionHint();
+
+      // Set telemetry values for clearing a permission
+      let histogram = Services.telemetry.getKeyedHistogramById("WEB_PERMISSION_CLEARED");
+
+      let permissionType = 0;
+      if (aPermission.state == SitePermissions.ALLOW) {
+        // 1 : clear permanently allowed permission
+        permissionType = 1;
+      } else if (aPermission.state == SitePermissions.BLOCK) {
+        // 2 : clear permanently blocked permission
+        permissionType = 2;
+      }
+      // 3 : TODO clear temporary allowed permission
+      // 4 : TODO clear temporary blocked permission
+
+      histogram.add("(all)", permissionType);
+      histogram.add(aPermission.id, permissionType);
     });
 
     container.appendChild(img);
     container.appendChild(nameLabel);
     container.appendChild(stateLabel);
     container.appendChild(button);
 
     return container;
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -686,70 +686,65 @@
                    aria-label="&urlbar.viewSiteInfo.label;"
                    onclick="gIdentityHandler.handleIdentityButtonEvent(event);"
                    onkeypress="gIdentityHandler.handleIdentityButtonEvent(event);"
                    ondragstart="gIdentityHandler.onDragStart(event);">
                 <image id="identity-icon"
                        consumeanchor="identity-box"
                        onclick="PageProxyClickHandler(event);"/>
                 <image id="sharing-icon" mousethrough="always"/>
-                <box id="blocked-permissions-container" align="center" tooltiptext="">
+                <box id="blocked-permissions-container" align="center">
                   <image data-permission-id="geo" class="blocked-permission-icon geo-icon" role="button"
-                         aria-label="&urlbar.geolocationNotificationAnchor.label;"/>
+                         tooltiptext="&urlbar.geolocationBlocked.tooltip;"/>
                   <image data-permission-id="desktop-notification" class="blocked-permission-icon desktop-notification-icon" role="button"
-                         aria-label="&urlbar.webNotsNotificationAnchor3.label;"/>
+                         tooltiptext="&urlbar.webNotificationsBlocked.tooltip;"/>
                   <image data-permission-id="camera" class="blocked-permission-icon camera-icon" role="button"
-                         aria-label="&urlbar.webRTCShareDevicesNotificationAnchor.label;"/>
+                         tooltiptext="&urlbar.cameraBlocked.tooltip;"/>
                   <image data-permission-id="indexedDB" class="blocked-permission-icon indexedDB-icon" role="button"
-                         aria-label="&urlbar.indexedDBNotificationAnchor.label;"/>
+                         tooltiptext="&urlbar.indexedDBBlocked.tooltip;"/>
                   <image data-permission-id="microphone" class="blocked-permission-icon microphone-icon" role="button"
-                         aria-label="&urlbar.webRTCShareMicrophoneNotificationAnchor.label;"/>
+                         tooltiptext="&urlbar.microphoneBlocked.tooltip;"/>
                   <image data-permission-id="screen" class="blocked-permission-icon screen-icon" role="button"
-                         aria-label="&urlbar.webRTCShareScreenNotificationAnchor.label;"/>
-                  <image data-permission-id="pointerLock" class="blocked-permission-icon pointerLock-icon" role="button"
-                         aria-label="&urlbar.pointerLockNotificationAnchor.label;"/>
+                         tooltiptext="&urlbar.screenBlocked.tooltip;"/>
                 </box>
                 <box id="notification-popup-box"
                      hidden="true"
-                     tooltiptext=""
                      onmouseover="document.getElementById('identity-icon').classList.add('no-hover');"
                      onmouseout="document.getElementById('identity-icon').classList.remove('no-hover');"
                      align="center">
                   <image id="default-notification-icon" class="notification-anchor-icon" role="button"
-                         aria-label="&urlbar.defaultNotificationAnchor.label;"/>
+                         tooltiptext="&urlbar.defaultNotificationAnchor.tooltip;"/>
                   <image id="geo-notification-icon" class="notification-anchor-icon geo-icon" role="button"
-                         aria-label="&urlbar.geolocationNotificationAnchor.label;"/>
+                         tooltiptext="&urlbar.geolocationNotificationAnchor.tooltip;"/>
                   <image id="addons-notification-icon" class="notification-anchor-icon install-icon" role="button"
-                         aria-label="&urlbar.addonsNotificationAnchor.label;"/>
+                         tooltiptext="&urlbar.addonsNotificationAnchor.tooltip;"/>
                   <image id="indexedDB-notification-icon" class="notification-anchor-icon indexedDB-icon" role="button"
-                         aria-label="&urlbar.indexedDBNotificationAnchor.label;"/>
+                         tooltiptext="&urlbar.indexedDBNotificationAnchor.tooltip;"/>
                   <image id="login-fill-notification-icon" class="notification-anchor-icon login-icon" role="button"
-                         aria-label="&urlbar.loginFillNotificationAnchor.label;"/>
+                         tooltiptext="&urlbar.loginFillNotificationAnchor.tooltip;"/>
                   <image id="password-notification-icon" class="notification-anchor-icon login-icon" role="button"
-                         aria-label="&urlbar.passwordNotificationAnchor.label;"/>
+                         tooltiptext="&urlbar.passwordNotificationAnchor.tooltip;"/>
                   <image id="plugins-notification-icon" class="notification-anchor-icon plugin-icon" role="button"
-                         aria-label="&urlbar.pluginsNotificationAnchor.label;"/>
+                         tooltiptext="&urlbar.pluginsNotificationAnchor.tooltip;"/>
                   <image id="web-notifications-notification-icon" class="notification-anchor-icon desktop-notification-icon" role="button"
-                         aria-label="&urlbar.webNotsNotificationAnchor3.label;"/>
+                         tooltiptext="&urlbar.webNotificationAnchor.tooltip;"/>
                   <image id="webRTC-shareDevices-notification-icon" class="notification-anchor-icon camera-icon" role="button"
-                         aria-label="&urlbar.webRTCShareDevicesNotificationAnchor.label;"/>
+                         tooltiptext="&urlbar.webRTCShareDevicesNotificationAnchor.tooltip;"/>
                   <image id="webRTC-shareMicrophone-notification-icon" class="notification-anchor-icon microphone-icon" role="button"
-                         aria-label="&urlbar.webRTCShareMicrophoneNotificationAnchor.label;"/>
+                         tooltiptext="&urlbar.webRTCShareMicrophoneNotificationAnchor.tooltip;"/>
                   <image id="webRTC-shareScreen-notification-icon" class="notification-anchor-icon screen-icon" role="button"
-                         aria-label="&urlbar.webRTCShareScreenNotificationAnchor.label;"/>
-                  <image id="pointerLock-notification-icon" class="notification-anchor-icon pointerLock-icon" role="button"
-                         aria-label="&urlbar.pointerLockNotificationAnchor.label;"/>
+                         tooltiptext="&urlbar.webRTCShareScreenNotificationAnchor.tooltip;"/>
                   <image id="servicesInstall-notification-icon" class="notification-anchor-icon service-icon" role="button"
-                         aria-label="&urlbar.servicesNotificationAnchor.label;"/>
+                         tooltiptext="&urlbar.servicesNotificationAnchor.tooltip;"/>
                   <image id="translate-notification-icon" class="notification-anchor-icon translation-icon" role="button"
-                         aria-label="&urlbar.translateNotificationAnchor.label;"/>
+                         tooltiptext="&urlbar.translateNotificationAnchor.tooltip;"/>
                   <image id="translated-notification-icon" class="notification-anchor-icon translation-icon in-use" role="button"
-                         aria-label="&urlbar.translatedNotificationAnchor.label;"/>
+                         tooltiptext="&urlbar.translatedNotificationAnchor.tooltip;"/>
                   <image id="eme-notification-icon" class="notification-anchor-icon drm-icon" role="button"
-                         aria-label="&urlbar.emeNotificationAnchor.label;"/>
+                         tooltiptext="&urlbar.emeNotificationAnchor.tooltip;"/>
                 </box>
                 <image id="tracking-protection-icon"/>
                 <image id="connection-icon"/>
                 <hbox id="identity-icon-labels">
                   <label id="identity-icon-label" class="plain" flex="1"/>
                   <label id="identity-icon-country-label" class="plain"/>
                 </hbox>
               </box>
@@ -1046,17 +1041,17 @@
     <hbox flex="1" id="browser">
       <vbox id="browser-border-start" hidden="true" layer="true"/>
       <vbox id="sidebar-box" hidden="true" class="chromeclass-extrachrome">
         <sidebarheader id="sidebar-header" align="center">
           <label id="sidebar-title" persist="value" flex="1" crop="end" control="sidebar"/>
           <image id="sidebar-throbber"/>
           <toolbarbutton class="close-icon tabbable" tooltiptext="&sidebarCloseButton.tooltip;" oncommand="SidebarUI.hide();"/>
         </sidebarheader>
-        <browser id="sidebar" flex="1" autoscroll="false" disablehistory="true"
+        <browser id="sidebar" flex="1" autoscroll="false" disablehistory="true" disablefullscreen="true"
                   style="min-width: 14em; width: 18em; max-width: 36em;" tooltip="aHTMLTooltip"/>
       </vbox>
 
       <splitter id="sidebar-splitter" class="chromeclass-extrachrome sidebar-splitter" hidden="true"/>
       <vbox id="appcontent" flex="1">
         <notificationbox id="high-priority-global-notificationbox" notificationside="top"/>
         <tabbrowser id="content"
                     flex="1" contenttooltip="aHTMLTooltip"
--- a/browser/base/content/newtab/newTab.css
+++ b/browser/base/content/newtab/newTab.css
@@ -394,41 +394,40 @@ input[type=button] {
 #newtab-search-text[keepfocus],
 #newtab-search-text:focus,
 #newtab-search-text[autofocus] {
   border-color: hsla(206,100%,60%,.6) hsla(206,76%,52%,.6) hsla(204,100%,40%,.6);
 }
 
 #newtab-search-submit {
   margin-inline-start: -1px;
+  color: transparent;
   background: url("chrome://browser/skin/search-arrow-go.svg#search-arrow-go") center center no-repeat, linear-gradient(hsla(0,0%,100%,.8), hsla(0,0%,100%,.1)) padding-box;
   padding: 0;
   border: 1px solid;
   border-color: hsla(210,54%,20%,.15) hsla(210,54%,20%,.17) hsla(210,54%,20%,.2);
   border-radius: 0 2px 2px 0;
   border-inline-start: 1px solid transparent;
   box-shadow: 0 0 2px hsla(0,0%,100%,.5) inset,
               0 1px 0 hsla(0,0%,100%,.2);
-  color: inherit;
   cursor: pointer;
   transition-property: background-color, border-color, box-shadow;
   transition-duration: 150ms;
   width: 50px;
 }
 
 #newtab-search-submit:dir(rtl) {
   border-radius: 2px 0 0 2px;
   background-image: url("chrome://browser/skin/search-arrow-go.svg#search-arrow-go-rtl"), linear-gradient(hsla(0,0%,100%,.8), hsla(0,0%,100%,.1));
 }
 
 #newtab-search-text:focus + #newtab-search-submit,
 #newtab-search-text + #newtab-search-submit:hover,
 #newtab-search-text[autofocus] + #newtab-search-submit {
   border-color: #59b5fc #45a3e7 #3294d5;
-  color: white;
 }
 
 #newtab-search-text:focus + #newtab-search-submit,
 #newtab-search-text[keepfocus] + #newtab-search-submit,
 #newtab-search-text[autofocus] + #newtab-search-submit {
   background-image: url("chrome://browser/skin/search-arrow-go.svg#search-arrow-go-inverted"), linear-gradient(#4cb1ff, #1793e5);
   box-shadow: 0 1px 0 hsla(0,0%,100%,.2) inset,
               0 0 0 1px hsla(0,0%,100%,.1) inset,
--- a/browser/base/content/newtab/newTab.xhtml
+++ b/browser/base/content/newtab/newTab.xhtml
@@ -66,18 +66,18 @@
       </div>
     </div>
 
     <div id="newtab-search-container">
       <div id="newtab-search-form">
         <div id="newtab-search-icon"/>
         <input type="text" name="q" value="" id="newtab-search-text"
              aria-label="&contentSearchInput.label;" maxlength="256" dir="auto"/>
-        <input id="newtab-search-submit" type="button" value=""
-             aria-label="&contentSearchSubmit.label;"/>
+        <input id="newtab-search-submit" type="button" value="&#x25b6;"
+             title="&contentSearchSubmit.tooltip;"/>
       </div>
     </div>
 
     <div id="newtab-horizontal-margin">
       <div class="newtab-side-margin"/>
       <div id="newtab-grid">
       </div>
       <div class="newtab-side-margin"/>
--- a/browser/base/content/popup-notifications.inc
+++ b/browser/base/content/popup-notifications.inc
@@ -39,22 +39,16 @@
     </popupnotification>
 
     <popupnotification id="servicesInstall-notification" hidden="true">
       <popupnotificationcontent orient="vertical" align="start">
         <!-- XXX bug 974146, tests are looking for this, can't remove yet. -->
       </popupnotificationcontent>
     </popupnotification>
 
-    <popupnotification id="pointerLock-notification" hidden="true">
-      <popupnotificationcontent orient="vertical" align="start">
-        <label id="pointerLock-cancel">&pointerLock.notification.message;</label>
-      </popupnotificationcontent>
-    </popupnotification>
-
     <popupnotification id="password-notification" hidden="true">
       <popupnotificationcontent orient="vertical">
         <textbox id="password-notification-username"/>
         <textbox id="password-notification-password" type="password" show-content=""/>
         <checkbox id="password-notification-visibilityToggle" hidden="true"/>
       </popupnotificationcontent>
     </popupnotification>
 
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -4941,17 +4941,17 @@
                            onmouseover="document.getBindingParent(this)._enterNewTab();"
                            onmouseout="document.getBindingParent(this)._leaveNewTab();"
                            tooltip="dynamic-shortcut-tooltip"/>
         <xul:spacer class="closing-tabs-spacer" anonid="closing-tabs-spacer"
                     style="width: 0;"/>
       </xul:arrowscrollbox>
     </content>
 
-    <implementation implements="nsIDOMEventListener, nsIObserver">
+    <implementation implements="nsIDOMEventListener">
       <constructor>
         <![CDATA[
           this.mTabClipWidth = Services.prefs.getIntPref("browser.tabs.tabClipWidth");
 
           var tab = this.firstChild;
           tab.label = this.tabbrowser.mStringBundle.getString("tabs.emptyTabTitle");
           tab.setAttribute("crop", "end");
           tab.setAttribute("onerror", "this.removeAttribute('image');");
@@ -4960,31 +4960,19 @@
           window.addEventListener("load", this, false);
 
           try {
             this._tabAnimationLoggingEnabled = Services.prefs.getBoolPref("browser.tabs.animationLogging.enabled");
           } catch (ex) {
             this._tabAnimationLoggingEnabled = false;
           }
           this._browserNewtabpageEnabled = Services.prefs.getBoolPref("browser.newtabpage.enabled");
-          this.observe(null, "nsPref:changed", "privacy.userContext.enabled");
-          Services.prefs.addObserver("privacy.userContext.enabled", this, false);
         ]]>
       </constructor>
 
-      <destructor>
-        <![CDATA[
-          Services.prefs.removeObserver("privacy.userContext.enabled", this);
-        ]]>
-      </destructor>
-
-      <field name="newtabUndoCloseTab" readonly="true">
-        document.getAnonymousElementByAttribute(this, "anonid", "newtab_undoCloseTab");
-      </field>
-
       <field name="tabbrowser" readonly="true">
         document.getElementById(this.getAttribute("tabbrowser"));
       </field>
 
       <field name="tabbox" readonly="true">
         this.tabbrowser.mTabBox;
       </field>
 
@@ -5000,64 +4988,16 @@
 
       <field name="_firstTab">null</field>
       <field name="_lastTab">null</field>
       <field name="_afterSelectedTab">null</field>
       <field name="_beforeHoveredTab">null</field>
       <field name="_afterHoveredTab">null</field>
       <field name="_hoveredTab">null</field>
 
-      <method name="observe">
-        <parameter name="aSubject"/>
-        <parameter name="aTopic"/>
-        <parameter name="aData"/>
-        <body><![CDATA[
-          switch (aTopic) {
-            case "nsPref:changed":
-              // This is the only pref observed.
-              let containersEnabled = Services.prefs.getBoolPref("privacy.userContext.enabled");
-
-              const newTab = document.getElementById("new-tab-button");
-              const newTab2 = document.getAnonymousElementByAttribute(this, "anonid", "tabs-newtab-button")
-
-              if (containersEnabled) {
-                for (let parent of [newTab, newTab2]) {
-                  if (!parent)
-                    continue;
-                  let popup = document.createElementNS(
-                                "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
-                                "menupopup");
-                  if (parent.id) {
-                    popup.id = "newtab-popup";
-                  } else {
-                    popup.setAttribute("anonid", "newtab-popup");
-                  }
-                  popup.oncommand="event.stopPropagation();";
-                  popup.className = "new-tab-popup";
-                  popup.setAttribute("position", "after_end");
-                  parent.appendChild(popup);
-
-                  addClickAndHoldListenersOnElement(parent);
-                  parent.setAttribute("type", "menu");
-                }
-              } else {
-                for (let parent of [newTab, newTab2]) {
-                  if (!parent)
-                    continue;
-                  removeClickAndHoldListenersOnElement(parent);
-                  parent.removeAttribute("type");
-                  parent.firstChild.remove();
-                }
-              }
-
-              break;
-          }
-        ]]></body>
-      </method>
-
       <property name="_isCustomizing" readonly="true">
         <getter>
           let root = document.documentElement;
           return root.getAttribute("customizing") == "true" ||
                  root.getAttribute("customize-exiting") == "true";
         </getter>
       </property>
 
@@ -6735,64 +6675,55 @@
       <handler event="popupshowing">
       <![CDATA[
         if (event.target.getAttribute('id') == "alltabs_containersMenuTab") {
           createUserContextMenu(event);
           return;
         }
 
         let containersEnabled = Services.prefs.getBoolPref("privacy.userContext.enabled");
-
-        if (event.target.getAttribute('anonid') == "newtab-popup" ||
-            event.target.id == "newtab-popup") {
-          createUserContextMenu(event);
-        } else {
-          document.getElementById("alltabs-popup-separator-1").hidden = !containersEnabled;
-          let containersTab = document.getElementById("alltabs_containersTab");
-
-          containersTab.hidden = !containersEnabled;
-          if (PrivateBrowsingUtils.isWindowPrivate(window)) {
-            containersTab.setAttribute("disabled", "true");
-          }
-
-          document.getElementById("alltabs_undoCloseTab").disabled =
-            SessionStore.getClosedTabCount(window) == 0;
-
-          var tabcontainer = gBrowser.tabContainer;
-
-          // Listen for changes in the tab bar.
-          tabcontainer.addEventListener("TabAttrModified", this, false);
-          tabcontainer.addEventListener("TabClose", this, false);
-          tabcontainer.mTabstrip.addEventListener("scroll", this, false);
-
-          let tabs = gBrowser.visibleTabs;
-          for (var i = 0; i < tabs.length; i++) {
-            if (!tabs[i].pinned)
-              this._createTabMenuItem(tabs[i]);
-          }
-          this._updateTabsVisibilityStatus();
+        document.getElementById("alltabs-popup-separator-1").hidden = !containersEnabled;
+        let containersTab = document.getElementById("alltabs_containersTab");
+
+        containersTab.hidden = !containersEnabled;
+        if (PrivateBrowsingUtils.isWindowPrivate(window)) {
+          containersTab.setAttribute("disabled", "true");
         }
+
+        document.getElementById("alltabs_undoCloseTab").disabled =
+          SessionStore.getClosedTabCount(window) == 0;
+
+        var tabcontainer = gBrowser.tabContainer;
+
+        // Listen for changes in the tab bar.
+        tabcontainer.addEventListener("TabAttrModified", this, false);
+        tabcontainer.addEventListener("TabClose", this, false);
+        tabcontainer.mTabstrip.addEventListener("scroll", this, false);
+
+        let tabs = gBrowser.visibleTabs;
+        for (var i = 0; i < tabs.length; i++) {
+          if (!tabs[i].pinned)
+            this._createTabMenuItem(tabs[i]);
+        }
+        this._updateTabsVisibilityStatus();
       ]]></handler>
 
       <handler event="popuphidden">
       <![CDATA[
         if (event.target.getAttribute('id') == "alltabs_containersMenuTab") {
           return;
         }
 
         // clear out the menu popup and remove the listeners
         for (let i = this.childNodes.length - 1; i > 0; i--) {
           let menuItem = this.childNodes[i];
           if (menuItem.tab) {
             menuItem.tab.mCorrespondingMenuitem = null;
             this.removeChild(menuItem);
           }
-          if (menuItem.hasAttribute("usercontextid")) {
-            this.removeChild(menuItem);
-          }
         }
         var tabcontainer = gBrowser.tabContainer;
         tabcontainer.mTabstrip.removeEventListener("scroll", this, false);
         tabcontainer.removeEventListener("TabAttrModified", this, false);
         tabcontainer.removeEventListener("TabClose", this, false);
       ]]></handler>
 
       <handler event="DOMMenuItemActive">
--- a/browser/base/content/test/general/browser_selectpopup.js
+++ b/browser/base/content/test/general/browser_selectpopup.js
@@ -1,15 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // This test checks that a <select> with an <optgroup> opens and can be navigated
 // in a child process. This is different than single-process as a <menulist> is used
 // to implement the dropdown list.
 
+requestLongerTimeout(2);
+
 const XHTML_DTD = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">';
 
 const PAGECONTENT =
   "<html xmlns='http://www.w3.org/1999/xhtml'>" +
   "<body onload='gChangeEvents = 0;gInputEvents = 0; document.body.firstChild.focus()'><select oninput='gInputEvents++' onchange='gChangeEvents++'>" +
   "  <optgroup label='First Group'>" +
   "    <option value='One'>One</option>" +
   "    <option value='Two'>Two</option>" +
--- a/browser/base/content/test/general/browser_tab_close_dependent_window.js
+++ b/browser/base/content/test/general/browser_tab_close_dependent_window.js
@@ -12,13 +12,13 @@ add_task(function* closing_tab_with_depe
   let depTabOpened = BrowserTestUtils.waitForEvent(win.gBrowser.tabContainer, "TabOpen");
   yield BrowserTestUtils.synthesizeMouse("html", 0, 0, {}, tab.linkedBrowser);
 
   let openedTab = (yield depTabOpened).target;
   info("Got opened tab");
 
   let windowClosedPromise = BrowserTestUtils.windowClosed(win);
   yield BrowserTestUtils.removeTab(tab);
-  is(openedTab.linkedBrowser, null, "Opened tab should also have closed");
+  is(Cu.isDeadWrapper(openedTab) || openedTab.linkedBrowser == null, true, "Opened tab should also have closed");
   info("If we timeout now, the window failed to close - that shouldn't happen!");
   yield windowClosedPromise;
 });
 
--- a/browser/base/content/test/popupNotifications/browser.ini
+++ b/browser/base/content/test/popupNotifications/browser.ini
@@ -7,8 +7,10 @@ skip-if = (os == "linux" && (debug || as
 [browser_popupNotification.js]
 skip-if = (os == "linux" && (debug || asan))
 [browser_popupNotification_2.js]
 skip-if = (os == "linux" && (debug || asan))
 [browser_popupNotification_3.js]
 skip-if = (os == "linux" && (debug || asan))
 [browser_popupNotification_4.js]
 skip-if = (os == "linux" && (debug || asan))
+[browser_popupNotification_checkbox.js]
+skip-if = (os == "linux" && (debug || asan))
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/popupNotifications/browser_popupNotification_checkbox.js
@@ -0,0 +1,197 @@
+/* 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/. */
+
+function test() {
+  waitForExplicitFinish();
+
+  ok(PopupNotifications, "PopupNotifications object exists");
+  ok(PopupNotifications.panel, "PopupNotifications panel exists");
+
+  setup();
+  goNext();
+}
+
+function checkCheckbox(checkbox, label, checked=false, hidden=false) {
+  is(checkbox.label, label, "Checkbox should have the correct label");
+  is(checkbox.hidden, hidden, "Checkbox should be shown");
+  is(checkbox.checked, checked, "Checkbox should be checked by default");
+}
+
+function checkMainAction(notification, disabled=false) {
+  let mainAction = notification.button;
+  let warningLabel = document.getAnonymousElementByAttribute(notification, "class", "popup-notification-warning");
+  is(warningLabel.hidden, !disabled, "Warning label should be shown");
+  is(mainAction.disabled, disabled, "MainAction should be disabled");
+}
+
+var gNotification;
+
+var tests = [
+  // Test that passing the checkbox field shows the checkbox.
+  { id: "show_checkbox",
+    run: function () {
+      this.notifyObj = new BasicNotification(this.id);
+      this.notifyObj.options.checkbox = {
+        label: "This is a checkbox",
+      };
+      gNotification = showNotification(this.notifyObj);
+    },
+    onShown: function (popup) {
+      checkPopup(popup, this.notifyObj);
+      let notification = popup.childNodes[0];
+      checkCheckbox(notification.checkbox, "This is a checkbox");
+      triggerMainCommand(popup);
+    },
+    onHidden: function () { }
+  },
+
+  // Test checkbox being checked by default
+  { id: "checkbox_checked",
+    run: function () {
+      this.notifyObj = new BasicNotification(this.id);
+      this.notifyObj.options.checkbox = {
+        label: "Check this",
+        checked: true,
+      };
+      gNotification = showNotification(this.notifyObj);
+    },
+    onShown: function (popup) {
+      checkPopup(popup, this.notifyObj);
+      let notification = popup.childNodes[0];
+      checkCheckbox(notification.checkbox, "Check this", true);
+      triggerMainCommand(popup);
+    },
+    onHidden: function () { }
+  },
+
+  // Test checkbox passing the checkbox state on mainAction
+  { id: "checkbox_passCheckboxChecked_mainAction",
+    run: function () {
+      this.notifyObj = new BasicNotification(this.id);
+      this.notifyObj.mainAction.callback = ({checkboxChecked}) => this.mainActionChecked = checkboxChecked;
+      this.notifyObj.options.checkbox = {
+        label: "This is a checkbox",
+      };
+      gNotification = showNotification(this.notifyObj);
+    },
+    onShown: function (popup) {
+      checkPopup(popup, this.notifyObj);
+      let notification = popup.childNodes[0];
+      let checkbox = notification.checkbox;
+      checkCheckbox(checkbox, "This is a checkbox");
+      EventUtils.synthesizeMouseAtCenter(checkbox, {});
+      checkCheckbox(checkbox, "This is a checkbox", true);
+      triggerMainCommand(popup);
+    },
+    onHidden: function () {
+      is(this.mainActionChecked, true, "mainAction callback is passed the correct checkbox value");
+    }
+  },
+
+  // Test checkbox passing the checkbox state on secondaryAction
+  { id: "checkbox_passCheckboxChecked_secondaryAction",
+    run: function () {
+      this.notifyObj = new BasicNotification(this.id);
+      this.notifyObj.secondaryActions = [{
+        label: "Test Secondary",
+        accessKey: "T",
+        callback: ({checkboxChecked}) => this.secondaryActionChecked = checkboxChecked,
+      }];
+      this.notifyObj.options.checkbox = {
+        label: "This is a checkbox",
+      };
+      gNotification = showNotification(this.notifyObj);
+    },
+    onShown: function (popup) {
+      checkPopup(popup, this.notifyObj);
+      let notification = popup.childNodes[0];
+      let checkbox = notification.checkbox;
+      checkCheckbox(checkbox, "This is a checkbox");
+      EventUtils.synthesizeMouseAtCenter(checkbox, {});
+      checkCheckbox(checkbox, "This is a checkbox", true);
+      triggerSecondaryCommand(popup, 0);
+    },
+    onHidden: function () {
+      is(this.secondaryActionChecked, true, "secondaryAction callback is passed the correct checkbox value");
+    }
+  },
+
+  // Test checkbox preserving its state through re-opening the doorhanger
+  { id: "checkbox_reopen",
+    run: function () {
+      this.notifyObj = new BasicNotification(this.id);
+      this.notifyObj.options.checkbox = {
+        label: "This is a checkbox",
+        checkedState: {
+          disableMainAction: true,
+          warningLabel: "Testing disable",
+        },
+      };
+      gNotification = showNotification(this.notifyObj);
+    },
+    onShown: function (popup) {
+      checkPopup(popup, this.notifyObj);
+      let notification = popup.childNodes[0];
+      let checkbox = notification.checkbox;
+      checkCheckbox(checkbox, "This is a checkbox");
+      EventUtils.synthesizeMouseAtCenter(checkbox, {});
+      dismissNotification(popup);
+    },
+    onHidden: function (popup) {
+      let icon = document.getElementById("default-notification-icon");
+      EventUtils.synthesizeMouseAtCenter(icon, {});
+      let notification = popup.childNodes[0];
+      let checkbox = notification.checkbox;
+      checkCheckbox(checkbox, "This is a checkbox", true);
+      checkMainAction(notification, true);
+      gNotification.remove();
+    }
+  },
+];
+
+// Test checkbox disabling the main action in different combinations
+["checkedState", "uncheckedState"].forEach(function (state) {
+  [true, false].forEach(function (checked) {
+    tests.push(
+      { id: `checkbox_disableMainAction_${state}_${checked ? 'checked' : 'unchecked'}`,
+        run: function () {
+          this.notifyObj = new BasicNotification(this.id);
+          this.notifyObj.options.checkbox = {
+            label: "This is a checkbox",
+            checked: checked,
+            [state]: {
+              disableMainAction: true,
+              warningLabel: "Testing disable",
+            },
+          };
+          gNotification = showNotification(this.notifyObj);
+        },
+        onShown: function (popup) {
+          checkPopup(popup, this.notifyObj);
+          let notification = popup.childNodes[0];
+          let checkbox = notification.checkbox;
+          let disabled = (state === "checkedState" && checked) ||
+                         (state === "uncheckedState" && !checked);
+
+          checkCheckbox(checkbox, "This is a checkbox", checked);
+          checkMainAction(notification, disabled);
+          EventUtils.synthesizeMouseAtCenter(checkbox, {});
+          checkCheckbox(checkbox, "This is a checkbox", !checked);
+          checkMainAction(notification, !disabled);
+          EventUtils.synthesizeMouseAtCenter(checkbox, {});
+          checkCheckbox(checkbox, "This is a checkbox", checked);
+          checkMainAction(notification, disabled);
+
+          // Unblock the main command if it's currently disabled.
+          if (disabled) {
+            EventUtils.synthesizeMouseAtCenter(checkbox, {});
+          }
+          triggerMainCommand(popup);
+        },
+        onHidden: function () { }
+      }
+    );
+  });
+});
+
--- a/browser/base/content/test/tabPrompts/browser_multiplePrompts.js
+++ b/browser/base/content/test/tabPrompts/browser_multiplePrompts.js
@@ -51,16 +51,22 @@ add_task(function*() {
       if (i !== promptsCount) {
         is(prompt.hidden, true, "This prompt should be hidden.");
         i++;
         continue;
       }
 
       is(prompt.hidden, false, "The last prompt should not be hidden.");
       prompt.onButtonClick(0);
+
+      // The click is handled async; wait for an event loop turn for that to
+      // happen.
+      yield new Promise(function(resolve) {
+        Services.tm.mainThread.dispatch(resolve, Ci.nsIThread.DISPATCH_NORMAL);
+      });
     }
   }
 
   let prompts = tab.linkedBrowser.parentNode.querySelectorAll("tabmodalprompt");
   is(prompts.length, 0, "Prompts should all be dismissed.");
 
   yield BrowserTestUtils.removeTab(tab);
 });
--- a/browser/base/content/test/tabPrompts/browser_openPromptInBackgroundTab.js
+++ b/browser/base/content/test/tabPrompts/browser_openPromptInBackgroundTab.js
@@ -37,16 +37,20 @@ add_task(function*() {
   let row = ourPrompt.querySelector("row");
   ok(row, "Should have found the row with our checkbox");
   let checkbox = row.querySelector("checkbox[label*='example.com']");
   ok(checkbox, "The checkbox should be there");
   ok(!checkbox.checked, "Checkbox shouldn't be checked");
   // tick box and accept dialog
   checkbox.checked = true;
   ourPrompt.onButtonClick(0);
+  // Wait for that click to actually be handled completely.
+  yield new Promise(function(resolve) {
+    Services.tm.mainThread.dispatch(resolve, Ci.nsIThread.DISPATCH_NORMAL);
+  });
   // check permission is set
   let ps = Services.perms;
   is(ps.ALLOW_ACTION, ps.testPermission(makeURI(pageWithAlert), "focus-tab-by-prompt"),
      "Tab switching should now be allowed");
 
   let openedTabSelectedPromise = BrowserTestUtils.waitForAttribute("selected", openedTab, "true");
   // switch to other tab again
   yield BrowserTestUtils.switchTab(gBrowser, firstTab);
--- a/browser/base/content/test/urlbar/browser_urlbarSearchSingleWordNotification.js
+++ b/browser/base/content/test/urlbar/browser_urlbarSearchSingleWordNotification.js
@@ -33,17 +33,17 @@ function promiseNotificationForTab(aBrow
     setTimeout(() => {
       is(notificationBox.getNotificationWithValue(value), null, "We are expecting to not get a notification");
       deferred.resolve();
     }, 1000);
   }
   return deferred.promise;
 }
 
-function* runURLBarSearchTest(valueToOpen, expectSearch, expectNotification, aWindow=window) {
+function* runURLBarSearchTest({valueToOpen, expectSearch, expectNotification, aWindow=window}) {
   aWindow.gURLBar.value = valueToOpen;
   let expectedURI;
   if (!expectSearch) {
     expectedURI = "http://" + valueToOpen + "/";
   } else {
     yield new Promise(resolve => {
       Services.search.init(resolve);
     });
@@ -57,31 +57,43 @@ function* runURLBarSearchTest(valueToOpe
     docLoadPromise,
     promiseNotificationForTab(aWindow.gBrowser, "keyword-uri-fixup", expectNotification)
   ]);
 }
 
 add_task(function* test_navigate_full_domain() {
   let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
   yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
-  yield* runURLBarSearchTest("www.mozilla.org", false, false);
+  yield* runURLBarSearchTest({
+    valueToOpen: "www.mozilla.org",
+    expectSearch: false,
+    expectNotification: false,
+  });
   gBrowser.removeTab(tab);
 });
 
-add_task(function* test_navigate_valid_numbers() {
+add_task(function* test_navigate_decimal_ip() {
   let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
   yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
-  yield* runURLBarSearchTest("1234", true, true);
+  yield* runURLBarSearchTest({
+    valueToOpen: "1234",
+    expectSearch: true,
+    expectNotification: false,
+  });
   gBrowser.removeTab(tab);
 });
 
-add_task(function* test_navigate_invalid_numbers() {
+add_task(function* test_navigate_large_number() {
   let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
   yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
-  yield* runURLBarSearchTest("123456789012345", true, false);
+  yield* runURLBarSearchTest({
+    valueToOpen: "123456789012345",
+    expectSearch: true,
+    expectNotification: false
+  });
   gBrowser.removeTab(tab);
 });
 function get_test_function_for_localhost_with_hostname(hostName, isPrivate) {
   return function* test_navigate_single_host() {
     const pref = "browser.fixup.domainwhitelist.localhost";
     let win;
     if (isPrivate) {
       win = yield promiseOpenAndLoadWindow({private: true}, true);
@@ -91,17 +103,22 @@ function get_test_function_for_localhost
     } else {
       win = window;
     }
     let browser = win.gBrowser;
     let tab = browser.selectedTab = browser.addTab("about:blank");
     yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
 
     Services.prefs.setBoolPref(pref, false);
-    yield* runURLBarSearchTest(hostName, true, true, win);
+    yield* runURLBarSearchTest({
+      valueToOpen: hostName,
+      expectSearch: true,
+      expectNotification: true,
+      aWindow: win,
+    });
 
     let notificationBox = browser.getNotificationBox(tab.linkedBrowser);
     let notification = notificationBox.getNotificationWithValue("keyword-uri-fixup");
     let docLoadPromise = waitForDocLoadAndStopIt("http://" + hostName + "/", tab.linkedBrowser);
     notification.querySelector(".notification-button-default").click();
 
     // check pref value
     let prefValue = Services.prefs.getBoolPref(pref);
@@ -109,17 +126,22 @@ function get_test_function_for_localhost
 
     yield docLoadPromise;
     browser.removeTab(tab);
 
     // Now try again with the pref set.
     tab = browser.selectedTab = browser.addTab("about:blank");
     yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
     // In a private window, the notification should appear again.
-    yield* runURLBarSearchTest(hostName, isPrivate, isPrivate, win);
+    yield* runURLBarSearchTest({
+      valueToOpen: hostName,
+      expectSearch: isPrivate,
+      expectNotification: isPrivate,
+      aWindow: win,
+    });
     browser.removeTab(tab);
     if (isPrivate) {
       info("Waiting for private window to close");
       yield promiseWindowClosed(win);
       let deferredFocus = Promise.defer();
       info("Waiting for focus");
       waitForFocus(deferredFocus.resolve, window);
       yield deferredFocus.promise;
@@ -129,11 +151,15 @@ function get_test_function_for_localhost
 
 add_task(get_test_function_for_localhost_with_hostname("localhost"));
 add_task(get_test_function_for_localhost_with_hostname("localhost."));
 add_task(get_test_function_for_localhost_with_hostname("localhost", true));
 
 add_task(function* test_navigate_invalid_url() {
   let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
   yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
-  yield* runURLBarSearchTest("mozilla is awesome", true, false);
+  yield* runURLBarSearchTest({
+    valueToOpen: "mozilla is awesome",
+    expectSearch: true,
+    expectNotification: false,
+  });
   gBrowser.removeTab(tab);
 });
--- a/browser/components/contextualidentity/test/browser/browser.ini
+++ b/browser/components/contextualidentity/test/browser/browser.ini
@@ -8,17 +8,19 @@ support-files =
   serviceworker.html
   worker.js
 
 [browser_aboutURLs.js]
 skip-if = (debug && (os == "win" || os == "linux")) # intermittent negative leak bug 1271182
 [browser_eme.js]
 [browser_favicon.js]
 [browser_forgetaboutsite.js]
-[browser_newtabButton.js]
+[browser_forgetAPI_cookie_getCookiesWithOriginAttributes.js]
+[browser_forgetAPI_EME_forgetThisSite.js]
+[browser_forgetAPI_quota_clearStoragesForPrincipal.js]
 [browser_usercontext.js]
 [browser_usercontextid_tabdrop.js]
 skip-if = os == "mac" || os == "win" # Intermittent failure - bug 1268276
 [browser_windowName.js]
 tags = openwindow
 [browser_windowOpen.js]
 tags = openwindow
 [browser_serviceworkers.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/contextualidentity/test/browser/browser_forgetAPI_EME_forgetThisSite.js
@@ -0,0 +1,218 @@
+/*
+ * Bug 1278037 - A Test case for checking whether forgetting APIs are working for the media key.
+ */
+
+const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
+
+const TEST_HOST = "example.com";
+const TEST_URL = "http://" + TEST_HOST + "/browser/browser/components/contextualidentity/test/browser/";
+
+const USER_CONTEXTS = [
+  "default",
+  "personal",
+];
+
+const TEST_EME_KEY = {
+  initDataType: 'keyids',
+  initData: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A"], "type":"persistent-license"}',
+  kid: "LwVHf8JLtPrv2GUXFW2v_A",
+  key: "97b9ddc459c8d5ff23c1f2754c95abe8",
+  sessionType: 'persistent-license',
+};
+
+//
+// Support functions.
+//
+
+function* openTabInUserContext(uri, userContextId) {
+  // Open the tab in the correct userContextId.
+  let tab = gBrowser.addTab(uri, {userContextId});
+
+  // Select tab and make sure its browser is focused.
+  gBrowser.selectedTab = tab;
+  tab.ownerGlobal.focus();
+
+  let browser = gBrowser.getBrowserForTab(tab);
+  yield BrowserTestUtils.browserLoaded(browser);
+  return {tab, browser};
+}
+
+function HexToBase64(hex) {
+  var bin = "";
+  for (var i = 0; i < hex.length; i += 2) {
+    bin += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
+  }
+  return window.btoa(bin).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
+}
+
+function Base64ToHex(str) {
+  var bin = window.atob(str.replace(/-/g, "+").replace(/_/g, "/"));
+  var res = "";
+  for (var i = 0; i < bin.length; i++) {
+    res += ("0" + bin.charCodeAt(i).toString(16)).substr(-2);
+  }
+  return res;
+}
+
+function ByteArrayToHex(array) {
+  let bin = String.fromCharCode.apply(null, new Uint8Array(array));
+  let res = "";
+
+  for (let i = 0; i < bin.length; i++) {
+    res += ("0" + bin.charCodeAt(i).toString(16)).substr(-2);
+  }
+
+  return res;
+}
+
+function generateKeyObject(aKid, aKey) {
+  let keyObj = {
+    kty: 'oct',
+    kid: aKid,
+    k: HexToBase64(aKey),
+  };
+
+  return new TextEncoder().encode(JSON.stringify({
+    keys: [keyObj]
+  }));
+}
+
+function generateKeyInfo(aData) {
+  let keyInfo = {
+    initDataType: aData.initDataType,
+    initData: new TextEncoder().encode(aData.initData),
+    sessionType: aData.sessionType,
+    keyObj: generateKeyObject(aData.kid, aData.key),
+  };
+
+  return keyInfo;
+}
+
+// Setup a EME key for the given browser, and return the sessionId.
+function* setupEMEKey(browser) {
+  // Generate the key info.
+  let keyInfo = generateKeyInfo(TEST_EME_KEY);
+
+  // Setup the EME key.
+  let result = yield ContentTask.spawn(browser, keyInfo, function* (aKeyInfo) {
+    let access = yield content.navigator.requestMediaKeySystemAccess('org.w3.clearkey',
+                                                                     [{
+                                                                       initDataTypes: [aKeyInfo.initDataType],
+                                                                       videoCapabilities: [{contentType: 'video/webm'}],
+                                                                       sessionTypes: ['persistent-license'],
+                                                                       persistentState: 'required',
+                                                                     }]);
+    let mediaKeys = yield access.createMediaKeys();
+    let session = mediaKeys.createSession(aKeyInfo.sessionType);
+    let res = {};
+
+    // Insert the EME key.
+    let result = yield new Promise(resolve => {
+      session.addEventListener("message", function(event) {
+        session.update(aKeyInfo.keyObj).then(
+          () => { resolve(); }
+        ).catch(
+          () => {
+            ok(false, "Update the EME key fail.");
+            resolve();
+          }
+        );
+      });
+
+      session.generateRequest(aKeyInfo.initDataType, aKeyInfo.initData);
+    });
+
+    let map = session.keyStatuses;
+
+    is(map.size, 1, "One EME key has been added.");
+
+    if (map.size === 1) {
+      res.keyId = map.keys().next().value;
+      res.sessionId = session.sessionId;
+    }
+
+    // Close the session.
+    session.close();
+    yield session.closed;
+
+    return res;
+  });
+
+  // Check the EME key ID.
+  is(ByteArrayToHex(result.keyId), Base64ToHex(TEST_EME_KEY.kid), "The key Id is correct.");
+  return result.sessionId;
+}
+
+// Check whether the EME key has been cleared.
+function* checkEMEKey(browser, emeSessionId) {
+  // Generate the key info.
+  let keyInfo = generateKeyInfo(TEST_EME_KEY);
+  keyInfo.sessionId = emeSessionId;
+
+  yield ContentTask.spawn(browser, keyInfo, function* (aKeyInfo) {
+    let access = yield content.navigator.requestMediaKeySystemAccess('org.w3.clearkey',
+                                                                     [{
+                                                                       initDataTypes: [aKeyInfo.initDataType],
+                                                                       videoCapabilities: [{contentType: 'video/webm'}],
+                                                                       sessionTypes: ['persistent-license'],
+                                                                       persistentState: 'required',
+                                                                     }]);
+    let mediaKeys = yield access.createMediaKeys();
+    let session = mediaKeys.createSession(aKeyInfo.sessionType);
+
+    // First, load the session with the sessionId.
+    yield session.load(aKeyInfo.sessionId);
+
+    let map = session.keyStatuses;
+
+    // Check that there is no media key here.
+    is(map.size, 0, "No media key should be here after forgetThisSite() was called.");
+  });
+}
+
+//
+// Test functions.
+//
+
+add_task(function* setup() {
+  // Make sure userContext is enabled.
+  yield SpecialPowers.pushPrefEnv({"set": [
+      [ "privacy.userContext.enabled", true ],
+      [ "media.mediasource.enabled", true ],
+      [ "media.eme.apiVisible", true ],
+      [ "media.mediasource.webm.enabled", true ],
+  ]});
+});
+
+add_task(function* test_EME_forgetThisSite() {
+  let tabs = [];
+  let emeSessionIds = [];
+
+  for (let userContextId of Object.keys(USER_CONTEXTS)) {
+    // Open our tab in the given user context.
+    tabs[userContextId] = yield* openTabInUserContext(TEST_URL+ "empty_file.html", userContextId);
+
+    // Setup EME Key.
+    emeSessionIds[userContextId] = yield setupEMEKey(tabs[userContextId].browser);
+
+    // Close this tab.
+    yield BrowserTestUtils.removeTab(tabs[userContextId].tab);
+  }
+
+  // Clear all EME data for a given domain with originAttributes pattern.
+  let mps = Cc["@mozilla.org/gecko-media-plugin-service;1"].
+               getService(Ci.mozIGeckoMediaPluginChromeService);
+  mps.forgetThisSite(TEST_HOST, JSON.stringify({}));
+
+  // Open tabs again to check EME keys have been cleared.
+  for (let userContextId of Object.keys(USER_CONTEXTS)) {
+    // Open our tab in the given user context.
+    tabs[userContextId] = yield* openTabInUserContext(TEST_URL+ "empty_file.html", userContextId);
+
+    // Check whether EME Key has been cleared.
+    yield checkEMEKey(tabs[userContextId].browser, emeSessionIds[userContextId]);
+
+    // Close this tab.
+    yield BrowserTestUtils.removeTab(tabs[userContextId].tab);
+  }
+});
new file mode 100644
--- /dev/null
+++ b/browser/components/contextualidentity/test/browser/browser_forgetAPI_cookie_getCookiesWithOriginAttributes.js
@@ -0,0 +1,86 @@
+/*
+ * Bug 1278037 - A Test case for checking whether forgetting APIs are working for cookies.
+ */
+
+const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
+
+const TEST_HOST = "example.com";
+const TEST_URL = "http://" + TEST_HOST + "/browser/browser/components/contextualidentity/test/browser/";
+
+const USER_CONTEXTS = [
+  "default",
+  "personal",
+];
+
+//
+// Support functions.
+//
+
+function* openTabInUserContext(uri, userContextId) {
+  // Open the tab in the correct userContextId.
+  let tab = gBrowser.addTab(uri, {userContextId});
+
+  // Select tab and make sure its browser is focused.
+  gBrowser.selectedTab = tab;
+  tab.ownerGlobal.focus();
+
+  let browser = gBrowser.getBrowserForTab(tab);
+  yield BrowserTestUtils.browserLoaded(browser);
+  return {tab, browser};
+}
+
+function getCookiesForOA(host, userContextId) {
+  return Services.cookies.getCookiesFromHost(host, {userContextId});
+}
+
+//
+// Test functions.
+//
+
+add_task(function* setup() {
+  // Make sure userContext is enabled.
+  yield SpecialPowers.pushPrefEnv({"set": [
+      [ "privacy.userContext.enabled", true ],
+  ]});
+});
+
+add_task(function* test_cookie_getCookiesWithOriginAttributes() {
+  let tabs = [];
+  let cookieName = "userContextId";
+
+  for (let userContextId of Object.keys(USER_CONTEXTS)) {
+    // Load the page in 2 different contexts and set a cookie
+    // which should only be visible in that context.
+    let value = USER_CONTEXTS[userContextId];
+
+    // Open our tab in the given user context.
+    tabs[userContextId] = yield* openTabInUserContext(TEST_URL+ "file_reflect_cookie_into_title.html?" + value, userContextId);
+
+    // Close this tab.
+    yield BrowserTestUtils.removeTab(tabs[userContextId].tab);
+  }
+
+  // Check that cookies have been set properly.
+  for (let userContextId of Object.keys(USER_CONTEXTS)) {
+    let enumerator = getCookiesForOA(TEST_HOST, userContextId);
+    ok(enumerator.hasMoreElements(), "Cookies available");
+
+    let foundCookie = enumerator.getNext().QueryInterface(Ci.nsICookie2);
+    is(foundCookie["name"], cookieName, "Check cookie name");
+    is(foundCookie["value"], USER_CONTEXTS[userContextId], "Check cookie value");
+  }
+
+  // Using getCookiesWithOriginAttributes() to get all cookies for a certain
+  // domain by using the originAttributes pattern, and clear all these cookies.
+  let enumerator = Services.cookies.getCookiesWithOriginAttributes(JSON.stringify({}), TEST_HOST);
+  while (enumerator.hasMoreElements()) {
+    let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie);
+    Services.cookies.remove(cookie.host, cookie.name, cookie.path, false, cookie.originAttributes);
+  }
+
+  // Check that whether cookies has been cleared.
+  for (let userContextId of Object.keys(USER_CONTEXTS)) {
+    let enumerator = getCookiesForOA(TEST_HOST, userContextId);
+    ok(!enumerator.hasMoreElements(), "No Cookie should be here");
+  }
+});
new file mode 100644
--- /dev/null
+++ b/browser/components/contextualidentity/test/browser/browser_forgetAPI_quota_clearStoragesForPrincipal.js
@@ -0,0 +1,148 @@
+/*
+ * Bug 1278037 - A Test case for checking whether forgetting APIs are working for the quota manager.
+ */
+
+const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
+
+const TEST_HOST = "example.com";
+const TEST_URL = "http://" + TEST_HOST + "/browser/browser/components/contextualidentity/test/browser/";
+
+const USER_CONTEXTS = [
+  "default",
+  "personal",
+];
+
+//
+// Support functions.
+//
+
+function* openTabInUserContext(uri, userContextId) {
+  // Open the tab in the correct userContextId.
+  let tab = gBrowser.addTab(uri, {userContextId});
+
+  // Select tab and make sure its browser is focused.
+  gBrowser.selectedTab = tab;
+  tab.ownerGlobal.focus();
+
+  let browser = gBrowser.getBrowserForTab(tab);
+  yield BrowserTestUtils.browserLoaded(browser);
+  return {tab, browser};
+}
+
+// Setup an entry for the indexedDB.
+function* setupIndexedDB(browser) {
+  yield ContentTask.spawn(browser, { input: "TestForgetAPIs" }, function* (arg) {
+    let request = content.indexedDB.open("idb", 1);
+
+    request.onerror = function() {
+      throw new Error("error opening db connection");
+    };
+
+    request.onupgradeneeded = event => {
+      let db = event.target.result;
+      let store = db.createObjectStore("obj", { keyPath: "id" });
+      store.createIndex("userContext", "userContext", { unique: false });
+    };
+
+    let db = yield new Promise(resolve => {
+      request.onsuccess = event => {
+        resolve(event.target.result);
+      };
+    });
+
+    // Add an entry into the indexedDB.
+    let transaction = db.transaction(["obj"], "readwrite");
+    let store = transaction.objectStore("obj");
+    store.add({id: 1, userContext: arg.input});
+
+    yield new Promise(resolve => {
+      transaction.oncomplete = () => {
+        resolve();
+      };
+    });
+
+    // Check the indexedDB has been set properly.
+    transaction = db.transaction(["obj"], "readonly");
+    store = transaction.objectStore("obj");
+    let getRequest = store.get(1);
+    yield new Promise(resolve => {
+      getRequest.onsuccess = () => {
+        let res = getRequest.result;
+        is(res.userContext, arg.input, "Check the indexedDB value");
+        resolve();
+      };
+    });
+  });
+}
+
+// Check whether the indexedDB has been cleared.
+function* checkIndexedDB(browser) {
+  yield ContentTask.spawn(browser, null, function* () {
+    let request = content.indexedDB.open("idb", 1);
+
+    let db = yield new Promise(done => {
+      request.onsuccess = event => {
+        done(event.target.result);
+      };
+    });
+
+    try {
+      let transaction = db.transaction(["obj"], "readonly");
+      ok(false, "The indexedDB should not exist");
+    } catch (e) {
+      is(e.name, "NotFoundError", "The indexedDB does not exist as expected");
+    }
+  });
+}
+
+//
+// Test functions.
+//
+
+add_task(function* setup() {
+  // Make sure userContext is enabled.
+  yield SpecialPowers.pushPrefEnv({"set": [
+      [ "privacy.userContext.enabled", true ],
+  ]});
+});
+
+add_task(function* test_quota_clearStoragesForPrincipal() {
+  let tabs = [];
+
+  for (let userContextId of Object.keys(USER_CONTEXTS)) {
+    // Open our tab in the given user context.
+    tabs[userContextId] = yield* openTabInUserContext(TEST_URL+ "empty_file.html", userContextId);
+
+    // Setup an entry for the indexedDB.
+    yield setupIndexedDB(tabs[userContextId].browser);
+
+    // Close this tab.
+    yield BrowserTestUtils.removeTab(tabs[userContextId].tab);
+  }
+
+  // Using quota manager to clear all indexed DB for a given domain.
+  let qms = Cc["@mozilla.org/dom/quota-manager-service;1"].
+              getService(Ci.nsIQuotaManagerService);
+
+  let caUtils = {};
+  let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
+                       getService(Ci.mozIJSSubScriptLoader);
+  scriptLoader.loadSubScript("chrome://global/content/contentAreaUtils.js",
+                             caUtils);
+  let httpURI = caUtils.makeURI("http://" + TEST_HOST);
+  let httpPrincipal = Services.scriptSecurityManager
+                              .createCodebasePrincipal(httpURI, {});
+  qms.clearStoragesForPrincipal(httpPrincipal, null, true);
+
+  for (let userContextId of Object.keys(USER_CONTEXTS)) {
+    // Open our tab in the given user context.
+    tabs[userContextId] = yield* openTabInUserContext(TEST_URL+ "empty_file.html", userContextId);
+
+    // Check whether indexed DB has been cleared.
+    yield checkIndexedDB(tabs[userContextId].browser);
+
+    // Close this tab.
+    yield BrowserTestUtils.removeTab(tabs[userContextId].tab);
+  }
+});
+
deleted file mode 100644
--- a/browser/components/contextualidentity/test/browser/browser_newtabButton.js
+++ /dev/null
@@ -1,34 +0,0 @@
-"use strict";
-
-// Testing that when the user opens the add tab menu and clicks menu items
-// the correct context id is opened
-
-add_task(function* test() {
-  yield SpecialPowers.pushPrefEnv({"set": [
-      ["privacy.userContext.enabled", true]
-  ]});
-
-  let newTab = document.getElementById('tabbrowser-tabs');
-  let newTabButton = document.getAnonymousElementByAttribute(newTab, "anonid", "tabs-newtab-button");
-  ok(newTabButton, "New tab button exists");
-  ok(!newTabButton.hidden, "New tab button is visible");
-  let popup = document.getAnonymousElementByAttribute(newTab, "anonid", "newtab-popup");
-
-  for (let i = 1; i <= 4; i++) {
-    let popupShownPromise = BrowserTestUtils.waitForEvent(popup, "popupshown");
-    EventUtils.synthesizeMouseAtCenter(newTabButton, {type: "mousedown"});
-
-    yield popupShownPromise;
-    let contextIdItem = popup.querySelector(`menuitem[usercontextid="${i}"]`);
-
-    ok(contextIdItem, `User context id ${i} exists`);
-
-    let waitForTabPromise = BrowserTestUtils.waitForNewTab(gBrowser);
-    EventUtils.synthesizeMouseAtCenter(contextIdItem, {});
-
-    let tab = yield waitForTabPromise;
-
-    is(tab.getAttribute('usercontextid'), i, `New tab has UCI equal ${i}`);
-    yield BrowserTestUtils.removeTab(tab);
-  }
-});
--- a/browser/components/extensions/schemas/history.json
+++ b/browser/components/extensions/schemas/history.json
@@ -86,29 +86,16 @@
             "type": "string",
             "description": "The visit ID of the referrer."
           },
           "transition": {
             "$ref": "TransitionType",
             "description": "The $(topic:transition-types)[transition type] for this visit from its referrer."
           }
         }
-      },
-      {
-        "id": "HistoryTime",
-        "description": "A time specified as a Date object, a number or string representing milliseconds since the epoch, or an ISO 8601 string",
-        "choices": [
-          {
-            "type": "string",
-            "pattern": "^[1-9]\\d*$"
-          },
-          {
-            "$ref": "extensionTypes.Date"
-          }
-        ]
       }
     ],
     "functions": [
       {
         "name": "search",
         "type": "function",
         "description": "Searches the history for the last visit time of each page matching the query.",
         "async": "callback",
@@ -117,22 +104,22 @@
             "name": "query",
             "type": "object",
             "properties": {
               "text": {
                 "type": "string",
                 "description": "A free-text query to the history service.  Leave empty to retrieve all pages."
               },
               "startTime": {
-                "$ref": "HistoryTime",
+                "$ref": "extensionTypes.Date",
                 "optional": true,
                 "description": "Limit results to those visited after this date. If not specified, this defaults to 24 hours in the past."
               },
               "endTime": {
-                "$ref": "HistoryTime",
+                "$ref": "extensionTypes.Date",
                 "optional": true,
                 "description": "Limit results to those visited before this date."
               },
               "maxResults": {
                 "type": "integer",
                 "optional": true,
                 "minimum": 1,
                 "description": "The maximum number of results to retrieve.  Defaults to 100."
@@ -205,17 +192,17 @@
                 "description": "The title of the page."
               },
               "transition": {
                 "$ref": "TransitionType",
                 "optional": true,
                 "description": "The $(topic:transition-types)[transition type] for this visit from its referrer."
               },
               "visitTime": {
-                "$ref": "HistoryTime",
+                "$ref": "extensionTypes.Date",
                 "optional": true,
                 "description": "The date when this visit occurred."
               }
             }
           },
           {
             "name": "callback",
             "type": "function",
@@ -254,21 +241,21 @@
         "description": "Removes all items within the specified date range from the history.  Pages will not be removed from the history unless all visits fall within the range.",
         "async": "callback",
         "parameters": [
           {
             "name": "range",
             "type": "object",
             "properties": {
               "startTime": {
-                "$ref": "HistoryTime",
+                "$ref": "extensionTypes.Date",
                 "description": "Items added to history after this date."
               },
               "endTime": {
-                "$ref": "HistoryTime",
+                "$ref": "extensionTypes.Date",
                 "description": "Items added to history before this date."
               }
             }
           },
           {
             "name": "callback",
             "type": "function",
             "parameters": []
--- a/browser/components/extensions/test/browser/browser.ini
+++ b/browser/components/extensions/test/browser/browser.ini
@@ -35,16 +35,17 @@ tags = webextensions
 [browser_ext_contextMenus_icons.js]
 [browser_ext_contextMenus_radioGroups.js]
 [browser_ext_contextMenus_uninstall.js]
 [browser_ext_contextMenus_urlPatterns.js]
 [browser_ext_currentWindow.js]
 [browser_ext_getViews.js]
 [browser_ext_incognito_popup.js]
 [browser_ext_lastError.js]
+[browser_ext_legacy_extension_context_contentscript.js]
 [browser_ext_optionsPage_privileges.js]
 [browser_ext_pageAction_context.js]
 [browser_ext_pageAction_popup.js]
 [browser_ext_pageAction_popup_resize.js]
 [browser_ext_pageAction_simple.js]
 [browser_ext_pageAction_title.js]
 [browser_ext_popup_api_injection.js]
 [browser_ext_popup_background.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_legacy_extension_context_contentscript.js
@@ -0,0 +1,171 @@
+"use strict";
+
+const {
+  LegacyExtensionContext,
+} = Cu.import("resource://gre/modules/LegacyExtensionsUtils.jsm", {});
+
+function promiseAddonStartup(extension) {
+  const {Management} = Cu.import("resource://gre/modules/Extension.jsm", {});
+
+  return new Promise((resolve) => {
+    let listener = (evt, extensionInstance) => {
+      Management.off("startup", listener);
+      resolve(extensionInstance);
+    };
+    Management.on("startup", listener);
+  });
+}
+
+/**
+ * This test case ensures that the LegacyExtensionContext can receive a connection
+ * from a content script and that the received port contains the expected sender
+ * tab info.
+ */
+add_task(function* test_legacy_extension_context_contentscript_connection() {
+  function backgroundScript() {
+    // Extract the assigned uuid from the background page url and send it
+    // in a test message.
+    let uuid = window.location.hostname;
+
+    browser.test.onMessage.addListener(msg => {
+      if (msg == "open-test-tab") {
+        browser.tabs.create({url: "http://example.com/"})
+          .then(tab => browser.test.sendMessage("get-expected-sender-info", {
+            uuid, tab,
+          }));
+      } else if (msg == "close-current-tab") {
+        browser.tabs.query({active: true})
+          .then(tabs => browser.tabs.remove(tabs[0].id))
+          .then(() => browser.test.sendMessage("current-tab-closed", true))
+          .catch(() => browser.test.sendMessage("current-tab-closed", false));
+      }
+    });
+
+    browser.test.sendMessage("ready");
+  }
+
+  function contentScript() {
+    browser.runtime.sendMessage("webextension -> legacy_extension message", (reply) => {
+      browser.test.assertEq("legacy_extension -> webextension reply", reply,
+                           "Got the expected reply from the LegacyExtensionContext");
+      browser.test.sendMessage("got-reply-message");
+    });
+
+    let port = browser.runtime.connect();
+
+    port.onMessage.addListener(msg => {
+      browser.test.assertEq("legacy_extension -> webextension port message", msg,
+                            "Got the expected message from the LegacyExtensionContext");
+      port.postMessage("webextension -> legacy_extension port message");
+    });
+  }
+
+  let extensionData = {
+    background: `new ${backgroundScript}`,
+    manifest: {
+      content_scripts: [
+        {
+          matches: ["http://example.com/*"],
+          js: ["content-script.js"],
+        },
+      ],
+    },
+    files: {
+      "content-script.js": `new ${contentScript}`,
+    },
+  };
+
+  let extension = ExtensionTestUtils.loadExtension(extensionData);
+
+  let waitForExtensionReady = extension.awaitMessage("ready");
+
+  let waitForExtensionInstance = promiseAddonStartup(extension);
+
+  extension.startup();
+
+  let extensionInstance = yield waitForExtensionInstance;
+
+  // Connect to the target extension.id as an external context
+  // using the given custom sender info.
+  let legacyContext = new LegacyExtensionContext(extensionInstance);
+
+  let waitConnectPort = new Promise(resolve => {
+    let {browser} = legacyContext.api;
+    browser.runtime.onConnect.addListener(port => {
+      resolve(port);
+    });
+  });
+
+  let waitMessage = new Promise(resolve => {
+    let {browser} = legacyContext.api;
+    browser.runtime.onMessage.addListener((singleMsg, msgSender, sendReply) => {
+      sendReply("legacy_extension -> webextension reply");
+      resolve({singleMsg, msgSender});
+    });
+  });
+
+  is(legacyContext.type, "legacy_extension",
+     "LegacyExtensionContext instance has the expected type");
+
+  ok(legacyContext.api, "Got the API object");
+
+  yield waitForExtensionReady;
+
+  extension.sendMessage("open-test-tab");
+
+  let {uuid, tab} = yield extension.awaitMessage("get-expected-sender-info");
+
+  let {singleMsg, msgSender} = yield waitMessage;
+  is(singleMsg, "webextension -> legacy_extension message",
+     "Got the expected message");
+  ok(msgSender, "Got a message sender object");
+
+  is(msgSender.id, uuid, "The sender has the expected id property");
+  is(msgSender.url, "http://example.com/", "The sender has the expected url property");
+  ok(msgSender.tab, "The sender has a tab property");
+  is(msgSender.tab.id, tab.id, "The port sender has the expected tab.id");
+
+  // Wait confirmation that the reply has been received.
+  yield extension.awaitMessage("got-reply-message");
+
+  let port = yield waitConnectPort;
+
+  ok(port, "Got the Port API object");
+  ok(port.sender, "The port has a sender property");
+
+  is(port.sender.id, uuid, "The port sender has an id property");
+  is(port.sender.url, "http://example.com/", "The port sender has the expected url property");
+  ok(port.sender.tab, "The port sender has a tab property");
+  is(port.sender.tab.id, tab.id, "The port sender has the expected tab.id");
+
+  let waitPortMessage = new Promise(resolve => {
+    port.onMessage.addListener((msg) => {
+      resolve(msg);
+    });
+  });
+
+  port.postMessage("legacy_extension -> webextension port message");
+
+  let msg = yield waitPortMessage;
+
+  is(msg, "webextension -> legacy_extension port message",
+     "LegacyExtensionContext received the expected message from the webextension");
+
+  let waitForDisconnect = new Promise(resolve => {
+    port.onDisconnect.addListener(resolve);
+  });
+
+  let waitForTestDone = extension.awaitMessage("current-tab-closed");
+
+  extension.sendMessage("close-current-tab");
+
+  yield waitForDisconnect;
+
+  info("Got the disconnect event on tab closed");
+
+  let success = yield waitForTestDone;
+
+  ok(success, "Test completed successfully");
+
+  yield extension.unload();
+});
--- a/browser/components/extensions/test/xpcshell/test_ext_history.js
+++ b/browser/components/extensions/test/xpcshell/test_ext_history.js
@@ -284,17 +284,16 @@ add_task(function* test_add_url() {
 
     browser.test.sendMessage("ready");
   }
 
   let addTestData = [
     [{}, "default"],
     [{visitTime: new Date()}, "with_date"],
     [{visitTime: Date.now()}, "with_ms_number"],
-    [{visitTime: Date.now().toString()}, "with_ms_string"],
     [{visitTime: new Date().toISOString()}, "with_iso_string"],
     [{transition: "typed"}, "valid_transition"],
   ];
 
   let failTestData = [
     [{transition: "generated"}, "an invalid transition", "|generated| is not a supported transition for history"],
     [{visitTime: Date.now() + 1000000}, "a future date", "cannot be a future date"],
     [{url: "about.config"}, "an invalid url", "about.config is not a valid URL"],
--- a/browser/components/migration/moz.build
+++ b/browser/components/migration/moz.build
@@ -1,16 +1,18 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
 
+MARIONETTE_UNIT_MANIFESTS += ['tests/marionette/manifest.ini']
+
 JAR_MANIFESTS += ['jar.mn']
 
 XPIDL_SOURCES += [
     'nsIBrowserProfileMigrator.idl',
 ]
 
 XPIDL_MODULE = 'migration'
 
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -750,16 +750,19 @@ BrowserGlue.prototype = {
     if (AppConstants.MOZ_CRASHREPORTER) {
       let dateLimit = new Date();
       dateLimit.setDate(dateLimit.getDate() - PENDING_CRASH_REPORT_DAYS);
       CrashSubmit.pendingIDsAsync(dateLimit).then(
         function onSuccess(ids) {
           let count = ids.length;
           if (count) {
             let win = RecentWindow.getMostRecentBrowserWindow();
+            if (!win) {
+              return;
+            }
             let nb =  win.document.getElementById("global-notificationbox");
             let notification = nb.getNotificationWithValue("pending-crash-reports");
             if (notification) {
               return;
             }
             let buttons = [
               {
                 label: win.gNavigatorBundle.getString("pendingCrashReports.submitAll"),
@@ -840,26 +843,44 @@ BrowserGlue.prototype = {
     } catch (e) { }
 
     let totalTime = (averageTime * samples) + currentTime;
     samples++;
     averageTime = totalTime / samples;
 
     if (samples >= Services.prefs.getIntPref("browser.slowStartup.maxSamples")) {
       if (averageTime > Services.prefs.getIntPref("browser.slowStartup.timeThreshold"))
-        this._showSlowStartupNotification();
+        this._calculateProfileAgeInDays().then(this._showSlowStartupNotification, null);
       averageTime = 0;
       samples = 0;
     }
 
     Services.prefs.setIntPref("browser.slowStartup.averageTime", averageTime);
     Services.prefs.setIntPref("browser.slowStartup.samples", samples);
   },
 
-  _showSlowStartupNotification: function () {
+  _calculateProfileAgeInDays: Task.async(function* () {
+    let ProfileAge = Cu.import("resource://gre/modules/ProfileAge.jsm", {}).ProfileAge;
+    let profileAge = new ProfileAge(null, null);
+
+    let creationDate = yield profileAge.created;
+    let resetDate = yield profileAge.reset;
+
+    // if the profile was reset, consider the
+    // reset date for its age.
+    let profileDate = resetDate || creationDate;
+
+    const ONE_DAY = 24 * 60 * 60 * 1000;
+    return (Date.now() - profileDate) / ONE_DAY;
+  }),
+
+  _showSlowStartupNotification: function (profileAge) {
+    if (profileAge < 90) // 3 months
+      return;
+
     let win = RecentWindow.getMostRecentBrowserWindow();
     if (!win)
       return;
 
     let productName = gBrandBundle.GetStringFromName("brandFullName");
     let message = win.gNavigatorBundle.getFormattedString("slowStartup.message", [productName]);
 
     let buttons = [
@@ -2609,55 +2630,16 @@ ContentPermissionPrompt.prototype = {
     }
 
     secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_GEOLOCATION_REQUEST);
 
     this._showPrompt(aRequest, message, "geo", actions, "geolocation",
                      "geo-notification-icon", options);
   },
 
-  _promptFlyWebPublishServer : function(aRequest) {
-    var message = "Would you like to let this site start a server accessible to nearby devices and people?";
-    var actions = [
-      {
-        stringId: "flyWebPublishServer.allowPublishServer",
-        action: Ci.nsIPermissionManager.ALLOW_ACTION,
-        expireType: Ci.nsIPermissionManager.EXPIRE_SESSION
-      },
-      {
-        stringId: "flyWebPublishServer.denyPublishServer",
-        action: Ci.nsIPermissionManager.DENY_ACTION,
-        expireType: Ci.nsIPermissionManager.EXPIRE_SESSION
-      }
-    ];
-
-    let options = {
-      learnMoreURL: "https://flyweb.github.io",
-      popupIconURL: "chrome://flyweb/skin/icon-64.png"
-    };
-
-    let browser = this._getBrowserForRequest(aRequest);
-    let chromeDoc = browser.ownerDocument;
-    let iconElem = chromeDoc.getElementById("flyweb-publish-server-notification-icon");
-    if (!iconElem) {
-      let notificationPopupBox = chromeDoc.getElementById("notification-popup-box");
-      let notificationIcon = chromeDoc.createElement("image");
-      notificationIcon.setAttribute("id", "flyweb-publish-server-notification-icon");
-      notificationIcon.setAttribute("src", "chrome://flyweb/skin/icon-64.png");
-      notificationIcon.setAttribute("class", "notification-anchor-icon flyweb-publish-server-icon");
-      notificationIcon.setAttribute("style", "filter: url(chrome://browser/skin/filters.svg#fill); fill: currentColor; opacity: .4;");
-      notificationIcon.setAttribute("role", "button");
-      notificationIcon.setAttribute("aria-label", "View the publish-server request");
-      notificationPopupBox.appendChild(notificationIcon);
-    }
-
-    this._showPrompt(aRequest, message, "flyweb-publish-server", actions, "flyweb-publish-server",
-                     "flyweb-publish-server-notification-icon", options);
-  },
-
   _promptWebNotifications : function(aRequest) {
     var message = gBrowserBundle.GetStringFromName("webNotifications.receiveFromSite");
 
     var actions;
 
     var browser = this._getBrowserForRequest(aRequest);
     // Only show "allow for session" in PB mode, we don't
     // support "allow for session" in non-PB mode.
@@ -2712,18 +2694,17 @@ ContentPermissionPrompt.prototype = {
     let types = request.types.QueryInterface(Ci.nsIArray);
     if (types.length != 1) {
       request.cancel();
       return;
     }
     let perm = types.queryElementAt(0, Ci.nsIContentPermissionType);
 
     const kFeatureKeys = { "geolocation" : "geo",
-                           "desktop-notification" : "desktop-notification",
-                           "flyweb-publish-server": "flyweb-publish-server"
+                           "desktop-notification" : "desktop-notification"
                          };
 
     // Make sure that we support the request.
     if (!(perm.type in kFeatureKeys)) {
       return;
     }
 
     var requestingPrincipal = request.principal;
@@ -2756,21 +2737,16 @@ ContentPermissionPrompt.prototype = {
     // Show the prompt.
     switch (perm.type) {
     case "geolocation":
       this._promptGeo(request);
       break;
     case "desktop-notification":
       this._promptWebNotifications(request);
       break;
-    case "flyweb-publish-server":
-      if (AppConstants.NIGHTLY_BUILD) {
-        this._promptFlyWebPublishServer(request);
-      }
-      break;
     }
   },
 
 };
 
 var DefaultBrowserCheck = {
   get OPTIONPOPUP() { return "defaultBrowserNotificationPopup" },
   _setAsDefaultTimer: null,
--- a/browser/components/originattributes/test/browser/browser.ini
+++ b/browser/components/originattributes/test/browser/browser.ini
@@ -1,10 +1,24 @@
 [DEFAULT]
 skip-if = buildapp == "mulet"
 tags = usercontextid firstpartyisolation originattributes
 support-files =
+  dummy.html
   file_firstPartyBasic.html
   head.js
+  test.js
+  test.js^headers^
+  test.html
+  test2.html
+  test2.js
+  test2.js^headers^
+  test_firstParty.html
+  test_firstParty_cookie.html
+  test_firstParty_html_redirect.html
+  test_firstParty_http_redirect.html
+  test_firstParty_http_redirect.html^headers^
+  test_firstParty_iframe_http_redirect.html
+  test_firstParty_postMessage.html
+  window.html
 
-[browser_dummy.js]
-skip-if = true
+[browser_firstPartyIsolation.js]
 [browser_localStorageIsolation.js]
deleted file mode 100644
--- a/browser/components/originattributes/test/browser/browser_dummy.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * This is a dummy test case which makes this could be built.
- * Should be removed after actual tests landed.
- */
-
-"use strict";
-
-add_task(function* () {
-  ok(true, "Make this test pass anyway.");
-});
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/browser_firstPartyIsolation.js
@@ -0,0 +1,174 @@
+const BASE_URL = "http://mochi.test:8888/browser/browser/components/originattributes/test/browser/";
+const BASE_DOMAIN = "mochi.test";
+
+add_task(function* setup() {
+  Services.prefs.setBoolPref("privacy.firstparty.isolate", true);
+  registerCleanupFunction(function () {
+    Services.prefs.clearUserPref("privacy.firstparty.isolate");
+  });
+});
+
+/**
+ * Test for the top-level document and child iframes should have the
+ * firstPartyDomain attribute.
+ */
+add_task(function* principal_test() {
+  let tab = gBrowser.addTab(BASE_URL + "test_firstParty.html");
+  yield BrowserTestUtils.browserLoaded(tab.linkedBrowser, true, function (url) {
+    return url == BASE_URL + "test_firstParty.html";
+  });
+
+  yield ContentTask.spawn(tab.linkedBrowser, { firstPartyDomain: BASE_DOMAIN }, function* (attrs) {
+    info("document principal: " + content.document.nodePrincipal.origin);
+    Assert.equal(docShell.getOriginAttributes().firstPartyDomain, "",
+                 "top-level docShell shouldn't have firstPartyDomain attribute.");
+    Assert.equal(content.document.nodePrincipal.originAttributes.firstPartyDomain,
+                 attrs.firstPartyDomain, "The document should have firstPartyDomain");
+
+    for (let i = 1; i < 4; i++) {
+      let iframe = content.document.getElementById("iframe" + i);
+      info("iframe principal: " + iframe.contentDocument.nodePrincipal.origin);
+      Assert.equal(iframe.frameLoader.docShell.getOriginAttributes().firstPartyDomain,
+                   attrs.firstPartyDomain, "iframe's docshell should have firstPartyDomain");
+      Assert.equal(iframe.contentDocument.nodePrincipal.originAttributes.firstPartyDomain,
+                   attrs.firstPartyDomain, "iframe should have firstPartyDomain");
+    }
+  });
+
+  gBrowser.removeTab(tab);
+});
+
+/**
+ * Test for the cookie jars of the top-level document and child iframe should be
+ * isolated by firstPartyDomain.
+ */
+add_task(function* cookie_test() {
+  let tab = gBrowser.addTab(BASE_URL + "test_firstParty_cookie.html");
+  yield BrowserTestUtils.browserLoaded(tab.linkedBrowser, true);
+
+  let iter = Services.cookies.enumerator;
+  let count = 0;
+  while (iter.hasMoreElements()) {
+    count++;
+    let cookie = iter.getNext().QueryInterface(Ci.nsICookie2);
+    Assert.equal(cookie.value, "foo", "Cookie value should be foo");
+    Assert.equal(cookie.originAttributes.firstPartyDomain, BASE_DOMAIN, "Cookie's origin attributes should be " + BASE_DOMAIN);
+  }
+
+  // one cookie is from requesting test.js from top-level doc, and the other from
+  // requesting test2.js from iframe test2.html.
+  Assert.equal(count, 2, "Should have two cookies");
+
+  gBrowser.removeTab(tab);
+});
+
+/**
+ * Test for after redirect, the top-level document should update the firstPartyDomain
+ * attribute. However if the redirect is happening on the iframe, the attribute
+ * should remain the same.
+ */
+add_task(function* redirect_test() {
+  let tab = gBrowser.addTab(BASE_URL + "test_firstParty_http_redirect.html");
+  yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+  yield ContentTask.spawn(tab.linkedBrowser, { firstPartyDomain: "example.com" }, function* (attrs) {
+    info("document principal: " + content.document.nodePrincipal.origin);
+    info("document uri: " + content.document.documentURI);
+
+    Assert.equal(content.document.documentURI, "http://example.com/browser/browser/components/originattributes/test/browser/dummy.html",
+                 "The page should have been redirected to http://example.com/browser/browser/components/originattributes/test/browser/dummy.html");
+    Assert.equal(content.document.nodePrincipal.originAttributes.firstPartyDomain,
+                 attrs.firstPartyDomain, "The document should have firstPartyDomain");
+  });
+
+  // Since this is a HTML redirect, we wait until the final page is loaded.
+  let tab2 = gBrowser.addTab(BASE_URL + "test_firstParty_html_redirect.html");
+  yield BrowserTestUtils.browserLoaded(tab2.linkedBrowser, false, function(url) {
+    return url == "http://example.com/";
+  });
+
+  yield ContentTask.spawn(tab2.linkedBrowser, { firstPartyDomain: "example.com" }, function* (attrs) {
+    info("2nd tab document principal: " + content.document.nodePrincipal.origin);
+    info("2nd tab document uri: " + content.document.documentURI);
+    Assert.equal(content.document.documentURI, "http://example.com/",
+                 "The page should have been redirected to http://example.com");
+    Assert.equal(content.document.nodePrincipal.originAttributes.firstPartyDomain,
+                 attrs.firstPartyDomain, "The document should have firstPartyDomain");
+  });
+
+  let tab3 = gBrowser.addTab(BASE_URL + "test_firstParty_iframe_http_redirect.html");
+  yield BrowserTestUtils.browserLoaded(tab3.linkedBrowser, true, function(url) {
+    return url == (BASE_URL + "test_firstParty_iframe_http_redirect.html");
+  });
+
+  // This redirect happens on the iframe, so unlike the two redirect tests above,
+  // the firstPartyDomain should still stick to the current top-level document,
+  // which is mochi.test.
+  yield ContentTask.spawn(tab3.linkedBrowser, { firstPartyDomain: "mochi.test" }, function* (attrs) {
+    let iframe = content.document.getElementById("iframe1");
+    info("iframe document principal: " + iframe.contentDocument.nodePrincipal.origin);
+    info("iframe document uri: " + iframe.contentDocument.documentURI);
+
+    Assert.equal(iframe.contentDocument.documentURI, "http://example.com/browser/browser/components/originattributes/test/browser/dummy.html",
+                 "The page should have been redirected to http://example.com/browser/browser/components/originattributes/test/browser/dummy.html");
+    Assert.equal(iframe.contentDocument.nodePrincipal.originAttributes.firstPartyDomain,
+                 attrs.firstPartyDomain, "The iframe should have firstPartyDomain: " + attrs.firstPartyDomain);
+  });
+
+  gBrowser.removeTab(tab);
+  gBrowser.removeTab(tab2);
+  gBrowser.removeTab(tab3);
+});
+
+/**
+ * Test for postMessage between document and iframe.
+ */
+add_task(function* postMessage_test() {
+  let tab = gBrowser.addTab(BASE_URL + "test_firstParty_postMessage.html");
+
+  // The top-level page will post a message to its child iframe, and wait for
+  // another message from the iframe, once it receives the message, it will
+  // create another iframe, dummy.html.
+  // So we wait until dummy.html is loaded
+  yield BrowserTestUtils.browserLoaded(tab.linkedBrowser, true, function (url) {
+    return url == BASE_URL + "dummy.html";
+  });
+
+  yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
+    info("document principal: " + content.document.nodePrincipal.origin);
+    let value = content.document.getElementById("message").textContent;
+    Assert.equal(value, "OK");
+  });
+
+  gBrowser.removeTab(tab);
+});
+
+/**
+ * When the web page calls window.open, the new window should have the same
+ * firstPartyDomain attribute.
+ */
+add_task(function* openWindow_test() {
+  Services.prefs.setIntPref("browser.link.open_newwindow", 2);
+  registerCleanupFunction(function () {
+    Services.prefs.clearUserPref("browser.link.open_newwindow");
+  });
+
+  let tab = gBrowser.addTab(BASE_URL + "window.html");
+  let win = yield BrowserTestUtils.waitForNewWindow();
+
+  yield ContentTask.spawn(win.gBrowser.selectedBrowser, { firstPartyDomain: "mochi.test" }, function* (attrs) {
+    Assert.equal(docShell.getOriginAttributes().firstPartyDomain, attrs.firstPartyDomain,
+                 "window.open() should have firstPartyDomain attribute");
+    Assert.equal(content.document.nodePrincipal.originAttributes.firstPartyDomain,
+                 attrs.firstPartyDomain, "The document should have firstPartyDomain");
+
+    let iframe = content.document.getElementById("iframe1");
+    Assert.equal(iframe.frameLoader.docShell.getOriginAttributes().firstPartyDomain,
+                 attrs.firstPartyDomain, "iframe's docshell should have firstPartyDomain");
+    Assert.equal(iframe.contentDocument.nodePrincipal.originAttributes.firstPartyDomain,
+                 attrs.firstPartyDomain, "iframe should have firstPartyDomain");
+  });
+
+  gBrowser.removeTab(tab);
+  yield BrowserTestUtils.closeWindow(win);
+});
+
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/dummy.html
@@ -0,0 +1,9 @@
+<html>
+<head>
+<title>Dummy test page</title>
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8"></meta>
+</head>
+<body>
+<p>Dummy test page</p>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/test.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 1260931</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script>
+  window.onmessage = function (evt) {
+    if (evt.data != "HI") {
+      return;
+    }
+
+    window.parent.postMessage("OK", "http://mochi.test:8888");
+  };
+
+  setTimeout(function() {
+    window.parent.postMessage("KO", "http://mochi.test:8888");
+  }, 1000);
+
+  </script>
+</head>
+<body>
+  Hello World.
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/test.js
@@ -0,0 +1,1 @@
+var i = 1;
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/test.js^headers^
@@ -0,0 +1,1 @@
+Set-Cookie: test=foo
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/test2.html
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 1260931</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script src="test2.js"></script>
+</head>
+<body>
+  Hello World.
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/test2.js
@@ -0,0 +1,1 @@
+var i = 1;
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/test2.js^headers^
@@ -0,0 +1,1 @@
+Set-Cookie: test2=foo
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/test_firstParty.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8"/>
+  <title>Test for Bug 1260931</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+  <div>
+    <iframe id="iframe1" src="http://example.com"></iframe>
+    <iframe id="iframe2" sandbox="" src="http://example.com"></iframe>
+    <iframe id="iframe3" sandbox="allow-same-origin" src="http://example.com"></iframe>
+  </div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/test_firstParty_cookie.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 1260931</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script src="test.js"></script>
+</head>
+<body>
+  Hello World.
+  <iframe id="iframe1" src="test2.html"></iframe>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/test_firstParty_html_redirect.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf8" http-equiv="refresh" content="0; url=http://example.com/"/>
+  <title>Test for Bug 1260931</title>
+</head>
+<body>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/test_firstParty_http_redirect.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8"/>
+  <title>Test for Bug 1260931</title>
+</head>
+<body>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/test_firstParty_http_redirect.html^headers^
@@ -0,0 +1,2 @@
+HTTP 302 Found
+Location: http://example.com/browser/browser/components/originattributes/test/browser/dummy.html
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/test_firstParty_iframe_http_redirect.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8"/>
+  <title>Test for Bug 1260931</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+  <div>
+    <iframe id="iframe1" src="test_firstParty_http_redirect.html"></iframe>
+  </div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/test_firstParty_postMessage.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8"/>
+  <title>Test for Bug 1260931</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<script>
+function onload() {
+  let iframe1 = document.getElementById("iframe1");
+  iframe1.contentWindow.postMessage("HI", "http://mochi.test:8888");
+}
+
+window.onmessage = function (evt) {
+  document.getElementById("message").textContent = evt.data;
+
+  let iframe2 = document.createElement("iframe");
+  iframe2.src = "dummy.html";
+  document.body.appendChild(iframe2);
+};
+</script>
+<body onload="onload()">
+  <div>
+    <iframe id="iframe1" src="test.html"></iframe>
+    <span id="message"></span>
+  </div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/window.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
+<html>
+  <head>
+    <meta charset="utf8">
+    <title>Page creating a popup</title>
+  </head>
+  <body>
+    <script type="text/javascript">
+       var w = window.open();
+       w.document.body.innerHTML = "<iframe id='iframe1' src='data:text/plain,test2'></iframe>";
+    </script>
+  </body>
+</html>
--- a/browser/components/preferences/in-content/advanced.js
+++ b/browser/components/preferences/in-content/advanced.js
@@ -606,35 +606,33 @@ var gAdvancedPane = {
                                    null, null, null, {});
     if (result != 0)
       return;
 
     // get the permission
     var pm = Components.classes["@mozilla.org/permissionmanager;1"]
                        .getService(Components.interfaces.nsIPermissionManager);
     var perm = pm.getPermissionObject(principal, "offline-app", true);
+    if (perm) {
+      // clear offline cache entries
+      try {
+        var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"].
+                           getService(Components.interfaces.nsIApplicationCacheService);
+        var groups = cacheService.getGroups();
+        for (var i = 0; i < groups.length; i++) {
+          var uri = Services.io.newURI(groups[i], null, null);
+          if (perm.matchesURI(uri, true)) {
+            var cache = cacheService.getActiveCache(groups[i]);
+            cache.discard();
+          }
+        }
+      } catch (e) {}
 
-    // clear offline cache entries
-    try {
-      var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"].
-                         getService(Components.interfaces.nsIApplicationCacheService);
-      var ios = Components.classes["@mozilla.org/network/io-service;1"].
-                getService(Components.interfaces.nsIIOService);
-      var groups = cacheService.getGroups();
-      for (var i = 0; i < groups.length; i++) {
-          var uri = ios.newURI(groups[i], null, null);
-          if (perm.matchesURI(uri, true)) {
-              var cache = cacheService.getActiveCache(groups[i]);
-              cache.discard();
-          }
-      }
-    } catch (e) {}
-
-    pm.removePermission(perm);
-
+      pm.removePermission(perm);
+    }
     list.removeChild(item);
     gAdvancedPane.offlineAppSelected();
     this.updateActualAppCacheSize();
   },
 
   // UPDATE TAB
 
   /*
--- a/browser/components/preferences/in-content/security.js
+++ b/browser/components/preferences/in-content/security.js
@@ -122,17 +122,30 @@ var gSecurityPane = {
   },
 
   /**
    * Displays a dialog in which the user can view and modify the list of sites
    * where passwords are never saved.
    */
   showPasswordExceptions: function ()
   {
-    gSubDialog.open("chrome://passwordmgr/content/passwordManagerExceptions.xul");
+    var bundlePrefs = document.getElementById("bundlePreferences");
+    var params = {
+      blockVisible: true,
+      sessionVisible: false,
+      allowVisible: false,
+      hideStatusColumn: true,
+      prefilledHost: "",
+      permissionType: "login-saving",
+      windowTitle: bundlePrefs.getString("savedLoginsExceptions_title"),
+      introText: bundlePrefs.getString("savedLoginsExceptions_desc")
+    };
+
+    gSubDialog.open("chrome://browser/content/preferences/permissions.xul",
+                    null, params);
   },
 
   /**
    * Initializes master password UI: the "use master password" checkbox, selects
    * the master password button to show, and enables/disables it as necessary.
    * The master password is controlled by various bits of NSS functionality, so
    * the UI for it can't be controlled by the normal preference bindings.
    */
--- a/browser/components/preferences/in-content/tests/browser_subdialogs.js
+++ b/browser/components/preferences/in-content/tests/browser_subdialogs.js
@@ -54,28 +54,29 @@ function* open_subdialog_and_test_generi
 function* close_subdialog_and_test_generic_end_state(browser, closingFn, closingButton, acceptCount, options) {
   let dialogclosingPromise = ContentTask.spawn(browser, {closingButton, acceptCount}, function*(expectations) {
     let win = content.window;
     let subdialog = win.gSubDialog;
     let frame = subdialog._frame;
     info("waiting for dialogclosing");
     let closingEvent =
       yield ContentTaskUtils.waitForEvent(frame.contentWindow, "dialogclosing");
+    let closingButton = closingEvent.detail.button;
     let actualAcceptCount = frame.contentWindow.arguments &&
                             frame.contentWindow.arguments[0].acceptCount;
 
     info("waiting for about:blank load");
     yield ContentTaskUtils.waitForEvent(frame, "load");
 
     Assert.notEqual(win.getComputedStyle(subdialog._overlay, "").visibility, "visible",
       "overlay is not visible");
     Assert.equal(frame.getAttribute("style"), "", "inline styles should be cleared");
     Assert.equal(frame.contentWindow.location.href.toString(), "about:blank",
       "sub-dialog should be unloaded");
-    Assert.equal(closingEvent.detail.button, expectations.closingButton,
+    Assert.equal(closingButton, expectations.closingButton,
       "closing event should indicate button was '" + expectations.closingButton + "'");
     Assert.equal(actualAcceptCount, expectations.acceptCount,
       "should be 1 if accepted, 0 if canceled, undefined if closed w/out button");
   });
 
   if (options && options.runClosingFnOutsideOfContentTask) {
     yield closingFn();
   } else {
--- a/browser/components/preferences/permissions.js
+++ b/browser/components/preferences/permissions.js
@@ -301,17 +301,17 @@ var gPermissionManager = {
           if (permission.matches(this._permissions[i].principal, true)) {
             this._permissions[i].capability = this._getCapabilityString(permission.capability);
             break;
           }
         }
         this._handleCapabilityChange();
       }
       else if (aData == "deleted") {
-        this._removePermissionFromList(permission);
+        this._removePermissionFromList(permission.principal);
       }
     }
   },
 
   onPermissionSelected: function ()
   {
     var hasSelection = this._tree.view.selection.count > 0;
     var hasRows = this._tree.view.rowCount > 0;
--- a/browser/components/preferences/permissions.xul
+++ b/browser/components/preferences/permissions.xul
@@ -1,16 +1,16 @@
 <?xml version="1.0"?>
 
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> 
-<?xml-stylesheet href="chrome://browser/skin/preferences/preferences.css" type="text/css"?> 
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://browser/skin/preferences/preferences.css" type="text/css"?>
 
 <!DOCTYPE dialog SYSTEM "chrome://browser/locale/preferences/permissions.dtd" >
 
 <window id="PermissionsDialog" class="windowDialog"
         windowtype="Browser:Permissions"
         title="&window.title;"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         style="width: &window.width;;"
@@ -29,17 +29,17 @@
     <key key="&windowClose.key;" modifiers="accel" oncommand="window.close();"/>
   </keyset>
 
   <vbox class="contentPane largeDialogContainer" flex="1">
     <description id="permissionsText" control="url"/>
     <separator class="thin"/>
     <label id="urlLabel" control="url" value="&address.label;" accesskey="&address.accesskey;"/>
     <hbox align="start">
-      <textbox id="url" flex="1" 
+      <textbox id="url" flex="1"
                oninput="gPermissionManager.onHostInput(event.target);"
                onkeypress="gPermissionManager.onHostKeyPress(event);"/>
     </hbox>
     <hbox pack="end">
       <button id="btnBlock" disabled="true" label="&block.label;" accesskey="&block.accesskey;"
               oncommand="gPermissionManager.addPermission(nsIPermissionManager.DENY_ACTION);"/>
       <button id="btnSession" disabled="true" label="&session.label;" accesskey="&session.accesskey;"
               oncommand="gPermissionManager.addPermission(nsICookiePermission.ACCESS_SESSION);"/>
@@ -64,17 +64,17 @@
   <vbox>
     <hbox class="actionButtons" align="left" flex="1">
       <button id="removePermission" disabled="true"
               accesskey="&removepermission.accesskey;"
               icon="remove" label="&removepermission.label;"
               oncommand="gPermissionManager.onPermissionDeleted();"/>
       <button id="removeAllPermissions"
               icon="clear" label="&removeallpermissions.label;"
-              accesskey="&removeallpermissions.accesskey;" 
+              accesskey="&removeallpermissions.accesskey;"
               oncommand="gPermissionManager.onAllPermissionsDeleted();"/>
     </hbox>
     <spacer flex="1"/>
     <hbox class="actionButtons" align="right" flex="1">
       <button oncommand="close();" icon="close"
               label="&button.cancel.label;" accesskey="&button.cancel.accesskey;" />
       <button id="btnApplyChanges" oncommand="gPermissionManager.onApplyChanges();" icon="save"
               label="&button.ok.label;" accesskey="&button.ok.accesskey;"/>
--- a/browser/components/search/test/browser.ini
+++ b/browser/components/search/test/browser.ini
@@ -18,18 +18,16 @@ support-files =
 [browser_addEngine.js]
 [browser_amazon.js]
 [browser_amazon_behavior.js]
 [browser_bing.js]
 [browser_bing_behavior.js]
 [browser_contextmenu.js]
 [browser_contextSearchTabPosition.js]
 skip-if = os == "mac" # bug 967013
-[browser_eBay.js]
-[browser_eBay_behavior.js]
 [browser_google.js]
 [browser_google_codes.js]
 [browser_google_behavior.js]
 [browser_healthreport.js]
 [browser_hiddenOneOffs_cleanup.js]
 [browser_hiddenOneOffs_diacritics.js]
 [browser_oneOffHeader.js]
 [browser_private_search_perwindowpb.js]
--- a/browser/components/search/test/browser_abouthome_behavior.js
+++ b/browser/components/search/test/browser_abouthome_behavior.js
@@ -70,23 +70,16 @@ function test() {
     {
       name: "Search with Yahoo from about:home",
       searchURL: replaceUrl("https://search.yahoo.com/search?p=foo&ei=UTF-8&fr=moz35"),
       run: function () {
         verify_about_home_search("Yahoo");
       }
     },
     {
-      name: "Search with eBay from about:home",
-      searchURL: replaceUrl("http://rover.ebay.com/rover/1/711-47294-18009-3/4?mfe=search&mpre=http://www.ebay.com/sch/i.html?_nkw=foo"),
-      run: function () {
-        verify_about_home_search("eBay");
-      }
-    },
-    {
       name: "Search with Google from about:home",
       searchURL: replaceUrl("https://www.google.com/search?q=foo&ie=utf-8&oe=utf-8"),
       run: function () {
         verify_about_home_search("Google");
       }
     },
     {
       name: "Search with Amazon.com from about:home",
deleted file mode 100644
--- a/browser/components/search/test/browser_eBay.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * Test eBay search plugin URLs
- */
-
-"use strict";
-
-const BROWSER_SEARCH_PREF = "browser.search.";
-
-function test() {
-  let engine = Services.search.getEngineByName("eBay");
-  ok(engine, "eBay");
-
-  let base = "http://rover.ebay.com/rover/1/711-47294-18009-3/4?mfe=search&mpre=http://www.ebay.com/sch/i.html?_nkw=foo";
-  let url;
-
-  // Test search URLs (including purposes).
-  url = engine.getSubmission("foo").uri.spec;
-  is(url, base, "Check search URL for 'foo'");
-
-  // Check search suggestion URL.
-  url = engine.getSubmission("foo", "application/x-suggestions+json").uri.spec;
-  is(url, "http://autosug.ebay.com/autosug?sId=0&kwd=foo&fmt=osr", "Check search suggestion URL for 'foo'");
-
-  // Check all other engine properties.
-  const EXPECTED_ENGINE = {
-    name: "eBay",
-    alias: null,
-    description: "eBay - Online auctions",
-    searchForm: "http://search.ebay.com/",
-    hidden: false,
-    wrappedJSObject: {
-      queryCharset: "ISO-8859-1",
-      "_iconURL": "data:image/x-icon;base64,AAABAAIAEBAAAAAAAAB6AQAAJgAAACAgAAAAAAAAQgMAAKABAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAFBSURBVDjLtZPdK0MBGIf3J5Babhx3rinFBWuipaUskX9DYvkopqgV90q5UJpyp0OKrUWM2VrRsS9D0zZKHGaOnW1nj4vtypVtPPe/533r9746QAAOAJXfo5Yzgg44pHrcugon/6Sgo0b+XuAOZ2iZiVQmyPoDpIwmUkYTzqM7GsdDdC7F6Lbf8pzOkfWOouzqeZem2b+2AqAV8zjD8yVBqqcf2b7C66yNiMGMfixIQSvi8Mp0LEbR5ADq1QSKWM+Gx0RC9nOZ2GLzwlIWdPWiuNzk4w/EpThNkyEAXKEP2ud8KGId2sspilhPMrmNwzfCuqePr/xbSfC5I/I0MMSj2YJ3z49gDdO2cEOrLUowJpE9G0QRG1ClKbR0EIdvmOPYcnUtnN+vsnZiQC1k/qnGagQ1n3LNzySUJZVskitnmr8BlQG7T2hvgxsAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAMJSURBVFjD7ZddSFNhGMeHXXQTZFFCWfR1pRhUECQlBdWVToo+6KYu1KigtDASG5qUfZgFZvahEDosECPDktKZS1FL+1DRnEvdUptjug91X2dnZzv/3vO6OZbWnR4v9sADL+fs7P97/s/znu2VAJD4UkpSSdKG+QubTyPBr+sXz8XCR64fIAHihVTis0SsUAoAVhEBrBKIHCGAEMB/ARi3F5LkbpS2WMRzYEEBXC2tsD6T03R9agsCGLNyqPw6CXmrBT06JvhbPHZwmkdwtR0B138PPKOHgzXD5jLAy3tmibo4K9weZwDAazJj/FQKRnfugfHMeRiTz0K3Ixam1HQKcPC+Fisu9NK1P08Uj4DleHgMdXC+WQ7nu3UEOhFMfTQcVUvQ1H4IN2sj8H2k7K+2TqCc3GseyA8AmDOzMBq7D9bS8sAr6nEJdNt3UbHVF1XQGtmZew8bTPT6tWoD3KpsUvlR8NxUoEICMvl6KQo+xqCwcRs4T8Ax5c8bFExjbAgAjO7aS8VsLypgq3g5nWStjztAhWRVhqAqeB6IuKTClkw1eNYEbrCQQBwD8yGGOsAooogLYejQPKBi7UPF9DkH+ezd+o141ZkUPAOC+L9SAMivNc7q46YMNSLTe4n1kaQF4XD3ZIDTPgU3XEYciKcAHrsGJS1xKFBGgyVzouiT4VbdGhjt/cEA5isyKsaz7jl3we7bg7Rqf6j0LoSldON4wWcqJDgQNGTN++l13vELA+MK6kKd6iryFOvxtidt9i5gO7owdjKJQliflNAU1pas6xQgnAzg1ux+lJEdILixNr0Pq9JUUA8NwVG9DM73G0jlcnh+V4BpjIWzJmIGQIjnXw5TiDuKSEwxurm3ITc8DNO51BnrLbIcsrW0dNA6RxgUKU1UdGVqLy5X6qGzTLvlnewiBZyGs3Yz6X8UeaYI3olvZDhzwLumZ+eHvooCCC0Q5VUsb4unwycM4YIDqA01tPqmgbzQr2EIYPECiPm33LYoDiZSsY9moh9O/Znoa4d9HkXtPg2pX/cPKCoRQ+ocZa4AAAAASUVORK5CYII=",
-      _urls : [
-        {
-          type: "application/x-suggestions+json",
-          method: "GET",
-          template: "http://autosug.ebay.com/autosug",
-          params: [
-            {
-              name: "sId",
-              value: "0",
-              purpose: undefined,
-            },
-            {
-              name: "kwd",
-              value: "{searchTerms}",
-              purpose: undefined,
-            },
-            {
-              name: "fmt",
-              value: "osr",
-              purpose: undefined,
-            },
-          ],
-        },
-        {
-          type: "text/html",
-          method: "GET",
-          template: "http://rover.ebay.com/rover/1/711-47294-18009-3/4",
-          params: [
-            {
-              name: "mfe",
-              value: "search",
-              purpose: undefined,
-            },
-            {
-              name: "mpre",
-              value: "http://www.ebay.com/sch/i.html?_nkw={searchTerms}",
-              purpose: undefined,
-            },
-          ],
-          mozparams: {},
-        },
-      ],
-    },
-  };
-
-  isSubObjectOf(EXPECTED_ENGINE, engine, "eBay");
-}
deleted file mode 100644
--- a/browser/components/search/test/browser_eBay_behavior.js
+++ /dev/null
@@ -1,166 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * Test eBay search plugin URLs
- */
-
-"use strict";
-
-const BROWSER_SEARCH_PREF = "browser.search.";
-
-
-function test() {
-  let engine = Services.search.getEngineByName("eBay");
-  ok(engine, "eBay is installed");
-
-  let previouslySelectedEngine = Services.search.currentEngine;
-  Services.search.currentEngine = engine;
-  engine.alias = 'e';
-
-  let base = "http://rover.ebay.com/rover/1/711-47294-18009-3/4?mfe=search&mpre=http://www.ebay.com/sch/i.html?_nkw=foo";
-  let url;
-
-  // Test search URLs (including purposes).
-  url = engine.getSubmission("foo").uri.spec;
-  is(url, base, "Check search URL for 'foo'");
-
-  waitForExplicitFinish();
-
-  var gCurrTest;
-  var gTests = [
-    {
-      name: "context menu search",
-      searchURL: base,
-      run: function () {
-        // Simulate a contextmenu search
-        // FIXME: This is a bit "low-level"...
-        BrowserSearch.loadSearch("foo", false, "contextmenu");
-      }
-    },
-    {
-      name: "keyword search",
-      searchURL: base,
-      run: function () {
-        gURLBar.value = "? foo";
-        gURLBar.focus();
-        EventUtils.synthesizeKey("VK_RETURN", {});
-      }
-    },
-    {
-      name: "keyword search",
-      searchURL: base,
-      run: function () {
-        gURLBar.value = "e foo";
-        gURLBar.focus();
-        EventUtils.synthesizeKey("VK_RETURN", {});
-      }
-    },
-    {
-      name: "search bar search",
-      searchURL: base,
-      run: function () {
-        let sb = BrowserSearch.searchBar;
-        sb.focus();
-        sb.value = "foo";
-        registerCleanupFunction(function () {
-          sb.value = "";
-        });
-        EventUtils.synthesizeKey("VK_RETURN", {});
-      }
-    },
-    {
-      name: "new tab search",
-      searchURL: base,
-      run: function () {
-        function doSearch(doc) {
-          // Re-add the listener, and perform a search
-          gBrowser.addProgressListener(listener);
-          doc.getElementById("newtab-search-text").value = "foo";
-          doc.getElementById("newtab-search-submit").click();
-        }
-
-        // load about:newtab, but remove the listener first so it doesn't
-        // get in the way
-        gBrowser.removeProgressListener(listener);
-        gBrowser.loadURI("about:newtab");
-        info("Waiting for about:newtab load");
-        tab.linkedBrowser.addEventListener("load", function load(event) {
-          if (event.originalTarget != tab.linkedBrowser.contentDocument ||
-              event.target.location.href == "about:blank") {
-            info("skipping spurious load event");
-            return;
-          }
-          tab.linkedBrowser.removeEventListener("load", load, true);
-
-          // Observe page setup
-          let win = gBrowser.contentWindow;
-          if (win.gSearch.currentEngineName ==
-              Services.search.currentEngine.name) {
-            doSearch(win.document);
-          }
-          else {
-            info("Waiting for newtab search init");
-            win.addEventListener("ContentSearchService", function done(event) {
-              info("Got newtab search event " + event.detail.type);
-              if (event.detail.type == "State") {
-                win.removeEventListener("ContentSearchService", done);
-                // Let gSearch respond to the event before continuing.
-                executeSoon(() => doSearch(win.document));
-              }
-            });
-          }
-        }, true);
-      }
-    }
-  ];
-
-  function nextTest() {
-    if (gTests.length) {
-      gCurrTest = gTests.shift();
-      info("Running : " + gCurrTest.name);
-      executeSoon(gCurrTest.run);
-    } else {
-      finish();
-    }
-  }
-
-  let tab = gBrowser.selectedTab = gBrowser.addTab();
-
-  let listener = {
-    onStateChange: function onStateChange(webProgress, req, flags, status) {
-      info("onStateChange");
-      // Only care about top-level document starts
-      let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
-                     Ci.nsIWebProgressListener.STATE_START;
-      if (!(flags & docStart) || !webProgress.isTopLevel)
-        return;
-
-      if (req.originalURI.spec == "about:blank")
-        return;
-
-      info("received document start");
-
-      ok(req instanceof Ci.nsIChannel, "req is a channel");
-      is(req.originalURI.spec, gCurrTest.searchURL, "search URL was loaded");
-      info("Actual URI: " + req.URI.spec);
-
-      req.cancel(Components.results.NS_ERROR_FAILURE);
-
-      executeSoon(nextTest);
-    }
-  }
-
-  registerCleanupFunction(function () {
-    engine.alias = undefined;
-    gBrowser.removeProgressListener(listener);
-    gBrowser.removeTab(tab);
-    Services.search.currentEngine = previouslySelectedEngine;
-  });
-
-  tab.linkedBrowser.addEventListener("load", function load() {
-    tab.linkedBrowser.removeEventListener("load", load, true);
-    gBrowser.addProgressListener(listener);
-    nextTest();
-  }, true);
-}
--- a/browser/config/tooltool-manifests/linux32/releng.manifest
+++ b/browser/config/tooltool-manifests/linux32/releng.manifest
@@ -11,27 +11,27 @@
 "size": 11189216,
 "digest": "18bc52b0599b1308b667e282abb45f47597bfc98a5140cfcab8da71dacf89dd76d0dee22a04ce26fe7ad1f04e2d6596991f9e5b01fd2aaaab5542965f596b0e6",
 "algorithm": "sha512",
 "filename": "gtk3.tar.xz",
 "setup": "setup.sh",
 "unpack": true
 },
 {
-"version": "gecko rustc 1.10.0 (cfcb716cf 2016-07-03)",
-"size": 102276708,
-"digest": "8cc9ea8347fc7e6e6fdb15a8fd1faae977f1235a426b879b3f9128ec91d8f2b6268297ce80bf4eceb47738bd40bfeda13f143dc3fe85f1434b13adfbc095ab90",
+"version": "gecko rustc 1.11.0 (9b21dcd6a 2016-08-15) x86_64+i586",
+"size": 99378568,
+"digest": "ea5ae0a37ab8c583ef3f9a97c45baf0644feed95f1e6191a4456fd42bbd45b218fe4bc528747a63af55ce67c4b6155bd50f312746628b30e41c421f4d54e5417",
 "algorithm": "sha512",
 "filename": "rustc.tar.xz",
 "unpack": true
 },
 {
-"version": "cargo 0.13.0-nightly (664125b 2016-07-19)",
-"size": 3123796,
-"digest": "4b9d2bcb8488b6649ba6c748e19d33bfceb25c7566e882fc7e00322392e424a5a9c5878c11c61d57cdaecf67bcc110842c6eff95e49736e8f3c83d9ce1677122",
+"version": "cargo 0.13.0-nightly (e713e7f 2016-08-31)",
+"size": 3245716,
+"digest": "d5bb0d88ce7bb1b5a316d7a8ca6341672f5ee8008fa7754511bf53fabd54c0770e95397232896d6087547891f1143f6968d8b1e106e39800b43defeb0025c7c0",
 "algorithm": "sha512",
 "filename": "cargo.tar.xz",
 "unpack": true
 },
 {
 "size": 167175,
 "digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
 "algorithm": "sha512",
--- a/browser/config/tooltool-manifests/linux64/hazard.manifest
+++ b/browser/config/tooltool-manifests/linux64/hazard.manifest
@@ -19,21 +19,22 @@
 "digest" : "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
 "unpack" : true,
 "setup" : "setup.sh",
 "algorithm" : "sha512",
 "filename" : "gtk3.tar.xz",
 "size" : 12072532
 },
 {
-"unpack" : true,
-"digest" : "5383d843c9f28abf0a6d254e9d975d96972d2c86d627ca836fa8e272a5d53230603b387d7d1499c49df7f84b1bb946946e800a85c88d968bdbe81c755fcb02e1",
-"filename" : "rustc.tar.xz",
-"algorithm" : "sha512",
-"size" : 89319524
+"version": "rustc 1.11.0 (9b21dcd6a 2016-08-15) repack",
+"size": 131489924,
+"digest": "59f7463a0da38f324daa4ffc2678d78afb4fe0df13248c1d215bcb996ec05e8521155563cde9a8b719a9b98c5feeaf97cc9e8d52c9b95f6b44728870d908d5b6",
+"algorithm": "sha512",
+"filename": "rustc.tar.xz",
+"unpack": true
 },
 {
 "filename" : "sccache.tar.bz2",
 "algorithm" : "sha512",
 "digest" : "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
 "unpack" : true,
 "size" : 167175
 }
--- a/browser/config/tooltool-manifests/linux64/releng.manifest
+++ b/browser/config/tooltool-manifests/linux64/releng.manifest
@@ -11,27 +11,27 @@
 "size": 12072532,
 "digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
 "algorithm": "sha512",
 "filename": "gtk3.tar.xz",
 "setup": "setup.sh",
 "unpack": true
 },
 {
-"version": "gecko rustc 1.10.0 (cfcb716cf 2016-07-03)",
-"size": 102276708,
-"digest": "8cc9ea8347fc7e6e6fdb15a8fd1faae977f1235a426b879b3f9128ec91d8f2b6268297ce80bf4eceb47738bd40bfeda13f143dc3fe85f1434b13adfbc095ab90",
+"version": "rustc 1.11.0 (9b21dcd6a 2016-08-15) repack",
+"size": 131489924,
+"digest": "59f7463a0da38f324daa4ffc2678d78afb4fe0df13248c1d215bcb996ec05e8521155563cde9a8b719a9b98c5feeaf97cc9e8d52c9b95f6b44728870d908d5b6",
 "algorithm": "sha512",
 "filename": "rustc.tar.xz",
 "unpack": true
 },
 {
-"version": "cargo 0.13.0-nightly (664125b 2016-07-19)",
-"size": 3123796,
-"digest": "4b9d2bcb8488b6649ba6c748e19d33bfceb25c7566e882fc7e00322392e424a5a9c5878c11c61d57cdaecf67bcc110842c6eff95e49736e8f3c83d9ce1677122",
+"version": "cargo 0.13.0-nightly (e713e7f 2016-08-31)",
+"size": 3245716,
+"digest": "d5bb0d88ce7bb1b5a316d7a8ca6341672f5ee8008fa7754511bf53fabd54c0770e95397232896d6087547891f1143f6968d8b1e106e39800b43defeb0025c7c0",
 "algorithm": "sha512",
 "filename": "cargo.tar.xz",
 "unpack": true
 },
 {
 "size": 167175,
 "digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
 "algorithm": "sha512",
--- a/browser/config/tooltool-manifests/macosx64/cross-releng.manifest
+++ b/browser/config/tooltool-manifests/macosx64/cross-releng.manifest
@@ -19,19 +19,19 @@
 "size": 35215976, 
 "visibility": "internal", 
 "digest": "8be736545ddab25ebded188458ce974d5c9a7e29f3c50d2ebfbcb878f6aff853dd2ff5a3528bdefc64396a10101a1b50fd2fe52000140df33643cebe1ea759da", 
 "algorithm": "sha512", 
 "unpack": true,
 "filename": "MacOSX10.7.sdk.tar.bz2"
 },
 {
-"version": "cargo 0.13.0-nightly (664125b 2016-07-19)",
-"size": 3123796,
-"digest": "4b9d2bcb8488b6649ba6c748e19d33bfceb25c7566e882fc7e00322392e424a5a9c5878c11c61d57cdaecf67bcc110842c6eff95e49736e8f3c83d9ce1677122",
+"version": "cargo 0.13.0-nightly (e713e7f 2016-08-31)",
+"size": 3245716,
+"digest": "d5bb0d88ce7bb1b5a316d7a8ca6341672f5ee8008fa7754511bf53fabd54c0770e95397232896d6087547891f1143f6968d8b1e106e39800b43defeb0025c7c0",
 "algorithm": "sha512",
 "filename": "cargo.tar.xz",
 "unpack": true
 },
 {
 "size": 167175,
 "digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
 "algorithm": "sha512",
@@ -50,24 +50,16 @@
 "size": 188880, 
 "visibility": "public", 
 "digest": "1ffddd43efb03aed897ee42035d9d8d758a8d66ab6c867599ef755e1a586768fc22011ce03698af61454920b00fe8bed08c9a681e7bd324d7f8f78c026c83943", 
 "algorithm": "sha512", 
 "unpack": true,
 "filename": "genisoimage.tar.xz"
 },
 {
-"version": "gecko rustc 1.10.0 (cfcb716cf 2016-07-03)",
-"size": 102276708,
-"digest": "8cc9ea8347fc7e6e6fdb15a8fd1faae977f1235a426b879b3f9128ec91d8f2b6268297ce80bf4eceb47738bd40bfeda13f143dc3fe85f1434b13adfbc095ab90",
+"version": "rustc 1.11.0 (9b21dcd6a 2016-08-15) repack",
+"size": 171059204,
+"digest": "7554ac993f55818827c80dab90135209e57db70c7c9131bef4309aff3b8d7452c4c0de663df7e8c46bd5702455c36292ade6c7a8007e567c4588c7f91aa88b57",
 "algorithm": "sha512",
 "filename": "rustc.tar.xz",
 "unpack": true
-},
-{
-"size": 53754194,
-"visibility": "public",
-"digest": "d861a8c857e5cbc98318951b009c82cd88cbf151f1f5ad83d140e5e662b92c1ae1250c71c5d4cd29ebbcb4efa360a2ed4a6eb4db6281ecfb313038b5487eb1d2",
-"algorithm": "sha512",
-"filename": "rust-std-lib-x86_64-apple-darwin.tar.bz2",
-"unpack": true
 }
 ]
--- a/browser/config/tooltool-manifests/macosx64/releng.manifest
+++ b/browser/config/tooltool-manifests/macosx64/releng.manifest
@@ -3,27 +3,27 @@
 "version": "clang 3.8.0",
 "size": 133060926,
 "digest": "aff5ad3ac2d41db19d1ba0df5f97b189a7d7e1b6af8c56e22c2b0cced84d75fa98394ded6a4ba5713652e6684a0a46f47aeccf87991f9e849bf8d7d82e564f6f",
 "algorithm": "sha512",
 "filename": "clang.tar.bz2",
 "unpack": true
 },
 {
-"version": "rust 1.10 repack",
-"size": 150726627,
-"digest": "a30476113212895a837b2c4c18eb34d767c7192c3e327fba84c0138eaf7e671e84d5294e75370af3fe7e527a61e0938cd6cce20fba0aec94537070eb0094e27e",
+"version": "rustc 1.11.0 (9b21dcd6a 2016-08-15) repack",
+"size": 146060042,
+"digest": "c7c5556af0dea1f97a737e4634496d407a5e0f7d14a7013746ad41ef188bab03be60cea59ed63d733dcb03bf11b05d8bf637dc0261f15cd5b0ab46d1199243cf",
 "algorithm": "sha512",
 "filename": "rustc.tar.bz2",
 "unpack": true
 },
 {
-"version": "cargo 0.13.0-nightly (664125b 2016-07-19)",
-"size": 2571167,
-"digest": "b2616459fbf15c75b54628a6bfe8cf89c0841ea08431f5096e72be4fac4c685785dfc7a2f18a03a5f7bd377e78d3c108e5029b12616842cbbd0497ff7363fdaf",
+"version": "cargo 0.13.0-nightly (e713e7f 2016-08-31)",
+"size": 2715131,
+"digest": "f037d2bbbeccb2c95519e083d6d9eecb5cb06a510e849b5721d6933a6c2428203b93ed3d20d3f20329f4d4eee17177d762f051b1ae79fee97d93b84611f3df66",
 "algorithm": "sha512",
 "filename": "cargo.tar.bz2",
 "unpack": true
 },
 {
 "version": "cctools port from commit hash db1f8d906cb28, ld only",
 "size": 634496,
 "digest": "037f31fcf29e7bb7fada0d2bdd5e95c7d4cb2692f2a5c98ed6f6a7561b9d81622d015f0d12b291d3667719655f1369e8ce8a0a4a4773aa0ee4753e04a8821173",
--- a/browser/config/tooltool-manifests/win32/clang.manifest
+++ b/browser/config/tooltool-manifests/win32/clang.manifest
@@ -1,20 +1,21 @@
 [
 {
 "size": 266240,
 "digest": "bb345b0e700ffab4d09436981f14b5de84da55a3f18a7f09ebc4364a4488acdeab8d46f447b12ac70f2da1444a68b8ce8b8675f0dae2ccf845e966d1df0f0869",
 "algorithm": "sha512",
 "filename": "mozmake.exe"
 },
 {
-"size": 78886322,
-"digest": "9c2c40637de27a0852aa1166f2a08159908b23f7a55855c933087c541461bbb2a1ec9e0522df0d2b9da2b2c343b673dbb5a2fa8d30216fe8acee1eb1383336ea",
+"version": "rustc 1.11.0 (9b21dcd6a 2016-08-15) repack",
+"size": 86199150,
+"digest": "fec209dc85a098817c892655fbfda2bd6961199b1c28422994a50daddcb219608673b87dde30b3380555400cf4484863a12d431a6a25ef01cb9b1b32bef48f8b",
 "algorithm": "sha512",
-"filename": "rustc-beta-i686-pc-windows-msvc.tar.bz2",
+"filename": "rustc.tar.bz2",
 "unpack": true
 },
 {
 "size": 167175,
 "digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
 "algorithm": "sha512",
 "filename": "sccache.tar.bz2",
 "unpack": true
--- a/browser/config/tooltool-manifests/win32/releng.manifest
+++ b/browser/config/tooltool-manifests/win32/releng.manifest
@@ -1,27 +1,27 @@
 [
 {
 "size": 266240,
 "digest": "bb345b0e700ffab4d09436981f14b5de84da55a3f18a7f09ebc4364a4488acdeab8d46f447b12ac70f2da1444a68b8ce8b8675f0dae2ccf845e966d1df0f0869",
 "algorithm": "sha512",
 "filename": "mozmake.exe"
 },
 {
-"version": "rustc 1.10.0 (cfcb716cf 2016-07-03)",
-"size": 88820579,
-"digest": "3bc772d951bf90b01cdba9dcd0e1d131a98519dff0710bb219784ea43d4d001dbce191071a4b3824933386bb9613f173760c438939eb396b0e0dfdad9a42e4f0",
+"version": "rustc 1.11.0 (9b21dcd6a 2016-08-15) repack",
+"size": 86199150,
+"digest": "fec209dc85a098817c892655fbfda2bd6961199b1c28422994a50daddcb219608673b87dde30b3380555400cf4484863a12d431a6a25ef01cb9b1b32bef48f8b",
 "algorithm": "sha512",
 "filename": "rustc.tar.bz2",
 "unpack": true
 },
 {
-"version": "cargo 0.13.0-nightly (664125b 2016-07-19)",
-"size": 2298848,
-"digest": "d3d1f7b6d195248550f98eb8ce87aa314d36a8a667c110ff2058777fe5a97b7007a41dc1c8a4605c4230e9105972768918222352d5e0fdebbc49639671de38ca",
+"version": "cargo 0.13.0-nightly (e713e7f 2016-08-31)",
+"size": 2402000,
+"digest": "56f12f7ac437742ed717ce0ccfb0b4134160948e45d73016e48d9033567e5b01a171ac95dd7965eb007702c31da73274b5913281655f461f611ddeee37181ecc",
 "algorithm": "sha512",
 "filename": "cargo.tar.bz2",
 "unpack": true
 },
 {
 "size": 167175,
 "digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
 "algorithm": "sha512",
--- a/browser/config/tooltool-manifests/win64/clang.manifest
+++ b/browser/config/tooltool-manifests/win64/clang.manifest
@@ -1,18 +1,19 @@
 [
 {
 "size": 266240,
 "digest": "bb345b0e700ffab4d09436981f14b5de84da55a3f18a7f09ebc4364a4488acdeab8d46f447b12ac70f2da1444a68b8ce8b8675f0dae2ccf845e966d1df0f0869",
 "algorithm": "sha512",
 "filename": "mozmake.exe"
 },
 {
-"size": 80157273,
-"digest": "c4704dcc6774b9f3baaa9313192d26e36bfba2d4380d0518ee7cb89153d9adfe63f228f0ac29848f02948eb1ab7e6624ba71210f0121196d2b54ecebd640d1e6",
+"version": "rustc 1.11.0 (9b21dcd6a 2016-08-15) repack",
+"size": 91329933,
+"digest": "db97f0186db432c57698e287798940abb5946c8903f990b087ea977fb938e83f2f9ca1bf90377bc575563af3144d429cc897a36750a1978a288a42b132c3d25d",
 "algorithm": "sha512",
 "visibility": "public",
 "filename": "rustc.tar.bz2",
 "unpack": true
 },
 {
 "size": 167175,
 "digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
--- a/browser/config/tooltool-manifests/win64/releng.manifest
+++ b/browser/config/tooltool-manifests/win64/releng.manifest
@@ -1,28 +1,28 @@
 [
 {
 "size": 266240,
 "digest": "bb345b0e700ffab4d09436981f14b5de84da55a3f18a7f09ebc4364a4488acdeab8d46f447b12ac70f2da1444a68b8ce8b8675f0dae2ccf845e966d1df0f0869",
 "algorithm": "sha512",
 "filename": "mozmake.exe"
 },
 {
-"version": "rustc 1.10.0 (cfcb716cf 2016-07-03)",
-"size": 94067220,
-"digest": "05cabda2a28ce6674f062aab589b4b3758e0cd4a4af364bb9a2e736254baa10d668936b2b7ed0df530c7f5ba8ea1e7f51ff3affc84a6551c46188b2f67f10e05",
+"version": "rustc 1.11.0 (9b21dcd6a 2016-08-15) repack",
+"size": 91329933,
+"digest": "db97f0186db432c57698e287798940abb5946c8903f990b087ea977fb938e83f2f9ca1bf90377bc575563af3144d429cc897a36750a1978a288a42b132c3d25d",
 "algorithm": "sha512",
 "visibility": "public",
 "filename": "rustc.tar.bz2",
 "unpack": true
 },
 {
-"version": "cargo 0.13.0-nightly (664125b 2016-07-19)",
-"size": 2561498,
-"digest": "d300fd06b16efe49bdb1a238d516c8797d2de0edca7efadd55249401e1dd1d775fb84649630e273f95d9e8b956d87d1f75726c0a68294d25fafe078c3b2b9ba9",
+"version": "cargo 0.13.0-nightly (e713e7f 2016-08-31)",
+"size": 2677831,
+"digest": "eada1edd6142dcde907f14f23c08a2a0b86f108a8fb242f62be6573bbbe1d3b2a4a04c05465d561253d6a617e18cdabee3c87d8cef9a1b5bdd20fe835ef25ff1",
 "algorithm": "sha512",
 "filename": "cargo.tar.bz2",
 "unpack": true
 },
 {
 "size": 167175,
 "digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
 "algorithm": "sha512",
--- a/browser/extensions/e10srollout/bootstrap.js
+++ b/browser/extensions/e10srollout/bootstrap.js
@@ -12,17 +12,18 @@ Cu.import("resource://gre/modules/Update
 
  // The amount of people to be part of e10s
 const TEST_THRESHOLD = {
   "beta"    : 0.5,  // 50%
   "release" : 1.0,  // 100%
 };
 
 const ADDON_ROLLOUT_POLICY = {
-  "beta"    : "2a", // Set 2 + any WebExtension
+  "beta"    : "49a", // 10 tested add-ons + any WebExtension
+  "release" : "49a", // 10 tested add-ons + any WebExtension
 };
 
 const PREF_COHORT_SAMPLE       = "e10s.rollout.cohortSample";
 const PREF_COHORT_NAME         = "e10s.rollout.cohort";
 const PREF_E10S_OPTED_IN       = "browser.tabs.remote.autostart";
 const PREF_E10S_FORCE_ENABLED  = "browser.tabs.remote.force-enable";
 const PREF_E10S_FORCE_DISABLED = "browser.tabs.remote.force-disable";
 const PREF_TOGGLE_E10S         = "browser.tabs.remote.autostart.2";
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -136,23 +136,16 @@
 @BINPATH@/@DLL_PREFIX@mozavcodec@DLL_SUFFIX@
 #endif
 @RESPATH@/browser/blocklist.xml
 #ifdef XP_UNIX
 #ifndef XP_MACOSX
 @RESPATH@/run-mozilla.sh
 #endif
 #endif
-#ifdef XP_WIN
-#ifdef _AMD64_
-@BINPATH@/@DLL_PREFIX@qipcap64@DLL_SUFFIX@
-#else
-@BINPATH@/@DLL_PREFIX@qipcap@DLL_SUFFIX@
-#endif
-#endif
 
 ; [Components]
 #ifdef MOZ_ARTIFACT_BUILDS
 @RESPATH@/components/prebuilt-interfaces.manifest
 @RESPATH@/components/interfaces.xpt
 @RESPATH@/browser/components/prebuilt-interfaces.manifest
 @RESPATH@/browser/components/interfaces.xpt
 #endif
@@ -192,17 +185,16 @@
 @RESPATH@/components/dom_apps.xpt
 @RESPATH@/components/dom_newapps.xpt
 @RESPATH@/components/dom_base.xpt
 @RESPATH@/components/dom_system.xpt
 #ifdef MOZ_B2G_BT
 @RESPATH@/components/dom_bluetooth.xpt
 #endif
 @RESPATH@/components/dom_canvas.xpt
-@RESPATH@/components/dom_alarm.xpt
 @RESPATH@/components/dom_core.xpt
 @RESPATH@/components/dom_css.xpt
 @RESPATH@/components/dom_events.xpt
 @RESPATH@/components/dom_geolocation.xpt
 @RESPATH@/components/dom_media.xpt
 @RESPATH@/components/dom_network.xpt
 @RESPATH@/components/dom_notification.xpt
 @RESPATH@/components/dom_html.xpt
@@ -266,16 +258,19 @@
 @RESPATH@/components/locale.xpt
 @RESPATH@/components/lwbrk.xpt
 #ifdef MOZ_ENABLE_PROFILER_SPS
 @RESPATH@/components/memory_profiler.xpt
 #endif
 @RESPATH@/browser/components/migration.xpt
 @RESPATH@/components/mimetype.xpt
 @RESPATH@/components/mozfind.xpt
+#ifdef ENABLE_INTL_API
+@RESPATH@/components/mozintl.xpt
+#endif
 @RESPATH@/components/necko_about.xpt
 @RESPATH@/components/necko_cache.xpt
 @RESPATH@/components/necko_cache2.xpt
 @RESPATH@/components/necko_cookie.xpt
 @RESPATH@/components/necko_dns.xpt
 @RESPATH@/components/necko_file.xpt
 @RESPATH@/components/necko_ftp.xpt
 @RESPATH@/components/necko_http.xpt
@@ -530,18 +525,16 @@
 @RESPATH@/components/PermissionSettings.js
 @RESPATH@/components/PermissionSettings.manifest
 @RESPATH@/components/ContactManager.js
 @RESPATH@/components/ContactManager.manifest
 @RESPATH@/components/PhoneNumberService.js
 @RESPATH@/components/PhoneNumberService.manifest
 @RESPATH@/components/NotificationStorage.js
 @RESPATH@/components/NotificationStorage.manifest
-@RESPATH@/components/AlarmsManager.js
-@RESPATH@/components/AlarmsManager.manifest
 @RESPATH@/components/Push.js
 @RESPATH@/components/Push.manifest
 @RESPATH@/components/PushComponents.js
 
 @RESPATH@/components/remotebrowserutils.manifest
 @RESPATH@/components/RemoteWebNavigation.js
 
 @RESPATH@/components/SlowScriptDebug.manifest
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -201,37 +201,41 @@ These should match what Safari and other
 <!ENTITY stopCmd.label                "Stop">
 <!ENTITY stopCmd.macCommandKey        ".">
 <!ENTITY stopButton.tooltip           "Stop loading this page">
 <!ENTITY goEndCap.tooltip             "Go to the address in the Location Bar">
 <!ENTITY printButton.label            "Print">
 <!ENTITY printButton.tooltip          "Print this page">
 
 <!ENTITY urlbar.viewSiteInfo.label                      "View site information">
-<!-- LOCALIZATION NOTE: all of the following urlbar NotificationAnchor.label strings are
-     used to provide accessible labels to users of assistive technology like screenreaders.
-     It is not possible to see them visually in the UI. -->
-<!ENTITY urlbar.defaultNotificationAnchor.label         "View a notification">
-<!ENTITY urlbar.geolocationNotificationAnchor.label     "View the location request">
-<!ENTITY urlbar.addonsNotificationAnchor.label          "View the add-on install message">
-<!ENTITY urlbar.indexedDBNotificationAnchor.label       "View the app-offline storage message">
-<!ENTITY urlbar.loginFillNotificationAnchor.label       "Manage your login information">
-<!ENTITY urlbar.passwordNotificationAnchor.label        "Check if you want to save your password">
-<!ENTITY urlbar.pluginsNotificationAnchor.label         "Manage plugin usage on this page">
-<!ENTITY urlbar.webNotsNotificationAnchor3.label        "Change whether you can receive notifications from the site">
+
+<!ENTITY urlbar.defaultNotificationAnchor.tooltip         "Open message panel">
+<!ENTITY urlbar.geolocationNotificationAnchor.tooltip     "Open location request panel">
+<!ENTITY urlbar.addonsNotificationAnchor.tooltip          "Open add-on installation message panel">
+<!ENTITY urlbar.indexedDBNotificationAnchor.tooltip       "Open offline storage message panel">
+<!ENTITY urlbar.loginFillNotificationAnchor.tooltip       "Manage your login information">
+<!ENTITY urlbar.passwordNotificationAnchor.tooltip        "Open save password message panel">
+<!ENTITY urlbar.pluginsNotificationAnchor.tooltip         "Manage plug-in use">
+<!ENTITY urlbar.webNotificationAnchor.tooltip             "Change whether you can receive notifications from the site">
 
-<!ENTITY urlbar.webRTCShareDevicesNotificationAnchor.label      "Manage sharing your camera and/or microphone with the site">
-<!ENTITY urlbar.webRTCShareMicrophoneNotificationAnchor.label   "Manage sharing your microphone with the site">
-<!ENTITY urlbar.webRTCShareScreenNotificationAnchor.label       "Manage sharing your windows or screen with the site">
+<!ENTITY urlbar.webRTCShareDevicesNotificationAnchor.tooltip      "Manage sharing your camera and/or microphone with the site">
+<!ENTITY urlbar.webRTCShareMicrophoneNotificationAnchor.tooltip   "Manage sharing your microphone with the site">
+<!ENTITY urlbar.webRTCShareScreenNotificationAnchor.tooltip       "Manage sharing your windows or screen with the site">
 
-<!ENTITY urlbar.pointerLockNotificationAnchor.label     "Change whether the site can hide the pointer">
-<!ENTITY urlbar.servicesNotificationAnchor.label        "View the service install message">
-<!ENTITY urlbar.translateNotificationAnchor.label       "Translate this page">
-<!ENTITY urlbar.translatedNotificationAnchor.label      "Manage page translation">
-<!ENTITY urlbar.emeNotificationAnchor.label             "Manage use of DRM software">
+<!ENTITY urlbar.servicesNotificationAnchor.tooltip        "Open install message panel">
+<!ENTITY urlbar.translateNotificationAnchor.tooltip       "Translate this page">
+<!ENTITY urlbar.translatedNotificationAnchor.tooltip      "Manage page translation">
+<!ENTITY urlbar.emeNotificationAnchor.tooltip             "Manage use of DRM software">
+
+<!ENTITY urlbar.cameraBlocked.tooltip            "You have blocked your camera for this website.">
+<!ENTITY urlbar.microphoneBlocked.tooltip        "You have blocked your microphone for this website.">
+<!ENTITY urlbar.screenBlocked.tooltip            "You have blocked this website from sharing your screen.">
+<!ENTITY urlbar.geolocationBlocked.tooltip       "You have blocked location information for this website.">
+<!ENTITY urlbar.indexedDBBlocked.tooltip         "You have blocked data storage for this website.">
+<!ENTITY urlbar.webNotificationsBlocked.tooltip  "You have blocked notifications for this website.">
 
 <!ENTITY urlbar.openHistoryPopup.tooltip                "Show history">
 
 <!ENTITY urlbar.zoomReset.tooltip     "Reset zoom level">
 
 <!ENTITY searchItem.title             "Search">
 
 <!-- Toolbar items --> 
@@ -418,21 +422,21 @@ These should match what Safari and other
   is a fundamental keybinding and we are maintaining a XP binding so that it is easy
   for people to switch to Linux.
 
  -->
 <!ENTITY searchFocus.commandkey       "k">
 <!ENTITY searchFocus.commandkey2      "e">
 <!ENTITY searchFocusUnix.commandkey   "j">
 
-<!-- LOCALIZATION NOTE (contentSearchInput.label, contentSearchSubmit.label):
-     These are set as the aria-label attribute for the search input box and
-     submit button in the in-content search UI, to be used by screen readers. -->
+<!-- LOCALIZATION NOTE (contentSearchInput.label):
+     This is set as the aria-label attribute for the search input box in the
+     in-content search UI, to be used by screen readers. -->
 <!ENTITY contentSearchInput.label     "Search query">
-<!ENTITY contentSearchSubmit.label    "Submit search">
+<!ENTITY contentSearchSubmit.tooltip  "Submit search">
 
 <!-- LOCALIZATION NOTE (searchFor.label, searchWith.label):
      These two strings are used to build the header above the list of one-click
      search providers:  "Search for <used typed keywords> with:" -->
 <!ENTITY searchFor.label              "Search for ">
 <!ENTITY searchWith.label             " with:">
 
 <!-- LOCALIZATION NOTE (search.label, searchAfter.label):
@@ -825,18 +829,16 @@ you can use these alternative items. Oth
 <!ENTITY trackingContentBlocked.learnMore "Learn More">
 <!ENTITY trackingContentBlocked.options "Options">
 <!ENTITY trackingContentBlocked.unblock2.label "Disable protection for this site">
 <!ENTITY trackingContentBlocked.unblock2.accesskey "D">
 <!ENTITY trackingContentBlocked.block.label "Enable protection">
 <!ENTITY trackingContentBlocked.block.accesskey "E">
 <!ENTITY trackingContentBlocked.disabled.message "Tracking protection is disabled">
 
-<!ENTITY pointerLock.notification.message "Press ESC at any time to show it again.">
-
 <!ENTITY pluginNotification.showAll.label "Show All">
 <!ENTITY pluginNotification.showAll.accesskey "S">
 
 <!-- LOCALIZATION NOTE (pluginActivateNow.label, pluginActivateAlways.label, pluginBlockNow.label): These should be the same as the matching strings in browser.properties -->
 <!ENTITY pluginActivateNow.label "Allow Now">
 <!ENTITY pluginActivateAlways.label "Allow and Remember">
 <!ENTITY pluginBlockNow.label "Block Plugin">
 
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -373,26 +373,16 @@ geolocation.shareLocation=Share Location
 geolocation.shareLocation.accesskey=a
 geolocation.alwaysShareLocation=Always Share Location
 geolocation.alwaysShareLocation.accesskey=A
 geolocation.neverShareLocation=Never Share Location
 geolocation.neverShareLocation.accesskey=N
 geolocation.shareWithSite2=Would you like to share your location with this site?
 geolocation.shareWithFile2=Would you like to share your location with this file?
 
-# FlyWeb UI
-# LOCALIZATION NOTE (flyWebPublishServer.allowPublishServer): This is an experimental feature only shipping in Nightly, and doesn't need translation.
-flyWebPublishServer.allowPublishServer=Allow Server
-# LOCALIZATION NOTE (flyWebPublishServer.allowPublishServer.accessKey): This is an experimental feature only shipping in Nightly, and doesn't need translation.
-flyWebPublishServer.allowPublishServer.accesskey=A
-# LOCALIZATION NOTE (flyWebPublishServer.denyPublishServer): This is an experimental feature only shipping in Nightly, and doesn't need translation.
-flyWebPublishServer.denyPublishServer=Block Server
-# LOCALIZATION NOTE (flyWebPublishServer.denyPublishServer.accessKey): This is an experimental feature only shipping in Nightly, and doesn't need translation.
-flyWebPublishServer.denyPublishServer.accesskey=B
-
 webNotifications.receiveForSession=Receive for this session
 webNotifications.receiveForSession.accesskey=s
 webNotifications.alwaysReceive=Always Receive Notifications
 webNotifications.alwaysReceive.accesskey=A
 webNotifications.neverShow=Always Block Notifications
 webNotifications.neverShow.accesskey=N
 webNotifications.receiveFromSite=Would you like to receive notifications from this site?
 # LOCALIZATION NOTE (webNotifications.upgradeTitle): When using native notifications on OS X, the title may be truncated around 32 characters.
@@ -738,8 +728,18 @@ pendingCrashReports.ignoreAll = Ignore
 decoder.noCodecs.button = Learn how
 decoder.noCodecs.accesskey = L
 decoder.noCodecs.message = To play video, you may need to install Microsoft’s Media Feature Pack.
 decoder.noCodecsVista.message = To play video, you may need to install Microsoft’s Platform Update Supplement for Windows Vista.
 decoder.noCodecsXP.message = To play video, you may need to enable Adobe’s Primetime Content Decryption Module.
 decoder.noCodecsLinux.message = To play video, you may need to install the required video codecs.
 decoder.noHWAcceleration.message = To improve video quality, you may need to install Microsoft’s Media Feature Pack.
 decoder.noHWAccelerationVista.message = To improve video quality, you may need to install Microsoft’s Platform Update Supplement for Windows Vista.
+
+permissions.remove.tooltip = Clear this permission and ask again
+
+# LOCALIZATION NOTE (aboutDialog.architecture.*):
+# The sixtyFourBit and thirtyTwoBit strings describe the architecture of the
+# current Firefox build: 32-bit or 64-bit. These strings are used in parentheses
+# between the Firefox version and the "What's new" link in the About dialog,
+# e.g.: "48.0.2 (32-bit) <What's new>" or "51.0a1 (2016-09-05) (64-bit)".
+aboutDialog.architecture.sixtyFourBit = 64-bit
+aboutDialog.architecture.thirtyTwoBit = 32-bit
--- a/browser/locales/en-US/chrome/browser/preferences/preferences.properties
+++ b/browser/locales/en-US/chrome/browser/preferences/preferences.properties
@@ -26,16 +26,18 @@ cookiepermissionstitle=Exceptions - Cook
 addonspermissionstext=You can specify which websites are allowed to install add-ons. Type the exact address of the site you want to allow and then click Allow.
 addons_permissions_title=Allowed Sites - Add-ons Installation
 popuppermissionstext=You can specify which websites are allowed to open pop-up windows. Type the exact address of the site you want to allow and then click Allow.
 popuppermissionstitle=Allowed Sites - Pop-ups
 notificationspermissionstext4=Control which websites are always or never allowed to send you notifications. If you remove a site, it will need to request permission again.
 notificationspermissionstitle=Notification Permissions
 invalidURI=Please enter a valid hostname
 invalidURITitle=Invalid Hostname Entered
+savedLoginsExceptions_title=Exceptions - Saved Logins
+savedLoginsExceptions_desc=Logins for the following sites will not be saved:
 
 #### Block List Manager
 
 blockliststext=You can choose which list Firefox will use to block Web elements that may track your browsing activity.
 blockliststitle=Block Lists
 # LOCALIZATION NOTE (mozNameTemplate): This template constructs the name of the
 # block list in the block lists dialog. It combines the list name and
 # description.
@@ -121,17 +123,17 @@ cannot=Block
 noCookieSelected=<no cookie selected>
 cookiesAll=The following cookies are stored on your computer:
 cookiesFiltered=The following cookies match your search:
 # LOCALIZATION NOTE (removeSelectedCookies):
 # Semicolon-separated list of plural forms. See:
 # http://developer.mozilla.org/en/docs/Localization_and_Plurals
 # If you need to display the number of selected elements in your language,
 # you can use #1 in your localization as a placeholder for the number.
-# For example this is the English string with numbers:   
+# For example this is the English string with numbers:
 # removeSelectedCookied=Remove #1 Selected;Remove #1 Selected
 removeSelectedCookies=Remove Selected;Remove Selected
 defaultUserContextLabel=None
 
 #### Offline apps
 offlineAppsList.height=7em
 offlineAppRemoveTitle=Remove offline website data
 offlineAppRemovePrompt=After removing this data, %S will not be available offline.  Are you sure you want to remove this offline website?
deleted file mode 100644
--- a/browser/locales/en-US/searchplugins/eBay.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
-   - License, v. 2.0. If a copy of the MPL was not distributed with this
-   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>eBay</ShortName>
-<Description>eBay - Online auctions</Description>
-<InputEncoding>ISO-8859-1</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAB6AQAAJgAAACAgAAAAAAAAQgMAAKABAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAFBSURBVDjLtZPdK0MBGIf3J5Babhx3rinFBWuipaUskX9DYvkopqgV90q5UJpyp0OKrUWM2VrRsS9D0zZKHGaOnW1nj4vtypVtPPe/533r9746QAAOAJXfo5Yzgg44pHrcugon/6Sgo0b+XuAOZ2iZiVQmyPoDpIwmUkYTzqM7GsdDdC7F6Lbf8pzOkfWOouzqeZem2b+2AqAV8zjD8yVBqqcf2b7C66yNiMGMfixIQSvi8Mp0LEbR5ADq1QSKWM+Gx0RC9nOZ2GLzwlIWdPWiuNzk4w/EpThNkyEAXKEP2ud8KGId2sspilhPMrmNwzfCuqePr/xbSfC5I/I0MMSj2YJ3z49gDdO2cEOrLUowJpE9G0QRG1ClKbR0EIdvmOPYcnUtnN+vsnZiQC1k/qnGagQ1n3LNzySUJZVskitnmr8BlQG7T2hvgxsAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAMJSURBVFjD7ZddSFNhGMeHXXQTZFFCWfR1pRhUECQlBdWVToo+6KYu1KigtDASG5qUfZgFZvahEDosECPDktKZS1FL+1DRnEvdUptjug91X2dnZzv/3vO6OZbWnR4v9sADL+fs7P97/s/znu2VAJD4UkpSSdKG+QubTyPBr+sXz8XCR64fIAHihVTis0SsUAoAVhEBrBKIHCGAEMB/ARi3F5LkbpS2WMRzYEEBXC2tsD6T03R9agsCGLNyqPw6CXmrBT06JvhbPHZwmkdwtR0B138PPKOHgzXD5jLAy3tmibo4K9weZwDAazJj/FQKRnfugfHMeRiTz0K3Ixam1HQKcPC+Fisu9NK1P08Uj4DleHgMdXC+WQ7nu3UEOhFMfTQcVUvQ1H4IN2sj8H2k7K+2TqCc3GseyA8AmDOzMBq7D9bS8sAr6nEJdNt3UbHVF1XQGtmZew8bTPT6tWoD3KpsUvlR8NxUoEICMvl6KQo+xqCwcRs4T8Ax5c8bFExjbAgAjO7aS8VsLypgq3g5nWStjztAhWRVhqAqeB6IuKTClkw1eNYEbrCQQBwD8yGGOsAooogLYejQPKBi7UPF9DkH+ezd+o141ZkUPAOC+L9SAMivNc7q46YMNSLTe4n1kaQF4XD3ZIDTPgU3XEYciKcAHrsGJS1xKFBGgyVzouiT4VbdGhjt/cEA5isyKsaz7jl3we7bg7Rqf6j0LoSldON4wWcqJDgQNGTN++l13vELA+MK6kKd6iryFOvxtidt9i5gO7owdjKJQliflNAU1pas6xQgnAzg1ux+lJEdILixNr0Pq9JUUA8NwVG9DM73G0jlcnh+V4BpjIWzJmIGQIjnXw5TiDuKSEwxurm3ITc8DNO51BnrLbIcsrW0dNA6RxgUKU1UdGVqLy5X6qGzTLvlnewiBZyGs3Yz6X8UeaYI3olvZDhzwLumZ+eHvooCCC0Q5VUsb4unwycM4YIDqA01tPqmgbzQr2EIYPECiPm33LYoDiZSsY9moh9O/Znoa4d9HkXtPg2pX/cPKCoRQ+ocZa4AAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="http://autosug.ebay.com/autosug">
-  <Param name="sId" value="0" />
-  <Param name="kwd" value="{searchTerms}" />
-  <Param name="fmt" value="osr" />
-</Url>
-<Url type="text/html" method="GET" template="http://rover.ebay.com/rover/1/711-47294-18009-3/4" resultdomain="ebay.com">
-  <Param name="mfe"  value="search" />
-  <Param name="mpre" value="http://www.ebay.com/sch/i.html?_nkw={searchTerms}" />
-</Url>
-<SearchForm>http://search.ebay.com/</SearchForm>
-</SearchPlugin>
--- a/browser/locales/en-US/searchplugins/list.txt
+++ b/browser/locales/en-US/searchplugins/list.txt
@@ -1,8 +1,7 @@
 amazondotcom
 bing
-eBay
 google
 twitter
 wikipedia
 yahoo
 yahoo-en-CA:hidden
--- a/browser/modules/ContentSearch.jsm
+++ b/browser/modules/ContentSearch.jsm
@@ -391,17 +391,19 @@ this.ContentSearch = {
     }
   },
 
   _onMessage: Task.async(function* (msg) {
     let methodName = "_onMessage" + msg.data.type;
     if (methodName in this) {
       yield this._initService();
       yield this[methodName](msg, msg.data.data);
-      msg.target.removeEventListener("SwapDocShells", msg, true);
+      if (!Cu.isDeadWrapper(msg.target)) {
+        msg.target.removeEventListener("SwapDocShells", msg, true);
+      }
     }
   }),
 
   _onMessageGetState: function (msg, data) {
     return this.currentStateObj().then(state => {
       this._reply(msg, "State", state);
     });
   },
@@ -484,17 +486,17 @@ this.ContentSearch = {
       this._suggestionMap.set(browser, data);
     }
     return data;
   },
 
   _reply: function (msg, type, data) {
     // We reply asyncly to messages, and by the time we reply the browser we're
     // responding to may have been destroyed.  messageManager is null then.
-    if (msg.target.messageManager) {
+    if (!Cu.isDeadWrapper(msg.target) && msg.target.messageManager) {
       msg.target.messageManager.sendAsyncMessage(...this._msgArgs(type, data));
     }
   },
 
   _broadcast: function (type, data) {
     Cc["@mozilla.org/globalmessagemanager;1"].
       getService(Ci.nsIMessageListenerManager).
       broadcastAsyncMessage(...this._msgArgs(type, data));
--- a/browser/modules/test/browser.ini
+++ b/browser/modules/test/browser.ini
@@ -19,9 +19,10 @@ support-files =
 [browser_NetworkPrioritizer.js]
 [browser_SelfSupportBackend.js]
 support-files =
   ../../components/uitour/test/uitour.html
   ../../components/uitour/UITour-lib.js
 [browser_taskbar_preview.js]
 skip-if = os != "win"
 [browser_UsageTelemetry.js]
+[browser_UsageTelemetry_private_and_restore.js]
 [browser_urlBar_zoom.js]
--- a/browser/modules/test/browser_UsageTelemetry.js
+++ b/browser/modules/test/browser_UsageTelemetry.js
@@ -39,25 +39,16 @@ function browserLocationChanged(browser)
     };
     const filter = Cc["@mozilla.org/appshell/component/browser-status-filter;1"]
                      .createInstance(Ci.nsIWebProgress);
     filter.addProgressListener(wpl, Ci.nsIWebProgress.NOTIFY_ALL);
     browser.webProgress.addProgressListener(filter, Ci.nsIWebProgress.NOTIFY_ALL);
   });
 }
 
-function promiseBrowserStateRestored() {
-  return new Promise(resolve => {
-     Services.obs.addObserver(function observer(aSubject, aTopic) {
-       Services.obs.removeObserver(observer, "sessionstore-browser-state-restored");
-       resolve();
-     }, "sessionstore-browser-state-restored", false);
-  });
-}
-
 /**
  * An helper that checks the value of a scalar if it's expected to be > 0,
  * otherwise makes sure that the scalar it's not reported.
  */
 let checkScalar = (scalars, scalarName, value, msg) => {
   if (value > 0) {
     is(scalars[scalarName], value, msg);
     return;
@@ -246,79 +237,8 @@ add_task(function* test_URIAndDomainCoun
     yield promiseIframeLoaded;
   });
   checkCounts(5, 2);
 
   // Clean up.
   yield BrowserTestUtils.removeTab(firstTab);
   yield BrowserTestUtils.closeWindow(newWin);
 });
-
-add_task(function* test_privateMode() {
-  // Let's reset the counts.
-  Services.telemetry.clearScalars();
-
-  // Open a private window and load a website in it.
-  let privateWin = yield BrowserTestUtils.openNewBrowserWindow({private: true});
-  yield BrowserTestUtils.loadURI(privateWin.gBrowser.selectedBrowser, "http://example.com/");
-  yield BrowserTestUtils.browserLoaded(privateWin.gBrowser.selectedBrowser);
-
-  // Check that tab and window count is recorded.
-  const scalars =
-    Services.telemetry.snapshotScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN);
-
-  ok(!(TOTAL_URI_COUNT in scalars), "We should not track URIs in private mode.");
-  ok(!(UNIQUE_DOMAINS_COUNT in scalars), "We should not track unique domains in private mode.");
-  is(scalars[TAB_EVENT_COUNT], 1, "The number of open tab event count must match the expected value.");
-  is(scalars[MAX_CONCURRENT_TABS], 2, "The maximum tab count must match the expected value.");
-  is(scalars[WINDOW_OPEN_COUNT], 1, "The number of window open event count must match the expected value.");
-  is(scalars[MAX_CONCURRENT_WINDOWS], 2, "The maximum window count must match the expected value.");
-
-  // Clean up.
-  yield BrowserTestUtils.closeWindow(privateWin);
-});
-
-add_task(function* test_sessionRestore() {
-  const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
-  Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
-  registerCleanupFunction(() => {
-    Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
-  });
-
-  // Let's reset the counts.
-  Services.telemetry.clearScalars();
-
-  // The first window will be put into the already open window and the second
-  // window will be opened with _openWindowWithState, which is the source of the problem.
-  const state = {
-    windows: [
-      {
-        tabs: [
-          { entries: [{ url: "http://example.org" }], extData: { "uniq": 3785 } }
-        ],
-        selected: 1
-      }
-    ]
-  };
-
-  // Save the current session.
-  let SessionStore =
-    Cu.import("resource:///modules/sessionstore/SessionStore.jsm", {}).SessionStore;
-  let backupState = SessionStore.getBrowserState();
-
-  // Load the custom state and wait for SSTabRestored, as we want to make sure
-  // that the URI counting code was hit.
-  let tabRestored = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "SSTabRestored");
-  SessionStore.setBrowserState(JSON.stringify(state));
-  yield tabRestored;
-
-  // Check that the URI is not recorded.
-  const scalars =
-    Services.telemetry.snapshotScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN);
-
-  ok(!(TOTAL_URI_COUNT in scalars), "We should not track URIs from restored sessions.");
-  ok(!(UNIQUE_DOMAINS_COUNT in scalars), "We should not track unique domains from restored sessions.");
-
-  // Restore the original session and cleanup.
-  let sessionRestored = promiseBrowserStateRestored();
-  SessionStore.setBrowserState(JSON.stringify(state));
-  yield sessionRestored;
-});
copy from browser/modules/test/browser_UsageTelemetry.js
copy to browser/modules/test/browser_UsageTelemetry_private_and_restore.js
--- a/browser/modules/test/browser_UsageTelemetry.js
+++ b/browser/modules/test/browser_UsageTelemetry_private_and_restore.js
@@ -2,261 +2,25 @@
 
 const MAX_CONCURRENT_TABS = "browser.engagement.max_concurrent_tab_count";
 const TAB_EVENT_COUNT = "browser.engagement.tab_open_event_count";
 const MAX_CONCURRENT_WINDOWS = "browser.engagement.max_concurrent_window_count";
 const WINDOW_OPEN_COUNT = "browser.engagement.window_open_event_count";
 const TOTAL_URI_COUNT = "browser.engagement.total_uri_count";
 const UNIQUE_DOMAINS_COUNT = "browser.engagement.unique_domains_count";
 
-const TELEMETRY_SUBSESSION_TOPIC = "internal-telemetry-after-subsession-split";
-
-/**
- * Waits for the web progress listener associated with this tab to fire an
- * onLocationChange for a non-error page.
- *
- * @param {xul:browser} browser
- *        A xul:browser.
- *
- * @return {Promise}
- * @resolves When navigating to a non-error page.
- */
-function browserLocationChanged(browser) {
-  return new Promise(resolve => {
-    let wpl = {
-      onStateChange() {},
-      onSecurityChange() {},
-      onStatusChange() {},
-      onLocationChange(aWebProgress, aRequest, aURI, aFlags) {
-        if (!(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE)) {
-          browser.webProgress.removeProgressListener(filter);
-          filter.removeProgressListener(wpl);
-          resolve();
-        }
-      },
-      QueryInterface: XPCOMUtils.generateQI([
-        Ci.nsIWebProgressListener,
-        Ci.nsIWebProgressListener2,
-      ]),
-    };
-    const filter = Cc["@mozilla.org/appshell/component/browser-status-filter;1"]
-                     .createInstance(Ci.nsIWebProgress);
-    filter.addProgressListener(wpl, Ci.nsIWebProgress.NOTIFY_ALL);
-    browser.webProgress.addProgressListener(filter, Ci.nsIWebProgress.NOTIFY_ALL);
-  });
-}
-
 function promiseBrowserStateRestored() {
   return new Promise(resolve => {
      Services.obs.addObserver(function observer(aSubject, aTopic) {
        Services.obs.removeObserver(observer, "sessionstore-browser-state-restored");
        resolve();
      }, "sessionstore-browser-state-restored", false);
   });
 }
 
-/**
- * An helper that checks the value of a scalar if it's expected to be > 0,
- * otherwise makes sure that the scalar it's not reported.
- */
-let checkScalar = (scalars, scalarName, value, msg) => {
-  if (value > 0) {
-    is(scalars[scalarName], value, msg);
-    return;
-  }
-  ok(!(scalarName in scalars), scalarName + " must not be reported.");
-};
-
-/**
- * Get a snapshot of the scalars and check them against the provided values.
- */
-let checkScalars = (maxTabs, tabOpenCount, maxWindows, windowsOpenCount, totalURIs, domainCount) => {
-  const scalars =
-    Services.telemetry.snapshotScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN);
-
-  // Check the expected values. Scalars that are never set must not be reported.
-  checkScalar(scalars, MAX_CONCURRENT_TABS, maxTabs,
-              "The maximum tab count must match the expected value.");
-  checkScalar(scalars, TAB_EVENT_COUNT, tabOpenCount,
-              "The number of open tab event count must match the expected value.");
-  checkScalar(scalars, MAX_CONCURRENT_WINDOWS, maxWindows,
-              "The maximum window count must match the expected value.");
-  checkScalar(scalars, WINDOW_OPEN_COUNT, windowsOpenCount,
-              "The number of window open event count must match the expected value.");
-  checkScalar(scalars, TOTAL_URI_COUNT, totalURIs,
-              "The total URI count must match the expected value.");
-  checkScalar(scalars, UNIQUE_DOMAINS_COUNT, domainCount,
-              "The unique domains count must match the expected value.");
-};
-
-add_task(function* test_tabsAndWindows() {
-  // Let's reset the counts.
-  Services.telemetry.clearScalars();
-
-  let openedTabs = [];
-  let expectedTabOpenCount = 0;
-  let expectedWinOpenCount = 0;
-  let expectedMaxTabs = 0;
-  let expectedMaxWins = 0;
-
-  // Add a new tab and check that the count is right.
-  openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"));
-  expectedTabOpenCount = 1;
-  expectedMaxTabs = 2;
-  checkScalars(expectedMaxTabs, expectedTabOpenCount, expectedMaxWins, expectedWinOpenCount, 0, 0);
-
-  // Add two new tabs in the same window.
-  openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"));
-  openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"));
-  expectedTabOpenCount += 2;
-  expectedMaxTabs += 2;
-  checkScalars(expectedMaxTabs, expectedTabOpenCount, expectedMaxWins, expectedWinOpenCount, 0, 0);
-
-  // Add a new window and then some tabs in it. An empty new windows counts as a tab.
-  let win = yield BrowserTestUtils.openNewBrowserWindow();
-  openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, "about:blank"));
-  openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, "about:blank"));
-  openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"));
-  // The new window started with a new tab, so account for it.
-  expectedTabOpenCount += 4;
-  expectedWinOpenCount += 1;
-  expectedMaxWins = 2;
-  expectedMaxTabs += 4;
-
-  // Remove a tab from the first window, the max shouldn't change.
-  yield BrowserTestUtils.removeTab(openedTabs.pop());
-  checkScalars(expectedMaxTabs, expectedTabOpenCount, expectedMaxWins, expectedWinOpenCount, 0, 0);
-
-  // Remove all the extra windows and tabs.
-  for (let tab of openedTabs) {
-    yield BrowserTestUtils.removeTab(tab);
-  }
-  yield BrowserTestUtils.closeWindow(win);
-
-  // Make sure all the scalars still have the expected values.
-  checkScalars(expectedMaxTabs, expectedTabOpenCount, expectedMaxWins, expectedWinOpenCount, 0, 0);
-});
-
-add_task(function* test_subsessionSplit() {
-  // Let's reset the counts.
-  Services.telemetry.clearScalars();
-
-  // Add a new window (that will have 4 tabs).
-  let win = yield BrowserTestUtils.openNewBrowserWindow();
-  let openedTabs = [];
-  openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, "about:blank"));
-  openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, "about:blank"));
-  openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, "http://www.example.com"));
-
-  // Check that the scalars have the right values.
-  checkScalars(5 /*maxTabs*/, 4 /*tabOpen*/, 2 /*maxWins*/, 1 /*winOpen*/,
-               1 /* toalURIs */, 1 /* uniqueDomains */);
-
-  // Remove a tab.
-  yield BrowserTestUtils.removeTab(openedTabs.pop());
-
-  // Simulate a subsession split by clearing the scalars (via |snapshotScalars|) and
-  // notifying the subsession split topic.
-  Services.telemetry.snapshotScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN,
-                                     true /* clearScalars*/);
-  Services.obs.notifyObservers(null, TELEMETRY_SUBSESSION_TOPIC, "");
-
-  // After a subsession split, only the MAX_CONCURRENT_* scalars must be available
-  // and have the correct value. No tabs or windows were opened so other scalars
-  // must not be reported.
-  checkScalars(4 /*maxTabs*/, 0 /*tabOpen*/, 2 /*maxWins*/, 0 /*winOpen*/,
-               0 /* toalURIs */, 0 /* uniqueDomains */);
-
-  // Remove all the extra windows and tabs.
-  for (let tab of openedTabs) {
-    yield BrowserTestUtils.removeTab(tab);
-  }
-  yield BrowserTestUtils.closeWindow(win);
-});
-
-add_task(function* test_URIAndDomainCounts() {
-  // Let's reset the counts.
-  Services.telemetry.clearScalars();
-
-  let checkCounts = (URICount, domainCount) => {
-    // Get a snapshot of the scalars and then clear them.
-    const scalars =
-      Services.telemetry.snapshotScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN);
-    checkScalar(scalars, TOTAL_URI_COUNT, URICount,
-                "The URI scalar must contain the expected value.");
-    checkScalar(scalars, UNIQUE_DOMAINS_COUNT, domainCount,
-                "The unique domains scalar must contain the expected value.");
-  };
-
-  // Check that about:blank doesn't get counted in the URI total.
-  let firstTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
-  checkCounts(0, 0);
-
-  // Open a different page and check the counts.
-  yield BrowserTestUtils.loadURI(firstTab.linkedBrowser, "http://example.com/");
-  yield BrowserTestUtils.browserLoaded(firstTab.linkedBrowser);
-  checkCounts(1, 1);
-
-  // Activating a different tab must not increase the URI count.
-  let secondTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
-  yield BrowserTestUtils.switchTab(gBrowser, firstTab);
-  checkCounts(1, 1);
-  yield BrowserTestUtils.removeTab(secondTab);
-
-  // Open a new window and set the tab to a new address.
-  let newWin = yield BrowserTestUtils.openNewBrowserWindow();
-  yield BrowserTestUtils.loadURI(newWin.gBrowser.selectedBrowser, "http://example.com/");
-  yield BrowserTestUtils.browserLoaded(newWin.gBrowser.selectedBrowser);
-  checkCounts(2, 1);
-
-  // We should not count AJAX requests.
-  const XHR_URL = "http://example.com/r";
-  yield ContentTask.spawn(newWin.gBrowser.selectedBrowser, XHR_URL, function(url) {
-    return new Promise(resolve => {
-      var xhr = new content.window.XMLHttpRequest();
-      xhr.open("GET", url);
-      xhr.onload = () => resolve();
-      xhr.send();
-    });
-  });
-  checkCounts(2, 1);
-
-  // Check that we're counting page fragments.
-  let loadingStopped = browserLocationChanged(newWin.gBrowser.selectedBrowser);
-  yield BrowserTestUtils.loadURI(newWin.gBrowser.selectedBrowser, "http://example.com/#2");
-  yield loadingStopped;
-  checkCounts(3, 1);
-
-  // Check test.domain.com and some.domain.com are only counted once unique.
-  yield BrowserTestUtils.loadURI(newWin.gBrowser.selectedBrowser, "http://test1.example.com/");
-  yield BrowserTestUtils.browserLoaded(newWin.gBrowser.selectedBrowser);
-  checkCounts(4, 1);
-
-  // Make sure that the unique domains counter is incrementing for a different domain.
-  yield BrowserTestUtils.loadURI(newWin.gBrowser.selectedBrowser, "https://example.org/");
-  yield BrowserTestUtils.browserLoaded(newWin.gBrowser.selectedBrowser);
-  checkCounts(5, 2);
-
-  // Check that we only account for top level loads (e.g. we don't count URIs from
-  // embedded iframes).
-  yield ContentTask.spawn(newWin.gBrowser.selectedBrowser, null, function* () {
-    let doc = content.document;
-    let iframe = doc.createElement("iframe");
-    let promiseIframeLoaded = ContentTaskUtils.waitForEvent(iframe, "load", false);
-    iframe.src = "https://example.org/test";
-    doc.body.insertBefore(iframe, doc.body.firstChild);
-    yield promiseIframeLoaded;
-  });
-  checkCounts(5, 2);
-
-  // Clean up.
-  yield BrowserTestUtils.removeTab(firstTab);
-  yield BrowserTestUtils.closeWindow(newWin);
-});
-
 add_task(function* test_privateMode() {
   // Let's reset the counts.
   Services.telemetry.clearScalars();
 
   // Open a private window and load a website in it.
   let privateWin = yield BrowserTestUtils.openNewBrowserWindow({private: true});
   yield BrowserTestUtils.loadURI(privateWin.gBrowser.selectedBrowser, "http://example.com/");
   yield BrowserTestUtils.browserLoaded(privateWin.gBrowser.selectedBrowser);
--- a/browser/modules/webrtcUI.jsm
+++ b/browser/modules/webrtcUI.jsm
@@ -342,18 +342,18 @@ function prompt(aBrowser, aRequest) {
 
   if (aRequest.secure && !sharingScreen && !sharingAudio) {
     // Don't show the 'Always' action if the connection isn't secure, or for
     // screen/audio sharing (because we can't guess which window the user wants
     // to share without prompting).
     secondaryActions.unshift({
       label: stringBundle.getString("getUserMedia.always.label"),
       accessKey: stringBundle.getString("getUserMedia.always.accesskey"),
-      callback: function () {
-        mainAction.callback(true);
+      callback: function (aState) {
+        mainAction.callback(aState, true);
       }
     });
   }
 
   let options = {
     eventCallback: function(aTopic, aNewBrowser) {
       if (aTopic == "swapping")
         return true;
@@ -514,17 +514,17 @@ function prompt(aBrowser, aRequest) {
       if (sharingScreen)
         listScreenShareDevices(windowMenupopup, videoDevices);
       else
         listDevices(camMenupopup, videoDevices);
 
       if (!sharingAudio)
         listDevices(micMenupopup, audioDevices);
 
-      this.mainAction.callback = function(aRemember) {
+      this.mainAction.callback = function(aState, aRemember) {
         let allowedDevices = [];
         let perms = Services.perms;
         if (videoDevices.length) {
           let listId = "webRTC-select" + (sharingScreen ? "Window" : "Camera") + "-menulist";
           let videoDeviceIndex = chromeDoc.getElementById(listId).value;
           let allowCamera = videoDeviceIndex != "-1";
           if (allowCamera) {
             allowedDevices.push(videoDeviceIndex);
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -50,22 +50,21 @@
   background-color: transparent;
   border-top: none;
 }
 
 #navigator-toolbox::after {
   content: "";
   display: -moz-box;
   -moz-box-ordinal-group: 101; /* tabs toolbar is 100 */
-  height: 1px;
-  background-color: ThreeDShadow;
+  border-bottom: 1px solid ThreeDShadow;
 }
 
 #navigator-toolbox:-moz-lwtheme::after {
-  background-color: rgba(0,0,0,.3);
+  border-bottom-color: rgba(0,0,0,.3);
 }
 
 #navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):not(#addon-bar) {
   background-image: linear-gradient(@toolbarHighlight@, @toolbarHighlight@);
 }
 
 #navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):not(#addon-bar):-moz-lwtheme {
   background-image: linear-gradient(@toolbarHighlightLWT@, @toolbarHighlightLWT@);
@@ -1707,70 +1706,16 @@ toolbarbutton.chevron > .toolbarbutton-t
 toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
   display: none;
 }
 
 toolbarbutton.chevron > .toolbarbutton-icon {
   margin: 0;
 }
 
-/* Ctrl-Tab */
-
-#ctrlTab-panel {
-  -moz-appearance: none;
-  background: hsla(0,0%,33%,.85);
-  color: white;
-  border-style: none;
-  padding: 20px 10px 10px;
-  font-weight: bold;
-  text-shadow: 0 0 1px hsl(0,0%,12%), 0 0 2px hsl(0,0%,12%);
-}
-
-.ctrlTab-favicon[src] {
-  background-color: white;
-  width: 20px;
-  height: 20px;
-  padding: 2px;
-}
-
-.ctrlTab-preview-inner > .tabPreview-canvas {
-  box-shadow: 1px 1px 2px hsl(0,0%,12%);
-}
-
-.ctrlTab-preview:not(#ctrlTab-showAll) > * > .ctrlTab-preview-inner > .tabPreview-canvas {
-  margin-bottom: 2px;
-}
-
-.ctrlTab-preview-inner {
-  padding-bottom: 10px;
-}
-
-#ctrlTab-showAll:not(:focus) > * > .ctrlTab-preview-inner {
-  padding: 10px;
-  background-color: rgba(255,255,255,.2);
-  border-radius: .5em;
-}
-
-.ctrlTab-preview:focus > * > .ctrlTab-preview-inner {
-  color: white;
-  background-color: rgba(0,0,0,.6);
-  text-shadow: none;
-  padding: 8px;
-  border: 2px solid white;
-  border-radius: .5em;
-}
-
-.ctrlTab-preview:not(#ctrlTab-showAll):focus > * > .ctrlTab-preview-inner {
-  margin: -10px -10px 0;
-}
-
-#ctrlTab-showAll {
-  margin-top: .5em;
-}
-
 /* Status panel */
 
 .statuspanel-label {
   margin: 0;
   padding: 2px 4px;
   background: -moz-dialog;
   border: 1px none ThreeDShadow;
   border-top-style: solid;
@@ -1788,19 +1733,19 @@ toolbarbutton.chevron > .toolbarbutton-i
 .statuspanel-label:-moz-locale-dir(rtl):not([mirror]),
 .statuspanel-label:-moz-locale-dir(ltr)[mirror] {
   border-left-style: solid;
   border-top-left-radius: .3em;
   margin-left: 1em;
 }
 
 %include ../shared/fullscreen/warning.inc.css
+%include ../shared/ctrlTab.inc.css
 %include ../../../devtools/client/themes/responsivedesign.inc.css
 %include ../../../devtools/client/themes/commandline.inc.css
-
 %include ../shared/plugin-doorhanger.inc.css
 
 notification.pluginVulnerable > .notification-inner > .messageCloseButton:not(:hover) {
   background-image: -moz-image-rect(url("chrome://global/skin/icons/close.svg"), 0, 80, 16, 64);
 }
 
 %include ../shared/login-doorhanger.inc.css
 
--- a/browser/themes/linux/searchbar.css
+++ b/browser/themes/linux/searchbar.css
@@ -127,65 +127,67 @@ menuitem[cmd="cmd_clearhistory"][disable
   -moz-box-align: center;
 }
 
 .search-panel-current-engine {
   border-bottom: none;
 }
 
 .search-panel-tree {
-  border-top: 1px solid #ccc !important;
+  border-top: 1px solid var(--panel-separator-color) !important;
 }
 
 .search-panel-header {
   font-weight: normal;
-  border-top: 1px solid rgba(0, 0, 0, 0.2);
+  background-color: hsla(210,4%,10%,.07);
+  border: none;
+  border-top: 1px solid var(--panel-separator-color);
   padding: 3px 5px;
   color: GrayText;
 }
 
 .search-panel-header > label {
   margin-top: 2px !important;
   margin-bottom: 1px !important;
 }
 
 .search-panel-current-input > label {
   margin: 2px 0 1px !important;
 }
 
 .search-panel-input-value {
-  color: Highlight;
+  color: -moz-fieldtext;
 }
 
 .search-panel-one-offs {
   margin: 0 !important;
-  border-top: 1px solid #ccc;
+  border-top: 1px solid var(--panel-separator-color);
 }
 
 .searchbar-engine-one-off-item {
   -moz-appearance: none;
   display: inline-block;
   border: none;
   min-width: 48px;
   height: 32px;
-  margin: 0 0;
-  padding: 0 0;
-  background: none;
-  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAWCAYAAAABxvaqAAAABmJLR0QA/wD/AP+gvaeTAAAAFElEQVQI12NgYGAwZmJgYGCgBwEAHpIAXs+dj/cAAAAASUVORK5CYII=');
+  margin: 0;
+  padding: 0;
+  background: linear-gradient(transparent 15%, var(--panel-separator-color) 15%, var(--panel-separator-color) 85%, transparent 85%);
+  background-size: 1px auto;
   background-repeat: no-repeat;
   background-position: right center;
 }
 
 .searchbar-engine-one-off-item:-moz-locale-dir(rtl) {
   background-position: left center;
 }
 
 .searchbar-engine-one-off-item:not(.last-row) {
   box-sizing: content-box;
-  border-bottom: 1px solid rgba(0, 0, 0, 0.2);
+  border-bottom: 1px solid var(--panel-separator-color);
 }
 
 .search-setting-button-compact {
   border-bottom: none !important;
 }
 
 .search-panel-one-offs:not([compact=true]) > .searchbar-engine-one-off-item.last-of-row,
 .search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.last-of-row:not(.dummy),
@@ -226,17 +228,17 @@ menuitem[cmd="cmd_clearhistory"][disable
   padding: 0 10px;
 }
 
 .addengine-item > .button-box {
   -moz-box-pack: start;
 }
 
 .addengine-item:first-of-type {
-  border-top: 1px solid rgba(0, 0, 0, 0.2);
+  border-top: 1px solid var(--panel-separator-color);
 }
 
 .addengine-item[selected] {
   background-color: Highlight;
   color: HighlightText;
 }
 
 .addengine-icon {
@@ -289,26 +291,22 @@ menuitem[cmd="cmd_clearhistory"][disable
 }
 
 .search-panel-tree > .autocomplete-treebody::-moz-tree-image(fromhistory, selected) {
   list-style-image: url("chrome://browser/skin/search-history-icon.svg#search-history-icon-active");
 }
 
 .search-setting-button {
   -moz-appearance: none;
-  border: none;
-  border-top: 1px solid rgba(0, 0, 0, 0.2);
   margin: 0;
   min-height: 32px;
 }
 
 .search-setting-button[selected] {
-  background-color: Highlight;
-  color: HighlightText;
-  border-top-color: #bdbebe;
+  background-color: hsla(210,4%,10%,.15);
 }
 
 .search-setting-button-compact {
   list-style-image: url("chrome://browser/skin/gear.svg#gear");
 }
 
 .search-setting-button-compact[selected] {
   list-style-image: url("chrome://browser/skin/gear.svg#gear-inverted");
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -50,28 +50,30 @@
 
 #urlbar:-moz-lwtheme:not([focused="true"]),
 .searchbar-textbox:-moz-lwtheme:not([focused="true"]) {
   opacity: .9;
 }
 
 #navigator-toolbox::after {
   -moz-box-ordinal-group: 101; /* tabs toolbar is 100 */
-  background-image: linear-gradient(to top, hsla(0,0%,0%,.15), hsla(0,0%,0%,.15) 1px, hsla(0,0%,100%,.15) 1px, hsla(0,0%,100%,.15) 2px, transparent 3px);
   content: "";
   display: -moz-box;
-  height: 2px;
+  border-top: 1px solid hsla(0,0%,100%,.15);
+  border-bottom: 1px solid hsla(0,0%,0%,.15);
   margin-top: -2px;
   position: relative;
   z-index: 2; /* navbar is at 1 */
 }
 
 @media (-moz-mac-yosemite-theme) {
   #navigator-toolbox:-moz-window-inactive::after {
-    background-image: linear-gradient(to top, hsla(0,0%,0%,.1), hsla(0,0%,0%,.1) 1px, hsla(0,0%,100%,0) 1px, hsla(0,0%,100%,0) 2px, transparent 3px);
+    border-top-style: none;
+    border-bottom-color: hsla(0,0%,0%,.1);
+    margin-top: -1px;
   }
 }
 
 #navigator-toolbox toolbarbutton:-moz-lwtheme {
   color: inherit;
   text-shadow: inherit;
 }
 
@@ -3116,70 +3118,16 @@ menulist.translate-infobar-element > .me
   width: 28em;
   max-width: 28em;
 }
 
 .addon-install-confirmation-name {
   font-weight: bold;
 }
 
-/* Ctrl-Tab */
-
-#ctrlTab-panel {
-  -moz-appearance: none;
-  -moz-window-shadow: none;
-  background: hsla(0,0%,33%,.85);
-  color: white;
-  border-style: none;
-  padding: 20px 10px 10px;
-  text-shadow: 0 0 1px hsl(0,0%,12%), 0 0 2px hsl(0,0%,12%);
-}
-
-.ctrlTab-favicon[src] {
-  background-color: white;
-  width: 20px;
-  height: 20px;
-  padding: 2px;
-}
-
-.ctrlTab-preview-inner > .tabPreview-canvas {
-  box-shadow: 1px 1px 2px hsl(0,0%,12%);
-}
-
-.ctrlTab-preview:not(#ctrlTab-showAll) > * > .ctrlTab-preview-inner > .tabPreview-canvas {
-  margin-bottom: 2px;
-}
-
-.ctrlTab-preview-inner {
-  padding-bottom: 10px;
-}
-
-#ctrlTab-showAll:not(:focus) > * > .ctrlTab-preview-inner {
-  padding: 10px;
-  background-color: rgba(255,255,255,.2);
-  border-radius: .5em;
-}
-
-.ctrlTab-preview:focus > * > .ctrlTab-preview-inner {
-  color: white;
-  background-color: rgba(0,0,0,.6);
-  text-shadow: none;
-  padding: 8px;
-  border: 2px solid white;
-  border-radius: .5em;
-}
-
-.ctrlTab-preview:not(#ctrlTab-showAll):focus > * > .ctrlTab-preview-inner {
-  margin: -10px -10px 0;
-}
-
-#ctrlTab-showAll {
-  margin-top: .5em;
-}
-
 /* Status panel */
 
 .statuspanel-label {
   margin: 0;
   padding: 2px 4px;
   background: linear-gradient(#fff, #ddd);
   border: 1px none #ccc;
   border-top-style: solid;
@@ -3197,16 +3145,17 @@ menulist.translate-infobar-element > .me
 .statuspanel-label:-moz-locale-dir(rtl):not([mirror]),
 .statuspanel-label:-moz-locale-dir(ltr)[mirror] {
   border-left-style: solid;
   border-top-left-radius: .3em;
   margin-left: 1em;
 }
 
 %include ../shared/fullscreen/warning.inc.css
+%include ../shared/ctrlTab.inc.css
 %include ../../../devtools/client/themes/responsivedesign.inc.css
 %include ../../../devtools/client/themes/commandline.inc.css
 %include ../shared/plugin-doorhanger.inc.css
 %include ../shared/login-doorhanger.inc.css
 
 %include downloads/indicator.css
 
 /* On mac, the popup notification contents are indented by default and so
--- a/browser/themes/osx/devedition.css
+++ b/browser/themes/osx/devedition.css
@@ -5,17 +5,18 @@
 %include ../shared/devedition.inc.css
 
 :root {
   --forwardbutton-width: 32px;
 }
 
 /* Use only 1px separator between nav toolbox and page content */
 #navigator-toolbox::after {
-  background: linear-gradient(to top, var(--chrome-navigator-toolbox-separator-color), var(--chrome-navigator-toolbox-separator-color) 1px, transparent 1px);
+  border-top-style: none;
+  margin-top: -1px;
 }
 
 /* Include extra space on left/right for dragging since there is no space above
    the tabs */
 #main-window[tabsintitlebar] #TabsToolbar {
   padding-left: 50px;
   padding-right: 50px;
   margin-bottom: 0; /* Don't overlap the inner highlight at the top of the nav-bar */
--- a/browser/themes/osx/searchbar.css
+++ b/browser/themes/osx/searchbar.css
@@ -116,66 +116,67 @@
   border-radius: 4px 4px 0 0;
 }
 
 .search-panel-current-engine {
   border-bottom: none;
 }
 
 .search-panel-tree {
-  border-top: 1px solid #ccc !important;
+  border-top: 1px solid var(--panel-separator-color) !important;
 }
 
 .search-panel-header {
   font-size: 10px;
   font-weight: normal;
-  background-color: rgb(245, 245, 245);
-  border-top: 1px solid #ccc;
+  background-color: hsla(210,4%,10%,.07);
+  border-top: 1px solid var(--panel-separator-color);
   margin: 0;
   padding: 3px 6px;
-  color: #666;
+  color: GrayText;
 }
 
 .search-panel-header > label {
   margin-top: 2px !important;
   margin-bottom: 2px !important;
 }
 
 .search-panel-current-input > label {
   margin: 2px 0 !important;
 }
 
 .search-panel-input-value {
-  color: black;
+  color: -moz-fieldtext;
 }
 
 .search-panel-one-offs {
-  margin: 0 0 !important;
-  border-top: 1px solid #ccc;
+  margin: 0 !important;
+  border-top: 1px solid var(--panel-separator-color);
 }
 
 .searchbar-engine-one-off-item {
   -moz-appearance: none;
   display: inline-block;
   min-width: 48px;
   height: 32px;
-  margin: 0 0;
-  padding: 0 0;
-  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAWCAYAAAABxvaqAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gofECQNNVW2/AAAABBJREFUGFdjOHPmzH8GehEA/KpKg9YTf4AAAAAASUVORK5CYII=');
+  margin: 0;
+  padding: 0;
+  background: linear-gradient(transparent 15%, var(--panel-separator-color) 15%, var(--panel-separator-color) 85%, transparent 85%);
+  background-size: 1px auto;
   background-repeat: no-repeat;
   background-position: right center;
 }
 
 .searchbar-engine-one-off-item:-moz-locale-dir(rtl) {
   background-position: left center;
 }
 
 .searchbar-engine-one-off-item:not(.last-row) {
   box-sizing: content-box;
-  border-bottom: 1px solid #ccc;
+  border-bottom: 1px solid var(--panel-separator-color);
 }
 
 .search-setting-button-compact {
   border-bottom: none !important;
 }
 
 .search-panel-one-offs:not([compact=true]) > .searchbar-engine-one-off-item.last-of-row,
 .search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.last-of-row:not(.dummy),
@@ -199,26 +200,26 @@
   width: 16px;
   height: 16px;
 }
 
 .addengine-item {
   -moz-appearance: none;
   font-size: 10px;
   height: 32px;
-  margin: 0 0;
+  margin: 0;
   padding: 0 10px;
 }
 
 .addengine-item > .button-box {
   -moz-box-pack: start;
 }
 
 .addengine-item:first-of-type {
-  border-top: 1px solid #ccc;
+  border-top: 1px solid var(--panel-separator-color);
 }
 
 .addengine-item[selected] {
   background-color: Highlight;
   color: HighlightText;
 }
 
 .addengine-icon {
@@ -277,18 +278,17 @@
 
 .search-setting-button {
   -moz-appearance: none;
   border-radius: 0 0 4px 4px;
   min-height: 32px;
 }
 
 .search-setting-button[selected] {
-  background-color: #d3d3d3;
-  border-top-color: #bdbebe;
+  background-color: hsla(210,4%,10%,.15);
 }
 
 .search-setting-button-compact {
   list-style-image: url("chrome://browser/skin/gear.svg#gear");
 }
 
 .search-setting-button-compact[selected] {
   list-style-image: url("chrome://browser/skin/gear.svg#gear-inverted");
copy from browser/themes/windows/browser.css
copy to browser/themes/shared/ctrlTab.inc.css
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/shared/ctrlTab.inc.css
@@ -1,2413 +1,28 @@
+%if 0
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-@import url("chrome://global/skin/");
-
-@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
-@namespace html url("http://www.w3.org/1999/xhtml");
-@namespace svg url("http://www.w3.org/2000/svg");
-
-%include ../shared/browser.inc
-%include windowsShared.inc
-%filter substitution
-%define toolbarShadowColor hsla(209,67%,12%,0.35)
-%define forwardTransitionLength 150ms
-%define conditionalForwardWithUrlbar window:not([chromehidden~="toolbar"]) #urlbar-wrapper
-
-:root {
-  --space-above-tabbar: 15px;
-
-  --backbutton-urlbar-overlap: 6px;
-
-  /* icon width + border + horizontal padding (without the overlap from backbutton-urlbar-overlap) */
-  --forwardbutton-width: 25px;
-
-  --toolbarbutton-vertical-inner-padding: 2px;
-  --toolbarbutton-vertical-outer-padding: 8px;
-
-  --toolbarbutton-hover-background: rgba(0,0,0,.1);
-  --toolbarbutton-hover-bordercolor: rgba(0,0,0,.2);
-  --toolbarbutton-hover-boxshadow: none;
-
-  --toolbarbutton-active-background: rgba(0,0,0,.15);
-  --toolbarbutton-active-bordercolor: rgba(0,0,0,.3);
-  --toolbarbutton-active-boxshadow: 0 0 0 1px rgba(0,0,0,.15) inset;
-
-  --toolbarbutton-checkedhover-backgroundcolor: rgba(0,0,0,.1);
-
-  --urlbar-dropmarker-url: url("chrome://browser/skin/urlbar-history-dropmarker.png");
-  --urlbar-dropmarker-region: rect(0px, 11px, 14px, 0px);
-  --urlbar-dropmarker-hover-region: rect(0px, 22px, 14px, 11px);
-  --urlbar-dropmarker-active-region: rect(0px, 33px, 14px, 22px);
-  --urlbar-dropmarker-2x-url: url("chrome://browser/skin/urlbar-history-dropmarker@2x.png");
-  --urlbar-dropmarker-2x-region: rect(0, 22px, 28px, 0);
-  --urlbar-dropmarker-hover-2x-region: rect(0, 44px, 28px, 22px);
-  --urlbar-dropmarker-active-2x-region: rect(0, 66px, 28px, 44px);
-
-  --panel-separator-color: ThreeDLightShadow;
-
-  --urlbar-separator-color: ThreeDLightShadow;
-}
-
-@media (-moz-windows-default-theme) {
-  :root {
-    --panel-separator-color: hsla(210,4%,10%,.14);
-  }
-}
-
-#nav-bar[brighttext] {
-  --toolbarbutton-hover-background: rgba(255,255,255,.25);
-  --toolbarbutton-hover-bordercolor: rgba(255,255,255,.5);
-
-  --toolbarbutton-active-background: rgba(255,255,255,.4);
-  --toolbarbutton-active-bordercolor: rgba(255,255,255,.7);
-  --toolbarbutton-active-boxshadow: 0 0 0 1px rgba(255,255,255,.4) inset;
-
-  --toolbarbutton-checkedhover-backgroundcolor: rgba(255,255,255,.3);
-}
-
-#nav-bar:-moz-lwtheme {
-  --toolbarbutton-hover-background: rgba(255,255,255,.25);
-  --toolbarbutton-hover-bordercolor: rgba(0,0,0,.2);
-
-  --toolbarbutton-active-background: rgba(70%,70%,70%,.25);
-  --toolbarbutton-active-bordercolor: rgba(0,0,0,.3);
-  --toolbarbutton-active-boxshadow: 0 0 2px rgba(0,0,0,.6) inset;
-
-  --toolbarbutton-checkedhover-backgroundcolor: rgba(85%,85%,85%,.25);
-}
-
-#menubar-items {
-  -moz-box-orient: vertical; /* for flex hack */
-}
-
-#main-menubar {
-  -moz-box-flex: 1; /* make menu items expand to fill toolbar height */
-}
-
-/* Hides the titlebar-placeholder underneath the window caption buttons when we
-   are not autohiding the menubar. */
-#toolbar-menubar:not([autohide="true"]) + #TabsToolbar > .titlebar-placeholder[type="caption-buttons"] {
-  display: none;
-}
-
-/* We want a 4px gap between the TabsToolbar and the toolbar-menubar when the
-   toolbar-menu is displayed, and a 16px gap when it is not. 1px is taken care
-   of by the (light) outer shadow of the tab, the remaining 3/15 are these margins. */
-#toolbar-menubar:not([autohide=true]) ~ #TabsToolbar:not([inFullscreen]),
-#toolbar-menubar[autohide=true]:not([inactive]) ~ #TabsToolbar:not([inFullscreen]) {
-  margin-top: 3px;
-}
-
-#main-window[tabsintitlebar][sizemode="normal"]:not([inFullscreen])[chromehidden~="menubar"] #toolbar-menubar ~ #TabsToolbar,
-#main-window[tabsintitlebar][sizemode="normal"]:not([inFullscreen]) #toolbar-menubar[autohide="true"][inactive] ~ #TabsToolbar {
-  margin-top: var(--space-above-tabbar);
-}
-
-#main-window[customize-entered][tabsintitlebar]:not([inFullscreen]) #toolbar-menubar[customizing-dragovertarget].customization-target::before,
-#main-window[customize-entered][tabsintitlebar]:not([inFullscreen]) #TabsToolbar[customizing-dragovertarget].customization-target::before,
-#main-window[customize-entered][tabsintitlebar]:not([inFullscreen]) #toolbar-menubar.customization-target:hover::before,
-#main-window[customize-entered][tabsintitlebar]:not([inFullscreen]) #TabsToolbar.customization-target:hover::before {
-  outline-color: CaptionText;
-}
-
-#navigator-toolbox {
-  -moz-appearance: none;
-  background-color: transparent;
-  border-top: none;
-}
-
-#navigator-toolbox::after {
-  content: "";
-  display: -moz-box;
-  -moz-box-ordinal-group: 101; /* tabs toolbar is 100 */
-  height: 1px;
-  background-color: ThreeDShadow;
-}
-
-@media (-moz-windows-default-theme) {
-  @media (-moz-os-version: windows-vista),
-         (-moz-os-version: windows-win7) {
-    #navigator-toolbox::after {
-      background-color: #aabccf;
-    }
-  }
-
-  @media (-moz-os-version: windows-win8),
-         (-moz-os-version: windows-win10) {
-    #navigator-toolbox::after {
-      background-color: #c2c2c2;
-    }
-  }
-}
-
-#navigator-toolbox:-moz-lwtheme::after {
-  background-color: rgba(0,0,0,.3);
-}
-
-#navigator-toolbox > toolbar {
-  -moz-appearance: none;
-  border-style: none;
-}
-
-#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar) {
-  background-clip: padding-box;
-  background-image: linear-gradient(@toolbarHighlight@, @toolbarHighlight@);
-}
-
-@media (-moz-os-version: windows-xp),
-       (-moz-os-version: windows-vista),
-       (-moz-os-version: windows-win7) {
-  #nav-bar {
-    background-image: linear-gradient(@toolbarHighlight@, transparent) !important;
-  }
-
-  #navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):not(#nav-bar) {
-    background-image: none;
-  }
-}
-
-#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):not(:-moz-lwtheme) {
-  background-color: -moz-Dialog;
-}
-
-#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):not(#nav-bar):not(#addon-bar) {
-  overflow: -moz-hidden-unscrollable;
-  max-height: 4em;
-  transition: min-height 170ms ease-out, max-height 170ms ease-out;
-  padding: 0 5px;
-}
-
-#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):not(#nav-bar):not(#addon-bar)[collapsed=true] {
-  min-height: 0.1px;
-  max-height: 0;
-  transition: min-height 170ms ease-out, max-height 170ms ease-out, visibility 170ms linear;
-}
-
-@media not all and (-moz-windows-compositor),
-       not all and (-moz-windows-default-theme) {
-  /* Please keep the menu text colors in this media block in sync with
-   * devedition.css, minus the :not(:-moz-lwtheme) condition - see Bug 1165718.
-   */
-  #main-window[tabsintitlebar]:not([inFullscreen]) #toolbar-menubar:not(:-moz-lwtheme),
-  #main-window[tabsintitlebar]:not([inFullscreen]) #TabsToolbar:not(:-moz-lwtheme) {
-    color: CaptionText;
-  }
-
-  #main-window[tabsintitlebar]:not([inFullscreen]) #toolbar-menubar:not(:-moz-lwtheme):-moz-window-inactive,
-  #main-window[tabsintitlebar]:not([inFullscreen]) #TabsToolbar:not(:-moz-lwtheme):-moz-window-inactive {
-    color: InactiveCaptionText;
-  }
-}
-
-@media not all and (-moz-windows-compositor) {
-  #main-window[tabsintitlebar] #titlebar:-moz-lwtheme {
-    visibility: hidden;
-  }
-
-  #main-window[tabsintitlebar] #titlebar-content:-moz-lwtheme {
-    -moz-binding: url("chrome://global/content/bindings/general.xml#windowdragbox");
-    visibility: visible;
-  }
-
-  /* Top-level menu appearance has transparent background, so the text color
-     needs to be inherited from our custom menubar too. */
-  #main-window[tabsintitlebar] #main-menubar > menu:not(:-moz-lwtheme) {
-    color: inherit;
-  }
-}
-
-/**
- * In the classic themes, the titlebar has a horizontal gradient, which is
- * problematic for reading the text of background tabs when they're in the
- * titlebar. We side-step this issue by layering our own background underneath
- * the tabs. Unfortunately, this requires a bunch of positioning in order to get
- * text and icons to not appear fuzzy.
- */
-@media (-moz-windows-classic) {
-  /**
-   * We need to bump up the z-index of the tabbrowser-tabs so that they appear
-   * over top of the fog we're applying for classic themes, as well as the nav-bar.
-   */
-  #main-window[tabsintitlebar]:not([sizemode=fullscreen]) #tabbrowser-tabs {
-    position: relative;
-    z-index: 2;
-  }
-
-  #main-window[tabsintitlebar] #TabsToolbar:not(:-moz-lwtheme) {
-    position: relative;
-  }
-
-  #main-window[tabsintitlebar]:not([sizemode=fullscreen]) #TabsToolbar:not(:-moz-lwtheme)::after {
-    /* Because we use placeholders for window controls etc. in the tabstrip,
-     * and position those with ordinal attributes, and because our layout code
-     * expects :before/:after nodes to come first/last in the frame list,
-     * we have to reorder this element to come last, hence the
-     * ordinal group value (see bug 853415). */
-    -moz-box-ordinal-group: 1001;
-    box-shadow: 0 0 50px 8px ActiveCaption;
-    content: "";
-    display: -moz-box;
-    height: 0;
-    margin: 0 50px;
-    position: absolute;
-    pointer-events: none;
-    top: 100%;
-    width: -moz-available;
-  }
-
-  #main-window[tabsintitlebar]:not([sizemode=fullscreen]) #TabsToolbar:not(:-moz-lwtheme):-moz-window-inactive::after {
-    box-shadow: 0 0 50px 8px InactiveCaption;
-  }
-
-  #main-window[tabsintitlebar]:not([sizemode=fullscreen]) toolbar[customindex]:not(:-moz-lwtheme),
-  #main-window[tabsintitlebar]:not([sizemode=fullscreen]) #PersonalToolbar:not(:-moz-lwtheme) {
-    position: relative;
-  }
-
-  /* Need to constrain the box shadow fade to avoid overlapping layers, see bug 886281. */
-  #main-window[tabsintitlebar]:not([sizemode=fullscreen]) #navigator-toolbox:not(:-moz-lwtheme) {
-    overflow: -moz-hidden-unscrollable;
-  }
-
-  /**
-   * When the tabstrip is overflowed, pinned tab separators get position: absolute,
-   * which makes the pinned tab separators leak over the nav-bar highlight. Forcing
-   * the element to snap to the bottom of the client rect works around the issue.
-   */
-  #main-window[tabsintitlebar] #tabbrowser-tabs[positionpinnedtabs] > .tabbrowser-tab[pinned]::before {
-    bottom: 0px;
-  }
-
-  #main-window[tabsintitlebar]:not([sizemode=fullscreen]) #TabsToolbar .toolbarbutton-1 {
-    position: relative;
-    z-index: 1;
-  }
-
-  /**
-   * With the tabbrowser-tabs element z-index'd above the nav-bar, we now get the
-   * scrollbox button borders leaking over the nav-bar highlight. This transparent bottom
-   * border forces the scrollbox button borders to terminate a pixel early, working
-   * around the issue.
-   */
-  #main-window[tabsintitlebar]:not([sizemode=fullscreen]) .tabbrowser-arrowscrollbox > .scrollbutton-up,
-  #main-window[tabsintitlebar]:not([sizemode=fullscreen]) .tabbrowser-arrowscrollbox > .scrollbutton-down {
-    border-bottom: 1px solid transparent;
-  }
-
-  #main-window[tabsintitlebar][sizemode="normal"] > #tab-view-deck > #browser-panel:-moz-lwtheme {
-    /* Render a window top border: */
-    background-image: linear-gradient(to bottom,
-          ThreeDLightShadow 0, ThreeDLightShadow 1px,
-          ThreeDHighlight 1px, ThreeDHighlight 2px,
-          ActiveBorder 2px, ActiveBorder 4px, transparent 4px);
-  }
-
-  /* End classic titlebar gradient */
-
-  #main-window[tabsintitlebar]:not([inFullscreen]) :-moz-any(#TabsToolbar, #toolbar-menubar) toolbarbutton:not(:-moz-lwtheme) {
-    color: inherit;
-  }
-}
-
-/* Render a window top border for lwthemes on WinXP modern themes: */
-@media (-moz-windows-theme: luna-blue) {
-  #main-window[tabsintitlebar][sizemode="normal"] > #tab-view-deck > #browser-panel:-moz-lwtheme {
-    background-image: linear-gradient(to bottom,
-        rgb(8, 49, 216) 0, rgb(8, 49, 216) 1px,
-        rgb(15, 77, 227) 1px, rgb(15, 77, 227) 2px,
-        rgb(22, 106, 238) 2px, rgb(22, 106, 238) 3px,
-        rgb(8, 85, 221) 3px, rgb(8, 85, 221) 4px,
-        transparent 4px);
-  }
-
-  #main-window[tabsintitlebar][sizemode="normal"] > #tab-view-deck > #browser-panel:-moz-lwtheme:-moz-window-inactive {
-    background-image: linear-gradient(to bottom,
-        rgb(91, 104, 205) 0, rgb(91, 104, 205) 1px,
-        rgb(116, 128, 220) 1px, rgb(116, 128, 220) 2px,
-        rgb(117, 140, 221) 2px, rgb(117, 140, 221) 4px,
-        transparent 4px);
-  }
-}
-
-@media (-moz-windows-theme: luna-silver) {
-  #main-window[tabsintitlebar][sizemode="normal"] > #tab-view-deck > #browser-panel:-moz-lwtheme {
-    background-image: linear-gradient(to bottom,
-        rgb(102,102,126) 0, rgb(102,102,126) 1px,
-        rgb(168,167,191) 1px, rgb(168,167,191) 2px,
-        white 2px, white 3px,
-        rgb(188,188,207) 3px, rgb(188,188,207) 4px,
-        transparent 4px);
-  }
-
-  #main-window[tabsintitlebar][sizemode="normal"] > #tab-view-deck > #browser-panel:-moz-lwtheme:-moz-window-inactive {
-    background-image: linear-gradient(to bottom,
-        rgb(186,186,197) 0, rgb(186,186,197) 1px,
-        rgb(236,238,245) 1px, rgb(236,238,245) 2px,
-        white 2px, white 3px,
-        rgb(215,215,227) 3px, rgb(215,215,227) 4px,
-        transparent 4px);
-  }
-}
-
-@media (-moz-windows-theme: luna-olive) {
-  #main-window[tabsintitlebar][sizemode="normal"] > #tab-view-deck > #browser-panel:-moz-lwtheme {
-    background-image: linear-gradient(to bottom,
-        rgb(139,161,105) 0, rgb(139,161,105) 1px,
-        rgb(171, 189, 133) 1px, rgb(171, 189, 133) 2px,
-        rgb(164,178,127) 2px, rgb(164,178,127) 3px,
-        transparent 3px);
-  }
-
-  #main-window[tabsintitlebar][sizemode="normal"] > #tab-view-deck > #browser-panel:-moz-lwtheme:-moz-window-inactive {
-    background-image: linear-gradient(to bottom,
-        rgb(207, 214, 188) 0, rgb(207, 214, 188) 1px,
-        rgb(224, 226, 200) 1px, rgb(224, 226, 200) 2px,
-        rgb(214, 216, 190) 2px, rgb(214, 216, 190) 3px,
-        transparent 3px);
-  }
-}
-
-#TabsToolbar:not([collapsed="true"]) + #nav-bar {
-  /* Move up into the TabsToolbar for the inner highlight at the top of the nav-bar */
-  margin-top: calc(-1 * var(--navbar-tab-toolbar-highlight-overlap));
-  /* Position the toolbar above the bottom of background tabs */
-  position: relative;
-  z-index: 1;
-}
-
-#nav-bar {
-  border-top: 1px solid @toolbarShadowColor@ !important;
-  box-shadow: 0 1px 0 @toolbarHighlight@ inset;
-}
-@media not all and (-moz-windows-compositor) {
-  #TabsToolbar[collapsed="true"] + #nav-bar {
-    border-top-style: none !important;
-  }
-}
-
-#personal-bookmarks {
-  min-height: 24px;
-}
-
-#print-preview-toolbar:not(:-moz-lwtheme) {
-  -moz-appearance: toolbox;
-}
-
-#browser-bottombox:not(:-moz-lwtheme) {
-  background-color: -moz-dialog;
-}
-
-@media (-moz-os-version: windows-xp) and (-moz-windows-default-theme) {
-  #main-window[tabsintitlebar][sizemode="normal"] #toolbar-menubar {
-    margin-top: 4px;
-  }
-}
-
-/* ::::: titlebar ::::: */
-
-#main-window[sizemode="normal"] > #titlebar {
-  -moz-appearance: -moz-window-titlebar;
-}
-
-#main-window[sizemode="maximized"] > #titlebar {
-  -moz-appearance: -moz-window-titlebar-maximized;
-}
-
-@media (-moz-windows-classic) {
-  #main-window[tabsintitlebar][sizemode="normal"] > #tab-view-deck > #browser-panel > #navigator-toolbox > #toolbar-menubar {
-    margin-top: 4px;
-  }
-}
-
-/* The button box must appear on top of the navigator-toolbox in order for
- * click and hover mouse events to work properly for the button in the restored
- * window state. Otherwise, elements in the navigator-toolbox, like the menubar,
- * can swallow those events. It will also place the buttons above the fog on
- * themes with Aero Glass.
- */
-#titlebar-buttonbox {
-  z-index: 1;
-}
-
-.titlebar-placeholder[type="caption-buttons"] {
-  margin-left: 22px; /* space needed for Aero Snap */
-}
-
-@media (-moz-os-version: windows-xp) {
-  .titlebar-placeholder[type="caption-buttons"] {
-    margin-left: 10px; /* less space needed on XP because there's no Aero Snap */
-  }
-}
-
-/* titlebar command buttons */
-
-#titlebar-min {
-  -moz-appearance: -moz-window-button-minimize;
-}
-
-#titlebar-max {
-  -moz-appearance: -moz-window-button-maximize;
-}
-
-#main-window[sizemode="maximized"] #titlebar-max {
-  -moz-appearance: -moz-window-button-restore;
-}
-
-#titlebar-close {
-  -moz-appearance: -moz-window-button-close;
-}
-
-@media not all and (-moz-windows-classic) {
-  #titlebar-min {
-    margin-inline-end: 2px;
-  }
-}
-
-/* ::::: bookmark buttons ::::: */
-
-toolbarbutton.bookmark-item:not(.subviewbutton),
-#personal-bookmarks[cui-areatype="toolbar"]:not([overflowedItem=true]) > #bookmarks-toolbar-placeholder {
-  margin: 0;
-  padding: 2px 3px;
-  -moz-appearance: none;
-  border: 1px solid transparent;
-  border-radius: 1px;
-  transition-property: background-color, border-color, box-shadow;
-  transition-duration: 150ms;
-}
-
-toolbarbutton.bookmark-item:not(.subviewbutton):hover:not([disabled="true"]):not([open]) {
-  border-color: var(--toolbarbutton-hover-bordercolor);
-  background: var(--toolbarbutton-hover-background);
-}
-
-toolbarbutton.bookmark-item:not(.subviewbutton):hover:active:not([disabled="true"]),
-toolbarbutton.bookmark-item[open="true"] {
-  border-color: var(--toolbarbutton-active-bordercolor);
-  box-shadow: var(--toolbarbutton-active-boxshadow);
-  background: var(--toolbarbutton-active-background);
-}
-
-toolbarbutton.bookmark-item:not(.subviewbutton):hover:not([disabled="true"]):-moz-lwtheme {
-  background-color: rgba(255,255,255,.25);
-  background-origin: padding-box;
-  background-clip: padding-box;
-}
-
-.bookmark-item > .toolbarbutton-icon,
-#personal-bookmarks[cui-areatype="toolbar"] > #bookmarks-toolbar-placeholder > .toolbarbutton-icon {
-  width: 16px;
-  height: 16px;
-}
-
-/* Force the display of the label for bookmarks */
-.bookmark-item > .toolbarbutton-text,
-#personal-bookmarks[cui-areatype="toolbar"] > #bookmarks-toolbar-placeholder > .toolbarbutton-text {
-  display: -moz-box !important;
-}
-
-.bookmark-item > .toolbarbutton-menu-dropmarker {
-  display: none;
-}
-
-#bookmarks-toolbar-placeholder {
-  list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png") !important;
-}
-
-toolbarpaletteitem[place="palette"] > #personal-bookmarks > #bookmarks-toolbar-placeholder,
-#personal-bookmarks[cui-areatype="menu-panel"] > #bookmarks-toolbar-placeholder {
-  list-style-image: url("chrome://browser/skin/places/bookmarksToolbar-menuPanel.png") !important;
-}
-
-/* ----- BOOKMARK STAR ANIMATION ----- */
-
-@keyframes animation-bookmarkAdded {
-  from { transform: rotate(0deg) translateX(-16px) rotate(0deg) scale(1); opacity: 0; }
-  60%  { transform: rotate(180deg) translateX(-16px) rotate(-180deg) scale(2.2); opacity: 1; }
-  80%  { opacity: 1; }
-  to   { transform: rotate(180deg) translateX(-16px) rotate(-180deg) scale(1); opacity: 0; }
-}
-
-@keyframes animation-bookmarkPulse {
-  from { transform: scale(1); }
-  50%  { transform: scale(1.3); }
-  to   { transform: scale(1); }
-}
-
-#bookmarked-notification-container {
-  min-height: 1px;
-  min-width: 1px;
-  height: 1px;
-  margin-bottom: -1px;
-  z-index: 5;
-  position: relative;
-}
-
-#bookmarked-notification {
-  background-size: 16px;
-  background-position: center;
-  background-repeat: no-repeat;
-  width: 16px;
-  height: 16px;
-  opacity: 0;
-}
-
-#bookmarked-notification-dropmarker-anchor {
-  z-index: -1;
-  position: relative;
-}
-
-#bookmarked-notification-dropmarker-icon {
-  width: 18px;
-  height: 18px;
-  visibility: hidden;
-}
-
-#bookmarked-notification-anchor[notification="finish"] > #bookmarked-notification {
-  background-image: url("chrome://browser/skin/places/bookmarks-notification-finish.png");
-  animation: animation-bookmarkAdded 800ms;
-  animation-timing-function: ease, ease, ease;
-}
-
-#bookmarks-menu-button[notification="finish"] > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon {
-  list-style-image: none !important;
-}
-
-#bookmarked-notification-dropmarker-anchor[notification="finish"] > #bookmarked-notification-dropmarker-icon {
-  visibility: visible;
-  animation: animation-bookmarkPulse 300ms;
-  animation-delay: 600ms;
-  animation-timing-function: ease-out;
-}
-
-/* ::::: bookmark menus ::::: */
-
-menu.bookmark-item,
-menuitem.bookmark-item {
-  min-width: 0;
-  max-width: 32em;
-}
-
-.bookmark-item:not(.subviewbutton) > .menu-iconic-left {
-  margin-top: 0;
-  margin-bottom: 0;
-}
-
-.bookmark-item > .menu-iconic-left > .menu-iconic-icon {
-  padding-inline-start: 0px;
-}
-
-/* ::::: bookmark items ::::: */
-
-.bookmark-item  {
-  list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
-}
-
-.bookmark-item[container] {
-  list-style-image: url("chrome://global/skin/icons/folder-item.png");
-  -moz-image-region: rect(0px, 32px, 16px, 16px);
-}
-
-.bookmark-item[container][open] {
-  -moz-image-region: rect(16px, 32px, 32px, 16px);
-}
-
-.bookmark-item[container][livemark] {
-  list-style-image: url("chrome://browser/skin/livemark-folder.png");
-  -moz-image-region: auto;
-}
-
-.bookmark-item[container][livemark] .bookmark-item {
-  list-style-image: url("chrome://browser/skin/places/livemark-item.png");
-  -moz-image-region: rect(0px, 16px, 16px, 0px);
-}
-
-.bookmark-item[container][livemark] .bookmark-item[visited] {
-  -moz-image-region: rect(0px, 32px, 16px, 16px);
-}
-
-.bookmark-item[container][query] {
-  list-style-image: url("chrome://browser/skin/places/query.png");
-  -moz-image-region: auto;
-}
-
-.bookmark-item[query][tagContainer] {
-  list-style-image: url("chrome://browser/skin/places/tag.png");
-  -moz-image-region: auto;
-}
-
-.bookmark-item[query][dayContainer] {
-  list-style-image: url("chrome://browser/skin/places/calendar.png");
-  -moz-image-region: auto;
-}
-
-.bookmark-item[query][hostContainer] {
-  list-style-image: url("chrome://global/skin/icons/folder-item.png");
-  -moz-image-region: rect(0px, 32px, 16px, 16px);
-}
-
-.bookmark-item[query][hostContainer][open] {
-  list-style-image: url("chrome://global/skin/icons/folder-item.png");
-  -moz-image-region: rect(16px, 32px, 32px, 16px);
-}
-
-.bookmark-item[cutting] > .toolbarbutton-icon,
-.bookmark-item[cutting] > .menu-iconic-left > .menu-iconic-icon {
-  opacity: 0.5;
-}
-
-.bookmark-item[cutting] > .toolbarbutton-text,
-.bookmark-item[cutting] > .menu-iconic-left > .menu-iconic-text {
-  opacity: 0.7;
-}
-
-/* ::::: primary toolbar buttons ::::: */
-
-%include ../shared/toolbarbuttons.inc.css
-
-@media (-moz-windows-theme: luna-silver) and (max-resolution: 1dppx) {
-  :-moz-any(@primaryToolbarButtons@),
-  #bookmarks-menu-button.toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon {
-    list-style-image: url("chrome://browser/skin/Toolbar-lunaSilver.png");
-  }
-}
-
-#main-window:not([customizing]) .toolbarbutton-1[disabled=true] > .toolbarbutton-icon,
-#main-window:not([customizing]) .toolbarbutton-1[disabled=true] > .toolbarbutton-menu-dropmarker,
-#main-window:not([customizing]) .toolbarbutton-1[disabled=true] > .toolbarbutton-menubutton-dropmarker,
-#main-window:not([customizing]) .toolbarbutton-1[disabled=true] > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
-#main-window:not([customizing]) .toolbarbutton-1 > .toolbarbutton-menubutton-button[disabled=true] > .toolbarbutton-icon {
-  opacity: .4;
-}
-
-.toolbarbutton-1 > .toolbarbutton-menu-dropmarker,
-.toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
-  list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow.png");
-}
-
-toolbar[brighttext] .toolbarbutton-1 > .toolbarbutton-menu-dropmarker,
-toolbar[brighttext] .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
-  list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow-inverted.png");
-}
-
-.toolbarbutton-1 > .toolbarbutton-icon,
-.toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon {
-  margin-inline-end: 0;
-}
-
-:-moz-any(toolbar, .widget-overflow-list) .toolbarbutton-1 > .toolbarbutton-icon,
-:-moz-any(toolbar, .widget-overflow-list) .toolbarbutton-1 > :-moz-any(.toolbarbutton-menubutton-button, .toolbarbutton-badge-stack) > .toolbarbutton-icon {
-  max-width: 16px;
-}
-
-:-moz-any(toolbar, .widget-overflow-list) .toolbarbutton-1:-moz-any(@primaryToolbarButtons@, .toolbarbutton-legacy-addon) > .toolbarbutton-icon,
-:-moz-any(toolbar, .widget-overflow-list) .toolbarbutton-1:-moz-any(@primaryToolbarButtons@, .toolbarbutton-legacy-addon) > :-moz-any(.toolbarbutton-menubutton-button, .toolbarbutton-badge-stack) > .toolbarbutton-icon,
-#bookmarks-menu-button[cui-areatype="toolbar"] > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon {
-  max-width: 18px;
-}
-
-%include ../shared/menupanel.inc.css
-
-@media (-moz-windows-default-theme) {
-  :-moz-any(@primaryToolbarButtons@)[cui-areatype="menu-panel"][panel-multiview-anchor=true] > .toolbarbutton-icon,
-  :-moz-any(@primaryToolbarButtons@)[cui-areatype="menu-panel"][panel-multiview-anchor=true] > .toolbarbutton-badge-stack > .toolbarbutton-icon,
-  :-moz-any(@primaryToolbarButtons@)[cui-areatype="menu-panel"][panel-multiview-anchor=true] > .toolbarbutton-menubutton-button > .toolbarbutton-icon {
-    filter: url(chrome://browser/skin/filters.svg#fill);
-    fill: currentColor;
-  }
-}
-
-@media not all and (-moz-windows-default-theme) {
-  :-moz-any(@primaryToolbarButtons@)[cui-areatype="menu-panel"] > .toolbarbutton-icon,
-  :-moz-any(@primaryToolbarButtons@)[cui-areatype="menu-panel"] > .toolbarbutton-badge-stack > .toolbarbutton-icon,
-  :-moz-any(@primaryToolbarButtons@)[cui-areatype="menu-panel"] > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
-  toolbaritem[cui-areatype="menu-panel"] > :-moz-any(@nestedButtons@) > .toolbarbutton-icon {
-    filter: url(chrome://browser/skin/filters.svg#fill);
-    fill: currentColor;
-    opacity: 0.7 !important; /* !important overrides .toolbarbutton-1[disabled=true] rule */
-  }
-}
-
-.findbar-button,
-#nav-bar .toolbarbutton-1,
-#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button {
-  -moz-appearance: none;
-  border: none;
-  padding: 0;
-  background: none;
-}
-
-#nav-bar .toolbarbutton-1:not([type=menu-button]),
-#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button,
-#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
-  padding: var(--toolbarbutton-vertical-outer-padding) 2px;
-  -moz-box-pack: center;
-}
-
-#nav-bar #PanelUI-menu-button {
-  padding-inline-start: 5px;
-  padding-inline-end: 5px;
-}
-
-#nav-bar .toolbarbutton-1[type=panel],
-#nav-bar .toolbarbutton-1[type=menu]:not(#back-button):not(#forward-button):not(#feed-button):not(#PanelUI-menu-button) {
-  padding-left: 5px;
-  padding-right: 5px;
-}
-
-#nav-bar .toolbarbutton-1 > menupopup {
-  margin-top: -3px;
-}
-
-#nav-bar .toolbarbutton-1 > menupopup.cui-widget-panel {
-  margin-top: -8px;
-}
-
-#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button {
-  padding-inline-end: 0;
-}
-
-#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
-  padding-inline-start: 0;
-  -moz-box-align: center;
-}
-
-.findbar-button > .toolbarbutton-text,
-#nav-bar .toolbarbutton-1 > .toolbarbutton-icon,
-#nav-bar .toolbarbutton-1 > .toolbarbutton-text,
-#nav-bar .toolbarbutton-1 > .toolbarbutton-badge-stack,
-#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
-#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon,
-@conditionalForwardWithUrlbar@ > .toolbarbutton-1:-moz-any([disabled],:not([open]):not([disabled]):not(:active)) > .toolbarbutton-icon {
-  padding: var(--toolbarbutton-vertical-inner-padding) 6px;
-  background-origin: padding-box !important;
-  background-clip: padding-box !important;
-  border: 1px solid transparent;
-  border-radius: 1px;
-  transition-property: background-color, border-color, box-shadow;
-  transition-duration: 150ms;
-}
-
-#nav-bar .toolbarbutton-1 > .toolbarbutton-icon,
-#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
-#nav-bar #bookmarks-menu-button[cui-areatype="toolbar"] > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon {
-  /* horizontal padding + border + actual icon width */
-  max-width: 32px;
-}
-
-@media (-moz-os-version: windows-xp),
-       (-moz-os-version: windows-vista),
-       (-moz-os-version: windows-win7) {
-  /* < Win8 */
-  :root {
-    --toolbarbutton-hover-background: linear-gradient(hsla(0,0%,100%,.6), hsla(0,0%,100%,.1));
-    --toolbarbutton-hover-bordercolor: hsla(210,54%,20%,.15) hsla(210,54%,20%,.2) hsla(210,54%,20%,.25);
-    --toolbarbutton-hover-boxshadow: 0 1px hsla(0,0%,100%,.3) inset,
-                                     0 1px hsla(210,54%,20%,.03),
-                                     0 0 2px hsla(210,54%,20%,.1);
-
-    --toolbarbutton-active-background: hsla(210,54%,20%,.15) linear-gradient(hsla(0,0%,100%,.6), hsla(0,0%,100%,.1));
-    --toolbarbutton-active-bordercolor: hsla(210,54%,20%,.3) hsla(210,54%,20%,.35) hsla(210,54%,20%,.4);
-    --toolbarbutton-active-boxshadow: 0 1px 1px hsla(210,54%,20%,.1) inset,
-                                      0 0 1px hsla(210,54%,20%,.2) inset,
-/* allows keyhole-forward-clip-path to be used for non-hover as well as hover: */
-                                      0 1px 0 hsla(210,54%,20%,0),
-                                      0 0 2px hsla(210,54%,20%,0);
-
-    --toolbarbutton-checkedhover-backgroundcolor: rgba(90%,90%,90%,.4);
-  }
-}
-
-#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon:-moz-locale-dir(ltr),
-#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon:-moz-locale-dir(rtl) {
-  border-top-right-radius: 0;
-  border-bottom-right-radius: 0;
-}
-
-#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon:-moz-locale-dir(rtl),
-#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon:-moz-locale-dir(ltr) {
-  border-top-left-radius: 0;
-  border-bottom-left-radius: 0;
-}
-
-#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon {
-  border-inline-end-style: none;
-}
-
-#nav-bar .toolbarbutton-1:not(:-moz-any(@primaryToolbarButtons@, .toolbarbutton-legacy-addon)) > .toolbarbutton-icon,
-#nav-bar .toolbarbutton-1:not(:-moz-any(@primaryToolbarButtons@, .toolbarbutton-legacy-addon)) > .toolbarbutton-badge-stack,
-#nav-bar .toolbarbutton-1:not(:-moz-any(@primaryToolbarButtons@, .toolbarbutton-legacy-addon)) > .toolbarbutton-menubutton-button > .toolbarbutton-icon {
-  padding: calc(var(--toolbarbutton-vertical-inner-padding) + 1px) 7px;
-}
-
-#nav-bar .toolbarbutton-1[type=panel] > .toolbarbutton-icon,
-#nav-bar .toolbarbutton-1[type=panel] > .toolbarbutton-badge-stack,
-#nav-bar .toolbarbutton-1[type=menu]:not(#PanelUI-menu-button):not(#back-button):not(#forward-button) > .toolbarbutton-icon,
-#nav-bar .toolbarbutton-1[type=menu]:not(#PanelUI-menu-button) > .toolbarbutton-badge-stack,
-#nav-bar .toolbarbutton-1[type=menu] > .toolbarbutton-text /* hack for add-ons that forcefully display the label */ {
-  padding-inline-end: 17px;
-}
-
-#nav-bar .toolbarbutton-1[type=panel] > .toolbarbutton-icon,
-#nav-bar .toolbarbutton-1[type=menu]:not(#PanelUI-menu-button):not(#back-button):not(#forward-button) > .toolbarbutton-icon {
-  /* horizontal padding + border + icon width */
-  max-width: 43px;
-}
-
-#nav-bar .toolbarbutton-1 > .toolbarbutton-menu-dropmarker {
-  margin-inline-start: -15px;
-}
-
-#nav-bar #bookmarks-menu-button[cui-areatype="toolbar"] > .toolbarbutton-menubutton-button > .toolbarbutton-icon {
-  /* horizontal padding + border + actual icon width */
-  max-width: 31px;
-}
-
-#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon {
-  padding-top: calc(var(--toolbarbutton-vertical-inner-padding) + 6px);
-  padding-bottom: calc(var(--toolbarbutton-vertical-inner-padding) + 6px);
-}
-
-#nav-bar .toolbaritem-combined-buttons {
-  margin-left: 2px;
-  margin-right: 2px;
-}
-
-#nav-bar .toolbaritem-combined-buttons > .toolbarbutton-1 {
-  padding-left: 0;
-  padding-right: 0;
-}
-
-#nav-bar .toolbaritem-combined-buttons:not(:hover) > separator,
-#nav-bar .toolbarbutton-1:not(:hover):not(:active):not([open]) > .toolbarbutton-menubutton-dropmarker::before {
-  content: "";
-  display: -moz-box;
-  width: 1px;
-  height: 16px;
-  margin-inline-end: -1px;
-  background-image: linear-gradient(currentColor 0, currentColor 100%);
-  background-position: center;
-  background-repeat: no-repeat;
-  background-size: 1px 16px;
-  opacity: .2;
-}
-
-#nav-bar[brighttext] .toolbaritem-combined-buttons > separator,
-#nav-bar[brighttext] .toolbarbutton-1:not(:hover):not(:active):not([open]) > .toolbarbutton-menubutton-dropmarker::before {
-  opacity: .3;
-}
-
-.findbar-button:not(:-moz-any([checked="true"],[disabled="true"])):hover > .toolbarbutton-text,
-#nav-bar .toolbarbutton-1:not([disabled=true]) > .toolbarbutton-menubutton-button[open] + .toolbarbutton-menubutton-dropmarker > .dropmarker-icon,
-#nav-bar .toolbarbutton-1:not([disabled=true]):-moz-any(:hover,[open]) > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
-#nav-bar .toolbarbutton-1:not([disabled=true]):-moz-any(:hover,[open]) > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon,
-#nav-bar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-icon,
-#nav-bar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-text,
-#nav-bar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-badge-stack,
-@conditionalForwardWithUrlbar@ > #forward-button:not([open]):not(:active):not([disabled]):hover > .toolbarbutton-icon,
-#nav-bar .toolbarbutton-1:not([buttonover]):not([open]):not(:active):hover > .toolbarbutton-menubutton-dropmarker:not([disabled]) > .dropmarker-icon {
-  background: var(--toolbarbutton-hover-background);
-  border-color: var(--toolbarbutton-hover-bordercolor);
-  box-shadow: var(--toolbarbutton-hover-boxshadow);
-}
-
-.findbar-button:not([disabled=true]):-moz-any([checked="true"],:hover:active) > .toolbarbutton-text,
-#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled=true]):-moz-any(:hover:active, [open]) > .toolbarbutton-icon,
-#nav-bar .toolbarbutton-1[open] > .toolbarbutton-menubutton-dropmarker:not([disabled=true]) > .dropmarker-icon,
-#nav-bar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-icon,
-#nav-bar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-text,
-#nav-bar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-badge-stack {
-  background: var(--toolbarbutton-active-background);
-  border-color: var(--toolbarbutton-active-bordercolor);
-  box-shadow: var(--toolbarbutton-active-boxshadow);
-  transition-duration: 10ms;
-}
-
-#nav-bar .toolbarbutton-1[checked]:not(:active):hover > .toolbarbutton-icon {
-  background-color: var(--toolbarbutton-checkedhover-backgroundcolor);
-  transition: background-color .4s;
-}
-
-#TabsToolbar .toolbarbutton-1,
-#TabsToolbar .toolbarbutton-1 > .toolbarbutton-menubutton-button,
-.tabbrowser-arrowscrollbox > .scrollbutton-up,
-.tabbrowser-arrowscrollbox > .scrollbutton-down {
-  -moz-appearance: none;
-  border-style: none;
-  padding: 0 3px;
-}
-
-#TabsToolbar .toolbarbutton-1 {
-  margin-bottom: var(--tab-toolbar-navbar-overlap);
-}
-
-#TabsToolbar .toolbarbutton-1:not([disabled=true]):hover,
-#TabsToolbar .toolbarbutton-1[open],
-#TabsToolbar .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled=true]):hover,
-.tabbrowser-arrowscrollbox > .scrollbutton-up:not([disabled=true]):hover,
-.tabbrowser-arrowscrollbox > .scrollbutton-down:not([disabled=true]):hover {
-  background-image: linear-gradient(transparent, rgba(255,255,255,.5)),
-                    linear-gradient(transparent, rgba(0,0,0,.25) 30%),
-                    linear-gradient(transparent, rgba(0,0,0,.25) 30%);
-  background-position: 1px -1px, 0 -1px, 100% -1px;
-  background-size: calc(100% - 2px) 100%, 1px 100%, 1px 100%;
-  background-repeat: no-repeat;
-}
-
-/* unified back/forward button */
-
-:-moz-any(#back-button, #forward-button) > .toolbarbutton-icon {
-  border-color: var(--urlbar-border-color-hover) !important;
-}
-
-:-moz-any(#back-button, #forward-button):not(:hover):not(:active):not([open=true]) > .toolbarbutton-icon,
-:-moz-any(#back-button, #forward-button)[disabled=true] > .toolbarbutton-icon {
-  background-color: rgba(255,255,255,.15) !important;
-}
-
-#forward-button {
-  -moz-box-align: stretch; /* let the button shape grow vertically with the location bar */
-  padding: 0 !important;
-}
-
-#forward-button > menupopup {
-  margin-top: 1px !important;
-}
-
-#forward-button > .toolbarbutton-icon {
-  border-left-style: none !important;
-  border-radius: 0 !important;
-  padding-left: calc(var(--backbutton-urlbar-overlap) + 3px) !important;
-  padding-right: 3px !important;
-  max-width: calc(var(--forwardbutton-width) + var(--backbutton-urlbar-overlap)) !important;
-}
-
-@conditionalForwardWithUrlbar@:not([switchingtabs]) > #forward-button {
-  transition: margin-left @forwardTransitionLength@ ease-out;
-}
-
-@conditionalForwardWithUrlbar@ > #forward-button[disabled] {
-  margin-left: calc(0px - var(--forwardbutton-width) - var(--backbutton-urlbar-overlap));
-}
-
-@conditionalForwardWithUrlbar@:hover:not([switchingtabs]) > #forward-button[disabled] {
-  /* delay the hiding of the forward button when hovered to avoid accidental clicks on the url bar */
-  transition-delay: 100s;
-}
-
-@conditionalForwardWithUrlbar@:not(:hover) > #forward-button[disabled] {
-  /* when not hovered anymore, trigger a new transition to hide the forward button immediately */
-  margin-left: calc(-0.01px - var(--forwardbutton-width) - var(--backbutton-urlbar-overlap));
-}
-
-#back-button {
-  padding-top: 3px !important;
-  padding-bottom: 3px !important;
-  padding-inline-start: 5px !important;
-  padding-inline-end: 0 !important;
-  position: relative !important;
-  z-index: 1 !important;
-  border-radius: 0 10000px 10000px 0 !important;
-}
-
-#back-button:-moz-locale-dir(rtl) {
-  border-radius: 10000px 0 0 10000px !important;
-}
-
-#back-button > menupopup {
-  margin-top: -1px !important;
-}
-
-#back-button > .toolbarbutton-icon {
-  border-radius: 10000px !important;
-  padding: 6px !important;
-  max-width: 32px !important; /* icon width + horizontal padding + border */
-}
-
-#back-button:-moz-locale-dir(rtl) > .toolbarbutton-icon {
-  transform: scaleX(-1);
-}
-
-.unified-nav-back[_moz-menuactive]:-moz-locale-dir(ltr),
-.unified-nav-forward[_moz-menuactive]:-moz-locale-dir(rtl) {
-  list-style-image: url("chrome://browser/skin/menu-back.png") !important;
-}
-
-.unified-nav-forward[_moz-menuactive]:-moz-locale-dir(ltr),
-.unified-nav-back[_moz-menuactive]:-moz-locale-dir(rtl) {
-  list-style-image: url("chrome://browser/skin/menu-forward.png") !important;
-}
-
-/* undo close tab menu item */
-#alltabs_undoCloseTab {
-  list-style-image: url(chrome://browser/skin/undoCloseTab.png);
-}
-
-@media (min-resolution: 1.1dppx) {
-  #alltabs_undoCloseTab {
-    list-style-image: url(chrome://browser/skin/undoCloseTab@2x.png);
-  }
-  #alltabs_undoCloseTab > .toolbarbutton-icon {
-    width: 16px;
-  }
-}
-
-/* zoom control text (reset) button special case: */
-
-#nav-bar #zoom-reset-button > .toolbarbutton-text {
-  /* To make this line up with the icons, it needs the same height (18px) +
-   * padding (2 * 2px) + border (2 * 1px), but as a minimum because otherwise
-   * increase in text sizes would break things...
-   */
-  min-height: 24px;
-}
-
-/* ::::: fullscreen window controls ::::: */
-
-#minimize-button,
-#restore-button,
-#close-button {
-  -moz-appearance: none;
-  border: none;
-  margin: 0 !important;
-  padding: 6px 12px;
-}
-
-#minimize-button {
-  list-style-image: url(chrome://browser/skin/caption-buttons.svg#minimize);
-}
-
-#restore-button {
-  list-style-image: url(chrome://browser/skin/caption-buttons.svg#restore);
-}
-
-#minimize-button:hover,
-#restore-button:hover {
-  background-color: hsla(0, 0%, 0%, .12);
-}
-
-#minimize-button:hover:active,
-#restore-button:hover:active {
-  background-color: hsla(0, 0%, 0%, .22);
-}
-
-#close-button {
-  list-style-image: url(chrome://browser/skin/caption-buttons.svg#close);
-}
-
-#close-button:hover {
-  background-color: hsl(355, 86%, 49%);
-  list-style-image: url(chrome://browser/skin/caption-buttons.svg#close-white);
-}
-
-#close-button:hover:active {
-  background-color: hsl(355, 82%, 69%);
-}
-
-toolbar[brighttext] #minimize-button {
-  list-style-image: url(chrome://browser/skin/caption-buttons.svg#minimize-white);
-}
-
-toolbar[brighttext] #restore-button {
-  list-style-image: url(chrome://browser/skin/caption-buttons.svg#restore-white);
-}
-
-toolbar[brighttext] #close-button {
-  list-style-image: url(chrome://browser/skin/caption-buttons.svg#close-white);
-}
-
-@media (-moz-os-version: windows-xp),
-       (-moz-os-version: windows-vista),
-       (-moz-os-version: windows-win7) {
-  #window-controls {
-    margin-inline-start: 4px;
-  }
-
-  #minimize-button,
-  #restore-button,
-  #close-button {
-    list-style-image: url("chrome://global/skin/icons/windowControls.png");
-    padding: 0;
-  }
-
-  #minimize-button {
-    -moz-image-region: rect(0, 16px, 16px, 0);
-  }
-
-  #minimize-button:hover {
-    -moz-image-region: rect(16px, 16px, 32px, 0);
-  }
-
-  #minimize-button:hover:active {
-    -moz-image-region: rect(32px, 16px, 48px, 0);
-  }
-
-  #restore-button {
-    -moz-image-region: rect(0, 32px, 16px, 16px);
-  }
-
-  #restore-button:hover {
-    -moz-image-region: rect(16px, 32px, 32px, 16px);
-  }
-
-  #restore-button:hover:active {
-    -moz-image-region: rect(32px, 32px, 48px, 16px);
-  }
-
-  #close-button {
-    -moz-image-region: rect(0, 48px, 16px, 32px);
-    -moz-appearance: none;
-    border-style: none;
-    margin: 2px;
-  }
-
-  #close-button:hover {
-    -moz-image-region: rect(16px, 48px, 32px, 32px);
-  }
-
-  #close-button:hover:active {
-    -moz-image-region: rect(32px, 48px, 48px, 32px);
-  }
-}
-
-@media (-moz-os-version: windows-vista),
-       (-moz-os-version: windows-win7) {
-  #window-controls {
-    -moz-box-align: start;
-  }
-
-  #minimize-button,
-  #restore-button,
-  #close-button {
-    -moz-appearance: none;
-    border-style: none;
-    margin: 0;
-  }
-
-  #close-button {
-    -moz-image-region: rect(0, 49px, 16px, 32px);
-  }
-
-  #close-button:hover {
-    -moz-image-region: rect(16px, 49px, 32px, 32px);
-  }
-
-  #close-button:hover:active {
-    -moz-image-region: rect(32px, 49px, 48px, 32px);
-  }
-
-  #minimize-button:-moz-locale-dir(rtl),
-  #restore-button:-moz-locale-dir(rtl),
-  #close-button:-moz-locale-dir(rtl) {
-    transform: scaleX(-1);
-  }
-}
-
-/* ::::: Location Bar ::::: */
-
-#main-window {
-  --urlbar-border-color: ThreeDShadow;
-  --urlbar-border-color-hover: var(--urlbar-border-color);
-}
-
-#navigator-toolbox:-moz-lwtheme {
-  --urlbar-border-color: var(--toolbarbutton-hover-bordercolor);
-}
-
-@media (-moz-windows-default-theme) {
-  @media (-moz-os-version: windows-vista),
-         (-moz-os-version: windows-win7),
-         (-moz-os-version: windows-win8) {
-    #main-window:not(:-moz-lwtheme) {
-      --urlbar-border-color: hsla(210,54%,20%,.25) hsla(210,54%,20%,.27) hsla(210,54%,20%,.3);
-      --urlbar-border-color-hover: hsla(210,54%,20%,.35) hsla(210,54%,20%,.37) hsla(210,54%,20%,.4);
-    }
-  }
-
-  @media (-moz-os-version: windows-win10) {
-    #main-window:not(:-moz-lwtheme) {
-      --urlbar-border-color: hsl(0,0%,90%);
-      --urlbar-border-color-hover: hsl(0,0%,80%);
-    }
-  }
-}
-
-#urlbar,
-.searchbar-textbox {
-  -moz-appearance: none;
-  margin: 0 3px;
-  padding: 0;
-  background-clip: padding-box;
-  border: 1px solid;
-  border-color: var(--urlbar-border-color);
-}
-
-#urlbar:hover,
-.searchbar-textbox:hover {
-  border-color: var(--urlbar-border-color-hover);
-}
-
-@media (-moz-windows-default-theme) {
-  #urlbar,
-  .searchbar-textbox {
-    border-radius: 1px;
-  }
-
-  @media (-moz-os-version: windows-vista),
-         (-moz-os-version: windows-win7),
-         (-moz-os-version: windows-win8) {
-    #urlbar:not(:-moz-lwtheme),
-    .searchbar-textbox:not(:-moz-lwtheme) {
-      box-shadow: 0 1px 0 hsla(0,0%,0%,.01) inset,
-                  0 1px 0 hsla(0,0%,100%,.1);
-    }
-  }
-
-  @media (-moz-os-version: windows-win10) {
-    #urlbar:not(:-moz-lwtheme),
-    .searchbar-textbox:not(:-moz-lwtheme) {
-      padding: 1px;
-      transition-property: border-color, box-shadow;
-      transition-duration: .1s;
-    }
-
-    #urlbar:not(:-moz-lwtheme)[focused],
-    .searchbar-textbox:not(:-moz-lwtheme)[focused] {
-      box-shadow: 0 0 0 1px Highlight inset;
-    }
-  }
-
-  @media not all and (-moz-os-version: windows-xp) {
-    #urlbar:not(:-moz-lwtheme)[focused],
-    .searchbar-textbox:not(:-moz-lwtheme)[focused] {
-      border-color: Highlight;
-    }
-  }
-}
-
-@media (-moz-os-version: windows-win10) {
-  #urlbar,
-  .searchbar-textbox {
-    font-size: 1.15em;
-    min-height: 28px;
-  }
-
-  :root {
-    /* let toolbar buttons match the location and search bar's minimum height */
-    --toolbarbutton-vertical-inner-padding: 4px;
-    --toolbarbutton-vertical-outer-padding: 5px;
-  }
-}
-
-#urlbar:-moz-lwtheme,
-.searchbar-textbox:-moz-lwtheme {
-  background-color: rgba(255,255,255,.8);
-  color: black;
-}
-
-#urlbar:-moz-lwtheme:hover:not([readonly]),
-.searchbar-textbox:-moz-lwtheme:hover {
-  background-color: rgba(255,255,255,.9);
-}
-
-#urlbar:-moz-lwtheme[focused]:not([readonly]),
-.searchbar-textbox:-moz-lwtheme[focused] {
-  background-color: white;
-}
-
-@conditionalForwardWithUrlbar@ > #urlbar {
-  border-inline-start: none;
-  padding-inline-start: 0;
-  margin-left: 0;
-}
-
-@conditionalForwardWithUrlbar@ > #urlbar:-moz-locale-dir(ltr) {
-  border-top-left-radius: 0;
-  border-bottom-left-radius: 0;
-}
-
-@conditionalForwardWithUrlbar@ > #urlbar:-moz-locale-dir(rtl) {
-  border-top-right-radius: 0;
-  border-bottom-right-radius: 0;
-}
-
-@conditionalForwardWithUrlbar@ {
-  clip-path: url("chrome://browser/content/browser.xul#urlbar-back-button-clip-path");
-  margin-inline-start: calc(-1 * var(--backbutton-urlbar-overlap));
-}
-
-@media (-moz-os-version: windows-win10) {
-  @conditionalForwardWithUrlbar@ {
-    clip-path: url("chrome://browser/content/browser.xul#urlbar-back-button-clip-path-win10");
-  }
-
-  :root {
-    --backbutton-urlbar-overlap: 9px;
-  }
-}
-
-@conditionalForwardWithUrlbar@:-moz-locale-dir(rtl),
-@conditionalForwardWithUrlbar@ > #urlbar:-moz-locale-dir(rtl) {
-  /* let urlbar-back-button-clip-path clip the urlbar's right side for RTL */
-  transform: scaleX(-1);
-}
-
-@conditionalForwardWithUrlbar@:-moz-locale-dir(rtl) {
-  -moz-box-direction: reverse;
-}
-
-html|*.urlbar-input:-moz-lwtheme::-moz-placeholder,
-.searchbar-textbox:-moz-lwtheme > .autocomplete-textbox-container > .textbox-input-box > html|*.textbox-input::-moz-placeholder {
-  opacity: 1.0;
-  color: #777;
-}
-
-#urlbar-container {
-  -moz-box-align: center;
-}
-
-.urlbar-textbox-container {
-  -moz-box-align: stretch;
-}
-
-.urlbar-input-box {
-  margin-inline-start: 0;
-}
-
-.urlbar-input-box,
-#urlbar-display-box {
-  padding-inline-start: 4px;
-  border-inline-start: 1px solid var(--urlbar-separator-color);
-  border-image: linear-gradient(transparent 15%, var(--urlbar-separator-color) 15%, var(--urlbar-separator-color) 85%, transparent 85%);
-  border-image-slice: 1;
-}
-
-#urlbar-icons {
-  -moz-box-align: center;
-}
-
-.urlbar-icon {
-  padding: 0 3px;
-  /* 16x16 icon with border-box sizing */
-  width: 22px;
-  height: 16px;
-}
-
-/* ::::: URL Bar Zoom Reset Button ::::: */
-@keyframes urlbar-zoom-reset-pulse {
-  0% {
-    transform: scale(0);
-  }
-  75% {
-    transform: scale(1.5);
-  }
-  100% {
-    transform: scale(1.0);
-  }
-}
-
-#urlbar-zoom-button {
-  -moz-appearance: none;
-  margin: 0 3px;
-  font-size: .8em;
-  padding: 0 8px;
-  border-radius: 1em;
-  background-color: hsla(0,0%,0%,.05);
-  border: 1px solid ThreeDLightShadow;
-}
-
-#urlbar-zoom-button[animate="true"] {
-  animation-name: urlbar-zoom-reset-pulse;
-  animation-duration: 250ms;
-}
-
-#urlbar-zoom-button:hover:active {
-  background-color: hsla(0,0%,0%,.1);
-}
-
-#urlbar-zoom-button > .toolbarbutton-text {
-  display: -moz-box;
-}
-
-#urlbar-zoom-button > .toolbarbutton-icon {
-  display: none;
-}
-
-.search-go-container {
-  padding: 2px 2px;
-}
-
-#urlbar-search-footer {
-  border-top: 1px solid var(--panel-separator-color);
-  background-color: hsla(210,4%,10%,.07);
-}
-
-#urlbar-search-settings {
-  -moz-appearance: none;
-  -moz-user-focus: ignore;
-  color: GrayText;
-  margin: 0;
-  border: 0;
-  padding: 8px 20px;
-  background: transparent;
-}
-
-#urlbar-search-settings:hover {
-  background-color: hsla(210,4%,10%,.07);
-}
-
-#urlbar-search-settings:hover:active {
-  background-color: hsla(210,4%,10%,.12);
-}
-
-#urlbar-search-splitter {
-  min-width: 6px;
-  margin-inline-start: -3px;
-  border: none;
-  background: transparent;
-}
-
-#urlbar-search-splitter + #search-container > #searchbar > .searchbar-textbox {
-  margin-inline-start: 0;
-}
-
-.urlbar-display {
-  margin-top: 0;
-  margin-bottom: 0;
-  margin-inline-start: 0;
-  color: GrayText;
-}
-
-%include ../shared/urlbarSearchSuggestionsNotification.inc.css
-
-#search-container {
-  min-width: calc(54px + 11ch);
-}
-
-/* identity box */
-
-#identity-box:-moz-focusring {
-  outline: 1px dotted;
-  outline-offset: -3px;
-}
-
-/* Location bar dropmarker */
-
-.urlbar-history-dropmarker {
-  -moz-appearance: none;
-  padding: 0 3px;
-  background-color: transparent;
-  border: none;
-  width: auto;
-  list-style-image: var(--urlbar-dropmarker-url);
-  -moz-image-region: var(--urlbar-dropmarker-region);
-  transition: opacity 0.15s ease;
-}
-
-#urlbar-wrapper[switchingtabs] > #urlbar > .urlbar-textbox-container > .urlbar-history-dropmarker {
-  transition: none;
-}
-
-#navigator-toolbox:not(:hover) #nav-bar:not([customizing="true"]) #urlbar:not([focused]) > .urlbar-textbox-container > .urlbar-history-dropmarker {
-  opacity: 0;
-}
-
-.urlbar-history-dropmarker:hover {
-  -moz-image-region: var(--urlbar-dropmarker-hover-region);
-}
-
-.urlbar-history-dropmarker:hover:active,
-.urlbar-history-dropmarker[open="true"] {
-  -moz-image-region: var(--urlbar-dropmarker-active-region);
-}
-
-@media (min-resolution: 1.1dppx) {
-  .urlbar-history-dropmarker {
-    list-style-image: var(--urlbar-dropmarker-2x-url);
-    -moz-image-region: var(--urlbar-dropmarker-2x-region);
-  }
-
-  .urlbar-history-dropmarker:hover {
-    -moz-image-region: var(--urlbar-dropmarker-hover-2x-region);
-  }
-
-  .urlbar-history-dropmarker[open="true"],
-  .urlbar-history-dropmarker:hover:active {
-    -moz-image-region: var(--urlbar-dropmarker-active-2x-region);
-  }
-
-  .urlbar-history-dropmarker > .dropmarker-icon {
-    width: 11px;
-  }
-}
-
-/* page proxy icon */
-
-%include ../shared/identity-block/identity-block.inc.css
-
-/* autocomplete */
-
-#treecolAutoCompleteImage {
-  max-width: 36px;
-}
-
-.autocomplete-richlistbox {
-  padding: 4px;
-}
-
-.autocomplete-richlistitem {
-  height: 30px;
-  min-height: 30px;
-  font: message-box;
-  border-radius: 2px;
-  border: 1px solid transparent;
-}
-
-.autocomplete-richlistitem[selected=true] {
-  background-color: hsl(210, 80%, 52%);
-}
-
-.ac-title {
-  font-size: 14px;
-  color: hsl(0, 0%, 0%);
-}
-
-.ac-tags {
-  font-size: 12px;
-}
-
-html|span.ac-tag {
-  background-color: hsl(216, 0%, 88%);
-  color: hsl(0, 0%, 0%);
-  border-radius: 2px;
-  border: 1px solid transparent;
-  padding: 0 1px;
-}
-
-.ac-separator,
-.ac-url,
-.ac-action {
-  font-size: 12px;
-}
-
-.ac-separator {
-  color: hsl(0, 0%, 50%);
-}
-
-.ac-url {
-  color: hsl(210, 77%, 47%);
-}
-
-.ac-action {
-  color: hsl(178, 100%, 28%);
-}
-
-.ac-title[selected=true],
-.ac-separator[selected],
-.ac-url[selected=true],
-.ac-action[selected=true] {
-  color: hsl(0, 0%, 100%);
-}
-
-.ac-tags-text[selected] > html|span.ac-tag {
-  background-color: hsl(0, 0%, 100%);
-  color: hsl(210, 80%, 40%);
-}
-
-html|span.ac-emphasize-text-title,
-html|span.ac-emphasize-text-tag,
-html|span.ac-emphasize-text-url {
-  font-weight: 600;
-}
-
-@media not all and (-moz-windows-default-theme) {
-  .autocomplete-richlistitem[selected=true] {
-    background-color: Highlight;
-  }
-
-  .ac-title {
-    color: inherit;
-  }
-
-  html|span.ac-tag {
-    background-color: -moz-FieldText;
-    color: -moz-Field;
-  }
-
-  .ac-separator,
-  .ac-url,
-  .ac-action {
-    color: -moz-nativehyperlinktext;
-  }
-
-  .ac-tags-text[selected] > html|span.ac-tag {
-    background-color: HighlightText;
-    color: Highlight;
-  }
-}
-
-.ac-type-icon[type=bookmark] {
-  list-style-image: url("chrome://browser/skin/urlbar-star.svg#star");
-}
-
-.ac-type-icon[type=bookmark][selected][current] {
-  list-style-image: url("chrome://browser/skin/urlbar-star.svg#star-inverted");
-}
-
-.autocomplete-treebody::-moz-tree-image(bookmark, treecolAutoCompleteImage) {
-  list-style-image: url("chrome://browser/skin/places/autocomplete-star.png");
-  -moz-image-region: rect(0 16px 16px 0);
-  width: 16px;
-  height: 16px;
-}
-
-@media (min-resolution: 1.1dppx) {
-  .autocomplete-treebody::-moz-tree-image(bookmark, treecolAutoCompleteImage) {
-    list-style-image: url("chrome://browser/skin/places/autocomplete-star@2x.png");
-    -moz-image-region: rect(0 32px 32px 0);
-  }
-}
-
-@media not all and (-moz-os-version: windows-vista) and (-moz-windows-default-theme) {
-  @media not all and (-moz-os-version: windows-win7) and (-moz-windows-default-theme) {
-    .autocomplete-treebody::-moz-tree-image(selected, current, bookmark, treecolAutoCompleteImage) {
-      -moz-image-region: rect(0 32px 16px 16px);
-    }
-
-    @media (min-resolution: 1.1dppx) {
-      .autocomplete-treebody::-moz-tree-image(selected, current, bookmark, treecolAutoCompleteImage) {
-        -moz-image-region: rect(0 64px 32px 32px);
-      }
-    }
-
-    .autocomplete-treebody::-moz-tree-image(keyword, treecolAutoCompleteImage, selected) {
-      list-style-image: url(chrome://global/skin/icons/autocomplete-search.svg#search-icon-inverted);
-    }
-  }
-}
-
-.ac-type-icon[type=keyword],
-.ac-site-icon[type=searchengine],
-.autocomplete-treebody::-moz-tree-image(keyword, treecolAutoCompleteImage) {
-  list-style-image: url(chrome://global/skin/icons/autocomplete-search.svg#search-icon);
-}
-
-.ac-type-icon[type=keyword][selected],
-.ac-site-icon[type=searchengine][selected],
-.autocomplete-treebody::-moz-tree-image(keyword, treecolAutoCompleteImage, selected) {
-  list-style-image: url(chrome://global/skin/icons/autocomplete-search.svg#search-icon-inverted);
-}
-
-.autocomplete-treebody::-moz-tree-image(tag, treecolAutoCompleteImage) {
-  list-style-image: url("chrome://browser/skin/places/tag.png");
-  width: 16px;
-  height: 16px;
-}
-
-.ac-type-icon[type=switchtab],
-.ac-type-icon[type=remotetab] {
-  list-style-image: url("chrome://browser/skin/urlbar-tab.svg#tab");
-}
-
-.ac-type-icon[type=switchtab][selected],
-.ac-type-icon[type=remotetab][selected] {
-  list-style-image: url("chrome://browser/skin/urlbar-tab.svg#tab-inverted");
-}
-
-.autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
-  color: GrayText;
-}
-
-.autocomplete-treebody::-moz-tree-cell-text(suggesthint, treecolAutoCompleteComment),
-.autocomplete-treebody::-moz-tree-cell-text(suggestfirst, treecolAutoCompleteComment)
-{
-  color: GrayText;
-  font-size: smaller;
-}
-
-.autocomplete-treebody::-moz-tree-cell(suggesthint) {
-  border-top: 1px solid GrayText;
-}
-
-/* combined go/reload/stop button in location bar */
-
-#urlbar-go-button,
-#urlbar-reload-button,
-#urlbar-stop-button {
-  -moz-appearance: none;
-  border-style: none;
-  list-style-image: url("chrome://browser/skin/reload-stop-go.png");
-  padding: 0 9px;
-  margin-inline-start: 5px;
-  border-inline-start: 1px solid var(--urlbar-separator-color);
-  border-image: linear-gradient(transparent 15%,
-                                var(--urlbar-separator-color) 15%,
-                                var(--urlbar-separator-color) 85%,
-                                transparent 85%);
-  border-image-slice: 1;
-}
-
-#urlbar-reload-button {
-  -moz-image-region: rect(0, 14px, 14px, 0);
-}
-
-#urlbar-reload-button:not([disabled]):hover {
-  -moz-image-region: rect(14px, 14px, 28px, 0);
-}
-
-#urlbar-reload-button:not([disabled]):hover:active {
-  -moz-image-region: rect(28px, 14px, 42px, 0);
-}
-
-#urlbar-reload-button:-moz-locale-dir(rtl) > .toolbarbutton-icon {
-  transform: scaleX(-1);
-}
-
-#urlbar-go-button {
-  -moz-image-region: rect(0, 42px, 14px, 28px);
-}
-
-#urlbar-go-button:hover {
-  -moz-image-region: rect(14px, 42px, 28px, 28px);
-}
-
-#urlbar-go-button:hover:active {
-  -moz-image-region: rect(28px, 42px, 42px, 28px);
-}
-
-#urlbar-go-button:-moz-locale-dir(rtl) > .toolbarbutton-icon {
-  transform: scaleX(-1);
-}
-
-#urlbar-stop-button {
-  -moz-image-region: rect(0, 28px, 14px, 14px);
-}
-
-#urlbar-stop-button:not([disabled]):hover {
-  -moz-image-region: rect(14px, 28px, 28px, 14px);
-}
-
-#urlbar-stop-button:hover:active {
-  -moz-image-region: rect(28px, 28px, 42px, 14px);
-}
-
-@media (min-resolution: 1.1dppx) {
-  #urlbar-go-button,
-  #urlbar-reload-button,
-  #urlbar-stop-button {
-    list-style-image: url("chrome://browser/skin/reload-stop-go@2x.png");
-  }
-
-  #urlbar-go-button > .toolbarbutton-icon,
-  #urlbar-reload-button > .toolbarbutton-icon,
-  #urlbar-stop-button > .toolbarbutton-icon {
-    width: 14px;
-  }
-
-  #urlbar-go-button {
-    -moz-image-region: rect(0, 84px, 28px, 56px);
-  }
-
-  #urlbar-go-button:hover {
-    -moz-image-region: rect(28px, 84px, 56px, 56px);
-  }
-
-  #urlbar-go-button:hover:active {
-    -moz-image-region: rect(56px, 84px, 84px, 56px);
-  }
-
-  #urlbar-reload-button {
-    -moz-image-region: rect(0, 28px, 28px, 0);
-  }
-
-  #urlbar-reload-button:not([disabled]):hover {
-    -moz-image-region: rect(28px, 28px, 56px, 0);
-  }
-
-  #urlbar-reload-button:not([disabled]):hover:active {
-    -moz-image-region: rect(56px, 28px, 84px, 0);
-  }
-
-  #urlbar-stop-button {
-    -moz-image-region: rect(0, 56px, 28px, 28px);
-  }
-
-  #urlbar-stop-button:not([disabled]):hover {
-    -moz-image-region: rect(28px, 56px, 56px, 28px);
-  }
-
-  #urlbar-stop-button:hover:active {
-    -moz-image-region: rect(56px, 56px, 84px, 28px);
-  }
-}
-
-/* popup blocker button */
-
-#page-report-button {
-  list-style-image: url("chrome://browser/skin/urlbar-popup-blocked.png");
-  -moz-image-region: rect(0, 16px, 16px, 0);
-}
-
-#page-report-button:hover {
-  -moz-image-region: rect(0, 32px, 16px, 16px);
-}
-
-#page-report-button:hover:active,
-#page-report-button[open="true"] {
-  -moz-image-region: rect(0, 48px, 16px, 32px);
-}
-
-/* Reader mode button */
-
-#reader-mode-button {
-  list-style-image: url("chrome://browser/skin/readerMode.svg");
-  -moz-image-region: rect(0, 16px, 16px, 0);
-}
-
-#reader-mode-button:hover,
-#reader-mode-button[readeractive]:hover {
-  -moz-image-region: rect(0, 32px, 16px, 16px);
-}
-
-#reader-mode-button:hover:active,
-#reader-mode-button[readeractive] {
-  -moz-image-region: rect(0, 48px, 16px, 32px);
-}
-
-/* social share panel */
-%include ../shared/social/social.inc.css
-
-.social-panel-frame {
-  border-radius: inherit;
-}
-
-.social-share-frame {
-  min-width: 756px;
-  height: 150px;
-}
-#share-container {
-  min-width: 756px;
-  background-color: white;
-  background-repeat: no-repeat;
-  background-position: center center;
-}
-#share-container[loading] {
-  background-image: url(chrome://browser/skin/tabbrowser/pendingpaint.png);
-}
-#share-container > browser {
-  transition: opacity 150ms ease-in-out;
-  opacity: 1;
-}
-#share-container[loading] > browser {
-  opacity: 0;
-}
-
-.social-share-toolbar {
-  border-bottom: 1px solid #e2e5e8;
-  padding: 2px;
-}
-
-#social-share-provider-buttons {
-  padding: 0;
-  margin: 0;
-}
-
-.share-provider-button {
-  padding: 5px;
-  margin: 2px;
-}
-
-.share-provider-button > .toolbarbutton-text {
-  display: none;
-}
-.share-provider-button > .toolbarbutton-icon {
-  width: 16px;
-  min-height: 16px;
-  max-height: 16px;
-}
-
-#social-share-panel {
-  min-height: 100px;
-  min-width: 766px;
-}
-
-#share-container,
-.social-share-frame {
-  border-top-left-radius: 0;
-  border-bottom-left-radius: inherit;
-  border-top-right-radius: 0;
-  border-bottom-right-radius: inherit;
-}
-
-#social-share-panel > .social-share-toolbar {
-  border-top-left-radius: inherit;
-  border-top-right-radius: inherit;
-}
-
-#social-share-provider-buttons {
-  border-top-left-radius: inherit;
-  border-top-right-radius: inherit;
-}
-
-/* bookmarks menu-button */
-
-#nav-bar #bookmarks-menu-button[cui-areatype="toolbar"]:not([overflowedItem=true]) > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon {
-  padding-top: var(--toolbarbutton-vertical-inner-padding);
-  padding-bottom: var(--toolbarbutton-vertical-inner-padding);
-}
-
-#BMB_bookmarksPopup[side="top"],
-#BMB_bookmarksPopup[side="bottom"] {
-  margin-left: -20px;
-  margin-right: -20px;
-}
-
-#BMB_bookmarksPopup[side="left"],
-#BMB_bookmarksPopup[side="right"] {
-  margin-top: -20px;
-  margin-bottom: -20px;
-}
-
-/* bookmarking panel */
-
-#editBookmarkPanelStarIcon {
-  list-style-image: url("chrome://browser/skin/places/starred48.png");
-  width: 48px;
-  height: 48px;
-}
-
-#editBookmarkPanelStarIcon[unstarred] {
-  list-style-image: url("chrome://browser/skin/places/unstarred48.png");
-}
-
-#editBookmarkPanelTitle {
-  font-size: 130%;
-}
-
-#editBookmarkPanelHeader,
-#editBookmarkPanelContent {
-  margin-bottom: .5em;
-}
-
-/* Implements editBookmarkPanel resizing on folderTree un-collapse. */
-#editBMPanel_folderTree {
-  min-width: 27em;
-}
-
-/* ::::: content area ::::: */
-
-#sidebar {
-  background-color: Window;
-}
-
-#sidebar-title {
-  padding-inline-start: 0px;
-}
-
-#sidebar-header > .close-icon {
-  -moz-appearance: none;
-  padding: 2px;
-  margin: 0;
-  border: none;
-}
-
-@media not all and (min-resolution: 1.1dppx) {
-  #sidebar-header > .close-icon:-moz-lwtheme-brighttext {
-    list-style-image: url("chrome://global/skin/icons/close-inverted.png");
-  }
-}
-
-@media (min-resolution: 1.1dppx) {
-  #sidebar-header > .close-icon:-moz-lwtheme-brighttext {
-    list-style-image: url("chrome://global/skin/icons/close-inverted@2x.png");
-  }
-}
-
-@media (-moz-os-version: windows-xp),
-       (-moz-os-version: windows-vista),
-       (-moz-os-version: windows-win7) {
-  #sidebar-header > .close-icon {
-    padding-top: 4px;
-    padding-bottom: 4px;
-  }
-}
-
-.browserContainer > findbar {
-  background-color: -moz-dialog;
-  color: -moz-DialogText;
-  text-shadow: none;
-}
-
-/* Tabstrip */
-
-#TabsToolbar {
-  min-height: 0;
-  padding: 0;
-  margin-bottom: calc(-1 * var(--tab-toolbar-navbar-overlap)); /* overlap the nav-bar's top border */
-}
-
-@media (-moz-os-version: windows-xp) and (-moz-windows-default-theme) {
-  #main-window[sizemode=normal] #TabsToolbar {
-    padding-left: 2px;
-    padding-right: 2px;
-  }
-}
-
-%include ../shared/tabs.inc.css
-
-/* Remove border between tab strip and navigation toolbar on Windows 10+ */
-@media not all and (-moz-os-version: windows-xp) {
-  @media not all and (-moz-os-version: windows-vista) {
-    @media not all and (-moz-os-version: windows-win7) {
-      @media not all and (-moz-os-version: windows-win8) {
-        @media (-moz-windows-default-theme) {
-          .tab-background-end[selected=true]::after,
-          .tab-background-start[selected=true]::after {
-            content: none;
-          }
-
-          #TabsToolbar {
-            --tab-stroke-background-size: 0 0;
-          }
-
-          :root {
-            --tab-toolbar-navbar-overlap: 0px;
-          }
-
-          #nav-bar {
-            border-top-style: none !important;
-            box-shadow: none;
-          }
-        }
-      }
-    }
-  }
-}
-
-/* Invert the unhovered close tab icons on bright-text tabs */
-@media not all and (min-resolution: 1.1dppx) {
-  .tab-close-button:-moz-lwtheme-brighttext,
-  #TabsToolbar[brighttext] .tab-close-button:not([selected="true"]) {
-    list-style-image: url("chrome://global/skin/icons/close-inverted.png");
-  }
-}
-
-@media (min-resolution: 1.1dppx) {
-  .tab-close-button:-moz-lwtheme-brighttext,
-  #TabsToolbar[brighttext] .tab-close-button:not([selected="true"]) {
-    list-style-image: url("chrome://global/skin/icons/close-inverted@2x.png");
-  }
-}
-
-/* tabbrowser-tab focus ring */
-.tabbrowser-tab:focus > .tab-stack > .tab-content {
-  outline: 1px dotted;
-  outline-offset: -6px;
-}
-
-/* Tab DnD indicator */
-.tab-drop-indicator {
-  list-style-image: url(chrome://browser/skin/tabbrowser/tabDragIndicator.png);
-  margin-bottom: -9px;
-  z-index: 3;
-}
-
-/* Tab close button */
-.tab-close-button {
-  -moz-appearance: none;
-  border: none;
-}
-
-/* Tab scrollbox arrow, tabstrip new tab and all-tabs buttons */
-
-.tabbrowser-arrowscrollbox > .scrollbutton-up,
-.tabbrowser-arrowscrollbox > .scrollbutton-down {
-  list-style-image: url("chrome://browser/skin/tabbrowser/tab-arrow-left.svg");
-  margin: 0 0 var(--tab-toolbar-navbar-overlap);
-}
-
-#TabsToolbar[brighttext] > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .scrollbutton-up,
-#TabsToolbar[brighttext] > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .scrollbutton-down {
-  list-style-image: url(chrome://browser/skin/tabbrowser/tab-arrow-left-inverted.svg);
-}
-
-.tabbrowser-arrowscrollbox > .scrollbutton-up[disabled],
-.tabbrowser-arrowscrollbox > .scrollbutton-down[disabled] {
-  opacity: .4;
-}
-
-.tabbrowser-arrowscrollbox > .scrollbutton-up:-moz-locale-dir(rtl),
-.tabbrowser-arrowscrollbox > .scrollbutton-down:-moz-locale-dir(ltr) {
-  transform: scaleX(-1);
-}
-
-.tabbrowser-arrowscrollbox > .scrollbutton-down {
-  transition: 1s background-color ease-out;
-}
-
-.tabbrowser-arrowscrollbox > .scrollbutton-down[notifybgtab] {
-  background-color: Highlight;
-  transition: none;
-}
-
-.tabs-newtab-button > .toolbarbutton-icon {
-  margin-top: -1px;
-  margin-bottom: -1px;
-}
-
-.tabs-newtab-button,
-#TabsToolbar > #new-tab-button,
-#TabsToolbar > toolbarpaletteitem > #new-tab-button {
-  list-style-image: url(chrome://browser/skin/tabbrowser/newtab.svg);
-  -moz-image-region: auto;
-}
-
-#TabsToolbar[brighttext] .tabs-newtab-button,
-#TabsToolbar[brighttext] > #new-tab-button,
-#TabsToolbar[brighttext] > toolbarpaletteitem > #new-tab-button {
-  list-style-image: url(chrome://browser/skin/tabbrowser/newtab-inverted.svg);
-}
-
-.tabs-newtab-button > .toolbarbutton-icon,
-#TabsToolbar > #new-tab-button > .toolbarbutton-icon,
-#TabsToolbar > toolbarpaletteitem > #new-tab-button > .toolbarbutton-icon {
-  width: 16px;
-}
-
-#TabsToolbar > #new-tab-button {
-  width: 26px;
-}
-
-#alltabs-button {
-  list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow.png");
-}
-
-#TabsToolbar[brighttext] > #alltabs-button,
-#TabsToolbar[brighttext] > toolbarpaletteitem > #alltabs-button {
-  list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow-inverted.png");
-}
-
-#alltabs-button > .toolbarbutton-icon {
-  margin: 0 2px;
-}
-
-#alltabs-button > .toolbarbutton-menu-dropmarker {
-  display: none;
-}
-
-/* All tabs menupopup */
-.alltabs-item > .menu-iconic-left > .menu-iconic-icon {
-  list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
-}
-
-.alltabs-item[selected="true"] {
-  font-weight: bold;
-}
-
-.alltabs-item[busy] > .menu-iconic-left > .menu-iconic-icon {
-  list-style-image: url("chrome://global/skin/icons/loading.png");
-}
-
-@media (min-resolution: 1.1dppx) {
-  .alltabs-item[busy] > .menu-iconic-left > .menu-iconic-icon {
-    list-style-image: url("chrome://global/skin/icons/loading@2x.png");
-  }
-}
-
-toolbarbutton.chevron {
-  list-style-image: url("chrome://global/skin/toolbar/chevron.gif") !important;
-}
-
-toolbar[brighttext] toolbarbutton.chevron {
-  list-style-image: url("chrome://global/skin/toolbar/chevron-inverted.png") !important;
-}
-
-toolbarbutton.chevron:-moz-locale-dir(rtl) > .toolbarbutton-icon {
-  transform: scaleX(-1);
-}
-
-toolbarbutton.chevron > .toolbarbutton-text,
-toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
-  display: none;
-}
-
-toolbarbutton.chevron > .toolbarbutton-icon {
-  margin: 0;
-}
-
-#sidebar-throbber[loading="true"] {
-  list-style-image: url("chrome://global/skin/icons/loading.png");
-  margin-inline-end: 4px;
-}
-
-@media (min-resolution: 1.1dppx) {
-  #sidebar-throbber[loading="true"] {
-    list-style-image: url("chrome://global/skin/icons/loading@2x.png");
-    width: 16px;
-  }
-}
-
-/* Bookmarks toolbar */
-#PlacesToolbarDropIndicator {
-  list-style-image: url(chrome://browser/skin/places/toolbarDropMarker.png);
-}
-
-toolbarbutton.bookmark-item[dragover="true"][open="true"] {
-  -moz-appearance: none;
-  background: Highlight !important;
-  color: HighlightText !important;
-}
-
-/* rules for menupopup drop indicators */
-.menupopup-drop-indicator-bar {
-  position: relative;
-  /* these two margins must together compensate the indicator's height */
-  margin-top: -1px;
-  margin-bottom: -1px;
-}
-
-.menupopup-drop-indicator {
-  list-style-image: none;
-  height: 2px;
-  margin-inline-end: -4em;
-  background-color: Highlight;
-}
-
-%include ../shared/notification-icons.inc.css
-
-.popup-notification-body[popupid="addon-progress"],
-.popup-notification-body[popupid="addon-install-confirmation"] {
-  width: 28em;
-  max-width: 28em;
-}
-
-.addon-install-confirmation-name {
-  font-weight: bold;
-}
-
-/* Notification icon box */
-
-.notification-anchor-icon:-moz-focusring {
-  outline: 1px dotted -moz-DialogText;
-}
-
-/* Translation infobar */
-
-%include ../shared/translation/infobar.inc.css
-
-notification[value="translation"] {
-  min-height: 40px;
-}
-
-@media (-moz-windows-default-theme) {
-  notification[value="translation"],
-  notification[value="translation"] button,
-  notification[value="translation"] menulist {
-    min-height: 30px;
-    color: #545454;
-  }
-
-  notification[value="translation"] {
-    background-color: #EEE;
-  }
-
-  notification[value="translation"] button,
-  notification[value="translation"] menulist {
-    padding-inline-end: 1ch;
-  }
-
-  notification[value="translation"] menulist {
-    border: 1px solid #C1C1C1;
-    background-color: #FFF;
-  }
-
-  notification[value="translation"] button {
-    border: 1px solid #C1C1C1;
-    background-color: #FBFBFB;
-  }
-
-  notification[value="translation"] button,
-  notification[value="translation"] menulist,
-  notification[value="translation"] menulist > .menulist-label-box {
-    margin-inline-start: 1ch;
-    margin-inline-end: 1ch;
-  }
-
-  notification[value="translation"] button:hover,
-  notification[value="translation"] button:active,
-  notification[value="translation"] menulist:hover,
-  notification[value="translation"] menulist:active {
-    background-color: #EBEBEB;
-  }
-
-  notification[value="translation"] button[anonid="translate"] {
-    color: #FFF;
-    background-color: #0095DD;
-    box-shadow: none;
-    border: 1px solid #006B9D;
-  }
-
-  notification[value="translation"] button[anonid="translate"]:hover,
-  notification[value="translation"] button[anonid="translate"]:active {
-    background-color: #008ACB;
-  }
-
-  notification[value="translation"] button[type="menu"] > .button-box > .button-menu-dropmarker,
-  notification[value="translation"] menulist > .menulist-dropmarker {
-    list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow.png");
-  }
-
-  notification[value="translation"] button > .button-box,
-  notification[value="translation"] button[type="menu"] > .button-box > .button-menu-dropmarker {
-    padding: 0;
-    margin-inline-start: 3ch;
-  }
-
-  notification[value="translation"] button:not([type="menu"]) > .button-box {
-    margin-inline-end: 3ch;
-  }
-}
-
-.translation-menupopup {
-  -moz-appearance: none;
-}
-
-/* Bookmarks roots menu-items */
-#subscribeToPageMenuitem:not([disabled]),
-#subscribeToPageMenupopup {
-  list-style-image: url("chrome://browser/skin/feeds/feedIcon16.png");
-}
-
-#bookmarksToolbarFolderMenu,
-#BMB_bookmarksToolbar,
-#panelMenu_bookmarksToolbar {
-  list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png");
-  -moz-image-region: auto;
-}
-
-#menu_unsortedBookmarks,
-#BMB_unsortedBookmarks,
-#panelMenu_unsortedBookmarks {
-  list-style-image: url("chrome://browser/skin/places/unsortedBookmarks.png");
-  -moz-image-region: auto;
-}
+%endif
 
 /* Ctrl-Tab */
 
 #ctrlTab-panel {
   -moz-appearance: none;
+%ifdef XP_MACOSX
+  -moz-window-shadow: none;
+%endif
   background: hsla(0,0%,33%,.85);
   color: white;
   border-style: none;
   padding: 20px 10px 10px;
+%ifndef XP_MACOSX
   font-weight: bold;
+%endif
   text-shadow: 0 0 1px hsl(0,0%,12%), 0 0 2px hsl(0,0%,12%);
 }
 
 .ctrlTab-favicon[src] {
   background-color: white;
   width: 20px;
   height: 20px;
   padding: 2px;
@@ -2417,305 +32,32 @@ notification[value="translation"] {
   box-shadow: 1px 1px 2px hsl(0,0%,12%);
 }
 
 .ctrlTab-preview:not(#ctrlTab-showAll) > * > .ctrlTab-preview-inner > .tabPreview-canvas {
   margin-bottom: 2px;
 }
 
 .ctrlTab-preview-inner {
-  padding-bottom: 10px;
+  padding: 8px;
+  border: 2px solid transparent;
+  border-radius: .5em;
+}
+
+.ctrlTab-preview:not(#ctrlTab-showAll) > * > .ctrlTab-preview-inner {
+  margin: -10px -10px 0;
 }
 
 #ctrlTab-showAll:not(:focus) > * > .ctrlTab-preview-inner {
-  padding: 10px;
   background-color: rgba(255,255,255,.2);
-  border-radius: .5em;
 }
 
 .ctrlTab-preview:focus > * > .ctrlTab-preview-inner {
   color: white;
   background-color: rgba(0,0,0,.6);
   text-shadow: none;
-  padding: 8px;
-  border: 2px solid white;
-  border-radius: .5em;
-}
-
-.ctrlTab-preview:not(#ctrlTab-showAll):focus > * > .ctrlTab-preview-inner {
-  margin: -10px -10px 0;
+  border-color: white;
 }
 
 #ctrlTab-showAll {
   margin-top: .5em;
 }
 
-/* Status panel */
-
-.statuspanel-label {
-  margin: 0;
-  padding: 2px 4px;
-  background: -moz-dialog;
-  border: 1px none ThreeDShadow;
-  border-top-style: solid;
-  color: -moz-dialogText;
-  text-shadow: none;
-}
-
-@media (-moz-windows-default-theme) {
-  .statuspanel-label {
-    background: linear-gradient(#fff, #ddd);
-    border-color: #ccc;
-    color: #333;
-  }
-}
-
-.statuspanel-label:-moz-locale-dir(ltr):not([mirror]),
-.statuspanel-label:-moz-locale-dir(rtl)[mirror] {
-  border-right-style: solid;
-  /* disabled for triggering grayscale AA (bug 659213)
-  border-top-right-radius: .3em;
-  */
-  margin-right: 1em;
-}
-
-.statuspanel-label:-moz-locale-dir(rtl):not([mirror]),
-.statuspanel-label:-moz-locale-dir(ltr)[mirror] {
-  border-left-style: solid;
-  /* disabled for triggering grayscale AA (bug 659213)
-  border-top-left-radius: .3em;
-  */
-  margin-left: 1em;
-}
-
-%include ../shared/fullscreen/warning.inc.css
-%include ../../../devtools/client/themes/responsivedesign.inc.css
-%include ../../../devtools/client/themes/commandline.inc.css
-
-%include ../shared/plugin-doorhanger.inc.css
-
-notification.pluginVulnerable > .notification-inner > .messageCloseButton {
-  list-style-image: url("chrome://global/skin/icons/close-inverted.png");
-}
-
-@media (min-resolution: 1.1dppx) {
-  notification.pluginVulnerable > .notification-inner > .messageCloseButton {
-    list-style-image: url("chrome://global/skin/icons/close-inverted@2x.png");
-  }
-}
-
-%include ../shared/login-doorhanger.inc.css
-
-%include downloads/indicator.css
-
-/* Error counter */
-
-#developer-toolbar-toolbox-button[error-count]:before {
-  color: #FDF3DE;
-  min-width: 16px;
-  text-shadow: none;
-  background-image: linear-gradient(#B4211B, #8A1915);
-  border-radius: 1px;
-  margin-inline-end: 5px;
-}
-
-/* Customization mode */
-
-%include ../shared/customizableui/customizeMode.inc.css
-
-/**
- * This next rule is a hack to disable subpixel anti-aliasing on all
- * labels during the customize mode transition. Subpixel anti-aliasing
- * on Windows with Direct2D layers acceleration is particularly slow to
- * paint, so this hack is how we sidestep that performance bottleneck.
- */
-#main-window:-moz-any([customize-entering],[customize-exiting]) label {
-  transform: perspective(0.01px);
-}
-
-#main-window[customize-entered] > #tab-view-deck {
-  background-image: url("chrome://browser/skin/customizableui/customizeMode-gridTexture.png");
-  background-attachment: fixed;
-}
-
-#main-window[customization-lwtheme] > #tab-view-deck:-moz-lwtheme {
-  background-repeat: no-repeat;
-  background-position: right top;
-  background-attachment: fixed;
-  /* The image will get set from CustomizeMode.jsm */
-  background-image: none;
-  background-color: transparent;
-}
-
-#main-window[customization-lwtheme]:-moz-lwtheme {
-  background-image: url("chrome://browser/skin/customizableui/customizeMode-gridTexture.png");
-  background-repeat: repeat;
-  background-attachment: fixed;
-  background-position: left top;
-}
-
-#main-window[customize-entered] #browser-bottombox,
-#main-window[customize-entered] #customization-container {
-  border-left: 1px solid @toolbarShadowColor@;
-  border-right: 1px solid @toolbarShadowColor@;
-  background-clip: padding-box;
-}
-
-#main-window[customize-entered] #browser-bottombox {
-  border-bottom: 1px solid @toolbarShadowColor@;
-}
-
-#customization-tipPanel > .panel-arrowcontainer > .panel-arrowbox > .panel-arrow[side="left"] {
-  margin-right: -2px;
-}
-
-#customization-tipPanel > .panel-arrowcontainer > .panel-arrowbox > .panel-arrow[side="right"] {
-  margin-left: -2px;
-}
-
-/* End customization mode */
-
-/* Private browsing indicators */
-
-/**
- * Currently, we have two places where we put private browsing indicators on
- * Windows. When tabsintitlebar is enabled, we draw the indicator in the titlebar.
- * When tabsintitlebar is disabled, we draw the indicator at the end of the
- * tabstrip. The titlebar indicator is the fiddliest of the bunch, since we
- * want the bottom border of the image to line up with the bottom of the window
- * caption buttons. That's why there's so much special-casing going on in here.
- */
-.private-browsing-indicator {
-  display: none;
-  pointer-events: none;
-}
-
-#private-browsing-indicator-titlebar {
-  display: block;
-  position: absolute;
-}
-
-#main-window[privatebrowsingmode=temporary][tabsintitlebar] #private-browsing-indicator-titlebar > .private-browsing-indicator {
-  display: block;
-}
-
-#main-window[privatebrowsingmode=temporary]:-moz-any([inFullscreen],:not([tabsintitlebar])) #TabsToolbar > .private-browsing-indicator {
-  display: -moz-box;
-}
-
-#TabsToolbar > .private-browsing-indicator {
-  background: url("chrome://browser/skin/privatebrowsing-mask-tabstrip.png") no-repeat center -3px;
-  margin-inline-start: 4px;
-  width: 48px;
-}
-
-/* Bug 1008183: We're intentionally using the titlebar asset here for fullscreen
- * mode, since the tabstrip "mimics" the titlebar in that case with its own
- * min/max/close window buttons.
- */
-#private-browsing-indicator-titlebar > .private-browsing-indicator,
-#main-window[inFullscreen] #TabsToolbar > .private-browsing-indicator {
-  background: url("chrome://browser/skin/privatebrowsing-mask-titlebar.png") no-repeat center 0px;
-  margin-inline-end: 4px;
-  width: 40px;
-  height: 20px;
-  position: relative;
-}
-
-@media (-moz-os-version: windows-xp) {
-  @media not all and (-moz-windows-classic) {
-    #private-browsing-indicator-titlebar > .private-browsing-indicator {
-      background-image: url("chrome://browser/skin/privatebrowsing-mask-titlebar-XPVista7-tall.png");
-      height: 28px;
-    }
-
-    #main-window[sizemode="maximized"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
-      top: -5px;
-    }
-    #main-window[sizemode="normal"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
-      top: -1px;
-    }
-  }
-}
-
-@media (-moz-windows-classic) {
-  /**
-   * We have to use top instead of background-position in this case, otherwise
-   * the bottom of the indicator would get cut off by the bounds of the
-   * private-browsing-indicator element.
-   */
-  #main-window[sizemode="normal"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
-    top: 4px;
-  }
-}
-
-@media (-moz-os-version: windows-vista),
-       (-moz-os-version: windows-win7) {
-  @media (-moz-windows-glass) {
-    #main-window[sizemode="normal"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
-      top: 1px;
-    }
-    #main-window[sizemode="maximized"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
-      top: -1px;
-    }
-  }
-
-  /**
-   * This next block targets Aero Basic, which has different positioning for the
-   * window caption buttons, and therefore needs to be special-cased.
-   */
-  @media (-moz-windows-default-theme) {
-    @media not all and (-moz-windows-compositor) {
-      #main-window[sizemode="normal"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
-        background-image: url("chrome://browser/skin/privatebrowsing-mask-titlebar-XPVista7-tall.png");
-        height: 28px;
-      }
-    }
-  }
-}
-
-/* End private browsing indicators */
-
-%include ../shared/UITour.inc.css
-
-#UITourTooltipButtons {
-  /**
-   * Override the --panel-arrowcontent-padding so the background extends
-   * to the sides and bottom of the panel.
-   */
-  margin-left: -10px;
-  margin-right: -10px;
-  margin-bottom: -10px;
-}
-
-%include ../shared/contextmenu.inc.css
-
-#context-navigation {
-  background-color: menu;
-  padding-bottom: 4px;
-}
-
-#context-sep-navigation {
-  margin-inline-start: -28px;
-  margin-top: -4px;
-}
-
-
-@media not all and (-moz-os-version: windows-xp) {
-%include browser-aero.css
-}
-
-.browser-extension-panel > .panel-arrowcontainer > .panel-arrowcontent {
-  padding: 0;
-  overflow: hidden;
-}
-
-@media (-moz-os-version: windows-xp),
-       (-moz-os-version: windows-vista),
-       (-moz-os-version: windows-win7) {
-  .cui-widget-panelview[id^=PanelUI-webext-] {
-    border-radius: 4px;
-  }
-}
-
-.webextension-popup-browser {
-  border-radius: inherit;
-}
--- a/browser/themes/shared/devedition.inc.css
+++ b/browser/themes/shared/devedition.inc.css
@@ -141,17 +141,17 @@
 #tabbrowser-tabs,
 #TabsToolbar,
 #browser-panel {
   background: var(--chrome-background-color);
   color: var(--chrome-color);
 }
 
 #navigator-toolbox:-moz-lwtheme::after {
-  background: var(--chrome-navigator-toolbox-separator-color);
+  border-bottom-color: var(--chrome-navigator-toolbox-separator-color);
 }
 
 #navigator-toolbox > toolbar:not(#TabsToolbar):not(#toolbar-menubar),
 .browserContainer > findbar,
 #browser-bottombox {
   background-color: var(--chrome-secondary-background-color) !important;
   background-image: none !important;
   color: var(--chrome-color);
--- a/browser/themes/shared/identity-block/identity-block.inc.css
+++ b/browser/themes/shared/identity-block/identity-block.inc.css
@@ -50,17 +50,16 @@
 }
 
 /* MAIN IDENTITY ICON */
 
 #identity-icon {
   width: 16px;
   height: 16px;
   list-style-image: url(chrome://browser/skin/identity-icon.svg#normal);
-  opacity: .5;
 }
 
 #identity-box:hover > #identity-icon:not(.no-hover),
 #identity-box[open=true] > #identity-icon {
   list-style-image: url(chrome://browser/skin/identity-icon.svg#hover);
 }
 
 #identity-box.grantedPermissions > #identity-icon {
@@ -69,29 +68,27 @@
 
 #identity-box.grantedPermissions:hover > #identity-icon:not(.no-hover),
 #identity-box.grantedPermissions[open=true] > #identity-icon {
   list-style-image: url(chrome://browser/skin/identity-icon.svg#notice-hover);
 }
 
 #urlbar[pageproxystate="valid"] > #identity-box.chromeUI > #identity-icon {
   list-style-image: url(chrome://branding/content/identity-icons-brand.svg);
-  opacity: 1;
 }
 
 #urlbar[pageproxystate="invalid"] > #identity-box > #identity-icon {
-  opacity: .2;
+  opacity: .3;
 }
 
 #urlbar[actiontype="searchengine"] > #identity-box > #identity-icon {
   -moz-image-region: inherit;
   list-style-image: url(chrome://global/skin/icons/autocomplete-search.svg#search-icon);
   width: 16px;
   height: 16px;
-  opacity: .5;
 }
 
 /* SHARING ICON */
 
 #sharing-icon {
   width: 16px;
   height: 16px;
   margin-inline-start: -16px;
@@ -135,23 +132,20 @@
 /* TRACKING PROTECTION ICON */
 
 #tracking-protection-icon {
   width: 16px;
   height: 16px;
   margin-inline-start: 2px;
   margin-inline-end: 0;
   list-style-image: url(chrome://browser/skin/tracking-protection-16.svg);
-  opacity: .5;
 }
 
 #tracking-protection-icon[state="loaded-tracking-content"] {
   list-style-image: url(chrome://browser/skin/tracking-protection-disabled-16.svg);
-  filter: none;
-  opacity: 1;
 }
 
 #tracking-protection-icon[animate] {
   transition: margin-left 200ms ease-out, margin-right 200ms ease-out;
 }
 
 #tracking-protection-icon:not([state]) {
   margin-inline-end: -18px;
--- a/browser/themes/shared/identity-block/identity-icon.svg
+++ b/browser/themes/shared/identity-block/identity-icon.svg
@@ -4,16 +4,17 @@
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
      width="64" height="16" viewBox="0 0 64 16">
   <defs>
     <style>
       path {
         fill-rule: evenodd;
         fill: -moz-fieldtext;
+        fill-opacity: .5;
       }
     </style>
   </defs>
 
   <view id="normal" viewBox="0 0 16 16"/>
   <g>
     <path d="M128,193a7,7,0,1,1,7-7A7,7,0,0,1,128,193Zm0-13a6,6,0,1,0,6,6A6,6,0,0,0,128,180Zm0,10a1,1,0,0,1-1-1v-3a1,1,0,0,1,2,0v3A1,1,0,0,1,128,190Zm0-6a1,1,0,1,1,1-1A1,1,0,0,1,128,184Z" transform="translate(-120 -178)"/>
   </g>
--- a/browser/themes/shared/identity-block/tracking-protection-16.svg
+++ b/browser/themes/shared/identity-block/tracking-protection-16.svg
@@ -12,10 +12,10 @@
     <mask id="mask-shield-cutout">
       <rect width="16" height="16" fill="#000" />
       <use xlink:href="#shape-shield-outer" fill="#fff" />
       <use xlink:href="#shape-shield-inner" fill="#000" />
       <use xlink:href="#shape-shield-detail" fill="#fff" />
     </mask>
   </defs>
 
-  <use xlink:href="#shape-shield-outer" mask="url(#mask-shield-cutout)" fill="-moz-fieldtext"/>
+  <use xlink:href="#shape-shield-outer" mask="url(#mask-shield-cutout)" fill="-moz-fieldtext" fill-opacity=".5"/>
 </svg>
--- a/browser/themes/shared/notification-icons.inc.css
+++ b/browser/themes/shared/notification-icons.inc.css
@@ -47,34 +47,32 @@
 
 .camera-icon,
 .geo-icon,
 .indexedDB-icon,
 .install-icon,
 .login-icon,
 .microphone-icon,
 .plugin-icon,
-.pointerLock-icon,
 .popup-icon,
 .screen-icon,
 .desktop-notification-icon,
 .popup-notification-icon[popupid="geolocation"],
 .popup-notification-icon[popupid="indexedDB-permissions-prompt"],
 .popup-notification-icon[popupid="password"],
-.popup-notification-icon[popupid="pointerLock"],
 .popup-notification-icon[popupid="webRTC-shareDevices"],
 .popup-notification-icon[popupid="webRTC-shareMicrophone"],
 .popup-notification-icon[popupid="webRTC-shareScreen"],
 .popup-notification-icon[popupid="web-notifications"] {
   filter: url(chrome://browser/skin/filters.svg#fill);
   fill: currentColor;
   opacity: .4;
 }
 
-.notification-anchor-icon:hover {
+.notification-anchor-icon:not(.plugin-blocked):hover {
   opacity: .6;
 }
 
 /* INDIVIDUAL NOTIFICATIONS */
 
 .popup-notification-icon[popupid="web-notifications"],
 .desktop-notification-icon {
   list-style-image: url(chrome://browser/skin/notification-icons.svg#desktop-notification);
@@ -161,25 +159,16 @@
 .screen-icon {
   list-style-image: url(chrome://browser/skin/notification-icons.svg#screen);
 }
 
 .screen-icon.blocked-permission-icon {
   list-style-image: url(chrome://browser/skin/notification-icons.svg#screen-blocked);
 }
 
-.popup-notification-icon[popupid="pointerLock"],
-.pointerLock-icon {
-  list-style-image: url(chrome://browser/skin/notification-icons.svg#pointerLock);
-}
-
-.pointerLock-icon.blocked-permission-icon {
-  list-style-image: url(chrome://browser/skin/notification-icons.svg#pointerLock-blocked);
-}
-
 /* This icon has a block sign in it, so we don't need a blocked version. */
 .popup-icon {
   list-style-image: url("chrome://browser/skin/notification-icons.svg#popup");
 }
 
 /* EME */
 
 .popup-notification-icon[popupid="drmContentPlaying"],
@@ -253,17 +242,17 @@
 
 .plugin-icon {
   list-style-image: url(chrome://browser/skin/notification-icons.svg#plugin);
 }
 
 .plugin-icon.plugin-blocked {
   list-style-image: url(chrome://browser/skin/notification-icons.svg#plugin-blocked);
   fill: #d92215;
-  opacity: 1 !important; /* !important to override the default hover opacity */
+  opacity: 1;
 }
 
 #notification-popup-box[hidden] {
   /* Override display:none to make the pluginBlockedNotification animation work
      when showing the notification repeatedly. */
   display: -moz-box;
   visibility: collapse;
 }
--- a/browser/themes/shared/notification-icons.svg
+++ b/browser/themes/shared/notification-icons.svg
@@ -29,17 +29,16 @@
     <path id="geo-windows-icon" d="m 2,14 0,4 2,0 a 12,12 0 0 0 10,10 l 0,2 4,0 0,-2 a 12,12 0 0 0 10,-10 l 2,0 0,-4 -2,0 a 12,12 0 0 0 -10,-10 l 0,-2 -4,0 0,2 a 12,12 0 0 0 -10,10 z m 4,1.9 a 10,10 0 1 1 0,0.2 z m 4,0 a 6,6 0 1 1 0,0.2 z" />
     <path id="geo-windows-detailed-icon" d="m 2,14.5 0,3 2,0.5 a 12,12 0 0 0 10,10 l 0.5,2 3,0 0.5,-2 a 12,12 0 0 0 10,-10 l 2,-0.5 0,-3 -2,-0.5 a 12,12 0 0 0 -10,-10 l -0.5,-2 -3,0 -0.5,2 a 12,12 0 0 0 -10,10 z m 4,1.4 a 10,10 0 1 1 0,0.2 z m 3,0 a 7,7 0 1 1 0,0.2 z" />
     <path id="indexedDB-icon" d="m 2,24 a 4,4 0 0 0 4,4 l 2,0 0,-4 -2,0 0,-16 20,0 0,16 -2,0 0,4 2,0 a 4,4 0 0 0 4,-4 l 0,-16 a 4,4 0 0 0 -4,-4 l -20,0 a 4,4 0 0 0 -4,4 z m 8,-2 6,7 6,-7 -4,0 0,-8 -4,0 0,8 z" />
     <path id="login-icon" d="m 2,26 0,4 6,0 0,-2 2,0 0,-2 1,0 0,-1 2,0 0,-3 2,0 2.5,-2.5 1.5,1.5 3,-3 a 8,8 0 1 0 -8,-8 l -3,3 2,2 z m 20,-18.1 a 2,2 0 1 1 0,0.2 z" />
     <path id="login-detailed-icon" d="m 1,27 0,3.5 a 0.5,0.5 0 0 0 0.5,0.5 l 5,0 a 0.5,0.5 0 0 0 0.5,-0.5 l 0,-1.5 1.5,0 a 0.5,0.5 0 0 0 0.5,-0.5 l 0,-1.5 1,0 a 0.5,0.5 0 0 0 0.5,-0.5 l 0,-1 1,0 a 0.5,0.5 0 0 0 0.5,-0.5 l 0,-2 2,0 2.5,-2.5 q 0.5,-0.5 1,0 l 1,1 c 0.5,0.5 1,0.5 1.5,-0.5 l 1,-2 a 9,9 0 1 0 -8,-8 l -2,1 c -1,0.5 -1,1 -0.5,1.5 l 1.5,1.5 q 0.5,0.5 0,1 z m 21,-19.1 a 2,2 0 1 1 0,0.2 z" />
     <path id="microphone-icon" d="m 8,14 0,4 a 8,8 0 0 0 6,7.7 l 0,2.3 -2,0 a 2,2 0 0 0 -2,2 l 12,0 a 2,2 0 0 0 -2,-2 l -2,0 0,-2.3 a 8,8 0 0 0 6,-7.7 l 0,-4 -2,0 0,4 a 6,6 0 0 1 -12,0 l 0,-4 z m 4,4 a 4,4 0 0 0 8,0 l 0,-12 a 4,4 0 0 0 -8,0 z" />
     <path id="microphone-detailed-icon" d="m 8,18 a 8,8 0 0 0 6,7.7 l 0,2.3 -1,0 a 3,2 0 0 0 -3,2 l 12,0 a 3,2 0 0 0 -3,-2 l -1,0 0,-2.3 a 8,8 0 0 0 6,-7.7 l 0,-4 a 1,1 0 0 0 -2,0 l 0,4 a 6,6 0 0 1 -12,0 l 0,-4 a 1,1 0 0 0 -2,0 z m 4,0 a 4,4 0 0 0 8,0 l 0,-12 a 4,4 0 0 0 -8,0 z" />
     <path id="plugin-icon" d="m 2,26 a 2,2 0 0 0 2,2 l 24,0 a 2,2 0 0 0 2,-2 l 0,-16 a 2,2 0 0 0 -2,-2 l -24,0 a 2,2 0 0 0 -2,2 z m 2,-20 10,0 0,-2 a 2,2 0 0 0 -2,-2 l -6,0 a 2,2 0 0 0 -2,2 z m 14,0 10,0 0,-2 a 2,2 0 0 0 -2,-2 l -6,0 a 2,2 0 0 0 -2,2 z" />
-    <path id="pointerLock-icon" d="m 8,24 6,-5 5,10 4,-2 -5,-10 7,-1 -17,-14 z" />
     <path id="popup-icon" d="m 2,24 a 4,4 0 0 0 4,4 l 8,0 a 10,10 0 0 1 -2,-4 l -4,0 a 2,2 0 0 1 -2,-2 l 0,-12 18,0 0,2 a 10,10 0 0 1 4,2 l 0,-8 a 4,4 0 0 0 -4,-4 l -18,0 a 4,4 0 0 0 -4,4 z m 12,-2.1 a 8,8 0 1 1 0,0.2 m 10.7,-4.3 a 5,5 0 0 0 -6.9,6.9 z m -5.4,8.4 a 5,5 0 0 0 6.9,-6.9 z" />
     <path id="screen-icon" d="m 2,18 a 2,2 0 0 0 2,2 l 2,0 0,-6 a 4,4 0 0 1 4,-4 l 14,0 0,-6 a 2,2 0 0 0 -2,-2 l -18,0 a 2,2 0 0 0 -2,2 z m 6,10 a 2,2 0 0 0 2,2 l 18,0 a 2,2 0 0 0 2,-2 l 0,-14 a 2,2 0 0 0 -2,-2 l -18,0 a 2,2 0 0 0 -2,2 z" />
 
     <clipPath id="clip">
       <path d="m 0,0 0,31 31,-31 z m 6,32 26,0 0,-26 z"/>
     </clipPath>
   </defs>
 
@@ -59,16 +58,14 @@
   <use id="indexedDB-blocked" class="blocked" xlink:href="#indexedDB-icon" />
   <use id="login" xlink:href="#login-icon" />
   <use id="login-detailed" xlink:href="#login-detailed-icon" />
   <use id="microphone" xlink:href="#microphone-icon" />
   <use id="microphone-blocked" class="blocked" xlink:href="#microphone-icon" />
   <use id="microphone-detailed" xlink:href="#microphone-detailed-icon" />
   <use id="plugin" xlink:href="#plugin-icon" />
   <use id="plugin-blocked" class="blocked" xlink:href="#plugin-icon" />
-  <use id="pointerLock" xlink:href="#pointerLock-icon" />
-  <use id="pointerLock-blocked" class="blocked" xlink:href="#pointerLock-icon" />
   <use id="popup" xlink:href="#popup-icon" />
   <use id="screen" xlink:href="#screen-icon" />
   <use id="screen-blocked" class="blocked" xlink:href="#screen-icon" />
 
   <path id="strikeout" d="m 2,28 2,2 26,-26 -2,-2 z"/>
 </svg>
--- a/browser/themes/shared/tabs.inc.css
+++ b/browser/themes/shared/tabs.inc.css
@@ -435,22 +435,30 @@
 .tab-label[attention]:not([selected="true"]) {
   font-weight: bold;
 }
 
 /* Tab separators */
 
 .tabbrowser-tab::after,
 .tabbrowser-tab::before {
+  margin-inline-start: -1px;
+  /* Vertical margin doesn't work here for positioned pinned tabs, see
+     bug 1198236 and bug 1300410. We're using linear-gradient instead
+     to cut off the border at the top and at the bottom. */
+  border-left: 1px solid;
+  border-image: linear-gradient(transparent 6px,
+                                currentColor 6px,
+                                currentColor calc(100% - 5px),
+                                transparent calc(100% - 5px));
+  border-image-slice: 1;
+  /* The 1px border and negative margin may amount to a different number of
+     device pixels (bug 477157), so we also set a width to match the margin. */
   width: 1px;
-  margin-inline-start: -1px;
-  background-image: linear-gradient(transparent 5px,
-                                    currentColor 5px,
-                                    currentColor calc(100% - 4px),
-                                    transparent calc(100% - 4px));
+  box-sizing: border-box;
   opacity: 0.2;
 }
 
 #TabsToolbar[brighttext] > #tabbrowser-tabs > .tabbrowser-tab::before,
 #TabsToolbar[brighttext] > #tabbrowser-tabs > .tabbrowser-tab::after {
   opacity: 0.4;
 }
 
--- a/browser/themes/windows/browser-aero.css
+++ b/browser/themes/windows/browser-aero.css
@@ -330,26 +330,31 @@
     color: white;
   }
 
   /* Show borders on vista through win8, but not on win10 and later: */
   @media (-moz-os-version: windows-vista),
          (-moz-os-version: windows-win7),
          (-moz-os-version: windows-win8) {
     /* Vertical toolbar border */
-    #main-window:not([customizing])[sizemode=normal] #navigator-toolbox:not(:-moz-lwtheme)::after,
     #main-window:not([customizing])[sizemode=normal] #navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):not(:-moz-lwtheme),
     #main-window:not([customizing])[sizemode=normal] #navigator-toolbox:-moz-lwtheme,
-    #main-window[customizing] #navigator-toolbox::after,
     #main-window[customizing] #navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar) {
       border-left: 1px solid @toolbarShadowColor@;
       border-right: 1px solid @toolbarShadowColor@;
       background-clip: padding-box;
     }
 
+    #main-window:not([customizing])[sizemode=normal] #navigator-toolbox:not(:-moz-lwtheme)::after,
+    #main-window[customizing] #navigator-toolbox::after {
+      box-shadow: 1px 0 0 @toolbarShadowColor@, -1px 0 0 @toolbarShadowColor@;
+      margin-left: 1px;
+      margin-right: 1px;
+    }
+
     #main-window[sizemode=normal] #browser-border-start,
     #main-window[sizemode=normal] #browser-border-end {
       display: -moz-box;
       background-color: @toolbarShadowColor@;
       width: 1px;
     }
 
     #main-window[sizemode=normal] #browser-bottombox {
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -117,38 +117,37 @@
   background-color: transparent;
   border-top: none;
 }
 
 #navigator-toolbox::after {
   content: "";
   display: -moz-box;
   -moz-box-ordinal-group: 101; /* tabs toolbar is 100 */
-  height: 1px;
-  background-color: ThreeDShadow;
+  border-bottom: 1px solid ThreeDShadow;
 }
 
 @media (-moz-windows-default-theme) {
   @media (-moz-os-version: windows-vista),
          (-moz-os-version: windows-win7) {
     #navigator-toolbox::after {
-      background-color: #aabccf;
+      border-bottom-color: #aabccf;
     }
   }
 
   @media (-moz-os-version: windows-win8),
          (-moz-os-version: windows-win10) {
     #navigator-toolbox::after {
-      background-color: #c2c2c2;
+      border-bottom-color: #c2c2c2;
     }
   }
 }
 
 #navigator-toolbox:-moz-lwtheme::after {
-  background-color: rgba(0,0,0,.3);
+  border-bottom-color: rgba(0,0,0,.3);
 }
 
 #navigator-toolbox > toolbar {
   -moz-appearance: none;
   border-style: none;
 }
 
 #navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar) {
@@ -2389,70 +2388,16 @@ notification[value="translation"] {
 
 #menu_unsortedBookmarks,
 #BMB_unsortedBookmarks,
 #panelMenu_unsortedBookmarks {
   list-style-image: url("chrome://browser/skin/places/unsortedBookmarks.png");
   -moz-image-region: auto;
 }
 
-/* Ctrl-Tab */
-
-#ctrlTab-panel {
-  -moz-appearance: none;
-  background: hsla(0,0%,33%,.85);
-  color: white;
-  border-style: none;
-  padding: 20px 10px 10px;
-  font-weight: bold;
-  text-shadow: 0 0 1px hsl(0,0%,12%), 0 0 2px hsl(0,0%,12%);
-}
-
-.ctrlTab-favicon[src] {
-  background-color: white;
-  width: 20px;
-  height: 20px;
-  padding: 2px;
-}
-
-.ctrlTab-preview-inner > .tabPreview-canvas {
-  box-shadow: 1px 1px 2px hsl(0,0%,12%);
-}
-
-.ctrlTab-preview:not(#ctrlTab-showAll) > * > .ctrlTab-preview-inner > .tabPreview-canvas {
-  margin-bottom: 2px;
-}
-
-.ctrlTab-preview-inner {
-  padding-bottom: 10px;
-}
-
-#ctrlTab-showAll:not(:focus) > * > .ctrlTab-preview-inner {
-  padding: 10px;
-  background-color: rgba(255,255,255,.2);
-  border-radius: .5em;
-}
-
-.ctrlTab-preview:focus > * > .ctrlTab-preview-inner {
-  color: white;
-  background-color: rgba(0,0,0,.6);
-  text-shadow: none;
-  padding: 8px;
-  border: 2px solid white;
-  border-radius: .5em;
-}
-
-.ctrlTab-preview:not(#ctrlTab-showAll):focus > * > .ctrlTab-preview-inner {
-  margin: -10px -10px 0;
-}
-
-#ctrlTab-showAll {
-  margin-top: .5em;
-}
-
 /* Status panel */
 
 .statuspanel-label {
   margin: 0;
   padding: 2px 4px;
   background: -moz-dialog;
   border: 1px none ThreeDShadow;
   border-top-style: solid;
@@ -2482,19 +2427,19 @@ notification[value="translation"] {
   border-left-style: solid;
   /* disabled for triggering grayscale AA (bug 659213)
   border-top-left-radius: .3em;
   */
   margin-left: 1em;
 }
 
 %include ../shared/fullscreen/warning.inc.css
+%include ../shared/ctrlTab.inc.css
 %include ../../../devtools/client/themes/responsivedesign.inc.css
 %include ../../../devtools/client/themes/commandline.inc.css
-
 %include ../shared/plugin-doorhanger.inc.css
 
 notification.pluginVulnerable > .notification-inner > .messageCloseButton {
   list-style-image: url("chrome://global/skin/icons/close-inverted.png");
 }
 
 @media (min-resolution: 1.1dppx) {
   notification.pluginVulnerable > .notification-inner > .messageCloseButton {
--- a/browser/themes/windows/searchbar.css
+++ b/browser/themes/windows/searchbar.css
@@ -122,68 +122,69 @@
   -moz-box-align: center;
 }
 
 .search-panel-current-engine {
   border-bottom: none;
 }
 
 .search-panel-tree {
-  border-top: 1px solid #ccc !important;
+  border-top: 1px solid var(--panel-separator-color) !important;
 }
 
 .search-panel-header {
   font-weight: normal;
-  background-color: rgb(245, 245, 245);
-  border-top: 1px solid #ccc;
+  background-color: hsla(210,4%,10%,.07);
+  border: none;
+  border-top: 1px solid var(--panel-separator-color);
   margin: 0;
   padding: 3px 6px;
-  color: #666;
+  color: GrayText;
 }
 
 .search-panel-header > label {
   margin-top: 2px !important;
   margin-bottom: 1px !important;
 }
 
 .search-panel-current-input > label {
   margin: 2px 0 1px !important;
 }
 
 .search-panel-input-value {
-  color: black;
+  color: -moz-fieldtext;
 }
 
 .search-panel-one-offs {
-  margin: 0 0 !important;
-  border-top: 1px solid #ccc;
+  margin: 0 !important;
+  border-top: 1px solid var(--panel-separator-color);
   line-height: 0;
 }
 
 .searchbar-engine-one-off-item {
   -moz-appearance: none;
   display: inline-block;
   border: none;
   min-width: 48px;
   height: 32px;
-  margin: 0 0;
-  padding: 0 0;
-  background: none;
-  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAWCAYAAAABxvaqAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gofECQNNVW2/AAAABBJREFUGFdjOHPmzH8GehEA/KpKg9YTf4AAAAAASUVORK5CYII=');
+  margin: 0;
+  padding: 0;
+  background: linear-gradient(transparent 15%, var(--panel-separator-color) 15%, var(--panel-separator-color) 85%, transparent 85%);
+  background-size: 1px auto;
   background-repeat: no-repeat;
   background-position: right center;
 }
 
 .searchbar-engine-one-off-item:-moz-locale-dir(rtl) {
   background-position: left center;
 }
 
 .searchbar-engine-one-off-item:not(.last-row) {
   box-sizing: content-box;
-  border-bottom: 1px solid #ccc;
+  border-bottom: 1px solid var(--panel-separator-color);
 }
 
 .search-setting-button-compact {
   border-bottom: none !important;
 }
 
 .search-panel-one-offs:not([compact=true]) > .searchbar-engine-one-off-item.last-of-row,
 .search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.last-of-row:not(.dummy),
@@ -195,42 +196,42 @@
 
 .searchbar-engine-one-off-item[selected] {
   background-color: Highlight;
   background-image: none;
 }
 
 .searchbar-engine-one-off-item > .button-box {
   border: none;
-  padding: 0 0;
+  padding: 0;
 }
 
 .searchbar-engine-one-off-item > .button-box > .button-text {
   display: none;
 }
 
 .searchbar-engine-one-off-item > .button-box > .button-icon {
   width: 16px;
   height: 16px;
 }
 
 .addengine-item {
   -moz-appearance: none;
   border: none;
   height: 32px;
-  margin: 0 0;
+  margin: 0;
   padding: 0 10px;
 }
 
 .addengine-item > .button-box {
   -moz-box-pack: start;
 }
 
 .addengine-item:first-of-type {
-  border-top: 1px solid #ccc;
+  border-top: 1px solid var(--panel-separator-color);
 }
 
 .addengine-item[selected] {
   background-color: Highlight;
   color: HighlightText;
 }
 
 .addengine-icon {
@@ -283,26 +284,21 @@
 }
 
 .search-panel-tree > .autocomplete-treebody::-moz-tree-image(fromhistory, selected) {
   list-style-image: url("chrome://browser/skin/search-history-icon.svg#search-history-icon-active");
 }
 
 .search-setting-button {
   -moz-appearance: none;
-  border-bottom: none;
-  border-left: none;
-  border-right: none;
-  -moz-border-top-colors: none;
   min-height: 32px;
 }
 
 .search-setting-button[selected] {
-  background-color: #d3d3d3;
-  border-top-color: #bdbebe;
+  background-color: hsla(210,4%,10%,.15);
 }
 
 .search-setting-button-compact {
   list-style-image: url("chrome://browser/skin/gear.svg#gear");
 }
 
 .search-setting-button-compact[selected] {
   list-style-image: url("chrome://browser/skin/gear.svg#gear-inverted");
--- a/build/autoconf/android.m4
+++ b/build/autoconf/android.m4
@@ -318,16 +318,17 @@ case "$target" in
     AC_SUBST(ANDROID_BUILD_TOOLS_VERSION)
 
     MOZ_ANDROID_AAR(customtabs, $ANDROID_SUPPORT_LIBRARY_VERSION, android, com/android/support)
     MOZ_ANDROID_AAR(appcompat-v7, $ANDROID_SUPPORT_LIBRARY_VERSION, android, com/android/support)
     MOZ_ANDROID_AAR(cardview-v7, $ANDROID_SUPPORT_LIBRARY_VERSION, android, com/android/support)
     MOZ_ANDROID_AAR(design, $ANDROID_SUPPORT_LIBRARY_VERSION, android, com/android/support)
     MOZ_ANDROID_AAR(recyclerview-v7, $ANDROID_SUPPORT_LIBRARY_VERSION, android, com/android/support)
     MOZ_ANDROID_AAR(support-v4, $ANDROID_SUPPORT_LIBRARY_VERSION, android, com/android/support, REQUIRED_INTERNAL_IMPL)
+    MOZ_ANDROID_AAR(palette-v7, $ANDROID_SUPPORT_LIBRARY_VERSION, android, com/android/support)
 
     ANDROID_SUPPORT_ANNOTATIONS_JAR="$ANDROID_SDK_ROOT/extras/android/m2repository/com/android/support/support-annotations/$ANDROID_SUPPORT_LIBRARY_VERSION/support-annotations-$ANDROID_SUPPORT_LIBRARY_VERSION.jar"
     AC_MSG_CHECKING([for support-annotations JAR])
     if ! test -e $ANDROID_SUPPORT_ANNOTATIONS_JAR ; then
         AC_MSG_ERROR([You must download the support-annotations lib.  Run the Android SDK tool and install the Android Support Repository under Extras.  See https://developer.android.com/tools/extras/support-library.html for more info. (looked for $ANDROID_SUPPORT_ANNOTATIONS_JAR)])
     fi
     AC_MSG_RESULT([$ANDROID_SUPPORT_ANNOTATIONS_JAR])
     AC_SUBST(ANDROID_SUPPORT_ANNOTATIONS_JAR)
--- a/build/clang-plugin/clang-plugin.cpp
+++ b/build/clang-plugin/clang-plugin.cpp
@@ -153,32 +153,38 @@ private:
     virtual void run(const MatchFinder::MatchResult &Result);
   };
 
   class AssertAssignmentChecker : public MatchFinder::MatchCallback {
   public:
     virtual void run(const MatchFinder::MatchResult &Result);
   };
 
+  class KungFuDeathGripChecker : public MatchFinder::MatchCallback {
+  public:
+    virtual void run(const MatchFinder::MatchResult &Result);
+  };
+
   ScopeChecker Scope;
   ArithmeticArgChecker ArithmeticArg;
   TrivialCtorDtorChecker TrivialCtorDtor;
   NaNExprChecker NaNExpr;
   NoAddRefReleaseOnReturnChecker NoAddRefReleaseOnReturn;
   RefCountedInsideLambdaChecker RefCountedInsideLambda;
   ExplicitOperatorBoolChecker ExplicitOperatorBool;
   NoDuplicateRefCntMemberChecker NoDuplicateRefCntMember;
   NeedsNoVTableTypeChecker NeedsNoVTableType;
   NonMemMovableTemplateArgChecker NonMemMovableTemplateArg;
   NonMemMovableMemberChecker NonMemMovableMember;
   ExplicitImplicitChecker ExplicitImplicit;
   NoAutoTypeChecker NoAutoType;
   NoExplicitMoveConstructorChecker NoExplicitMoveConstructor;
   RefCountedCopyConstructorChecker RefCountedCopyConstructor;
   AssertAssignmentChecker AssertAttribution;
+  KungFuDeathGripChecker KungFuDeathGrip;
   MatchFinder AstMatcher;
 };
 
 namespace {
 
 std::string getDeclarationNamespace(const Decl *Declaration) {
   const DeclContext *DC =
       Declaration->getDeclContext()->getEnclosingNamespaceContext();
@@ -264,16 +270,21 @@ bool isIgnoredPathForImplicitConversion(
   SmallString<1024> FileName = SM.getFilename(Loc);
   llvm::sys::fs::make_absolute(FileName);
   llvm::sys::path::reverse_iterator Begin = llvm::sys::path::rbegin(FileName),
                                     End = llvm::sys::path::rend(FileName);
   for (; Begin != End; ++Begin) {
     if (Begin->compare_lower(StringRef("graphite2")) == 0) {
       return true;
     }
+    if (Begin->compare_lower(StringRef("chromium")) == 0) {
+      // Ignore security/sandbox/chromium but not ipc/chromium.
+      ++Begin;
+      return Begin != End && Begin->compare_lower(StringRef("sandbox")) == 0;
+    }
   }
   return false;
 }
 
 bool isInterestingDeclForImplicitConversion(const Decl *Declaration) {
   return !isInIgnoredNamespaceForImplicitConversion(Declaration) &&
          !isIgnoredPathForImplicitConversion(Declaration);
 }
@@ -304,16 +315,54 @@ bool isIgnoredExprForMustUse(const Expr 
 
   return false;
 }
 
 template<typename T>
 StringRef getNameChecked(const T& D) {
   return D->getIdentifier() ? D->getName() : "";
 }
+
+bool typeIsRefPtr(QualType Q) {
+  CXXRecordDecl *D = Q->getAsCXXRecordDecl();
+  if (!D || !D->getIdentifier()) {
+    return false;
+  }
+
+  StringRef name = D->getName();
+  if (name == "RefPtr" || name == "nsCOMPtr") {
+    return true;
+  }
+  return false;
+}
+
+// The method defined in clang for ignoring implicit nodes doesn't work with
+// some AST trees. To get around this, we define our own implementation of
+// IgnoreImplicit.
+const Stmt *IgnoreImplicit(const Stmt *s) {
+  while (true) {
+    if (auto *ewc = dyn_cast<ExprWithCleanups>(s)) {
+      s = ewc->getSubExpr();
+    } else if (auto *mte = dyn_cast<MaterializeTemporaryExpr>(s)) {
+      s = mte->GetTemporaryExpr();
+    } else if (auto *bte = dyn_cast<CXXBindTemporaryExpr>(s)) {
+      s = bte->getSubExpr();
+    } else if (auto *ice = dyn_cast<ImplicitCastExpr>(s)) {
+      s = ice->getSubExpr();
+    } else {
+      break;
+    }
+  }
+
+  return s;
+}
+
+const Expr *IgnoreImplicit(const Expr *e) {
+  return cast<Expr>(IgnoreImplicit(static_cast<const Stmt *>(e)));
+}
 }
 
 class CustomTypeAnnotation {
   enum ReasonKind {
     RK_None,
     RK_Direct,
     RK_ArrayElement,
     RK_BaseClass,
@@ -811,16 +860,19 @@ AST_MATCHER(CallExpr, isAssertAssignment
       && Method->getDeclName().isIdentifier()
       && Method->getName() == AssertName;
 }
 
 AST_MATCHER(CXXRecordDecl, isLambdaDecl) {
   return Node.isLambda();
 }
 
+AST_MATCHER(QualType, isRefPtr) {
+  return typeIsRefPtr(Node);
+}
 }
 }
 
 namespace {
 
 void CustomTypeAnnotation::dumpAnnotationReason(DiagnosticsEngine &Diag,
                                                 QualType T,
                                                 SourceLocation Loc) {
@@ -1135,16 +1187,19 @@ DiagnosticsMatcher::DiagnosticsMatcher()
           hasDeclaration(cxxConstructorDecl(isCompilerProvidedCopyConstructor(),
                                             ofClass(hasRefCntMember()))))
           .bind("node"),
       &RefCountedCopyConstructor);
 
   AstMatcher.addMatcher(
       callExpr(isAssertAssignmentTestFunc()).bind("funcCall"),
       &AssertAttribution);
+
+  AstMatcher.addMatcher(varDecl(hasType(isRefPtr())).bind("decl"),
+                        &KungFuDeathGrip);
 }
 
 // These enum variants determine whether an allocation has occured in the code.
 enum AllocationVariety {
   AV_None,
   AV_Global,
   AV_Automatic,
   AV_Temporary,
@@ -1683,16 +1738,107 @@ void DiagnosticsMatcher::AssertAssignmen
       DiagnosticIDs::Error, "Forbidden assignment in assert expression");
   const CallExpr *FuncCall = Result.Nodes.getNodeAs<CallExpr>("funcCall");
 
   if (FuncCall && hasSideEffectAssignment(FuncCall)) {
     Diag.Report(FuncCall->getLocStart(), AssignInsteadOfComp);
   }
 }
 
+void DiagnosticsMatcher::KungFuDeathGripChecker::run(
+    const MatchFinder::MatchResult &Result) {
+  DiagnosticsEngine &Diag = Result.Context->getDiagnostics();
+  unsigned ErrorID = Diag.getDiagnosticIDs()->getCustomDiagID(
+      DiagnosticIDs::Error,
+      "Unused \"kungFuDeathGrip\" %0 objects constructed from %1 are prohibited");
+
+  unsigned NoteID = Diag.getDiagnosticIDs()->getCustomDiagID(
+      DiagnosticIDs::Note,
+      "Please switch all accesses to this %0 to go through '%1', or explicitly pass '%1' to `mozilla::Unused`");
+
+  const VarDecl *D = Result.Nodes.getNodeAs<VarDecl>("decl");
+  if (D->isReferenced() || !D->hasLocalStorage() || !D->hasInit()) {
+    return;
+  }
+
+  // Not interested in parameters.
+  if (isa<ImplicitParamDecl>(D) || isa<ParmVarDecl>(D)) {
+    return;
+  }
+
+  const Expr *E = IgnoreImplicit(D->getInit());
+  const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E);
+  if (CE && CE->getNumArgs() == 0) {
+    // We don't report an error when we construct and don't use a nsCOMPtr /
+    // nsRefPtr with no arguments. We don't report it because the error is not
+    // related to the current check. In the future it may be reported through a
+    // more generic mechanism.
+    return;
+  }
+
+  // We don't want to look at the single argument conversion constructors
+  // which are inbetween the declaration and the actual object which we are
+  // assigning into the nsCOMPtr/RefPtr. To do this, we repeatedly
+  // IgnoreImplicit, then look at the expression. If it is one of these
+  // conversion constructors, we ignore it and continue to dig.
+  while ((CE = dyn_cast<CXXConstructExpr>(E)) && CE->getNumArgs() == 1) {
+    E = IgnoreImplicit(CE->getArg(0));
+  }
+
+  // We allow taking a kungFuDeathGrip of `this` because it cannot change
+  // beneath us, so calling directly through `this` is OK. This is the same
+  // for local variable declarations.
+  //
+  // We also don't complain about unused RefPtrs which are constructed from
+  // the return value of a new expression, as these are required in order to
+  // immediately destroy the value created (which was presumably created for
+  // its side effects), and are not used as a death grip.
+  if (isa<CXXThisExpr>(E) || isa<DeclRefExpr>(E) || isa<CXXNewExpr>(E)) {
+    return;
+  }
+
+  // These types are assigned into nsCOMPtr and RefPtr for their side effects,
+  // and not as a kungFuDeathGrip. We don't want to consider RefPtr and nsCOMPtr
+  // types which are initialized with these types as errors.
+  const TagDecl *TD = E->getType()->getAsTagDecl();
+  if (TD && TD->getIdentifier()) {
+    static const char *IgnoreTypes[] = {
+      "already_AddRefed",
+      "nsGetServiceByCID",
+      "nsGetServiceByCIDWithError",
+      "nsGetServiceByContractID",
+      "nsGetServiceByContractIDWithError",
+      "nsCreateInstanceByCID",
+      "nsCreateInstanceByContractID",
+      "nsCreateInstanceFromFactory",
+    };
+
+    for (uint32_t i = 0; i < sizeof(IgnoreTypes) / sizeof(IgnoreTypes[0]); ++i) {
+      if (TD->getName() == IgnoreTypes[i]) {
+        return;
+      }
+    }
+  }
+
+  // Report the error
+  const char *ErrThing;
+  const char *NoteThing;
+  if (isa<MemberExpr>(E)) {
+    ErrThing  = "members";
+    NoteThing = "member";
+  } else {
+    ErrThing = "temporary values";
+    NoteThing = "value";
+  }
+
+  // We cannot provide the note if we don't have an initializer
+  Diag.Report(D->getLocStart(), ErrorID) << D->getType() << ErrThing;
+  Diag.Report(E->getLocStart(), NoteID) << NoteThing << getNameChecked(D);
+}
+
 class MozCheckAction : public PluginASTAction {
 public:
   ASTConsumerPtr CreateASTConsumer(CompilerInstance &CI,
                                    StringRef FileName) override {
 #if CLANG_VERSION_FULL >= 306
     std::unique_ptr<MozChecker> Checker(llvm::make_unique<MozChecker>(CI));
     ASTConsumerPtr Other(Checker->getOtherConsumer());
 
new file mode 100644
--- /dev/null
+++ b/build/clang-plugin/tests/TestKungFuDeathGrip.cpp
@@ -0,0 +1,107 @@
+#define MOZ_IMPLICIT __attribute__((annotate("moz_implicit")))
+
+template <typename T>
+class already_AddRefed {
+public:
+  already_AddRefed();
+  T* mPtr;
+};
+
+template <typename T>
+class RefPtr {
+public:
+  RefPtr();
+  MOZ_IMPLICIT RefPtr(T* aIn);
+  MOZ_IMPLICIT RefPtr(already_AddRefed<T> aIn);
+  ~RefPtr();
+  T* mPtr;
+};
+
+template <typename T>
+class nsCOMPtr {
+public:
+  nsCOMPtr();
+  MOZ_IMPLICIT nsCOMPtr(T* aIn);
+  MOZ_IMPLICIT nsCOMPtr(already_AddRefed<T> aIn);
+  ~nsCOMPtr();
+  T* mPtr;
+};
+
+class Type {
+public:
+  static nsCOMPtr<Type> someStaticCOMPtr;
+
+  void f(nsCOMPtr<Type> ignoredArgument, Type *param) {
+    nsCOMPtr<Type> never_referenced;
+    nsCOMPtr<Type> kfdg_t1(this);
+    nsCOMPtr<Type> kfdg_t2 = this;
+
+    nsCOMPtr<Type> kfdg_m1(p); // expected-error {{Unused "kungFuDeathGrip" 'nsCOMPtr<Type>' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m1', or explicitly pass 'kfdg_m1' to `mozilla::Unused`}}
+    nsCOMPtr<Type> kfdg_m2 = p; // expected-error {{Unused "kungFuDeathGrip" 'nsCOMPtr<Type>' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m2', or explicitly pass 'kfdg_m2' to `mozilla::Unused`}}
+    nsCOMPtr<Type> kfdg_m3(p);
+    kfdg_m3.mPtr->f(nullptr, nullptr);
+    nsCOMPtr<Type> kfdg_m4 = p;
+    kfdg_m4.mPtr->f(nullptr, nullptr);
+
+    nsCOMPtr<Type> kfdg_a1((already_AddRefed<Type>()));
+    nsCOMPtr<Type> kfdg_a2 = already_AddRefed<Type>();
+
+    nsCOMPtr<Type> kfdg_p1(param);
+    nsCOMPtr<Type> kfdg_p2 = param;
+
+
+    RefPtr<Type> never_referenced2;
+    RefPtr<Type> kfdg_t3(this);
+    RefPtr<Type> kfdg_t4 = this;
+
+    RefPtr<Type> kfdg_m5(p); // expected-error {{Unused "kungFuDeathGrip" 'RefPtr<Type>' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m5', or explicitly pass 'kfdg_m5' to `mozilla::Unused`}}
+    RefPtr<Type> kfdg_m6 = p; // expected-error {{Unused "kungFuDeathGrip" 'RefPtr<Type>' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m6', or explicitly pass 'kfdg_m6' to `mozilla::Unused`}}
+    RefPtr<Type> kfdg_m7(p);
+    kfdg_m7.mPtr->f(nullptr, nullptr);
+    RefPtr<Type> kfdg_m8 = p;
+    kfdg_m8.mPtr->f(nullptr, nullptr);
+
+    RefPtr<Type> kfdg_a3((already_AddRefed<Type>()));
+    RefPtr<Type> kfdg_a4 = already_AddRefed<Type>()