michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim: set ts=2 sw=2 et tw=79: */ 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 nsXBLChildrenElement_h___ michael@0: #define nsXBLChildrenElement_h___ michael@0: michael@0: #include "nsIDOMElement.h" michael@0: #include "nsINodeList.h" michael@0: #include "nsBindingManager.h" michael@0: #include "mozilla/dom/nsXMLElement.h" michael@0: michael@0: class nsAnonymousContentList; michael@0: michael@0: namespace mozilla { michael@0: namespace dom { michael@0: michael@0: class ExplicitChildIterator; michael@0: michael@0: class XBLChildrenElement : public nsXMLElement michael@0: { michael@0: public: michael@0: friend class mozilla::dom::ExplicitChildIterator; michael@0: friend class nsAnonymousContentList; michael@0: XBLChildrenElement(already_AddRefed& aNodeInfo) michael@0: : nsXMLElement(aNodeInfo) michael@0: { michael@0: } michael@0: XBLChildrenElement(already_AddRefed&& aNodeInfo) michael@0: : nsXMLElement(aNodeInfo) michael@0: { michael@0: } michael@0: ~XBLChildrenElement(); michael@0: michael@0: // nsISupports michael@0: NS_DECL_ISUPPORTS_INHERITED michael@0: michael@0: // nsINode interface methods michael@0: virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; michael@0: michael@0: virtual nsXPCClassInfo* GetClassInfo() { return nullptr; } michael@0: michael@0: virtual nsIDOMNode* AsDOMNode() { return this; } michael@0: michael@0: // nsIContent interface methods michael@0: virtual nsIAtom *GetIDAttributeName() const; michael@0: virtual nsIAtom* DoGetID() const; michael@0: virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute, michael@0: bool aNotify); michael@0: virtual bool ParseAttribute(int32_t aNamespaceID, michael@0: nsIAtom* aAttribute, michael@0: const nsAString& aValue, michael@0: nsAttrValue& aResult); michael@0: michael@0: void AppendInsertedChild(nsIContent* aChild) michael@0: { michael@0: mInsertedChildren.AppendElement(aChild); michael@0: aChild->SetXBLInsertionParent(GetParent()); michael@0: } michael@0: michael@0: void InsertInsertedChildAt(nsIContent* aChild, uint32_t aIndex) michael@0: { michael@0: mInsertedChildren.InsertElementAt(aIndex, aChild); michael@0: aChild->SetXBLInsertionParent(GetParent()); michael@0: } michael@0: michael@0: void RemoveInsertedChild(nsIContent* aChild) michael@0: { michael@0: // Can't use this assertion as we cheat for dynamic insertions and michael@0: // only insert in the innermost insertion point. michael@0: //NS_ASSERTION(mInsertedChildren.Contains(aChild), michael@0: // "Removing child that's not there"); michael@0: mInsertedChildren.RemoveElement(aChild); michael@0: } michael@0: michael@0: void ClearInsertedChildren() michael@0: { michael@0: for (uint32_t c = 0; c < mInsertedChildren.Length(); ++c) { michael@0: mInsertedChildren[c]->SetXBLInsertionParent(nullptr); michael@0: } michael@0: mInsertedChildren.Clear(); michael@0: } michael@0: michael@0: void MaybeSetupDefaultContent() michael@0: { michael@0: if (!HasInsertedChildren()) { michael@0: for (nsIContent* child = static_cast(this)->GetFirstChild(); michael@0: child; michael@0: child = child->GetNextSibling()) { michael@0: child->SetXBLInsertionParent(GetParent()); michael@0: } michael@0: } michael@0: } michael@0: michael@0: void MaybeRemoveDefaultContent() michael@0: { michael@0: if (!HasInsertedChildren()) { michael@0: for (nsIContent* child = static_cast(this)->GetFirstChild(); michael@0: child; michael@0: child = child->GetNextSibling()) { michael@0: child->SetXBLInsertionParent(nullptr); michael@0: } michael@0: } michael@0: } michael@0: michael@0: uint32_t InsertedChildrenLength() michael@0: { michael@0: return mInsertedChildren.Length(); michael@0: } michael@0: michael@0: bool HasInsertedChildren() michael@0: { michael@0: return !mInsertedChildren.IsEmpty(); michael@0: } michael@0: michael@0: enum { michael@0: NoIndex = uint32_t(-1) michael@0: }; michael@0: uint32_t IndexOfInsertedChild(nsIContent* aChild) michael@0: { michael@0: return mInsertedChildren.IndexOf(aChild); michael@0: } michael@0: michael@0: bool Includes(nsIContent* aChild) michael@0: { michael@0: NS_ASSERTION(!mIncludes.IsEmpty(), michael@0: "Shouldn't check for includes on default insertion point"); michael@0: return mIncludes.Contains(aChild->Tag()); michael@0: } michael@0: michael@0: bool IsDefaultInsertion() michael@0: { michael@0: return mIncludes.IsEmpty(); michael@0: } michael@0: michael@0: nsTArray mInsertedChildren; michael@0: michael@0: private: michael@0: nsTArray > mIncludes; michael@0: }; michael@0: michael@0: } // namespace dom michael@0: } // namespace mozilla michael@0: michael@0: class nsAnonymousContentList : public nsINodeList michael@0: { michael@0: public: michael@0: nsAnonymousContentList(nsIContent* aParent) michael@0: : mParent(aParent) michael@0: { michael@0: MOZ_COUNT_CTOR(nsAnonymousContentList); michael@0: SetIsDOMBinding(); michael@0: } michael@0: michael@0: virtual ~nsAnonymousContentList() michael@0: { michael@0: MOZ_COUNT_DTOR(nsAnonymousContentList); michael@0: } michael@0: michael@0: NS_DECL_CYCLE_COLLECTING_ISUPPORTS michael@0: NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsAnonymousContentList) michael@0: // nsIDOMNodeList interface michael@0: NS_DECL_NSIDOMNODELIST michael@0: michael@0: // nsINodeList interface michael@0: virtual int32_t IndexOf(nsIContent* aContent); michael@0: virtual nsINode* GetParentObject() { return mParent; } michael@0: virtual nsIContent* Item(uint32_t aIndex); michael@0: michael@0: virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE; michael@0: michael@0: bool IsListFor(nsIContent* aContent) { michael@0: return mParent == aContent; michael@0: } michael@0: michael@0: private: michael@0: nsCOMPtr mParent; michael@0: }; michael@0: michael@0: #endif // nsXBLChildrenElement_h___