diff --git a/mozilla/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp b/mozilla/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp index 8e652fd7a46..e766faaa32b 100644 --- a/mozilla/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp +++ b/mozilla/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp @@ -325,52 +325,12 @@ nsDocShellTreeOwner::FindItemWithNameAcrossWindows(const PRUnichar* aName, nsIDocShellTreeItem** aFoundItem) { // search for the item across the list of top-level windows - nsCOMPtr wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID)); + nsCOMPtr wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID)); if (!wwatch) return NS_OK; - PRBool more; - nsresult rv; - - nsCOMPtr windows; - wwatch->GetWindowEnumerator(getter_AddRefs(windows)); - - rv = NS_OK; - do { - windows->HasMoreElements(&more); - if (!more) - break; - nsCOMPtr nextSupWindow; - windows->GetNext(getter_AddRefs(nextSupWindow)); - if (nextSupWindow) { - // it's a DOM Window. cut straight to the ScriptGlobalObject. - nsCOMPtr sgo(do_QueryInterface(nextSupWindow)); - if (sgo) { - nsCOMPtr item = - do_QueryInterface(sgo->GetDocShell()); - if (item) { - // Get the root tree item of same type, since roots are the only - // things that call into the treeowner to look for named items. - nsCOMPtr root; - item->GetSameTypeRootTreeItem(getter_AddRefs(root)); - NS_ASSERTION(root, "Must have root tree item of same type"); - // Make sure not to call back into our kid if we got called from it - if (root != aRequestor) { - // Get the tree owner so we can pass it in as the - // requestor so the child knows not to call back up. - nsCOMPtr rootOwner; - root->GetTreeOwner(getter_AddRefs(rootOwner)); - rv = root->FindItemWithName(aName, rootOwner, aOriginalRequestor, - aFoundItem); - if (NS_FAILED(rv) || *aFoundItem) - break; - } - } - } - } - } while(1); - - return rv; + return wwatch->FindItemWithName(aName, aRequestor, aOriginalRequestor, + aFoundItem); } void diff --git a/mozilla/embedding/components/windowwatcher/public/nsPIWindowWatcher.idl b/mozilla/embedding/components/windowwatcher/public/nsPIWindowWatcher.idl index 3ae2d047a6a..e6ad82f2d19 100644 --- a/mozilla/embedding/components/windowwatcher/public/nsPIWindowWatcher.idl +++ b/mozilla/embedding/components/windowwatcher/public/nsPIWindowWatcher.idl @@ -45,6 +45,7 @@ interface nsIDOMWindow; interface nsISimpleEnumerator; interface nsIWebBrowserChrome; +interface nsIDocShellTreeItem; %{C++ #include "jspubtd.h" @@ -52,7 +53,7 @@ interface nsIWebBrowserChrome; [ptr] native jsvalptr(jsval); -[uuid(d535806e-afaf-47d1-8d89-783ad088c62a)] +[uuid(3aaad312-e09d-4010-a013-78ef653dac99)] interface nsPIWindowWatcher : nsISupports { @@ -88,6 +89,28 @@ interface nsPIWindowWatcher : nsISupports in string aName, in string aFeatures, in boolean aDialog, in PRUint32 argc, in jsvalptr argv); + /** + * Find a named docshell tree item amongst all windows registered + * with the window watcher. This may be a subframe in some window, + * for example. + * + * @param aName the name of the window. Must not be null. + * @param aRequestor the tree item immediately making the request. + * We should make sure to not recurse down into its findItemWithName + * method. + * @param aOriginalRequestor the original treeitem that made the request. + * Used for security checks. + * @return the tree item with aName as the name, or null if there + * isn't one. "Special" names, like _self, _top, etc, will be + * treated specially only if aRequestor is null; in that case they + * will be resolved relative to the first window the windowwatcher + * knows about. + * @see findItemWithName methods on nsIDocShellTreeItem and + * nsIDocShellTreeOwner + */ + nsIDocShellTreeItem findItemWithName(in wstring aName, + in nsIDocShellTreeItem aRequestor, + in nsIDocShellTreeItem aOriginalRequestor); }; %{C++ diff --git a/mozilla/embedding/components/windowwatcher/src/nsWindowWatcher.cpp b/mozilla/embedding/components/windowwatcher/src/nsWindowWatcher.cpp index 288a57d0436..d01b109e1d5 100644 --- a/mozilla/embedding/components/windowwatcher/src/nsWindowWatcher.cpp +++ b/mozilla/embedding/components/windowwatcher/src/nsWindowWatcher.cpp @@ -558,7 +558,7 @@ nsWindowWatcher::OpenWindowJS(nsIDOMWindow *aParent, parentItem->FindItemWithName(name.get(), nsnull, callerItem, getter_AddRefs(newDocShellItem)); } else - FindItemWithName(name.get(), callerItem, + FindItemWithName(name.get(), nsnull, callerItem, getter_AddRefs(newDocShellItem)); } @@ -1069,7 +1069,7 @@ nsWindowWatcher::GetWindowByName(const PRUnichar *aTargetName, docShellTreeItem = do_QueryInterface(webNav); if (docShellTreeItem) { - // XXXbz sort out original requestor? + // Note: original requestor is null here, per idl comments docShellTreeItem->FindItemWithName(aTargetName, nsnull, nsnull, getter_AddRefs(treeItem)); } @@ -1077,7 +1077,8 @@ nsWindowWatcher::GetWindowByName(const PRUnichar *aTargetName, // Next, see if the TargetName exists in any window hierarchy if (!treeItem) { - FindItemWithName(aTargetName, nsnull, getter_AddRefs(treeItem)); + // Note: original requestor is null here, per idl comments + FindItemWithName(aTargetName, nsnull, nsnull, getter_AddRefs(treeItem)); } if (treeItem) { @@ -1396,8 +1397,9 @@ nsWindowWatcher::WinHasOption(const char *aOptions, const char *aName, known open window. a failure to find the item will not necessarily return a failure method value. check aFoundItem. */ -nsresult +NS_IMETHODIMP nsWindowWatcher::FindItemWithName(const PRUnichar* aName, + nsIDocShellTreeItem* aRequestor, nsIDocShellTreeItem* aOriginalRequestor, nsIDocShellTreeItem** aFoundItem) { @@ -1409,10 +1411,6 @@ nsWindowWatcher::FindItemWithName(const PRUnichar* aName, nsDependentString name(aName); - if(name.LowerCaseEqualsLiteral("_blank") || name.LowerCaseEqualsLiteral("_new")) - return NS_OK; - // _content will be handled by individual windows, below - nsCOMPtr windows; GetWindowEnumerator(getter_AddRefs(windows)); if (!windows) @@ -1427,15 +1425,33 @@ nsWindowWatcher::FindItemWithName(const PRUnichar* aName, break; nsCOMPtr nextSupWindow; windows->GetNext(getter_AddRefs(nextSupWindow)); - if (nextSupWindow) { - nsCOMPtr nextWindow(do_QueryInterface(nextSupWindow)); - if (nextWindow) { - nsCOMPtr treeItem; - GetWindowTreeItem(nextWindow, getter_AddRefs(treeItem)); - if (treeItem) { - rv = treeItem->FindItemWithName(aName, treeItem, aOriginalRequestor, - aFoundItem); - if (NS_FAILED(rv) || *aFoundItem) + nsCOMPtr nextWindow(do_QueryInterface(nextSupWindow)); + if (nextWindow) { + nsCOMPtr treeItem; + GetWindowTreeItem(nextWindow, getter_AddRefs(treeItem)); + if (treeItem) { + // Get the root tree item of same type, since roots are the only + // things that call into the treeowner to look for named items. + nsCOMPtr root; + treeItem->GetSameTypeRootTreeItem(getter_AddRefs(root)); + NS_ASSERTION(root, "Must have root tree item of same type"); + // Make sure not to call back into aRequestor + if (root != aRequestor) { + // Get the tree owner so we can pass it in as the requestor so + // the child knows not to call back up, since we're walking + // all windows already. + nsCOMPtr rootOwner; + // Note: if we have no aRequestor, then we want to also look for + // "special" window names, so pass a null requestor. This will mean + // that the treeitem calls back up to us, effectively (with a + // non-null aRequestor), so break the loop immediately after the + // call in that case. + if (aRequestor) { + root->GetTreeOwner(getter_AddRefs(rootOwner)); + } + rv = root->FindItemWithName(aName, rootOwner, aOriginalRequestor, + aFoundItem); + if (NS_FAILED(rv) || *aFoundItem || !aRequestor) break; } } diff --git a/mozilla/embedding/components/windowwatcher/src/nsWindowWatcher.h b/mozilla/embedding/components/windowwatcher/src/nsWindowWatcher.h index bbd87a32ae3..178ae6992ef 100644 --- a/mozilla/embedding/components/windowwatcher/src/nsWindowWatcher.h +++ b/mozilla/embedding/components/windowwatcher/src/nsWindowWatcher.h @@ -84,10 +84,6 @@ private: nsWatcherWindowEntry *FindWindowEntry(nsIDOMWindow *aWindow); nsresult RemoveWindow(nsWatcherWindowEntry *inInfo); - nsresult FindItemWithName(const PRUnichar *aName, - nsIDocShellTreeItem *aOriginalRequestor, - nsIDocShellTreeItem **aFoundItem); - static JSContext *GetJSContextFromWindow(nsIDOMWindow *aWindow); static JSContext *GetJSContextFromCallStack(); static nsresult URIfromURL(const char *aURL,