summaryrefslogtreecommitdiff
path: root/dom/base/CustomElementRegistry.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/base/CustomElementRegistry.h')
-rw-r--r--dom/base/CustomElementRegistry.h110
1 files changed, 110 insertions, 0 deletions
diff --git a/dom/base/CustomElementRegistry.h b/dom/base/CustomElementRegistry.h
index 8ef0785af3..b3b4d7c0f0 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<JSObject*> 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<nsWeakPtr> ElementQueue;
+
+ /**
+ * Invoke custom element reactions
+ * https://html.spec.whatwg.org/multipage/scripting.html#invoke-custom-element-reactions
+ */
+ void InvokeReactions(ElementQueue& aElementQueue);
+
typedef nsClassHashtable<nsISupportsHashKey, CustomElementDefinition>
DefinitionMap;
typedef nsClassHashtable<nsISupportsHashKey, nsTArray<nsWeakPtr>>
@@ -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<nsAutoPtr<CustomElementReaction>> ReactionQueue;
+ typedef nsClassHashtable<nsISupportsHashKey, ReactionQueue>
+ ElementReactionQueueMap;
+
+ ElementReactionQueueMap mElementReactionQueueMap;
+
+ nsTArray<ElementQueue> 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<CustomElementRegistry> mRegistry;
+ };
+
public:
nsISupports* GetParentObject() const;
@@ -272,6 +369,19 @@ public:
already_AddRefed<Promise> 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<CustomElementRegistry> mRegistry;
+};
+
} // namespace dom
} // namespace mozilla