Bug 179089 - crash in selection stuff loading a newsgroup message [@JS_GetPrivate] (Refactors and address release of null pointer). r=caillon, sr=jst

This commit is contained in:
dbradley%netscape.com 2003-07-14 14:28:59 +00:00
Родитель b51877775e
Коммит 90ae82072a
2 изменённых файлов: 166 добавлений и 174 удалений

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

@ -8648,6 +8648,83 @@ nsCSSFrameConstructor::NeedSpecialFrameReframe(nsIPresShell* aPresShell,
return PR_FALSE; return PR_FALSE;
} }
#ifdef MOZ_XUL
enum content_operation
{
CONTENT_INSERTED,
CONTENT_REMOVED
};
// Helper function to lookup the listbox body frame and send a notification
// for insertion or removal of content
static
PRBool NotifyListBoxBody(nsIPresContext* aPresContext,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer,
nsIDocument* aDocument,
nsIFrame* aChildFrame,
PRBool aUseXBLForms,
content_operation aOperation)
{
if (!aContainer)
return PR_FALSE;
nsCOMPtr<nsIBindingManager> bindingManager;
aDocument->GetBindingManager(getter_AddRefs(bindingManager));
nsCOMPtr<nsIAtom> tag;
aChild->GetTag(getter_AddRefs(tag));
if (tag == nsXULAtoms::listitem) {
nsListBoxBodyFrame* listBoxBody = nsnull;
if (aChildFrame) {
// There is a frame for the removed content, so its parent frame is the listboxbody
nsIFrame* parentFrame = aChildFrame->GetParent();
if (parentFrame)
listBoxBody = (nsListBoxBodyFrame*)parentFrame;
} else {
// There is no frame for the removed/inserted content, so we need to dig
// further for the body frame. XBL insertion may not yet have taken
// place here (in the case of replacements), so our only connection
// to the listbox content is through aContainer. Use the boxObject
// to get to the listboxbody frame so we can notify it of the removal or
// insertion.
nsCOMPtr<nsIDOMXULElement> xulEl(do_QueryInterface(aContainer));
if (xulEl) {
nsCOMPtr<nsIBoxObject> boxObject;
xulEl->GetBoxObject(getter_AddRefs(boxObject));
nsCOMPtr<nsIListBoxObject> listBoxObject(do_QueryInterface(boxObject));
nsIListBoxObject* bodyBoxObject = nsnull;
listBoxObject->GetListboxBody(&bodyBoxObject);
listBoxBody = NS_STATIC_CAST(nsListBoxBodyFrame*, bodyBoxObject);
NS_IF_RELEASE(bodyBoxObject);
}
}
if (listBoxBody)
if (aOperation == CONTENT_REMOVED)
listBoxBody->OnContentRemoved(aPresContext, aChildFrame, aIndexInContainer);
else
listBoxBody->OnContentInserted(aPresContext, aChild);
return PR_TRUE;
}
PRInt32 namespaceID;
bindingManager->ResolveTag(aContainer, &namespaceID, getter_AddRefs(tag));
// Just ignore tree tags, anyway we don't create any frames for them.
if (tag == nsXULAtoms::treechildren ||
tag == nsXULAtoms::treeitem ||
tag == nsXULAtoms::treerow ||
(aUseXBLForms && ShouldIgnoreSelectChild(aContainer)))
return PR_TRUE;
return PR_FALSE;
}
#endif // MOZ_XUL
NS_IMETHODIMP NS_IMETHODIMP
nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext, nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext,
nsIContent* aContainer, nsIContent* aContainer,
@ -8676,45 +8753,9 @@ nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext,
nsresult rv = NS_OK; nsresult rv = NS_OK;
#ifdef MOZ_XUL #ifdef MOZ_XUL
if (aContainer) { if (NotifyListBoxBody(aPresContext, aContainer, aChild, aIndexInContainer,
nsCOMPtr<nsIBindingManager> bindingManager; mDocument, nsnull, UseXBLForms(), CONTENT_INSERTED))
mDocument->GetBindingManager(getter_AddRefs(bindingManager)); return NS_OK;
nsCOMPtr<nsIAtom> tag;
aChild->GetTag(getter_AddRefs(tag));
PRBool listitem = tag && tag.get() == nsXULAtoms::listitem;
if (listitem) {
// XBL insertion may not yet have taken place here (in the case of
// replacements), so our only connection to the listbox content is
// through aContainer. Use the boxObject to get to the listboxbody
// frame so we can notify it of the insertion
nsCOMPtr<nsIDOMXULElement> xulEl(do_QueryInterface(aContainer));
if (xulEl) {
nsCOMPtr<nsIBoxObject> boxObject;
xulEl->GetBoxObject(getter_AddRefs(boxObject));
nsCOMPtr<nsIListBoxObject> listBoxObject(do_QueryInterface(boxObject));
nsIListBoxObject* bodyBoxObject = nsnull;
listBoxObject->GetListboxBody(&bodyBoxObject);
nsListBoxBodyFrame* listBoxBody = NS_STATIC_CAST(nsListBoxBodyFrame*, bodyBoxObject);
NS_IF_RELEASE(bodyBoxObject);
if (listBoxBody)
listBoxBody->OnContentInserted(aPresContext, aChild);
}
return NS_OK;
}
PRInt32 namespaceID;
bindingManager->ResolveTag(aContainer, &namespaceID, getter_AddRefs(tag));
// Just ignore tree tags, anyway we don't create any frames for them.
if (tag == nsXULAtoms::treechildren ||
tag == nsXULAtoms::treeitem ||
tag == nsXULAtoms::treerow ||
(UseXBLForms() && ShouldIgnoreSelectChild(aContainer)))
return NS_OK;
}
#endif // MOZ_XUL #endif // MOZ_XUL
// If we have a null parent, then this must be the document element // If we have a null parent, then this must be the document element
@ -9388,55 +9429,10 @@ nsCSSFrameConstructor::ContentRemoved(nsIPresContext* aPresContext,
} }
#ifdef MOZ_XUL #ifdef MOZ_XUL
if (aContainer) { if (NotifyListBoxBody(aPresContext, aContainer, aChild, aIndexInContainer,
nsCOMPtr<nsIBindingManager> bindingManager; mDocument, childFrame, UseXBLForms(), CONTENT_REMOVED))
mDocument->GetBindingManager(getter_AddRefs(bindingManager)); return NS_OK;
nsCOMPtr<nsIAtom> tag;
aChild->GetTag(getter_AddRefs(tag));
PRBool listitem = tag && tag.get() == nsXULAtoms::listitem;
if (listitem) {
nsListBoxBodyFrame* listBoxBody = nsnull;
if (childFrame) {
// There is a frame for the removed content, so its parent frame is the listboxbody
nsIFrame* parentFrame = childFrame->GetParent();
if (parentFrame)
listBoxBody = (nsListBoxBodyFrame*)parentFrame;
} else {
// There is no frame for the removed content, so we need to dig
// further for the body frame. XBL insertion may not yet have taken
// place here (in the case of replacements), so our only connection
// to the listbox content is through aContainer. Use the boxObject
// to get to the listboxbody frame so we can notify it of the removal.
nsCOMPtr<nsIDOMXULElement> xulEl(do_QueryInterface(aContainer));
if (xulEl) {
nsCOMPtr<nsIBoxObject> boxObject;
xulEl->GetBoxObject(getter_AddRefs(boxObject));
nsCOMPtr<nsIListBoxObject> listBoxObject(do_QueryInterface(boxObject));
nsIListBoxObject* bodyBoxObject = nsnull;
listBoxObject->GetListboxBody(&bodyBoxObject);
listBoxBody = NS_STATIC_CAST(nsListBoxBodyFrame*, bodyBoxObject);
NS_RELEASE(bodyBoxObject);
}
}
if (listBoxBody)
listBoxBody->OnContentRemoved(aPresContext, childFrame, aIndexInContainer);
return NS_OK;
}
PRInt32 namespaceID;
bindingManager->ResolveTag(aContainer, &namespaceID, getter_AddRefs(tag));
// Just ignore tree tags, anyway we don't create any frames for them.
if (tag == nsXULAtoms::treechildren ||
tag == nsXULAtoms::treeitem ||
tag == nsXULAtoms::treerow ||
(UseXBLForms() && ShouldIgnoreSelectChild(aContainer)))
return NS_OK;
}
#endif // MOZ_XUL #endif // MOZ_XUL
if (childFrame) { if (childFrame) {

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

@ -8648,6 +8648,83 @@ nsCSSFrameConstructor::NeedSpecialFrameReframe(nsIPresShell* aPresShell,
return PR_FALSE; return PR_FALSE;
} }
#ifdef MOZ_XUL
enum content_operation
{
CONTENT_INSERTED,
CONTENT_REMOVED
};
// Helper function to lookup the listbox body frame and send a notification
// for insertion or removal of content
static
PRBool NotifyListBoxBody(nsIPresContext* aPresContext,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer,
nsIDocument* aDocument,
nsIFrame* aChildFrame,
PRBool aUseXBLForms,
content_operation aOperation)
{
if (!aContainer)
return PR_FALSE;
nsCOMPtr<nsIBindingManager> bindingManager;
aDocument->GetBindingManager(getter_AddRefs(bindingManager));
nsCOMPtr<nsIAtom> tag;
aChild->GetTag(getter_AddRefs(tag));
if (tag == nsXULAtoms::listitem) {
nsListBoxBodyFrame* listBoxBody = nsnull;
if (aChildFrame) {
// There is a frame for the removed content, so its parent frame is the listboxbody
nsIFrame* parentFrame = aChildFrame->GetParent();
if (parentFrame)
listBoxBody = (nsListBoxBodyFrame*)parentFrame;
} else {
// There is no frame for the removed/inserted content, so we need to dig
// further for the body frame. XBL insertion may not yet have taken
// place here (in the case of replacements), so our only connection
// to the listbox content is through aContainer. Use the boxObject
// to get to the listboxbody frame so we can notify it of the removal or
// insertion.
nsCOMPtr<nsIDOMXULElement> xulEl(do_QueryInterface(aContainer));
if (xulEl) {
nsCOMPtr<nsIBoxObject> boxObject;
xulEl->GetBoxObject(getter_AddRefs(boxObject));
nsCOMPtr<nsIListBoxObject> listBoxObject(do_QueryInterface(boxObject));
nsIListBoxObject* bodyBoxObject = nsnull;
listBoxObject->GetListboxBody(&bodyBoxObject);
listBoxBody = NS_STATIC_CAST(nsListBoxBodyFrame*, bodyBoxObject);
NS_IF_RELEASE(bodyBoxObject);
}
}
if (listBoxBody)
if (aOperation == CONTENT_REMOVED)
listBoxBody->OnContentRemoved(aPresContext, aChildFrame, aIndexInContainer);
else
listBoxBody->OnContentInserted(aPresContext, aChild);
return PR_TRUE;
}
PRInt32 namespaceID;
bindingManager->ResolveTag(aContainer, &namespaceID, getter_AddRefs(tag));
// Just ignore tree tags, anyway we don't create any frames for them.
if (tag == nsXULAtoms::treechildren ||
tag == nsXULAtoms::treeitem ||
tag == nsXULAtoms::treerow ||
(aUseXBLForms && ShouldIgnoreSelectChild(aContainer)))
return PR_TRUE;
return PR_FALSE;
}
#endif // MOZ_XUL
NS_IMETHODIMP NS_IMETHODIMP
nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext, nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext,
nsIContent* aContainer, nsIContent* aContainer,
@ -8676,45 +8753,9 @@ nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext,
nsresult rv = NS_OK; nsresult rv = NS_OK;
#ifdef MOZ_XUL #ifdef MOZ_XUL
if (aContainer) { if (NotifyListBoxBody(aPresContext, aContainer, aChild, aIndexInContainer,
nsCOMPtr<nsIBindingManager> bindingManager; mDocument, nsnull, UseXBLForms(), CONTENT_INSERTED))
mDocument->GetBindingManager(getter_AddRefs(bindingManager)); return NS_OK;
nsCOMPtr<nsIAtom> tag;
aChild->GetTag(getter_AddRefs(tag));
PRBool listitem = tag && tag.get() == nsXULAtoms::listitem;
if (listitem) {
// XBL insertion may not yet have taken place here (in the case of
// replacements), so our only connection to the listbox content is
// through aContainer. Use the boxObject to get to the listboxbody
// frame so we can notify it of the insertion
nsCOMPtr<nsIDOMXULElement> xulEl(do_QueryInterface(aContainer));
if (xulEl) {
nsCOMPtr<nsIBoxObject> boxObject;
xulEl->GetBoxObject(getter_AddRefs(boxObject));
nsCOMPtr<nsIListBoxObject> listBoxObject(do_QueryInterface(boxObject));
nsIListBoxObject* bodyBoxObject = nsnull;
listBoxObject->GetListboxBody(&bodyBoxObject);
nsListBoxBodyFrame* listBoxBody = NS_STATIC_CAST(nsListBoxBodyFrame*, bodyBoxObject);
NS_IF_RELEASE(bodyBoxObject);
if (listBoxBody)
listBoxBody->OnContentInserted(aPresContext, aChild);
}
return NS_OK;
}
PRInt32 namespaceID;
bindingManager->ResolveTag(aContainer, &namespaceID, getter_AddRefs(tag));
// Just ignore tree tags, anyway we don't create any frames for them.
if (tag == nsXULAtoms::treechildren ||
tag == nsXULAtoms::treeitem ||
tag == nsXULAtoms::treerow ||
(UseXBLForms() && ShouldIgnoreSelectChild(aContainer)))
return NS_OK;
}
#endif // MOZ_XUL #endif // MOZ_XUL
// If we have a null parent, then this must be the document element // If we have a null parent, then this must be the document element
@ -9388,55 +9429,10 @@ nsCSSFrameConstructor::ContentRemoved(nsIPresContext* aPresContext,
} }
#ifdef MOZ_XUL #ifdef MOZ_XUL
if (aContainer) { if (NotifyListBoxBody(aPresContext, aContainer, aChild, aIndexInContainer,
nsCOMPtr<nsIBindingManager> bindingManager; mDocument, childFrame, UseXBLForms(), CONTENT_REMOVED))
mDocument->GetBindingManager(getter_AddRefs(bindingManager)); return NS_OK;
nsCOMPtr<nsIAtom> tag;
aChild->GetTag(getter_AddRefs(tag));
PRBool listitem = tag && tag.get() == nsXULAtoms::listitem;
if (listitem) {
nsListBoxBodyFrame* listBoxBody = nsnull;
if (childFrame) {
// There is a frame for the removed content, so its parent frame is the listboxbody
nsIFrame* parentFrame = childFrame->GetParent();
if (parentFrame)
listBoxBody = (nsListBoxBodyFrame*)parentFrame;
} else {
// There is no frame for the removed content, so we need to dig
// further for the body frame. XBL insertion may not yet have taken
// place here (in the case of replacements), so our only connection
// to the listbox content is through aContainer. Use the boxObject
// to get to the listboxbody frame so we can notify it of the removal.
nsCOMPtr<nsIDOMXULElement> xulEl(do_QueryInterface(aContainer));
if (xulEl) {
nsCOMPtr<nsIBoxObject> boxObject;
xulEl->GetBoxObject(getter_AddRefs(boxObject));
nsCOMPtr<nsIListBoxObject> listBoxObject(do_QueryInterface(boxObject));
nsIListBoxObject* bodyBoxObject = nsnull;
listBoxObject->GetListboxBody(&bodyBoxObject);
listBoxBody = NS_STATIC_CAST(nsListBoxBodyFrame*, bodyBoxObject);
NS_RELEASE(bodyBoxObject);
}
}
if (listBoxBody)
listBoxBody->OnContentRemoved(aPresContext, childFrame, aIndexInContainer);
return NS_OK;
}
PRInt32 namespaceID;
bindingManager->ResolveTag(aContainer, &namespaceID, getter_AddRefs(tag));
// Just ignore tree tags, anyway we don't create any frames for them.
if (tag == nsXULAtoms::treechildren ||
tag == nsXULAtoms::treeitem ||
tag == nsXULAtoms::treerow ||
(UseXBLForms() && ShouldIgnoreSelectChild(aContainer)))
return NS_OK;
}
#endif // MOZ_XUL #endif // MOZ_XUL
if (childFrame) { if (childFrame) {