Fix for bug 56764 (Document appendChild, insertBefore fail to throw HIERARCHY_REQUEST_ERR when inserting Text Nodes). r=sicking, sr=jst.

This commit is contained in:
peter%propagandism.org 2003-10-21 12:27:00 +00:00
Родитель f3c345fee8
Коммит 0626ddaef4
2 изменённых файлов: 66 добавлений и 54 удалений

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

@ -3132,75 +3132,94 @@ nsDocument::GetLocalName(nsAString& aLocalName)
return NS_OK; return NS_OK;
} }
nsresult
nsDocument::IsAllowedAsChild(PRUint16 aNodeType, nsIContent* aRefContent)
{
if (aNodeType != nsIDOMNode::COMMENT_NODE &&
aNodeType != nsIDOMNode::ELEMENT_NODE &&
aNodeType != nsIDOMNode::PROCESSING_INSTRUCTION_NODE &&
aNodeType != nsIDOMNode::DOCUMENT_TYPE_NODE) {
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
if (aNodeType == nsIDOMNode::ELEMENT_NODE && mRootContent &&
mRootContent != aRefContent) {
// We already have a child Element, and we're not trying to
// replace it, so throw an error.
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
if (aNodeType == nsIDOMNode::DOCUMENT_TYPE_NODE) {
nsCOMPtr<nsIDOMDocumentType> docType;
GetDoctype(getter_AddRefs(docType));
nsCOMPtr<nsIContent> docTypeContent = do_QueryInterface(docType);
if (docTypeContent && docTypeContent != aRefContent) {
// We already have a doctype, and we're not trying to
// replace it, so throw an error.
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
}
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsDocument::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsDocument::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
nsIDOMNode** aReturn) nsIDOMNode** aReturn)
{ {
NS_ASSERTION(aNewChild, "null ptr"); *aReturn = nsnull;
PRInt32 indx;
PRUint16 nodeType;
*aReturn = nsnull; // Do we need to do this? NS_ENSURE_ARG(aNewChild);
if (!aNewChild) {
return NS_ERROR_NULL_POINTER;
}
nsresult rv = nsContentUtils::CheckSameOrigin(this, aNewChild); nsresult rv = nsContentUtils::CheckSameOrigin(this, aNewChild);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
// If it's a child type we can't handle (per DOM spec), or if it's an PRUint16 nodeType;
// element and we already have a root (our addition to DOM spec), throw
// HIERARCHY_REQUEST_ERR.
aNewChild->GetNodeType(&nodeType); aNewChild->GetNodeType(&nodeType);
if (((nodeType != COMMENT_NODE) &&
(nodeType != TEXT_NODE) && rv = IsAllowedAsChild(nodeType, nsnull);
(nodeType != PROCESSING_INSTRUCTION_NODE) && if (NS_FAILED(rv)) {
(nodeType != DOCUMENT_TYPE_NODE) && return rv;
(nodeType != ELEMENT_NODE)) ||
((nodeType == ELEMENT_NODE) && mRootContent)) {
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
} }
nsCOMPtr<nsIContent> content(do_QueryInterface(aNewChild)); nsCOMPtr<nsIContent> content = do_QueryInterface(aNewChild);
if (!content) { if (!content) {
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
} }
PRInt32 indx;
if (!aRefChild) { if (!aRefChild) {
indx = mChildren.Count(); indx = mChildren.Count();
mChildren.AppendObject(content); mChildren.AppendObject(content);
} }
else { else {
nsCOMPtr<nsIContent> refContent(do_QueryInterface(aRefChild)); nsCOMPtr<nsIContent> refContent(do_QueryInterface(aRefChild));
if (!refContent) { if (!refContent) {
return NS_ERROR_DOM_NOT_FOUND_ERR; return NS_ERROR_DOM_NOT_FOUND_ERR;
} }
indx = mChildren.IndexOf(refContent); indx = mChildren.IndexOf(refContent);
if (indx != -1) { if (indx == -1) {
mChildren.InsertObjectAt(content, indx);
} else {
// couldn't find refChild // couldn't find refChild
return NS_ERROR_DOM_NOT_FOUND_ERR; return NS_ERROR_DOM_NOT_FOUND_ERR;
} }
mChildren.InsertObjectAt(content, indx);
} }
// If we get here, we've succesfully inserted content into the // If we get here, we've succesfully inserted content into the
// index-th spot in mChildren. // index-th spot in mChildren.
if (nodeType == ELEMENT_NODE) { if (nodeType == nsIDOMNode::ELEMENT_NODE) {
mRootContent = content; mRootContent = content;
} }
content->SetDocument(this, PR_TRUE, PR_TRUE); content->SetDocument(this, PR_TRUE, PR_TRUE);
ContentInserted(nsnull, content, indx); ContentInserted(nsnull, content, indx);
*aReturn = aNewChild; NS_ADDREF(*aReturn = aNewChild);
NS_ADDREF(aNewChild);
return NS_OK; return NS_OK;
} }
@ -3211,40 +3230,32 @@ nsDocument::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild,
{ {
*aReturn = nsnull; *aReturn = nsnull;
NS_ENSURE_TRUE(aNewChild && aOldChild, NS_ERROR_NULL_POINTER); NS_ENSURE_ARG(aNewChild && aOldChild);
nsresult rv = NS_OK; nsCOMPtr<nsIContent> refContent(do_QueryInterface(aOldChild));
PRInt32 indx; if (!refContent) {
PRUint16 nodeType; return NS_ERROR_DOM_NOT_FOUND_ERR;
}
rv = nsContentUtils::CheckSameOrigin(this, aNewChild); nsCOMPtr<nsIContent> content = do_QueryInterface(aNewChild);
if (!content) {
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
nsresult rv = nsContentUtils::CheckSameOrigin(this, aNewChild);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
PRUint16 nodeType;
aNewChild->GetNodeType(&nodeType); aNewChild->GetNodeType(&nodeType);
if ((COMMENT_NODE != nodeType) && rv = IsAllowedAsChild(nodeType, refContent);
(TEXT_NODE != nodeType) && if (NS_FAILED(rv)) {
(PROCESSING_INSTRUCTION_NODE != nodeType) && return rv;
(DOCUMENT_TYPE_NODE != nodeType) &&
(ELEMENT_NODE != nodeType)) {
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
} }
nsCOMPtr<nsIContent> content(do_QueryInterface(aNewChild)); PRInt32 indx = mChildren.IndexOf(refContent);
nsCOMPtr<nsIContent> refContent(do_QueryInterface(aOldChild));
if (!content || !refContent) {
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
if (nodeType == ELEMENT_NODE && mRootContent &&
mRootContent != refContent) {
// Caller attempted to add a second element as a child.
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
indx = mChildren.IndexOf(refContent);
if (indx == -1) { if (indx == -1) {
// The reference child is not a child of the document. // The reference child is not a child of the document.
return NS_ERROR_DOM_NOT_FOUND_ERR; return NS_ERROR_DOM_NOT_FOUND_ERR;
@ -3255,15 +3266,14 @@ nsDocument::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild,
mChildren.ReplaceObjectAt(content, indx); mChildren.ReplaceObjectAt(content, indx);
// This is OK because we checked above. // This is OK because we checked above.
if (nodeType == ELEMENT_NODE) { if (nodeType == nsIDOMNode::ELEMENT_NODE) {
mRootContent = content; mRootContent = content;
} }
content->SetDocument(this, PR_TRUE, PR_TRUE); content->SetDocument(this, PR_TRUE, PR_TRUE);
ContentInserted(nsnull, content, indx); ContentInserted(nsnull, content, indx);
*aReturn = aOldChild; NS_ADDREF(*aReturn = aNewChild);
NS_ADDREF(aOldChild);
return rv; return rv;
} }

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

@ -676,6 +676,8 @@ protected:
nsCOMPtr<nsIScriptEventManager> mScriptEventManager; nsCOMPtr<nsIScriptEventManager> mScriptEventManager;
private: private:
nsresult IsAllowedAsChild(PRUint16 aNodeType, nsIContent* aRefContent);
// These are not implemented and not supported. // These are not implemented and not supported.
nsDocument(const nsDocument& aOther); nsDocument(const nsDocument& aOther);
nsDocument& operator=(const nsDocument& aOther); nsDocument& operator=(const nsDocument& aOther);