Bug 1384661 - Part 2: Add class nsParentNodeChildContentList. r=smaug

--HG--
extra : rebase_source : d5a5c93ba62c03e01fffaade0fd20b934732e095
This commit is contained in:
btian 2017-08-21 16:11:56 +08:00
Родитель 5c02026b84
Коммит b4fa979d43
2 изменённых файлов: 119 добавлений и 5 удалений

Просмотреть файл

@ -570,6 +570,77 @@ nsAttrChildContentList::IndexOf(nsIContent* aContent)
return -1; return -1;
} }
//----------------------------------------------------------------------
NS_IMETHODIMP
nsParentNodeChildContentList::GetLength(uint32_t* aLength)
{
if (!mIsCacheValid && !ValidateCache()) {
*aLength = 0;
return NS_OK;
}
MOZ_ASSERT(mIsCacheValid);
*aLength = mCachedChildArray.Length();
return NS_OK;
}
NS_IMETHODIMP
nsParentNodeChildContentList::Item(uint32_t aIndex, nsIDOMNode** aReturn)
{
nsINode* node = Item(aIndex);
if (!node) {
*aReturn = nullptr;
return NS_OK;
}
return CallQueryInterface(node, aReturn);
}
nsIContent*
nsParentNodeChildContentList::Item(uint32_t aIndex)
{
if (!mIsCacheValid && !ValidateCache()) {
return nullptr;
}
MOZ_ASSERT(mIsCacheValid);
return mCachedChildArray.SafeElementAt(aIndex, nullptr);
}
int32_t
nsParentNodeChildContentList::IndexOf(nsIContent* aContent)
{
if (!mIsCacheValid && !ValidateCache()) {
return -1;
}
MOZ_ASSERT(mIsCacheValid);
return mCachedChildArray.IndexOf(aContent);
}
bool
nsParentNodeChildContentList::ValidateCache()
{
MOZ_ASSERT(!mIsCacheValid);
MOZ_ASSERT(mCachedChildArray.IsEmpty());
nsINode* parent = GetParentObject();
if (!parent) {
return false;
}
for (nsIContent* node = parent->GetFirstChild(); node;
node = node->GetNextSibling()) {
mCachedChildArray.AppendElement(node);
}
mIsCacheValid = true;
return true;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
nsIHTMLCollection* nsIHTMLCollection*

Просмотреть файл

@ -8,7 +8,7 @@
#define nsChildContentList_h__ #define nsChildContentList_h__
#include "nsISupportsImpl.h" #include "nsISupportsImpl.h"
#include "nsINodeList.h" // base class #include "nsINodeList.h" // base class
#include "js/TypeDecls.h" // for Handle, Value, JSObject, JSContext #include "js/TypeDecls.h" // for Handle, Value, JSObject, JSContext
class nsIContent; class nsIContent;
@ -20,7 +20,7 @@ class nsINode;
* and Item to its existing child list. * and Item to its existing child list.
* @see nsIDOMNodeList * @see nsIDOMNodeList
*/ */
class nsAttrChildContentList final : public nsINodeList class nsAttrChildContentList : public nsINodeList
{ {
public: public:
explicit nsAttrChildContentList(nsINode* aNode) explicit nsAttrChildContentList(nsINode* aNode)
@ -42,7 +42,7 @@ public:
virtual int32_t IndexOf(nsIContent* aContent) override; virtual int32_t IndexOf(nsIContent* aContent) override;
virtual nsIContent* Item(uint32_t aIndex) override; virtual nsIContent* Item(uint32_t aIndex) override;
void DropReference() virtual void DropReference()
{ {
mNode = nullptr; mNode = nullptr;
} }
@ -52,13 +52,56 @@ public:
return mNode; return mNode;
} }
private: protected:
~nsAttrChildContentList() {} virtual ~nsAttrChildContentList() {}
private:
// The node whose children make up the list. // The node whose children make up the list.
// This is a non-owning ref which is safe because it's set to nullptr by // This is a non-owning ref which is safe because it's set to nullptr by
// DropReference() by the node slots get destroyed. // DropReference() by the node slots get destroyed.
nsINode* MOZ_NON_OWNING_REF mNode; nsINode* MOZ_NON_OWNING_REF mNode;
}; };
class nsParentNodeChildContentList final : public nsAttrChildContentList
{
public:
explicit nsParentNodeChildContentList(nsINode* aNode)
: nsAttrChildContentList(aNode)
, mIsCacheValid(false)
{
ValidateCache();
}
// nsIDOMNodeList interface
NS_DECL_NSIDOMNODELIST
// nsINodeList interface
virtual int32_t IndexOf(nsIContent* aContent) override;
virtual nsIContent* Item(uint32_t aIndex) override;
void DropReference() override
{
InvalidateCache();
nsAttrChildContentList::DropReference();
}
void InvalidateCache()
{
mIsCacheValid = false;
mCachedChildArray.Clear();
}
private:
~nsParentNodeChildContentList() {}
// Return true if validation succeeds, false otherwise
bool ValidateCache();
// Whether cached array of child nodes is valid
bool mIsCacheValid;
// Cached array of child nodes
AutoTArray<nsIContent*, 8> mCachedChildArray;
};
#endif /* nsChildContentList_h__ */ #endif /* nsChildContentList_h__ */