Bug 1245262 - Long press keyboard shortcut for containers menu r?Gijs
MozReview-Commit-ID: 43ShHmiH3Uw
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1420,16 +1420,17 @@ pref("privacy.trackingprotection.ui.enab
pref("privacy.trackingprotection.ui.enabled", false);
#endif
pref("privacy.trackingprotection.introCount", 0);
pref("privacy.trackingprotection.introURL", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%/tracking-protection/start/");
// Enable Contextual Identity Containers
#ifdef NIGHTLY_BUILD
pref("privacy.userContext.enabled", true);
+pref("privacy.userContext.newTab.timeout", 1000);
pref("privacy.userContext.ui.enabled", true);
pref("privacy.usercontext.about_newtab_segregation.enabled", true);
#else
pref("privacy.userContext.enabled", false);
pref("privacy.userContext.ui.enabled", false);
pref("privacy.usercontext.about_newtab_segregation.enabled", false);
#endif
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1222,16 +1222,17 @@ var gBrowserInit = {
Services.obs.addObserver(gXPInstallObserver, "addon-install-blocked", false);
Services.obs.addObserver(gXPInstallObserver, "addon-install-origin-blocked", false);
Services.obs.addObserver(gXPInstallObserver, "addon-install-failed", false);
Services.obs.addObserver(gXPInstallObserver, "addon-install-confirmation", false);
Services.obs.addObserver(gXPInstallObserver, "addon-install-complete", false);
window.messageManager.addMessageListener("Browser:URIFixup", gKeywordURIFixup);
BrowserOffline.init();
+ NewTabShortcut.init();
IndexedDBPromptHelper.init();
if (AppConstants.E10S_TESTING_ONLY)
gRemoteTabsUI.init();
// Initialize the full zoom setting.
// We do this before the session restore service gets initialized so we can
// apply full zoom settings to tabs restored by the session restore service.
@@ -1564,16 +1565,17 @@ var gBrowserInit = {
Cu.reportError(ex);
}
if (this.gmpInstallManager) {
this.gmpInstallManager.uninit();
}
BrowserOffline.uninit();
+ NewTabShortcut.uninit();
IndexedDBPromptHelper.uninit();
LightweightThemeListener.uninit();
PanelUI.uninit();
AutoShowBookmarksToolbar.uninit();
}
// Final window teardown, do this last.
window.XULBrowserWindow = null;
@@ -1646,16 +1648,19 @@ if (AppConstants.platform == "macosx") {
};
gBrowserInit.nonBrowserWindowDelayedStartup = function() {
this._delayedStartupTimeoutId = null;
// initialise the offline listener
BrowserOffline.init();
+ // initialize the new tab shortcut
+ NewTabShortcut.init();
+
// initialize the private browsing UI
gPrivateBrowsingUI.init();
// initialize the sync UI
gSyncUI.init();
if (AppConstants.E10S_TESTING_ONLY) {
gRemoteTabsUI.init();
@@ -1670,16 +1675,17 @@ if (AppConstants.platform == "macosx") {
// If nonBrowserWindowDelayedStartup hasn't run yet, we have no work to do -
// just cancel the pending timeout and return;
if (this._delayedStartupTimeoutId) {
clearTimeout(this._delayedStartupTimeoutId);
return;
}
BrowserOffline.uninit();
+ NewTabShortcut.uninit();
};
}
/* Legacy global init functions */
var BrowserStartup = gBrowserInit.onLoad.bind(gBrowserInit);
var BrowserShutdown = gBrowserInit.onUnload.bind(gBrowserInit);
@@ -5927,16 +5933,95 @@ function setStyleDisabled(disabled) {
var LanguageDetectionListener = {
init() {
window.messageManager.addMessageListener("Translation:DocumentState", msg => {
Translation.documentStateReceived(msg.target, msg.data);
});
}
};
+var NewTabShortcut = {
+ init() {
+ let elm = document.getElementById("key_newNavigatorTab");
+
+ this._key = elm.getAttribute("key");
+
+ this._timeout = Services.prefs.getIntPref("privacy.userContext.newTab.timeout");
+
+ this._menupopup = document.getElementById("alltabs-popup");
+
+ window.addEventListener("keydown", this);
+ window.addEventListener("keyup", this);
+ },
+
+ uninint() {
+ if (!Services.prefs.getBoolPref("privacy.userContext.enabled")) {
+ return;
+ }
+
+ window.removeEventListener("keydown", this);
+ window.removeEventListener("keyup", this);
+ },
+
+ handleEvent(event) {
+ let 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();
+ }
+ }
+
+ // 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() {
+ let tabbrowser = document.getElementById('tabbrowser-tabs');
+ let newTabOverflowButton = document.getElementById("newtab-popup");
+ let newTabButton = document.getAnonymousElementByAttribute(tabbrowser, "anonid", "newtab-popup");
+
+ if (tabbrowser.getAttribute("overflow") == "true") {
+ newTabOverflowButton.showPopup();
+ } else {
+ newTabButton.showPopup();
+ }
+ }
+};
var BrowserOffline = {
_inited: false,
// BrowserOffline Public Methods
init() {
if (!this._uiElement)
this._uiElement = document.getElementById("workOfflineMenuitemState");
--- a/browser/components/contextualidentity/test/browser/browser_newtabButton.js
+++ b/browser/components/contextualidentity/test/browser/browser_newtabButton.js
@@ -1,10 +1,13 @@
"use strict";
+const Cu = Components.utils;
+Cu.import("resource://gre/modules/Preferences.jsm");
+
// Testing that when the user opens the add tab menu and clicks menu items
// the correct context id is opened
add_task(function* test() {
yield SpecialPowers.pushPrefEnv({"set": [
["privacy.userContext.enabled", true]
]});
@@ -43,8 +46,29 @@ add_task(function* test_private_mode() {
let newTab2 = privateDocument.getElementById("new-tab-button");
// Check to ensure we are talking about the right button
ok(!!newTab.clientWidth, "new tab button should not be hidden");
ok(!newTab2.clientWidth, "overflow new tab button should be hidden");
let popup = privateDocument.getAnonymousElementByAttribute(newTab, "anonid", "newtab-popup");
ok(!popup, "new tab should not have a popup");
yield BrowserTestUtils.closeWindow(privateWindow);
});
+
+add_task(function* test() {
+ yield SpecialPowers.pushPrefEnv({"set": [
+ ["privacy.userContext.enabled", true]
+ ]});
+ let newTabTimeout = Preferences.get("privacy.userContext.newTab.timeout");
+
+ let newTab = document.getElementById('tabbrowser-tabs');
+ let newTabButton = document.getAnonymousElementByAttribute(newTab, "anonid", "tabs-newtab-button");
+ ok(newTabButton, "New tab button exists");
+ ok(!newTabButton.hidden, "New tab button is visible");
+ yield BrowserTestUtils.waitForCondition(() => !!document.getAnonymousElementByAttribute(newTab, "anonid", "newtab-popup"), "Wait for popup to exist");
+ let popup = document.getAnonymousElementByAttribute(newTab, "anonid", "newtab-popup");
+
+ let popupShownPromise = BrowserTestUtils.waitForEvent(popup, "popupshown");
+ EventUtils.synthesizeKey("t", {accelKey: true, type: 'keydown'}, window);
+ yield new Promise(resolve => setTimeout(resolve, newTabTimeout));
+ EventUtils.synthesizeKey("t", {accelKey: true, type: 'keyup'}, window);
+ yield popupShownPromise;
+ ok(true, "Promise resolved as the menu loaded on longpress");
+});