diff --git a/content/base/src/nsDOMAttributeMap.cpp b/content/base/src/nsDOMAttributeMap.cpp index 53f6fdffa7d..3a05ad0d930 100644 --- a/content/base/src/nsDOMAttributeMap.cpp +++ b/content/base/src/nsDOMAttributeMap.cpp @@ -42,8 +42,10 @@ #include "nsDOMAttributeMap.h" #include "nsDOMAttribute.h" +#include "nsIDOM3Document.h" #include "nsGenericElement.h" #include "nsIContent.h" +#include "nsIDocument.h" #include "nsINameSpaceManager.h" #include "nsDOMError.h" #include "nsContentUtils.h" @@ -271,7 +273,15 @@ nsDOMAttributeMap::SetNamedItemInternal(nsIDOMNode *aNode, } if (!mContent->HasSameOwnerDoc(iAttribute)) { - return NS_ERROR_DOM_WRONG_DOCUMENT_ERR; + nsCOMPtr domDoc = + do_QueryInterface(mContent->GetOwnerDoc(), &rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr adoptedNode; + rv = domDoc->AdoptNode(aNode, getter_AddRefs(adoptedNode)); + NS_ENSURE_SUCCESS(rv, rv); + + NS_ASSERTION(adoptedNode == aNode, "Uh, adopt node changed nodes?"); } // Get nodeinfo and preexisting attribute (if it exists) diff --git a/content/base/src/nsGenericElement.cpp b/content/base/src/nsGenericElement.cpp index 4abd16a8194..4c51abc8ccb 100644 --- a/content/base/src/nsGenericElement.cpp +++ b/content/base/src/nsGenericElement.cpp @@ -2738,22 +2738,29 @@ nsGenericElement::doInsertChildAt(nsIContent* aKid, PRUint32 aIndex, nsresult rv; nsINode* container = NODE_FROM(aParent, aDocument); - if (!container->HasSameOwnerDoc(aKid)) { - if (aKid->GetOwnerDoc()) { - return NS_ERROR_DOM_WRONG_DOCUMENT_ERR; - } + if (!container->HasSameOwnerDoc(aKid)) { nsCOMPtr kid = do_QueryInterface(aKid, &rv); NS_ENSURE_SUCCESS(rv, rv); - + PRUint16 nodeType = 0; rv = kid->GetNodeType(&nodeType); NS_ENSURE_SUCCESS(rv, rv); - // DocumentType nodes are the only nodes that can have a null ownerDocument - // according to the DOM spec, and we need to allow inserting them. - if (nodeType != nsIDOMNode::DOCUMENT_TYPE_NODE) { - return NS_ERROR_DOM_WRONG_DOCUMENT_ERR; + nsCOMPtr domDoc = + do_QueryInterface(container->GetOwnerDoc()); + + // DocumentType nodes are the only nodes that can have a null + // ownerDocument according to the DOM spec, and we need to allow + // inserting them w/o calling AdoptNode(). + + if (domDoc && (nodeType != nsIDOMNode::DOCUMENT_TYPE_NODE || + aKid->GetOwnerDoc())) { + nsCOMPtr adoptedKid; + rv = domDoc->AdoptNode(kid, getter_AddRefs(adoptedKid)); + NS_ENSURE_SUCCESS(rv, rv); + + NS_ASSERTION(adoptedKid == kid, "Uh, adopt node changed nodes?"); } } @@ -3254,16 +3261,20 @@ nsGenericElement::doReplaceOrInsertBefore(PRBool aReplace, return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; } - if (!container->HasSameOwnerDoc(newContent)) { - // DocumentType nodes are the only nodes that can have a null ownerDocument - // according to the DOM spec, and we need to allow inserting them. - if (nodeType != nsIDOMNode::DOCUMENT_TYPE_NODE || - newContent->GetOwnerDoc()) { - return NS_ERROR_DOM_WRONG_DOCUMENT_ERR; - } + // DocumentType nodes are the only nodes that can have a null + // ownerDocument according to the DOM spec, and we need to allow + // inserting them w/o calling AdoptNode(). + if (!container->HasSameOwnerDoc(newContent) && + (nodeType != nsIDOMNode::DOCUMENT_TYPE_NODE || + newContent->GetOwnerDoc())) { + nsCOMPtr domDoc = do_QueryInterface(aDocument); - if (!nsContentUtils::CanCallerAccess(aNewChild)) { - return NS_ERROR_DOM_SECURITY_ERR; + if (domDoc) { + nsCOMPtr adoptedKid; + nsresult rv = domDoc->AdoptNode(aNewChild, getter_AddRefs(adoptedKid)); + NS_ENSURE_SUCCESS(rv, rv); + + NS_ASSERTION(adoptedKid == aNewChild, "Uh, adopt node changed nodes?"); } } diff --git a/dom/tests/mochitest/dom-level2-core/test_namednodemapsetnameditemns04.html b/dom/tests/mochitest/dom-level2-core/test_namednodemapsetnameditemns04.html index 7c1c1081396..fa130ffcebd 100644 --- a/dom/tests/mochitest/dom-level2-core/test_namednodemapsetnameditemns04.html +++ b/dom/tests/mochitest/dom-level2-core/test_namednodemapsetnameditemns04.html @@ -122,7 +122,7 @@ docAlt = domImpl.createDocument(nullNS,"newDoc",docType); catch(ex) { success = (typeof(ex.code) != 'undefined' && ex.code == 4); } - assertTrue("throw_WRONG_DOCUMENT_ERR",success); + todo(success, "throw_WRONG_DOCUMENT_ERR"); } }