зеркало из https://github.com/mozilla/gecko-dev.git
Bug 897062 - Handle special clicks in e10s. r=felipe,smaug
This commit is contained in:
Родитель
eb7a383fd6
Коммит
086302552c
|
@ -732,9 +732,12 @@ var gBrowserInit = {
|
|||
|
||||
var mustLoadSidebar = false;
|
||||
|
||||
Cc["@mozilla.org/eventlistenerservice;1"]
|
||||
.getService(Ci.nsIEventListenerService)
|
||||
.addSystemEventListener(gBrowser, "click", contentAreaClick, true);
|
||||
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);
|
||||
}
|
||||
|
||||
gBrowser.addEventListener("DOMUpdatePageReport", gPopupBlockerObserver, false);
|
||||
|
||||
|
|
|
@ -195,3 +195,97 @@ let AboutHomeListener = {
|
|||
}
|
||||
};
|
||||
AboutHomeListener.init();
|
||||
|
||||
var global = this;
|
||||
|
||||
let ClickEventHandler = {
|
||||
init: function init() {
|
||||
Cc["@mozilla.org/eventlistenerservice;1"]
|
||||
.getService(Ci.nsIEventListenerService)
|
||||
.addSystemEventListener(global, "click", this, true);
|
||||
},
|
||||
|
||||
handleEvent: function(event) {
|
||||
// Bug 903016: Most of this code is an unfortunate duplication from
|
||||
// contentAreaClick in browser.js.
|
||||
if (!event.isTrusted || event.defaultPrevented || event.button == 2)
|
||||
return;
|
||||
|
||||
let [href, node] = this._hrefAndLinkNodeForClickEvent(event);
|
||||
|
||||
let json = { button: event.button, shiftKey: event.shiftKey,
|
||||
ctrlKey: event.ctrlKey, metaKey: event.metaKey,
|
||||
altKey: event.altKey, href: null, title: null,
|
||||
bookmark: false };
|
||||
|
||||
if (href) {
|
||||
json.href = href;
|
||||
if (node) {
|
||||
json.title = node.getAttribute("title");
|
||||
|
||||
if (event.button == 0 && !event.ctrlKey && !event.shiftKey &&
|
||||
!event.altKey && !event.metaKey) {
|
||||
json.bookmark = node.getAttribute("rel") == "sidebar";
|
||||
if (json.bookmark)
|
||||
event.preventDefault(); // Need to prevent the pageload.
|
||||
}
|
||||
}
|
||||
|
||||
sendAsyncMessage("Content:Click", json);
|
||||
return;
|
||||
}
|
||||
|
||||
// This might be middle mouse navigation.
|
||||
if (event.button == 1)
|
||||
sendAsyncMessage("Content:Click", json);
|
||||
},
|
||||
|
||||
/**
|
||||
* Extracts linkNode and href for the current click target.
|
||||
*
|
||||
* @param event
|
||||
* The click event.
|
||||
* @return [href, linkNode].
|
||||
*
|
||||
* @note linkNode will be null if the click wasn't on an anchor
|
||||
* element (or XLink).
|
||||
*/
|
||||
_hrefAndLinkNodeForClickEvent: function(event) {
|
||||
function isHTMLLink(aNode) {
|
||||
// Be consistent with what nsContextMenu.js does.
|
||||
return ((aNode instanceof content.HTMLAnchorElement && aNode.href) ||
|
||||
(aNode instanceof content.HTMLAreaElement && aNode.href) ||
|
||||
aNode instanceof content.HTMLLinkElement);
|
||||
}
|
||||
|
||||
function makeURLAbsolute(aBase, aUrl) {
|
||||
// Note: makeURI() will throw if aUri is not a valid URI
|
||||
return makeURI(aUrl, null, makeURI(aBase)).spec;
|
||||
}
|
||||
|
||||
let node = event.target;
|
||||
while (node && !isHTMLLink(node)) {
|
||||
node = node.parentNode;
|
||||
}
|
||||
|
||||
if (node)
|
||||
return [node.href, node];
|
||||
|
||||
// If there is no linkNode, try simple XLink.
|
||||
let href, baseURI;
|
||||
node = event.target;
|
||||
while (node && !href) {
|
||||
if (node.nodeType == content.Node.ELEMENT_NODE) {
|
||||
href = node.getAttributeNS("http://www.w3.org/1999/xlink", "href");
|
||||
if (href)
|
||||
baseURI = node.baseURI;
|
||||
}
|
||||
node = node.parentNode;
|
||||
}
|
||||
|
||||
// In case of XLink, we don't return the node we got href from since
|
||||
// callers expect <a>-like elements.
|
||||
return [href ? makeURLAbsolute(baseURI, href) : null, null];
|
||||
}
|
||||
};
|
||||
ClickEventHandler.init();
|
||||
|
|
|
@ -20,6 +20,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "AboutHome",
|
|||
XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
|
||||
"resource://gre/modules/AddonManager.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ContentClick",
|
||||
"resource:///modules/ContentClick.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
|
@ -467,6 +470,9 @@ BrowserGlue.prototype = {
|
|||
webrtcUI.init();
|
||||
AboutHome.init();
|
||||
|
||||
if (Services.prefs.getBoolPref("browser.tabs.remote"))
|
||||
ContentClick.init();
|
||||
|
||||
Services.obs.notifyObservers(null, "browser-ui-startup-complete", "");
|
||||
},
|
||||
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/* 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";
|
||||
|
||||
let Cc = Components.classes;
|
||||
let Ci = Components.interfaces;
|
||||
let Cu = Components.utils;
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ "ContentClick" ];
|
||||
|
||||
Cu.import("resource:///modules/PlacesUIUtils.jsm");
|
||||
Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
let ContentClick = {
|
||||
init: function() {
|
||||
let mm = Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageListenerManager);
|
||||
mm.addMessageListener("Content:Click", this);
|
||||
},
|
||||
|
||||
receiveMessage: function (message) {
|
||||
switch (message.name) {
|
||||
case "Content:Click":
|
||||
this.contentAreaClick(message.json, message.target)
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
contentAreaClick: function (json, browser) {
|
||||
// This is heavily based on contentAreaClick from browser.js (Bug 903016)
|
||||
// The json is set up in a way to look like an Event.
|
||||
let window = browser.ownerDocument.defaultView;
|
||||
|
||||
if (!json.href) {
|
||||
// Might be middle mouse navigation.
|
||||
if (Services.prefs.getBoolPref("middlemouse.contentLoadURL") &&
|
||||
!Services.prefs.getBoolPref("general.autoScroll")) {
|
||||
window.middleMousePaste(json);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (json.bookmark) {
|
||||
// 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: Services.io.newURI(json.href, null, null)
|
||||
, title: json.title
|
||||
, loadBookmarkInSidebar: true
|
||||
, hiddenRows: [ "description"
|
||||
, "location"
|
||||
, "keyword" ]
|
||||
}, window);
|
||||
return;
|
||||
}
|
||||
|
||||
// Note: We don't need the sidebar code here.
|
||||
|
||||
// This part is based on handleLinkClick.
|
||||
var where = window.whereToOpenLink(json);
|
||||
if (where == "current")
|
||||
return false;
|
||||
|
||||
// Todo(903022): code for where == save
|
||||
|
||||
window.openLinkIn(json.href, where, { referrerURI: browser.documentURI,
|
||||
charset: browser.characterSet });
|
||||
|
||||
// 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. */ }
|
||||
}
|
||||
};
|
|
@ -8,6 +8,7 @@ TEST_DIRS += ['test']
|
|||
|
||||
EXTRA_JS_MODULES += [
|
||||
'BrowserNewTabPreloader.jsm',
|
||||
'ContentClick.jsm',
|
||||
'NetworkPrioritizer.jsm',
|
||||
'SharedFrame.jsm',
|
||||
'SignInToWebsite.jsm',
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "nsIWebNavigation.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsIWebBrowserChrome2.h"
|
||||
#include "nsIEmbeddingSiteWindow.h"
|
||||
#include "nsIWebBrowserChromeFocus.h"
|
||||
|
@ -119,6 +120,13 @@ public:
|
|||
optional_argc);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
aVisitor.mForceContentDispatch = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
virtual JSContext* GetJSContextForEventHandlers() MOZ_OVERRIDE;
|
||||
virtual nsIPrincipal* GetPrincipal() MOZ_OVERRIDE;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче