Bug 409111, WRONG_DOCUMENT_ERR on unattached nodes through getBoxObjectFor, r+sr=sicking, a=mtschrep

This commit is contained in:
Olli.Pettay@helsinki.fi 2008-02-14 12:45:07 -08:00
Родитель 7c0fde4cae
Коммит f9417e7a4d
6 изменённых файлов: 46 добавлений и 14 удалений

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

@ -785,6 +785,15 @@ nsDocument::nsDocument(const char* aContentType)
SetDOMStringToNull(mLastStyleSheetSet); SetDOMStringToNull(mLastStyleSheetSet);
} }
PR_STATIC_CALLBACK(PLDHashOperator)
ClearAllBoxObjects(const void* aKey, nsPIBoxObject* aBoxObject, void* aUserArg)
{
if (aBoxObject) {
aBoxObject->Clear();
}
return PL_DHASH_NEXT;
}
nsDocument::~nsDocument() nsDocument::~nsDocument()
{ {
#ifdef PR_LOGGING #ifdef PR_LOGGING
@ -876,7 +885,12 @@ nsDocument::~nsDocument()
} }
delete mHeaderData; delete mHeaderData;
if (mBoxObjectTable) {
mBoxObjectTable->EnumerateRead(ClearAllBoxObjects, nsnull);
delete mBoxObjectTable; delete mBoxObjectTable;
}
delete mContentWrapperHash; delete mContentWrapperHash;
} }
@ -919,12 +933,11 @@ RadioGroupsTraverser(const nsAString& aKey, nsAutoPtr<nsRadioGroupStruct>& aData
} }
PR_STATIC_CALLBACK(PLDHashOperator) PR_STATIC_CALLBACK(PLDHashOperator)
BoxObjectTraverser(nsISupports* key, nsPIBoxObject* boxObject, void* userArg) BoxObjectTraverser(const void* key, nsPIBoxObject* boxObject, void* userArg)
{ {
nsCycleCollectionTraversalCallback *cb = nsCycleCollectionTraversalCallback *cb =
static_cast<nsCycleCollectionTraversalCallback*>(userArg); static_cast<nsCycleCollectionTraversalCallback*>(userArg);
cb->NoteXPCOMChild(key);
cb->NoteXPCOMChild(boxObject); cb->NoteXPCOMChild(boxObject);
return PL_DHASH_NEXT; return PL_DHASH_NEXT;
@ -3662,14 +3675,25 @@ nsDocument::GetBoxObjectFor(nsIDOMElement* aElement, nsIBoxObject** aResult)
nsCOMPtr<nsIContent> content(do_QueryInterface(aElement)); nsCOMPtr<nsIContent> content(do_QueryInterface(aElement));
NS_ENSURE_TRUE(content, NS_ERROR_UNEXPECTED); NS_ENSURE_TRUE(content, NS_ERROR_UNEXPECTED);
nsIDocument* doc = content->HasFlag(NODE_FORCE_XBL_BINDINGS) ? nsIDocument* doc = content->GetOwnerDoc();
content->GetOwnerDoc() : content->GetCurrentDoc();
NS_ENSURE_TRUE(doc == this, NS_ERROR_DOM_WRONG_DOCUMENT_ERR); NS_ENSURE_TRUE(doc == this, NS_ERROR_DOM_WRONG_DOCUMENT_ERR);
if (!mHasWarnedAboutBoxObjects && !content->IsNodeOfType(eXUL)) {
mHasWarnedAboutBoxObjects = PR_TRUE;
nsContentUtils::ReportToConsole(nsContentUtils::eDOM_PROPERTIES,
"UseOfGetBoxObjectForWarning",
nsnull, 0,
static_cast<nsIDocument*>(this)->
GetDocumentURI(),
EmptyString(), 0, 0,
nsIScriptError::warningFlag,
"BoxObjects");
}
*aResult = nsnull; *aResult = nsnull;
if (!mBoxObjectTable) { if (!mBoxObjectTable) {
mBoxObjectTable = new nsInterfaceHashtable<nsISupportsHashKey, nsPIBoxObject>; mBoxObjectTable = new nsInterfaceHashtable<nsVoidPtrHashKey, nsPIBoxObject>;
if (mBoxObjectTable && !mBoxObjectTable->Init(12)) { if (mBoxObjectTable && !mBoxObjectTable->Init(12)) {
mBoxObjectTable = nsnull; mBoxObjectTable = nsnull;
} }

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

@ -776,11 +776,13 @@ protected:
// True if document has ever had script handling object. // True if document has ever had script handling object.
PRPackedBool mHasHadScriptHandlingObject:1; PRPackedBool mHasHadScriptHandlingObject:1;
PRPackedBool mHasWarnedAboutBoxObjects:1;
PRUint8 mXMLDeclarationBits; PRUint8 mXMLDeclarationBits;
PRUint8 mDefaultElementType; PRUint8 mDefaultElementType;
nsInterfaceHashtable<nsISupportsHashKey, nsPIBoxObject> *mBoxObjectTable; nsInterfaceHashtable<nsVoidPtrHashKey, nsPIBoxObject> *mBoxObjectTable;
nsInterfaceHashtable<nsVoidPtrHashKey, nsISupports> *mContentWrapperHash; nsInterfaceHashtable<nsVoidPtrHashKey, nsISupports> *mContentWrapperHash;
// The channel that got passed to StartDocumentLoad(), if any // The channel that got passed to StartDocumentLoad(), if any

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

@ -2123,8 +2123,6 @@ nsGenericElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
if (HasAttr(kNameSpaceID_XLink, nsGkAtoms::href)) { if (HasAttr(kNameSpaceID_XLink, nsGkAtoms::href)) {
document->ForgetLink(this); document->ForgetLink(this);
} }
document->ClearBoxObjectFor(this);
} }
// Unset things in the reverse order from how we set them in BindToTree // Unset things in the reverse order from how we set them in BindToTree
@ -2891,7 +2889,6 @@ nsGenericElement::DestroyContent()
nsIDocument *document = GetOwnerDoc(); nsIDocument *document = GetOwnerDoc();
if (document) { if (document) {
document->BindingManager()->ChangeDocumentFor(this, document, nsnull); document->BindingManager()->ChangeDocumentFor(this, document, nsnull);
document->ClearBoxObjectFor(this);
} }
PRUint32 i, count = mAttrsAndChildren.ChildCount(); PRUint32 i, count = mAttrsAndChildren.ChildCount();

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

@ -235,6 +235,13 @@ nsNodeUtils::LastRelease(nsINode* aNode)
aNode->UnsetFlags(NODE_HAS_LISTENERMANAGER); aNode->UnsetFlags(NODE_HAS_LISTENERMANAGER);
} }
if (aNode->IsNodeOfType(nsINode::eELEMENT)) {
nsIDocument* ownerDoc = aNode->GetOwnerDoc();
if (ownerDoc) {
ownerDoc->ClearBoxObjectFor(static_cast<nsIContent*>(aNode));
}
}
delete aNode; delete aNode;
} }
@ -544,6 +551,9 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep,
nsCOMPtr<nsISupports> oldRef; nsCOMPtr<nsISupports> oldRef;
nsIDocument* oldDoc = aNode->GetOwnerDoc(); nsIDocument* oldDoc = aNode->GetOwnerDoc();
if (oldDoc) { if (oldDoc) {
if (aNode->IsNodeOfType(nsINode::eELEMENT)) {
oldDoc->ClearBoxObjectFor(static_cast<nsIContent*>(aNode));
}
oldRef = oldDoc->GetReference(aNode); oldRef = oldDoc->GetReference(aNode);
if (oldRef) { if (oldRef) {
oldDoc->RemoveReference(aNode); oldDoc->RemoveReference(aNode);

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

@ -1830,9 +1830,7 @@ nsXULElement::GetBoxObject(nsIBoxObject** aResult)
*aResult = nsnull; *aResult = nsnull;
// XXX sXBL/XBL2 issue! Owner or current document? // XXX sXBL/XBL2 issue! Owner or current document?
nsIDocument* doc = HasFlag(NODE_FORCE_XBL_BINDINGS) ? nsCOMPtr<nsIDOMNSDocument> nsDoc = do_QueryInterface(GetOwnerDoc());
GetOwnerDoc() : GetCurrentDoc();
nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(doc));
return nsDoc ? nsDoc->GetBoxObjectFor(this, aResult) : NS_ERROR_FAILURE; return nsDoc ? nsDoc->GetBoxObjectFor(this, aResult) : NS_ERROR_FAILURE;
} }

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

@ -55,5 +55,6 @@ UseOfReleaseEventsWarning=Use of releaseEvents() is deprecated, see bug 330494.
UseOfRouteEventWarning=Use of routeEvent() is deprecated, see bug 330494. UseOfRouteEventWarning=Use of routeEvent() is deprecated, see bug 330494.
UseOfPreventBubbleWarning=Event=%S, use of preventBubble() is deprecated. Use W3C standard stopPropagation() instead. UseOfPreventBubbleWarning=Event=%S, use of preventBubble() is deprecated. Use W3C standard stopPropagation() instead.
UseOfPreventCaptureWarning=Event=%S, use of preventCapture() is deprecated. Use W3C standard stopPropagation() instead. UseOfPreventCaptureWarning=Event=%S, use of preventCapture() is deprecated. Use W3C standard stopPropagation() instead.
UseOfGetBoxObjectForWarning=Use of getBoxObjectFor() is deprecated. Try to use element.getBoundingClientRect() if possible.
UnexpectedCanvasVariantStyle=canvas: an attempt to set strokeStyle or fillStyle to a value that is neither a string, a CanvasGradient, or a CanvasPattern was ignored. UnexpectedCanvasVariantStyle=canvas: an attempt to set strokeStyle or fillStyle to a value that is neither a string, a CanvasGradient, or a CanvasPattern was ignored.
EmptyGetElementByIdParam=Empty string passed to getElementById(). EmptyGetElementByIdParam=Empty string passed to getElementById().