Merge m-c to fx-team, a=merge
authorWes Kocher <wkocher@mozilla.com>
Fri, 02 Sep 2016 13:36:24 -0700
changeset 312479 969397f22187cfd25fca153f0d1624dde9490589
parent 312333 46e86751a3429cd64ae06d3029008a20cff67d64 (current diff)
parent 312478 d0830980ffdb36a10855d02a588b4869cad6707e (diff)
child 312480 18ab41c28e2e073d7a8d1854b565236b44ce9ba7
push id20447
push userkwierso@gmail.com
push dateFri, 02 Sep 2016 20:36:44 +0000
treeherderfx-team@969397f22187 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone51.0a1
Merge m-c to fx-team, a=merge
browser/components/contextualidentity/test/browser/browser_newtabButton.js
browser/components/search/test/browser_eBay.js
browser/components/search/test/browser_eBay_behavior.js
browser/locales/en-US/searchplugins/eBay.xml
build/autoconf/linux.m4
dom/bindings/parser/tests/test_array.py
dom/bindings/parser/tests/test_array_of_interface.py
dom/simplepush/Push.js
dom/simplepush/Push.manifest
dom/simplepush/PushService.jsm
dom/simplepush/PushServiceLauncher.js
dom/simplepush/moz.build
dom/simplepush/test/mochitest.ini
dom/simplepush/test/test_permissions.html
dom/simplepush/test/test_prefs.html
dom/simplepush/test/test_register.html
dom/webidl/SimplePushManager.webidl
mobile/android/base/java/org/mozilla/gecko/favicons/FaviconGenerator.java
mobile/android/base/java/org/mozilla/gecko/favicons/Favicons.java
mobile/android/base/java/org/mozilla/gecko/favicons/LoadFaviconTask.java
mobile/android/base/java/org/mozilla/gecko/favicons/OnFaviconLoadedListener.java
mobile/android/base/java/org/mozilla/gecko/favicons/RemoteFavicon.java
mobile/android/base/java/org/mozilla/gecko/favicons/cache/FaviconCache.java
mobile/android/base/java/org/mozilla/gecko/favicons/cache/FaviconCacheElement.java
mobile/android/base/java/org/mozilla/gecko/favicons/cache/FaviconsForURL.java
mobile/android/base/java/org/mozilla/gecko/favicons/decoders/FaviconDecoder.java
mobile/android/base/java/org/mozilla/gecko/favicons/decoders/ICODecoder.java
mobile/android/base/java/org/mozilla/gecko/favicons/decoders/IconDirectoryEntry.java
mobile/android/base/java/org/mozilla/gecko/favicons/decoders/LoadFaviconResult.java
mobile/android/base/java/org/mozilla/gecko/home/UpdateViewFaviconLoadedListener.java
mobile/android/tests/background/junit4/src/org/mozilla/gecko/favicons/TestFaviconGenerator.java
--- a/CLOBBER
+++ b/CLOBBER
@@ -17,9 +17,9 @@
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
 # Are you updating CLOBBER because you think it's needed for your WebIDL
 # changes to stick? As of bug 928195, this shouldn't be necessary! Please
 # don't change CLOBBER for WebIDL changes any more.
 
-Bug 1299332 for the relanding of Bug 1299276.
+Bug 1289951 maybe needed a clobber to fix xpcshell tests?
--- a/accessible/base/Logging.cpp
+++ b/accessible/base/Logging.cpp
@@ -85,20 +85,17 @@ EnableLogging(const char* aModulesStr)
     if (*token == ',')
       token++; // skip ',' char
   }
 }
 
 static void
 LogDocURI(nsIDocument* aDocumentNode)
 {
-  nsIURI* uri = aDocumentNode->GetDocumentURI();
-  nsAutoCString spec;
-  uri->GetSpec(spec);
-  printf("uri: %s", spec.get());
+  printf("uri: %s", aDocumentNode->GetDocumentURI()->GetSpecOrDefault().get());
 }
 
 static void
 LogDocShellState(nsIDocument* aDocumentNode)
 {
   printf("docshell busy: ");
 
   nsAutoCString docShellBusy;
--- a/accessible/base/nsTextEquivUtils.cpp
+++ b/accessible/base/nsTextEquivUtils.cpp
@@ -122,17 +122,17 @@ nsTextEquivUtils::AppendTextEquivFromTex
     if (parentContent) {
       nsIFrame *frame = parentContent->GetPrimaryFrame();
       if (frame) {
         // If this text is inside a block level frame (as opposed to span
         // level), we need to add spaces around that block's text, so we don't
         // get words jammed together in final name.
         const nsStyleDisplay* display = frame->StyleDisplay();
         if (display->IsBlockOutsideStyle() ||
-            display->mDisplay == NS_STYLE_DISPLAY_TABLE_CELL) {
+            display->mDisplay == StyleDisplay::TableCell) {
           isHTMLBlock = true;
           if (!aString->IsEmpty()) {
             aString->Append(char16_t(' '));
           }
         }
       }
     }
     
--- a/accessible/tests/mochitest/tree/test_tabbrowser.xul
+++ b/accessible/tests/mochitest/tree/test_tabbrowser.xul
@@ -85,25 +85,16 @@
             {
               // xul:toolbarbutton ("Close current tab")
               role: ROLE_PUSHBUTTON,
               children: []
             }
             );
         } else {
           SimpleTest.ok(true, "Testing Firefox tabbrowser UI.");
-          let newTabChildren = [];
-          if (SpecialPowers.getBoolPref("privacy.userContext.enabled")) {
-            newTabChildren = [
-              {
-                role: ROLE_MENUPOPUP,
-                children: []
-              }
-            ];
-          }
 
           // NB: The (3) buttons are not visible, unless manually hovered,
           //     probably due to size reduction in this test.
           tabsAccTree.children.splice(0, 0,
             {
               // xul:tab ("about:")
               role: ROLE_PAGETAB,
               children: [
@@ -123,17 +114,17 @@
                   role: ROLE_PUSHBUTTON,
                   children: []
                 }
               ]
             },
             {
               // xul:toolbarbutton ("Open a new tab")
               role: ROLE_PUSHBUTTON,
-              children: newTabChildren
+              children: []
             }
             // "List all tabs" dropdown
             // XXX: This child(?) is not present in this test.
             //      I'm not sure why (though probably expected).
             );
         }
 
         testAccessibleTree(tabBrowser().tabContainer, tabsAccTree);
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -18,17 +18,16 @@ builtin(include, build/autoconf/mozprog.
 builtin(include, build/autoconf/mozheader.m4)dnl
 builtin(include, build/autoconf/lto.m4)dnl
 builtin(include, build/autoconf/frameptr.m4)dnl
 builtin(include, build/autoconf/compiler-opts.m4)dnl
 builtin(include, build/autoconf/expandlibs.m4)dnl
 builtin(include, build/autoconf/arch.m4)dnl
 builtin(include, build/autoconf/android.m4)dnl
 builtin(include, build/autoconf/zlib.m4)dnl
-builtin(include, build/autoconf/linux.m4)dnl
 builtin(include, build/autoconf/icu.m4)dnl
 builtin(include, build/autoconf/ffi.m4)dnl
 builtin(include, build/autoconf/clang-plugin.m4)dnl
 builtin(include, build/autoconf/alloc.m4)dnl
 builtin(include, build/autoconf/ios.m4)dnl
 builtin(include, build/autoconf/jemalloc.m4)dnl
 builtin(include, build/autoconf/sanitize.m4)dnl
 
--- a/addon-sdk/source/test/windows/test-firefox-windows.js
+++ b/addon-sdk/source/test/windows/test-firefox-windows.js
@@ -284,20 +284,20 @@ exports.testActiveWindow = function*(ass
     onFocus(rawWindow3).then(resolve);
     window3.activate();
     assert.pass("activating window3");
   });
 
   assert.equal(windows.activeWindow.title, window3.title, "Correct active window - 3");
 
   yield close(rawWindow2);
-  assert.equal(rawWindow2.closed, true, 'window 2 is closed');
+  yield close(rawWindow3);
 
-  yield close(rawWindow3);
-  assert.equal(rawWindow3.closed, true, 'window 3 is closed');
+  assert.equal(windows.length, 1, "Correct number of browser windows");
+  assert.equal(window.closed, false, "Original window is still open");
 };
 
 exports.testTrackWindows = function(assert, done) {
   let windows = [];
   let actions = [];
 
   let expects = [
     "activate 0", "global activate 0", "deactivate 0", "global deactivate 0",
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -401,50 +401,16 @@ pref("dom.phonenumber.substringmatching.
 pref("dom.phonenumber.substringmatching.CO", 10);
 pref("dom.phonenumber.substringmatching.VE", 7);
 pref("dom.phonenumber.substringmatching.CL", 8);
 pref("dom.phonenumber.substringmatching.PE", 7);
 
 // WebAlarms
 pref("dom.mozAlarms.enabled", true);
 
-// SimplePush
-pref("services.push.enabled", true);
-// Debugging enabled.
-pref("services.push.debug", false);
-// Is the network connection allowed to be up?
-// This preference should be used in UX to enable/disable push.
-pref("services.push.connection.enabled", true);
-// serverURL to be assigned by services team
-pref("services.push.serverURL", "wss://push.services.mozilla.com/");
-pref("services.push.userAgentID", "");
-// Exponential back-off start is 5 seconds like in HTTP/1.1.
-// Maximum back-off is pingInterval.
-pref("services.push.retryBaseInterval", 5000);
-// Interval at which to ping PushServer to check connection status. In
-// milliseconds. If no reply is received within requestTimeout, the connection
-// is considered closed.
-pref("services.push.pingInterval", 1800000); // 30 minutes
-// How long before a DOMRequest errors as timeout
-pref("services.push.requestTimeout", 10000);
-pref("services.push.pingInterval.default", 180000);// 3 min
-pref("services.push.pingInterval.mobile", 180000); // 3 min
-pref("services.push.pingInterval.wifi", 180000);  // 3 min
-// Adaptive ping
-pref("services.push.adaptive.enabled", true);
-pref("services.push.adaptive.lastGoodPingInterval", 180000);// 3 min
-pref("services.push.adaptive.lastGoodPingInterval.mobile", 180000);// 3 min
-pref("services.push.adaptive.lastGoodPingInterval.wifi", 180000);// 3 min
-// Valid gap between the biggest good ping and the bad ping
-pref("services.push.adaptive.gap", 60000); // 1 minute
-// We limit the ping to this maximum value
-pref("services.push.adaptive.upperLimit", 1740000); // 29 min
-// enable udp wakeup support
-pref("services.push.udp.wakeupEnabled", true);
-
 // NetworkStats
 #ifdef MOZ_WIDGET_GONK
 pref("dom.mozNetworkStats.enabled", true);
 pref("dom.webapps.firstRunWithSIM", true);
 #endif
 
 // ResourceStats
 #ifdef MOZ_WIDGET_GONK
--- a/b2g/confvars.sh
+++ b/b2g/confvars.sh
@@ -31,17 +31,16 @@ fi
 MOZ_USE_NATIVE_POPUP_WINDOWS=1
 
 MOZ_XULRUNNER=
 
 MOZ_APP_ID={3c2e2abc-06d4-11e1-ac3b-374f68613e61}
 
 MOZ_TIME_MANAGER=1
 
-MOZ_SIMPLEPUSH=1
 MOZ_TOOLKIT_SEARCH=
 MOZ_B2G=1
 
 MOZ_JSDOWNLOADS=1
 
 MOZ_BUNDLED_FONTS=1
 
 export JS_GC_SMALL_CHUNK_SIZE=1
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -599,21 +599,17 @@
 @RESPATH@/components/XULStore.js
 @RESPATH@/components/XULStore.manifest
 @RESPATH@/components/Webapps.js
 @RESPATH@/components/Webapps.manifest
 @RESPATH@/components/AppsService.js
 @RESPATH@/components/AppsService.manifest
 @RESPATH@/components/Push.js
 @RESPATH@/components/Push.manifest
-#ifdef MOZ_SIMPLEPUSH
-@RESPATH@/components/PushServiceLauncher.js
-#else
 @RESPATH@/components/PushComponents.js
-#endif
 
 @RESPATH@/components/nsDOMIdentity.js
 @RESPATH@/components/nsIDService.js
 @RESPATH@/components/Identity.manifest
 
 @RESPATH@/components/SystemMessageInternal.js
 @RESPATH@/components/SystemMessageManager.js
 @RESPATH@/components/SystemMessageCache.js
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -114,26 +114,16 @@ tabbrowser {
 #TabsToolbar[customizing="true"] > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .tabs-newtab-button {
   visibility: collapse;
 }
 
 #tabbrowser-tabs:not([overflow="true"])[using-closing-tabs-spacer] ~ #alltabs-button {
   visibility: hidden; /* temporary space to keep a tab's close button under the cursor */
 }
 
-.tabs-newtab-button > .toolbarbutton-menu-dropmarker,
-#new-tab-button > .toolbarbutton-menu-dropmarker {
-  display: none;
-}
-
-.tabs-newtab-button > .toolbarbutton-icon,
-#new-tab-button > .toolbarbutton-icon {
-  margin-inline-end: 0;
-}
-
 .tabbrowser-tab {
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tab");
 }
 
 .tabbrowser-tab:not([pinned]) {
   -moz-box-flex: 100;
   max-width: 210px;
   min-width: 100px;
@@ -182,17 +172,16 @@ tabbrowser {
   z-index: 2;
   pointer-events: none; /* avoid blocking dragover events on scroll buttons */
 }
 
 .tabbrowser-tabs[movingtab] > .tabbrowser-tab[fadein]:not([selected]) {
   transition: transform 200ms ease-out;
 }
 
-.new-tab-popup,
 #alltabs-popup {
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-alltabs-popup");
 }
 
 toolbar[printpreview="true"] {
   -moz-binding: url("chrome://global/content/printPreviewBindings.xml#printpreviewtoolbar");
 }
 
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -256,102 +256,92 @@ function UpdateBackForwardCommands(aWebN
   }
 }
 
 /**
  * Click-and-Hold implementation for the Back and Forward buttons
  * XXXmano: should this live in toolbarbutton.xml?
  */
 function SetClickAndHoldHandlers() {
+  var timer;
+
+  function openMenu(aButton) {
+    cancelHold(aButton);
+    aButton.firstChild.hidden = false;
+    aButton.open = true;
+  }
+
+  function mousedownHandler(aEvent) {
+    if (aEvent.button != 0 ||
+        aEvent.currentTarget.open ||
+        aEvent.currentTarget.disabled)
+      return;
+
+    // Prevent the menupopup from opening immediately
+    aEvent.currentTarget.firstChild.hidden = true;
+
+    aEvent.currentTarget.addEventListener("mouseout", mouseoutHandler, false);
+    aEvent.currentTarget.addEventListener("mouseup", mouseupHandler, false);
+    timer = setTimeout(openMenu, 500, aEvent.currentTarget);
+  }
+
+  function mouseoutHandler(aEvent) {
+    let buttonRect = aEvent.currentTarget.getBoundingClientRect();
+    if (aEvent.clientX >= buttonRect.left &&
+        aEvent.clientX <= buttonRect.right &&
+        aEvent.clientY >= buttonRect.bottom)
+      openMenu(aEvent.currentTarget);
+    else
+      cancelHold(aEvent.currentTarget);
+  }
+
+  function mouseupHandler(aEvent) {
+    cancelHold(aEvent.currentTarget);
+  }
+
+  function cancelHold(aButton) {
+    clearTimeout(timer);
+    aButton.removeEventListener("mouseout", mouseoutHandler, false);
+    aButton.removeEventListener("mouseup", mouseupHandler, false);
+  }
+
+  function clickHandler(aEvent) {
+    if (aEvent.button == 0 &&
+        aEvent.target == aEvent.currentTarget &&
+        !aEvent.currentTarget.open &&
+        !aEvent.currentTarget.disabled) {
+      let cmdEvent = document.createEvent("xulcommandevent");
+      cmdEvent.initCommandEvent("command", true, true, window, 0,
+                                aEvent.ctrlKey, aEvent.altKey, aEvent.shiftKey,
+                                aEvent.metaKey, null);
+      aEvent.currentTarget.dispatchEvent(cmdEvent);
+    }
+  }
+
+  function _addClickAndHoldListenersOnElement(aElm) {
+    aElm.addEventListener("mousedown", mousedownHandler, true);
+    aElm.addEventListener("click", clickHandler, true);
+  }
+
   // Bug 414797: Clone the back/forward buttons' context menu into both buttons.
   let popup = document.getElementById("backForwardMenu").cloneNode(true);
   popup.removeAttribute("id");
   // Prevent the back/forward buttons' context attributes from being inherited.
   popup.setAttribute("context", "");
 
   let backButton = document.getElementById("back-button");
   backButton.setAttribute("type", "menu");
   backButton.appendChild(popup);
-  addClickAndHoldListenersOnElement(backButton);
+  _addClickAndHoldListenersOnElement(backButton);
 
   let forwardButton = document.getElementById("forward-button");
   popup = popup.cloneNode(true);
   forwardButton.setAttribute("type", "menu");
   forwardButton.appendChild(popup);
-  addClickAndHoldListenersOnElement(forwardButton);
-}
-
-let holdTimersMap = new Map();
-function holdMousedownHandler(aEvent) {
-  if (aEvent.button != 0 ||
-      aEvent.currentTarget.open ||
-      aEvent.currentTarget.disabled)
-    return;
-
-  // Prevent the menupopup from opening immediately
-  aEvent.currentTarget.firstChild.hidden = true;
-
-  aEvent.currentTarget.addEventListener("mouseout", holdMouseoutHandler, false);
-  aEvent.currentTarget.addEventListener("mouseup", holdMouseupHandler, false);
-  holdTimersMap.set(aEvent.currentTarget, setTimeout(holdOpenMenu, 500, aEvent.currentTarget));
-}
-
-function holdClickHandler(aEvent) {
-  if (aEvent.button == 0 &&
-      aEvent.target == aEvent.currentTarget &&
-      !aEvent.currentTarget.open &&
-      !aEvent.currentTarget.disabled) {
-    let cmdEvent = document.createEvent("xulcommandevent");
-    cmdEvent.initCommandEvent("command", true, true, window, 0,
-                              aEvent.ctrlKey, aEvent.altKey, aEvent.shiftKey,
-                              aEvent.metaKey, null);
-    aEvent.currentTarget.dispatchEvent(cmdEvent);
-  }
-  // This is here to cancel the XUL default event
-  // dom.click() triggers a command even if there is a click handler
-  // however this can now be prevented with preventDefault().
-  aEvent.preventDefault();
-}
-
-function holdOpenMenu(aButton) {
-  cancelHold(aButton);
-  aButton.firstChild.hidden = false;
-  aButton.open = true;
-}
-
-function holdMouseoutHandler(aEvent) {
-  let buttonRect = aEvent.currentTarget.getBoundingClientRect();
-  if (aEvent.clientX >= buttonRect.left &&
-      aEvent.clientX <= buttonRect.right &&
-      aEvent.clientY >= buttonRect.bottom)
-    holdOpenMenu(aEvent.currentTarget);
-  else
-    cancelHold(aEvent.currentTarget);
-}
-
-function holdMouseupHandler(aEvent) {
-  cancelHold(aEvent.currentTarget);
-}
-
-function cancelHold(aButton) {
-  clearTimeout(holdTimersMap.get(aButton));
-  aButton.removeEventListener("mouseout", holdMouseoutHandler, false);
-  aButton.removeEventListener("mouseup", holdMouseupHandler, false);
-}
-
-function removeClickAndHoldListenersOnElement(aElm) {
-  aElm.removeEventListener("mousedown", holdMousedownHandler, true);
-  aElm.removeEventListener("click", holdClickHandler, true);
-}
-
-function addClickAndHoldListenersOnElement(aElm) {
-  holdTimersMap.delete(aElm);
-
-  aElm.addEventListener("mousedown", holdMousedownHandler, true);
-  aElm.addEventListener("click", holdClickHandler, true);
+  _addClickAndHoldListenersOnElement(forwardButton);
 }
 
 const gSessionHistoryObserver = {
   observe: function(subject, topic, data)
   {
     if (topic != "browser:purge-session-history")
       return;
 
@@ -7386,16 +7376,18 @@ var gIdentityHandler = {
     let stateLabel = document.createElement("label");
     stateLabel.setAttribute("flex", "1");
     stateLabel.setAttribute("class", "identity-popup-permission-state-label");
     stateLabel.textContent = SitePermissions.getStateLabel(
       aPermission.id, aPermission.state, aPermission.inUse || false);
 
     let button = document.createElement("button");
     button.setAttribute("class", "identity-popup-permission-remove-button");
+    let tooltiptext = gNavigatorBundle.getString("permissions.remove.tooltip");
+    button.setAttribute("tooltiptext", tooltiptext);
     button.addEventListener("command", () => {
       this._permissionList.removeChild(container);
       if (aPermission.inUse &&
           ["camera", "microphone", "screen"].includes(aPermission.id)) {
         let windowId = this._sharingState.windowId;
         if (aPermission.id == "screen") {
           windowId = "screen:" + windowId;
         } else {
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -4941,17 +4941,17 @@
                            onmouseover="document.getBindingParent(this)._enterNewTab();"
                            onmouseout="document.getBindingParent(this)._leaveNewTab();"
                            tooltip="dynamic-shortcut-tooltip"/>
         <xul:spacer class="closing-tabs-spacer" anonid="closing-tabs-spacer"
                     style="width: 0;"/>
       </xul:arrowscrollbox>
     </content>
 
-    <implementation implements="nsIDOMEventListener, nsIObserver">
+    <implementation implements="nsIDOMEventListener">
       <constructor>
         <![CDATA[
           this.mTabClipWidth = Services.prefs.getIntPref("browser.tabs.tabClipWidth");
 
           var tab = this.firstChild;
           tab.label = this.tabbrowser.mStringBundle.getString("tabs.emptyTabTitle");
           tab.setAttribute("crop", "end");
           tab.setAttribute("onerror", "this.removeAttribute('image');");
@@ -4960,31 +4960,19 @@
           window.addEventListener("load", this, false);
 
           try {
             this._tabAnimationLoggingEnabled = Services.prefs.getBoolPref("browser.tabs.animationLogging.enabled");
           } catch (ex) {
             this._tabAnimationLoggingEnabled = false;
           }
           this._browserNewtabpageEnabled = Services.prefs.getBoolPref("browser.newtabpage.enabled");
-          this.observe(null, "nsPref:changed", "privacy.userContext.enabled");
-          Services.prefs.addObserver("privacy.userContext.enabled", this, false);
         ]]>
       </constructor>
 
-      <destructor>
-        <![CDATA[
-          Services.prefs.removeObserver("privacy.userContext.enabled", this);
-        ]]>
-      </destructor>
-
-      <field name="newtabUndoCloseTab" readonly="true">
-        document.getAnonymousElementByAttribute(this, "anonid", "newtab_undoCloseTab");
-      </field>
-
       <field name="tabbrowser" readonly="true">
         document.getElementById(this.getAttribute("tabbrowser"));
       </field>
 
       <field name="tabbox" readonly="true">
         this.tabbrowser.mTabBox;
       </field>
 
@@ -5000,64 +4988,16 @@
 
       <field name="_firstTab">null</field>
       <field name="_lastTab">null</field>
       <field name="_afterSelectedTab">null</field>
       <field name="_beforeHoveredTab">null</field>
       <field name="_afterHoveredTab">null</field>
       <field name="_hoveredTab">null</field>
 
-      <method name="observe">
-        <parameter name="aSubject"/>
-        <parameter name="aTopic"/>
-        <parameter name="aData"/>
-        <body><![CDATA[
-          switch (aTopic) {
-            case "nsPref:changed":
-              // This is the only pref observed.
-              let containersEnabled = Services.prefs.getBoolPref("privacy.userContext.enabled");
-
-              const newTab = document.getElementById("new-tab-button");
-              const newTab2 = document.getAnonymousElementByAttribute(this, "anonid", "tabs-newtab-button")
-
-              if (containersEnabled) {
-                for (let parent of [newTab, newTab2]) {
-                  if (!parent)
-                    continue;
-                  let popup = document.createElementNS(
-                                "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
-                                "menupopup");
-                  if (parent.id) {
-                    popup.id = "newtab-popup";
-                  } else {
-                    popup.setAttribute("anonid", "newtab-popup");
-                  }
-                  popup.oncommand="event.stopPropagation();";
-                  popup.className = "new-tab-popup";
-                  popup.setAttribute("position", "after_end");
-                  parent.appendChild(popup);
-
-                  addClickAndHoldListenersOnElement(parent);
-                  parent.setAttribute("type", "menu");
-                }
-              } else {
-                for (let parent of [newTab, newTab2]) {
-                  if (!parent)
-                    continue;
-                  removeClickAndHoldListenersOnElement(parent);
-                  parent.removeAttribute("type");
-                  parent.firstChild.remove();
-                }
-              }
-
-              break;
-          }
-        ]]></body>
-      </method>
-
       <property name="_isCustomizing" readonly="true">
         <getter>
           let root = document.documentElement;
           return root.getAttribute("customizing") == "true" ||
                  root.getAttribute("customize-exiting") == "true";
         </getter>
       </property>
 
@@ -6735,64 +6675,55 @@
       <handler event="popupshowing">
       <![CDATA[
         if (event.target.getAttribute('id') == "alltabs_containersMenuTab") {
           createUserContextMenu(event);
           return;
         }
 
         let containersEnabled = Services.prefs.getBoolPref("privacy.userContext.enabled");
-
-        if (event.target.getAttribute('anonid') == "newtab-popup" ||
-            event.target.id == "newtab-popup") {
-          createUserContextMenu(event);
-        } else {
-          document.getElementById("alltabs-popup-separator-1").hidden = !containersEnabled;
-          let containersTab = document.getElementById("alltabs_containersTab");
-
-          containersTab.hidden = !containersEnabled;
-          if (PrivateBrowsingUtils.isWindowPrivate(window)) {
-            containersTab.setAttribute("disabled", "true");
-          }
-
-          document.getElementById("alltabs_undoCloseTab").disabled =
-            SessionStore.getClosedTabCount(window) == 0;
-
-          var tabcontainer = gBrowser.tabContainer;
-
-          // Listen for changes in the tab bar.
-          tabcontainer.addEventListener("TabAttrModified", this, false);
-          tabcontainer.addEventListener("TabClose", this, false);
-          tabcontainer.mTabstrip.addEventListener("scroll", this, false);
-
-          let tabs = gBrowser.visibleTabs;
-          for (var i = 0; i < tabs.length; i++) {
-            if (!tabs[i].pinned)
-              this._createTabMenuItem(tabs[i]);
-          }
-          this._updateTabsVisibilityStatus();
+        document.getElementById("alltabs-popup-separator-1").hidden = !containersEnabled;
+        let containersTab = document.getElementById("alltabs_containersTab");
+
+        containersTab.hidden = !containersEnabled;
+        if (PrivateBrowsingUtils.isWindowPrivate(window)) {
+          containersTab.setAttribute("disabled", "true");
         }
+
+        document.getElementById("alltabs_undoCloseTab").disabled =
+          SessionStore.getClosedTabCount(window) == 0;
+
+        var tabcontainer = gBrowser.tabContainer;
+
+        // Listen for changes in the tab bar.
+        tabcontainer.addEventListener("TabAttrModified", this, false);
+        tabcontainer.addEventListener("TabClose", this, false);
+        tabcontainer.mTabstrip.addEventListener("scroll", this, false);
+
+        let tabs = gBrowser.visibleTabs;
+        for (var i = 0; i < tabs.length; i++) {
+          if (!tabs[i].pinned)
+            this._createTabMenuItem(tabs[i]);
+        }
+        this._updateTabsVisibilityStatus();
       ]]></handler>
 
       <handler event="popuphidden">
       <![CDATA[
         if (event.target.getAttribute('id') == "alltabs_containersMenuTab") {
           return;
         }
 
         // clear out the menu popup and remove the listeners
         for (let i = this.childNodes.length - 1; i > 0; i--) {
           let menuItem = this.childNodes[i];
           if (menuItem.tab) {
             menuItem.tab.mCorrespondingMenuitem = null;
             this.removeChild(menuItem);
           }
-          if (menuItem.hasAttribute("usercontextid")) {
-            this.removeChild(menuItem);
-          }
         }
         var tabcontainer = gBrowser.tabContainer;
         tabcontainer.mTabstrip.removeEventListener("scroll", this, false);
         tabcontainer.removeEventListener("TabAttrModified", this, false);
         tabcontainer.removeEventListener("TabClose", this, false);
       ]]></handler>
 
       <handler event="DOMMenuItemActive">
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -213,16 +213,18 @@ skip-if = buildapp == 'mulet' # Bug 1066
 skip-if = true # bug 1057615
 [browser_bug563588.js]
 [browser_bug565575.js]
 [browser_bug567306.js]
 subsuite = clipboard
 [browser_bug1261299.js]
 subsuite = clipboard
 skip-if = toolkit != "cocoa" # Because of tests for supporting Service Menu of macOS, bug 1261299
+[browser_bug1297539.js]
+skip-if = toolkit != "cocoa" # Because of tests for supporting pasting from Service Menu of macOS, bug 1297539
 [browser_bug575561.js]
 [browser_bug575830.js]
 [browser_bug577121.js]
 [browser_bug578534.js]
 [browser_bug579872.js]
 [browser_bug580638.js]
 [browser_bug580956.js]
 [browser_bug581242.js]
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/general/browser_bug1297539.js
@@ -0,0 +1,114 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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/. */
+
+/**
+ * Test for Bug 1297539
+ * Test that the content event "pasteTransferable"
+ * (mozilla::EventMessage::eContentCommandPasteTransferable)
+ * is handled correctly for plain text and html in the remote case.
+ *
+ * Original test test_bug525389.html for command content event
+ * "pasteTransferable" runs only in the content process.
+ * This doesn't test the remote case.
+ *
+ */
+
+"use strict";
+
+function getLoadContext() {
+  return window.QueryInterface(Ci.nsIInterfaceRequestor)
+               .getInterface(Ci.nsIWebNavigation)
+               .QueryInterface(Ci.nsILoadContext);
+}
+
+function getTransferableFromClipboard(asHTML) {
+  let trans = Cc["@mozilla.org/widget/transferable;1"].
+                    createInstance(Ci.nsITransferable);
+  trans.init(getLoadContext());
+  if (asHTML) {
+    trans.addDataFlavor("text/html");
+  } else {
+    trans.addDataFlavor("text/unicode");
+  }
+  let clip = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
+  clip.getData(trans, Ci.nsIClipboard.kGlobalClipboard);
+  return trans;
+}
+
+function* cutCurrentSelection(elementQueryString, property, browser) {
+  // Cut the current selection.
+  yield BrowserTestUtils.synthesizeKey("x", {accelKey: true}, browser);
+
+  // The editor should be empty after cut.
+  yield ContentTask.spawn(browser, {elementQueryString, property},
+    function* ({elementQueryString, property}) {
+      let element = content.document.querySelector(elementQueryString);
+      is(element[property], "",
+        `${elementQueryString} should be empty after cut (superkey + x)`);
+    });
+}
+
+// Test that you are able to pasteTransferable for plain text
+// which is handled by TextEditor::PasteTransferable to paste into the editor.
+add_task(function* test_paste_transferable_plain_text()
+{
+  let testPage =
+    'data:text/html,' +
+    '<textarea id="textarea">Write something here</textarea>';
+
+  yield BrowserTestUtils.withNewTab(testPage, function* (browser) {
+    // Select all the content in your editor element.
+    yield BrowserTestUtils.synthesizeMouse("#textarea", 0, 0, {}, browser);
+    yield BrowserTestUtils.synthesizeKey("a", {accelKey: true}, browser);
+
+    yield* cutCurrentSelection("#textarea", "value", browser);
+
+    let trans = getTransferableFromClipboard(false);
+    let DOMWindowUtils = EventUtils._getDOMWindowUtils(window);
+    DOMWindowUtils.sendContentCommandEvent("pasteTransferable", trans);
+
+    yield ContentTask.spawn(browser, null, function* () {
+      let textArea = content.document.querySelector('#textarea');
+      is(textArea.value, "Write something here",
+         "Send content command pasteTransferable successful");
+    });
+  });
+});
+
+// Test that you are able to pasteTransferable for html
+// which is handled by HTMLEditor::PasteTransferable to paste into the editor.
+//
+// On Linux,
+// BrowserTestUtils.synthesizeKey("a", {accelKey: true}, browser);
+// doesn't seem to trigger for contenteditable which is why we use
+// Selection to select the contenteditable contents.
+add_task(function* test_paste_transferable_html()
+{
+  let testPage =
+    'data:text/html,' +
+    '<div contenteditable="true"><b>Bold Text</b><i>italics</i></div>';
+
+  yield BrowserTestUtils.withNewTab(testPage, function* (browser) {
+    // Select all the content in your editor element.
+    yield BrowserTestUtils.synthesizeMouse("div", 0, 0, {}, browser);
+    yield ContentTask.spawn(browser, {}, function* () {
+      let element = content.document.querySelector("div");
+      let selection = content.window.getSelection();
+      selection.selectAllChildren(element);
+    });
+
+    yield* cutCurrentSelection("div", "textContent", browser);
+
+    let trans = getTransferableFromClipboard(true);
+    let DOMWindowUtils = EventUtils._getDOMWindowUtils(window);
+    DOMWindowUtils.sendContentCommandEvent("pasteTransferable", trans);
+
+    yield ContentTask.spawn(browser, null, function* () {
+      let textArea = content.document.querySelector('div');
+      is(textArea.innerHTML, "<b>Bold Text</b><i>italics</i>",
+         "Send content command pasteTransferable successful");
+    });
+  });
+});
--- a/browser/base/content/test/tabPrompts/browser_multiplePrompts.js
+++ b/browser/base/content/test/tabPrompts/browser_multiplePrompts.js
@@ -51,16 +51,22 @@ add_task(function*() {
       if (i !== promptsCount) {
         is(prompt.hidden, true, "This prompt should be hidden.");
         i++;
         continue;
       }
 
       is(prompt.hidden, false, "The last prompt should not be hidden.");
       prompt.onButtonClick(0);
+
+      // The click is handled async; wait for an event loop turn for that to
+      // happen.
+      yield new Promise(function(resolve) {
+        Services.tm.mainThread.dispatch(resolve, Ci.nsIThread.DISPATCH_NORMAL);
+      });
     }
   }
 
   let prompts = tab.linkedBrowser.parentNode.querySelectorAll("tabmodalprompt");
   is(prompts.length, 0, "Prompts should all be dismissed.");
 
   yield BrowserTestUtils.removeTab(tab);
 });
--- a/browser/base/content/test/tabPrompts/browser_openPromptInBackgroundTab.js
+++ b/browser/base/content/test/tabPrompts/browser_openPromptInBackgroundTab.js
@@ -37,16 +37,20 @@ add_task(function*() {
   let row = ourPrompt.querySelector("row");
   ok(row, "Should have found the row with our checkbox");
   let checkbox = row.querySelector("checkbox[label*='example.com']");
   ok(checkbox, "The checkbox should be there");
   ok(!checkbox.checked, "Checkbox shouldn't be checked");
   // tick box and accept dialog
   checkbox.checked = true;
   ourPrompt.onButtonClick(0);
+  // Wait for that click to actually be handled completely.
+  yield new Promise(function(resolve) {
+    Services.tm.mainThread.dispatch(resolve, Ci.nsIThread.DISPATCH_NORMAL);
+  });
   // check permission is set
   let ps = Services.perms;
   is(ps.ALLOW_ACTION, ps.testPermission(makeURI(pageWithAlert), "focus-tab-by-prompt"),
      "Tab switching should now be allowed");
 
   let openedTabSelectedPromise = BrowserTestUtils.waitForAttribute("selected", openedTab, "true");
   // switch to other tab again
   yield BrowserTestUtils.switchTab(gBrowser, firstTab);
--- a/browser/components/contextualidentity/test/browser/browser.ini
+++ b/browser/components/contextualidentity/test/browser/browser.ini
@@ -8,17 +8,16 @@ support-files =
   serviceworker.html
   worker.js
 
 [browser_aboutURLs.js]
 skip-if = (debug && (os == "win" || os == "linux")) # intermittent negative leak bug 1271182
 [browser_eme.js]
 [browser_favicon.js]
 [browser_forgetaboutsite.js]
-[browser_newtabButton.js]
 [browser_usercontext.js]
 [browser_usercontextid_tabdrop.js]
 skip-if = os == "mac" || os == "win" # Intermittent failure - bug 1268276
 [browser_windowName.js]
 tags = openwindow
 [browser_windowOpen.js]
 tags = openwindow
 [browser_serviceworkers.js]
deleted file mode 100644
--- a/browser/components/contextualidentity/test/browser/browser_newtabButton.js
+++ /dev/null
@@ -1,34 +0,0 @@
-"use strict";
-
-// Testing that when the user opens the add tab menu and clicks menu items
-// the correct context id is opened
-
-add_task(function* test() {
-  yield SpecialPowers.pushPrefEnv({"set": [
-      ["privacy.userContext.enabled", true]
-  ]});
-
-  let newTab = document.getElementById('tabbrowser-tabs');
-  let newTabButton = document.getAnonymousElementByAttribute(newTab, "anonid", "tabs-newtab-button");
-  ok(newTabButton, "New tab button exists");
-  ok(!newTabButton.hidden, "New tab button is visible");
-  let popup = document.getAnonymousElementByAttribute(newTab, "anonid", "newtab-popup");
-
-  for (let i = 1; i <= 4; i++) {
-    let popupShownPromise = BrowserTestUtils.waitForEvent(popup, "popupshown");
-    EventUtils.synthesizeMouseAtCenter(newTabButton, {type: "mousedown"});
-
-    yield popupShownPromise;
-    let contextIdItem = popup.querySelector(`menuitem[usercontextid="${i}"]`);
-
-    ok(contextIdItem, `User context id ${i} exists`);
-
-    let waitForTabPromise = BrowserTestUtils.waitForNewTab(gBrowser);
-    EventUtils.synthesizeMouseAtCenter(contextIdItem, {});
-
-    let tab = yield waitForTabPromise;
-
-    is(tab.getAttribute('usercontextid'), i, `New tab has UCI equal ${i}`);
-    yield BrowserTestUtils.removeTab(tab);
-  }
-});
--- a/browser/components/places/content/editBookmarkOverlay.js
+++ b/browser/components/places/content/editBookmarkOverlay.js
@@ -126,24 +126,28 @@ var gEditItemOverlay = {
   _initDescriptionField() {
     if (!this._paneInfo.isItem)
       throw new Error("_initDescriptionField called unexpectedly");
 
     this._initTextField(this._descriptionField,
                         PlacesUIUtils.getItemDescription(this._paneInfo.itemId));
   },
 
-  _initKeywordField: Task.async(function* (aNewKeyword) {
-    if (!this._paneInfo.isBookmark)
+  _initKeywordField: Task.async(function* (newKeyword = "") {
+    if (!this._paneInfo.isBookmark) {
       throw new Error("_initKeywordField called unexpectedly");
+    }
 
-    let newKeyword = aNewKeyword;
-    if (newKeyword === undefined) {
-      let itemId = this._paneInfo.itemId;
-      newKeyword = PlacesUtils.bookmarks.getKeywordForBookmark(itemId);
+    if (!newKeyword) {
+      let entries = [];
+      yield PlacesUtils.keywords.fetch({ url: this._paneInfo.uri.spec },
+                                       e => entries.push(e));
+      if (entries.length > 0) {
+        this._keyword = newKeyword = entries[0].keyword;
+      }
     }
     this._initTextField(this._keywordField, newKeyword);
   }),
 
   _initLoadInSidebar: Task.async(function* () {
     if (!this._paneInfo.isBookmark)
       throw new Error("_initLoadInSidebar called unexpectedly");
 
@@ -210,17 +214,17 @@ var gEditItemOverlay = {
     // hide the description field for
     if (showOrCollapse("descriptionRow", isItem && !this.readOnly,
                        "description")) {
       this._initDescriptionField();
       this._descriptionField.readOnly = this.readOnly;
     }
 
     if (showOrCollapse("keywordRow", isBookmark, "keyword")) {
-      this._initKeywordField();
+      this._initKeywordField().catch(Components.utils.reportError);
       this._keywordField.readOnly = this.readOnly;
     }
 
     // Collapse the tag selector if the item does not accept tags.
     if (showOrCollapse("tagsRow", isURI || bulkTagging, "tags"))
       this._initTagsField().catch(Components.utils.reportError);
     else if (!this._element("tagsSelectorRow").collapsed)
       this.toggleTagsSelector().catch(Components.utils.reportError);
@@ -563,17 +567,17 @@ var gEditItemOverlay = {
         return;
       }
       Task.spawn(function* () {
         let guid = this._paneInfo.isTag
                     ? (yield PlacesUtils.promiseItemGuid(this._paneInfo.itemId))
                     : this._paneInfo.itemGuid;
         PlacesTransactions.EditTitle({ guid, title: newTitle })
                           .transact().catch(Components.utils.reportError);
-      }).catch(Cu.reportError);
+      }).catch(Components.utils.reportError);
     }
   },
 
   onDescriptionFieldChange() {
     if (this.readOnly || !this._paneInfo.isItem)
       return;
 
     let itemId = this._paneInfo.itemId;
@@ -620,24 +624,29 @@ var gEditItemOverlay = {
                       .transact().catch(Components.utils.reportError);
   },
 
   onKeywordFieldChange() {
     if (this.readOnly || !this._paneInfo.isBookmark)
       return;
 
     let itemId = this._paneInfo.itemId;
-    let newKeyword = this._keywordField.value;
+    let oldKeyword = this._keyword;
+    let keyword = this._keyword = this._keywordField.value;
+    let postData = this._paneInfo.postData;
     if (!PlacesUIUtils.useAsyncTransactions) {
-      let txn = new PlacesEditBookmarkKeywordTransaction(itemId, newKeyword, this._paneInfo.postData);
+      let txn = new PlacesEditBookmarkKeywordTransaction(itemId,
+                                                         keyword,
+                                                         postData,
+                                                         oldKeyword);
       PlacesUtils.transactionManager.doTransaction(txn);
       return;
     }
     let guid = this._paneInfo.itemGuid;
-    PlacesTransactions.EditKeyword({ guid, keyword: newKeyword })
+    PlacesTransactions.EditKeyword({ guid, keyword, postData, oldKeyword })
                       .transact().catch(Components.utils.reportError);
   },
 
   onLoadInSidebarCheckboxCommand() {
     if (!this.initialized || !this._paneInfo.isBookmark)
       return;
 
     let annotation = { name : PlacesUIUtils.LOAD_IN_SIDEBAR_ANNO };
@@ -1080,17 +1089,17 @@ var gEditItemOverlay = {
         if (this._paneInfo.visibleRows.has("tagsRow")) {
           delete this._paneInfo._cachedCommonTags;
           this._onTagsChange(aItemId);
         }
       }
       break;
     case "keyword":
       if (this._paneInfo.visibleRows.has("keywordRow"))
-        this._initKeywordField(aValue);
+        this._initKeywordField(aValue).catch(Components.utils.reportError);
       break;
     case PlacesUIUtils.DESCRIPTION_ANNO:
       if (this._paneInfo.visibleRows.has("descriptionRow"))
         this._initDescriptionField();
       break;
     case PlacesUIUtils.LOAD_IN_SIDEBAR_ANNO:
       if (this._paneInfo.visibleRows.has("loadInSidebarCheckbox"))
         this._initLoadInSidebar();
--- a/browser/components/preferences/in-content/tests/browser_subdialogs.js
+++ b/browser/components/preferences/in-content/tests/browser_subdialogs.js
@@ -54,28 +54,29 @@ function* open_subdialog_and_test_generi
 function* close_subdialog_and_test_generic_end_state(browser, closingFn, closingButton, acceptCount, options) {
   let dialogclosingPromise = ContentTask.spawn(browser, {closingButton, acceptCount}, function*(expectations) {
     let win = content.window;
     let subdialog = win.gSubDialog;
     let frame = subdialog._frame;
     info("waiting for dialogclosing");
     let closingEvent =
       yield ContentTaskUtils.waitForEvent(frame.contentWindow, "dialogclosing");
+    let closingButton = closingEvent.detail.button;
     let actualAcceptCount = frame.contentWindow.arguments &&
                             frame.contentWindow.arguments[0].acceptCount;
 
     info("waiting for about:blank load");
     yield ContentTaskUtils.waitForEvent(frame, "load");
 
     Assert.notEqual(win.getComputedStyle(subdialog._overlay, "").visibility, "visible",
       "overlay is not visible");
     Assert.equal(frame.getAttribute("style"), "", "inline styles should be cleared");
     Assert.equal(frame.contentWindow.location.href.toString(), "about:blank",
       "sub-dialog should be unloaded");
-    Assert.equal(closingEvent.detail.button, expectations.closingButton,
+    Assert.equal(closingButton, expectations.closingButton,
       "closing event should indicate button was '" + expectations.closingButton + "'");
     Assert.equal(actualAcceptCount, expectations.acceptCount,
       "should be 1 if accepted, 0 if canceled, undefined if closed w/out button");
   });
 
   if (options && options.runClosingFnOutsideOfContentTask) {
     yield closingFn();
   } else {
--- a/browser/components/search/test/browser.ini
+++ b/browser/components/search/test/browser.ini
@@ -18,18 +18,16 @@ support-files =
 [browser_addEngine.js]
 [browser_amazon.js]
 [browser_amazon_behavior.js]
 [browser_bing.js]
 [browser_bing_behavior.js]
 [browser_contextmenu.js]
 [browser_contextSearchTabPosition.js]
 skip-if = os == "mac" # bug 967013
-[browser_eBay.js]
-[browser_eBay_behavior.js]
 [browser_google.js]
 [browser_google_codes.js]
 [browser_google_behavior.js]
 [browser_healthreport.js]
 [browser_hiddenOneOffs_cleanup.js]
 [browser_hiddenOneOffs_diacritics.js]
 [browser_oneOffHeader.js]
 [browser_private_search_perwindowpb.js]
--- a/browser/components/search/test/browser_abouthome_behavior.js
+++ b/browser/components/search/test/browser_abouthome_behavior.js
@@ -70,23 +70,16 @@ function test() {
     {
       name: "Search with Yahoo from about:home",
       searchURL: replaceUrl("https://search.yahoo.com/search?p=foo&ei=UTF-8&fr=moz35"),
       run: function () {
         verify_about_home_search("Yahoo");
       }
     },
     {
-      name: "Search with eBay from about:home",
-      searchURL: replaceUrl("http://rover.ebay.com/rover/1/711-47294-18009-3/4?mfe=search&mpre=http://www.ebay.com/sch/i.html?_nkw=foo"),
-      run: function () {
-        verify_about_home_search("eBay");
-      }
-    },
-    {
       name: "Search with Google from about:home",
       searchURL: replaceUrl("https://www.google.com/search?q=foo&ie=utf-8&oe=utf-8"),
       run: function () {
         verify_about_home_search("Google");
       }
     },
     {
       name: "Search with Amazon.com from about:home",
deleted file mode 100644
--- a/browser/components/search/test/browser_eBay.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * Test eBay search plugin URLs
- */
-
-"use strict";
-
-const BROWSER_SEARCH_PREF = "browser.search.";
-
-function test() {
-  let engine = Services.search.getEngineByName("eBay");
-  ok(engine, "eBay");
-
-  let base = "http://rover.ebay.com/rover/1/711-47294-18009-3/4?mfe=search&mpre=http://www.ebay.com/sch/i.html?_nkw=foo";
-  let url;
-
-  // Test search URLs (including purposes).
-  url = engine.getSubmission("foo").uri.spec;
-  is(url, base, "Check search URL for 'foo'");
-
-  // Check search suggestion URL.
-  url = engine.getSubmission("foo", "application/x-suggestions+json").uri.spec;
-  is(url, "http://autosug.ebay.com/autosug?sId=0&kwd=foo&fmt=osr", "Check search suggestion URL for 'foo'");
-
-  // Check all other engine properties.
-  const EXPECTED_ENGINE = {
-    name: "eBay",
-    alias: null,
-    description: "eBay - Online auctions",
-    searchForm: "http://search.ebay.com/",
-    hidden: false,
-    wrappedJSObject: {
-      queryCharset: "ISO-8859-1",
-      "_iconURL": "data:image/x-icon;base64,AAABAAIAEBAAAAAAAAB6AQAAJgAAACAgAAAAAAAAQgMAAKABAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAFBSURBVDjLtZPdK0MBGIf3J5Babhx3rinFBWuipaUskX9DYvkopqgV90q5UJpyp0OKrUWM2VrRsS9D0zZKHGaOnW1nj4vtypVtPPe/533r9746QAAOAJXfo5Yzgg44pHrcugon/6Sgo0b+XuAOZ2iZiVQmyPoDpIwmUkYTzqM7GsdDdC7F6Lbf8pzOkfWOouzqeZem2b+2AqAV8zjD8yVBqqcf2b7C66yNiMGMfixIQSvi8Mp0LEbR5ADq1QSKWM+Gx0RC9nOZ2GLzwlIWdPWiuNzk4w/EpThNkyEAXKEP2ud8KGId2sspilhPMrmNwzfCuqePr/xbSfC5I/I0MMSj2YJ3z49gDdO2cEOrLUowJpE9G0QRG1ClKbR0EIdvmOPYcnUtnN+vsnZiQC1k/qnGagQ1n3LNzySUJZVskitnmr8BlQG7T2hvgxsAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAMJSURBVFjD7ZddSFNhGMeHXXQTZFFCWfR1pRhUECQlBdWVToo+6KYu1KigtDASG5qUfZgFZvahEDosECPDktKZS1FL+1DRnEvdUptjug91X2dnZzv/3vO6OZbWnR4v9sADL+fs7P97/s/znu2VAJD4UkpSSdKG+QubTyPBr+sXz8XCR64fIAHihVTis0SsUAoAVhEBrBKIHCGAEMB/ARi3F5LkbpS2WMRzYEEBXC2tsD6T03R9agsCGLNyqPw6CXmrBT06JvhbPHZwmkdwtR0B138PPKOHgzXD5jLAy3tmibo4K9weZwDAazJj/FQKRnfugfHMeRiTz0K3Ixam1HQKcPC+Fisu9NK1P08Uj4DleHgMdXC+WQ7nu3UEOhFMfTQcVUvQ1H4IN2sj8H2k7K+2TqCc3GseyA8AmDOzMBq7D9bS8sAr6nEJdNt3UbHVF1XQGtmZew8bTPT6tWoD3KpsUvlR8NxUoEICMvl6KQo+xqCwcRs4T8Ax5c8bFExjbAgAjO7aS8VsLypgq3g5nWStjztAhWRVhqAqeB6IuKTClkw1eNYEbrCQQBwD8yGGOsAooogLYejQPKBi7UPF9DkH+ezd+o141ZkUPAOC+L9SAMivNc7q46YMNSLTe4n1kaQF4XD3ZIDTPgU3XEYciKcAHrsGJS1xKFBGgyVzouiT4VbdGhjt/cEA5isyKsaz7jl3we7bg7Rqf6j0LoSldON4wWcqJDgQNGTN++l13vELA+MK6kKd6iryFOvxtidt9i5gO7owdjKJQliflNAU1pas6xQgnAzg1ux+lJEdILixNr0Pq9JUUA8NwVG9DM73G0jlcnh+V4BpjIWzJmIGQIjnXw5TiDuKSEwxurm3ITc8DNO51BnrLbIcsrW0dNA6RxgUKU1UdGVqLy5X6qGzTLvlnewiBZyGs3Yz6X8UeaYI3olvZDhzwLumZ+eHvooCCC0Q5VUsb4unwycM4YIDqA01tPqmgbzQr2EIYPECiPm33LYoDiZSsY9moh9O/Znoa4d9HkXtPg2pX/cPKCoRQ+ocZa4AAAAASUVORK5CYII=",
-      _urls : [
-        {
-          type: "application/x-suggestions+json",
-          method: "GET",
-          template: "http://autosug.ebay.com/autosug",
-          params: [
-            {
-              name: "sId",
-              value: "0",
-              purpose: undefined,
-            },
-            {
-              name: "kwd",
-              value: "{searchTerms}",
-              purpose: undefined,
-            },
-            {
-              name: "fmt",
-              value: "osr",
-              purpose: undefined,
-            },
-          ],
-        },
-        {
-          type: "text/html",
-          method: "GET",
-          template: "http://rover.ebay.com/rover/1/711-47294-18009-3/4",
-          params: [
-            {
-              name: "mfe",
-              value: "search",
-              purpose: undefined,
-            },
-            {
-              name: "mpre",
-              value: "http://www.ebay.com/sch/i.html?_nkw={searchTerms}",
-              purpose: undefined,
-            },
-          ],
-          mozparams: {},
-        },
-      ],
-    },
-  };
-
-  isSubObjectOf(EXPECTED_ENGINE, engine, "eBay");
-}
deleted file mode 100644
--- a/browser/components/search/test/browser_eBay_behavior.js
+++ /dev/null
@@ -1,166 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * Test eBay search plugin URLs
- */
-
-"use strict";
-
-const BROWSER_SEARCH_PREF = "browser.search.";
-
-
-function test() {
-  let engine = Services.search.getEngineByName("eBay");
-  ok(engine, "eBay is installed");
-
-  let previouslySelectedEngine = Services.search.currentEngine;
-  Services.search.currentEngine = engine;
-  engine.alias = 'e';
-
-  let base = "http://rover.ebay.com/rover/1/711-47294-18009-3/4?mfe=search&mpre=http://www.ebay.com/sch/i.html?_nkw=foo";
-  let url;
-
-  // Test search URLs (including purposes).
-  url = engine.getSubmission("foo").uri.spec;
-  is(url, base, "Check search URL for 'foo'");
-
-  waitForExplicitFinish();
-
-  var gCurrTest;
-  var gTests = [
-    {
-      name: "context menu search",
-      searchURL: base,
-      run: function () {
-        // Simulate a contextmenu search
-        // FIXME: This is a bit "low-level"...
-        BrowserSearch.loadSearch("foo", false, "contextmenu");
-      }
-    },
-    {
-      name: "keyword search",
-      searchURL: base,
-      run: function () {
-        gURLBar.value = "? foo";
-        gURLBar.focus();
-        EventUtils.synthesizeKey("VK_RETURN", {});
-      }
-    },
-    {
-      name: "keyword search",
-      searchURL: base,
-      run: function () {
-        gURLBar.value = "e foo";
-        gURLBar.focus();
-        EventUtils.synthesizeKey("VK_RETURN", {});
-      }
-    },
-    {
-      name: "search bar search",
-      searchURL: base,
-      run: function () {
-        let sb = BrowserSearch.searchBar;
-        sb.focus();
-        sb.value = "foo";
-        registerCleanupFunction(function () {
-          sb.value = "";
-        });
-        EventUtils.synthesizeKey("VK_RETURN", {});
-      }
-    },
-    {
-      name: "new tab search",
-      searchURL: base,
-      run: function () {
-        function doSearch(doc) {
-          // Re-add the listener, and perform a search
-          gBrowser.addProgressListener(listener);
-          doc.getElementById("newtab-search-text").value = "foo";
-          doc.getElementById("newtab-search-submit").click();
-        }
-
-        // load about:newtab, but remove the listener first so it doesn't
-        // get in the way
-        gBrowser.removeProgressListener(listener);
-        gBrowser.loadURI("about:newtab");
-        info("Waiting for about:newtab load");
-        tab.linkedBrowser.addEventListener("load", function load(event) {
-          if (event.originalTarget != tab.linkedBrowser.contentDocument ||
-              event.target.location.href == "about:blank") {
-            info("skipping spurious load event");
-            return;
-          }
-          tab.linkedBrowser.removeEventListener("load", load, true);
-
-          // Observe page setup
-          let win = gBrowser.contentWindow;
-          if (win.gSearch.currentEngineName ==
-              Services.search.currentEngine.name) {
-            doSearch(win.document);
-          }
-          else {
-            info("Waiting for newtab search init");
-            win.addEventListener("ContentSearchService", function done(event) {
-              info("Got newtab search event " + event.detail.type);
-              if (event.detail.type == "State") {
-                win.removeEventListener("ContentSearchService", done);
-                // Let gSearch respond to the event before continuing.
-                executeSoon(() => doSearch(win.document));
-              }
-            });
-          }
-        }, true);
-      }
-    }
-  ];
-
-  function nextTest() {
-    if (gTests.length) {
-      gCurrTest = gTests.shift();
-      info("Running : " + gCurrTest.name);
-      executeSoon(gCurrTest.run);
-    } else {
-      finish();
-    }
-  }
-
-  let tab = gBrowser.selectedTab = gBrowser.addTab();
-
-  let listener = {
-    onStateChange: function onStateChange(webProgress, req, flags, status) {
-      info("onStateChange");
-      // Only care about top-level document starts
-      let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
-                     Ci.nsIWebProgressListener.STATE_START;
-      if (!(flags & docStart) || !webProgress.isTopLevel)
-        return;
-
-      if (req.originalURI.spec == "about:blank")
-        return;
-
-      info("received document start");
-
-      ok(req instanceof Ci.nsIChannel, "req is a channel");
-      is(req.originalURI.spec, gCurrTest.searchURL, "search URL was loaded");
-      info("Actual URI: " + req.URI.spec);
-
-      req.cancel(Components.results.NS_ERROR_FAILURE);
-
-      executeSoon(nextTest);
-    }
-  }
-
-  registerCleanupFunction(function () {
-    engine.alias = undefined;
-    gBrowser.removeProgressListener(listener);
-    gBrowser.removeTab(tab);
-    Services.search.currentEngine = previouslySelectedEngine;
-  });
-
-  tab.linkedBrowser.addEventListener("load", function load() {
-    tab.linkedBrowser.removeEventListener("load", load, true);
-    gBrowser.addProgressListener(listener);
-    nextTest();
-  }, true);
-}
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -738,8 +738,10 @@ pendingCrashReports.ignoreAll = Ignore
 decoder.noCodecs.button = Learn how
 decoder.noCodecs.accesskey = L
 decoder.noCodecs.message = To play video, you may need to install Microsoft’s Media Feature Pack.
 decoder.noCodecsVista.message = To play video, you may need to install Microsoft’s Platform Update Supplement for Windows Vista.
 decoder.noCodecsXP.message = To play video, you may need to enable Adobe’s Primetime Content Decryption Module.
 decoder.noCodecsLinux.message = To play video, you may need to install the required video codecs.
 decoder.noHWAcceleration.message = To improve video quality, you may need to install Microsoft’s Media Feature Pack.
 decoder.noHWAccelerationVista.message = To improve video quality, you may need to install Microsoft’s Platform Update Supplement for Windows Vista.
+
+permissions.remove.tooltip = Clear this permission and ask again
deleted file mode 100644
--- a/browser/locales/en-US/searchplugins/eBay.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
-   - License, v. 2.0. If a copy of the MPL was not distributed with this
-   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>eBay</ShortName>
-<Description>eBay - Online auctions</Description>
-<InputEncoding>ISO-8859-1</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAB6AQAAJgAAACAgAAAAAAAAQgMAAKABAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAFBSURBVDjLtZPdK0MBGIf3J5Babhx3rinFBWuipaUskX9DYvkopqgV90q5UJpyp0OKrUWM2VrRsS9D0zZKHGaOnW1nj4vtypVtPPe/533r9746QAAOAJXfo5Yzgg44pHrcugon/6Sgo0b+XuAOZ2iZiVQmyPoDpIwmUkYTzqM7GsdDdC7F6Lbf8pzOkfWOouzqeZem2b+2AqAV8zjD8yVBqqcf2b7C66yNiMGMfixIQSvi8Mp0LEbR5ADq1QSKWM+Gx0RC9nOZ2GLzwlIWdPWiuNzk4w/EpThNkyEAXKEP2ud8KGId2sspilhPMrmNwzfCuqePr/xbSfC5I/I0MMSj2YJ3z49gDdO2cEOrLUowJpE9G0QRG1ClKbR0EIdvmOPYcnUtnN+vsnZiQC1k/qnGagQ1n3LNzySUJZVskitnmr8BlQG7T2hvgxsAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAMJSURBVFjD7ZddSFNhGMeHXXQTZFFCWfR1pRhUECQlBdWVToo+6KYu1KigtDASG5qUfZgFZvahEDosECPDktKZS1FL+1DRnEvdUptjug91X2dnZzv/3vO6OZbWnR4v9sADL+fs7P97/s/znu2VAJD4UkpSSdKG+QubTyPBr+sXz8XCR64fIAHihVTis0SsUAoAVhEBrBKIHCGAEMB/ARi3F5LkbpS2WMRzYEEBXC2tsD6T03R9agsCGLNyqPw6CXmrBT06JvhbPHZwmkdwtR0B138PPKOHgzXD5jLAy3tmibo4K9weZwDAazJj/FQKRnfugfHMeRiTz0K3Ixam1HQKcPC+Fisu9NK1P08Uj4DleHgMdXC+WQ7nu3UEOhFMfTQcVUvQ1H4IN2sj8H2k7K+2TqCc3GseyA8AmDOzMBq7D9bS8sAr6nEJdNt3UbHVF1XQGtmZew8bTPT6tWoD3KpsUvlR8NxUoEICMvl6KQo+xqCwcRs4T8Ax5c8bFExjbAgAjO7aS8VsLypgq3g5nWStjztAhWRVhqAqeB6IuKTClkw1eNYEbrCQQBwD8yGGOsAooogLYejQPKBi7UPF9DkH+ezd+o141ZkUPAOC+L9SAMivNc7q46YMNSLTe4n1kaQF4XD3ZIDTPgU3XEYciKcAHrsGJS1xKFBGgyVzouiT4VbdGhjt/cEA5isyKsaz7jl3we7bg7Rqf6j0LoSldON4wWcqJDgQNGTN++l13vELA+MK6kKd6iryFOvxtidt9i5gO7owdjKJQliflNAU1pas6xQgnAzg1ux+lJEdILixNr0Pq9JUUA8NwVG9DM73G0jlcnh+V4BpjIWzJmIGQIjnXw5TiDuKSEwxurm3ITc8DNO51BnrLbIcsrW0dNA6RxgUKU1UdGVqLy5X6qGzTLvlnewiBZyGs3Yz6X8UeaYI3olvZDhzwLumZ+eHvooCCC0Q5VUsb4unwycM4YIDqA01tPqmgbzQr2EIYPECiPm33LYoDiZSsY9moh9O/Znoa4d9HkXtPg2pX/cPKCoRQ+ocZa4AAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="http://autosug.ebay.com/autosug">
-  <Param name="sId" value="0" />
-  <Param name="kwd" value="{searchTerms}" />
-  <Param name="fmt" value="osr" />
-</Url>
-<Url type="text/html" method="GET" template="http://rover.ebay.com/rover/1/711-47294-18009-3/4" resultdomain="ebay.com">
-  <Param name="mfe"  value="search" />
-  <Param name="mpre" value="http://www.ebay.com/sch/i.html?_nkw={searchTerms}" />
-</Url>
-<SearchForm>http://search.ebay.com/</SearchForm>
-</SearchPlugin>
--- a/browser/locales/en-US/searchplugins/list.txt
+++ b/browser/locales/en-US/searchplugins/list.txt
@@ -1,8 +1,7 @@
 amazondotcom
 bing
-eBay
 google
 twitter
 wikipedia
 yahoo
 yahoo-en-CA:hidden
--- a/browser/modules/ContentSearch.jsm
+++ b/browser/modules/ContentSearch.jsm
@@ -391,17 +391,19 @@ this.ContentSearch = {
     }
   },
 
   _onMessage: Task.async(function* (msg) {
     let methodName = "_onMessage" + msg.data.type;
     if (methodName in this) {
       yield this._initService();
       yield this[methodName](msg, msg.data.data);
-      msg.target.removeEventListener("SwapDocShells", msg, true);
+      if (!Cu.isDeadWrapper(msg.target)) {
+        msg.target.removeEventListener("SwapDocShells", msg, true);
+      }
     }
   }),
 
   _onMessageGetState: function (msg, data) {
     return this.currentStateObj().then(state => {
       this._reply(msg, "State", state);
     });
   },
@@ -484,17 +486,17 @@ this.ContentSearch = {
       this._suggestionMap.set(browser, data);
     }
     return data;
   },
 
   _reply: function (msg, type, data) {
     // We reply asyncly to messages, and by the time we reply the browser we're
     // responding to may have been destroyed.  messageManager is null then.
-    if (msg.target.messageManager) {
+    if (!Cu.isDeadWrapper(msg.target) && msg.target.messageManager) {
       msg.target.messageManager.sendAsyncMessage(...this._msgArgs(type, data));
     }
   },
 
   _broadcast: function (type, data) {
     Cc["@mozilla.org/globalmessagemanager;1"].
       getService(Ci.nsIMessageListenerManager).
       broadcastAsyncMessage(...this._msgArgs(type, data));
deleted file mode 100644
--- a/build/autoconf/linux.m4
+++ /dev/null
@@ -1,39 +0,0 @@
-dnl This Source Code Form is subject to the terms of the Mozilla Public
-dnl License, v. 2.0. If a copy of the MPL was not distributed with this
-dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-AC_DEFUN([MOZ_LINUX_PERF_EVENT],
-[
-
-MOZ_ARG_WITH_STRING(linux-headers,
-[  --with-linux-headers=DIR
-                          location where the Linux kernel headers can be found],
-    linux_headers=$withval)
-
-LINUX_HEADERS_INCLUDES=
-
-if test "$linux_headers"; then
-    LINUX_HEADERS_INCLUDES="-I$linux_headers"
-fi
-
-_SAVE_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS $LINUX_HEADERS_INCLUDES"
-
-dnl Performance measurement headers.
-MOZ_CHECK_HEADER(linux/perf_event.h,
-    [AC_CACHE_CHECK(for perf_event_open system call,ac_cv_perf_event_open,
-        [AC_TRY_COMPILE([#include <asm/unistd.h>],[return sizeof(__NR_perf_event_open);],
-        ac_cv_perf_event_open=yes,
-        ac_cv_perf_event_open=no)])])
-if test "$ac_cv_perf_event_open" = "yes"; then
-    HAVE_LINUX_PERF_EVENT_H=1
-else
-    HAVE_LINUX_PERF_EVENT_H=
-    LINUX_HEADERS_INCLUDES=
-fi
-AC_SUBST(HAVE_LINUX_PERF_EVENT_H)
-AC_SUBST(LINUX_HEADERS_INCLUDES)
-
-CFLAGS="$_SAVE_CFLAGS"
-
-])
--- a/build/moz.configure/compilers-util.configure
+++ b/build/moz.configure/compilers-util.configure
@@ -38,24 +38,20 @@ def compiler_class(compiler):
 
             if check_msg:
                 def checking_fn(fn):
                     return checking(check_msg)(fn)
             else:
                 def checking_fn(fn):
                     return fn
 
-            def get_flags():
-                if flags:
-                    return flags[:]
-
-            @depends_when(self, extra_toolchain_flags, when=when)
+            @depends_when(self, dependable(flags), extra_toolchain_flags, when=when)
             @checking_fn
-            def func(compiler, extra_flags):
-                flags = get_flags() or []
+            def func(compiler, flags, extra_flags):
+                flags = flags or []
                 flags += extra_flags
                 flags.append('-c')
 
                 if try_invoke_compiler(
                     compiler.wrapper + [compiler.compiler] + compiler.flags,
                     compiler.language, source, flags,
                     onerror=onerror) is not None:
                     return True
--- a/build/moz.configure/headers.configure
+++ b/build/moz.configure/headers.configure
@@ -56,8 +56,36 @@ check_header('sys/queue.h',
              when=non_msvc_compiler)
 
 check_headers(
     'sys/types.h',
     'netinet/in.h',
     'byteswap.h',
     when=non_msvc_compiler,
 )
+
+# TODO: Move these checks to file specific to --enable-project=js.
+have_perf_event_h = check_header('linux/perf_event.h',
+                                 when=building_linux)
+
+js_option('--with-linux-headers',
+          help='location where the Linux kernel headers can be found',
+          nargs=1)
+
+passed_linux_header_flags = depends_if('--with-linux-headers')(lambda v: ['-I%s' % v[0]])
+
+@depends_when(try_compile(includes=['asm/unistd.h'],
+                          body='return sizeof(__NR_perf_event_open);',
+                          flags=passed_linux_header_flags,
+                          check_msg='for perf_event_open system call'),
+              when=have_perf_event_h)
+def have_perf_event_open(have_perf_event_open):
+    if have_perf_event_open:
+        return True
+
+set_config('HAVE_LINUX_PERF_EVENT_H', have_perf_event_open)
+
+@depends(passed_linux_header_flags, have_perf_event_open)
+def linux_headers_includes(passed_linux_header_flags, have_perf_event_open):
+    if have_perf_event_open and passed_linux_header_flags:
+        return passed_linux_header_flags[0]
+
+set_config('LINUX_HEADERS_INCLUDES', linux_headers_includes)
--- a/build/moz.configure/old.configure
+++ b/build/moz.configure/old.configure
@@ -265,17 +265,16 @@ def old_configure_options(*options):
     '--with-doc-include-dirs',
     '--with-doc-input-dirs',
     '--with-doc-output-dir',
     '--with-float-abi',
     '--with-fpu',
     '--with-intl-api',
     '--with-ios-sdk',
     '--with-jitreport-granularity',
-    '--with-linux-headers',
     '--with-macbundlename-prefix',
     '--with-macos-private-frameworks',
     '--with-macos-sdk',
     '--with-nspr-cflags',
     '--with-nspr-exec-prefix',
     '--with-nspr-libs',
     '--with-nspr-prefix',
     '--with-nss-exec-prefix',
--- a/caps/nsScriptSecurityManager.cpp
+++ b/caps/nsScriptSecurityManager.cpp
@@ -251,18 +251,20 @@ nsScriptSecurityManager::AppStatusForPri
     // browser frame, so non-desktop should be able to assume that
     // inIsolatedMozBrowser is true for all mozbrowser frames.  Additionally,
     // apps are no longer used on desktop, so appId is always NO_APP_ID.  We use
     // a release assertion in nsFrameLoader::OwnerIsIsolatedMozBrowserFrame so
     // that platforms with apps can assume inIsolatedMozBrowser is true for all
     // mozbrowser frames.
     bool inIsolatedMozBrowser = aPrin->GetIsInIsolatedMozBrowserElement();
 
-    NS_WARN_IF_FALSE(appId != nsIScriptSecurityManager::UNKNOWN_APP_ID,
-                     "Asking for app status on a principal with an unknown app id");
+    NS_WARNING_ASSERTION(
+      appId != nsIScriptSecurityManager::UNKNOWN_APP_ID,
+      "Asking for app status on a principal with an unknown app id");
+
     // Installed apps have a valid app id (not NO_APP_ID or UNKNOWN_APP_ID)
     // and they are not inside a mozbrowser.
     if (appId == nsIScriptSecurityManager::NO_APP_ID ||
         appId == nsIScriptSecurityManager::UNKNOWN_APP_ID ||
         inIsolatedMozBrowser)
     {
         return nsIPrincipal::APP_STATUS_NOT_INSTALLED;
     }
--- a/chrome/nsChromeProtocolHandler.cpp
+++ b/chrome/nsChromeProtocolHandler.cpp
@@ -134,19 +134,18 @@ nsChromeProtocolHandler::NewChannel2(nsI
             mozilla::services::GetChromeRegistryService();
         NS_ENSURE_TRUE(nsChromeRegistry::gChromeRegistry, NS_ERROR_FAILURE);
     }
 
     nsCOMPtr<nsIURI> resolvedURI;
     rv = nsChromeRegistry::gChromeRegistry->ConvertChromeURL(aURI, getter_AddRefs(resolvedURI));
     if (NS_FAILED(rv)) {
 #ifdef DEBUG
-        nsAutoCString spec;
-        aURI->GetSpec(spec);
-        printf("Couldn't convert chrome URL: %s\n", spec.get());
+        printf("Couldn't convert chrome URL: %s\n",
+               aURI->GetSpecOrDefault().get());
 #endif
         return rv;
     }
 
     rv = NS_NewChannelInternal(getter_AddRefs(result),
                                resolvedURI,
                                aLoadInfo);
     NS_ENSURE_SUCCESS(rv, rv);
--- a/chrome/nsChromeRegistryChrome.cpp
+++ b/chrome/nsChromeRegistryChrome.cpp
@@ -448,17 +448,18 @@ nsChromeRegistryChrome::SendRegisteredCh
     ContentParent::GetAll(parents);
     if (!parents.Length())
       return;
 
     for (uint32_t i = 0; i < parents.Length(); i++) {
       DebugOnly<bool> success =
         parents[i]->SendRegisterChrome(packages, resources, overrides,
                                        mSelectedLocale, true);
-      NS_WARN_IF_FALSE(success, "couldn't reset a child's registered chrome");
+      NS_WARNING_ASSERTION(success,
+                           "couldn't reset a child's registered chrome");
     }
   }
 }
 
 /* static */ void
 nsChromeRegistryChrome::ChromePackageFromPackageEntry(const nsACString& aPackageName,
                                                       PackageEntry* aPackage,
                                                       ChromePackage* aChromePackage,
--- a/devtools/client/debugger/moz.build
+++ b/devtools/client/debugger/moz.build
@@ -10,10 +10,11 @@ DIRS += [
 
 DevToolsModules(
     'debugger-commands.js',
     'panel.js'
 )
 
 BROWSER_CHROME_MANIFESTS += [
   'new/test/mochitest/browser.ini',
-  'test/mochitest/browser.ini'
+  'test/mochitest/browser.ini',
+  'test/mochitest/browser2.ini'
 ]
--- a/devtools/client/debugger/test/mochitest/browser.ini
+++ b/devtools/client/debugger/test/mochitest/browser.ini
@@ -1,8 +1,11 @@
+# Tests in this directory are split into two manifests (this and browser2.ini)
+# to facilitate better chunking; see bug 1294489.
+
 [DEFAULT]
 tags = devtools
 subsuite = devtools
 skip-if = (os == 'linux' && debug && bits == 32)
 support-files =
   addon1.xpi
   addon2.xpi
   addon3.xpi
@@ -307,331 +310,8 @@ skip-if = e10s && debug
 [browser_dbg_location-changes-03-new.js]
 skip-if = e10s # TODO
 [browser_dbg_location-changes-04-breakpoint.js]
 skip-if = e10s # TODO
 [browser_dbg_multiple-windows.js]
 skip-if = e10s # TODO
 [browser_dbg_navigation.js]
 skip-if = e10s && debug
-[browser_dbg_no-dangling-breakpoints.js]
-skip-if = e10s && debug
-[browser_dbg_no-page-sources.js]
-skip-if = e10s && debug
-[browser_dbg_on-pause-highlight.js]
-skip-if = e10s && debug
-[browser_dbg_on-pause-raise.js]
-skip-if = e10s && debug || os == "linux" # Bug 888811 & bug 891176
-[browser_dbg_optimized-out-vars.js]
-skip-if = e10s && debug
-[browser_dbg_panel-size.js]
-skip-if = e10s && debug
-[browser_dbg_parser-01.js]
-skip-if = e10s && debug
-[browser_dbg_parser-02.js]
-skip-if = e10s && debug
-[browser_dbg_parser-03.js]
-skip-if = e10s && debug
-[browser_dbg_parser-04.js]
-skip-if = e10s && debug
-[browser_dbg_parser-05.js]
-skip-if = e10s && debug
-[browser_dbg_parser-06.js]
-skip-if = e10s && debug
-[browser_dbg_parser-07.js]
-skip-if = e10s && debug
-[browser_dbg_parser-08.js]
-skip-if = e10s && debug
-[browser_dbg_parser-09.js]
-skip-if = e10s && debug
-[browser_dbg_parser-10.js]
-skip-if = e10s && debug
-[browser_dbg_parser-11.js]
-[browser_dbg_parser-computed-name.js]
-[browser_dbg_parser-function-defaults.js]
-[browser_dbg_parser-spread-expression.js]
-[browser_dbg_parser-template-strings.js]
-skip-if = e10s && debug
-[browser_dbg_pause-exceptions-01.js]
-skip-if = e10s && debug
-[browser_dbg_pause-exceptions-02.js]
-skip-if = e10s && debug
-[browser_dbg_pause-no-step.js]
-skip-if = e10s && debug
-[browser_dbg_pause-resume.js]
-skip-if = e10s && debug
-[browser_dbg_pause-warning.js]
-skip-if = e10s && debug
-[browser_dbg_paused-keybindings.js]
-skip-if = e10s
-[browser_dbg_post-page.js]
-[browser_dbg_pretty-print-01.js]
-skip-if = e10s && debug
-[browser_dbg_pretty-print-02.js]
-skip-if = e10s && debug
-[browser_dbg_pretty-print-03.js]
-skip-if = e10s && debug
-[browser_dbg_pretty-print-04.js]
-skip-if = e10s && debug
-[browser_dbg_pretty-print-05.js]
-skip-if = e10s && debug
-[browser_dbg_pretty-print-06.js]
-skip-if = e10s && debug
-[browser_dbg_pretty-print-07.js]
-skip-if = e10s && debug
-[browser_dbg_pretty-print-08.js]
-skip-if = e10s && debug
-[browser_dbg_pretty-print-09.js]
-skip-if = e10s && debug
-[browser_dbg_pretty-print-10.js]
-skip-if = e10s && debug
-[browser_dbg_pretty-print-11.js]
-skip-if = e10s && debug
-[browser_dbg_pretty-print-12.js]
-skip-if = e10s && debug
-[browser_dbg_pretty-print-13.js]
-skip-if = e10s && debug
-[browser_dbg_pretty-print-on-paused.js]
-skip-if = e10s && debug
-[browser_dbg_progress-listener-bug.js]
-skip-if = e10s && debug
-[browser_dbg_promises-allocation-stack.js]
-skip-if = e10s && debug
-[browser_dbg_promises-chrome-allocation-stack.js]
-skip-if = true # Bug 1177730
-[browser_dbg_promises-fulfillment-stack.js]
-skip-if = e10s && debug
-[browser_dbg_promises-rejection-stack.js]
-skip-if = e10s && debug
-[browser_dbg_reload-preferred-script-02.js]
-skip-if = e10s && debug
-[browser_dbg_reload-preferred-script-03.js]
-skip-if = e10s && debug
-[browser_dbg_reload-same-script.js]
-skip-if = e10s && debug
-[browser_dbg_scripts-switching-01.js]
-skip-if = e10s && debug
-[browser_dbg_scripts-switching-02.js]
-skip-if = e10s && debug
-[browser_dbg_scripts-switching-03.js]
-skip-if = e10s && debug
-[browser_dbg_search-autofill-identifier.js]
-skip-if = e10s && debug
-[browser_dbg_search-basic-01.js]
-skip-if = e10s && debug
-[browser_dbg_search-basic-02.js]
-skip-if = e10s && debug
-[browser_dbg_search-basic-03.js]
-skip-if = e10s && debug
-[browser_dbg_search-basic-04.js]
-skip-if = e10s && debug
-[browser_dbg_search-global-01.js]
-skip-if = e10s && debug
-[browser_dbg_search-global-02.js]
-skip-if = e10s && debug
-[browser_dbg_search-global-03.js]
-skip-if = e10s # Bug 1093535
-[browser_dbg_search-global-04.js]
-skip-if = e10s && debug
-[browser_dbg_search-global-05.js]
-skip-if = e10s && debug
-[browser_dbg_search-global-06.js]
-skip-if = e10s && debug
-[browser_dbg_search-popup-jank.js]
-skip-if = e10s && debug
-[browser_dbg_search-sources-01.js]
-skip-if = e10s && debug
-[browser_dbg_search-sources-02.js]
-skip-if = e10s && debug
-[browser_dbg_search-sources-03.js]
-skip-if = e10s && debug
-[browser_dbg_search-symbols.js]
-skip-if = (e10s && debug) || os == "linux" # Bug 1132375
-[browser_dbg_searchbox-help-popup-01.js]
-skip-if = e10s && debug
-[browser_dbg_searchbox-help-popup-02.js]
-skip-if = e10s && debug
-[browser_dbg_searchbox-parse.js]
-skip-if = e10s && debug
-[browser_dbg_source-maps-01.js]
-skip-if = e10s && debug
-[browser_dbg_source-maps-02.js]
-skip-if = e10s && debug
-[browser_dbg_source-maps-03.js]
-skip-if = e10s && debug
-[browser_dbg_source-maps-04.js]
-skip-if = e10s # Bug 1093535
-[browser_dbg_sources-cache.js]
-[browser_dbg_sources-contextmenu-01.js]
-subsuite = clipboard
-[browser_dbg_sources-contextmenu-02.js]
-skip-if = e10s && debug
-[browser_dbg_sources-eval-01.js]
-skip-if = true # non-named eval sources turned off for now, bug 1124106
-[browser_dbg_sources-eval-02.js]
-[browser_dbg_sources-iframe-reload.js]
-[browser_dbg_sources-keybindings.js]
-subsuite = clipboard
-skip-if = e10s && debug
-[browser_dbg_sources-labels.js]
-skip-if = e10s && debug
-[browser_dbg_sources-large.js]
-[browser_dbg_sources-sorting.js]
-skip-if = e10s && debug
-[browser_dbg_sources-bookmarklet.js]
-skip-if = e10s && debug
-[browser_dbg_sources-webext-contentscript.js]
-[browser_dbg_split-console-paused-reload.js]
-skip-if = true # Bug 1288348 - previously e10s && debug
-[browser_dbg_stack-01.js]
-skip-if = e10s && debug
-[browser_dbg_stack-02.js]
-skip-if = e10s && debug
-[browser_dbg_stack-03.js]
-skip-if = e10s # TODO
-[browser_dbg_stack-04.js]
-skip-if = e10s && debug
-[browser_dbg_stack-05.js]
-skip-if = e10s && (debug || asan) # timeouts
-[browser_dbg_stack-06.js]
-skip-if = e10s && debug
-[browser_dbg_stack-07.js]
-skip-if = e10s && debug
-[browser_dbg_stack-contextmenu-01.js]
-skip-if = e10s && debug
-[browser_dbg_stack-contextmenu-02.js]
-subsuite = clipboard
-skip-if = e10s && debug
-[browser_dbg_step-out.js]
-skip-if = e10s && debug
-[browser_dbg_tabactor-01.js]
-skip-if = e10s # TODO
-[browser_dbg_tabactor-02.js]
-skip-if = e10s # TODO
-[browser_dbg_terminate-on-tab-close.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-01.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-02.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-03.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-04.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-05.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-06.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-07.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-08.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-accessibility.js]
-subsuite = clipboard
-skip-if = e10s && debug
-[browser_dbg_variables-view-data.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-edit-cancel.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-edit-click.js]
-skip-if = e10s || (os == 'mac' || os == 'win') && (debug == false) # Bug 986166
-[browser_dbg_variables-view-edit-getset-01.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-edit-getset-02.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-edit-value.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-edit-watch.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-filter-01.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-filter-02.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-filter-03.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-filter-04.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-filter-05.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-filter-pref.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-filter-searchbox.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-frame-parameters-01.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-frame-parameters-02.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-frame-parameters-03.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-frame-with.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-frozen-sealed-nonext.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-hide-non-enums.js]
-[browser_dbg_variables-view-large-array-buffer.js]
-[browser_dbg_variables-view-map-set.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-override-01.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-override-02.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-popup-01.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-popup-02.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-popup-03.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-popup-04.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-popup-05.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-popup-06.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-popup-07.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-popup-08.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-popup-09.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-popup-10.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-popup-11.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-popup-12.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-popup-13.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-popup-14.js]
-skip-if = true # Bug 1029545
-[browser_dbg_variables-view-popup-15.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-popup-16.js]
-skip-if = e10s  && debug
-[browser_dbg_variables-view-popup-17.js]
-skip-if = e10s  && debug
-[browser_dbg_variables-view-reexpand-01.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-reexpand-02.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-reexpand-03.js]
-skip-if = e10s && debug
-[browser_dbg_variables-view-webidl.js]
-skip-if = e10s && debug
-[browser_dbg_watch-expressions-01.js]
-skip-if = e10s && debug
-[browser_dbg_watch-expressions-02.js]
-skip-if = e10s && debug
-[browser_dbg_worker-console-01.js]
-skip-if = e10s && debug
-[browser_dbg_worker-console-02.js]
-skip-if = e10s && debug
-[browser_dbg_worker-console-03.js]
-skip-if = e10s && debug
-[browser_dbg_worker-source-map.js]
-skip-if = e10s && debug
-[browser_dbg_worker-window.js]
-skip-if = e10s && debug
-[browser_dbg_WorkerActor.attach.js]
-skip-if = e10s && debug
-[browser_dbg_WorkerActor.attachThread.js]
-skip-if = e10s && debug
-[browser_dbg_split-console-keypress.js]
-skip-if = e10s && (debug || os == "linux") # Bug 1214439
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/test/mochitest/browser2.ini
@@ -0,0 +1,460 @@
+# Tests in this directory are split into two manifests (this and browser.ini)
+# to facilitate better chunking; see bug 1294489.
+
+[DEFAULT]
+tags = devtools
+subsuite = devtools
+skip-if = (os == 'linux' && debug && bits == 32)
+support-files =
+  addon1.xpi
+  addon2.xpi
+  addon3.xpi
+  addon4.xpi
+  addon5.xpi
+  addon-webext-contentscript.xpi
+  addon-source/browser_dbg_addon5/*
+  code_binary_search.coffee
+  code_binary_search.js
+  code_binary_search.map
+  code_blackboxing_blackboxme.js
+  code_blackboxing_one.js
+  code_blackboxing_three.js
+  code_blackboxing_two.js
+  code_blackboxing_unblackbox.min.js
+  code_breakpoints-break-on-last-line-of-script-on-reload.js
+  code_breakpoints-other-tabs.js
+  code_bug-896139.js
+  code_frame-script.js
+  code_function-jump-01.js
+  code_function-search-01.js
+  code_function-search-02.js
+  code_function-search-03.js
+  code_location-changes.js
+  code_listworkers-worker1.js
+  code_listworkers-worker2.js
+  code_math.js
+  code_math.map
+  code_math.min.js
+  code_math_bogus_map.js
+  code_same-line-functions.js
+  code_script-eval.js
+  code_script-switching-01.js
+  code_script-switching-02.js
+  code_test-editor-mode
+  code_ugly.js
+  code_ugly-2.js
+  code_ugly-3.js
+  code_ugly-4.js
+  code_ugly-5.js
+  code_ugly-6.js
+  code_ugly-7.js
+  code_ugly-8
+  code_ugly-8^headers^
+  code_worker-source-map.coffee
+  code_worker-source-map.js
+  code_worker-source-map.js.map
+  code_WorkerActor.attach-worker1.js
+  code_WorkerActor.attach-worker2.js
+  code_WorkerActor.attachThread-worker.js
+  doc_auto-pretty-print-01.html
+  doc_auto-pretty-print-02.html
+  doc_binary_search.html
+  doc_blackboxing.html
+  doc_blackboxing_unblackbox.html
+  doc_breakpoints-break-on-last-line-of-script-on-reload.html
+  doc_breakpoints-other-tabs.html
+  doc_breakpoints-reload.html
+  doc_bug-896139.html
+  doc_closures.html
+  doc_closure-optimized-out.html
+  doc_cmd-break.html
+  doc_cmd-dbg.html
+  doc_breakpoint-move.html
+  doc_conditional-breakpoints.html
+  doc_domnode-variables.html
+  doc_editor-mode.html
+  doc_empty-tab-01.html
+  doc_empty-tab-02.html
+  doc_event-listeners-01.html
+  doc_event-listeners-02.html
+  doc_event-listeners-03.html
+  doc_event-listeners-04.html
+  doc_frame-parameters.html
+  doc_function-display-name.html
+  doc_function-jump.html
+  doc_function-search.html
+  doc_global-method-override.html
+  doc_iframes.html
+  doc_included-script.html
+  doc_inline-debugger-statement.html
+  doc_inline-script.html
+  doc_large-array-buffer.html
+  doc_listworkers-tab.html
+  doc_map-set.html
+  doc_minified.html
+  doc_minified_bogus_map.html
+  doc_native-event-handler.html
+  doc_no-page-sources.html
+  doc_pause-exceptions.html
+  doc_pretty-print.html
+  doc_pretty-print-2.html
+  doc_pretty-print-3.html
+  doc_pretty-print-on-paused.html
+  doc_promise-get-allocation-stack.html
+  doc_promise-get-fulfillment-stack.html
+  doc_promise-get-rejection-stack.html
+  doc_promise.html
+  doc_proxy.html
+  doc_random-javascript.html
+  doc_recursion-stack.html
+  doc_scope-variable.html
+  doc_scope-variable-2.html
+  doc_scope-variable-3.html
+  doc_scope-variable-4.html
+  doc_script-eval.html
+  doc_script-bookmarklet.html
+  doc_script-switching-01.html
+  doc_script-switching-02.html
+  doc_script_webext_contentscript.html
+  doc_split-console-paused-reload.html
+  doc_step-many-statements.html
+  doc_step-out.html
+  doc_terminate-on-tab-close.html
+  doc_watch-expressions.html
+  doc_watch-expression-button.html
+  doc_whitespace-property-names.html
+  doc_with-frame.html
+  doc_worker-source-map.html
+  doc_WorkerActor.attach-tab1.html
+  doc_WorkerActor.attach-tab2.html
+  doc_WorkerActor.attachThread-tab.html
+  head.js
+  sjs_post-page.sjs
+  sjs_random-javascript.sjs
+  testactors.js
+  !/devtools/client/commandline/test/helpers.js
+  !/devtools/client/framework/test/shared-head.js
+
+[browser_dbg_no-dangling-breakpoints.js]
+skip-if = e10s && debug
+[browser_dbg_no-page-sources.js]
+skip-if = e10s && debug
+[browser_dbg_on-pause-highlight.js]
+skip-if = e10s && debug
+[browser_dbg_on-pause-raise.js]
+skip-if = e10s && debug || os == "linux" # Bug 888811 & bug 891176
+[browser_dbg_optimized-out-vars.js]
+skip-if = e10s && debug
+[browser_dbg_panel-size.js]
+skip-if = e10s && debug
+[browser_dbg_parser-01.js]
+skip-if = e10s && debug
+[browser_dbg_parser-02.js]
+skip-if = e10s && debug
+[browser_dbg_parser-03.js]
+skip-if = e10s && debug
+[browser_dbg_parser-04.js]
+skip-if = e10s && debug
+[browser_dbg_parser-05.js]
+skip-if = e10s && debug
+[browser_dbg_parser-06.js]
+skip-if = e10s && debug
+[browser_dbg_parser-07.js]
+skip-if = e10s && debug
+[browser_dbg_parser-08.js]
+skip-if = e10s && debug
+[browser_dbg_parser-09.js]
+skip-if = e10s && debug
+[browser_dbg_parser-10.js]
+skip-if = e10s && debug
+[browser_dbg_parser-11.js]
+[browser_dbg_parser-computed-name.js]
+[browser_dbg_parser-function-defaults.js]
+[browser_dbg_parser-spread-expression.js]
+[browser_dbg_parser-template-strings.js]
+skip-if = e10s && debug
+[browser_dbg_pause-exceptions-01.js]
+skip-if = e10s && debug
+[browser_dbg_pause-exceptions-02.js]
+skip-if = e10s && debug
+[browser_dbg_pause-no-step.js]
+skip-if = e10s && debug
+[browser_dbg_pause-resume.js]
+skip-if = e10s && debug
+[browser_dbg_pause-warning.js]
+skip-if = e10s && debug
+[browser_dbg_paused-keybindings.js]
+skip-if = e10s
+[browser_dbg_post-page.js]
+[browser_dbg_pretty-print-01.js]
+skip-if = e10s && debug
+[browser_dbg_pretty-print-02.js]
+skip-if = e10s && debug
+[browser_dbg_pretty-print-03.js]
+skip-if = e10s && debug
+[browser_dbg_pretty-print-04.js]
+skip-if = e10s && debug
+[browser_dbg_pretty-print-05.js]
+skip-if = e10s && debug
+[browser_dbg_pretty-print-06.js]
+skip-if = e10s && debug
+[browser_dbg_pretty-print-07.js]
+skip-if = e10s && debug
+[browser_dbg_pretty-print-08.js]
+skip-if = e10s && debug
+[browser_dbg_pretty-print-09.js]
+skip-if = e10s && debug
+[browser_dbg_pretty-print-10.js]
+skip-if = e10s && debug
+[browser_dbg_pretty-print-11.js]
+skip-if = e10s && debug
+[browser_dbg_pretty-print-12.js]
+skip-if = e10s && debug
+[browser_dbg_pretty-print-13.js]
+skip-if = e10s && debug
+[browser_dbg_pretty-print-on-paused.js]
+skip-if = e10s && debug
+[browser_dbg_progress-listener-bug.js]
+skip-if = e10s && debug
+[browser_dbg_promises-allocation-stack.js]
+skip-if = e10s && debug
+[browser_dbg_promises-chrome-allocation-stack.js]
+skip-if = true # Bug 1177730
+[browser_dbg_promises-fulfillment-stack.js]
+skip-if = e10s && debug
+[browser_dbg_promises-rejection-stack.js]
+skip-if = e10s && debug
+[browser_dbg_reload-preferred-script-02.js]
+skip-if = e10s && debug
+[browser_dbg_reload-preferred-script-03.js]
+skip-if = e10s && debug
+[browser_dbg_reload-same-script.js]
+skip-if = e10s && debug
+[browser_dbg_scripts-switching-01.js]
+skip-if = e10s && debug
+[browser_dbg_scripts-switching-02.js]
+skip-if = e10s && debug
+[browser_dbg_scripts-switching-03.js]
+skip-if = e10s && debug
+[browser_dbg_search-autofill-identifier.js]
+skip-if = e10s && debug
+[browser_dbg_search-basic-01.js]
+skip-if = e10s && debug
+[browser_dbg_search-basic-02.js]
+skip-if = e10s && debug
+[browser_dbg_search-basic-03.js]
+skip-if = e10s && debug
+[browser_dbg_search-basic-04.js]
+skip-if = e10s && debug
+[browser_dbg_search-global-01.js]
+skip-if = e10s && debug
+[browser_dbg_search-global-02.js]
+skip-if = e10s && debug
+[browser_dbg_search-global-03.js]
+skip-if = e10s # Bug 1093535
+[browser_dbg_search-global-04.js]
+skip-if = e10s && debug
+[browser_dbg_search-global-05.js]
+skip-if = e10s && debug
+[browser_dbg_search-global-06.js]
+skip-if = e10s && debug
+[browser_dbg_search-popup-jank.js]
+skip-if = e10s && debug
+[browser_dbg_search-sources-01.js]
+skip-if = e10s && debug
+[browser_dbg_search-sources-02.js]
+skip-if = e10s && debug
+[browser_dbg_search-sources-03.js]
+skip-if = e10s && debug
+[browser_dbg_search-symbols.js]
+skip-if = (e10s && debug) || os == "linux" # Bug 1132375
+[browser_dbg_searchbox-help-popup-01.js]
+skip-if = e10s && debug
+[browser_dbg_searchbox-help-popup-02.js]
+skip-if = e10s && debug
+[browser_dbg_searchbox-parse.js]
+skip-if = e10s && debug
+[browser_dbg_source-maps-01.js]
+skip-if = e10s && debug
+[browser_dbg_source-maps-02.js]
+skip-if = e10s && debug
+[browser_dbg_source-maps-03.js]
+skip-if = e10s && debug
+[browser_dbg_source-maps-04.js]
+skip-if = e10s # Bug 1093535
+[browser_dbg_sources-cache.js]
+[browser_dbg_sources-contextmenu-01.js]
+subsuite = clipboard
+[browser_dbg_sources-contextmenu-02.js]
+skip-if = e10s && debug
+[browser_dbg_sources-eval-01.js]
+skip-if = true # non-named eval sources turned off for now, bug 1124106
+[browser_dbg_sources-eval-02.js]
+[browser_dbg_sources-iframe-reload.js]
+[browser_dbg_sources-keybindings.js]
+subsuite = clipboard
+skip-if = e10s && debug
+[browser_dbg_sources-labels.js]
+skip-if = e10s && debug
+[browser_dbg_sources-large.js]
+[browser_dbg_sources-sorting.js]
+skip-if = e10s && debug
+[browser_dbg_sources-bookmarklet.js]
+skip-if = e10s && debug
+[browser_dbg_sources-webext-contentscript.js]
+[browser_dbg_split-console-paused-reload.js]
+skip-if = true # Bug 1288348 - previously e10s && debug
+[browser_dbg_stack-01.js]
+skip-if = e10s && debug
+[browser_dbg_stack-02.js]
+skip-if = e10s && debug
+[browser_dbg_stack-03.js]
+skip-if = e10s # TODO
+[browser_dbg_stack-04.js]
+skip-if = e10s && debug
+[browser_dbg_stack-05.js]
+skip-if = e10s && (debug || asan) # timeouts
+[browser_dbg_stack-06.js]
+skip-if = e10s && debug
+[browser_dbg_stack-07.js]
+skip-if = e10s && debug
+[browser_dbg_stack-contextmenu-01.js]
+skip-if = e10s && debug
+[browser_dbg_stack-contextmenu-02.js]
+subsuite = clipboard
+skip-if = e10s && debug
+[browser_dbg_step-out.js]
+skip-if = e10s && debug
+[browser_dbg_tabactor-01.js]
+skip-if = e10s # TODO
+[browser_dbg_tabactor-02.js]
+skip-if = e10s # TODO
+[browser_dbg_terminate-on-tab-close.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-01.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-02.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-03.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-04.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-05.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-06.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-07.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-08.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-accessibility.js]
+subsuite = clipboard
+skip-if = e10s && debug
+[browser_dbg_variables-view-data.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-edit-cancel.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-edit-click.js]
+skip-if = e10s || (os == 'mac' || os == 'win') && (debug == false) # Bug 986166
+[browser_dbg_variables-view-edit-getset-01.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-edit-getset-02.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-edit-value.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-edit-watch.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-filter-01.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-filter-02.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-filter-03.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-filter-04.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-filter-05.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-filter-pref.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-filter-searchbox.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-frame-parameters-01.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-frame-parameters-02.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-frame-parameters-03.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-frame-with.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-frozen-sealed-nonext.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-hide-non-enums.js]
+[browser_dbg_variables-view-large-array-buffer.js]
+[browser_dbg_variables-view-map-set.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-override-01.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-override-02.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-popup-01.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-popup-02.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-popup-03.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-popup-04.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-popup-05.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-popup-06.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-popup-07.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-popup-08.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-popup-09.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-popup-10.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-popup-11.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-popup-12.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-popup-13.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-popup-14.js]
+skip-if = true # Bug 1029545
+[browser_dbg_variables-view-popup-15.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-popup-16.js]
+skip-if = e10s  && debug
+[browser_dbg_variables-view-popup-17.js]
+skip-if = e10s  && debug
+[browser_dbg_variables-view-reexpand-01.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-reexpand-02.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-reexpand-03.js]
+skip-if = e10s && debug
+[browser_dbg_variables-view-webidl.js]
+skip-if = e10s && debug
+[browser_dbg_watch-expressions-01.js]
+skip-if = e10s && debug
+[browser_dbg_watch-expressions-02.js]
+skip-if = e10s && debug
+[browser_dbg_worker-console-01.js]
+skip-if = e10s && debug
+[browser_dbg_worker-console-02.js]
+skip-if = e10s && debug
+[browser_dbg_worker-console-03.js]
+skip-if = e10s && debug
+[browser_dbg_worker-source-map.js]
+skip-if = e10s && debug
+[browser_dbg_worker-window.js]
+skip-if = e10s && debug
+[browser_dbg_WorkerActor.attach.js]
+skip-if = e10s && debug
+[browser_dbg_WorkerActor.attachThread.js]
+skip-if = e10s && debug
+[browser_dbg_split-console-keypress.js]
+skip-if = e10s && (debug || os == "linux") # Bug 1214439
--- a/devtools/server/actors/errordocs.js
+++ b/devtools/server/actors/errordocs.js
@@ -43,16 +43,17 @@ const ErrorDocs = {
   JSMSG_OVER_RECURSED: "Too_much_recursion",
   JSMSG_BRACKET_AFTER_LIST: "Missing_bracket_after_list",
   JSMSG_PAREN_AFTER_ARGS: "Missing_parenthesis_after_argument_list",
   JSMSG_MORE_ARGS_NEEDED: "More_arguments_needed",
   JSMSG_BAD_LEFTSIDE_OF_ASS: "Invalid_assignment_left-hand_side",
   JSMSG_UNTERMINATED_STRING: "Unterminated_string_literal",
   JSMSG_NOT_CONSTRUCTOR: "Not_a_constructor",
   JSMSG_CURLY_AFTER_LIST: "Missing_curly_after_property_list",
+  JSMSG_DEPRECATED_FOR_EACH: "For-each-in_loops_are_deprecated",
 };
 
 const MIXED_CONTENT_LEARN_MORE = "https://developer.mozilla.org/docs/Web/Security/Mixed_content";
 const TRACKING_PROTECTION_LEARN_MORE = "https://developer.mozilla.org/Firefox/Privacy/Tracking_Protection";
 const INSECURE_PASSWORDS_LEARN_MORE = "https://developer.mozilla.org/docs/Web/Security/Insecure_passwords";
 const PUBLIC_KEY_PINS_LEARN_MORE = "https://developer.mozilla.org/docs/Web/Security/Public_Key_Pinning";
 const STRICT_TRANSPORT_SECURITY_LEARN_MORE = "https://developer.mozilla.org/docs/Web/Security/HTTP_strict_transport_security";
 const WEAK_SIGNATURE_ALGORITHM_LEARN_MORE = "https://developer.mozilla.org/docs/Web/Security/Weak_Signature_Algorithm";
--- a/devtools/server/actors/webbrowser.js
+++ b/devtools/server/actors/webbrowser.js
@@ -916,18 +916,16 @@ TabActor.prototype = {
     return this._tabPool;
   },
 
   _contextPool: null,
   get contextActorPool() {
     return this._contextPool;
   },
 
-  _pendingNavigation: null,
-
   // A constant prefix that will be used to form the actor ID by the server.
   actorPrefix: "tab",
 
   /**
    * An object on which listen for DOMWindowCreated and pageshow events.
    */
   get chromeEventHandler() {
     return getDocShellChromeEventHandler(this.docShell);
@@ -1801,20 +1799,16 @@ TabActor.prototype = {
       // The tab is already closed.
       return;
     }
     let windowUtils = this.window
                           .QueryInterface(Ci.nsIInterfaceRequestor)
                           .getInterface(Ci.nsIDOMWindowUtils);
     windowUtils.resumeTimeouts();
     windowUtils.suppressEventHandling(false);
-    if (this._pendingNavigation) {
-      this._pendingNavigation.resume();
-      this._pendingNavigation = null;
-    }
   },
 
   _changeTopLevelDocument(window) {
     // Fake a will-navigate on the previous document
     // to let a chance to unregister it
     this._willNavigate(this.window, window.location.href, null, true);
 
     this._windowDestroyed(this.window, null, true);
@@ -1942,22 +1936,20 @@ TabActor.prototype = {
     if (!isTopLevel) {
       return;
     }
 
     // Proceed normally only if the debuggee is not paused.
     // TODO bug 997119: move that code to ThreadActor by listening to
     // will-navigate
     let threadActor = this.threadActor;
-    if (request && threadActor.state == "paused") {
-      request.suspend();
+    if (threadActor.state == "paused") {
       this.conn.send(
         threadActor.unsafeSynchronize(Promise.resolve(threadActor.onResume())));
       threadActor.dbg.enabled = false;
-      this._pendingNavigation = request;
     }
     threadActor.disableAllBreakpoints();
 
     this.conn.send({
       from: this.actorID,
       type: "tabNavigated",
       url: newURI,
       nativeConsoleAPI: true,
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -1872,21 +1872,18 @@ nsDocShell::SetCurrentURI(nsIURI* aURI)
   return NS_OK;
 }
 
 bool
 nsDocShell::SetCurrentURI(nsIURI* aURI, nsIRequest* aRequest,
                           bool aFireOnLocationChange, uint32_t aLocationFlags)
 {
   if (gDocShellLeakLog && MOZ_LOG_TEST(gDocShellLeakLog, LogLevel::Debug)) {
-    nsAutoCString spec;
-    if (aURI) {
-      aURI->GetSpec(spec);
-    }
-    PR_LogPrint("DOCSHELL %p SetCurrentURI %s\n", this, spec.get());
+    PR_LogPrint("DOCSHELL %p SetCurrentURI %s\n",
+                this, aURI ? aURI->GetSpecOrDefault().get() : "");
   }
 
   // We don't want to send a location change when we're displaying an error
   // page, and we don't want to change our idea of "current URI" either
   if (mLoadType == LOAD_ERROR_PAGE) {
     return false;
   }
 
@@ -5244,29 +5241,27 @@ nsDocShell::LoadErrorPage(nsIURI* aURI, 
                           const char* aErrorPage,
                           const char16_t* aErrorType,
                           const char16_t* aDescription,
                           const char* aCSSClass,
                           nsIChannel* aFailedChannel)
 {
 #if defined(DEBUG)
   if (MOZ_LOG_TEST(gDocShellLog, LogLevel::Debug)) {
-    nsAutoCString spec;
-    aURI->GetSpec(spec);
-
     nsAutoCString chanName;
     if (aFailedChannel) {
       aFailedChannel->GetName(chanName);
     } else {
       chanName.AssignLiteral("<no channel>");
     }
 
     MOZ_LOG(gDocShellLog, LogLevel::Debug,
            ("nsDocShell[%p]::LoadErrorPage(\"%s\", \"%s\", {...}, [%s])\n", this,
-            spec.get(), NS_ConvertUTF16toUTF8(aURL).get(), chanName.get()));
+            aURI->GetSpecOrDefault().get(), NS_ConvertUTF16toUTF8(aURL).get(),
+            chanName.get()));
   }
 #endif
   mFailedChannel = aFailedChannel;
   mFailedURI = aURI;
   mFailedLoadType = mLoadType;
 
   if (mLSHE) {
     // Abandon mLSHE's BFCache entry and create a new one.  This way, if
@@ -6331,19 +6326,19 @@ NS_IMETHODIMP
 nsDocShell::SetMixedContentChannel(nsIChannel* aMixedContentChannel)
 {
 #ifdef DEBUG
   // if the channel is non-null
   if (aMixedContentChannel) {
     // Get the root docshell.
     nsCOMPtr<nsIDocShellTreeItem> root;
     GetSameTypeRootTreeItem(getter_AddRefs(root));
-    NS_WARN_IF_FALSE(root.get() == static_cast<nsIDocShellTreeItem*>(this),
-                     "Setting mMixedContentChannel on a docshell that is not "
-                     "the root docshell");
+    NS_WARNING_ASSERTION(root.get() == static_cast<nsIDocShellTreeItem*>(this),
+                         "Setting mMixedContentChannel on a docshell that is "
+                         "not the root docshell");
   }
 #endif
   mMixedContentChannel = aMixedContentChannel;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::GetFailedChannel(nsIChannel** aFailedChannel)
@@ -9713,21 +9708,18 @@ nsDocShell::InternalLoad(nsIURI* aURI,
                          nsIURI* aBaseURI,
                          nsIDocShell** aDocShell,
                          nsIRequest** aRequest)
 {
   nsresult rv = NS_OK;
   mOriginalUriString.Truncate();
 
   if (gDocShellLeakLog && MOZ_LOG_TEST(gDocShellLeakLog, LogLevel::Debug)) {
-    nsAutoCString spec;
-    if (aURI) {
-      aURI->GetSpec(spec);
-    }
-    PR_LogPrint("DOCSHELL %p InternalLoad %s\n", this, spec.get());
+    PR_LogPrint("DOCSHELL %p InternalLoad %s\n",
+                this, aURI ? aURI->GetSpecOrDefault().get() : "");
   }
   // Initialize aDocShell/aRequest
   if (aDocShell) {
     *aDocShell = nullptr;
   }
   if (aRequest) {
     *aRequest = nullptr;
   }
@@ -11428,29 +11420,26 @@ nsDocShell::OnNewURI(nsIURI* aURI, nsICh
                      uint32_t aLoadType, bool aFireOnLocationChange,
                      bool aAddToGlobalHistory, bool aCloneSHChildren)
 {
   NS_PRECONDITION(aURI, "uri is null");
   NS_PRECONDITION(!aChannel || !aTriggeringPrincipal, "Shouldn't have both set");
 
 #if defined(DEBUG)
   if (MOZ_LOG_TEST(gDocShellLog, LogLevel::Debug)) {
-    nsAutoCString spec;
-    aURI->GetSpec(spec);
-
     nsAutoCString chanName;
     if (aChannel) {
       aChannel->GetName(chanName);
     } else {
       chanName.AssignLiteral("<no channel>");
     }
 
     MOZ_LOG(gDocShellLog, LogLevel::Debug,
-           ("nsDocShell[%p]::OnNewURI(\"%s\", [%s], 0x%x)\n", this, spec.get(),
-            chanName.get(), aLoadType));
+            ("nsDocShell[%p]::OnNewURI(\"%s\", [%s], 0x%x)\n",
+             this, aURI->GetSpecOrDefault().get(), chanName.get(), aLoadType));
   }
 #endif
 
   bool equalUri = false;
 
   // Get the post data and the HTTP response code from the channel.
   uint32_t responseStatus = 0;
   nsCOMPtr<nsIInputStream> inputStream;
@@ -12074,29 +12063,26 @@ nsDocShell::AddToSessionHistory(nsIURI* 
                                 bool aCloneChildren,
                                 nsISHEntry** aNewEntry)
 {
   NS_PRECONDITION(aURI, "uri is null");
   NS_PRECONDITION(!aChannel || !aTriggeringPrincipal, "Shouldn't have both set");
 
 #if defined(DEBUG)
   if (MOZ_LOG_TEST(gDocShellLog, LogLevel::Debug)) {
-    nsAutoCString spec;
-    aURI->GetSpec(spec);
-
     nsAutoCString chanName;
     if (aChannel) {
       aChannel->GetName(chanName);
     } else {
       chanName.AssignLiteral("<no channel>");
     }
 
     MOZ_LOG(gDocShellLog, LogLevel::Debug,
-           ("nsDocShell[%p]::AddToSessionHistory(\"%s\", [%s])\n",
-            this, spec.get(), chanName.get()));
+            ("nsDocShell[%p]::AddToSessionHistory(\"%s\", [%s])\n",
+             this, aURI->GetSpecOrDefault().get(), chanName.get()));
   }
 #endif
 
   nsresult rv = NS_OK;
   nsCOMPtr<nsISHEntry> entry;
   bool shouldPersist;
 
   shouldPersist = ShouldAddToSessionHistory(aURI);
@@ -12882,17 +12868,17 @@ nsDocShell::ExtractLastVisit(nsIChannel*
     // There is no last visit for this channel, so this must be the first
     // link.  Link the visit to the referrer of this request, if any.
     // Treat referrer as null if there is an error getting it.
     (void)NS_GetReferrerFromChannel(aChannel, aURI);
   } else {
     rv = props->GetPropertyAsUint32(NS_LITERAL_STRING("docshell.previousFlags"),
                                     aChannelRedirectFlags);
 
-    NS_WARN_IF_FALSE(
+    NS_WARNING_ASSERTION(
       NS_SUCCEEDED(rv),
       "Could not fetch previous flags, URI will be treated like referrer");
   }
 }
 
 void
 nsDocShell::SaveLastVisit(nsIChannel* aChannel,
                           nsIURI* aURI,
@@ -14236,18 +14222,17 @@ nsDocShell::SetOriginAttributes(const Do
   // attributes.
   if (mContentViewer) {
     nsIDocument* doc = mContentViewer->GetDocument();
     if (doc) {
       nsIURI* uri = doc->GetDocumentURI();
       if (!uri) {
         return NS_ERROR_FAILURE;
       }
-      nsAutoCString uriSpec;
-      uri->GetSpec(uriSpec);
+      nsCString uriSpec = uri->GetSpecOrDefault();
       MOZ_ASSERT(uriSpec.EqualsLiteral("about:blank"));
       if (!uriSpec.EqualsLiteral("about:blank")) {
         return NS_ERROR_FAILURE;
       }
     }
   }
 
   AssertOriginAttributesMatchPrivateBrowsing();
@@ -14466,18 +14451,17 @@ nsDocShell::ShouldPrepareForIntercept(ns
   nsresult result;
   nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
     do_GetService(THIRDPARTYUTIL_CONTRACTID, &result);
   NS_ENSURE_SUCCESS(result, result);
 
   if (mCurrentURI &&
       nsContentUtils::CookiesBehavior() == nsICookieService::BEHAVIOR_REJECT_FOREIGN) {
     nsAutoCString uriSpec;
-    mCurrentURI->GetSpec(uriSpec);
-    if (!(uriSpec.EqualsLiteral("about:blank"))) {
+    if (!(mCurrentURI->GetSpecOrDefault().EqualsLiteral("about:blank"))) {
       // Reject the interception of third-party iframes if the cookie behaviour
       // is set to reject all third-party cookies (1). In case that this pref
       // is not set or can't be read, we default to allow all cookies (0) as
       // this is the default value in all.js.
       bool isThirdPartyURI = true;
       result = thirdPartyUtil->IsThirdPartyURI(mCurrentURI, aURI,
                                                &isThirdPartyURI);
       if (NS_FAILED(result)) {
--- a/docshell/shistory/nsSHistory.cpp
+++ b/docshell/shistory/nsSHistory.cpp
@@ -69,17 +69,17 @@ static LazyLogModule gSHistoryLog("nsSHi
 //  nsIURI *uri = [...];
 //  LOG_SPEC(("The URI is %s.", _spec), uri);
 //
 #define LOG_SPEC(format, uri)                              \
   PR_BEGIN_MACRO                                           \
     if (MOZ_LOG_TEST(gSHistoryLog, LogLevel::Debug)) {     \
       nsAutoCString _specStr(NS_LITERAL_CSTRING("(null)"));\
       if (uri) {                                           \
-        uri->GetSpec(_specStr);                            \
+        _specStr = uri->GetSpecOrDefault();                \
       }                                                    \
       const char* _spec = _specStr.get();                  \
       LOG(format);                                         \
     }                                                      \
   PR_END_MACRO
 
 // This macro makes it easy to log a message including an SHEntry's URI.
 // For example:
--- a/dom/base/CustomElementsRegistry.cpp
+++ b/dom/base/CustomElementsRegistry.cpp
@@ -1,26 +1,164 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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/. */
 
 #include "mozilla/dom/CustomElementsRegistry.h"
+
 #include "mozilla/dom/CustomElementsRegistryBinding.h"
+#include "mozilla/dom/HTMLElementBinding.h"
 #include "mozilla/dom/WebComponentsBinding.h"
+#include "nsIParserService.h"
+#include "jsapi.h"
 
 namespace mozilla {
 namespace dom {
 
+void
+CustomElementCallback::Call()
+{
+  ErrorResult rv;
+  switch (mType) {
+    case nsIDocument::eCreated:
+    {
+      // For the duration of this callback invocation, the element is being created
+      // flag must be set to true.
+      mOwnerData->mElementIsBeingCreated = true;
+
+      // The callback hasn't actually been invoked yet, but we need to flip
+      // this now in order to enqueue the attached callback. This is a spec
+      // bug (w3c bug 27437).
+      mOwnerData->mCreatedCallbackInvoked = true;
+
+      // If ELEMENT is in a document and this document has a browsing context,
+      // enqueue attached callback for ELEMENT.
+      nsIDocument* document = mThisObject->GetComposedDoc();
+      if (document && document->GetDocShell()) {
+        nsContentUtils::EnqueueLifecycleCallback(
+          document, nsIDocument::eAttached, mThisObject);
+      }
+
+      static_cast<LifecycleCreatedCallback *>(mCallback.get())->Call(mThisObject, rv);
+      mOwnerData->mElementIsBeingCreated = false;
+      break;
+    }
+    case nsIDocument::eAttached:
+      static_cast<LifecycleAttachedCallback *>(mCallback.get())->Call(mThisObject, rv);
+      break;
+    case nsIDocument::eDetached:
+      static_cast<LifecycleDetachedCallback *>(mCallback.get())->Call(mThisObject, rv);
+      break;
+    case nsIDocument::eAttributeChanged:
+      static_cast<LifecycleAttributeChangedCallback *>(mCallback.get())->Call(mThisObject,
+        mArgs.name, mArgs.oldValue, mArgs.newValue, rv);
+      break;
+  }
+}
+
+void
+CustomElementCallback::Traverse(nsCycleCollectionTraversalCallback& aCb) const
+{
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mThisObject");
+  aCb.NoteXPCOMChild(mThisObject);
+
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mCallback");
+  aCb.NoteXPCOMChild(mCallback);
+}
+
+CustomElementCallback::CustomElementCallback(Element* aThisObject,
+                                             nsIDocument::ElementCallbackType aCallbackType,
+                                             mozilla::dom::CallbackFunction* aCallback,
+                                             CustomElementData* aOwnerData)
+  : mThisObject(aThisObject),
+    mCallback(aCallback),
+    mType(aCallbackType),
+    mOwnerData(aOwnerData)
+{
+}
+
+CustomElementData::CustomElementData(nsIAtom* aType)
+  : mType(aType),
+    mCurrentCallback(-1),
+    mElementIsBeingCreated(false),
+    mCreatedCallbackInvoked(true),
+    mAssociatedMicroTask(-1)
+{
+}
+
+void
+CustomElementData::RunCallbackQueue()
+{
+  // Note: It's possible to re-enter this method.
+  while (static_cast<uint32_t>(++mCurrentCallback) < mCallbackQueue.Length()) {
+    mCallbackQueue[mCurrentCallback]->Call();
+  }
+
+  mCallbackQueue.Clear();
+  mCurrentCallback = -1;
+}
 
 // Only needed for refcounted objects.
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CustomElementsRegistry, mWindow)
+NS_IMPL_CYCLE_COLLECTION_CLASS(CustomElementsRegistry)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CustomElementsRegistry)
+  tmp->mCustomDefinitions.Clear();
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CustomElementsRegistry)
+  for (auto iter = tmp->mCustomDefinitions.Iter(); !iter.Done(); iter.Next()) {
+    nsAutoPtr<LifecycleCallbacks>& callbacks = iter.UserData()->mCallbacks;
+
+    if (callbacks->mAttributeChangedCallback.WasPassed()) {
+      NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
+        "mCustomDefinitions->mCallbacks->mAttributeChangedCallback");
+      cb.NoteXPCOMChild(callbacks->mAttributeChangedCallback.Value());
+    }
+
+    if (callbacks->mCreatedCallback.WasPassed()) {
+      NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
+        "mCustomDefinitions->mCallbacks->mCreatedCallback");
+      cb.NoteXPCOMChild(callbacks->mCreatedCallback.Value());
+    }
+
+    if (callbacks->mAttachedCallback.WasPassed()) {
+      NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
+        "mCustomDefinitions->mCallbacks->mAttachedCallback");
+      cb.NoteXPCOMChild(callbacks->mAttachedCallback.Value());
+    }
+
+    if (callbacks->mDetachedCallback.WasPassed()) {
+      NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
+        "mCustomDefinitions->mCallbacks->mDetachedCallback");
+      cb.NoteXPCOMChild(callbacks->mDetachedCallback.Value());
+    }
+  }
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(CustomElementsRegistry)
+  for (auto iter = tmp->mCustomDefinitions.Iter(); !iter.Done(); iter.Next()) {
+    aCallbacks.Trace(&iter.UserData()->mConstructor,
+                     "mCustomDefinitions constructor",
+                     aClosure);
+    aCallbacks.Trace(&iter.UserData()->mPrototype,
+                     "mCustomDefinitions prototype",
+                     aClosure);
+  }
+  NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
+
 NS_IMPL_CYCLE_COLLECTING_ADDREF(CustomElementsRegistry)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(CustomElementsRegistry)
+
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CustomElementsRegistry)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 /* static */ bool
 CustomElementsRegistry::IsCustomElementsEnabled(JSContext* aCx, JSObject* aObject)
 {
@@ -38,48 +176,624 @@ CustomElementsRegistry::Create(nsPIDOMWi
 {
   MOZ_ASSERT(aWindow);
   MOZ_ASSERT(aWindow->IsInnerWindow());
 
   if (!aWindow->GetDocShell()) {
     return nullptr;
   }
 
+  if (!Preferences::GetBool("dom.webcomponents.customelements.enabled") &&
+      !Preferences::GetBool("dom.webcomponents.enabled")) {
+    return nullptr;
+  }
+
   RefPtr<CustomElementsRegistry> customElementsRegistry =
     new CustomElementsRegistry(aWindow);
   return customElementsRegistry.forget();
 }
 
+/* static */ void
+CustomElementsRegistry::ProcessTopElementQueue()
+{
+  MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
+
+  nsTArray<RefPtr<CustomElementData>>& stack = *sProcessingStack;
+  uint32_t firstQueue = stack.LastIndexOf((CustomElementData*) nullptr);
+
+  for (uint32_t i = firstQueue + 1; i < stack.Length(); ++i) {
+    // Callback queue may have already been processed in an earlier
+    // element queue or in an element queue that was popped
+    // off more recently.
+    if (stack[i]->mAssociatedMicroTask != -1) {
+      stack[i]->RunCallbackQueue();
+      stack[i]->mAssociatedMicroTask = -1;
+    }
+  }
+
+  // If this was actually the base element queue, don't bother trying to pop
+  // the first "queue" marker (sentinel).
+  if (firstQueue != 0) {
+    stack.SetLength(firstQueue);
+  } else {
+    // Don't pop sentinel for base element queue.
+    stack.SetLength(1);
+  }
+}
+
+/* static */ void
+CustomElementsRegistry::XPCOMShutdown()
+{
+  sProcessingStack.reset();
+}
+
+/* static */ Maybe<nsTArray<RefPtr<CustomElementData>>>
+CustomElementsRegistry::sProcessingStack;
+
 CustomElementsRegistry::CustomElementsRegistry(nsPIDOMWindowInner* aWindow)
  : mWindow(aWindow)
+ , mIsCustomDefinitionRunning(false)
 {
+  mozilla::HoldJSObjects(this);
+
+  if (!sProcessingStack) {
+    sProcessingStack.emplace();
+    // Add the base queue sentinel to the processing stack.
+    sProcessingStack->AppendElement((CustomElementData*) nullptr);
+  }
 }
 
 CustomElementsRegistry::~CustomElementsRegistry()
 {
+  mozilla::DropJSObjects(this);
+}
+
+CustomElementDefinition*
+CustomElementsRegistry::LookupCustomElementDefinition(const nsAString& aLocalName,
+                                                      const nsAString* aIs) const
+{
+  nsCOMPtr<nsIAtom> localNameAtom = NS_Atomize(aLocalName);
+  nsCOMPtr<nsIAtom> typeAtom = aIs ? NS_Atomize(*aIs) : localNameAtom;
+
+  CustomElementDefinition* data = mCustomDefinitions.Get(typeAtom);
+  if (data && data->mLocalName == localNameAtom) {
+    return data;
+  }
+
+  return nullptr;
+}
+
+void
+CustomElementsRegistry::RegisterUnresolvedElement(Element* aElement, nsIAtom* aTypeName)
+{
+  mozilla::dom::NodeInfo* info = aElement->NodeInfo();
+
+  // Candidate may be a custom element through extension,
+  // in which case the custom element type name will not
+  // match the element tag name. e.g. <button is="x-button">.
+  nsCOMPtr<nsIAtom> typeName = aTypeName;
+  if (!typeName) {
+    typeName = info->NameAtom();
+  }
+
+  if (mCustomDefinitions.Get(typeName)) {
+    return;
+  }
+
+  nsTArray<nsWeakPtr>* unresolved = mCandidatesMap.LookupOrAdd(typeName);
+  nsWeakPtr* elem = unresolved->AppendElement();
+  *elem = do_GetWeakReference(aElement);
+  aElement->AddStates(NS_EVENT_STATE_UNRESOLVED);
+
+  return;
+}
+
+void
+CustomElementsRegistry::SetupCustomElement(Element* aElement,
+                                           const nsAString* aTypeExtension)
+{
+  nsCOMPtr<nsIAtom> tagAtom = aElement->NodeInfo()->NameAtom();
+  nsCOMPtr<nsIAtom> typeAtom = aTypeExtension ?
+    NS_Atomize(*aTypeExtension) : tagAtom;
+
+  if (aTypeExtension && !aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::is)) {
+    // Custom element setup in the parser happens after the "is"
+    // attribute is added.
+    aElement->SetAttr(kNameSpaceID_None, nsGkAtoms::is, *aTypeExtension, true);
+  }
+
+  CustomElementDefinition* data = LookupCustomElementDefinition(
+    aElement->NodeInfo()->LocalName(), aTypeExtension);
+
+  if (!data) {
+    // The type extension doesn't exist in the registry,
+    // thus we don't need to enqueue callback or adjust
+    // the "is" attribute, but it is possibly an upgrade candidate.
+    RegisterUnresolvedElement(aElement, typeAtom);
+    return;
+  }
+
+  if (data->mLocalName != tagAtom) {
+    // The element doesn't match the local name for the
+    // definition, thus the element isn't a custom element
+    // and we don't need to do anything more.
+    return;
+  }
+
+  // Enqueuing the created callback will set the CustomElementData on the
+  // element, causing prototype swizzling to occur in Element::WrapObject.
+  EnqueueLifecycleCallback(nsIDocument::eCreated, aElement, nullptr, data);
+}
+
+void
+CustomElementsRegistry::EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
+                                                 Element* aCustomElement,
+                                                 LifecycleCallbackArgs* aArgs,
+                                                 CustomElementDefinition* aDefinition)
+{
+  CustomElementData* elementData = aCustomElement->GetCustomElementData();
+
+  // Let DEFINITION be ELEMENT's definition
+  CustomElementDefinition* definition = aDefinition;
+  if (!definition) {
+    mozilla::dom::NodeInfo* info = aCustomElement->NodeInfo();
+
+    // Make sure we get the correct definition in case the element
+    // is a extended custom element e.g. <button is="x-button">.
+    nsCOMPtr<nsIAtom> typeAtom = elementData ?
+      elementData->mType.get() : info->NameAtom();
+
+    definition = mCustomDefinitions.Get(typeAtom);
+    if (!definition || definition->mLocalName != info->NameAtom()) {
+      // Trying to enqueue a callback for an element that is not
+      // a custom element. We are done, nothing to do.
+      return;
+    }
+  }
+
+  if (!elementData) {
+    // Create the custom element data the first time
+    // that we try to enqueue a callback.
+    elementData = new CustomElementData(definition->mType);
+    // aCustomElement takes ownership of elementData
+    aCustomElement->SetCustomElementData(elementData);
+    MOZ_ASSERT(aType == nsIDocument::eCreated,
+               "First callback should be the created callback");
+  }
+
+  // Let CALLBACK be the callback associated with the key NAME in CALLBACKS.
+  CallbackFunction* func = nullptr;
+  switch (aType) {
+    case nsIDocument::eCreated:
+      if (definition->mCallbacks->mCreatedCallback.WasPassed()) {
+        func = definition->mCallbacks->mCreatedCallback.Value();
+      }
+      break;
+
+    case nsIDocument::eAttached:
+      if (definition->mCallbacks->mAttachedCallback.WasPassed()) {
+        func = definition->mCallbacks->mAttachedCallback.Value();
+      }
+      break;
+
+    case nsIDocument::eDetached:
+      if (definition->mCallbacks->mDetachedCallback.WasPassed()) {
+        func = definition->mCallbacks->mDetachedCallback.Value();
+      }
+      break;
+
+    case nsIDocument::eAttributeChanged:
+      if (definition->mCallbacks->mAttributeChangedCallback.WasPassed()) {
+        func = definition->mCallbacks->mAttributeChangedCallback.Value();
+      }
+      break;
+  }
+
+  // If there is no such callback, stop.
+  if (!func) {
+    return;
+  }
+
+  if (aType == nsIDocument::eCreated) {
+    elementData->mCreatedCallbackInvoked = false;
+  } else if (!elementData->mCreatedCallbackInvoked) {
+    // Callbacks other than created callback must not be enqueued
+    // until after the created callback has been invoked.
+    return;
+  }
+
+  // Add CALLBACK to ELEMENT's callback queue.
+  CustomElementCallback* callback = new CustomElementCallback(aCustomElement,
+                                                              aType,
+                                                              func,
+                                                              elementData);
+  // Ownership of callback is taken by mCallbackQueue.
+  elementData->mCallbackQueue.AppendElement(callback);
+  if (aArgs) {
+    callback->SetArgs(*aArgs);
+  }
+
+  if (!elementData->mElementIsBeingCreated) {
+    CustomElementData* lastData =
+      sProcessingStack->SafeLastElement(nullptr);
+
+    // A new element queue needs to be pushed if the queue at the
+    // top of the stack is associated with another microtask level.
+    bool shouldPushElementQueue =
+      (!lastData || lastData->mAssociatedMicroTask <
+         static_cast<int32_t>(nsContentUtils::MicroTaskLevel()));
+
+    // Push a new element queue onto the processing stack when appropriate
+    // (when we enter a new microtask).
+    if (shouldPushElementQueue) {
+      // Push a sentinel value on the processing stack to mark the
+      // boundary between the element queues.
+      sProcessingStack->AppendElement((CustomElementData*) nullptr);
+    }
+
+    sProcessingStack->AppendElement(elementData);
+    elementData->mAssociatedMicroTask =
+      static_cast<int32_t>(nsContentUtils::MicroTaskLevel());
+
+    // Add a script runner to pop and process the element queue at
+    // the top of the processing stack.
+    if (shouldPushElementQueue) {
+      // Lifecycle callbacks enqueued by user agent implementation
+      // should be invoked prior to returning control back to script.
+      // Create a script runner to process the top of the processing
+      // stack as soon as it is safe to run script.
+      nsCOMPtr<nsIRunnable> runnable =
+        NS_NewRunnableFunction(&CustomElementsRegistry::ProcessTopElementQueue);
+      nsContentUtils::AddScriptRunner(runnable);
+    }
+  }
+}
+
+void
+CustomElementsRegistry::GetCustomPrototype(nsIAtom* aAtom,
+                                           JS::MutableHandle<JSObject*> aPrototype)
+{
+  mozilla::dom::CustomElementDefinition* definition = mCustomDefinitions.Get(aAtom);
+  if (definition) {
+    aPrototype.set(definition->mPrototype);
+  } else {
+    aPrototype.set(nullptr);
+  }
+}
+
+void
+CustomElementsRegistry::UpgradeCandidates(JSContext* aCx,
+                                          nsIAtom* aKey,
+                                          CustomElementDefinition* aDefinition)
+{
+  nsAutoPtr<nsTArray<nsWeakPtr>> candidates;
+  mCandidatesMap.RemoveAndForget(aKey, candidates);
+  if (candidates) {
+    for (size_t i = 0; i < candidates->Length(); ++i) {
+      nsCOMPtr<Element> elem = do_QueryReferent(candidates->ElementAt(i));
+      if (!elem) {
+        continue;
+      }
+
+      elem->RemoveStates(NS_EVENT_STATE_UNRESOLVED);
+
+      // Make sure that the element name matches the name in the definition.
+      // (e.g. a definition for x-button extending button should match
+      // <button is="x-button"> but not <x-button>.
+      if (elem->NodeInfo()->NameAtom() != aDefinition->mLocalName) {
+        //Skip over this element because definition does not apply.
+        continue;
+      }
+
+      MOZ_ASSERT(elem->IsHTMLElement(aDefinition->mLocalName));
+      nsWrapperCache* cache;
+      CallQueryInterface(elem, &cache);
+      MOZ_ASSERT(cache, "Element doesn't support wrapper cache?");
+
+      // We want to set the custom prototype in the caller's comparment.
+      // In the case that element is in a different compartment,
+      // this will set the prototype on the element's wrapper and
+      // thus only visible in the wrapper's compartment.
+      JS::RootedObject wrapper(aCx);
+      JS::Rooted<JSObject*> prototype(aCx, aDefinition->mPrototype);
+      if ((wrapper = cache->GetWrapper()) && JS_WrapObject(aCx, &wrapper)) {
+        if (!JS_SetPrototype(aCx, wrapper, prototype)) {
+          continue;
+        }
+      }
+
+      nsContentUtils::EnqueueLifecycleCallback(
+        elem->OwnerDoc(), nsIDocument::eCreated, elem, nullptr, aDefinition);
+    }
+  }
 }
 
 JSObject*
 CustomElementsRegistry::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return CustomElementsRegistryBinding::Wrap(aCx, this, aGivenProto);
 }
 
 nsISupports* CustomElementsRegistry::GetParentObject() const
 {
   return mWindow;
 }
 
-void CustomElementsRegistry::Define(const nsAString& aName,
-                                    Function& aFunctionConstructor,
-                                    const ElementDefinitionOptions& aOptions,
-                                    ErrorResult& aRv)
+static const char* kLifeCycleCallbackNames[] = {
+  "connectedCallback",
+  "disconnectedCallback",
+  "adoptedCallback",
+  "attributeChangedCallback",
+  // The life cycle callbacks from v0 spec.
+  "createdCallback",
+  "attachedCallback",
+  "detachedCallback"
+};
+
+static void
+CheckLifeCycleCallbacks(JSContext* aCx,
+                        JS::Handle<JSObject*> aConstructor,
+                        ErrorResult& aRv)
+{
+  for (size_t i = 0; i < ArrayLength(kLifeCycleCallbackNames); ++i) {
+    const char* callbackName = kLifeCycleCallbackNames[i];
+    JS::Rooted<JS::Value> callbackValue(aCx);
+    if (!JS_GetProperty(aCx, aConstructor, callbackName, &callbackValue)) {
+      aRv.StealExceptionFromJSContext(aCx);
+      return;
+    }
+    if (!callbackValue.isUndefined()) {
+      if (!callbackValue.isObject()) {
+        aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_ConvertASCIItoUTF16(callbackName));
+        return;
+      }
+      JS::Rooted<JSObject*> callback(aCx, &callbackValue.toObject());
+      if (!JS::IsCallable(callback)) {
+        aRv.ThrowTypeError<MSG_NOT_CALLABLE>(NS_ConvertASCIItoUTF16(callbackName));
+        return;
+      }
+    }
+  }
+}
+
+// https://html.spec.whatwg.org/multipage/scripting.html#element-definition
+void
+CustomElementsRegistry::Define(const nsAString& aName,
+                               Function& aFunctionConstructor,
+                               const ElementDefinitionOptions& aOptions,
+                               ErrorResult& aRv)
 {
-  // TODO: This function will be implemented in bug 1275835
-  aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+  aRv.MightThrowJSException();
+
+  AutoJSAPI jsapi;
+  if (NS_WARN_IF(!jsapi.Init(mWindow))) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return;
+  }
+
+  JSContext *cx = jsapi.cx();
+  JS::Rooted<JSObject*> constructor(cx, aFunctionConstructor.Callable());
+
+  /**
+   * 1. If IsConstructor(constructor) is false, then throw a TypeError and abort
+   *    these steps.
+   */
+  // For now, all wrappers are constructable if they are callable. So we need to
+  // unwrap constructor to check it is really constructable.
+  JS::Rooted<JSObject*> constructorUnwrapped(cx, js::CheckedUnwrap(constructor));
+  if (!constructorUnwrapped) {
+    // If the caller's compartment does not have permission to access the
+    // unwrapped constructor then throw.
+    aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
+    return;
+  }
+
+  if (!JS::IsConstructor(constructorUnwrapped)) {
+    aRv.ThrowTypeError<MSG_NOT_CONSTRUCTOR>(NS_LITERAL_STRING("Argument 2 of CustomElementsRegistry.define"));
+    return;
+  }
+
+  /**
+   * 2. If name is not a valid custom element name, then throw a "SyntaxError"
+   *    DOMException and abort these steps.
+   */
+  nsCOMPtr<nsIAtom> nameAtom(NS_Atomize(aName));
+  if (!nsContentUtils::IsCustomElementName(nameAtom)) {
+    aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+    return;
+  }
+
+  /**
+   * 3. If this CustomElementsRegistry contains an entry with name name, then
+   *    throw a "NotSupportedError" DOMException and abort these steps.
+   */
+  if (mCustomDefinitions.Get(nameAtom)) {
+    aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+    return;
+  }
+
+  /**
+   * 4. If this CustomElementsRegistry contains an entry with constructor constructor,
+   *    then throw a "NotSupportedError" DOMException and abort these steps.
+   */
+  // TODO: Step 3 of HTMLConstructor also needs a way to look up definition by
+  // using constructor. So I plans to figure out a solution to support both of
+  // them in bug 1274159.
+
+  /**
+   * 5. Let localName be name.
+   * 6. Let extends be the value of the extends member of options, or null if
+   *    no such member exists.
+   * 7. If extends is not null, then:
+   *    1. If extends is a valid custom element name, then throw a
+   *       "NotSupportedError" DOMException.
+   *    2. If the element interface for extends and the HTML namespace is
+   *       HTMLUnknownElement (e.g., if extends does not indicate an element
+   *       definition in this specification), then throw a "NotSupportedError"
+   *       DOMException.
+   *    3. Set localName to extends.
+   */
+  nsAutoString localName(aName);
+  if (aOptions.mExtends.WasPassed()) {
+    nsCOMPtr<nsIAtom> extendsAtom(NS_Atomize(aOptions.mExtends.Value()));
+    if (nsContentUtils::IsCustomElementName(extendsAtom)) {
+      aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+      return;
+    }
+
+    nsIParserService* ps = nsContentUtils::GetParserService();
+    if (!ps) {
+      aRv.Throw(NS_ERROR_UNEXPECTED);
+      return;
+    }
+
+    // bgsound and multicol are unknown html element.
+    int32_t tag = ps->HTMLCaseSensitiveAtomTagToId(extendsAtom);
+    if (tag == eHTMLTag_userdefined ||
+        tag == eHTMLTag_bgsound ||
+        tag == eHTMLTag_multicol) {
+      aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+      return;
+    }
+
+    localName.Assign(aOptions.mExtends.Value());
+  }
+
+  /**
+   * 8. If this CustomElementRegistry's element definition is running flag is set,
+   *    then throw a "NotSupportedError" DOMException and abort these steps.
+   */
+  if (mIsCustomDefinitionRunning) {
+    aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+    return;
+  }
+
+  JS::Rooted<JSObject*> constructorPrototype(cx);
+  nsAutoPtr<LifecycleCallbacks> callbacksHolder(new LifecycleCallbacks());
+  { // Set mIsCustomDefinitionRunning.
+    /**
+     * 9. Set this CustomElementRegistry's element definition is running flag.
+     */
+    AutoSetRunningFlag as(this);
+
+    { // Enter constructor's compartment.
+      /**
+       * 10.1. Let prototype be Get(constructor, "prototype"). Rethrow any exceptions.
+       */
+      JSAutoCompartment ac(cx, constructor);
+      JS::Rooted<JS::Value> prototypev(cx);
+      // The .prototype on the constructor passed from document.registerElement
+      // is the "expando" of a wrapper. So we should get it from wrapper instead
+      // instead of underlying object.
+      if (!JS_GetProperty(cx, constructor, "prototype", &prototypev)) {
+        aRv.StealExceptionFromJSContext(cx);
+        return;
+      }
+
+      /**
+       * 10.2. If Type(prototype) is not Object, then throw a TypeError exception.
+       */
+      if (!prototypev.isObject()) {
+        aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("constructor.prototype"));
+        return;
+      }
+
+      constructorPrototype = &prototypev.toObject();
+    } // Leave constructor's compartment.
+
+    JS::Rooted<JSObject*> constructorProtoUnwrapped(cx, js::CheckedUnwrap(constructorPrototype));
+    if (!constructorProtoUnwrapped) {
+      // If the caller's compartment does not have permission to access the
+      // unwrapped prototype then throw.
+      aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
+      return;
+    }
+
+    { // Enter constructorProtoUnwrapped's compartment
+      JSAutoCompartment ac(cx, constructorProtoUnwrapped);
+
+      /**
+       * 10.3. Let lifecycleCallbacks be a map with the four keys
+       *       "connectedCallback", "disconnectedCallback", "adoptedCallback", and
+       *       "attributeChangedCallback", each of which belongs to an entry whose
+       *       value is null.
+       * 10.4. For each of the four keys callbackName in lifecycleCallbacks:
+       *       1. Let callbackValue be Get(prototype, callbackName). Rethrow any
+       *          exceptions.
+       *       2. If callbackValue is not undefined, then set the value of the
+       *          entry in lifecycleCallbacks with key callbackName to the result
+       *          of converting callbackValue to the Web IDL Function callback type.
+       *          Rethrow any exceptions from the conversion.
+       */
+      // Will do the same checking for the life cycle callbacks from v0 spec.
+      CheckLifeCycleCallbacks(cx, constructorProtoUnwrapped, aRv);
+      if (aRv.Failed()) {
+        return;
+      }
+
+      /**
+       * 10.5. Let observedAttributes be an empty sequence<DOMString>.
+       * 10.6. If the value of the entry in lifecycleCallbacks with key
+       *       "attributeChangedCallback" is not null, then:
+       *       1. Let observedAttributesIterable be Get(constructor,
+       *          "observedAttributes"). Rethrow any exceptions.
+       *       2. If observedAttributesIterable is not undefined, then set
+       *          observedAttributes to the result of converting
+       *          observedAttributesIterable to a sequence<DOMString>. Rethrow
+       *          any exceptions from the conversion.
+       */
+      // TODO: Bug 1293921 - Implement connected/disconnected/adopted/attributeChanged lifecycle callbacks for custom elements
+
+      // Note: We call the init from the constructorProtoUnwrapped's compartment
+      //       here.
+      JS::RootedValue rootedv(cx, JS::ObjectValue(*constructorProtoUnwrapped));
+      if (!JS_WrapValue(cx, &rootedv) || !callbacksHolder->Init(cx, rootedv)) {
+        aRv.Throw(NS_ERROR_FAILURE);
+        return;
+      }
+    } // Leave constructorProtoUnwrapped's compartment.
+  } // Unset mIsCustomDefinitionRunning
+
+  /**
+   * 11. Let definition be a new custom element definition with name name,
+   *     local name localName, constructor constructor, prototype prototype,
+   *     observed attributes observedAttributes, and lifecycle callbacks
+   *     lifecycleCallbacks.
+   */
+  // Associate the definition with the custom element.
+  nsCOMPtr<nsIAtom> localNameAtom(NS_Atomize(localName));
+  LifecycleCallbacks* callbacks = callbacksHolder.forget();
+  CustomElementDefinition* definition =
+    new CustomElementDefinition(nameAtom,
+                                localNameAtom,
+                                constructor,
+                                constructorPrototype,
+                                callbacks,
+                                0 /* TODO dependent on HTML imports. Bug 877072 */);
+
+  /**
+   * 12. Add definition to this CustomElementsRegistry.
+   */
+  mCustomDefinitions.Put(nameAtom, definition);
+
+  /**
+   * 13. 14. 15. Upgrade candidates
+   */
+  // TODO: Bug 1299363 - Implement custom element v1 upgrade algorithm
+  UpgradeCandidates(cx, nameAtom, definition);
+
+  /**
+   * 16. If this CustomElementsRegistry's when-defined promise map contains an
+   *     entry with key name:
+   *     1. Let promise be the value of that entry.
+   *     2. Resolve promise with undefined.
+   *     3. Delete the entry with key name from this CustomElementsRegistry's
+   *        when-defined promise map.
+   */
+  // TODO: Bug 1275839 - Implement CustomElementsRegistry whenDefined function
 }
 
 void
 CustomElementsRegistry::Get(JSContext* aCx, const nsAString& aName,
                             JS::MutableHandle<JS::Value> aRetVal,
                             ErrorResult& aRv)
 {
   // TODO: This function will be implemented in bug 1275838
@@ -89,25 +803,25 @@ CustomElementsRegistry::Get(JSContext* a
 already_AddRefed<Promise>
 CustomElementsRegistry::WhenDefined(const nsAString& name, ErrorResult& aRv)
 {
   // TODO: This function will be implemented in bug 1275839
   aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
   return nullptr;
 }
 
-CustomElementDefinition::CustomElementDefinition(JSObject* aPrototype,
-                                                 nsIAtom* aType,
+CustomElementDefinition::CustomElementDefinition(nsIAtom* aType,
                                                  nsIAtom* aLocalName,
+                                                 JSObject* aConstructor,
+                                                 JSObject* aPrototype,
                                                  LifecycleCallbacks* aCallbacks,
-                                                 uint32_t aNamespaceID,
                                                  uint32_t aDocOrder)
-  : mPrototype(aPrototype),
-    mType(aType),
+  : mType(aType),
     mLocalName(aLocalName),
+    mConstructor(aConstructor),
+    mPrototype(aPrototype),
     mCallbacks(aCallbacks),
-    mNamespaceID(aNamespaceID),
     mDocOrder(aDocOrder)
 {
 }
 
 } // namespace dom
 } // namespace mozilla
\ No newline at end of file
--- a/dom/base/CustomElementsRegistry.h
+++ b/dom/base/CustomElementsRegistry.h
@@ -10,116 +10,239 @@
 #include "js/TypeDecls.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/BindingDeclarations.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsWrapperCache.h"
 #include "mozilla/dom/FunctionBinding.h"
 
+class nsDocument;
+
 namespace mozilla {
 namespace dom {
 
+struct CustomElementData;
 struct ElementDefinitionOptions;
 struct LifecycleCallbacks;
+class CallbackFunction;
 class Function;
 class Promise;
 
-class CustomElementHashKey : public PLDHashEntryHdr
+struct LifecycleCallbackArgs
+{
+  nsString name;
+  nsString oldValue;
+  nsString newValue;
+};
+
+class CustomElementCallback
 {
 public:
-  typedef CustomElementHashKey *KeyType;
-  typedef const CustomElementHashKey *KeyTypePointer;
-
-  CustomElementHashKey(int32_t aNamespaceID, nsIAtom *aAtom)
-    : mNamespaceID(aNamespaceID),
-      mAtom(aAtom)
-  {}
-  explicit CustomElementHashKey(const CustomElementHashKey* aKey)
-    : mNamespaceID(aKey->mNamespaceID),
-      mAtom(aKey->mAtom)
-  {}
-  ~CustomElementHashKey()
-  {}
-
-  KeyType GetKey() const { return const_cast<KeyType>(this); }
-  bool KeyEquals(const KeyTypePointer aKey) const
+  CustomElementCallback(Element* aThisObject,
+                        nsIDocument::ElementCallbackType aCallbackType,
+                        CallbackFunction* aCallback,
+                        CustomElementData* aOwnerData);
+  void Traverse(nsCycleCollectionTraversalCallback& aCb) const;
+  void Call();
+  void SetArgs(LifecycleCallbackArgs& aArgs)
   {
-    MOZ_ASSERT(mNamespaceID != kNameSpaceID_Unknown,
-               "This equals method is not transitive, nor symmetric. "
-               "A key with a namespace of kNamespaceID_Unknown should "
-               "not be stored in a hashtable.");
-    return (kNameSpaceID_Unknown == aKey->mNamespaceID ||
-            mNamespaceID == aKey->mNamespaceID) &&
-           aKey->mAtom == mAtom;
+    MOZ_ASSERT(mType == nsIDocument::eAttributeChanged,
+               "Arguments are only used by attribute changed callback.");
+    mArgs = aArgs;
   }
 
-  static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
-  static PLDHashNumber HashKey(const KeyTypePointer aKey)
-  {
-    return aKey->mAtom->hash();
-  }
-  enum { ALLOW_MEMMOVE = true };
+private:
+  // The this value to use for invocation of the callback.
+  RefPtr<Element> mThisObject;
+  RefPtr<CallbackFunction> mCallback;
+  // The type of callback (eCreated, eAttached, etc.)
+  nsIDocument::ElementCallbackType mType;
+  // Arguments to be passed to the callback,
+  // used by the attribute changed callback.
+  LifecycleCallbackArgs mArgs;
+  // CustomElementData that contains this callback in the
+  // callback queue.
+  CustomElementData* mOwnerData;
+};
+
+// Each custom element has an associated callback queue and an element is
+// being created flag.
+struct CustomElementData
+{
+  NS_INLINE_DECL_REFCOUNTING(CustomElementData)
+
+  explicit CustomElementData(nsIAtom* aType);
+  // Objects in this array are transient and empty after each microtask
+  // checkpoint.
+  nsTArray<nsAutoPtr<CustomElementCallback>> mCallbackQueue;
+  // Custom element type, for <button is="x-button"> or <x-button>
+  // this would be x-button.
+  nsCOMPtr<nsIAtom> mType;
+  // The callback that is next to be processed upon calling RunCallbackQueue.
+  int32_t mCurrentCallback;
+  // Element is being created flag as described in the custom elements spec.
+  bool mElementIsBeingCreated;
+  // Flag to determine if the created callback has been invoked, thus it
+  // determines if other callbacks can be enqueued.
+  bool mCreatedCallbackInvoked;
+  // The microtask level associated with the callbacks in the callback queue,
+  // it is used to determine if a new queue needs to be pushed onto the
+  // processing stack.
+  int32_t mAssociatedMicroTask;
+
+  // Empties the callback queue.
+  void RunCallbackQueue();
 
 private:
-  int32_t mNamespaceID;
-  nsCOMPtr<nsIAtom> mAtom;
+  virtual ~CustomElementData() {}
 };
 
 // The required information for a custom element as defined in:
-// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html
+// https://html.spec.whatwg.org/multipage/scripting.html#custom-element-definition
 struct CustomElementDefinition
 {
-  CustomElementDefinition(JSObject* aPrototype,
-                          nsIAtom* aType,
+  CustomElementDefinition(nsIAtom* aType,
                           nsIAtom* aLocalName,
+                          JSObject* aConstructor,
+                          JSObject* aPrototype,
                           mozilla::dom::LifecycleCallbacks* aCallbacks,
-                          uint32_t aNamespaceID,
                           uint32_t aDocOrder);
 
-  // The prototype to use for new custom elements of this type.
-  JS::Heap<JSObject *> mPrototype;
-
   // The type (name) for this custom element.
   nsCOMPtr<nsIAtom> mType;
 
   // The localname to (e.g. <button is=type> -- this would be button).
   nsCOMPtr<nsIAtom> mLocalName;
 
+  // The custom element constructor.
+  JS::Heap<JSObject *> mConstructor;
+
+  // The prototype to use for new custom elements of this type.
+  JS::Heap<JSObject *> mPrototype;
+
   // The lifecycle callbacks to call for this custom element.
   nsAutoPtr<mozilla::dom::LifecycleCallbacks> mCallbacks;
 
   // Whether we're currently calling the created callback for a custom element
   // of this type.
   bool mElementIsBeingCreated;
 
-  // Element namespace.
-  int32_t mNamespaceID;
+  // A construction stack.
+  // TODO: Bug 1287348 - Implement construction stack for upgrading an element
 
   // The document custom element order.
   uint32_t mDocOrder;
 };
 
 class CustomElementsRegistry final : public nsISupports,
                                      public nsWrapperCache
 {
+  // Allow nsDocument to access mCustomDefinitions and mCandidatesMap.
+  friend class ::nsDocument;
+
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CustomElementsRegistry)
 
 public:
   static bool IsCustomElementsEnabled(JSContext* aCx, JSObject* aObject);
   static already_AddRefed<CustomElementsRegistry> Create(nsPIDOMWindowInner* aWindow);
-  already_AddRefed<nsIDocument> GetOwnerDocument() const;
+  static void ProcessTopElementQueue();
+
+  static void XPCOMShutdown();
+
+  /**
+   * Looking up a custom element definition.
+   * https://html.spec.whatwg.org/#look-up-a-custom-element-definition
+   */
+  CustomElementDefinition* LookupCustomElementDefinition(
+    const nsAString& aLocalName, const nsAString* aIs = nullptr) const;
+
+  /**
+   * Enqueue created callback or register upgrade candidate for
+   * newly created custom elements, possibly extending an existing type.
+   * ex. <x-button>, <button is="x-button> (type extension)
+   */
+  void SetupCustomElement(Element* aElement, const nsAString* aTypeExtension);
+
+  void EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
+                                Element* aCustomElement,
+                                LifecycleCallbackArgs* aArgs,
+                                CustomElementDefinition* aDefinition);
+
+  void GetCustomPrototype(nsIAtom* aAtom,
+                          JS::MutableHandle<JSObject*> aPrototype);
 
 private:
   explicit CustomElementsRegistry(nsPIDOMWindowInner* aWindow);
   ~CustomElementsRegistry();
+
+  /**
+   * Registers an unresolved custom element that is a candidate for
+   * upgrade when the definition is registered via registerElement.
+   * |aTypeName| is the name of the custom element type, if it is not
+   * provided, then element name is used. |aTypeName| should be provided
+   * when registering a custom element that extends an existing
+   * element. e.g. <button is="x-button">.
+   */
+  void RegisterUnresolvedElement(Element* aElement,
+                                 nsIAtom* aTypeName = nullptr);
+
+  void UpgradeCandidates(JSContext* aCx,
+                         nsIAtom* aKey,
+                         CustomElementDefinition* aDefinition);
+
+  typedef nsClassHashtable<nsISupportsHashKey, CustomElementDefinition>
+    DefinitionMap;
+  typedef nsClassHashtable<nsISupportsHashKey, nsTArray<nsWeakPtr>>
+    CandidateMap;
+
+  // Hashtable for custom element definitions in web components.
+  // Custom prototypes are stored in the compartment where
+  // registerElement was called.
+  DefinitionMap mCustomDefinitions;
+
+  // The "upgrade candidates map" from the web components spec. Maps from a
+  // namespace id and local name to a list of elements to upgrade if that
+  // element is registered as a custom element.
+  CandidateMap mCandidatesMap;
+
   nsCOMPtr<nsPIDOMWindowInner> mWindow;
 
+  // Array representing the processing stack in the custom elements
+  // specification. The processing stack is conceptually a stack of
+  // element queues. Each queue is represented by a sequence of
+  // CustomElementData in this array, separated by nullptr that
+  // represent the boundaries of the items in the stack. The first
+  // queue in the stack is the base element queue.
+  static mozilla::Maybe<nsTArray<RefPtr<CustomElementData>>> sProcessingStack;
+
+  // It is used to prevent reentrant invocations of element definition.
+  bool mIsCustomDefinitionRunning;
+
+private:
+  class MOZ_RAII AutoSetRunningFlag final {
+    public:
+      explicit AutoSetRunningFlag(CustomElementsRegistry* aRegistry)
+        : mRegistry(aRegistry)
+      {
+        MOZ_ASSERT(!mRegistry->mIsCustomDefinitionRunning,
+                   "IsCustomDefinitionRunning flag should be initially false");
+        mRegistry->mIsCustomDefinitionRunning = true;
+      }
+
+      ~AutoSetRunningFlag() {
+        mRegistry->mIsCustomDefinitionRunning = false;
+      }
+
+    private:
+      CustomElementsRegistry* mRegistry;
+  };
+
 public:
   nsISupports* GetParentObject() const;
 
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   void Define(const nsAString& aName, Function& aFunctionConstructor,
               const ElementDefinitionOptions& aOptions, ErrorResult& aRv);
 
--- a/dom/base/DOMImplementation.cpp
+++ b/dom/base/DOMImplementation.cpp
@@ -128,17 +128,16 @@ DOMImplementation::CreateDocument(const 
 
   // When DOMImplementation's createDocument method is invoked with
   // namespace set to HTML Namespace use the registry of the associated
   // document to the new instance.
   nsCOMPtr<nsIDocument> doc = do_QueryInterface(document);
 
   if (aNamespaceURI.EqualsLiteral("http://www.w3.org/1999/xhtml")) {
     doc->SetContentType(NS_LITERAL_STRING("application/xhtml+xml"));
-    doc->UseRegistryFromDocument(mOwner);
   } else if (aNamespaceURI.EqualsLiteral("http://www.w3.org/2000/svg")) {
     doc->SetContentType(NS_LITERAL_STRING("image/svg+xml"));
   } else {
     doc->SetContentType(NS_LITERAL_STRING("application/xml"));
   }
 
   doc->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
 
@@ -230,20 +229,16 @@ DOMImplementation::CreateHTMLDocument(co
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   nsCOMPtr<Element> body = doc->CreateElem(NS_LITERAL_STRING("body"), nullptr,
                                            kNameSpaceID_XHTML);
   rv = root->AppendChildTo(body, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  // When the createHTMLDocument method is invoked,
-  // use the registry of the associated document to the new instance.
-  doc->UseRegistryFromDocument(mOwner);
-
   doc->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
 
   doc.forget(aDocument);
   document.forget(aDOMDocument);
   return NS_OK;
 }
 
 already_AddRefed<nsIDocument>
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -465,18 +465,18 @@ Element::WrapObject(JSContext *aCx, JS::
   JS::Rooted<JSObject*> givenProto(aCx, aGivenProto);
   JS::Rooted<JSObject*> customProto(aCx);
 
   if (!givenProto) {
     // Custom element prototype swizzling.
     CustomElementData* data = GetCustomElementData();
     if (data) {
       // If this is a registered custom element then fix the prototype.
-      nsDocument* document = static_cast<nsDocument*>(OwnerDoc());
-      document->GetCustomPrototype(NodeInfo()->NamespaceID(), data->mType, &customProto);
+      nsContentUtils::GetCustomPrototype(OwnerDoc(), NodeInfo()->NamespaceID(),
+                                         data->mType, &customProto);
       if (customProto &&
           NodePrincipal()->SubsumesConsideringDomain(nsContentUtils::ObjectPrincipal(customProto))) {
         // Just go ahead and create with the right proto up front.  Set
         // customProto to null to flag that we don't need to do any post-facto
         // proto fixups here.
         givenProto = customProto;
         customProto = nullptr;
       }
@@ -951,17 +951,17 @@ Element::GetClientAreaRect()
   nsIFrame* styledFrame;
   nsIScrollableFrame* sf = GetScrollFrame(&styledFrame);
 
   if (sf) {
     return sf->GetScrollPortRect();
   }
 
   if (styledFrame &&
-      (styledFrame->StyleDisplay()->mDisplay != NS_STYLE_DISPLAY_INLINE ||
+      (styledFrame->StyleDisplay()->mDisplay != StyleDisplay::Inline ||
        styledFrame->IsFrameOfType(nsIFrame::eReplaced))) {
     // Special case code to make client area work even when there isn't
     // a scroll view, see bug 180552, bug 227567.
     return styledFrame->GetPaddingRect() - styledFrame->GetPositionIgnoringScrolling();
   }
 
   // SVG nodes reach here and just return 0
   return nsRect(0, 0, 0, 0);
@@ -1603,17 +1603,18 @@ Element::BindToTree(nsIDocument* aDocume
   }
 
   nsIDocument* composedDoc = GetComposedDoc();
   if (composedDoc) {
     // Attached callback must be enqueued whenever custom element is inserted into a
     // document and this document has a browsing context.
     if (GetCustomElementData() && composedDoc->GetDocShell()) {
       // Enqueue an attached callback for the custom element.
-      composedDoc->EnqueueLifecycleCallback(nsIDocument::eAttached, this);
+      nsContentUtils::EnqueueLifecycleCallback(
+        composedDoc, nsIDocument::eAttached, this);
     }
   }
 
   // Propagate scoped style sheet tracking bit.
   if (mParent->IsContent()) {
     nsIContent* parent;
     ShadowRoot* shadowRootParent = ShadowRoot::FromNode(mParent);
     if (shadowRootParent) {
@@ -1884,17 +1885,18 @@ Element::UnbindFromTree(bool aDeep, bool
     }
 
     document->ClearBoxObjectFor(this);
 
     // Detached must be enqueued whenever custom element is removed from
     // the document and this document has a browsing context.
     if (GetCustomElementData() && document->GetDocShell()) {
       // Enqueue a detached callback for the custom element.
-      document->EnqueueLifecycleCallback(nsIDocument::eDetached, this);
+      nsContentUtils::EnqueueLifecycleCallback(
+        document, nsIDocument::eDetached, this);
     }
   }
 
   // Unset this since that's what the old code effectively did.
   UnsetFlags(NODE_FORCE_XBL_BINDINGS);
   bool clearBindingParent = true;
 
 #ifdef MOZ_XUL
@@ -2490,17 +2492,18 @@ Element::SetAttrAndNotify(int32_t aNames
     nsCOMPtr<nsIAtom> newValueAtom = valueForAfterSetAttr.GetAsAtom();
     LifecycleCallbackArgs args = {
       nsDependentAtomString(aName),
       aModType == nsIDOMMutationEvent::ADDITION ?
         NullString() : nsDependentAtomString(oldValueAtom),
       nsDependentAtomString(newValueAtom)
     };
 
-    ownerDoc->EnqueueLifecycleCallback(nsIDocument::eAttributeChanged, this, &args);
+    nsContentUtils::EnqueueLifecycleCallback(
+      ownerDoc, nsIDocument::eAttributeChanged, this, &args);
   }
 
   if (aCallAfterSetAttr) {
     rv = AfterSetAttr(aNamespaceID, aName, &valueForAfterSetAttr, aNotify);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (aNamespaceID == kNameSpaceID_None && aName == nsGkAtoms::dir) {
       OnSetDirAttr(this, &valueForAfterSetAttr,
@@ -2744,17 +2747,18 @@ Element::UnsetAttr(int32_t aNameSpaceID,
   if (ownerDoc && GetCustomElementData()) {
     nsCOMPtr<nsIAtom> oldValueAtom = oldValue.GetAsAtom();
     LifecycleCallbackArgs args = {
       nsDependentAtomString(aName),
       nsDependentAtomString(oldValueAtom),
       NullString()
     };
 
-    ownerDoc->EnqueueLifecycleCallback(nsIDocument::eAttributeChanged, this, &args);
+    nsContentUtils::EnqueueLifecycleCallback(
+      ownerDoc, nsIDocument::eAttributeChanged, this, &args);
   }
 
   if (aNotify) {
     // We can always pass oldValue here since there is no new value which could
     // have corrupted it.
     nsNodeUtils::AttributeChanged(this, aNameSpaceID, aName,
                                   nsIDOMMutationEvent::REMOVAL, &oldValue);
   }
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -131,16 +131,17 @@ class EventChainPostVisitor;
 class EventChainPreVisitor;
 class EventChainVisitor;
 class EventListenerManager;
 class EventStateManager;
 
 namespace dom {
 
 class Animation;
+class CustomElementsRegistry;
 class Link;
 class UndoManager;
 class DOMRect;
 class DOMRectList;
 class DestinationInsertionPointList;
 class Grid;
 
 // IID for the dom::Element interface
@@ -419,17 +420,19 @@ protected:
   }
 
 private:
   // Need to allow the ESM, nsGlobalWindow, and the focus manager to
   // set our state
   friend class mozilla::EventStateManager;
   friend class ::nsGlobalWindow;
   friend class ::nsFocusManager;
-  friend class ::nsDocument;
+
+  // Allow CusomtElementRegistry to call AddStates.
+  friend class CustomElementsRegistry;
 
   // Also need to allow Link to call UpdateLinkState.
   friend class Link;
 
   void NotifyStateChange(EventStates aStates);
 
   void NotifyStyleStateChange(EventStates aStates);
 
--- a/dom/base/File.h
+++ b/dom/base/File.h
@@ -730,17 +730,18 @@ protected:
     if (mFile && mIsTemporary) {
       NS_WARNING("In temporary ~BlobImplFile");
       // Ignore errors if any, not much we can do. Clean-up will be done by
       // https://mxr.mozilla.org/mozilla-central/source/xpcom/io/nsAnonymousTemporaryFile.cpp?rev=6c1c7e45c902#127
 #ifdef DEBUG
       nsresult rv =
 #endif
       mFile->Remove(false);
-      NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to remove temporary DOMFile.");
+      NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
+                           "Failed to remove temporary DOMFile.");
     }
   }
 
 private:
   // Create slice
   BlobImplFile(const BlobImplFile* aOther, uint64_t aStart,
                uint64_t aLength, const nsAString& aContentType)
     : BlobImplBase(aContentType, aOther->mStart + aStart, aLength)
--- a/dom/base/SameProcessMessageQueue.cpp
+++ b/dom/base/SameProcessMessageQueue.cpp
@@ -16,17 +16,18 @@ SameProcessMessageQueue::SameProcessMess
 {
 }
 
 SameProcessMessageQueue::~SameProcessMessageQueue()
 {
   // This code should run during shutdown, and we should already have pumped the
   // event loop. So we should only see messages here if someone is sending
   // messages pretty late in shutdown.
-  NS_WARN_IF_FALSE(mQueue.IsEmpty(), "Shouldn't send messages during shutdown");
+  NS_WARNING_ASSERTION(mQueue.IsEmpty(),
+                       "Shouldn't send messages during shutdown");
   sSingleton = nullptr;
 }
 
 void
 SameProcessMessageQueue::Push(Runnable* aRunnable)
 {
   mQueue.AppendElement(aRunnable);
   NS_DispatchToCurrentThread(aRunnable);
--- a/dom/base/nsAttrValue.cpp
+++ b/dom/base/nsAttrValue.cpp
@@ -1729,19 +1729,19 @@ nsAttrValue::LoadImage(nsIDocument* aDoc
     ToString(val);
     NS_ASSERTION(!val.IsEmpty(),
                  "How did we end up with an empty string for eURL");
   }
 #endif
 
   MiscContainer* cont = GetMiscContainer();
   mozilla::css::URLValue* url = cont->mValue.mURL;
-  mozilla::css::ImageValue* image = 
-    new css::ImageValue(url->GetURI(), url->mString, url->mReferrer,
-                        url->mOriginPrincipal, aDocument);
+  mozilla::css::ImageValue* image =
+    new css::ImageValue(url->GetURI(), url->mString, url->mBaseURI,
+                        url->mReferrer, url->mOriginPrincipal, aDocument);
 
   NS_ADDREF(image);
   cont->mValue.mImage = image;
   NS_RELEASE(url);
   cont->mType = eImage;
 }
 
 bool
--- a/dom/base/nsContentPolicy.cpp
+++ b/dom/base/nsContentPolicy.cpp
@@ -198,39 +198,35 @@ nsContentPolicy::CheckPolicy(CPMethod   
 
     // everyone returned failure, or no policies: sanitize result
     *decision = nsIContentPolicy::ACCEPT;
     return NS_OK;
 }
 
 //uses the parameters from ShouldXYZ to produce and log a message
 //logType must be a literal string constant
-#define LOG_CHECK(logType)                                                    \
-  PR_BEGIN_MACRO                                                              \
-    /* skip all this nonsense if the call failed or logging is disabled */    \
-    if (NS_SUCCEEDED(rv) && MOZ_LOG_TEST(gConPolLog, LogLevel::Debug)) {          \
-      const char *resultName;                                                 \
-      if (decision) {                                                         \
-        resultName = NS_CP_ResponseName(*decision);                           \
-      } else {                                                                \
-        resultName = "(null ptr)";                                            \
-      }                                                                       \
-      nsAutoCString spec("None");                                             \
-      if (contentLocation) {                                                  \
-          contentLocation->GetSpec(spec);                                     \
-      }                                                                       \
-      nsAutoCString refSpec("None");                                          \
-      if (requestingLocation) {                                               \
-          requestingLocation->GetSpec(refSpec);                               \
-      }                                                                       \
-      MOZ_LOG(gConPolLog, LogLevel::Debug,                                        \
-             ("Content Policy: " logType ": <%s> <Ref:%s> result=%s",         \
-              spec.get(), refSpec.get(), resultName)                          \
-             );                                                               \
-    }                                                                         \
+#define LOG_CHECK(logType)                                                     \
+  PR_BEGIN_MACRO                                                               \
+    /* skip all this nonsense if the call failed or logging is disabled */     \
+    if (NS_SUCCEEDED(rv) && MOZ_LOG_TEST(gConPolLog, LogLevel::Debug)) {       \
+      const char *resultName;                                                  \
+      if (decision) {                                                          \
+        resultName = NS_CP_ResponseName(*decision);                            \
+      } else {                                                                 \
+        resultName = "(null ptr)";                                             \
+      }                                                                        \
+      MOZ_LOG(gConPolLog, LogLevel::Debug,                                     \
+             ("Content Policy: " logType ": <%s> <Ref:%s> result=%s",          \
+              contentLocation ? contentLocation->GetSpecOrDefault().get()      \
+                              : "None",                                        \
+              requestingLocation ? requestingLocation->GetSpecOrDefault().get()\
+                                 : "None",                                     \
+              resultName)                                                      \
+             );                                                                \
+    }                                                                          \
   PR_END_MACRO
 
 NS_IMETHODIMP
 nsContentPolicy::ShouldLoad(uint32_t          contentType,
                             nsIURI           *contentLocation,
                             nsIURI           *requestingLocation,
                             nsISupports      *requestingContext,
                             const nsACString &mimeType,
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -33,16 +33,17 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/AutoTimelineMarker.h"
 #include "mozilla/Base64.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/LoadInfo.h"
 #include "mozilla/dom/ContentChild.h"
+#include "mozilla/dom/CustomElementsRegistry.h"
 #include "mozilla/dom/DocumentFragment.h"
 #include "mozilla/dom/DOMTypes.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "mozilla/dom/HTMLTemplateElement.h"
 #include "mozilla/dom/HTMLContentElement.h"
 #include "mozilla/dom/HTMLShadowElement.h"
 #include "mozilla/dom/ipc/BlobChild.h"
@@ -5152,19 +5153,17 @@ nsContentUtils::GetMostRecentNonPBWindow
 /* static */
 void
 nsContentUtils::WarnScriptWasIgnored(nsIDocument* aDocument)
 {
   nsAutoString msg;
   if (aDocument) {
     nsCOMPtr<nsIURI> uri = aDocument->GetDocumentURI();
     if (uri) {
-      nsCString spec;
-      uri->GetSpec(spec);
-      msg.Append(NS_ConvertUTF8toUTF16(spec));
+      msg.Append(NS_ConvertUTF8toUTF16(uri->GetSpecOrDefault()));
       msg.AppendLiteral(" : ");
     }
   }
   msg.AppendLiteral("Unable to run script because scripts are blocked internally.");
 
   LogSimpleConsoleError(msg, "DOM");
 }
 
@@ -7388,16 +7387,88 @@ nsContentUtils::SetKeyboardIndicatorsOnR
                                                       UIStateChangeType aShowAccelerators,
                                                       UIStateChangeType aShowFocusRings)
 {
   UIStateChangeInfo stateInfo(aShowAccelerators, aShowFocusRings);
   CallOnAllRemoteChildren(aWindow, SetKeyboardIndicatorsChild,
                           (void *)&stateInfo);
 }
 
+nsresult
+nsContentUtils::IPCTransferableToTransferable(const IPCDataTransfer& aDataTransfer,
+                                              const bool& aIsPrivateData,
+                                              nsIPrincipal* aRequestingPrincipal,
+                                              nsITransferable* aTransferable,
+                                              mozilla::dom::nsIContentParent* aContentParent,
+                                              mozilla::dom::TabChild* aTabChild)
+{
+  nsresult rv;
+
+  const nsTArray<IPCDataTransferItem>& items = aDataTransfer.items();
+  for (const auto& item : items) {
+    aTransferable->AddDataFlavor(item.flavor().get());
+
+    if (item.data().type() == IPCDataTransferData::TnsString) {
+      nsCOMPtr<nsISupportsString> dataWrapper =
+        do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      const nsString& text = item.data().get_nsString();
+      rv = dataWrapper->SetData(text);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      rv = aTransferable->SetTransferData(item.flavor().get(), dataWrapper,
+                                  text.Length() * sizeof(char16_t));
+
+      NS_ENSURE_SUCCESS(rv, rv);
+    } else if (item.data().type() == IPCDataTransferData::TShmem) {
+      if (nsContentUtils::IsFlavorImage(item.flavor())) {
+        nsCOMPtr<imgIContainer> imageContainer;
+        rv = nsContentUtils::DataTransferItemToImage(item,
+                                                     getter_AddRefs(imageContainer));
+        NS_ENSURE_SUCCESS(rv, rv);
+
+        nsCOMPtr<nsISupportsInterfacePointer> imgPtr =
+          do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID);
+        NS_ENSURE_TRUE(imgPtr, NS_ERROR_FAILURE);
+
+        rv = imgPtr->SetData(imageContainer);
+        NS_ENSURE_SUCCESS(rv, rv);
+
+        aTransferable->SetTransferData(item.flavor().get(), imgPtr, sizeof(nsISupports*));
+      } else {
+        nsCOMPtr<nsISupportsCString> dataWrapper =
+          do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv);
+        NS_ENSURE_SUCCESS(rv, rv);
+
+        // The buffer contains the terminating null.
+        Shmem itemData = item.data().get_Shmem();
+        const nsDependentCString text(itemData.get<char>(),
+                                      itemData.Size<char>());
+        rv = dataWrapper->SetData(text);
+        NS_ENSURE_SUCCESS(rv, rv);
+
+        rv = aTransferable->SetTransferData(item.flavor().get(), dataWrapper, text.Length());
+
+        NS_ENSURE_SUCCESS(rv, rv);
+      }
+
+      if (aContentParent) {
+        Unused << aContentParent->DeallocShmem(item.data().get_Shmem());
+      } else if (aTabChild) {
+        Unused << aTabChild->DeallocShmem(item.data().get_Shmem());
+      }
+    }
+  }
+
+  aTransferable->SetIsPrivateData(aIsPrivateData);
+  aTransferable->SetRequestingPrincipal(aRequestingPrincipal);
+  return NS_OK;
+}
+
 void
 nsContentUtils::TransferablesToIPCTransferables(nsISupportsArray* aTransferables,
                                                 nsTArray<IPCDataTransfer>& aIPC,
                                                 bool aInSyncMessage,
                                                 mozilla::dom::nsIContentChild* aChild,
                                                 mozilla::dom::nsIContentParent* aParent)
 {
   aIPC.Clear();
@@ -9356,8 +9427,128 @@ nsContentUtils::HttpsStateIsModern(nsIDo
     csm->IsOriginPotentiallyTrustworthy(principal, &isTrustworthyOrigin);
     if (isTrustworthyOrigin) {
       return true;
     }
   }
 
   return false;
 }
+
+/* static */ CustomElementDefinition*
+nsContentUtils::LookupCustomElementDefinition(nsIDocument* aDoc,
+                                              const nsAString& aLocalName,
+                                              uint32_t aNameSpaceID,
+                                              const nsAString* aIs)
+{
+  MOZ_ASSERT(aDoc);
+
+  // To support imported document.
+  nsCOMPtr<nsIDocument> doc = aDoc->MasterDocument();
+
+  if (aNameSpaceID != kNameSpaceID_XHTML ||
+      !doc->GetDocShell()) {
+    return nullptr;
+  }
+
+  nsCOMPtr<nsPIDOMWindowInner> window(doc->GetInnerWindow());
+  if (!window) {
+    return nullptr;
+  }
+
+  RefPtr<CustomElementsRegistry> registry(window->CustomElements());
+  if (!registry) {
+    return nullptr;
+  }
+
+  return registry->LookupCustomElementDefinition(aLocalName, aIs);
+}
+
+/* static */ void
+nsContentUtils::SetupCustomElement(Element* aElement,
+                                   const nsAString* aTypeExtension)
+{
+  MOZ_ASSERT(aElement);
+
+  nsCOMPtr<nsIDocument> doc = aElement->OwnerDoc();
+
+  if (!doc) {
+    return;
+  }
+
+  // To support imported document.
+  doc = doc->MasterDocument();
+
+  if (aElement->GetNameSpaceID() != kNameSpaceID_XHTML ||
+      !doc->GetDocShell()) {
+    return;
+  }
+
+  nsCOMPtr<nsPIDOMWindowInner> window(doc->GetInnerWindow());
+  if (!window) {
+    return;
+  }
+
+  RefPtr<CustomElementsRegistry> registry(window->CustomElements());
+  if (!registry) {
+    return;
+  }
+
+  return registry->SetupCustomElement(aElement, aTypeExtension);
+}
+
+/* static */ void
+nsContentUtils::EnqueueLifecycleCallback(nsIDocument* aDoc,
+                                         nsIDocument::ElementCallbackType aType,
+                                         Element* aCustomElement,
+                                         LifecycleCallbackArgs* aArgs,
+                                         CustomElementDefinition* aDefinition)
+{
+  MOZ_ASSERT(aDoc);
+
+  // To support imported document.
+  nsCOMPtr<nsIDocument> doc = aDoc->MasterDocument();
+
+  if (!doc->GetDocShell()) {
+    return;
+  }
+
+  nsCOMPtr<nsPIDOMWindowInner> window(doc->GetInnerWindow());
+  if (!window) {
+    return;
+  }
+
+  RefPtr<CustomElementsRegistry> registry(window->CustomElements());
+  if (!registry) {
+    return;
+  }
+
+  registry->EnqueueLifecycleCallback(aType, aCustomElement, aArgs, aDefinition);
+}
+
+/* static */ void
+nsContentUtils::GetCustomPrototype(nsIDocument* aDoc,
+                                   int32_t aNamespaceID,
+                                   nsIAtom* aAtom,
+                                   JS::MutableHandle<JSObject*> aPrototype)
+{
+  MOZ_ASSERT(aDoc);
+
+  // To support imported document.
+  nsCOMPtr<nsIDocument> doc = aDoc->MasterDocument();
+
+  if (aNamespaceID != kNameSpaceID_XHTML ||
+      !doc->GetDocShell()) {
+    return;
+  }
+
+  nsCOMPtr<nsPIDOMWindowInner> window(doc->GetInnerWindow());
+  if (!window) {
+    return;
+  }
+
+  RefPtr<CustomElementsRegistry> registry(window->CustomElements());
+  if (!registry) {
+    return;
+  }
+
+  return registry->GetCustomPrototype(aAtom, aPrototype);
+}
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -29,16 +29,17 @@
 #include "Units.h"
 #include "mozilla/dom/AutocompleteInfoBinding.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/net/ReferrerPolicy.h"
 #include "mozilla/Logging.h"
 #include "mozilla/NotNull.h"
 #include "nsIContentPolicy.h"
+#include "nsIDocument.h"
 #include "nsPIDOMWindow.h"
 
 #if defined(XP_WIN)
 // Undefine LoadImage to prevent naming conflict with Windows.
 #undef LoadImage
 #endif
 
 class imgICache;
@@ -50,17 +51,16 @@ class imgRequestProxy;
 class nsAutoScriptBlockerSuppressNodeRemoved;
 class nsHtml5StringParser;
 class nsIChannel;
 class nsIConsoleService;
 class nsIContent;
 class nsIContentPolicy;
 class nsIContentSecurityPolicy;
 class nsIDocShellTreeItem;
-class nsIDocument;
 class nsIDocumentLoaderFactory;
 class nsIDOMDocument;
 class nsIDOMDocumentFragment;
 class nsIDOMEvent;
 class nsIDOMHTMLInputElement;
 class nsIDOMKeyEvent;
 class nsIDOMNode;
 class nsIDragSession;
@@ -114,24 +114,27 @@ template<class K, class V> class nsDataH
 template<class K, class V> class nsRefPtrHashtable;
 template<class T> class nsReadingIterator;
 
 namespace mozilla {
 class ErrorResult;
 class EventListenerManager;
 
 namespace dom {
+struct CustomElementDefinition;
 class DocumentFragment;
 class Element;
 class EventTarget;
 class IPCDataTransfer;
 class IPCDataTransferItem;
+struct LifecycleCallbackArgs;
 class NodeInfo;
 class nsIContentChild;
 class nsIContentParent;
+class TabChild;
 class Selection;
 class TabParent;
 } // namespace dom
 
 namespace ipc {
 class Shmem;
 class IShmemAllocator;
 }
@@ -2476,16 +2479,23 @@ public:
                                           imgIContainer** aContainer);
 
   /**
    * Given a flavor obtained from an IPCDataTransferItem or nsITransferable,
    * returns true if we should treat the data as an image.
    */
   static bool IsFlavorImage(const nsACString& aFlavor);
 
+  static nsresult IPCTransferableToTransferable(const mozilla::dom::IPCDataTransfer& aDataTransfer,
+                                                const bool& aIsPrivateData,
+                                                nsIPrincipal* aRequestingPrincipal,
+                                                nsITransferable* aTransferable,
+                                                mozilla::dom::nsIContentParent* aContentParent,
+                                                mozilla::dom::TabChild* aTabChild);
+
   static void TransferablesToIPCTransferables(nsISupportsArray* aTransferables,
                                               nsTArray<mozilla::dom::IPCDataTransfer>& aIPC,
                                               bool aInSyncMessage,
                                               mozilla::dom::nsIContentChild* aChild,
                                               mozilla::dom::nsIContentParent* aParent);
 
   static void TransferableToIPCTransferable(nsITransferable* aTransferable,
                                             mozilla::dom::IPCDataTransfer* aIPCDataTransfer,
@@ -2663,16 +2673,40 @@ public:
   /**
    * Returns true if the "HTTPS state" of the document should be "modern". See:
    *
    * https://html.spec.whatwg.org/#concept-document-https-state
    * https://fetch.spec.whatwg.org/#concept-response-https-state
    */
   static bool HttpsStateIsModern(nsIDocument* aDocument);
 
+  /**
+   * Looking up a custom element definition.
+   * https://html.spec.whatwg.org/#look-up-a-custom-element-definition
+   */
+  static mozilla::dom::CustomElementDefinition*
+    LookupCustomElementDefinition(nsIDocument* aDoc,
+                                  const nsAString& aLocalName,
+                                  uint32_t aNameSpaceID,
+                                  const nsAString* aIs = nullptr);
+
+  static void SetupCustomElement(Element* aElement,
+                                 const nsAString* aTypeExtension = nullptr);
+
+  static void EnqueueLifecycleCallback(nsIDocument* aDoc,
+                                       nsIDocument::ElementCallbackType aType,
+                                       Element* aCustomElement,
+                                       mozilla::dom::LifecycleCallbackArgs* aArgs = nullptr,
+                                       mozilla::dom::CustomElementDefinition* aDefinition = nullptr);
+
+  static void GetCustomPrototype(nsIDocument* aDoc,
+                                 int32_t aNamespaceID,
+                                 nsIAtom* aAtom,
+                                 JS::MutableHandle<JSObject*> prototype);
+
 private:
   static bool InitializeEventTable();
 
   static nsresult EnsureStringBundle(PropertiesFile aFile);
 
   static bool CanCallerAccess(nsIPrincipal* aSubjectPrincipal,
                                 nsIPrincipal* aPrincipal);
 
--- a/dom/base/nsDOMMutationObserver.cpp
+++ b/dom/base/nsDOMMutationObserver.cpp
@@ -706,18 +706,18 @@ nsDOMMutationObserver::Observe(nsINode& 
   r->SetNativeAnonymousChildList(nativeAnonymousChildList);
   r->SetAttributeFilter(Move(filters));
   r->SetAllAttributes(allAttrs);
   r->SetAnimations(animations);
   r->RemoveClones();
 
 #ifdef DEBUG
   for (int32_t i = 0; i < mReceivers.Count(); ++i) {
-    NS_WARN_IF_FALSE(mReceivers[i]->Target(),
-                     "All the receivers should have a target!");
+    NS_WARNING_ASSERTION(mReceivers[i]->Target(),
+                         "All the receivers should have a target!");
   }
 #endif
 }
 
 void
 nsDOMMutationObserver::Disconnect()
 {
   for (int32_t i = 0; i < mReceivers.Count(); ++i) {
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -213,16 +213,18 @@
 #include "mozilla/dom/HTMLBodyElement.h"
 #include "mozilla/dom/HTMLInputElement.h"
 #include "mozilla/dom/MediaQueryList.h"
 #include "mozilla/dom/NodeFilterBinding.h"
 #include "mozilla/OwningNonNull.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/UndoManager.h"
 #include "mozilla/dom/WebComponentsBinding.h"
+#include "mozilla/dom/CustomElementsRegistryBinding.h"
+#include "mozilla/dom/CustomElementsRegistry.h"
 #include "nsFrame.h"
 #include "nsDOMCaretPosition.h"
 #include "nsIDOMHTMLTextAreaElement.h"
 #include "nsViewportInfo.h"
 #include "mozilla/StaticPtr.h"
 #include "nsITextControlElement.h"
 #include "nsIDOMNSEditableElement.h"
 #include "nsIEditor.h"
@@ -363,166 +365,16 @@ nsIdentifierMapEntry::RemoveContentChang
     return;
   ChangeCallback cc = { aCallback, aData, aForImage };
   mChangeCallbacks->RemoveEntry(cc);
   if (mChangeCallbacks->Count() == 0) {
     mChangeCallbacks = nullptr;
   }
 }
 
-namespace mozilla {
-namespace dom {
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(Registry)
-
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Registry)
-  for (auto iter = tmp->mCustomDefinitions.Iter(); !iter.Done(); iter.Next()) {
-    aCallbacks.Trace(&iter.UserData()->mPrototype,
-                     "mCustomDefinitions prototype",
-                     aClosure);
-  }
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Registry)
-  for (auto iter = tmp->mCustomDefinitions.Iter(); !iter.Done(); iter.Next()) {
-    nsAutoPtr<LifecycleCallbacks>& callbacks = iter.UserData()->mCallbacks;
-
-    if (callbacks->mAttributeChangedCallback.WasPassed()) {
-      NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
-        "mCustomDefinitions->mCallbacks->mAttributeChangedCallback");
-      cb.NoteXPCOMChild(callbacks->mAttributeChangedCallback.Value());
-    }
-
-    if (callbacks->mCreatedCallback.WasPassed()) {
-      NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
-        "mCustomDefinitions->mCallbacks->mCreatedCallback");
-      cb.NoteXPCOMChild(callbacks->mCreatedCallback.Value());
-    }
-
-    if (callbacks->mAttachedCallback.WasPassed()) {
-      NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
-        "mCustomDefinitions->mCallbacks->mAttachedCallback");
-      cb.NoteXPCOMChild(callbacks->mAttachedCallback.Value());
-    }
-
-    if (callbacks->mDetachedCallback.WasPassed()) {
-      NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
-        "mCustomDefinitions->mCallbacks->mDetachedCallback");
-      cb.NoteXPCOMChild(callbacks->mDetachedCallback.Value());
-    }
-  }
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Registry)
-  tmp->mCustomDefinitions.Clear();
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Registry)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(Registry)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(Registry)
-
-Registry::Registry()
-{
-  mozilla::HoldJSObjects(this);
-}
-
-Registry::~Registry()
-{
-  mozilla::DropJSObjects(this);
-}
-
-void
-CustomElementCallback::Call()
-{
-  ErrorResult rv;
-  switch (mType) {
-    case nsIDocument::eCreated:
-    {
-      // For the duration of this callback invocation, the element is being created
-      // flag must be set to true.
-      mOwnerData->mElementIsBeingCreated = true;
-
-      // The callback hasn't actually been invoked yet, but we need to flip
-      // this now in order to enqueue the attached callback. This is a spec
-      // bug (w3c bug 27437).
-      mOwnerData->mCreatedCallbackInvoked = true;
-
-      // If ELEMENT is in a document and this document has a browsing context,
-      // enqueue attached callback for ELEMENT.
-      nsIDocument* document = mThisObject->GetComposedDoc();
-      if (document && document->GetDocShell()) {
-        document->EnqueueLifecycleCallback(nsIDocument::eAttached, mThisObject);
-      }
-
-      static_cast<LifecycleCreatedCallback *>(mCallback.get())->Call(mThisObject, rv);
-      mOwnerData->mElementIsBeingCreated = false;
-      break;
-    }
-    case nsIDocument::eAttached:
-      static_cast<LifecycleAttachedCallback *>(mCallback.get())->Call(mThisObject, rv);
-      break;
-    case nsIDocument::eDetached:
-      static_cast<LifecycleDetachedCallback *>(mCallback.get())->Call(mThisObject, rv);
-      break;
-    case nsIDocument::eAttributeChanged:
-      static_cast<LifecycleAttributeChangedCallback *>(mCallback.get())->Call(mThisObject,
-        mArgs.name, mArgs.oldValue, mArgs.newValue, rv);
-      break;
-  }
-}
-
-void
-CustomElementCallback::Traverse(nsCycleCollectionTraversalCallback& aCb) const
-{
-  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mThisObject");
-  aCb.NoteXPCOMChild(mThisObject);
-
-  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mCallback");
-  aCb.NoteXPCOMChild(mCallback);
-}
-
-CustomElementCallback::CustomElementCallback(Element* aThisObject,
-                                             nsIDocument::ElementCallbackType aCallbackType,
-                                             mozilla::dom::CallbackFunction* aCallback,
-                                             CustomElementData* aOwnerData)
-  : mThisObject(aThisObject),
-    mCallback(aCallback),
-    mType(aCallbackType),
-    mOwnerData(aOwnerData)
-{
-}
-
-CustomElementData::CustomElementData(nsIAtom* aType)
-  : mType(aType),
-    mCurrentCallback(-1),
-    mElementIsBeingCreated(false),
-    mCreatedCallbackInvoked(true),
-    mAssociatedMicroTask(-1)
-{
-}
-
-void
-CustomElementData::RunCallbackQueue()
-{
-  // Note: It's possible to re-enter this method.
-  while (static_cast<uint32_t>(++mCurrentCallback) < mCallbackQueue.Length()) {
-    mCallbackQueue[mCurrentCallback]->Call();
-  }
-
-  mCallbackQueue.Clear();
-  mCurrentCallback = -1;
-}
-
-} // namespace dom
-} // namespace mozilla
-
 void
 nsIdentifierMapEntry::FireChangeCallbacks(Element* aOldElement,
                                           Element* aNewElement,
                                           bool aImageOnly)
 {
   if (!mChangeCallbacks)
     return;
 
@@ -1489,22 +1341,16 @@ nsDocument::nsDocument(const char* aCont
            ("DOCUMENT %p created", this));
 
   // Start out mLastStyleSheetSet as null, per spec
   SetDOMStringToNull(mLastStyleSheetSet);
 
   // void state used to differentiate an empty source from an unselected source
   mPreloadPictureFoundSource.SetIsVoid(true);
 
-  if (!sProcessingStack) {
-    sProcessingStack.emplace();
-    // Add the base queue sentinel to the processing stack.
-    sProcessingStack->AppendElement((CustomElementData*) nullptr);
-  }
-
   mEverInForeground = false;
 }
 
 void
 nsDocument::ClearAllBoxObjects()
 {
   if (mBoxObjectTable) {
     for (auto iter = mBoxObjectTable->Iter(); !iter.Done(); iter.Next()) {
@@ -1612,18 +1458,16 @@ nsDocument::~nsDocument()
     }
   }
 
   ReportUseCounters();
 
   mInDestructor = true;
   mInUnlinkOrDeletion = true;
 
-  mRegistry = nullptr;
-
   mozilla::DropJSObjects(this);
 
   // Clear mObservers to keep it in sync with the mutationobserver list
   mObservers.Clear();
 
   if (mStyleSheetSetList) {
     mStyleSheetSetList->Disconnect();
   }
@@ -1787,17 +1631,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
     if (tmp->IsLoadedAsData()) {
       loadedAsData.AssignLiteral("data");
     } else {
       loadedAsData.AssignLiteral("normal");
     }
     uint32_t nsid = tmp->GetDefaultNamespaceID();
     nsAutoCString uri;
     if (tmp->mDocumentURI)
-      tmp->mDocumentURI->GetSpec(uri);
+      uri = tmp->mDocumentURI->GetSpecOrDefault();
     if (nsid < ArrayLength(kNSURIs)) {
       SprintfLiteral(name, "nsDocument %s %s %s",
                      loadedAsData.get(), kNSURIs[nsid], uri.get());
     }
     else {
       SprintfLiteral(name, "nsDocument %s %s",
                      loadedAsData.get(), uri.get());
     }
@@ -1885,17 +1729,16 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOriginalDocument)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCachedEncoder)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStateObjectCached)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mUndoManager)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentTimeline)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPendingAnimationTracker)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTemplateContentsOwner)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChildrenCollection)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRegistry)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAnonymousContents)
 
   // Traverse all our nsCOMArrays.
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStyleSheets)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOnDemandBuiltInUASheets)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPreloadingImages)
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSubImportLinks)
@@ -1970,17 +1813,16 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMImplementation)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mImageMaps)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mCachedEncoder)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mUndoManager)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentTimeline)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mPendingAnimationTracker)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mTemplateContentsOwner)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mChildrenCollection)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mRegistry)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mMasterDocument)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mOrientationPendingPromise)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mImportManager)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mSubImportLinks)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mFontFaceSet)
 
   tmp->mParentDocument = nullptr;
 
@@ -2182,19 +2024,18 @@ nsDocument::Reset(nsIChannel* aChannel, 
 
 void
 nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
                        nsIPrincipal* aPrincipal)
 {
   NS_PRECONDITION(aURI, "Null URI passed to ResetToURI");
 
   if (gDocumentLeakPRLog && MOZ_LOG_TEST(gDocumentLeakPRLog, LogLevel::Debug)) {
-    nsAutoCString spec;
-    aURI->GetSpec(spec);
-    PR_LogPrint("DOCUMENT %p ResetToURI %s", this, spec.get());
+    PR_LogPrint("DOCUMENT %p ResetToURI %s", this,
+                aURI->GetSpecOrDefault().get());
   }
 
   mSecurityInfo = nullptr;
 
   mDocumentLoadGroup = nullptr;
 
   // Delete references to sub-documents and kill the subdocument map,
   // if any. It holds strong references
@@ -2221,23 +2062,16 @@ nsDocument::ResetToURI(nsIURI *aURI, nsI
       mChildren.RemoveChildAt(i);
       nsNodeUtils::ContentRemoved(this, content, i, previousSibling);
       content->UnbindFromTree();
     }
     mCachedRootElement = nullptr;
   }
   mInUnlinkOrDeletion = oldVal;
 
-  if (!mMasterDocument) {
-    // "When creating an import, use the registry of the master document."
-    // Note: at this point the mMasterDocument is already set for imports
-    // (and only for imports)
-    mRegistry = nullptr;
-  }
-
   // Reset our stylesheets
   ResetStylesheetsToURI(aURI);
 
   // Release the listener manager
   if (mListenerManager) {
     mListenerManager->Disconnect();
     mListenerManager = nullptr;
   }
@@ -2523,20 +2357,18 @@ nsDocument::StartDocumentLoad(const char
                               nsILoadGroup* aLoadGroup,
                               nsISupports* aContainer,
                               nsIStreamListener **aDocListener,
                               bool aReset, nsIContentSink* aSink)
 {
   if (gDocumentLeakPRLog && MOZ_LOG_TEST(gDocumentLeakPRLog, LogLevel::Debug)) {
     nsCOMPtr<nsIURI> uri;
     aChannel->GetURI(getter_AddRefs(uri));
-    nsAutoCString spec;
-    if (uri)
-      uri->GetSpec(spec);
-    PR_LogPrint("DOCUMENT %p StartDocumentLoad %s", this, spec.get());
+    PR_LogPrint("DOCUMENT %p StartDocumentLoad %s",
+                this, uri ? uri->GetSpecOrDefault().get() : "");
   }
 
   MOZ_ASSERT(NodePrincipal()->GetAppId() != nsIScriptSecurityManager::UNKNOWN_APP_ID,
              "Document should never have UNKNOWN_APP_ID");
 
   MOZ_ASSERT(GetReadyStateEnum() == nsIDocument::READYSTATE_UNINITIALIZED,
              "Bad readyState");
   SetReadyStateInternal(READYSTATE_LOADING);
@@ -4730,20 +4562,16 @@ nsDocument::SetScriptGlobalObject(nsIScr
 #endif
         bool allowDNSPrefetch;
         docShell->GetAllowDNSPrefetch(&allowDNSPrefetch);
         mAllowDNSPrefetch = allowDNSPrefetch;
       }
     }
 
     MaybeRescheduleAnimationFrameNotifications();
-    if (Preferences::GetBool("dom.webcomponents.enabled") ||
-        Preferences::GetBool("dom.webcomponents.customelements.enabled")) {
-      mRegistry = new Registry();
-    }
   }
 
   // Remember the pointer to our window (or lack there of), to avoid
   // having to QI every time it's asked for.
   nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(mScriptGlobalObject);
   mWindow = window;
 
   // Now that we know what our window is, we can flush the CSP errors to the
@@ -5559,36 +5387,39 @@ bool IsLowercaseASCII(const nsAString& a
     char16_t c = aValue[i];
     if (!(0x0061 <= (c) && ((c) <= 0x007a))) {
       return false;
     }
   }
   return true;
 }
 
-CustomElementDefinition*
-nsDocument::LookupCustomElementDefinition(const nsAString& aLocalName,
-                                          uint32_t aNameSpaceID,
-                                          const nsAString* aIs)
-{
-  if (!mRegistry || aNameSpaceID != kNameSpaceID_XHTML) {
+already_AddRefed<mozilla::dom::CustomElementsRegistry>
+nsDocument::GetCustomElementsRegistry()
+{
+  nsAutoString contentType;
+  GetContentType(contentType);
+  if (!IsHTMLDocument() &&
+      !contentType.EqualsLiteral("application/xhtml+xml")) {
     return nullptr;
   }
 
-  nsCOMPtr<nsIAtom> localNameAtom = NS_Atomize(aLocalName);
-  nsCOMPtr<nsIAtom> typeAtom = aIs ? NS_Atomize(*aIs) : localNameAtom;
-
-  CustomElementDefinition* data;
-  CustomElementHashKey key(aNameSpaceID, typeAtom);
-  if (mRegistry->mCustomDefinitions.Get(&key, &data) &&
-      data->mLocalName == localNameAtom) {
-    return data;
-  }
-
-  return nullptr;
+  nsCOMPtr<nsPIDOMWindowInner> window(
+    do_QueryInterface(mScriptGlobalObject ? mScriptGlobalObject
+                                          : GetScopeObject()));
+  if (!window) {
+    return nullptr;
+  }
+
+  RefPtr<CustomElementsRegistry> registry = window->CustomElements();
+  if (!registry) {
+    return nullptr;
+  }
+
+  return registry.forget();
 }
 
 already_AddRefed<Element>
 nsDocument::CreateElement(const nsAString& aTagName,
                           const ElementCreationOptions& aOptions,
                           ErrorResult& rv)
 {
   rv = nsContentUtils::CheckQName(aTagName, false);
@@ -5610,58 +5441,16 @@ nsDocument::CreateElement(const nsAStrin
   }
 
   RefPtr<Element> elem = CreateElem(
     needsLowercase ? lcTagName : aTagName, nullptr, mDefaultElementType, is);
 
   return elem.forget();
 }
 
-void
-nsDocument::SetupCustomElement(Element* aElement,
-                               uint32_t aNamespaceID,
-                               const nsAString* aTypeExtension)
-{
-  if (!mRegistry || aNamespaceID != kNameSpaceID_XHTML) {
-    return;
-  }
-
-  nsCOMPtr<nsIAtom> tagAtom = aElement->NodeInfo()->NameAtom();
-  nsCOMPtr<nsIAtom> typeAtom = aTypeExtension ?
-    NS_Atomize(*aTypeExtension) : tagAtom;
-
-  if (aTypeExtension && !aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::is)) {
-    // Custom element setup in the parser happens after the "is"
-    // attribute is added.
-    aElement->SetAttr(kNameSpaceID_None, nsGkAtoms::is, *aTypeExtension, true);
-  }
-
-  CustomElementDefinition* data = LookupCustomElementDefinition(
-    aElement->NodeInfo()->LocalName(), aNamespaceID, aTypeExtension);
-
-  if (!data) {
-    // The type extension doesn't exist in the registry,
-    // thus we don't need to enqueue callback or adjust
-    // the "is" attribute, but it is possibly an upgrade candidate.
-    RegisterUnresolvedElement(aElement, typeAtom);
-    return;
-  }
-
-  if (data->mLocalName != tagAtom) {
-    // The element doesn't match the local name for the
-    // definition, thus the element isn't a custom element
-    // and we don't need to do anything more.
-    return;
-  }
-
-  // Enqueuing the created callback will set the CustomElementData on the
-  // element, causing prototype swizzling to occur in Element::WrapObject.
-  EnqueueLifecycleCallback(nsIDocument::eCreated, aElement, nullptr, data);
-}
-
 NS_IMETHODIMP
 nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
                             const nsAString& aQualifiedName,
                             nsIDOMElement** aReturn)
 {
   *aReturn = nullptr;
   ElementCreationOptions options;
   ErrorResult rv;
@@ -5911,35 +5700,38 @@ nsDocument::CustomElementConstructor(JSC
   // Function name is the type of the custom element.
   JSString* jsFunName =
     JS_GetFunctionId(JS_ValueToFunction(aCx, args.calleev()));
   nsAutoJSString elemName;
   if (!elemName.init(aCx, jsFunName)) {
     return true;
   }
 
+  RefPtr<mozilla::dom::CustomElementsRegistry> registry = window->CustomElements();
+  if (!registry) {
+    return true;
+  }
+
   nsCOMPtr<nsIAtom> typeAtom(NS_Atomize(elemName));
-  CustomElementHashKey key(kNameSpaceID_Unknown, typeAtom);
-  CustomElementDefinition* definition;
-  if (!document->mRegistry ||
-      !document->mRegistry->mCustomDefinitions.Get(&key, &definition)) {
+  CustomElementDefinition* definition = registry->mCustomDefinitions.Get(typeAtom);
+  if (!definition) {
     return true;
   }
 
   nsDependentAtomString localName(definition->mLocalName);
 
   nsCOMPtr<Element> element =
-    document->CreateElem(localName, nullptr, definition->mNamespaceID);
+    document->CreateElem(localName, nullptr, kNameSpaceID_XHTML);
   NS_ENSURE_TRUE(element, true);
 
   if (definition->mLocalName != typeAtom) {
     // This element is a custom element by extension, thus we need to
     // do some special setup. For non-extended custom elements, this happens
     // when the element is created.
-    document->SetupCustomElement(element, definition->mNamespaceID, &elemName);
+    nsContentUtils::SetupCustomElement(element, &elemName);
   }
 
   nsresult rv = nsContentUtils::WrapNative(aCx, element, element, args.rval());
   NS_ENSURE_SUCCESS(rv, true);
 
   return true;
 }
 
@@ -5970,447 +5762,92 @@ nsDocument::IsWebComponentsEnabled(JSCon
     NS_ENSURE_SUCCESS(rv, false);
 
     return perm == nsIPermissionManager::ALLOW_ACTION;
   }
 
   return false;
 }
 
-nsresult
-nsDocument::RegisterUnresolvedElement(Element* aElement, nsIAtom* aTypeName)
-{
-  if (!mRegistry) {
-    return NS_OK;
-  }
-
-  mozilla::dom::NodeInfo* info = aElement->NodeInfo();
-
-  // Candidate may be a custom element through extension,
-  // in which case the custom element type name will not
-  // match the element tag name. e.g. <button is="x-button">.
-  nsCOMPtr<nsIAtom> typeName = aTypeName;
-  if (!typeName) {
-    typeName = info->NameAtom();
-  }
-
-  CustomElementHashKey key(info->NamespaceID(), typeName);
-  if (mRegistry->mCustomDefinitions.Get(&key)) {
-    return NS_OK;
-  }
-
-  nsTArray<nsWeakPtr>* unresolved;
-  mRegistry->mCandidatesMap.Get(&key, &unresolved);
-  if (!unresolved) {
-    unresolved = new nsTArray<nsWeakPtr>();
-    // Ownership of unresolved is taken by mCandidatesMap.
-    mRegistry->mCandidatesMap.Put(&key, unresolved);
-  }
-
-  nsWeakPtr* elem = unresolved->AppendElement();
-  *elem = do_GetWeakReference(aElement);
-  aElement->AddStates(NS_EVENT_STATE_UNRESOLVED);
-
-  return NS_OK;
-}
-
-void
-nsDocument::EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
-                                     Element* aCustomElement,
-                                     LifecycleCallbackArgs* aArgs,
-                                     CustomElementDefinition* aDefinition)
-{
-  if (!mRegistry) {
-    // The element might not belong to a document that
-    // has a browsing context, and thus no registry.
-    return;
-  }
-
-  CustomElementData* elementData = aCustomElement->GetCustomElementData();
-
-  // Let DEFINITION be ELEMENT's definition
-  CustomElementDefinition* definition = aDefinition;
-  if (!definition) {
-    mozilla::dom::NodeInfo* info = aCustomElement->NodeInfo();
-
-    // Make sure we get the correct definition in case the element
-    // is a extended custom element e.g. <button is="x-button">.
-    nsCOMPtr<nsIAtom> typeAtom = elementData ?
-      elementData->mType.get() : info->NameAtom();
-
-    CustomElementHashKey key(info->NamespaceID(), typeAtom);
-    if (!mRegistry->mCustomDefinitions.Get(&key, &definition) ||
-        definition->mLocalName != info->NameAtom()) {
-      // Trying to enqueue a callback for an element that is not
-      // a custom element. We are done, nothing to do.
-      return;
-    }
-  }
-
-  if (!elementData) {
-    // Create the custom element data the first time
-    // that we try to enqueue a callback.
-    elementData = new CustomElementData(definition->mType);
-    // aCustomElement takes ownership of elementData
-    aCustomElement->SetCustomElementData(elementData);
-    MOZ_ASSERT(aType == nsIDocument::eCreated,
-               "First callback should be the created callback");
-  }
-
-  // Let CALLBACK be the callback associated with the key NAME in CALLBACKS.
-  CallbackFunction* func = nullptr;
-  switch (aType) {
-    case nsIDocument::eCreated:
-      if (definition->mCallbacks->mCreatedCallback.WasPassed()) {
-        func = definition->mCallbacks->mCreatedCallback.Value();
-      }
-      break;
-
-    case nsIDocument::eAttached:
-      if (definition->mCallbacks->mAttachedCallback.WasPassed()) {
-        func = definition->mCallbacks->mAttachedCallback.Value();
-      }
-      break;
-
-    case nsIDocument::eDetached:
-      if (definition->mCallbacks->mDetachedCallback.WasPassed()) {
-        func = definition->mCallbacks->mDetachedCallback.Value();
-      }
-      break;
-
-    case nsIDocument::eAttributeChanged:
-      if (definition->mCallbacks->mAttributeChangedCallback.WasPassed()) {
-        func = definition->mCallbacks->mAttributeChangedCallback.Value();
-      }
-      break;
-  }
-
-  // If there is no such callback, stop.
-  if (!func) {
-    return;
-  }
-
-  if (aType == nsIDocument::eCreated) {
-    elementData->mCreatedCallbackInvoked = false;
-  } else if (!elementData->mCreatedCallbackInvoked) {
-    // Callbacks other than created callback must not be enqueued
-    // until after the created callback has been invoked.
-    return;
-  }
-
-  // Add CALLBACK to ELEMENT's callback queue.
-  CustomElementCallback* callback = new CustomElementCallback(aCustomElement,
-                                                              aType,
-                                                              func,
-                                                              elementData);
-  // Ownership of callback is taken by mCallbackQueue.
-  elementData->mCallbackQueue.AppendElement(callback);
-  if (aArgs) {
-    callback->SetArgs(*aArgs);
-  }
-
-  if (!elementData->mElementIsBeingCreated) {
-    CustomElementData* lastData =
-      sProcessingStack->SafeLastElement(nullptr);
-
-    // A new element queue needs to be pushed if the queue at the
-    // top of the stack is associated with another microtask level.
-    bool shouldPushElementQueue =
-      (!lastData || lastData->mAssociatedMicroTask <
-         static_cast<int32_t>(nsContentUtils::MicroTaskLevel()));
-
-    // Push a new element queue onto the processing stack when appropriate
-    // (when we enter a new microtask).
-    if (shouldPushElementQueue) {
-      // Push a sentinel value on the processing stack to mark the
-      // boundary between the element queues.
-      sProcessingStack->AppendElement((CustomElementData*) nullptr);
-    }
-
-    sProcessingStack->AppendElement(elementData);
-    elementData->mAssociatedMicroTask =
-      static_cast<int32_t>(nsContentUtils::MicroTaskLevel());
-
-    // Add a script runner to pop and process the element queue at
-    // the top of the processing stack.
-    if (shouldPushElementQueue) {
-      // Lifecycle callbacks enqueued by user agent implementation
-      // should be invoked prior to returning control back to script.
-      // Create a script runner to process the top of the processing
-      // stack as soon as it is safe to run script.
-      nsCOMPtr<nsIRunnable> runnable =
-        NS_NewRunnableFunction(&nsDocument::ProcessTopElementQueue);
-      nsContentUtils::AddScriptRunner(runnable);
-    }
-  }
-}
-
-// static
-void
-nsDocument::ProcessTopElementQueue()
-{
-  MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
-
-  nsTArray<RefPtr<CustomElementData>>& stack = *sProcessingStack;
-  uint32_t firstQueue = stack.LastIndexOf((CustomElementData*) nullptr);
-
-  for (uint32_t i = firstQueue + 1; i < stack.Length(); ++i) {
-    // Callback queue may have already been processed in an earlier
-    // element queue or in an element queue that was popped
-    // off more recently.
-    if (stack[i]->mAssociatedMicroTask != -1) {
-      stack[i]->RunCallbackQueue();
-      stack[i]->mAssociatedMicroTask = -1;
-    }
-  }
-
-  // If this was actually the base element queue, don't bother trying to pop
-  // the first "queue" marker (sentinel).
-  if (firstQueue != 0) {
-    stack.SetLength(firstQueue);
-  } else {
-    // Don't pop sentinel for base element queue.
-    stack.SetLength(1);
-  }
-}
-
-bool
-nsDocument::RegisterEnabled()
-{
-  static bool sPrefValue =
-    Preferences::GetBool("dom.webcomponents.enabled", false);
-  return sPrefValue;
-}
-
-// static
-Maybe<nsTArray<RefPtr<mozilla::dom::CustomElementData>>>
-nsDocument::sProcessingStack;
-
 void
 nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
                             const ElementRegistrationOptions& aOptions,
                             JS::MutableHandle<JSObject*> aRetval,
                             ErrorResult& rv)
 {
-  if (!mRegistry) {
+  RefPtr<CustomElementsRegistry> registry(GetCustomElementsRegistry());
+  if (!registry) {
     rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
     return;
   }
 
-  Registry::DefinitionMap& definitions = mRegistry->mCustomDefinitions;
-
   // Unconditionally convert TYPE to lowercase.
   nsAutoString lcType;
   nsContentUtils::ASCIIToLower(aType, lcType);
 
-  // Only convert NAME to lowercase in HTML documents. Note that NAME is
-  // options.extends.
-  nsAutoString lcName;
-  if (IsHTMLDocument()) {
-    nsContentUtils::ASCIIToLower(aOptions.mExtends, lcName);
-  } else {
-    lcName.Assign(aOptions.mExtends);
-  }
-
-  nsCOMPtr<nsIAtom> typeAtom(NS_Atomize(lcType));
-  if (!nsContentUtils::IsCustomElementName(typeAtom)) {
-    rv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
-    return;
-  }
-
-  // If there already exists a definition with the same TYPE, set ERROR to
-  // DuplicateDefinition and stop.
-  // Note that we need to find existing custom elements from either namespace.
-  CustomElementHashKey duplicateFinder(kNameSpaceID_Unknown, typeAtom);
-  if (definitions.Get(&duplicateFinder)) {
-    rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
-    return;
-  }
-
   nsIGlobalObject* sgo = GetScopeObject();
   if (!sgo) {
     rv.Throw(NS_ERROR_UNEXPECTED);
     return;
   }
 
   JS::Rooted<JSObject*> global(aCx, sgo->GetGlobalJSObject());
-  nsCOMPtr<nsIAtom> nameAtom;
-  int32_t namespaceID = kNameSpaceID_XHTML;
   JS::Rooted<JSObject*> protoObject(aCx);
-  {
+
+  if (!aOptions.mPrototype) {
     JS::Rooted<JSObject*> htmlProto(aCx);
-    {
-      JSAutoCompartment ac(aCx, global);
-
-      htmlProto = HTMLElementBinding::GetProtoObjectHandle(aCx);
-      if (!htmlProto) {
-        rv.Throw(NS_ERROR_OUT_OF_MEMORY);
-        return;
-      }
-    }
-
-    if (!aOptions.mPrototype) {
-      if (!JS_WrapObject(aCx, &htmlProto)) {
-        rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
-        return;
-      }
-
-      protoObject = JS_NewObjectWithGivenProto(aCx, nullptr, htmlProto);
-      if (!protoObject) {
-        rv.Throw(NS_ERROR_UNEXPECTED);
-        return;
-      }
-    } else {
-      protoObject = aOptions.mPrototype;
-
-      // Get the unwrapped prototype to do some checks.
-      JS::Rooted<JSObject*> protoObjectUnwrapped(aCx, js::CheckedUnwrap(protoObject));
-      if (!protoObjectUnwrapped) {
-        // If the caller's compartment does not have permission to access the
-        // unwrapped prototype then throw.
-        rv.Throw(NS_ERROR_DOM_SECURITY_ERR);
-        return;
-      }
-
-      // If PROTOTYPE is already an interface prototype object for any interface
-      // object or PROTOTYPE has a non-configurable property named constructor,
-      // throw a NotSupportedError and stop.
-      const js::Class* clasp = js::GetObjectClass(protoObjectUnwrapped);
-      if (IsDOMIfaceAndProtoClass(clasp)) {
-        rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
-        return;
-      }
-
-      JS::Rooted<JS::PropertyDescriptor> descRoot(aCx);
-      JS::MutableHandle<JS::PropertyDescriptor> desc(&descRoot);
-      // This check may go through a wrapper, but as we checked above
-      // it should be transparent or an xray. This should be fine for now,
-      // until the spec is sorted out.
-      if (!JS_GetPropertyDescriptor(aCx, protoObject, "constructor", desc)) {
-        rv.Throw(NS_ERROR_UNEXPECTED);
-        return;
-      }
-
-      if (!desc.configurable()) {
-        rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
-        return;
-      }
-
-      JS::Rooted<JSObject*> protoProto(aCx, protoObject);
-
-      if (!JS_WrapObject(aCx, &htmlProto)) {
-        rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
-        return;
-      }
-
-      while (protoProto) {
-        if (protoProto == htmlProto) {
-          break;
-        }
-
-        if (!JS_GetPrototype(aCx, protoProto, &protoProto)) {
-          rv.Throw(NS_ERROR_UNEXPECTED);
-          return;
-        }
-      }
-    } // Done with the checks, leave prototype's compartment.
-
-    // If name was provided and not null...
-    if (!lcName.IsEmpty()) {
-      // Let BASE be the element interface for NAME and NAMESPACE.
-      nameAtom = NS_Atomize(lcName);
-      nsIParserService* ps = nsContentUtils::GetParserService();
-      if (!ps) {
-        rv.Throw(NS_ERROR_UNEXPECTED);
-        return;
-      }
-
-      bool known =
-        ps->HTMLCaseSensitiveAtomTagToId(nameAtom) != eHTMLTag_userdefined;
-
-      // If BASE does not exist or is an interface for a custom element, set ERROR
-      // to InvalidName and stop.
-      // If BASE exists, then it cannot be an interface for a custom element.
-      if (!known) {
-        rv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
-        return;
-      }
-    } else {
-      nameAtom = typeAtom;
-    }
-  } // Leaving the document's compartment for the LifecycleCallbacks init
-
-  JS::Rooted<JSObject*> wrappedProto(aCx, protoObject);
-  if (!JS_WrapObject(aCx, &wrappedProto)) {
-    rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
-    return;
-  }
-
-  // Note: We call the init from the caller compartment here
-  nsAutoPtr<LifecycleCallbacks> callbacksHolder(new LifecycleCallbacks());
-  JS::RootedValue rootedv(aCx, JS::ObjectValue(*wrappedProto));
-  if (!JS_WrapValue(aCx, &rootedv) || !callbacksHolder->Init(aCx, rootedv)) {
-    rv.Throw(NS_ERROR_FAILURE);
-    return;
-  }
-
-  // Associate the definition with the custom element.
-  CustomElementHashKey key(namespaceID, typeAtom);
-  LifecycleCallbacks* callbacks = callbacksHolder.forget();
-  CustomElementDefinition* definition =
-    new CustomElementDefinition(wrappedProto,
-                                typeAtom,
-                                nameAtom,
-                                callbacks,
-                                namespaceID,
-                                0 /* TODO dependent on HTML imports. Bug 877072 */);
-  definitions.Put(&key, definition);
-
-  // Do element upgrade.
-  nsAutoPtr<nsTArray<nsWeakPtr>> candidates;
-  mRegistry->mCandidatesMap.RemoveAndForget(&key, candidates);
-  if (candidates) {
-    for (size_t i = 0; i < candidates->Length(); ++i) {
-      nsCOMPtr<Element> elem = do_QueryReferent(candidates->ElementAt(i));
-      if (!elem) {
-        continue;
-      }
-
-      elem->RemoveStates(NS_EVENT_STATE_UNRESOLVED);
-
-      // Make sure that the element name matches the name in the definition.
-      // (e.g. a definition for x-button extending button should match
-      // <button is="x-button"> but not <x-button>.
-      if (elem->NodeInfo()->NameAtom() != nameAtom) {
-        //Skip over this element because definition does not apply.
-        continue;
-      }
-
-      MOZ_ASSERT(elem->IsHTMLElement(nameAtom));
-      nsWrapperCache* cache;
-      CallQueryInterface(elem, &cache);
-      MOZ_ASSERT(cache, "Element doesn't support wrapper cache?");
-
-      // We want to set the custom prototype in the caller's comparment.
-      // In the case that element is in a different compartment,
-      // this will set the prototype on the element's wrapper and
-      // thus only visible in the wrapper's compartment.
-      JS::RootedObject wrapper(aCx);
-      if ((wrapper = cache->GetWrapper()) && JS_WrapObject(aCx, &wrapper)) {
-        if (!JS_SetPrototype(aCx, wrapper, wrappedProto)) {
-          continue;
-        }
-      }
-
-      EnqueueLifecycleCallback(nsIDocument::eCreated, elem, nullptr, definition);
+    htmlProto = HTMLElementBinding::GetProtoObjectHandle(aCx);
+    if (!htmlProto) {
+      rv.Throw(NS_ERROR_OUT_OF_MEMORY);
+      return;
+    }
+
+    protoObject = JS_NewObjectWithGivenProto(aCx, nullptr, htmlProto);
+    if (!protoObject) {
+      rv.Throw(NS_ERROR_UNEXPECTED);
+      return;
+    }
+  } else {
+    protoObject = aOptions.mPrototype;
+
+    // Get the unwrapped prototype to do some checks.
+    JS::Rooted<JSObject*> protoObjectUnwrapped(aCx, js::CheckedUnwrap(protoObject));
+    if (!protoObjectUnwrapped) {
+      // If the caller's compartment does not have permission to access the
+      // unwrapped prototype then throw.
+      rv.Throw(NS_ERROR_DOM_SECURITY_ERR);
+      return;
+    }
+
+    // If PROTOTYPE is already an interface prototype object for any interface
+    // object or PROTOTYPE has a non-configurable property named constructor,
+    // throw a NotSupportedError and stop.
+    const js::Class* clasp = js::GetObjectClass(protoObjectUnwrapped);
+    if (IsDOMIfaceAndProtoClass(clasp)) {
+      rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+      return;
+    }
+
+    JS::Rooted<JS::PropertyDescriptor> descRoot(aCx);
+    JS::MutableHandle<JS::PropertyDescriptor> desc(&descRoot);
+    // This check may go through a wrapper, but as we checked above
+    // it should be transparent or an xray. This should be fine for now,
+    // until the spec is sorted out.
+    if (!JS_GetPropertyDescriptor(aCx, protoObject, "constructor", desc)) {
+      rv.Throw(NS_ERROR_UNEXPECTED);
+      return;
+    }
+
+    if (!desc.configurable()) {
+      rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+      return;
     }
   }
 
   JS::Rooted<JSFunction*> constructor(aCx);
-
   {
     // Go into the document's global compartment when creating the constructor
     // function because we want to get the correct document (where the
     // definition is registered) when it is called.
     JSAutoCompartment ac(aCx, global);
 
     // Create constructor to return. Store the name of the custom element as the
     // name of the function.
@@ -6430,27 +5867,34 @@ nsDocument::RegisterElement(JSContext* a
     return;
   }
 
   if (!JS_LinkConstructorAndPrototype(aCx, wrappedConstructor, protoObject)) {
     rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
     return;
   }
 
+  ElementDefinitionOptions options;
+  if (!aOptions.mExtends.IsVoid()) {
+    // Only convert NAME to lowercase in HTML documents.
+    nsAutoString lcName;
+    IsHTMLDocument() ? nsContentUtils::ASCIIToLower(aOptions.mExtends, lcName)
+                     : lcName.Assign(aOptions.mExtends);
+
+    options.mExtends.Construct(lcName);
+  }
+
+  RootedCallback<OwningNonNull<binding_detail::FastFunction>> functionConstructor(aCx);
+  functionConstructor = new binding_detail::FastFunction(aCx, wrappedConstructor, sgo);
+
+  registry->Define(lcType, functionConstructor, options, rv);
+
   aRetval.set(wrappedConstructor);
 }
 
-void
-nsDocument::UseRegistryFromDocument(nsIDocument* aDocument)
-{
-  nsDocument* doc = static_cast<nsDocument*>(aDocument);
-  MOZ_ASSERT(!mRegistry, "There should be no existing registry.");
-  mRegistry = doc->mRegistry;
-}
-
 NS_IMETHODIMP
 nsDocument::GetElementsByTagName(const nsAString& aTagname,
                                  nsIDOMNodeList** aReturn)
 {
   RefPtr<nsContentList> list = GetElementsByTagName(aTagname);
   NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
 
   // transfer ref to aReturn
@@ -8985,18 +8429,16 @@ nsDocument::Destroy()
   mInUnlinkOrDeletion = oldVal;
 
   mLayoutHistoryState = nullptr;
 
   // Shut down our external resource map.  We might not need this for
   // leak-fixing if we fix nsDocumentViewer to do cycle-collection, but
   // tearing down all those frame trees right now is the right thing to do.
   mExternalResourceMap.Shutdown();
-
-  mRegistry = nullptr;
 }
 
 void
 nsDocument::RemovedFromDocShell()
 {
   if (mRemovedFromDocShell)
     return;
 
@@ -10339,17 +9781,18 @@ nsIDocument::CreateStaticClone(nsIDocShe
       for (int32_t i = 0; i < sheetsCount; ++i) {
         StyleSheetHandle::RefPtr sheet = GetStyleSheetAt(i);
         if (sheet) {
           if (sheet->IsApplicable()) {
             // XXXheycam Need to make ServoStyleSheet cloning work.
             if (sheet->IsGecko()) {
               RefPtr<CSSStyleSheet> clonedSheet =
                 sheet->AsGecko()->Clone(nullptr, nullptr, clonedDoc, nullptr);
-              NS_WARN_IF_FALSE(clonedSheet, "Cloning a stylesheet didn't work!");
+              NS_WARNING_ASSERTION(clonedSheet,
+                                   "Cloning a stylesheet didn't work!");
               if (clonedSheet) {
                 clonedDoc->AddStyleSheet(clonedSheet);
               }
             } else {
               NS_ERROR("stylo: ServoStyleSheet doesn't support cloning");
             }
           }
         }
@@ -10358,17 +9801,18 @@ nsIDocument::CreateStaticClone(nsIDocShe
       // Iterate backwards to maintain order
       for (StyleSheetHandle sheet : Reversed(thisAsDoc->mOnDemandBuiltInUASheets)) {
         if (sheet) {
           if (sheet->IsApplicable()) {
             // XXXheycam Need to make ServoStyleSheet cloning work.
             if (sheet->IsGecko()) {
               RefPtr<CSSStyleSheet> clonedSheet =
                 sheet->AsGecko()->Clone(nullptr, nullptr, clonedDoc, nullptr);
-              NS_WARN_IF_FALSE(clonedSheet, "Cloning a stylesheet didn't work!");
+              NS_WARNING_ASSERTION(clonedSheet,
+                                   "Cloning a stylesheet didn't work!");
               if (clonedSheet) {
                 clonedDoc->AddOnDemandBuiltInUASheet(clonedSheet);
               }
             } else {
               NS_ERROR("stylo: ServoStyleSheet doesn't support cloning");
             }
           }
         }
@@ -12414,18 +11858,20 @@ nsDocument::SetPointerLock(Element* aEle
     NS_WARNING("SetPointerLock(): Unable to get PresContext");
     return false;
   }
 
   nsCOMPtr<nsIWidget> widget;
   nsIFrame* rootFrame = shell->GetRootFrame();
   if (!NS_WARN_IF(!rootFrame)) {
     widget = rootFrame->GetNearestWidget();
-    NS_WARN_IF_FALSE(widget, "SetPointerLock(): Unable to find widget "
-                     "in shell->GetRootFrame()->GetNearestWidget();");
+    NS_WARNING_ASSERTION(
+      widget,
+      "SetPointerLock(): Unable to find widget in "
+      "shell->GetRootFrame()->GetNearestWidget();");
     if (aElement && !widget) {
       return false;
     }
   }
 
   // Hide the cursor and set pointer lock for future mouse events
   RefPtr<EventStateManager> esm = presContext->EventStateManager();
   esm->SetCursor(aCursorStyle, nullptr, false,
@@ -12572,22 +12018,16 @@ nsDocument::OnAppThemeChanged()
     }
     bool willNotify;
     bool isAlternate;
     link->UpdateStyleSheet(nullptr, &willNotify, &isAlternate, true);
   }
 }
 
 void
-nsDocument::XPCOMShutdown()
-{
-  sProcessingStack.reset();
-}
-
-void
 nsDocument::UpdateVisibilityState()
 {
   dom::VisibilityState oldState = mVisibilityState;
   mVisibilityState = GetVisibilityState();
   if (oldState != mVisibilityState) {
     nsContentUtils::DispatchTrustedEvent(this, static_cast<nsIDocument*>(this),
                                          NS_LITERAL_STRING("visibilitychange"),
                                          /* bubbles = */ true,
@@ -13050,18 +12490,17 @@ nsDocument::ReportUseCounters()
       (IsContentDocument() || IsResourceDoc())) {
     nsCOMPtr<nsIURI> uri;
     NodePrincipal()->GetURI(getter_AddRefs(uri));
     if (!uri || MightBeAboutOrChromeScheme(uri)) {
       return;
     }
 
     if (sDebugUseCounters) {
-      nsCString spec;
-      uri->GetSpec(spec);
+      nsCString spec = uri->GetSpecOrDefault();
 
       // URIs can be rather long for data documents, so truncate them to
       // some reasonable length.
       spec.Truncate(std::min(128U, spec.Length()));
       printf("-- Use counters for %s --\n", spec.get());
     }
 
     // We keep separate counts for individual documents and top-level
@@ -13462,14 +12901,15 @@ nsDocument::CheckCustomElementName(const
   if (!aOptions.mIs.WasPassed() ||
       !Preferences::GetBool("dom.webcomponents.enabled")) {
       return nullptr;
   }
 
   nsString* is = const_cast<nsString*>(&(aOptions.mIs.Value()));
 
   // Throw NotFoundError if 'is' is not-null and definition is null
-  if (!LookupCustomElementDefinition(aLocalName, aNamespaceID, is)) {
+  if (!nsContentUtils::LookupCustomElementDefinition(this, aLocalName,
+                                                     aNamespaceID, is)) {
       rv.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
   }
 
   return is;
 }
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -258,117 +258,16 @@ private:
   nsTArray<Element*> mIdContentList;
   RefPtr<nsBaseContentList> mNameContentList;
   nsAutoPtr<nsTHashtable<ChangeCallbackEntry> > mChangeCallbacks;
   RefPtr<Element> mImageElement;
 };
 
 namespace mozilla {
 namespace dom {
-struct LifecycleCallbackArgs
-{
-  nsString name;
-  nsString oldValue;
-  nsString newValue;
-};
-
-struct CustomElementData;
-
-class CustomElementCallback
-{
-public:
-  CustomElementCallback(Element* aThisObject,
-                        nsIDocument::ElementCallbackType aCallbackType,
-                        mozilla::dom::CallbackFunction* aCallback,
-                        CustomElementData* aOwnerData);
-  void Traverse(nsCycleCollectionTraversalCallback& aCb) const;
-  void Call();
-  void SetArgs(LifecycleCallbackArgs& aArgs)
-  {
-    MOZ_ASSERT(mType == nsIDocument::eAttributeChanged,
-               "Arguments are only used by attribute changed callback.");
-    mArgs = aArgs;
-  }
-
-private:
-  // The this value to use for invocation of the callback.
-  RefPtr<mozilla::dom::Element> mThisObject;
-  RefPtr<mozilla::dom::CallbackFunction> mCallback;
-  // The type of callback (eCreated, eAttached, etc.)
-  nsIDocument::ElementCallbackType mType;
-  // Arguments to be passed to the callback,
-  // used by the attribute changed callback.
-  LifecycleCallbackArgs mArgs;
-  // CustomElementData that contains this callback in the
-  // callback queue.
-  CustomElementData* mOwnerData;
-};
-
-// Each custom element has an associated callback queue and an element is
-// being created flag.
-struct CustomElementData
-{
-  NS_INLINE_DECL_REFCOUNTING(CustomElementData)
-
-  explicit CustomElementData(nsIAtom* aType);
-  // Objects in this array are transient and empty after each microtask
-  // checkpoint.
-  nsTArray<nsAutoPtr<CustomElementCallback>> mCallbackQueue;
-  // Custom element type, for <button is="x-button"> or <x-button>
-  // this would be x-button.
-  nsCOMPtr<nsIAtom> mType;
-  // The callback that is next to be processed upon calling RunCallbackQueue.
-  int32_t mCurrentCallback;
-  // Element is being created flag as described in the custom elements spec.
-  bool mElementIsBeingCreated;
-  // Flag to determine if the created callback has been invoked, thus it
-  // determines if other callbacks can be enqueued.
-  bool mCreatedCallbackInvoked;
-  // The microtask level associated with the callbacks in the callback queue,
-  // it is used to determine if a new queue needs to be pushed onto the
-  // processing stack.
-  int32_t mAssociatedMicroTask;
-
-  // Empties the callback queue.
-  void RunCallbackQueue();
-
-private:
-  virtual ~CustomElementData() {}
-};
-
-class Registry : public nsISupports
-{
-public:
-  friend class ::nsDocument;
-
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Registry)
-
-  Registry();
-
-protected:
-  virtual ~Registry();
-
-  typedef nsClassHashtable<mozilla::dom::CustomElementHashKey,
-                           mozilla::dom::CustomElementDefinition>
-    DefinitionMap;
-  typedef nsClassHashtable<mozilla::dom::CustomElementHashKey,
-                           nsTArray<nsWeakPtr>>
-    CandidateMap;
-
-  // Hashtable for custom element definitions in web components.
-  // Custom prototypes are stored in the compartment where
-  // registerElement was called.
-  DefinitionMap mCustomDefinitions;
-
-  // The "upgrade candidates map" from the web components spec. Maps from a
-  // namespace id and local name to a list of elements to upgrade if that
-  // element is registered as a custom element.
-  CandidateMap mCandidatesMap;
-};
 
 } // namespace dom
 } // namespace mozilla
 
 class nsDocHeaderData
 {
 public:
   nsDocHeaderData(nsIAtom* aField, const nsAString& aData)
@@ -1213,46 +1112,16 @@ public:
   // to notify window when the page was first visited.
   void MaybeActiveMediaComponents();
 
   virtual void DocAddSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const override;
   // DocAddSizeOfIncludingThis is inherited from nsIDocument.
 
   virtual nsIDOMNode* AsDOMNode() override { return this; }
 
-  virtual void EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
-                                        Element* aCustomElement,
-                                        mozilla::dom::LifecycleCallbackArgs* aArgs = nullptr,
-                                        mozilla::dom::CustomElementDefinition* aDefinition = nullptr) override;
-
-  static void ProcessTopElementQueue();
-
-  void GetCustomPrototype(int32_t aNamespaceID,
-                          nsIAtom* aAtom,
-                          JS::MutableHandle<JSObject*> prototype)
-  {
-    if (!mRegistry) {
-      prototype.set(nullptr);
-      return;
-    }
-
-    mozilla::dom::CustomElementHashKey key(aNamespaceID, aAtom);
-    mozilla::dom::CustomElementDefinition* definition;
-    if (mRegistry->mCustomDefinitions.Get(&key, &definition)) {
-      prototype.set(definition->mPrototype);
-    } else {
-      prototype.set(nullptr);
-    }
-  }
-
-  static bool RegisterEnabled();
-
-  virtual nsresult RegisterUnresolvedElement(mozilla::dom::Element* aElement,
-                                             nsIAtom* aTypeName = nullptr) override;
-
   // WebIDL bits
   virtual mozilla::dom::DOMImplementation*
     GetImplementation(mozilla::ErrorResult& rv) override;
   virtual void
     RegisterElement(JSContext* aCx, const nsAString& aName,
                     const mozilla::dom::ElementRegistrationOptions& aOptions,
                     JS::MutableHandle<JSObject*> aRetval,
                     mozilla::ErrorResult& rv) override;
@@ -1263,29 +1132,27 @@ public:
   virtual void EnableStyleSheetsForSet(const nsAString& aSheetSet) override;
   virtual already_AddRefed<Element> CreateElement(const nsAString& aTagName,
                                                   const mozilla::dom::ElementCreationOptions& aOptions,
                                                   ErrorResult& rv) override;
   virtual already_AddRefed<Element> CreateElementNS(const nsAString& aNamespaceURI,
                                                     const nsAString& aQualifiedName,
                                                     const mozilla::dom::ElementCreationOptions& aOptions,
                                                     mozilla::ErrorResult& rv) override;
-  virtual void UseRegistryFromDocument(nsIDocument* aDocument) override;
 
   virtual nsIDocument* MasterDocument() override
   {
     return mMasterDocument ? mMasterDocument.get()
                            : this;
   }
 
   virtual void SetMasterDocument(nsIDocument* master) override
   {
     MOZ_ASSERT(master);
     mMasterDocument = master;
-    UseRegistryFromDocument(mMasterDocument);
   }
 
   virtual bool IsMasterDocument() override
   {
     return !mMasterDocument;
   }
 
   virtual mozilla::dom::ImportManager* ImportManager() override
@@ -1392,18 +1259,16 @@ protected:
   Element* GetTitleElement();
 
 public:
   // Get our title
   virtual void GetTitle(nsString& aTitle) override;
   // Set our title
   virtual void SetTitle(const nsAString& aTitle, mozilla::ErrorResult& rv) override;
 
-  static void XPCOMShutdown();
-
   bool mIsTopLevelContentDocument: 1;
   bool mIsContentDocument: 1;
 
   bool IsTopLevelContentDocument();
   void SetIsTopLevelContentDocument(bool aIsTopLevelContentDocument);
 
   bool IsContentDocument() const;
   void SetIsContentDocument(bool aIsContentDocument);
@@ -1498,60 +1363,38 @@ protected:
   // pop one off this stack, restoring the previous full-screen state
   nsTArray<nsWeakPtr> mFullScreenStack;
 
   // The root of the doc tree in which this document is in. This is only
   // non-null when this document is in fullscreen mode.
   nsWeakPtr mFullscreenRoot;
 
 private:
-  // Array representing the processing stack in the custom elements
-  // specification. The processing stack is conceptually a stack of
-  // element queues. Each queue is represented by a sequence of
-  // CustomElementData in this array, separated by nullptr that
-  // represent the boundaries of the items in the stack. The first
-  // queue in the stack is the base element queue.
-  static mozilla::Maybe<nsTArray<RefPtr<mozilla::dom::CustomElementData>>> sProcessingStack;
-
   static bool CustomElementConstructor(JSContext* aCx, unsigned aArgc, JS::Value* aVp);
 
   /**
-   * Looking up a custom element definition.
-   * https://html.spec.whatwg.org/#look-up-a-custom-element-definition
-   */
-  mozilla::dom::CustomElementDefinition* LookupCustomElementDefinition(
-    const nsAString& aLocalName, uint32_t aNameSpaceID, const nsAString* aIs);
-
-  /**
    * Check if the passed custom element name, aOptions.mIs, is a registered
    * custom element type or not, then return the custom element name for future
    * usage.
    *
    * If there is no existing custom element definition for this name, throw a
    * NotFoundError.
    */
   nsString* CheckCustomElementName(
     const mozilla::dom::ElementCreationOptions& aOptions,
     const nsAString& aLocalName,
     uint32_t aNamespaceID,
     ErrorResult& rv);
 
 public:
-  // Enqueue created callback or register upgrade candidate for
-  // newly created custom elements, possibly extending an existing type.
-  // ex. <x-button>, <button is="x-button> (type extension)
-  virtual void SetupCustomElement(Element* aElement,
-                                  uint32_t aNamespaceID,
-                                  const nsAString* aTypeExtension) override;
+  virtual already_AddRefed<mozilla::dom::CustomElementsRegistry>
+    GetCustomElementsRegistry() override;
 
   static bool IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject);
 
-  // The "registry" from the web components spec.
-  RefPtr<mozilla::dom::Registry> mRegistry;
-
   RefPtr<mozilla::EventListenerManager> mListenerManager;
   RefPtr<mozilla::dom::StyleSheetList> mDOMStyleSheets;
   RefPtr<nsDOMStyleSheetSetList> mStyleSheetSetList;
   RefPtr<nsScriptLoader> mScriptLoader;
   nsDocHeaderData* mHeaderData;
   /* mIdentifierMap works as follows for IDs:
    * 1) Attribute changes affect the table immediately (removing and adding
    *    entries as needed).
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -507,19 +507,19 @@ nsFocusManager::MoveFocus(mozIDOMWindowP
 {
   *aElement = nullptr;
 
   LOGFOCUS(("<<MoveFocus begin Type: %d Flags: %x>>", aType, aFlags));
 
   if (MOZ_LOG_TEST(gFocusLog, LogLevel::Debug) && mFocusedWindow) {
     nsIDocument* doc = mFocusedWindow->GetExtantDoc();
     if (doc && doc->GetDocumentURI()) {
-      nsAutoCString spec;
-      doc->GetDocumentURI()->GetSpec(spec);
-      LOGFOCUS((" Focused Window: %p %s", mFocusedWindow.get(), spec.get()));
+      LOGFOCUS((" Focused Window: %p %s",
+                mFocusedWindow.get(),
+                doc->GetDocumentURI()->GetSpecOrDefault().get()));
     }
   }
 
   LOGCONTENT("  Current Focus: %s", mFocusedContent.get());
 
   // use FLAG_BYMOVEFOCUS when switching focus with MoveFocus unless one of
   // the other focus methods is already set, or we're just moving to the root
   // or caret position.
@@ -659,27 +659,26 @@ nsFocusManager::MoveCaretToFocus(mozIDOM
 NS_IMETHODIMP
 nsFocusManager::WindowRaised(mozIDOMWindowProxy* aWindow)
 {
   NS_ENSURE_TRUE(aWindow, NS_ERROR_INVALID_ARG);
   nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
 
   if (MOZ_LOG_TEST(gFocusLog, LogLevel::Debug)) {
     LOGFOCUS(("Window %p Raised [Currently: %p %p]", aWindow, mActiveWindow.get(), mFocusedWindow.get()));
-    nsAutoCString spec;
     nsIDocument* doc = window->GetExtantDoc();
     if (doc && doc->GetDocumentURI()) {
-      doc->GetDocumentURI()->GetSpec(spec);
-      LOGFOCUS(("  Raised Window: %p %s", aWindow, spec.get()));
+      LOGFOCUS(("  Raised Window: %p %s", aWindow,
+                doc->GetDocumentURI()->GetSpecOrDefault().get()));
     }
     if (mActiveWindow) {
       doc = mActiveWindow->GetExtantDoc();
       if (doc && doc->GetDocumentURI()) {
-        doc->GetDocumentURI()->GetSpec(spec);
-        LOGFOCUS(("  Active Window: %p %s", mActiveWindow.get(), spec.get()));
+        LOGFOCUS(("  Active Window: %p %s", mActiveWindow.get(),
+                  doc->GetDocumentURI()->GetSpecOrDefault().get()));
       }
     }
   }
 
   if (mActiveWindow == window) {
     // The window is already active, so there is no need to focus anything,
     // but make sure that the right widget is focused. This is a special case
     // for Windows because when restoring a minimized window, a second
@@ -745,27 +744,26 @@ nsFocusManager::WindowRaised(mozIDOMWind
 NS_IMETHODIMP
 nsFocusManager::WindowLowered(mozIDOMWindowProxy* aWindow)
 {
   NS_ENSURE_TRUE(aWindow, NS_ERROR_INVALID_ARG);
   nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
 
   if (MOZ_LOG_TEST(gFocusLog, LogLevel::Debug)) {
     LOGFOCUS(("Window %p Lowered [Currently: %p %p]", aWindow, mActiveWindow.get(), mFocusedWindow.get()));
-    nsAutoCString spec;
     nsIDocument* doc = window->GetExtantDoc();
     if (doc && doc->GetDocumentURI()) {
-      doc->GetDocumentURI()->GetSpec(spec);
-      LOGFOCUS(("  Lowered Window: %s", spec.get()));
+      LOGFOCUS(("  Lowered Window: %s",
+                doc->GetDocumentURI()->GetSpecOrDefault().get()));
     }
     if (mActiveWindow) {
       doc = mActiveWindow->GetExtantDoc();
       if (doc && doc->GetDocumentURI()) {
-        doc->GetDocumentURI()->GetSpec(spec);
-        LOGFOCUS(("  Active Window: %s", spec.get()));
+        LOGFOCUS(("  Active Window: %s",
+                  doc->GetDocumentURI()->GetSpecOrDefault().get()));
       }
     }
   }
 
   if (mActiveWindow != window)
     return NS_OK;
 
   // clear the mouse capture as the active window has changed
@@ -874,28 +872,27 @@ nsFocusManager::ContentRemoved(nsIDocume
 NS_IMETHODIMP
 nsFocusManager::WindowShown(mozIDOMWindowProxy* aWindow, bool aNeedsFocus)
 {
   NS_ENSURE_TRUE(aWindow, NS_ERROR_INVALID_ARG);
   nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
 
   if (MOZ_LOG_TEST(gFocusLog, LogLevel::Debug)) {
     LOGFOCUS(("Window %p Shown [Currently: %p %p]", window.get(), mActiveWindow.get(), mFocusedWindow.get()));
-    nsAutoCString spec;
     nsIDocument* doc = window->GetExtantDoc();
     if (doc && doc->GetDocumentURI()) {
-      doc->GetDocumentURI()->GetSpec(spec);
-      LOGFOCUS(("Shown Window: %s", spec.get()));
+      LOGFOCUS(("Shown Window: %s",
+                doc->GetDocumentURI()->GetSpecOrDefault().get()));
     }
 
     if (mFocusedWindow) {
       doc = mFocusedWindow->GetExtantDoc();
       if (doc && doc->GetDocumentURI()) {
-        doc->GetDocumentURI()->GetSpec(spec);
-        LOGFOCUS((" Focused Window: %s", spec.get()));
+        LOGFOCUS((" Focused Window: %s",
+                  doc->GetDocumentURI()->GetSpecOrDefault().get()));
       }
     }
   }
 
   if (nsIDocShell* docShell = window->GetDocShell()) {
     if (nsCOMPtr<nsITabChild> child = docShell->GetTabChild()) {
       bool active = static_cast<TabChild*>(child.get())->ParentIsActive();
       ActivateOrDeactivate(window, active);
@@ -932,33 +929,33 @@ nsFocusManager::WindowHidden(mozIDOMWind
   NS_ENSURE_TRUE(aWindow, NS_ERROR_INVALID_ARG);
   nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
 
   if (MOZ_LOG_TEST(gFocusLog, LogLevel::Debug)) {
     LOGFOCUS(("Window %p Hidden [Currently: %p %p]", window.get(), mActiveWindow.get(), mFocusedWindow.get()));
     nsAutoCString spec;
     nsIDocument* doc = window->GetExtantDoc();
     if (doc && doc->GetDocumentURI()) {
-      doc->GetDocumentURI()->GetSpec(spec);
-      LOGFOCUS(("  Hide Window: %s", spec.get()));
+      LOGFOCUS(("  Hide Window: %s",
+                doc->GetDocumentURI()->GetSpecOrDefault().get()));
     }
 
     if (mFocusedWindow) {
       doc = mFocusedWindow->GetExtantDoc();
       if (doc && doc->GetDocumentURI()) {
-        doc->GetDocumentURI()->GetSpec(spec);
-        LOGFOCUS(("  Focused Window: %s", spec.get()));
+        LOGFOCUS(("  Focused Window: %s",
+                  doc->GetDocumentURI()->GetSpecOrDefault().get()));
       }
     }
 
     if (mActiveWindow) {
       doc = mActiveWindow->GetExtantDoc();
       if (doc && doc->GetDocumentURI()) {
-        doc->GetDocumentURI()->GetSpec(spec);
-        LOGFOCUS(("  Active Window: %s", spec.get()));
+        LOGFOCUS(("  Active Window: %s",
+                  doc->GetDocumentURI()->GetSpecOrDefault().get()));
       }
     }
   }
 
   if (!IsSameOrAncestor(window, mFocusedWindow))
     return NS_OK;
 
   // at this point, we know that the window being hidden is either the focused
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -2224,18 +2224,18 @@ nsFrameLoader::CheckForRecursiveLoad(nsI
                "MaybeCreateDocShell succeeded, but null mDocShell");
   if (!mDocShell) {
     return NS_ERROR_FAILURE;
   }
 
   // Check that we're still in the docshell tree.
   nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
   mDocShell->GetTreeOwner(getter_AddRefs(treeOwner));
-  NS_WARN_IF_FALSE(treeOwner,
-                   "Trying to load a new url to a docshell without owner!");
+  NS_WARNING_ASSERTION(treeOwner,
+                       "Trying to load a new url to a docshell without owner!");
   NS_ENSURE_STATE(treeOwner);
 
   if (mDocShell->ItemType() != nsIDocShellTreeItem::typeContent) {
     // No need to do recursion-protection here XXXbz why not??  Do we really
     // trust people not to screw up with non-content docshells?
     return NS_OK;
   }
 
--- a/dom/base/nsGenericDOMDataNode.cpp
+++ b/dom/base/nsGenericDOMDataNode.cpp
@@ -965,19 +965,19 @@ nsGenericDOMDataNode::GetWholeText(nsASt
 {
   nsIContent* parent = GetParent();
 
   // Handle parent-less nodes
   if (!parent)
     return GetData(aWholeText);
 
   int32_t index = parent->IndexOf(this);
-  NS_WARN_IF_FALSE(index >= 0,
-                   "Trying to use .wholeText with an anonymous"
-                    "text node child of a binding parent?");
+  NS_WARNING_ASSERTION(index >= 0,
+                       "Trying to use .wholeText with an anonymous"
+                       "text node child of a binding parent?");
   NS_ENSURE_TRUE(index >= 0, NS_ERROR_DOM_NOT_SUPPORTED_ERR);
   int32_t first =
     FirstLogicallyAdjacentTextNode(parent, index);
   int32_t last =
     LastLogicallyAdjacentTextNode(parent, index, parent->GetChildCount());
 
   aWholeText.Truncate();
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1354,17 +1354,17 @@ nsGlobalWindow::~nsGlobalWindow()
   }
 
   --gRefCnt;
 
 #ifdef DEBUG
   if (!PR_GetEnv("MOZ_QUIET")) {
     nsAutoCString url;
     if (mLastOpenedURI) {
-      mLastOpenedURI->GetSpec(url);
+      url = mLastOpenedURI->GetSpecOrDefault();
 
       // Data URLs can be very long, so truncate to avoid flooding the log.
       const uint32_t maxURLLength = 1000;
       if (url.Length() > maxURLLength) {
         url.Truncate(maxURLLength);
       }
     }
 
@@ -1841,17 +1841,17 @@ ImplCycleCollectionTraverse(nsCycleColle
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalWindow)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow)
   if (MOZ_UNLIKELY(cb.WantDebugInfo())) {
     char name[512];
     nsAutoCString uri;
     if (tmp->mDoc && tmp->mDoc->GetDocumentURI()) {
-      tmp->mDoc->GetDocumentURI()->GetSpec(uri);
+      uri = tmp->mDoc->GetDocumentURI()->GetSpecOrDefault();
     }
     SprintfLiteral(name, "nsGlobalWindow # %" PRIu64 " %s %s", tmp->mWindowID,
                    tmp->IsInnerWindow() ? "inner" : "outer", uri.get());
     cb.DescribeRefCountedNode(tmp->mRefCnt.get(), name);
   } else {
     NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsGlobalWindow, tmp->mRefCnt.get())
   }
 
@@ -2988,20 +2988,18 @@ nsGlobalWindow::ClearStatus()
 void
 nsGlobalWindow::InnerSetNewDocument(JSContext* aCx, nsIDocument* aDocument)
 {
   NS_PRECONDITION(IsInnerWindow(), "Must only be called on inner windows");
   MOZ_ASSERT(aDocument);
 
   if (gDOMLeakPRLog && MOZ_LOG_TEST(gDOMLeakPRLog, LogLevel::Debug)) {
     nsIURI *uri = aDocument->GetDocumentURI();
-    nsAutoCString spec;
-    if (uri)
-      uri->GetSpec(spec);
-    PR_LogPrint("DOMWINDOW %p SetNewDocument %s", this, spec.get());
+    PR_LogPrint("DOMWINDOW %p SetNewDocument %s",
+                this, uri ? uri->GetSpecOrDefault().get() : "");
   }
 
   mDoc = aDocument;
   ClearDocumentDependentSlots(aCx);
   mFocusedNode = nullptr;
   mLocalStorage = nullptr;
   mSessionStorage = nullptr;
 
@@ -6531,17 +6529,17 @@ nsGlobalWindow::FinishFullscreenChange(b
     if (!pmService) {
       return;
     }
 
     // XXXkhuey using the inner here, do we need to do something if it changes?
     ErrorResult rv;
     mWakeLock = pmService->NewWakeLock(NS_LITERAL_STRING("DOM_Fullscreen"),
                                        AsOuter()->GetCurrentInnerWindow(), rv);
-    NS_WARN_IF_FALSE(!rv.Failed(), "Failed to lock the wakelock");
+    NS_WARNING_ASSERTION(!rv.Failed(), "Failed to lock the wakelock");
     rv.SuppressException();
   } else if (mWakeLock && !mFullScreen) {
     ErrorResult rv;
     mWakeLock->Unlock(rv);
     mWakeLock = nullptr;
     rv.SuppressException();
   }
 }
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -2477,44 +2477,23 @@ public:
     eCreated,
     eAttached,
     eDetached,
     eAttributeChanged
   };
 
   nsIDocument* GetTopLevelContentDocument();
 
-  /**
-   * Registers an unresolved custom element that is a candidate for
-   * upgrade when the definition is registered via registerElement.
-   * |aTypeName| is the name of the custom element type, if it is not
-   * provided, then element name is used. |aTypeName| should be provided
-   * when registering a custom element that extends an existing
-   * element. e.g. <button is="x-button">.
-   */
-  virtual nsresult RegisterUnresolvedElement(Element* aElement,
-                                             nsIAtom* aTypeName = nullptr) = 0;
-  virtual void EnqueueLifecycleCallback(ElementCallbackType aType,
-                                        Element* aCustomElement,
-                                        mozilla::dom::LifecycleCallbackArgs* aArgs = nullptr,
-                                        mozilla::dom::CustomElementDefinition* aDefinition = nullptr) = 0;
-  virtual void SetupCustomElement(Element* aElement,
-                                  uint32_t aNamespaceID,
-                                  const nsAString* aTypeExtension = nullptr) = 0;
   virtual void
     RegisterElement(JSContext* aCx, const nsAString& aName,
                     const mozilla::dom::ElementRegistrationOptions& aOptions,
                     JS::MutableHandle<JSObject*> aRetval,
                     mozilla::ErrorResult& rv) = 0;
-
-  /**
-   * In some cases, new document instances must be associated with
-   * an existing web components custom element registry as specified.
-   */
-  virtual void UseRegistryFromDocument(nsIDocument* aDocument) = 0;
+  virtual already_AddRefed<mozilla::dom::CustomElementsRegistry>
+    GetCustomElementsRegistry() = 0;
 
   already_AddRefed<nsContentList>
   GetElementsByTagName(const nsAString& aTagName)
   {
     return NS_GetContentList(this, kNameSpaceID_Unknown, aTagName);
   }
   already_AddRefed<nsContentList>
     GetElementsByTagNameNS(const nsAString& aNamespaceURI,
--- a/dom/base/nsInProcessTabChildGlobal.cpp
+++ b/dom/base/nsInProcessTabChildGlobal.cpp
@@ -124,18 +124,18 @@ nsInProcessTabChildGlobal::MarkForCC()
 
 nsresult
 nsInProcessTabChildGlobal::Init()
 {
 #ifdef DEBUG
   nsresult rv =
 #endif
   InitTabChildGlobal();
-  NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
-                   "Couldn't initialize nsInProcessTabChildGlobal");
+  NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
+                       "Couldn't initialize nsInProcessTabChildGlobal");
   mMessageManager = new nsFrameMessageManager(this,
                                               nullptr,
                                               dom::ipc::MM_CHILD);
   return NS_OK;
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsInProcessTabChildGlobal)
 
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -526,19 +526,17 @@ PrintWinURI(nsGlobalWindow *win)
   }
 
   nsIURI *uri = doc->GetDocumentURI();
   if (!uri) {
     printf("Document doesn't have a URI.\n");
     return;
   }
 
-  nsAutoCString spec;
-  uri->GetSpec(spec);
-  printf("%s\n", spec.get());
+  printf("%s\n", uri->GetSpecOrDefault().get());
 }
 
 void
 PrintWinCodebase(nsGlobalWindow *win)
 {
   if (!win) {
     printf("No window passed in.\n");
     return;
@@ -552,19 +550,17 @@ PrintWinCodebase(nsGlobalWindow *win)
 
   nsCOMPtr<nsIURI> uri;
   prin->GetURI(getter_AddRefs(uri));
   if (!uri) {
     printf("No URI, maybe the system principal.\n");
     return;
   }
 
-  nsAutoCString spec;
-  uri->GetSpec(spec);
-  printf("%s\n", spec.get());
+  printf("%s\n", uri->GetSpecOrDefault().get());
 }
 
 void
 DumpString(const nsAString &str)
 {
   printf("%s\n", NS_ConvertUTF16toUTF8(str).get());
 }
 #endif
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -466,25 +466,24 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
     rv = aNode->Clone(nodeInfo, getter_AddRefs(clone));
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (clone->IsElement()) {
       // The cloned node may be a custom element that may require
       // enqueing created callback and prototype swizzling.
       Element* elem = clone->AsElement();
       if (nsContentUtils::IsCustomElementName(nodeInfo->NameAtom())) {
-        elem->OwnerDoc()->SetupCustomElement(elem, nodeInfo->NamespaceID());
+        nsContentUtils::SetupCustomElement(elem);
       } else {
         // Check if node may be custom element by type extension.
         // ex. <button is="x-button">
         nsAutoString extension;
         if (elem->GetAttr(kNameSpaceID_None, nsGkAtoms::is, extension) &&
             !extension.IsEmpty()) {
-          elem->OwnerDoc()->SetupCustomElement(elem, nodeInfo->NamespaceID(),
-                                               &extension);
+          nsContentUtils::SetupCustomElement(elem, &extension);
         }
       }
     }
 
     if (aParent) {
       // If we're cloning we need to insert the cloned children into the cloned
       // parent.
       rv = aParent->AppendChildTo(static_cast<nsIContent*>(clone.get()),
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -1134,20 +1134,18 @@ nsObjectLoadingContent::OnStartRequest(n
   bool success = IsSuccessfulRequest(aRequest, &status);
 
   if (status == NS_ERROR_BLOCKED_URI) {
     nsCOMPtr<nsIConsoleService> console(
       do_GetService("@mozilla.org/consoleservice;1"));
     if (console) {
       nsCOMPtr<nsIURI> uri;
       chan->GetURI(getter_AddRefs(uri));
-      nsAutoCString spec;
-      uri->GetSpec(spec);
       nsString message = NS_LITERAL_STRING("Blocking ") +
-        NS_ConvertASCIItoUTF16(spec.get()) +
+        NS_ConvertASCIItoUTF16(uri->GetSpecOrDefault().get()) +
         NS_LITERAL_STRING(" since it was found on an internal Firefox blocklist.");
       console->LogStringMessage(message.get());
     }
     Telemetry::Accumulate(Telemetry::PLUGIN_BLOCKED_FOR_STABILITY, 1);
     return NS_ERROR_FAILURE;
   } else if (status == NS_ERROR_TRACKING_URI) {
     return NS_ERROR_FAILURE;
   } else {
@@ -1644,22 +1642,18 @@ nsObjectLoadingContent::CheckLoadPolicy(
                                           thisContent,
                                           mContentType,
                                           nullptr, //extra
                                           aContentPolicy,
                                           nsContentUtils::GetContentPolicy(),
                                           nsContentUtils::GetSecurityManager());
   NS_ENSURE_SUCCESS(rv, false);
   if (NS_CP_REJECTED(*aContentPolicy)) {
-    nsAutoCString uri;
-    nsAutoCString baseUri;
-    mURI->GetSpec(uri);
-    mURI->GetSpec(baseUri);
-    LOG(("OBJLC [%p]: Content policy denied load of %s (base %s)",
-         this, uri.get(), baseUri.get()));
+    LOG(("OBJLC [%p]: Content policy denied load of %s",
+         this, mURI->GetSpecOrDefault().get()));
     return false;
   }
 
   return true;
 }
 
 bool
 nsObjectLoadingContent::CheckProcessPolicy(int16_t *aContentPolicy)
--- a/dom/base/nsPlainTextSerializer.cpp
+++ b/dom/base/nsPlainTextSerializer.cpp
@@ -108,17 +108,17 @@ nsPlainTextSerializer::nsPlainTextSerial
 
   mIgnoredChildNodeLevel = 0;
 }
 
 nsPlainTextSerializer::~nsPlainTextSerializer()
 {
   delete[] mTagStack;
   delete[] mOLStack;
-  NS_WARN_IF_FALSE(mHeadLevel == 0, "Wrong head level!");
+  NS_WARNING_ASSERTION(mHeadLevel == 0, "Wrong head level!");
 }
 
 NS_IMPL_ISUPPORTS(nsPlainTextSerializer,
                   nsIContentSerializer)
 
 
 NS_IMETHODIMP 
 nsPlainTextSerializer::Init(uint32_t aFlags, uint32_t aWrapColumn,
--- a/dom/base/nsRange.cpp
+++ b/dom/base/nsRange.cpp
@@ -3367,17 +3367,17 @@ enum TreeTraversalState {
 static int8_t
 GetRequiredInnerTextLineBreakCount(nsIFrame* aFrame)
 {
   if (aFrame->GetContent()->IsHTMLElement(nsGkAtoms::p)) {
     return 2;
   }
   const nsStyleDisplay* styleDisplay = aFrame->StyleDisplay();
   if (styleDisplay->IsBlockOutside(aFrame) ||
-      styleDisplay->mDisplay == NS_STYLE_DISPLAY_TABLE_CAPTION) {
+      styleDisplay->mDisplay == StyleDisplay::TableCaption) {
     return 1;
   }
   return 0;
 }
 
 static bool
 IsLastCellOfRow(nsIFrame* aFrame)
 {
@@ -3484,27 +3484,29 @@ nsRange::GetInnerTextNoFlush(DOMString& 
     if (currentNode == endNode && currentState == endState) {
       break;
     }
     if (isVisibleAndNotReplaced) {
       if (currentNode->IsHTMLElement(nsGkAtoms::br)) {
         result.Append('\n');
       }
       switch (f->StyleDisplay()->mDisplay) {
-      case NS_STYLE_DISPLAY_TABLE_CELL:
+      case StyleDisplay::TableCell:
         if (!IsLastCellOfRow(f)) {
           result.Append('\t');
         }
         break;
-      case NS_STYLE_DISPLAY_TABLE_ROW:
+      case StyleDisplay::TableRow:
         if (!IsLastRowOfRowGroup(f) ||
             !IsLastNonemptyRowGroupOfTable(f->GetParent())) {
           result.Append('\n');
         }
         break;
+      default:
+        break; // Do nothing
       }
       result.AddRequiredLineBreakCount(GetRequiredInnerTextLineBreakCount(f));
     }
     nsIContent* next = currentNode->GetNextSibling();
     if (next) {
       currentNode = next;
       currentState = AT_NODE;
     } else {
--- a/dom/base/nsScriptLoader.cpp
+++ b/dom/base/nsScriptLoader.cpp
@@ -1913,16 +1913,18 @@ nsScriptLoader::ProcessRequest(nsScriptL
 
   nsCOMPtr<nsIScriptElement> oldParserInsertedScript;
   uint32_t parserCreated = aRequest->mElement->GetParserCreated();
   if (parserCreated) {
     oldParserInsertedScript = mCurrentParserInsertedScript;
     mCurrentParserInsertedScript = aRequest->mElement;
   }
 
+  aRequest->mElement->BeginEvaluating();
+
   FireScriptAvailable(NS_OK, aRequest);
 
   // The window may have gone away by this point, in which case there's no point
   // in trying to run the script.
   nsCOMPtr<nsIDocument> master = mDocument->MasterDocument();
   {
     // Try to perform a microtask checkpoint
     nsAutoMicroTask mt;
@@ -1943,31 +1945,31 @@ nsScriptLoader::ProcessRequest(nsScriptL
     runScript = false;
   }
 
   nsresult rv = NS_OK;
   if (runScript) {
     if (doc) {
       doc->BeginEvaluatingExternalScript();
     }
-    aRequest->mElement->BeginEvaluating();
     rv = EvaluateScript(aRequest);
-    aRequest->mElement->EndEvaluating();
     if (doc) {
       doc->EndEvaluatingExternalScript();
     }
 
     nsContentUtils::DispatchTrustedEvent(scriptElem->OwnerDoc(),
                                          scriptElem,
                                          NS_LITERAL_STRING("afterscriptexecute"),
                                          true, false);
   }
 
   FireScriptEvaluated(rv, aRequest);
 
+  aRequest->mElement->EndEvaluating();
+
   if (parserCreated) {
     mCurrentParserInsertedScript = oldParserInsertedScript;
   }
 
   if (aRequest->mOffThreadToken) {
     // The request was parsed off-main-thread, but the result of the off
     // thread parse was not actually needed to process the request
     // (disappearing window, some other error, ...). Finish the
--- a/dom/base/nsWindowMemoryReporter.cpp
+++ b/dom/base/nsWindowMemoryReporter.cpp
@@ -165,18 +165,17 @@ static void
 AppendWindowURI(nsGlobalWindow *aWindow, nsACString& aStr, bool aAnonymize)
 {
   nsCOMPtr<nsIURI> uri = GetWindowURI(aWindow);
 
   if (uri) {
     if (aAnonymize && !aWindow->IsChromeWindow()) {
       aStr.AppendPrintf("<anonymized-%llu>", aWindow->WindowID());
     } else {
-      nsCString spec;
-      uri->GetSpec(spec);
+      nsCString spec = uri->GetSpecOrDefault();
 
       // A hack: replace forward slashes with '\\' so they aren't
       // treated as path separators.  Users of the reporters
       // (such as about:memory) have to undo this change.
       spec.ReplaceChar('/', '\\');
 
       aStr += spec;
     }
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -4474,19 +4474,16 @@ def getJSToNativeConversionInfo(type, de
 
     def incrementNestingLevel():
         if nestingLevel is "":
             return 1
         return nestingLevel + 1
 
     assert not (isEnforceRange and isClamp)  # These are mutually exclusive
 
-    if type.isArray():
-        raise TypeError("Can't handle array arguments yet")
-
     if type.isSequence():
         assert not isEnforceRange and not isClamp
 
         if failureCode is None:
             notSequence = ('ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "%s");\n'
                            "%s" % (firstCap(sourceDescription), exceptionCode))
         else:
             notSequence = failureCode
@@ -4749,26 +4746,26 @@ def getJSToNativeConversionInfo(type, de
                     CGGeneric("(failed = !%s.TrySetTo%s(cx, ${val}, tryNext, ${passedToJSImpl})) || !tryNext" %
                               (unionArgumentObj, name)))
                 names.append(name)
             interfaceObject = CGWrapper(CGList(interfaceObject, " ||\n"),
                                         pre="done = ", post=";\n\n", reindent=True)
         else:
             interfaceObject = None
 
-        arrayObjectMemberTypes = filter(lambda t: t.isArray() or t.isSequence(), memberTypes)
-        if len(arrayObjectMemberTypes) > 0:
-            assert len(arrayObjectMemberTypes) == 1
-            name = getUnionMemberName(arrayObjectMemberTypes[0])
-            arrayObject = CGGeneric(
+        sequenceObjectMemberTypes = filter(lambda t: t.isSequence(), memberTypes)
+        if len(sequenceObjectMemberTypes) > 0:
+            assert len(sequenceObjectMemberTypes) == 1
+            name = getUnionMemberName(sequenceObjectMemberTypes[0])
+            sequenceObject = CGGeneric(
                 "done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext, ${passedToJSImpl})) || !tryNext;\n" %
                 (unionArgumentObj, name))
             names.append(name)
         else:
-            arrayObject = None
+            sequenceObject = None
 
         dateObjectMemberTypes = filter(lambda t: t.isDate(), memberTypes)
         if len(dateObjectMemberTypes) > 0:
             assert len(dateObjectMemberTypes) == 1
             memberType = dateObjectMemberTypes[0]
             name = getUnionMemberName(memberType)
             dateObject = CGGeneric("%s.SetTo%s(cx, ${val});\n"
                                    "done = true;\n" % (unionArgumentObj, name))
@@ -4820,26 +4817,26 @@ def getJSToNativeConversionInfo(type, de
             object = CGGeneric("if (!%s.SetToObject(cx, &${val}.toObject(), ${passedToJSImpl})) {\n"
                                "%s"
                                "}\n"
                                "done = true;\n" % (unionArgumentObj, indent(exceptionCode)))
             names.append(objectMemberTypes[0].name)
         else:
             object = None
 
-        hasObjectTypes = interfaceObject or arrayObject or dateObject or callbackObject or object or mozMapObject
+        hasObjectTypes = interfaceObject or sequenceObject or dateObject or callbackObject or object or mozMapObject
         if hasObjectTypes:
             # "object" is not distinguishable from other types
-            assert not object or not (interfaceObject or arrayObject or dateObject or callbackObject or mozMapObject)
-            if arrayObject or dateObject or callbackObject:
-                # An object can be both an array object and a callback or
+            assert not object or not (interfaceObject or sequenceObject or dateObject or callbackObject or mozMapObject)
+            if sequenceObject or dateObject or callbackObject:
+                # An object can be both an sequence object and a callback or
                 # dictionary, but we shouldn't have both in the union's members
                 # because they are not distinguishable.
-                assert not (arrayObject and callbackObject)
-                templateBody = CGElseChain([arrayObject, dateObject, callbackObject])
+                assert not (sequenceObject and callbackObject)
+                templateBody = CGElseChain([sequenceObject, dateObject, callbackObject])
             else:
                 templateBody = None
             if interfaceObject:
                 assert not object
                 if templateBody:
                     templateBody = CGIfWrapper(templateBody, "!done")
                 templateBody = CGList([interfaceObject, templateBody])
             else:
@@ -6235,19 +6232,16 @@ def getWrapTemplateForType(type, descrip
             """,
             wrapCall=wrapCall,
             failureCode=failureCode,
             successCode=successCode)
 
     if type is None or type.isVoid():
         return (setUndefined(), True)
 
-    if type.isArray():
-        raise TypeError("Can't handle array return values yet")
-
     if (type.isSequence() or type.isMozMap()) and type.nullable():
         # These are both wrapped in Nullable<>
         recTemplate, recInfall = getWrapTemplateForType(type.inner, descriptorProvider,
                                                         "%s.Value()" % result, successCode,
                                                         returnsNewObject, exceptionCode,
                                                         typedArraysAreStructs)
         code = fill(
             """
@@ -6647,17 +6641,17 @@ def typeNeedsScopeObject(type, retVal=Fa
                              lambda t: leafTypeNeedsScopeObject(t, retVal))
 
 
 def typeMatchesLambda(type, func):
     if type is None:
         return False
     if type.nullable():
         return typeMatchesLambda(type.inner, func)
-    if type.isSequence() or type.isMozMap() or type.isArray():
+    if type.isSequence() or type.isMozMap():
         return typeMatchesLambda(type.inner, func)
     if type.isUnion():
         return any(typeMatchesLambda(t, func) for t in
                    type.unroll().flatMemberTypes)
     if type.isDictionary():
         return dictionaryMatchesLambda(type.inner, func)
     return func(type)
 
@@ -7833,33 +7827,32 @@ class CGMethodCall(CGThing):
             # And all the overloads that take callbacks
             objectSigs.extend(s for s in possibleSignatures
                               if distinguishingType(s).isCallback())
 
             # And all the overloads that take sequences
             objectSigs.extend(s for s in possibleSignatures
                               if distinguishingType(s).isSequence())
 
-            # Now append all the overloads that take an array or dictionary or
-            # callback interface or MozMap.  There should be only one of these!
+            # Now append all the overloads that take a dictionary or callback
+            # interface or MozMap.  There should be only one of these!
             genericObjectSigs = [
                 s for s in possibleSignatures
-                if (distinguishingType(s).isArray() or
-                    distinguishingType(s).isDictionary() or
+                if (distinguishingType(s).isDictionary() or
                     distinguishingType(s).isMozMap() or
                     distinguishingType(s).isCallbackInterface())]
             assert len(genericObjectSigs) <= 1
             objectSigs.extend(genericObjectSigs)
 
             # There might be more than one thing in objectSigs; we need to check
             # which ones we unwrap to.
             if len(objectSigs) > 0:
                 # Here it's enough to guard on our argument being an object. The
                 # code for unwrapping non-callback interfaces, typed arrays,
-                # sequences, arrays, and Dates will just bail out and move on to
+                # sequences, and Dates will just bail out and move on to
                 # the next overload if the object fails to unwrap correctly,
                 # while "object" accepts any object anyway.  We could even not
                 # do the isObject() check up front here, but in cases where we
                 # have multiple object overloads it makes sense to do it only
                 # once instead of for each overload.  That will also allow the
                 # unwrapping test to skip having to do codegen for the
                 # null-or-undefined case, which we already handled above.
                 caseBody.append(CGGeneric("if (%s.isObject()) {\n" %
@@ -9081,19 +9074,16 @@ class CGMemberJITInfo(CGThing):
     @staticmethod
     def getJSReturnTypeTag(t):
         if t.nullable():
             # Sometimes it might return null, sometimes not
             return "JSVAL_TYPE_UNKNOWN"
         if t.isVoid():
             # No return, every time
             return "JSVAL_TYPE_UNDEFINED"
-        if t.isArray():
-            # No idea yet
-            assert False
         if t.isSequence():
             return "JSVAL_TYPE_OBJECT"
         if t.isMozMap():
             return "JSVAL_TYPE_OBJECT"
         if t.isGeckoInterface():
             return "JSVAL_TYPE_OBJECT"
         if t.isString():
             return "JSVAL_TYPE_STRING"
@@ -9159,19 +9149,16 @@ class CGMemberJITInfo(CGThing):
         return "JSVAL_TYPE_UNKNOWN"
 
     @staticmethod
     def getJSArgType(t):
         assert not t.isVoid()
         if t.nullable():
             # Sometimes it might return null, sometimes not
             return "JSJitInfo::ArgType(JSJitInfo::Null | %s)" % CGMemberJITInfo.getJSArgType(t.inner)
-        if t.isArray():
-            # No idea yet
-            assert False
         if t.isSequence():
             return "JSJitInfo::Object"
         if t.isGeckoInterface():
             return "JSJitInfo::Object"
         if t.isString():
             return "JSJitInfo::String"
         if t.isEnum():
             return "JSJitInfo::String"
@@ -9350,19 +9337,16 @@ class CGEnum(CGThing):
 def getUnionAccessorSignatureType(type, descriptorProvider):
     """
     Returns the types that are used in the getter and setter signatures for
     union types
     """
     # Flat member types have already unwrapped nullables.
     assert not type.nullable()
 
-    if type.isArray():
-        raise TypeError("Can't handle array arguments yet")
-
     if type.isSequence() or type.isMozMap():
         if type.isSequence():
             wrapperType = "Sequence"
         else:
             wrapperType = "MozMap"
         # We don't use the returned template here, so it's OK to just pass no
         # sourceDescription.
         elementInfo = getJSToNativeConversionInfo(type.inner,
@@ -13412,17 +13396,17 @@ class CGBindingRoot(CGThing):
         # Do codegen for all the dictionaries.  We have to be a bit careful
         # here, because we have to generate these in order from least derived
         # to most derived so that class inheritance works out.  We also have to
         # generate members before the dictionary that contains them.
 
         def getDependenciesFromType(type):
             if type.isDictionary():
                 return set([type.unroll().inner])
-            if type.isSequence() or type.isArray():
+            if type.isSequence():
                 return getDependenciesFromType(type.unroll())
             if type.isUnion():
                 return set([type.unroll()])
             return set()
 
         def getDependencies(unionTypeOrDictionary):
             if isinstance(unionTypeOrDictionary, IDLDictionary):
                 deps = set()
@@ -13791,19 +13775,16 @@ class CGNativeMember(ClassMethod):
         """
         The main work of getArgType.  Returns a string type decl, whether this
         is a const ref, as well as whether the type should be wrapped in
         Nullable as needed.
 
         isMember can be false or one of the strings "Sequence", "Variadic",
                  "MozMap"
         """
-        if type.isArray():
-            raise TypeError("Can't handle array arguments yet")
-
         if type.isSequence():
             nullable = type.nullable()
             if nullable:
                 type = type.inner
             elementType = type.inner
             argType = self.getArgType(elementType, False, "Sequence")[0]
             decl = CGTemplatedType("Sequence", argType)
             return decl.define(), True, True
--- a/dom/bindings/Errors.msg
+++ b/dom/bindings/Errors.msg
@@ -21,16 +21,17 @@
  * {X} where X  is an integer representing the argument number that will
  * be replaced with a string value when the error is reported.
  */
 
 MSG_DEF(MSG_INVALID_ENUM_VALUE, 3, JSEXN_TYPEERR, "{0} '{1}' is not a valid value for enumeration {2}.")
 MSG_DEF(MSG_MISSING_ARGUMENTS, 1, JSEXN_TYPEERR, "Not enough arguments to {0}.")
 MSG_DEF(MSG_NOT_OBJECT, 1, JSEXN_TYPEERR, "{0} is not an object.")
 MSG_DEF(MSG_NOT_CALLABLE, 1, JSEXN_TYPEERR, "{0} is not callable.")
+MSG_DEF(MSG_NOT_CONSTRUCTOR, 1, JSEXN_TYPEERR, "{0} is not a constructor.")
 MSG_DEF(MSG_DOES_NOT_IMPLEMENT_INTERFACE, 2, JSEXN_TYPEERR, "{0} does not implement interface {1}.")
 MSG_DEF(MSG_METHOD_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, JSEXN_TYPEERR, "'{0}' called on an object that does not implement interface {1}.")
 MSG_DEF(MSG_METHOD_THIS_UNWRAPPING_DENIED, 1, JSEXN_TYPEERR, "Permission to call '{0}' denied.")
 MSG_DEF(MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 1, JSEXN_TYPEERR, "\"this\" object does not implement interface {0}.")
 MSG_DEF(MSG_NOT_IN_UNION, 2, JSEXN_TYPEERR, "{0} could not be converted to any of: {1}.")
 MSG_DEF(MSG_ILLEGAL_CONSTRUCTOR, 0, JSEXN_TYPEERR, "Illegal constructor.")
 MSG_DEF(MSG_CONSTRUCTOR_WITHOUT_NEW, 1, JSEXN_TYPEERR, "Constructor {0} requires 'new'")
 MSG_DEF(MSG_ENFORCE_RANGE_NON_FINITE, 1, JSEXN_TYPEERR, "Non-finite value is out of range for {0}.")
--- a/dom/bindings/moz.build
+++ b/dom/bindings/moz.build
@@ -139,19 +139,16 @@ FINAL_LIBRARY = 'xul'
 SPHINX_TREES['webidl'] = 'docs'
 SPHINX_PYTHON_PACKAGE_DIRS += ['mozwebidlcodegen']
 
 if CONFIG['MOZ_BUILD_APP'] in ['browser', 'mobile/android', 'xulrunner']:
     # This is needed for Window.webidl
     DEFINES['HAVE_SIDEBAR'] = True
 
 
-if CONFIG['MOZ_SIMPLEPUSH']:
-    DEFINES['MOZ_SIMPLEPUSH'] = True
-
 PYTHON_UNIT_TESTS += [
     'mozwebidlcodegen/test/test_mozwebidlcodegen.py',
 ]
 
 if CONFIG['GNU_CXX']:
     CXXFLAGS += ['-Wno-error=shadow']
 
 if CONFIG['COMPILE_ENVIRONMENT']:
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -1851,17 +1851,16 @@ class IDLDictionary(IDLObjectWithScope):
                     A list of locations that leads from the type that was passed in
                     the memberType argument, to the dictionary being validated,
                     if the boolean value in the first element is True.
 
                     None, if the boolean value in the first element is False.
             """
 
             if (memberType.nullable() or
-                memberType.isArray() or
                 memberType.isSequence() or
                 memberType.isMozMap()):
                 return typeContainsDictionary(memberType.inner, dictionary)
 
             if memberType.isDictionary():
                 if memberType.inner == dictionary:
                     return (True, [memberType.location])
 
@@ -1974,18 +1973,17 @@ class IDLType(IDLObject):
         'void',
         # Funny stuff
         'interface',
         'dictionary',
         'enum',
         'callback',
         'union',
         'sequence',
-        'mozmap',
-        'array'
+        'mozmap'
         )
 
     def __init__(self, location, name):
         IDLObject.__init__(self, location)
         self.name = name
         self.builtin = False
 
     def __eq__(self, other):
@@ -2028,19 +2026,16 @@ class IDLType(IDLObject):
         return self.name == "Void"
 
     def isSequence(self):
         return False
 
     def isMozMap(self):
         return False
 
-    def isArray(self):
-        return False
-
     def isArrayBuffer(self):
         return False
 
     def isArrayBufferView(self):
         return False
 
     def isSharedArrayBuffer(self):
         return False
@@ -2256,19 +2251,16 @@ class IDLNullableType(IDLParameterizedTy
         return False
 
     def isSequence(self):
         return self.inner.isSequence()
 
     def isMozMap(self):
         return self.inner.isMozMap()
 
-    def isArray(self):
-        return self.inner.isArray()
-
     def isArrayBuffer(self):
         return self.inner.isArrayBuffer()
 
     def isArrayBufferView(self):
         return self.inner.isArrayBufferView()
 
     def isSharedArrayBuffer(self):
         return self.inner.isSharedArrayBuffer()
@@ -2361,19 +2353,16 @@ class IDLSequenceType(IDLParameterizedTy
         return False
 
     def isVoid(self):
         return False
 
     def isSequence(self):
         return True
 
-    def isArray(self):
-        return False
-
     def isDictionary(self):
         return False
 
     def isInterface(self):
         return False
 
     def isEnum(self):
         return False
@@ -2568,116 +2557,16 @@ class IDLUnionType(IDLType):
     def hasPossiblyEmptyDictionaryType(self):
         return (self._dictionaryType is not None and
                 self._dictionaryType.inner.canBeEmpty())
 
     def _getDependentObjects(self):
         return set(self.memberTypes)
 
 
-class IDLArrayType(IDLType):
-    def __init__(self, location, parameterType):
-        assert not parameterType.isVoid()
-        if parameterType.isSequence():
-            raise WebIDLError("Array type cannot parameterize over a sequence type",
-                              [location])
-        if parameterType.isMozMap():
-            raise WebIDLError("Array type cannot parameterize over a MozMap type",
-                              [location])
-        if parameterType.isDictionary():
-            raise WebIDLError("Array type cannot parameterize over a dictionary type",
-                              [location])
-
-        IDLType.__init__(self, location, parameterType.name)
-        self.inner = parameterType
-        self.builtin = False
-
-    def __eq__(self, other):
-        return isinstance(other, IDLArrayType) and self.inner == other.inner
-
-    def __str__(self):
-        return self.inner.__str__() + "Array"
-
-    def nullable(self):
-        return False
-
-    def isPrimitive(self):
-        return False
-
-    def isString(self):
-        return False
-
-    def isByteString(self):
-        return False
-
-    def isDOMString(self):
-        return False
-
-    def isUSVString(self):
-        return False
-
-    def isVoid(self):
-        return False
-
-    def isSequence(self):
-        assert not self.inner.isSequence()
-        return False
-
-    def isArray(self):
-        return True
-
-    def isDictionary(self):
-        assert not self.inner.isDictionary()
-        return False
-
-    def isInterface(self):
-        return False
-
-    def isEnum(self):
-        return False
-
-    def tag(self):
-        return IDLType.Tags.array
-
-    def resolveType(self, parentScope):
-        assert isinstance(parentScope, IDLScope)
-        self.inner.resolveType(parentScope)
-
-    def isComplete(self):
-        return self.inner.isComplete()
-
-    def complete(self, scope):
-        self.inner = self.inner.complete(scope)
-        self.name = self.inner.name
-
-        if self.inner.isDictionary():
-            raise WebIDLError("Array type must not contain "
-                              "dictionary as element type.",
-                              [self.inner.location])
-
-        assert not self.inner.isSequence()
-
-        return self
-
-    def unroll(self):
-        return self.inner.unroll()
-
-    def isDistinguishableFrom(self, other):
-        if other.isPromise():
-            return False
-        if other.isUnion():
-            # Just forward to the union; it'll deal
-            return other.isDistinguishableFrom(self)
-        return (other.isPrimitive() or other.isString() or other.isEnum() or
-                other.isDate() or other.isNonCallbackInterface())
-
-    def _getDependentObjects(self):
-        return self.inner._getDependentObjects()
-
-
 class IDLTypedefType(IDLType):
     def __init__(self, location, innerType, name):
         IDLType.__init__(self, location, name)
         self.inner = innerType
         self.builtin = False
 
     def __eq__(self, other):
         return isinstance(other, IDLTypedefType) and self.inner == other.inner
@@ -2713,19 +2602,16 @@ class IDLTypedefType(IDLType):
         return self.inner.isVoid()
 
     def isSequence(self):
         return self.inner.isSequence()
 
     def isMozMap(self):
         return self.inner.isMozMap()
 
-    def isArray(self):
-        return self.inner.isArray()
-
     def isDictionary(self):
         return self.inner.isDictionary()
 
     def isArrayBuffer(self):
         return self.inner.isArrayBuffer()
 
     def isArrayBufferView(self):
         return self.inner.isArrayBufferView()
@@ -2831,19 +2717,16 @@ class IDLWrapperType(IDLType):
         return False
 
     def isVoid(self):
         return False
 
     def isSequence(self):
         return False
 
-    def isArray(self):
-        return False
-
     def isDictionary(self):
         return isinstance(self.inner, IDLDictionary)
 
     def isInterface(self):
         return (isinstance(self.inner, IDLInterface) or
                 isinstance(self.inner, IDLExternalInterface))
 
     def isCallbackInterface(self):
@@ -2900,18 +2783,17 @@ class IDLWrapperType(IDLType):
             return False
         if other.isUnion():
             # Just forward to the union; it'll deal
             return other.isDistinguishableFrom(self)
         assert self.isInterface() or self.isEnum() or self.isDictionary()
         if self.isEnum():
             return (other.isPrimitive() or other.isInterface() or other.isObject() or
                     other.isCallback() or other.isDictionary() or
-                    other.isSequence() or other.isMozMap() or other.isArray() or
-                    other.isDate())
+                    other.isSequence() or other.isMozMap() or other.isDate())
         if self.isDictionary() and other.nullable():
             return False
         if (other.isPrimitive() or other.isString() or other.isEnum() or
             other.isDate() or other.isSequence()):
             return True
         if self.isDictionary():
             return other.isNonCallbackInterface()
 
@@ -2923,17 +2805,17 @@ class IDLWrapperType(IDLType):
             assert self.isGeckoInterface() and other.isGeckoInterface()
             if self.inner.isExternal() or other.unroll().inner.isExternal():
                 return self != other
             return (len(self.inner.interfacesBasedOnSelf &
                         other.unroll().inner.interfacesBasedOnSelf) == 0 and
                     (self.isNonCallbackInterface() or
                      other.isNonCallbackInterface()))
         if (other.isDictionary() or other.isCallback() or
-            other.isMozMap() or other.isArray()):
+            other.isMozMap()):
             return self.isNonCallbackInterface()
 
         # Not much else |other| can be
         assert other.isObject()
         return False
 
     def isExposedInAllOf(self, exposureSet):
         if not self.isInterface():
@@ -3133,49 +3015,45 @@ class IDLBuiltinType(IDLType):
             return False
         if other.isUnion():
             # Just forward to the union; it'll deal
             return other.isDistinguishableFrom(self)
         if self.isBoolean():
             return (other.isNumeric() or other.isString() or other.isEnum() or
                     other.isInterface() or other.isObject() or
                     other.isCallback() or other.isDictionary() or
-                    other.isSequence() or other.isMozMap() or other.isArray() or
-                    other.isDate())
+                    other.isSequence() or other.isMozMap() or other.isDate())
         if self.isNumeric():
             return (other.isBoolean() or other.isString() or other.isEnum() or
                     other.isInterface() or other.isObject() or
                     other.isCallback() or other.isDictionary() or
-                    other.isSequence() or other.isMozMap() or other.isArray() or
-                    other.isDate())
+                    other.isSequence() or other.isMozMap() or other.isDate())
         if self.isString():
             return (other.isPrimitive() or other.isInterface() or
                     other.isObject() or
                     other.isCallback() or other.isDictionary() or
-                    other.isSequence() or other.isMozMap() or other.isArray() or
-                    other.isDate())
+                    other.isSequence() or other.isMozMap() or other.isDate())
         if self.isAny():
             # Can't tell "any" apart from anything
             return False
         if self.isObject():
             return other.isPrimitive() or other.isString() or other.isEnum()
         if self.isDate():
             return (other.isPrimitive() or other.isString() or other.isEnum() or
                     other.isInterface() or other.isCallback() or
                     other.isDictionary() or other.isSequence() or
-                    other.isMozMap() or other.isArray())
+                    other.isMozMap())
         if self.isVoid():
             return not other.isVoid()
         # Not much else we could be!
         assert self.isSpiderMonkeyInterface()
         # Like interfaces, but we know we're not a callback
         return (other.isPrimitive() or other.isString() or other.isEnum() or
                 other.isCallback() or other.isDictionary() or
-                other.isSequence() or other.isMozMap() or other.isArray() or
-                other.isDate() or
+                other.isSequence() or other.isMozMap() or other.isDate() or
                 (other.isInterface() and (
                  # ArrayBuffer is distinguishable from everything
                  # that's not an ArrayBuffer or a callback interface
                  (self.isArrayBuffer() and not other.isArrayBuffer()) or
                  (self.isSharedArrayBuffer() and not other.isSharedArrayBuffer()) or
                  # ArrayBufferView is distinguishable from everything
                  # that's not an ArrayBufferView or typed array.
                  (self.isArrayBufferView() and not other.isArrayBufferView() and
@@ -4591,22 +4469,16 @@ class IDLMethod(IDLInterfaceMember, IDLS
         'Getter',
         'Setter',
         'Creator',
         'Deleter',
         'LegacyCaller',
         base=IDLInterfaceMember.Special
     )
 
-    TypeSuffixModifier = enum(
-        'None',
-        'QMark',
-        'Brackets'
-    )
-
     NamedOrIndexed = enum(
         'Neither',
         'Named',
         'Indexed'
     )
 
     def __init__(self, location, identifier, returnType, arguments,
                  static=False, getter=False, setter=False, creator=False,
@@ -6398,128 +6270,114 @@ class Parser(Tokenizer):
     def p_TypeSingleType(self, p):
         """
             Type : SingleType
         """
         p[0] = p[1]
 
     def p_TypeUnionType(self, p):
         """
-            Type : UnionType TypeSuffix
-        """
-        p[0] = self.handleModifiers(p[1], p[2])
+            Type : UnionType Null
+        """
+        p[0] = self.handleNullable(p[1], p[2])
 
     def p_SingleTypeNonAnyType(self, p):
         """
             SingleType : NonAnyType
         """
         p[0] = p[1]
 
     def p_SingleTypeAnyType(self, p):
         """
-            SingleType : ANY TypeSuffixStartingWithArray
-        """
-        p[0] = self.handleModifiers(BuiltinTypes[IDLBuiltinType.Types.any], p[2])
+            SingleType : ANY
+        """
+        p[0] = BuiltinTypes[IDLBuiltinType.Types.any]
 
     def p_UnionType(self, p):
         """
             UnionType : LPAREN UnionMemberType OR UnionMemberType UnionMemberTypes RPAREN
         """
         types = [p[2], p[4]]
         types.extend(p[5])
         p[0] = IDLUnionType(self.getLocation(p, 1), types)
 
     def p_UnionMemberTypeNonAnyType(self, p):
         """
             UnionMemberType : NonAnyType
         """
         p[0] = p[1]
 
-    def p_UnionMemberTypeArrayOfAny(self, p):
-        """
-            UnionMemberTypeArrayOfAny : ANY LBRACKET RBRACKET
-        """
-        p[0] = IDLArrayType(self.getLocation(p, 2),
-                            BuiltinTypes[IDLBuiltinType.Types.any])
-
     def p_UnionMemberType(self, p):
         """
-            UnionMemberType : UnionType TypeSuffix
-                            | UnionMemberTypeArrayOfAny TypeSuffix
-        """
-        p[0] = self.handleModifiers(p[1], p[2])
+            UnionMemberType : UnionType Null
+        """
+        p[0] = self.handleNullable(p[1], p[2])
 
     def p_UnionMemberTypes(self, p):
         """
             UnionMemberTypes : OR UnionMemberType UnionMemberTypes
         """
         p[0] = [p[2]]
         p[0].extend(p[3])
 
     def p_UnionMemberTypesEmpty(self, p):
         """
             UnionMemberTypes :
         """
         p[0] = []
 
     def p_NonAnyType(self, p):
         """
-            NonAnyType : PrimitiveOrStringType TypeSuffix
-                       | ARRAYBUFFER TypeSuffix
-                       | SHAREDARRAYBUFFER TypeSuffix
-                       | OBJECT TypeSuffix
+            NonAnyType : PrimitiveOrStringType Null
+                       | ARRAYBUFFER Null
+                       | SHAREDARRAYBUFFER Null
+                       | OBJECT Null
         """
         if p[1] == "object":
             type = BuiltinTypes[IDLBuiltinType.Types.object]
         elif p[1] == "ArrayBuffer":
             type = BuiltinTypes[IDLBuiltinType.Types.ArrayBuffer]
         elif p[1] == "SharedArrayBuffer":
             type = BuiltinTypes[IDLBuiltinType.Types.SharedArrayBuffer]
         else:
             type = BuiltinTypes[p[1]]
 
-        p[0] = self.handleModifiers(type, p[2])
+        p[0] = self.handleNullable(type, p[2])
 
     def p_NonAnyTypeSequenceType(self, p):
         """
             NonAnyType : SEQUENCE LT Type GT Null
         """
         innerType = p[3]
         type = IDLSequenceType(self.getLocation(p, 1), innerType)
-        if p[5]:
-            type = IDLNullableType(self.getLocation(p, 5), type)
-        p[0] = type
+        p[0] = self.handleNullable(type, p[5])
 
     # Note: Promise<void> is allowed, so we want to parametrize on
     # ReturnType, not Type.  Also, we want this to end up picking up
     # the Promise interface for now, hence the games with IDLUnresolvedType.
     def p_NonAnyTypePromiseType(self, p):
         """
             NonAnyType : PROMISE LT ReturnType GT Null
         """
         innerType = p[3]
         promiseIdent = IDLUnresolvedIdentifier(self.getLocation(p, 1), "Promise")
         type = IDLUnresolvedType(self.getLocation(p, 1), promiseIdent, p[3])
-        if p[5]:
-            type = IDLNullableType(self.getLocation(p, 5), type)
-        p[0] = type
+        p[0] = self.handleNullable(type, p[5])
 
     def p_NonAnyTypeMozMapType(self, p):
         """
             NonAnyType : MOZMAP LT Type GT Null
         """
         innerType = p[3]
         type = IDLMozMapType(self.getLocation(p, 1), innerType)
-        if p[5]:
-            type = IDLNullableType(self.getLocation(p, 5), type)
-        p[0] = type
+        p[0] = self.handleNullable(type, p[5])
 
     def p_NonAnyTypeScopedName(self, p):
         """
-            NonAnyType : ScopedName TypeSuffix
+            NonAnyType : ScopedName Null
         """
         assert isinstance(p[1], IDLUnresolvedIdentifier)
 
         if p[1].name == "Promise":
             raise WebIDLError("Promise used without saying what it's "
                               "parametrized over",
                               [self.getLocation(p, 1)])
 
@@ -6531,50 +6389,46 @@ class Parser(Tokenizer):
                 assert not obj.isType()
                 if obj.isTypedef():
                     type = IDLTypedefType(self.getLocation(p, 1), obj.innerType,
                                           obj.identifier.name)
                 elif obj.isCallback() and not obj.isInterface():
                     type = IDLCallbackType(self.getLocation(p, 1), obj)
                 else:
                     type = IDLWrapperType(self.getLocation(p, 1), p[1])
-                p[0] = self.handleModifiers(type, p[2])
+                p[0] = self.handleNullable(type, p[2])
                 return
         except:
             pass
 
         type = IDLUnresolvedType(self.getLocation(p, 1), p[1])
-        p[0] = self.handleModifiers(type, p[2])
+        p[0] = self.handleNullable(type, p[2])
 
     def p_NonAnyTypeDate(self, p):
         """
-            NonAnyType : DATE TypeSuffix
-        """
-        p[0] = self.handleModifiers(BuiltinTypes[IDLBuiltinType.Types.date],
-                                    p[2])
+            NonAnyType : DATE Null
+        """
+        p[0] = self.handleNullable(BuiltinTypes[IDLBuiltinType.Types.date],
+                                   p[2])
 
     def p_ConstType(self, p):
         """
             ConstType : PrimitiveOrStringType Null
         """
         type = BuiltinTypes[p[1]]
-        if p[2]:
-            type = IDLNullableType(self.getLocation(p, 1), type)
-        p[0] = type
+        p[0] = self.handleNullable(type, p[2])
 
     def p_ConstTypeIdentifier(self, p):
         """
             ConstType : IDENTIFIER Null
         """
         identifier = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1])
 
         type = IDLUnresolvedType(self.getLocation(p, 1), identifier)
-        if p[2]:
-            type = IDLNullableType(self.getLocation(p, 1), type)
-        p[0] = type
+        p[0] = self.handleNullable(type, p[2])
 
     def p_PrimitiveOrStringTypeUint(self, p):
         """
             PrimitiveOrStringType : UnsignedIntegerType
         """
         p[0] = p[1]
 
     def p_PrimitiveOrStringTypeBoolean(self, p):
@@ -6672,58 +6526,25 @@ class Parser(Tokenizer):
         p[0] = True
 
     def p_OptionalLongEmpty(self, p):
         """
             OptionalLong :
         """
         p[0] = False
 
-    def p_TypeSuffixBrackets(self, p):
-        """
-            TypeSuffix : LBRACKET RBRACKET TypeSuffix
-        """
-        p[0] = [(IDLMethod.TypeSuffixModifier.Brackets, self.getLocation(p, 1))]
-        p[0].extend(p[3])
-
-    def p_TypeSuffixQMark(self, p):
-        """
-            TypeSuffix : QUESTIONMARK TypeSuffixStartingWithArray
-        """
-        p[0] = [(IDLMethod.TypeSuffixModifier.QMark, self.getLocation(p, 1))]
-        p[0].extend(p[2])
-
-    def p_TypeSuffixEmpty(self, p):
-        """
-            TypeSuffix :
-        """
-        p[0] = []
-
-    def p_TypeSuffixStartingWithArray(self, p):
-        """
-            TypeSuffixStartingWithArray : LBRACKET RBRACKET TypeSuffix
-        """
-        p[0] = [(IDLMethod.TypeSuffixModifier.Brackets, self.getLocation(p, 1))]
-        p[0].extend(p[3])
-
-    def p_TypeSuffixStartingWithArrayEmpty(self, p):
-        """
-            TypeSuffixStartingWithArray :
-        """
-        p[0] = []
-
     def p_Null(self, p):
         """
             Null : QUESTIONMARK
                  |
         """
         if len(p) > 1:
-            p[0] = True
+            p[0] = self.getLocation(p, 1)
         else:
-            p[0] = False
+            p[0] = None
 
     def p_ReturnTypeType(self, p):
         """
             ReturnType : Type
         """
         p[0] = p[1]
 
     def p_ReturnTypeVoid(self, p):
@@ -6871,25 +6692,19 @@ class Parser(Tokenizer):
 
         # xrange omits the last value.
         for x in xrange(IDLBuiltinType.Types.ArrayBuffer, IDLBuiltinType.Types.Float64Array + 1):
             builtin = BuiltinTypes[x]
             name = builtin.name
             typedef = IDLTypedef(BuiltinLocation("<builtin type>"), scope, builtin, name)
 
     @ staticmethod
-    def handleModifiers(type, modifiers):
-        for (modifier, modifierLocation) in modifiers:
-            assert (modifier == IDLMethod.TypeSuffixModifier.QMark or
-                    modifier == IDLMethod.TypeSuffixModifier.Brackets)
-
-            if modifier == IDLMethod.TypeSuffixModifier.QMark:
-                type = IDLNullableType(modifierLocation, type)
-            elif modifier == IDLMethod.TypeSuffixModifier.Brackets:
-                type = IDLArrayType(modifierLocation, type)
+    def handleNullable(type, questionMarkLocation):
+        if questionMarkLocation is not None:
+            type = IDLNullableType(questionMarkLocation, type)
 
         return type
 
     def parse(self, t, filename=None):
         self.lexer.input(t)
 
         # for tok in iter(self.lexer.token, None):
         #    print tok
deleted file mode 100644
--- a/dom/bindings/parser/tests/test_array.py
+++ /dev/null
@@ -1,18 +0,0 @@
-def WebIDLTest(parser, harness):
-    threw = False
-    try:
-        parser.parse("""
-          dictionary Foo {
-            short a;
-          };
-
-          dictionary Foo1 {
-            Foo[] b;
-          };
-        """)
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Array must not contain dictionary "
-                      "as element type.")
deleted file mode 100644
--- a/dom/bindings/parser/tests/test_array_of_interface.py
+++ /dev/null
@@ -1,13 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
-    parser.parse("""
-      interface A {
-        attribute long a;
-      };
-
-      interface B {
-        attribute A[] b;
-      };
-    """);
-    parser.finish()
--- a/dom/bindings/parser/tests/test_arraybuffer.py
+++ b/dom/bindings/parser/tests/test_arraybuffer.py
@@ -1,45 +1,45 @@
 import WebIDL
 
 def WebIDLTest(parser, harness):
     parser.parse("""
         interface TestArrayBuffer {
           attribute ArrayBuffer bufferAttr;
-          void bufferMethod(ArrayBuffer arg1, ArrayBuffer? arg2, ArrayBuffer[] arg3, sequence<ArrayBuffer> arg4);
+          void bufferMethod(ArrayBuffer arg1, ArrayBuffer? arg2, sequence<ArrayBuffer> arg3);
 
           attribute ArrayBufferView viewAttr;
-          void viewMethod(ArrayBufferView arg1, ArrayBufferView? arg2, ArrayBufferView[] arg3, sequence<ArrayBufferView> arg4);
+          void viewMethod(ArrayBufferView arg1, ArrayBufferView? arg2, sequence<ArrayBufferView> arg3);
 
           attribute Int8Array int8ArrayAttr;
-          void int8ArrayMethod(Int8Array arg1, Int8Array? arg2, Int8Array[] arg3, sequence<Int8Array> arg4);
+          void int8ArrayMethod(Int8Array arg1, Int8Array? arg2, sequence<Int8Array> arg3);
 
           attribute Uint8Array uint8ArrayAttr;
-          void uint8ArrayMethod(Uint8Array arg1, Uint8Array? arg2, Uint8Array[] arg3, sequence<Uint8Array> arg4);
+          void uint8ArrayMethod(Uint8Array arg1, Uint8Array? arg2, sequence<Uint8Array> arg3);
 
           attribute Uint8ClampedArray uint8ClampedArrayAttr;
-          void uint8ClampedArrayMethod(Uint8ClampedArray arg1, Uint8ClampedArray? arg2, Uint8ClampedArray[] arg3, sequence<Uint8ClampedArray> arg4);
+          void uint8ClampedArrayMethod(Uint8ClampedArray arg1, Uint8ClampedArray? arg2, sequence<Uint8ClampedArray> arg3);
 
           attribute Int16Array int16ArrayAttr;
-          void int16ArrayMethod(Int16Array arg1, Int16Array? arg2, Int16Array[] arg3, sequence<Int16Array> arg4);
+          void int16ArrayMethod(Int16Array arg1, Int16Array? arg2, sequence<Int16Array> arg3);
 
           attribute Uint16Array uint16ArrayAttr;
-          void uint16ArrayMethod(Uint16Array arg1, Uint16Array? arg2, Uint16Array[] arg3, sequence<Uint16Array> arg4);
+          void uint16ArrayMethod(Uint16Array arg1, Uint16Array? arg2, sequence<Uint16Array> arg3);
 
           attribute Int32Array int32ArrayAttr;
-          void int32ArrayMethod(Int32Array arg1, Int32Array? arg2, Int32Array[] arg3, sequence<Int32Array> arg4);
+          void int32ArrayMethod(Int32Array arg1, Int32Array? arg2, sequence<Int32Array> arg3);
 
           attribute Uint32Array uint32ArrayAttr;
-          void uint32ArrayMethod(Uint32Array arg1, Uint32Array? arg2, Uint32Array[] arg3, sequence<Uint32Array> arg4);
+          void uint32ArrayMethod(Uint32Array arg1, Uint32Array? arg2, sequence<Uint32Array> arg3);
 
           attribute Float32Array float32ArrayAttr;
-          void float32ArrayMethod(Float32Array arg1, Float32Array? arg2, Float32Array[] arg3, sequence<Float32Array> arg4);
+          void float32ArrayMethod(Float32Array arg1, Float32Array? arg2, sequence<Float32Array> arg3);
 
           attribute Float64Array float64ArrayAttr;
-          void float64ArrayMethod(Float64Array arg1, Float64Array? arg2, Float64Array[] arg3, sequence<Float64Array> arg4);
+          void float64ArrayMethod(Float64Array arg1, Float64Array? arg2, sequence<Float64Array> arg3);
         };
     """)
 
     results = parser.finish()
 
     iface = results[0]
 
     harness.ok(True, "TestArrayBuffer interface parsed without error")
@@ -51,30 +51,27 @@ def WebIDLTest(parser, harness):
         harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Expect an IDLAttribute")
         harness.ok(isinstance(method, WebIDL.IDLMethod), "Expect an IDLMethod")
 
         harness.check(str(attr.type), t, "Expect an ArrayBuffer type")
         harness.ok(attr.type.isSpiderMonkeyInterface(), "Should test as a js interface")
 
         (retType, arguments) = method.signatures()[0]
         harness.ok(retType.isVoid(), "Should have a void return type")
-        harness.check(len(arguments), 4, "Expect 4 arguments")
+        harness.check(len(arguments), 3, "Expect 3 arguments")
 
         harness.check(str(arguments[0].type), t,  "Expect an ArrayBuffer type")
         harness.ok(arguments[0].type.isSpiderMonkeyInterface(), "Should test as a js interface")
 
         harness.check(str(arguments[1].type), t + "OrNull",  "Expect an ArrayBuffer type")
         harness.ok(arguments[1].type.inner.isSpiderMonkeyInterface(), "Should test as a js interface")
 
-        harness.check(str(arguments[2].type), t + "Array",  "Expect an ArrayBuffer type")
+        harness.check(str(arguments[2].type), t + "Sequence",  "Expect an ArrayBuffer type")
         harness.ok(arguments[2].type.inner.isSpiderMonkeyInterface(), "Should test as a js interface")
 
-        harness.check(str(arguments[3].type), t + "Sequence",  "Expect an ArrayBuffer type")
-        harness.ok(arguments[3].type.inner.isSpiderMonkeyInterface(), "Should test as a js interface")
-
 
     checkStuff(members[0],  members[1],  "ArrayBuffer")
     checkStuff(members[2],  members[3],  "ArrayBufferView")
     checkStuff(members[4],  members[5],  "Int8Array")
     checkStuff(members[6],  members[7],  "Uint8Array")
     checkStuff(members[8],  members[9],  "Uint8ClampedArray")
     checkStuff(members[10], members[11], "Int16Array")
     checkStuff(members[12], members[13], "Uint16Array")
--- a/dom/bindings/parser/tests/test_attr.py
+++ b/dom/bindings/parser/tests/test_attr.py
@@ -72,137 +72,33 @@ def WebIDLTest(parser, harness):
           attribute DOMString? str;
           readonly attribute DOMString? rstr;
           attribute object? obj;
           readonly attribute object? robj;
           attribute object? _object;
           attribute float? f;
           readonly attribute float? rf;
         };
-
-        interface TestAttrArray {
-          attribute byte[] b;
-          readonly attribute byte[] rb;
-          attribute octet[] o;
-          readonly attribute octet[] ro;
-          attribute short[] s;
-          readonly attribute short[] rs;
-          attribute unsigned short[] us;
-          readonly attribute unsigned short[] rus;
-          attribute long[] l;
-          readonly attribute long[] rl;
-          attribute unsigned long[] ul;
-          readonly attribute unsigned long[] rul;
-          attribute long long[] ll;
-          readonly attribute long long[] rll;
-          attribute unsigned long long[] ull;
-          readonly attribute unsigned long long[] rull;
-          attribute DOMString[] str;
-          readonly attribute DOMString[] rstr;
-          attribute object[] obj;
-          readonly attribute object[] robj;
-          attribute object[] _object;
-          attribute float[] f;
-          readonly attribute float[] rf;
-        };
-
-        interface TestAttrNullableArray {
-          attribute byte[]? b;
-          readonly attribute byte[]? rb;
-          attribute octet[]? o;
-          readonly attribute octet[]? ro;
-          attribute short[]? s;
-          readonly attribute short[]? rs;
-          attribute unsigned short[]? us;
-          readonly attribute unsigned short[]? rus;
-          attribute long[]? l;
-          readonly attribute long[]? rl;
-          attribute unsigned long[]? ul;
-          readonly attribute unsigned long[]? rul;
-          attribute long long[]? ll;
-          readonly attribute long long[]? rll;
-          attribute unsigned long long[]? ull;
-          readonly attribute unsigned long long[]? rull;
-          attribute DOMString[]? str;
-          readonly attribute DOMString[]? rstr;
-          attribute object[]? obj;
-          readonly attribute object[]? robj;
-          attribute object[]? _object;
-          attribute float[]? f;
-          readonly attribute float[]? rf;
-        };
-
-        interface TestAttrArrayOfNullableTypes {
-          attribute byte?[] b;
-          readonly attribute byte?[] rb;
-          attribute octet?[] o;
-          readonly attribute octet?[] ro;
-          attribute short?[] s;
-          readonly attribute short?[] rs;
-          attribute unsigned short?[] us;
-          readonly attribute unsigned short?[] rus;
-          attribute long?[] l;
-          readonly attribute long?[] rl;
-          attribute unsigned long?[] ul;
-          readonly attribute unsigned long?[] rul;
-          attribute long long?[] ll;
-          readonly attribute long long?[] rll;
-          attribute unsigned long long?[] ull;
-          readonly attribute unsigned long long?[] rull;
-          attribute DOMString?[] str;
-          readonly attribute DOMString?[] rstr;
-          attribute object?[] obj;
-          readonly attribute object?[] robj;
-          attribute object?[] _object;
-          attribute float?[] f;
-          readonly attribute float?[] rf;
-        };
-
-        interface TestAttrNullableArrayOfNullableTypes {
-          attribute byte?[]? b;
-          readonly attribute byte?[]? rb;
-          attribute octet?[]? o;
-          readonly attribute octet?[]? ro;
-          attribute short?[]? s;
-          readonly attribute short?[]? rs;
-          attribute unsigned short?[]? us;
-          readonly attribute unsigned short?[]? rus;
-          attribute long?[]? l;
-          readonly attribute long?[]? rl;
-          attribute unsigned long?[]? ul;
-          readonly attribute unsigned long?[]? rul;
-          attribute long long?[]? ll;
-          readonly attribute long long?[]? rll;
-          attribute unsigned long long?[]? ull;
-          readonly attribute unsigned long long?[]? rull;
-          attribute DOMString?[]? str;
-          readonly attribute DOMString?[]? rstr;
-          attribute object?[]? obj;
-          readonly attribute object?[]? robj;
-          attribute object?[]? _object;
-          attribute float?[]? f;
-          readonly attribute float?[]? rf;
-        };
     """)
 
     results = parser.finish()
 
     def checkAttr(attr, QName, name, type, readonly):
         harness.ok(isinstance(attr, WebIDL.IDLAttribute),
                   "Should be an IDLAttribute")
         harness.ok(attr.isAttr(), "Attr is an Attr")
         harness.ok(not attr.isMethod(), "Attr is not an method")
         harness.ok(not attr.isConst(), "Attr is not a const")
         harness.check(attr.identifier.QName(), QName, "Attr has the right QName")
         harness.check(attr.identifier.name, name, "Attr has the right name")
         harness.check(str(attr.type), type, "Attr has the right type")
         harness.check(attr.readonly, readonly, "Attr's readonly state is correct")
 
     harness.ok(True, "TestAttr interface parsed without error.")
-    harness.check(len(results), 6, "Should be six productions.")
+    harness.check(len(results), 2, "Should be two productions.")
     iface = results[0]
     harness.ok(isinstance(iface, WebIDL.IDLInterface),
                "Should be an IDLInterface")
     harness.check(iface.identifier.QName(), "::TestAttr", "Interface has the right QName")
     harness.check(iface.identifier.name, "TestAttr", "Interface has the right name")
     harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
 
     attrs = iface.members
@@ -223,76 +119,16 @@ def WebIDLTest(parser, harness):
     attrs = iface.members
 
     for i in range(len(attrs)):
         data = testData[i]
         attr = attrs[i]
         (QName, name, type, readonly) = data
         checkAttr(attr, QName % "Nullable", name, type % "OrNull", readonly)
 
-    iface = results[2]
-    harness.ok(isinstance(iface, WebIDL.IDLInterface),
-               "Should be an IDLInterface")
-    harness.check(iface.identifier.QName(), "::TestAttrArray", "Interface has the right QName")
-    harness.check(iface.identifier.name, "TestAttrArray", "Interface has the right name")
-    harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
-
-    attrs = iface.members
-
-    for i in range(len(attrs)):
-        data = testData[i]
-        attr = attrs[i]
-        (QName, name, type, readonly) = data
-        checkAttr(attr, QName % "Array", name, type % "Array", readonly)
-
-    iface = results[3]
-    harness.ok(isinstance(iface, WebIDL.IDLInterface),
-               "Should be an IDLInterface")
-    harness.check(iface.identifier.QName(), "::TestAttrNullableArray", "Interface has the right QName")
-    harness.check(iface.identifier.name, "TestAttrNullableArray", "Interface has the right name")
-    harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
-
-    attrs = iface.members
-
-    for i in range(len(attrs)):
-        data = testData[i]
-        attr = attrs[i]
-        (QName, name, type, readonly) = data
-        checkAttr(attr, QName % "NullableArray", name, type % "ArrayOrNull", readonly)
-
-    iface = results[4]
-    harness.ok(isinstance(iface, WebIDL.IDLInterface),
-               "Should be an IDLInterface")
-    harness.check(iface.identifier.QName(), "::TestAttrArrayOfNullableTypes", "Interface has the right QName")
-    harness.check(iface.identifier.name, "TestAttrArrayOfNullableTypes", "Interface has the right name")
-    harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
-
-    attrs = iface.members
-
-    for i in range(len(attrs)):
-        data = testData[i]
-        attr = attrs[i]
-        (QName, name, type, readonly) = data
-        checkAttr(attr, QName % "ArrayOfNullableTypes", name, type % "OrNullArray", readonly)
-
-    iface = results[5]
-    harness.ok(isinstance(iface, WebIDL.IDLInterface),
-               "Should be an IDLInterface")
-    harness.check(iface.identifier.QName(), "::TestAttrNullableArrayOfNullableTypes", "Interface has the right QName")
-    harness.check(iface.identifier.name, "TestAttrNullableArrayOfNullableTypes", "Interface has the right name")
-    harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
-
-    attrs = iface.members
-
-    for i in range(len(attrs)):
-        data = testData[i]
-        attr = attrs[i]
-        (QName, name, type, readonly) = data
-        checkAttr(attr, QName % "NullableArrayOfNullableTypes", name, type % "OrNullArrayOrNull", readonly)
-
     parser = parser.reset()
     threw = False
     try:
         parser.parse("""
           interface A {
             [SetterThrows] readonly attribute boolean foo;
           };
         """)
--- a/dom/bindings/parser/tests/test_distinguishability.py
+++ b/dom/bindings/parser/tests/test_distinguishability.py
@@ -154,17 +154,17 @@ def WebIDLTest(parser, harness):
                  "boolean?", "DOMString", "ByteString", "Enum", "Enum2",
                  "Interface", "Interface?",
                  "AncestorInterface", "UnrelatedInterface",
                  "ImplementedInterface", "CallbackInterface",
                  "CallbackInterface?", "CallbackInterface2",
                  "object", "Callback", "Callback2", "optional Dict",
                  "optional Dict2", "sequence<long>", "sequence<short>",
                  "MozMap<object>", "MozMap<Dict>", "MozMap<long>",
-                 "long[]", "short[]", "Date", "Date?", "any",
+                 "Date", "Date?", "any",
                  "Promise<any>", "Promise<any>?",
                  "USVString", "ArrayBuffer", "ArrayBufferView", "SharedArrayBuffer",
                  "Uint8Array", "Uint16Array" ]
     # When we can parse Date and RegExp, we need to add them here.
 
     # Try to categorize things a bit to keep list lengths down
     def allBut(list1, list2):
         return [a for a in list1 if a not in list2 and
@@ -182,17 +182,16 @@ def WebIDLTest(parser, harness):
     sharedBufferSourceTypes = ["SharedArrayBuffer"]
     interfaces = [ "Interface", "Interface?", "AncestorInterface",
                    "UnrelatedInterface", "ImplementedInterface" ] + bufferSourceTypes + sharedBufferSourceTypes
     nullables = ["long?", "short?", "boolean?", "Interface?",
                  "CallbackInterface?", "optional Dict", "optional Dict2",
                  "Date?", "any", "Promise<any>?"]
     dates = [ "Date", "Date?" ]
     sequences = [ "sequence<long>", "sequence<short>" ]
-    arrays = [ "long[]", "short[]" ]
     nonUserObjects = nonObjects + interfaces + dates + sequences
     otherObjects = allBut(argTypes, nonUserObjects + ["object"])
     notRelatedInterfaces = (nonObjects + ["UnrelatedInterface"] +
                             otherObjects + dates + sequences + bufferSourceTypes + sharedBufferSourceTypes)
     mozMaps = [ "MozMap<object>", "MozMap<Dict>", "MozMap<long>" ]
 
     # Build a representation of the distinguishability table as a dict
     # of dicts, holding True values where needed, holes elsewhere.
@@ -224,24 +223,22 @@ def WebIDLTest(parser, harness):
     setDistinguishable("CallbackInterface?", allBut(nonUserObjects, nullables))
     setDistinguishable("CallbackInterface2", nonUserObjects)
     setDistinguishable("object", nonObjects)
     setDistinguishable("Callback", nonUserObjects)
     setDistinguishable("Callback2", nonUserObjects)
     setDistinguishable("optional Dict", allBut(nonUserObjects, nullables))
     setDistinguishable("optional Dict2", allBut(nonUserObjects, nullables))
     setDistinguishable("sequence<long>",
-                       allBut(argTypes, sequences + arrays + ["object"]))
+                       allBut(argTypes, sequences + ["object"]))
     setDistinguishable("sequence<short>",
-                       allBut(argTypes, sequences + arrays + ["object"]))
+                       allBut(argTypes, sequences + ["object"]))
     setDistinguishable("MozMap<object>", nonUserObjects)
     setDistinguishable("MozMap<Dict>", nonUserObjects)
     setDistinguishable("MozMap<long>", nonUserObjects)
-    setDistinguishable("long[]", allBut(nonUserObjects, sequences))
-    setDistinguishable("short[]", allBut(nonUserObjects, sequences))
     setDistinguishable("Date", allBut(argTypes, dates + ["object"]))
     setDistinguishable("Date?", allBut(argTypes, dates + nullables + ["object"]))
     setDistinguishable("any", [])
     setDistinguishable("Promise<any>", [])
     setDistinguishable("Promise<any>?", [])
     setDistinguishable("ArrayBuffer", allBut(argTypes, ["ArrayBuffer", "object"]))
     setDistinguishable("ArrayBufferView", allBut(argTypes, ["ArrayBufferView", "Uint8Array", "Uint16Array", "object"]))
     setDistinguishable("Uint8Array", allBut(argTypes, ["ArrayBufferView", "Uint8Array", "object"]))
--- a/dom/bindings/parser/tests/test_method.py
+++ b/dom/bindings/parser/tests/test_method.py
@@ -6,34 +6,33 @@ def WebIDLTest(parser, harness):
           void basic();
           static void basicStatic();
           void basicWithSimpleArgs(boolean arg1, byte arg2, unsigned long arg3);
           boolean basicBoolean();
           static boolean basicStaticBoolean();
           boolean basicBooleanWithSimpleArgs(boolean arg1, byte arg2, unsigned long arg3);
           void optionalArg(optional byte? arg1, optional sequence<byte> arg2);
           void variadicArg(byte?... arg1);
-          void crazyTypes(sequence<long?[]>? arg1, boolean?[][]? arg2);
           object getObject();
           void setObject(object arg1);
           void setAny(any arg1);
           float doFloats(float arg1);
         };
     """)
 
     results = parser.finish()
 
     harness.ok(True, "TestMethods interface parsed without error.")
     harness.check(len(results), 1, "Should be one production.")
     iface = results[0]
     harness.ok(isinstance(iface, WebIDL.IDLInterface),
                "Should be an IDLInterface")
     harness.check(iface.identifier.QName(), "::TestMethods", "Interface has the right QName")
     harness.check(iface.identifier.name, "TestMethods", "Interface has the right name")
-    harness.check(len(iface.members), 13, "Expect 13 members")
+    harness.check(len(iface.members), 12, "Expect 12 members")
 
     methods = iface.members
 
     def checkArgument(argument, QName, name, type, optional, variadic):
         harness.ok(isinstance(argument, WebIDL.IDLArgument),
                    "Should be an IDLArgument")
         harness.check(argument.identifier.QName(), QName, "Argument has the right QName")
         harness.check(argument.identifier.name, name, "Argument has the right name")
@@ -93,32 +92,27 @@ def WebIDLTest(parser, harness):
                 "optionalArg",
        [("Void",
         [("::TestMethods::optionalArg::arg1", "arg1", "ByteOrNull", True, False),
          ("::TestMethods::optionalArg::arg2", "arg2", "ByteSequence", True, False)])])
     checkMethod(methods[7], "::TestMethods::variadicArg",
                 "variadicArg",
        [("Void",
         [("::TestMethods::variadicArg::arg1", "arg1", "ByteOrNull", True, True)])])
-    checkMethod(methods[8], "::TestMethods::crazyTypes",
-                "crazyTypes",
-       [("Void",
-        [("::TestMethods::crazyTypes::arg1", "arg1", "LongOrNullArraySequenceOrNull", False, False),
-         ("::TestMethods::crazyTypes::arg2", "arg2", "BooleanOrNullArrayArrayOrNull", False, False)])])
-    checkMethod(methods[9], "::TestMethods::getObject",
+    checkMethod(methods[8], "::TestMethods::getObject",
                 "getObject", [("Object", [])])
-    checkMethod(methods[10], "::TestMethods::setObject",
+    checkMethod(methods[9], "::TestMethods::setObject",
                 "setObject",
        [("Void",
         [("::TestMethods::setObject::arg1", "arg1", "Object", False, False)])])
-    checkMethod(methods[11], "::TestMethods::setAny",
+    checkMethod(methods[10], "::TestMethods::setAny",
                 "setAny",
        [("Void",
         [("::TestMethods::setAny::arg1", "arg1", "Any", False, False)])])
-    checkMethod(methods[12], "::TestMethods::doFloats",
+    checkMethod(methods[11], "::TestMethods::doFloats",
                 "doFloats",
        [("Float",
         [("::TestMethods::doFloats::arg1", "arg1", "Float", False, False)])])
 
     parser = parser.reset()
     threw = False
     try:
         parser.parse("""
--- a/dom/bindings/parser/tests/test_nullable_equivalency.py
+++ b/dom/bindings/parser/tests/test_nullable_equivalency.py
@@ -48,26 +48,16 @@ def WebIDLTest(parser, harness):
           attribute double  a;
           attribute double? b;
         };
 
         interface TestNullableEquivalency10 {
           attribute object  a;
           attribute object? b;
         };
-
-        interface TestNullableEquivalency11 {
-          attribute double[]  a;
-          attribute double[]? b;
-        };
-
-        interface TestNullableEquivalency12 {
-          attribute TestNullableEquivalency9[]  a;
-          attribute TestNullableEquivalency9[]? b;
-        };
     """)
 
     for decl in parser.finish():
         if decl.isInterface():
             checkEquivalent(decl, harness)
 
 def checkEquivalent(iface, harness):
     type1 = iface.members[0].type
--- a/dom/bindings/parser/tests/test_union.py
+++ b/dom/bindings/parser/tests/test_union.py
@@ -134,19 +134,16 @@ def WebIDLTest(parser, harness):
     interface = testPre + """
         interface TestUnion {
         """
     for (i, type) in enumerate(validUnionTypes):
         interface += string.Template("""
           void method${i}(${type} arg);
           ${type} returnMethod${i}();
           attribute ${type} attr${i};
-          void arrayMethod${i}(${type}[] arg);
-          ${type}[] arrayReturnMethod${i}();
-          attribute ${type}[] arrayAttr${i};
           void optionalMethod${i}(${type}? arg);
         """).substitute(i=i, type=type)
     interface += """
         };
         """
     parser.parse(interface)
     results = parser.finish()
 
--- a/dom/bluetooth/ipc/BluetoothServiceChildProcess.cpp
+++ b/dom/bluetooth/ipc/BluetoothServiceChildProcess.cpp
@@ -23,19 +23,19 @@ BluetoothChild* sBluetoothChild;
 
 inline
 void
 SendRequest(BluetoothReplyRunnable* aRunnable, const Request& aRequest)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aRunnable);
 
-  NS_WARN_IF_FALSE(sBluetoothChild,
-                   "Calling methods on BluetoothServiceChildProcess during "
-                   "shutdown!");
+  NS_WARNING_ASSERTION(
+    sBluetoothChild,
+    "Calling methods on BluetoothServiceChildProcess during shutdown!");
 
   if (sBluetoothChild) {
     BluetoothRequestChild* actor = new BluetoothRequestChild(aRunnable);
     sBluetoothChild->SendPBluetoothRequestConstructor(actor, aRequest);
   }
 }
 
 } // namespace
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -1733,17 +1733,17 @@ CanvasRenderingContext2D::TrySkiaGLTarge
 
   if (!layerManager) {
     return false;
   }
 
   DemoteOldestContextIfNecessary();
   mBufferProvider = nullptr;
 
-#if USE_SKIA_GPU
+#ifdef USE_SKIA_GPU
   SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
   if (!glue || !glue->GetGrContext() || !glue->GetGLContext()) {
     return false;
   }
 
   SurfaceFormat format = GetSurfaceFormat();
   aOutDT = Factory::CreateDrawTargetSkiaWithGrContext(glue->GetGrContext(),
                                                       size, format);
new file mode 100644
--- /dev/null
+++ b/dom/canvas/crashtests/1299062-1.html
@@ -0,0 +1,5 @@
+<canvas id='id0' width='35376.4661501'></canvas>
+<script>
+var ctx=document.getElementById('id0').getContext('2d');
+ctx.getImageData(66,-1,32,87);
+</script>
--- a/dom/canvas/crashtests/crashtests.list
+++ b/dom/canvas/crashtests/crashtests.list
@@ -31,9 +31,10 @@ load 1246775-1.html
 load 1284356-1.html
 load 1284578-1.html
 skip-if(d2d) load 1287515-1.html
 load 1287652-1.html
 load 1288872-1.html
 load 1290628-1.html
 load 1283113-1.html
 load 1286458-1.html
+load 1299062-1.html
 
--- a/dom/canvas/test/webgl-conf/generate-wrappers-and-manifest.py
+++ b/dom/canvas/test/webgl-conf/generate-wrappers-and-manifest.py
@@ -15,18 +15,17 @@ MANIFEST_TEMPLATE_FILE = 'mochitest.ini.
 ERRATA_FILE = 'mochitest-errata.ini'
 DEST_MANIFEST_PATHSTR = 'generated-mochitest.ini'
 
 BASE_TEST_LIST_PATHSTR = 'checkout/00_test_list.txt'
 GENERATED_PATHSTR = 'generated'
 WEBGL2_TEST_MANGLE = '2_'
 PATH_SEP_MANGLING = '__'
 WEBGL2_SKIP_IF_CONDITION = "(os == 'android' || os == 'linux' || " \
-                           "(os == 'win' && os_version == '5.1') || " \
-                           "(os == 'win' && os_version == '6.2'))"
+                           "(os == 'win' && os_version == '5.1'))"
 
 SUPPORT_DIRS = [
     'checkout',
 ]
 
 EXTRA_SUPPORT_FILES = [
     'always-fail.html',
     'iframe-passthrough.css',
--- a/dom/canvas/test/webgl-conf/generated-mochitest.ini
+++ b/dom/canvas/test/webgl-conf/generated-mochitest.ini
@@ -4449,1484 +4449,1494 @@ support-files = always-fail.html
                 checkout/test-guidelines.md
                 checkout/webgl-conformance-tests.html
                 iframe-passthrough.css
                 mochi-single.html
 
 [generated/test_..__always-fail.html]
 fail-if = 1
 [generated/test_2_conformance2__attribs__gl-vertex-attrib-i-render.html]
-skip-if = (os == 'win') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'win') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__attribs__gl-vertex-attrib.html]
-skip-if = (os == 'win') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'win') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__attribs__gl-vertexattribipointer-offsets.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__attribs__gl-vertexattribipointer.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__buffers__bound-buffer-size-change-test.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__buffers__buffer-copying-contents.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__buffers__buffer-copying-restrictions.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__buffers__buffer-overflow-test.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__buffers__buffer-type-restrictions.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__buffers__getBufferSubData.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__buffers__uniform-buffers.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__context__constants-and-properties-2.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__context__context-attributes-depth-stencil-antialias-obeyed.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__context__context-type-test-2.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__context__methods-2.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__extensions__ext-color-buffer-float.html]
-skip-if = (os == 'mac' && debug) || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'mac' && debug) || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__extensions__promoted-extensions-in-shaders.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__extensions__promoted-extensions.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__array-as-return-value.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__array-assign-constructor.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__array-assign.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__array-complex-indexing.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__array-equality.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__array-in-complex-expression.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__array-length-side-effects.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__attrib-location-length-limits.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__compare-structs-containing-arrays.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__const-array-init.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__forbidden-operators.html]
 fail-if = (os == 'mac') || (os == 'win')
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__frag-depth.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__invalid-default-precision.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__loops-with-side-effects.html]
-skip-if = (os == 'win') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'win') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__misplaced-version-directive.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__sampler-no-precision.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__sequence-operator-returns-non-constant.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__shader-linking.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__shader-with-1024-character-define.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__shader-with-1024-character-identifier.frag.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__shader-with-1025-character-define.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__shader-with-1025-character-identifier.frag.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__short-circuiting-in-loop-condition.html]
-skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__texture-offset-out-of-range.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__uniform-location-length-limits.html]
-skip-if = (os == 'win' && debug) || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'win' && debug) || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__glsl3__vector-dynamic-indexing.html]
-skip-if = (os == 'win') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'win') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__misc__expando-loss-2.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__misc__instanceof-test.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__misc__uninitialized-test-2.html]
-skip-if = (os == 'mac') || (os == 'win') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'mac') || (os == 'win') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__query__occlusion-query.html]
-skip-if = (os == 'win') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'win') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__query__query.html]
-skip-if = (os == 'win') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'win') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__reading__read-pixels-from-fbo-test.html]
-skip-if = (os == 'mac') || (os == 'win') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'mac') || (os == 'win') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__reading__read-pixels-into-pixel-pack-buffer.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__reading__read-pixels-pack-parameters.html]
 fail-if = (os == 'mac') || (os == 'win')
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__renderbuffers__framebuffer-object-attachment.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__renderbuffers__framebuffer-test.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__renderbuffers__framebuffer-texture-layer.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__renderbuffers__invalidate-framebuffer.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__renderbuffers__multisampled-renderbuffer-initialization.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__renderbuffers__readbuffer.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__rendering__draw-buffers.html]
 fail-if = (os == 'mac') || (os == 'win')
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__rendering__element-index-uint.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__rendering__framebuffer-completeness-unaffected.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__rendering__instanced-arrays.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__samplers__sampler-drawing-test.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__samplers__samplers.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__state__gl-enum-tests.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__state__gl-get-calls.html]
 fail-if = (os == 'mac')
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__state__gl-getstring.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__state__gl-object-get-calls.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__transform_feedback__transform_feedback.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance2__vertex_arrays__vertex-array-object.html]
 fail-if = (os == 'mac') || (os == 'win')
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__attribs__gl-bindAttribLocation-aliasing.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__attribs__gl-bindAttribLocation-matrix.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__attribs__gl-bindAttribLocation-repeated.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__attribs__gl-disabled-vertex-attrib.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__attribs__gl-enable-vertex-attrib.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__attribs__gl-matrix-attributes.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__attribs__gl-vertex-attrib-render.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__attribs__gl-vertex-attrib-zero-issues.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__attribs__gl-vertexattribpointer-offsets.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__attribs__gl-vertexattribpointer.html]
 fail-if = (os == 'mac') || (os == 'win')
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__buffers__buffer-bind-test.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__buffers__buffer-data-and-buffer-sub-data.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__buffers__buffer-data-array-buffer-delete.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__buffers__element-array-buffer-delete-recreate.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__buffers__index-validation-copies-indices.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__buffers__index-validation-crash-with-buffer-sub-data.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__buffers__index-validation-large-buffer.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__buffers__index-validation-verifies-too-many-indices.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__buffers__index-validation-with-resized-buffer.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__buffers__index-validation.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__canvas__buffer-offscreen-test.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__canvas__buffer-preserve-test.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__canvas__canvas-test.html]
-skip-if = (os == 'win') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'win') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__canvas__canvas-zero-size.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__canvas__draw-static-webgl-to-multiple-canvas-test.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__canvas__draw-webgl-to-canvas-test.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__canvas__drawingbuffer-hd-dpi-test.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__canvas__drawingbuffer-static-canvas-test.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'win' && os_version == '6.2') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__canvas__drawingbuffer-test.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__canvas__framebuffer-bindings-affected-by-to-data-url.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__canvas__framebuffer-bindings-unaffected-on-resize.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__canvas__rapid-resizing.html]
-fail-if = (os == 'win' && os_version != '6.1')
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+fail-if = (os == 'win' && os_version == '5.1')
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__canvas__texture-bindings-unaffected-on-resize.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__canvas__to-data-url-test.html]
-skip-if = (os == 'win') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'win') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__canvas__viewport-unchanged-upon-resize.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__context__context-attribute-preserve-drawing-buffer.html]
-skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__context__context-attributes-alpha-depth-stencil-antialias.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__context__context-creation-and-destruction.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__context__context-creation.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__context__context-eviction-with-garbage-collection.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__context__context-hidden-alpha.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__context__context-lost-restored.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__context__context-lost.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__context__context-release-upon-reload.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__context__context-release-with-workers.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__context__context-size-change.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__context__incorrect-context-object-behaviour.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__context__premultiplyalpha-test.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__context__resource-sharing-test.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__context__user-defined-properties-on-context.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__extensions__ext-disjoint-timer-query.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__extensions__ext-texture-filter-anisotropic.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__extensions__get-extension.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__extensions__oes-texture-float-linear.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__extensions__webgl-compressed-texture-atc.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__extensions__webgl-compressed-texture-pvrtc.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__extensions__webgl-compressed-texture-s3tc.html]
 fail-if = (os == 'mac') || (os == 'win')
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__extensions__webgl-compressed-texture-size-limit.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__extensions__webgl-debug-renderer-info.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__extensions__webgl-debug-shaders.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__extensions__webgl-shared-resources.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__angle-ambiguous-function-call.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__angle-constructor-invalid-parameters.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__angle-d3d11-compiler-error.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__angle-dx-variable-bug.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__array-of-struct-with-int-first-position.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__compare-loop-index-to-uniform.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__complex-glsl-does-not-crash.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__compound-assignment-type-combination.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__conditional-discard-in-loop.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__conditional-discard-optimization.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__constant-precision-qualifier.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__floor-div-cos-should-not-truncate.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__floored-division-accuracy.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__fragcoord-linking-bug.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__gl-fragcoord-multisampling-bug.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__logic-inside-block-without-braces.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__long-expressions-should-not-crash.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__loop-if-loop-gradient.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__modulo-arithmetic-accuracy.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__multiplication-assignment.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__nested-functions-should-not-crash.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__nested-loops-with-break-and-continue.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__pow-of-small-constant-in-user-defined-function.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__pow-with-constant-exponent-should-not-crash.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__qualcomm-crash.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__qualcomm-loop-with-continue-crash.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__sampler-array-using-loop-index.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__sampler-struct-function-arg.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__sequence-operator-evaluation-order.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__sketchfab-lighting-shader-crash.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__struct-constructor-highp-bug.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__temp-expressions-should-not-crash.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__undefined-index-should-not-crash.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__bugs__uniforms-should-not-lose-values.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__constructors__glsl-construct-bvec2.html]
-skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
+fail-if = (os == 'win' && os_version == '6.2')
 [generated/test_2_conformance__glsl__constructors__glsl-construct-bvec3.html]
-skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
+fail-if = (os == 'win' && os_version == '6.2')
 [generated/test_2_conformance__glsl__constructors__glsl-construct-bvec4.html]
-skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
+fail-if = (os == 'win' && os_version == '6.2')
 [generated/test_2_conformance__glsl__constructors__glsl-construct-ivec2.html]
-skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
+fail-if = (os == 'win' && os_version == '6.2')
 [generated/test_2_conformance__glsl__constructors__glsl-construct-ivec3.html]
-skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
+fail-if = (os == 'win' && os_version == '6.2')
 [generated/test_2_conformance__glsl__constructors__glsl-construct-ivec4.html]
-skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
+fail-if = (os == 'win' && os_version == '6.2')
 [generated/test_2_conformance__glsl__constructors__glsl-construct-mat2.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__constructors__glsl-construct-mat3.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__constructors__glsl-construct-mat4.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__constructors__glsl-construct-vec-mat-corner-cases.html]
-skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
+fail-if = (os == 'win' && os_version == '6.2')
 [generated/test_2_conformance__glsl__constructors__glsl-construct-vec-mat-index.html]
-skip-if = (os == 'mac') || (os == 'win') || (os == 'linux') || (os == 'android') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'mac') || (os == 'win') || (os == 'linux') || (os == 'android') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__constructors__glsl-construct-vec2.html]
-skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
+fail-if = (os == 'win' && os_version == '6.2')
 [generated/test_2_conformance__glsl__constructors__glsl-construct-vec3.html]
-skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
+fail-if = (os == 'win' && os_version == '6.2')
 [generated/test_2_conformance__glsl__constructors__glsl-construct-vec4.html]
-skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
+fail-if = (os == 'win' && os_version == '6.2')
 [generated/test_2_conformance__glsl__functions__glsl-function-abs.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-acos.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-asin.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-atan-xy.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-atan.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-ceil.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-clamp-float.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-clamp-gentype.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-cos.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-cross.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-distance.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-dot.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-faceforward.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-floor.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-fract.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-length.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-max-float.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-max-gentype.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-min-float.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-min-gentype.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-mix-float.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-mix-gentype.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-mod-float.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-mod-gentype.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-normalize.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-reflect.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-sign.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-sin.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-smoothstep-float.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-smoothstep-gentype.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-step-float.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function-step-gentype.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__functions__glsl-function.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__add_int_float.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__add_int_mat2.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__add_int_mat3.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__add_int_mat4.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__add_int_vec2.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__add_int_vec3.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__add_int_vec4.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__add_ivec2_vec2.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__add_ivec3_vec3.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__add_ivec4_vec4.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__assign_int_to_float.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__assign_ivec2_to_vec2.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__assign_ivec3_to_vec3.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__assign_ivec4_to_vec4.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__construct_struct.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__divide_int_float.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__divide_int_mat2.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__divide_int_mat3.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__divide_int_mat4.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__divide_int_vec2.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__divide_int_vec3.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__divide_int_vec4.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__divide_ivec2_vec2.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__divide_ivec3_vec3.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__divide_ivec4_vec4.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__equal_int_float.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__equal_ivec2_vec2.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__equal_ivec3_vec3.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__equal_ivec4_vec4.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__function_int_float.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__function_ivec2_vec2.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__function_ivec3_vec3.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__function_ivec4_vec4.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__greater_than.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__greater_than_equal.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__less_than.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__less_than_equal.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__multiply_int_float.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__multiply_int_mat2.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__multiply_int_mat3.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__multiply_int_mat4.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__multiply_int_vec2.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__multiply_int_vec3.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__multiply_int_vec4.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__multiply_ivec2_vec2.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__multiply_ivec3_vec3.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__multiply_ivec4_vec4.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__not_equal_int_float.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__not_equal_ivec2_vec2.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__not_equal_ivec3_vec3.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__not_equal_ivec4_vec4.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__subtract_int_float.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__subtract_int_mat2.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__subtract_int_mat3.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__subtract_int_mat4.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__subtract_int_vec2.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__subtract_int_vec3.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__subtract_int_vec4.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__subtract_ivec2_vec2.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__subtract_ivec3_vec3.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__subtract_ivec4_vec4.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__ternary_int_float.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__ternary_ivec2_vec2.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__ternary_ivec3_vec3.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__implicit__ternary_ivec4_vec4.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__literals__float_literal.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__literals__literal_precision.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__literals__overflow_leak.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__matrices__glsl-mat3-construction.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__matrices__glsl-mat4-to-mat3.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__matrices__matrix-compound-multiply.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__boolean_precision.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__const-variable-initialization.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__embedded-struct-definitions-forbidden.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__empty-declaration.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__empty_main.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__expression-list-in-declarator-initializer.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__gl_position_unset.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__global-variable-init.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__glsl-function-nodes.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__glsl-long-variable-names.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__glsl-vertex-branch.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__large-loop-compile.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__non-ascii-comments.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__non-ascii.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__re-compile-re-link.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__sequence-operator-returns-constant.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-precision-format-obeyed.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-struct-scope.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-uniform-packing-restrictions.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-varying-packing-restrictions.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-256-character-define.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-256-character-identifier.frag.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-_webgl-identifier.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-arbitrary-indexing.frag.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-arbitrary-indexing.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-array-of-structs-containing-arrays.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-array-of-structs-uniform.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-attrib-array.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-attrib-struct.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-clipvertex.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-comma-assignment.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-comma-conditional-assignment.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-comma-separated-variable-declarations.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-conditional-scoping-negative.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-conditional-scoping.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-default-precision.frag.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-default-precision.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-define-line-continuation.frag.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-dfdx-no-ext.frag.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-dfdx.frag.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-do-loop.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-error-directive.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
+skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
 [generated/test_2_conformance__glsl__misc__shader-with-explicit-int-cast.vert.html]
-skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))