Adding in longpress for new tab menu

This commit is contained in:
Jonathan Kingston 2017-02-07 13:04:03 +00:00
parent a9a0cc1ba2
commit 1e1ffd2b41
3 changed files with 397 additions and 2 deletions

View file

@ -37,6 +37,7 @@ const { viewFor } = require("sdk/view/core");
const webExtension = require("sdk/webextension");
const windows = require("sdk/windows");
const windowUtils = require("sdk/window/utils");
const shortcuts = require("shortcuts");
// ----------------------------------------------------------------------------
// ContainerService
@ -605,6 +606,7 @@ ContainerWindow.prototype = {
_init(window) {
this._window = window;
this._newTabShortcut = new shortcuts.NewTabShortcut(window);
const style = Style({ uri: self.data.url("usercontext.css") });
attachTo(style, this._window);
},
@ -663,6 +665,8 @@ ContainerWindow.prototype = {
}
};
this._window.showPopup = showPopup;
[button, overflowButton].forEach((buttonElement) => {
buttonElement.addEventListener("mouseover", () => {
showPopup(buttonElement);

391
shortcuts.js Normal file
View file

@ -0,0 +1,391 @@
const AppConstants = require("resource://gre/modules/AppConstants.jsm");
const { Cc, Ci } = require("chrome");
const {Services} = require("resource://gre/modules/Services.jsm");
const NEW_TAB_TIMEOUT = 300;
function getBrowserURL() {
return "chrome://browser/content/browser.xul";
}
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";
const shift = e.shiftKey;
const ctrl = e.ctrlKey;
const meta = e.metaKey;
const alt = e.altKey && !ignoreAlt;
// ignoreButton allows "middle-click paste" to use function without always opening in a new window.
const middle = !ignoreButton && e.button === 1;
const middleUsesTabs = Services.prefs.getBoolPref("browser.tabs.opentabfor.middleclick", true);
// Don't do anything special with right-mouse clicks. They're probably clicks on context menu items.
const metaKey = AppConstants.platform === "macosx" ? meta : ctrl;
if (metaKey || (middle && middleUsesTabs))
return shift ? "tabshifted" : "tab";
if (alt && Services.prefs.getBoolPref("browser.altClickSave", false))
return "save";
if (shift || (middle && !middleUsesTabs))
return "window";
return "current";
}
function BrowserOpenTab(event, win) {
let where = "tab";
let relatedToCurrent = false;
//let doc = event.target.ownerDocument;
//let win = doc.defaultView;
if (event) {
where = whereToOpenLink(event, false, true);
switch (where) {
case "tab":
case "tabshifted":
// When accel-click or middle-click are used, open the new tab as
// related to the current tab.
relatedToCurrent = true;
break;
case "current":
where = "tab";
break;
}
}
openUILinkIn(win.BROWSER_NEW_TAB_URL, where, { relatedToCurrent }, undefined, undefined, win);
}
function openUILinkIn(url, where, aAllowThirdPartyFixup, aPostData, aReferrerURI, win) {
let params;
if (arguments.length === 3 && typeof arguments[2] === "object") {
params = aAllowThirdPartyFixup;
} else {
params = {
allowThirdPartyFixup: aAllowThirdPartyFixup,
postData: aPostData,
referrerURI: aReferrerURI,
referrerPolicy: Ci.nsIHttpChannel.REFERRER_POLICY_UNSET
};
}
params.fromChrome = true;
openLinkIn(url, where, params, win);
}
function openLinkIn(url, where, params, win) {
if (!where || !url)
return;
const aAllowThirdPartyFixup = params.allowThirdPartyFixup;
const aPostData = params.postData;
const aCharset = params.charset;
const aReferrerURI = params.referrerURI;
const aReferrerPolicy = ("referrerPolicy" in params ?
params.referrerPolicy : Ci.nsIHttpChannel.REFERRER_POLICY_UNSET);
let aRelatedToCurrent = params.relatedToCurrent;
const aAllowMixedContent = params.allowMixedContent;
const aInBackground = params.inBackground;
const aDisallowInheritPrincipal = params.disallowInheritPrincipal;
const aIsPrivate = params.private;
const aSkipTabAnimation = params.skipTabAnimation;
const aAllowPinnedTabHostChange = !!params.allowPinnedTabHostChange;
const aNoReferrer = params.noReferrer;
const aAllowPopups = !!params.allowPopups;
const aUserContextId = params.userContextId;
const aIndicateErrorPageLoad = params.indicateErrorPageLoad;
const aPrincipal = params.originPrincipal;
const aForceAboutBlankViewerInCurrent =
params.forceAboutBlankViewerInCurrent;
//if (where === "save") {
// // TODO(1073187): propagate referrerPolicy.
// // ContentClick.jsm passes isContentWindowPrivate for saveURL instead of passing a CPOW initiatingDoc
// if ("isContentWindowPrivate" in params) {
// saveURL(url, null, null, true, true, aNoReferrer ? null : aReferrerURI, null, params.isContentWindowPrivate);
// } else {
// if (!aInitiatingDoc) {
// Cu.reportError("openUILink/openLinkIn was called with " +
// "where === 'save' but without initiatingDoc. See bug 814264.");
// return;
// }
// saveURL(url, null, null, true, true, aNoReferrer ? null : aReferrerURI, aInitiatingDoc);
// }
// return;
//}
// Establish which window we'll load the link in.
let w;
if (where === "current" && params.targetBrowser) {
w = params.targetBrowser.ownerGlobal;
} else {
w = win.top;
}
// We don't want to open tabs in popups, so try to find a non-popup window in
// that case.
if ((where === "tab" || where === "tabshifted") &&
w && !w.toolbar.visible) {
w = win.top;
aRelatedToCurrent = false;
}
if (!w || where === "window") {
// This propagates to window.arguments.
const sa = Cc["@mozilla.org/array;1"].
createInstance(Ci.nsIMutableArray);
const wuri = Cc["@mozilla.org/supports-string;1"].
createInstance(Ci.nsISupportsString);
wuri.data = url;
let charset = null;
if (aCharset) {
charset = Cc["@mozilla.org/supports-string;1"]
.createInstance(Ci.nsISupportsString);
charset.data = "charset=" + aCharset;
}
const allowThirdPartyFixupSupports = Cc["@mozilla.org/supports-PRBool;1"].
createInstance(Ci.nsISupportsPRBool);
allowThirdPartyFixupSupports.data = aAllowThirdPartyFixup;
let referrerURISupports = null;
if (aReferrerURI && !aNoReferrer) {
referrerURISupports = Cc["@mozilla.org/supports-string;1"].
createInstance(Ci.nsISupportsString);
referrerURISupports.data = aReferrerURI.spec;
}
const referrerPolicySupports = Cc["@mozilla.org/supports-PRUint32;1"].
createInstance(Ci.nsISupportsPRUint32);
referrerPolicySupports.data = aReferrerPolicy;
const userContextIdSupports = Cc["@mozilla.org/supports-PRUint32;1"].
createInstance(Ci.nsISupportsPRUint32);
userContextIdSupports.data = aUserContextId;
sa.appendElement(wuri, /* weak =*/ false);
sa.appendElement(charset, /* weak =*/ false);
sa.appendElement(referrerURISupports, /* weak =*/ false);
sa.appendElement(aPostData, /* weak =*/ false);
sa.appendElement(allowThirdPartyFixupSupports, /* weak =*/ false);
sa.appendElement(referrerPolicySupports, /* weak =*/ false);
sa.appendElement(userContextIdSupports, /* weak =*/ false);
sa.appendElement(aPrincipal, /* weak =*/ false);
let features = "chrome,dialog=no,all";
if (aIsPrivate) {
features += ",private";
}
Services.ww.openWindow(w || win, getBrowserURL(), null, features, sa);
return;
}
// We're now committed to loading the link in an existing browser window.
// Raise the target window before loading the URI, since loading it may
// result in a new frontmost window (e.g. "javascript:window.open('');").
w.focus();
let targetBrowser;
let loadInBackground;
let uriObj;
if (where === "current") {
targetBrowser = params.targetBrowser || w.gBrowser.selectedBrowser;
loadInBackground = false;
try {
uriObj = Services.io.newURI(url);
} catch (e) {
//blank
}
if (w.gBrowser.getTabForBrowser(targetBrowser).pinned &&
!aAllowPinnedTabHostChange) {
try {
// nsIURI.host can throw for non-nsStandardURL nsIURIs.
if (!uriObj || (!uriObj.schemeIs("javascript") &&
targetBrowser.currentURI.host !== uriObj.host)) {
where = "tab";
loadInBackground = false;
}
} catch (err) {
where = "tab";
loadInBackground = false;
}
}
} else {
// 'where' is "tab" or "tabshifted", so we'll load the link in a new tab.
loadInBackground = aInBackground;
if (loadInBackground === null) {
loadInBackground = true;
}
}
let flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
let tabUsedForLoad;
switch (where) {
case "current":
if (aAllowThirdPartyFixup) {
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_FIXUP_SCHEME_TYPOS;
}
// LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL isn't supported for javascript URIs,
// i.e. it causes them not to load at all. Callers should strip
// "javascript:" from pasted strings to protect users from malicious URIs
// (see stripUnsafeProtocolOnPaste).
if (aDisallowInheritPrincipal && !(uriObj && uriObj.schemeIs("javascript"))) {
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL;
}
if (aAllowPopups) {
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_POPUPS;
}
if (aIndicateErrorPageLoad) {
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_ERROR_LOAD_CHANGES_RV;
}
if (aForceAboutBlankViewerInCurrent) {
targetBrowser.createAboutBlankContentViewer(aPrincipal);
}
targetBrowser.loadURIWithFlags(url, {
triggeringPrincipal: aPrincipal,
flags,
referrerURI: aNoReferrer ? null : aReferrerURI,
referrerPolicy: aReferrerPolicy,
postData: aPostData,
userContextId: aUserContextId
});
break;
case "tabshifted":
loadInBackground = !loadInBackground;
// fall through
case "tab":
tabUsedForLoad = w.gBrowser.loadOneTab(url, {
referrerURI: aReferrerURI,
referrerPolicy: aReferrerPolicy,
charset: aCharset,
postData: aPostData,
inBackground: loadInBackground,
allowThirdPartyFixup: aAllowThirdPartyFixup,
relatedToCurrent: aRelatedToCurrent,
skipAnimation: aSkipTabAnimation,
allowMixedContent: aAllowMixedContent,
noReferrer: aNoReferrer,
userContextId: aUserContextId,
originPrincipal: aPrincipal,
triggeringPrincipal: aPrincipal
});
targetBrowser = tabUsedForLoad.linkedBrowser;
break;
}
// Focus the content, but only if the browser used for the load is selected.
if (targetBrowser === w.gBrowser.selectedBrowser) {
targetBrowser.focus();
}
if (!loadInBackground && w.isBlankPageURL(url)) {
w.focusAndSelectUrlBar();
}
}
const NewTabShortcut = function (window) {
this.init(window);
};
NewTabShortcut.prototype = {
init(window) {
this._window = window;
const elm = this._window.document.getElementById("key_newNavigatorTab");
this._key = elm.getAttribute("key");
this._timeout = NEW_TAB_TIMEOUT;
this._menupopup = this._window.document.getElementById("alltabs-popup");
this._window.addEventListener("keydown", this);
this._window.addEventListener("keyup", this);
},
uninint() {
this._window.removeEventListener("keydown", this);
this._window.removeEventListener("keyup", this);
},
handleEvent(event) {
const accelKey = AppConstants.platform === "macosx" ? "metaKey" : "ctrlKey";
if (event.key !== this._key || !event[accelKey]) {
this._clearTimer();
return;
}
// Lets return early if the userContext is disabled
if (!Services.prefs.getBoolPref("privacy.userContext.enabled")) {
return false;
}
// Let's see if this is a long press.
if (event.type === "keydown" && !this._timer) {
if (event.shiftKey) {
return;
}
this._timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
this._timer.initWithCallback(this, this._timeout, this._timer.TYPE_ONE_SHOT);
} else if (event.type === "keyup") {
// Timeout has not expired yet
if (this._timer) {
this._clearTimer();
BrowserOpenTab(event, this._window);
return false;
}
}
// We suppress the default behavior of accel+T.
event.preventDefault();
},
_clearTimer() {
if (this._timer) {
this._timer.cancel();
this._timer = null;
}
},
// Timer expired
notify() {
this._clearTimer();
this._openContainerMenu();
},
_openContainerMenu() {
const tabbrowser = this._window.document.getElementById("tabbrowser-tabs");
const newTabOverflowButton = this._window.document.getElementById("new-tab-button");
const newTabButton = this._window.document.getAnonymousElementByAttribute(tabbrowser, "anonid", "tabs-newtab-button");
if (tabbrowser.getAttribute("overflow") === "true") {
this._window.showPopup(newTabOverflowButton);
} else {
this._window.showPopup(newTabButton);
}
}
};
exports.NewTabShortcut = NewTabShortcut;

View file

@ -13,6 +13,6 @@ browser.tabs.query({}).then(tabs => {
}).catch(() => {});
function disableAddon(tabId) {
browser.browserAction.disable(tabId);
browser.browserAction.setTitle({ tabId, title: "Containers disabled in Private Browsing Mode" });
browser.browserAction.disable(tabId);
browser.browserAction.setTitle({ tabId, title: "Containers disabled in Private Browsing Mode" });
}