tor-browser

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

Actions.mjs (15597B)


      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 // This file is accessed from both content and system scopes.
      6 
      7 export const MAIN_MESSAGE_TYPE = "ActivityStream:Main";
      8 export const CONTENT_MESSAGE_TYPE = "ActivityStream:Content";
      9 export const PRELOAD_MESSAGE_TYPE = "ActivityStream:PreloadedBrowser";
     10 export const UI_CODE = 1;
     11 export const BACKGROUND_PROCESS = 2;
     12 
     13 /**
     14 * globalImportContext - Are we in UI code (i.e. react, a dom) or some kind of background process?
     15 *                       Use this in action creators if you need different logic
     16 *                       for ui/background processes.
     17 */
     18 export const globalImportContext =
     19  typeof Window === "undefined" ? BACKGROUND_PROCESS : UI_CODE;
     20 
     21 // Create an object that avoids accidental differing key/value pairs:
     22 // {
     23 //   INIT: "INIT",
     24 //   UNINIT: "UNINIT"
     25 // }
     26 export const actionTypes = {};
     27 
     28 for (const type of [
     29  "ABOUT_SPONSORED_TOP_SITES",
     30  "ADDONS_INFO_REQUEST",
     31  "ADDONS_INFO_RESPONSE",
     32  "ADS_FEED_UPDATE",
     33  "ADS_INIT",
     34  "ADS_RESET",
     35  "ADS_UPDATE_SPOCS",
     36  "ADS_UPDATE_TILES",
     37  "BLOCK_SECTION",
     38  "BLOCK_URL",
     39  "BOOKMARK_URL",
     40  "CARD_SECTION_IMPRESSION",
     41  "CLEAR_PREF",
     42  "COPY_DOWNLOAD_LINK",
     43  "DELETE_BOOKMARK_BY_ID",
     44  "DELETE_HISTORY_URL",
     45  "DIALOG_CANCEL",
     46  "DIALOG_CLOSE",
     47  "DIALOG_OPEN",
     48  "DISABLE_SEARCH",
     49  "DISCOVERY_STREAM_CONFIG_CHANGE",
     50  "DISCOVERY_STREAM_CONFIG_RESET",
     51  "DISCOVERY_STREAM_CONFIG_RESET_DEFAULTS",
     52  "DISCOVERY_STREAM_CONFIG_SETUP",
     53  "DISCOVERY_STREAM_CONFIG_SET_VALUE",
     54  "DISCOVERY_STREAM_DEV_BLOCKS",
     55  "DISCOVERY_STREAM_DEV_BLOCKS_RESET",
     56  "DISCOVERY_STREAM_DEV_EXPIRE_CACHE",
     57  "DISCOVERY_STREAM_DEV_IDLE_DAILY",
     58  "DISCOVERY_STREAM_DEV_IMPRESSIONS",
     59  "DISCOVERY_STREAM_DEV_SHOW_PLACEHOLDER",
     60  "DISCOVERY_STREAM_DEV_SYNC_RS",
     61  "DISCOVERY_STREAM_DEV_SYSTEM_TICK",
     62  "DISCOVERY_STREAM_EXPERIMENT_DATA",
     63  "DISCOVERY_STREAM_FEEDS_UPDATE",
     64  "DISCOVERY_STREAM_FEED_UPDATE",
     65  "DISCOVERY_STREAM_IMPRESSION_STATS",
     66  "DISCOVERY_STREAM_LAYOUT_RESET",
     67  "DISCOVERY_STREAM_LAYOUT_UPDATE",
     68  "DISCOVERY_STREAM_LINK_BLOCKED",
     69  "DISCOVERY_STREAM_LOADED_CONTENT",
     70  "DISCOVERY_STREAM_PERSONALIZATION_INIT",
     71  "DISCOVERY_STREAM_PERSONALIZATION_LAST_UPDATED",
     72  "DISCOVERY_STREAM_PERSONALIZATION_OVERRIDE",
     73  "DISCOVERY_STREAM_PERSONALIZATION_RESET",
     74  "DISCOVERY_STREAM_PERSONALIZATION_TOGGLE",
     75  "DISCOVERY_STREAM_PERSONALIZATION_UPDATED",
     76  "DISCOVERY_STREAM_PREFS_SETUP",
     77  "DISCOVERY_STREAM_RETRY_FEED",
     78  "DISCOVERY_STREAM_SPOCS_CAPS",
     79  "DISCOVERY_STREAM_SPOCS_ENDPOINT",
     80  "DISCOVERY_STREAM_SPOCS_ONDEMAND_LOAD",
     81  "DISCOVERY_STREAM_SPOCS_ONDEMAND_RESET",
     82  "DISCOVERY_STREAM_SPOCS_ONDEMAND_UPDATE",
     83  "DISCOVERY_STREAM_SPOCS_PLACEMENTS",
     84  "DISCOVERY_STREAM_SPOCS_UPDATE",
     85  "DISCOVERY_STREAM_SPOC_BLOCKED",
     86  "DISCOVERY_STREAM_SPOC_IMPRESSION",
     87  "DISCOVERY_STREAM_SPOC_PLACEHOLDER_DURATION",
     88  "DISCOVERY_STREAM_TOPICS_LOADING",
     89  "DISCOVERY_STREAM_USER_EVENT",
     90  "DOWNLOAD_CHANGED",
     91  "FAKE_FOCUS_SEARCH",
     92  "FILL_SEARCH_TERM",
     93  "FOLLOW_SECTION",
     94  "HANDOFF_SEARCH_TO_AWESOMEBAR",
     95  "HIDE_PERSONALIZE",
     96  "HIDE_TOAST_MESSAGE",
     97  "INFERRED_PERSONALIZATION_MODEL_UPDATE",
     98  "INFERRED_PERSONALIZATION_REFRESH",
     99  "INFERRED_PERSONALIZATION_RESET",
    100  "INFERRED_PERSONALIZATION_UPDATE",
    101  "INIT",
    102  "INLINE_SELECTION_CLICK",
    103  "INLINE_SELECTION_IMPRESSION",
    104  "MESSAGE_BLOCK",
    105  "MESSAGE_CLICK",
    106  "MESSAGE_DISMISS",
    107  "MESSAGE_IMPRESSION",
    108  "MESSAGE_NOTIFY_VISIBILITY",
    109  "MESSAGE_SET",
    110  "MESSAGE_TOGGLE_VISIBILITY",
    111  "NEW_TAB_INIT",
    112  "NEW_TAB_INITIAL_STATE",
    113  "NEW_TAB_LOAD",
    114  "NEW_TAB_REHYDRATED",
    115  "NEW_TAB_STATE_REQUEST",
    116  "NEW_TAB_STATE_REQUEST_STARTUPCACHE",
    117  "NEW_TAB_STATE_REQUEST_WITHOUT_STARTUPCACHE",
    118  "NEW_TAB_UNLOAD",
    119  "OPEN_DOWNLOAD_FILE",
    120  "OPEN_LINK",
    121  "OPEN_NEW_WINDOW",
    122  "OPEN_PRIVATE_WINDOW",
    123  "OPEN_WEBEXT_SETTINGS",
    124  "PARTNER_LINK_ATTRIBUTION",
    125  "PLACES_BOOKMARKS_REMOVED",
    126  "PLACES_BOOKMARK_ADDED",
    127  "PLACES_HISTORY_CLEARED",
    128  "PLACES_LINKS_CHANGED",
    129  "PLACES_LINKS_DELETED",
    130  "PLACES_LINK_BLOCKED",
    131  "POCKET_CTA",
    132  "POCKET_WAITING_FOR_SPOC",
    133  "PREFS_INITIAL_VALUES",
    134  "PREF_CHANGED",
    135  "PREVIEW_REQUEST",
    136  "PREVIEW_REQUEST_CANCEL",
    137  "PREVIEW_RESPONSE",
    138  "PROMO_CARD_CLICK",
    139  "PROMO_CARD_DISMISS",
    140  "PROMO_CARD_IMPRESSION",
    141  "REFRESH_EXTERNAL_COMPONENTS",
    142  "REMOVE_DOWNLOAD_FILE",
    143  "REPORT_AD_OPEN",
    144  "REPORT_AD_SUBMIT",
    145  "REPORT_CLOSE",
    146  "REPORT_CONTENT_OPEN",
    147  "REPORT_CONTENT_SUBMIT",
    148  "RICH_ICON_MISSING",
    149  "SAVE_SESSION_PERF_DATA",
    150  "SCREENSHOT_UPDATED",
    151  "SECTION_DEREGISTER",
    152  "SECTION_DISABLE",
    153  "SECTION_ENABLE",
    154  "SECTION_OPTIONS_CHANGED",
    155  "SECTION_PERSONALIZATION_SET",
    156  "SECTION_PERSONALIZATION_UPDATE",
    157  "SECTION_REGISTER",
    158  "SECTION_UPDATE",
    159  "SECTION_UPDATE_CARD",
    160  "SETTINGS_CLOSE",
    161  "SETTINGS_OPEN",
    162  "SET_PREF",
    163  "SHOW_DOWNLOAD_FILE",
    164  "SHOW_FIREFOX_ACCOUNTS",
    165  "SHOW_PERSONALIZE",
    166  "SHOW_PRIVACY_INFO",
    167  "SHOW_SEARCH",
    168  "SHOW_TOAST_MESSAGE",
    169  "SKIPPED_SIGNIN",
    170  "SOV_UPDATED",
    171  "SUBMIT_EMAIL",
    172  "SUBMIT_SIGNIN",
    173  "SYSTEM_TICK",
    174  "TELEMETRY_IMPRESSION_STATS",
    175  "TELEMETRY_USER_EVENT",
    176  "TOPIC_SELECTION_IMPRESSION",
    177  "TOPIC_SELECTION_MAYBE_LATER",
    178  "TOPIC_SELECTION_SPOTLIGHT_CLOSE",
    179  "TOPIC_SELECTION_SPOTLIGHT_OPEN",
    180  "TOPIC_SELECTION_USER_DISMISS",
    181  "TOPIC_SELECTION_USER_OPEN",
    182  "TOPIC_SELECTION_USER_SAVE",
    183  "TOP_SITES_ADD",
    184  "TOP_SITES_CANCEL_EDIT",
    185  "TOP_SITES_CLOSE_SEARCH_SHORTCUTS_MODAL",
    186  "TOP_SITES_EDIT",
    187  "TOP_SITES_INSERT",
    188  "TOP_SITES_OPEN_SEARCH_SHORTCUTS_MODAL",
    189  "TOP_SITES_ORGANIC_IMPRESSION_STATS",
    190  "TOP_SITES_PIN",
    191  "TOP_SITES_PREFS_UPDATED",
    192  "TOP_SITES_SPONSORED_IMPRESSION_STATS",
    193  "TOP_SITES_UNPIN",
    194  "TOP_SITES_UPDATED",
    195  "TOTAL_BOOKMARKS_REQUEST",
    196  "TOTAL_BOOKMARKS_RESPONSE",
    197  "UNBLOCK_SECTION",
    198  "UNFOLLOW_SECTION",
    199  "UNINIT",
    200  "UPDATE_PINNED_SEARCH_SHORTCUTS",
    201  "UPDATE_SEARCH_SHORTCUTS",
    202  "WALLPAPERS_CATEGORY_SET",
    203  "WALLPAPERS_CUSTOM_SET",
    204  "WALLPAPERS_FEATURE_HIGHLIGHT_COUNTER_INCREMENT",
    205  "WALLPAPERS_FEATURE_HIGHLIGHT_CTA_CLICKED",
    206  "WALLPAPERS_FEATURE_HIGHLIGHT_DISMISSED",
    207  "WALLPAPERS_FEATURE_HIGHLIGHT_SEEN",
    208  "WALLPAPERS_SET",
    209  "WALLPAPER_CATEGORY_CLICK",
    210  "WALLPAPER_CLICK",
    211  "WALLPAPER_REMOVE_UPLOAD",
    212  "WALLPAPER_UPLOAD",
    213  "WEATHER_DETECT_LOCATION",
    214  "WEATHER_IMPRESSION",
    215  "WEATHER_LOAD_ERROR",
    216  "WEATHER_LOCATION_DATA_UPDATE",
    217  "WEATHER_LOCATION_SEARCH_UPDATE",
    218  "WEATHER_LOCATION_SUGGESTIONS_UPDATE",
    219  "WEATHER_OPEN_PROVIDER_URL",
    220  "WEATHER_OPT_IN_PROMPT_SELECTION",
    221  "WEATHER_QUERY_UPDATE",
    222  "WEATHER_SEARCH_ACTIVE",
    223  "WEATHER_UPDATE",
    224  "WEATHER_USER_OPT_IN_LOCATION",
    225  "WEBEXT_CLICK",
    226  "WEBEXT_DISMISS",
    227  "WIDGETS_LISTS_CHANGE_SELECTED",
    228  "WIDGETS_LISTS_SET",
    229  "WIDGETS_LISTS_SET_SELECTED",
    230  "WIDGETS_LISTS_UPDATE",
    231  "WIDGETS_LISTS_USER_EVENT",
    232  "WIDGETS_LISTS_USER_IMPRESSION",
    233  "WIDGETS_TIMER_END",
    234  "WIDGETS_TIMER_PAUSE",
    235  "WIDGETS_TIMER_PLAY",
    236  "WIDGETS_TIMER_RESET",
    237  "WIDGETS_TIMER_SET",
    238  "WIDGETS_TIMER_SET_DURATION",
    239  "WIDGETS_TIMER_SET_TYPE",
    240  "WIDGETS_TIMER_USER_EVENT",
    241  "WIDGETS_TIMER_USER_IMPRESSION",
    242 ]) {
    243  actionTypes[type] = type;
    244 }
    245 
    246 // Helper function for creating routed actions between content and main
    247 // Not intended to be used by consumers
    248 function _RouteMessage(action, options) {
    249  const meta = action.meta ? { ...action.meta } : {};
    250  if (!options || !options.from || !options.to) {
    251    throw new Error(
    252      "Routed Messages must have options as the second parameter, and must at least include a .from and .to property."
    253    );
    254  }
    255  // For each of these fields, if they are passed as an option,
    256  // add them to the action. If they are not defined, remove them.
    257  ["from", "to", "toTarget", "fromTarget", "skipMain", "skipLocal"].forEach(
    258    o => {
    259      if (typeof options[o] !== "undefined") {
    260        meta[o] = options[o];
    261      } else if (meta[o]) {
    262        delete meta[o];
    263      }
    264    }
    265  );
    266  return { ...action, meta };
    267 }
    268 
    269 /**
    270 * AlsoToMain - Creates a message that will be dispatched locally and also sent to the Main process.
    271 *
    272 * @param  {object} action Any redux action (required)
    273 * @param  {object} options
    274 * @param  {bool}   skipLocal Used by OnlyToMain to skip the main reducer
    275 * @param  {string} fromTarget The id of the content port from which the action originated. (optional)
    276 * @return {object} An action with added .meta properties
    277 */
    278 function AlsoToMain(action, fromTarget, skipLocal) {
    279  return _RouteMessage(action, {
    280    from: CONTENT_MESSAGE_TYPE,
    281    to: MAIN_MESSAGE_TYPE,
    282    fromTarget,
    283    skipLocal,
    284  });
    285 }
    286 
    287 /**
    288 * OnlyToMain - Creates a message that will be sent to the Main process and skip the local reducer.
    289 *
    290 * @param  {object} action Any redux action (required)
    291 * @param  {object} options
    292 * @param  {string} fromTarget The id of the content port from which the action originated. (optional)
    293 * @return {object} An action with added .meta properties
    294 */
    295 function OnlyToMain(action, fromTarget) {
    296  return AlsoToMain(action, fromTarget, true);
    297 }
    298 
    299 /**
    300 * BroadcastToContent - Creates a message that will be dispatched to main and sent to ALL content processes.
    301 *
    302 * @param  {object} action Any redux action (required)
    303 * @param  {object} options (optional)
    304 * @return {object} An action with added .meta properties
    305 */
    306 function BroadcastToContent(action, options) {
    307  return _RouteMessage(action, {
    308    from: MAIN_MESSAGE_TYPE,
    309    to: CONTENT_MESSAGE_TYPE,
    310    ...options,
    311  });
    312 }
    313 
    314 /**
    315 * AlsoToOneContent - Creates a message that will be will be dispatched to the main store
    316 *                    and also sent to a particular Content process.
    317 *
    318 * @param  {object} action Any redux action (required)
    319 * @param  {string} target The id of a content port
    320 * @param  {bool} skipMain Used by OnlyToOneContent to skip the main process
    321 * @return {object} An action with added .meta properties
    322 */
    323 function AlsoToOneContent(action, target, skipMain) {
    324  if (!target) {
    325    throw new Error(
    326      "You must provide a target ID as the second parameter of AlsoToOneContent. If you want to send to all content processes, use BroadcastToContent"
    327    );
    328  }
    329  return _RouteMessage(action, {
    330    from: MAIN_MESSAGE_TYPE,
    331    to: CONTENT_MESSAGE_TYPE,
    332    toTarget: target,
    333    skipMain,
    334  });
    335 }
    336 
    337 /**
    338 * OnlyToOneContent - Creates a message that will be sent to a particular Content process
    339 *                    and skip the main reducer.
    340 *
    341 * @param  {object} action Any redux action (required)
    342 * @param  {string} target The id of a content port
    343 * @return {object} An action with added .meta properties
    344 */
    345 function OnlyToOneContent(action, target) {
    346  return AlsoToOneContent(action, target, true);
    347 }
    348 
    349 /**
    350 * AlsoToPreloaded - Creates a message that dispatched to the main reducer and also sent to the preloaded tab.
    351 *
    352 * @param  {object} action Any redux action (required)
    353 * @return {object} An action with added .meta properties
    354 */
    355 function AlsoToPreloaded(action) {
    356  return _RouteMessage(action, {
    357    from: MAIN_MESSAGE_TYPE,
    358    to: PRELOAD_MESSAGE_TYPE,
    359  });
    360 }
    361 
    362 /**
    363 * UserEvent - A telemetry ping indicating a user action. This should only
    364 *                   be sent from the UI during a user session.
    365 *
    366 * @param  {object} data Fields to include in the ping (source, etc.)
    367 * @return {object} An AlsoToMain action
    368 */
    369 function UserEvent(data) {
    370  return AlsoToMain({
    371    type: actionTypes.TELEMETRY_USER_EVENT,
    372    data,
    373  });
    374 }
    375 
    376 /**
    377 * DiscoveryStreamUserEvent - A telemetry ping indicating a user action from Discovery Stream. This should only
    378 *                     be sent from the UI during a user session.
    379 *
    380 * @param  {object} data Fields to include in the ping (source, etc.)
    381 * @return {object} An AlsoToMain action
    382 */
    383 function DiscoveryStreamUserEvent(data) {
    384  return AlsoToMain({
    385    type: actionTypes.DISCOVERY_STREAM_USER_EVENT,
    386    data,
    387  });
    388 }
    389 
    390 /**
    391 * ImpressionStats - A telemetry ping indicating an impression stats.
    392 *
    393 * @param  {object} data Fields to include in the ping
    394 * @param  {int} importContext (For testing) Override the import context for testing.
    395 * #return {object} An action. For UI code, a AlsoToMain action.
    396 */
    397 function ImpressionStats(data, importContext = globalImportContext) {
    398  const action = {
    399    type: actionTypes.TELEMETRY_IMPRESSION_STATS,
    400    data,
    401  };
    402  return importContext === UI_CODE ? AlsoToMain(action) : action;
    403 }
    404 
    405 /**
    406 * DiscoveryStreamImpressionStats - A telemetry ping indicating an impression stats in Discovery Stream.
    407 *
    408 * @param  {object} data Fields to include in the ping
    409 * @param  {int} importContext (For testing) Override the import context for testing.
    410 * #return {object} An action. For UI code, a AlsoToMain action.
    411 */
    412 function DiscoveryStreamImpressionStats(
    413  data,
    414  importContext = globalImportContext
    415 ) {
    416  const action = {
    417    type: actionTypes.DISCOVERY_STREAM_IMPRESSION_STATS,
    418    data,
    419  };
    420  return importContext === UI_CODE ? AlsoToMain(action) : action;
    421 }
    422 
    423 /**
    424 * DiscoveryStreamLoadedContent - A telemetry ping indicating a content gets loaded in Discovery Stream.
    425 *
    426 * @param  {object} data Fields to include in the ping
    427 * @param  {int} importContext (For testing) Override the import context for testing.
    428 * #return {object} An action. For UI code, a AlsoToMain action.
    429 */
    430 function DiscoveryStreamLoadedContent(
    431  data,
    432  importContext = globalImportContext
    433 ) {
    434  const action = {
    435    type: actionTypes.DISCOVERY_STREAM_LOADED_CONTENT,
    436    data,
    437  };
    438  return importContext === UI_CODE ? AlsoToMain(action) : action;
    439 }
    440 
    441 function SetPref(prefName, value, importContext = globalImportContext) {
    442  const action = {
    443    type: actionTypes.SET_PREF,
    444    data: { name: prefName, value },
    445  };
    446  return importContext === UI_CODE ? AlsoToMain(action) : action;
    447 }
    448 
    449 function WebExtEvent(type, data, importContext = globalImportContext) {
    450  if (!data || !data.source) {
    451    throw new Error(
    452      'WebExtEvent actions should include a property "source", the id of the webextension that should receive the event.'
    453    );
    454  }
    455  const action = { type, data };
    456  return importContext === UI_CODE ? AlsoToMain(action) : action;
    457 }
    458 
    459 export const actionCreators = {
    460  BroadcastToContent,
    461  UserEvent,
    462  DiscoveryStreamUserEvent,
    463  ImpressionStats,
    464  AlsoToOneContent,
    465  OnlyToOneContent,
    466  AlsoToMain,
    467  OnlyToMain,
    468  AlsoToPreloaded,
    469  SetPref,
    470  WebExtEvent,
    471  DiscoveryStreamImpressionStats,
    472  DiscoveryStreamLoadedContent,
    473 };
    474 
    475 // These are helpers to test for certain kinds of actions
    476 export const actionUtils = {
    477  isSendToMain(action) {
    478    if (!action.meta) {
    479      return false;
    480    }
    481    return (
    482      action.meta.to === MAIN_MESSAGE_TYPE &&
    483      action.meta.from === CONTENT_MESSAGE_TYPE
    484    );
    485  },
    486  isBroadcastToContent(action) {
    487    if (!action.meta) {
    488      return false;
    489    }
    490    if (action.meta.to === CONTENT_MESSAGE_TYPE && !action.meta.toTarget) {
    491      return true;
    492    }
    493    return false;
    494  },
    495  isSendToOneContent(action) {
    496    if (!action.meta) {
    497      return false;
    498    }
    499    if (action.meta.to === CONTENT_MESSAGE_TYPE && action.meta.toTarget) {
    500      return true;
    501    }
    502    return false;
    503  },
    504  isSendToPreloaded(action) {
    505    if (!action.meta) {
    506      return false;
    507    }
    508    return (
    509      action.meta.to === PRELOAD_MESSAGE_TYPE &&
    510      action.meta.from === MAIN_MESSAGE_TYPE
    511    );
    512  },
    513  isFromMain(action) {
    514    if (!action.meta) {
    515      return false;
    516    }
    517    return (
    518      action.meta.from === MAIN_MESSAGE_TYPE &&
    519      action.meta.to === CONTENT_MESSAGE_TYPE
    520    );
    521  },
    522  getPortIdOfSender(action) {
    523    return (action.meta && action.meta.fromTarget) || null;
    524  },
    525  _RouteMessage,
    526 };