Bug 504224, crash in GetCommonAncestor, caused because child frame is still focused. Move focus when frame content is removed, and add warnings, r=smaug

This commit is contained in:
Neil Deakin 2009-07-29 10:36:03 -04:00
parent cd0b27cceb
commit 0067af27eb
3 changed files with 42 additions and 4 deletions

View File

@ -0,0 +1,22 @@
<html class="reftest-wait">
<head>
<title>Crash [@ nsFocusManager::GetCommonAncestor], part 2</title>
</head>
<body>
<iframe src="data:text/html;charset=utf-8,%3Chtml%3E%3Chead%3E%3C/head%3E%0A%3Cbody%20onunload%3D%22window.frameElement.parentNode.removeChild%28window.frameElement%29%22%20tabindex%3D%221%22%3E%0A%3Cscript%3E%0Adocument.body.focus%28%29%3B%0A%3C/script%3E%0A%3C/body%3E%0A%3C/html%3E" id="content"></iframe>
<script>
var src=document.getElementById('src');
setInterval(function() {
if (!document.getElementById('content')) {
var x=document.createElement('iframe');
x.src=src;
x.id = 'content';
document.body.appendChild(x);
setTimeout(function() { window.focus(); document.documentElement.removeAttribute('class'); }, 100);
} else
window.frames[0].location.reload();
}, 500);
</script>
</body>
</html>

View File

@ -17,3 +17,4 @@ load 462947.html
load 439206-1.html
load 473284.xul
load 502617.html
load 504224.html

View File

@ -727,9 +727,6 @@ nsFocusManager::ContentRemoved(nsIDocument* aDocument, nsIContent* aContent)
// if the content is currently focused in the window, or is an ancestor
// of the currently focused element, reset the focus within that window.
// Note that nothing special needs to happen when the focused node is an
// iframe; in that case, DocumentUnloaded should be called to invalidate the
// child frame.
nsCOMPtr<nsIContent> content = window->GetFocusedNode();
if (content && nsContentUtils::ContentIsDescendantOf(content, aContent)) {
window->SetFocusedNode(nsnull);
@ -743,8 +740,24 @@ nsFocusManager::ContentRemoved(nsIDocument* aDocument, nsIContent* aContent)
// if this window is currently focused, clear the global focused
// element as well, but don't fire any events.
if (window == mFocusedWindow)
if (window == mFocusedWindow) {
mFocusedContent = nsnull;
}
else {
// Check if the node that was focused is an iframe or similar by looking
// if it has a subdocument. This would indicate that this focused iframe
// and its descendants will be going away. We will need to move the
// focus somewhere else, so just clear the focus in the toplevel window
// so that no element is focused.
nsIDocument* subdoc = aDocument->GetSubDocumentFor(content);
if (subdoc) {
nsCOMPtr<nsISupports> container = subdoc->GetContainer();
nsCOMPtr<nsPIDOMWindow> childWindow = do_GetInterface(container);
if (childWindow && IsSameOrAncestor(childWindow, mFocusedWindow)) {
ClearFocus(mActiveWindow);
}
}
}
}
return NS_OK;
@ -1118,9 +1131,11 @@ nsFocusManager::GetCommonAncestor(nsPIDOMWindow* aWindow1,
{
nsCOMPtr<nsIWebNavigation> webnav(do_GetInterface(aWindow1));
nsCOMPtr<nsIDocShellTreeItem> dsti1 = do_QueryInterface(webnav);
NS_ENSURE_TRUE(dsti1, nsnull);
webnav = do_GetInterface(aWindow2);
nsCOMPtr<nsIDocShellTreeItem> dsti2 = do_QueryInterface(webnav);
NS_ENSURE_TRUE(dsti2, nsnull);
nsAutoTPtrArray<nsIDocShellTreeItem, 30> parents1, parents2;
do {