зеркало из https://github.com/mozilla/gecko-dev.git
Add a faster method for iterating the nsIContent children of an
nsINode if we know that there will be no DOM mutations of any sort during the iteration. Bug 429744, r+sr=jst
This commit is contained in:
Родитель
8e6047ac2b
Коммит
e73857359a
|
@ -148,8 +148,9 @@ inline nsINode* NODE_FROM(C& aContent, D& aDocument)
|
|||
|
||||
// IID for the nsINode interface
|
||||
#define NS_INODE_IID \
|
||||
{ 0x6f69dd90, 0x318d, 0x40ac, \
|
||||
{ 0xb8, 0xb8, 0x99, 0xb8, 0xa7, 0xbb, 0x9a, 0x58 } }
|
||||
{ 0x2593b0d5, 0x9a06, 0x4d6b, \
|
||||
{ 0x9a, 0x10, 0xb1, 0x39, 0x9f, 0x1b, 0xa0, 0x8e } }
|
||||
|
||||
|
||||
/**
|
||||
* An internal interface that abstracts some DOMNode-related parts that both
|
||||
|
@ -233,6 +234,16 @@ public:
|
|||
*/
|
||||
virtual nsIContent* GetChildAt(PRUint32 aIndex) const = 0;
|
||||
|
||||
/**
|
||||
* Get a raw pointer to the child array. This should only be used if you
|
||||
* plan to walk a bunch of the kids, promise to make sure that nothing ever
|
||||
* mutates (no attribute changes, not DOM tree changes, no script execution,
|
||||
* NOTHING), and will never ever peform an out-of-bounds access here. This
|
||||
* method may return null if there are no children, or it may return a
|
||||
* garbage pointer..
|
||||
*/
|
||||
virtual nsIContent * const * GetChildArray() const = 0;
|
||||
|
||||
/**
|
||||
* Get the index of a child within this content
|
||||
* @param aPossibleChild the child to get the index of.
|
||||
|
|
|
@ -145,6 +145,16 @@ nsAttrAndChildArray::GetSafeChildAt(PRUint32 aPos) const
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
nsIContent * const *
|
||||
nsAttrAndChildArray::GetChildArray() const
|
||||
{
|
||||
if (!mImpl) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return reinterpret_cast<nsIContent**>(mImpl->mBuffer + AttrSlotsSize());
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAttrAndChildArray::InsertChildAt(nsIContent* aChild, PRUint32 aPos)
|
||||
{
|
||||
|
|
|
@ -88,6 +88,7 @@ public:
|
|||
return reinterpret_cast<nsIContent*>(mImpl->mBuffer[AttrSlotsSize() + aPos]);
|
||||
}
|
||||
nsIContent* GetSafeChildAt(PRUint32 aPos) const;
|
||||
nsIContent * const * GetChildArray() const;
|
||||
nsresult AppendChild(nsIContent* aChild)
|
||||
{
|
||||
return InsertChildAt(aChild, ChildCount());
|
||||
|
|
|
@ -64,7 +64,7 @@ PRBool nsDOMAttribute::sInitialized;
|
|||
nsDOMAttribute::nsDOMAttribute(nsDOMAttributeMap *aAttrMap,
|
||||
nsINodeInfo *aNodeInfo,
|
||||
const nsAString &aValue)
|
||||
: nsIAttribute(aAttrMap, aNodeInfo), mValue(aValue)
|
||||
: nsIAttribute(aAttrMap, aNodeInfo), mValue(aValue), mChild(nsnull)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mNodeInfo, "We must get a nodeinfo here!");
|
||||
|
||||
|
@ -73,18 +73,23 @@ nsDOMAttribute::nsDOMAttribute(nsDOMAttributeMap *aAttrMap,
|
|||
// to drop our reference when it goes away.
|
||||
}
|
||||
|
||||
nsDOMAttribute::~nsDOMAttribute()
|
||||
{
|
||||
NS_IF_RELEASE(mChild);
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMAttribute)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMAttribute)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNodeInfo)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChild)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mChild)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_LISTENERMANAGER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_USERDATA
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMAttribute)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChild)
|
||||
NS_IF_RELEASE(tmp->mChild);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_LISTENERMANAGER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_USERDATA
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
|
@ -668,8 +673,14 @@ nsDOMAttribute::GetChildAt(PRUint32 aIndex) const
|
|||
PRBool hasChild;
|
||||
EnsureChildState(PR_TRUE, hasChild);
|
||||
|
||||
return aIndex == 0 && hasChild ? mChild.get() : nsnull;
|
||||
return aIndex == 0 && hasChild ? mChild : nsnull;
|
||||
}
|
||||
|
||||
nsIContent * const *
|
||||
nsDOMAttribute::GetChildArray() const
|
||||
{
|
||||
return &mChild;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsDOMAttribute::IndexOf(nsINode* aPossibleChild) const
|
||||
|
@ -779,7 +790,7 @@ nsDOMAttribute::EnsureChildState(PRBool aSetText, PRBool &aHasChild) const
|
|||
mutableThis->GetValue(value);
|
||||
|
||||
if (!mChild && !value.IsEmpty()) {
|
||||
nsresult rv = NS_NewTextNode(getter_AddRefs(mutableThis->mChild),
|
||||
nsresult rv = NS_NewTextNode(&mutableThis->mChild,
|
||||
mNodeInfo->NodeInfoManager());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@ class nsDOMAttribute : public nsIAttribute,
|
|||
public:
|
||||
nsDOMAttribute(nsDOMAttributeMap* aAttrMap, nsINodeInfo *aNodeInfo,
|
||||
const nsAString& aValue);
|
||||
virtual ~nsDOMAttribute();
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
|
||||
|
@ -90,6 +91,7 @@ public:
|
|||
virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
|
||||
virtual PRUint32 GetChildCount() const;
|
||||
virtual nsIContent *GetChildAt(PRUint32 aIndex) const;
|
||||
virtual nsIContent * const * GetChildArray() const;
|
||||
virtual PRInt32 IndexOf(nsINode* aPossibleChild) const;
|
||||
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
PRBool aNotify);
|
||||
|
@ -121,9 +123,10 @@ private:
|
|||
nsresult EnsureChildState(PRBool aSetText, PRBool &aHasChild) const;
|
||||
|
||||
nsString mValue;
|
||||
// XXX For now, there's only a single child - a text
|
||||
// element representing the value
|
||||
nsCOMPtr<nsIContent> mChild;
|
||||
// XXX For now, there's only a single child - a text element
|
||||
// representing the value. This is strong ref, but we use a raw
|
||||
// pointer so we can implement GetChildArray().
|
||||
nsIContent* mChild;
|
||||
|
||||
nsIContent *GetContentInternal() const
|
||||
{
|
||||
|
|
|
@ -2682,6 +2682,13 @@ nsDocument::GetChildCount() const
|
|||
return mChildren.ChildCount();
|
||||
}
|
||||
|
||||
nsIContent * const *
|
||||
nsDocument::GetChildArray() const
|
||||
{
|
||||
return mChildren.GetChildArray();
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsDocument::InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
PRBool aNotify)
|
||||
|
|
|
@ -630,6 +630,7 @@ public:
|
|||
// nsINode
|
||||
virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
|
||||
virtual nsIContent *GetChildAt(PRUint32 aIndex) const;
|
||||
virtual nsIContent * const * GetChildArray() const;
|
||||
virtual PRInt32 IndexOf(nsINode* aPossibleChild) const;
|
||||
virtual PRUint32 GetChildCount() const;
|
||||
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
|
|
|
@ -800,6 +800,12 @@ nsGenericDOMDataNode::GetChildAt(PRUint32 aIndex) const
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
nsIContent * const *
|
||||
nsGenericDOMDataNode::GetChildArray() const
|
||||
{
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsGenericDOMDataNode::IndexOf(nsINode* aPossibleChild) const
|
||||
{
|
||||
|
|
|
@ -172,6 +172,7 @@ public:
|
|||
// nsINode methods
|
||||
virtual PRUint32 GetChildCount() const;
|
||||
virtual nsIContent *GetChildAt(PRUint32 aIndex) const;
|
||||
virtual nsIContent * const * GetChildArray() const;
|
||||
virtual PRInt32 IndexOf(nsINode* aPossibleChild) const;
|
||||
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
PRBool aNotify);
|
||||
|
|
|
@ -4322,6 +4322,12 @@ nsGenericElement::GetChildAt(PRUint32 aIndex) const
|
|||
return mAttrsAndChildren.GetSafeChildAt(aIndex);
|
||||
}
|
||||
|
||||
nsIContent * const *
|
||||
nsGenericElement::GetChildArray() const
|
||||
{
|
||||
return mAttrsAndChildren.GetChildArray();
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsGenericElement::IndexOf(nsINode* aPossibleChild) const
|
||||
{
|
||||
|
|
|
@ -361,6 +361,7 @@ public:
|
|||
// nsINode interface methods
|
||||
virtual PRUint32 GetChildCount() const;
|
||||
virtual nsIContent *GetChildAt(PRUint32 aIndex) const;
|
||||
virtual nsIContent * const * GetChildArray() const;
|
||||
virtual PRInt32 IndexOf(nsINode* aPossibleChild) const;
|
||||
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
PRBool aNotify);
|
||||
|
|
|
@ -947,6 +947,16 @@ nsXULElement::GetChildAt(PRUint32 aIndex) const
|
|||
return mAttrsAndChildren.GetSafeChildAt(aIndex);
|
||||
}
|
||||
|
||||
nsIContent * const *
|
||||
nsXULElement::GetChildArray() const
|
||||
{
|
||||
if (NS_FAILED(EnsureContentsGenerated())) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return mAttrsAndChildren.GetChildArray();
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsXULElement::IndexOf(nsINode* aPossibleChild) const
|
||||
{
|
||||
|
|
|
@ -543,6 +543,7 @@ public:
|
|||
// nsINode
|
||||
virtual PRUint32 GetChildCount() const;
|
||||
virtual nsIContent *GetChildAt(PRUint32 aIndex) const;
|
||||
virtual nsIContent * const * GetChildArray() const;
|
||||
virtual PRInt32 IndexOf(nsINode* aPossibleChild) const;
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
|
|
Загрузка…
Ссылка в новой задаче