以前的版本,点击书签,可以新标签页打开,新的42.0没有配置选项,又不想安装扩展组件,很是困惑Firefox为什么不做配置项。于是下载了42.0的源代码,自己找找。
初看源代码,不知道从何处下手,经过一番摸索,觉得书签点击类操作应该在browser目录下,果然找到了。
(1) browser\base\content\browser.js(998)
var gBrowserInit = {
delayedStartupFinished: false,
onLoad: function() {
gBrowser.addEventListener("DOMUpdatePageReport", gPopupBlockerObserver, false);
Services.obs.addObserver(gPluginHandler.NPAPIPluginCrashed, "plugin-crashed", false);
window.addEventListener("AppCommand", HandleAppCommandEvent, true);
// These routines add message listeners. They must run before
// loading the frame script to ensure that we don't miss any
// message sent between when the frame script is loaded and when
// the listener is registered.
DOMLinkHandler.init();
gPageStyleMenu.init();
LanguageDetectionListener.init();
BrowserOnClick.init();
DevEdition.init();
AboutPrivateBrowsingListener.init();
TrackingProtection.init();
let mm = window.getGroupMessageManager("browsers");
mm.loadFrameScript("chrome://browser/content/tab-content.js", true);
mm.loadFrameScript("chrome://browser/content/content.js", true);
mm.loadFrameScript("chrome://browser/content/content-UITour.js", true);
mm.loadFrameScript("chrome://global/content/manifestMessages.js", true);
window.messageManager.addMessageListener("Browser:LoadURI", RedirectLoad);
// initialize observers and listeners
// and give C++ access to gBrowser
XULBrowserWindow.init();
window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIXULWindow)
.XULBrowserWindow = window.XULBrowserWindow;
window.QueryInterface(Ci.nsIDOMChromeWindow).browserDOMWindow =
new nsBrowserAccess();
if (!gMultiProcessBrowser) {
// There is a Content:Click message manually sent from content.
Cc["@mozilla.org/eventlistenerservice;1"]
.getService(Ci.nsIEventListenerService)
.addSystemEventListener(gBrowser, "click", contentAreaClick, true);
}
...
/**
* Called whenever the user clicks in the content area.
*
* @param event
* The click event.
* @param isPanelClick
* Whether the event comes from a web panel.
* @note default event is prevented if the click is handled.
*/
function contentAreaClick(event, isPanelClick)
{
if (!event.isTrusted || event.defaultPrevented || event.button == 2)
return;
let [href, linkNode] = hrefAndLinkNodeForClickEvent(event);
if (!href) {
// Not a link, handle middle mouse navigation.
if (event.button == 1 &&
gPrefService.getBoolPref("middlemouse.contentLoadURL") &&
!gPrefService.getBoolPref("general.autoScroll")) {
middleMousePaste(event);
event.preventDefault();
}
return;
}
// This code only applies if we have a linkNode (i.e. clicks on real anchor
// elements, as opposed to XLink).
if (linkNode && event.button == 0 &&
!event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey) {
// A Web panel's links should target the main content area. Do this
// if no modifier keys are down and if there's no target or the target
// equals _main (the IE convention) or _content (the Mozilla convention).
let target = linkNode.target;
let mainTarget = !target || target == "_content" || target == "_main";
if (isPanelClick && mainTarget) {
// javascript and data links should be executed in the current browser.
if (linkNode.getAttribute("onclick") ||
href.startsWith("javascript:") ||
href.startsWith("data:"))
return;
try {
urlSecurityCheck(href, linkNode.ownerDocument.nodePrincipal);
}
catch(ex) {
// Prevent loading unsecure destinations.
event.preventDefault();
return;
}
loadURI(href, null, null, false);
event.preventDefault();
return;
}
if (linkNode.getAttribute("rel") == "sidebar") {
// This is the Opera convention for a special link that, when clicked,
// allows to add a sidebar panel. The link's title attribute contains
// the title that should be used for the sidebar panel.
PlacesUIUtils.showBookmarkDialog({ action: "add"
, type: "bookmark"
, uri: makeURI(href)
, title: linkNode.getAttribute("title")
, loadBookmarkInSidebar: true
, hiddenRows: [ "description", "location", "keyword" ]
}, window);
event.preventDefault();
return;
}
}
handleLinkClick(event, href, linkNode);
// Mark the page as a user followed link. This is done so that history can
// distinguish automatic embed visits from user activated ones. For example
// pages loaded in frames are embed visits and lost with the session, while
// visits across frames should be preserved.
try {
if (!PrivateBrowsingUtils.isWindowPrivate(window))
PlacesUIUtils.markPageAsFollowedLink(href);
} catch (ex) { /* Skip invalid URIs. */ }
}
/**
* Handles clicks on links.
*
* @return true if the click event was handled, false otherwise.
*/
function handleLinkClick(event, href, linkNode) {
if (event.button == 2) // right click
return false;
var where = whereToOpenLink(event);
if (where == "current")
return false;
var doc = event.target.ownerDocument;
if (where == "save") {
saveURL(href, linkNode ? gatherTextUnder(linkNode) : "", null, true,
true, doc.documentURIObject, doc);
event.preventDefault();
return true;
}
(2) browser\base\content\utilityOverlay.js(119)
/* 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 )
{
// 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 = getBoolPref("browser.tabs.opentabfor.middleclick", true);
// Don't do anything special with right-mouse clicks. They're probably clicks on context menu items.
#ifdef XP_MACOSX
if (meta || (middle && middleUsesTabs))
#else
if (ctrl || (middle && middleUsesTabs))
#endif
return shift ? "tabshifted" : "tab";
if (alt && getBoolPref("browser.altClickSave", false))
return "save";
if (shift || (middle && !middleUsesTabs))
return "window";
return "current";
}
从源代码可以看出,按住CTRL点击书签,或者用鼠标中键点击书签(与配置相关),都是新标签页打开链接。