From 0aa21449ad9b3161d490e159a142ac4f754bf858 Mon Sep 17 00:00:00 2001 From: Peter Van der Beken Date: Mon, 28 Sep 2009 22:33:29 +0200 Subject: [PATCH] Part 1 of fix for bug 518669 (Remove a QI and AddRef/Release from nsNodeUtils::CloneAndAdopt). r=bz. --HG-- extra : rebase_source : 27c23cc1871c5fe6152fc6dba14f4c1c7c54338a --- content/base/src/nsNodeUtils.cpp | 30 +++++++++++++++--------------- content/base/src/nsNodeUtils.h | 32 ++++++++++++++++++++++++++------ 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/content/base/src/nsNodeUtils.cpp b/content/base/src/nsNodeUtils.cpp index a2e7c45f919..be3671325ce 100644 --- a/content/base/src/nsNodeUtils.cpp +++ b/content/base/src/nsNodeUtils.cpp @@ -501,7 +501,7 @@ AdoptFunc(nsAttrHashKey::KeyType aKey, nsIDOMNode *aData, void* aUserArg) data->mCx, data->mOldScope, data->mNewScope, data->mNodesWithProperties, - nsnull, getter_AddRefs(node)); + getter_AddRefs(node)); if (NS_SUCCEEDED(rv) && clone) { nsCOMPtr dummy, attribute = do_QueryInterface(node, &rv); @@ -520,14 +520,14 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep, JSContext *aCx, JSObject *aOldScope, JSObject *aNewScope, nsCOMArray &aNodesWithProperties, - nsINode *aParent, nsIDOMNode **aResult) + nsINode *aParent, nsINode **aResult) { NS_PRECONDITION((!aClone && aNewNodeInfoManager) || !aCx, "If cloning or not getting a new nodeinfo we shouldn't " "rewrap"); NS_PRECONDITION(!aCx || (aOldScope && aNewScope), "Must have scopes"); - NS_PRECONDITION(!aParent || !aNode->IsNodeOfType(nsINode::eDOCUMENT), - "Can't insert document nodes into a parent"); + NS_PRECONDITION(!aParent || aNode->IsNodeOfType(nsINode::eCONTENT), + "Can't insert document or attribute nodes into a parent"); *aResult = nsnull; @@ -578,10 +578,8 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep, if (aParent) { // If we're cloning we need to insert the cloned children into the cloned // parent. - nsCOMPtr cloneContent = do_QueryInterface(clone, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - rv = aParent->AppendChildTo(cloneContent, PR_FALSE); + rv = aParent->AppendChildTo(static_cast(clone.get()), + PR_FALSE); NS_ENSURE_SUCCESS(rv, rv); } else if (aDeep && clone->IsNodeOfType(nsINode::eDOCUMENT)) { @@ -685,17 +683,17 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep, // aNode's children. PRUint32 i, length = aNode->GetChildCount(); for (i = 0; i < length; ++i) { - nsCOMPtr child; + nsCOMPtr child; rv = CloneAndAdopt(aNode->GetChildAt(i), aClone, PR_TRUE, nodeInfoManager, aCx, aOldScope, aNewScope, aNodesWithProperties, clone, getter_AddRefs(child)); NS_ENSURE_SUCCESS(rv, rv); if (isDeepDocumentClone) { - nsCOMPtr content = do_QueryInterface(child); - if (content) { - static_cast(clone.get())-> - RegisterNamedItems(content); - } + NS_ASSERTION(child->IsNodeOfType(nsINode::eCONTENT), + "A clone of a child of a node is not nsIContent?"); + + nsIContent* content = static_cast(child.get()); + static_cast(clone.get())->RegisterNamedItems(content); } } } @@ -729,7 +727,9 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep, NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY); } - return clone ? CallQueryInterface(clone, aResult) : NS_OK; + clone.forget(aResult); + + return NS_OK; } diff --git a/content/base/src/nsNodeUtils.h b/content/base/src/nsNodeUtils.h index ebf54792489..a373779d4f1 100644 --- a/content/base/src/nsNodeUtils.h +++ b/content/base/src/nsNodeUtils.h @@ -167,8 +167,7 @@ public: nsIDOMNode **aResult) { return CloneAndAdopt(aNode, PR_TRUE, aDeep, aNewNodeInfoManager, nsnull, - nsnull, nsnull, aNodesWithProperties, nsnull, - aResult); + nsnull, nsnull, aNodesWithProperties, aResult); } /** @@ -199,7 +198,7 @@ public: nsCOMPtr dummy; return CloneAndAdopt(aNode, PR_FALSE, PR_TRUE, aNewNodeInfoManager, aCx, aOldScope, aNewScope, aNodesWithProperties, - nsnull, getter_AddRefs(dummy)); + getter_AddRefs(dummy)); } /** @@ -312,8 +311,6 @@ private: * descendants) with properties. If aClone is * PR_TRUE every node will be followed by its * clone. - * @param aParent If aClone is PR_TRUE the cloned node will be appended to - * aParent's children. May be null. * @param aResult *aResult will contain the cloned node (if aClone is * PR_TRUE). */ @@ -322,7 +319,30 @@ private: JSContext *aCx, JSObject *aOldScope, JSObject *aNewScope, nsCOMArray &aNodesWithProperties, - nsINode *aParent, nsIDOMNode **aResult); + nsIDOMNode **aResult) + { + nsCOMPtr clone; + nsresult rv = CloneAndAdopt(aNode, aClone, aDeep, aNewNodeInfoManager, + aCx, aOldScope, aNewScope, aNodesWithProperties, + nsnull, getter_AddRefs(clone)); + NS_ENSURE_SUCCESS(rv, rv); + + return clone ? CallQueryInterface(clone, aResult) : NS_OK; + } + + /** + * See above for arguments that aren't described here. + * + * @param aParent If aClone is PR_TRUE the cloned node will be appended to + * aParent's children. May be null. If not null then aNode + * must be an nsIContent. + */ + static nsresult CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep, + nsNodeInfoManager *aNewNodeInfoManager, + JSContext *aCx, JSObject *aOldScope, + JSObject *aNewScope, + nsCOMArray &aNodesWithProperties, + nsINode *aParent, nsINode **aResult); }; #endif // nsNodeUtils_h___