tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

navigator-toolbox.js (15813B)


      1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
      2 * This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 document.addEventListener(
      7  "DOMContentLoaded",
      8  () => {
      9    const navigatorToolbox = document.getElementById("navigator-toolbox");
     10    const widgetOverflow = document.getElementById("widget-overflow");
     11 
     12    function onPopupShowing(event) {
     13      switch (event.target.id) {
     14        case "PlacesChevronPopup":
     15          document
     16            .getElementById("PlacesToolbar")
     17            ._placesView._onChevronPopupShowing(event);
     18          break;
     19 
     20        case "BMB_bookmarksPopup":
     21          BookmarkingUI.onPopupShowing(event);
     22        // fall-through
     23        case "BMB_bookmarksToolbarPopup":
     24        case "BMB_unsortedBookmarksPopup":
     25        case "BMB_mobileBookmarksPopup":
     26          if (!event.target.parentNode._placesView) {
     27            let placeMap = {
     28              BMB_bookmarksPopup: PlacesUtils.bookmarks.menuGuid,
     29              BMB_bookmarksToolbarPopup: PlacesUtils.bookmarks.toolbarGuid,
     30              BMB_unsortedBookmarksPopup: PlacesUtils.bookmarks.unfiledGuid,
     31              BMB_mobileBookmarksPopup: PlacesUtils.bookmarks.mobileGuid,
     32            };
     33            new PlacesMenu(event, `place:parent=${placeMap[event.target.id]}`);
     34          }
     35          break;
     36      }
     37    }
     38    navigatorToolbox.addEventListener("popupshowing", onPopupShowing);
     39    widgetOverflow.addEventListener("popupshowing", onPopupShowing);
     40 
     41    function onCommand(event) {
     42      let element = event.target.closest(`
     43        #firefox-view-button,
     44        .content-analysis-indicator,
     45        #bookmarks-toolbar-button,
     46        #PlacesToolbar,
     47        #import-button,
     48        #bookmarks-menu-button,
     49        #BMB_bookmarksPopup,
     50        #BMB_viewBookmarksSidebar,
     51        #BMB_searchBookmarks,
     52        #BMB_viewBookmarksToolbar`);
     53      if (!element) {
     54        return;
     55      }
     56 
     57      switch (element.id) {
     58        case "firefox-view-button":
     59          FirefoxViewHandler.openTab();
     60          break;
     61 
     62        case "bookmarks-toolbar-button":
     63          PlacesToolbarHelper.onPlaceholderCommand();
     64          break;
     65 
     66        case "PlacesToolbar":
     67        case "BMB_bookmarksPopup":
     68          BookmarksEventHandler.onCommand(event);
     69          break;
     70 
     71        case "import-button":
     72          MigrationUtils.showMigrationWizard(window, {
     73            entrypoint: MigrationUtils.MIGRATION_ENTRYPOINTS.BOOKMARKS_TOOLBAR,
     74          });
     75          break;
     76 
     77        case "bookmarks-menu-button":
     78          BookmarkingUI.onCommand(event);
     79          break;
     80 
     81        case "BMB_viewBookmarksSidebar":
     82          SidebarController.toggle("viewBookmarksSidebar");
     83          break;
     84 
     85        case "BMB_searchBookmarks":
     86          PlacesCommandHook.searchBookmarks();
     87          break;
     88 
     89        case "BMB_viewBookmarksToolbar":
     90          BookmarkingUI.toggleBookmarksToolbar("bookmarks-widget");
     91          break;
     92 
     93        default:
     94          if (element.classList.contains("content-analysis-indicator")) {
     95            ContentAnalysis.showPanel(element, PanelUI);
     96          } else {
     97            throw new Error(`Missing case for #${element.id}`);
     98          }
     99      }
    100    }
    101    navigatorToolbox.addEventListener("command", onCommand);
    102    widgetOverflow.addEventListener("command", onCommand);
    103 
    104    function onMouseDown(event) {
    105      let element = event.target.closest(`
    106        #firefox-view-button,
    107        #alltabs-button,
    108        #pageActionButton,
    109        #downloads-button,
    110        #fxa-toolbar-menu-button,
    111        #unified-extensions-button,
    112        #library-button
    113        `);
    114      if (!element) {
    115        return;
    116      }
    117 
    118      switch (element.id) {
    119        case "firefox-view-button":
    120          FirefoxViewHandler.openToolbarMouseEvent(event);
    121          break;
    122 
    123        case "alltabs-button":
    124          gTabsPanel.showAllTabsPanel(event, "alltabs-button");
    125          break;
    126 
    127        case "pageActionButton":
    128          BrowserPageActions.mainButtonClicked(event);
    129          break;
    130 
    131        case "downloads-button":
    132          DownloadsIndicatorView.onCommand(event);
    133          break;
    134 
    135        case "fxa-toolbar-menu-button":
    136          gSync.toggleAccountPanel(element, event);
    137          break;
    138 
    139        case "unified-extensions-button":
    140          gUnifiedExtensions.togglePanel(event);
    141          break;
    142 
    143        case "library-button":
    144          PanelUI.showSubView("appMenu-libraryView", element, event);
    145          break;
    146 
    147        default:
    148          throw new Error(`Missing case for #${element.id}`);
    149      }
    150    }
    151    navigatorToolbox.addEventListener("mousedown", onMouseDown);
    152    widgetOverflow.addEventListener("mousedown", onMouseDown);
    153 
    154    function onMouseUp(event) {
    155      let element = event.target.closest(`
    156        #PlacesToolbar,
    157        #BMB_bookmarksPopup
    158        `);
    159      if (!element) {
    160        return;
    161      }
    162 
    163      switch (element.id) {
    164        case "PlacesToolbar":
    165        case "BMB_bookmarksPopup":
    166          BookmarksEventHandler.onMouseUp(event);
    167          break;
    168 
    169        default:
    170          throw new Error(`Missing case for #${element.id}`);
    171      }
    172    }
    173    navigatorToolbox.addEventListener("mouseup", onMouseUp);
    174    widgetOverflow.addEventListener("mouseup", onMouseUp);
    175 
    176    function onClick(event) {
    177      const isLeftClick = event.button === 0;
    178 
    179      let element = event.target.closest(`
    180        #vertical-tabs-newtab-button,
    181        #tabs-newtab-button,
    182        #new-tab-button,
    183        #back-button,
    184        #forward-button,
    185        #reload-button ,
    186        #reader-mode-button,
    187        #picture-in-picture-button,
    188        #urlbar-zoom-button,
    189        #star-button-box,
    190        #personal-toolbar-empty-description,
    191        #home-button,
    192        #PlacesToolbar,
    193        #BMB_bookmarksPopup,
    194        #trust-icon-container,
    195        #tracking-protection-icon-container,
    196        #identity-icon-box,
    197        #identity-permission-box,
    198        #translations-button,
    199        #split-view-button
    200        `);
    201      if (!element) {
    202        return;
    203      }
    204 
    205      switch (element.id) {
    206        case "vertical-tabs-newtab-button":
    207        case "tabs-newtab-button":
    208        case "new-tab-button":
    209          gBrowser.handleNewTabMiddleClick(element, event);
    210          break;
    211 
    212        case "back-button":
    213        case "forward-button":
    214        case "reload-button":
    215          checkForMiddleClick(element, event);
    216          break;
    217 
    218        case "reader-mode-button":
    219          if (isLeftClick) {
    220            AboutReaderParent.toggleReaderMode(event);
    221          }
    222          break;
    223 
    224        case "picture-in-picture-button":
    225          if (isLeftClick) {
    226            PictureInPicture.toggleUrlbar(event);
    227          }
    228          break;
    229 
    230        case "urlbar-zoom-button":
    231          if (isLeftClick) {
    232            FullZoom.resetFromURLBar();
    233          }
    234          break;
    235 
    236        case "star-button-box":
    237          BrowserPageActions.doCommandForAction(
    238            PageActions.actionForID("bookmark"),
    239            event,
    240            element
    241          );
    242          break;
    243 
    244        case "personal-toolbar-empty-description":
    245          if (isLeftClick && event.target.localName == "a") {
    246            PlacesCommandHook.showPlacesOrganizer("BookmarksToolbar");
    247          }
    248          break;
    249 
    250        case "home-button":
    251          BrowserCommands.home(event);
    252          break;
    253 
    254        case "PlacesToolbar":
    255          BookmarksEventHandler.onClick(event, element._placesView);
    256          break;
    257 
    258        case "BMB_bookmarksPopup":
    259          BookmarksEventHandler.onClick(event, element.parentNode._placesView);
    260          break;
    261 
    262        case "trust-icon-container":
    263          gTrustPanelHandler.handleProtectionsButtonEvent(event);
    264          break;
    265 
    266        case "tracking-protection-icon-container":
    267          gProtectionsHandler.handleProtectionsButtonEvent(event);
    268          break;
    269 
    270        case "identity-icon-box":
    271          if (UrlbarPrefs.get("trustPanel.featureGate")) {
    272            gTrustPanelHandler.handleProtectionsButtonEvent(event);
    273            break;
    274          }
    275          gIdentityHandler.handleIdentityButtonEvent(event);
    276          PageProxyClickHandler(event);
    277          break;
    278 
    279        case "identity-permission-box":
    280          gPermissionPanel.handleIdentityButtonEvent(event);
    281          PageProxyClickHandler(event);
    282          break;
    283 
    284        case "translations-button":
    285          FullPageTranslationsPanel.open(event);
    286          break;
    287 
    288        case "split-view-button":
    289          if (isLeftClick) {
    290            gBrowser.openSplitViewMenu(element);
    291          }
    292          break;
    293 
    294        default:
    295          throw new Error(`Missing case for #${element.id}`);
    296      }
    297    }
    298    navigatorToolbox.addEventListener("click", onClick);
    299    widgetOverflow.addEventListener("click", onClick);
    300    document.getElementById("sidebar-main").addEventListener("click", onClick);
    301 
    302    function onKeyPress(event) {
    303      const isLikeLeftClick = event.key === "Enter" || event.key === " ";
    304 
    305      let element = event.target.closest(`
    306        #reader-mode-button,
    307        #picture-in-picture-button,
    308        #urlbar-zoom-button,
    309        #star-button-box,
    310        #personal-toolbar-empty-description,
    311        #home-button,
    312        #tracking-protection-icon-container,
    313        #identity-icon-box,
    314        #identity-permission-box,
    315        #translations-button,
    316        #alltabs-button,
    317        #pageActionButton,
    318        #downloads-button,
    319        #fxa-toolbar-menu-button,
    320        #unified-extensions-button,
    321        #library-button,
    322        #split-view-button
    323      `);
    324      if (!element) {
    325        return;
    326      }
    327 
    328      switch (element.id) {
    329        case "reader-mode-button":
    330          if (isLikeLeftClick) {
    331            AboutReaderParent.toggleReaderMode(event);
    332          }
    333          break;
    334 
    335        case "picture-in-picture-button":
    336          if (isLikeLeftClick) {
    337            PictureInPicture.toggleUrlbar(event);
    338          }
    339          break;
    340 
    341        case "urlbar-zoom-button":
    342          if (isLikeLeftClick) {
    343            FullZoom.resetFromURLBar();
    344          }
    345          break;
    346 
    347        case "star-button-box":
    348          // This already handles checking for enter and space.
    349          BrowserPageActions.doCommandForAction(
    350            PageActions.actionForID("bookmark"),
    351            event,
    352            element
    353          );
    354          break;
    355 
    356        case "personal-toolbar-empty-description":
    357          if (isLikeLeftClick && event.target.localName == "a") {
    358            PlacesCommandHook.showPlacesOrganizer("BookmarksToolbar");
    359          }
    360          break;
    361 
    362        case "home-button":
    363          if (isLikeLeftClick) {
    364            BrowserCommands.home(event);
    365          }
    366          break;
    367 
    368        case "tracking-protection-icon-container":
    369          gProtectionsHandler.handleProtectionsButtonEvent(event);
    370          break;
    371 
    372        case "identity-icon-box":
    373          gIdentityHandler.handleIdentityButtonEvent(event);
    374          break;
    375 
    376        case "identity-permission-box":
    377          gPermissionPanel.handleIdentityButtonEvent(event);
    378          break;
    379 
    380        case "translations-button":
    381          FullPageTranslationsPanel.open(event);
    382          break;
    383 
    384        case "alltabs-button":
    385          gTabsPanel.showAllTabsPanel(event, "alltabs-button");
    386          break;
    387 
    388        case "pageActionButton":
    389          BrowserPageActions.mainButtonClicked(event);
    390          break;
    391 
    392        case "downloads-button":
    393          DownloadsIndicatorView.onCommand(event);
    394          break;
    395 
    396        case "fxa-toolbar-menu-button":
    397          gSync.toggleAccountPanel(element, event);
    398          break;
    399 
    400        case "unified-extensions-button":
    401          gUnifiedExtensions.togglePanel(event);
    402          break;
    403 
    404        case "library-button":
    405          PanelUI.showSubView("appMenu-libraryView", element, event);
    406          break;
    407 
    408        case "split-view-button":
    409          if (isLikeLeftClick) {
    410            gBrowser.openSplitViewMenu(element);
    411          }
    412          break;
    413 
    414        default:
    415          throw new Error(`Missing case for #${element.id}`);
    416      }
    417    }
    418    // Make sure this preempts browser-toolbarKeyNav.js.
    419    navigatorToolbox.addEventListener("keypress", onKeyPress, {
    420      capture: true,
    421    });
    422    widgetOverflow.addEventListener("keypress", onKeyPress, { capture: true });
    423 
    424    function onDragAndDrop(event) {
    425      let element = event.target.closest(`
    426        #new-tab-button,
    427        #downloads-button,
    428        #new-window-button,
    429        #bookmarks-menu-button,
    430        #home-button
    431      `);
    432      if (!element) {
    433        return;
    434      }
    435 
    436      switch (element.id) {
    437        case "new-tab-button":
    438          if (event.type === "dragenter" || event.type === "dragover") {
    439            ToolbarDropHandler.onDragOver(event);
    440          } else if (event.type === "drop") {
    441            ToolbarDropHandler.onDropNewTabButtonObserver(event);
    442          }
    443          break;
    444 
    445        case "downloads-button":
    446          if (event.type === "dragenter" || event.type === "dragover") {
    447            DownloadsIndicatorView.onDragOver(event);
    448          } else if (event.type === "drop") {
    449            DownloadsIndicatorView.onDrop(event);
    450          }
    451          break;
    452 
    453        case "new-window-button":
    454          if (event.type === "dragenter" || event.type === "dragover") {
    455            ToolbarDropHandler.onDragOver(event);
    456          } else if (event.type === "drop") {
    457            ToolbarDropHandler.onDropNewWindowButtonObserver(event);
    458          }
    459          break;
    460 
    461        case "bookmarks-menu-button":
    462          switch (event.type) {
    463            case "dragenter":
    464              PlacesMenuDNDHandler.onDragEnter(event);
    465              break;
    466            case "dragover":
    467              PlacesMenuDNDHandler.onDragOver(event);
    468              break;
    469            case "dragleave":
    470              PlacesMenuDNDHandler.onDragLeave(event);
    471              break;
    472            case "drop":
    473              PlacesMenuDNDHandler.onDrop(event);
    474              break;
    475          }
    476          break;
    477 
    478        case "home-button":
    479          if (event.type === "dragenter" || event.type === "dragover") {
    480            if (HomePage.locked) {
    481              return;
    482            }
    483            ToolbarDropHandler.onDragOver(event);
    484            event.dropEffect = "link";
    485          } else if (event.type == "drop") {
    486            ToolbarDropHandler.onDropHomeButtonObserver(event);
    487          }
    488          break;
    489 
    490        default:
    491          throw new Error(`Missing case for #${element.id}`);
    492      }
    493    }
    494 
    495    navigatorToolbox.addEventListener("dragenter", onDragAndDrop);
    496    widgetOverflow.addEventListener("dragenter", onDragAndDrop);
    497    navigatorToolbox.addEventListener("dragover", onDragAndDrop);
    498    widgetOverflow.addEventListener("dragover", onDragAndDrop);
    499    navigatorToolbox.addEventListener("dragleave", onDragAndDrop);
    500    widgetOverflow.addEventListener("dragleave", onDragAndDrop);
    501    navigatorToolbox.addEventListener("drop", onDragAndDrop);
    502    widgetOverflow.addEventListener("drop", onDragAndDrop);
    503 
    504    document
    505      .getElementById("identity-box")
    506      .addEventListener("dragstart", event => {
    507        gIdentityHandler.onDragStart(event);
    508      });
    509    document
    510      .getElementById("trust-icon-container")
    511      .addEventListener("dragstart", event => {
    512        gIdentityHandler.onDragStart(event);
    513      });
    514 
    515    let trackingProtectionIconContainer = document.getElementById(
    516      "tracking-protection-icon-container"
    517    );
    518    trackingProtectionIconContainer.addEventListener("focus", () => {
    519      gProtectionsHandler.onTrackingProtectionIconHoveredOrFocused();
    520    });
    521    trackingProtectionIconContainer.addEventListener("mouseover", () => {
    522      gProtectionsHandler.onTrackingProtectionIconHoveredOrFocused();
    523    });
    524  },
    525  { once: true }
    526 );