Bug 1515582. Remove the separate XBL scope setup. r=bholley
authorBoris Zbarsky <bzbarsky@mit.edu>
Mon, 11 Feb 2019 21:51:47 +0000
changeset 516464 9f776274089a2e001b347eb6d92e99d3decba8d8
parent 516463 41e7f49db5a64bb3930fd192cab4f0b3b1b76c5e
child 516465 21620d9c3bb45e0827a1737c8f09096ac5c85a9e
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs1515582, 944407, 419527, 391568, 1086996, 1197913, 495385, 1359859, 389322, 400705, 401907, 403162, 526178, 639338, 821850, 950909
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1515582. Remove the separate XBL scope setup. r=bholley With these changes, XBL just runs in the window scope of whatever document it's attached to. Since (outside of tests and "remote XUL") we no longer attach XBL to web documents, this is fine. And "remote XUL" already ran without the XBL scope. Native anonymous content, which used to be placed in the XBL scope to hide it from the page, is now placed in the unprivileged junk scope, so it stays hidden from the page. dom/xbl/test/test_bug944407.xul is being removed because we are changing the behavior it's trying to test for. Since we now always put the XBL in the same scope as the page, script is enabled for the XBL if and only if it's enabled for the page. dom/base/test/test_bug419527.xhtml, dom/events/test/test_bug391568.xhtml, dom/xbl/test/test_bug1086996.xhtml are being switched to a chrome test because otherwise the XBL can't see the getAnonymousNodes method. All the XBL bits are being removed from test_interfaces because we no longer have a separate XBL scope to test the behavior of. js/xpconnect/tests/mochitest/test_nac.xhtml is being removed because XBL no longer has access to NAC unless the page it's attached to does too, so the test doesn't really make sense. layout/xul/test/test_bug1197913.xul is being switched to a chrome test because its XUL elements use bindings that rely on APIs that are not exposed to normal web content. layout/reftests/bugs/495385-2f.xhtml is being removed because I can't think of a sane way to test that in the new world, short of running the reftest as chrome. And it doesn't seem worthwhile to look for a way to do that. dom/xbl/test/test_bug1098628_throw_from_construct.xhtml now needs to expectUncaughtException(), because the exception is now being thrown in Window scope. dom/xbl/test/test_bug1359859.xhtml needs to expectUncaughtException() as needed and not use XPCNativeWrapper (which it doesn't need to anyway now). dom/xbl/test/test_bug389322.xhtml, dom/xbl/test/test_bug400705.xhtml, dom/xbl/test/test_bug401907.xhtml, dom/xbl/test/test_bug403162.xhtml, dom/xbl/test/test_bug526178.xhtml, dom/xbl/test/test_bug639338.xhtml don't need to use XPCNativeWrapper anymore. dom/xbl/test/test_bug821850.html is being removed because it exists only to test XBL scopes. dom/xbl/test/file_bug950909.xml is being changed to work without a separate XBL scope (though whether the test still makes sense at that point is a bit questionable). Differential Revision: https://phabricator.services.mozilla.com/D19260
dom/base/Document.h
dom/base/nsGlobalWindowOuter.cpp
dom/base/nsINode.cpp
dom/base/test/chrome.ini
dom/base/test/mochitest.ini
dom/base/test/test_bug419527.xhtml
dom/bindings/BindingDeclarations.h
dom/bindings/BindingUtils.h
dom/events/test/chrome.ini
dom/events/test/mochitest.ini
dom/events/test/test_bug391568.xhtml
dom/tests/mochitest/general/file_interfaces.xml
dom/tests/mochitest/general/mochitest.ini
dom/tests/mochitest/general/test_interfaces.html
dom/tests/mochitest/general/test_interfaces.js
dom/tests/mochitest/general/test_interfaces_secureContext.html
dom/xbl/nsXBLBinding.cpp
dom/xbl/test/chrome.ini
dom/xbl/test/file_bug366770.xml
dom/xbl/test/file_bug821850.xhtml
dom/xbl/test/file_bug944407.html
dom/xbl/test/file_bug944407.xml
dom/xbl/test/file_bug950909.xml
dom/xbl/test/mochitest.ini
dom/xbl/test/test_bug1086996.xhtml
dom/xbl/test/test_bug1098628_throw_from_construct.xhtml
dom/xbl/test/test_bug1359859.xhtml
dom/xbl/test/test_bug389322.xhtml
dom/xbl/test/test_bug400705.xhtml
dom/xbl/test/test_bug401907.xhtml
dom/xbl/test/test_bug403162.xhtml
dom/xbl/test/test_bug526178.xhtml
dom/xbl/test/test_bug639338.xhtml
dom/xbl/test/test_bug821850.html
dom/xbl/test/test_bug944407.xul
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCWrappedNativeScope.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/src/xpcpublic.h
js/xpconnect/tests/mochitest/mochitest.ini
js/xpconnect/tests/mochitest/test_nac.xhtml
layout/reftests/bugs/495385-2f.xhtml
layout/reftests/bugs/reftest.list
layout/xul/test/chrome.ini
layout/xul/test/mochitest.ini
layout/xul/test/test_bug1197913.xul
--- a/dom/base/Document.h
+++ b/dom/base/Document.h
@@ -4754,41 +4754,30 @@ nsresult NS_NewPluginDocument(mozilla::d
 inline mozilla::dom::Document* nsINode::GetOwnerDocument() const {
   mozilla::dom::Document* ownerDoc = OwnerDoc();
 
   return ownerDoc != this ? ownerDoc : nullptr;
 }
 
 inline nsINode* nsINode::OwnerDocAsNode() const { return OwnerDoc(); }
 
-// ShouldUseXBLScope is defined here as a template so that we can get the faster
-// version of IsInAnonymousSubtree if we're statically known to be an
-// nsIContent.  we could try defining ShouldUseXBLScope separately on nsINode
-// and nsIContent, but then we couldn't put its nsINode implementation here
-// (because this header does not include nsIContent) and we can't put it in
-// nsIContent.h, because the definition of nsIContent::IsInAnonymousSubtree is
-// in nsIContentInlines.h.  And then we get include hell from people trying to
-// call nsINode::GetParentObject but not including nsIContentInlines.h and with
-// no really good way to include it.
-template <typename T>
-inline bool ShouldUseXBLScope(const T* aNode) {
-  return aNode->IsInAnonymousSubtree();
+inline bool ShouldUseNACScope(const nsINode* aNode) {
+  return aNode->IsInNativeAnonymousSubtree();
 }
 
-template <typename T>
-inline bool ShouldUseUAWidgetScope(const T* aNode) {
+inline bool ShouldUseUAWidgetScope(const nsINode* aNode) {
   return aNode->IsInUAWidget();
 }
 
 inline mozilla::dom::ParentObject nsINode::GetParentObject() const {
   mozilla::dom::ParentObject p(OwnerDoc());
   // Note that mReflectionScope is a no-op for chrome, and other places
   // where we don't check this value.
-  if (ShouldUseXBLScope(this)) {
-    p.mReflectionScope = mozilla::dom::ReflectionScope::XBL;
+  if (ShouldUseNACScope(this)) {
+    p.mReflectionScope = mozilla::dom::ReflectionScope::NAC;
   } else if (ShouldUseUAWidgetScope(this)) {
     p.mReflectionScope = mozilla::dom::ReflectionScope::UAWidget;
   }
   return p;
 }
 
 inline mozilla::dom::Document* nsINode::AsDocument() {
   MOZ_ASSERT(IsDocument());
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -1989,19 +1989,16 @@ nsresult nsGlobalWindowOuter::SetNewDocu
     aDocument->NodePrincipal()->Equals(existing, &sameOrigin);
     MOZ_ASSERT(sameOrigin);
     MOZ_ASSERT_IF(aDocument == oldDoc,
                   xpc::GetRealmPrincipal(realm) == aDocument->NodePrincipal());
 #endif
     if (aDocument != oldDoc) {
       JS::SetRealmPrincipals(realm,
                              nsJSPrincipals::get(aDocument->NodePrincipal()));
-      // Make sure we clear out the old content XBL scope, so the new one will
-      // get created with a principal that subsumes our new principal.
-      xpc::ClearContentXBLScope(newInnerGlobal);
     }
   } else {
     if (aState) {
       newInnerWindow = wsh->GetInnerWindow();
       newInnerGlobal = newInnerWindow->GetWrapperPreserveColor();
     } else {
       newInnerWindow = nsGlobalWindowInner::Create(this, thisChrome);
       if (StaticPrefs::dom_timeout_defer_during_load()) {
--- a/dom/base/nsINode.cpp
+++ b/dom/base/nsINode.cpp
@@ -1189,17 +1189,17 @@ static void CheckForOutdatedParent(nsINo
     if (JS::GetNonCCWObjectGlobal(existingObj) != global->GetGlobalJSObject()) {
       JSAutoRealm ar(cx, existingObj);
       UpdateReflectorGlobal(cx, existingObj, aError);
     }
   }
 }
 
 static nsresult UpdateGlobalsInSubtree(nsIContent* aRoot) {
-  MOZ_ASSERT(ShouldUseXBLScope(aRoot));
+  MOZ_ASSERT(ShouldUseNACScope(aRoot));
   // Start off with no global so we don't fire any error events on failure.
   AutoJSAPI jsapi;
   jsapi.Init();
 
   JSContext* cx = jsapi.cx();
 
   ErrorResult rv;
   JS::Rooted<JSObject*> reflector(cx);
@@ -1267,22 +1267,23 @@ nsresult nsINode::InsertChildBefore(nsIC
   if (!aChildToInsertBefore) {
     AppendChildToChildList(aKid);
   } else {
     InsertChildToChildList(aKid, aChildToInsertBefore);
   }
 
   nsIContent* parent = IsContent() ? AsContent() : nullptr;
 
-  bool wasInXBLScope = ShouldUseXBLScope(aKid);
+  // XXXbz Do we even need this code anymore?
+  bool wasInNACScope = ShouldUseNACScope(aKid);
   nsresult rv = aKid->BindToTree(doc, parent,
                                  parent ? parent->GetBindingParent() : nullptr);
-  if (NS_SUCCEEDED(rv) && !wasInXBLScope && ShouldUseXBLScope(aKid)) {
-    MOZ_ASSERT(ShouldUseXBLScope(this),
-               "Why does the kid need to use an XBL scope?");
+  if (NS_SUCCEEDED(rv) && !wasInNACScope && ShouldUseNACScope(aKid)) {
+    MOZ_ASSERT(ShouldUseNACScope(this),
+               "Why does the kid need to use an the anonymous content scope?");
     rv = UpdateGlobalsInSubtree(aKid);
   }
   if (NS_FAILED(rv)) {
     DisconnectChild(aKid);
     aKid->UnbindFromTree();
     return rv;
   }
 
@@ -2652,19 +2653,20 @@ JSObject* nsINode::WrapObject(JSContext*
   bool hasHadScriptHandlingObject = false;
   if (!OwnerDoc()->GetScriptHandlingObject(hasHadScriptHandlingObject) &&
       !hasHadScriptHandlingObject && !nsContentUtils::IsSystemCaller(aCx)) {
     Throw(aCx, NS_ERROR_UNEXPECTED);
     return nullptr;
   }
 
   JS::Rooted<JSObject*> obj(aCx, WrapNode(aCx, aGivenProto));
-  MOZ_ASSERT_IF(obj && ChromeOnlyAccess(),
-                xpc::IsInContentXBLScope(obj) ||
-                    !xpc::UseContentXBLScope(JS::GetObjectRealmOrNull(obj)));
+  MOZ_ASSERT_IF(
+      obj && ChromeOnlyAccess(),
+      JS::GetNonCCWObjectGlobal(obj) == xpc::UnprivilegedJunkScope() ||
+          xpc::IsInUAWidgetScope(obj) || xpc::AccessCheck::isChrome(obj));
   return obj;
 }
 
 already_AddRefed<nsINode> nsINode::CloneNode(bool aDeep, ErrorResult& aError) {
   return nsNodeUtils::CloneNodeImpl(this, aDeep, aError);
 }
 
 nsDOMAttributeMap* nsINode::GetAttributes() {
--- a/dom/base/test/chrome.ini
+++ b/dom/base/test/chrome.ini
@@ -14,16 +14,17 @@ support-files =
   referrer_helper.js
   referrer_testserver.sjs
   mozbrowser_api_utils.js
   !/image/test/mochitest/shaver.png
 
 [test_anonymousContent_xul_window.xul]
 [test_blockParsing.html]
 [test_blocking_image.html]
+[test_bug419527.xhtml]
 [test_bug715041.xul]
 [test_bug715041_removal.xul]
 [test_bug945152.html]
 [test_bug1008126.html]
 [test_bug1016960.html]
 [test_anchor_target_blank_referrer.html]
 [test_copypaste.xul]
 subsuite = clipboard
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -365,17 +365,16 @@ support-files = test_bug402150.html^head
 [test_bug416317-1.html]
 [test_bug416317-2.html]
 [test_bug416383.html]
 [test_bug417255.html]
 [test_bug417384.html]
 [test_bug418214.html]
 [test_bug418986-1.html]
 [test_bug419132.html]
-[test_bug419527.xhtml]
 [test_bug420609.xhtml]
 [test_bug420700.html]
 [test_bug421602.html]
 [test_bug422403-1.html]
 [test_bug422403-2.xhtml]
 [test_bug422537.html]
 [test_bug424212.html]
 [test_bug424359-1.html]
--- a/dom/base/test/test_bug419527.xhtml
+++ b/dom/base/test/test_bug419527.xhtml
@@ -1,32 +1,32 @@
 <?xml version="1.0"?>
 <html xmlns="http://www.w3.org/1999/xhtml">
 <!--
 https://bugzilla.mozilla.org/show_bug.cgi?id=419527
 -->
 <head>
   <title>Test for Bug 419527</title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
   <bindings xmlns="http://www.mozilla.org/xbl"
             xmlns:html="http://www.w3.org/1999/xhtml">
     <binding id="rangebinding">
       <content><html:span>Foo</html:span>
       </content>
       <implementation>
         <constructor>
-          var win = XPCNativeWrapper.unwrap(window);
+          var win = window;
           var span = document.getAnonymousNodes(this)[0];
           win.ok(span.localName == "span", "Wrong anon node!");
           var range = document.createRange();
           range.selectNode(span.firstChild);
           win.ok(range.startContainer == span, "Wrong start container!");
           win.ok(range.endContainer == span, "Wrong end container!");
-          var newSubTree = XPCNativeWrapper(win.newSubTree);
+          var newSubTree = win.newSubTree;
           newSubTree.appendChild(this);
           range.setStart(newSubTree.firstChild, 0);
           win.ok(range.startContainer == newSubTree.firstChild,
                  "Range should have been collapsed to newSubTree.firstChild!");
           win.ok(range.endContainer == newSubTree.firstChild,
                  "Range should have been collapsed to newSubTree.firstChild!");
           //XXX This should just call SimpleTest.finish(), bugs 478528, 499735.
           setTimeout(win.finish, 0);
--- a/dom/bindings/BindingDeclarations.h
+++ b/dom/bindings/BindingDeclarations.h
@@ -415,17 +415,17 @@ inline nsWrapperCache* GetWrapperCache(v
 
 // Helper template for smart pointers to resolve ambiguity between
 // GetWrappeCache(void*) and GetWrapperCache(const ParentObject&).
 template <template <typename> class SmartPtr, typename T>
 inline nsWrapperCache* GetWrapperCache(const SmartPtr<T>& aObject) {
   return GetWrapperCache(aObject.get());
 }
 
-enum class ReflectionScope { Content, XBL, UAWidget };
+enum class ReflectionScope { Content, NAC, UAWidget };
 
 struct MOZ_STACK_CLASS ParentObject {
   template <class T>
   MOZ_IMPLICIT ParentObject(T* aObject)
       : mObject(ToSupports(aObject)),
         mWrapperCache(GetWrapperCache(aObject)),
         mReflectionScope(ReflectionScope::Content) {}
 
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -1616,28 +1616,18 @@ static inline JSObject* FindAssociatedGl
   }
   JS::AssertObjectIsNotGray(obj);
 
   // The object is never a CCW but it may not be in the current compartment of
   // the JSContext.
   obj = JS::GetNonCCWObjectGlobal(obj);
 
   switch (scope) {
-    case mozilla::dom::ReflectionScope::XBL: {
-      // If scope is set to XBLScope, it means that the canonical reflector for
-      // this native object should live in the content XBL scope. Note that we
-      // never put anonymous content inside an add-on scope.
-      if (xpc::IsInContentXBLScope(obj)) {
-        return obj;
-      }
-      JS::Rooted<JSObject*> rootedObj(cx, obj);
-      JSObject* xblScope = xpc::GetXBLScope(cx, rootedObj);
-      MOZ_ASSERT_IF(xblScope, JS_IsGlobalObject(xblScope));
-      JS::AssertObjectIsNotGray(xblScope);
-      return xblScope;
+    case mozilla::dom::ReflectionScope::NAC: {
+      return xpc::NACScope(obj);
     }
 
     case mozilla::dom::ReflectionScope::UAWidget: {
       // If scope is set to UAWidgetScope, it means that the canonical reflector
       // for this native object should live in the UA widget scope.
       if (xpc::IsInUAWidgetScope(obj)) {
         return obj;
       }
--- a/dom/events/test/chrome.ini
+++ b/dom/events/test/chrome.ini
@@ -7,16 +7,17 @@ support-files =
   bug591249_iframe.xul
   bug602962.xul
   file_bug679494.html
   window_bug617528.xul
   window_bug1412775.xul
   test_bug336682.js
 
 [test_bug336682_2.xul]
+[test_bug391568.xhtml]
 [test_bug415498.xul]
 [test_bug418986-3.xul]
 [test_bug524674.xul]
 [test_bug586961.xul]
 [test_bug591249.xul]
 [test_bug602962.xul]
 [test_bug617528.xul]
 [test_bug679494.xul]
--- a/dom/events/test/mochitest.ini
+++ b/dom/events/test/mochitest.ini
@@ -31,17 +31,16 @@ support-files =
 [test_bug1037990.html]
 [test_bug299673-2.html]
 [test_bug322588.html]
 [test_bug328885.html]
 [test_bug336682_1.html]
 support-files = test_bug336682.js
 [test_bug367781.html]
 [test_bug379120.html]
-[test_bug391568.xhtml]
 [test_bug402089.html]
 [test_bug405632.html]
 [test_bug409604.html]
 skip-if = toolkit == 'android' #TIMED_OUT
 [test_bug412567.html]
 [test_bug418986-3.html]
 [test_bug422132.html]
 [test_bug426082.html]
--- a/dom/events/test/test_bug391568.xhtml
+++ b/dom/events/test/test_bug391568.xhtml
@@ -1,31 +1,31 @@
 <?xml version="1.0"?>
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:xbl="http://www.mozilla.org/xbl">
 <!--
 https://bugzilla.mozilla.org/show_bug.cgi?id=391568
 -->
 <head>
   <title>Test for Bug 391568</title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
   <script>
     var constructorFired = 0;
   </script>
   <xbl:bindings>
     <xbl:binding id="test">
       <xbl:content><span>
         (anonumous content)
         <span><xbl:children/></span>
         (anonumous content)</span>
       </xbl:content>
   
       <xbl:implementation>
         <xbl:constructor>
-          var win = XPCNativeWrapper.unwrap(window);
+          var win = window;
           ++win.constructorFired;
           document.getAnonymousNodes(this)[0].addEventListener(
             "DOMCharacterDataModified", 
             function(evt) {
               ++win.characterdatamodified;
             },
             true);
         </xbl:constructor>
deleted file mode 100644
--- a/dom/tests/mochitest/general/file_interfaces.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0"?>
-<bindings id="xbltestBindings" xmlns="http://www.mozilla.org/xbl">
-  <binding id="xbltest">
-    <content>PASS</content>
-    <implementation>
-      <constructor>
-        var win = XPCNativeWrapper.unwrap(window);
-        var SpecialPowers = win.SpecialPowers;
-        var is = win.is;
-        var todo_is = win.todo_is;
-        var ok = win.ok;
-        var legacyMozPrefixedInterfaces = win.legacyMozPrefixedInterfaces;
-        var createInterfaceMap = win.createInterfaceMap;
-        eval(win.runTest.toString());
-        runTest(true);
-        win.SimpleTest.finish();
-      </constructor>
-    </implementation>
-  </binding>
-</bindings>
--- a/dom/tests/mochitest/general/mochitest.ini
+++ b/dom/tests/mochitest/general/mochitest.ini
@@ -1,17 +1,16 @@
 [DEFAULT]
 support-files =
   497633.html
   fail.png
   file_bug628069.html
   file_clonewrapper.html
   file_domWindowUtils_scrollbarSize.html
   file_frameElementWrapping.html
-  file_interfaces.xml
   file_moving_nodeList.html
   file_moving_xhr.html
   file_resource_timing_nocors.html
   generateCss.sjs
   historyframes.html
   start_historyframe.html
   url1_historyframe.html
   url2_historyframe.html
--- a/dom/tests/mochitest/general/test_interfaces.html
+++ b/dom/tests/mochitest/general/test_interfaces.html
@@ -15,12 +15,11 @@ https://bugzilla.mozilla.org/show_bug.cg
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 <script>
   ok(!self.isSecureContext, "The test should not be running in a secure context");
 </script>
 <script type="text/javascript" src="test_interfaces.js"></script>
-<span id="span" style="-moz-binding: url(file_interfaces.xml)"></span>
 </pre>
 </body>
 </html>
--- a/dom/tests/mochitest/general/test_interfaces.js
+++ b/dom/tests/mochitest/general/test_interfaces.js
@@ -10,17 +10,16 @@
 // property giving the interface name as a string, and additional
 // properties which qualify the exposure of that interface. For example:
 //
 // [
 //   "AGlobalInterface",
 //   {name: "ExperimentalThing", release: false},
 //   {name: "ReallyExperimentalThing", nightly: true},
 //   {name: "DesktopOnlyThing", desktop: true},
-//   {name: "FancyControl", xbl: true},
 //   {name: "DisabledEverywhere", disabled: true},
 // ];
 //
 // See createInterfaceMap() below for a complete list of properties.
 //
 // The values of the properties need to be either literal true/false
 // (e.g. indicating whether something is enabled on a particular
 // channel/OS) or one of the is* constants below (in cases when
@@ -171,18 +170,16 @@ var interfaceNamesInGlobalScope =
     {name: "BeforeUnloadEvent", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "BiquadFilterNode", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "Blob", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "BlobEvent", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "BoxObject", insecureContext: true, xbl: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "BroadcastChannel", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "Cache", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "CacheStorage", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "CanvasCaptureMediaStream", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
@@ -197,26 +194,22 @@ var interfaceNamesInGlobalScope =
     {name: "CDATASection", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "ChannelMergerNode", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "ChannelSplitterNode", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "CharacterData", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "ChromeNodeList", insecureContext: true, xbl: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "Clipboard"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "ClipboardEvent", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "CloseEvent", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "CommandEvent", insecureContext: true, xbl: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "Comment", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "CompositionEvent", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "ConstantSourceNode", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "ConvolverNode", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
@@ -887,35 +880,33 @@ var interfaceNamesInGlobalScope =
     {name: "ScopedCredential", insecureContext: true, disabled: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "ScopedCredentialInfo", insecureContext: true, disabled: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "ShadowRoot", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "SharedWorker", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SimpleGestureEvent", insecureContext: true, xbl: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SimpleTest", insecureContext: true, xbl: false},
+    {name: "SimpleTest", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "SourceBuffer", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "SourceBufferList", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "SpeechSynthesisErrorEvent", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "SpeechSynthesisEvent", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "SpeechSynthesis", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "SpeechSynthesisUtterance", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "SpeechSynthesisVoice", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SpecialPowers", insecureContext: true, xbl: false},
+    {name: "SpecialPowers", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "StereoPannerNode", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "Storage", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "StorageEvent", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "StorageManager", android: false},
@@ -1149,22 +1140,16 @@ var interfaceNamesInGlobalScope =
     {name: "TouchEvent", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "TouchList", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "TrackEvent", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "TransitionEvent", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "TreeColumn", insecureContext: true, xbl: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "TreeColumns", insecureContext: true, xbl: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "TreeContentView", insecureContext: true, xbl: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "TreeWalker", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "U2F", insecureContext: true, disabled: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "UIEvent", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "URL", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
@@ -1263,48 +1248,31 @@ var interfaceNamesInGlobalScope =
     {name: "XPathEvaluator", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "XPathExpression", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "XPathResult", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "XSLTProcessor", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "XULCommandEvent", insecureContext: true, xbl: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "XULDocument", insecureContext: true, xbl: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "XULElement", insecureContext: true, xbl: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "XULFrameElement", insecureContext: true, xbl: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "XULMenuElement", insecureContext: true, xbl: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "XULPopupElement", insecureContext: true, xbl: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "XULTextElement", insecureContext: true, xbl: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "XULTreeElement", insecureContext: true, xbl: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
   ];
 // IMPORTANT: Do not change the list above without review from a DOM peer!
 
-function createInterfaceMap(isXBLScope) {
+function createInterfaceMap() {
   var interfaceMap = {};
 
   function addInterfaces(interfaces)
   {
     for (var entry of interfaces) {
       if (typeof(entry) === "string") {
         interfaceMap[entry] = !isInsecureContext;
       } else {
         ok(!("pref" in entry), "Bogus pref annotation for " + entry.name);
         if ((entry.nightly === !isNightly) ||
             (entry.nightlyAndroid === !(isAndroid && isNightly) && isAndroid) ||
-            (entry.xbl === !isXBLScope) ||
             (entry.desktop === !isDesktop) ||
             (entry.windows === !isWindows) ||
             (entry.mac === !isMac) ||
             (entry.linux === !isLinux) ||
             (entry.android === !isAndroid && !entry.nightlyAndroid) ||
             (entry.fennecOrDesktop === (isAndroid && !isFennec)) ||
             (entry.release === !isRelease) ||
             (entry.releaseNonWindowsAndMac === !(isRelease && !isWindows && !isMac)) ||
@@ -1325,42 +1293,41 @@ function createInterfaceMap(isXBLScope) 
   }
 
   addInterfaces(ecmaGlobals);
   addInterfaces(interfaceNamesInGlobalScope);
 
   return interfaceMap;
 }
 
-function runTest(isXBLScope) {
-  var interfaceMap = createInterfaceMap(isXBLScope);
+function runTest() {
+  var interfaceMap = createInterfaceMap();
   for (var name of Object.getOwnPropertyNames(window)) {
     // An interface name should start with an upper case character.
     // However, we have a couple of legacy interfaces that start with 'moz', so
     // we want to allow those until we can remove them.
     if (!/^[A-Z]/.test(name) && !legacyMozPrefixedInterfaces.includes(name)) {
       continue;
     }
     ok(interfaceMap[name],
        "If this is failing: DANGER, are you sure you want to expose the new interface " + name +
-       " to all webpages as a property on the window (XBL: " + isXBLScope + ")? Do not make a change to this file without a " +
+       " to all webpages as a property on the window? Do not make a change to this file without a " +
        " review from a DOM peer for that specific change!!! (or a JS peer for changes to ecmaGlobals)");
 
     ok(name in window,
-       `${name} is exposed as an own property on the window but tests false for "in" in the ${isXBLScope ? "XBL" : "global"} scope`);
+       `${name} is exposed as an own property on the window but tests false for "in" in the global scope`);
     ok(Object.getOwnPropertyDescriptor(window, name),
-       `${name} is exposed as an own property on the window but has no property descriptor in the ${isXBLScope ? "XBL" : "global"} scope`);
+       `${name} is exposed as an own property on the window but has no property descriptor in the global scope`);
 
     delete interfaceMap[name];
   }
   for (var name of Object.keys(interfaceMap)) {
     ok(name in window === interfaceMap[name],
-       name + " should " + (interfaceMap[name] ? "" : " NOT") + " be defined on the " + (isXBLScope ? "XBL" : "global") +" scope");
+       name + " should " + (interfaceMap[name] ? "" : " NOT") + " be defined on the global scope");
     if (!interfaceMap[name]) {
       delete interfaceMap[name];
     }
   }
   is(Object.keys(interfaceMap).length, 0,
      "The following interface(s) are not enumerated: " + Object.keys(interfaceMap).join(", "));
 }
 
-runTest(false);
-SimpleTest.waitForExplicitFinish();
+runTest();
--- a/dom/tests/mochitest/general/test_interfaces_secureContext.html
+++ b/dom/tests/mochitest/general/test_interfaces_secureContext.html
@@ -15,12 +15,11 @@ https://bugzilla.mozilla.org/show_bug.cg
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 <script>
   ok(self.isSecureContext, "The test should be running in a secure context");
 </script>
 <script type="text/javascript" src="test_interfaces.js"></script>
-<span id="span" style="-moz-binding: url(file_interfaces.xml)"></span>
 </pre>
 </body>
 </html>
--- a/dom/xbl/nsXBLBinding.cpp
+++ b/dom/xbl/nsXBLBinding.cpp
@@ -213,26 +213,18 @@ void nsXBLBinding::UnbindAnonymousConten
 void nsXBLBinding::SetBoundElement(Element* aElement) {
   mBoundElement = aElement;
   if (mNextBinding) mNextBinding->SetBoundElement(aElement);
 
   if (!mBoundElement) {
     return;
   }
 
-  // Compute whether we're using an XBL scope.
-  //
-  // We disable XBL scopes for remote XUL, where we care about compat more
-  // than security. So we need to know whether we're using an XBL scope so that
-  // we can decide what to do about untrusted events when "allowuntrusted"
-  // is not given in the handler declaration.
-  nsCOMPtr<nsIGlobalObject> go = mBoundElement->OwnerDoc()->GetScopeObject();
-  NS_ENSURE_TRUE_VOID(go && go->GetGlobalJSObject());
-  mUsingContentXBLScope = xpc::UseContentXBLScope(
-      JS::GetObjectRealmOrNull(go->GetGlobalJSObject()));
+  // mUsingContentXBLScope can go away.  See bug 1527116.
+  mUsingContentXBLScope = false;
 }
 
 bool nsXBLBinding::HasStyleSheets() const {
   // Find out if we need to re-resolve style.  We'll need to do this
   // if we have additional stylesheets in our binding document.
   if (mPrototypeBinding->HasStyleSheets()) return true;
 
   return mNextBinding ? mNextBinding->HasStyleSheets() : false;
--- a/dom/xbl/test/chrome.ini
+++ b/dom/xbl/test/chrome.ini
@@ -1,16 +1,15 @@
 [DEFAULT]
 support-files =
-  file_bug944407.xml
   file_bug950909.xml
   file_fieldScopeChain.xml
 
 [test_bug378518.xul]
 skip-if = (verify && debug && (os == 'linux' || os == 'mac'))
 [test_bug398135.xul]
 [test_bug398492.xul]
 [test_bug721452.xul]
 [test_bug723676.xul]
 [test_bug772966.xul]
-[test_bug944407.xul]
 [test_bug950909.xul]
+[test_bug1086996.xhtml]
 [test_fieldScopeChain.html]
--- a/dom/xbl/test/file_bug366770.xml
+++ b/dom/xbl/test/file_bug366770.xml
@@ -1,14 +1,14 @@
 <?xml version="1.0"?>
 <bindings id="xbltestBindings" xmlns="http://www.mozilla.org/xbl">
   <binding id="xbltest">
     <content>PASS</content>
     <implementation>
       <constructor>
-        var win = XPCNativeWrapper.unwrap(window);
+        var win = window;
         win.document.bindingConstructorRan = true;
         win.ok(true, "binding URI with no fragment applied");
         win.SimpleTest.finish();
       </constructor>
     </implementation>
   </binding>
 </bindings>
deleted file mode 100644
--- a/dom/xbl/test/file_bug821850.xhtml
+++ /dev/null
@@ -1,300 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=821850
--->
-<head>
-  <bindings xmlns="http://www.mozilla.org/xbl">
-    <binding id="testBinding">
-      <implementation>
-        <constructor>
-          // Store a property as an expando on the bound element.
-          this._prop = "propVal";
-
-          // Wait for both constructors to fire.
-          window.constructorCount = (window.constructorCount + 1) || 1;
-          if (window.constructorCount != 3)
-            return;
-
-          // Grab some basic infrastructure off the content window.
-          var win = XPCNativeWrapper.unwrap(window);
-          SpecialPowers = win.SpecialPowers;
-          Cu = SpecialPowers.Cu;
-          Ci = SpecialPowers.Ci;
-          is = win.is;
-          ok = win.ok;
-          SimpleTest = win.SimpleTest;
-
-          // Stick some expandos on the content window.
-          window.xrayExpando = 3;
-          win.primitiveExpando = 11;
-          win.stringExpando = "stringExpando";
-          win.objectExpando = { foo: 12 };
-          win.globalExpando = SpecialPowers.unwrap(Cu.getGlobalForObject({}));
-          win.functionExpando = function() { return "called" };
-          win.functionExpando.prop = 2;
-
-          // Make sure we're Xraying.
-          ok(Cu.isXrayWrapper(window), "Window is Xrayed");
-          ok(Cu.isXrayWrapper(document), "Document is Xrayed");
-
-          var bound = document.getElementById('bound');
-          var bound2 = document.getElementById('bound2');
-          var bound3 = document.getElementById('bound3');
-          ok(bound, "bound is non-null");
-          is(bound.method('baz'), "method:baz", "Xray methods work");
-          is(bound.prop, "propVal", "Property Xrays work");
-          is(bound.primitiveField, undefined, "Xrays don't show fields");
-          is(bound.wrappedJSObject.primitiveField, 2, "Waiving Xrays show fields");
-
-          // Check exposure behavior.
-          is(typeof bound.unexposedMethod, 'function',
-             "Unexposed method should be visible to XBL");
-          is(typeof bound.wrappedJSObject.unexposedMethod, 'undefined',
-             "Unexposed method should not be defined in content");
-          is(typeof bound.unexposedProperty, 'number',
-             "Unexposed property should be visible to XBL");
-          is(typeof bound.wrappedJSObject.unexposedProperty, 'undefined',
-             "Unexposed property should not be defined in content");
-
-          // Check that here HTMLImageElement.QueryInterface works
-          var img = document.querySelector("img");
-          ok("QueryInterface" in SpecialPowers.wrap(img),
-             "Should have a img.QueryInterface here");
-          is(SpecialPowers.unwrap(SpecialPowers.wrap(img).QueryInterface(Ci.nsIImageLoadingContent)),
-             img, "Should be able to QI the image");
-
-          // Make sure standard constructors work right in the presence of
-          // sandboxPrototype and Xray-resolved constructors.
-          is(window.Function, XPCNativeWrapper(window.wrappedJSObject.Function),
-             "window.Function comes from the window, not the global");
-          ok(Function != window.Function, "Function constructors are distinct");
-          is(Object.getPrototypeOf(Function.prototype), Object.getPrototypeOf({foo: 42}),
-             "Function constructor is local");
-
-          ok(Object.getPrototypeOf(bound.wrappedJSObject) == Object.getPrototypeOf(bound2.wrappedJSObject),
-             "Div and div should have the same content-side prototype");
-          ok(Object.getPrototypeOf(bound.wrappedJSObject) != Object.getPrototypeOf(bound3.wrappedJSObject),
-             "Div and span should have different content-side prototypes");
-          ok(bound.wrappedJSObject.method == bound3.wrappedJSObject.method,
-             "Methods should be shared");
-
-          // This gets invoked by an event handler.
-          window.finish = function() {
-            // Content messed with stuff. Make sure we still see the right thing.
-            is(bound.method('bay'), "method:bay", "Xray methods work");
-            is(bound.wrappedJSObject.method('bay'), "hah", "Xray waived methods work");
-            is(bound.prop, "set:someOtherVal", "Xray props work");
-            is(bound.wrappedJSObject.prop, "redefined", "Xray waived props work");
-            is(bound.wrappedJSObject.primitiveField, 321, "Can't do anything about redefined fields");
-
-            SimpleTest.finish();
-          }
-
-          // Hand things off to content. Content will call us back.
-          win.go();
-        </constructor>
-        <field name="primitiveField">2</field>
-        <method name="unexposedMethod"><body></body></method>
-        <property name="unexposedProperty" onget="return 2;" readonly="true"></property>
-        <method name="method" exposeToUntrustedContent="true">
-          <parameter name="arg" />
-          <body>
-            return "method:" + arg;
-          </body>
-        </method>
-        <method name="passMeAJSObject" exposeToUntrustedContent="true">
-          <parameter name="arg" />
-          <body>
-            is(typeof arg.prop, 'undefined', "No properties");
-            is(arg.wrappedJSObject.prop, 2, "Underlying object has properties");
-            is(Object.getOwnPropertyNames(arg).length, 0, "Should have no own properties");
-            is(Object.getOwnPropertyNames(arg.wrappedJSObject).length, 1, "Underlying object has properties");
-            arg.foo = 2;
-            is(arg.foo, 2, "Should place expandos");
-            is(typeof arg.wrappedJSObject.foo, 'undefined', "Expandos should be invisible to content");
-          </body>
-        </method>
-        <property name="prop" exposeToUntrustedContent="true">
-          <getter>return this._prop;</getter>
-          <setter>this._prop = "set:" + val;</setter>
-        </property>
-      </implementation>
-      <handlers>
-        <handler event="testevent" action="ok(true, 'called event handler'); finish();" allowuntrusted="true"/>
-        <handler event="testtrusted" action="ok(true, 'called trusted handler'); window.wrappedJSObject.triggeredTrustedHandler = true;"/>
-        <handler event="keyup" action="ok(true, 'called untrusted key handler'); window.wrappedJSObject.triggeredUntrustedKeyHandler = true;" allowuntrusted="true"/>
-        <handler event="keydown" action="ok(true, 'called trusted key handler'); window.wrappedJSObject.triggeredTrustedKeyHandler = true;"/>
-      </handlers>
-    </binding>
-  </bindings>
-  <script type="application/javascript">
-  <![CDATA[
-
-  ok = parent.ok;
-  is = parent.is;
-  SimpleTest = parent.SimpleTest;
-  SpecialPowers = parent.SpecialPowers;
-
-  // Test the Xray waiving behavior when accessing fields. We should be able to
-  // see sequential JS-implemented properties, but should regain Xrays when we
-  // hit a native property.
-  window.contentVal = { foo: 10, rabbit: { hole: { bar: 100, win: window} } };
-  ok(true, "Set contentVal");
-
-  // Check that we're not exposing QueryInterface to non-XBL code
-  ok(!("QueryInterface" in document),
-     "Should not have a document.QueryInterface here");
-
-  function go() {
-    "use strict";
-
-    // Test what we can and cannot access in the XBL scope.
-    is(typeof window.xrayExpando, "undefined", "Xray expandos are private to the caller");
-    is(window.primitiveExpando, 11, "Can see waived expandos");
-    is(window.stringExpando, "stringExpando", "Can see waived expandos");
-    is(typeof window.objectExpando, "object", "object expando exists");
-    checkThrows(() => window.objectExpando.foo);
-    is(SpecialPowers.wrap(window.objectExpando).foo, 12, "SpecialPowers sees the right thing");
-    is(typeof window.globalExpando, "object", "Can see global object");
-    checkThrows(() => window.globalExpando.win);
-    is(window.functionExpando(), "called", "XBL functions are callable");
-    checkThrows(() => window.functionExpando.prop);
-
-    // Inspect the bound element.
-    var bound = document.getElementById('bound');
-    is(bound.primitiveField, 2, "Can see primitive fields");
-    is(bound.method("foo"), "method:foo", "Can invoke XBL method from content");
-    is(bound.prop, "propVal", "Can access properties from content");
-    bound.prop = "someOtherVal";
-    is(bound.prop, "set:someOtherVal", "Can set properties from content");
-
-    // Make sure that XBL scopes get opaque wrappers.
-    //
-    // Note: Now that we have object Xrays, we have to pass in a more obscure
-    // ES type that we don't Xray to test this.
-    var proto = bound.__proto__;
-    var nonXrayableObject = new WeakMap();
-    nonXrayableObject.prop = 2;
-    proto.passMeAJSObject(nonXrayableObject);
-
-    //
-    // Try sticking a bunch of stuff on the prototype object.
-    //
-
-    proto.someExpando = 201;
-    is(bound.someExpando, 201, "Can stick non-XBL properties on the proto");
-
-    // Previously, this code checked that content couldn't tamper with its XBL
-    // prototype. But we decided to allow this to reduce regression risk, so for
-    // now just check that this works.
-    function checkMayTamper(obj, propName, desc) {
-      var accessor = !('value' in Object.getOwnPropertyDescriptor(obj, propName));
-      if (!accessor)
-        checkAllowed(function() { obj[propName] = function() {} }, desc + ": assign");
-      checkAllowed(function() { Object.defineProperty(obj, propName, {configurable: true, value: 3}) }, desc + ": define with value");
-      checkAllowed(function() { Object.defineProperty(obj, propName, {configurable: true, writable: true}) }, desc + ": make writable");
-      checkAllowed(function() { Object.defineProperty(obj, propName, {configurable: true}) }, desc + ": make configurable");
-      checkAllowed(function() { Object.defineProperty(obj, propName, {configurable: true, get: function() {}}) }, desc + ": define with getter");
-      checkAllowed(function() { Object.defineProperty(obj, propName, {configurable: true, set: function() {}}) }, desc + ": define with setter");
-
-      // Windows are implemented as proxies, and Proxy::delete_ doesn't currently
-      // pass strict around. Work around it in the window.binding case by just
-      // checking if delete returns false.
-      // manually.
-      checkAllowed(function() { delete obj[propName]; }, desc + ": delete");
-
-      if (!accessor)
-        checkAllowed(function() { obj[propName] = function() {} }, desc + ": assign (again)");
-    }
-
-    // Make sure content can do whatever it wants with the prototype.
-    checkMayTamper(proto, 'method', "XBL Proto Method");
-    checkMayTamper(proto, 'prop', "XBL Proto Prop");
-    checkMayTamper(proto, 'primitiveField', "XBL Field Accessor");
-
-    // Tamper with the derived object. This doesn't affect the XBL scope thanks
-    // to Xrays.
-    bound.method = function() { return "heh"; };
-    Object.defineProperty(bound, 'method', {value: function() { return "hah" }});
-    Object.defineProperty(bound, 'prop', {value: "redefined"});
-    bound.primitiveField = 321;
-
-    // Untrusted events should not trigger event handlers without
-    // exposeToUntrustedContent=true.
-    window.triggeredTrustedHandler = false;
-    var untrustedEvent = new CustomEvent('testtrusted');
-    is(untrustedEvent.type, 'testtrusted', "Constructor should see type");
-    bound.dispatchEvent(untrustedEvent);
-    ok(!window.triggeredTrustedHandler, "untrusted events should not trigger trusted handler");
-    var trustedEvent = new CustomEvent('testtrusted');
-    is(trustedEvent.type, 'testtrusted', "Wrapped constructor should see type");
-    SpecialPowers.wrap(bound).dispatchEvent(trustedEvent); // Dispatch over SpecialPowers to make the event trusted.
-    ok(window.triggeredTrustedHandler, "trusted events should trigger trusted handler");
-
-    //
-    // We check key events as well, since they're implemented differently.
-    //
-    // NB: We don't check isTrusted on the events we create here, because
-    // according to smaug, old-style event initialization doesn't mark the
-    // event as trusted until it's dispatched.
-    //
-
-    window.triggeredUntrustedKeyHandler = false;
-    window.triggeredTrustedKeyHandler = false;
-
-    // Untrusted event, permissive handler.
-    var untrustedKeyEvent = document.createEvent('KeyboardEvent');
-    untrustedKeyEvent.initEvent('keyup', true, true);
-    bound.dispatchEvent(untrustedKeyEvent);
-    ok(window.triggeredUntrustedKeyHandler, "untrusted key events should trigger untrusted handler");
-
-    // Untrusted event, strict handler.
-    var fakeTrustedKeyEvent = document.createEvent('KeyboardEvent');
-    fakeTrustedKeyEvent.initEvent('keydown', true, true);
-    bound.dispatchEvent(fakeTrustedKeyEvent);
-    ok(!window.triggeredTrustedKeyHandler, "untrusted key events should not trigger trusted handler");
-
-    // Trusted event, strict handler. Dispatch using SpecialPowers to make the event trusted.
-    var trustedKeyEvent = document.createEvent('KeyboardEvent');
-    trustedKeyEvent.initEvent('keydown', true, true);
-    SpecialPowers.wrap(bound).dispatchEvent(trustedKeyEvent);
-    ok(window.triggeredTrustedKeyHandler, "trusted key events should trigger trusted handler");
-
-    // Hand control back to the XBL scope by dispatching an event on the bound element.
-    bound.dispatchEvent(new CustomEvent('testevent'));
-  }
-
-  function checkThrows(fn) {
-    try { fn(); ok(false, "Should have thrown"); }
-    catch (e) { ok(!!/denied|insecure/.exec(e), "Should have thrown security exception: " + e); }
-  }
-
-  function checkAllowed(fn, desc) {
-    try { fn(); ok(true, desc + ": Didn't throw"); }
-    catch (e) { ok(false, desc + ": Threw: " + e); }
-  }
-
-  function setup() {
-    // When the bindings are applied, the constructor will be invoked and the
-    // test will continue.
-    document.getElementById('bound').style.MozBinding = 'url(#testBinding)';
-    document.getElementById('bound2').style.MozBinding = 'url(#testBinding)';
-    document.getElementById('bound3').style.MozBinding = 'url(#testBinding)';
-  }
-
-  ]]>
-</script>
-</head>
-<body onload="setup()">
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=821850">Mozilla Bug 821850</a>
-<p id="display"></p>
-<div id="content">
-  <div id="bound">Bound element</div>
-  <div id="bound2">Bound element</div>
-  <span id="bound3">Bound element</span>
-  <img/>
-</div>
-<pre id="test">
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/dom/xbl/test/file_bug944407.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE html>
-<html>
-<body>
-<div id="deny" style="-moz-binding: url(file_bug944407.xml#testAllowScript)"></div>
-<div id="allow" style="-moz-binding: url(chrome://mochitests/content/chrome/dom/xbl/test/file_bug944407.xml#testAllowScript)"</div>
-<script>/* Flush layout with a script tab - see bug 944407 comment 37. */</script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/xbl/test/file_bug944407.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version="1.0"?>
-<bindings id="testBindings" xmlns="http://www.mozilla.org/xbl"
-          xmlns:html="http://www.w3.org/1999/xhtml">
-  <binding id="testAllowScript" bindToUntrustedContent="true">
-    <implementation>
-       <property name="someProp" onget="return 2;" readonly="true"></property>
-       <method name="someMethod"><body> return 3; </body></method>
-       <method name="startTest">
-         <body>
-         <![CDATA[
-           // Make sure we only get constructed when we're loaded from a domain
-           // with script enabled.
-           is(this.id, 'allow', "XBL should only be bound when the origin of the binding allows scripts");
-
-           var t = this;
-           doFinish = function() {
-             // Take a moment to make sure that other constructors don't run when they shouldn't.
-             if (t.id == 'allow')
-               setTimeout(SpecialPowers.wrap(window.parent).finish, 100);
-           }
-
-           onTestEvent = function(target) {
-             ok(true, 'called event handler');
-
-             // Try calling event handlers on anonymous content.
-             var e = new MouseEvent('click');
-             document.getAnonymousNodes(target)[1].dispatchEvent(e);
-             ok(window.calledEventHandlerOnAC, "Should invoke event handler on AC");
-
-             // Now, dispatch a key event to test key handlers and move the test along.
-             var k = document.createEvent('KeyboardEvent');
-             k.initEvent('keyup', true, true);
-             target.dispatchEvent(k);
-           }
-
-           // Check the implementation.
-           is(this.someProp, 2, "Properties work");
-           is(this.someMethod(), 3, "Methods work");
-
-           // Kick over to the event handlers. This tests XBL event handlers,
-           // XBL key handlers, and event handlers on anonymous content.
-           this.dispatchEvent(new CustomEvent('testEvent'));
-         ]]>
-         </body>
-       </method>
-
-      <constructor>
-      <![CDATA[
-        win = XPCNativeWrapper.unwrap(window);
-        SpecialPowers = win.SpecialPowers;
-        ok = win.ok = SpecialPowers.wrap(window.parent).ok;
-        is = win.is = SpecialPowers.wrap(window.parent).is;
-        info = win.info = SpecialPowers.wrap(window.parent).info;
-
-        info("Invoked constructor for " + this.id);
-
-        var t = this;
-        window.addEventListener('load', function() {
-          // Wait two refresh-driver ticks to make sure that the constructor runs
-          // for both |allow| and |deny| if it's ever going to.
-          //
-          // See bug 944407 comment 37.
-          info("Invoked load listener for " + t.id);
-          window.requestAnimationFrame(function() { window.requestAnimationFrame(t.startTest.bind(t)); });
-        }, {once: true});
-      ]]>
-      </constructor>
-    </implementation>
-    <handlers>
-      <handler event="testEvent" action="onTestEvent(this)" allowuntrusted="true"/>
-      <handler event="keyup" action="ok(true, 'called key handler'); doFinish();" allowuntrusted="true"/>
-    </handlers>
-    <content>Anonymous Content<html:div onclick="window.calledEventHandlerOnAC = true;"></html:div><html:b style="display:none"><children/></html:b></content>
-  </binding>
-</bindings>
--- a/dom/xbl/test/file_bug950909.xml
+++ b/dom/xbl/test/file_bug950909.xml
@@ -1,20 +1,17 @@
 <?xml version="1.0"?>
 <bindings id="chromeTestBindings" xmlns="http://www.mozilla.org/xbl">
   <binding id="testBinding" bindToUntrustedContent="true">
     <implementation implements="nsIObserver">
       <constructor>
       <![CDATA[
-        // This binding gets applied to a content object, and thus is actually
-        // running in a content XBL scope.
-        var win = XPCNativeWrapper.unwrap(window);
+        var win = window;
         var SpecialPowers = win.SpecialPowers;
         var ok = SpecialPowers.unwrap(SpecialPowers.wrap(window).parent.ok);
-        ok(win != window, "Should be running in an XBL scope with Xrays");
 
         // Generate an XPCWrappedJS for the reflector. We need to do this
         // explicitly with a testing helper, because we're converging on
         // removing XPConnect from the web, which means that it won't be
         // possible to generate an XPCWrappedJS from content (or XBL) code.
         var scope = {};
         var holder = SpecialPowers.Cu.generateXPCWrappedJS(this, scope);
 
--- a/dom/xbl/test/mochitest.ini
+++ b/dom/xbl/test/mochitest.ini
@@ -7,20 +7,17 @@ support-files =
   file_bug379959_cross.html
   file_bug379959_data.html
   file_bug379959_xbl.xml
   file_bug397934.xhtml
   file_bug481558.xbl
   file_bug481558css.sjs
   file_bug591198_inner.html
   file_bug591198_xbl.xml
-  file_bug821850.xhtml
   file_bug844783.xhtml
-  file_bug944407.html
-  file_bug944407.xml
   file_bug950909.html
 
 [test_bug310107.html]
 [test_bug366770.html]
 [test_bug371724.xhtml]
 [test_bug372769.html]
 [test_bug378866.xhtml]
 [test_bug379959.html]
@@ -31,14 +28,12 @@ support-files =
 [test_bug403162.xhtml]
 [test_bug468210.xhtml]
 [test_bug481558.html]
 [test_bug526178.xhtml]
 [test_bug542406.xhtml]
 [test_bug591198.html]
 [test_bug639338.xhtml]
 [test_bug790265.xhtml]
-[test_bug821850.html]
 [test_bug844783.html]
 [test_bug872273.xhtml]
-[test_bug1086996.xhtml]
 [test_bug1098628_throw_from_construct.xhtml]
 [test_bug1359859.xhtml]
--- a/dom/xbl/test/test_bug1086996.xhtml
+++ b/dom/xbl/test/test_bug1086996.xhtml
@@ -3,17 +3,17 @@
 https://bugzilla.mozilla.org/show_bug.cgi?id=1086996
 -->
 <head>
   <bindings xmlns="http://www.mozilla.org/xbl"
             xmlns:html="http://www.w3.org/1999/xhtml">
     <binding id="handlerBinding">
       <implementation>
         <constructor>
-          <![CDATA[XPCNativeWrapper.unwrap(window).constructedHandlerBinding();]]>
+          <![CDATA[window.constructedHandlerBinding();]]>
         </constructor>
       </implementation>
       <handlers>
         <handler event="testevent" action="XPCNativeWrapper.unwrap(window).gotEvent();" allowuntrusted="true"/>
       </handlers>
     </binding>
     <binding id="mainBinding">
       <content>
@@ -24,18 +24,18 @@ https://bugzilla.mozilla.org/show_bug.cg
           <body>
             <![CDATA[document.getAnonymousNodes(this)[0].dispatchEvent(new CustomEvent('testevent'));]]>
           </body>
         </method>
       </implementation>
     </binding>
   </bindings>
   <title>Test for Bug 1086996</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1086996">Mozilla Bug 1086996</a>
 <div id="content" style="display: none">
 </div>
 <pre id="test">
 <script type="application/javascript">
 <![CDATA[
--- a/dom/xbl/test/test_bug1098628_throw_from_construct.xhtml
+++ b/dom/xbl/test/test_bug1098628_throw_from_construct.xhtml
@@ -16,16 +16,17 @@ https://bugzilla.mozilla.org/show_bug.cg
     SimpleTest.executeSoon(SimpleTest.endMonitorConsole);
   });
   ]]>
   </script>
   <bindings xmlns="http://www.mozilla.org/xbl">
     <binding id="test">
       <implementation>
         <constructor><![CDATA[
+          SimpleTest.expectUncaughtException();
           throw "flimfniffle";
         ]]></constructor>
       </implementation>
     </binding>
   </bindings>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1098628">Mozilla Bug 1098628</a>
--- a/dom/xbl/test/test_bug1359859.xhtml
+++ b/dom/xbl/test/test_bug1359859.xhtml
@@ -4,21 +4,25 @@
   -->
   <head>
     <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
     <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
     <bindings xmlns="http://www.mozilla.org/xbl">
       <binding id="testBinding">
         <implementation>
           <constructor>
-            XPCNativeWrapper.unwrap(window).running();
+            window.running();
             this.constructed = true;
+            SimpleTest.expectUncaughtException();
             throw new Error("Constructor threw");
           </constructor>
-          <field name="throwingField">throw new Error("field threw")</field>
+          <field name="throwingField">
+            SimpleTest.expectUncaughtException();
+            throw new Error("field threw")
+          </field>
           <field name="normalField">"hello"</field>
         </implementation>
       </binding>
     </bindings>
     <script>
       // We need to wait for the binding to load.
       SimpleTest.waitForExplicitFinish();
       function running() {
--- a/dom/xbl/test/test_bug389322.xhtml
+++ b/dom/xbl/test/test_bug389322.xhtml
@@ -12,61 +12,61 @@ https://bugzilla.mozilla.org/show_bug.cg
       <implementation>
         <field name="field"><![CDATA[
           (function () {
              try {
                eval("let x = 1;");
                var success = true;
              }
              catch (e) { success = false; }
-             XPCNativeWrapper.unwrap(window).report("XBL fields", success)
+             window.report("XBL fields", success)
              return ""
            }())
         ]]></field>
         <property name="property">
           <getter><![CDATA[
              try {
                eval("let x = 1;");
                var success = true;
              }
              catch (e) { success = false; }
-             XPCNativeWrapper.unwrap(window).report("XBL property getters", success)
+             window.report("XBL property getters", success)
              return 1
            ]]></getter>
           <setter><![CDATA[
             try {
               eval("let x = 1;");
               var success = true
             }
             catch (e) { success = false }
-            XPCNativeWrapper.unwrap(window).report("XBL property setters", success)
+            window.report("XBL property setters", success)
             return val
           ]]></setter>
         </property>
         <method name="method">
           <body><![CDATA[
             try {
               eval("let x = 1;");
               var success = true;
 
             }
             catch (e) { success = false; }
-            XPCNativeWrapper.unwrap(window).report("XBL methods", success)
+            window.report("XBL methods", success)
           ]]></body>
         </method>
         <constructor><![CDATA[
           this.property += 1
           var x = this.field;
           this.method()
           try {
             eval("let x = 1;");
             var success = true
           }
           catch (e) { success = false }
-          var win = XPCNativeWrapper.unwrap(window);
+          var win = window;
           win.report("XBL constructors", success)
         
           var ev = document.createEvent("Events")
           ev.initEvent("custom", false, false)
           this.dispatchEvent(ev)
           win.ctorRan = true;
         ]]></constructor>
       </implementation>
--- a/dom/xbl/test/test_bug400705.xhtml
+++ b/dom/xbl/test/test_bug400705.xhtml
@@ -4,18 +4,18 @@ https://bugzilla.mozilla.org/show_bug.cg
 -->
 <head>
   <title>Test for Bug 400705</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
   <bindings xmlns="http://www.mozilla.org/xbl">
     <binding id="test">
       <implementation>
-        <field name="a">XPCNativeWrapper.unwrap(window).countera++</field>
-        <field name="b">XPCNativeWrapper.unwrap(window).counterb++</field>
+        <field name="a">window.countera++</field>
+        <field name="b">window.counterb++</field>
       </implementation>
     </binding>
   </bindings>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=400705">Mozilla Bug 400705</a>
 <p id="display" style="-moz-binding: url(#test)"></p>
 <div id="content" style="display: none">
--- a/dom/xbl/test/test_bug401907.xhtml
+++ b/dom/xbl/test/test_bug401907.xhtml
@@ -6,29 +6,29 @@ https://bugzilla.mozilla.org/show_bug.cg
 <head>
   <title>Test for Bug 401907</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
   <bindings xmlns="http://www.mozilla.org/xbl">
     <binding id="binding">
       <implementation>
         <constructor>
-          var win = XPCNativeWrapper.unwrap(window);
+          var win = window;
           win.ok(true, "First binding with ID 'binding' should be used!");
           win.testRun = true;
           if (win.needsFinish) {
             win.SimpleTest.finish();
           }
         </constructor>
       </implementation>
     </binding>
     <binding id="binding">
       <implementation>
         <constructor>
-          var win = XPCNativeWrapper.unwrap(window);
+          var win = window;
           win.ok(false, "First binding with ID 'binding' should be used!");
           win.testRun = true;
           if (win.needsFinish) {
             win.SimpleTest.finish();
           }
         </constructor>
       </implementation>
     </binding>
--- a/dom/xbl/test/test_bug403162.xhtml
+++ b/dom/xbl/test/test_bug403162.xhtml
@@ -4,17 +4,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 -->
 <head>
   <title>Test for Bug 403162</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
   <bindings xmlns="http://www.mozilla.org/xbl">
     <binding id="test">
       <handlers>
-        <handler event="foo" action="XPCNativeWrapper.unwrap(window).triggerCount++" allowuntrusted="true"/>
+        <handler event="foo" action="window.triggerCount++" allowuntrusted="true"/>
       </handlers>
     </binding>
   </bindings>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=403162">Mozilla Bug 403162</a>
 <p id="display" style="-moz-binding: url(#test)"></p>
 <div id="content" style="display: none">
--- a/dom/xbl/test/test_bug526178.xhtml
+++ b/dom/xbl/test/test_bug526178.xhtml
@@ -11,17 +11,17 @@ https://bugzilla.mozilla.org/show_bug.cg
       display: block;
       -moz-binding: url("#binding");
     }
   </style>
   <bindings xmlns="http://www.mozilla.org/xbl">
     <binding id="binding">
       <implementation>
         <constructor>
-          var win = XPCNativeWrapper.unwrap(window);
+          var win = window;
           win.logString += this.localName;
           win.bindingDone();
         </constructor>
       </implementation>
     </binding>
   </bindings>
 </head>
 <body>
--- a/dom/xbl/test/test_bug639338.xhtml
+++ b/dom/xbl/test/test_bug639338.xhtml
@@ -4,19 +4,19 @@ https://bugzilla.mozilla.org/show_bug.cg
 -->
 <head>
   <title>Test for Bug 639338</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
   <bindings xmlns="http://www.mozilla.org/xbl">
     <binding id="test">
       <handlers>
-        <handler event="DOMMouseScroll" action="XPCNativeWrapper.unwrap(window).triggerCount++" allowuntrusted="true"/>
-        <handler event="DOMMouseScroll" modifiers="shift" action="XPCNativeWrapper.unwrap(window).shiftCount++" allowuntrusted="true"/>
-        <handler event="DOMMouseScroll" modifiers="control" action="XPCNativeWrapper.unwrap(window).controlCount++" allowuntrusted="true"/>
+        <handler event="DOMMouseScroll" action="window.triggerCount++" allowuntrusted="true"/>
+        <handler event="DOMMouseScroll" modifiers="shift" action="window.shiftCount++" allowuntrusted="true"/>
+        <handler event="DOMMouseScroll" modifiers="control" action="window.controlCount++" allowuntrusted="true"/>
       </handlers>
     </binding>
   </bindings>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=639338">Mozilla Bug 639338</a>
 <p id="display" style="-moz-binding: url(#test)"></p>
 <div id="content" style="display: none">
deleted file mode 100644
--- a/dom/xbl/test/test_bug821850.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=821850
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 821850</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <script type="application/javascript">
-
-  /** Test for XBL scope behavior. **/
-  SimpleTest.waitForExplicitFinish();
-
-  // Embed the real test. It will take care of everything else.
-  //
-  // NB: This two-layer setup used to exist because XBL scopes were behind a
-  // pref, and we wanted to make sure that we properly set the pref before
-  // loading the real test. This stuff is no longer behind a pref, but we just
-  // leave the structure as-is for expediency.
-  function setup() {
-    $('ifr').setAttribute('src', 'file_bug821850.xhtml');
-  }
-
-  </script>
-</head>
-<body onload="setup();">
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=821850">Mozilla Bug 821850</a>
-<p id="display"></p>
-<div id="content">
-<iframe id="ifr"></iframe>
-</div>
-<pre id="test">
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/dom/xbl/test/test_bug944407.xul
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
-<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=944407
--->
-<window title="Mozilla Bug 944407"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
-
-  <!-- test results are displayed in the html:body -->
-  <body xmlns="http://www.w3.org/1999/xhtml">
-  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=944407"
-     target="_blank">Mozilla Bug 944407</a>
-  </body>
-
-  <!-- test code goes here -->
-  <script type="application/javascript">
-  <![CDATA[
-
-  /** Test for XBL bindings with script disabled. **/
-  SimpleTest.waitForExplicitFinish();
-  const {Services} = ChromeUtils.import('resource://gre/modules/Services.jsm');
-
-  function go() {
-
-    // Disable javascript, and load the frame.
-    function loadFrame() {
-      ok(!Services.prefs.getBoolPref('javascript.enabled'), "Javascript should be disabled");
-      $('ifr').setAttribute('src', 'http://mochi.test:8888/tests/dom/xbl/test/file_bug944407.html');
-    }
-    SpecialPowers.pushPrefEnv({ set: [['javascript.enabled', false]] }, loadFrame);
-  }
-
-  function finish() {
-    SimpleTest.finish();
-  }
-
-  addLoadEvent(go);
-  ]]>
-  </script>
-  <iframe id='ifr' />
-</window>
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -632,16 +632,27 @@ void SetCompartmentChangedDocumentDomain
     priv->originInfo.SetChangedDocumentDomain();
   }
 }
 
 JSObject* UnprivilegedJunkScope() {
   return XPCJSRuntime::Get()->UnprivilegedJunkScope();
 }
 
+JSObject* NACScope(JSObject* global) {
+  // If we're a chrome global, just use ourselves.
+  if (AccessCheck::isChrome(global)) {
+    return global;
+  }
+
+  JSObject* scope = UnprivilegedJunkScope();
+  JS::ExposeObjectToActiveJS(scope);
+  return scope;
+}
+
 JSObject* PrivilegedJunkScope() { return XPCJSRuntime::Get()->LoaderGlobal(); }
 
 JSObject* CompilationScope() { return XPCJSRuntime::Get()->LoaderGlobal(); }
 
 nsGlobalWindowInner* WindowOrNull(JSObject* aObj) {
   MOZ_ASSERT(aObj);
   MOZ_ASSERT(!js::IsWrapper(aObj));
 
--- a/js/xpconnect/src/XPCWrappedNativeScope.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp
@@ -74,25 +74,21 @@ XPCWrappedNativeScope::XPCWrappedNativeS
   mNext = gScopes;
   gScopes = this;
 
   MOZ_COUNT_CTOR(XPCWrappedNativeScope);
 
   // Determine whether we would allow an XBL scope in this situation.
   // In addition to being pref-controlled, we also disable XBL scopes for
   // remote XUL domains, _except_ if we have an additional pref override set.
+  //
+  // Note that we can't quite remove this yet, even though we never actually
+  // use XBL scopes, because some code (including the security manager) uses
+  // this boolean to make decisions that we rely on in our test infrastructure.
   mAllowContentXBLScope = !RemoteXULForbidsXBLScope(aFirstGlobal);
-
-  // Determine whether to use an XBL scope.
-  mUseContentXBLScope = mAllowContentXBLScope;
-  if (mUseContentXBLScope) {
-    const js::Class* clasp = js::GetObjectClass(aFirstGlobal);
-    mUseContentXBLScope =
-        !AccessCheck::isChrome(mCompartment) && !strcmp(clasp->name, "Window");
-  }
 }
 
 // static
 bool XPCWrappedNativeScope::IsDyingScope(XPCWrappedNativeScope* scope) {
   for (XPCWrappedNativeScope* cur = gDyingScopes; cur; cur = cur->mNext) {
     if (scope == cur) {
       return true;
     }
@@ -201,68 +197,20 @@ bool XPCWrappedNativeScope::AttachCompon
 
 JSObject* XPCWrappedNativeScope::EnsureContentXBLScope(JSContext* cx) {
   JS::RootedObject global(cx, CurrentGlobalOrNull(cx));
   MOZ_ASSERT(js::IsObjectInContextCompartment(global, cx));
   MOZ_ASSERT(!IsContentXBLScope());
   MOZ_ASSERT(strcmp(js::GetObjectClass(global)->name,
                     "nsXBLPrototypeScript compilation scope"));
 
-  // If this scope doesn't need an XBL scope, just return the global.
-  if (!mUseContentXBLScope) {
-    return global;
-  }
-
-  // Given the status of in-content XBL, release assert we have a single realm
-  // for now so we don't have to worry about the multiple-realms case.
-  // See bug 1515582.
-  js::AssertCompartmentHasSingleRealm(Compartment());
-
-  // If we already have a special XBL scope object, we know what to use.
-  if (mContentXBLScope) {
-    return mContentXBLScope;
-  }
-
-  // Set up the sandbox options. Note that we use the DOM global as the
-  // sandboxPrototype so that the XBL scope can access all the DOM objects
-  // it's accustomed to accessing.
-  //
-  // In general wantXrays shouldn't matter much here, but there are weird
-  // cases when adopting bound content between same-origin globals where a
-  // <destructor> in one content XBL scope sees anonymous content in another
-  // content XBL scope. When that happens, we hit LookupBindingMember for an
-  // anonymous element that lives in a content XBL scope, which isn't a tested
-  // or audited codepath. So let's avoid hitting that case by opting out of
-  // same-origin Xrays.
-  SandboxOptions options;
-  options.wantXrays = false;
-  options.wantComponents = false;
-  options.proto = global;
-  options.sameZoneAs = global;
-  options.isContentXBLScope = true;
-
-  // Use an ExpandedPrincipal to create asymmetric security.
-  nsIPrincipal* principal = xpc::GetObjectPrincipal(global);
-  MOZ_ASSERT(!nsContentUtils::IsExpandedPrincipal(principal));
-  nsTArray<nsCOMPtr<nsIPrincipal>> principalAsArray(1);
-  principalAsArray.AppendElement(principal);
-  RefPtr<ExpandedPrincipal> ep = ExpandedPrincipal::Create(
-      principalAsArray, principal->OriginAttributesRef());
-
-  // Create the sandbox.
-  RootedValue v(cx);
-  nsresult rv = CreateSandboxObject(
-      cx, &v, static_cast<nsIExpandedPrincipal*>(ep), options);
-  NS_ENSURE_SUCCESS(rv, nullptr);
-  mContentXBLScope = &v.toObject();
-
-  MOZ_ASSERT(xpc::IsInContentXBLScope(js::UncheckedUnwrap(mContentXBLScope)));
-
-  // Good to go!
-  return mContentXBLScope;
+  // We can probably remove EnsureContentXBLScope and clean up all its callers,
+  // but a bunch (all?) of those callers will just go away when we remove XBL
+  // support, so it's simpler to just leave it here as a no-op.
+  return global;
 }
 
 bool XPCWrappedNativeScope::AllowContentXBLScope(Realm* aRealm) {
   // We only disallow XBL scopes in remote XUL situations.
   MOZ_ASSERT_IF(!mAllowContentXBLScope, nsContentUtils::AllowXULXBLForPrincipal(
                                             xpc::GetRealmPrincipal(aRealm)));
   return mAllowContentXBLScope;
 }
@@ -304,26 +252,16 @@ JSObject* GetUAWidgetScope(JSContext* cx
 }
 
 bool AllowContentXBLScope(JS::Realm* realm) {
   JS::Compartment* comp = GetCompartmentForRealm(realm);
   XPCWrappedNativeScope* scope = CompartmentPrivate::Get(comp)->scope;
   return scope && scope->AllowContentXBLScope(realm);
 }
 
-bool UseContentXBLScope(JS::Realm* realm) {
-  JS::Compartment* comp = GetCompartmentForRealm(realm);
-  XPCWrappedNativeScope* scope = CompartmentPrivate::Get(comp)->scope;
-  return scope && scope->UseContentXBLScope();
-}
-
-void ClearContentXBLScope(JSObject* global) {
-  CompartmentPrivate::Get(global)->scope->ClearContentXBLScope();
-}
-
 } /* namespace xpc */
 
 XPCWrappedNativeScope::~XPCWrappedNativeScope() {
   MOZ_COUNT_DTOR(XPCWrappedNativeScope);
 
   // We can do additional cleanup assertions here...
 
   MOZ_ASSERT(0 == mWrappedNativeMap->Count(), "scope has non-empty map");
@@ -409,33 +347,21 @@ void XPCWrappedNativeScope::UpdateWeakPo
 
   if (!js::IsCompartmentZoneSweepingOrCompacting(mCompartment)) {
     return;
   }
 
   // Update our pointer to the compartment in case we finalized all globals.
   if (js::gc::AllRealmsNeedSweep(mCompartment)) {
     mCompartment = nullptr;
-    JSContext* cx = dom::danger::GetJSContext();
-    mContentXBLScope.finalize(cx);
     GetWrappedNativeMap()->Clear();
     mWrappedNativeProtoMap->Clear();
     return;
   }
 
-#ifdef DEBUG
-  // These are traced, so no updates are necessary.
-  if (mContentXBLScope) {
-    JSObject* prev = mContentXBLScope.unbarrieredGet();
-    mContentXBLScope.updateWeakPointerAfterGC();
-    MOZ_ASSERT(prev == mContentXBLScope.unbarrieredGet());
-    MOZ_ASSERT_IF(prev, js::GetObjectCompartment(prev) == mCompartment);
-  }
-#endif
-
   // Sweep mWrappedNativeMap for dying flat JS objects. Moving has already
   // been handled by XPCWrappedNative::FlatJSObjectMoved.
   for (auto iter = GetWrappedNativeMap()->Iter(); !iter.Done(); iter.Next()) {
     auto entry = static_cast<Native2WrappedNativeMap::Entry*>(iter.Get());
     XPCWrappedNative* wrapper = entry->value;
     JSObject* obj = wrapper->GetFlatJSObjectPreserveColor();
     JS_UpdateWeakPointerAfterGCUnbarriered(&obj);
     MOZ_ASSERT(!obj || obj == wrapper->GetFlatJSObjectPreserveColor());
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -837,19 +837,16 @@ class XPCWrappedNativeScope final {
   bool SetExpandoChain(JSContext* cx, JS::HandleObject target,
                        JS::HandleObject chain);
 
   static void SystemIsBeingShutDown();
 
   static void TraceWrappedNativesInAllScopes(JSTracer* trc);
 
   void TraceInside(JSTracer* trc) {
-    if (mContentXBLScope) {
-      mContentXBLScope.trace(trc, "XPCWrappedNativeScope::mXBLScope");
-    }
     if (mXrayExpandos.initialized()) {
       mXrayExpandos.trace(trc);
     }
     if (mIDProto) {
       mIDProto.trace(trc, "XPCWrappedNativeScope::mIDProto");
     }
     if (mIIDProto) {
       mIIDProto.trace(trc, "XPCWrappedNativeScope::mIIDProto");
@@ -910,18 +907,16 @@ class XPCWrappedNativeScope final {
   JSObject* GetGlobalForWrappedNatives() {
     return js::GetFirstGlobalInCompartment(Compartment());
   }
 
   bool IsContentXBLScope() {
     return xpc::IsContentXBLCompartment(Compartment());
   }
   bool AllowContentXBLScope(JS::Realm* aRealm);
-  bool UseContentXBLScope() { return mUseContentXBLScope; }
-  void ClearContentXBLScope() { mContentXBLScope = nullptr; }
 
   // ID Object prototype caches.
   JS::ObjectPtr mIDProto;
   JS::ObjectPtr mIIDProto;
   JS::ObjectPtr mCIDProto;
 
  protected:
   virtual ~XPCWrappedNativeScope();
@@ -933,36 +928,22 @@ class XPCWrappedNativeScope final {
   static XPCWrappedNativeScope* gDyingScopes;
 
   Native2WrappedNativeMap* mWrappedNativeMap;
   ClassInfo2WrappedNativeProtoMap* mWrappedNativeProtoMap;
   RefPtr<nsXPCComponentsBase> mComponents;
   XPCWrappedNativeScope* mNext;
   JS::Compartment* mCompartment;
 
-  // XBL Scope. This is is a lazily-created sandbox for non-system scopes.
-  // EnsureContentXBLScope() decides whether it needs to be created or not.
-  // This reference is wrapped into the compartment of mGlobalJSObject.
-  JS::ObjectPtr mContentXBLScope;
-
   JS::WeakMapPtr<JSObject*, JSObject*> mXrayExpandos;
 
   // For remote XUL domains, we run all XBL in the content scope for compat
-  // reasons (though we sometimes pref this off for automation). We separately
-  // track the result of this decision (mAllowContentXBLScope), from the
-  // decision of whether to actually _use_ an XBL scope (mUseContentXBLScope),
-  // which depends on the type of global and whether the compartment is system
-  // principal or not.
-  //
-  // This distinction is useful primarily because, if true, we know that we
-  // have no way of distinguishing XBL script from content script for the
-  // given scope. In these (unsupported) situations, we just always claim to
-  // be XBL.
+  // reasons (though we sometimes pref this off for automation). We
+  // track the result of this decision (mAllowContentXBLScope) for now.
   bool mAllowContentXBLScope;
-  bool mUseContentXBLScope;
 };
 
 /***************************************************************************/
 // Slots we use for our functions
 #define XPC_FUNCTION_NATIVE_MEMBER_SLOT 0
 #define XPC_FUNCTION_PARENT_OBJECT_SLOT 1
 
 /***************************************************************************/
--- a/js/xpconnect/src/xpcpublic.h
+++ b/js/xpconnect/src/xpcpublic.h
@@ -124,25 +124,19 @@ inline JSObject* GetXBLScopeOrGlobal(JSC
   }
   return GetXBLScope(cx, obj);
 }
 
 // Returns whether XBL scopes have been explicitly disabled for code running
 // in this compartment. See the comment around mAllowContentXBLScope.
 bool AllowContentXBLScope(JS::Realm* realm);
 
-// Returns whether we will use an XBL scope for this realm. This is
-// semantically equivalent to comparing global != GetXBLScope(global), but it
-// does not have the side-effect of eagerly creating the XBL scope if it does
-// not already exist.
-bool UseContentXBLScope(JS::Realm* realm);
-
-// Clear out the content XBL scope (if any) on the given global.  This will
-// force creation of a new one if one is needed again.
-void ClearContentXBLScope(JSObject* global);
+// Get the scope for creating reflectors for native anonymous content
+// whose normal global would be the given global.
+JSObject* NACScope(JSObject* global);
 
 bool IsSandboxPrototypeProxy(JSObject* obj);
 
 // The JSContext argument represents the Realm that's asking the question.  This
 // is needed to properly answer without exposing information unnecessarily
 // from behind security wrappers.  There will be no exceptions thrown on this
 // JSContext.
 bool IsReflector(JSObject* obj, JSContext* cx);
--- a/js/xpconnect/tests/mochitest/mochitest.ini
+++ b/js/xpconnect/tests/mochitest/mochitest.ini
@@ -99,15 +99,14 @@ support-files =
 [test_crosscompartment_weakmap.html]
 [test_frameWrapping.html]
 # The JS test component we use below is only available in debug builds.
 [test_getWebIDLCaller.html]
 skip-if = (debug == false)
 [test_getweakmapkeys.html]
 [test_paris_weakmap_keys.html]
 skip-if = (debug == false)
-[test_nac.xhtml]
 [test_nukeContentWindow.html]
 [test_sameOriginPolicy.html]
 [test_sandbox_fetch.html]
   support-files =
     ../../../../dom/tests/mochitest/fetch/test_fetch_basic.js
 [test_weakmaps.html]
deleted file mode 100644
--- a/js/xpconnect/tests/mochitest/test_nac.xhtml
+++ /dev/null
@@ -1,64 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=914618
--->
-<head>
-  <title>Test for Bug 914618</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <bindings xmlns="http://www.mozilla.org/xbl"
-            xmlns:html="http://www.w3.org/1999/xhtml">
-    <binding id="testBinding" chromeOnlyContent="true">
-      <!-- The root of the anonymous subtree is special, and is not allowed to
-           be adopted, among other things. Work with a child of the root. -->
-      <content><html:div><html:span id="nac">hidden text</html:span></html:div></content>
-      <implementation>
-        <constructor>
-          var win = XPCNativeWrapper.unwrap(window);
-          var nac = document.getAnonymousNodes(this)[0].firstChild;
-          win.is(nac.textContent, "hidden text", "XBL can see NAC");
-          win.playWithNAC(nac);
-        </constructor>
-      </implementation>
-    </binding>
-  </bindings>
-  <script type="application/javascript">
-  <![CDATA[
-
-  /** Test for Bug 914618 **/
-  SimpleTest.waitForExplicitFinish();
-
-  function checkThrows(fn) {
-    try {
-      fn();
-      ok(false, "Should have thrown");
-    } catch (e) {
-      ok(/denied|insecure|/.test(e), "Should have thrown security error");
-    }
-  }
-
-  function playWithNAC(nac) {
-    checkThrows(function() { nac.toString(); });
-    checkThrows(function() { nac.textContent; });
-    var iwin = document.getElementById('ifr').contentWindow;
-    iwin.nac = window.nac = nac;
-    checkThrows(new iwin.Function('nac.toString();'));
-    checkThrows(new iwin.Function('nac.textContent;'));
-
-    SimpleTest.finish();
-  }
-
-  ]]>
-</script>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=914618">Mozilla Bug 914618</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-</div>
-<div id="bindingSink" style="-moz-binding: url(#testBinding);"></div>
-<iframe id="ifr"></iframe>
-<pre id="test">
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/bugs/495385-2f.xhtml
+++ /dev/null
@@ -1,50 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<!-- Test that suppression works (or is turned off) for XBL content -->
-<bindings xmlns="http://www.mozilla.org/xbl">
-  <binding id="before">
-    <content>Hello<children/></content>
-  </binding>
-  <binding id="after">
-    <content><children/>Kitty</content>
-  </binding>
-  <binding id="empty1">
-    <content><div xmlns="http://www.w3.org/1999/xhtml">Hello</div><children/></content>
-  </binding>
-  <binding id="empty2">
-    <content><children/><div xmlns="http://www.w3.org/1999/xhtml">Kitty</div></content>
-    <implementation>
-      <constructor>
-        // We used to do this in an onload handler, but getAnonymousNodes is no
-        // longer accessible to content, and we can't use SpecialPowers in
-        // reftests. So we enable XBL scopes and take advantage of the fact that XBL
-        // scopes can access these functions. We apply this binding
-        // programatically to make absolutely sure this constructor runs after all the
-        // other bindings have been set up.
-        document.body.offsetHeight;
-        document.getAnonymousNodes(document.getElementById("d3"))[0].style.display = 'inline';
-        document.getAnonymousNodes(document.getElementById("d4"))[2].style.display = 'inline';
-      </constructor>
-    </implementation>
-  </binding>
-</bindings>
-<style>
-body > div { border:1px solid black; margin:1em;
-             font-family:sans-serif; letter-spacing:2px; }
-#d1 { -moz-binding:url(#before); }
-#d2 { -moz-binding:url(#after); }
-#d3 { -moz-binding:url(#empty1); }
-</style>
-<script>
-function loaded() {
-  document.getElementById('d4').style.MozBinding = "url(#empty2)";
-}
-</script>
-</head>
-<body onload="loaded()">
-  <div id="d1"> <span>Kitty</span></div>
-  <div id="d2"><span>Hello</span> </div>
-  <div id="d3"> <span>Kitty</span></div>
-  <div id="d4"><span>Hello</span> </div>
-</body>
-</html>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1380,17 +1380,16 @@ random-if(/^Windows\x20NT\x206\.1/.test(
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 495385-1d.html 495385-1-ref.html # Bug 1392106
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 495385-1e.html 495385-1-ref.html # Bug 1392106
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 495385-1f.html 495385-1-ref.html # Bug 1392106
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 495385-2a.html 495385-2-ref.html # Bug 1392106
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 495385-2b.html 495385-2-ref.html # Bug 1392106
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 495385-2c.html 495385-2-ref.html # Bug 1392106
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 495385-2d.html 495385-2-ref.html # Bug 1392106
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 495385-2e.html 495385-2-ref.html # Bug 1392106
-pref(dom.use_xbl_scopes_for_remote_xul,true) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 495385-2f.xhtml 495385-2-ref.html # Bug 1392106
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 495385-2g.html 495385-2-ref.html # Bug 1392106
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 495385-2h.html 495385-2-ref.html # Bug 1392106
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 495385-2i.html 495385-2-ref.html # Bug 1392106
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 495385-3.html 495385-3-ref.html # Bug 1392106
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 495385-4.html 495385-4-ref.html # Bug 1392106
 == 496032-1.html 496032-1-ref.html
 == 496840-1.html 496840-1-ref.html
 == 501037.html 501037-ref.html
--- a/layout/xul/test/chrome.ini
+++ b/layout/xul/test/chrome.ini
@@ -22,16 +22,17 @@ support-files =
 skip-if = (verify && debug && (os == 'linux'))
 [test_bug398982-1.xul]
 [test_bug398982-2.xul]
 [test_bug467442.xul]
 [test_bug477754.xul]
 [test_bug703150.xul]
 [test_bug987230.xul]
 skip-if = os == 'linux' # No native mousedown event on Linux
+[test_bug1197913.xul]
 [test_popupReflowPos.xul]
 [test_popupSizeTo.xul]
 [test_popupZoom.xul]
 [test_resizer.xul]
 skip-if = (verify && (os == 'win'))
 [test_stack.xul]
 [test_submenuClose.xul]
 [test_windowminmaxsize.xul]
--- a/layout/xul/test/mochitest.ini
+++ b/layout/xul/test/mochitest.ini
@@ -1,13 +1,12 @@
 [DEFAULT]
 support-files =
   file_bug386386.sjs
 [test_bug386386.html]
 [test_bug394800.xhtml]
 [test_bug511075.html]
 skip-if = toolkit == 'android' #bug 798806
 [test_bug563416.html]
-[test_bug1197913.xul]
 skip-if = toolkit == 'android'
 [test_resizer_incontent.xul]
 [test_splitter.xul]
 skip-if = toolkit == 'android' # no XUL theme
--- a/layout/xul/test/test_bug1197913.xul
+++ b/layout/xul/test/test_bug1197913.xul
@@ -2,18 +2,18 @@
 <?xml-stylesheet type="text/css" href="chrome://global/skin"?>
 <?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
 <!--
 https://bugzilla.mozilla.org/show_bug.cgi?id=1197913
 -->
 <window title="Mozilla Bug 1197913"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         onload="SimpleTest.waitForFocus(nextTest, window)">
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"/>
-  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"/>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
 
 
   <!-- test results are displayed in the html:body -->
   <body xmlns="http://www.w3.org/1999/xhtml">
   <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1197913"
      target="_blank">Mozilla Bug 1197913</a>
   </body>