morgan pushed to branch base-browser-128.2.0esr-14.0-1 at The Tor Project / Applications / Tor Browser
Commits:
-
9cd3c30f
by Henry Wilkes at 2024-09-17T18:39:47+00:00
5 changed files:
- browser/components/places/PlacesUIUtils.sys.mjs
- browser/components/places/content/controller.js
- browser/components/places/content/placesContextMenu.inc.xhtml
- browser/components/places/tests/browser/browser_bookmark_context_menu_contents.js
- browser/components/places/tests/browser/head.js
Changes:
| ... | ... | @@ -1514,6 +1514,40 @@ export var PlacesUIUtils = { |
| 1514 | 1514 | }
|
| 1515 | 1515 | },
|
| 1516 | 1516 | |
| 1517 | + /**
|
|
| 1518 | + * Determines whether the given "placesContext" menu item would open a link
|
|
| 1519 | + * under some special conditions, but those special conditions cannot be met.
|
|
| 1520 | + *
|
|
| 1521 | + * @param {Element} item The menu or menu item to decide for.
|
|
| 1522 | + *
|
|
| 1523 | + * @returns {boolean} Whether the item is an "open" item that should be
|
|
| 1524 | + * hidden.
|
|
| 1525 | + */
|
|
| 1526 | + shouldHideOpenMenuItem(item) {
|
|
| 1527 | + if (
|
|
| 1528 | + item.hasAttribute("hide-if-disabled-private-browsing") &&
|
|
| 1529 | + !lazy.PrivateBrowsingUtils.enabled
|
|
| 1530 | + ) {
|
|
| 1531 | + return true;
|
|
| 1532 | + }
|
|
| 1533 | + |
|
| 1534 | + if (
|
|
| 1535 | + item.hasAttribute("hide-if-private-browsing") &&
|
|
| 1536 | + lazy.PrivateBrowsingUtils.isWindowPrivate(item.ownerGlobal)
|
|
| 1537 | + ) {
|
|
| 1538 | + return true;
|
|
| 1539 | + }
|
|
| 1540 | + |
|
| 1541 | + if (
|
|
| 1542 | + item.hasAttribute("hide-if-usercontext-disabled") &&
|
|
| 1543 | + !Services.prefs.getBoolPref("privacy.userContext.enabled", false)
|
|
| 1544 | + ) {
|
|
| 1545 | + return true;
|
|
| 1546 | + }
|
|
| 1547 | + |
|
| 1548 | + return false;
|
|
| 1549 | + },
|
|
| 1550 | + |
|
| 1517 | 1551 | async managedPlacesContextShowing(event) {
|
| 1518 | 1552 | let menupopup = event.target;
|
| 1519 | 1553 | let document = menupopup.ownerDocument;
|
| ... | ... | @@ -1528,12 +1562,6 @@ export var PlacesUIUtils = { |
| 1528 | 1562 | menupopup.triggerNode.menupopup
|
| 1529 | 1563 | );
|
| 1530 | 1564 | }
|
| 1531 | - let linkItems = [
|
|
| 1532 | - "placesContext_open:newtab",
|
|
| 1533 | - "placesContext_open:newwindow",
|
|
| 1534 | - "placesContext_openSeparator",
|
|
| 1535 | - "placesContext_copy",
|
|
| 1536 | - ];
|
|
| 1537 | 1565 | // Hide everything. We'll unhide the things we need.
|
| 1538 | 1566 | Array.from(menupopup.children).forEach(function (child) {
|
| 1539 | 1567 | child.hidden = true;
|
| ... | ... | @@ -1555,12 +1583,18 @@ export var PlacesUIUtils = { |
| 1555 | 1583 | openContainerInTabs_menuitem.disabled = !openContainerInTabs;
|
| 1556 | 1584 | openContainerInTabs_menuitem.hidden = false;
|
| 1557 | 1585 | } else {
|
| 1558 | - linkItems.forEach(id => (document.getElementById(id).hidden = false));
|
|
| 1559 | - document.getElementById("placesContext_open:newprivatewindow").hidden =
|
|
| 1560 | - lazy.PrivateBrowsingUtils.isWindowPrivate(window) ||
|
|
| 1561 | - !lazy.PrivateBrowsingUtils.enabled;
|
|
| 1562 | - document.getElementById("placesContext_open:newcontainertab").hidden =
|
|
| 1563 | - !Services.prefs.getBoolPref("privacy.userContext.enabled", false);
|
|
| 1586 | + for (let id of [
|
|
| 1587 | + "placesContext_open:newtab",
|
|
| 1588 | + "placesContext_open:newcontainertab",
|
|
| 1589 | + "placesContext_open:newwindow",
|
|
| 1590 | + "placesContext_open:newprivatewindow",
|
|
| 1591 | + ]) {
|
|
| 1592 | + let item = document.getElementById(id);
|
|
| 1593 | + item.hidden = this.shouldHideOpenMenuItem(item);
|
|
| 1594 | + }
|
|
| 1595 | + for (let id of ["placesContext_openSeparator", "placesContext_copy"]) {
|
|
| 1596 | + document.getElementById(id).hidden = false;
|
|
| 1597 | + }
|
|
| 1564 | 1598 | }
|
| 1565 | 1599 | |
| 1566 | 1600 | event.target.ownerGlobal.updateCommands("places");
|
| ... | ... | @@ -465,17 +465,7 @@ PlacesController.prototype = { |
| 465 | 465 | * and the item can be displayed, false otherwise.
|
| 466 | 466 | */
|
| 467 | 467 | _shouldShowMenuItem(aMenuItem, aMetaData) {
|
| 468 | - if (
|
|
| 469 | - aMenuItem.hasAttribute("hide-if-private-browsing") &&
|
|
| 470 | - !PrivateBrowsingUtils.enabled
|
|
| 471 | - ) {
|
|
| 472 | - return false;
|
|
| 473 | - }
|
|
| 474 | - |
|
| 475 | - if (
|
|
| 476 | - aMenuItem.hasAttribute("hide-if-usercontext-disabled") &&
|
|
| 477 | - !Services.prefs.getBoolPref("privacy.userContext.enabled", false)
|
|
| 478 | - ) {
|
|
| 468 | + if (PlacesUIUtils.shouldHideOpenMenuItem(aMenuItem)) {
|
|
| 479 | 469 | return false;
|
| 480 | 470 | }
|
| 481 | 471 | |
| ... | ... | @@ -566,8 +556,12 @@ PlacesController.prototype = { |
| 566 | 556 | * menuitem when there's no insertion point. An insertion point represents
|
| 567 | 557 | * a point in the view where a new item can be inserted.
|
| 568 | 558 | * 9) The boolean `hide-if-private-browsing` attribute may be set to hide a
|
| 569 | - * menuitem in private browsing mode
|
|
| 570 | - * 10) The boolean `hide-if-single-click-opens` attribute may be set to hide a
|
|
| 559 | + * menuitem in private browsing mode.
|
|
| 560 | + * 10) The boolean `hide-if-disabled-private-browsing` attribute may be set to
|
|
| 561 | + * hide a menuitem if private browsing is not enabled.
|
|
| 562 | + * 11) The boolean `hide-if-usercontext-disabled` attribute may be set to
|
|
| 563 | + * hide a menuitem if containers are disabled.
|
|
| 564 | + * 12) The boolean `hide-if-single-click-opens` attribute may be set to hide a
|
|
| 571 | 565 | * menuitem in views opening entries with a single click.
|
| 572 | 566 | *
|
| 573 | 567 | * @param {object} aPopup
|
| ... | ... | @@ -593,9 +587,6 @@ PlacesController.prototype = { |
| 593 | 587 | item.getAttribute("hide-if-no-insertion-point") == "true" &&
|
| 594 | 588 | noIp &&
|
| 595 | 589 | !(ip && ip.isTag && item.id == "placesContext_paste");
|
| 596 | - let hideIfPrivate =
|
|
| 597 | - item.getAttribute("hide-if-private-browsing") == "true" &&
|
|
| 598 | - PrivateBrowsingUtils.isWindowPrivate(window);
|
|
| 599 | 590 | // Hide `Open` if the primary action on click is opening.
|
| 600 | 591 | let hideIfSingleClickOpens =
|
| 601 | 592 | item.getAttribute("hide-if-single-click-opens") == "true" &&
|
| ... | ... | @@ -610,7 +601,6 @@ PlacesController.prototype = { |
| 610 | 601 | |
| 611 | 602 | let shouldHideItem =
|
| 612 | 603 | hideIfNoIP ||
|
| 613 | - hideIfPrivate ||
|
|
| 614 | 604 | hideIfSingleClickOpens ||
|
| 615 | 605 | hideIfNotSearch ||
|
| 616 | 606 | !this._shouldShowMenuItem(item, metadata);
|
| ... | ... | @@ -52,13 +52,14 @@ |
| 52 | 52 | command="placesCmd_open:window"
|
| 53 | 53 | data-l10n-id="places-open-in-window"
|
| 54 | 54 | selection-type="single"
|
| 55 | - node-type="link"/>
|
|
| 55 | + node-type="link"
|
|
| 56 | + hide-if-private-browsing="true"/>
|
|
| 56 | 57 | <menuitem id="placesContext_open:newprivatewindow"
|
| 57 | 58 | command="placesCmd_open:privatewindow"
|
| 58 | 59 | data-l10n-id="places-open-in-private-window"
|
| 59 | 60 | selection-type="single"
|
| 60 | 61 | node-type="link"
|
| 61 | - hide-if-private-browsing="true"/>
|
|
| 62 | + hide-if-disabled-private-browsing="true"/>
|
|
| 62 | 63 | <menuitem id="placesContext_showInFolder"
|
| 63 | 64 | data-l10n-id="places-show-in-folder"
|
| 64 | 65 | command="placesCmd_showInFolder"
|
| ... | ... | @@ -814,3 +814,118 @@ add_task(async function test_library_noselection_contextmenu_contents() { |
| 814 | 814 | );
|
| 815 | 815 | });
|
| 816 | 816 | });
|
| 817 | + |
|
| 818 | +add_task(async function test_private_browsing_window() {
|
|
| 819 | + // Test the context menu when in a private browsing window.
|
|
| 820 | + |
|
| 821 | + let win = await BrowserTestUtils.openNewBrowserWindow({
|
|
| 822 | + private: true,
|
|
| 823 | + });
|
|
| 824 | + |
|
| 825 | + let optionItems = [
|
|
| 826 | + "placesContext_open:newtab",
|
|
| 827 | + // Hidden in private window "placesContext_open:newcontainertab"
|
|
| 828 | + // Hidden in private window "placesContext_open:newwindow"
|
|
| 829 | + "placesContext_open:newprivatewindow",
|
|
| 830 | + "placesContext_show_bookmark:info",
|
|
| 831 | + "placesContext_deleteBookmark",
|
|
| 832 | + "placesContext_cut",
|
|
| 833 | + "placesContext_copy",
|
|
| 834 | + "placesContext_paste_group",
|
|
| 835 | + "placesContext_new:bookmark",
|
|
| 836 | + "placesContext_new:folder",
|
|
| 837 | + "placesContext_new:separator",
|
|
| 838 | + ];
|
|
| 839 | + |
|
| 840 | + // Test toolbar.
|
|
| 841 | + await checkContextMenu(
|
|
| 842 | + async function () {
|
|
| 843 | + let toolbarBookmark = await PlacesUtils.bookmarks.insert({
|
|
| 844 | + parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
|
| 845 | + title: "Bookmark Title",
|
|
| 846 | + url: TEST_URL,
|
|
| 847 | + });
|
|
| 848 | + |
|
| 849 | + let toolbarNode = getToolbarNodeForItemGuid(toolbarBookmark.guid, win);
|
|
| 850 | + |
|
| 851 | + let contextMenu = win.document.getElementById("placesContext");
|
|
| 852 | + let popupShownPromise = BrowserTestUtils.waitForEvent(
|
|
| 853 | + contextMenu,
|
|
| 854 | + "popupshown"
|
|
| 855 | + );
|
|
| 856 | + |
|
| 857 | + EventUtils.synthesizeMouseAtCenter(
|
|
| 858 | + toolbarNode,
|
|
| 859 | + { button: 2, type: "contextmenu" },
|
|
| 860 | + win
|
|
| 861 | + );
|
|
| 862 | + await popupShownPromise;
|
|
| 863 | + return contextMenu;
|
|
| 864 | + },
|
|
| 865 | + [
|
|
| 866 | + ...optionItems,
|
|
| 867 | + "placesContext_showAllBookmarks",
|
|
| 868 | + "toggle_PersonalToolbar",
|
|
| 869 | + "show-other-bookmarks_PersonalToolbar",
|
|
| 870 | + ],
|
|
| 871 | + win.document
|
|
| 872 | + );
|
|
| 873 | + |
|
| 874 | + // Test side bar.
|
|
| 875 | + await withSidebarTree(
|
|
| 876 | + "bookmarks",
|
|
| 877 | + async tree => {
|
|
| 878 | + await checkContextMenu(
|
|
| 879 | + async bookmark => {
|
|
| 880 | + tree.selectItems([bookmark.guid]);
|
|
| 881 | + |
|
| 882 | + let contextMenu =
|
|
| 883 | + win.SidebarController.browser.contentDocument.getElementById(
|
|
| 884 | + "placesContext"
|
|
| 885 | + );
|
|
| 886 | + let popupShownPromise = BrowserTestUtils.waitForEvent(
|
|
| 887 | + contextMenu,
|
|
| 888 | + "popupshown"
|
|
| 889 | + );
|
|
| 890 | + synthesizeClickOnSelectedTreeCell(tree, { type: "contextmenu" }, win);
|
|
| 891 | + await popupShownPromise;
|
|
| 892 | + return contextMenu;
|
|
| 893 | + },
|
|
| 894 | + optionItems,
|
|
| 895 | + win.SidebarController.browser.contentDocument
|
|
| 896 | + );
|
|
| 897 | + },
|
|
| 898 | + win
|
|
| 899 | + );
|
|
| 900 | + |
|
| 901 | + // Test library window opened when using private browsing window.
|
|
| 902 | + optionItems.splice(
|
|
| 903 | + optionItems.indexOf("placesContext_show_bookmark:info"),
|
|
| 904 | + 1
|
|
| 905 | + );
|
|
| 906 | + optionItems.splice(0, 0, "placesContext_open");
|
|
| 907 | + |
|
| 908 | + await withLibraryWindow(
|
|
| 909 | + "BookmarksToolbar",
|
|
| 910 | + async ({ right }) => {
|
|
| 911 | + await checkContextMenu(
|
|
| 912 | + async bookmark => {
|
|
| 913 | + let contextMenu = right.ownerDocument.getElementById("placesContext");
|
|
| 914 | + let popupShownPromise = BrowserTestUtils.waitForEvent(
|
|
| 915 | + contextMenu,
|
|
| 916 | + "popupshown"
|
|
| 917 | + );
|
|
| 918 | + right.selectItems([bookmark.guid]);
|
|
| 919 | + synthesizeClickOnSelectedTreeCell(right, { type: "contextmenu" });
|
|
| 920 | + await popupShownPromise;
|
|
| 921 | + return contextMenu;
|
|
| 922 | + },
|
|
| 923 | + optionItems,
|
|
| 924 | + right.ownerDocument
|
|
| 925 | + );
|
|
| 926 | + },
|
|
| 927 | + win
|
|
| 928 | + );
|
|
| 929 | + |
|
| 930 | + await BrowserTestUtils.closeWindow(win);
|
|
| 931 | +}); |
| ... | ... | @@ -6,8 +6,8 @@ ChromeUtils.defineLazyGetter(this, "gFluentStrings", function () { |
| 6 | 6 | return new Localization(["branding/brand.ftl", "browser/browser.ftl"], true);
|
| 7 | 7 | });
|
| 8 | 8 | |
| 9 | -function openLibrary(callback, aLeftPaneRoot) {
|
|
| 10 | - let library = window.openDialog(
|
|
| 9 | +function openLibrary(callback, aLeftPaneRoot, win = window) {
|
|
| 10 | + let library = win.openDialog(
|
|
| 11 | 11 | "chrome://browser/content/places/places.xhtml",
|
| 12 | 12 | "",
|
| 13 | 13 | "chrome,toolbar=yes,dialog=no,resizable",
|
| ... | ... | @@ -27,10 +27,12 @@ function openLibrary(callback, aLeftPaneRoot) { |
| 27 | 27 | *
|
| 28 | 28 | * @param {object} aLeftPaneRoot
|
| 29 | 29 | * Hierarchy to open and select in the left pane.
|
| 30 | + * @param {Window} [win]
|
|
| 31 | + * The window to use to open the library.
|
|
| 30 | 32 | * @returns {Promise}
|
| 31 | 33 | * Resolves to the handle to the library window.
|
| 32 | 34 | */
|
| 33 | -function promiseLibrary(aLeftPaneRoot) {
|
|
| 35 | +function promiseLibrary(aLeftPaneRoot, win = window) {
|
|
| 34 | 36 | return new Promise(resolve => {
|
| 35 | 37 | let library = Services.wm.getMostRecentWindow("Places:Organizer");
|
| 36 | 38 | if (library && !library.closed) {
|
| ... | ... | @@ -42,7 +44,7 @@ function promiseLibrary(aLeftPaneRoot) { |
| 42 | 44 | checkLibraryPaneVisibility(library, aLeftPaneRoot);
|
| 43 | 45 | resolve(library);
|
| 44 | 46 | } else {
|
| 45 | - openLibrary(resolve, aLeftPaneRoot);
|
|
| 47 | + openLibrary(resolve, aLeftPaneRoot, win);
|
|
| 46 | 48 | }
|
| 47 | 49 | });
|
| 48 | 50 | }
|
| ... | ... | @@ -380,9 +382,11 @@ function fillBookmarkTextField(id, text, win, blur = true) { |
| 380 | 382 | * @param {Function} taskFn
|
| 381 | 383 | * The task to execute once the sidebar is ready. Will get the Places
|
| 382 | 384 | * tree view as input.
|
| 385 | + * @param {Window} [win]
|
|
| 386 | + * The window to open the sidebar in, else uses the default window.
|
|
| 383 | 387 | */
|
| 384 | -var withSidebarTree = async function (type, taskFn) {
|
|
| 385 | - let sidebar = document.getElementById("sidebar");
|
|
| 388 | +var withSidebarTree = async function (type, taskFn, win = window) {
|
|
| 389 | + let sidebar = win.document.getElementById("sidebar");
|
|
| 386 | 390 | info("withSidebarTree: waiting sidebar load");
|
| 387 | 391 | let sidebarLoadedPromise = new Promise(resolve => {
|
| 388 | 392 | sidebar.addEventListener(
|
| ... | ... | @@ -395,7 +399,7 @@ var withSidebarTree = async function (type, taskFn) { |
| 395 | 399 | });
|
| 396 | 400 | let sidebarId =
|
| 397 | 401 | type == "bookmarks" ? "viewBookmarksSidebar" : "viewHistorySidebar";
|
| 398 | - SidebarController.show(sidebarId);
|
|
| 402 | + win.SidebarController.show(sidebarId);
|
|
| 399 | 403 | await sidebarLoadedPromise;
|
| 400 | 404 | |
| 401 | 405 | let treeId = type == "bookmarks" ? "bookmarks-view" : "historyTree";
|
| ... | ... | @@ -406,7 +410,7 @@ var withSidebarTree = async function (type, taskFn) { |
| 406 | 410 | try {
|
| 407 | 411 | await taskFn(tree);
|
| 408 | 412 | } finally {
|
| 409 | - SidebarController.hide();
|
|
| 413 | + win.SidebarController.hide();
|
|
| 410 | 414 | }
|
| 411 | 415 | };
|
| 412 | 416 | |
| ... | ... | @@ -419,9 +423,11 @@ var withSidebarTree = async function (type, taskFn) { |
| 419 | 423 | * @param {Function} taskFn
|
| 420 | 424 | * The task to execute once the Library is ready.
|
| 421 | 425 | * Will get { left, right } trees as argument.
|
| 426 | + * @param {Window} [win]
|
|
| 427 | + * The window to use to open the library.
|
|
| 422 | 428 | */
|
| 423 | -var withLibraryWindow = async function (hierarchy, taskFn) {
|
|
| 424 | - let library = await promiseLibrary(hierarchy);
|
|
| 429 | +var withLibraryWindow = async function (hierarchy, taskFn, win = window) {
|
|
| 430 | + let library = await promiseLibrary(hierarchy, win);
|
|
| 425 | 431 | let left = library.document.getElementById("placesList");
|
| 426 | 432 | let right = library.document.getElementById("placeContent");
|
| 427 | 433 | info("withLibrary: executing the task");
|
| ... | ... | @@ -477,8 +483,8 @@ function promisePopupHidden(popup) { |
| 477 | 483 | }
|
| 478 | 484 | |
| 479 | 485 | // Identify a bookmark node in the Bookmarks Toolbar by its guid.
|
| 480 | -function getToolbarNodeForItemGuid(itemGuid) {
|
|
| 481 | - let children = document.getElementById("PlacesToolbarItems").childNodes;
|
|
| 486 | +function getToolbarNodeForItemGuid(itemGuid, win = window) {
|
|
| 487 | + let children = win.document.getElementById("PlacesToolbarItems").childNodes;
|
|
| 482 | 488 | for (let child of children) {
|
| 483 | 489 | if (itemGuid === child._placesNode.bookmarkGuid) {
|
| 484 | 490 | return child;
|