Bug 1276880 - 'Open link in a new <container_name> Tab' in the context menu, r=gijs
--- a/browser/base/content/browser-context.inc
+++ b/browser/base/content/browser-context.inc
@@ -49,28 +49,32 @@
label="&spellUndoAddToDictionary.label;"
accesskey="&spellUndoAddToDictionary.accesskey;"
oncommand="InlineSpellCheckerUI.undoAddToDictionary();" />
<menuseparator id="spell-suggestions-separator"/>
<menuitem id="context-openlinkincurrent"
label="&openLinkCmdInCurrent.label;"
accesskey="&openLinkCmdInCurrent.accesskey;"
oncommand="gContextMenu.openLinkInCurrent();"/>
+# label and usercontextid are dynamically set.
+ <menuitem id="context-openlinkincontainertab"
+ accesskey="&openLinkCmdInTab.accesskey;"
+ oncommand="gContextMenu.openLinkInTab(event);"/>
<menuitem id="context-openlinkintab"
label="&openLinkCmdInTab.label;"
accesskey="&openLinkCmdInTab.accesskey;"
usercontextid="0"
oncommand="gContextMenu.openLinkInTab(event);"/>
<menu id="context-openlinkinusercontext-menu"
label="&openLinkCmdInContainerTab.label;"
accesskey="&openLinkCmdInContainerTab.accesskey;"
hidden="true">
<menupopup oncommand="gContextMenu.openLinkInTab(event);"
- onpopupshowing="return createUserContextMenu(event, false);" />
+ onpopupshowing="return gContextMenu.createContainerMenu(event);" />
</menu>
<menuitem id="context-openlink"
label="&openLinkCmd.label;"
accesskey="&openLinkCmd.accesskey;"
oncommand="gContextMenu.openLink();"/>
<menuitem id="context-openlinkprivate"
label="&openLinkInPrivateWindowCmd.label;"
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -6,16 +6,18 @@
Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
Components.utils.import("resource://gre/modules/InlineSpellChecker.jsm");
Components.utils.import("resource://gre/modules/LoginManagerContextMenu.jsm");
Components.utils.import("resource://gre/modules/BrowserUtils.jsm");
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "ContextualIdentityService",
+ "resource:///modules/ContextualIdentityService.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper",
"resource://gre/modules/LoginHelper.jsm");
var gContextMenuContentData = null;
function nsContextMenu(aXulMenu, aIsShift) {
this.shouldDisplay = true;
@@ -138,22 +140,37 @@ nsContextMenu.prototype = {
try {
this.linkURI = makeURI(this.linkURL);
} catch (ex) {}
this.linkTextStr = this.selectionInfo.linkText;
this.onPlainTextLink = true;
}
+ var inContainer = false;
+ var userContextId = this.browser.contentPrincipal.originAttributes.userContextId;
+ if (userContextId) {
+ inContainer = true;
+ var item = document.getElementById("context-openlinkincontainertab");
+
+ item.setAttribute("usercontextid", userContextId);
+
+ var label = ContextualIdentityService.getUserContextLabel(userContextId);
+ item.setAttribute("label",
+ gBrowserBundle.formatStringFromName("userContextOpenLink.label",
+ [label], 1));
+ }
+
var shouldShow = this.onSaveableLink || isMailtoInternal || this.onPlainTextLink;
var isWindowPrivate = PrivateBrowsingUtils.isWindowPrivate(window);
var showContainers = Services.prefs.getBoolPref("privacy.userContext.enabled");
this.showItem("context-openlink", shouldShow && !isWindowPrivate);
this.showItem("context-openlinkprivate", shouldShow);
- this.showItem("context-openlinkintab", shouldShow);
+ this.showItem("context-openlinkintab", shouldShow && !inContainer);
+ this.showItem("context-openlinkincontainertab", shouldShow && inContainer);
this.showItem("context-openlinkinusercontext-menu", shouldShow && !isWindowPrivate && showContainers);
this.showItem("context-openlinkincurrent", this.onPlainTextLink);
this.showItem("context-sep-open", shouldShow);
},
initNavigationItems: function CM_initNavigationItems() {
var shouldShow = !(this.isContentSelected || this.onLink || this.onImage ||
this.onCanvas || this.onVideo || this.onAudio ||
@@ -1855,9 +1872,14 @@ nsContextMenu.prototype = {
},
_checkTelemetryForMenu: function(aXulMenu) {
this._telemetryClickID = null;
this._telemetryPageContext = this._getTelemetryPageContextInfo();
this._telemetryHadCustomItems = this.hasPageMenu;
this._getTelemetryClickInfo(aXulMenu);
},
+
+ createContainerMenu: function(aEvent) {
+ var userContextId = this.browser.contentPrincipal.originAttributes.userContextId;
+ return createUserContextMenu(aEvent, false, userContextId);
+ },
};
--- a/browser/base/content/test/referrer/browser.ini
+++ b/browser/base/content/test/referrer/browser.ini
@@ -6,18 +6,16 @@ support-files =
head.js
[browser_referrer_middle_click.js]
[browser_referrer_middle_click_in_container.js]
[browser_referrer_open_link_in_private.js]
skip-if = os == 'linux' # Bug 1145199
[browser_referrer_open_link_in_tab.js]
skip-if = os == 'linux' # Bug 1144816
-[browser_referrer_open_link_in_tab_in_container.js]
-skip-if = os == 'linux' # Bug 1144816
[browser_referrer_open_link_in_window.js]
skip-if = os == 'linux' # Bug 1145199
[browser_referrer_open_link_in_window_in_container.js]
skip-if = os == 'linux' # Bug 1145199
[browser_referrer_simple_click.js]
[browser_referrer_open_link_in_container_tab.js]
skip-if = os == 'linux' # Bug 1144816
[browser_referrer_open_link_in_container_tab2.js]
--- a/browser/base/content/test/referrer/browser_referrer_middle_click_in_container.js
+++ b/browser/base/content/test/referrer/browser_referrer_middle_click_in_container.js
@@ -10,11 +10,17 @@ function startMiddleClickTestCase(aTestN
startMiddleClickTestCase,
{ userContextId: 3 });
});
clickTheLink(gTestWindow, "testlink", {button: 1});
}
function test() {
- requestLongerTimeout(10); // slowwww shutdown on e10s
- startReferrerTest(startMiddleClickTestCase, { userContextId: 3 });
+ waitForExplicitFinish();
+
+ SpecialPowers.pushPrefEnv(
+ {set: [["privacy.userContext.enabled", true]]},
+ function() {
+ requestLongerTimeout(10); // slowwww shutdown on e10s
+ startReferrerTest(startMiddleClickTestCase, { userContextId: 3 });
+ });
}
--- a/browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab2.js
+++ b/browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab2.js
@@ -10,38 +10,17 @@ function startNewTabTestCase(aTestNumber
contextMenuOpened(gTestWindow, "testlink").then(function(aContextMenu) {
someTabLoaded(gTestWindow).then(function(aNewTab) {
gTestWindow.gBrowser.selectedTab = aNewTab;
checkReferrerAndStartNextTest(aTestNumber, null, aNewTab,
startNewTabTestCase, { userContextId: 1 });
});
- let menu = gTestWindow.document.getElementById("context-openlinkinusercontext-menu");
- let menupopup = menu.menupopup;
- menu.addEventListener("popupshown", function onPopupShown() {
- menu.removeEventListener("popupshown", onPopupShown);
-
- is(menupopup.nodeType, Node.ELEMENT_NODE, "We have a menupopup.");
- ok(menupopup.firstChild, "We have a first container entry.");
-
- let firstContext = menupopup.firstChild;
- is(firstContext.nodeType, Node.ELEMENT_NODE, "We have a first container entry.");
- ok(firstContext.hasAttribute("usercontextid"), "We have a usercontextid value.");
- is("1", firstContext.getAttribute("usercontextid"), "We have the right usercontextid value.");
-
- aContextMenu.addEventListener("popuphidden", function onPopupHidden() {
- aContextMenu.removeEventListener("popuphidden", onPopupHidden);
- firstContext.doCommand();
- });
-
- aContextMenu.hidePopup();
- });
-
- menupopup.showPopup();
+ doContextMenuCommand(gTestWindow, aContextMenu, "context-openlinkincontainertab");
});
}
function test() {
waitForExplicitFinish();
SpecialPowers.pushPrefEnv(
{set: [["privacy.userContext.enabled", true]]},
--- a/browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab3.js
+++ b/browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab3.js
@@ -32,17 +32,17 @@ function startNewTabTestCase(aTestNumber
menu.removeEventListener("popupshown", onPopupShown);
is(menupopup.nodeType, Node.ELEMENT_NODE, "We have a menupopup.");
ok(menupopup.firstChild, "We have a first container entry.");
let firstContext = menupopup.firstChild;
is(firstContext.nodeType, Node.ELEMENT_NODE, "We have a first container entry.");
ok(firstContext.hasAttribute("usercontextid"), "We have a usercontextid value.");
- is("1", firstContext.getAttribute("usercontextid"), "We have the right usercontextid value.");
+ is("0", firstContext.getAttribute("usercontextid"), "We have the right usercontextid value.");
aContextMenu.addEventListener("popuphidden", function onPopupHidden() {
aContextMenu.removeEventListener("popuphidden", onPopupHidden);
firstContext.doCommand();
});
aContextMenu.hidePopup();
});
deleted file mode 100644
--- a/browser/base/content/test/referrer/browser_referrer_open_link_in_tab_in_container.js
+++ /dev/null
@@ -1,34 +0,0 @@
-// Tests referrer on context menu navigation - open link in new tab.
-// Selects "open link in new tab" from the context menu.
-
-// This test starts from a container tab. We don't want to propagate the
-// referrer.
-function getReferrerTest(aTestNumber) {
- let test = _referrerTests[aTestNumber];
- if (test) {
- // We want all the referrer tests to fail!
- test.result = "";
- }
-
- return test;
-}
-
-function startNewTabTestCase(aTestNumber) {
- info("browser_referrer_open_link_in_tab: " +
- getReferrerTestDescription(aTestNumber));
- contextMenuOpened(gTestWindow, "testlink").then(function(aContextMenu) {
- someTabLoaded(gTestWindow).then(function(aNewTab) {
- gTestWindow.gBrowser.selectedTab = aNewTab;
- checkReferrerAndStartNextTest(aTestNumber, null, aNewTab,
- startNewTabTestCase,
- { userContextId: 4 });
- });
-
- doContextMenuCommand(gTestWindow, aContextMenu, "context-openlinkintab");
- });
-}
-
-function test() {
- requestLongerTimeout(10); // slowwww shutdown on e10s
- startReferrerTest(startNewTabTestCase, { userContextId: 4 });
-}
--- a/browser/base/content/test/referrer/browser_referrer_open_link_in_window_in_container.js
+++ b/browser/base/content/test/referrer/browser_referrer_open_link_in_window_in_container.js
@@ -16,11 +16,17 @@ function startNewWindowTestCase(aTestNum
});
});
doContextMenuCommand(gTestWindow, aContextMenu, "context-openlink");
});
}
function test() {
- requestLongerTimeout(10); // slowwww shutdown on e10s
- startReferrerTest(startNewWindowTestCase, { userContextId: 1 });
+ waitForExplicitFinish();
+
+ SpecialPowers.pushPrefEnv(
+ {set: [["privacy.userContext.enabled", true]]},
+ function() {
+ requestLongerTimeout(10); // slowwww shutdown on e10s
+ startReferrerTest(startNewWindowTestCase, { userContextId: 1 });
+ });
}
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -410,25 +410,46 @@ function checkForMiddleClick(node, event
// (Menus close automatically with left-click but not with middle-click.)
closeMenus(event.target);
}
}
// Populate a menu with user-context menu items. This method should be called
// by onpopupshowing passing the event as first argument. addCommandAttribute
// param is used to set the 'command' attribute in the new menuitem elements.
-function createUserContextMenu(event, addCommandAttribute = true) {
+function createUserContextMenu(event, addCommandAttribute = true, excludeUserContextId = 0) {
while (event.target.hasChildNodes()) {
event.target.removeChild(event.target.firstChild);
}
let bundle = document.getElementById("bundle_browser");
let docfrag = document.createDocumentFragment();
+ // If we are excluding a userContextId, we want to add a 'no-container' item.
+ if (excludeUserContextId) {
+ let menuitem = document.createElement("menuitem");
+ menuitem.setAttribute("usercontextid", "0");
+ menuitem.setAttribute("label", bundle.getString("userContextNone.label"));
+ menuitem.setAttribute("accesskey", bundle.getString("userContextNone.accesskey"));
+
+ // We don't set an oncommand/command attribute attribute because if we have
+ // to exclude a userContextId we are generating the contextMenu and
+ // addCommandAttribute will be false.
+
+ docfrag.appendChild(menuitem);
+
+ let menuseparator = document.createElement("menuseparator");
+ docfrag.appendChild(menuseparator);
+ }
+
ContextualIdentityService.getIdentities().forEach(identity => {
+ if (identity.userContextId == excludeUserContextId) {
+ return;
+ }
+
let menuitem = document.createElement("menuitem");
menuitem.setAttribute("usercontextid", identity.userContextId);
menuitem.setAttribute("label", bundle.getString(identity.label));
menuitem.setAttribute("accesskey", bundle.getString(identity.accessKey));
menuitem.classList.add("menuitem-iconic");
if (addCommandAttribute) {
menuitem.setAttribute("command", "Browser:NewUserContextTab");
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -702,35 +702,40 @@ e10s.accessibilityNotice.mainMessage2 =
e10s.accessibilityNotice.acceptButton.label = OK
e10s.accessibilityNotice.acceptButton.accesskey = O
e10s.accessibilityNotice.enableAndRestart.label = Enable (Requires Restart)
e10s.accessibilityNotice.enableAndRestart.accesskey = E
# LOCALIZATION NOTE (userContextPersonal.label,
# userContextWork.label,
# userContextShopping.label,
-# userContextBanking.label):
+# userContextBanking.label,
+# userContextNone.label):
# These strings specify the four predefined contexts included in support of the
# Contextual Identity / Containers project. Each context is meant to represent
# the context that the user is in when interacting with the site. Different
# contexts will store cookies and other information from those sites in
# different, isolated locations. You can enable the feature by typing
# about:config in the URL bar and changing privacy.userContext.enabled to true.
# Once enabled, you can open a new tab in a specific context by clicking
# File > New Container Tab > (1 of 4 contexts). Once opened, you will see these
# strings on the right-hand side of the URL bar.
userContextPersonal.label = Personal
userContextWork.label = Work
userContextBanking.label = Banking
userContextShopping.label = Shopping
+userContextNone.label = No Container
userContextPersonal.accesskey = P
userContextWork.accesskey = W
userContextBanking.accesskey = B
userContextShopping.accesskey = S
+userContextNone.accesskey = N
+
+userContextOpenLink.label = Open Link in New %S Tab
muteTab.label = Mute Tab
muteTab.accesskey = M
unmuteTab.label = Unmute Tab
unmuteTab.accesskey = M
# LOCALIZATION NOTE (weakCryptoOverriding.message): %S is brandShortName
weakCryptoOverriding.message = %S recommends that you don’t enter your password, credit card and other personal information on this website.
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -345,16 +345,17 @@ menuitem:not([type]):not(.menuitem-toolt
list-style-image: url("chrome://browser/skin/Toolbar-small.png");
-moz-image-region: rect(0px 80px 16px 64px);
}
#placesContext_open\:newtab,
#placesContext_openContainer\:tabs,
#menu_newNavigatorTab,
#context-openlinkintab,
+#context-openlinkincontainertab,
#context-openframeintab {
list-style-image: url("chrome://browser/skin/Toolbar-small.png");
-moz-image-region: rect(0px 64px 16px 48px);
}
#menu_openFile {
list-style-image: url("moz-icon://stock/gtk-open?size=menu");
}