michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef mozilla_dom_shadowroot_h__ michael@0: #define mozilla_dom_shadowroot_h__ michael@0: michael@0: #include "mozilla/dom/DocumentFragment.h" michael@0: #include "mozilla/dom/StyleSheetList.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "nsCycleCollectionParticipant.h" michael@0: #include "nsTHashtable.h" michael@0: #include "nsDocument.h" michael@0: michael@0: class nsIAtom; michael@0: class nsIContent; michael@0: class nsIDocument; michael@0: class nsINodeInfo; michael@0: class nsPIDOMWindow; michael@0: class nsXBLPrototypeBinding; michael@0: class nsTagNameMapEntry; michael@0: michael@0: namespace mozilla { michael@0: namespace dom { michael@0: michael@0: class Element; michael@0: class HTMLContentElement; michael@0: class HTMLShadowElement; michael@0: class ShadowRootStyleSheetList; michael@0: michael@0: class ShadowRoot : public DocumentFragment, michael@0: public nsStubMutationObserver michael@0: { michael@0: friend class ShadowRootStyleSheetList; michael@0: public: michael@0: NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ShadowRoot, michael@0: DocumentFragment) michael@0: NS_DECL_ISUPPORTS_INHERITED michael@0: michael@0: NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED michael@0: NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED michael@0: NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED michael@0: NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED michael@0: michael@0: ShadowRoot(nsIContent* aContent, already_AddRefed&& aNodeInfo, michael@0: nsXBLPrototypeBinding* aProtoBinding); michael@0: virtual ~ShadowRoot(); michael@0: michael@0: void AddToIdTable(Element* aElement, nsIAtom* aId); michael@0: void RemoveFromIdTable(Element* aElement, nsIAtom* aId); michael@0: void InsertSheet(nsCSSStyleSheet* aSheet, nsIContent* aLinkingContent); michael@0: void RemoveSheet(nsCSSStyleSheet* aSheet); michael@0: bool ApplyAuthorStyles(); michael@0: void SetApplyAuthorStyles(bool aApplyAuthorStyles); michael@0: StyleSheetList* StyleSheets(); michael@0: HTMLShadowElement* GetShadowElement() { return mShadowElement; } michael@0: michael@0: /** michael@0: * Sets the current shadow insertion point where the older michael@0: * ShadowRoot will be projected. michael@0: */ michael@0: void SetShadowElement(HTMLShadowElement* aShadowElement); michael@0: michael@0: /** michael@0: * Change the node that populates the distribution pool with michael@0: * its children. This is distinct from the ShadowRoot host described michael@0: * in the specifications. The ShadowRoot host is the element michael@0: * which created this ShadowRoot and does not change. The pool host michael@0: * is the same as the ShadowRoot host if this is the youngest michael@0: * ShadowRoot. If this is an older ShadowRoot, the pool host is michael@0: * the element in the younger ShadowRoot (if it exists). michael@0: */ michael@0: void ChangePoolHost(nsIContent* aNewHost); michael@0: michael@0: /** michael@0: * Distributes a single explicit child of the pool host to the content michael@0: * insertion points in this ShadowRoot. michael@0: */ michael@0: void DistributeSingleNode(nsIContent* aContent); michael@0: michael@0: /** michael@0: * Removes a single explicit child of the pool host from the content michael@0: * insertion points in this ShadowRoot. michael@0: */ michael@0: void RemoveDistributedNode(nsIContent* aContent); michael@0: michael@0: /** michael@0: * Distributes all the explicit children of the pool host to the content michael@0: * insertion points in this ShadowRoot. michael@0: */ michael@0: void DistributeAllNodes(); michael@0: michael@0: void AddInsertionPoint(HTMLContentElement* aInsertionPoint); michael@0: void RemoveInsertionPoint(HTMLContentElement* aInsertionPoint); michael@0: michael@0: void SetYoungerShadow(ShadowRoot* aYoungerShadow); michael@0: ShadowRoot* GetOlderShadow() { return mOlderShadow; } michael@0: ShadowRoot* GetYoungerShadow() { return mYoungerShadow; } michael@0: void SetInsertionPointChanged() { mInsertionPointChanged = true; } michael@0: michael@0: void SetAssociatedBinding(nsXBLBinding* aBinding) { mAssociatedBinding = aBinding; } michael@0: michael@0: nsISupports* GetParentObject() const { return mPoolHost; } michael@0: michael@0: nsIContent* GetPoolHost() { return mPoolHost; } michael@0: nsTArray& ShadowDescendants() { return mShadowDescendants; } michael@0: michael@0: JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE; michael@0: michael@0: static bool IsPooledNode(nsIContent* aChild, nsIContent* aContainer, michael@0: nsIContent* aHost); michael@0: static ShadowRoot* FromNode(nsINode* aNode); michael@0: static bool IsShadowInsertionPoint(nsIContent* aContent); michael@0: michael@0: // WebIDL methods. michael@0: Element* GetElementById(const nsAString& aElementId); michael@0: already_AddRefed michael@0: GetElementsByTagName(const nsAString& aNamespaceURI); michael@0: already_AddRefed michael@0: GetElementsByTagNameNS(const nsAString& aNamespaceURI, michael@0: const nsAString& aLocalName); michael@0: already_AddRefed michael@0: GetElementsByClassName(const nsAString& aClasses); michael@0: void GetInnerHTML(nsAString& aInnerHTML); michael@0: void SetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError); michael@0: protected: michael@0: void Restyle(); michael@0: michael@0: // The pool host is the parent of the nodes that will be distributed michael@0: // into the insertion points in this ShadowRoot. See |ChangeShadowRoot|. michael@0: nsCOMPtr mPoolHost; michael@0: michael@0: // An array of content insertion points that are a descendant of the ShadowRoot michael@0: // sorted in tree order. Insertion points are responsible for notifying michael@0: // the ShadowRoot when they are removed or added as a descendant. The insertion michael@0: // points are kept alive by the parent node, thus weak references are held michael@0: // by the array. michael@0: nsTArray mInsertionPoints; michael@0: michael@0: // An array of the elements that are descendant of the ShadowRoot michael@0: // sorted in tree order. Only the first may be a shadow insertion point. michael@0: nsTArray mShadowDescendants; michael@0: michael@0: nsTHashtable mIdentifierMap; michael@0: nsXBLPrototypeBinding* mProtoBinding; michael@0: michael@0: // It is necessary to hold a reference to the associated nsXBLBinding michael@0: // because the binding holds a reference on the nsXBLDocumentInfo that michael@0: // owns |mProtoBinding|. michael@0: nsRefPtr mAssociatedBinding; michael@0: michael@0: nsRefPtr mStyleSheetList; michael@0: michael@0: // The current shadow insertion point of this ShadowRoot. michael@0: HTMLShadowElement* mShadowElement; michael@0: michael@0: // The ShadowRoot that was created by the host element before michael@0: // this ShadowRoot was created. michael@0: nsRefPtr mOlderShadow; michael@0: michael@0: // The ShadowRoot that was created by the host element after michael@0: // this ShadowRoot was created. michael@0: nsRefPtr mYoungerShadow; michael@0: michael@0: // A boolean that indicates that an insertion point was added or removed michael@0: // from this ShadowRoot and that the nodes need to be redistributed into michael@0: // the insertion points. After this flag is set, nodes will be distributed michael@0: // on the next mutation event. michael@0: bool mInsertionPointChanged; michael@0: }; michael@0: michael@0: class ShadowRootStyleSheetList : public StyleSheetList michael@0: { michael@0: public: michael@0: ShadowRootStyleSheetList(ShadowRoot* aShadowRoot); michael@0: virtual ~ShadowRootStyleSheetList(); michael@0: michael@0: NS_DECL_ISUPPORTS_INHERITED michael@0: NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ShadowRootStyleSheetList, StyleSheetList) michael@0: michael@0: virtual nsINode* GetParentObject() const MOZ_OVERRIDE michael@0: { michael@0: return mShadowRoot; michael@0: } michael@0: michael@0: virtual uint32_t Length() MOZ_OVERRIDE; michael@0: virtual nsCSSStyleSheet* IndexedGetter(uint32_t aIndex, bool& aFound) MOZ_OVERRIDE; michael@0: michael@0: protected: michael@0: nsRefPtr mShadowRoot; michael@0: }; michael@0: michael@0: } // namespace dom michael@0: } // namespace mozilla michael@0: michael@0: #endif // mozilla_dom_shadowroot_h__ michael@0: