diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 2071c20a034..80f7caab9a5 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -8648,6 +8648,83 @@ nsCSSFrameConstructor::NeedSpecialFrameReframe(nsIPresShell* aPresShell, 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 bindingManager; + aDocument->GetBindingManager(getter_AddRefs(bindingManager)); + + nsCOMPtr 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 xulEl(do_QueryInterface(aContainer)); + if (xulEl) { + nsCOMPtr boxObject; + xulEl->GetBoxObject(getter_AddRefs(boxObject)); + nsCOMPtr 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 nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext, nsIContent* aContainer, @@ -8676,45 +8753,9 @@ nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext, nsresult rv = NS_OK; #ifdef MOZ_XUL - if (aContainer) { - nsCOMPtr bindingManager; - mDocument->GetBindingManager(getter_AddRefs(bindingManager)); - - nsCOMPtr 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 xulEl(do_QueryInterface(aContainer)); - if (xulEl) { - nsCOMPtr boxObject; - xulEl->GetBoxObject(getter_AddRefs(boxObject)); - nsCOMPtr 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; - - } + if (NotifyListBoxBody(aPresContext, aContainer, aChild, aIndexInContainer, + mDocument, nsnull, UseXBLForms(), CONTENT_INSERTED)) + return NS_OK; #endif // MOZ_XUL // If we have a null parent, then this must be the document element @@ -9388,55 +9429,10 @@ nsCSSFrameConstructor::ContentRemoved(nsIPresContext* aPresContext, } #ifdef MOZ_XUL - if (aContainer) { - nsCOMPtr bindingManager; - mDocument->GetBindingManager(getter_AddRefs(bindingManager)); + if (NotifyListBoxBody(aPresContext, aContainer, aChild, aIndexInContainer, + mDocument, childFrame, UseXBLForms(), CONTENT_REMOVED)) + return NS_OK; - nsCOMPtr 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 xulEl(do_QueryInterface(aContainer)); - if (xulEl) { - nsCOMPtr boxObject; - xulEl->GetBoxObject(getter_AddRefs(boxObject)); - nsCOMPtr 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 if (childFrame) { diff --git a/layout/html/style/src/nsCSSFrameConstructor.cpp b/layout/html/style/src/nsCSSFrameConstructor.cpp index 2071c20a034..80f7caab9a5 100644 --- a/layout/html/style/src/nsCSSFrameConstructor.cpp +++ b/layout/html/style/src/nsCSSFrameConstructor.cpp @@ -8648,6 +8648,83 @@ nsCSSFrameConstructor::NeedSpecialFrameReframe(nsIPresShell* aPresShell, 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 bindingManager; + aDocument->GetBindingManager(getter_AddRefs(bindingManager)); + + nsCOMPtr 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 xulEl(do_QueryInterface(aContainer)); + if (xulEl) { + nsCOMPtr boxObject; + xulEl->GetBoxObject(getter_AddRefs(boxObject)); + nsCOMPtr 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 nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext, nsIContent* aContainer, @@ -8676,45 +8753,9 @@ nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext, nsresult rv = NS_OK; #ifdef MOZ_XUL - if (aContainer) { - nsCOMPtr bindingManager; - mDocument->GetBindingManager(getter_AddRefs(bindingManager)); - - nsCOMPtr 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 xulEl(do_QueryInterface(aContainer)); - if (xulEl) { - nsCOMPtr boxObject; - xulEl->GetBoxObject(getter_AddRefs(boxObject)); - nsCOMPtr 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; - - } + if (NotifyListBoxBody(aPresContext, aContainer, aChild, aIndexInContainer, + mDocument, nsnull, UseXBLForms(), CONTENT_INSERTED)) + return NS_OK; #endif // MOZ_XUL // If we have a null parent, then this must be the document element @@ -9388,55 +9429,10 @@ nsCSSFrameConstructor::ContentRemoved(nsIPresContext* aPresContext, } #ifdef MOZ_XUL - if (aContainer) { - nsCOMPtr bindingManager; - mDocument->GetBindingManager(getter_AddRefs(bindingManager)); + if (NotifyListBoxBody(aPresContext, aContainer, aChild, aIndexInContainer, + mDocument, childFrame, UseXBLForms(), CONTENT_REMOVED)) + return NS_OK; - nsCOMPtr 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 xulEl(do_QueryInterface(aContainer)); - if (xulEl) { - nsCOMPtr boxObject; - xulEl->GetBoxObject(getter_AddRefs(boxObject)); - nsCOMPtr 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 if (childFrame) {