From 3a97503b361b0b5ff1b5d8948a74497710f2a095 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Thu, 2 Jan 2020 22:04:11 -0500 Subject: Bug 1309184 - Implement upgrade reaction for custom element reactions. Tag UXP Issue #1344 --- dom/base/CustomElementRegistry.h | 110 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) (limited to 'dom/base/CustomElementRegistry.h') diff --git a/dom/base/CustomElementRegistry.h b/dom/base/CustomElementRegistry.h index 8ef0785af..b3b4d7c0f 100644 --- a/dom/base/CustomElementRegistry.h +++ b/dom/base/CustomElementRegistry.h @@ -134,6 +134,37 @@ struct CustomElementDefinition } }; +class CustomElementReaction +{ +public: + explicit CustomElementReaction(CustomElementRegistry* aRegistry, + CustomElementDefinition* aDefinition) + : mRegistry(aRegistry) + , mDefinition(aDefinition) + { + }; + + virtual ~CustomElementReaction() = default; + virtual void Invoke(Element* aElement) = 0; + +protected: + CustomElementRegistry* mRegistry; + CustomElementDefinition* mDefinition; +}; + +class CustomElementUpgradeReaction final : public CustomElementReaction +{ +public: + explicit CustomElementUpgradeReaction(CustomElementRegistry* aRegistry, + CustomElementDefinition* aDefinition) + : CustomElementReaction(aRegistry, aDefinition) + { + } + +private: + virtual void Invoke(Element* aElement) override; +}; + class CustomElementRegistry final : public nsISupports, public nsWrapperCache { @@ -177,6 +208,24 @@ 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: explicit CustomElementRegistry(nsPIDOMWindowInner* aWindow); ~CustomElementRegistry(); @@ -198,6 +247,21 @@ private: 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); + typedef nsClassHashtable DefinitionMap; typedef nsClassHashtable> @@ -238,6 +302,17 @@ 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 { @@ -258,6 +333,28 @@ 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; @@ -272,6 +369,19 @@ public: already_AddRefed WhenDefined(const nsAString& aName, ErrorResult& aRv); }; +class MOZ_RAII AutoCEReaction final { + public: + explicit AutoCEReaction(CustomElementRegistry* aRegistry) + : mRegistry(aRegistry) { + mRegistry->CreateAndPushElementQueue(); + } + ~AutoCEReaction() { + mRegistry->PopAndInvokeElementQueue(); + } + private: + RefPtr mRegistry; +}; + } // namespace dom } // namespace mozilla -- cgit v1.2.3