tor-browser

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

AdBannerContextMenu.jsx (4514B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
      4 
      5 import React, { useState } from "react";
      6 import { actionCreators as ac } from "common/Actions.mjs";
      7 import { LinkMenu } from "../../LinkMenu/LinkMenu";
      8 
      9 /**
     10 * A context menu for IAB banners (e.g. billboard, leaderboard).
     11 *
     12 * Note: MREC ad formats and sponsored stories share the context menu with
     13 * other cards: make sure you also look at DSLinkMenu component
     14 * to keep any updates to ad-related context menu items in sync.
     15 *
     16 * @param dispatch
     17 * @param spoc
     18 * @param position
     19 * @param type
     20 * @param showAdReporting
     21 * @returns {Element}
     22 * @class
     23 */
     24 export function AdBannerContextMenu({
     25  dispatch,
     26  spoc,
     27  position,
     28  type,
     29  showAdReporting,
     30  toggleActive = () => {},
     31 }) {
     32  const ADBANNER_CONTEXT_MENU_OPTIONS = [
     33    "BlockAdUrl",
     34    ...(showAdReporting ? ["ReportAd"] : []),
     35    "ManageSponsoredContent",
     36    "OurSponsorsAndYourPrivacy",
     37  ];
     38 
     39  const [showContextMenu, setShowContextMenu] = useState(false);
     40  const [contextMenuClassNames, setContextMenuClassNames] =
     41    useState("ads-context-menu");
     42 
     43  // The keyboard access parameter is passed down to LinkMenu component
     44  // that uses it to focus on the first context menu option for accessibility.
     45  const [isKeyboardAccess, setIsKeyboardAccess] = useState(false);
     46 
     47  /**
     48   * Toggles the style fix for context menu hover/active styles.
     49   * This allows us to have unobtrusive, transparent button background by default,
     50   * yet flip it over to semi-transparent grey when the menu is visible.
     51   *
     52   * @param contextMenuOpen
     53   */
     54  const toggleContextMenuStyleSwitch = contextMenuOpen => {
     55    if (contextMenuOpen) {
     56      setContextMenuClassNames("ads-context-menu context-menu-open");
     57    } else {
     58      setContextMenuClassNames("ads-context-menu");
     59    }
     60  };
     61 
     62  /**
     63   * Toggles the context menu to open or close. Sets state depending on whether
     64   * the context menu is accessed by mouse or keyboard.
     65   *
     66   * @param isKeyBoard
     67   */
     68  const toggleContextMenu = isKeyBoard => {
     69    toggleContextMenuStyleSwitch(!showContextMenu);
     70    toggleActive(!showContextMenu);
     71    setShowContextMenu(!showContextMenu);
     72    setIsKeyboardAccess(isKeyBoard);
     73  };
     74 
     75  const onClick = e => {
     76    e.preventDefault();
     77    toggleContextMenu(false);
     78  };
     79 
     80  const onKeyDown = e => {
     81    if (e.key === "Enter" || e.key === " ") {
     82      e.preventDefault();
     83      toggleContextMenu(true);
     84    }
     85  };
     86 
     87  const onUpdate = () => {
     88    toggleContextMenuStyleSwitch(!showContextMenu);
     89    toggleActive(!showContextMenu);
     90    setShowContextMenu(!showContextMenu);
     91  };
     92 
     93  return (
     94    <div className="ads-context-menu-wrapper">
     95      <div className={contextMenuClassNames}>
     96        <moz-button
     97          type="icon"
     98          size="default"
     99          data-l10n-id="newtab-menu-content-tooltip"
    100          data-l10n-args={JSON.stringify({
    101            title: spoc.title || spoc.sponsor || spoc.alt_text,
    102          })}
    103          iconsrc="chrome://global/skin/icons/more.svg"
    104          onClick={onClick}
    105          onKeyDown={onKeyDown}
    106        />
    107        {showContextMenu && (
    108          <LinkMenu
    109            onUpdate={onUpdate}
    110            dispatch={dispatch}
    111            keyboardAccess={isKeyboardAccess}
    112            options={ADBANNER_CONTEXT_MENU_OPTIONS}
    113            shouldSendImpressionStats={true}
    114            userEvent={ac.DiscoveryStreamUserEvent}
    115            site={{
    116              // Props we want to pass on for new ad types that come from Unified Ads API
    117              block_key: spoc.block_key,
    118              fetchTimestamp: spoc.fetchTimestamp,
    119              flight_id: spoc.flight_id,
    120              format: spoc.format,
    121              id: spoc.id,
    122              guid: spoc.guid,
    123              card_type: "spoc",
    124              // required to record telemetry for an action, see handleBlockUrl in TelemetryFeed.sys.mjs
    125              is_pocket_card: true,
    126              position,
    127              sponsor: spoc.sponsor,
    128              title: spoc.title,
    129              url: spoc.url || spoc.shim.url,
    130              personalization_models: spoc.personalization_models,
    131              priority: spoc.priority,
    132              score: spoc.score,
    133              alt_text: spoc.alt_text,
    134              shim: spoc.shim,
    135            }}
    136            index={position}
    137            source={type.toUpperCase()}
    138          />
    139        )}
    140      </div>
    141    </div>
    142  );
    143 }