Merge mozilla-central to beta. a=merge, l10n=me on a CLOSED TREE
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 10 Nov 2017 16:17:02 -0500
changeset 444588 6c6c0e855154324123b4667ae35218dfcac74498
parent 444250 7ca33aee2c1d86c25220bc71c95fe6ac62b0dfe6 (current diff)
parent 444587 092ccc6335a529133a8412a8f1bf1cdda872c6a9 (diff)
child 444591 95bb0fe925ede241a79413eb0ed078e0c9c5f901
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone58.0
Merge mozilla-central to beta. a=merge, l10n=me on a CLOSED TREE
browser/themes/shared/notification-icons/plugin-blocked.svg
browser/themes/shared/notification-icons/plugin.svg
build/sccache.mk
config/stl-headers
config/system-headers
dom/base/WebSocket.cpp
dom/base/WebSocket.h
dom/base/test/file_bug1384658.html
dom/base/test/file_websocket_basic_wsh.py
dom/base/test/file_websocket_bigBlob_wsh.py
dom/base/test/file_websocket_hello_wsh.py
dom/base/test/file_websocket_http_resource.txt
dom/base/test/file_websocket_permessage_deflate_disabled_wsh.py
dom/base/test/file_websocket_permessage_deflate_params_wsh.py
dom/base/test/file_websocket_permessage_deflate_rejected_wsh.py
dom/base/test/file_websocket_permessage_deflate_wsh.py
dom/base/test/file_websocket_wsh.py
dom/base/test/frame_bug1384658.html
dom/base/test/iframe_webSocket_sandbox.html
dom/base/test/test_bug1081686.html
dom/base/test/test_bug1384658.html
dom/base/test/test_webSocket_sandbox.html
dom/base/test/test_websocket1.html
dom/base/test/test_websocket2.html
dom/base/test/test_websocket3.html
dom/base/test/test_websocket4.html
dom/base/test/test_websocket5.html
dom/base/test/test_websocket_basic.html
dom/base/test/test_websocket_bigBlob.html
dom/base/test/test_websocket_frame.html
dom/base/test/test_websocket_hello.html
dom/base/test/test_websocket_permessage_deflate.html
dom/base/test/websocket_helpers.js
dom/base/test/websocket_hybi/file_binary-frames_wsh.py
dom/base/test/websocket_hybi/file_check-binary-messages_wsh.py
dom/base/test/websocket_hybi/mochitest.ini
dom/base/test/websocket_hybi/test_receive-arraybuffer.html
dom/base/test/websocket_hybi/test_receive-blob.html
dom/base/test/websocket_hybi/test_send-arraybuffer.html
dom/base/test/websocket_hybi/test_send-blob.html
dom/base/test/websocket_tests.js
dom/base/test/window_bug1384658.html
dom/interfaces/html/nsIDOMHTMLOptionElement.idl
dom/interfaces/json/moz.build
dom/interfaces/json/nsIJSON.idl
dom/json/moz.build
dom/json/nsJSON.cpp
dom/json/nsJSON.h
dom/json/test/mochitest.ini
dom/json/test/test_json.html
dom/json/test/unit/decodeFromStream-01.json
dom/json/test/unit/decodeFromStream-small.json
dom/json/test/unit/test_decodeFromStream.js
dom/json/test/unit/xpcshell.ini
dom/workers/test/test_webSocket_sharedWorker.html
dom/workers/test/test_websocket1.html
dom/workers/test/test_websocket2.html
dom/workers/test/test_websocket3.html
dom/workers/test/test_websocket4.html
dom/workers/test/test_websocket5.html
dom/workers/test/test_websocket_basic.html
dom/workers/test/test_websocket_https.html
dom/workers/test/test_websocket_loadgroup.html
dom/workers/test/webSocket_sharedWorker.js
dom/workers/test/websocket_basic_worker.js
dom/workers/test/websocket_helpers.js
dom/workers/test/websocket_https.html
dom/workers/test/websocket_https_worker.js
dom/workers/test/websocket_loadgroup_worker.js
dom/workers/test/websocket_worker1.js
dom/workers/test/websocket_worker2.js
dom/workers/test/websocket_worker3.js
dom/workers/test/websocket_worker4.js
dom/workers/test/websocket_worker5.js
ipc/chromium/src/base/platform_file_posix.cc
ipc/chromium/src/base/platform_file_win.cc
ipc/chromium/src/base/thread_local_storage_posix.cc
ipc/chromium/src/base/thread_local_storage_win.cc
js/src/ds/FixedSizeHash.h
js/src/jit-test/tests/xdr/bug1385310.js
js/src/tests/ecma_6/Comprehensions/arguments.js
js/src/tests/ecma_6/Comprehensions/array-yield.js
js/src/tests/ecma_6/Comprehensions/error-messages.js
js/src/tests/ecma_6/Comprehensions/for-reserved-word.js
js/src/tests/ecma_6/Comprehensions/generator-semantics.js
js/src/tests/ecma_6/Comprehensions/inside-derived-class.js
js/src/tests/ecma_6/Comprehensions/nested-for-if.js
js/src/tests/ecma_6/Comprehensions/scope.js
js/src/tests/ecma_6/Comprehensions/shell.js
js/src/tests/ecma_6/Comprehensions/sudoku.js
js/src/tests/ecma_6/Comprehensions/syntax.js
js/src/tests/ecma_6/Comprehensions/toSource.js
js/src/tests/js1_8_5/reflect-parse/comprehensions.js
js/src/tests/js1_8_5/reflect-parse/generatorExpressions.js
netwerk/base/nsIIOService2.idl
services/sync/tests/tps/mozmill_sanity.js
services/sync/tests/tps/mozmill_sanity2.js
services/sync/tests/tps/test_mozmill_sanity.js
services/sync/tps/extensions/mozmill/chrome.manifest
services/sync/tps/extensions/mozmill/install.rdf
services/sync/tps/extensions/mozmill/resource/driver/controller.js
services/sync/tps/extensions/mozmill/resource/driver/elementslib.js
services/sync/tps/extensions/mozmill/resource/driver/mozelement.js
services/sync/tps/extensions/mozmill/resource/driver/mozmill.js
services/sync/tps/extensions/mozmill/resource/driver/msgbroker.js
services/sync/tps/extensions/mozmill/resource/modules/assertions.js
services/sync/tps/extensions/mozmill/resource/modules/driver.js
services/sync/tps/extensions/mozmill/resource/modules/errors.js
services/sync/tps/extensions/mozmill/resource/modules/frame.js
services/sync/tps/extensions/mozmill/resource/modules/l10n.js
services/sync/tps/extensions/mozmill/resource/modules/stack.js
services/sync/tps/extensions/mozmill/resource/modules/windows.js
services/sync/tps/extensions/mozmill/resource/stdlib/EventUtils.js
services/sync/tps/extensions/mozmill/resource/stdlib/arrays.js
services/sync/tps/extensions/mozmill/resource/stdlib/dom.js
services/sync/tps/extensions/mozmill/resource/stdlib/httpd.js
services/sync/tps/extensions/mozmill/resource/stdlib/json2.js
services/sync/tps/extensions/mozmill/resource/stdlib/objects.js
services/sync/tps/extensions/mozmill/resource/stdlib/os.js
services/sync/tps/extensions/mozmill/resource/stdlib/securable-module.js
services/sync/tps/extensions/mozmill/resource/stdlib/strings.js
services/sync/tps/extensions/mozmill/resource/stdlib/utils.js
services/sync/tps/extensions/mozmill/resource/stdlib/withs.js
testing/web-platform/tests/service-workers/service-worker/resources/resource-timing-iframe.html
testing/web-platform/tests/web-animations/animation-model/animation-types/discrete-animation.html
testing/web-platform/tests/web-animations/animation-model/keyframe-effects/effect-value-visibility.html
testing/web-platform/tests/web-animations/interfaces/AnimationEffectTiming/getAnimations.html
testing/web-platform/tests/web-animations/interfaces/AnimationEffectTiming/getComputedStyle.html
testing/web-platform/tests/web-animations/interfaces/KeyframeEffect/setTarget.html
toolkit/content/Makefile.in
toolkit/crashreporter/tools/unit-symbolstore.py
toolkit/themes/shared/plugins/contentPluginActivate.png
toolkit/themes/shared/plugins/contentPluginClose.png
tools/lint/eslint/eslint-plugin-mozilla/lib/rules/avoid-nsISupportsString-preferences.js
tools/lint/eslint/eslint-plugin-mozilla/tests/avoid-nsISupportsString-preferences.js
--- a/.eslintignore
+++ b/.eslintignore
@@ -240,16 +240,17 @@ dom/system/**
 dom/tests/**
 dom/time/**
 dom/u2f/**
 dom/url/**
 dom/vr/**
 dom/webauthn/**
 dom/webbrowserpersist/**
 dom/webidl/**
+dom/websocket/**
 dom/workers/**
 dom/worklet/**
 dom/xbl/**
 dom/xhr/**
 dom/xml/**
 dom/xslt/**
 dom/xul/**
 
@@ -329,17 +330,16 @@ testing/talos/talos/tests/kraken/**
 
 testing/web-platform/**
 testing/xpcshell/moz-http2/**
 testing/xpcshell/node-http2/**
 
 # Third party services
 services/common/kinto-http-client.js
 services/common/kinto-offline-client.js
-services/sync/tps/extensions/mozmill
 
 # toolkit/ exclusions
 
 # Not part of the default build
 toolkit/components/help/**
 
 # Intentionally invalid JS
 toolkit/components/workerloader/tests/moduleF-syntax-error.js
--- a/accessible/generic/ApplicationAccessible.cpp
+++ b/accessible/generic/ApplicationAccessible.cpp
@@ -160,27 +160,26 @@ void
 ApplicationAccessible::Init()
 {
   // Basically children are kept updated by Append/RemoveChild method calls.
   // However if there are open windows before accessibility was started
   // then we need to make sure root accessibles for open windows are created so
   // that all root accessibles are stored in application accessible children
   // array.
 
-  nsGlobalWindow::WindowByIdTable* windowsById =
-    nsGlobalWindow::GetWindowsTable();
+  nsGlobalWindowOuter::OuterWindowByIdTable* windowsById =
+    nsGlobalWindowOuter::GetWindowsTable();
 
   if (!windowsById) {
     return;
   }
 
   for (auto iter = windowsById->Iter(); !iter.Done(); iter.Next()) {
-    nsGlobalWindow* window = iter.Data();
-    if (window->GetDocShell() && window->IsOuterWindow() &&
-        window->IsRootOuterWindow()) {
+    nsGlobalWindowOuter* window = iter.Data();
+    if (window->GetDocShell() && window->IsRootOuterWindow()) {
       nsCOMPtr<nsIDocument> docNode = window->GetExtantDoc();
 
       if (docNode) {
         GetAccService()->GetDocAccessible(docNode);  // ensure creation
       }
     }
   }
 }
--- a/accessible/generic/RootAccessible.cpp
+++ b/accessible/generic/RootAccessible.cpp
@@ -480,17 +480,18 @@ RootAccessible::Shutdown()
 
 Relation
 RootAccessible::RelationByType(RelationType aType)
 {
   if (!mDocumentNode || aType != RelationType::EMBEDS)
     return DocAccessibleWrap::RelationByType(aType);
 
   if (nsPIDOMWindowOuter* rootWindow = mDocumentNode->GetWindow()) {
-    nsCOMPtr<nsPIDOMWindowOuter> contentWindow = nsGlobalWindow::Cast(rootWindow)->GetContent();
+    nsCOMPtr<nsPIDOMWindowOuter> contentWindow =
+      nsGlobalWindowOuter::Cast(rootWindow)->GetContent();
     if (contentWindow) {
       nsCOMPtr<nsIDocument> contentDocumentNode = contentWindow->GetDoc();
       if (contentDocumentNode) {
         DocAccessible* contentDocument =
           GetAccService()->GetDocAccessible(contentDocumentNode);
         if (contentDocument)
           return Relation(contentDocument);
       }
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -48,21 +48,16 @@ ifdef COMPILE_ENVIRONMENT
 libs::
 	cp -p $(MOZ_APP_NAME)$(BIN_SUFFIX) $(DIST)/bin/$(MOZ_APP_NAME)-bin$(BIN_SUFFIX)
 endif
 
 GARBAGE += $(addprefix $(FINAL_TARGET)/defaults/pref/, firefox.js)
 
 endif
 
-# channel-prefs.js is handled separate from other prefs due to bug 756325
-libs:: $(srcdir)/profile/channel-prefs.js
-	$(NSINSTALL) -D $(DIST)/bin/defaults/pref
-	$(call py_action,preprocessor,-Fsubstitution $(PREF_PPFLAGS) $(ACDEFINES) $^ -o $(DIST)/bin/defaults/pref/channel-prefs.js)
-
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 
 MAC_APP_NAME = $(MOZ_APP_DISPLAYNAME)
 
 ifdef MOZ_DEBUG
 MAC_APP_NAME := $(MAC_APP_NAME)Debug
 endif
 
--- a/browser/app/moz.build
+++ b/browser/app/moz.build
@@ -31,28 +31,25 @@ with Files("profile/channel-prefs.js"):
 with Files("profile/firefox.js"):
     BUG_COMPONENT = ("Firefox", "General")
 
 
 DIRS += ['profile/extensions']
 
 GeckoProgram(CONFIG['MOZ_APP_NAME'])
 
-JS_PREFERENCE_PP_FILES += [
-    'profile/firefox.js',
-]
-
 SOURCES += [
     'nsBrowserApp.cpp',
 ]
 
-FINAL_TARGET_FILES += ['blocklist.xml']
-FINAL_TARGET_FILES.defaults += ['permissions']
+# Neither channel-prefs.js nor firefox.exe want to end up in dist/bin/browser.
+DIST_SUBDIR = ""
 
-DEFINES['APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
+# channel-prefs.js is handled separate from other prefs due to bug 756325
+JS_PREFERENCE_PP_FILES += ['profile/channel-prefs.js']
 
 LOCAL_INCLUDES += [
     '!/build',
     '/toolkit/xre',
     '/xpcom/base',
     '/xpcom/build',
 ]
 
@@ -69,19 +66,16 @@ if CONFIG['_MSC_VER']:
     # Always enter a Windows program through wmain, whether or not we're
     # a console application.
     WIN32_EXE_LDFLAGS += ['-ENTRY:wmainCRTStartup']
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     RCINCLUDE = 'splash.rc'
     DEFINES['MOZ_PHOENIX'] = True
 
-for cdm in CONFIG['MOZ_EME_MODULES']:
-    DEFINES['MOZ_%s_EME' % cdm.upper()] = True
-
 if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
     # For sandbox includes and the include dependencies those have
     LOCAL_INCLUDES += [
         '/security/sandbox/chromium',
         '/security/sandbox/chromium-shim',
     ]
 
     USE_LIBS += [
@@ -107,19 +101,16 @@ if CONFIG['OS_ARCH'] == 'WINNT' and not 
 DisableStlWrapping()
 
 if CONFIG['MOZ_LINKER']:
     OS_LIBS += CONFIG['MOZ_ZLIB_LIBS']
 
 if CONFIG['HAVE_CLOCK_MONOTONIC']:
     OS_LIBS += CONFIG['REALTIME_LIBS']
 
-if CONFIG['MOZ_GPSD']:
-    DEFINES['MOZ_GPSD'] = True
-
 if CONFIG['MOZ_LINUX_32_SSE2_STARTUP_ERROR']:
     DEFINES['MOZ_LINUX_32_SSE2_STARTUP_ERROR'] = True
     COMPILE_FLAGS['OS_CXXFLAGS'] = [
         f for f in COMPILE_FLAGS.get('OS_CXXFLAGS', [])
         if not f.startswith('-march=') and f not in ('-msse', '-msse2', '-mfpmath=sse')
     ] + [
         '-mno-sse', '-mno-sse2', '-mfpmath=387',
     ]
--- a/browser/app/profile/channel-prefs.js
+++ b/browser/app/profile/channel-prefs.js
@@ -1,5 +1,6 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#filter substitution
 pref("app.update.channel", "@MOZ_UPDATE_CHANNEL@");
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -424,16 +424,17 @@ pref("browser.sessionhistory.max_entries
 pref("permissions.manager.defaultsUrl", "resource://app/defaults/permissions");
 
 // Set default fallback values for site permissions we want
 // the user to be able to globally change.
 pref("permissions.default.camera", 0);
 pref("permissions.default.microphone", 0);
 pref("permissions.default.geo", 0);
 pref("permissions.default.desktop-notification", 0);
+pref("permissions.default.shortcuts", 0);
 
 // handle links targeting new windows
 // 1=current window/tab, 2=new window, 3=new tab in most recent window
 pref("browser.link.open_newwindow", 3);
 
 // handle external links (i.e. links opened from a different application)
 // default: use browser.link.open_newwindow
 // 1-3: see browser.link.open_newwindow for interpretation
--- a/browser/base/content/browser-pageActions.js
+++ b/browser/base/content/browser-pageActions.js
@@ -43,34 +43,16 @@ var BrowserPageActions = {
     return this.mainViewBodyNode = this.mainViewNode.querySelector(".panel-subview-body");
   },
 
   /**
    * Inits.  Call to init.
    */
   init() {
     this.placeAllActions();
-
-    // Add a click listener to #page-action-buttons for blocking clicks on
-    // disabled actions in the urlbar.  Normally we'd do this by setting
-    // `pointer-events: none` in the CSS, but that also blocks context menu
-    // events, and we want the context menu even on disabled actions so that
-    // they can be removed from the urlbar.
-    this.mainButtonNode.parentNode.addEventListener("click", event => {
-      if (event.button == 2) {
-        // Let context-clicks be handled normally.
-        return;
-      }
-      let node = event.originalTarget;
-      let action = this.actionForNode(node);
-      if (action && action.getDisabled(window)) {
-        event.preventDefault();
-        event.stopPropagation();
-      }
-    }, true);
   },
 
   /**
    * Places all registered actions.
    */
   placeAllActions() {
     // Place actions in the panel.  Notify of onBeforePlacedInWindow too.
     for (let action of PageActions.actions) {
@@ -81,17 +63,17 @@ var BrowserPageActions = {
     // Place actions in the urlbar.  Do this in reverse order.  The reason is
     // subtle.  If there were no urlbar nodes already in markup (like the
     // bookmark star button), then doing this in forward order would be fine.
     // Forward order means that the insert-before relationship is always broken:
     // there's never a next-sibling node before which to insert a new node, so
     // node.insertBefore() is always passed null, and nodes are always appended.
     // That will break the position of nodes that should be inserted before
     // nodes that are in markup, which in turn can break other nodes.
-    let actionsInUrlbar = PageActions.actionsInUrlbar;
+    let actionsInUrlbar = PageActions.actionsInUrlbar(window);
     for (let i = actionsInUrlbar.length - 1; i >= 0; i--) {
       let action = actionsInUrlbar[i];
       this.placeActionInUrlbar(action);
     }
   },
 
   /**
    * Adds or removes as necessary DOM nodes for the given action.
@@ -107,31 +89,29 @@ var BrowserPageActions = {
 
   /**
    * Adds or removes as necessary DOM nodes for the action in the panel.
    *
    * @param  action (PageActions.Action, required)
    *         The action to place.
    */
   placeActionInPanel(action) {
-    let insertBeforeID = PageActions.nextActionIDInPanel(action);
     let id = this.panelButtonNodeIDForActionID(action.id);
     let node = document.getElementById(id);
     if (!node) {
       let panelViewNode;
       [node, panelViewNode] = this._makePanelButtonNodeForAction(action);
       node.id = id;
-      let insertBeforeNode = null;
-      if (insertBeforeID) {
-        let insertBeforeNodeID =
-          this.panelButtonNodeIDForActionID(insertBeforeID);
-        insertBeforeNode = document.getElementById(insertBeforeNodeID);
-      }
+      let insertBeforeID = PageActions.nextActionIDInPanel(action);
+      let insertBeforeNode =
+        insertBeforeID ? this.panelButtonNodeForActionID(insertBeforeID) :
+        null;
       this.mainViewBodyNode.insertBefore(node, insertBeforeNode);
       this.updateAction(action);
+      this._updateActionDisabledInPanel(action);
       action.onPlacedInPanel(node);
       if (panelViewNode) {
         action.subview.onPlaced(panelViewNode);
       }
     }
   },
 
   _makePanelButtonNodeForAction(action) {
@@ -351,21 +331,20 @@ var BrowserPageActions = {
 
   /**
    * Adds or removes as necessary a DOM node for the given action in the urlbar.
    *
    * @param  action (PageActions.Action, required)
    *         The action to place.
    */
   placeActionInUrlbar(action) {
-    let insertBeforeID = PageActions.nextActionIDInUrlbar(action);
     let id = this.urlbarButtonNodeIDForActionID(action.id);
     let node = document.getElementById(id);
 
-    if (!action.shownInUrlbar) {
+    if (!action.shouldShowInUrlbar(window)) {
       if (node) {
         if (action.__urlbarNodeInMarkup) {
           node.hidden = true;
         } else {
           node.remove();
         }
       }
       return;
@@ -377,49 +356,42 @@ var BrowserPageActions = {
       node.hidden = false;
     } else if (!node) {
       newlyPlaced = true;
       node = this._makeUrlbarButtonNode(action);
       node.id = id;
     }
 
     if (newlyPlaced) {
-      let parentNode = this.mainButtonNode.parentNode;
-      let insertBeforeNode = null;
-      if (insertBeforeID) {
-        let insertBeforeNodeID =
-          this.urlbarButtonNodeIDForActionID(insertBeforeID);
-        insertBeforeNode = document.getElementById(insertBeforeNodeID);
-      }
-      parentNode.insertBefore(node, insertBeforeNode);
+      let insertBeforeID = PageActions.nextActionIDInUrlbar(window, action);
+      let insertBeforeNode =
+        insertBeforeID ? this.urlbarButtonNodeForActionID(insertBeforeID) :
+        null;
+      this.mainButtonNode.parentNode.insertBefore(node, insertBeforeNode);
       this.updateAction(action);
       action.onPlacedInUrlbar(node);
 
       // urlbar buttons should always have tooltips, so if the node doesn't have
       // one, then as a last resort use the label of the corresponding panel
       // button.  Why not set tooltiptext to action.title when the node is
       // created?  Because the consumer may set a title dynamically.
       if (!node.hasAttribute("tooltiptext")) {
-        let panelNodeID = this.panelButtonNodeIDForActionID(action.id);
-        let panelNode = document.getElementById(panelNodeID);
+        let panelNode = this.panelButtonNodeForActionID(action.id);
         if (panelNode) {
           node.setAttribute("tooltiptext", panelNode.getAttribute("label"));
         }
       }
     }
   },
 
   _makeUrlbarButtonNode(action) {
     let buttonNode = document.createElement("image");
     buttonNode.classList.add("urlbar-icon", "urlbar-page-action");
     buttonNode.setAttribute("actionid", action.id);
     buttonNode.setAttribute("role", "button");
-    buttonNode.addEventListener("contextmenu", event => {
-      BrowserPageActions.onContextMenu(event);
-    });
     if (action.nodeAttributes) {
       for (let name in action.nodeAttributes) {
         buttonNode.setAttribute(name, action.nodeAttributes[name]);
       }
     }
     buttonNode.addEventListener("click", event => {
       this.doCommandForAction(action, event, buttonNode);
     });
@@ -434,18 +406,17 @@ var BrowserPageActions = {
    */
   removeAction(action) {
     this._removeActionFromPanel(action);
     this._removeActionFromUrlbar(action);
     action.onRemovedFromWindow(window);
   },
 
   _removeActionFromPanel(action) {
-    let id = this.panelButtonNodeIDForActionID(action.id);
-    let node = document.getElementById(id);
+    let node = this.panelButtonNodeForActionID(action.id);
     if (node) {
       node.remove();
     }
     if (action.subview) {
       let panelViewNodeID = this._panelViewNodeIDForActionID(action.id, false);
       let panelViewNode = document.getElementById(panelViewNodeID);
       if (panelViewNode) {
         panelViewNode.remove();
@@ -461,127 +432,120 @@ var BrowserPageActions = {
       );
       if (separator) {
         separator.remove();
       }
     }
   },
 
   _removeActionFromUrlbar(action) {
-    let id = this.urlbarButtonNodeIDForActionID(action.id);
-    let node = document.getElementById(id);
+    let node = this.urlbarButtonNodeForActionID(action.id);
     if (node) {
       node.remove();
     }
   },
 
   /**
    * Updates the DOM nodes of an action to reflect either a changed property or
    * all properties.
    *
    * @param  action (PageActions.Action, required)
    *         The action to update.
-   * @param  nameToUpdate (string, optional)
-   *         The property's name.  If not given, then DOM nodes will be updated
-   *         to reflect the current values of all properties.
+   * @param  propertyName (string, optional)
+   *         The name of the property to update.  If not given, then DOM nodes
+   *         will be updated to reflect the current values of all properties.
    */
-  updateAction(action, nameToUpdate = null) {
-    let names = nameToUpdate ? [nameToUpdate] : [
-      "disabled",
+  updateAction(action, propertyName = null) {
+    let propertyNames = propertyName ? [propertyName] : [
       "iconURL",
       "title",
       "tooltip",
     ];
-    for (let name of names) {
+    for (let name of propertyNames) {
       let upper = name[0].toUpperCase() + name.substr(1);
       this[`_updateAction${upper}`](action);
     }
   },
 
   _updateActionDisabled(action) {
-    let nodeIDs = [
-      this.panelButtonNodeIDForActionID(action.id),
-      this.urlbarButtonNodeIDForActionID(action.id),
-    ];
-    for (let nodeID of nodeIDs) {
-      let node = document.getElementById(nodeID);
-      if (node) {
-        if (action.getDisabled(window)) {
-          node.setAttribute("disabled", "true");
-        } else {
-          node.removeAttribute("disabled");
-        }
+    this._updateActionDisabledInPanel(action);
+    this.placeActionInUrlbar(action);
+  },
+
+  _updateActionDisabledInPanel(action) {
+    let panelButton = this.panelButtonNodeForActionID(action.id);
+    if (panelButton) {
+      if (action.getDisabled(window)) {
+        panelButton.setAttribute("disabled", "true");
+      } else {
+        panelButton.removeAttribute("disabled");
       }
     }
   },
 
   _updateActionIconURL(action) {
-    let nodeIDs = [
-      this.panelButtonNodeIDForActionID(action.id),
-      this.urlbarButtonNodeIDForActionID(action.id),
-    ];
-    for (let nodeID of nodeIDs) {
-      let node = document.getElementById(nodeID);
-      if (node) {
-        for (let size of [16, 32]) {
-          let url = action.iconURLForSize(size, window);
-          let prop = `--pageAction-image-${size}px`;
-          if (url) {
-            node.style.setProperty(prop, `url("${url}")`);
-          } else {
-            node.style.removeProperty(prop);
-          }
+    let nodes = [
+      this.panelButtonNodeForActionID(action.id),
+      this.urlbarButtonNodeForActionID(action.id),
+    ].filter(n => !!n);
+    for (let node of nodes) {
+      for (let size of [16, 32]) {
+        let url = action.iconURLForSize(size, window);
+        let prop = `--pageAction-image-${size}px`;
+        if (url) {
+          node.style.setProperty(prop, `url("${url}")`);
+        } else {
+          node.style.removeProperty(prop);
         }
       }
     }
   },
 
   _updateActionTitle(action) {
     let title = action.getTitle(window);
     if (!title) {
       // `title` is a required action property, but the bookmark action's is an
       // empty string since its actual title is set via
       // BookmarkingUI.updateBookmarkPageMenuItem().  The purpose of this early
       // return is to ignore that empty title.
       return;
     }
-    let attrNamesByNodeIDFnName = {
-      panelButtonNodeIDForActionID: "label",
-      urlbarButtonNodeIDForActionID: "aria-label",
+    let attrNamesByNodeFnName = {
+      panelButtonNodeForActionID: "label",
+      urlbarButtonNodeForActionID: "aria-label",
     };
-    for (let [fnName, attrName] of Object.entries(attrNamesByNodeIDFnName)) {
-      let nodeID = this[fnName](action.id);
-      let node = document.getElementById(nodeID);
+    for (let [fnName, attrName] of Object.entries(attrNamesByNodeFnName)) {
+      let node = this[fnName](action.id);
       if (node) {
         node.setAttribute(attrName, title);
       }
     }
     // tooltiptext falls back to the title, so update it, too.
     this._updateActionTooltip(action);
   },
 
   _updateActionTooltip(action) {
-    let node = document.getElementById(
-      this.urlbarButtonNodeIDForActionID(action.id)
-    );
+    let node = this.urlbarButtonNodeForActionID(action.id);
     if (node) {
       let tooltip = action.getTooltip(window) || action.getTitle(window);
       node.setAttribute("tooltiptext", tooltip);
     }
   },
 
   doCommandForAction(action, event, buttonNode) {
     if (event && event.type == "click" && event.button != 0) {
       return;
     }
     PageActions.logTelemetry("used", action, buttonNode);
     // If we're in the panel, open a subview inside the panel:
     // Note that we can't use this.panelNode.contains(buttonNode) here
-    // because of XBL boundaries breaking ELement.contains.
-    if (action.subview && buttonNode && buttonNode.closest("panel") == this.panelNode) {
+    // because of XBL boundaries breaking Element.contains.
+    if (action.subview &&
+        buttonNode &&
+        buttonNode.closest("panel") == this.panelNode) {
       let panelViewNodeID = this._panelViewNodeIDForActionID(action.id, false);
       let panelViewNode = document.getElementById(panelViewNodeID);
       action.subview.onShowing(panelViewNode);
       this.multiViewNode.showSubView(panelViewNode, buttonNode);
       return;
     }
     // Otherwise, hide the main popup in case it was open:
     this.panelNode.hidePopup();
@@ -623,27 +587,49 @@ var BrowserPageActions = {
         actionID = this._actionIDForNodeID(n.id);
         action = PageActions.actionForID(actionID);
       }
     }
     return action;
   },
 
   /**
+   * The given action's top-level button in the main panel.
+   *
+   * @param  actionID (string, required)
+   *         The action ID.
+   * @return (DOM node) The action's button in the main panel.
+   */
+  panelButtonNodeForActionID(actionID) {
+    return document.getElementById(this.panelButtonNodeIDForActionID(actionID));
+  },
+
+  /**
    * The ID of the given action's top-level button in the main panel.
    *
    * @param  actionID (string, required)
    *         The action ID.
    * @return (string) The ID of the action's button in the main panel.
    */
   panelButtonNodeIDForActionID(actionID) {
     return `pageAction-panel-${actionID}`;
   },
 
   /**
+   * The given action's button in the urlbar.
+   *
+   * @param  actionID (string, required)
+   *         The action ID.
+   * @return (DOM node) The action's urlbar button node.
+   */
+  urlbarButtonNodeForActionID(actionID) {
+    return document.getElementById(this.urlbarButtonNodeIDForActionID(actionID));
+  },
+
+  /**
    * The ID of the given action's button in the urlbar.
    *
    * @param  actionID (string, required)
    *         The action ID.
    * @return (string) The ID of the action's urlbar button node.
    */
   urlbarButtonNodeIDForActionID(actionID) {
     let action = PageActions.actionForID(actionID);
@@ -717,86 +703,95 @@ var BrowserPageActions = {
    * Show the page action panel
    *
    * @param  event (DOM event, optional)
    *         The event that triggers showing the panel. (such as a mouse click,
    *         if the user clicked something to open the panel)
    */
   showPanel(event = null) {
     for (let action of PageActions.actions) {
-      let buttonNodeID = this.panelButtonNodeIDForActionID(action.id);
-      let buttonNode = document.getElementById(buttonNodeID);
+      let buttonNode = this.panelButtonNodeForActionID(action.id);
       action.onShowingInPanel(buttonNode);
     }
 
     this.panelNode.hidden = false;
     this.panelNode.addEventListener("popuphiding", () => {
       this.mainButtonNode.removeAttribute("open");
     }, {once: true});
     this.mainButtonNode.setAttribute("open", "true");
     this.panelNode.openPopup(this.mainButtonNode, {
       position: "bottomcenter topright",
       triggerEvent: event,
     });
   },
 
   /**
-   * Call this on the contextmenu event.  Note that this is called before
-   * onContextMenuShowing.
-   *
-   * @param  event (DOM event, required)
-   *         The contextmenu event.
-   */
-  onContextMenu(event) {
-    let node = event.originalTarget;
-    this._contextAction = this.actionForNode(node);
-    // Don't show the menu if there's no action where the user clicked!
-    if (!this._contextAction) {
-      event.preventDefault();
-    }
-  },
-
-  /**
    * Call this on the context menu's popupshowing event.
    *
    * @param  event (DOM event, required)
    *         The popupshowing event.
    * @param  popup (DOM node, required)
    *         The context menu popup DOM node.
    */
   onContextMenuShowing(event, popup) {
     if (event.target != popup) {
       return;
     }
-    // Right now there's only one item in the context menu, to toggle the
-    // context action's shown-in-urlbar state.  Update it now.
-    let toggleItem = popup.firstChild;
-    let toggleItemLabel = null;
-    if (this._contextAction) {
-      toggleItem.disabled = false;
-      if (this._contextAction.shownInUrlbar) {
-        toggleItemLabel = toggleItem.getAttribute("remove-label");
-      }
+
+    this._contextAction = this.actionForNode(popup.triggerNode);
+    if (!this._contextAction) {
+      event.preventDefault();
+      return;
     }
-    if (!toggleItemLabel) {
-      toggleItemLabel = toggleItem.getAttribute("add-label");
+
+    let state;
+    if (this._contextAction._isBuiltIn) {
+      state =
+        this._contextAction.pinnedToUrlbar ?
+        "builtInPinned" :
+        "builtInUnpinned";
+    } else {
+      state =
+        this._contextAction.pinnedToUrlbar ?
+        "extensionPinned" :
+        "extensionUnpinned";
     }
-    toggleItem.label = toggleItemLabel;
+    popup.setAttribute("state", state);
   },
 
   /**
-   * Call this from the context menu's toggle menu item.
+   * Call this from the menu item in the context menu that toggles pinning.
    */
-  toggleShownInUrlbarForContextAction() {
+  togglePinningForContextAction() {
     if (!this._contextAction) {
       return;
     }
-    let telemetryType = this._contextAction.shownInUrlbar ? "removed" : "added";
-    PageActions.logTelemetry(telemetryType, this._contextAction);
-    this._contextAction.shownInUrlbar = !this._contextAction.shownInUrlbar;
+    let action = this._contextAction;
+    this._contextAction = null;
+
+    let telemetryType = action.pinnedToUrlbar ? "removed" : "added";
+    PageActions.logTelemetry(telemetryType, action);
+
+    action.pinnedToUrlbar = !action.pinnedToUrlbar;
+  },
+
+  /**
+   * Call this from the menu item in the context menu that opens about:addons.
+   */
+  openAboutAddonsForContextAction() {
+    if (!this._contextAction) {
+      return;
+    }
+    let action = this._contextAction;
+    this._contextAction = null;
+
+    PageActions.logTelemetry("managed", action);
+
+    let viewID = "addons://detail/" + encodeURIComponent(action.extensionID);
+    window.BrowserOpenAddonsMgr(viewID);
   },
 
   _contextAction: null,
 
   /**
    * Titles for a few of the built-in actions are defined in DTD, but the
    * actions are created in JS.  So what we do is for each title, set an
    * attribute in markup on the main page action panel whose value is the DTD
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -776,20 +776,16 @@ html|input.urlbar-input[textoverflow]:no
 #identity-icon-country-label {
   direction: ltr;
 }
 
 #identity-box.verifiedIdentity > #identity-icon-labels > #identity-icon-label {
   margin-inline-end: 0.25em !important;
 }
 
-#main-window[customizing] :-moz-any(#urlbar, .searchbar-textbox) > .urlbar-textbox-container > .textbox-input-box {
-  visibility: hidden;
-}
-
 /* Flexible spacer sizing (matching url bar) */
 toolbarpaletteitem[place=toolbar][id^=wrapper-customizableui-special-spring],
 toolbarspring {
   -moz-box-flex: 1;
   min-width: 28px;
   max-width: 112px;
 }
 
@@ -1415,16 +1411,27 @@ toolbarpaletteitem[place="palette"][hidd
   .pageAction-panel-button > .toolbarbutton-icon {
     list-style-image: var(--pageAction-image-32px, inherit);
   }
   .urlbar-page-action {
     list-style-image: var(--pageAction-image-32px, inherit);
   }
 }
 
+/* Page action context menu */
+#pageActionContextMenu > .pageActionContextMenuItem {
+  visibility: collapse;
+}
+#pageActionContextMenu[state=builtInPinned] > .pageActionContextMenuItem.builtInPinned,
+#pageActionContextMenu[state=builtInUnpinned] > .pageActionContextMenuItem.builtInUnpinned,
+#pageActionContextMenu[state=extensionPinned] > .pageActionContextMenuItem.extensionPinned,
+#pageActionContextMenu[state=extensionUnpinned] > .pageActionContextMenuItem.extensionUnpinned {
+  visibility: visible;
+}
+
 /* WebExtension Sidebars */
 #sidebar-box[sidebarcommand$="-sidebar-action"] > #sidebar-header > #sidebar-switcher-target > #sidebar-icon {
   list-style-image: var(--webextension-menuitem-image, inherit);
   -moz-context-properties: fill;
   fill: currentColor;
   width: 16px;
   height: 16px;
 }
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -417,17 +417,16 @@
            emailLink-title="&emailPageCmd.label;"
            sendToDevice-title="&pageAction.sendTabToDevice.label;"
            sendToDevice-notReadyTitle="&sendToDevice.syncNotReady.label;">
       <photonpanelmultiview id="pageActionPanelMultiView"
                             mainViewId="pageActionPanelMainView"
                             viewCacheId="appMenu-viewCache">
         <panelview id="pageActionPanelMainView"
                    context="pageActionContextMenu"
-                   oncontextmenu="BrowserPageActions.onContextMenu(event);"
                    class="PanelUI-subView">
           <vbox class="panel-subview-body"/>
         </panelview>
       </photonpanelmultiview>
     </panel>
     <panel id="pageActionFeedback"
            role="alert"
            type="arrow"
@@ -441,21 +440,32 @@
       <hbox id="pageActionFeedbackAnimatableBox">
         <image id="pageActionFeedbackAnimatableImage"/>
       </hbox>
       <label id="pageActionFeedbackMessage"/>
     </panel>
 
     <menupopup id="pageActionContextMenu"
                onpopupshowing="BrowserPageActions.onContextMenuShowing(event, this);">
-      <menuitem id="pageActionContextMenu-toggleUrlbar"
-                add-label="&pageAction.addToUrlbar.label;"
-                remove-label="&pageAction.removeFromUrlbar.label;"
+      <menuitem class="pageActionContextMenuItem builtInUnpinned"
                 label="&pageAction.addToUrlbar.label;"
-                oncommand="BrowserPageActions.toggleShownInUrlbarForContextAction();"/>
+                oncommand="BrowserPageActions.togglePinningForContextAction();"/>
+      <menuitem class="pageActionContextMenuItem builtInPinned"
+                label="&pageAction.removeFromUrlbar.label;"
+                oncommand="BrowserPageActions.togglePinningForContextAction();"/>
+      <menuitem class="pageActionContextMenuItem extensionUnpinned"
+                label="&pageAction.allowInUrlbar.label;"
+                oncommand="BrowserPageActions.togglePinningForContextAction();"/>
+      <menuitem class="pageActionContextMenuItem extensionPinned"
+                label="&pageAction.disallowInUrlbar.label;"
+                oncommand="BrowserPageActions.togglePinningForContextAction();"/>
+      <menuseparator class="pageActionContextMenuItem extensionPinned extensionUnpinned"/>
+      <menuitem class="pageActionContextMenuItem extensionPinned extensionUnpinned"
+                label="&pageAction.manageExtension.label;"
+                oncommand="BrowserPageActions.openAboutAddonsForContextAction();"/>
     </menupopup>
 
     <!-- Bookmarks and history tooltip -->
     <tooltip id="bhTooltip"/>
 
     <tooltip id="tabbrowser-tab-tooltip" onpopupshowing="gBrowser.createTooltip(event);"/>
 
     <tooltip id="back-button-tooltip">
@@ -854,19 +864,17 @@
                   <label id="identity-icon-label" class="plain" flex="1"/>
                   <label id="identity-icon-country-label" class="plain"/>
                 </hbox>
               </box>
               <box id="urlbar-display-box" align="center">
                 <label id="switchtab" class="urlbar-display urlbar-display-switchtab" value="&urlbar.switchToTab.label;"/>
                 <label id="extension" class="urlbar-display urlbar-display-extension" value="&urlbar.extension.label;"/>
               </box>
-              <hbox id="page-action-buttons"
-                    context="pageActionContextMenu"
-                    oncontextmenu="BrowserPageActions.onContextMenu(event);">
+              <hbox id="page-action-buttons" context="pageActionContextMenu">
                 <hbox id="userContext-icons" hidden="true">
                   <label id="userContext-label"/>
                   <image id="userContext-indicator"/>
                 </hbox>
                 <image id="reader-mode-button"
                        class="urlbar-icon urlbar-page-action"
                        role="button"
                        hidden="true"
--- a/browser/base/content/newtab/grid.js
+++ b/browser/base/content/newtab/grid.js
@@ -30,17 +30,17 @@ var gGrid = {
    * All cells contained in the grid.
    */
   _cells: [],
   get cells() { return this._cells; },
 
   /**
    * All sites contained in the grid's cells. Sites may be empty.
    */
-  get sites() { return [for (cell of this.cells) cell.site]; },
+  get sites() { return this.cells.map(cell => cell.site); },
 
   // Tells whether the grid has already been initialized.
   get ready() { return !!this._ready; },
 
   // Returns whether the page has finished loading yet.
   get isDocumentLoaded() { return document.readyState == "complete"; },
 
   /**
--- a/browser/base/content/pageinfo/pageInfo.xul
+++ b/browser/base/content/pageinfo/pageInfo.xul
@@ -284,16 +284,17 @@
                  value="&permPlugins;" control="pluginsRadioGroup"/>
           <hbox id="permPluginTemplate" role="group" aria-labelledby="permPluginsLabel" align="baseline">
             <label class="permPluginTemplateLabel"/>
             <spacer flex="1"/>
             <radiogroup class="permPluginTemplateRadioGroup" orient="horizontal" command="cmd_pluginsToggle">
               <radio class="permPluginTemplateRadioDefault" label="&permUseDefault;"/>
               <radio class="permPluginTemplateRadioAsk" label="&permAskAlways;"/>
               <radio class="permPluginTemplateRadioAllow" label="&permAllow;"/>
+              <radio class="permPluginTemplateRadioHide" label="&permHide;"/>
               <radio class="permPluginTemplateRadioBlock" label="&permBlock;"/>
             </radiogroup>
           </hbox>
         </vbox>
       </vbox>
       <hbox pack="end">
         <button command="cmd_help" label="&helpButton.label;" dlgtype="help"/>
       </hbox>
--- a/browser/base/content/pageinfo/permissions.js
+++ b/browser/base/content/pageinfo/permissions.js
@@ -178,16 +178,18 @@ function fillInPluginPermissionTemplate(
   let permPluginTemplate = document.getElementById("permPluginTemplate").cloneNode(true);
   permPluginTemplate.setAttribute("permString", aPermissionString);
   let attrs = [
     [ ".permPluginTemplateLabel", "value", aPluginName ],
     [ ".permPluginTemplateRadioGroup", "id", aPermissionString + "RadioGroup" ],
     [ ".permPluginTemplateRadioDefault", "id", aPermissionString + "#0" ],
     [ ".permPluginTemplateRadioAsk", "id", aPermissionString + "#3" ],
     [ ".permPluginTemplateRadioAllow", "id", aPermissionString + "#1" ],
+    // #8 comes from Ci.nsIObjectLoadingContent.PLUGIN_PERMISSION_PROMPT_ACTION_QUIET
+    [ ".permPluginTemplateRadioHide", "id", aPermissionString + "#8"],
     [ ".permPluginTemplateRadioBlock", "id", aPermissionString + "#2" ]
   ];
 
   for (let attr of attrs) {
     permPluginTemplate.querySelector(attr[0]).setAttribute(attr[1], attr[2]);
   }
 
   return permPluginTemplate;
--- a/browser/base/content/test/permissions/browser.ini
+++ b/browser/base/content/test/permissions/browser.ini
@@ -1,14 +1,15 @@
 [DEFAULT]
 support-files=
   head.js
   permissions.html
 
 [browser_canvas_fingerprinting_resistance.js]
 [browser_permissions.js]
+[browser_reservedkey.js]
 [browser_temporary_permissions.js]
 support-files =
   temporary_permissions_subframe.html
   ../webrtc/get_user_media.html
 [browser_temporary_permissions_expiry.js]
 [browser_temporary_permissions_navigation.js]
 [browser_temporary_permissions_tabs.js]
--- a/browser/base/content/test/permissions/browser_permissions.js
+++ b/browser/base/content/test/permissions/browser_permissions.js
@@ -171,8 +171,48 @@ add_task(async function testPermissionIc
     SitePermissions.remove(gBrowser.currentURI, "geo");
 
     ok(!geoIcon.hasAttribute("showing"),
       "blocked permission icon is not shown after reset");
 
     SitePermissions.remove(gBrowser.currentURI, "camera");
   });
 });
+
+add_task(async function testPermissionShortcuts() {
+  await BrowserTestUtils.withNewTab(PERMISSIONS_PAGE, async function(browser) {
+    browser.focus();
+
+    await new Promise(r => {
+      SpecialPowers.pushPrefEnv({"set": [["permissions.default.shortcuts", 0]]}, r);
+    });
+
+    async function tryKey(desc, expectedValue) {
+      await EventUtils.synthesizeAndWaitKey("c", { accelKey: true });
+      let result = await ContentTask.spawn(browser, null, function() {
+        return content.wrappedJSObject.gKeyPresses;
+      });
+      is(result, expectedValue, desc);
+    }
+
+    await tryKey("pressed with default permissions", 1);
+
+    SitePermissions.set(gBrowser.currentURI, "shortcuts", SitePermissions.BLOCK);
+    await tryKey("pressed when site blocked", 1);
+
+    SitePermissions.set(gBrowser.currentURI, "shortcuts", SitePermissions.ALLOW);
+    await tryKey("pressed when site allowed", 2);
+
+    SitePermissions.remove(gBrowser.currentURI, "shortcuts");
+    await new Promise(r => {
+      SpecialPowers.pushPrefEnv({"set": [["permissions.default.shortcuts", 2]]}, r);
+    });
+
+    await tryKey("pressed when globally blocked", 2);
+    SitePermissions.set(gBrowser.currentURI, "shortcuts", SitePermissions.ALLOW);
+    await tryKey("pressed when globally blocked but site allowed", 3);
+
+    SitePermissions.set(gBrowser.currentURI, "shortcuts", SitePermissions.BLOCK);
+    await tryKey("pressed when globally blocked and site blocked", 3);
+
+    SitePermissions.remove(gBrowser.currentURI, "shortcuts");
+  });
+});
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/permissions/browser_reservedkey.js
@@ -0,0 +1,92 @@
+add_task(async function test_reserved_shortcuts() {
+  /* eslint-disable no-unsanitized/property */
+  let keyset = `<keyset>
+                  <key id='kt_reserved' modifiers='shift' key='O' reserved='true' count='0'
+                       oncommand='this.setAttribute("count", Number(this.getAttribute("count")) + 1)'/>
+                  <key id='kt_notreserved' modifiers='shift' key='P' reserved='false' count='0'
+                       oncommand='this.setAttribute("count", Number(this.getAttribute("count")) + 1)'/>
+                  <key id='kt_reserveddefault' modifiers='shift' key='Q' count='0'
+                       oncommand='this.setAttribute("count", Number(this.getAttribute("count")) + 1)'/>
+                </keyset>`;
+
+  let container = document.createElement("box");
+  container.innerHTML = keyset;
+  document.documentElement.appendChild(container);
+  /* eslint-enable no-unsanitized/property */
+
+  const pageUrl = "data:text/html,<body onload='document.body.firstChild.focus();'><div onkeydown='event.preventDefault();' tabindex=0>Test</div></body>";
+  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl);
+
+  EventUtils.synthesizeKey("O", { shiftKey: true });
+  EventUtils.synthesizeKey("P", { shiftKey: true });
+  EventUtils.synthesizeKey("Q", { shiftKey: true });
+
+  is(document.getElementById("kt_reserved").getAttribute("count"), "1", "reserved='true' with preference off");
+  is(document.getElementById("kt_notreserved").getAttribute("count"), "0", "reserved='false' with preference off");
+  is(document.getElementById("kt_reserveddefault").getAttribute("count"), "0", "default reserved with preference off");
+
+  // Now try with reserved shortcut key handling enabled.
+  await new Promise(resolve => {
+    SpecialPowers.pushPrefEnv({"set": [["permissions.default.shortcuts", 2]]}, resolve);
+  });
+
+  EventUtils.synthesizeKey("O", { shiftKey: true });
+  EventUtils.synthesizeKey("P", { shiftKey: true });
+  EventUtils.synthesizeKey("Q", { shiftKey: true });
+
+  is(document.getElementById("kt_reserved").getAttribute("count"), "2", "reserved='true' with preference on");
+  is(document.getElementById("kt_notreserved").getAttribute("count"), "0", "reserved='false' with preference on");
+  is(document.getElementById("kt_reserveddefault").getAttribute("count"), "1", "default reserved with preference on");
+
+  document.documentElement.removeChild(container);
+
+  await BrowserTestUtils.removeTab(tab);
+});
+
+// This test checks that Alt+<key> and F10 cannot be blocked when the preference is set.
+if (navigator.platform.indexOf("Mac") == -1) {
+  add_task(async function test_accesskeys_menus() {
+    await new Promise(resolve => {
+      SpecialPowers.pushPrefEnv({"set": [["permissions.default.shortcuts", 2]]}, resolve);
+    });
+
+    const uri = "data:text/html,<body onkeydown='if (event.key == \"H\" || event.key == \"F10\") event.preventDefault();'>";
+    let tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, uri);
+
+    // Pressing Alt+H should open the Help menu.
+    let helpPopup = document.getElementById("menu_HelpPopup");
+    let popupShown = BrowserTestUtils.waitForEvent(helpPopup, "popupshown");
+    EventUtils.synthesizeKey("VK_ALT", { type: "keydown" });
+    EventUtils.synthesizeKey("H", { altKey: true });
+    EventUtils.synthesizeKey("VK_ALT", { type: "keyup" });
+    await popupShown;
+
+    ok(true, "Help menu opened");
+
+    let popupHidden = BrowserTestUtils.waitForEvent(helpPopup, "popuphidden");
+    helpPopup.hidePopup();
+    await popupHidden;
+
+    // Pressing F10 should focus the menubar. On Linux, the file menu should open, but on Windows,
+    // pressing Down will open the file menu.
+    let menubar = document.getElementById("main-menubar");
+    let menubarActive = BrowserTestUtils.waitForEvent(menubar, "DOMMenuBarActive");
+    EventUtils.sendKey("F10");
+    await menubarActive;
+
+    let filePopup = document.getElementById("menu_FilePopup");
+    popupShown = BrowserTestUtils.waitForEvent(filePopup, "popupshown");
+    if (navigator.platform.indexOf("Win") >= 0) {
+      EventUtils.synthesizeKey("KEY_ArrowDown", { code: "ArrowDown" });
+    }
+    await popupShown;
+
+    ok(true, "File menu opened");
+
+    popupHidden = BrowserTestUtils.waitForEvent(filePopup, "popuphidden");
+    filePopup.hidePopup();
+    await popupHidden;
+
+    await BrowserTestUtils.removeTab(tab1);
+  });
+}
--- a/browser/base/content/test/permissions/permissions.html
+++ b/browser/base/content/test/permissions/permissions.html
@@ -1,15 +1,18 @@
 <!DOCTYPE HTML>
 <!-- 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/. -->
 <html dir="ltr" xml:lang="en-US" lang="en-US">
   <head>
     <meta charset="utf8">
   </head>
-  <body>
+<script>
+var gKeyPresses = 0;
+</script>
+  <body onkeypress="gKeyPresses++;">
 	<!-- This page could eventually request permissions from content
 	     and make sure that chrome responds appropriately -->
   <button id="geo" onclick="navigator.geolocation.getCurrentPosition(() => {})">Geolocation</button>
   <button id="camera" onclick="navigator.mediaDevices.getUserMedia({video: true, fake: true})">Camera</button>
   </body>
 </html>
--- a/browser/base/content/test/plugins/browser.ini
+++ b/browser/base/content/test/plugins/browser.ini
@@ -21,16 +21,17 @@ support-files =
   plugin_bug797677.html
   plugin_bug820497.html
   plugin_clickToPlayAllow.html
   plugin_clickToPlayDeny.html
   plugin_favorfallback.html
   plugin_hidden_to_visible.html
   plugin_iframe.html
   plugin_outsideScrollArea.html
+  plugin_overlay_styles.html
   plugin_overlayed.html
   plugin_positioned.html
   plugin_simple_blank.swf
   plugin_shouldShowOverlay.html
   plugin_small.html
   plugin_small_2.html
   plugin_syncRemoved.html
   plugin_test.html
@@ -66,16 +67,17 @@ tags = blocklist
 [browser_CTP_iframe.js]
 tags = blocklist
 [browser_CTP_nonplugins.js]
 tags = blocklist
 [browser_CTP_notificationBar.js]
 tags = blocklist
 [browser_CTP_outsideScrollArea.js]
 tags = blocklist
+[browser_CTP_overlay_styles.js]
 [browser_CTP_remove_navigate.js]
 tags = blocklist
 [browser_CTP_resize.js]
 tags = blocklist
 [browser_CTP_shouldShowOverlay.js]
 [browser_CTP_zoom.js]
 tags = blocklist
 [browser_blocking.js]
--- a/browser/base/content/test/plugins/browser_CTP_notificationBar.js
+++ b/browser/base/content/test/plugins/browser_CTP_notificationBar.js
@@ -77,18 +77,18 @@ add_task(async function() {
 
   let pluginInfo = await promiseForPluginInfo("test");
   ok(!pluginInfo.activated, "Test 1a, plugin should not be activated");
 
   await ContentTask.spawn(gTestBrowser, null, async function() {
     let doc = content.document;
     let plugin = doc.getElementById("test");
     let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
-    Assert.ok(!overlay || !overlay.classList.contains("visible"),
-      "Test 3b, overlay should be hidden.");
+    Assert.ok(!overlay || overlay.getAttribute("sizing") == "blank",
+      "Test 3b, overlay should be blank.");
   });
 });
 
 add_task(async function() {
   await promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_positioned.html");
 
   // Work around for delayed PluginBindingAttached
   await promiseUpdatePluginBindings(gTestBrowser);
@@ -104,18 +104,18 @@ add_task(async function() {
     Assert.equal(plugin.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY,
       "Test 4b, plugin fallback type should be PLUGIN_CLICK_TO_PLAY");
   });
 
   await ContentTask.spawn(gTestBrowser, null, async function() {
     let doc = content.document;
     let plugin = doc.getElementById("test");
     let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
-    Assert.ok(!overlay || !overlay.classList.contains("visible"),
-      "Test 4b, overlay should be hidden.");
+    Assert.ok(!overlay || overlay.getAttribute("sizing") == "blank",
+      "Test 4b, overlay should be blank.");
   });
 });
 
 // Test that the notification bar is getting dismissed when directly activating plugins
 // via the doorhanger.
 
 add_task(async function() {
   await promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_small.html");
--- a/browser/base/content/test/plugins/browser_CTP_outsideScrollArea.js
+++ b/browser/base/content/test/plugins/browser_CTP_outsideScrollArea.js
@@ -53,17 +53,17 @@ add_task(async function() {
 
   await promisePopupNotification("click-to-play-plugins");
 
   await ContentTask.spawn(gTestBrowser, {}, async function() {
     let plugin = content.document.getElementById("test");
     let doc = content.document;
     let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
     Assert.ok(overlay && overlay.classList.contains("visible") &&
-              !overlay.classList.contains("minimal"),
+              overlay.getAttribute("sizing") != "blank",
               "Test 2, overlay should be visible.");
   });
 });
 
 add_task(async function() {
   await promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_outsideScrollArea.html");
 
   await ContentTask.spawn(gTestBrowser, {}, async function() {
@@ -83,17 +83,17 @@ add_task(async function() {
 
   await promisePopupNotification("click-to-play-plugins");
 
   await ContentTask.spawn(gTestBrowser, null, async function() {
     let plugin = content.document.getElementById("test");
     let doc = content.document;
     let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
     Assert.ok(overlay && overlay.classList.contains("visible") &&
-              !overlay.classList.contains("minimal"),
+              overlay.getAttribute("sizing") != "blank",
               "Test 3, overlay should be visible.");
   });
 });
 
 add_task(async function() {
   await promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_outsideScrollArea.html");
 
   await ContentTask.spawn(gTestBrowser, {}, async function() {
@@ -111,12 +111,12 @@ add_task(async function() {
   // Work around for delayed PluginBindingAttached
   await promiseUpdatePluginBindings(gTestBrowser);
 
   await promisePopupNotification("click-to-play-plugins");
   await ContentTask.spawn(gTestBrowser, null, async function() {
     let plugin = content.document.getElementById("test");
     let doc = content.document;
     let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
-    Assert.ok(!overlay || !overlay.classList.contains("visible"),
-      "Test 4, overlay should be hidden.");
+    Assert.ok(!overlay || overlay.getAttribute("sizing") == "blank",
+      "Test 4, overlay should be blank.");
   });
 });
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/plugins/browser_CTP_overlay_styles.js
@@ -0,0 +1,93 @@
+/* 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";
+
+/* This test ensures that the click-to-play "Activate Plugin" overlay
+ * is shown in the right style (which is dependent on its size).
+ */
+
+const rootDir = getRootDirectory(gTestPath);
+const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
+
+var gTestBrowser = null;
+
+const gTestcases = {
+
+  // 10x10
+  testcase1: {
+    sizing: "blank",
+    notext: null,
+  },
+
+  // 40x40
+  testcase2: {
+    sizing: "tiny",
+    notext: "notext",
+  },
+
+  // 100x70
+  testcase3: {
+    sizing: "reduced",
+    notext: "notext",
+  },
+
+  // 200x200
+  testcase4: {
+    sizing: null,
+    notext: "notext",
+  },
+
+  // 300x300
+  testcase5: {
+    sizing: null,
+    notext: null,
+  },
+}
+
+
+add_task(async function() {
+  registerCleanupFunction(function() {
+    clearAllPluginPermissions();
+    setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
+    gBrowser.removeCurrentTab();
+    gTestBrowser = null;
+  });
+});
+
+add_task(async function() {
+  gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
+  gTestBrowser = gBrowser.selectedBrowser;
+
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
+
+  let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
+  ok(!popupNotification, "Sanity check, should not have a click-to-play notification");
+
+  await promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_overlay_styles.html");
+
+  // Work around for delayed PluginBindingAttached
+  await promiseUpdatePluginBindings(gTestBrowser);
+
+  await ContentTask.spawn(gTestBrowser, gTestcases, async function(testcases) {
+    let doc = content.document;
+
+    for (let testcaseId of Object.keys(testcases)) {
+      let plugin = doc.querySelector(`#${testcaseId} > object`);
+      let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
+      Assert.ok(overlay, `overlay exists in ${testcaseId}`);
+
+      let expectations = testcases[testcaseId];
+
+      Assert.ok(overlay.classList.contains("visible") == true,
+                `The expected visibility is correct in ${testcaseId}`);
+
+      Assert.ok(overlay.getAttribute("sizing") == expectations.sizing,
+                `The expected sizing is correct in ${testcaseId}`);
+
+      Assert.ok(overlay.getAttribute("notext") == expectations.notext,
+                `The expected notext is correct in ${testcaseId}`);
+    }
+  });
+});
--- a/browser/base/content/test/plugins/browser_CTP_resize.js
+++ b/browser/base/content/test/plugins/browser_CTP_resize.js
@@ -41,36 +41,36 @@ add_task(async function() {
 add_task(async function() {
   let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
   ok(popupNotification, "Test 2, Should have a click-to-play notification");
 
   await ContentTask.spawn(gTestBrowser, null, async function() {
     let doc = content.document;
     let plugin = doc.getElementById("test");
     let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
-    Assert.ok(!overlay || overlay.classList.contains("minimal"),
-      "Test 2, overlay should be hidden.");
+    Assert.ok(!overlay || overlay.getAttribute("sizing") == "blank",
+      "Test 2, overlay should be blank.");
   });
 });
 
 add_task(async function() {
   await ContentTask.spawn(gTestBrowser, {}, async function() {
     let plugin = content.document.getElementById("test");
     plugin.style.width = "300px";
   });
 
   // Work around for delayed PluginBindingAttached
   await promiseUpdatePluginBindings(gTestBrowser);
 
   await ContentTask.spawn(gTestBrowser, null, async function() {
     let doc = content.document;
     let plugin = doc.getElementById("test");
     let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
-    Assert.ok(!overlay || overlay.classList.contains("minimal"),
-      "Test 3, overlay should be hidden.");
+    Assert.ok(!overlay || overlay.getAttribute("sizing") == "blank",
+      "Test 3, overlay should be blank.");
   });
 });
 
 
 add_task(async function() {
   await ContentTask.spawn(gTestBrowser, {}, async function() {
     let plugin = content.document.getElementById("test");
     plugin.style.height = "300px";
@@ -79,17 +79,17 @@ add_task(async function() {
   await ContentTask.spawn(gTestBrowser, {}, async function() {
     content.document.getElementById("test").clientTop;
   });
 
   await ContentTask.spawn(gTestBrowser, null, async function() {
     let doc = content.document;
     let plugin = doc.getElementById("test");
     let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
-    Assert.ok(overlay && overlay.classList.contains("visible"),
+    Assert.ok(overlay && overlay.getAttribute("sizing") != "blank",
       "Test 4, overlay should be visible.");
   });
 });
 
 add_task(async function() {
   await ContentTask.spawn(gTestBrowser, {}, async function() {
     let plugin = content.document.getElementById("test");
     plugin.style.width = "10px";
@@ -99,18 +99,18 @@ add_task(async function() {
   await ContentTask.spawn(gTestBrowser, {}, async function() {
     content.document.getElementById("test").clientTop;
   });
 
   await ContentTask.spawn(gTestBrowser, null, async function() {
     let doc = content.document;
     let plugin = doc.getElementById("test");
     let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
-    Assert.ok(!overlay || overlay.classList.contains("minimal"),
-      "Test 5, overlay should be hidden.");
+    Assert.ok(!overlay || overlay.getAttribute("sizing") == "blank",
+      "Test 5, overlay should be blank.");
   });
 });
 
 add_task(async function() {
   await ContentTask.spawn(gTestBrowser, {}, async function() {
     let plugin = content.document.getElementById("test");
     plugin.style.height = "300px";
     plugin.style.width = "300px";
@@ -119,12 +119,12 @@ add_task(async function() {
   await ContentTask.spawn(gTestBrowser, {}, async function() {
     content.document.getElementById("test").clientTop;
   });
 
   await ContentTask.spawn(gTestBrowser, null, async function() {
     let doc = content.document;
     let plugin = doc.getElementById("test");
     let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
-    Assert.ok(overlay && overlay.classList.contains("visible"),
+    Assert.ok(overlay && overlay.getAttribute("sizing") != "blank",
       "Test 6, overlay should be visible.");
   });
 });
--- a/browser/base/content/test/plugins/browser_CTP_shouldShowOverlay.js
+++ b/browser/base/content/test/plugins/browser_CTP_shouldShowOverlay.js
@@ -2,16 +2,22 @@
  * 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";
 
 /* This test ensures that the click-to-play "Activate Plugin" overlay
  * is shown when expected.
  * All testcases are in the plugin_shouldShowOverlay.html file.
+ *
+ * Note: Technically, the overlay is *always* shown. When this test was
+ * originally written, the meaning of "shown" was "shown with the contents",
+ * as opposed to "shown as blank". The behavior hasn't changed, but the naming
+ * has: now, a "shown as blank" overlay no longer receives a ".hidden" class.
+ * It receives a sizing="blank" attribute.
  */
 
 var rootDir = getRootDirectory(gTestPath);
 const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
 
 var gTestBrowser = null;
 
 add_task(async function() {
@@ -44,13 +50,13 @@ add_task(async function() {
     for (let testcase of testcases) {
       let plugin = testcase.querySelector("object");
       Assert.ok(plugin, `plugin exists in ${testcase.id}`);
 
       let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
       Assert.ok(overlay, `overlay exists in ${testcase.id}`);
 
       let expectedVisibility = (testcase.getAttribute("shouldshow") == "true");
-      Assert.ok(overlay.classList.contains("visible") == expectedVisibility,
+      Assert.ok((overlay.getAttribute("sizing") != "blank") == expectedVisibility,
                 `The expected visibility is correct in ${testcase.id}`);
     }
   })
 });
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/plugins/plugin_overlay_styles.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+</head>
+<body>
+
+  <div id="testcase1" class="testcase">
+    <object width="10" height="10" type="application/x-test"></object>
+  </div>
+
+  <div id="testcase2" class="testcase">
+    <object width="40" height="40" type="application/x-test"></object>
+  </div>
+
+  <div id="testcase3" class="testcase">
+    <object width="100" height="70" type="application/x-test"></object>
+  </div>
+
+  <div id="testcase4" class="testcase">
+    <object width="200" height="200" type="application/x-test"></object>
+  </div>
+
+  <div id="testcase5" class="testcase">
+    <object width="300" height="300" type="application/x-test"></object>
+  </div>
+
+</body>
+</html>
--- a/browser/base/content/test/plugins/plugin_test.html
+++ b/browser/base/content/test/plugins/plugin_test.html
@@ -1,9 +1,9 @@
 <!DOCTYPE html>
 <html>
 <head>
 <meta charset="utf-8">
 </head>
 <body>
-<embed id="test" style="width: 200px; height: 200px" type="application/x-test">
+<embed id="test" style="width: 300px; height: 300px" type="application/x-test">
 </body>
 </html>
--- a/browser/base/content/test/static/browser_all_files_referenced.js
+++ b/browser/base/content/test/static/browser_all_files_referenced.js
@@ -117,19 +117,16 @@ var whitelist = [
 
   // browser/extensions/pdfjs/content/web/viewer.js#7450
   {file: "resource://pdf.js/web/debugger.js"},
 
   // These are used in content processes. They are actually referenced.
   {file: "resource://shield-recipe-client-content/shield-content-frame.js"},
   {file: "resource://shield-recipe-client-content/shield-content-process.js"},
 
-  // New L10n API that is not yet used in production
-  {file: "chrome://global/content/l10n.js"},
-
   // Starting from here, files in the whitelist are bugs that need fixing.
   // Bug 1339424 (wontfix?)
   {file: "chrome://browser/locale/taskbar.properties",
    platforms: ["linux", "macosx"]},
   // Bug 1316187
   {file: "chrome://global/content/customizeToolbar.xul"},
   // Bug 1343837
   {file: "chrome://global/content/findUtils.js"},
--- a/browser/base/content/test/urlbar/browser_page_action_menu.js
+++ b/browser/base/content/test/urlbar/browser_page_action_menu.js
@@ -152,18 +152,18 @@ add_task(async function copyURLFromPanel
 
 add_task(async function copyURLFromURLBar() {
   // Open an actionable page so that the main page action button appears.  (It
   // does not appear on about:blank for example.)
   let url = "http://example.com/";
   await BrowserTestUtils.withNewTab(url, async () => {
     // Add action to URL bar.
     let action = PageActions._builtInActions.find(a => a.id == "copyURL");
-    action.shownInUrlbar = true;
-    registerCleanupFunction(() => action.shownInUrlbar = false);
+    action.pinnedToUrlbar = true;
+    registerCleanupFunction(() => action.pinnedToUrlbar = false);
 
     let copyURLButton =
       document.getElementById("pageAction-urlbar-copyURL");
     let feedbackShownPromise = promisePanelShown("pageActionFeedback");
     EventUtils.synthesizeMouseAtCenter(copyURLButton, {});
 
     await feedbackShownPromise;
     let panel = document.getElementById("pageActionFeedback");
@@ -539,17 +539,17 @@ add_task(async function sendToDevice_inU
 
     let cleanUp = () => {
       sandbox.restore();
     };
     registerCleanupFunction(cleanUp);
 
     // Add Send to Device to the urlbar.
     let action = PageActions.actionForID("sendToDevice");
-    action.shownInUrlbar = true;
+    action.pinnedToUrlbar = true;
 
     // Click it to open its panel.
     let urlbarButton = document.getElementById(
       BrowserPageActions.urlbarButtonNodeIDForActionID(action.id)
     );
     Assert.ok(!urlbarButton.disabled);
     let panelPromise =
       promisePanelShown(BrowserPageActions._activatedActionPanelID);
@@ -617,17 +617,17 @@ add_task(async function sendToDevice_inU
     Assert.equal(
       BrowserPageActionFeedback.panelNode.anchorNode.id,
       urlbarButton.id
     );
     info("Waiting for the Sent! notification panel to close");
     await promisePanelHidden(BrowserPageActionFeedback.panelNode.id);
 
     // Remove Send to Device from the urlbar.
-    action.shownInUrlbar = false;
+    action.pinnedToUrlbar = false;
 
     cleanUp();
   });
 });
 
 add_task(async function contextMenu() {
   // Open an actionable page so that the main page action button appears.
   let url = "http://example.com/";
@@ -637,24 +637,24 @@ add_task(async function contextMenu() {
     let bookmarkButton = document.getElementById("pageAction-panel-bookmark");
     let contextMenuPromise = promisePanelShown("pageActionContextMenu");
     EventUtils.synthesizeMouseAtCenter(bookmarkButton, {
       type: "contextmenu",
       button: 2,
     });
     await contextMenuPromise;
 
-    // The context menu should show "Remove from Address Bar".  Click it.
-    let contextMenuNode = document.getElementById("pageActionContextMenu");
-    Assert.equal(contextMenuNode.childNodes.length, 1,
+    // The context menu should show the "remove" item.  Click it.
+    let menuItems = collectContextMenuItems();
+    Assert.equal(menuItems.length, 1,
                  "Context menu has one child");
-    Assert.equal(contextMenuNode.childNodes[0].label, "Remove from Address Bar",
+    Assert.equal(menuItems[0].label, "Remove from Address Bar",
                  "Context menu is in the 'remove' state");
     contextMenuPromise = promisePanelHidden("pageActionContextMenu");
-    EventUtils.synthesizeMouseAtCenter(contextMenuNode.childNodes[0], {});
+    EventUtils.synthesizeMouseAtCenter(menuItems[0], {});
     await contextMenuPromise;
 
     // The action should be removed from the urlbar.  In this case, the bookmark
     // star, the node in the urlbar should be hidden.
     let starButtonBox = document.getElementById("star-button-box");
     await BrowserTestUtils.waitForCondition(() => {
       return starButtonBox.hidden;
     }, "Waiting for star button to become hidden");
@@ -663,67 +663,71 @@ add_task(async function contextMenu() {
     // panel remains open.)
     contextMenuPromise = promisePanelShown("pageActionContextMenu");
     EventUtils.synthesizeMouseAtCenter(bookmarkButton, {
       type: "contextmenu",
       button: 2,
     });
     await contextMenuPromise;
 
-    // The context menu should show "Add to Address Bar".  Click it.
-    Assert.equal(contextMenuNode.childNodes.length, 1,
+    // The context menu should show the "add" item.  Click it.
+    menuItems = collectContextMenuItems();
+    Assert.equal(menuItems.length, 1,
                  "Context menu has one child");
-    Assert.equal(contextMenuNode.childNodes[0].label, "Add to Address Bar",
+    Assert.equal(menuItems[0].label, "Add to Address Bar",
                  "Context menu is in the 'add' state");
     contextMenuPromise = promisePanelHidden("pageActionContextMenu");
-    EventUtils.synthesizeMouseAtCenter(contextMenuNode.childNodes[0], {});
+    EventUtils.synthesizeMouseAtCenter(menuItems[0], {});
     await contextMenuPromise;
 
     // The action should be added to the urlbar.
     await BrowserTestUtils.waitForCondition(() => {
       return !starButtonBox.hidden;
     }, "Waiting for star button to become unhidden");
 
     // Open the context menu on the bookmark star in the urlbar.
     contextMenuPromise = promisePanelShown("pageActionContextMenu");
     EventUtils.synthesizeMouseAtCenter(starButtonBox, {
       type: "contextmenu",
       button: 2,
     });
     await contextMenuPromise;
 
-    // The context menu should show "Remove from Address Bar".  Click it.
-    Assert.equal(contextMenuNode.childNodes.length, 1,
+    // The context menu should show the "remove" item.  Click it.
+    menuItems = collectContextMenuItems();
+    Assert.equal(menuItems.length, 1,
                  "Context menu has one child");
-    Assert.equal(contextMenuNode.childNodes[0].label, "Remove from Address Bar",
+    Assert.equal(menuItems[0].label, "Remove from Address Bar",
                  "Context menu is in the 'remove' state");
     contextMenuPromise = promisePanelHidden("pageActionContextMenu");
-    EventUtils.synthesizeMouseAtCenter(contextMenuNode.childNodes[0], {});
+    EventUtils.synthesizeMouseAtCenter(menuItems[0], {});
     await contextMenuPromise;
 
     // The action should be removed from the urlbar.
     await BrowserTestUtils.waitForCondition(() => {
       return starButtonBox.hidden;
     }, "Waiting for star button to become hidden");
 
     // Finally, add the bookmark star back to the urlbar so that other tests
     // that rely on it are OK.
     await promisePageActionPanelOpen();
     contextMenuPromise = promisePanelShown("pageActionContextMenu");
     EventUtils.synthesizeMouseAtCenter(bookmarkButton, {
       type: "contextmenu",
       button: 2,
     });
     await contextMenuPromise;
-    Assert.equal(contextMenuNode.childNodes.length, 1,
+
+    menuItems = collectContextMenuItems();
+    Assert.equal(menuItems.length, 1,
                  "Context menu has one child");
-    Assert.equal(contextMenuNode.childNodes[0].label, "Add to Address Bar",
+    Assert.equal(menuItems[0].label, "Add to Address Bar",
                  "Context menu is in the 'add' state");
     contextMenuPromise = promisePanelHidden("pageActionContextMenu");
-    EventUtils.synthesizeMouseAtCenter(contextMenuNode.childNodes[0], {});
+    EventUtils.synthesizeMouseAtCenter(menuItems[0], {});
     await contextMenuPromise;
     await BrowserTestUtils.waitForCondition(() => {
       return !starButtonBox.hidden;
     }, "Waiting for star button to become unhidden");
   });
 
   // urlbar tests that run after this one can break if the mouse is left over
   // the area where the urlbar popup appears, which seems to happen due to the
@@ -770,8 +774,15 @@ function checkSendToDeviceItems(expected
         if (name == "label") {
           attrVal = attrVal.normalize("NFKC"); // There's a bug with …
         }
         Assert.equal(attrVal, expected.attrs[name]);
       }
     }
   }
 }
+
+function collectContextMenuItems() {
+  let contextMenu = document.getElementById("pageActionContextMenu");
+  return Array.filter(contextMenu.childNodes, node => {
+    return window.getComputedStyle(node).visibility == "visible";
+  });
+}
--- a/browser/components/extensions/ext-pageAction.js
+++ b/browser/components/extensions/ext-pageAction.js
@@ -61,19 +61,20 @@ this.pageAction = class extends Extensio
 
     this.defaults.icon = await StartupCache.get(
       extension, ["pageAction", "default_icon"],
       () => IconDetails.normalize({path: options.default_icon}, extension));
 
     if (!this.browserPageAction) {
       this.browserPageAction = PageActions.addAction(new PageActions.Action({
         id: widgetId,
+        extensionID: extension.id,
         title: this.defaults.title,
         iconURL: this.getIconData(this.defaults.icon),
-        shownInUrlbar: true,
+        pinnedToUrlbar: true,
         disabled: true,
         onCommand: (event, buttonNode) => {
           this.handleClick(event.target.ownerGlobal);
         },
         onBeforePlacedInWindow: browserWindow => {
           if (this.extension.hasPermission("menus") ||
               this.extension.hasPermission("contextMenus")) {
             browserWindow.document.addEventListener("popupshowing", this);
--- a/browser/components/extensions/test/xpcshell/test_ext_pageAction_shutdown.js
+++ b/browser/components/extensions/test/xpcshell/test_ext_pageAction_shutdown.js
@@ -19,17 +19,17 @@ createAppInfo("xpcshell@tests.mozilla.or
 // This is copied and pasted from ExtensionPopups.jsm.  It's used as the
 // PageActions action ID.  See ext-pageAction.js.
 function makeWidgetId(id) {
   id = id.toLowerCase();
   // FIXME: This allows for collisions.
   return id.replace(/[^a-z0-9_-]/g, "_");
 }
 
-// Tests that the shownInUrlbar property of the PageActions.Action object
+// Tests that the pinnedToUrlbar property of the PageActions.Action object
 // backing the extension's page action persists across app restarts.
 add_task(async function testAppShutdown() {
   let extensionData = {
     useAddonManager: "permanent",
     manifest: {
       page_action: {
         default_title: "test_ext_pageAction_shutdown.js",
         browser_style: false,
@@ -39,41 +39,41 @@ add_task(async function testAppShutdown(
 
   // Simulate starting up the app.
   PageActions.init();
   await promiseStartupManager();
 
   let extension = ExtensionTestUtils.loadExtension(extensionData);
   await extension.startup();
 
-  // Get the PageAction.Action object.  Its shownInUrlbar should have been
+  // Get the PageAction.Action object.  Its pinnedToUrlbar should have been
   // initialized to true in ext-pageAction.js, when it's created.
   let actionID = makeWidgetId(extension.id);
   let action = PageActions.actionForID(actionID);
-  Assert.equal(action.shownInUrlbar, true);
+  Assert.equal(action.pinnedToUrlbar, true);
 
   // Simulate restarting the app without first unloading the extension.
   await promiseShutdownManager();
   PageActions._reset();
   await promiseStartupManager();
   await extension.awaitStartup();
 
-  // Get the action.  Its shownInUrlbar should remain true.
+  // Get the action.  Its pinnedToUrlbar should remain true.
   action = PageActions.actionForID(actionID);
-  Assert.equal(action.shownInUrlbar, true);
+  Assert.equal(action.pinnedToUrlbar, true);
 
-  // Now set its shownInUrlbar to false.
-  action.shownInUrlbar = false;
+  // Now set its pinnedToUrlbar to false.
+  action.pinnedToUrlbar = false;
 
   // Simulate restarting the app again without first unloading the extension.
   await promiseShutdownManager();
   PageActions._reset();
   await promiseStartupManager();
   await extension.awaitStartup();
 
-  // Get the action.  Its shownInUrlbar should remain false.
+  // Get the action.  Its pinnedToUrlbar should remain false.
   action = PageActions.actionForID(actionID);
-  Assert.equal(action.shownInUrlbar, false);
+  Assert.equal(action.pinnedToUrlbar, false);
 
   // Now unload the extension and quit the app.
   await extension.unload();
   await promiseShutdownManager();
 });
--- a/browser/components/preferences/handlers.xml
+++ b/browser/components/preferences/handlers.xml
@@ -77,22 +77,22 @@
         <xul:hbox flex="1" align="center">
           <xul:hbox xbl:inherits="data-identity-icon=containerIcon,data-identity-color=containerColor" height="24" width="24" class="userContext-icon"/>
           <xul:label flex="1" crop="end" xbl:inherits="xbl:text=containerName,highlightable"/>
         </xul:hbox>
         <xul:hbox flex="1" align="right">
           <xul:button anonid="preferencesButton"
                       label="&preferencesButton.label;"
                       xbl:inherits="value=userContextId"
-                      onclick="gContainersPane.onPreferenceClick(event.originalTarget)">
+                      oncommand="gContainersPane.onPreferenceCommand(event.originalTarget)">
           </xul:button>
           <xul:button anonid="removeButton"
                       label="&removeButton.label;"
                       xbl:inherits="value=userContextId"
-                      onclick="gContainersPane.onRemoveClick(event.originalTarget)">
+                      oncommand="gContainersPane.onRemoveCommand(event.originalTarget)">
           </xul:button>
         </xul:hbox>
       </xul:hbox>
     </content>
   </binding>
 
   <binding id="offlineapp"
 	   extends="chrome://global/content/bindings/listbox.xml#listitem">
--- a/browser/components/preferences/in-content/containers.js
+++ b/browser/components/preferences/in-content/containers.js
@@ -35,17 +35,17 @@ let gContainersPane = {
       item.setAttribute("containerIcon", container.icon);
       item.setAttribute("containerColor", container.color);
       item.setAttribute("userContextId", container.userContextId);
 
       this._list.appendChild(item);
     }
   },
 
-  async onRemoveClick(button) {
+  async onRemoveCommand(button) {
     let userContextId = parseInt(button.getAttribute("value"), 10);
 
     let count = ContextualIdentityService.countContainerTabs(userContextId);
     if (count > 0) {
       let bundlePreferences = document.getElementById("bundlePreferences");
 
       let title = bundlePreferences.getString("removeContainerAlertTitle");
       let message = PluralForm.get(count, bundlePreferences.getString("removeContainerMsg"))
@@ -64,21 +64,21 @@ let gContainersPane = {
 
       await ContextualIdentityService.closeContainerTabs(userContextId);
     }
 
     ContextualIdentityService.remove(userContextId);
     this._rebuildView();
   },
 
-  onPreferenceClick(button) {
+  onPreferenceCommand(button) {
     this.openPreferenceDialog(button.getAttribute("value"));
   },
 
-  onAddButtonClick(button) {
+  onAddButtonCommand(button) {
     this.openPreferenceDialog(null);
   },
 
   openPreferenceDialog(userContextId) {
     let identity = {
       name: "",
       icon: defaultContainerIcon,
       color: defaultContainerColor
--- a/browser/components/preferences/in-content/containers.xul
+++ b/browser/components/preferences/in-content/containers.xul
@@ -34,12 +34,12 @@
   <vbox id="browserContainersbox">
 
     <richlistbox id="containersView" orient="vertical" persist="lastSelectedType"
                  flex="1">
     </richlistbox>
   </vbox>
   <vbox>
     <hbox flex="1">
-      <button id="containersAdd" onclick="gContainersPane.onAddButtonClick();" accesskey="&addButton.accesskey;" label="&addButton.label;"/>
+      <button id="containersAdd" oncommand="gContainersPane.onAddButtonCommand();" accesskey="&addButton.accesskey;" label="&addButton.label;"/>
     </hbox>
   </vbox>
 </groupbox>
--- a/browser/components/preferences/in-content/main.js
+++ b/browser/components/preferences/in-content/main.js
@@ -1181,22 +1181,38 @@ var gMainPane = {
     }
   },
 
   buildContentProcessCountMenuList() {
     if (Services.appinfo.browserTabsRemoteAutostart) {
       let processCountPref = document.getElementById("dom.ipc.processCount");
       let defaultProcessCount = processCountPref.defaultValue;
       let bundlePreferences = document.getElementById("bundlePreferences");
-      let label = bundlePreferences.getFormattedString("defaultContentProcessCount",
-        [defaultProcessCount]);
+
       let contentProcessCount =
         document.querySelector(`#contentProcessCount > menupopup >
                                 menuitem[value="${defaultProcessCount}"]`);
-      contentProcessCount.label = label;
+
+      // New localization API experiment (October 2017).
+      // See bug 1402061 for details.
+      //
+      // The `intl.l10n.fluent.disabled` pref can be used
+      // to opt-out of the experiment in case of any
+      // unforseen problems. The legacy API will then
+      // be used.
+      if (Services.prefs.getBoolPref("intl.l10n.fluent.disabled", false)) {
+        let label = bundlePreferences.getFormattedString("defaultContentProcessCount",
+          [defaultProcessCount]);
+        contentProcessCount.label = label;
+      } else {
+        document.l10n.setAttributes(
+          contentProcessCount,
+          "default-content-process-count",
+          { num: defaultProcessCount });
+      }
 
       document.getElementById("limitContentProcess").disabled = false;
       document.getElementById("contentProcessCount").disabled = false;
       document.getElementById("contentProcessCountEnabledDescription").hidden = false;
       document.getElementById("contentProcessCountDisabledDescription").hidden = true;
     } else {
       document.getElementById("limitContentProcess").disabled = true;
       document.getElementById("contentProcessCount").disabled = true;
--- a/browser/components/preferences/in-content/main.xul
+++ b/browser/components/preferences/in-content/main.xul
@@ -1,14 +1,17 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 <!-- General panel -->
 
+<link rel="localization" href="browser/preferences/main.ftl"/>
+<script type="text/javascript" src="chrome://global/content/l10n.js"></script>
+
 <script type="application/javascript"
         src="chrome://browser/content/preferences/in-content/main.js"/>
 
 #ifdef MOZ_UPDATER
   <script type="application/javascript" src="chrome://browser/content/aboutDialog-appUpdater.js"/>
 #endif
 
 <script type="application/javascript"
--- a/browser/components/preferences/in-content/preferences.xul
+++ b/browser/components/preferences/in-content/preferences.xul
@@ -171,17 +171,19 @@
           <label class="category-name" flex="1">&paneSync1.title;</label>
         </richlistitem>
       </richlistbox>
 
       <spacer flex="1"/>
 
       <hbox class="help-button" pack="center">
         <label class="text-link">
-          <image class="help-icon"/><label class="help-label" flex="1">&helpButton2.label;</label>
+          <hbox align="center">
+            <image class="help-icon"/><label class="help-label" flex="1">&helpButton2.label;</label>
+          </hbox>
         </label>
       </hbox>
     </vbox>
 
     <keyset>
       <key key="&focusSearch1.key;" modifiers="accel" id="focusSearch1" oncommand="gSearchResultsPane.searchInput.focus();"/>
     </keyset>
 
--- a/browser/components/preferences/in-content/tests/browser.ini
+++ b/browser/components/preferences/in-content/tests/browser.ini
@@ -80,8 +80,9 @@ skip-if = e10s
 support-files =
   subdialog.xul
   subdialog2.xul
 [browser_telemetry.js]
 # Skip this test on Android as FHR and Telemetry are separate systems there.
 skip-if = !healthreport || !telemetry || (os == 'linux' && debug) || (os == 'android')
 [browser_containers_name_input.js]
 run-if = nightly_build # Containers is enabled only on Nightly
+[browser_fluent.js]
--- a/browser/components/preferences/in-content/tests/browser_containers_name_input.js
+++ b/browser/components/preferences/in-content/tests/browser_containers_name_input.js
@@ -9,17 +9,17 @@ add_task(async function setup() {
 
 add_task(async function() {
   async function openDialog() {
     let doc = gBrowser.selectedBrowser.contentDocument;
 
     let dialogPromise = promiseLoadSubDialog(CONTAINERS_URL);
 
     let addButton = doc.getElementById("containersAdd");
-    addButton.click();
+    addButton.doCommand();
 
     let dialog = await dialogPromise;
 
     return dialog.document;
   }
 
   let doc = await openDialog();
 
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/in-content/tests/browser_fluent.js
@@ -0,0 +1,48 @@
+/* eslint-disable mozilla/no-cpows-in-tests */
+
+function whenMainPaneLoadedFinished() {
+  return new Promise(function(resolve, reject) {
+    const topic = "main-pane-loaded";
+    Services.obs.addObserver(function observer(aSubject) {
+      Services.obs.removeObserver(observer, topic);
+      resolve();
+    }, topic);
+  });
+}
+
+// Temporary test for an experimental new localization API.
+// See bug 1402069 for details.
+add_task(async function() {
+  // The string is used only when `browserTabsRemoteAutostart` is true
+  if (!Services.appinfo.browserTabsRemoteAutostart) {
+    ok(true, "fake test to avoid harness complaining");
+    return;
+  }
+
+  await Promise.all([
+    openPreferencesViaOpenPreferencesAPI("general", {leaveOpen: true}),
+    whenMainPaneLoadedFinished(),
+  ]);
+
+  let doc = gBrowser.contentDocument;
+  await doc.l10n.ready;
+
+  let processCountPref = doc.getElementById("dom.ipc.processCount");
+  let defaultProcessCount = processCountPref.defaultValue;
+
+  let [ msg ] = await doc.l10n.formatMessages([
+    ["default-content-process-count", { num: defaultProcessCount }]
+  ]);
+
+  let elem = doc.querySelector(
+    `#contentProcessCount > menupopup > menuitem[value="${defaultProcessCount}"]`);
+
+  Assert.deepEqual(msg, {
+    value: null,
+    attrs: [
+      ["label", elem.getAttribute("label")]
+    ]
+  });
+
+  await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+});
--- a/browser/components/uitour/test/browser_UITour_availableTargets.js
+++ b/browser/components/uitour/test/browser_UITour_availableTargets.js
@@ -131,27 +131,27 @@ async function assertTargetNode(targetNa
   let target = await UITour.getTarget(window, targetName);
   is(target.node.id, expectedNodeId, "UITour should get the right target node");
 }
 
 var pageActionsHelper = {
   setActionsUrlbarState(inUrlbar) {
     this._originalStates = [];
     PageActions._actionsByID.forEach(action => {
-      this._originalStates.push([ action, action.shownInUrlbar ]);
-      action.shownInUrlbar = inUrlbar;
+      this._originalStates.push([ action, action.pinnedToUrlbar ]);
+      action.pinnedToUrlbar = inUrlbar;
     });
   },
 
   restoreActionsUrlbarState() {
     if (!this._originalStates) {
       return;
     }
     for (let [ action, originalState] of this._originalStates) {
-      action.shownInUrlbar = originalState;
+      action.pinnedToUrlbar = originalState;
     }
     this._originalStates = null;
   }
 };
 
 function ensureScreenshotsEnabled() {
   SpecialPowers.pushPrefEnv({ set: [
     [ "extensions.screenshots.disabled", false ]
--- a/browser/extensions/formautofill/FormAutofillDoorhanger.jsm
+++ b/browser/extensions/formautofill/FormAutofillDoorhanger.jsm
@@ -41,17 +41,17 @@ const CONTENT = {
     message: formatStringFromName("saveAddressesMessage", [brandShortName], 1),
     anchor: {
       id: "autofill-address-notification-icon",
       URL: "chrome://formautofill/content/formfill-anchor.svg",
       tooltiptext: GetStringFromName("openAutofillMessagePanel"),
     },
     mainAction: {
       label: GetStringFromName(changeAutofillOptsKey),
-      accessKey: "C",
+      accessKey: GetStringFromName("changeAutofillOptionsAccessKey"),
       callbackState: "open-pref",
       disableHighlight: true,
     },
     options: {
       persistWhileVisible: true,
       popupIconURL: "chrome://formautofill/content/icon-address-save.svg",
       checkbox: {
         get checked() {
@@ -77,22 +77,22 @@ const CONTENT = {
     linkMessage: GetStringFromName(autofillOptsKey),
     anchor: {
       id: "autofill-address-notification-icon",
       URL: "chrome://formautofill/content/formfill-anchor.svg",
       tooltiptext: GetStringFromName("openAutofillMessagePanel"),
     },
     mainAction: {
       label: GetStringFromName("updateAddressLabel"),
-      accessKey: "U",
+      accessKey: GetStringFromName("updateAddressAccessKey"),
       callbackState: "update",
     },
     secondaryActions: [{
       label: GetStringFromName("createAddressLabel"),
-      accessKey: "C",
+      accessKey: GetStringFromName("createAddressAccessKey"),
       callbackState: "create",
     }],
     options: {
       persistWhileVisible: true,
       popupIconURL: "chrome://formautofill/content/icon-address-update.svg",
       hideClose: true,
     },
   },
@@ -102,26 +102,26 @@ const CONTENT = {
     linkMessage: GetStringFromName(autofillSecurityOptionsKey),
     anchor: {
       id: "autofill-credit-card-notification-icon",
       URL: "chrome://formautofill/content/formfill-anchor.svg",
       tooltiptext: GetStringFromName("openAutofillMessagePanel"),
     },
     mainAction: {
       label: GetStringFromName("saveCreditCardLabel"),
-      accessKey: "S",
+      accessKey: GetStringFromName("saveCreditCardAccessKey"),
       callbackState: "save",
     },
     secondaryActions: [{
       label: GetStringFromName("cancelCreditCardLabel"),
-      accessKey: "D",
+      accessKey: GetStringFromName("cancelCreditCardAccessKey"),
       callbackState: "cancel",
     }, {
       label: GetStringFromName("neverSaveCreditCardLabel"),
-      accessKey: "N",
+      accessKey: GetStringFromName("neverSaveCreditCardAccessKey"),
       callbackState: "disable",
     }],
     options: {
       persistWhileVisible: true,
       popupIconURL: "chrome://formautofill/content/icon-credit-card.svg",
       hideClose: true,
       checkbox: {
         get checked() {
@@ -155,22 +155,22 @@ const CONTENT = {
     linkMessage: GetStringFromName(autofillOptsKey),
     anchor: {
       id: "autofill-credit-card-notification-icon",
       URL: "chrome://formautofill/content/formfill-anchor.svg",
       tooltiptext: GetStringFromName("openAutofillMessagePanel"),
     },
     mainAction: {
       label: GetStringFromName("updateCreditCardLabel"),
-      accessKey: "U",
+      accessKey: GetStringFromName("updateCreditCardAccessKey"),
       callbackState: "update",
     },
     secondaryActions: [{
       label: GetStringFromName("createCreditCardLabel"),
-      accessKey: "C",
+      accessKey: GetStringFromName("createCreditCardAccessKey"),
       callbackState: "create",
     }],
     options: {
       persistWhileVisible: true,
       popupIconURL: "chrome://formautofill/content/icon-credit-card.svg",
       hideClose: true,
     },
   },
--- a/browser/extensions/formautofill/locales/en-US/formautofill.properties
+++ b/browser/extensions/formautofill/locales/en-US/formautofill.properties
@@ -12,39 +12,47 @@ autofillOptionsLinkOSX = Form Autofill P
 # LOCALIZATION NOTE (autofillSecurityOptionsLink, autofillSecurityOptionsLinkOSX): These strings are used
 # in the doorhanger for saving credit card info. The link leads users to Form Autofill browser preferences.
 autofillSecurityOptionsLink = Form Autofill & Security Options
 autofillSecurityOptionsLinkOSX = Form Autofill & Security Preferences
 # LOCALIZATION NOTE (changeAutofillOptions, changeAutofillOptionsOSX): These strings are used on the doorhanger
 # that notifies users that addresses are saved. The button leads users to Form Autofill browser preferences.
 changeAutofillOptions = Change Form Autofill Options
 changeAutofillOptionsOSX = Change Form Autofill Preferences
+changeAutofillOptionsAccessKey = C
 # LOCALIZATION NOTE (addressesSyncCheckbox): If Sync is enabled, this checkbox is displayed on the doorhanger
 # shown when saving addresses.
 addressesSyncCheckbox = Share addresses with synced devices
 # LOCALIZATION NOTE (creditCardsSyncCheckbox): If Sync is enabled and credit card sync is available,
 # this checkbox is displayed on the doorhanger shown when saving credit card.
 creditCardsSyncCheckbox = Share credit cards with synced devices
 # LOCALIZATION NOTE (updateAddressMessage, createAddressLabel, updateAddressLabel): Used on the doorhanger
 # when an address change is detected.
 updateAddressMessage = Would you like to update your address with this new information?
 createAddressLabel = Create New Address
+createAddressAccessKey = C
 updateAddressLabel = Update Address
+updateAddressAccessKey = U
 # LOCALIZATION NOTE (saveCreditCardMessage, saveCreditCardLabel, cancelCreditCardLabel, neverSaveCreditCardLabel):
 # Used on the doorhanger when users submit payment with credit card.
 # LOCALIZATION NOTE (saveCreditCardMessage): %S is brandShortName.
 saveCreditCardMessage = Would you like %S to save this credit card? (Security code will not be saved)
 saveCreditCardLabel = Save Credit Card
+saveCreditCardAccessKey = S
 cancelCreditCardLabel = Don’t Save
+cancelCreditCardAccessKey = D
 neverSaveCreditCardLabel = Never Save Credit Cards
+neverSaveCreditCardAccessKey = N
 # LOCALIZATION NOTE (updateCreditCardMessage, createCreditCardLabel, updateCreditCardLabel): Used on the doorhanger
 # when an credit card change is detected.
 updateCreditCardMessage = Would you like to update your credit card with this new information?
 createCreditCardLabel = Create New Credit Card
+createCreditCardAccessKey = C
 updateCreditCardLabel = Update Credit Card
+updateCreditCardAccessKey = U
 # LOCALIZATION NOTE (openAutofillMessagePanel): Tooltip label for Form Autofill doorhanger icon on address bar.
 openAutofillMessagePanel = Open Form Autofill message panel
 
 # LOCALIZATION NOTE (autocompleteFooterOption, autocompleteFooterOptionOSX): Used as a label for the button,
 # displayed at the bottom of the drop down suggestion, to open Form Autofill browser preferences.
 autocompleteFooterOption = Form Autofill Options
 autocompleteFooterOptionOSX = Form Autofill Preferences
 # LOCALIZATION NOTE (autocompleteFooterOptionShort, autocompleteFooterOptionOSXShort): Used as a label for the button,
--- a/browser/extensions/pdfjs/README.mozilla
+++ b/browser/extensions/pdfjs/README.mozilla
@@ -1,5 +1,5 @@
 This is the PDF.js project output, https://github.com/mozilla/pdf.js
 
-Current extension version is: 2.0.104
+Current extension version is: 2.0.106
 
-Taken from upstream commit: 012d0756
+Taken from upstream commit: 0052dc2b
--- a/browser/extensions/pdfjs/content/PdfStreamConverter.jsm
+++ b/browser/extensions/pdfjs/content/PdfStreamConverter.jsm
@@ -144,43 +144,52 @@ function getLocalizedString(strings, id,
     return strings[id][property];
   }
   return id;
 }
 
 // PDF data storage
 function PdfDataListener(length) {
   this.length = length; // less than 0, if length is unknown
-  this.buffer = null;
+  this.buffers = [];
   this.loaded = 0;
 }
 
 PdfDataListener.prototype = {
   append: function PdfDataListener_append(chunk) {
     // In most of the cases we will pass data as we receive it, but at the
     // beginning of the loading we may accumulate some data.
-    if (!this.buffer) {
-      this.buffer = new Uint8Array(chunk);
-    } else {
-      var buffer = this.buffer;
-      var newBuffer = new Uint8Array(buffer.length + chunk.length);
-      newBuffer.set(buffer);
-      newBuffer.set(chunk, buffer.length);
-      this.buffer = newBuffer;
-    }
+    this.buffers.push(chunk);
     this.loaded += chunk.length;
     if (this.length >= 0 && this.length < this.loaded) {
       this.length = -1; // reset the length, server is giving incorrect one
     }
     this.onprogress(this.loaded, this.length >= 0 ? this.length : void 0);
   },
   readData: function PdfDataListener_readData() {
-    var result = this.buffer;
-    this.buffer = null;
-    return result;
+    if (this.buffers.length === 0) {
+      return null;
+    }
+    if (this.buffers.length === 1) {
+      return this.buffers.pop();
+    }
+    // There are multiple buffers that need to be combined into a single
+    // buffer.
+    let combinedLength = 0;
+    for (let buffer of this.buffers) {
+      combinedLength += buffer.length;
+    }
+    let combinedArray = new Uint8Array(combinedLength);
+    let writeOffset = 0;
+    while (this.buffers.length) {
+      let buffer = this.buffers.shift();
+      combinedArray.set(buffer, writeOffset);
+      writeOffset += buffer.length;
+    }
+    return combinedArray;
   },
   finish: function PdfDataListener_finish() {
     this.isDataReady = true;
     if (this.oncompleteCallback) {
       this.oncompleteCallback(this.readData());
     }
   },
   error: function PdfDataListener_error(errorCode) {
@@ -873,18 +882,19 @@ PdfStreamConverter.prototype = {
   // nsIStreamListener::onDataAvailable
   onDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount) {
     if (!this.dataListener) {
       return;
     }
 
     var binaryStream = this.binaryStream;
     binaryStream.setInputStream(aInputStream);
-    var chunk = binaryStream.readByteArray(aCount);
-    this.dataListener.append(chunk);
+    let chunk = new ArrayBuffer(aCount);
+    binaryStream.readArrayBuffer(aCount, chunk);
+    this.dataListener.append(new Uint8Array(chunk));
   },
 
   // nsIRequestObserver::onStartRequest
   onStartRequest(aRequest, aContext) {
     // Setup the request so we can use it below.
     var isHttpRequest = false;
     try {
       aRequest.QueryInterface(Ci.nsIHttpChannel);
--- a/browser/extensions/pdfjs/content/build/pdf.js
+++ b/browser/extensions/pdfjs/content/build/pdf.js
@@ -1956,17 +1956,17 @@ function getDocument(src) {
     });
   }).catch(task._capability.reject);
   return task;
 }
 function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
   if (worker.destroyed) {
     return Promise.reject(new Error('Worker was destroyed'));
   }
-  let apiVersion = '2.0.104';
+  let apiVersion = '2.0.106';
   source.disableAutoFetch = (0, _dom_utils.getDefaultSetting)('disableAutoFetch');
   source.disableStream = (0, _dom_utils.getDefaultSetting)('disableStream');
   source.chunkedViewerLoading = !!pdfDataRangeTransport;
   if (pdfDataRangeTransport) {
     source.length = pdfDataRangeTransport.length;
     source.initialData = pdfDataRangeTransport.initialData;
   }
   return worker.messageHandler.sendWithPromise('GetDocRequest', {
@@ -3253,18 +3253,18 @@ var InternalRenderTask = function Intern
         }
       }
     }
   };
   return InternalRenderTask;
 }();
 var version, build;
 {
-  exports.version = version = '2.0.104';
-  exports.build = build = '012d0756';
+  exports.version = version = '2.0.106';
+  exports.build = build = '0052dc2b';
 }
 exports.getDocument = getDocument;
 exports.LoopbackPort = LoopbackPort;
 exports.PDFDataRangeTransport = PDFDataRangeTransport;
 exports.PDFWorker = PDFWorker;
 exports.PDFDocumentProxy = PDFDocumentProxy;
 exports.PDFPageProxy = PDFPageProxy;
 exports.setPDFNetworkStreamClass = setPDFNetworkStreamClass;
@@ -4988,18 +4988,18 @@ exports.SVGGraphics = SVGGraphics;
 
 /***/ }),
 /* 9 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
-var pdfjsVersion = '2.0.104';
-var pdfjsBuild = '012d0756';
+var pdfjsVersion = '2.0.106';
+var pdfjsBuild = '0052dc2b';
 var pdfjsSharedUtil = __w_pdfjs_require__(0);
 var pdfjsDisplayGlobal = __w_pdfjs_require__(13);
 var pdfjsDisplayAPI = __w_pdfjs_require__(3);
 var pdfjsDisplayTextLayer = __w_pdfjs_require__(7);
 var pdfjsDisplayAnnotationLayer = __w_pdfjs_require__(6);
 var pdfjsDisplayDOMUtils = __w_pdfjs_require__(1);
 var pdfjsDisplaySVG = __w_pdfjs_require__(8);
 ;
@@ -8113,18 +8113,18 @@ var _svg = __w_pdfjs_require__(8);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 if (!_global_scope2.default.PDFJS) {
   _global_scope2.default.PDFJS = {};
 }
 var PDFJS = _global_scope2.default.PDFJS;
 {
-  PDFJS.version = '2.0.104';
-  PDFJS.build = '012d0756';
+  PDFJS.version = '2.0.106';
+  PDFJS.build = '0052dc2b';
 }
 PDFJS.pdfBug = false;
 if (PDFJS.verbosity !== undefined) {
   (0, _util.setVerbosityLevel)(PDFJS.verbosity);
 }
 delete PDFJS.verbosity;
 Object.defineProperty(PDFJS, 'verbosity', {
   get() {
--- a/browser/extensions/pdfjs/content/build/pdf.worker.js
+++ b/browser/extensions/pdfjs/content/build/pdf.worker.js
@@ -23279,18 +23279,18 @@ exports.PostScriptCompiler = PostScriptC
 
 /***/ }),
 /* 17 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
-var pdfjsVersion = '2.0.104';
-var pdfjsBuild = '012d0756';
+var pdfjsVersion = '2.0.106';
+var pdfjsBuild = '0052dc2b';
 var pdfjsCoreWorker = __w_pdfjs_require__(18);
 exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
 
 /***/ }),
 /* 18 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
@@ -23475,17 +23475,17 @@ var WorkerMessageHandler = {
     });
   },
   createDocumentHandler(docParams, port) {
     var pdfManager;
     var terminated = false;
     var cancelXHRs = null;
     var WorkerTasks = [];
     let apiVersion = docParams.apiVersion;
-    let workerVersion = '2.0.104';
+    let workerVersion = '2.0.106';
     if (apiVersion !== null && apiVersion !== workerVersion) {
       throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
     }
     var docId = docParams.docId;
     var docBaseUrl = docParams.docBaseUrl;
     var workerHandlerName = docParams.docId + '_worker';
     var handler = new _util.MessageHandler(workerHandlerName, docId, port);
     handler.postMessageTransfers = docParams.postMessageTransfers;
--- a/browser/extensions/pocket/bootstrap.js
+++ b/browser/extensions/pocket/bootstrap.js
@@ -89,17 +89,17 @@ var PocketPageAction = {
 
   init() {
     let id = "pocket";
     this.pageAction = PageActions.actionForID(id);
     if (!this.pageAction) {
       this.pageAction = PageActions.addAction(new PageActions.Action({
         id,
         title: gPocketBundle.GetStringFromName("saveToPocketCmd.label"),
-        shownInUrlbar: true,
+        pinnedToUrlbar: true,
         wantsIframe: true,
         urlbarIDOverride: "pocket-button-box",
         anchorIDOverride: "pocket-button",
         _insertBeforeActionID: PageActions.ACTION_ID_BOOKMARK_SEPARATOR,
         _urlbarNodeInMarkup: true,
         onBeforePlacedInWindow(window) {
           let doc = window.document;
 
--- a/browser/extensions/shield-recipe-client/bootstrap.js
+++ b/browser/extensions/shield-recipe-client/bootstrap.js
@@ -1,14 +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";
 
-const {utils: Cu} = Components;
+const {results: Cr, utils: Cu} = Components;
 Cu.import("resource://gre/modules/AppConstants.jsm");
 Cu.import("resource://gre/modules/Log.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "LogManager",
   "resource://shield-recipe-client/lib/LogManager.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ShieldRecipeClient",
@@ -77,36 +77,46 @@ this.Bootstrap = {
       const realPrefType = defaultBranch.getPrefType(prefName);
 
       if (realPrefType !== Services.prefs.PREF_INVALID && realPrefType !== experimentPrefType) {
         log.error(`Error setting startup pref ${prefName}; pref type does not match.`);
         continue;
       }
 
       // record the value of the default branch before setting it
-      switch (realPrefType) {
-        case Services.prefs.PREF_STRING:
-          studyPrefsChanged[prefName] = defaultBranch.getCharPref(prefName);
-          break;
+      try {
+        switch (realPrefType) {
+          case Services.prefs.PREF_STRING:
+            studyPrefsChanged[prefName] = defaultBranch.getCharPref(prefName);
+            break;
 
-        case Services.prefs.PREF_INT:
-          studyPrefsChanged[prefName] = defaultBranch.getIntPref(prefName);
-          break;
+          case Services.prefs.PREF_INT:
+            studyPrefsChanged[prefName] = defaultBranch.getIntPref(prefName);
+            break;
+
+          case Services.prefs.PREF_BOOL:
+            studyPrefsChanged[prefName] = defaultBranch.getBoolPref(prefName);
+            break;
 
-        case Services.prefs.PREF_BOOL:
-          studyPrefsChanged[prefName] = defaultBranch.getBoolPref(prefName);
-          break;
+          case Services.prefs.PREF_INVALID:
+            studyPrefsChanged[prefName] = null;
+            break;
 
-        case Services.prefs.PREF_INVALID:
+          default:
+            // This should never happen
+            log.error(`Error getting startup pref ${prefName}; unknown value type ${experimentPrefType}.`);
+        }
+      } catch (e) {
+        if (e.result == Cr.NS_ERROR_UNEXPECTED) {
+          // There is a value for the pref on the user branch but not on the default branch. This is ok.
           studyPrefsChanged[prefName] = null;
-          break;
-
-        default:
-          // This should never happen
-          log.error(`Error getting startup pref ${prefName}; unknown value type ${experimentPrefType}.`);
+        } else {
+          // rethrow
+          throw e;
+        }
       }
 
       // now set the new default value
       switch (experimentPrefType) {
         case Services.prefs.PREF_STRING:
           defaultBranch.setCharPref(prefName, experimentBranch.getCharPref(prefName));
           break;
 
--- a/browser/extensions/shield-recipe-client/test/browser/browser_bootstrap.js
+++ b/browser/extensions/shield-recipe-client/test/browser/browser_bootstrap.js
@@ -247,8 +247,24 @@ decorate_task(
         [experimentPref2]: 1,
         [experimentPref3]: "original string",
         [experimentPref4]: null,  // null because it was not initially set.
       }],
       "finishStartup should record original values of the prefs initExperimentPrefs changed",
     );
   },
 );
+
+// Test that startup prefs are handled correctly when there is a value on the user branch but not the default branch.
+decorate_task(
+  withPrefEnv({
+    set: [
+      ["extensions.shield-recipe-client.startupExperimentPrefs.testing.does-not-exist", "foo"],
+      ["testing.does-not-exist", "foo"],
+    ],
+  }),
+  withBootstrap,
+  withStub(PreferenceExperiments, "recordOriginalValues"),
+  async function testInitExperimentPrefsNoDefaultValue(Bootstrap) {
+    Bootstrap.initExperimentPrefs();
+    ok(true, "initExperimentPrefs should not throw for non-existant prefs");
+  },
+);
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -41,16 +41,17 @@
 @APPNAME@/Contents/PkgInfo
 @RESPATH@/firefox.icns
 @RESPATH@/document.icns
 @RESPATH@/@LPROJ_ROOT@.lproj/*
 #endif
 
 [@AB_CD@]
 @RESPATH@/dictionaries/*
+@RESPATH@/browser/localization/*
 #if defined(XP_WIN) || defined(XP_LINUX)
 @RESPATH@/fonts/*
 #endif
 @RESPATH@/hyphenation/*
 @RESPATH@/browser/@PREF_DIR@/firefox-l10n.js
 #ifdef HAVE_MAKENSISU
 @BINPATH@/uninstall/helper.exe
 #endif
@@ -201,17 +202,16 @@
 @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
 @RESPATH@/components/dom_offline.xpt
-@RESPATH@/components/dom_json.xpt
 @RESPATH@/components/dom_payments.xpt
 @RESPATH@/components/dom_power.xpt
 @RESPATH@/components/dom_push.xpt
 @RESPATH@/components/dom_quota.xpt
 @RESPATH@/components/dom_range.xpt
 @RESPATH@/components/dom_security.xpt
 @RESPATH@/components/dom_sidebar.xpt
 @RESPATH@/components/dom_storage.xpt
--- a/browser/locales/all-locales
+++ b/browser/locales/all-locales
@@ -91,11 +91,12 @@ ta
 te
 th
 tl
 tr
 uk
 ur
 uz
 vi
+wo
 xh
 zh-CN
 zh-TW
new file mode 100644
--- /dev/null
+++ b/browser/locales/en-US/browser/preferences/main.ftl
@@ -0,0 +1,4 @@
+// Variables:
+//   $num - default value of the `dom.ipc.processCount` pref.
+default-content-process-count
+    .label = { $num } (default)
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -956,16 +956,19 @@ you can use these alternative items. Oth
 <!ENTITY updateRestart.acceptButton.accesskey "R">
 <!ENTITY updateRestart.cancelButton.label "Not Now">
 <!ENTITY updateRestart.cancelButton.accesskey "N">
 <!ENTITY updateRestart.panelUI.label2 "Restart to update &brandShorterName;">
 
 <!ENTITY pageActionButton.tooltip "Page actions">
 <!ENTITY pageAction.addToUrlbar.label "Add to Address Bar">
 <!ENTITY pageAction.removeFromUrlbar.label "Remove from Address Bar">
+<!ENTITY pageAction.allowInUrlbar.label "Show in Address Bar">
+<!ENTITY pageAction.disallowInUrlbar.label "Don’t Show in Address Bar">
+<!ENTITY pageAction.manageExtension.label "Manage Extension…">
 
 <!ENTITY pageAction.sendTabToDevice.label "Send Tab to Device">
 <!ENTITY sendToDevice.syncNotReady.label "Syncing Devices…">
 
 <!ENTITY libraryButton.tooltip "View history, saved bookmarks, and more">
 
 <!-- LOCALIZATION NOTE: (accessibilityIndicator.tooltip): This is used to
      display a tooltip for accessibility indicator in toolbar/tabbar. It is also
--- a/browser/locales/en-US/chrome/browser/pageInfo.dtd
+++ b/browser/locales/en-US/chrome/browser/pageInfo.dtd
@@ -50,16 +50,17 @@
 <!ENTITY  feedSubscribe.accesskey "u">
 
 <!ENTITY  permTab               "Permissions">
 <!ENTITY  permTab.accesskey     "P">
 <!ENTITY  permUseDefault        "Use Default">
 <!ENTITY  permAskAlways         "Always ask">
 <!ENTITY  permAllow             "Allow">
 <!ENTITY  permAllowSession      "Allow for Session">
+<!ENTITY  permHide              "Hide">
 <!ENTITY  permBlock             "Block">
 <!ENTITY  permissionsFor        "Permissions for:">
 <!ENTITY  permPlugins           "Activate Plugins">
 
 <!ENTITY  securityTab           "Security">
 <!ENTITY  securityTab.accesskey "S">
 <!ENTITY  securityView.certView "View Certificate">
 <!ENTITY  securityView.accesskey "V">
--- a/browser/locales/en-US/chrome/browser/sitePermissions.properties
+++ b/browser/locales/en-US/chrome/browser/sitePermissions.properties
@@ -30,10 +30,11 @@ permission.cookie.label = Set Cookies
 permission.desktop-notification2.label = Receive Notifications
 permission.image.label = Load Images
 permission.camera.label = Use the Camera
 permission.microphone.label = Use the Microphone
 permission.screen.label = Share the Screen
 permission.install.label = Install Add-ons
 permission.popup.label = Open Pop-up Windows
 permission.geo.label = Access Your Location
+permission.shortcuts.label = Override Keyboard Shortcuts
 permission.focus-tab-by-prompt.label = Switch to this Tab
 permission.persistent-storage.label = Store Data in Persistent Storage
--- a/browser/locales/jar.mn
+++ b/browser/locales/jar.mn
@@ -2,16 +2,19 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 # Note: This file should only contain locale entries. All
 # override and resource entries should go to browser/base/jar.mn to avoid
 # having to create the same entry for each locale.
 
+[localization] @AB_CD@.jar:
+  browser                                          (%browser/**/*.ftl)
+
 @AB_CD@.jar:
 % locale browser @AB_CD@ %locale/browser/
 *   locale/browser/bookmarks.html                  (generic/profile/bookmarks.html.in)
     locale/browser/aboutDialog.dtd                 (%chrome/browser/aboutDialog.dtd)
     locale/browser/aboutPrivateBrowsing.dtd        (%chrome/browser/aboutPrivateBrowsing.dtd)
     locale/browser/aboutPrivateBrowsing.properties (%chrome/browser/aboutPrivateBrowsing.properties)
     locale/browser/aboutRobots.dtd                 (%chrome/browser/aboutRobots.dtd)
     locale/browser/aboutHome.dtd                   (%chrome/browser/aboutHome.dtd)
--- a/browser/locales/l10n.toml
+++ b/browser/locales/l10n.toml
@@ -98,16 +98,17 @@ locales = [
     "te",
     "th",
     "tl",
     "tr",
     "uk",
     "ur",
     "uz",
     "vi",
+    "wo",
     "xh",
     "zh-CN",
     "zh-TW",
     ]
 
 [env]
     l = "{l10n_base}/{locale}/"
 
--- a/browser/modules/PageActions.jsm
+++ b/browser/modules/PageActions.jsm
@@ -114,25 +114,30 @@ this.PageActions = {
   /**
    * The list of non-built-in actions.  Not live.  (array of Action objects)
    */
   get nonBuiltInActions() {
     return this._nonBuiltInActions.slice();
   },
 
   /**
-   * The list of actions in the urlbar, sorted in the order in which they should
-   * appear there.  Not live.  (array of Action objects)
+   * The list of actions currently in the urlbar, sorted in the order in which
+   * they appear.  Not live.
+   *
+   * @param  browserWindow (DOM window, required)
+   *         This window's actions will be returned.
+   * @return (array of PageAction.Action objects) The actions currently in the
+   *         given window's urlbar.
    */
-  get actionsInUrlbar() {
+  actionsInUrlbar(browserWindow) {
     // Remember that IDs in idsInUrlbar may belong to actions that aren't
     // currently registered.
     return this._persistedActions.idsInUrlbar.reduce((actions, id) => {
       let action = this.actionForID(id);
-      if (action) {
+      if (action && action.shouldShowInUrlbar(browserWindow)) {
         actions.push(action);
       }
       return actions;
     }, []);
   },
 
   /**
    * Gets an action.
@@ -223,40 +228,39 @@ this.PageActions = {
       // Keep this list sorted by title.
       let index = BinarySearch.insertionIndexOf((a1, a2) => {
         return a1.getTitle().localeCompare(a2.getTitle());
       }, this._nonBuiltInActions, action);
       this._nonBuiltInActions.splice(index, 0, action);
     }
 
     if (this._persistedActions.ids.includes(action.id)) {
-      // The action has been seen before.  Override its shownInUrlbar value
+      // The action has been seen before.  Override its pinnedToUrlbar value
       // with the persisted value.  Set the private version of that property
-      // so that onActionToggledShownInUrlbar isn't called, which happens when
+      // so that onActionToggledPinnedToUrlbar isn't called, which happens when
       // the public version is set.
-      action._shownInUrlbar =
+      action._pinnedToUrlbar =
         this._persistedActions.idsInUrlbar.includes(action.id);
     } else {
       // The action is new.  Store it in the persisted actions.
       this._persistedActions.ids.push(action.id);
-      this._updateIDsInUrlbarForAction(action);
+      this._updateIDsPinnedToUrlbarForAction(action);
     }
   },
 
-  _updateIDsInUrlbarForAction(action) {
+  _updateIDsPinnedToUrlbarForAction(action) {
     let index = this._persistedActions.idsInUrlbar.indexOf(action.id);
-    if (action.shownInUrlbar) {
+    if (action.pinnedToUrlbar) {
       if (index < 0) {
-        let nextID = this.nextActionIDInUrlbar(action.id);
-        let nextIndex =
-          nextID ? this._persistedActions.idsInUrlbar.indexOf(nextID) : -1;
-        if (nextIndex < 0) {
-          nextIndex = this._persistedActions.idsInUrlbar.length;
+        index = action.id == ACTION_ID_BOOKMARK ? -1 :
+                this._persistedActions.idsInUrlbar.indexOf(ACTION_ID_BOOKMARK);
+        if (index < 0) {
+          index = this._persistedActions.idsInUrlbar.length;
         }
-        this._persistedActions.idsInUrlbar.splice(nextIndex, 0, action.id);
+        this._persistedActions.idsInUrlbar.splice(index, 0, action.id);
       }
     } else if (index >= 0) {
       this._persistedActions.idsInUrlbar.splice(index, 1);
     }
     this._storePersistedActions();
   },
 
   // These keep track of currently registered actions.
@@ -268,23 +272,23 @@ this.PageActions = {
    * Returns the ID of the action before which the given action should be
    * inserted in the urlbar.
    *
    * @param  action (Action object, required)
    *         The action you're inserting.
    * @return The ID of the reference action, or null if your action should be
    *         appended.
    */
-  nextActionIDInUrlbar(action) {
+  nextActionIDInUrlbar(browserWindow, action) {
     // Actions in the urlbar are always inserted before the bookmark action,
     // which always comes last if it's present.
     if (action.id == ACTION_ID_BOOKMARK) {
       return null;
     }
-    let id = this._nextActionID(action, this.actionsInUrlbar);
+    let id = this._nextActionID(action, this.actionsInUrlbar(browserWindow));
     return id || ACTION_ID_BOOKMARK;
   },
 
   /**
    * Returns the ID of the action before which the given action should be
    * inserted in the panel.
    *
    * @param  action (Action object, required)
@@ -349,44 +353,42 @@ this.PageActions = {
     }
 
     for (let bpa of allBrowserPageActions()) {
       bpa.removeAction(action);
     }
   },
 
   /**
-   * Call this when an action's shownInUrlbar property changes.
+   * Call this when an action's pinnedToUrlbar property changes.
    *
    * @param  action (Action object, required)
-   *         The action whose shownInUrlbar property changed.
+   *         The action whose pinnedToUrlbar property changed.
    */
-  onActionToggledShownInUrlbar(action) {
+  onActionToggledPinnedToUrlbar(action) {
     if (!this.actionForID(action.id)) {
       // This may be called before the action has been added.
       return;
     }
-    this._updateIDsInUrlbarForAction(action);
+    this._updateIDsPinnedToUrlbarForAction(action);
     for (let bpa of allBrowserPageActions()) {
       bpa.placeActionInUrlbar(action);
     }
   },
 
   logTelemetry(type, action, node = null) {
-    const kAllowedLabels = ["pocket", "screenshots", "webcompat"].concat(
-      gBuiltInActions.filter(a => !a.__isSeparator).map(a => a.id)
-    );
-
     if (type == "used") {
-      type = (node && node.closest("#urlbar-container")) ? "urlbar_used" : "panel_used";
+      type =
+        node && node.closest("#urlbar-container") ? "urlbar_used" :
+        "panel_used";
     }
     let histogramID = "FX_PAGE_ACTION_" + type.toUpperCase();
     try {
       let histogram = Services.telemetry.getHistogramById(histogramID);
-      if (kAllowedLabels.includes(action.labelForHistogram)) {
+      if (action._isBuiltIn) {
         histogram.add(action.labelForHistogram);
       } else {
         histogram.add("other");
       }
     } catch (ex) {
       Cu.reportError(ex);
     }
   },
@@ -487,16 +489,18 @@ this.PageActions = {
  * @param title (string, required)
  *        The action's title.
  * @param anchorIDOverride (string, optional)
  *        Pass a string to override the node to which the action's activated-
  *        action panel is anchored.
  * @param disabled (bool, optional)
  *        Pass true to cause the action to be disabled initially in all browser
  *        windows.  False by default.
+ * @param extensionID (string, optional)
+ *        If the action lives in an extension, pass its ID.
  * @param iconURL (string or object, optional)
  *        The URL string of the action's icon.  Usually you want to specify an
  *        icon in CSS, but this option is useful if that would be a pain for
  *        some reason.  You can also pass an object that maps pixel sizes to
  *        URLs, like { 16: url16, 32: url32 }.  The best size for the user's
  *        screen will be used.
  * @param nodeAttributes (object, optional)
  *        An object of name-value pairs.  Each pair will be added as an
@@ -544,19 +548,19 @@ this.PageActions = {
  * @param onRemovedFromWindow (function, optional)
  *        Called after the action is removed from a browser window:
  *        onRemovedFromWindow(browserWindow)
  *        * browserWindow: The browser window that the action was removed from.
  * @param onShowingInPanel (function, optional)
  *        Called when a browser window's page action panel is showing:
  *        onShowingInPanel(buttonNode)
  *        * buttonNode: The action's node in the page action panel.
- * @param shownInUrlbar (bool, optional)
- *        Pass true to show the action in the urlbar, false otherwise.  False by
- *        default.
+ * @param pinnedToUrlbar (bool, optional)
+ *        Pass true to pin the action to the urlbar.  An action is shown in the
+ *        urlbar if it's pinned and not disabled.  False by default.
  * @param subview (object, optional)
  *        An options object suitable for passing to the Subview constructor, if
  *        you'd like the action to have a subview.  See the subview constructor
  *        for info on this object's properties.
  * @param tooltip (string, optional)
  *        The action's button tooltip text.
  * @param urlbarIDOverride (string, optional)
  *        Usually the ID of the action's button in the urlbar will be generated
@@ -567,30 +571,31 @@ this.PageActions = {
  *        clicked.
  */
 function Action(options) {
   setProperties(this, options, {
     id: true,
     title: !options._isSeparator,
     anchorIDOverride: false,
     disabled: false,
+    extensionID: false,
     iconURL: false,
     labelForHistogram: false,
     nodeAttributes: false,
     onBeforePlacedInWindow: false,
     onCommand: false,
     onIframeHiding: false,
     onIframeHidden: false,
     onIframeShown: false,
     onLocationChange: false,
     onPlacedInPanel: false,
     onPlacedInUrlbar: false,
     onRemovedFromWindow: false,
     onShowingInPanel: false,
-    shownInUrlbar: false,
+    pinnedToUrlbar: false,
     subview: false,
     tooltip: false,
     urlbarIDOverride: false,
     wantsIframe: false,
 
     // private
 
     // (string, optional)
@@ -613,42 +618,50 @@ function Action(options) {
   });
   if (this._subview) {
     this._subview = new Subview(options.subview);
   }
 }
 
 Action.prototype = {
   /**
+   * The ID of the action's parent extension (string, nullable)
+   */
+  get extensionID() {
+    return this._extensionID;
+  },
+
+  /**
    * The action's ID (string, nonnull)
    */
   get id() {
     return this._id;
   },
 
   /**
    * Attribute name => value mapping to set on nodes created for this action
    * (object, nullable)
    */
   get nodeAttributes() {
     return this._nodeAttributes;
   },
 
   /**
-   * True if the action is shown in the urlbar (bool, nonnull)
+   * True if the action is pinned to the urlbar.  The action is shown in the
+   * urlbar if it's pinned and not disabled.  (bool, nonnull)
    */
-  get shownInUrlbar() {
-    return this._shownInUrlbar || false;
+  get pinnedToUrlbar() {
+    return this._pinnedToUrlbar || false;
   },
-  set shownInUrlbar(shown) {
-    if (this.shownInUrlbar != shown) {
-      this._shownInUrlbar = shown;
-      PageActions.onActionToggledShownInUrlbar(this);
+  set pinnedToUrlbar(shown) {
+    if (this.pinnedToUrlbar != shown) {
+      this._pinnedToUrlbar = shown;
+      PageActions.onActionToggledPinnedToUrlbar(this);
     }
-    return this.shownInUrlbar;
+    return this.pinnedToUrlbar;
   },
 
   /**
    * The action's disabled state (bool, nonnull)
    */
   getDisabled(browserWindow = null) {
     return !!this._getProperty("disabled", browserWindow);
   },
@@ -967,17 +980,38 @@ Action.prototype = {
    *
    * PageActions will remember the action's urlbar placement, if any, after this
    * method is called until app shutdown.  If the action is not added again
    * before shutdown, then PageActions will discard the placement, and the next
    * time the action is added, its placement will be reset.
    */
   remove() {
     PageActions.onActionRemoved(this);
-  }
+  },
+
+  /**
+   * Returns whether the action should be shown in a given window's urlbar.
+   *
+   * @param  browserWindow (DOM window, required)
+   *         The window.
+   * @return True if the action should be shown and false otherwise.  The action
+   *         should be shown if it's both pinned and not disabled.
+   */
+  shouldShowInUrlbar(browserWindow) {
+    return this.pinnedToUrlbar && !this.getDisabled(browserWindow);
+  },
+
+  get _isBuiltIn() {
+    let builtInIDs = [
+      "pocket",
+      "screenshots",
+      "webcompat-reporter-button",
+    ].concat(gBuiltInActions.filter(a => !a.__isSeparator).map(a => a.id));
+    return builtInIDs.includes(this.id);
+  },
 };
 
 this.PageActions.Action = Action;
 
 
 /**
  * A Subview represents a PanelUI panelview that your actions can show.
  * `options` is a required object with the following properties.
@@ -1141,17 +1175,17 @@ var gBuiltInActions = [
   // bookmark
   {
     id: ACTION_ID_BOOKMARK,
     urlbarIDOverride: "star-button-box",
     _urlbarNodeInMarkup: true,
     // The title is set in browser-pageActions.js by calling
     // BookmarkingUI.updateBookmarkPageMenuItem().
     title: "",
-    shownInUrlbar: true,
+    pinnedToUrlbar: true,
     nodeAttributes: {
       observes: "bookmarkThisPageBroadcaster",
     },
     onShowingInPanel(buttonNode) {
       browserPageActions(buttonNode).bookmark.onShowingInPanel(buttonNode);
     },
     onCommand(event, buttonNode) {
       browserPageActions(buttonNode).bookmark.onCommand(event, buttonNode);
--- a/browser/modules/PluginContent.jsm
+++ b/browser/modules/PluginContent.jsm
@@ -25,19 +25,24 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 
 this.PluginContent = function(global) {
   this.init(global);
 };
 
 const FLASH_MIME_TYPE = "application/x-shockwave-flash";
 const REPLACEMENT_STYLE_SHEET = Services.io.newURI("chrome://pluginproblem/content/pluginReplaceBinding.css");
 
-const OVERLAY_DISPLAY_HIDDEN = 0;
-const OVERLAY_DISPLAY_VISIBLE = 1;
-const OVERLAY_DISPLAY_MINIMAL = 2;
+const OVERLAY_DISPLAY = {
+  HIDDEN: 0, // The overlay will be transparent
+  BLANK: 1, // The overlay will be just a grey box
+  TINY: 2, // The overlay with a 16x16 plugin icon
+  REDUCED: 3, // The overlay with a 32x32 plugin icon
+  NOTEXT: 4, // The overlay with a 48x48 plugin icon and the close button
+  FULL: 5, // The full overlay: 48x48 plugin icon, close button and label
+};
 
 PluginContent.prototype = {
   init(global) {
     this.global = global;
     // Need to hold onto the content window or else it'll get destroyed
     this.content = this.global.content;
     // Cache of plugin actions for the current page.
     this.pluginData = new Map();
@@ -284,54 +289,90 @@ PluginContent.prototype = {
              blocklistState,
            };
   },
 
   /**
    * Update the visibility of the plugin overlay.
    */
   setVisibility(plugin, overlay, overlayDisplayState) {
-    overlay.classList.toggle("visible", overlayDisplayState != OVERLAY_DISPLAY_HIDDEN);
-    overlay.classList.toggle("minimal", overlayDisplayState == OVERLAY_DISPLAY_MINIMAL)
-    if (overlayDisplayState == OVERLAY_DISPLAY_VISIBLE) {
+    overlay.classList.toggle("visible", overlayDisplayState != OVERLAY_DISPLAY.HIDDEN);
+    if (overlayDisplayState != OVERLAY_DISPLAY.HIDDEN) {
       overlay.removeAttribute("dismissed");
     }
   },
 
   /**
-   * Check whether the plugin should be visible on the page. A plugin should
-   * not be visible if the overlay is too big, or if any other page content
-   * overlays it.
+   * Adjust the style in which the overlay will be displayed. It might be adjusted
+   * based on its size, or if there's some other element covering all corners of
+   * the overlay.
    *
-   * This function will handle showing or hiding the overlay.
-   * @returns true if the plugin is invisible.
+   * This function will handle adjusting the style of the overlay, but will
+   * not handle hiding it. That is done by setVisibility with the return value
+   * from this function.
+   *
+   * @returns A value from OVERLAY_DISPLAY.
    */
-  computeOverlayDisplayState(plugin, overlay) {
+  computeAndAdjustOverlayDisplay(plugin, overlay) {
     let fallbackType = plugin.pluginFallbackType;
     if (plugin.pluginFallbackTypeOverride !== undefined) {
       fallbackType = plugin.pluginFallbackTypeOverride;
     }
     if (fallbackType == Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY_QUIET) {
-      return OVERLAY_DISPLAY_HIDDEN;
+      return OVERLAY_DISPLAY.HIDDEN;
     }
 
     // If the overlay size is 0, we haven't done layout yet. Presume that
     // plugins are visible until we know otherwise.
     if (overlay.scrollWidth == 0) {
-      return OVERLAY_DISPLAY_VISIBLE;
+      return OVERLAY_DISPLAY.FULL;
     }
 
+    let overlayDisplay = OVERLAY_DISPLAY.FULL;
+
     // Is the <object>'s size too small to hold what we want to show?
     let pluginRect = plugin.getBoundingClientRect();
+    let pluginWidth = Math.ceil(pluginRect.width);
+    let pluginHeight = Math.ceil(pluginRect.height);
+
+    // We must set the attributes while here inside this function in order
+    // for a possible re-style to occur, which will make the scrollWidth/Height
+    // checks below correct. Otherwise, we would be requesting e.g. a TINY
+    // overlay here, but the default styling would be used, and that would make
+    // it overflow, causing it to change to BLANK instead of remaining as TINY.
+
+    if (pluginWidth <= 32 || pluginHeight <= 32) {
+      overlay.setAttribute("sizing", "blank");
+      overlayDisplay = OVERLAY_DISPLAY.BLANK;
+    } else if (pluginWidth <= 80 || pluginHeight <= 60) {
+      overlayDisplay = OVERLAY_DISPLAY.TINY;
+      overlay.setAttribute("sizing", "tiny");
+      overlay.setAttribute("notext", "notext");
+    } else if (pluginWidth <= 120 || pluginHeight <= 80) {
+      overlayDisplay = OVERLAY_DISPLAY.REDUCED;
+      overlay.setAttribute("sizing", "reduced");
+      overlay.setAttribute("notext", "notext");
+    } else if (pluginWidth <= 240 || pluginHeight <= 160) {
+      overlayDisplay = OVERLAY_DISPLAY.NOTEXT;
+      overlay.removeAttribute("sizing");
+      overlay.setAttribute("notext", "notext");
+    } else {
+      overlayDisplay = OVERLAY_DISPLAY.FULL;
+      overlay.removeAttribute("sizing");
+      overlay.removeAttribute("notext");
+    }
+
+
     // XXX bug 446693. The text-shadow on the submitted-report text at
     //     the bottom causes scrollHeight to be larger than it should be.
-    let overflows = (overlay.scrollWidth > Math.ceil(pluginRect.width)) ||
-                    (overlay.scrollHeight - 5 > Math.ceil(pluginRect.height));
+    let overflows = (overlay.scrollWidth > pluginWidth) ||
+                    (overlay.scrollHeight - 5 > pluginHeight);
     if (overflows) {
-      return OVERLAY_DISPLAY_MINIMAL;
+      overlay.setAttribute("sizing", "blank");
+      return OVERLAY_DISPLAY.BLANK;
     }
 
     // Is the plugin covered up by other content so that it is not clickable?
     // Floating point can confuse .elementFromPoint, so inset just a bit
     let left = pluginRect.left + 2;
     let right = pluginRect.right - 2;
     let top = pluginRect.top + 2;
     let bottom = pluginRect.bottom - 2;
@@ -348,21 +389,22 @@ PluginContent.prototype = {
                            .getInterface(Ci.nsIDOMWindowUtils);
 
     for (let [x, y] of points) {
       if (x < 0 || y < 0) {
         continue;
       }
       let el = cwu.elementFromPoint(x, y, true, true);
       if (el === plugin) {
-        return OVERLAY_DISPLAY_VISIBLE;
+        return overlayDisplay;
       }
     }
 
-    return OVERLAY_DISPLAY_HIDDEN;
+    overlay.setAttribute("sizing", "blank");
+    return OVERLAY_DISPLAY.BLANK;
   },
 
   addLinkClickCallback(linkNode, callbackName /* callbackArgs...*/) {
     // XXX just doing (callback)(arg) was giving a same-origin error. bug?
     let self = this;
     let callbackArgs = Array.prototype.slice.call(arguments).slice(2);
     linkNode.addEventListener("click",
                               function(evt) {
@@ -471,17 +513,17 @@ PluginContent.prototype = {
       }
     }
 
     let plugin = event.target;
 
     if (eventType == "PluginPlaceholderReplaced") {
       plugin.removeAttribute("href");
       let overlay = this.getPluginUI(plugin, "main");
-      this.setVisibility(plugin, overlay, OVERLAY_DISPLAY_VISIBLE);
+      this.setVisibility(plugin, overlay, OVERLAY_DISPLAY.FULL);
       let inIDOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"]
                           .getService(Ci.inIDOMUtils);
       // Add psuedo class so our styling will take effect
       inIDOMUtils.addPseudoClassLock(plugin, "-moz-handler-clicktoplay");
       overlay.addEventListener("click", this, true);
       return;
     }
 
@@ -556,20 +598,20 @@ PluginContent.prototype = {
         break;
     }
 
     // Show the in-content UI if it's not too big. The crashed plugin handler already did this.
     let overlay = this.getPluginUI(plugin, "main");
     if (eventType != "PluginCrashed") {
       if (overlay != null) {
         this.setVisibility(plugin, overlay,
-                           this.computeOverlayDisplayState(plugin, overlay));
+                           this.computeAndAdjustOverlayDisplay(plugin, overlay));
         let resizeListener = () => {
           this.setVisibility(plugin, overlay,
-            this.computeOverlayDisplayState(plugin, overlay));
+            this.computeAndAdjustOverlayDisplay(plugin, overlay));
           this.updateNotificationUI();
         };
         plugin.addEventListener("overflow", resizeListener);
         plugin.addEventListener("underflow", resizeListener);
       }
     }
 
     let closeIcon = this.getPluginUI(plugin, "closeIcon");
@@ -898,19 +940,19 @@ PluginContent.prototype = {
           fallbackType != Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE &&
           fallbackType != Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE) {
         continue;
       }
       let overlay = this.getPluginUI(plugin, "main");
       if (!overlay) {
         continue;
       }
-      let overlayDisplayState = this.computeOverlayDisplayState(plugin, overlay);
+      let overlayDisplayState = this.computeAndAdjustOverlayDisplay(plugin, overlay);
       this.setVisibility(plugin, overlay, overlayDisplayState);
-      if (overlayDisplayState == OVERLAY_DISPLAY_VISIBLE) {
+      if (overlayDisplayState > OVERLAY_DISPLAY.BLANK) {
         actions.delete(info.permissionString);
         if (actions.size == 0) {
           break;
         }
       }
     }
 
     // If there are any items remaining in `actions` now, they are hidden
@@ -1084,31 +1126,31 @@ PluginContent.prototype = {
     this.addLinkClickCallback(helpIcon, "openHelpPage");
 
     let crashText = this.getPluginUI(plugin, "crashedText");
     crashText.textContent = message;
 
     let link = this.getPluginUI(plugin, "reloadLink");
     this.addLinkClickCallback(link, "reloadPage");
 
-    let overlayDisplayState = this.computeOverlayDisplayState(plugin, overlay);
+    let overlayDisplayState = this.computeAndAdjustOverlayDisplay(plugin, overlay);
 
     // Is the <object>'s size too small to hold what we want to show?
-    if (overlayDisplayState != OVERLAY_DISPLAY_VISIBLE) {
+    if (overlayDisplayState != OVERLAY_DISPLAY.FULL) {
       // First try hiding the crash report submission UI.
       statusDiv.removeAttribute("status");
 
-      overlayDisplayState = this.computeOverlayDisplayState(plugin, overlay);
+      overlayDisplayState = this.computeAndAdjustOverlayDisplay(plugin, overlay);
     }
     this.setVisibility(plugin, overlay, overlayDisplayState);
 
     let doc = plugin.ownerDocument;
     let runID = plugin.runID;
 
-    if (overlayDisplayState == OVERLAY_DISPLAY_VISIBLE) {
+    if (overlayDisplayState == OVERLAY_DISPLAY.FULL) {
       // If a previous plugin on the page was too small and resulted in adding a
       // notification bar, then remove it because this plugin instance it big
       // enough to serve as in-content notification.
       this.hideNotificationBar("plugin-crashed");
       doc.mozNoPluginCrashedNotification = true;
 
       // Notify others that the crash reporter UI is now ready.
       // Currently, this event is only used by tests.
--- a/browser/modules/SitePermissions.jsm
+++ b/browser/modules/SitePermissions.jsm
@@ -621,17 +621,21 @@ var gPermissionObject = {
   },
 
   "focus-tab-by-prompt": {
     exactHostMatch: true,
     states: [ SitePermissions.UNKNOWN, SitePermissions.ALLOW ],
   },
   "persistent-storage": {
     exactHostMatch: true
-  }
+  },
+
+  "shortcuts": {
+    states: [ SitePermissions.ALLOW, SitePermissions.BLOCK ],
+  },
 };
 
 // Delete this entry while being pre-off
 // or the persistent-storage permission would appear in Page info's Permission section
 if (!Services.prefs.getBoolPref("browser.storageManager.enabled")) {
   delete gPermissionObject["persistent-storage"];
 }
 
--- a/browser/modules/test/browser/browser_PageActions.js
+++ b/browser/modules/test/browser/browser_PageActions.js
@@ -1,9 +1,8 @@
-/* eslint-disable mozilla/no-arbitrary-setTimeout */
 "use strict";
 
 // This is a test for PageActions.jsm, specifically the generalized parts that
 // add and remove page actions and toggle them in the urlbar.  This does not
 // test the built-in page actions; browser_page_action_menu.js does that.
 
 // Initialization.  Must run first.
 add_task(async function init() {
@@ -72,20 +71,24 @@ add_task(async function simple() {
       Assert.ok(buttonNode, "buttonNode should be non-null: " + buttonNode);
       Assert.equal(buttonNode.id, panelButtonID, "buttonNode.id");
     },
   }));
 
   Assert.equal(action.getIconURL(), iconURL, "iconURL");
   Assert.equal(action.id, id, "id");
   Assert.deepEqual(action.nodeAttributes, nodeAttributes, "nodeAttributes");
-  Assert.equal(action.shownInUrlbar, false, "shownInUrlbar");
+  Assert.equal(action.pinnedToUrlbar, false, "pinnedToUrlbar");
   Assert.equal(action.subview, null, "subview");
+  Assert.equal(action.getDisabled(), false, "disabled");
+  Assert.equal(action.getDisabled(window), false, "disabled in window");
   Assert.equal(action.getTitle(), title, "title");
+  Assert.equal(action.getTitle(window), title, "title in window");
   Assert.equal(action.getTooltip(), tooltip, "tooltip");
+  Assert.equal(action.getTooltip(window), tooltip, "tooltip in window");
   Assert.equal(action.urlbarIDOverride, null, "urlbarIDOverride");
   Assert.equal(action.wantsIframe, false, "wantsIframe");
 
   Assert.ok(!("__insertBeforeActionID" in action), "__insertBeforeActionID");
   Assert.ok(!("__isSeparator" in action), "__isSeparator");
   Assert.ok(!("__urlbarNodeInMarkup" in action), "__urlbarNodeInMarkup");
 
   Assert.equal(onPlacedInPanelCallCount, 1,
@@ -146,17 +149,17 @@ add_task(async function simple() {
   Assert.equal(onShowingInPanelCallCount, 1,
                "onShowingInPanelCallCount should be inc'ed");
   onCommandExpectedButtonID = panelButtonID;
   EventUtils.synthesizeMouseAtCenter(panelButtonNode, {});
   await promisePageActionPanelHidden();
   Assert.equal(onCommandCallCount, 1, "onCommandCallCount should be inc'ed");
 
   // Show the action's button in the urlbar.
-  action.shownInUrlbar = true;
+  action.pinnedToUrlbar = true;
   Assert.equal(onPlacedInUrlbarCallCount, 1,
                "onPlacedInUrlbarCallCount should be inc'ed");
   urlbarButtonNode = document.getElementById(urlbarButtonID);
   Assert.notEqual(urlbarButtonNode, null, "urlbarButtonNode");
   for (let name in action.nodeAttributes) {
     Assert.ok(urlbarButtonNode.hasAttribute(name), name,
               "Has attribute: " + name);
     Assert.equal(urlbarButtonNode.getAttribute(name),
@@ -167,29 +170,45 @@ add_task(async function simple() {
   // The button should have been inserted before the bookmark star.
   Assert.notEqual(urlbarButtonNode.nextSibling, null, "Should be a next node");
   Assert.equal(
     urlbarButtonNode.nextSibling.id,
     PageActions.actionForID(PageActions.ACTION_ID_BOOKMARK).urlbarIDOverride,
     "Next node should be the bookmark star"
   );
 
+  // Disable the action.  The button in the urlbar should be removed, and the
+  // button in the panel should be disabled.
+  action.setDisabled(true);
+  urlbarButtonNode = document.getElementById(urlbarButtonID);
+  Assert.equal(urlbarButtonNode, null, "urlbar button should be removed");
+  Assert.equal(panelButtonNode.disabled, true,
+               "panel button should be disabled");
+
+  // Enable the action.  The button in the urlbar should be added back, and the
+  // button in the panel should be enabled.
+  action.setDisabled(false);
+  urlbarButtonNode = document.getElementById(urlbarButtonID);
+  Assert.notEqual(urlbarButtonNode, null, "urlbar button should be added back");
+  Assert.equal(panelButtonNode.disabled, false,
+               "panel button should not be disabled");
+
   // Click the urlbar button.
   onCommandExpectedButtonID = urlbarButtonID;
   EventUtils.synthesizeMouseAtCenter(urlbarButtonNode, {});
   Assert.equal(onCommandCallCount, 2, "onCommandCallCount should be inc'ed");
 
   // Set a new title.
   let newTitle = title + " new title";
   action.setTitle(newTitle);
   Assert.equal(action.getTitle(), newTitle, "New title");
   Assert.equal(panelButtonNode.getAttribute("label"), action.getTitle(),
                "New label");
 
-  // Now that shownInUrlbar has been toggled, make sure that it sticks across
+  // Now that pinnedToUrlbar has been toggled, make sure that it sticks across
   // app restarts.  Simulate that by "unregistering" the action (not by removing
   // it, which is more permanent) and then registering it again.
 
   // unregister
   PageActions._actionsByID.delete(action.id);
   let index = PageActions._nonBuiltInActions.findIndex(a => a.id == action.id);
   Assert.ok(index >= 0, "Action should be in _nonBuiltInActions to begin with");
   PageActions._nonBuiltInActions.splice(index, 1);
@@ -197,20 +216,20 @@ add_task(async function simple() {
   // register again
   PageActions._registerAction(action);
 
   // check relevant properties
   Assert.ok(PageActions._persistedActions.ids.includes(action.id),
             "PageActions should have 'seen' the action");
   Assert.ok(PageActions._persistedActions.idsInUrlbar.includes(action.id),
             "idsInUrlbar should still include the action");
-  Assert.ok(action.shownInUrlbar,
-            "shownInUrlbar should still be true");
-  Assert.ok(action._shownInUrlbar,
-            "_shownInUrlbar should still be true, for good measure");
+  Assert.ok(action.pinnedToUrlbar,
+            "pinnedToUrlbar should still be true");
+  Assert.ok(action._pinnedToUrlbar,
+            "_pinnedToUrlbar should still be true, for good measure");
 
   // Remove the action.
   action.remove();
   panelButtonNode = document.getElementById(panelButtonID);
   Assert.equal(panelButtonNode, null, "panelButtonNode");
   urlbarButtonNode = document.getElementById(urlbarButtonID);
   Assert.equal(urlbarButtonNode, null, "urlbarButtonNode");
 
@@ -296,17 +315,17 @@ add_task(async function withSubview() {
         break;
       }
     }
   };
 
   let action = PageActions.addAction(new PageActions.Action({
     iconURL: "chrome://browser/skin/mail.svg",
     id,
-    shownInUrlbar: true,
+    pinnedToUrlbar: true,
     subview,
     title: "Test subview",
     onCommand(event, buttonNode) {
       onActionCommandCallCount++;
     },
     onPlacedInPanel(buttonNode) {
       onActionPlacedInPanelCallCount++;
       Assert.ok(buttonNode, "buttonNode should be non-null: " + buttonNode);
@@ -439,17 +458,17 @@ add_task(async function withIframe() {
   let onIframeShownCount = 0;
 
   let panelButtonID = BrowserPageActions.panelButtonNodeIDForActionID(id);
   let urlbarButtonID = BrowserPageActions.urlbarButtonNodeIDForActionID(id);
 
   let action = PageActions.addAction(new PageActions.Action({
     iconURL: "chrome://browser/skin/mail.svg",
     id,
-    shownInUrlbar: true,
+    pinnedToUrlbar: true,
     title: "Test iframe",
     wantsIframe: true,
     onCommand(event, buttonNode) {
       onCommandCallCount++;
     },
     onIframeShown(iframeNode, panelNode) {
       onIframeShownCount++;
       Assert.ok(iframeNode, "iframeNode should be non-null: " + iframeNode);
@@ -525,17 +544,17 @@ add_task(async function withIframe() {
   // action's urlbar button.
   aaPanel = document.getElementById(BrowserPageActions._activatedActionPanelID);
   Assert.notEqual(aaPanel, null, "aaPanel");
   Assert.equal(aaPanel.anchorNode.id, urlbarButtonID, "aaPanel.anchorNode.id");
   EventUtils.synthesizeMouseAtCenter(urlbarButtonNode, {});
   await promisePanelHidden(BrowserPageActions._activatedActionPanelID);
 
   // Hide the action's button in the urlbar.
-  action.shownInUrlbar = false;
+  action.pinnedToUrlbar = false;
   urlbarButtonNode = document.getElementById(urlbarButtonID);
   Assert.equal(urlbarButtonNode, null, "urlbarButtonNode");
 
   // Open the panel, click the action's button.
   await promisePageActionPanelOpen();
   EventUtils.synthesizeMouseAtCenter(panelButtonNode, {});
   await promisePanelShown(BrowserPageActions._activatedActionPanelID);
   Assert.equal(onCommandCallCount, 0, "onCommandCallCount should remain 0");
@@ -825,32 +844,32 @@ add_task(async function nonBuiltFirst() 
 
 // Makes sure that urlbar nodes appear in the correct order in a new window.
 add_task(async function urlbarOrderNewWindow() {
   // Make some new actions.
   let actions = [0, 1, 2].map(i => {
     return PageActions.addAction(new PageActions.Action({
       id: `test-urlbarOrderNewWindow-${i}`,
       title: `Test urlbarOrderNewWindow ${i}`,
-      shownInUrlbar: true,
+      pinnedToUrlbar: true,
     }));
   });
 
   // Make sure PageActions knows they're inserted before the bookmark action in
   // the urlbar.
   Assert.deepEqual(
     PageActions._persistedActions.idsInUrlbar.slice(
       PageActions._persistedActions.idsInUrlbar.length - (actions.length + 1)
     ),
     actions.map(a => a.id).concat([PageActions.ACTION_ID_BOOKMARK]),
     "PageActions._persistedActions.idsInUrlbar has new actions inserted"
   );
   Assert.deepEqual(
-    PageActions.actionsInUrlbar.slice(
-      PageActions.actionsInUrlbar.length - (actions.length + 1)
+    PageActions.actionsInUrlbar(window).slice(
+      PageActions.actionsInUrlbar(window).length - (actions.length + 1)
     ).map(a => a.id),
     actions.map(a => a.id).concat([PageActions.ACTION_ID_BOOKMARK]),
     "PageActions.actionsInUrlbar has new actions inserted"
   );
 
   // Reach into _persistedActions to move the new actions to the front of the
   // urlbar, same as if the user moved them.  That way we can test that insert-
   // before IDs are correctly non-null when the urlbar nodes are inserted in the
@@ -929,35 +948,35 @@ add_task(async function migrate1() {
     JSON.stringify(persisted)
   );
 
   // Migrate.
   PageActions._loadPersistedActions();
 
   Assert.equal(PageActions._persistedActions.version, 1, "Correct version");
 
-  // Need to set copyURL's _shownInUrlbar.  It won't be set since it's false by
+  // Need to set copyURL's _pinnedToUrlbar.  It won't be set since it's false by
   // default and we reached directly into persisted storage above.
-  PageActions.actionForID("copyURL")._shownInUrlbar = true;
+  PageActions.actionForID("copyURL")._pinnedToUrlbar = true;
 
   // expected order
   let orderedIDs = [
     "pocket",
     "copyURL",
     PageActions.ACTION_ID_BOOKMARK,
   ];
 
   // Check the ordering.
   Assert.deepEqual(
     PageActions._persistedActions.idsInUrlbar,
     orderedIDs,
     "PageActions._persistedActions.idsInUrlbar has right order"
   );
   Assert.deepEqual(
-    PageActions.actionsInUrlbar.map(a => a.id),
+    PageActions.actionsInUrlbar(window).map(a => a.id),
     orderedIDs,
     "PageActions.actionsInUrlbar has right order"
   );
 
   // Open a new window.
   let win = await BrowserTestUtils.openNewBrowserWindow();
   await BrowserTestUtils.openNewForegroundTab({
     gBrowser: win.gBrowser,
@@ -977,31 +996,33 @@ add_task(async function migrate1() {
     actualUrlbarNodeIDs,
     orderedIDs.map(id => win.BrowserPageActions.urlbarButtonNodeIDForActionID(id)),
     "Expected actions in new window's urlbar"
   );
 
   // Done, clean up.
   await BrowserTestUtils.closeWindow(win);
   Services.prefs.clearUserPref(PageActions.PREF_PERSISTED_ACTIONS);
-  PageActions.actionForID("copyURL").shownInUrlbar = false;
+  PageActions.actionForID("copyURL").pinnedToUrlbar = false;
 });
 
 
 // Opens a new browser window and makes sure per-window state works right.
 add_task(async function perWindowState() {
   // Add a test action.
   let title = "Test perWindowState";
   let action = PageActions.addAction(new PageActions.Action({
     iconURL: "chrome://browser/skin/mail.svg",
     id: "test-perWindowState",
-    shownInUrlbar: true,
+    pinnedToUrlbar: true,
     title,
   }));
 
+  let actionsInUrlbar = PageActions.actionsInUrlbar(window);
+
   // Open a new browser window and load an actionable page so that the action
   // shows up in it.
   let newWindow = await BrowserTestUtils.openNewBrowserWindow();
   await BrowserTestUtils.openNewForegroundTab({
     gBrowser: newWindow.gBrowser,
     url: "http://example.com/",
   });
 
@@ -1038,53 +1059,100 @@ add_task(async function perWindowState()
   // same in the old window.
   let panelButtonNode1 = document.getElementById(panelButtonID);
   Assert.equal(panelButtonNode1.getAttribute("label"), newGlobalTitle,
                "Panel button label in old window");
   let panelButtonNode2 = newWindow.document.getElementById(panelButtonID);
   Assert.equal(panelButtonNode2.getAttribute("label"), newPerWinTitle,
                "Panel button label in new window");
 
+  // Disable the action in the new window.
+  action.setDisabled(true, newWindow);
+  Assert.equal(action.getDisabled(), false,
+               "Disabled: global should remain false");
+  Assert.equal(action.getDisabled(window), false,
+               "Disabled: old window should remain false");
+  Assert.equal(action.getDisabled(newWindow), true,
+               "Disabled: new window should be true");
+
+  // Check PageActions.actionsInUrlbar for each window.
+  Assert.deepEqual(
+    PageActions.actionsInUrlbar(window).map(a => a.id),
+    actionsInUrlbar.map(a => a.id),
+    "PageActions.actionsInUrlbar: old window should have all actions in urlbar"
+  );
+  Assert.deepEqual(
+    PageActions.actionsInUrlbar(newWindow).map(a => a.id),
+    actionsInUrlbar.map(a => a.id).filter(id => id != action.id),
+    "PageActions.actionsInUrlbar: new window should have all actions in urlbar except the test action"
+  );
+
+  // Check the urlbar nodes for the old window.
+  let actualUrlbarNodeIDs = [];
+  for (let node = BrowserPageActions.mainButtonNode.nextSibling;
+       node;
+       node = node.nextSibling) {
+    actualUrlbarNodeIDs.push(node.id);
+  }
+  Assert.deepEqual(
+    actualUrlbarNodeIDs,
+    actionsInUrlbar.map(a => BrowserPageActions.urlbarButtonNodeIDForActionID(a.id)),
+    "Old window should have all nodes in urlbar"
+  );
+
+  // Check the urlbar nodes for the new window.
+  actualUrlbarNodeIDs = [];
+  for (let node = newWindow.BrowserPageActions.mainButtonNode.nextSibling;
+       node;
+       node = node.nextSibling) {
+    actualUrlbarNodeIDs.push(node.id);
+  }
+  Assert.deepEqual(
+    actualUrlbarNodeIDs,
+    actionsInUrlbar.filter(a => a.id != action.id).map(a => BrowserPageActions.urlbarButtonNodeIDForActionID(a.id)),
+    "New window should have all nodes in urlbar except for the test action's"
+  );
+
   // Done, clean up.
   await BrowserTestUtils.closeWindow(newWindow);
   action.remove();
 });
 
 
 // Adds an action, changes its placement in the urlbar to something non-default,
 // removes the action, and then adds it back.  Since the action was removed and
 // re-added without restarting the app (or more accurately without calling
 // PageActions._purgeUnregisteredPersistedActions), the action should remain in
 // persisted state and retain its last placement in the urlbar.
 add_task(async function removeRetainState() {
   // Get the list of actions initially in the urlbar.
-  let initialActionsInUrlbar = PageActions.actionsInUrlbar;
+  let initialActionsInUrlbar = PageActions.actionsInUrlbar(window);
   Assert.ok(initialActionsInUrlbar.length > 0,
             "This test expects there to be at least one action in the urlbar initially (like the bookmark star)");
 
   // Add a test action.
   let id = "test-removeRetainState";
   let testAction = PageActions.addAction(new PageActions.Action({
     id,
     title: "Test removeRetainState",
   }));
 
   // Show its button in the urlbar.
-  testAction.shownInUrlbar = true;
+  testAction.pinnedToUrlbar = true;
 
-  // "Move" the test action to the front of the urlbar by toggling shownInUrlbar
-  // for all the other actions in the urlbar.
+  // "Move" the test action to the front of the urlbar by toggling
+  // pinnedToUrlbar for all the other actions in the urlbar.
   for (let action of initialActionsInUrlbar) {
-    action.shownInUrlbar = false;
-    action.shownInUrlbar = true;
+    action.pinnedToUrlbar = false;
+    action.pinnedToUrlbar = true;
   }
 
   // Check the actions in PageActions.actionsInUrlbar.
   Assert.deepEqual(
-    PageActions.actionsInUrlbar.map(a => a.id),
+    PageActions.actionsInUrlbar(window).map(a => a.id),
     [testAction].concat(initialActionsInUrlbar).map(a => a.id),
     "PageActions.actionsInUrlbar should be in expected order: testAction followed by all initial actions"
   );
 
   // Check the nodes in the urlbar.
   let actualUrlbarNodeIDs = [];
   for (let node = BrowserPageActions.mainButtonNode.nextSibling;
        node;
@@ -1097,17 +1165,17 @@ add_task(async function removeRetainStat
     "urlbar nodes should be in expected order: testAction followed by all initial actions"
   );
 
   // Remove the test action.
   testAction.remove();
 
   // Check the actions in PageActions.actionsInUrlbar.
   Assert.deepEqual(
-    PageActions.actionsInUrlbar.map(a => a.id),
+    PageActions.actionsInUrlbar(window).map(a => a.id),
     initialActionsInUrlbar.map(a => a.id),
     "PageActions.actionsInUrlbar should be in expected order after removing test action: all initial actions"
   );
 
   // Check the nodes in the urlbar.
   actualUrlbarNodeIDs = [];
   for (let node = BrowserPageActions.mainButtonNode.nextSibling;
        node;
@@ -1122,21 +1190,21 @@ add_task(async function removeRetainStat
 
   // Add the test action again.
   testAction = PageActions.addAction(new PageActions.Action({
     id,
     title: "Test removeRetainState",
   }));
 
   // Show its button in the urlbar again.
-  testAction.shownInUrlbar = true;
+  testAction.pinnedToUrlbar = true;
 
   // Check the actions in PageActions.actionsInUrlbar.
   Assert.deepEqual(
-    PageActions.actionsInUrlbar.map(a => a.id),
+    PageActions.actionsInUrlbar(window).map(a => a.id),
     [testAction].concat(initialActionsInUrlbar).map(a => a.id),
     "PageActions.actionsInUrlbar should be in expected order after re-adding test action: testAction followed by all initial actions"
   );
 
   // Check the nodes in the urlbar.
   actualUrlbarNodeIDs = [];
   for (let node = BrowserPageActions.mainButtonNode.nextSibling;
        node;
@@ -1149,16 +1217,210 @@ add_task(async function removeRetainStat
     "urlbar nodes should be in expected order after re-adding test action: testAction followed by all initial actions"
   );
 
   // Done, clean up.
   testAction.remove();
 });
 
 
+// Opens the context menu on a non-built-in action.  (The context menu for
+// built-in actions is tested in browser_page_action_menu.js.)
+add_task(async function contextMenu() {
+  // Add a test action.
+  let action = PageActions.addAction(new PageActions.Action({
+    id: "test-contextMenu",
+    title: "Test contextMenu",
+    pinnedToUrlbar: true,
+  }));
+
+  // Open the panel and then open the context menu on the action's item.
+  await promisePageActionPanelOpen();
+  let panelButton = BrowserPageActions.panelButtonNodeForActionID(action.id);
+  let contextMenuPromise = promisePanelShown("pageActionContextMenu");
+  EventUtils.synthesizeMouseAtCenter(panelButton, {
+    type: "contextmenu",
+    button: 2,
+  });
+  await contextMenuPromise;
+
+  // The context menu should show the "don't show" item and the "manage" item.
+  // Click the "don't show" item.
+  let menuItems = collectContextMenuItems();
+  Assert.equal(menuItems.length, 3,
+               "Context menu has 3 children");
+  Assert.equal(menuItems[0].label, "Don\u2019t Show in Address Bar",
+               "Context menu is in the 'don't show' state");
+  Assert.equal(menuItems[1].localName, "menuseparator",
+               "menuseparator is present");
+  Assert.equal(menuItems[2].label, "Manage Extension\u2026",
+               "'Manage' item is present");
+  contextMenuPromise = promisePanelHidden("pageActionContextMenu");
+  EventUtils.synthesizeMouseAtCenter(menuItems[0], {});
+  await contextMenuPromise;
+
+  // The action should be removed from the urlbar.
+  await BrowserTestUtils.waitForCondition(() => {
+    return !BrowserPageActions.urlbarButtonNodeForActionID(action.id);
+  }, "Waiting for urlbar button to be removed");
+
+  // Open the context menu again on the action's button in the panel.  (The
+  // panel should still be open.)
+  contextMenuPromise = promisePanelShown("pageActionContextMenu");
+  EventUtils.synthesizeMouseAtCenter(panelButton, {
+    type: "contextmenu",
+    button: 2,
+  });
+  await contextMenuPromise;
+
+  // The context menu should show the "show" item and the "manage" item.  Click
+  // the "show" item.
+  menuItems = collectContextMenuItems();
+  Assert.equal(menuItems.length, 3,
+               "Context menu has 3 children");
+  Assert.equal(menuItems[0].label, "Show in Address Bar",
+               "Context menu is in the 'show' state");
+  Assert.equal(menuItems[1].localName, "menuseparator",
+               "menuseparator is present");
+  Assert.equal(menuItems[2].label, "Manage Extension\u2026",
+               "'Manage' item is present");
+  contextMenuPromise = promisePanelHidden("pageActionContextMenu");
+  EventUtils.synthesizeMouseAtCenter(menuItems[0], {});
+  await contextMenuPromise;
+
+  // The action should be added back to the urlbar.
+  await BrowserTestUtils.waitForCondition(() => {
+    return BrowserPageActions.urlbarButtonNodeForActionID(action.id);
+  }, "Waiting for urlbar button to be added back");
+
+  // Open the context menu again on the action's button in the panel.  (The
+  // panel should still be open.)
+  contextMenuPromise = promisePanelShown("pageActionContextMenu");
+  EventUtils.synthesizeMouseAtCenter(panelButton, {
+    type: "contextmenu",
+    button: 2,
+  });
+  await contextMenuPromise;
+
+  // The context menu should show the "don't show" item and the "manage" item.
+  // Click the "manage" item.  about:addons should open.
+  menuItems = collectContextMenuItems();
+  Assert.equal(menuItems.length, 3,
+               "Context menu has 3 children");
+  Assert.equal(menuItems[0].label, "Don\u2019t Show in Address Bar",
+               "Context menu is in the 'don't show' state");
+  Assert.equal(menuItems[1].localName, "menuseparator",
+               "menuseparator is present");
+  Assert.equal(menuItems[2].label, "Manage Extension\u2026",
+               "'Manage' item is present");
+  contextMenuPromise = promisePanelHidden("pageActionContextMenu");
+  let aboutAddonsPromise =
+    BrowserTestUtils.waitForNewTab(gBrowser, "about:addons");
+  EventUtils.synthesizeMouseAtCenter(menuItems[2], {});
+  let values = await Promise.all([aboutAddonsPromise, contextMenuPromise]);
+  let aboutAddonsTab = values[0];
+  await BrowserTestUtils.removeTab(aboutAddonsTab);
+
+  // Open the context menu on the action's urlbar button.
+  let urlbarButton = BrowserPageActions.urlbarButtonNodeForActionID(action.id);
+  contextMenuPromise = promisePanelShown("pageActionContextMenu");
+  EventUtils.synthesizeMouseAtCenter(urlbarButton, {
+    type: "contextmenu",
+    button: 2,
+  });
+  await contextMenuPromise;
+
+  // The context menu should show the "don't show" item and the "manage" item.
+  // Click the "don't show" item.
+  menuItems = collectContextMenuItems();
+  Assert.equal(menuItems.length, 3,
+               "Context menu has 3 children");
+  Assert.equal(menuItems[0].label, "Don\u2019t Show in Address Bar",
+               "Context menu is in the 'don't show' state");
+  Assert.equal(menuItems[1].localName, "menuseparator",
+               "menuseparator is present");
+  Assert.equal(menuItems[2].label, "Manage Extension\u2026",
+               "'Manage' item is present");
+  contextMenuPromise = promisePanelHidden("pageActionContextMenu");
+  EventUtils.synthesizeMouseAtCenter(menuItems[0], {});
+  await contextMenuPromise;
+
+  // The action should be removed from the urlbar.
+  await BrowserTestUtils.waitForCondition(() => {
+    return !BrowserPageActions.urlbarButtonNodeForActionID(action.id);
+  }, "Waiting for urlbar button to be removed");
+
+  // Open the panel and then open the context menu on the action's item.
+  await promisePageActionPanelOpen();
+  contextMenuPromise = promisePanelShown("pageActionContextMenu");
+  EventUtils.synthesizeMouseAtCenter(panelButton, {
+    type: "contextmenu",
+    button: 2,
+  });
+  await contextMenuPromise;
+
+  // The context menu should show the "show" item and the "manage" item.  Click
+  // the "show" item.
+  menuItems = collectContextMenuItems();
+  Assert.equal(menuItems.length, 3,
+               "Context menu has 3 children");
+  Assert.equal(menuItems[0].label, "Show in Address Bar",
+               "Context menu is in the 'show' state");
+  Assert.equal(menuItems[1].localName, "menuseparator",
+               "menuseparator is present");
+  Assert.equal(menuItems[2].label, "Manage Extension\u2026",
+               "'Manage' item is present");
+  contextMenuPromise = promisePanelHidden("pageActionContextMenu");
+  EventUtils.synthesizeMouseAtCenter(menuItems[0], {});
+  await contextMenuPromise;
+
+  // The action should be added back to the urlbar.
+  await BrowserTestUtils.waitForCondition(() => {
+    return BrowserPageActions.urlbarButtonNodeForActionID(action.id);
+  }, "Waiting for urlbar button to be added back");
+
+  // Open the context menu on the action's urlbar button.
+  urlbarButton = BrowserPageActions.urlbarButtonNodeForActionID(action.id);
+  contextMenuPromise = promisePanelShown("pageActionContextMenu");
+  EventUtils.synthesizeMouseAtCenter(urlbarButton, {
+    type: "contextmenu",
+    button: 2,
+  });
+  await contextMenuPromise;
+
+  // The context menu should show the "don't show" item and the "manage" item.
+  // Click the "manage" item.  about:addons should open.
+  menuItems = collectContextMenuItems();
+  Assert.equal(menuItems.length, 3,
+               "Context menu has 3 children");
+  Assert.equal(menuItems[0].label, "Don\u2019t Show in Address Bar",
+               "Context menu is in the 'don't show' state");
+  Assert.equal(menuItems[1].localName, "menuseparator",
+               "menuseparator is present");
+  Assert.equal(menuItems[2].label, "Manage Extension\u2026",
+               "'Manage' item is present");
+  contextMenuPromise = promisePanelHidden("pageActionContextMenu");
+  aboutAddonsPromise =
+    BrowserTestUtils.waitForNewTab(gBrowser, "about:addons");
+  EventUtils.synthesizeMouseAtCenter(menuItems[2], {});
+  values = await Promise.all([aboutAddonsPromise, contextMenuPromise]);
+  aboutAddonsTab = values[0];
+  await BrowserTestUtils.removeTab(aboutAddonsTab);
+
+  // Done, clean up.
+  action.remove();
+
+  // urlbar tests that run after this one can break if the mouse is left over
+  // the area where the urlbar popup appears, which seems to happen due to the
+  // above synthesized mouse events.  Move it over the urlbar.
+  EventUtils.synthesizeMouseAtCenter(gURLBar, { type: "mousemove" });
+  gURLBar.focus();
+});
+
+
 function promisePageActionPanelOpen() {
   let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor)
                   .getInterface(Ci.nsIDOMWindowUtils);
   return BrowserTestUtils.waitForCondition(() => {
     // Wait for the main page action button to become visible.  It's hidden for
     // some URIs, so depending on when this is called, it may not yet be quite
     // visible.  It's up to the caller to make sure it will be visible.
     info("Waiting for main page action button to have non-0 size");
@@ -1230,8 +1492,15 @@ function promisePageActionViewChildrenVi
       let bounds = dwu.getBoundsWithoutFlushing(childNode);
       if (bounds.width > 0 && bounds.height > 0) {
         return true;
       }
     }
     return false;
   });
 }
+
+function collectContextMenuItems() {
+  let contextMenu = document.getElementById("pageActionContextMenu");
+  return Array.filter(contextMenu.childNodes, node => {
+    return window.getComputedStyle(node).visibility == "visible";
+  });
+}
--- a/browser/modules/test/browser/browser_SitePermissions.js
+++ b/browser/modules/test/browser/browser_SitePermissions.js
@@ -20,20 +20,23 @@ add_task(async function testTempAllowThr
 });
 
 // This tests the SitePermissions.getAllPermissionDetailsForBrowser function.
 add_task(async function testGetAllPermissionDetailsForBrowser() {
   let uri = Services.io.newURI("https://example.com");
 
   let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, uri.spec);
 
+  Services.prefs.setIntPref("permissions.default.shortcuts", 2);
+
   SitePermissions.set(uri, "camera", SitePermissions.ALLOW);
   SitePermissions.set(uri, "cookie", SitePermissions.ALLOW_COOKIES_FOR_SESSION);
   SitePermissions.set(uri, "popup", SitePermissions.BLOCK);
   SitePermissions.set(uri, "geo", SitePermissions.ALLOW, SitePermissions.SCOPE_SESSION);
+  SitePermissions.set(uri, "shortcuts", SitePermissions.ALLOW);
 
   let permissions = SitePermissions.getAllPermissionDetailsForBrowser(tab.linkedBrowser);
 
   let camera = permissions.find(({id}) => id === "camera");
   Assert.deepEqual(camera, {
     id: "camera",
     label: "Use the Camera",
     state: SitePermissions.ALLOW,
@@ -66,15 +69,26 @@ add_task(async function testGetAllPermis
   let geo = permissions.find(({id}) => id === "geo");
   Assert.deepEqual(geo, {
     id: "geo",
     label: "Access Your Location",
     state: SitePermissions.ALLOW,
     scope: SitePermissions.SCOPE_SESSION,
   });
 
+  let shortcuts = permissions.find(({id}) => id === "shortcuts");
+  Assert.deepEqual(shortcuts, {
+    id: "shortcuts",
+    label: "Override Keyboard Shortcuts",
+    state: SitePermissions.ALLOW,
+    scope: SitePermissions.SCOPE_PERSISTENT,
+  });
+
   SitePermissions.remove(uri, "cookie");
   SitePermissions.remove(uri, "popup");
   SitePermissions.remove(uri, "geo");
+  SitePermissions.remove(uri, "shortcuts");
+
+  Services.prefs.clearUserPref("permissions.default.shortcuts");
 
   await BrowserTestUtils.removeTab(gBrowser.selectedTab);
 });
 
--- a/browser/modules/test/unit/test_SitePermissions.js
+++ b/browser/modules/test/unit/test_SitePermissions.js
@@ -5,17 +5,17 @@
 
 Components.utils.import("resource:///modules/SitePermissions.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 const STORAGE_MANAGER_ENABLED = Services.prefs.getBoolPref("browser.storageManager.enabled");
 
 add_task(async function testPermissionsListing() {
   let expectedPermissions = ["camera", "cookie", "desktop-notification", "focus-tab-by-prompt",
-     "geo", "image", "install", "microphone", "popup", "screen"];
+     "geo", "image", "install", "microphone", "popup", "screen", "shortcuts"];
   if (STORAGE_MANAGER_ENABLED) {
     // The persistent-storage permission is still only pref-on on Nightly
     // so we add it only when it's pref-on.
     // Should remove this checking and add it as default after it is fully pref-on.
     expectedPermissions.push("persistent-storage");
   }
   Assert.deepEqual(SitePermissions.listPermissions().sort(), expectedPermissions.sort(),
     "Correct list of all permissions");
@@ -53,16 +53,28 @@ add_task(async function testGetAllByURI(
   SitePermissions.remove(uri, "camera");
   SitePermissions.remove(uri, "desktop-notification");
   Assert.deepEqual(SitePermissions.getAllByURI(uri), []);
 
   // XXX Bug 1303108 - Control Center should only show non-default permissions
   SitePermissions.set(uri, "addon", SitePermissions.BLOCK);
   Assert.deepEqual(SitePermissions.getAllByURI(uri), []);
   SitePermissions.remove(uri, "addon");
+
+  Assert.equal(Services.prefs.getIntPref("permissions.default.shortcuts"), 0);
+  SitePermissions.set(uri, "shortcuts", SitePermissions.BLOCK);
+
+  // Customized preference should have been enabled, but the default should not.
+  Assert.equal(Services.prefs.getIntPref("permissions.default.shortcuts"), 0);
+  Assert.deepEqual(SitePermissions.getAllByURI(uri), [
+      { id: "shortcuts", state: SitePermissions.BLOCK, scope: SitePermissions.SCOPE_PERSISTENT },
+  ]);
+
+  SitePermissions.remove(uri, "shortcuts");
+  Services.prefs.clearUserPref("permissions.default.shortcuts");
 });
 
 add_task(async function testGetAvailableStates() {
   Assert.deepEqual(SitePermissions.getAvailableStates("camera"),
                    [ SitePermissions.UNKNOWN,
                      SitePermissions.ALLOW,
                      SitePermissions.BLOCK ]);
 
@@ -91,17 +103,17 @@ add_task(async function testExactHostMat
   let exactHostMatched = ["desktop-notification", "focus-tab-by-prompt", "camera",
                           "microphone", "screen", "geo"];
   if (STORAGE_MANAGER_ENABLED) {
     // The persistent-storage permission is still only pref-on on Nightly
     // so we add it only when it's pref-on.
     // Should remove this checking and add it as default after it is fully pref-on.
     exactHostMatched.push("persistent-storage");
   }
-  let nonExactHostMatched = ["image", "cookie", "popup", "install"];
+  let nonExactHostMatched = ["image", "cookie", "popup", "install", "shortcuts"];
 
   let permissions = SitePermissions.listPermissions();
   for (let permission of permissions) {
     SitePermissions.set(uri, permission, SitePermissions.ALLOW);
 
     if (exactHostMatched.includes(permission)) {
       // Check that the sub-origin does not inherit the permission from its parent.
       Assert.equal(SitePermissions.get(subUri, permission).state, SitePermissions.UNKNOWN,
--- a/browser/moz.build
+++ b/browser/moz.build
@@ -35,16 +35,34 @@ export('DIST_SUBDIR')
 
 if CONFIG['MOZ_ARTIFACT_BUILDS']:
     # Ensure a pre-built interfaces.xpt installed to the objdir by the artifact
     # code is included by the top-level chrome.manifest.
     EXTRA_COMPONENTS += [
         '../build/prebuilt-interfaces.manifest',
     ]
 
+
+# These defines are read in firefox.js
+DEFINES['APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
+
+for cdm in CONFIG['MOZ_EME_MODULES']:
+    DEFINES['MOZ_%s_EME' % cdm.upper()] = True
+
+if CONFIG['MOZ_GPSD']:
+    DEFINES['MOZ_GPSD'] = True
+
+# These files are specified in this moz.build to pick up DIST_SUBDIR as set in
+# this directory, which is un-set in browser/app.
+JS_PREFERENCE_PP_FILES += [
+    'app/profile/firefox.js',
+]
+FINAL_TARGET_FILES += ['app/blocklist.xml']
+FINAL_TARGET_FILES.defaults += ['app/permissions']
+
 with Files("**"):
     BUG_COMPONENT = ("Firefox", "General")
 
 with Files("Makefile.in"):
     BUG_COMPONENT = ("Core", "Build Config")
 
 with Files("*.mk"):
     BUG_COMPONENT = ("Core", "Build Config")
--- a/browser/themes/shared/incontentprefs/preferences.inc.css
+++ b/browser/themes/shared/incontentprefs/preferences.inc.css
@@ -659,16 +659,17 @@ button > hbox > label {
 }
 
 .help-icon:hover {
   fill: currentColor !important;
 }
 
 .help-label {
   margin: 0 4px;
+  line-height: 22px;
   -moz-user-select: none;
 }
 
 @media (max-width: 830px) {
   .help-button > .text-link {
     -moz-box-flex: 0;
     width: 36px;
     height: 36px;
--- a/browser/themes/shared/jar.inc.mn
+++ b/browser/themes/shared/jar.inc.mn
@@ -63,18 +63,16 @@
   skin/classic/browser/notification-icons/login-detailed.svg                (../shared/notification-icons/login-detailed.svg)
   skin/classic/browser/notification-icons/login.svg                         (../shared/notification-icons/login.svg)
   skin/classic/browser/notification-icons/microphone-blocked.svg            (../shared/notification-icons/microphone-blocked.svg)
   skin/classic/browser/notification-icons/microphone-detailed.svg           (../shared/notification-icons/microphone-detailed.svg)
   skin/classic/browser/notification-icons/microphone.svg                    (../shared/notification-icons/microphone.svg)
   skin/classic/browser/notification-icons/persistent-storage-blocked.svg    (../shared/notification-icons/persistent-storage-blocked.svg)
   skin/classic/browser/notification-icons/persistent-storage.svg            (../shared/notification-icons/persistent-storage.svg)
   skin/classic/browser/notification-icons/plugin-badge.svg                  (../shared/notification-icons/plugin-badge.svg)
-  skin/classic/browser/notification-icons/plugin-blocked.svg                (../shared/notification-icons/plugin-blocked.svg)
-  skin/classic/browser/notification-icons/plugin.svg                        (../shared/notification-icons/plugin.svg)
   skin/classic/browser/notification-icons/popup.svg                         (../shared/notification-icons/popup.svg)
   skin/classic/browser/notification-icons/popup-subitem.svg                 (../shared/notification-icons/popup-subitem.svg)
   skin/classic/browser/notification-icons/screen-blocked.svg                (../shared/notification-icons/screen-blocked.svg)
   skin/classic/browser/notification-icons/screen.svg                        (../shared/notification-icons/screen.svg)
   skin/classic/browser/notification-icons/update.svg                        (../shared/notification-icons/update.svg)
 
   skin/classic/browser/tracking-protection-16.svg              (../shared/identity-block/tracking-protection-16.svg)
   skin/classic/browser/newtab/close.png                        (../shared/newtab/close.png)
--- a/browser/themes/shared/notification-icons.inc.css
+++ b/browser/themes/shared/notification-icons.inc.css
@@ -218,22 +218,22 @@ html|*#webRTC-previewVideo {
 .popup-notification-icon[popupid*="offline-app-requested"],
 .popup-notification-icon[popupid="offline-app-usage"] {
   list-style-image: url(chrome://global/skin/icons/question-64.png);
 }
 
 /* PLUGINS */
 
 .plugin-icon {
-  list-style-image: url(chrome://browser/skin/notification-icons/plugin.svg);
+  list-style-image: url(chrome://mozapps/skin/plugins/plugin.svg);
   transition: fill 1.5s;
 }
 
 .plugin-blocked-icon {
-  list-style-image: url(chrome://browser/skin/notification-icons/plugin-blocked.svg);
+  list-style-image: url(chrome://mozapps/skin/plugins/plugin-blocked.svg);
   transition: fill 1.5s;
 }
 
 #plugin-icon-badge {
   list-style-image: url(chrome://browser/skin/notification-icons/plugin-badge.svg);
   opacity: 0;
   transition: opacity 1.5s;
 }
@@ -255,17 +255,17 @@ html|*#webRTC-previewVideo {
     opacity: 0;
   }
   to {
     opacity: 1;
   }
 }
 
 .plugin-blocked > .plugin-icon {
-  list-style-image: url(chrome://browser/skin/notification-icons/plugin-blocked.svg);
+  list-style-image: url(chrome://mozapps/skin/plugins/plugin-blocked.svg);
   fill: #d92215 !important;
 }
 
 .plugin-blocked > #plugin-icon-badge {
   visibility: collapse;
 }
 
 #notification-popup-box[hidden] {
--- a/browser/themes/shared/plugin-doorhanger.inc.css
+++ b/browser/themes/shared/plugin-doorhanger.inc.css
@@ -1,14 +1,14 @@
 .messageImage[value="plugin-hidden"] {
-  list-style-image: url(chrome://browser/skin/notification-icons/plugin.svg);
+  list-style-image: url(chrome://mozapps/skin/plugins/plugin.svg);
 }
 
 /* Keep any changes to this style in sync with pluginProblem.css */
 notification.pluginVulnerable {
   background-color: rgb(72,72,72);
   background-image: url(chrome://mozapps/skin/plugins/contentPluginStripe.png);
   color: white;
 }
 
 notification.pluginVulnerable .messageImage {
-  list-style-image: url(chrome://browser/skin/notification-icons/plugin-blocked.svg);
+  list-style-image: url(chrome://mozapps/skin/plugins/plugin-blocked.svg);
 }
--- a/browser/themes/shared/urlbar-searchbar.inc.css
+++ b/browser/themes/shared/urlbar-searchbar.inc.css
@@ -64,16 +64,20 @@
   min-height: 32px;
 }
 
 :root[chromehidden~="toolbar"] #urlbar {
   /* Remove excess space between the address bar and the menu button in popups. */
   margin-inline-end: 0;
 }
 
+:root[customizing] .urlbar-input-box {
+  visibility: hidden;
+}
+
 #urlbar-container {
   -moz-box-align: center;
 }
 
 #urlbar-search-splitter {
   /* The splitter width should equal the location and search bars' combined
      neighboring margin and border width. */
   min-width: 12px;
--- a/build/autoconf/config.status.m4
+++ b/build/autoconf/config.status.m4
@@ -7,48 +7,67 @@ define([MOZ_DIVERSION_SUBST], 11)
 
 dnl Replace AC_SUBST to store values in a format suitable for python.
 dnl The necessary comma after the tuple can't be put here because it
 dnl can mess around with things like:
 dnl    AC_SOMETHING(foo,AC_SUBST(),bar)
 define([AC_SUBST],
 [ifdef([AC_SUBST_SET_$1], [m4_fatal([Cannot use AC_SUBST and AC_SUBST_SET on the same variable ($1)])],
 [ifdef([AC_SUBST_LIST_$1], [m4_fatal([Cannot use AC_SUBST and AC_SUBST_LIST on the same variable ($1)])],
+[ifdef([AC_SUBST_TOML_LIST_$1], [m4_fatal([Cannot use AC_SUBST and AC_SUBST_TOML_LIST on the same variable ($1)])],
 [ifdef([AC_SUBST_$1], ,
 [define([AC_SUBST_$1], )dnl
 AC_DIVERT_PUSH(MOZ_DIVERSION_SUBST)dnl
     (''' $1 ''', r''' [$]$1 ''')
 AC_DIVERT_POP()dnl
-])])])])
+])])])])])
 
 dnl Like AC_SUBST, but makes the value available as a set in python,
 dnl with values got from the value of the environment variable, split on
 dnl whitespaces.
 define([AC_SUBST_SET],
 [ifdef([AC_SUBST_$1], [m4_fatal([Cannot use AC_SUBST and AC_SUBST_SET on the same variable ($1)])],
-[ifdef([AC_SUBST_LIST$1], [m4_fatal([Cannot use AC_SUBST_LIST and AC_SUBST_SET on the same variable ($1)])],
+[ifdef([AC_SUBST_LIST_$1], [m4_fatal([Cannot use AC_SUBST_LIST and AC_SUBST_SET on the same variable ($1)])],
+[ifdef([AC_SUBST_TOML_LIST_$1], [m4_fatal([Cannot use AC_SUBST_TOML_LIST and AC_SUBST_SET on the same variable ($1)])],
 [ifdef([AC_SUBST_SET_$1], ,
 [define([AC_SUBST_SET_$1], )dnl
 AC_DIVERT_PUSH(MOZ_DIVERSION_SUBST)dnl
     (''' $1 ''', unique_list(split(r''' [$]$1 ''')))
 AC_DIVERT_POP()dnl
-])])])])
+])])])])])
 
 dnl Like AC_SUBST, but makes the value available as a list in python,
 dnl with values got from the value of the environment variable, split on
 dnl whitespaces.
 define([AC_SUBST_LIST],
 [ifdef([AC_SUBST_$1], [m4_fatal([Cannot use AC_SUBST and AC_SUBST_LIST on the same variable ($1)])],
 [ifdef([AC_SUBST_SET_$1], [m4_fatal([Cannot use AC_SUBST_SET and AC_SUBST_LIST on the same variable ($1)])],
+[ifdef([AC_SUBST_TOML_LIST_$1], [m4_fatal([Cannot use AC_SUBST_TOML_LIST and AC_SUBST_LIST on the same variable ($1)])],
 [ifdef([AC_SUBST_LIST_$1], ,
 [define([AC_SUBST_LIST_$1], )dnl
 AC_DIVERT_PUSH(MOZ_DIVERSION_SUBST)dnl
     (''' $1 ''', list(split(r''' [$]$1 ''')))
 AC_DIVERT_POP()dnl
-])])])])
+])])])])])
+
+dnl Like AC_SUBST, but makes the value available as a string of comma-separated
+dnl quoted strings in python, with values got from the value of the environment
+dnl variable, split on whitespaces. The value is suitable for embedding into a
+dnl .toml list.
+define([AC_SUBST_TOML_LIST],
+[ifdef([AC_SUBST_$1], [m4_fatal([Cannot use AC_SUBST and AC_SUBST_TOML_LIST on the same variable ($1)])],
+[ifdef([AC_SUBST_SET_$1], [m4_fatal([Cannot use AC_SUBST_SET and AC_SUBST_TOML_LIST on the same variable ($1)])],
+[ifdef([AC_SUBST_LIST_$1], [m4_fatal([Cannot use AC_SUBST_LIST and AC_SUBST_TOML_LIST on the same variable ($1)])],
+[ifdef([AC_SUBST_TOML_LIST_$1], ,
+[define([AC_SUBST_TOML_LIST_$1], )dnl
+AC_DIVERT_PUSH(MOZ_DIVERSION_SUBST)dnl
+    (''' $1 ''', r''' %s ''' % str(', '.join("'%s'" % s for s in split(r''' [$]$1 '''))))
+AC_DIVERT_POP()dnl
+])])])])])
+
 
 dnl Ignore AC_SUBSTs for variables we don't have use for but that autoconf
 dnl itself exports.
 define([AC_SUBST_CFLAGS], )
 define([AC_SUBST_CPPFLAGS], )
 define([AC_SUBST_CXXFLAGS], )
 define([AC_SUBST_FFLAGS], )
 define([AC_SUBST_DEFS], )
--- a/build/build-clang/clang-win32.json
+++ b/build/build-clang/clang-win32.json
@@ -8,11 +8,16 @@
     "clang_repo": "https://llvm.org/svn/llvm-project/cfe/trunk",
     "compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/trunk",
     "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/trunk",
     "python_path": "c:/mozilla-build/python/python.exe",
     "cc": "cl.exe",
     "cxx": "cl.exe",
     "patches": [
       "msvc-host-x64.patch",
-      "loosen-msvc-detection.patch"
+      "loosen-msvc-detection.patch",
+      "r314201.patch",
+      "r315677.patch",
+      "r316048.patch",
+      "r317705.patch",
+      "r317709.patch"
     ]
 }
--- a/build/build-clang/clang-win64.json
+++ b/build/build-clang/clang-win64.json
@@ -8,11 +8,16 @@
     "clang_repo": "https://llvm.org/svn/llvm-project/cfe/trunk",
     "compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/trunk",
     "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/trunk",
     "python_path": "c:/mozilla-build/python/python.exe",
     "cc": "cl.exe",
     "cxx": "cl.exe",
     "ml": "ml64.exe",
     "patches": [
-      "loosen-msvc-detection.patch"
+      "loosen-msvc-detection.patch",
+      "r314201.patch",
+      "r315677.patch",
+      "r316048.patch",
+      "r317705.patch",
+      "r317709.patch"
     ]
 }
new file mode 100644
--- /dev/null
+++ b/build/build-clang/r314201.patch
@@ -0,0 +1,54 @@
+From 71e7a8ba8994e5b1f9cc0a0986b2ef5d37ed8ad2 Mon Sep 17 00:00:00 2001
+From: Sylvestre Ledru <sylvestre@debian.org>
+Date: Tue, 26 Sep 2017 11:56:43 +0000
+Subject: [PATCH] Don't move llvm.localescape outside the entry block in the
+ GCOV profiling pass
+
+Summary:
+This fixes https://bugs.llvm.org/show_bug.cgi?id=34714.
+
+Patch by Marco Castelluccio
+
+Reviewers: rnk
+
+Reviewed By: rnk
+
+Subscribers: llvm-commits
+
+Differential Revision: https://reviews.llvm.org/D38224
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@314201 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ lib/Transforms/Instrumentation/GCOVProfiling.cpp | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+index b2033536ac8..3154c1939ea 100644
+--- a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
++++ b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+@@ -502,6 +502,16 @@ static bool functionHasLines(Function &F) {
+   return false;
+ }
+ 
++static bool shouldKeepInEntry(BasicBlock::iterator It) {
++	if (isa<AllocaInst>(*It)) return true;
++	if (isa<DbgInfoIntrinsic>(*It)) return true;
++	if (auto *II = dyn_cast<IntrinsicInst>(It)) {
++		if (II->getIntrinsicID() == llvm::Intrinsic::localescape) return true;
++	}
++
++	return false;
++}
++
+ void GCOVProfiler::emitProfileNotes() {
+   NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
+   if (!CU_Nodes) return;
+@@ -537,7 +547,7 @@ void GCOVProfiler::emitProfileNotes() {
+       // single successor, so split the entry block to make sure of that.
+       BasicBlock &EntryBlock = F.getEntryBlock();
+       BasicBlock::iterator It = EntryBlock.begin();
+-      while (isa<AllocaInst>(*It) || isa<DbgInfoIntrinsic>(*It))
++      while (shouldKeepInEntry(It))
+         ++It;
+       EntryBlock.splitBasicBlock(It);
+ 
new file mode 100644
--- /dev/null
+++ b/build/build-clang/r315677.patch
@@ -0,0 +1,67 @@
+From 44847b2e9838888e1536c90ad442a3958362139a Mon Sep 17 00:00:00 2001
+From: Marco Castelluccio <mcastelluccio@mozilla.com>
+Date: Fri, 13 Oct 2017 13:49:15 +0000
+Subject: [PATCH] Disable gcov instrumentation of functions using funclet-based
+ exception handling
+
+Summary: This patch fixes the crash from https://bugs.llvm.org/show_bug.cgi?id=34659 and https://bugs.llvm.org/show_bug.cgi?id=34833.
+
+Reviewers: rnk, majnemer
+
+Reviewed By: rnk, majnemer
+
+Subscribers: majnemer, llvm-commits
+
+Differential Revision: https://reviews.llvm.org/D38223
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315677 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ lib/Transforms/Instrumentation/GCOVProfiling.cpp | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+index 3154c1939ea..67ca8172b0d 100644
+--- a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
++++ b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+@@ -21,6 +21,7 @@
+ #include "llvm/ADT/StringExtras.h"
+ #include "llvm/ADT/StringMap.h"
+ #include "llvm/ADT/UniqueVector.h"
++#include "llvm/Analysis/EHPersonalities.h"
+ #include "llvm/IR/DebugInfo.h"
+ #include "llvm/IR/DebugLoc.h"
+ #include "llvm/IR/IRBuilder.h"
+@@ -502,6 +503,13 @@ static bool functionHasLines(Function &F) {
+   return false;
+ }
+ 
++static bool isUsingFuncletBasedEH(Function &F) {
++  if (!F.hasPersonalityFn()) return false;
++
++  EHPersonality Personality = classifyEHPersonality(F.getPersonalityFn());
++  return isFuncletEHPersonality(Personality);
++}
++
+ static bool shouldKeepInEntry(BasicBlock::iterator It) {
+ 	if (isa<AllocaInst>(*It)) return true;
+ 	if (isa<DbgInfoIntrinsic>(*It)) return true;
+@@ -542,6 +550,8 @@ void GCOVProfiler::emitProfileNotes() {
+       DISubprogram *SP = F.getSubprogram();
+       if (!SP) continue;
+       if (!functionHasLines(F)) continue;
++      // TODO: Functions using funclet-based EH are currently not supported.
++      if (isUsingFuncletBasedEH(F)) continue;
+ 
+       // gcov expects every function to start with an entry block that has a
+       // single successor, so split the entry block to make sure of that.
+@@ -619,7 +629,10 @@ bool GCOVProfiler::emitProfileArcs() {
+       DISubprogram *SP = F.getSubprogram();
+       if (!SP) continue;
+       if (!functionHasLines(F)) continue;
++      // TODO: Functions using funclet-based EH are currently not supported.
++      if (isUsingFuncletBasedEH(F)) continue;
+       if (!Result) Result = true;
++
+       unsigned Edges = 0;
+       for (auto &BB : F) {
+         TerminatorInst *TI = BB.getTerminator();
new file mode 100644
--- /dev/null
+++ b/build/build-clang/r316048.patch
@@ -0,0 +1,60 @@
+From 98adaa2097783c0fe3a4c948397e3f2182dcc5d2 Mon Sep 17 00:00:00 2001
+From: Marco Castelluccio <mcastelluccio@mozilla.com>
+Date: Wed, 18 Oct 2017 00:22:01 +0000
+Subject: [PATCH] Use O_BINARY when opening GCDA file on Windows
+
+Summary:
+Fixes https://bugs.llvm.org/show_bug.cgi?id=34922.
+
+Apparently, the mode in **fdopen** gets simply ignored and Windows only cares about the mode of the original **open**.
+
+I have verified this both with the simple case from bug 34922 and with a full Firefox build.
+
+Reviewers: zturner
+
+Reviewed By: zturner
+
+Subscribers: llvm-commits
+
+Differential Revision: https://reviews.llvm.org/D38984
+
+git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@316048 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ lib/profile/GCDAProfiling.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/compiler-rt/lib/profile/GCDAProfiling.c b/compiler-rt/lib/profile/GCDAProfiling.c
+index 138af6ec4..8c92546bd 100644
+--- a/compiler-rt/lib/profile/GCDAProfiling.c
++++ b/compiler-rt/lib/profile/GCDAProfiling.c
+@@ -37,6 +37,9 @@
+ #ifndef MAP_FILE
+ #define MAP_FILE 0
+ #endif
++#ifndef O_BINARY
++#define O_BINARY 0
++#endif
+ #endif
+ 
+ #if defined(__FreeBSD__) && defined(__i386__)
+@@ -238,17 +241,17 @@ void llvm_gcda_start_file(const char *orig_filename, const char version[4],
+ 
+   /* Try just opening the file. */
+   new_file = 0;
+-  fd = open(filename, O_RDWR);
++  fd = open(filename, O_RDWR | O_BINARY);
+ 
+   if (fd == -1) {
+     /* Try opening the file, creating it if necessary. */
+     new_file = 1;
+     mode = "w+b";
+-    fd = open(filename, O_RDWR | O_CREAT, 0644);
++    fd = open(filename, O_RDWR | O_CREAT | O_BINARY, 0644);
+     if (fd == -1) {
+       /* Try creating the directories first then opening the file. */
+       __llvm_profile_recursive_mkdir(filename);
+-      fd = open(filename, O_RDWR | O_CREAT, 0644);
++      fd = open(filename, O_RDWR | O_CREAT | O_BINARY, 0644);
+       if (fd == -1) {
+         /* Bah! It's hopeless. */
+         int errnum = errno;
new file mode 100644
--- /dev/null
+++ b/build/build-clang/r317705.patch
@@ -0,0 +1,92 @@
+From 07e2a968c83c489c5b46efe4973114e78e1804c1 Mon Sep 17 00:00:00 2001
+From: Marco Castelluccio <mcastelluccio@mozilla.com>
+Date: Wed, 8 Nov 2017 19:11:54 +0000
+Subject: [PATCH] Implement flock for Windows in compiler-rt
+
+Summary:
+This patch implements flock for Windows, needed to make gcda writing work in a multiprocessing scenario.
+
+Fixes https://bugs.llvm.org/show_bug.cgi?id=34923.
+
+Reviewers: zturner
+
+Reviewed By: zturner
+
+Subscribers: rnk, zturner, llvm-commits
+
+Differential Revision: https://reviews.llvm.org/D38891
+
+git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317705 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ lib/profile/WindowsMMap.c | 58 ++++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 55 insertions(+), 3 deletions(-)
+
+diff --git a/compiler-rt/lib/profile/WindowsMMap.c b/lib/profile/WindowsMMap.c
+index f81d7da53..0c534710b 100644
+--- a/compiler-rt/lib/profile/WindowsMMap.c
++++ b/compiler-rt/lib/profile/WindowsMMap.c
+@@ -120,9 +120,61 @@ int msync(void *addr, size_t length, int flags)
+ }
+ 
+ COMPILER_RT_VISIBILITY
+-int flock(int fd, int operation)
+-{
+-  return -1; /* Not supported. */
++int lock(HANDLE handle, DWORD lockType, BOOL blocking) {
++  DWORD flags = lockType;
++  if (!blocking)
++    flags |= LOCKFILE_FAIL_IMMEDIATELY;
++
++  OVERLAPPED overlapped;
++  ZeroMemory(&overlapped, sizeof(OVERLAPPED));
++  overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
++  BOOL result = LockFileEx(handle, flags, 0, MAXDWORD, MAXDWORD, &overlapped);
++  if (!result) {
++    DWORD dw = GetLastError();
++
++    // In non-blocking mode, return an error if the file is locked.
++    if (!blocking && dw == ERROR_LOCK_VIOLATION)
++      return -1; // EWOULDBLOCK
++
++    // If the error is ERROR_IO_PENDING, we need to wait until the operation
++    // finishes. Otherwise, we return an error.
++    if (dw != ERROR_IO_PENDING)
++      return -1;
++
++    DWORD dwNumBytes;
++    if (!GetOverlappedResult(handle, &overlapped, &dwNumBytes, TRUE))
++      return -1;
++  }
++
++  return 0;
++}
++
++COMPILER_RT_VISIBILITY
++int flock(int fd, int operation) {
++  HANDLE handle = (HANDLE)_get_osfhandle(fd);
++  if (handle == INVALID_HANDLE_VALUE)
++    return -1;
++
++  BOOL blocking = (operation & LOCK_NB) == 0;
++  int op = operation & ~LOCK_NB;
++
++  switch (op) {
++  case LOCK_EX:
++    return lock(handle, LOCKFILE_EXCLUSIVE_LOCK, blocking);
++
++  case LOCK_SH:
++    return lock(handle, 0, blocking);
++
++  case LOCK_UN:
++    if (!UnlockFile(handle, 0, 0, MAXDWORD, MAXDWORD))
++      return -1;
++    break;
++
++  default:
++    return -1;
++  }
++
++  return 0;
+ }
+ 
+ #undef DWORD_HI
new file mode 100644
--- /dev/null
+++ b/build/build-clang/r317709.patch
@@ -0,0 +1,51 @@
+From 8f15f3c70065372ce412075f5f369847b55351d2 Mon Sep 17 00:00:00 2001
+From: Marco Castelluccio <mcastelluccio@mozilla.com>
+Date: Wed, 8 Nov 2017 19:21:54 +0000
+Subject: [PATCH] Add CoreOption flag to "-coverage" option to make it
+ available for clang-cl
+
+Summary:
+The -coverage option is not a CoreOption, so it is not available to clang-cl.
+This patch adds the CoreOption flag to "-coverage" to allow it to be used with clang-cl.
+
+Reviewers: rnk
+
+Reviewed By: rnk
+
+Subscribers: cfe-commits
+
+Differential Revision: https://reviews.llvm.org/D38221
+
+git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@317709 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ include/clang/Driver/Options.td | 2 +-
+ test/Driver/coverage.c          | 7 +++++++
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+ create mode 100644 test/Driver/coverage.c
+
+diff --git a/clang/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
+index 597e03b563d..01605619e02 100644
+--- a/clang/include/clang/Driver/Options.td
++++ b/clang/include/clang/Driver/Options.td
+@@ -519,7 +519,7 @@ def cl_fp32_correctly_rounded_divide_sqrt : Flag<["-"], "cl-fp32-correctly-round
+ def client__name : JoinedOrSeparate<["-"], "client_name">;
+ def combine : Flag<["-", "--"], "combine">, Flags<[DriverOption, Unsupported]>;
+ def compatibility__version : JoinedOrSeparate<["-"], "compatibility_version">;
+-def coverage : Flag<["-", "--"], "coverage">;
++def coverage : Flag<["-", "--"], "coverage">, Flags<[CoreOption]>;
+ def cpp_precomp : Flag<["-"], "cpp-precomp">, Group<clang_ignored_f_Group>;
+ def current__version : JoinedOrSeparate<["-"], "current_version">;
+ def cxx_isystem : JoinedOrSeparate<["-"], "cxx-isystem">, Group<clang_i_Group>,
+diff --git a/clang/test/Driver/coverage.c b/clang/test/Driver/coverage.c
+new file mode 100644
+index 00000000000..339c4a3f366
+--- /dev/null
++++ b/clang/test/Driver/coverage.c
+@@ -0,0 +1,7 @@
++// Test coverage flag.
++//
++// RUN: %clang_cl -### -coverage %s -o foo/bar.o 2>&1 | FileCheck -check-prefix=CLANG-CL-COVERAGE %s
++// CLANG-CL-COVERAGE-NOT: error:
++// CLANG-CL-COVERAGE-NOT: warning:
++// CLANG-CL-COVERAGE-NOT: argument unused
++// CLANG-CL-COVERAGE-NOT: unknown argument
--- a/build/moz.build
+++ b/build/moz.build
@@ -10,16 +10,20 @@ with Files('**'):
 # This cannot be named "build" because of bug 922191.
 SPHINX_TREES['buildsystem'] = 'docs'
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     DIRS += ['win32']
 else:
     DIRS += ['unix']
 
+CRAMTEST_MANIFESTS += [
+    'tests/cram/cram.ini',
+]
+
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     DIRS += ['annotationProcessors']
 
 DEFINES['ACCEPTED_MAR_CHANNEL_IDS'] = CONFIG['ACCEPTED_MAR_CHANNEL_IDS']
 
 if CONFIG['MOZ_BUILD_APP'] == 'browser':
     PYTHON_UNITTEST_MANIFESTS += [
         'compare-mozconfig/python.ini',
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -1,17 +1,17 @@
 # -*- 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/.
 
 # PGO
 # ==============================================================
-option(env='MOZ_PGO', help='Build with profile guided optimizations')
+js_option(env='MOZ_PGO', help='Build with profile guided optimizations')
 
 set_config('MOZ_PGO', depends('MOZ_PGO')(lambda x: bool(x)))
 add_old_configure_assignment('MOZ_PGO', depends('MOZ_PGO')(lambda x: bool(x)))
 
 # Code optimization
 # ==============================================================
 
 js_option('--enable-optimize',
@@ -1067,26 +1067,23 @@ def check_have_64_bit(have_64_bit, compi
 
 option(env='BINDGEN_CFLAGS',
        nargs=1,
        default=bindgen_cflags_defaults,
        help='Options bindgen should pass to the C/C++ parser')
 
 
 @depends('BINDGEN_CFLAGS')
-@checking('bindgen cflags', lambda s: s if s and s.strip() else 'no')
+@checking('bindgen cflags', lambda s: s if s else 'no')
 def bindgen_cflags(value):
     if value and len(value):
-        # Reformat the env value for substitution into a toml list.
-        flags = value[0].split()
-        return ', '.join('"' + flag + '"' for flag in flags)
-    return ''
+        return value[0].split()
 
 
-set_config('BINDGEN_CFLAGS', bindgen_cflags)
+add_old_configure_assignment('_BINDGEN_CFLAGS', bindgen_cflags)
 
 
 @depends(c_compiler)
 def default_debug_flags(compiler_info):
     # Debug info is ON by default.
     if compiler_info.type in ('msvc', 'clang-cl'):
         return '-Zi'
     return '-g'
--- a/build/mozconfig.cache
+++ b/build/mozconfig.cache
@@ -114,18 +114,17 @@ else
     mk_add_options "export SCCACHE_BUCKET=$bucket"
     case "$master" in
     *us[ew][12].mozilla.com*|*euc1.mozilla.com*)
         mk_add_options "export SCCACHE_NAMESERVER=169.254.169.253"
         ;;
     esac
     export CCACHE="$topsrcdir/sccache2/sccache${suffix}"
     export SCCACHE_VERBOSE_STATS=1
-    mk_add_options MOZ_PREFLIGHT_ALL+=build/sccache.mk
-    mk_add_options MOZ_POSTFLIGHT_ALL+=build/sccache.mk
+    mk_add_options MOZBUILD_MANAGE_SCCACHE_DAEMON=${topsrcdir}/sccache2/sccache
     mk_add_options "UPLOAD_EXTRA_FILES+=sccache.log.gz"
     case "$platform" in
     win*)
         # sccache supports a special flag to create depfiles.
         #TODO: bug 1318370 - move this all into toolchain.configure
         export _DEPEND_CFLAGS='-deps$(MDDEPDIR)/$(@F).pp'
         # Windows builds have a default wrapper that needs to be overridden
         mk_add_options "export CC_WRAPPER="
deleted file mode 100644
--- a/build/sccache.mk
+++ /dev/null
@@ -1,15 +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/.
-
-preflight_all:
-	# Terminate any sccache server that might still be around
-	-$(TOPSRCDIR)/sccache2/sccache --stop-server > /dev/null 2>&1
-	# Start a new server, ensuring it gets the jobserver file descriptors
-	# from make (but don't use the + prefix when make -n is used, so that
-	# the command doesn't run in that case)
-	$(if $(findstring n,$(filter-out --%, $(MAKEFLAGS))),,+)env RUST_LOG=sccache::compiler=debug SCCACHE_ERROR_LOG=$(OBJDIR)/dist/sccache.log $(TOPSRCDIR)/sccache2/sccache --start-server
-
-postflight_all:
-	# Terminate sccache server. This prints sccache stats.
-	-$(TOPSRCDIR)/sccache2/sccache --stop-server
new file mode 100644
--- /dev/null
+++ b/build/tests/cram/cram.ini
@@ -0,0 +1,1 @@
+[test_configure_help.t]
new file mode 100644
--- /dev/null
+++ b/build/tests/cram/test_configure_help.t
@@ -0,0 +1,14 @@
+configure --help works
+
+  $ cd $TESTDIR/../../..
+
+  $ touch $TMP/mozconfig
+  $ export MOZCONFIG=$TMP/mozconfig
+  $ ./configure --help 2>& 1 | head -n 7
+  Adding configure options from */tmp/mozconfig (glob)
+  checking for vcs source checkout... hg
+  checking for vcs source checkout... hg
+  Usage: configure.py [options]
+  
+  Options: [defaults in brackets after descriptions]
+    --help                    print this message
--- a/caps/tests/mochitest/test_bug292789.html
+++ b/caps/tests/mochitest/test_bug292789.html
@@ -51,18 +51,18 @@ function testScriptSrc(aCallback) {
       // trigger the callback
       if (aCallback)
         aCallback();
     }
 }
 
 /** <img src=""> tests **/
 var img_global = "chrome://global/skin/media/error.png";
-var img_mozapps = "chrome://mozapps/skin/plugins/contentPluginClose.png";
-var res_mozapps = "resource://gre/chrome/toolkit/skin/classic/mozapps/plugins/contentPluginClose.png";
+var img_mozapps = "chrome://mozapps/skin/plugins/contentPluginCrashed.png";
+var res_mozapps = "resource://gre/chrome/toolkit/skin/classic/mozapps/plugins/contentPluginCrashed.png";
 
 var imgTests = [[img_global, "success"],
                 [img_mozapps, "fail"],
                 [res_mozapps, "success"]];
 
 var curImgTest = 0;
 
 function runImgTest() {
--- a/client.mk
+++ b/client.mk
@@ -7,24 +7,20 @@
 # Defines main targets for driving the Firefox build system.
 #
 # This make file should not be invoked directly. Instead, use
 # `mach` (likely `mach build`) for invoking the build system.
 #
 # Options:
 #   MOZ_OBJDIR           - Destination object directory
 #   MOZ_MAKE_FLAGS       - Flags to pass to $(MAKE)
-#   MOZ_PREFLIGHT_ALL    - Makefiles to run before building.
-#   MOZ_POSTFLIGHT_ALL   - Makefiles to run after building.
 #
 #######################################################################
 # Defines
 
-comma := ,
-
 ifdef MACH
 ifndef NO_BUILDSTATUS_MESSAGES
 define BUILDSTATUS
 @echo 'BUILDSTATUS $1'
 
 endef
 endif
 endif
@@ -39,18 +35,16 @@ endif
 ifndef TOPSRCDIR
 ifeq (,$(wildcard client.mk))
 TOPSRCDIR := $(patsubst %/,%,$(dir $(MAKEFILE_LIST)))
 else
 TOPSRCDIR := $(CWD)
 endif
 endif
 
-SH := /bin/sh
-PERL ?= perl
 PYTHON ?= $(shell which python2.7 > /dev/null 2>&1 && echo python2.7 || echo python)
 
 CONFIG_GUESS := $(shell $(TOPSRCDIR)/build/autoconf/config.guess)
 
 ####################################
 # Sanity checks
 
 # Windows checks.
@@ -120,16 +114,21 @@ CONFIGURES += $(TOPSRCDIR)/js/src/config
 OBJDIR_TARGETS = install export libs clean realclean distclean upload sdk installer package package-compare stage-package source-package l10n-check automation/build
 
 #######################################################################
 # Rules
 
 # The default rule is build
 build::
 
+ifndef MACH
+$(error client.mk must be used via `mach`. Try running \
+`./mach $(firstword $(MAKECMDGOALS) $(.DEFAULT_GOAL))`)
+endif
+
 # Include baseconfig.mk for its $(MAKE) validation.
 include $(TOPSRCDIR)/config/baseconfig.mk
 
 # Define mkdir
 include $(TOPSRCDIR)/config/makefiles/makeutils.mk
 include $(TOPSRCDIR)/config/makefiles/autotargets.mk
 
 # For now, only output "export" lines and lines containing UPLOAD_EXTRA_FILES
@@ -148,25 +147,26 @@ all build clean distclean export libs in
 ifneq (,$(strip $(MOZCONFIG_OUT_FILTERED)))
 	$(info Adding client.mk options from $(FOUND_MOZCONFIG):)
 	$(foreach line,$(MOZCONFIG_OUT_FILTERED),$(info $(NULL) $(NULL) $(NULL) $(NULL) $(subst ||, ,$(line))))
 endif
 
 # helper target for mobile
 build_and_deploy: build package install
 
-#####################################################
-# Preflight, before building any project
-
-ifdef MOZ_PREFLIGHT_ALL
-build preflight_all::
-	set -e; \
-	for mkfile in $(MOZ_PREFLIGHT_ALL); do \
-	  $(MAKE) -f $(TOPSRCDIR)/$$mkfile preflight_all TOPSRCDIR=$(TOPSRCDIR) OBJDIR=$(OBJDIR) MOZ_OBJDIR=$(MOZ_OBJDIR); \
-	done
+# In automation, manage an sccache daemon. The starting of the server
+# needs to be in a make file so sccache inherits the jobserver.
+ifdef MOZBUILD_MANAGE_SCCACHE_DAEMON
+build::
+	# Terminate any sccache server that might still be around.
+	-$(MOZBUILD_MANAGE_SCCACHE_DAEMON) --stop-server > /dev/null 2>&1
+	# Start a new server, ensuring it gets the jobserver file descriptors
+	# from make (but don't use the + prefix when make -n is used, so that
+	# the command doesn't run in that case)
+	$(if $(findstring n,$(filter-out --%, $(MAKEFLAGS))),,+)env RUST_LOG=sccache::compiler=debug SCCACHE_ERROR_LOG=$(OBJDIR)/dist/sccache.log $(MOZBUILD_MANAGE_SCCACHE_DAEMON) --start-server
 endif
 
 ####################################
 # Configure
 
 MAKEFILE      = $(wildcard $(OBJDIR)/Makefile)
 CONFIG_STATUS = $(wildcard $(OBJDIR)/config.status)
 
@@ -275,38 +275,28 @@ build::  $(OBJDIR)/Makefile $(OBJDIR)/co
 
 ####################################
 # Other targets
 
 # Pass these target onto the real build system
 $(OBJDIR_TARGETS):: $(OBJDIR)/Makefile $(OBJDIR)/config.status
 	+$(MOZ_MAKE) $@
 
-####################################
-# Postflight, after building all projects
-
 ifdef MOZ_AUTOMATION
 build::
 	$(MAKE) -f $(TOPSRCDIR)/client.mk automation/build
 endif
 
-ifdef MOZ_POSTFLIGHT_ALL
-build postflight_all::
-	set -e; \
-	for mkfile in $(MOZ_POSTFLIGHT_ALL); do \
-	  $(MAKE) -f $(TOPSRCDIR)/$$mkfile postflight_all TOPSRCDIR=$(TOPSRCDIR) OBJDIR=$(OBJDIR) MOZ_OBJDIR=$(MOZ_OBJDIR); \
-	done
+ifdef MOZBUILD_MANAGE_SCCACHE_DAEMON
+build::
+	# Terminate sccache server. This prints sccache stats.
+	-$(MOZBUILD_MANAGE_SCCACHE_DAEMON) --stop-server
 endif
 
-echo-variable-%:
-	@echo $($*)
-
 # This makefile doesn't support parallel execution. It does pass
 # MOZ_MAKE_FLAGS to sub-make processes, so they will correctly execute
 # in parallel.
 .NOTPARALLEL:
 
 .PHONY: \
     build \
     configure \
-    preflight_all \
-    postflight_all \
     $(OBJDIR_TARGETS)
--- a/config/Makefile.in
+++ b/config/Makefile.in
@@ -27,63 +27,16 @@ NSINSTALL_EXECUTABLES := nsinstall$(HOST
 NSINSTALL_DEST := $(DIST)/bin
 NSINSTALL_TARGET := host
 INSTALL_TARGETS += NSINSTALL
 endif
 endif
 
 include $(topsrcdir)/config/rules.mk
 
-ifdef WRAP_SYSTEM_INCLUDES
-export-preqs = \
-  $(call mkdir_deps,system_wrappers) \
-  $(NULL)
-
-export:: $(export-preqs)
-	$(PYTHON) -m mozbuild.action.preprocessor $(DEFINES) $(ACDEFINES) \
-		-DMOZ_TREE_CAIRO=$(MOZ_TREE_CAIRO) \
-		-DMOZ_TREE_PIXMAN=$(MOZ_TREE_PIXMAN) \
-		-DMOZ_SYSTEM_HUNSPELL=$(MOZ_SYSTEM_HUNSPELL) \
-		-DMOZ_SYSTEM_BZ2=$(MOZ_SYSTEM_BZ2) \
-		-DMOZ_SYSTEM_ZLIB=$(MOZ_SYSTEM_ZLIB) \
-		-DMOZ_SYSTEM_PNG=$(MOZ_SYSTEM_PNG) \
-		-DMOZ_SYSTEM_JPEG=$(MOZ_SYSTEM_JPEG) \
-		-DMOZ_SYSTEM_LIBEVENT=$(MOZ_SYSTEM_LIBEVENT) \
-		-DMOZ_SYSTEM_LIBVPX=$(MOZ_SYSTEM_LIBVPX) \
-		-DMOZ_SYSTEM_ICU=$(MOZ_SYSTEM_ICU) \
-		$(srcdir)/system-headers $(srcdir)/stl-headers | $(PERL) $(topsrcdir)/nsprpub/config/make-system-wrappers.pl system_wrappers
-	$(INSTALL) system_wrappers $(DIST)
-
-GARBAGE_DIRS += system_wrappers
-endif
-
-ifdef WRAP_STL_INCLUDES
-ifdef GNU_CXX
-stl_compiler = gcc
-else
-ifdef _MSC_VER
-stl_compiler = msvc
-endif
-endif
-endif
-
-ifdef stl_compiler
-STL_WRAPPERS_SENTINEL = $(DIST)/stl_wrappers/sentinel
-
-$(STL_WRAPPERS_SENTINEL): $(srcdir)/make-stl-wrappers.py $(srcdir)/$(stl_compiler)-stl-wrapper.template.h $(srcdir)/stl-headers $(GLOBAL_DEPS)
-	$(PYTHON) $(srcdir)/make-stl-wrappers.py stl_wrappers $(stl_compiler) $(srcdir)/$(stl_compiler)-stl-wrapper.template.h $(srcdir)/stl-headers
-	$(PYTHON) $(srcdir)/nsinstall.py -t stl_wrappers $(DIST)
-	touch $(STL_WRAPPERS_SENTINEL)
-
-export:: $(STL_WRAPPERS_SENTINEL)
-
-GARBAGE += $(STL_WRAPPERS_SENTINEL)
-GARBAGE_DIRS += stl_wrappers
-endif
-
 GARBAGE += \
   $(FINAL_LINK_COMPS) $(FINAL_LINK_LIBS) $(FINAL_LINK_COMP_NAMES) $(srcdir)/*.pyc *.pyc
 
 FORCE:
 
 ifndef JS_STANDALONE
 check-preqs += check-jar-mn
 endif
--- a/config/faster/rules.mk
+++ b/config/faster/rules.mk
@@ -54,18 +54,17 @@ ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 default:
 	$(MAKE) -C $(TOPOBJDIR)/$(MOZ_BUILD_APP)/app repackage
 endif
 endif
 
 .PHONY: FORCE
 
 # Extra define to trigger some workarounds. We should strive to limit the
-# use of those. As of writing the only ones are in
-# toolkit/content/buildconfig.html and browser/locales/jar.mn.
+# use of those. As of writing the only one is in browser/locales/jar.mn.
 ACDEFINES += -DBUILD_FASTER
 
 # Files under the faster/ sub-directory, however, are not meant to use the
 # fallback
 $(TOPOBJDIR)/faster/%: ;
 
 # Generic rule to fall back to the recursive make backend.
 # This needs to stay after other $(TOPOBJDIR)/* rules because GNU Make
--- a/config/make-stl-wrappers.py
+++ b/config/make-stl-wrappers.py
@@ -17,36 +17,18 @@ def header_path(header, compiler):
         # we use include_next on gcc
         return header
     elif compiler == 'msvc':
         return find_in_path(header, os.environ.get('INCLUDE', ''))
     else:
         # hope someone notices this ...
         raise NotImplementedError(compiler)
 
-def is_comment(line):
-    return re.match(r'\s*#.*', line)
-
-def main(outdir, compiler, template_file, header_list_file):
-    if not os.path.isdir(outdir):
-        os.mkdir(outdir)
-
+# The 'unused' arg is the output file from the file_generate action. We actually
+# generate all the files in header_list
+def gen_wrappers(unused, outdir, compiler, template_file, *header_list):
     template = open(template_file, 'r').read()
 
-    for header in open(header_list_file, 'r'):
-        header = header.rstrip()
-        if 0 == len(header) or is_comment(header):
-            continue
-
+    for header in header_list:
         path = header_path(header, compiler)
         with FileAvoidWrite(os.path.join(outdir, header)) as f:
             f.write(string.Template(template).substitute(HEADER=header,
                                                          HEADER_PATH=path))
-
-
-if __name__ == '__main__':
-    if 5 != len(sys.argv):
-        print("""Usage:
-  python {0} OUT_DIR ('msvc'|'gcc') TEMPLATE_FILE HEADER_LIST_FILE
-""".format(sys.argv[0]), file=sys.stderr)
-        sys.exit(1)
-
-    main(*sys.argv[1:])
new file mode 100644
--- /dev/null
+++ b/config/make-system-wrappers.py
@@ -0,0 +1,23 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+from __future__ import print_function
+import os
+import sys
+from mozbuild.util import FileAvoidWrite
+
+header_template = '''#pragma GCC system_header
+#pragma GCC visibility push(default)
+#include_next <%(header)s>
+#pragma GCC visibility pop
+'''
+
+
+# The 'unused' arg is the output file from the file_generate action. We actually
+# generate all the files in header_list
+def gen_wrappers(unused, outdir, *header_list):
+    for header in header_list:
+        with FileAvoidWrite(os.path.join(outdir, header)) as f:
+            f.write(header_template % {
+                'header': header,
+            })
--- a/config/moz.build
+++ b/config/moz.build
@@ -37,8 +37,40 @@ PYTHON_UNITTEST_MANIFESTS += [
 
 if CONFIG['GNU_CC'] and CONFIG['MOZ_OPTIMIZE']:
     CFLAGS += ['-O3']
 
 HOST_DEFINES = {
     'UNICODE': True,
     '_UNICODE': True,
 }
+
+include('stl-headers.mozbuild')
+if CONFIG['WRAP_STL_INCLUDES']:
+    stl_compiler = None
+    if CONFIG['GNU_CXX']:
+        stl_compiler = 'gcc'
+    elif CONFIG['_MSC_VER']:
+        stl_compiler = 'msvc'
+
+    if stl_compiler:
+        template_file = SRCDIR + '/%s-stl-wrapper.template.h' % stl_compiler
+        output_dir = '../dist/stl_wrappers'
+        # We have to use a sentinel file as the first file because the
+        # file_generate action will create it for us, but we want to create all
+        # the files in gen_wrappers()
+        outputs = tuple(['stl.sentinel'] + ['%s/%s' % (output_dir, h) for h in stl_headers])
+        GENERATED_FILES += [outputs]
+        stl = GENERATED_FILES[outputs]
+        stl.script = 'make-stl-wrappers.py:gen_wrappers'
+        stl.flags = [output_dir, stl_compiler, template_file]
+        stl.flags.extend(stl_headers)
+
+if CONFIG['WRAP_SYSTEM_INCLUDES']:
+    include('system-headers.mozbuild')
+    output_dir = '../dist/system_wrappers'
+    outputs = tuple(['system-header.sentinel'] + ['%s/%s' % (output_dir, h) for h in stl_headers + system_headers])
+    GENERATED_FILES += [outputs]
+    system = GENERATED_FILES[outputs]
+    system.script = 'make-system-wrappers.py:gen_wrappers'
+    system.flags = [output_dir]
+    system.flags.extend(stl_headers)
+    system.flags.extend(system_headers)
deleted file mode 100644
--- a/config/stl-headers
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# This file contains a list the of STL headers that have been reviewed
-# for exception safety and approved. See
-#
-#   https://bugzilla.mozilla.org/show_bug.cgi?id=551254
-#
-# At build time, each header listed here is converted into a "wrapper
-# header" that is installed into dist/stl_includes.
-#
-# If you would like to request a new STL header <foo> be added, please
-# file a Core:XPCOM bug with a title like "STL: Review exception
-# safety of <foo> for gcc and MSVC".
-#
-
-new
-
-# FIXME: these headers haven't been reviewed yet, but we use them
-# unsafely in Gecko, so we might as well prevent them from
-# throwing exceptions
-algorithm
-atomic
-deque
-functional
-ios
-iosfwd
-iostream
-istream
-iterator
-limits
-list
-map
-memory
-ostream
-set
-stack
-string
-thread
-type_traits
-unordered_map
-unordered_set
-utility
-vector
-cassert
-climits
-cmath
-cstdarg
-cstdio
-cstdlib
-cstring
-cwchar
-tuple
-xutility
new file mode 100644
--- /dev/null
+++ b/config/stl-headers.mozbuild
@@ -0,0 +1,57 @@
+# -*- 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/.
+
+# This list contains the of STL headers that have been reviewed for exception
+# safety and approved. See
+#
+#   https://bugzilla.mozilla.org/show_bug.cgi?id=551254
+#
+# At build time, each header listed here is converted into a "wrapper
+# header" that is installed into dist/stl_includes.
+#
+# If you would like to request a new STL header <foo> be added, please
+# file a Core:XPCOM bug with a title like "STL: Review exception
+# safety of <foo> for gcc and MSVC".
+stl_headers = [
+    'new',
+
+    # FIXME: these headers haven't been reviewed yet, but we use them
+    # unsafely in Gecko, so we might as well prevent them from
+    # throwing exceptions
+    'algorithm',
+    'atomic',
+    'deque',
+    'functional',
+    'ios',
+    'iosfwd',
+    'iostream',
+    'istream',
+    'iterator',
+    'limits',
+    'list',
+    'map',
+    'memory',
+    'ostream',
+    'set',
+    'stack',
+    'string',
+    'thread',
+    'type_traits',
+    'unordered_map',
+    'unordered_set',
+    'utility',
+    'vector',
+    'cassert',
+    'climits',
+    'cmath',
+    'cstdarg',
+    'cstdio',
+    'cstdlib',
+    'cstring',
+    'cwchar',
+    'tuple',
+    'xutility',
+]
deleted file mode 100644
--- a/config/system-headers
+++ /dev/null
@@ -1,1347 +0,0 @@
-atomic.h
-nspr.h
-plarena.h
-plarenas.h
-plbase64.h
-plerror.h
-plgetopt.h
-plhash.h
-plstr.h
-pratom.h
-prbit.h
-prclist.h
-prcmon.h
-prcountr.h
-prcpucfg.h
-prcvar.h
-prdtoa.h
-prenv.h
-prerr.h
-prerror.h
-prinet.h
-prinit.h
-prinrval.h
-prio.h
-pripcsem.h
-private
-prlink.h
-prlock.h
-prlog.h
-prlong.h
-prmem.h
-prmon.h
-prmwait.h
-prnetdb.h
-prolock.h
-prpdce.h
-prprf.h
-prproces.h
-prrng.h
-prrwlock.h
-prshm.h
-prshma.h
-prsystem.h
-prthread.h
-prtime.h
-prtpool.h
-prtrace.h
-prtypes.h
-prvrsion.h
-prwin16.h
-base64.h
-blapit.h
-cert.h
-certdb.h
-certt.h
-ciferfam.h
-cmmf.h
-cmmft.h
-cms.h
-cmsreclist.h
-cmst.h
-crmf.h
-crmft.h
-cryptohi.h
-cryptoht.h
-ecl-exp.h
-hasht.h
-jar-ds.h
-jar.h
-jarfile.h
-key.h
-keyhi.h
-keyt.h
-keythi.h
-nss.h
-nssb64.h
-nssb64t.h
-nssbase.h
-nssbaset.h
-nssck.api
-nssckbi.h
-nssckepv.h
-nssckft.h
-nssckfw.h
-nssckfwc.h
-nssckfwt.h
-nssckg.h
-nssckmdt.h
-nssckt.h
-nssilckt.h
-nssilock.h
-nsslocks.h
-nssrwlk.h
-nssrwlkt.h
-nssutil.h
-ocsp.h
-ocspt.h
-p12.h
-p12plcy.h
-p12t.h
-pk11func.h
-pk11pqg.h
-pk11priv.h
-pk11pub.h
-pk11sdr.h
-pkcs11.h
-pkcs11f.h
-pkcs11n.h
-pkcs11p.h
-pkcs11t.h
-pkcs11u.h
-pkcs12.h
-pkcs12t.h
-pkcs7t.h
-portreg.h
-preenc.h
-secasn1.h
-secasn1t.h
-seccomon.h
-secder.h
-secdert.h
-secdig.h
-secdigt.h
-secerr.h
-sechash.h
-secitem.h
-secmime.h
-secmod.h
-secmodt.h
-secoid.h
-secoidt.h
-secpkcs5.h
-secpkcs7.h
-secport.h
-shsign.h
-smime.h
-ssl.h
-sslerr.h
-sslproto.h
-sslt.h
-utilmodt.h
-utilpars.h
-utilparst.h
-utilrename.h
-A4Stuff.h
-activscp.h
-AEDataModel.h
-AEObjects.h
-AEPackObject.h
-AERegistry.h
-AEUtils.h
-afxcmn.h
-afxcoll.h
-afxcview.h
-afxdisp.h
-afxdtctl.h
-afxext.h
-afxmt.h
-afxpriv.h
-afxtempl.h
-afxwin.h
-Aliases.h
-all.h
-alloca.h
-alloc.h
-alsa/asoundlib.h
-#ifdef ANDROID
-android/ashmem.h
-android/log.h
-android/looper.h
-android/native_window.h
-android_audio/AudioSystem.h
-#endif
-ansi_parms.h
-a.out.h
-app/Cursor.h
-Appearance.h
-AppFileInfo.h
-AppKit.h
-AppleEvents.h
-Application.h
-app/Message.h
-app/MessageRunner.h
-arpa/inet.h
-arpa/nameser.h
-array
-asm/page.h
-asm/sigcontext.h
-asm/signal.h
-ASRegistry.h
-assert.h
-atk/atk.h
-atlcom.h
-atlconv.h
-atlctl.cpp
-atlctl.h
-ATLCTL.H
-atlhost.h
-atlimpl.cpp
-atlwin.cpp
-ATSTypes.h
-ATSUnicode.h
-#ifdef ANDROID
-audio_effects/effect_aec.h
-audio_effects/effect_ns.h
-AudioParameter.h
-AudioSystem.h
-AudioTrack.h
-avc_utils.h
-#endif
-Balloons.h
-base/pblock.h
-base/PCR_Base.h
-base/session.h
-basetyps.h
-be/app/Application.h
-Beep.h
-be/kernel/image.h
-be/kernel/OS.h
-bfd.h
-#ifdef ANDROID
-binder/Binder.h
-binder/BinderService.h
-binder/IBinder.h
-binder/IInterface.h
-binder/IMemory.h
-binder/IPCThreadState.h
-binder/IPermissionController.h
-binder/IServiceManager.h
-binder/Parcel.h
-binder/ProcessState.h
-#endif
-Bitmap.h
-bitset
-blapi.h
-bsd/libc.h
-bsd/syscall.h
-bstring.h
-builtin.h
-Button.h
-byteswap.h
-pixman.h
-cairo.h
-cairo-atsui.h
-cairo-beos.h
-cairo-ft.h
-cairo-glitz.h
-cairo-gobject.h
-cairo-pdf.h
-cairo-ps.h
-cairo-tee.h
-cairo-quartz.h
-cairo-win32.h
-cairo-xlib.h
-cairo-xlib-xrender.h
-cairo-directfb.h
-cairo-qpainter.h
-cairo-qt.h
-complex
-dfiff.h
-exception
-ffi.h
-fusion/reactor.h
-fusion/property.h
-fusion/conf.h
-fusion/build.h
-fusion/hash.h
-fusion/shm/shm.h
-fusion/shm/shm_internal.h
-fusion/shm/pool.h
-fusion/ref.h
-fusion/fusion_internal.h
-fusion/lock.h
-fusion/types.h
-fusion/vector.h
-fusion/call.h
-fusion/shmalloc.h
-fusion/protocol.h
-fusion/fusion.h
-fusion/arena.h
-fusion/object.h
-dgiff.h
-direct/util.h
-direct/memcpy.h
-direct/interface.h
-direct/conf.h
-direct/tree.h
-direct/signals.h
-direct/build.h
-direct/interface_implementation.h
-direct/utf8.h
-direct/serial.h
-direct/hash.h
-direct/direct.h
-direct/clock.h
-direct/types.h
-direct/mem.h
-direct/thread.h
-direct/debug.h
-direct/stream.h
-direct/messages.h
-direct/trace.h
-direct/modules.h
-direct/log.h
-direct/system.h
-direct/list.h
-dfb_types.h
-directfb_strings.h
-directfb_keyboard.h
-callconv.h
-#ifdef ANDROID
-camera/Camera.h
-camera/CameraParameters.h
-#endif
-Carbon/Carbon.h
-CarbonEvents.h
-Carbon.h
-c_asm.h
-cctype
-cderr.h
-cerrno
-CFBase.h
-CFBundle.h
-CFData.h
-CFDictionary.h
-cf.h
-CFNumber.h
-CFPlugIn.h
-CFPreferences.h
-CFString.h
-CFURL.h
-CGAffineTransform.h
-CheckBox.h
-Clipboard.h
-cmplrs/stsupport.h
-Cocoa/Cocoa.h
-CodeFragments.h
-#ifdef ANDROID
-ColorConverter.h
-#endif
-comdef.h
-commctrl.h
-COMMCTRL.H
-commdlg.h
-compat.h
-condapi.h
-ConditionalMacros.h
-conio.h
-console.h
-ControlDefinitions.h
-Controls.h
-CoreFoundation/CoreFoundation.h
-CoreServices/CoreServices.h
-CPalmRec.cpp
-Cpalmrec.h
-CPCatgry.cpp
-CPDbBMgr.h
-CPString.cpp
-CPString.h
-crtdbg.h
-crt_externs.h
-crypt.h
-cstddef
-ctime
-ctype.h
-curl/curl.h
-curl/easy.h
-curses.h
-#ifdef ANDROID
-cutils/android_reboot.h
-cutils/atomic.h
-cutils/compiler.h
-cutils/log.h
-cutils/native_handle.h
-cutils/properties.h
-cutils/sockets.h
-#endif
-cxxabi.h
-DateTimeUtils.h
-dbus/dbus.h
-dbus/dbus-glib.h
-dbus/dbus-glib-lowlevel.h
-ddeml.h
-Debug.h
-dem.h
-descrip.h
-Devices.h
-Dialogs.h
-direct.h
-dirent.h
-DiskInit.h
-dlfcn.h
-dlgs.h
-dl.h
-docobj.h
-dos/dosextens.h
-dos.h
-Drag.h
-DriverServices.h
-DriverSynchronization.h
-DropInPanel.h
-dvidef.h
-elf.h
-endian.h
-Entry.h
-errno.h
-Errors.h
-Events.h
-exdisp.h
-ExDisp.h
-exe386.h
-execinfo.h
-extras.h
-fcntl.h
-features.h
-fibdef.h
-File.h
-filehdr.h
-files.h
-Files.h
-FindDirectory.h
-Finder.h
-FinderRegistry.h
-FixMath.h
-float.h
-fnmatch.h
-Folders.h
-fontconfig/fontconfig.h
-fontconfig/fcfreetype.h
-Font.h
-Fonts.h
-#ifdef ANDROID
-foundation/ABase.h
-foundation/ABitReader.h
-foundation/ABuffer.h
-foundation/ADebug.h
-foundation/AHandler.h
-foundation/AHandlerReflector.h
-foundation/ALooper.h
-foundation/AMessage.h
-foundation/AString.h
-foundation/base64.h
-foundation/hexdump.h
-#endif
-fp.h
-fpieee.h
-frame/log.h
-frame/req.h
-freetype/freetype.h
-freetype/ftcache.h
-freetype/ftfntfmt.h
-freetype/ftglyph.h
-freetype/ftsynth.h
-freetype/ftoutln.h
-freetype/ttnameid.h
-freetype/tttables.h
-freetype/t1tables.h
-freetype/ftlcdfil.h
-freetype/ftsizes.h
-freetype/ftadvanc.h
-freetype/ftbitmap.h
-freetype/ftxf86.h
-freetype.h
-ftcache.h
-ftfntfmt.h
-ftglyph.h
-ftsynth.h
-ftoutln.h
-ttnameid.h
-tttables.h
-t1tables.h
-ftlcdfil.h
-ftsizes.h
-ftadvanc.h
-ftbitmap.h
-ftxf86.h
-fribidi/fribidi.h
-FSp_fopen.h
-fstream
-fstream.h
-ft2build.h
-fts.h
-gconf/gconf-client.h
-Gdiplus.h
-gdk/gdk.h
-gdk/gdkkeysyms.h
-gdk/gdkprivate.h
-gdk/gdkx.h
-gdk/gdkdirectfb.h
-gdk/gdkwayland.h
-gdk-pixbuf/gdk-pixbuf.h
-Gestalt.h
-getopt.h
-glibconfig.h
-glib.h
-glib-object.h
-glob.h
-gmodule.h
-gnome.h
-gnu/libc-version.h
-gps.h
-grp.h
-gssapi_generic.h
-gssapi/gssapi_generic.h
-gssapi/gssapi.h
-gssapi.h
-gtk/gtk.h
-gtk/gtkx.h
-gtk/gtkunixprint.h
-#ifdef ANDROID
-gui/BufferQueue.h
-gui/ConsumerBase.h
-gui/GraphicBufferAlloc.h
-gui/IConsumerListener.h
-gui/IGraphicBufferAlloc.h
-gui/IGraphicBufferProducer.h
-gui/ISurfaceComposer.h
-gui/ISurfaceComposerClient.h
-gui/ISurfaceTexture.h
-gui/Surface.h
-gui/SurfaceComposerClient.h
-gui/SurfaceTextureClient.h
-hardware/audio.h
-hardware/gralloc.h
-hardware/hardware.h
-hardware/hwcomposer.h
-hardware/lights.h
-hardware/power.h
-hardware_legacy/power.h
-hardware_legacy/uevent.h
-hardware_legacy/vibrator.h
-#endif
-HIToolbox/HIToolbox.h
-hlink.h
-#ifdef ANDROID
-HTTPBase.h
-#endif
-ia64/sys/inline.h
-Icons.h
-iconv.h
-ieeefp.h
-ifaddrs.h
-image.h
-imagehlp.h
-imm.h
-initguid.h
-initializer_list
-InterfaceDefs.h
-InternetConfig.h
-IntlResources.h
-ints.h
-intshcut.h
-inttypes.h
-iodef.h
-io.h
-IOKit/IOKitLib.h
-IOKit/IOMessage.h
-IOKit/pwr_mgt/IOPMLib.h
-iomanip
-iostream.h
-#if MOZ_JACK==1
-jack/jack.h
-jack/statistics.h
-#endif
-JavaControl.h
-JavaEmbedding/JavaControl.h
-JavaVM/jni.h
-JManager.h
-JNIEnvTests.h
-jni.h
-#if MOZ_SYSTEM_JPEG==1
-jpeglib.h
-#endif
-JVMManagerTests.h
-Kerberos/Kerberos.h
-kernel/image.h
-kernel/OS.h
-LAction.h
-langinfo.h
-LApplication.h
-LArray.h
-LArrayIterator.h
-LAttachable.h
-LAttachment.h
-LaunchServices.h
-lber.h
-LBroadcaster.h
-LButton.h
-lcache.h
-LCaption.h
-LCheckBox.h
-LCicnButton.h
-LClipboard.h
-LCommander.h
-LComparator.h
-LControl.h
-ldap.h
-ldaplog.h
-ldappr.h
-ldap_ssl.h
-LDataStream.h
-ldfcn.h
-LDialogBox.h
-ldif.h
-LDocApplication.h
-LDocument.h
-LDragAndDrop.h
-LDragTask.h
-LEditField.h
-LEditText.h
-LEventDispatcher.h
-LFile.h
-LFileStream.h
-LFileTypeList.h
-LFocusBox.h
-LGrafPortView.h
-LHandleStream.h
-libc_r.h
-libelf.h
-libelf/libelf.h
-libgen.h
-libgnome/gnome-url.h
-libgnome/libgnome.h
-libgnomeui/gnome-icon-lookup.h
-libgnomeui/gnome-icon-theme.h
-libgnomeui/gnome-ui-init.h
-limits.h
-link.h
-#ifdef ANDROID
-linux/android_alarm.h
-linux/ashmem.h
-#endif
-linux/ioprio.h
-linux/kernel.h
-linux/limits.h
-linux/rtc.h
-linux/version.h
-List.h
-Lists.h
-LListBox.h
-LListener.h
-LMenuBar.h
-LMenu.h
-LModelDirector.h
-LModelObject.h
-LModelProperty.h
-loader.h
-locale
-locale.h
-LOffscreenView.h
-logkeys.h
-logstrng.h
-Looper.h
-LowMem.h
-LPane.h
-LPeriodical.h
-LPicture.h
-LPlaceHolder.h
-LPrintout.h
-LProgressBar.h
-LPushButton.h
-LRadioGroup.h
-LRadioGroupView.h
-LRunArray.h
-LScroller.h
-LSharable.h
-LSingleDoc.h
-LStaticText.h
-LStdControl.h
-LStream.h
-LString.h
-LTabGroup.h
-LTabGroupView.h
-LTableArrayStorage.h
-LTableMonoGeometry.h
-LTableSingleSelector.h
-LTableView.h
-LTextEditView.h
-LTextTableView.h
-LUndoer.h
-LVariableArray.h
-LView.h
-LWindow.h
-m68881.h
-MacErrors.h
-MacHeadersCarbon.h
-machine/ansi.h
-machine/builtins.h
-machine/clock.h
-machine/endian.h
-machine/frame.h
-machine/inline.h
-machine/limits.h
-machine/signal.h
-machine/trap.h
-mach/mach_host.h
-mach/mach_init.h
-mach/mach_interface.h
-mach/mach_port.h
-mach-o/dyld.h
-MacLocales.h
-MacMemory.h
-MacTCP.h
-MacTypes.h
-MacWindows.h
-malloc.h
-malloc_np.h
-mapicode.h
-mapidefs.h
-mapiguid.h
-mapi.h
-mapitags.h
-mapiutil.h
-mapix.h
-Math64.h
-math.h
-mbstring.h
-#ifdef ANDROID
-android/native_window.h
-android/native_window_jni.h
-media/AudioEffect.h
-media/AudioSystem.h
-media/ICrypto.h
-media/IOMX.h
-media/MediaProfiles.h
-media/MediaRecorderBase.h
-media/openmax/OMX_Audio.h
-media/stagefright/AACWriter.h
-media/stagefright/AMRWriter.h
-media/stagefright/AudioSource.h
-media/stagefright/DataSource.h
-media/stagefright/foundation/ABase.h
-media/stagefright/foundation/ABitReader.h
-media/stagefright/foundation/ABuffer.h
-media/stagefright/foundation/ADebug.h
-media/stagefright/foundation/AHandler.h
-media/stagefright/foundation/AHandlerReflector.h
-media/stagefright/foundation/ALooper.h
-media/stagefright/foundation/AMessage.h
-media/stagefright/foundation/AString.h
-media/stagefright/foundation/base64.h
-media/stagefright/foundation/hexdump.h
-media/stagefright/MediaBuffer.h
-media/stagefright/MediaBufferGroup.h
-media/stagefright/MediaCodec.h
-media/stagefright/MediaCodecList.h
-media/stagefright/MediaCodecSource.h
-media/stagefright/MediaDefs.h
-media/stagefright/MediaErrors.h
-media/stagefright/MediaExtractor.h
-media/stagefright/MediaSource.h
-media/stagefright/MediaWriter.h
-media/stagefright/MetaData.h
-media/stagefright/MPEG2TSWriter.h
-media/stagefright/MPEG4Writer.h
-media/stagefright/OMXClient.h
-media/stagefright/OMXCodec.h
-media/stagefright/openmax/OMX_Core.h
-media/stagefright/openmax/OMX_Index.h
-media/stagefright/openmax/OMX_IVCommon.h
-media/stagefright/openmax/OMX_Types.h
-media/stagefright/openmax/OMX_Video.h
-media/stagefright/Utils.h
-#endif
-mem.h
-memory.h
-Memory.h
-MenuBar.h
-Menu.h
-Menus.h
-Message.h
-Mime.h
-MixedMode.h
-mlang.h
-mmsystem.h
-model.h
-Movies.h
-mpw/errno.h
-mshtmhst.h
-mshtml.h
-mswsock.h
-Multiprocessing.h
-mutex.h
-Navigation.h
-ncompat.h
-ncurses.h
-netCore.h
-netdb.h
-net/if.h
-netinet/in.h
-netinet/in_systm.h
-netinet/tcp.h
-newexe.h
-new.h
-nl_types.h
-NodeInfo.h
-nsswitch.h
-objbase.h
-objidl.h
-Objsafe.h
-ojiapitests.h
-ole2.h
-oleidl.h
-#ifdef ANDROID
-OMX.h
-OMX_Component.h
-#endif
-OpenGL/OpenGL.h
-OpenTptInternet.h
-OpenTransport.h
-OS.h
-osreldate.h
-OSUtils.h
-Packages.h
-Palettes.h
-PALM_CMN.H
-pango/pango-modules.h
-pango/pangocairo.h
-pango/pangofc-decoder.h
-pango/pangofc-font.h
-pango/pangofc-fontmap.h
-pango/pango-break.h
-pango/pango-fontmap.h
-pango/pango.h
-pango/pangoxft.h
-pango/pango-utils.h
-pascal.h
-Patches.h
-Path.h
-pcfs/pc_dir.h
-Pgenerr.h
-PGenErr.h
-Ph.h
-PLStringFuncs.h
-PMApplication.h
-pmddim.h
-poll.h
-Polygon.h
-port.h
-portable.h
-Power.h
-PP_ClassHeaders.cp
-PP_Constants.h
-PPCToolbox.h
-PP_DebugHeaders.cp
-PP_KeyCodes.h
-PP_Macros.h
-PP_Messages.h
-PP_Prefix.h
-PP_Resources.h
-PP_Types.h
-Printing.h
-Print/PMPrintingDialogExtensions.h
-#ifdef ANDROID
-private/android_filesystem_config.h
-private/qucomextra_p.h
-#endif
-Processes.h
-process.h
-Process.h
-proto/dos.h
-proto/exec.h
-psap.h
-Pt.h
-pthread.h
-pthread_np.h
-pulse/pulseaudio.h
-pwd.h
-Python.h
-QDOffscreen.h
-queue
-Quickdraw.h
-QuickDraw.h
-QuickTimeComponents.h
-quipu/attr.h
-regex.h
-Region.h
-resolv.h
-Resources.h
-Retrace.h
-rld_interface.h
-Roster.h
-rpc.h
-rpcproxy.h
-rpc/types.h
-sane/sane.h
-sane/sanei.h
-sane/saneopts.h
-sanitizer/asan_interface.h
-sched.h
-Scrap.h
-Screen.h
-Script.h
-ScrollBar.h
-sec.h
-secrng.h
-security.h
-secutil.h
-semaphore.h
-servprov.h
-setjmp.h
-SFNTLayoutTypes.h
-SFNTTypes.h
-sha1.h
-share.h
-shellapi.h
-shlguid.h
-shlobj.h
-sigcontext.h
-signal.h
-SimpleGameSound.h
-SIOUX.h
-size_t.h
-sndio.h
-someincludefile.h
-Sound.h
-soundcard.h
-sqlite3.h
-sstream
-#ifdef ANDROID
-stagefright/AACWriter.h
-stagefright/AMRWriter.h
-stagefright/AudioSource.h
-stagefright/DataSource.h
-stagefright/foundation/ABase.h
-stagefright/foundation/ABitReader.h
-stagefright/foundation/ABuffer.h
-stagefright/foundation/ADebug.h
-stagefright/foundation/AHandler.h
-stagefright/foundation/AHandlerReflector.h
-stagefright/foundation/ALooper.h
-stagefright/foundation/AMessage.h
-stagefright/foundation/AString.h
-stagefright/foundation/base64.h
-stagefright/foundation/hexdump.h
-stagefright/MediaBuffer.h
-stagefright/MediaBufferGroup.h
-stagefright/MediaCodec.h
-stagefright/MediaDefs.h
-stagefright/MediaErrors.h
-stagefright/MediaExtractor.h
-stagefright/MediaSource.h
-stagefright/MediaWriter.h
-stagefright/MetaData.h
-stagefright/MPEG2TSWriter.h
-stagefright/MPEG4Writer.h
-stagefright/OMXCodec.h
-stagefright/OMXClient.h
-stagefright/openmax/OMX_Component.h
-stagefright/openmax/OMX_Core.h
-stagefright/openmax/OMX_Index.h
-stagefright/openmax/OMX_IVCommon.h
-stagefright/openmax/OMX_Types.h
-stagefright/openmax/OMX_Video.h
-stagefright/Utils.h
-#endif
-StandardFile.h
-starlet.h
-stat.h
-statreg.cpp
-statreg.h
-stdarg.h
-stdbool.h
-stddef.h
-stdint.h
-stdio.h
-stdlib.h
-storage/FindDirectory.h
-StorageKit.h
-StringCompare.h
-string.h
-String.h
-strings.h
-Strings.h
-StringView.h
-stropts.h
-strstrea.h
-structs.h
-stsdef.h
-SupportDefs.h
-support/String.h
-support/SupportDefs.h
-support/TLS.h
-#ifdef ANDROID
-suspend/autosuspend.h
-#endif
-svrcore.h
-symconst.h
-sym.h
-synch.h
-syncmgr.h
-sys/atomic_op.h
-sys/auxv.h
-sys/bitypes.h
-sys/byteorder.h
-syscall.h
-sys/cdefs.h
-sys/cfgodm.h
-sys/elf.h
-sys/endian.h
-sys/epoll.h
-sys/errno.h
-sys/eventfd.h
-sys/fault.h
-sys/fcntl.h
-sys/file.h
-sys/filio.h
-sys/frame.h
-sys/immu.h
-sys/inotify.h
-sys/inttypes.h
-sys/ioccom.h
-sys/ioctl.h
-sys/ipc.h
-sys/klog.h
-sys/ldr.h
-sys/link.h
-sys/locking.h
-syslog.h
-sys/lwp.h
-sys/machine.h
-sys/mman.h
-sys/mmu.h
-sys/mount.h
-sys/mpctl.h
-sys/param.h
-sys/pda.h
-sys/poll.h
-sys/ppc.h
-sys/prctl.h
-sys/priv.h
-sys/procfs.h
-sys/pstat.h
-sys/ptrace.h
-sys/queue.h
-sys/quota.h
-sys/reboot.h
-sys/reg.h
-sys/regset.h
-sys/resource.h
-sys/sched.h
-sys/select.h
-sys/sem.h
-sys/sendfile.h
-sys/shm.h
-sys/siginfo.h
-sys/signal.h
-sys/socket.h
-sys/sockio.h
-sys/sparc/frame.h
-sys/stack.h
-sys/statfs.h
-sys/stat.h
-sys/statvfs.h
-sys/syscall.h
-sys/sysctl.h
-sys/sysinfo.h
-sys/sysmacros.h
-sys/sysmp.h
-sys/syssgi.h
-sys/system_properties.h
-sys/systeminfo.h
-sys/timeb.h
-sys/time.h
-sys/times.h
-sys/ttycom.h
-sys/types.h
-sys/ucontext.h
-sys/uio.h
-sys/un.h
-sys/unistd.h
-sys/utsname.h
-sys/vfs.h
-sys/wait.h
-#ifdef ANDROID
-sysutils/NetlinkEvent.h
-system/audio.h
-system/graphics.h
-system/window.h
-#endif
-tables.h
-TArray.h
-TArrayIterator.h
-task.h
-tchar.h
-TCHAR.H
-termios.h
-TextCommon.h
-TextEdit.h
-TextEncodingConverter.h
-TextServices.h
-TextUtils.h
-TextView.h
-th/PCR_Th.h
-thread.h
-ThreadManagerTests.h
-Threads.h
-time.h
-Timer.h
-tlhelp32.h
-ToolUtils.h
-tr1/functional
-trace.h
-Traps.h
-typeinfo
-types.h
-Types.h
-UAppleEventsMgr.h
-UAttachments.h
-ucontext.h
-uconv.h
-UCursor.h
-ucx$inetdef.h
-UDebugging.h
-UDesktop.h
-UDrawingState.h
-UDrawingUtils.h
-UEnvironment.h
-UEventMgr.h
-UException.h
-UExtractFromAEDesc.h
-UGWorld.h
-#ifdef ANDROID
-ui/ANativeObjectBase.h
-ui/egl/android_natives.h
-ui/Fence.h
-ui/FramebufferNativeWindow.h
-ui/GraphicBuffer.h
-ui/Rect.h
-ui/Region.h
-#endif
-UKeyFilters.h
-ulocks.h
-ulserrno.h
-UMemoryMgr.h
-UModalDialogs.h
-UNavServicesDialogs.h
-UnicodeBlockObjects.h
-UnicodeConverter.h
-UnicodeUtilities.h
-unidef.h
-unikbd.h
-unistd.h
-unix.h
-unixio.h
-unknwn.h
-UPrinting.h
-UQuickTime.h
-UReanimator.h
-URegions.h
-URegistrar.h
-UResourceMgr.h
-#ifdef ANDROID
-utils/BitSet.h
-utils/CallStack.h
-utils/Errors.h
-utils/FileMap.h
-utils/KeyedVector.h
-utils/List.h
-utils/Log.h
-utils/Looper.h
-utils/PropertyMap.h
-utils/RefBase.h
-utils/String16.h
-utils/String8.h
-utils/threads.h
-utils/TextOutput.h
-utils/Timers.h
-utils/Trace.h
-utils/TypeHelpers.h
-utils/Unicode.h
-utils/Vector.h
-utils/VectorImpl.h
-#endif
-urlhist.h
-urlmon.h
-UScrap.h
-UScreenPort.h
-UTCUtils.h
-UTETextAction.h
-UTEViewTextAction.h
-UTextEdit.h
-UTextTraits.h
-utime.h
-UWindows.h
-values.h
-varargs.h
-vcclr.h
-View.h
-Volume.h
-#ifdef ANDROID
-vr/gvr/capi/include/gvr.h
-vr/gvr/capi/include/gvr_controller.h
-#endif
-wab.h
-wait.h
-wchar.h
-wctype.h
-winbase.h
-win/compobj.h
-windef.h
-Window.h
-windows.h
-Windows.h
-windowsx.h
-Wininet.h
-winnls.h
-winperf.h
-winreg.h
-Winreg.h
-winsock2.h
-winsock.h
-winspool.h
-winsvc.h
-winuser.h
-winver.h
-wmem.h
-workbench/startup.h
-wtypes.h
-wx/image.h
-wx/listctrl.h
-wx/log.h
-wx/toolbar.h
-wx/wx.h
-wx/xrc/xmlres.h
-xcb/xcb.h
-xcb/shm.h
-X11/cursorfont.h
-X11/extensions/Print.h
-X11/extensions/shape.h
-X11/extensions/scrnsaver.h
-X11/extensions/XShm.h
-X11/extensions/Xrender.h
-X11/extensions/Xfixes.h
-X11/extensions/Xdamage.h
-X11/extensions/Xcomposite.h
-X11/ImUtil.h
-X11/Intrinsic.h
-X11/keysymdef.h
-X11/keysym.h
-X11/Shell.h
-X11/StringDefs.h
-X11/Xatom.h
-X11/Xft/Xft.h
-X11/Xfuncproto.h
-X11/X.h
-X11/XKBlib.h
-X11/Xlib.h
-X11/Xlibint.h
-X11/Xlib-xcb.h
-X11/Xlocale.h
-X11/Xos.h
-X11/Xutil.h
-zmouse.h
-soundtouch/SoundTouch.h
-soundtouch/SoundTouchFactory.h
-#if MOZ_LIBAV_FFT==1
-libavcodec/avfft.h
-#endif
-#if MOZ_SYSTEM_PNG==1
-png.h
-#endif
-#if MOZ_SYSTEM_ZLIB==1
-zlib.h
-#endif
-#ifdef MOZ_ENABLE_STARTUP_NOTIFICATION
-libsn/sn.h
-libsn/sn-common.h
-libsn/sn-launchee.h
-libsn/sn-launcher.h
-libsn/sn-monitor.h
-libsn/sn-util.h
-#endif
-#if MOZ_SYSTEM_HUNSPELL==1
-hunspell.hxx
-#endif
-#if MOZ_SYSTEM_BZ2==1
-bzlib.h
-#endif
-gio/gio.h
-#if MOZ_SYSTEM_LIBEVENT==1
-event.h
-event2/event.h
-event2/event_compat.h
-event2/event_struct.h
-#else
-sys/event.h
-#endif
-#ifdef MOZ_ENABLE_LIBPROXY
-proxy.h
-#endif
-#ifdef MOZ_ENABLE_CONTENTMANAGER
-SelectSingleContentItemPage.h
-SelectMultipleContentItemsPage.h
-QtSparql/qsparqlconnection.h
-QtSparql/qsparqlquery.h
-QtSparql/qsparqlresult.h
-#endif
-
-#if MOZ_TREE_PIXMAN!=1
-pixman.h
-#endif
-#if MOZ_SYSTEM_LIBVPX==1
-vpx/svc_context.h
-vpx/vpx_codec.h
-vpx/vpx_decoder.h
-vpx/vpx_encoder.h
-vpx/vp8cx.h
-vpx/vp8dx.h
-vpx_mem/vpx_mem.h
-#endif
-gst/gst.h
-gst/app/gstappsink.h
-gst/app/gstappsrc.h
-gst/video/video.h
-sys/msg.h
-sys/ipc.h
-sys/thr.h
-sys/user.h
-kvm.h
-spawn.h
-err.h
-xlocale.h
-#ifdef MOZ_SYSTEM_ICU
-unicode/locid.h
-unicode/numsys.h
-unicode/plurrule.h
-unicode/timezone.h
-unicode/ucal.h
-unicode/uchar.h
-unicode/uclean.h
-unicode/ucol.h
-unicode/udat.h
-unicode/udatpg.h
-unicode/udisplaycontext.h
-unicode/uenum.h
-unicode/unistr.h
-unicode/unorm.h
-unicode/unum.h
-unicode/upluralrules.h
-unicode/ureldatefmt.h
-unicode/ustring.h
-unicode/utypes.h
-#endif
-libutil.h
-unwind.h
-fenv.h
new file mode 100644
--- /dev/null
+++ b/config/system-headers.mozbuild
@@ -0,0 +1,1346 @@
+# -*- 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/.
+
+system_headers = [
+    'A4Stuff.h',
+    'activscp.h',
+    'AEDataModel.h',
+    'AEObjects.h',
+    'AEPackObject.h',
+    'AERegistry.h',
+    'AEUtils.h',
+    'afxcmn.h',
+    'afxcoll.h',
+    'afxcview.h',
+    'afxdisp.h',
+    'afxdtctl.h',
+    'afxext.h',
+    'afxmt.h',
+    'afxpriv.h',
+    'afxtempl.h',
+    'afxwin.h',
+    'Aliases.h',
+    'all.h',
+    'alloca.h',
+    'alloc.h',
+    'alsa/asoundlib.h',
+    'ansi_parms.h',
+    'a.out.h',
+    'app/Cursor.h',
+    'Appearance.h',
+    'AppFileInfo.h',
+    'AppKit.h',
+    'AppleEvents.h',
+    'Application.h',
+    'app/Message.h',
+    'app/MessageRunner.h',
+    'arpa/inet.h',
+    'arpa/nameser.h',
+    'array',
+    'asm/page.h',
+    'asm/sigcontext.h',
+    'asm/signal.h',
+    'ASRegistry.h',
+    'assert.h',
+    'atk/atk.h',
+    'atlcom.h',
+    'atlconv.h',
+    'atlctl.cpp',
+    'atlctl.h',
+    'ATLCTL.H',
+    'atlhost.h',
+    'atlimpl.cpp',
+    'atlwin.cpp',
+    'atomic.h',
+    'ATSTypes.h',
+    'ATSUnicode.h',
+    'Balloons.h',
+    'base64.h',
+    'base/pblock.h',
+    'base/PCR_Base.h',
+    'base/session.h',
+    'basetyps.h',
+    'be/app/Application.h',
+    'Beep.h',
+    'be/kernel/image.h',
+    'be/kernel/OS.h',
+    'bfd.h',
+    'Bitmap.h',
+    'bitset',
+    'blapi.h',
+    'blapit.h',
+    'bsd/libc.h',
+    'bsd/syscall.h',
+    'bstring.h',
+    'builtin.h',
+    'Button.h',
+    'byteswap.h',
+    'cairo-atsui.h',
+    'cairo-beos.h',
+    'cairo-directfb.h',
+    'cairo-ft.h',
+    'cairo-glitz.h',
+    'cairo-gobject.h',
+    'cairo.h',
+    'cairo-pdf.h',
+    'cairo-ps.h',
+    'cairo-qpainter.h',
+    'cairo-qt.h',
+    'cairo-quartz.h',
+    'cairo-tee.h',
+    'cairo-win32.h',
+    'cairo-xlib.h',
+    'cairo-xlib-xrender.h',
+    'callconv.h',
+    'Carbon/Carbon.h',
+    'CarbonEvents.h',
+    'Carbon.h',
+    'c_asm.h',
+    'cctype',
+    'cderr.h',
+    'cerrno',
+    'certdb.h',
+    'cert.h',
+    'certt.h',
+    'CFBase.h',
+    'CFBundle.h',
+    'CFData.h',
+    'CFDictionary.h',
+    'cf.h',
+    'CFNumber.h',
+    'CFPlugIn.h',
+    'CFPreferences.h',
+    'CFString.h',
+    'CFURL.h',
+    'CGAffineTransform.h',
+    'CheckBox.h',
+    'ciferfam.h',
+    'Clipboard.h',
+    'cmmf.h',
+    'cmmft.h',
+    'cmplrs/stsupport.h',
+    'cms.h',
+    'cmsreclist.h',
+    'cmst.h',
+    'Cocoa/Cocoa.h',
+    'CodeFragments.h',
+    'comdef.h',
+    'commctrl.h',
+    'COMMCTRL.H',
+    'commdlg.h',
+    'compat.h',
+    'complex',
+    'condapi.h',
+    'ConditionalMacros.h',
+    'conio.h',
+    'console.h',
+    'ControlDefinitions.h',
+    'Controls.h',
+    'CoreFoundation/CoreFoundation.h',
+    'CoreServices/CoreServices.h',
+    'CPalmRec.cpp',
+    'Cpalmrec.h',
+    'CPCatgry.cpp',
+    'CPDbBMgr.h',
+    'CPString.cpp',
+    'CPString.h',
+    'crmf.h',
+    'crmft.h',
+    'crtdbg.h',
+    'crt_externs.h',
+    'crypt.h',
+    'cryptohi.h',
+    'cryptoht.h',
+    'cstddef',
+    'ctime',
+    'ctype.h',
+    'curl/curl.h',
+    'curl/easy.h',
+    'curses.h',
+    'cxxabi.h',
+    'DateTimeUtils.h',
+    'dbus/dbus-glib.h',
+    'dbus/dbus-glib-lowlevel.h',
+    'dbus/dbus.h',
+    'ddeml.h',
+    'Debug.h',
+    'dem.h',
+    'descrip.h',
+    'Devices.h',
+    'dfb_types.h',
+    'dfiff.h',
+    'dgiff.h',
+    'Dialogs.h',
+    'direct/build.h',
+    'direct/clock.h',
+    'direct/conf.h',
+    'direct/debug.h',
+    'direct/direct.h',
+    'directfb_keyboard.h',
+    'directfb_strings.h',
+    'direct.h',
+    'direct/hash.h',
+    'direct/interface.h',
+    'direct/interface_implementation.h',
+    'direct/list.h',
+    'direct/log.h',
+    'direct/memcpy.h',
+    'direct/mem.h',
+    'direct/messages.h',
+    'direct/modules.h',
+    'direct/serial.h',
+    'direct/signals.h',
+    'direct/stream.h',
+    'direct/system.h',
+    'direct/thread.h',
+    'direct/trace.h',
+    'direct/tree.h',
+    'direct/types.h',
+    'direct/utf8.h',
+    'direct/util.h',
+    'dirent.h',
+    'DiskInit.h',
+    'dlfcn.h',
+    'dlgs.h',
+    'dl.h',
+    'docobj.h',
+    'dos/dosextens.h',
+    'dos.h',
+    'Drag.h',
+    'DriverServices.h',
+    'DriverSynchronization.h',
+    'DropInPanel.h',
+    'dvidef.h',
+    'ecl-exp.h',
+    'elf.h',
+    'endian.h',
+    'Entry.h',
+    'err.h',
+    'errno.h',
+    'Errors.h',
+    'Events.h',
+    'exception',
+    'exdisp.h',
+    'ExDisp.h',
+    'exe386.h',
+    'execinfo.h',
+    'extras.h',
+    'fcntl.h',
+    'features.h',
+    'fenv.h',
+    'ffi.h',
+    'fibdef.h',
+    'File.h',
+    'filehdr.h',
+    'files.h',
+    'Files.h',
+    'FindDirectory.h',
+    'Finder.h',
+    'FinderRegistry.h',
+    'FixMath.h',
+    'float.h',
+    'fnmatch.h',
+    'Folders.h',
+    'fontconfig/fcfreetype.h',
+    'fontconfig/fontconfig.h',
+    'Font.h',
+    'Fonts.h',
+    'fp.h',
+    'fpieee.h',
+    'frame/log.h',
+    'frame/req.h',
+    'freetype/freetype.h',
+    'freetype/ftadvanc.h',
+    'freetype/ftbitmap.h',
+    'freetype/ftcache.h',
+    'freetype/ftfntfmt.h',
+    'freetype/ftglyph.h',
+    'freetype/ftlcdfil.h',
+    'freetype/ftoutln.h',
+    'freetype/ftsizes.h',
+    'freetype/ftsynth.h',
+    'freetype/ftxf86.h',
+    'freetype.h',
+    'freetype/t1tables.h',
+    'freetype/ttnameid.h',
+    'freetype/tttables.h',
+    'fribidi/fribidi.h',
+    'FSp_fopen.h',
+    'fstream',
+    'fstream.h',
+    'ft2build.h',
+    'ftadvanc.h',
+    'ftbitmap.h',
+    'ftcache.h',
+    'ftfntfmt.h',
+    'ftglyph.h',
+    'ftlcdfil.h',
+    'ftoutln.h',
+    'fts.h',
+    'ftsizes.h',
+    'ftsynth.h',
+    'ftxf86.h',
+    'fusion/arena.h',
+    'fusion/build.h',
+    'fusion/call.h',
+    'fusion/conf.h',
+    'fusion/fusion.h',
+    'fusion/fusion_internal.h',
+    'fusion/hash.h',
+    'fusion/lock.h',
+    'fusion/object.h',
+    'fusion/property.h',
+    'fusion/protocol.h',
+    'fusion/reactor.h',
+    'fusion/ref.h',
+    'fusion/shmalloc.h',
+    'fusion/shm/pool.h',
+    'fusion/shm/shm.h',
+    'fusion/shm/shm_internal.h',
+    'fusion/types.h',
+    'fusion/vector.h',
+    'gconf/gconf-client.h',
+    'Gdiplus.h',
+    'gdk/gdkdirectfb.h',
+    'gdk/gdk.h',
+    'gdk/gdkkeysyms.h',
+    'gdk/gdkprivate.h',
+    'gdk/gdkwayland.h',
+    'gdk/gdkx.h',
+    'gdk-pixbuf/gdk-pixbuf.h',
+    'Gestalt.h',
+    'getopt.h',
+    'gio/gio.h',
+    'glibconfig.h',
+    'glib.h',
+    'glib-object.h',
+    'glob.h',
+    'gmodule.h',
+    'gnome.h',
+    'gnu/libc-version.h',
+    'gps.h',
+    'grp.h',
+    'gssapi_generic.h',
+    'gssapi/gssapi_generic.h',
+    'gssapi/gssapi.h',
+    'gssapi.h',
+    'gst/app/gstappsink.h',
+    'gst/app/gstappsrc.h',
+    'gst/gst.h',
+    'gst/video/video.h',
+    'gtk/gtk.h',
+    'gtk/gtkunixprint.h',
+    'gtk/gtkx.h',
+    'hasht.h',
+    'HIToolbox/HIToolbox.h',
+    'hlink.h',
+    'ia64/sys/inline.h',
+    'Icons.h',
+    'iconv.h',
+    'ieeefp.h',
+    'ifaddrs.h',
+    'image.h',
+    'imagehlp.h',
+    'imm.h',
+    'initguid.h',
+    'initializer_list',
+    'InterfaceDefs.h',
+    'InternetConfig.h',
+    'IntlResources.h',
+    'ints.h',
+    'intshcut.h',
+    'inttypes.h',
+    'iodef.h',
+    'io.h',
+    'IOKit/IOKitLib.h',
+    'IOKit/IOMessage.h',
+    'IOKit/pwr_mgt/IOPMLib.h',
+    'iomanip',
+    'iostream.h',
+    'jar-ds.h',
+    'jarfile.h',
+    'jar.h',
+    'JavaControl.h',
+    'JavaEmbedding/JavaControl.h',
+    'JavaVM/jni.h',
+    'JManager.h',
+    'JNIEnvTests.h',
+    'jni.h',
+    'JVMManagerTests.h',
+    'Kerberos/Kerberos.h',
+    'kernel/image.h',
+    'kernel/OS.h',
+    'key.h',
+    'keyhi.h',
+    'keyt.h',
+    'keythi.h',
+    'kvm.h',
+    'LAction.h',
+    'langinfo.h',
+    'LApplication.h',
+    'LArray.h',
+    'LArrayIterator.h',
+    'LAttachable.h',
+    'LAttachment.h',
+    'LaunchServices.h',
+    'lber.h',
+    'LBroadcaster.h',
+    'LButton.h',
+    'lcache.h',
+    'LCaption.h',
+    'LCheckBox.h',
+    'LCicnButton.h',
+    'LClipboard.h',
+    'LCommander.h',
+    'LComparator.h',
+    'LControl.h',
+    'ldap.h',
+    'ldaplog.h',
+    'ldappr.h',
+    'ldap_ssl.h',
+    'LDataStream.h',
+    'ldfcn.h',
+    'LDialogBox.h',
+    'ldif.h',
+    'LDocApplication.h',
+    'LDocument.h',
+    'LDragAndDrop.h',
+    'LDragTask.h',
+    'LEditField.h',
+    'LEditText.h',
+    'LEventDispatcher.h',
+    'LFile.h',
+    'LFileStream.h',
+    'LFileTypeList.h',
+    'LFocusBox.h',
+    'LGrafPortView.h',
+    'LHandleStream.h',
+    'libc_r.h',
+    'libelf.h',
+    'libelf/libelf.h',
+    'libgen.h',
+    'libgnome/gnome-url.h',
+    'libgnome/libgnome.h',
+    'libgnomeui/gnome-icon-lookup.h',
+    'libgnomeui/gnome-icon-theme.h',
+    'libgnomeui/gnome-ui-init.h',
+    'libutil.h',
+    'limits.h',
+    'link.h',
+    'linux/ioprio.h',
+    'linux/kernel.h',
+    'linux/limits.h',
+    'linux/rtc.h',
+    'linux/version.h',
+    'List.h',
+    'Lists.h',
+    'LListBox.h',
+    'LListener.h',
+    'LMenuBar.h',
+    'LMenu.h',
+    'LModelDirector.h',
+    'LModelObject.h',
+    'LModelProperty.h',
+    'loader.h',
+    'locale',
+    'locale.h',
+    'LOffscreenView.h',
+    'logkeys.h',
+    'logstrng.h',
+    'Looper.h',
+    'LowMem.h',
+    'LPane.h',
+    'LPeriodical.h',
+    'LPicture.h',
+    'LPlaceHolder.h',
+    'LPrintout.h',
+    'LProgressBar.h',
+    'LPushButton.h',
+    'LRadioGroup.h',
+    'LRadioGroupView.h',
+    'LRunArray.h',
+    'LScroller.h',
+    'LSharable.h',
+    'LSingleDoc.h',
+    'LStaticText.h',
+    'LStdControl.h',
+    'LStream.h',
+    'LString.h',
+    'LTabGroup.h',
+    'LTabGroupView.h',
+    'LTableArrayStorage.h',
+    'LTableMonoGeometry.h',
+    'LTableSingleSelector.h',
+    'LTableView.h',
+    'LTextEditView.h',
+    'LTextTableView.h',
+    'LUndoer.h',
+    'LVariableArray.h',
+    'LView.h',
+    'LWindow.h',
+    'm68881.h',
+    'MacErrors.h',
+    'MacHeadersCarbon.h',
+    'machine/ansi.h',
+    'machine/builtins.h',
+    'machine/clock.h',
+    'machine/endian.h',
+    'machine/frame.h',
+    'machine/inline.h',
+    'machine/limits.h',
+    'machine/signal.h',
+    'machine/trap.h',
+    'mach/mach_host.h',
+    'mach/mach_init.h',
+    'mach/mach_interface.h',
+    'mach/mach_port.h',
+    'mach-o/dyld.h',
+    'MacLocales.h',
+    'MacMemory.h',
+    'MacTCP.h',
+    'MacTypes.h',
+    'MacWindows.h',
+    'malloc.h',
+    'malloc_np.h',
+    'mapicode.h',
+    'mapidefs.h',
+    'mapiguid.h',
+    'mapi.h',
+    'mapitags.h',
+    'mapiutil.h',
+    'mapix.h',
+    'Math64.h',
+    'math.h',
+    'mbstring.h',
+    'mem.h',
+    'memory.h',
+    'Memory.h',
+    'MenuBar.h',
+    'Menu.h',
+    'Menus.h',
+    'Message.h',
+    'Mime.h',
+    'MixedMode.h',
+    'mlang.h',
+    'mmsystem.h',
+    'model.h',
+    'Movies.h',
+    'mpw/errno.h',
+    'mshtmhst.h',
+    'mshtml.h',
+    'mswsock.h',
+    'Multiprocessing.h',
+    'mutex.h',
+    'Navigation.h',
+    'ncompat.h',
+    'ncurses.h',
+    'netCore.h',
+    'netdb.h',
+    'net/if.h',
+    'netinet/in.h',
+    'netinet/in_systm.h',
+    'netinet/tcp.h',
+    'newexe.h',
+    'new.h',
+    'nl_types.h',
+    'NodeInfo.h',
+    'nspr.h',
+    'nssb64.h',
+    'nssb64t.h',
+    'nssbase.h',
+    'nssbaset.h',
+    'nssck.api',
+    'nssckbi.h',
+    'nssckepv.h',
+    'nssckft.h',
+    'nssckfwc.h',
+    'nssckfw.h',
+    'nssckfwt.h',
+    'nssckg.h',
+    'nssckmdt.h',
+    'nssckt.h',
+    'nss.h',
+    'nssilckt.h',
+    'nssilock.h',
+    'nsslocks.h',
+    'nssrwlk.h',
+    'nssrwlkt.h',
+    'nssutil.h',
+    'nsswitch.h',
+    'objbase.h',
+    'objidl.h',
+    'Objsafe.h',
+    'ocsp.h',
+    'ocspt.h',
+    'ojiapitests.h',
+    'ole2.h',
+    'oleidl.h',
+    'OpenGL/OpenGL.h',
+    'OpenTptInternet.h',
+    'OpenTransport.h',
+    'OS.h',
+    'osreldate.h',
+    'OSUtils.h',
+    'p12.h',
+    'p12plcy.h',
+    'p12t.h',
+    'Packages.h',
+    'Palettes.h',
+    'PALM_CMN.H',
+    'pango/pango-break.h',
+    'pango/pangocairo.h',
+    'pango/pangofc-decoder.h',
+    'pango/pangofc-font.h',
+    'pango/pangofc-fontmap.h',
+    'pango/pango-fontmap.h',
+    'pango/pango.h',
+    'pango/pango-modules.h',
+    'pango/pango-utils.h',
+    'pango/pangoxft.h',
+    'pascal.h',
+    'Patches.h',
+    'Path.h',
+    'pcfs/pc_dir.h',
+    'Pgenerr.h',
+    'PGenErr.h',
+    'Ph.h',
+    'pixman.h',
+    'pk11func.h',
+    'pk11pqg.h',
+    'pk11priv.h',
+    'pk11pub.h',
+    'pk11sdr.h',
+    'pkcs11f.h',
+    'pkcs11.h',
+    'pkcs11n.h',
+    'pkcs11p.h',
+    'pkcs11t.h',
+    'pkcs11u.h',
+    'pkcs12.h',
+    'pkcs12t.h',
+    'pkcs7t.h',
+    'plarena.h',
+    'plarenas.h',
+    'plbase64.h',
+    'plerror.h',
+    'plgetopt.h',
+    'plhash.h',
+    'plstr.h',
+    'PLStringFuncs.h',
+    'PMApplication.h',
+    'pmddim.h',
+    'poll.h',
+    'Polygon.h',
+    'portable.h',
+    'port.h',
+    'portreg.h',
+    'Power.h',
+    'PP_ClassHeaders.cp',
+    'PP_Constants.h',
+    'PPCToolbox.h',
+    'PP_DebugHeaders.cp',
+    'PP_KeyCodes.h',
+    'PP_Macros.h',
+    'PP_Messages.h',
+    'PP_Prefix.h',
+    'PP_Resources.h',
+    'PP_Types.h',
+    'pratom.h',
+    'prbit.h',
+    'prclist.h',
+    'prcmon.h',
+    'prcountr.h',
+    'prcpucfg.h',
+    'prcvar.h',
+    'prdtoa.h',
+    'preenc.h',
+    'prenv.h',
+    'prerr.h',
+    'prerror.h',
+    'prinet.h',
+    'prinit.h',
+    'prinrval.h',
+    'Printing.h',
+    'Print/PMPrintingDialogExtensions.h',
+    'prio.h',
+    'pripcsem.h',
+    'private',
+    'prlink.h',
+    'prlock.h',
+    'prlog.h',
+    'prlong.h',
+    'prmem.h',
+    'prmon.h',
+    'prmwait.h',
+    'prnetdb.h',
+    'Processes.h',
+    'process.h',
+    'Process.h',
+    'prolock.h',
+    'proto/dos.h',
+    'proto/exec.h',
+    'prpdce.h',
+    'prprf.h',
+    'prproces.h',
+    'prrng.h',
+    'prrwlock.h',
+    'prshma.h',
+    'prshm.h',
+    'prsystem.h',
+    'prthread.h',
+    'prtime.h',
+    'prtpool.h',
+    'prtrace.h',
+    'prtypes.h',
+    'prvrsion.h',
+    'prwin16.h',
+    'psap.h',
+    'Pt.h',
+    'pthread.h',
+    'pthread_np.h',
+    'pulse/pulseaudio.h',
+    'pwd.h',
+    'Python.h',
+    'QDOffscreen.h',
+    'queue',
+    'Quickdraw.h',
+    'QuickDraw.h',
+    'QuickTimeComponents.h',
+    'quipu/attr.h',
+    'regex.h',
+    'Region.h',
+    'resolv.h',
+    'Resources.h',
+    'Retrace.h',
+    'rld_interface.h',
+    'Roster.h',
+    'rpc.h',
+    'rpcproxy.h',
+    'rpc/types.h',
+    'sane/sane.h',
+    'sane/sanei.h',
+    'sane/saneopts.h',
+    'sanitizer/asan_interface.h',
+    'sched.h',
+    'Scrap.h',
+    'Screen.h',
+    'Script.h',
+    'ScrollBar.h',
+    'secasn1.h',
+    'secasn1t.h',
+    'seccomon.h',
+    'secder.h',
+    'secdert.h',
+    'secdig.h',
+    'secdigt.h',
+    'secerr.h',
+    'sec.h',
+    'sechash.h',
+    'secitem.h',
+    'secmime.h',
+    'secmod.h',
+    'secmodt.h',
+    'secoid.h',
+    'secoidt.h',
+    'secpkcs5.h',
+    'secpkcs7.h',
+    'secport.h',
+    'secrng.h',
+    'security.h',
+    'secutil.h',
+    'semaphore.h',
+    'servprov.h',
+    'setjmp.h',
+    'SFNTLayoutTypes.h',
+    'SFNTTypes.h',
+    'sha1.h',
+    'share.h',
+    'shellapi.h',
+    'shlguid.h',
+    'shlobj.h',
+    'shsign.h',
+    'sigcontext.h',
+    'signal.h',
+    'SimpleGameSound.h',
+    'SIOUX.h',
+    'size_t.h',
+    'smime.h',
+    'sndio.h',
+    'someincludefile.h',
+    'soundcard.h',
+    'Sound.h',
+    'soundtouch/SoundTouchFactory.h',
+    'soundtouch/SoundTouch.h',
+    'spawn.h',
+    'sqlite3.h',
+    'sslerr.h',
+    'ssl.h',
+    'sslproto.h',
+    'sslt.h',
+    'sstream',
+    'StandardFile.h',
+    'starlet.h',
+    'stat.h',
+    'statreg.cpp',
+    'statreg.h',
+    'stdarg.h',
+    'stdbool.h',
+    'stddef.h',
+    'stdint.h',
+    'stdio.h',
+    'stdlib.h',
+    'storage/FindDirectory.h',
+    'StorageKit.h',
+    'StringCompare.h',
+    'string.h',
+    'String.h',
+    'strings.h',
+    'Strings.h',
+    'StringView.h',
+    'stropts.h',
+    'strstrea.h',
+    'structs.h',
+    'stsdef.h',
+    'SupportDefs.h',
+    'support/String.h',
+    'support/SupportDefs.h',
+    'support/TLS.h',
+    'svrcore.h',
+    'symconst.h',
+    'sym.h',
+    'synch.h',
+    'syncmgr.h',
+    'sys/atomic_op.h',
+    'sys/auxv.h',
+    'sys/bitypes.h',
+    'sys/byteorder.h',
+    'syscall.h',
+    'sys/cdefs.h',
+    'sys/cfgodm.h',
+    'sys/elf.h',
+    'sys/endian.h',
+    'sys/epoll.h',
+    'sys/errno.h',
+    'sys/eventfd.h',
+    'sys/fault.h',
+    'sys/fcntl.h',
+    'sys/file.h',
+    'sys/filio.h',
+    'sys/frame.h',
+    'sys/immu.h',
+    'sys/inotify.h',
+    'sys/inttypes.h',
+    'sys/ioccom.h',
+    'sys/ioctl.h',
+    'sys/ipc.h',
+    'sys/klog.h',
+    'sys/ldr.h',
+    'sys/link.h',
+    'sys/locking.h',
+    'syslog.h',
+    'sys/lwp.h',
+    'sys/machine.h',
+    'sys/mman.h',
+    'sys/mmu.h',
+    'sys/mount.h',
+    'sys/mpctl.h',
+    'sys/msg.h',
+    'sys/param.h',
+    'sys/pda.h',
+    'sys/poll.h',
+    'sys/ppc.h',
+    'sys/prctl.h',
+    'sys/priv.h',
+    'sys/procfs.h',
+    'sys/pstat.h',
+    'sys/ptrace.h',
+    'sys/queue.h',
+    'sys/quota.h',
+    'sys/reboot.h',
+    'sys/reg.h',
+    'sys/regset.h',
+    'sys/resource.h',
+    'sys/sched.h',
+    'sys/select.h',
+    'sys/sem.h',
+    'sys/sendfile.h',
+    'sys/shm.h',
+    'sys/siginfo.h',
+    'sys/signal.h',
+    'sys/socket.h',
+    'sys/sockio.h',
+    'sys/sparc/frame.h',
+    'sys/stack.h',
+    'sys/statfs.h',
+    'sys/stat.h',
+    'sys/statvfs.h',
+    'sys/syscall.h',
+    'sys/sysctl.h',
+    'sys/sysinfo.h',
+    'sys/sysmacros.h',
+    'sys/sysmp.h',
+    'sys/syssgi.h',
+    'sys/systeminfo.h',
+    'sys/system_properties.h',
+    'sys/thr.h',
+    'sys/timeb.h',
+    'sys/time.h',
+    'sys/times.h',
+    'sys/ttycom.h',
+    'sys/types.h',
+    'sys/ucontext.h',
+    'sys/uio.h',
+    'sys/un.h',
+    'sys/unistd.h',
+    'sys/user.h',
+    'sys/utsname.h',
+    'sys/vfs.h',
+    'sys/wait.h',
+    't1tables.h',
+    'tables.h',
+    'TArray.h',
+    'TArrayIterator.h',
+    'task.h',
+    'tchar.h',
+    'TCHAR.H',
+    'termios.h',
+    'TextCommon.h',
+    'TextEdit.h',
+    'TextEncodingConverter.h',
+    'TextServices.h',
+    'TextUtils.h',
+    'TextView.h',
+    'th/PCR_Th.h',
+    'thread.h',
+    'ThreadManagerTests.h',
+    'Threads.h',
+    'time.h',
+    'Timer.h',
+    'tlhelp32.h',
+    'ToolUtils.h',
+    'tr1/functional',
+    'trace.h',
+    'Traps.h',
+    'ttnameid.h',
+    'tttables.h',
+    'typeinfo',
+    'types.h',
+    'Types.h',
+    'UAppleEventsMgr.h',
+    'UAttachments.h',
+    'ucontext.h',
+    'uconv.h',
+    'UCursor.h',
+    'UDebugging.h',
+    'UDesktop.h',
+    'UDrawingState.h',
+    'UDrawingUtils.h',
+    'UEnvironment.h',
+    'UEventMgr.h',
+    'UException.h',
+    'UExtractFromAEDesc.h',
+    'UGWorld.h',
+    'UKeyFilters.h',
+    'ulocks.h',
+    'ulserrno.h',
+    'UMemoryMgr.h',
+    'UModalDialogs.h',
+    'UNavServicesDialogs.h',
+    'UnicodeBlockObjects.h',
+    'UnicodeConverter.h',
+    'UnicodeUtilities.h',
+    'unidef.h',
+    'unikbd.h',
+    'unistd.h',
+    'unix.h',
+    'unixio.h',
+    'unknwn.h',
+    'unwind.h',
+    'UPrinting.h',
+    'UQuickTime.h',
+    'UReanimator.h',
+    'URegions.h',
+    'URegistrar.h',
+    'UResourceMgr.h',
+    'urlhist.h',
+    'urlmon.h',
+    'UScrap.h',
+    'UScreenPort.h',
+    'UTCUtils.h',
+    'UTETextAction.h',
+    'UTEViewTextAction.h',
+    'UTextEdit.h',
+    'UTextTraits.h',
+    'utilmodt.h',
+    'utilpars.h',
+    'utilparst.h',
+    'utilrename.h',
+    'utime.h',
+    'UWindows.h',
+    'values.h',
+    'varargs.h',
+    'vcclr.h',
+    'View.h',
+    'Volume.h',
+    'wab.h',
+    'wait.h',
+    'wchar.h',
+    'wctype.h',
+    'winbase.h',
+    'win/compobj.h',
+    'windef.h',
+    'Window.h',
+    'windows.h',
+    'Windows.h',
+    'windowsx.h',
+    'Wininet.h',
+    'winnls.h',
+    'winperf.h',
+    'winreg.h',
+    'Winreg.h',
+    'winsock2.h',
+    'winsock.h',
+    'winspool.h',
+    'winsvc.h',
+    'winuser.h',
+    'winver.h',
+    'wmem.h',
+    'workbench/startup.h',
+    'wtypes.h',
+    'wx/image.h',
+    'wx/listctrl.h',
+    'wx/log.h',
+    'wx/toolbar.h',
+    'wx/wx.h',
+    'wx/xrc/xmlres.h',
+    'X11/cursorfont.h',
+    'X11/extensions/Print.h',
+    'X11/extensions/scrnsaver.h',
+    'X11/extensions/shape.h',
+    'X11/extensions/Xcomposite.h',
+    'X11/extensions/Xdamage.h',
+    'X11/extensions/Xfixes.h',
+    'X11/extensions/Xrender.h',
+    'X11/extensions/XShm.h',
+    'X11/ImUtil.h',
+    'X11/Intrinsic.h',
+    'X11/keysymdef.h',
+    'X11/keysym.h',
+    'X11/Shell.h',
+    'X11/StringDefs.h',
+    'X11/Xatom.h',
+    'X11/Xft/Xft.h',
+    'X11/Xfuncproto.h',
+    'X11/X.h',
+    'X11/XKBlib.h',
+    'X11/Xlib.h',
+    'X11/Xlibint.h',
+    'X11/Xlib-xcb.h',
+    'X11/Xlocale.h',
+    'X11/Xos.h',
+    'X11/Xutil.h',
+    'xcb/shm.h',
+    'xcb/xcb.h',
+    'xlocale.h',
+    'zmouse.h',
+]
+
+if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
+    system_headers += [
+        'android/ashmem.h',
+        'android_audio/AudioSystem.h',
+        'android/log.h',
+        'android/looper.h',
+        'android/native_window.h',
+        'android/native_window.h',
+        'android/native_window_jni.h',
+        'audio_effects/effect_aec.h',
+        'audio_effects/effect_ns.h',
+        'AudioParameter.h',
+        'AudioSystem.h',
+        'AudioTrack.h',
+        'avc_utils.h',
+        'binder/Binder.h',
+        'binder/BinderService.h',
+        'binder/IBinder.h',
+        'binder/IInterface.h',
+        'binder/IMemory.h',
+        'binder/IPCThreadState.h',
+        'binder/IPermissionController.h',
+        'binder/IServiceManager.h',
+        'binder/Parcel.h',
+        'binder/ProcessState.h',
+        'camera/Camera.h',
+        'camera/CameraParameters.h',
+        'ColorConverter.h',
+        'cutils/android_reboot.h',
+        'cutils/atomic.h',
+        'cutils/compiler.h',
+        'cutils/log.h',
+        'cutils/native_handle.h',
+        'cutils/properties.h',
+        'cutils/sockets.h',
+        'foundation/ABase.h',
+        'foundation/ABitReader.h',
+        'foundation/ABuffer.h',
+        'foundation/ADebug.h',
+        'foundation/AHandler.h',
+        'foundation/AHandlerReflector.h',
+        'foundation/ALooper.h',
+        'foundation/AMessage.h',
+        'foundation/AString.h',
+        'foundation/base64.h',
+        'foundation/hexdump.h',
+        'gui/BufferQueue.h',
+        'gui/ConsumerBase.h',
+        'gui/GraphicBufferAlloc.h',
+        'gui/IConsumerListener.h',
+        'gui/IGraphicBufferAlloc.h',
+        'gui/IGraphicBufferProducer.h',
+        'gui/ISurfaceComposerClient.h',
+        'gui/ISurfaceComposer.h',
+        'gui/ISurfaceTexture.h',
+        'gui/SurfaceComposerClient.h',
+        'gui/Surface.h',
+        'gui/SurfaceTextureClient.h',
+        'hardware/audio.h',
+        'hardware/gralloc.h',
+        'hardware/hardware.h',
+        'hardware/hwcomposer.h',
+        'hardware_legacy/power.h',
+        'hardware_legacy/uevent.h',
+        'hardware_legacy/vibrator.h',
+        'hardware/lights.h',
+        'hardware/power.h',
+        'HTTPBase.h',
+        'linux/android_alarm.h',
+        'linux/ashmem.h',
+        'media/AudioEffect.h',
+        'media/AudioSystem.h',
+        'media/ICrypto.h',
+        'media/IOMX.h',
+        'media/MediaProfiles.h',
+        'media/MediaRecorderBase.h',
+        'media/openmax/OMX_Audio.h',
+        'media/stagefright/AACWriter.h',
+        'media/stagefright/AMRWriter.h',
+        'media/stagefright/AudioSource.h',
+        'media/stagefright/DataSource.h',
+        'media/stagefright/foundation/ABase.h',
+        'media/stagefright/foundation/ABitReader.h',
+        'media/stagefright/foundation/ABuffer.h',
+        'media/stagefright/foundation/ADebug.h',
+        'media/stagefright/foundation/AHandler.h',
+        'media/stagefright/foundation/AHandlerReflector.h',
+        'media/stagefright/foundation/ALooper.h',
+        'media/stagefright/foundation/AMessage.h',
+        'media/stagefright/foundation/AString.h',
+        'media/stagefright/foundation/base64.h',
+        'media/stagefright/foundation/hexdump.h',
+        'media/stagefright/MediaBufferGroup.h',
+        'media/stagefright/MediaBuffer.h',
+        'media/stagefright/MediaCodec.h',
+        'media/stagefright/MediaCodecList.h',
+        'media/stagefright/MediaCodecSource.h',
+        'media/stagefright/MediaDefs.h',
+        'media/stagefright/MediaErrors.h',
+        'media/stagefright/MediaExtractor.h',
+        'media/stagefright/MediaSource.h',
+        'media/stagefright/MediaWriter.h',
+        'media/stagefright/MetaData.h',
+        'media/stagefright/MPEG2TSWriter.h',
+        'media/stagefright/MPEG4Writer.h',
+        'media/stagefright/OMXClient.h',
+        'media/stagefright/OMXCodec.h',
+        'media/stagefright/openmax/OMX_Core.h',
+        'media/stagefright/openmax/OMX_Index.h',
+        'media/stagefright/openmax/OMX_IVCommon.h',
+        'media/stagefright/openmax/OMX_Types.h',
+        'media/stagefright/openmax/OMX_Video.h',
+        'media/stagefright/Utils.h',
+        'OMX_Component.h',
+        'OMX.h',
+        'stagefright/AACWriter.h',
+        'stagefright/AMRWriter.h',
+        'stagefright/AudioSource.h',
+        'stagefright/DataSource.h',
+        'stagefright/foundation/ABase.h',
+        'stagefright/foundation/ABitReader.h',
+        'stagefright/foundation/ABuffer.h',
+        'stagefright/foundation/ADebug.h',
+        'stagefright/foundation/AHandler.h',
+        'stagefright/foundation/AHandlerReflector.h',
+        'stagefright/foundation/ALooper.h',
+        'stagefright/foundation/AMessage.h',
+        'stagefright/foundation/AString.h',
+        'stagefright/foundation/base64.h',
+        'stagefright/foundation/hexdump.h',
+        'stagefright/MediaBufferGroup.h',
+        'stagefright/MediaBuffer.h',
+        'stagefright/MediaCodec.h',
+        'stagefright/MediaDefs.h',
+        'stagefright/MediaErrors.h',
+        'stagefright/MediaExtractor.h',
+        'stagefright/MediaSource.h',
+        'stagefright/MediaWriter.h',
+        'stagefright/MetaData.h',
+        'stagefright/MPEG2TSWriter.h',
+        'stagefright/MPEG4Writer.h',
+        'stagefright/OMXClient.h',
+        'stagefright/OMXCodec.h',
+        'stagefright/openmax/OMX_Component.h',
+        'stagefright/openmax/OMX_Core.h',
+        'stagefright/openmax/OMX_Index.h',
+        'stagefright/openmax/OMX_IVCommon.h',
+        'stagefright/openmax/OMX_Types.h',
+        'stagefright/openmax/OMX_Video.h',
+        'stagefright/Utils.h',
+        'suspend/autosuspend.h',
+        'system/audio.h',
+        'system/graphics.h',
+        'system/window.h',
+        'sysutils/NetlinkEvent.h',
+        'ui/ANativeObjectBase.h',
+        'ui/egl/android_natives.h',
+        'ui/Fence.h',
+        'ui/FramebufferNativeWindow.h',
+        'ui/GraphicBuffer.h',
+        'ui/Rect.h',
+        'ui/Region.h',
+        'utils/BitSet.h',
+        'utils/CallStack.h',
+        'utils/Errors.h',
+        'utils/FileMap.h',
+        'utils/KeyedVector.h',
+        'utils/List.h',
+        'utils/Log.h',
+        'utils/Looper.h',
+        'utils/PropertyMap.h',
+        'utils/RefBase.h',
+        'utils/String16.h',
+        'utils/String8.h',
+        'utils/TextOutput.h',
+        'utils/threads.h',
+        'utils/Timers.h',
+        'utils/Trace.h',
+        'utils/TypeHelpers.h',
+        'utils/Unicode.h',
+        'utils/Vector.h',
+        'utils/VectorImpl.h',
+        'vr/gvr/capi/include/gvr_controller.h',
+        'vr/gvr/capi/include/gvr.h',
+    ]
+
+if CONFIG['MOZ_JACK']:
+    system_headers += [
+        'jack/jack.h',
+        'jack/statistics.h',
+    ]
+
+if CONFIG['MOZ_SYSTEM_JPEG']:
+    system_headers += [
+        'jpeglib.h',
+    ]
+
+if CONFIG['MOZ_LIBAV_FFT']:
+    system_headers += [
+        'libavcodec/avfft.h',
+    ]
+
+if CONFIG['MOZ_SYSTEM_PNG']:
+    system_headers += [
+        'png.h',
+    ]
+
+if CONFIG['MOZ_SYSTEM_ZLIB']:
+    system_headers += [
+        'zlib.h',
+    ]
+
+if CONFIG['MOZ_ENABLE_STARTUP_NOTIFICATION']:
+    system_headers += [
+        'libsn/sn-common.h',
+        'libsn/sn.h',
+        'libsn/sn-launchee.h',
+        'libsn/sn-launcher.h',
+        'libsn/sn-monitor.h',
+        'libsn/sn-util.h',
+    ]
+
+if CONFIG['MOZ_SYSTEM_HUNSPELL']:
+    system_headers += [
+        'hunspell.hxx',
+    ]
+
+if CONFIG['MOZ_SYSTEM_BZ2']:
+    system_headers += [
+        'bzlib.h',
+    ]
+
+if CONFIG['MOZ_SYSTEM_LIBEVENT']:
+    system_headers += [
+        'event2/event_compat.h',
+        'event2/event.h',
+        'event2/event_struct.h',
+        'event.h',
+    ]
+else:
+    system_headers += [
+        'sys/event.h',
+    ]
+
+if CONFIG['MOZ_ENABLE_LIBPROXY']:
+    system_headers += [
+        'proxy.h',
+    ]
+
+if CONFIG['MOZ_ENABLE_CONTENTMANAGER']:
+    system_headers += [
+        'QtSparql/qsparqlconnection.h',
+        'QtSparql/qsparqlquery.h',
+        'QtSparql/qsparqlresult.h',
+        'SelectMultipleContentItemsPage.h',
+        'SelectSingleContentItemPage.h',
+    ]
+
+if not CONFIG['MOZ_TREE_PIXMAN']:
+    system_headers += [
+        'pixman.h',
+    ]
+
+if CONFIG['MOZ_SYSTEM_LIBVPX']:
+    system_headers += [
+        'vpx_mem/vpx_mem.h',
+        'vpx/svc_context.h',
+        'vpx/vp8cx.h',
+        'vpx/vp8dx.h',
+        'vpx/vpx_codec.h',
+        'vpx/vpx_decoder.h',
+        'vpx/vpx_encoder.h',
+    ]
+
+if CONFIG['MOZ_SYSTEM_ICU']:
+    system_headers += [
+        'unicode/locid.h',
+        'unicode/numsys.h',
+        'unicode/plurrule.h',
+        'unicode/timezone.h',
+        'unicode/ucal.h',
+        'unicode/uchar.h',
+        'unicode/uclean.h',
+        'unicode/ucol.h',
+        'unicode/udat.h',
+        'unicode/udatpg.h',
+        'unicode/udisplaycontext.h',
+        'unicode/uenum.h',
+        'unicode/unistr.h',
+        'unicode/unorm.h',
+        'unicode/unum.h',
+        'unicode/upluralrules.h',
+        'unicode/ureldatefmt.h',
+        'unicode/ustring.h',
+        'unicode/utypes.h',
+    ]
--- a/devtools/client/commandline/test/browser_cmd_pref3.js
+++ b/devtools/client/commandline/test/browser_cmd_pref3.js
@@ -2,19 +2,16 @@
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests that the pref commands work
 
 var prefBranch = Cc["@mozilla.org/preferences-service;1"]
                     .getService(Ci.nsIPrefService).getBranch(null)
                     .QueryInterface(Ci.nsIPrefBranch);
 
-var supportsString = Cc["@mozilla.org/supports-string;1"]
-                      .createInstance(Ci.nsISupportsString);
-
 const TEST_URI = "data:text/html;charset=utf-8,gcli-pref3";
 
 function test() {
   return Task.spawn(spawnTest).then(finish, helpers.handleError);
 }
 
 function* spawnTest() {
   let options = yield helpers.openTab(TEST_URI);
@@ -96,15 +93,13 @@ function* spawnTest() {
       },
       post: function () {
         var mozfoo = prefBranch.getStringPref("devtools.debugger.remote-host");
         is(mozfoo, "moz.foo", "devtools.debugger.remote-host is moz.foo");
       }
     },
   ]);
 
-  supportsString.data = remoteHostOrig;
-  prefBranch.setComplexValue("devtools.debugger.remote-host",
-                             Ci.nsISupportsString, supportsString);
+  prefBranch.setStringPref("devtools.debugger.remote-host", remoteHostOrig);
 
   yield helpers.closeToolbar(options);
   yield helpers.closeTab(options);
 }
--- a/devtools/client/commandline/test/browser_cmd_settings.js
+++ b/devtools/client/commandline/test/browser_cmd_settings.js
@@ -2,19 +2,16 @@
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests that the pref commands work
 
 var prefBranch = Cc["@mozilla.org/preferences-service;1"]
                     .getService(Ci.nsIPrefService).getBranch(null)
                     .QueryInterface(Ci.nsIPrefBranch);
 
-var supportsString = Cc["@mozilla.org/supports-string;1"]
-                      .createInstance(Ci.nsISupportsString);
-
 const TEST_URI = "data:text/html;charset=utf-8,gcli-settings";
 
 function test() {
   return Task.spawn(spawnTest).then(finish, helpers.handleError);
 }
 
 function* spawnTest() {
   // Setup
@@ -109,15 +106,12 @@ function* spawnTest() {
 
   is(hideIntroEnabled.value, hideIntroEnabledDefault, "hideIntroEnabled reset");
   is(tabSize.value, tabSizeDefault, "tabSize reset");
   is(remoteHost.value, remoteHostDefault, "remoteHost reset");
 
   // Cleanup
   prefBranch.setBoolPref("devtools.gcli.hideIntro", hideIntroOrig);
   prefBranch.setIntPref("devtools.editor.tabsize", tabSizeOrig);
-  supportsString.data = remoteHostOrig;
-  prefBranch.setComplexValue("devtools.debugger.remote-host",
-          Components.interfaces.nsISupportsString,
-          supportsString);
+  prefBranch.setStringPref("devtools.debugger.remote-host", remoteHostOrig);
 
   yield helpers.closeTab(options);
 }
--- a/devtools/client/debugger/new/README.mozilla
+++ b/devtools/client/debugger/new/README.mozilla
@@ -1,11 +1,11 @@
 This is the debugger.html project output.
 See https://github.com/devtools-html/debugger.html
 
-Taken from upstream commit: d9f18b2cd0792de70289d4dcde5ed3e38be87cf1
+Taken from upstream commit: be179268c9b89390c13bdc9c4cca6000f6f583e5
 
 Packages:
 - babel-plugin-transform-es2015-modules-commonjs @6.26.0
 - babel-preset-react @6.24.1
 - react @15.6.2
 - react-dom @15.6.2
 - webpack @3.8.1
--- a/devtools/client/debugger/new/debugger.css
+++ b/devtools/client/debugger/new/debugger.css
@@ -405,16 +405,20 @@ body {
   .sidebar
   .title-wrapper
   .launchpad-container
   .launchpad-container-title {
   display: inline;
   padding-left: 3px;
   font-weight: normal;
 }
+/* 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/>. */
+
 .modal-wrapper {
   position: fixed;
   display: flex;
   flex-direction: column;
   align-items: center;
   width: 100%;
   height: 100%;
   top: 0;
@@ -468,43 +472,33 @@ body {
     height: auto;
     max-height: 80vh;
   }
   .modal.entered,
   .modal.exiting {
     transform: translateY(30px);
   }
 }
+/* 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/>. */
+
 .shortcuts-content {
   padding: 15px;
   -moz-column-width: 250px;
   -webkit-column-width: 250px;
   column-width: 250px;
 }
 
 .shortcuts-content h2 {
   margin-top: 2px;
   margin-bottom: 2px;
   color: var(--theme-content-color1);
 }
 
-.mac .keystroke {
-  border-style: solid;
-  border-width: 1px;
-  border-radius: 3px;
-  border-color: var(--theme-graphs-grey);
-  background-color: var(--theme-selection-color);
-  width: 21px;
-  height: 17px;
-  display: inline-block;
-  font-size: 10px;
-  text-align: center;
-  padding-top: 2px;
-}
-
 .shortcuts-section {
   display: inline-block;
   margin: 5px;
   margin-bottom: 15px;
   width: 250px;
 }
 
 .shortcuts-list {
@@ -524,31 +518,39 @@ body {
   border: 1px solid transparent;
 }
 
 @media (max-width: 640px) {
   .shortcuts-section {
     width: 100%;
   }
 }
+/* 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/>. */
+
 :root {
   --arrow-width: 10px;
 }
 
 :root.theme-light,
 :root .theme-light {
   --search-overlays-semitransparent: rgba(221, 225, 228, 0.66);
   --popup-shadow-color: #d0d0d0;
 }
 
 :root.theme-dark,
 :root .theme-dark {
   --search-overlays-semitransparent: rgba(42, 46, 56, 0.66);
   --popup-shadow-color: #5c667b;
 }
+/* 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/>. */
+
 * {
   box-sizing: border-box;
 }
 
 button {
   background: transparent;
   outline: none;
   border: none;
@@ -597,16 +599,20 @@ button:focus {
 
 /* Utils */
 .absolute-center {
   position: absolute;
   top: 50%;
   left: 50%;
   transform: translate(-50%, -50%);
 }
+/* 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/>. */
+
 menupopup {
   position: fixed;
   z-index: 10000;
   background: white;
   border: 1px solid #cccccc;
   padding: 5px 0;
   background: #f2f2f2;
   border-radius: 5px;
@@ -917,16 +923,20 @@ menuseparator {
  * Make sure splitter panels are not processing any mouse
  * events. This is good for performance during splitter
  * bar dragging.
  */
 .split-box.dragging > .controlled,
 .split-box.dragging > .uncontrolled {
   pointer-events: none;
 }
+/* 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/>. */
+
 .arrow,
 .worker,
 .refresh,
 .shortcut,
 .add-button {
   fill: var(--theme-splitter-color);
 }
 
@@ -1030,16 +1040,20 @@ html .arrow.expanded svg {
   height: 15px;
   margin-right: 5px;
   vertical-align: sub;
 }
 
 .theme-dark .webpack {
   opacity: 0.5;
 }
+/* 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/>. */
+
 .managed-tree .tree {
   -webkit-user-select: none;
   -moz-user-select: none;
   -ms-user-select: none;
   -o-user-select: none;
   user-select: none;
 
   white-space: nowrap;
@@ -1071,16 +1085,20 @@ html[dir="rtl"] .managed-tree .tree .nod
 
 .managed-tree .tree .node.focused svg {
   fill: white;
 }
 
 .managed-tree .tree-node button {
   position: fixed;
 }
+/* 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/>. */
+
 .close-btn path {
   fill: var(--theme-comment-alt);
 }
 
 .close-btn .close {
   width: 14px;
   height: 14px;
   transition: all 0.15s ease-in-out;
@@ -1118,16 +1136,20 @@ html[dir="rtl"] .managed-tree .tree .nod
 .close-btn.big .close {
   width: 16px;
   height: 16px;
 }
 
 .close-btn.big .close svg {
   width: 9px;
 }
+/* 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/>. */
+
 .search-field {
   width: calc(100% - 1px);
   height: 27px;
   background-color: var(--theme-toolbar-background);
   border-bottom: 1px solid var(--theme-splitter-color);
   padding-right: 10px;
   display: flex;
   flex-shrink: 0;
@@ -1224,16 +1246,20 @@ html[dir="rtl"] .managed-tree .tree .nod
 
 .search-field .search-nav-buttons .nav-btn:active path {
   fill: var(--theme-comment-alt);
 }
 
 .search-field .search-nav-buttons .nav-btn path {
   fill: var(--theme-comment);
 }
+/* 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/>. */
+
 .project-text-search {
   flex-grow: 1;
   display: flex;
   flex-direction: column;
   overflow-y: hidden;
   height: 100%;
 }
 
@@ -1312,28 +1338,36 @@ html[dir="rtl"] .managed-tree .tree .nod
 .project-text-search .managed-tree {
   overflow-y: auto;
   height: calc(100% - 81px);
 }
 
 .project-text-search .managed-tree .tree {
   height: 100%;
 }
+/* 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/>. */
+
 .search-container {
   position: absolute;
   top: 30px;
   left: 0;
   width: calc(100% - 1px);
   height: calc(100% - 31px);
   display: flex;
   flex-direction: column;
   z-index: 20;
   background-color: var(--theme-body-background);
   overflow-y: hidden;
 }
+/* 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/>. */
+
 .sources-panel {
   background-color: var(--theme-sidebar-background);
   display: flex;
   flex: 1;
   flex-direction: column;
   overflow: hidden;
   position: relative;
 }
@@ -1415,16 +1449,17 @@ html[dir="rtl"] .managed-tree .tree .nod
 .source-outline-tabs {
   width: 100%;
   background: var(--theme-body-background);
   border-top: 1px solid var(--theme-splitter-color);
   display: flex;
   -moz-user-select: none;
   user-select: none;
   box-sizing: border-box;
+  height: 29px;
 }
 
 .source-outline-tabs .tab {
   flex: 1;
   justify-content: center;
   border-bottom: 1px solid transparent;
   border-left: 1px solid transparent;
   display: inline-flex;
@@ -1483,16 +1518,20 @@ html[dir="rtl"] .managed-tree .tree .nod
 
 .theme-dark .sources-list .managed-tree .tree .node img.blackBox {
   background-color: var(--theme-body-color);
 }
 
 .theme-dark .sources-list .managed-tree .tree .node.focused img.blackBox {
   background-color: white;
 }
+/* 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/>. */
+
 .outline {
   overflow-y: auto;
 }
 
 .outline .outline-pane-info {
   width: 100%;
   font-style: italic;
   text-align: center;
@@ -1528,16 +1567,20 @@ html[dir="rtl"] .managed-tree .tree .nod
   padding-right: 0.5rem;
   padding-top: 0.2rem;
   cursor: default;
 }
 
 .outline-list__element:hover {
   background: var(--theme-toolbar-background-hover);
 }
+/* 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-signature {
   align-self: center;
 }
 
 .function-signature .function-name {
   color: var(--theme-highlight-blue);
 }
 
@@ -1547,16 +1590,20 @@ html[dir="rtl"] .managed-tree .tree .nod
 
 .function-signature .paren {
   color: var(--object-color);
 }
 
 .function-signature .comma {
   color: var(--object-color);
 }
+/* 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/>. */
+
 .toggle-button-start,
 .toggle-button-end {
   transform: translate(0, 0px);
   transition: transform 0.25s ease-in-out;
   padding: 5px;
 }
 
 .toggle-button-start.vertical,
@@ -1592,16 +1639,20 @@ html[dir="rtl"] .toggle-button-start svg
 html .toggle-button-end.vertical svg {
   transform: rotate(-90deg);
 }
 
 .toggle-button-start.collapsed,
 .toggle-button-end.collapsed {
   transform: rotate(180deg);
 }
+/* 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/>. */
+
 .source-footer {
   background: var(--theme-body-background);
   border-top: 1px solid var(--theme-splitter-color);
   position: absolute;
   display: flex;
   bottom: 0;
   left: 0;
   right: 0;
@@ -1678,16 +1729,20 @@ html .toggle-button-end.vertical svg {
 
 .source-footer > .commands > .blackboxed > img.blackBox {
   background: var(--theme-highlight-blue);
 }
 
 .source-footer .blackbox-summary {
   color: var(--theme-body-color);
 }
+/* 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/>. */
+
 .search-bar {
   display: flex;
   flex-direction: column;
 }
 
 .search-bar .search-field {
   padding-left: 7px;
   height: var(--editor-searchbar-height);
@@ -2058,16 +2113,20 @@ html[dir="rtl"] .arrow svg,
 .tree .node .unavailable {
   color: var(--theme-content-color3);
 }
 
 .lessen {
   opacity: 0.6;
 }
 
+/* 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/>. */
+
 .bracket-arrow {
   position: absolute;
 }
 
 .bracket-arrow::before,
 .bracket-arrow::after {
   content: "";
   height: 0;
@@ -2100,25 +2159,33 @@ html[dir="rtl"] .arrow svg,
   border-top-color: var(--theme-body-color);
 }
 
 .bracket-arrow.down::after {
   border-bottom-color: transparent;
   border-top-color: var(--theme-body-background);
   top: -1px;
 }
+/* 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/>. */
+
 .popover {
   position: fixed;
   z-index: 100;
 }
 
 .popover .gap {
   height: 5px;
   padding-top: 5px;
 }
+/* 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/>. */
+
 .popover .preview-popup {
   background: var(--theme-body-background);
   width: 350px;
   min-height: 80px;
   border: 1px solid var(--theme-splitter-color);
   padding: 10px;
   height: auto;
   min-height: inherit;
@@ -2233,16 +2300,20 @@ html[dir="rtl"] .arrow svg,
 .add-to-expression-bar .expression-to-save-label {
   width: calc(100% - 4em);
 }
 
 .add-to-expression-bar .expression-to-save-button {
   font-size: 14px;
   color: var(--theme-content-color3);
 }
+/* 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/>. */
+
 .call-site {
   background: #f0f9ff;
   position: relative;
 }
 
 .call-site::before {
   content: "";
   position: absolute;
@@ -2278,19 +2349,27 @@ html[dir="rtl"] .arrow svg,
 
 .theme-dark .call-site-bp {
   background-color: #4b3f3f;
 }
 
 .theme-dark .call-site-bp::before {
   border-bottom-color: #dd4d4d;
 }
+/* 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/>. */
+
 .empty-line .CodeMirror-linenumber {
   opacity: 0.5;
 }
+/* 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/>. */
+
 .conditional-breakpoint-panel {
   cursor: initial;
   margin: 1em 0;
   position: relative;
   display: flex;
   align-items: center;
   background: var(--theme-toolbar-background);
   border-top: 1px solid var(--theme-splitter-color);
@@ -2315,23 +2394,28 @@ html[dir="rtl"] .arrow svg,
   font-size: 14px;
   color: var(--theme-conditional-breakpoint-color);
   line-height: 30px;
 }
 
 .conditional-breakpoint-panel input:focus {
   outline-width: 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/>. */
+
 .editor-wrapper {
   --debug-line-border: rgb(145, 188, 219);
   --debug-expression-background: rgba(202, 227, 255, 0.5);
   --editor-searchbar-height: 27px;
   --editor-second-searchbar-height: 27px;
   --debug-line-error-border: rgb(255, 0, 0);
   --debug-expression-error-background: rgba(231, 116, 113, 0.3);
+  --editor-header-height: 30px;
 }
 
 .theme-dark .editor-wrapper {
   --debug-expression-background: #54617e;
   --debug-line-border: #7786a2;
 }
 
 .editor-wrapper .CodeMirror-linewidget {
@@ -2347,19 +2431,19 @@ html[dir="rtl"] .arrow svg,
 }
 
 /**
  * There's a known codemirror flex issue with chrome that this addresses.
  * BUG https://github.com/devtools-html/debugger.html/issues/63
  */
 .editor-wrapper {
   position: absolute;
-  height: calc(100% - 29px);
+  height: calc(100% - var(--editor-header-height));
   width: calc(100% - 1px);
-  top: 29px;
+  top: var(--editor-header-height);
   left: 0px;
   --editor-footer-height: 24px;
 }
 
 html[dir="rtl"] .editor-mount {
   direction: ltr;
 }
 
@@ -2529,16 +2613,20 @@ debug-expression-error {
 
 .CodeMirror-guttermarker-subtle {
   visibility: hidden;
 }
 
 .visible {
   visibility: visible;
 }
+/* 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/>. */
+
 .cm-highlight {
   position: relative;
 }
 
 .cm-highlight::before {
   position: absolute;
   border-top-style: solid;
   border-bottom-style: solid;
@@ -2554,16 +2642,20 @@ debug-expression-error {
   margin-bottom: -1px;
 }
 
 .cm-highlight-full::before {
   border: 1px solid var(--theme-comment-alt);
   border-radius: 2px;
   margin: 0 -1px -1px -1px;
 }
+/* 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/>. */
+
 .breakpoints-toggle {
   margin: 2px 3px;
 }
 
 .breakpoints-list * {
   user-select: none;
 }
 
@@ -2666,16 +2758,20 @@ html .breakpoints-list .breakpoint.pause
 
 .breakpoint .close {
   visibility: hidden;
 }
 
 .breakpoint:hover .close {
   visibility: visible;
 }
+/* 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/>. */
+
 .input-expression {
   width: 100%;
   margin: 0px;
   border: 1px;
   background-color: var(--theme-sidebar-background);
   font-size: 12px;
   padding: 0px 20px;
   color: var(--theme-body-color);
@@ -2747,16 +2843,20 @@ html .breakpoints-list .breakpoint.pause
 
 .expression-container:hover .close-btn {
   display: block;
 }
 
 .expression-input {
   max-width: 50%;
 }
+/* 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/>. */
+
 .frames ul .frames-group .group,
 .frames ul .frames-group .group .location {
   font-weight: 500;
   cursor: default;
 }
 
 .frames ul .frames-group.expanded .group,
 .frames ul .frames-group.expanded .group .location {
@@ -2770,16 +2870,20 @@ html .breakpoints-list .breakpoint.pause
 .frames ul .frames-group .frames-list li {
   padding-left: 30px;
 }
 
 .frames ul .frames-group .frames-list {
   border-top: 1px solid var(--theme-splitter-color);
   border-bottom: 1px solid var(--theme-splitter-color);
 }
+/* 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/>. */
+
 .why-paused {
   background-color: var(--theme-body-background);
   color: var(--theme-body-color);
   padding: 10px 10px 10px 20px;
   white-space: normal;
   opacity: 0.6;
   font-size: 12px;
   flex: 0 1 auto;
@@ -2798,16 +2902,20 @@ html .breakpoints-list .breakpoint.pause
 }
 
 .why-paused .message.warning {
   font-size: 10px;
   color: var(--theme-graphs-red);
   font-weight: bold;
   font-style: normal;
 }
+/* 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/>. */
+
 .frames ul {
   list-style: none;
   margin: 0;
   padding: 0;
 }
 
 .frames ul li {
   padding: 7px 10px 7px 21px;
@@ -2890,16 +2998,20 @@ html .breakpoints-list .breakpoint.pause
   width: 12px;
   margin-left: 3px;
   line-height: 8px;
 }
 
 :root.theme-dark .annotation-logo svg path {
   fill: var(--theme-highlight-blue);
 }
+/* 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/>. */
+
 .event-listeners {
   list-style: none;
   margin: 0;
   padding: 0;
 }
 
 .event-listeners .listener {
   padding: 7px 10px 7px 21px;
@@ -2935,28 +3047,36 @@ html .breakpoints-list .breakpoint.pause
 
 .event-listeners .listener .close {
   display: none;
 }
 
 .event-listeners .listener:hover .close {
   display: block;
 }
+/* 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/>. */
+
 .workers-list * {
   user-select: none;
 }
 
 .workers-list .worker {
   font-size: 12px;
   color: var(--theme-content-color1);
   padding: 0.5em 1em 0.5em 0.5em;
   line-height: 1em;
   position: relative;
   transition: all 0.25s ease;
 }
+/* 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/>. */
+
 :root {
   --accordion-header-background: var(--theme-toolbar-background);
 }
 
 :root.theme-dark {
   --accordion-header-background: #141416;
 }
 
@@ -3023,16 +3143,20 @@ html .breakpoints-list .breakpoint.pause
   padding: 0;
   width: 16px;
   height: 16px;
 }
 
 .accordion .header-buttons button::-moz-focus-inner {
   border: none;
 }
+/* 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/>. */
+
 .command-bar {
   flex: 0 0 29px;
   border-bottom: 1px solid var(--theme-splitter-color);
   display: flex;
   overflow: hidden;
   z-index: 1;
   background-color: var(--theme-toolbar-background);
 }
@@ -3151,16 +3275,20 @@ img.resume {
 
 .command-bar.bottom > button {
   color: var(--theme-comment);
   width: 26px;
 }
 .command-bar.bottom > button:hover {
   color: var(--theme-body-color);
 }
+/* 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/>. */
+
 .object-node.default-property {
   opacity: 0.6;
 }
 
 .object-label {
   color: var(--theme-highlight-blue);
 }
 
@@ -3181,16 +3309,20 @@ img.resume {
 
 .scopes-pane {
   overflow: auto;
 }
 
 .scopes-list .function-signature {
   display: inline-block;
 }
+/* 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/>. */
+
 .secondary-panes {
   overflow: auto;
   display: flex;
   flex-direction: column;
   flex: 1;
   white-space: nowrap;
   --breakpoint-expression-right-clear-space: 36px;
 }
@@ -3225,16 +3357,20 @@ img.resume {
   -moz-user-select: none;
   user-select: none;
   cursor: default;
 }
 
 .theme-dark .secondary-panes .accordion .arrow svg {
   fill: var(--theme-content-color3);
 }
+/* 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/>. */
+
 .welcomebox {
   width: calc(100% - 1px);
 
   /* Offsetting it by 30px for the sources-header area */
   height: calc(100% - 30px);
   position: absolute;
   top: 30px;
   left: 0;
@@ -3306,16 +3442,20 @@ html .welcomebox .toggle-button-end.coll
   .shortcutFunction {
     margin-left: 0;
   }
 
   .shortcutKey {
     display: block;
   }
 }
+/* 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/>. */
+
 .source-header {
   border-bottom: 1px solid var(--theme-splitter-color);
   width: 100%;
   height: 29px;
   display: flex;
   align-items: flex-end;
 }
 
@@ -3434,16 +3574,20 @@ html .welcomebox .toggle-button-end.coll
 
 .source-tab.active .close-btn {
   visibility: visible;
 }
 
 .source-tab:hover .close-btn {
   visibility: visible;
 }
+/* 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/>. */
+
 .dropdown {
   --width: 150px;
   background: var(--theme-body-background);
   border: 1px solid var(--theme-splitter-color);
   box-shadow: 0 4px 4px 0 var(--search-overlays-semitransparent);
   max-height: 300px;
   position: absolute;
   right: 0;
@@ -3497,16 +3641,20 @@ html[dir="rtl"] .dropdown {
   position: fixed;
   width: 100%;
   height: 100%;
   background: transparent;
   z-index: 999;
   left: 0;
   top: 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/>. */
+
 .result-list {
   list-style: none;
   margin: 0px;
   padding: 0px;
   overflow: auto;
   width: calc(100% - 1px); /* 1px fixes the hidden right border */
 }
 
@@ -3586,8 +3734,10 @@ html[dir="rtl"] .dropdown {
 
 .search-bar .result-list {
   border-bottom: 1px solid var(--theme-splitter-color);
 }
 
 .theme-dark .result-list {
   background-color: var(--theme-body-background);
 }
+
+/*# sourceMappingURL=debugger.css.map*/
\ No newline at end of file
--- a/devtools/client/debugger/new/debugger.js
+++ b/devtools/client/debugger/new/debugger.js
@@ -10199,16 +10199,20 @@ module.exports = isLength;
 /* 223 */,
 /* 224 */,
 /* 225 */,
 /* 226 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
+/* 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/>. */
+
 // @flow
 
 const { isDevelopment } = __webpack_require__(1355);
 const { Services, PrefsHelper } = __webpack_require__(1376);
 
 const prefsSchemaVersion = "1.0.3";
 
 const pref = Services.pref;
@@ -10612,17 +10616,17 @@ module.exports = charenc;
 
 /***/ }),
 /* 251 */
 /***/ (function(module, exports) {
 
 /*!
  * Determine if an object is a Buffer
  *
- * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
+ * @author   Feross Aboukhadijeh <https://feross.org>
  * @license  MIT
  */
 
 // The _isBuffer check is for Safari 5-7 support, because it's missing
 // Object.prototype.constructor. Remove this eventually
 module.exports = function (obj) {
   return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)
 }
@@ -16492,17 +16496,19 @@ module.exports = "<!-- This Source Code 
 /* 1350 */,
 /* 1351 */,
 /* 1352 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
-var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /* 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/>. */
 
 var _expressions = __webpack_require__(1417);
 
 var expressions = _interopRequireWildcard(_expressions);
 
 var _sources = __webpack_require__(1369);
 
 var sources = _interopRequireWildcard(_sources);
@@ -17005,16 +17011,20 @@ module.exports = {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /* 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/>. */
+
 var _breakpoints = __webpack_require__(1396);
 
 var breakpoints = _interopRequireWildcard(_breakpoints);
 
 var _expressions = __webpack_require__(1398);
 
 var expressions = _interopRequireWildcard(_expressions);
 
@@ -17071,17 +17081,17 @@ var _debuggee = __webpack_require__(1533
 var debuggee = _interopRequireWildcard(_debuggee);
 
 var _toolbox = __webpack_require__(1534);
 
 var toolbox = _interopRequireWildcard(_toolbox);
 
 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
-exports.default = Object.assign({}, navigation, breakpoints, expressions, eventListeners, sources, pause, ui, fileSearch, ast, coverage, projectTextSearch, quickOpen, sourceTree, loadSourceText, debuggee, toolbox);
+exports.default = _extends({}, navigation, breakpoints, expressions, eventListeners, sources, pause, ui, fileSearch, ast, coverage, projectTextSearch, quickOpen, sourceTree, loadSourceText, debuggee, toolbox);
 
 /***/ }),
 /* 1355 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -17110,17 +17120,19 @@ var _path = __webpack_require__(1393);
 var _url = __webpack_require__(334);
 
 /**
  * Trims the query part or reference identifier of a url string, if necessary.
  *
  * @memberof utils/source
  * @static
  */
-
+/* 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/>. */
 
 /**
  * Utils for working with Source URLs
  * @module utils/source
  */
 
 function trimUrlQuery(url) {
   const length = url.length;
@@ -17221,17 +17233,22 @@ function getFormattedSourceId(id) {
  * @static
  */
 function getFilename(source) {
   const { url, id } = source;
   if (!url) {
     return getFormattedSourceId(id);
   }
 
-  return getFilenameFromURL(url);
+  let filename = getFilenameFromURL(url);
+  const qMarkIdx = filename.indexOf("?");
+  if (qMarkIdx > 0) {
+    filename = filename.slice(0, qMarkIdx);
+  }
+  return filename;
 }
 
 /**
  * Show a source url.
  * If the source does not have a url, use the source id.
  *
  * @memberof utils/source
  * @static
@@ -17286,23 +17303,27 @@ function getSourceLineCount(source) {
  *
  * Returns Code Mirror mode for source content type
  * @param contentType
  * @return String
  * @memberof utils/source
  * @static
  */
 
-function getMode(source) {
+function getMode(source, sourceMetaData) {
   const { contentType, text, isWasm, url } = source;
 
   if (!text || isWasm) {
     return { name: "text" };
   }
 
+  if (url && url.match(/\.jsx$/i) || sourceMetaData && sourceMetaData.isReactComponent) {
+    return "jsx";
+  }
+
   // if the url ends with .marko we set the name to Javascript so
   // syntax highlighting works for marko too
   if (url && url.match(/\.marko$/i)) {
     return { name: "javascript" };
   }
 
   // Use HTML mode for files in which the first non whitespace
   // character is `<` regardless of extension.
@@ -17373,16 +17394,20 @@ module.exports = {
 
 /***/ }),
 /* 1358 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /* 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/>. */
+
 var _devtoolsConfig = __webpack_require__(1355);
 
 var _sourceDocuments = __webpack_require__(1436);
 
 var sourceDocumentUtils = _interopRequireWildcard(_sourceDocuments);
 
 var _source = __webpack_require__(1356);
 
@@ -17391,16 +17416,18 @@ var _expression = __webpack_require__(15
 var expressionUtils = _interopRequireWildcard(_expression);
 
 var _sourceSearch = __webpack_require__(1526);
 
 var sourceSearchUtils = _interopRequireWildcard(_sourceSearch);
 
 var _wasm = __webpack_require__(1401);
 
+var _ui = __webpack_require__(1439);
+
 var _devtoolsSourceEditor = __webpack_require__(1386);
 
 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
 const { findNext, findPrev } = sourceSearchUtils;
 
 function shouldShowPrettyPrint(selectedSource) {
   if (!selectedSource) {
@@ -17480,18 +17507,19 @@ function toEditorRange(sourceId, locatio
 
 function toSourceLine(sourceId, line) {
   return (0, _wasm.isWasm)(sourceId) ? (0, _wasm.lineToWasmOffset)(sourceId, line) : line + 1;
 }
 
 function scrollToColumn(codeMirror, line, column) {
   const { top, left } = codeMirror.charCoords({ line: line, ch: column }, "local");
 
-  const centeredX = left - codeMirror.getScrollerElement().offsetWidth / 2;
-  const centeredY = top - codeMirror.getScrollerElement().offsetHeight / 2;
+  const scroller = codeMirror.getScrollerElement();
+  const centeredX = Math.max(left - scroller.offsetWidth / 2, 0);
+  const centeredY = Math.max(top - scroller.offsetHeight / 2, 0);
 
   codeMirror.scrollTo(centeredX, centeredY);
 }
 
 function toSourceLocation(sourceId, location) {
   return {
     line: toSourceLine(sourceId, location.line),
     column: (0, _wasm.isWasm)(sourceId) ? undefined : location.column
@@ -17517,31 +17545,32 @@ function getSourceLocationFromMouseEvent
 
   return {
     sourceId: selectedLocation.sourceId,
     line: line + 1,
     column: ch + 1
   };
 }
 
-module.exports = Object.assign({}, expressionUtils, sourceDocumentUtils, sourceSearchUtils, _devtoolsSourceEditor.SourceEditorUtils, {
+module.exports = _extends({}, expressionUtils, sourceDocumentUtils, sourceSearchUtils, _devtoolsSourceEditor.SourceEditorUtils, {
   createEditor,
   isWasm: _wasm.isWasm,
   toEditorLine,
   toEditorPosition,
   toEditorRange,
   toSourceLine,
   scrollToColumn,
   toSourceLocation,
   shouldShowPrettyPrint,
   shouldShowFooter,
   traverseResults,
   markText,
   lineAtHeight,
-  getSourceLocationFromMouseEvent
+  getSourceLocationFromMouseEvent,
+  resizeBreakpointGutter: _ui.resizeBreakpointGutter
 });
 
 /***/ }),
 /* 1359 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
@@ -17553,16 +17582,20 @@ Object.defineProperty(exports, "__esModu
 var _Svg = __webpack_require__(1540);
 
 var _Svg2 = _interopRequireDefault(_Svg);
 
 __webpack_require__(1310);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* 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/>. */
+
 /**
  * This file maps the SVG React Components in the assets/images directory.
  */
 
 exports.default = _Svg2.default;
 
 /***/ }),
 /* 1360 */
@@ -17574,17 +17607,17 @@ exports.default = _Svg2.default;
 
 const {
   originalToGeneratedId,
   generatedToOriginalId,
   isGeneratedId,
   isOriginalId
 } = __webpack_require__(1389);
 
-const { workerUtils: { WorkerDispatcher } } = __webpack_require__(1390);
+const { workerUtils: { WorkerDispatcher } } = __webpack_require__(1363);
 
 const dispatcher = new WorkerDispatcher();
 
 const getOriginalURLs = dispatcher.task("getOriginalURLs");
 const getGeneratedLocation = dispatcher.task("getGeneratedLocation");
 const getOriginalLocation = dispatcher.task("getOriginalLocation");
 const getLocationScopes = dispatcher.task("getLocationScopes");
 const getOriginalSourceText = dispatcher.task("getOriginalSourceText");
@@ -17637,17 +17670,19 @@ function _interopRequireWildcard(obj) { 
 
 
 /**
  * @memberof utils/makeRecord
  * @static
  */
 function makeRecord(spec) {
   return I.Record(spec);
-}
+} /* 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/>. */
 
 /**
  * When Flow 0.29 is released (very soon), we can use this Record type
  * instead of the builtin immutable.js Record type. This is better
  * because all the fields are actually typed, unlike the builtin one.
  * This depends on a performance fix that will go out in 0.29 though;
  * @module utils/makeRecord
  */
@@ -18009,24 +18044,29 @@ function breakpointExists(state, locatio
 }
 
 function createBreakpoint(location, overrides = {}) {
   const {
     condition,
     disabled,
     hidden,
     generatedLocation,
-    astLocation
+    astLocation,
+    id
   } = overrides;
 
+  const defaultASTLocation = { name: undefined, offset: location };
   const properties = {
+    id,
     condition: condition || null,
     disabled: disabled || false,
     hidden: hidden || false,
-    astLocation: astLocation || { offset: location },
+    loading: false,
+    text: "",
+    astLocation: astLocation || defaultASTLocation,
     generatedLocation: generatedLocation || location,
     location
   };
 
   return properties;
 }
 
 function createPendingLocation(location) {
@@ -18054,21 +18094,23 @@ function createPendingBreakpoint(bp) {
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.hasSyntaxError = exports.clearSources = exports.setSource = exports.hasSource = exports.getEmptyLines = exports.getNextStep = exports.clearASTs = exports.clearScopes = exports.clearSymbols = exports.getOutOfScopeLocations = exports.getVariablesInScope = exports.getScopes = exports.getSymbols = exports.getClosestExpression = exports.stopParserWorker = exports.startParserWorker = undefined;
+exports.replaceOriginalVariableName = exports.isReactComponent = exports.hasSyntaxError = exports.clearSources = exports.setSource = exports.hasSource = exports.getEmptyLines = exports.getNextStep = exports.clearASTs = exports.clearScopes = exports.clearSymbols = exports.getOutOfScopeLocations = exports.getVariablesInScope = exports.getScopes = exports.getSymbols = exports.getClosestExpression = exports.stopParserWorker = exports.startParserWorker = undefined;
 
 var _devtoolsUtils = __webpack_require__(1363);
 
-const { WorkerDispatcher } = _devtoolsUtils.workerUtils;
+const { WorkerDispatcher } = _devtoolsUtils.workerUtils; /* 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/>. */
 
 const dispatcher = new WorkerDispatcher();
 const startParserWorker = exports.startParserWorker = dispatcher.start.bind(dispatcher);
 const stopParserWorker = exports.stopParserWorker = dispatcher.stop.bind(dispatcher);
 
 const getClosestExpression = exports.getClosestExpression = dispatcher.task("getClosestExpression");
 const getSymbols = exports.getSymbols = dispatcher.task("getSymbols");
 const getScopes = exports.getScopes = dispatcher.task("getScopes");
@@ -18078,28 +18120,32 @@ const clearSymbols = exports.clearSymbol
 const clearScopes = exports.clearScopes = dispatcher.task("clearScopes");
 const clearASTs = exports.clearASTs = dispatcher.task("clearASTs");
 const getNextStep = exports.getNextStep = dispatcher.task("getNextStep");
 const getEmptyLines = exports.getEmptyLines = dispatcher.task("getEmptyLines");
 const hasSource = exports.hasSource = dispatcher.task("hasSource");
 const setSource = exports.setSource = dispatcher.task("setSource");
 const clearSources = exports.clearSources = dispatcher.task("clearSources");
 const hasSyntaxError = exports.hasSyntaxError = dispatcher.task("hasSyntaxError");
+const isReactComponent = exports.isReactComponent = dispatcher.task("isReactComponent");
+const replaceOriginalVariableName = exports.replaceOriginalVariableName = dispatcher.task("replaceOriginalVariableName");
 
 /***/ }),
 /* 1366 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-
+/* 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/>. */
 
 /**
  * Utils for utils, by utils
  * @module utils/utils
  */
 
 /**
  * @memberof utils/utils
@@ -18334,20 +18380,19 @@ module.exports = {
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.getSelectedSourceText = exports.getSelectedSource = exports.getSelectedLocation = exports.getSourcesForTabs = exports.getSearchTabs = exports.getSourceTabs = exports.getSources = undefined;
 
-var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
-/* 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/. */
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /* 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/>. */
 
 /**
  * Sources reducer
  * @module reducers/sources
  */
 
 exports.initialState = initialState;
 exports.removeSourceFromTabList = removeSourceFromTabList;
@@ -18672,88 +18717,17 @@ const getSelectedSource = exports.getSel
 const getSelectedSourceText = exports.getSelectedSourceText = (0, _reselect.createSelector)(getSelectedSource, getSourcesState, (selectedSource, sources) => {
   const id = selectedSource.get("id");
   return id ? sources.sourcesText.get(id) : null;
 });
 
 exports.default = update;
 
 /***/ }),
-/* 1370 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-exports.promise = exports.PROMISE = undefined;
-
-var _lodash = __webpack_require__(2);
-
-var _DevToolsUtils = __webpack_require__(1432);
-
-/* 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/. */
-
-let seqIdVal = 1;
-
-function seqIdGen() {
-  return seqIdVal++;
-}
-
-function filterAction(action) {
-  return (0, _lodash.fromPairs)((0, _lodash.toPairs)(action).filter(pair => pair[0] !== PROMISE));
-}
-
-function promiseMiddleware({ dispatch, getState }) {
-  return next => action => {
-    if (!(PROMISE in action)) {
-      return next(action);
-    }
-
-    const promiseInst = action[PROMISE];
-    const seqId = seqIdGen().toString();
-
-    // Create a new action that doesn't have the promise field and has
-    // the `seqId` field that represents the sequence id
-    action = Object.assign(filterAction(action), { seqId });
-
-    dispatch(Object.assign({}, action, { status: "start" }));
-
-    // Return the promise so action creators can still compose if they
-    // want to.
-    return new Promise((resolve, reject) => {
-      promiseInst.then(value => {
-        (0, _DevToolsUtils.executeSoon)(() => {
-          dispatch(Object.assign({}, action, {
-            status: "done",
-            value: value
-          }));
-          resolve(value);
-        });
-      }, error => {
-        (0, _DevToolsUtils.executeSoon)(() => {
-          dispatch(Object.assign({}, action, {
-            status: "error",
-            error: error.message || error
-          }));
-          reject(error);
-        });
-      });
-    });
-  };
-}
-
-const PROMISE = exports.PROMISE = "@@dispatch/promise";
-exports.promise = promiseMiddleware;
-
-/***/ }),
+/* 1370 */,
 /* 1371 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
@@ -18767,16 +18741,20 @@ exports.partIsFile = partIsFile;
 exports.createNode = createNode;
 exports.createParentMap = createParentMap;
 exports.getRelativePath = getRelativePath;
 
 var _url = __webpack_require__(334);
 
 var _source = __webpack_require__(1356);
 
+/* 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/>. */
+
 const IGNORED_URLS = ["debugger eval code", "XStringBundle"];
 
 function nodeHasChildren(item) {
   return Array.isArray(item.contents);
 }
 
 function isExactUrlMatch(pathPart, debuggeeUrl) {
   // compare to hostname with an optional 'www.' prefix
@@ -19007,17 +18985,17 @@ exports.jumpToMappedLocation = jumpToMap
 exports.addTab = addTab;
 exports.moveTab = moveTab;
 exports.closeTab = closeTab;
 exports.closeTabs = closeTabs;
 exports.togglePrettyPrint = togglePrettyPrint;
 exports.toggleBlackBox = toggleBlackBox;
 exports.loadAllSources = loadAllSources;
 
-var _promise = __webpack_require__(1370);
+var _promise = __webpack_require__(1653);
 
 var _assert = __webpack_require__(1384);
 
 var _assert2 = _interopRequireDefault(_assert);
 
 var _breakpoints = __webpack_require__(1396);
 
 var _ast = __webpack_require__(1399);
@@ -19045,21 +19023,19 @@ function _interopRequireDefault(obj) { r
 // If a request has been made to show this source, go ahead and
 // select it.
 async function checkSelectedSource(state, dispatch, source) {
   const pendingLocation = (0, _selectors.getPendingSelectedLocation)(state);
 
   if (pendingLocation && !!source.url && pendingLocation.url === source.url) {
     await dispatch(selectSource(source.id, { location: pendingLocation }));
   }
-}
-
-/* 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/. */
+} /* 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/>. */
 
 /**
  * Redux actions for the sources state
  * @module actions/sources
  */
 
 async function checkPendingBreakpoints(state, dispatch, sourceId) {
   // source may have been modified by selectSource
@@ -19296,32 +19272,33 @@ function togglePrettyPrint(sourceId) {
 
     if (!source || !(0, _source2.isLoaded)(source)) {
       return {};
     }
 
     (0, _assert2.default)(sourceMaps.isGeneratedId(sourceId), "Pretty-printing only allowed on generated sources");
 
     const selectedLocation = (0, _selectors.getSelectedLocation)(getState());
-    const selectedOriginalLocation = selectedLocation ? await sourceMaps.getOriginalLocation(selectedLocation) : {};
-
     const url = (0, _source2.getPrettySourceURL)(source.url);
     const prettySource = (0, _selectors.getSourceByURL)(getState(), url);
 
+    const options = {};
+    if (selectedLocation) {
+      options.location = await sourceMaps.getOriginalLocation(selectedLocation);
+    }
+
     if (prettySource) {
-      return dispatch(selectSource(prettySource.get("id"), {
-        location: selectedOriginalLocation
-      }));
+      return dispatch(selectSource(prettySource.get("id"), options));
     }
 
     const newPrettySource = await dispatch((0, _createPrettySource.createPrettySource)(sourceId));
     await dispatch((0, _breakpoints.remapBreakpoints)(sourceId));
     await dispatch((0, _ast.setEmptyLines)(newPrettySource.id));
 
-    return dispatch(selectSource(newPrettySource.id, { location: selectedOriginalLocation }));
+    return dispatch(selectSource(newPrettySource.id, options));
   };
 }
 
 function toggleBlackBox(source) {
   return async ({ dispatch, getState, client, sourceMaps }) => {
     const { isBlackBoxed, id } = source;
 
     return dispatch({
@@ -19385,17 +19362,20 @@ function CloseButton({ handleClick, butt
     "div",
     {
       className: buttonClass ? `close-btn ${buttonClass}` : "close-btn",
       onClick: handleClick,
       title: tooltip
     },
     _react2.default.createElement(_Svg2.default, { name: "close" })
   );
-}
+} /* 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/>. */
+
 exports.default = CloseButton;
 
 /***/ }),
 /* 1375 */,
 /* 1376 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -19480,20 +19460,19 @@ module.exports = {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 
-var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
-/* 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/. */
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /* 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/>. */
 
 /**
  * Breakpoints reducer
  * @module reducers/breakpoints
  */
 
 exports.initialState = initialState;
 exports.getBreakpoints = getBreakpoints;
@@ -19709,16 +19688,20 @@ var _classnames2 = _interopRequireDefaul
 var _Close = __webpack_require__(1374);
 
 var _Close2 = _interopRequireDefault(_Close);
 
 __webpack_require__(1313);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* 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/>. */
+
 const arrowBtn = (onClick, type, className, tooltip) => {
   const props = {
     onClick,
     type,
     className,
     title: tooltip,
     key: type
   };
@@ -19838,16 +19821,21 @@ exports.default = SearchInput;
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
+
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /* 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/>. */
+
 exports.getLibraryFromUrl = getLibraryFromUrl;
 exports.annotateFrame = annotateFrame;
 exports.simplifyDisplayName = simplifyDisplayName;
 exports.formatDisplayName = formatDisplayName;
 exports.formatCopyName = formatCopyName;
 exports.collapseFrames = collapseFrames;
 
 var _lodash = __webpack_require__(2);
@@ -19971,17 +19959,17 @@ function mapDisplayNames(frame, library)
 
 function annotateFrame(frame) {
   if (!(0, _devtoolsConfig.isEnabled)("collapseFrame")) {
     return frame;
   }
 
   const library = getLibraryFromUrl(frame);
   if (library) {
-    return Object.assign({}, frame, { library });
+    return _extends({}, frame, { library });
   }
 
   return frame;
 }
 
 // Decodes an anonymous naming scheme that
 // spider monkey implements based on "Naming Anonymous JavaScript Functions"
 // http://johnjbarton.github.io/nonymous/index.html
@@ -20307,44 +20295,46 @@ Object.defineProperty(exports, "__esModu
 });