/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:set ts=2 sw=2 sts=2 et cindent: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_dom_CustomElementRegistry_h #define mozilla_dom_CustomElementRegistry_h #include "js/GCHashTable.h" #include "js/TypeDecls.h" #include "mozilla/Attributes.h" #include "mozilla/ErrorResult.h" #include "mozilla/dom/BindingDeclarations.h" #include "mozilla/dom/FunctionBinding.h" #include "mozilla/dom/WebComponentsBinding.h" #include "nsCycleCollectionParticipant.h" #include "nsGenericHTMLElement.h" #include "nsWrapperCache.h" class nsDocument; namespace mozilla { namespace dom { struct CustomElementData; struct ElementDefinitionOptions; class CallbackFunction; class CustomElementReaction; class DocGroup; class Function; class Promise; struct LifecycleCallbackArgs { nsString name; nsString oldValue; nsString newValue; nsString namespaceURI; }; struct LifecycleAdoptedCallbackArgs { nsCOMPtr mOldDocument; nsCOMPtr mNewDocument; }; class CustomElementCallback { public: CustomElementCallback(Element* aThisObject, nsIDocument::ElementCallbackType aCallbackType, CallbackFunction* aCallback); void Traverse(nsCycleCollectionTraversalCallback& aCb) const; void Call(); void SetArgs(LifecycleCallbackArgs& aArgs) { MOZ_ASSERT(mType == nsIDocument::eAttributeChanged, "Arguments are only used by attribute changed callback."); mArgs = aArgs; } void SetAdoptedCallbackArgs(LifecycleAdoptedCallbackArgs& aAdoptedCallbackArgs) { MOZ_ASSERT(mType == nsIDocument::eAdopted, "Arguments are only used by adopted callback."); mAdoptedCallbackArgs = aAdoptedCallbackArgs; } private: // The this value to use for invocation of the callback. RefPtr mThisObject; RefPtr mCallback; // The type of callback (eCreated, eAttached, etc.) nsIDocument::ElementCallbackType mType; // Arguments to be passed to the callback, // used by the attribute changed callback. LifecycleCallbackArgs mArgs; LifecycleAdoptedCallbackArgs mAdoptedCallbackArgs; }; class CustomElementConstructor final : public CallbackFunction { public: explicit CustomElementConstructor(CallbackFunction* aOther) : CallbackFunction(aOther) { MOZ_ASSERT(JS::IsConstructor(mCallback)); } already_AddRefed Construct(const char* aExecutionReason, ErrorResult& aRv); }; // Each custom element has an associated callback queue and an element is // being created flag. struct CustomElementData { NS_INLINE_DECL_REFCOUNTING(CustomElementData) // https://dom.spec.whatwg.org/#concept-element-custom-element-state // CustomElementData is only created on the element which is a custom element // or an upgrade candidate, so the state of an element without // CustomElementData is "uncustomized". enum class State { eUndefined, eFailed, eCustom }; explicit CustomElementData(nsIAtom* aType); CustomElementData(nsIAtom* aType, State aState); // Custom element state as described in the custom element spec. State mState; // custom element reaction queue as described in the custom element spec. // There is 1 reaction in reaction queue, when 1) it becomes disconnected, // 2) it’s adopted into a new document, 3) its attributes are changed, // appended, removed, or replaced. // There are 3 reactions in reaction queue when doing upgrade operation, // e.g., create an element, insert a node. AutoTArray, 3> mReactionQueue; void SetCustomElementDefinition(CustomElementDefinition* aDefinition); CustomElementDefinition* GetCustomElementDefinition(); nsIAtom* GetCustomElementType(); void Traverse(nsCycleCollectionTraversalCallback& aCb) const; void Unlink(); private: virtual ~CustomElementData() {} // Custom element type, for