From 25a33c7123d457a59ecb4b15a2466cfc8507406b Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Fri, 3 Jan 2020 22:18:55 -0500 Subject: Bug 1347446 - Move custom element reactions stack to DocGroup. Tag UXP Issue #1344 --- dom/base/CustomElementRegistry.cpp | 58 ++++++++----- dom/base/CustomElementRegistry.h | 157 +++++++++++++++++++--------------- dom/base/DocGroup.h | 10 +++ dom/flyweb/FlyWebDiscoveryManager.cpp | 1 + 4 files changed, 136 insertions(+), 90 deletions(-) (limited to 'dom') diff --git a/dom/base/CustomElementRegistry.cpp b/dom/base/CustomElementRegistry.cpp index 25267f5d3..1ab566e1d 100644 --- a/dom/base/CustomElementRegistry.cpp +++ b/dom/base/CustomElementRegistry.cpp @@ -9,6 +9,7 @@ #include "mozilla/dom/CustomElementRegistryBinding.h" #include "mozilla/dom/HTMLElementBinding.h" #include "mozilla/dom/WebComponentsBinding.h" +#include "mozilla/dom/DocGroup.h" #include "nsIParserService.h" #include "jsapi.h" @@ -214,7 +215,6 @@ CustomElementRegistry::sProcessingStack; CustomElementRegistry::CustomElementRegistry(nsPIDOMWindowInner* aWindow) : mWindow(aWindow) , mIsCustomDefinitionRunning(false) - , mIsBackupQueueProcessing(false) { MOZ_ASSERT(aWindow); MOZ_ASSERT(aWindow->IsInnerWindow()); @@ -467,18 +467,27 @@ CustomElementRegistry::GetCustomPrototype(nsIAtom* aAtom, void CustomElementRegistry::UpgradeCandidates(JSContext* aCx, nsIAtom* aKey, - CustomElementDefinition* aDefinition) + CustomElementDefinition* aDefinition, + ErrorResult& aRv) { + DocGroup* docGroup = mWindow->GetDocGroup(); + if (!docGroup) { + aRv.Throw(NS_ERROR_UNEXPECTED); + return; + } + nsAutoPtr> candidates; mCandidatesMap.RemoveAndForget(aKey, candidates); if (candidates) { + CustomElementReactionsStack* reactionsStack = + docGroup->CustomElementReactionsStack(); for (size_t i = 0; i < candidates->Length(); ++i) { nsCOMPtr elem = do_QueryReferent(candidates->ElementAt(i)); if (!elem) { continue; } - EnqueueUpgradeReaction(elem, aDefinition); + reactionsStack->EnqueueUpgradeReaction(this, elem, aDefinition); } } } @@ -540,7 +549,13 @@ CustomElementRegistry::Define(const nsAString& aName, { // We do this for [CEReaction] temporarily and it will be removed // after webidl supports [CEReaction] annotation in bug 1309147. - AutoCEReaction ceReaction(this); + DocGroup* docGroup = mWindow->GetDocGroup(); + if (!docGroup) { + aRv.Throw(NS_ERROR_UNEXPECTED); + return; + } + + AutoCEReaction ceReaction(docGroup->CustomElementReactionsStack()); aRv.MightThrowJSException(); AutoJSAPI jsapi; @@ -770,7 +785,7 @@ CustomElementRegistry::Define(const nsAString& aName, * 13. 14. 15. Upgrade candidates */ // TODO: Bug 1299363 - Implement custom element v1 upgrade algorithm - UpgradeCandidates(cx, nameAtom, definition); + UpgradeCandidates(cx, nameAtom, definition, aRv); /** * 16. If this CustomElementRegistry's when-defined promise map contains an @@ -834,13 +849,6 @@ CustomElementRegistry::WhenDefined(const nsAString& aName, ErrorResult& aRv) return promise.forget(); } -void -CustomElementRegistry::EnqueueUpgradeReaction(Element* aElement, - CustomElementDefinition* aDefinition) -{ - Enqueue(aElement, new CustomElementUpgradeReaction(this, aDefinition)); -} - void CustomElementRegistry::Upgrade(Element* aElement, CustomElementDefinition* aDefinition) @@ -887,16 +895,18 @@ CustomElementRegistry::Upgrade(Element* aElement, EnqueueLifecycleCallback(nsIDocument::eCreated, aElement, nullptr, aDefinition); } +//----------------------------------------------------- +// CustomElementReactionsStack void -CustomElementRegistry::CreateAndPushElementQueue() +CustomElementReactionsStack::CreateAndPushElementQueue() { // Push a new element queue onto the custom element reactions stack. mReactionsStack.AppendElement(); } void -CustomElementRegistry::PopAndInvokeElementQueue() +CustomElementReactionsStack::PopAndInvokeElementQueue() { // Pop the element queue from the custom element reactions stack, // and invoke custom element reactions in that queue. @@ -904,15 +914,23 @@ CustomElementRegistry::PopAndInvokeElementQueue() "Reaction stack shouldn't be empty"); ElementQueue& elementQueue = mReactionsStack.LastElement(); - CustomElementRegistry::InvokeReactions(elementQueue); + InvokeReactions(elementQueue); DebugOnly isRemovedElement = mReactionsStack.RemoveElement(elementQueue); MOZ_ASSERT(isRemovedElement, "Reaction stack should have an element queue to remove"); } void -CustomElementRegistry::Enqueue(Element* aElement, - CustomElementReaction* aReaction) +CustomElementReactionsStack::EnqueueUpgradeReaction(CustomElementRegistry* aRegistry, + Element* aElement, + CustomElementDefinition* aDefinition) +{ + Enqueue(aElement, new CustomElementUpgradeReaction(aRegistry, aDefinition)); +} + +void +CustomElementReactionsStack::Enqueue(Element* aElement, + CustomElementReaction* aReaction) { // Add element to the current element queue. if (!mReactionsStack.IsEmpty()) { @@ -943,13 +961,13 @@ CustomElementRegistry::Enqueue(Element* aElement, } void -CustomElementRegistry::InvokeBackupQueue() +CustomElementReactionsStack::InvokeBackupQueue() { - CustomElementRegistry::InvokeReactions(mBackupQueue); + InvokeReactions(mBackupQueue); } void -CustomElementRegistry::InvokeReactions(ElementQueue& aElementQueue) +CustomElementReactionsStack::InvokeReactions(ElementQueue& aElementQueue) { for (uint32_t i = 0; i < aElementQueue.Length(); ++i) { nsCOMPtr element = do_QueryReferent(aElementQueue[i]); diff --git a/dom/base/CustomElementRegistry.h b/dom/base/CustomElementRegistry.h index 8fdf28289..5fc2eb2fd 100644 --- a/dom/base/CustomElementRegistry.h +++ b/dom/base/CustomElementRegistry.h @@ -165,6 +165,86 @@ private: virtual void Invoke(Element* aElement) override; }; +// https://html.spec.whatwg.org/multipage/scripting.html#custom-element-reactions-stack +class CustomElementReactionsStack +{ +public: + NS_INLINE_DECL_REFCOUNTING(CustomElementReactionsStack) + + CustomElementReactionsStack() + : mIsBackupQueueProcessing(false) + { + } + + // nsWeakPtr is a weak pointer of Element + // The element reaction queues are stored in ElementReactionQueueMap. + // We need to lookup ElementReactionQueueMap again to get relevant reaction queue. + typedef nsTArray ElementQueue; + + /** + * Enqueue a custom element upgrade reaction + * https://html.spec.whatwg.org/multipage/scripting.html#enqueue-a-custom-element-upgrade-reaction + */ + void EnqueueUpgradeReaction(CustomElementRegistry* aRegistry, + Element* aElement, + CustomElementDefinition* aDefinition); + + // [CEReactions] Before executing the algorithm's steps + // Push a new element queue onto the custom element reactions stack. + void CreateAndPushElementQueue(); + + // [CEReactions] After executing the algorithm's steps + // Pop the element queue from the custom element reactions stack, + // and invoke custom element reactions in that queue. + void PopAndInvokeElementQueue(); + +private: + ~CustomElementReactionsStack() {}; + + typedef nsTArray> ReactionQueue; + typedef nsClassHashtable + ElementReactionQueueMap; + + ElementReactionQueueMap mElementReactionQueueMap; + + nsTArray mReactionsStack; + ElementQueue mBackupQueue; + // https://html.spec.whatwg.org/#enqueue-an-element-on-the-appropriate-element-queue + bool mIsBackupQueueProcessing; + + void InvokeBackupQueue(); + + /** + * Invoke custom element reactions + * https://html.spec.whatwg.org/multipage/scripting.html#invoke-custom-element-reactions + */ + void InvokeReactions(ElementQueue& aElementQueue); + + void Enqueue(Element* aElement, CustomElementReaction* aReaction); + +private: + class ProcessBackupQueueRunnable : public mozilla::Runnable { + public: + explicit ProcessBackupQueueRunnable(CustomElementReactionsStack* aReactionStack) + : mReactionStack(aReactionStack) + { + MOZ_ASSERT(!mReactionStack->mIsBackupQueueProcessing, + "mIsBackupQueueProcessing should be initially false"); + mReactionStack->mIsBackupQueueProcessing = true; + } + + NS_IMETHOD Run() override + { + mReactionStack->InvokeBackupQueue(); + mReactionStack->mIsBackupQueueProcessing = false; + return NS_OK; + } + + private: + RefPtr mReactionStack; + }; +}; + class CustomElementRegistry final : public nsISupports, public nsWrapperCache { @@ -210,24 +290,8 @@ public: void GetCustomPrototype(nsIAtom* aAtom, JS::MutableHandle aPrototype); - /** - * Enqueue a custom element upgrade reaction - * https://html.spec.whatwg.org/multipage/scripting.html#enqueue-a-custom-element-upgrade-reaction - */ - void EnqueueUpgradeReaction(Element* aElement, - CustomElementDefinition* aDefinition); - void Upgrade(Element* aElement, CustomElementDefinition* aDefinition); - // [CEReactions] Before executing the algorithm's steps - // Push a new element queue onto the custom element reactions stack. - void CreateAndPushElementQueue(); - - // [CEReactions] After executing the algorithm's steps - // Pop the element queue from the custom element reactions stack, - // and invoke custom element reactions in that queue. - void PopAndInvokeElementQueue(); - private: ~CustomElementRegistry(); @@ -244,22 +308,8 @@ private: void UpgradeCandidates(JSContext* aCx, nsIAtom* aKey, - CustomElementDefinition* aDefinition); - - void InvokeBackupQueue(); - - void Enqueue(Element* aElement, CustomElementReaction* aReaction); - - // nsWeakPtr is a weak pointer of Element - // The element reaction queues are stored in ElementReactionQueueMap. - // We need to lookup ElementReactionQueueMap again to get relevant reaction queue. - typedef nsTArray ElementQueue; - - /** - * Invoke custom element reactions - * https://html.spec.whatwg.org/multipage/scripting.html#invoke-custom-element-reactions - */ - void InvokeReactions(ElementQueue& aElementQueue); + CustomElementDefinition* aDefinition, + ErrorResult& aRv); typedef nsClassHashtable DefinitionMap; @@ -301,17 +351,6 @@ private: // It is used to prevent reentrant invocations of element definition. bool mIsCustomDefinitionRunning; - // https://html.spec.whatwg.org/#enqueue-an-element-on-the-appropriate-element-queue - bool mIsBackupQueueProcessing; - - typedef nsTArray> ReactionQueue; - typedef nsClassHashtable - ElementReactionQueueMap; - - ElementReactionQueueMap mElementReactionQueueMap; - - nsTArray mReactionsStack; - ElementQueue mBackupQueue; private: class MOZ_RAII AutoSetRunningFlag final { @@ -332,28 +371,6 @@ private: CustomElementRegistry* mRegistry; }; -private: - class ProcessBackupQueueRunnable : public mozilla::Runnable { - public: - explicit ProcessBackupQueueRunnable(CustomElementRegistry* aRegistry) - : mRegistry(aRegistry) - { - MOZ_ASSERT(!mRegistry->mIsBackupQueueProcessing, - "mIsBackupQueueProcessing should be initially false"); - mRegistry->mIsBackupQueueProcessing = true; - } - - NS_IMETHOD Run() override - { - mRegistry->InvokeBackupQueue(); - mRegistry->mIsBackupQueueProcessing = false; - return NS_OK; - } - - private: - RefPtr mRegistry; - }; - public: nsISupports* GetParentObject() const; @@ -370,15 +387,15 @@ public: class MOZ_RAII AutoCEReaction final { public: - explicit AutoCEReaction(CustomElementRegistry* aRegistry) - : mRegistry(aRegistry) { - mRegistry->CreateAndPushElementQueue(); + explicit AutoCEReaction(CustomElementReactionsStack* aReactionsStack) + : mReactionsStack(aReactionsStack) { + mReactionsStack->CreateAndPushElementQueue(); } ~AutoCEReaction() { - mRegistry->PopAndInvokeElementQueue(); + mReactionsStack->PopAndInvokeElementQueue(); } private: - RefPtr mRegistry; + RefPtr mReactionsStack; }; } // namespace dom diff --git a/dom/base/DocGroup.h b/dom/base/DocGroup.h index f4f7ac8ad..5b8f627cc 100644 --- a/dom/base/DocGroup.h +++ b/dom/base/DocGroup.h @@ -14,6 +14,7 @@ #include "nsString.h" #include "mozilla/RefPtr.h" +#include "mozilla/dom/CustomElementRegistry.h" namespace mozilla { namespace dom { @@ -52,6 +53,14 @@ public: { return mTabGroup; } + mozilla::dom::CustomElementReactionsStack* CustomElementReactionsStack() + { + if (!mReactionsStack) { + mReactionsStack = new mozilla::dom::CustomElementReactionsStack(); + } + + return mReactionsStack; + } void RemoveDocument(nsIDocument* aWindow); // Iterators for iterating over every document within the DocGroup @@ -71,6 +80,7 @@ private: nsCString mKey; RefPtr mTabGroup; nsTArray mDocuments; + RefPtr mReactionsStack; }; } // namespace dom diff --git a/dom/flyweb/FlyWebDiscoveryManager.cpp b/dom/flyweb/FlyWebDiscoveryManager.cpp index 5a97eb6d8..14ad5aa1f 100644 --- a/dom/flyweb/FlyWebDiscoveryManager.cpp +++ b/dom/flyweb/FlyWebDiscoveryManager.cpp @@ -16,6 +16,7 @@ #include "mozilla/dom/FlyWebDiscoveryManager.h" #include "mozilla/dom/FlyWebDiscoveryManagerBinding.h" +#include "mozilla/dom/Element.h" namespace mozilla { namespace dom { -- cgit v1.2.3