tor-browser

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

UITour-lib.js (27479B)


      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 http://mozilla.org/MPL/2.0/. */
      4 
      5 // create namespace
      6 if (typeof Mozilla == "undefined") {
      7  var Mozilla = {};
      8 }
      9 
     10 (function () {
     11  "use strict";
     12 
     13  // create namespace
     14  if (typeof Mozilla.UITour == "undefined") {
     15    /**
     16     * Library that exposes an event-based Web API for communicating with the
     17     * desktop browser chrome. It can be used for tasks such as opening menu
     18     * panels and highlighting the position of buttons in the toolbar.
     19     *
     20     * For security/privacy reasons `Mozilla.UITour` will only work on a list of allowed
     21     * secure origins. The list of allowed origins can be found in
     22     * https://searchfox.org/mozilla-central/source/browser/app/permissions.
     23     *
     24     * @since 29
     25     * @namespace
     26     */
     27    Mozilla.UITour = {};
     28  }
     29 
     30  function _sendEvent(action, data) {
     31    var event = new CustomEvent("mozUITour", {
     32      bubbles: true,
     33      detail: {
     34        action,
     35        data: data || {},
     36      },
     37    });
     38 
     39    document.dispatchEvent(event);
     40  }
     41 
     42  function _generateCallbackID() {
     43    return Math.random()
     44      .toString(36)
     45      .replace(/[^a-z]+/g, "");
     46  }
     47 
     48  function _waitForCallback(callback) {
     49    var id = _generateCallbackID();
     50 
     51    function listener(event) {
     52      if (typeof event.detail != "object") {
     53        return;
     54      }
     55      if (event.detail.callbackID != id) {
     56        return;
     57      }
     58 
     59      document.removeEventListener("mozUITourResponse", listener);
     60      callback(event.detail.data);
     61    }
     62    document.addEventListener("mozUITourResponse", listener);
     63 
     64    return id;
     65  }
     66 
     67  var notificationListener = null;
     68  function _notificationListener(event) {
     69    if (typeof event.detail != "object") {
     70      return;
     71    }
     72    if (typeof notificationListener != "function") {
     73      return;
     74    }
     75 
     76    notificationListener(event.detail.event, event.detail.params);
     77  }
     78 
     79  Mozilla.UITour.DEFAULT_THEME_CYCLE_DELAY = 10 * 1000;
     80 
     81  Mozilla.UITour.CONFIGNAME_SYNC = "sync";
     82  Mozilla.UITour.CONFIGNAME_AVAILABLETARGETS = "availableTargets";
     83 
     84  /**
     85   * @typedef {string} Mozilla.UITour.Target
     86   *
     87   * @summary Not all targets are available at all times because they may not be visible
     88   * or UITour doesn't not how to automatically make them visible. Use the
     89   * following to determine which ones are available at a given time::
     90   *
     91   * .. code-block:: javascript
     92   *
     93   *    Mozilla.UITour.getConfiguration('availableTargets', callback)
     94   *
     95   * @see Mozilla.UITour.getConfiguration
     96   * @see Mozilla.UITour.showHighlight
     97   * @see Mozilla.UITour.showInfo
     98   *
     99   * @description Valid values:
    100   *
    101   * - accountStatus
    102   * - addons
    103   * - appMenu
    104   * - backForward
    105   * - bookmarks
    106   * - forget
    107   * - help
    108   * - home
    109   * - logins
    110   * - pageAction-bookmark
    111   * - pocket
    112   * - privateWindow
    113   * - quit
    114   * - readerMode-urlBar
    115   * - search
    116   * - searchIcon
    117   * - selectedTabIcon
    118   * - urlbar
    119   *
    120   * Generate using the following in the Browser Console:
    121   *
    122   * .. code-block:: javascript
    123   *
    124   *    [...UITour.targets.keys()].join("\n* - ")
    125   */
    126 
    127  /**
    128   * Ensure the browser is ready to handle this document as a tour.
    129   *
    130   * @param {Function} [callback] Callback to call if UITour is working for the document.
    131   * @since 35
    132   */
    133  Mozilla.UITour.ping = function (callback) {
    134    var data = {};
    135    if (callback) {
    136      data.callbackID = _waitForCallback(callback);
    137    }
    138    _sendEvent("ping", data);
    139  };
    140 
    141  /**
    142   * @summary Register a listener to observe all UITour notifications.
    143   *
    144   * @description There can only be one observer per tour tab so calling this a second time will
    145   * replace any previous `listener`.
    146   * To remove an observer, call the method with `null` as the first argument.
    147   *
    148   * @param {?Function} listener - Called when any UITour notification occurs.
    149   * @param {Function} [callback] - Called when the browser acknowledges the observer.
    150   */
    151  Mozilla.UITour.observe = function (listener, callback) {
    152    notificationListener = listener;
    153 
    154    if (listener) {
    155      document.addEventListener("mozUITourNotification", _notificationListener);
    156      Mozilla.UITour.ping(callback);
    157    } else {
    158      document.removeEventListener(
    159        "mozUITourNotification",
    160        _notificationListener
    161      );
    162    }
    163  };
    164 
    165  /**
    166   * Register an identifier to use in
    167   * `Telemetry <https://wiki.mozilla.org/Telemetry>`_. `pageID` must be a
    168   * string unique to the page/tour.
    169   *
    170   * @example
    171   * Mozilla.UITour.registerPageID('firstrun-page-firefox-29');
    172   *
    173   * @param {string} pageID Unique identifier for the page/tour.
    174   * @memberof Mozilla.UITour
    175   */
    176  Mozilla.UITour.registerPageID = function (pageID) {
    177    _sendEvent("registerPageID", {
    178      pageID,
    179    });
    180  };
    181 
    182  /**
    183   * @typedef {string} Mozilla.UITour.HighlightEffect
    184   *
    185   * Specifies the effect/animation to use when highlighting UI elements.
    186   * @description Valid values:
    187   *
    188   * - random
    189   * - wobble
    190   * - zoom
    191   * - color
    192   *
    193   * Generate using the following in the Browser Console:
    194   *
    195   * .. code-block:: javascript
    196   *
    197   *    [...UITour.highlightEffects].join("\n* - ")
    198   *
    199   * @see Mozilla.UITour.showHighlight
    200   */
    201 
    202  /**
    203   * Visually highlight a UI widget.
    204   *
    205   * @see Mozilla.UITour.hideHighlight
    206   * @example Mozilla.UITour.showHighlight('appMenu', 'wobble');
    207   *
    208   * @param {Mozilla.UITour.Target} target - Identifier of the UI widget to show a highlight on.
    209   * @param {Mozilla.UITour.HighlightEffect} [effect="none"] - Name of the effect to use when highlighting.
    210   */
    211  Mozilla.UITour.showHighlight = function (target, effect) {
    212    _sendEvent("showHighlight", {
    213      target,
    214      effect,
    215    });
    216  };
    217 
    218  /**
    219   * Hide any visible UI highlight.
    220   *
    221   * @see Mozilla.UITour.showHighlight
    222   */
    223  Mozilla.UITour.hideHighlight = function () {
    224    _sendEvent("hideHighlight");
    225  };
    226 
    227  /**
    228   * Show an arrow panel with optional images and buttons anchored at a specific UI target.
    229   *
    230   * @see Mozilla.UITour.hideInfo
    231   *
    232   * @param {Mozilla.UITour.Target} target - Identifier of the UI widget to anchor the panel at.
    233   * @param {string} title - Title text to be shown as the heading of the panel.
    234   * @param {string} text - Body text of the panel.
    235   * @param {string} [icon=null] - URL of a 48x48px (96px @ 2dppx) image (which will be resolved
    236   *                               relative to the tab's URI) to display in the panel.
    237   * @param {object[]} [buttons=[]] - Array of objects describing buttons.
    238   * @param {string} buttons[].label - Button label
    239   * @param {string} buttons[].icon - Button icon URL
    240   * @param {string} buttons[].style - Button style ("primary" or "link")
    241   * @param {Function} buttons[].callback - Called when the button is clicked
    242   * @param {object} [options={}] - Advanced options
    243   * @param {Function} options.closeButtonCallback - Called when the panel's close button is clicked.
    244   *
    245   * @example
    246   * var buttons = [
    247   *   {
    248   *     label: 'Cancel',
    249   *     style: 'link',
    250   *     callback: cancelBtnCallback
    251   *   },
    252   *   {
    253   *     label: 'Confirm',
    254   *     style: 'primary',
    255   *     callback: confirmBtnCallback
    256   *   }
    257   * ];
    258   *
    259   * var icon = '//mozorg.cdn.mozilla.net/media/img/firefox/australis/logo.png';
    260   *
    261   * var options = {
    262   *   closeButtonCallback: closeBtnCallback
    263   * };
    264   *
    265   * Mozilla.UITour.showInfo('appMenu', 'my title', 'my text', icon, buttons, options);
    266   */
    267  Mozilla.UITour.showInfo = function (
    268    target,
    269    title,
    270    text,
    271    icon,
    272    buttons,
    273    options
    274  ) {
    275    var buttonData = [];
    276    if (Array.isArray(buttons)) {
    277      for (var i = 0; i < buttons.length; i++) {
    278        buttonData.push({
    279          label: buttons[i].label,
    280          icon: buttons[i].icon,
    281          style: buttons[i].style,
    282          callbackID: _waitForCallback(buttons[i].callback),
    283        });
    284      }
    285    }
    286 
    287    var closeButtonCallbackID, targetCallbackID;
    288    if (options && options.closeButtonCallback) {
    289      closeButtonCallbackID = _waitForCallback(options.closeButtonCallback);
    290    }
    291    if (options && options.targetCallback) {
    292      targetCallbackID = _waitForCallback(options.targetCallback);
    293    }
    294 
    295    _sendEvent("showInfo", {
    296      target,
    297      title,
    298      text,
    299      icon,
    300      buttons: buttonData,
    301      closeButtonCallbackID,
    302      targetCallbackID,
    303    });
    304  };
    305 
    306  /**
    307   * Hide any visible info panels.
    308   *
    309   * @see Mozilla.UITour.showInfo
    310   */
    311  Mozilla.UITour.hideInfo = function () {
    312    _sendEvent("hideInfo");
    313  };
    314 
    315  /**
    316   * @typedef {string} Mozilla.UITour.MenuName
    317   * Valid values:
    318   *
    319   * - appMenu
    320   * - bookmarks
    321   * - pocket
    322   *
    323   * @see Mozilla.UITour.showMenu
    324   * @see Mozilla.UITour.hideMenu
    325   */
    326 
    327  /**
    328   * Open the named application menu.
    329   *
    330   * @see Mozilla.UITour.hideMenu
    331   *
    332   * @param {Mozilla.UITour.MenuName} name - Menu name
    333   * @param {Function} [callback] - Callback to be called with no arguments when
    334   *                                the menu opens.
    335   *
    336   * @example
    337   * Mozilla.UITour.showMenu('appMenu', function() {
    338   *   console.log('menu was opened');
    339   * });
    340   */
    341  Mozilla.UITour.showMenu = function (name, callback) {
    342    var showCallbackID;
    343    if (callback) {
    344      showCallbackID = _waitForCallback(callback);
    345    }
    346 
    347    _sendEvent("showMenu", {
    348      name,
    349      showCallbackID,
    350    });
    351  };
    352 
    353  /**
    354   * Close the named application menu.
    355   *
    356   * @see Mozilla.UITour.showMenu
    357   *
    358   * @param {Mozilla.UITour.MenuName} name - Menu name
    359   */
    360  Mozilla.UITour.hideMenu = function (name) {
    361    _sendEvent("hideMenu", {
    362      name,
    363    });
    364  };
    365 
    366  /**
    367   * Loads about:newtab in the tour tab.
    368   *
    369   * @since 51
    370   */
    371  Mozilla.UITour.showNewTab = function () {
    372    _sendEvent("showNewTab");
    373  };
    374 
    375  /**
    376   * Loads about:protections in the tour tab.
    377   *
    378   * @since 70
    379   */
    380  Mozilla.UITour.showProtectionReport = function () {
    381    _sendEvent("showProtectionReport");
    382  };
    383 
    384  /**
    385   * @typedef Mozilla.UITour.ConfigurationName
    386   * @description Valid values:
    387   *
    388   * - :js:func:`appinfo <Mozilla.UITour.Configuration.AppInfo>`
    389   * - :js:func:`canReset <Mozilla.UITour.Configuration.CanReset>`
    390   * - :js:func:`availableTargets <Mozilla.UITour.Configuration.AvailableTargets>`
    391   * - :js:func:`search <Mozilla.UITour.Configuration.Search>`
    392   * - :js:func:`selectedSearchEngine <Mozilla.UITour.Configuration.Search>`
    393   *   DEPRECATED, use 'search'
    394   * - :js:func:`sync <Mozilla.UITour.Configuration.Sync>`
    395   *   DEPRECATED, use 'fxa'
    396   * - :js:func:`fxa <Mozilla.UITour.Configuration.FxA>`
    397   * - :js:func:`fxaConnections <Mozilla.UITour.Configuration.FxAConnections>`
    398   */
    399 
    400  /**
    401   * @namespace Mozilla.UITour.Configuration
    402   * @see Mozilla.UITour.getConfiguration
    403   * @see Mozilla.UITour.ConfigurationName
    404   */
    405 
    406  /**
    407   * @typedef {boolean} Mozilla.UITour.Configuration.CanReset
    408   *
    409   * @description Indicate whether a user can refresh their Firefox profile via :js:func:`Mozilla.UITour.resetFirefox`.
    410   *
    411   * @see Mozilla.UITour.resetFirefox
    412   * @since 48
    413   */
    414 
    415  /**
    416   * @typedef {object} Mozilla.UITour.Configuration.AppInfo
    417   * @property {boolean} canSetDefaultBrowserInBackground - Whether the application can be set as
    418   *                                                        the default browser in the background
    419   *                                                        without user interaction.
    420   * @property {boolean} defaultBrowser - Whether the application is the default browser. Since Fx40.
    421   * @property {string} defaultUpdateChannel - Update channel e.g. 'release', 'beta', 'aurora',
    422   *                                           'nightly', 'default'
    423   *                                           (self-built or automated testing builds)
    424   * @property {string} distribution - Contains the distributionId property. This value will be
    425   *                                   "default" in most cases but can differ for repack or
    426   *                                   funnelcake builds. Since Fx48
    427   * @property {number} profileCreatedWeeksAgo - The number of weeks since the profile was created,
    428   *                                             starting from 0 for profiles dating less than
    429   *                                             seven days old. Since Fx56.
    430   * @property {number} profileResetWeeksAgo - The number of weeks since the profile was last reset,
    431   *                                           starting from 0 for profiles reset less than seven
    432   *                                           days ago. If the profile has never been reset it
    433   *                                           returns null. Since Fx56.
    434   * @property {string} version - Version string e.g. "48.0a2"
    435   * @since 35
    436   */
    437 
    438  /**
    439   * @summary Search service configuration.
    440   *
    441   * @description From version 34 through 42 inclusive, a string was returned for the 'selectedSearchEngine'
    442   * configuration instead of the object like 'search'.
    443   *
    444   * @typedef {string | object} Mozilla.UITour.Configuration.Search
    445   * @property {string} searchEngineIdentifier - The default engine's identifier
    446   * @property {string[]} engines - Identifiers of visible engines
    447   * @since 43
    448   */
    449 
    450  /**
    451   * Sync status and device counts.
    452   *
    453   * @typedef {object} Mozilla.UITour.Configuration.Sync
    454   * @property {boolean} setup - Whether sync is setup
    455   * @property {number} desktopDevices - Number of desktop devices
    456   * @property {number} mobileDevices - Number of mobile devices
    457   * @property {number} totalDevices - Total number of connected devices
    458   * @since 50
    459   */
    460 
    461  /**
    462   * FxA local status, including whether FxA is connected and the general
    463   * account state.
    464   *
    465   * @typedef {object} Mozilla.UITour.Configuration.FxA
    466   * @property {boolean} setup - Whether FxA is setup on this device. If false,
    467   *    no other properties will exist.
    468   * @property {boolean} accountStateOK - Whether the FxA account state is OK.
    469   *    If false, it probably means the account is unverified or the user has
    470   *    changed their password on another device and needs to update it here.
    471   *    In that case many other properties will not exist.
    472   * @property {Mozilla.UITour.Configuration.BrowserServices} [browserServices] -
    473   *    Information about account services attached to this browser, and with
    474   *    special support implemented by this browser. You should not expect
    475   *    every accountService connected in this browser to get a special entry
    476   *    here. Indeed, what services, and in what circumstances they may appear
    477   *    here in the future is largely TBD.
    478   * @since 71
    479   */
    480 
    481  /**
    482   * FxA connections status - information about the account which typically
    483   * isn't stored locally, so needs to be obtained from the FxA servers. As such,
    484   * requesting this information is likely to be high-latency and may return
    485   * incomplete data if there is a network or server error.
    486   *
    487   * @typedef {object} Mozilla.UITour.Configuration.FxAConnections
    488   * @property {boolean} setup - Whether FxA is setup on this device. If false,
    489   *    no other properties will exist.
    490   * @property {number} [numOtherDevices] - Number of devices connected to this
    491   *    account, not counting this device.
    492   * @property {Record<string, number>} [numDevicesByType] - A count of devices
    493   *    connected to the account by device 'type'. Valid values for type are
    494   *    defined by the FxA server but roughly correspond to form-factor with
    495   *    values like 'desktop', 'mobile', 'vr', etc.
    496   * @property {Mozilla.UITour.Configuration.AccountServices} [accountServices] -
    497   *    Information about services attached to this account. These services
    498   *    may be enabled on devices or applications external to this
    499   *    browser and should not be confused with devices. For example, if the user
    500   *    has enabled Monitor or Lockwise on one or more devices - including on
    501   *    this device - that service will have a single entry here.
    502   * @since 73
    503   */
    504 
    505  /**
    506   * Information about clients attached to the account.
    507   * An object. The key is a string ID of the attached service. A list of attached
    508   * service IDs can be found
    509   * `on our telemetry documentation site <https://docs.telemetry.mozilla.org/datasets/fxa_metrics/attribution.html#service-attribution>`_.
    510   * The value is a :js:func:`Mozilla.UITour.Configuration.AccountService`
    511   *
    512   * @typedef {Record<string, Mozilla.UITour.Configuration.AccountService>} Mozilla.UITour.Configuration.AccountServices
    513   * @since 71
    514   */
    515 
    516  /**
    517   * Information about an account service
    518   *
    519   * @typedef {object} Mozilla.UITour.Configuration.AccountService
    520   * @property {string} id - The service ID. A list of attached
    521   * service IDs can be found
    522   * `on our telemetry documentation site <https://docs.telemetry.mozilla.org/datasets/fxa_metrics/attribution.html#service-attribution>`_.
    523   * @property {number} lastAccessedWeeksAgo - How many weeks ago the service
    524   *    was accessed by this account.
    525   * @since 71
    526   */
    527 
    528  /**
    529   * Information about a services attached to the browser. All properties are
    530   * optional and only exist if the service is enabled.
    531   *
    532   * @typedef {object} Mozilla.UITour.Configuration.BrowserServices
    533   * @property {Mozilla.UITour.Configuration.Sync} sync - If sync is configured
    534   * @since 71
    535   */
    536 
    537  /**
    538   * Array of UI :js:func:`Targets <Mozilla.UITour.Target>` currently available to be annotated.
    539   *
    540   * @typedef {Mozilla.UITour.Target[]} Mozilla.UITour.Configuration.AvailableTargets
    541   */
    542 
    543  /**
    544   * Retrieve some information about the application/profile.
    545   *
    546   * @param {Mozilla.UITour.ConfigurationName} configName - Name of configuration to retrieve
    547   * @param {Function} callback - Called with one argument containing the value of the configuration.
    548   */
    549  Mozilla.UITour.getConfiguration = function (configName, callback) {
    550    _sendEvent("getConfiguration", {
    551      callbackID: _waitForCallback(callback),
    552      configuration: configName,
    553    });
    554  };
    555 
    556  /**
    557   * Set some value or take some action.
    558   *
    559   * Valid configuration names:
    560   *
    561   * defaultBrowser
    562   *   Try to set the application as the default web browser. Since Fx40
    563   *
    564   * @param {string} configName - Configuration name to set (e.g. "defaultBrowser")
    565   * @param {string | number | boolean} [configValue] - Not currently used
    566   *
    567   * @since 40
    568   * @example
    569   * Mozilla.UITour.setConfiguration('defaultBrowser');
    570   */
    571  Mozilla.UITour.setConfiguration = function (configName, configValue) {
    572    _sendEvent("setConfiguration", {
    573      configuration: configName,
    574      value: configValue,
    575    });
    576  };
    577 
    578  /**
    579   * Request the browser open the Firefox Accounts page.
    580   *
    581   * @param {object} extraURLParams - An object containing additional
    582   * parameters for the URL opened by the browser for reasons of promotional
    583   * campaign tracking. Each attribute of the object must have a name that
    584   * is a string, is "flow_id", "flow_begin_time", "device_id" or begins
    585   * with `utm_` and contains only only alphanumeric characters, dashes or
    586   * underscores. The values may be any string and will automatically be encoded.
    587   * For Flow metrics, see details at https://mozilla.github.io/ecosystem-platform/docs/fxa-engineering/fxa-metrics#content-server
    588   * @param {string} entrypoint - A string containing the entrypoint name.
    589   * @param {string} email - A string containing the default email account
    590   * for the URL opened by the browser.
    591   * @since 31, 47 for `extraURLParams`
    592   * @since 79 for "flow_id", "flow_begin_time", "device_id", "entrypoint_experiment",
    593   * "entrypoint", "entrypoint_variation" fields.
    594   * @example
    595   * // Will open https://accounts.firefox.com/signup?entrypoint=uitour
    596   * Mozilla.UITour.showFirefoxAccounts();
    597   * @example
    598   * // Will open:
    599   * // https://accounts.firefox.com/signup?entrypoint=uitour&utm_foo=bar&utm_bar=baz
    600   * Mozilla.UITour.showFirefoxAccounts({
    601   *   'utm_foo': 'bar',
    602   *   'utm_bar': 'baz'
    603   * });
    604   * @example
    605   * // Will open:
    606   * // https://accounts.firefox.com/?action=email&email=foo%40bar.com&entrypoint=uitour
    607   * Mozilla.UITour.showFirefoxAccounts(null, null, "foo@bar.com");
    608   * @example
    609   * // Will open:
    610   * // https://accounts.firefox.com/signup?entrypoint=sample
    611   * Mozilla.UITour.showFirefoxAccounts(null, "sample");
    612   * @example
    613   * // Will open:
    614   * // https://accounts.firefox.com/?action=email&email=foo%40bar.com&entrypoint=uitour&flow_id=c5b5ad7c4a94462afe4b9a7fbcca263dbd6c8409fb4539449c50c4a52544b2ed&flow_begin_time=1590680755812
    615   * Mozilla.UITour.showFirefoxAccounts({
    616   *   flow_id: 'c5b5ad7c4a94462afe4b9a7fbcca263dbd6c8409fb4539449c50c4a52544b2ed',
    617   *   flow_begin_time: 1590680755812,
    618   *   device_id: '7e450f3337d3479b8582ea1c9bb5ba6c'
    619   * }, "foo@bar.com");
    620   */
    621  Mozilla.UITour.showFirefoxAccounts = function (
    622    extraURLParams,
    623    entrypoint,
    624    email
    625  ) {
    626    _sendEvent("showFirefoxAccounts", {
    627      extraURLParams: JSON.stringify(extraURLParams),
    628      entrypoint,
    629      email,
    630    });
    631  };
    632 
    633  /**
    634   * Request the browser open the "Connect Another Device" Firefox Accounts page.
    635   *
    636   * @param {object} extraURLParams - An object containing additional
    637   * parameters for the URL opened by the browser for reasons of promotional
    638   * campaign tracking. Each attribute of the object must have a name that
    639   * is a string, is "flow_id", "flow_begin_time", "device_id" or begins
    640   * with `utm_` and contains only only alphanumeric characters, dashes or
    641   * underscores. The values may be any string and will automatically be encoded.
    642   * For Flow metrics, see details at https://mozilla.github.io/ecosystem-platform/docs/fxa-engineering/fxa-metrics#content-server
    643   * @since 59
    644   * @example
    645   * // Will open https://accounts.firefox.com/connect_another_device?entrypoint=uitour
    646   * Mozilla.UITour.showConnectAnotherDevice();
    647   * @example
    648   * // Will open:
    649   * // https://accounts.firefox.com/connect_another_device?entrypoint=uitour&utm_foo=bar&utm_bar=baz
    650   * Mozilla.UITour.showConnectAnotherDevice({
    651   *   'utm_foo': 'bar',
    652   *   'utm_bar': 'baz'
    653   * });
    654   */
    655  Mozilla.UITour.showConnectAnotherDevice = function (extraURLParams) {
    656    _sendEvent("showConnectAnotherDevice", {
    657      extraURLParams: JSON.stringify(extraURLParams),
    658    });
    659  };
    660 
    661  /**
    662   * Show a profile refresh/reset dialog, allowing users to choose to reomve
    663   * add-ons and customizations as well as restore browser defaults, if possible.
    664   * `getConfiguration('canReset')` should first be used to determine whether
    665   * Refresh/Reset is possible for the user's build/profile.
    666   *
    667   * @since 48
    668   * @see Mozilla.UITour.Configuration.CanReset
    669   */
    670  Mozilla.UITour.resetFirefox = function () {
    671    _sendEvent("resetFirefox");
    672  };
    673 
    674  /**
    675   * Add the specified customizable widget to the navigation toolbar.
    676   *
    677   * @param {Mozilla.UITour.Target} name - Identifier of the customizable widget.
    678   * @param {Function} callback - Called with no arguments once the icon was successfully added to
    679   *                              the toolbar. Not called if it doesn't succeed.
    680   * @since 33.1
    681   * @example
    682   * Mozilla.UITour.addNavBarWidget('forget', function () {
    683   *   console.log('forget button added to toolbar');
    684   * });
    685   */
    686  Mozilla.UITour.addNavBarWidget = function (name, callback) {
    687    _sendEvent("addNavBarWidget", {
    688      name,
    689      callbackID: _waitForCallback(callback),
    690    });
    691  };
    692 
    693  /**
    694   * Set the specified search engine as the user-set default.
    695   *
    696   * See https://searchfox.org/mozilla-release/source/browser/locales/search/list.json
    697   *
    698   * @param {string} identifier - Identifier of the engine (e.g. 'yahoo').
    699   * @see Mozilla.UITour.Configuration.Search
    700   * @since 34
    701   */
    702  Mozilla.UITour.setDefaultSearchEngine = function (identifier) {
    703    _sendEvent("setDefaultSearchEngine", {
    704      identifier,
    705    });
    706  };
    707 
    708  /**
    709   * Sets a key+value pair as a treatment tag for recording in FHR.
    710   *
    711   * @param {string} name - tag name for the treatment
    712   * @param {string} value - tag value for the treatment
    713   * @since 34
    714   * @see Mozilla.UITour.getTreatmentTag
    715   * @example
    716   * Mozilla.UITour.setTreatmentTag('srch-chg-action', 'Switch');
    717   */
    718  Mozilla.UITour.setTreatmentTag = function (name, value) {
    719    _sendEvent("setTreatmentTag", {
    720      name,
    721      value,
    722    });
    723  };
    724 
    725  /**
    726   * Retrieved the value for a set FHR treatment tag.
    727   *
    728   * @param {string} name - Tag name to be retrieved
    729   * @param {Function} callback - Called once the data has been retrieved
    730   * @since 34
    731   * @see Mozilla.UITour.setTreatmentTag
    732   * @example
    733   * Mozilla.UITour.getTreatmentTag('srch-chg-action', function(value) {
    734   *   console.log(value);
    735   * });
    736   */
    737  Mozilla.UITour.getTreatmentTag = function (name, callback) {
    738    _sendEvent("getTreatmentTag", {
    739      name,
    740      callbackID: _waitForCallback(callback),
    741    });
    742  };
    743 
    744  /**
    745   * Set the search term in the search box.
    746   *
    747   * This should have been implemented via `setConfiguration("searchTerm", …)`.
    748   *
    749   * @param {string} term - Search string e.g. 'Firefox'
    750   * @since 34
    751   */
    752  Mozilla.UITour.setSearchTerm = function (term) {
    753    _sendEvent("setSearchTerm", {
    754      term,
    755    });
    756  };
    757 
    758  /**
    759   * @summary Force the reader mode icon to appear in the address bar regardless of whether
    760   * heuristics determine it's appropriate.
    761   *
    762   * @description This is useful if you want to target an annotation (panel/highlight) on it
    763   * but the tour page doesn't have much textual content.
    764   */
    765  Mozilla.UITour.forceShowReaderIcon = function () {
    766    _sendEvent("forceShowReaderIcon");
    767  };
    768 
    769  /**
    770   * Toggle into reader mode for the current tab. Once the user enters reader
    771   * mode, the UITour document will not be active and therefore cannot call other
    772   * UITour APIs.
    773   */
    774  Mozilla.UITour.toggleReaderMode = function () {
    775    _sendEvent("toggleReaderMode");
    776  };
    777 
    778  /**
    779   * @param {string} pane - Pane to open/switch the preferences to.
    780   * Valid values match fragments on about:preferences and are subject to change e.g.:
    781   *
    782   * For the Preferences:
    783   *
    784   * - general
    785   * - applications
    786   * - sync
    787   * - privacy
    788   * - advanced
    789   *
    790   * To open to the options of sending telemetry, health report, crash reports,
    791   * that is, the privacy pane > reports on the preferences.
    792   * Please call `Mozilla.UITour.openPreferences("privacy-reports")`.
    793   * UITour would do route mapping automatically.
    794   *
    795   * @since 42
    796   */
    797  Mozilla.UITour.openPreferences = function (pane) {
    798    _sendEvent("openPreferences", {
    799      pane,
    800    });
    801  };
    802 
    803  /**
    804   * @summary Closes the tab where this code is running. As usual, if the tab is in the
    805   * foreground, the tab that was displayed before is selected.
    806   *
    807   * @description The last tab in the current window will never be closed, in which case
    808   * this call will have no effect. The calling code is expected to take an
    809   * action after a small timeout in order to handle this case, for example by
    810   * displaying a goodbye message or a button to restart the tour.
    811   * @since 46
    812   */
    813  Mozilla.UITour.closeTab = function () {
    814    _sendEvent("closeTab");
    815  };
    816 })();
    817 
    818 // Make this library Require-able.
    819 /* eslint-env commonjs */
    820 if (typeof module !== "undefined" && module.exports) {
    821  module.exports = Mozilla.UITour;
    822 }