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;
}
//----------------------------------------------------------------------
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*

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

@ -8,7 +8,7 @@
#define nsChildContentList_h__
#include "nsISupportsImpl.h"
#include "nsINodeList.h" // base class
#include "nsINodeList.h" // base class
#include "js/TypeDecls.h" // for Handle, Value, JSObject, JSContext
class nsIContent;
@ -20,7 +20,7 @@ class nsINode;
* and Item to its existing child list.
* @see nsIDOMNodeList
*/
class nsAttrChildContentList final : public nsINodeList
class nsAttrChildContentList : public nsINodeList
{
public:
explicit nsAttrChildContentList(nsINode* aNode)
@ -42,7 +42,7 @@ public:
virtual int32_t IndexOf(nsIContent* aContent) override;
virtual nsIContent* Item(uint32_t aIndex) override;
void DropReference()
virtual void DropReference()
{
mNode = nullptr;
}
@ -52,13 +52,56 @@ public:
return mNode;
}
private:
~nsAttrChildContentList() {}
protected:
virtual ~nsAttrChildContentList() {}
private:
// The node whose children make up the list.
// This is a non-owning ref which is safe because it's set to nullptr by
// DropReference() by the node slots get destroyed.
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__ */