зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1196151 - use BrowsingContext for external helper app handling of protocols, r=mattwoodrow
Differential Revision: https://phabricator.services.mozilla.com/D74434
This commit is contained in:
Родитель
e83010ea13
Коммит
228e52aebe
|
@ -11845,7 +11845,7 @@ nsresult nsDocShell::OnLinkClickSync(
|
|||
nsresult rv =
|
||||
extProtService->IsExposedProtocol(scheme.get(), &isExposed);
|
||||
if (NS_SUCCEEDED(rv) && !isExposed) {
|
||||
return extProtService->LoadURI(aURI, this);
|
||||
return extProtService->LoadURI(aURI, mBrowsingContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ XPIDL_SOURCES += [
|
|||
'nsIImageLoadingContent.idl',
|
||||
'nsIMessageManager.idl',
|
||||
'nsIObjectLoadingContent.idl',
|
||||
'nsIRemoteWindowContext.idl',
|
||||
'nsIScriptableContentIterator.idl',
|
||||
'nsIScriptChannel.idl',
|
||||
'nsISelectionController.idl',
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et tw=80 : */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIURI;
|
||||
|
||||
[scriptable, builtinclass, uuid(94f4a92b-752e-4fd9-8345-11b069ca19f3)]
|
||||
interface nsIRemoteWindowContext : nsISupports
|
||||
{
|
||||
/*
|
||||
* Determines if the window is in private browsing.
|
||||
*/
|
||||
readonly attribute boolean usePrivateBrowsing;
|
||||
|
||||
void openURI(in nsIURI aURI);
|
||||
};
|
|
@ -1411,30 +1411,6 @@ void ContentParent::Init() {
|
|||
mScriptableHelper = new ScriptableCPInfo(this);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(RemoteWindowContext, nsIRemoteWindowContext,
|
||||
nsIInterfaceRequestor)
|
||||
|
||||
RemoteWindowContext::RemoteWindowContext(BrowserParent* aBrowserParent)
|
||||
: mBrowserParent(aBrowserParent) {}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RemoteWindowContext::GetInterface(const nsIID& aIID, void** aSink) {
|
||||
return QueryInterface(aIID, aSink);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RemoteWindowContext::OpenURI(nsIURI* aURI) {
|
||||
mBrowserParent->LoadURL(aURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RemoteWindowContext::GetUsePrivateBrowsing(bool* aUsePrivateBrowsing) {
|
||||
nsCOMPtr<nsILoadContext> loadContext = mBrowserParent->GetLoadContext();
|
||||
*aUsePrivateBrowsing = loadContext && loadContext->UsePrivateBrowsing();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void ContentParent::MaybeAsyncSendShutDownMessage() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!TryToRecycle());
|
||||
|
@ -3750,7 +3726,11 @@ mozilla::ipc::IPCResult ContentParent::RecvAccumulateMixedContentHSTS(
|
|||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentParent::RecvLoadURIExternal(
|
||||
nsIURI* uri, PBrowserParent* windowContext) {
|
||||
nsIURI* uri, const MaybeDiscarded<BrowsingContext>& aContext) {
|
||||
if (aContext.IsNullOrDiscarded()) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIExternalProtocolService> extProtService(
|
||||
do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID));
|
||||
if (!extProtService) {
|
||||
|
@ -3761,9 +3741,8 @@ mozilla::ipc::IPCResult ContentParent::RecvLoadURIExternal(
|
|||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
|
||||
RefPtr<RemoteWindowContext> context =
|
||||
new RemoteWindowContext(static_cast<BrowserParent*>(windowContext));
|
||||
extProtService->LoadURI(uri, context);
|
||||
BrowsingContext* bc = aContext.get();
|
||||
extProtService->LoadURI(uri, bc);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
#include "nsIRemoteTab.h"
|
||||
#include "nsIDOMGeoPositionCallback.h"
|
||||
#include "nsIDOMGeoPositionErrorCallback.h"
|
||||
#include "nsIRemoteWindowContext.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "PermissionMessageUtils.h"
|
||||
#include "DriverCrashGuard.h"
|
||||
|
@ -1017,8 +1016,8 @@ class ContentParent final
|
|||
mozilla::ipc::IPCResult RecvNotificationEvent(
|
||||
const nsString& aType, const NotificationEventData& aData);
|
||||
|
||||
mozilla::ipc::IPCResult RecvLoadURIExternal(nsIURI* uri,
|
||||
PBrowserParent* windowContext);
|
||||
mozilla::ipc::IPCResult RecvLoadURIExternal(
|
||||
nsIURI* uri, const MaybeDiscarded<BrowsingContext>& aContext);
|
||||
mozilla::ipc::IPCResult RecvExtProtocolChannelConnectParent(
|
||||
const uint32_t& registrarId);
|
||||
|
||||
|
@ -1512,20 +1511,6 @@ bool IsWebRemoteType(const nsAString& aContentProcessType);
|
|||
|
||||
bool IsWebCoopCoepRemoteType(const nsAString& aContentProcessType);
|
||||
|
||||
class RemoteWindowContext final : public nsIRemoteWindowContext,
|
||||
public nsIInterfaceRequestor {
|
||||
public:
|
||||
explicit RemoteWindowContext(BrowserParent* aBrowserParent);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
NS_DECL_NSIREMOTEWINDOWCONTEXT
|
||||
|
||||
private:
|
||||
~RemoteWindowContext() = default;
|
||||
RefPtr<BrowserParent> mBrowserParent;
|
||||
};
|
||||
|
||||
inline nsISupports* ToSupports(mozilla::dom::ContentParent* aContentParent) {
|
||||
return static_cast<nsIContentParent*>(aContentParent);
|
||||
}
|
||||
|
|
|
@ -968,7 +968,7 @@ parent:
|
|||
async StartVisitedQueries(nsIURI[] uri);
|
||||
async SetURITitle(nsIURI uri, nsString title);
|
||||
|
||||
async LoadURIExternal(nsIURI uri, PBrowser windowContext);
|
||||
async LoadURIExternal(nsIURI uri, MaybeDiscardedBrowsingContext browsingContext);
|
||||
async ExtProtocolChannelConnectParent(uint32_t registrarId);
|
||||
|
||||
// PrefService message
|
||||
|
|
|
@ -12,6 +12,7 @@ interface nsIHandlerApp;
|
|||
interface nsIArray;
|
||||
interface nsIMutableArray;
|
||||
interface nsIInterfaceRequestor;
|
||||
webidl BrowsingContext;
|
||||
|
||||
typedef long nsHandlerInfoAction;
|
||||
|
||||
|
@ -78,7 +79,7 @@ interface nsIHandlerInfo : nsISupports {
|
|||
* @param aURI
|
||||
* The URI to launch this application with
|
||||
*
|
||||
* @param aWindowContext
|
||||
* @param aBrowsingContext
|
||||
* The window to parent the dialog against, and, if a web handler
|
||||
* is chosen, it is loaded in this window as well. See
|
||||
* nsIHandlerApp.launchWithURI for more details.
|
||||
|
@ -87,7 +88,7 @@ interface nsIHandlerInfo : nsISupports {
|
|||
* call. Other exceptions may be thrown.
|
||||
*/
|
||||
void launchWithURI(in nsIURI aURI,
|
||||
[optional] in nsIInterfaceRequestor aWindowContext);
|
||||
[optional] in BrowsingContext aBrowsingContext);
|
||||
|
||||
/**
|
||||
* preferredAction is how the user specified they would like to handle
|
||||
|
@ -247,10 +248,9 @@ interface nsIHandlerApp : nsISupports {
|
|||
* @param aURI
|
||||
* The URI to launch this application with
|
||||
*
|
||||
* @param aWindowContext
|
||||
* @param aBrowsingContext
|
||||
*
|
||||
* Currently only relevant to web-handler apps. If given, this
|
||||
* represents the docshell to load the handler in and is passed
|
||||
* This represents the docshell to load the handler in and is passed
|
||||
* through to nsIURILoader.openURI. If this parameter is null or
|
||||
* not present, the web handler app implementation will attempt to
|
||||
* find/create a place to load the handler and do so. As of this
|
||||
|
@ -260,7 +260,7 @@ interface nsIHandlerApp : nsISupports {
|
|||
* off to the system default browser (bug 394479).
|
||||
*/
|
||||
void launchWithURI(in nsIURI aURI,
|
||||
[optional] in nsIInterfaceRequestor aWindowContext);
|
||||
[optional] in BrowsingContext aBrowsingContext);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -44,8 +44,7 @@ ParentChannelListener::ParentChannelListener(
|
|||
mShouldIntercept(false),
|
||||
mShouldSuspendIntercept(false),
|
||||
mInterceptCanceled(false),
|
||||
mBrowsingContext(aBrowsingContext),
|
||||
mUsePrivateBrowsing(aUsePrivateBrowsing) {
|
||||
mBrowsingContext(aBrowsingContext) {
|
||||
LOG(("ParentChannelListener::ParentChannelListener [this=%p, next=%p]", this,
|
||||
aListener));
|
||||
|
||||
|
@ -72,7 +71,6 @@ NS_INTERFACE_MAP_BEGIN(ParentChannelListener)
|
|||
NS_INTERFACE_MAP_ENTRY(nsINetworkInterceptController)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableStreamListener)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAuthPromptProvider, mBrowsingContext)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIRemoteWindowContext, mBrowsingContext)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInterfaceRequestor)
|
||||
NS_INTERFACE_MAP_ENTRY_CONCRETE(ParentChannelListener)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
@ -158,8 +156,7 @@ ParentChannelListener::OnAfterLastPart(nsresult aStatus) {
|
|||
|
||||
NS_IMETHODIMP
|
||||
ParentChannelListener::GetInterface(const nsIID& aIID, void** result) {
|
||||
if (aIID.Equals(NS_GET_IID(nsINetworkInterceptController)) ||
|
||||
aIID.Equals(NS_GET_IID(nsIRemoteWindowContext))) {
|
||||
if (aIID.Equals(NS_GET_IID(nsINetworkInterceptController))) {
|
||||
return QueryInterface(aIID, result);
|
||||
}
|
||||
|
||||
|
@ -421,38 +418,6 @@ ParentChannelListener::GetAuthPrompt(uint32_t aPromptReason, const nsIID& iid,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ParentChannelListener::nsIRemoteWindowContext
|
||||
//
|
||||
|
||||
NS_IMETHODIMP
|
||||
ParentChannelListener::OpenURI(nsIURI* aURI) {
|
||||
nsCString spec;
|
||||
aURI->GetSpec(spec);
|
||||
|
||||
RefPtr<dom::CanonicalBrowsingContext> bc = mBrowsingContext;
|
||||
|
||||
NS_DispatchToMainThread(
|
||||
NS_NewRunnableFunction("ParentChannelListener::OpenURI", [spec, bc]() {
|
||||
dom::LoadURIOptions loadURIOptions;
|
||||
loadURIOptions.mTriggeringPrincipal =
|
||||
nsContentUtils::GetSystemPrincipal();
|
||||
loadURIOptions.mLoadFlags =
|
||||
nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
|
||||
nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL;
|
||||
|
||||
ErrorResult rv;
|
||||
bc->LoadURI(NS_ConvertUTF8toUTF16(spec), loadURIOptions, rv);
|
||||
}));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ParentChannelListener::GetUsePrivateBrowsing(bool* aUsePrivateBrowsing) {
|
||||
*aUsePrivateBrowsing = mUsePrivateBrowsing;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ParentChannelListener::nsIThreadRetargetableStreamListener
|
||||
//
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIMultiPartChannel.h"
|
||||
#include "nsINetworkInterceptController.h"
|
||||
#include "nsIRemoteWindowContext.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIThreadRetargetableStreamListener.h"
|
||||
|
||||
|
@ -36,8 +35,7 @@ class ParentChannelListener final : public nsIInterfaceRequestor,
|
|||
public nsIMultiPartChannelListener,
|
||||
public nsINetworkInterceptController,
|
||||
public nsIThreadRetargetableStreamListener,
|
||||
private nsIAuthPromptProvider,
|
||||
private nsIRemoteWindowContext {
|
||||
private nsIAuthPromptProvider {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
|
@ -46,7 +44,6 @@ class ParentChannelListener final : public nsIInterfaceRequestor,
|
|||
NS_DECL_NSIMULTIPARTCHANNELLISTENER
|
||||
NS_DECL_NSINETWORKINTERCEPTCONTROLLER
|
||||
NS_DECL_NSIAUTHPROMPTPROVIDER
|
||||
NS_DECL_NSIREMOTEWINDOWCONTEXT
|
||||
NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(PARENT_CHANNEL_LISTENER)
|
||||
|
@ -109,9 +106,6 @@ class ParentChannelListener final : public nsIInterfaceRequestor,
|
|||
// True if we received OnStartRequest for a nsIMultiPartChannel, and are
|
||||
// expected AllPartsStopped to be called when complete.
|
||||
bool mIsMultiPart = false;
|
||||
|
||||
// True if the nsILoadContext for this channel has private browsing enabled.
|
||||
bool mUsePrivateBrowsing = false;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(ParentChannelListener, PARENT_CHANNEL_LISTENER)
|
||||
|
|
|
@ -79,7 +79,7 @@ var dialog = {
|
|||
_URI: null,
|
||||
_itemChoose: null,
|
||||
_okButton: null,
|
||||
_windowCtxt: null,
|
||||
_browsingContext: null,
|
||||
_buttonDisabled: true,
|
||||
|
||||
// Methods
|
||||
|
@ -90,25 +90,10 @@ var dialog = {
|
|||
initialize: function initialize() {
|
||||
this._handlerInfo = window.arguments[7].QueryInterface(Ci.nsIHandlerInfo);
|
||||
this._URI = window.arguments[8].QueryInterface(Ci.nsIURI);
|
||||
this._windowCtxt = window.arguments[9];
|
||||
this._browsingContext = window.arguments[9];
|
||||
let usePrivateBrowsing = false;
|
||||
if (this._windowCtxt) {
|
||||
// The context should be nsIRemoteWindowContext in OOP, or nsIDOMWindow otherwise.
|
||||
try {
|
||||
usePrivateBrowsing = this._windowCtxt.getInterface(
|
||||
Ci.nsIRemoteWindowContext
|
||||
).usePrivateBrowsing;
|
||||
} catch (e) {
|
||||
try {
|
||||
let opener = this._windowCtxt.getInterface(Ci.nsIDOMWindow);
|
||||
usePrivateBrowsing = PrivateBrowsingUtils.isContentWindowPrivate(
|
||||
opener
|
||||
);
|
||||
} catch (e) {
|
||||
Cu.reportError(`No interface to determine privateness: ${e}`);
|
||||
}
|
||||
}
|
||||
this._windowCtxt.QueryInterface(Ci.nsIInterfaceRequestor);
|
||||
if (this._browsingContext) {
|
||||
usePrivateBrowsing = this._browsingContext.usePrivateBrowsing;
|
||||
}
|
||||
|
||||
this.isPrivate =
|
||||
|
@ -348,7 +333,7 @@ var dialog = {
|
|||
);
|
||||
hs.store(this._handlerInfo);
|
||||
|
||||
this._handlerInfo.launchWithURI(this._URI, this._windowCtxt);
|
||||
this._handlerInfo.launchWithURI(this._URI, this._browsingContext);
|
||||
window.close();
|
||||
},
|
||||
|
||||
|
|
|
@ -82,8 +82,8 @@ nsFlatpakHandlerApp::Equals(nsIHandlerApp* aHandlerApp, bool* _retval) {
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFlatpakHandlerApp::LaunchWithURI(nsIURI* aUri,
|
||||
nsIInterfaceRequestor* aRequestor) {
|
||||
nsFlatpakHandlerApp::LaunchWithURI(
|
||||
nsIURI* aUri, mozilla::dom::BrowsingContext* aBrowsingContext) {
|
||||
nsCString spec;
|
||||
aUri->GetSpec(spec);
|
||||
GError* error = nullptr;
|
||||
|
@ -229,7 +229,8 @@ nsGIOMimeApp::Equals(nsIHandlerApp* aHandlerApp, bool* _retval) {
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGIOMimeApp::LaunchWithURI(nsIURI* aUri, nsIInterfaceRequestor* aRequestor) {
|
||||
nsGIOMimeApp::LaunchWithURI(nsIURI* aUri,
|
||||
mozilla::dom::BrowsingContext* aBrowsingContext) {
|
||||
GList uris = {0};
|
||||
nsCString spec;
|
||||
aUri->GetSpec(spec);
|
||||
|
|
|
@ -117,7 +117,7 @@ NS_IMETHODIMP RemoteHandlerApp::Equals(nsIHandlerApp* aHandlerApp,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP RemoteHandlerApp::LaunchWithURI(
|
||||
nsIURI* aURI, nsIInterfaceRequestor* aWindowContext) {
|
||||
nsIURI* aURI, BrowsingContext* aBrowsingContext) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
|
|
@ -105,9 +105,9 @@ NS_IMETHODIMP ProxyHandlerInfo::GetDefaultDescription(
|
|||
}
|
||||
|
||||
/* void launchWithURI (in nsIURI aURI,
|
||||
[optional] in nsIInterfaceRequestor aWindowContext); */
|
||||
[optional] in BrowsingContext aBrowsingContext); */
|
||||
NS_IMETHODIMP ProxyHandlerInfo::LaunchWithURI(
|
||||
nsIURI* aURI, nsIInterfaceRequestor* aWindowContext) {
|
||||
nsIURI* aURI, mozilla::dom::BrowsingContext* aBrowsingContext) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
ChromeUtils.defineModuleGetter(
|
||||
|
@ -60,7 +59,7 @@ nsWebHandlerApp.prototype = {
|
|||
return false;
|
||||
},
|
||||
|
||||
launchWithURI(aURI, aWindowContext) {
|
||||
launchWithURI(aURI, aBrowsingContext) {
|
||||
// XXX need to strip passwd & username from URI to handle, as per the
|
||||
// WhatWG HTML5 draft. nsSimpleURL, which is what we're going to get,
|
||||
// can't do this directly. Ideally, we'd fix nsStandardURL to make it
|
||||
|
@ -76,67 +75,18 @@ nsWebHandlerApp.prototype = {
|
|||
let policy = WebExtensionPolicy.getByURI(uriToSend);
|
||||
let privateAllowed = !policy || policy.privateBrowsingAllowed;
|
||||
|
||||
// if we have a window context, use the URI loader to load there
|
||||
if (aWindowContext) {
|
||||
try {
|
||||
let remoteWindow = aWindowContext.getInterface(
|
||||
Ci.nsIRemoteWindowContext
|
||||
// if we have a context, use the URI loader to load there
|
||||
if (aBrowsingContext) {
|
||||
if (aBrowsingContext.usePrivateBrowsing && !privateAllowed) {
|
||||
throw Components.Exception(
|
||||
"Extension not allowed in private windows.",
|
||||
Cr.NS_ERROR_FILE_NOT_FOUND
|
||||
);
|
||||
if (remoteWindow.usePrivateBrowsing && !privateAllowed) {
|
||||
throw Components.Exception(
|
||||
"Extension not allowed in private windows.",
|
||||
Cr.NS_ERROR_FILE_NOT_FOUND
|
||||
);
|
||||
}
|
||||
// getInterface throws if the object doesn't implement the given
|
||||
// interface, so this try/catch statement is more of an if.
|
||||
// If aWindowContext refers to a remote docshell, send the load
|
||||
// request to the correct process.
|
||||
remoteWindow.openURI(uriToSend);
|
||||
return;
|
||||
} catch (e) {
|
||||
if (e.result != Cr.NS_NOINTERFACE) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
let isPrivate = aWindowContext
|
||||
.getInterface(Ci.nsIDocShell)
|
||||
.QueryInterface(Ci.nsILoadContext).usePrivateBrowsing;
|
||||
if (isPrivate && !privateAllowed) {
|
||||
throw Components.Exception(
|
||||
"Extension not allowed in private windows.",
|
||||
Cr.NS_ERROR_FILE_NOT_FOUND
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.result != Cr.NS_NOINTERFACE) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// create a channel from this URI
|
||||
var channel = NetUtil.newChannel({
|
||||
uri: uriToSend,
|
||||
loadUsingSystemPrincipal: true,
|
||||
});
|
||||
channel.loadFlags = Ci.nsIChannel.LOAD_DOCUMENT_URI;
|
||||
|
||||
// load the channel
|
||||
var uriLoader = Cc["@mozilla.org/uriloader;1"].getService(
|
||||
Ci.nsIURILoader
|
||||
);
|
||||
|
||||
// XXX ideally, whether to pass the IS_CONTENT_PREFERRED flag should be
|
||||
// passed in from above. Practically, the flag is probably a reasonable
|
||||
// default since browsers don't care much, and link click is likely to be
|
||||
// the more interesting case for non-browser apps. See
|
||||
// <https://bugzilla.mozilla.org/show_bug.cgi?id=392957#c9> for details.
|
||||
uriLoader.openURI(
|
||||
channel,
|
||||
Ci.nsIURILoader.IS_CONTENT_PREFERRED,
|
||||
aWindowContext
|
||||
let triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
|
||||
Services.tm.dispatchToMainThread(() =>
|
||||
aBrowsingContext.loadURI(uriSpecToSend, { triggeringPrincipal })
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
@ -144,7 +94,7 @@ nsWebHandlerApp.prototype = {
|
|||
let win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
|
||||
// If this is an extension handler, check private browsing access.
|
||||
if (!privateAllowed && PrivateBrowsingUtils.isContentWindowPrivate(win)) {
|
||||
if (!privateAllowed && PrivateBrowsingUtils.isWindowPrivate(win)) {
|
||||
throw Components.Exception(
|
||||
"Extension not allowed in private windows.",
|
||||
Cr.NS_ERROR_FILE_NOT_FOUND
|
||||
|
|
|
@ -67,8 +67,8 @@ nsAndroidHandlerApp::Equals(nsIHandlerApp* aHandlerApp, bool* aRetval) {
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAndroidHandlerApp::LaunchWithURI(nsIURI* aURI,
|
||||
nsIInterfaceRequestor* aWindowContext) {
|
||||
nsAndroidHandlerApp::LaunchWithURI(
|
||||
nsIURI* aURI, mozilla::dom::BrowsingContext* aBrowsingContext) {
|
||||
nsCString uriSpec;
|
||||
aURI->GetSpec(uriSpec);
|
||||
return java::GeckoAppShell::OpenUriExternal(uriSpec, mMimeType, mPackageName,
|
||||
|
|
|
@ -202,8 +202,9 @@ nsMIMEInfoAndroid::GetDefaultDescription(nsAString& aDesc) {
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMIMEInfoAndroid::LaunchWithURI(nsIURI* aURI, nsIInterfaceRequestor* req) {
|
||||
return mPrefApp->LaunchWithURI(aURI, req);
|
||||
nsMIMEInfoAndroid::LaunchWithURI(
|
||||
nsIURI* aURI, mozilla::dom::BrowsingContext* aBrowsingContext) {
|
||||
return mPrefApp->LaunchWithURI(aURI, aBrowsingContext);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -408,6 +409,6 @@ nsresult nsMIMEInfoAndroid::SystemChooser::Equals(nsIHandlerApp* aHandlerApp,
|
|||
}
|
||||
|
||||
nsresult nsMIMEInfoAndroid::SystemChooser::LaunchWithURI(
|
||||
nsIURI* aURI, nsIInterfaceRequestor*) {
|
||||
nsIURI* aURI, mozilla::dom::BrowsingContext*) {
|
||||
return mOuter->LoadUriInternal(aURI);
|
||||
}
|
||||
|
|
|
@ -18,8 +18,8 @@ class nsLocalHandlerAppMac : public nsLocalHandlerApp {
|
|||
: nsLocalHandlerApp(aName, aExecutable) {}
|
||||
virtual ~nsLocalHandlerAppMac() {}
|
||||
|
||||
NS_IMETHOD LaunchWithURI(nsIURI* aURI,
|
||||
nsIInterfaceRequestor* aWindowContext) override;
|
||||
NS_IMETHOD LaunchWithURI(
|
||||
nsIURI* aURI, mozilla::dom::BrowsingContext* aBrowsingContext) override;
|
||||
NS_IMETHOD GetName(nsAString& aName) override;
|
||||
};
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ NS_IMETHODIMP nsLocalHandlerAppMac::GetName(nsAString& aName) {
|
|||
* somewhere more central (see bug 389922).
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsLocalHandlerAppMac::LaunchWithURI(nsIURI* aURI, nsIInterfaceRequestor* aWindowContext) {
|
||||
nsLocalHandlerAppMac::LaunchWithURI(nsIURI* aURI, mozilla::dom::BrowsingContext* aBrowsingContext) {
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
nsresult rv;
|
||||
|
|
|
@ -77,8 +77,8 @@ nsDBusHandlerApp::Equals(nsIHandlerApp* aHandlerApp, bool* _retval) {
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDBusHandlerApp::LaunchWithURI(nsIURI* aURI,
|
||||
nsIInterfaceRequestor* aWindowContext) {
|
||||
nsDBusHandlerApp::LaunchWithURI(
|
||||
nsIURI* aURI, mozilla::dom::BrowsingContext* aBrowsingContext) {
|
||||
nsAutoCString spec;
|
||||
nsresult rv = aURI->GetAsciiSpec(spec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
|
|
@ -921,13 +921,13 @@ static const char kExternalProtocolDefaultPref[] =
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsExternalHelperAppService::LoadURI(nsIURI* aURI,
|
||||
nsIInterfaceRequestor* aWindowContext) {
|
||||
BrowsingContext* aBrowsingContext) {
|
||||
NS_ENSURE_ARG_POINTER(aURI);
|
||||
NS_ENSURE_ARG_POINTER(aBrowsingContext);
|
||||
|
||||
if (XRE_IsContentProcess()) {
|
||||
nsCOMPtr<nsIBrowserChild> browserChild(do_GetInterface(aWindowContext));
|
||||
mozilla::dom::ContentChild::GetSingleton()->SendLoadURIExternal(
|
||||
aURI, static_cast<dom::BrowserChild*>(browserChild.get()));
|
||||
aURI, aBrowsingContext);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -977,7 +977,7 @@ nsExternalHelperAppService::LoadURI(nsIURI* aURI,
|
|||
// a helper app or the system default, we just launch the URI.
|
||||
if (!alwaysAsk && (preferredAction == nsIHandlerInfo::useHelperApp ||
|
||||
preferredAction == nsIHandlerInfo::useSystemDefault)) {
|
||||
rv = handler->LaunchWithURI(uri, aWindowContext);
|
||||
rv = handler->LaunchWithURI(uri, aBrowsingContext);
|
||||
// We are not supposed to ask, but when file not found the user most likely
|
||||
// uninstalled the application which handles the uri so we will continue
|
||||
// by application chooser dialog.
|
||||
|
@ -990,7 +990,7 @@ nsExternalHelperAppService::LoadURI(nsIURI* aURI,
|
|||
do_CreateInstance("@mozilla.org/content-dispatch-chooser;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return chooser->Ask(handler, aWindowContext, uri,
|
||||
return chooser->Ask(handler, aBrowsingContext, uri,
|
||||
nsIContentDispatchChooser::REASON_CANNOT_HANDLE);
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ class nsExternalHelperAppService : public nsIExternalHelperAppService,
|
|||
NS_IMETHOD GetProtocolHandlerInfo(const nsACString& aScheme,
|
||||
nsIHandlerInfo** aHandlerInfo) override;
|
||||
NS_IMETHOD LoadURI(nsIURI* aURI,
|
||||
nsIInterfaceRequestor* aWindowContext) override;
|
||||
mozilla::dom::BrowsingContext* aBrowsingContext) override;
|
||||
NS_IMETHOD SetProtocolHandlerDefaults(nsIHandlerInfo* aHandlerInfo,
|
||||
bool aOSHandlerExists) override;
|
||||
|
||||
|
|
|
@ -158,14 +158,12 @@ nsresult nsExtProtocolChannel::OpenURL() {
|
|||
"the protocol?");
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIInterfaceRequestor> aggCallbacks;
|
||||
rv = NS_NewNotificationCallbacksAggregation(mCallbacks, mLoadGroup,
|
||||
getter_AddRefs(aggCallbacks));
|
||||
RefPtr<mozilla::dom::BrowsingContext> ctx;
|
||||
rv = mLoadInfo->GetTargetBrowsingContext(getter_AddRefs(ctx));
|
||||
if (NS_FAILED(rv)) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
rv = extProtService->LoadURI(mUrl, aggCallbacks);
|
||||
rv = extProtService->LoadURI(mUrl, ctx);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && mListener) {
|
||||
mStatus = NS_ERROR_NO_CONTENT;
|
||||
|
|
|
@ -8,6 +8,7 @@ interface nsIHandlerInfo;
|
|||
interface nsIHelperAppLauncher;
|
||||
interface nsIURI;
|
||||
interface nsIInterfaceRequestor;
|
||||
webidl BrowsingContext;
|
||||
|
||||
/**
|
||||
* This is used to ask a user what they would like to do with a given piece of
|
||||
|
@ -27,18 +28,15 @@ interface nsIContentDispatchChooser : nsISupports {
|
|||
* @param aHander
|
||||
* The interface describing the details of how this content should or
|
||||
* can be handled.
|
||||
* @param aWindowContext
|
||||
* The parent window context to show this chooser. This can be null,
|
||||
* and some implementations may not care about it. Generally, you'll
|
||||
* want to pass an nsIDOMWindow in so the chooser can be properly
|
||||
* parented when opened.
|
||||
* @param aBrowsingContext
|
||||
* The browsing context that's the parent for this chooser.
|
||||
* @param aURI
|
||||
* The URI of the resource that we are asking about.
|
||||
* @param aReason
|
||||
* The reason why we are asking (see above).
|
||||
*/
|
||||
void ask(in nsIHandlerInfo aHandler,
|
||||
in nsIInterfaceRequestor aWindowContext,
|
||||
in BrowsingContext aBrowsingContext,
|
||||
in nsIURI aURI,
|
||||
in unsigned long aReason);
|
||||
};
|
||||
|
|
|
@ -35,8 +35,7 @@ interface nsIExternalHelperAppService : nsISupports
|
|||
* @param aMimeContentType The content type of the incoming data
|
||||
* @param aRequest The request corresponding to the incoming data
|
||||
* @param aContentContext Used in processing content document refresh
|
||||
* headers after target content is downloaded. Note in e10s land
|
||||
* this is likely a CPOW that points to a window in the child process.
|
||||
* headers after target content is downloaded.
|
||||
* @param aForceSave True to always save this content to disk, regardless of
|
||||
* nsIMIMEInfo and other such influences.
|
||||
* @param aWindowContext Used in parenting helper app dialogs, usually
|
||||
|
|
|
@ -11,6 +11,8 @@ interface nsIFile;
|
|||
interface nsIInterfaceRequestor;
|
||||
interface nsIHandlerInfo;
|
||||
|
||||
webidl BrowsingContext;
|
||||
|
||||
/**
|
||||
* The external protocol service is used for finding and launching
|
||||
* web handlers (a la registerProtocolHandler in the HTML5 draft) or
|
||||
|
@ -95,8 +97,8 @@ interface nsIExternalProtocolService : nsISupports
|
|||
* @param aURI
|
||||
* The URI to load
|
||||
*
|
||||
* @param aWindowContext
|
||||
* The window to parent the dialog against, and, if a web handler
|
||||
* @param aBrowsingContext
|
||||
* The context to parent the dialog against, and, if a web handler
|
||||
* is chosen, it is loaded in this window as well. This parameter
|
||||
* may be ultimately passed nsIURILoader.openURI in the case of a
|
||||
* web handler, and aWindowContext is null or not present, web
|
||||
|
@ -108,7 +110,7 @@ interface nsIExternalProtocolService : nsISupports
|
|||
* (bug 394479).
|
||||
*/
|
||||
void loadURI(in nsIURI aURI,
|
||||
[optional] in nsIInterfaceRequestor aWindowContext);
|
||||
in BrowsingContext aBrowsingContext);
|
||||
|
||||
/**
|
||||
* Gets a human-readable description for the application responsible for
|
||||
|
|
|
@ -89,8 +89,8 @@ nsLocalHandlerApp::Equals(nsIHandlerApp* aHandlerApp, bool* _retval) {
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLocalHandlerApp::LaunchWithURI(nsIURI* aURI,
|
||||
nsIInterfaceRequestor* aWindowContext) {
|
||||
nsLocalHandlerApp::LaunchWithURI(
|
||||
nsIURI* aURI, mozilla::dom::BrowsingContext* aBrowsingContext) {
|
||||
// pass the entire URI to the handler.
|
||||
nsAutoCString spec;
|
||||
aURI->GetAsciiSpec(spec);
|
||||
|
|
|
@ -307,8 +307,7 @@ nsMIMEInfoBase::LaunchWithFile(nsIFile* aFile) {
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMIMEInfoBase::LaunchWithURI(nsIURI* aURI,
|
||||
nsIInterfaceRequestor* aWindowContext) {
|
||||
nsMIMEInfoBase::LaunchWithURI(nsIURI* aURI, BrowsingContext* aBrowsingContext) {
|
||||
// This is only being called with protocol handlers
|
||||
NS_ASSERTION(mClass == eProtocolInfo,
|
||||
"nsMIMEInfoBase should be a protocol handler");
|
||||
|
@ -353,7 +352,7 @@ nsMIMEInfoBase::LaunchWithURI(nsIURI* aURI,
|
|||
return NS_ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
return mPreferredApplication->LaunchWithURI(aURI, aWindowContext);
|
||||
return mPreferredApplication->LaunchWithURI(aURI, aBrowsingContext);
|
||||
}
|
||||
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIProcess.h"
|
||||
#include "mozilla/dom/BrowsingContext.h"
|
||||
|
||||
/**
|
||||
* UTF8 moz-icon URI string for the default handler application's icon, if
|
||||
|
@ -57,8 +58,8 @@ class nsMIMEInfoBase : public nsIMIMEInfo {
|
|||
nsIMutableArray** aPossibleAppHandlers) override;
|
||||
NS_IMETHOD GetDefaultDescription(nsAString& aDefaultDescription) override;
|
||||
NS_IMETHOD LaunchWithFile(nsIFile* aFile) override;
|
||||
NS_IMETHOD LaunchWithURI(nsIURI* aURI,
|
||||
nsIInterfaceRequestor* aWindowContext) override;
|
||||
NS_IMETHOD LaunchWithURI(
|
||||
nsIURI* aURI, mozilla::dom::BrowsingContext* aBrowsingContext) override;
|
||||
NS_IMETHOD GetPreferredAction(nsHandlerInfoAction* aPreferredAction) override;
|
||||
NS_IMETHOD SetPreferredAction(nsHandlerInfoAction aPreferredAction) override;
|
||||
NS_IMETHOD GetAlwaysAskBeforeHandling(
|
||||
|
|
|
@ -45,11 +45,32 @@ add_task(async function() {
|
|||
);
|
||||
handlerSvc.store(protoInfo);
|
||||
|
||||
// Middle-click a testprotocol link and check the new tab is correct
|
||||
let link = "#link";
|
||||
const expectedURL =
|
||||
"https://example.com/foobar?uri=web%2Btestprotocol%3Atest";
|
||||
|
||||
// Create a framed link:
|
||||
await SpecialPowers.spawn(browser, [], async function() {
|
||||
let iframe = content.document.createElement("iframe");
|
||||
iframe.src = `data:text/html,<a href="web+testprotocol:test">Click me</a>`;
|
||||
content.document.body.append(iframe);
|
||||
// Can't return this promise because it resolves to the event object.
|
||||
await ContentTaskUtils.waitForEvent(iframe, "load");
|
||||
iframe.contentDocument.querySelector("a").click();
|
||||
});
|
||||
let kidContext = browser.browsingContext.children[0];
|
||||
await TestUtils.waitForCondition(() => {
|
||||
let spec = kidContext.currentWindowGlobal?.documentURI?.spec || "";
|
||||
return spec == expectedURL;
|
||||
});
|
||||
is(
|
||||
kidContext.currentWindowGlobal.documentURI.spec,
|
||||
expectedURL,
|
||||
"Should load in frame."
|
||||
);
|
||||
|
||||
// Middle-click a testprotocol link and check the new tab is correct
|
||||
let link = "#link";
|
||||
|
||||
let promiseTabOpened = BrowserTestUtils.waitForNewTab(gBrowser, expectedURL);
|
||||
await BrowserTestUtils.synthesizeMouseAtCenter(link, { button: 1 }, browser);
|
||||
let tab = await promiseTabOpened;
|
||||
|
|
|
@ -21,7 +21,7 @@ class nsLocalHandlerAppUIKit final : public nsLocalHandlerApp {
|
|||
: nsLocalHandlerApp(aName, aExecutable) {}
|
||||
|
||||
NS_IMETHOD LaunchWithURI(nsIURI* aURI,
|
||||
nsIInterfaceRequestor* aWindowContext) override;
|
||||
BrowsingContext* aBrowsingContext) override;
|
||||
};
|
||||
|
||||
#endif /* nslocalhandlerappuikit_h_ */
|
||||
|
|
Загрузка…
Ссылка в новой задаче