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.
155 lines
5.7 KiB
155 lines
5.7 KiB
6 years ago
|
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||
|
Cu.import("resource://gre/modules/Services.jsm");
|
||
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||
|
|
||
|
const EXPORTED_SYMBOLS = [];
|
||
|
|
||
|
var gForceExternalHandler = false;
|
||
|
|
||
|
XPCOMUtils.defineLazyServiceGetter(this, "extProtocolSvc",
|
||
|
"@mozilla.org/uriloader/external-protocol-service;1", "nsIExternalProtocolService");
|
||
|
|
||
|
var documentObserver = {
|
||
|
observe: function observe(subject, topic, data) {
|
||
|
if (subject instanceof Ci.nsIDOMWindow && topic == 'content-document-global-created') {
|
||
|
var doc = subject.document;
|
||
|
doc.addEventListener("DOMContentLoaded", function onLoad(event) {
|
||
|
event.target.removeEventListener("DOMContentLoaded", onLoad, false);
|
||
|
// If the parent document is a local file, don't do anything
|
||
|
// Links will just work
|
||
|
if (doc.location.href.indexOf("file://") == 0) {
|
||
|
return;
|
||
|
}
|
||
|
var links = event.target.getElementsByTagName("a");
|
||
|
for (var i=0; i < links.length; i++) {
|
||
|
var link = links[i];
|
||
|
if (link.href.indexOf("file://") != 0) {
|
||
|
continue;
|
||
|
}
|
||
|
link.addEventListener("click", function(link) {
|
||
|
return function(event) {
|
||
|
event.preventDefault();
|
||
|
if (gForceExternalHandler) {
|
||
|
extProtocolSvc.loadUrl(Services.io.newURI(link.href, null, null));
|
||
|
} else {
|
||
|
var target = "_self";
|
||
|
if (link.hasAttribute("target")) {
|
||
|
target = link.getAttribute("target");
|
||
|
}
|
||
|
// If we were told somewhere other than current (based on modifier keys), use it
|
||
|
var where = whereToOpenLink(event);
|
||
|
if (where != "current" || target == "_blank") {
|
||
|
sendAsyncMessage("cck2:open-url", {
|
||
|
"url": link.href,
|
||
|
"where": (target == "_blank") ? "tab" : where
|
||
|
});
|
||
|
return;
|
||
|
}
|
||
|
switch (target) {
|
||
|
case "_self":
|
||
|
link.ownerDocument.location = link.href;
|
||
|
break;
|
||
|
case "_parent":
|
||
|
link.ownerDocument.defaultView.parent.document.location = link.href;
|
||
|
break;
|
||
|
case "_top":
|
||
|
link.ownerDocument.defaultView.top.document.location = link.href;
|
||
|
break;
|
||
|
default:
|
||
|
// Attempt to find the iframe that this goes into
|
||
|
var iframes = doc.defaultView.parent.document.getElementsByName(target);
|
||
|
if (iframes.length > 0) {
|
||
|
iframes[0].contentDocument.location = link.href;
|
||
|
} else {
|
||
|
link.ownerDocument.location = link.href;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}(link), false);
|
||
|
}
|
||
|
}, false);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Don't do this check before Firefox 29
|
||
|
if (Services.vc.compare(Services.appinfo.version, "29") > 0) {
|
||
|
try {
|
||
|
if (Services.prefs.getCharPref("capability.policy.default.checkloaduri.enabled") == "allAccess") {
|
||
|
gForceExternalHandler = !extProtocolSvc.isExposedProtocol('file');
|
||
|
Services.obs.addObserver(documentObserver, "content-document-global-created", false);
|
||
|
addEventListener("unload", function() {
|
||
|
Services.obs.removeObserver(documentObserver, "content-document-global-created", false);
|
||
|
})
|
||
|
}
|
||
|
} catch (e) {}
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Copied from http://mxr.mozilla.org/mozilla-central/source/browser/base/content/utilityOverlay.js?raw=1 */
|
||
|
|
||
|
function getBoolPref(prefname, def)
|
||
|
{
|
||
|
try {
|
||
|
return Services.prefs.getBoolPref(prefname);
|
||
|
}
|
||
|
catch(er) {
|
||
|
return def;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* whereToOpenLink() looks at an event to decide where to open a link.
|
||
|
*
|
||
|
* The event may be a mouse event (click, double-click, middle-click) or keypress event (enter).
|
||
|
*
|
||
|
* On Windows, the modifiers are:
|
||
|
* Ctrl new tab, selected
|
||
|
* Shift new window
|
||
|
* Ctrl+Shift new tab, in background
|
||
|
* Alt save
|
||
|
*
|
||
|
* Middle-clicking is the same as Ctrl+clicking (it opens a new tab).
|
||
|
*
|
||
|
* Exceptions:
|
||
|
* - Alt is ignored for menu items selected using the keyboard so you don't accidentally save stuff.
|
||
|
* (Currently, the Alt isn't sent here at all for menu items, but that will change in bug 126189.)
|
||
|
* - Alt is hard to use in context menus, because pressing Alt closes the menu.
|
||
|
* - Alt can't be used on the bookmarks toolbar because Alt is used for "treat this as something draggable".
|
||
|
* - The button is ignored for the middle-click-paste-URL feature, since it's always a middle-click.
|
||
|
*/
|
||
|
function whereToOpenLink( e, ignoreButton, ignoreAlt )
|
||
|
{
|
||
|
Components.utils.import("resource://gre/modules/AppConstants.jsm");
|
||
|
|
||
|
// This method must treat a null event like a left click without modifier keys (i.e.
|
||
|
// e = { shiftKey:false, ctrlKey:false, metaKey:false, altKey:false, button:0 })
|
||
|
// for compatibility purposes.
|
||
|
if (!e)
|
||
|
return "current";
|
||
|
|
||
|
var shift = e.shiftKey;
|
||
|
var ctrl = e.ctrlKey;
|
||
|
var meta = e.metaKey;
|
||
|
var alt = e.altKey && !ignoreAlt;
|
||
|
|
||
|
// ignoreButton allows "middle-click paste" to use function without always opening in a new window.
|
||
|
var middle = !ignoreButton && e.button == 1;
|
||
|
var middleUsesTabs = true;
|
||
|
|
||
|
// Don't do anything special with right-mouse clicks. They're probably clicks on context menu items.
|
||
|
|
||
|
var metaKey = AppConstants.platform == "macosx" ? meta : ctrl;
|
||
|
if (metaKey || (middle && middleUsesTabs))
|
||
|
return shift ? "tabshifted" : "tab";
|
||
|
|
||
|
if (alt && getBoolPref("browser.altClickSave", false))
|
||
|
return "save";
|
||
|
|
||
|
if (shift || (middle && !middleUsesTabs))
|
||
|
return "window";
|
||
|
|
||
|
return "current";
|
||
|
}
|