зеркало из https://github.com/mozilla/gecko-dev.git
Fix nsWindowWatcher::FindItemWithName to pass in the right requestor; expose it
on nsPIWindowWatcher and use it from nsDocShellTreeOwner. Bug 282296, r=danm, sr=jst
This commit is contained in:
Родитель
ead05b8709
Коммит
20fcb245ac
|
@ -325,52 +325,12 @@ nsDocShellTreeOwner::FindItemWithNameAcrossWindows(const PRUnichar* aName,
|
|||
nsIDocShellTreeItem** aFoundItem)
|
||||
{
|
||||
// search for the item across the list of top-level windows
|
||||
nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
|
||||
nsCOMPtr<nsPIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
|
||||
if (!wwatch)
|
||||
return NS_OK;
|
||||
|
||||
PRBool more;
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> windows;
|
||||
wwatch->GetWindowEnumerator(getter_AddRefs(windows));
|
||||
|
||||
rv = NS_OK;
|
||||
do {
|
||||
windows->HasMoreElements(&more);
|
||||
if (!more)
|
||||
break;
|
||||
nsCOMPtr<nsISupports> nextSupWindow;
|
||||
windows->GetNext(getter_AddRefs(nextSupWindow));
|
||||
if (nextSupWindow) {
|
||||
// it's a DOM Window. cut straight to the ScriptGlobalObject.
|
||||
nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryInterface(nextSupWindow));
|
||||
if (sgo) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> 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<nsIDocShellTreeItem> 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<nsIDocShellTreeOwner> 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
|
||||
|
|
|
@ -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++
|
||||
|
|
|
@ -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<nsISimpleEnumerator> windows;
|
||||
GetWindowEnumerator(getter_AddRefs(windows));
|
||||
if (!windows)
|
||||
|
@ -1427,15 +1425,33 @@ nsWindowWatcher::FindItemWithName(const PRUnichar* aName,
|
|||
break;
|
||||
nsCOMPtr<nsISupports> nextSupWindow;
|
||||
windows->GetNext(getter_AddRefs(nextSupWindow));
|
||||
if (nextSupWindow) {
|
||||
nsCOMPtr<nsIDOMWindow> nextWindow(do_QueryInterface(nextSupWindow));
|
||||
if (nextWindow) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem;
|
||||
GetWindowTreeItem(nextWindow, getter_AddRefs(treeItem));
|
||||
if (treeItem) {
|
||||
rv = treeItem->FindItemWithName(aName, treeItem, aOriginalRequestor,
|
||||
aFoundItem);
|
||||
if (NS_FAILED(rv) || *aFoundItem)
|
||||
nsCOMPtr<nsIDOMWindow> nextWindow(do_QueryInterface(nextSupWindow));
|
||||
if (nextWindow) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> 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<nsIDocShellTreeItem> 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<nsIDocShellTreeOwner> 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче