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.
154 lines
5.7 KiB
154 lines
5.7 KiB
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"; |
|
}
|
|
|