You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
4.1 KiB
128 lines
4.1 KiB
/* 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/. */ |
|
|
|
"use strict"; |
|
|
|
this.EXPORTED_SYMBOLS = ["E10SUtils"]; |
|
|
|
const {interfaces: Ci, utils: Cu, classes: Cc} = Components; |
|
|
|
Cu.import("resource://gre/modules/Services.jsm"); |
|
|
|
function getAboutModule(aURL) { |
|
// Needs to match NS_GetAboutModuleName |
|
let moduleName = aURL.path.replace(/[#?].*/, "").toLowerCase(); |
|
let contract = "@mozilla.org/network/protocol/about;1?what=" + moduleName; |
|
try { |
|
return Cc[contract].getService(Ci.nsIAboutModule); |
|
} |
|
catch (e) { |
|
// Either the about module isn't defined or it is broken. In either case |
|
// ignore it. |
|
return null; |
|
} |
|
} |
|
|
|
this.E10SUtils = { |
|
canLoadURIInProcess: function(aURL, aProcess) { |
|
// loadURI in browser.xml treats null as about:blank |
|
if (!aURL) |
|
aURL = "about:blank"; |
|
|
|
// Javascript urls can load in any process, they apply to the current document |
|
if (aURL.startsWith("javascript:")) |
|
return true; |
|
|
|
let processIsRemote = aProcess == Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT; |
|
|
|
let canLoadRemote = true; |
|
let mustLoadRemote = true; |
|
|
|
if (aURL.startsWith("about:")) { |
|
let url = Services.io.newURI(aURL, null, null); |
|
let module = getAboutModule(url); |
|
// If the module doesn't exist then an error page will be loading, that |
|
// should be ok to load in either process |
|
if (module) { |
|
let flags = module.getURIFlags(url); |
|
canLoadRemote = !!(flags & Ci.nsIAboutModule.URI_CAN_LOAD_IN_CHILD); |
|
mustLoadRemote = !!(flags & Ci.nsIAboutModule.URI_MUST_LOAD_IN_CHILD); |
|
} |
|
} |
|
|
|
if (aURL.startsWith("chrome:")) { |
|
let url; |
|
try { |
|
// This can fail for invalid Chrome URIs, in which case we will end up |
|
// not loading anything anyway. |
|
url = Services.io.newURI(aURL, null, null); |
|
} catch (ex) { |
|
canLoadRemote = true; |
|
mustLoadRemote = false; |
|
} |
|
if (url) { |
|
let chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"]. |
|
getService(Ci.nsIXULChromeRegistry); |
|
canLoadRemote = chromeReg.canLoadURLRemotely(url); |
|
mustLoadRemote = chromeReg.mustLoadURLRemotely(url); |
|
} |
|
} |
|
|
|
if (aURL.startsWith("moz-extension:")) { |
|
canLoadRemote = false; |
|
mustLoadRemote = false; |
|
} |
|
|
|
if (aURL.startsWith("view-source:")) { |
|
return this.canLoadURIInProcess(aURL.substr("view-source:".length), aProcess); |
|
} |
|
|
|
if (mustLoadRemote) |
|
return processIsRemote; |
|
|
|
if (!canLoadRemote && processIsRemote) |
|
return false; |
|
|
|
return true; |
|
}, |
|
|
|
shouldLoadURI: function(aDocShell, aURI, aReferrer) { |
|
// Inner frames should always load in the current process |
|
if (aDocShell.QueryInterface(Ci.nsIDocShellTreeItem).sameTypeParent) |
|
return true; |
|
|
|
// If the URI can be loaded in the current process then continue |
|
return this.canLoadURIInProcess(aURI.spec, Services.appinfo.processType); |
|
}, |
|
|
|
redirectLoad: function(aDocShell, aURI, aReferrer, aFreshProcess) { |
|
// Retarget the load to the correct process |
|
let messageManager = aDocShell.QueryInterface(Ci.nsIInterfaceRequestor) |
|
.getInterface(Ci.nsIContentFrameMessageManager); |
|
let sessionHistory = aDocShell.getInterface(Ci.nsIWebNavigation).sessionHistory; |
|
|
|
messageManager.sendAsyncMessage("Browser:LoadURI", { |
|
loadOptions: { |
|
uri: aURI.spec, |
|
flags: Ci.nsIWebNavigation.LOAD_FLAGS_NONE, |
|
referrer: aReferrer ? aReferrer.spec : null, |
|
reloadInFreshProcess: !!aFreshProcess, |
|
}, |
|
historyIndex: sessionHistory.requestedIndex, |
|
}); |
|
return false; |
|
}, |
|
|
|
wrapHandlingUserInput: function(aWindow, aIsHandling, aCallback) { |
|
var handlingUserInput; |
|
try { |
|
handlingUserInput = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) |
|
.getInterface(Ci.nsIDOMWindowUtils) |
|
.setHandlingUserInput(aIsHandling); |
|
aCallback(); |
|
} finally { |
|
handlingUserInput.destruct(); |
|
} |
|
}, |
|
};
|
|
|