Bug 1444285, let custom element upgrades to use backup queue inside chrome/XBL, r=mrbkap
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Fri, 27 Apr 2018 02:08:27 +0300
changeset 472074 6825c9cd5bd5b98009d99384999a4de4945552ba
parent 472073 2321cd280739952a9481a1ad96008aeb3d0a0bd7
child 472075 2f1e8f0e6b5316f9119a7111100af50c4b7025af
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs1444285
milestone61.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 1444285, let custom element upgrades to use backup queue inside chrome/XBL, r=mrbkap
dom/base/CustomElementRegistry.cpp
dom/base/CustomElementRegistry.h
--- a/dom/base/CustomElementRegistry.cpp
+++ b/dom/base/CustomElementRegistry.cpp
@@ -23,19 +23,17 @@ namespace dom {
 // CustomElementUpgradeReaction
 
 class CustomElementUpgradeReaction final : public CustomElementReaction
 {
 public:
   explicit CustomElementUpgradeReaction(CustomElementDefinition* aDefinition)
     : mDefinition(aDefinition)
   {
-#if DEBUG
     mIsUpgradeReaction = true;
-#endif
   }
 
 private:
   virtual void Invoke(Element* aElement, ErrorResult& aRv) override
   {
     CustomElementRegistry::Upgrade(aElement, mDefinition, aRv);
   }
 
@@ -1179,18 +1177,20 @@ CustomElementReactionsStack::Enqueue(Ele
     elementData->mReactionQueue.AppendElement(aReaction);
     return;
   }
 
   // If the custom element reactions stack is empty, then:
   // Add element to the backup element queue.
   MOZ_ASSERT(mReactionsStack.IsEmpty(),
              "custom element reactions stack should be empty");
-  MOZ_ASSERT(!aReaction->IsUpgradeReaction(),
-             "Upgrade reaction should not be scheduled to backup queue");
+  MOZ_ASSERT(!aReaction->IsUpgradeReaction() ||
+             nsContentUtils::IsChromeDoc(aElement->OwnerDoc()),
+             "Upgrade reaction should not be scheduled to backup queue "
+             "except when Custom Element is used inside XBL (in chrome).");
   mBackupQueue.AppendElement(aElement);
   elementData->mReactionQueue.AppendElement(aReaction);
 
   if (mIsBackupQueueProcessing) {
     return;
   }
 
   CycleCollectedJSContext* context = CycleCollectedJSContext::Get();
@@ -1234,27 +1234,38 @@ CustomElementReactionsStack::InvokeReact
       // This happens when the document is destroyed and the element is already
       // unlinked, no need to fire the callbacks in this case.
       continue;
     }
 
     auto& reactions = elementData->mReactionQueue;
     for (uint32_t j = 0; j < reactions.Length(); ++j) {
       // Transfer the ownership of the entry due to reentrant invocation of
-      // this funciton. The entry will be removed when bug 1379573 is landed.
+      // this function.
       auto reaction(Move(reactions.ElementAt(j)));
       if (reaction) {
+        if (!aGlobal && reaction->IsUpgradeReaction()) {
+          // This is for the special case when custom element is included
+          // inside XBL.
+          MOZ_ASSERT(nsContentUtils::IsChromeDoc(element->OwnerDoc()));
+          nsIGlobalObject* global = element->GetOwnerGlobal();
+          MOZ_ASSERT(!aes);
+          aes.emplace(global, "custom elements reaction invocation");
+        }
         ErrorResult rv;
         reaction->Invoke(element, rv);
         if (aes) {
           JSContext* cx = aes->cx();
           if (rv.MaybeSetPendingException(cx)) {
             aes->ReportException();
           }
           MOZ_ASSERT(!JS_IsExceptionPending(cx));
+          if (!aGlobal && reaction->IsUpgradeReaction()) {
+            aes.reset();
+          }
         }
         MOZ_ASSERT(!rv.Failed());
       }
     }
     reactions.Clear();
   }
   aElementQueue->Clear();
 }
--- a/dom/base/CustomElementRegistry.h
+++ b/dom/base/CustomElementRegistry.h
@@ -194,25 +194,23 @@ class CustomElementReaction
 {
 public:
   virtual ~CustomElementReaction() = default;
   virtual void Invoke(Element* aElement, ErrorResult& aRv) = 0;
   virtual void Traverse(nsCycleCollectionTraversalCallback& aCb) const
   {
   }
 
-#if DEBUG
   bool IsUpgradeReaction()
   {
     return mIsUpgradeReaction;
   }
 
 protected:
   bool mIsUpgradeReaction = false;
-#endif
 };
 
 // https://html.spec.whatwg.org/multipage/scripting.html#custom-element-reactions-stack
 class CustomElementReactionsStack
 {
 public:
   NS_INLINE_DECL_REFCOUNTING(CustomElementReactionsStack)