tor-browser

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

FeatureCalloutMessages.sys.mjs (46524B)


      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 // Eventually, make this a messaging system
      6 // provider instead of adding these message
      7 // into OnboardingMessageProvider.sys.mjs
      8 const PDFJS_PREF = "browser.pdfjs.feature-tour";
      9 // Empty screens are included as placeholders to ensure step
     10 // indicator shows the correct number of total steps in the tour
     11 const ONE_DAY_IN_MS = 24 * 60 * 60 * 1000;
     12 
     13 // Generate a JEXL targeting string based on the `complete` property being true
     14 // in a given Feature Callout tour progress preference value (which is JSON).
     15 const matchIncompleteTargeting = (prefName, defaultValue = false) => {
     16  // regExpMatch() is a JEXL filter expression. Here we check if 'complete'
     17  // exists in the pref's value, and returns true if the tour is incomplete.
     18  const prefVal = `'${prefName}' | preferenceValue`;
     19  // prefVal might be null if the preference doesn't exist. in this case, don't
     20  // try to pipe into regExpMatch.
     21  const completeMatch = `${prefVal} | regExpMatch('(?<=complete":)(.*)(?=})')`;
     22  return `((${prefVal}) ? ((${completeMatch}) ? (${completeMatch}[1] != "true") : ${String(
     23    defaultValue
     24  )}) : ${String(defaultValue)})`;
     25 };
     26 
     27 // Generate a JEXL targeting string based on the current screen id found in a
     28 // given Feature Callout tour progress preference.
     29 const matchCurrentScreenTargeting = (prefName, screenIdRegEx = ".*") => {
     30  // regExpMatch() is a JEXL filter expression. Here we check if 'screen' exists
     31  // in the pref's value, and if it matches the screenIdRegEx. Returns
     32  // null otherwise.
     33  const prefVal = `'${prefName}' | preferenceValue`;
     34  const screenMatch = `${prefVal} | regExpMatch('(?<=screen"\s*:)\s*"(${screenIdRegEx})(?="\s*,)')`;
     35  const screenValMatches = `(${screenMatch}) ? !!(${screenMatch}[1]) : false`;
     36  return `(${screenValMatches})`;
     37 };
     38 
     39 /**
     40 * add24HourImpressionJEXLTargeting -
     41 * Creates a "hasn't been viewed in > 24 hours"
     42 * JEXL string and adds it to each message specified
     43 *
     44 * @param {Array} messageIds - IDs of messages that the targeting string will be added to
     45 * @param {string} prefix - The prefix of messageIDs that will used to create the JEXL string
     46 * @param {Array} messages - The array of messages that will be edited
     47 * @returns {Array} - The array of messages with the appropriate targeting strings edited
     48 */
     49 function add24HourImpressionJEXLTargeting(
     50  messageIds,
     51  prefix,
     52  uneditedMessages
     53 ) {
     54  let noImpressionsIn24HoursString = uneditedMessages
     55    .filter(message => message.id.startsWith(prefix))
     56    .map(
     57      message =>
     58        // If the last impression is null or if epoch time
     59        // of the impression is < current time - 24hours worth of MS
     60        `(messageImpressions.${message.id}[messageImpressions.${
     61          message.id
     62        } | length - 1] == null || messageImpressions.${
     63          message.id
     64        }[messageImpressions.${message.id} | length - 1] < ${
     65          Date.now() - ONE_DAY_IN_MS
     66        })`
     67    )
     68    .join(" && ");
     69 
     70  // We're appending the string here instead of using
     71  // template strings to avoid a recursion error from
     72  // using the 'messages' variable within itself
     73  return uneditedMessages.map(message => {
     74    if (messageIds.includes(message.id)) {
     75      message.targeting += `&& ${noImpressionsIn24HoursString}`;
     76    }
     77 
     78    return message;
     79  });
     80 }
     81 
     82 // Exporting the about:firefoxview messages as a method here
     83 // acts as a safety guard against mutations of the original objects
     84 const MESSAGES = () => {
     85  let messages = [
     86    {
     87      id: "TAB_GROUP_ONBOARDING_CALLOUT",
     88      template: "feature_callout",
     89      groups: ["cfr"],
     90      content: {
     91        id: "TAB_GROUP_ONBOARDING_CALLOUT",
     92        template: "multistage",
     93        backdrop: "transparent",
     94        transitions: false,
     95        screens: [
     96          {
     97            id: "TAB_GROUP_ONBOARDING_CALLOUT_HORIZONTAL",
     98            anchors: [
     99              {
    100                selector:
    101                  "#tabbrowser-tabs:not([overflow]) .tab-content[selected]:not([pinned])",
    102                panel_position: {
    103                  anchor_attachment: "bottomcenter",
    104                  callout_attachment: "topright",
    105                },
    106              },
    107              {
    108                selector:
    109                  "#tabbrowser-tabs:not([overflow]) tab:not([pinned]):last-of-type",
    110                panel_position: {
    111                  anchor_attachment: "bottomcenter",
    112                  callout_attachment: "topright",
    113                },
    114              },
    115              {
    116                selector:
    117                  "#tabbrowser-tabs:not([overflow]) #tabs-newtab-button",
    118                panel_position: {
    119                  anchor_attachment: "bottomcenter",
    120                  callout_attachment: "topright",
    121                },
    122              },
    123              {
    124                selector: "#tabbrowser-tabs",
    125                panel_position: {
    126                  anchor_attachment: "bottomcenter",
    127                  callout_attachment: "topright",
    128                },
    129              },
    130            ],
    131            content: {
    132              position: "callout",
    133              width: "333px",
    134              padding: 16,
    135              logo: {
    136                imageURL:
    137                  "chrome://browser/content/asrouter/assets/tabgroups/hort-animated-light.svg",
    138                darkModeImageURL:
    139                  "chrome://browser/content/asrouter/assets/tabgroups/hort-animated-dark.svg",
    140                reducedMotionImageURL:
    141                  "chrome://browser/content/asrouter/assets/tabgroups/hort-static-light.svg",
    142                darkModeReducedMotionImageURL:
    143                  "chrome://browser/content/asrouter/assets/tabgroups/hort-static-dark.svg",
    144                height: "172px",
    145                width: "300px",
    146              },
    147              title: {
    148                string_id: "tab-groups-onboarding-feature-callout-title",
    149              },
    150              subtitle: {
    151                string_id: "tab-groups-onboarding-feature-callout-subtitle",
    152              },
    153              dismiss_button: {
    154                action: {
    155                  dismiss: true,
    156                },
    157                background: true,
    158                size: "small",
    159                marginInline: "0 20px",
    160                marginBlock: "20px 0",
    161              },
    162            },
    163          },
    164        ],
    165      },
    166      targeting:
    167        "tabsClosedCount >= 1 && currentTabsOpen >= 8 && ('browser.tabs.groups.enabled' | preferenceValue) && (!'sidebar.verticalTabs' | preferenceValue) && currentTabGroups == 0 && savedTabGroups == 0 && !activeNotifications",
    168      trigger: {
    169        id: "nthTabClosed",
    170      },
    171      frequency: {
    172        lifetime: 1,
    173      },
    174      skip_in_tests: "it's not tested in automation",
    175    },
    176    {
    177      id: "TAB_GROUP_ONBOARDING_CALLOUT",
    178      template: "feature_callout",
    179      groups: ["cfr"],
    180      content: {
    181        id: "TAB_GROUP_ONBOARDING_CALLOUT",
    182        template: "multistage",
    183        backdrop: "transparent",
    184        transitions: false,
    185        screens: [
    186          {
    187            id: "TAB_GROUP_ONBOARDING_CALLOUT_VERTICAL",
    188            anchors: [
    189              {
    190                selector:
    191                  "#tabbrowser-tabs:not([overflow]) .tab-content[selected]:not([pinned])",
    192                panel_position: {
    193                  anchor_attachment: "rightcenter",
    194                  callout_attachment: "topleft",
    195                },
    196              },
    197              {
    198                selector:
    199                  "#tabbrowser-tabs:not([overflow]) tab:not([pinned]):last-of-type",
    200                panel_position: {
    201                  anchor_attachment: "rightcenter",
    202                  callout_attachment: "topleft",
    203                },
    204              },
    205              {
    206                selector:
    207                  "#tabbrowser-tabs:not([overflow]) #tabs-newtab-button",
    208                panel_position: {
    209                  anchor_attachment: "rightcenter",
    210                  callout_attachment: "topleft",
    211                },
    212              },
    213              {
    214                selector: "#tabbrowser-tabs",
    215                panel_position: {
    216                  anchor_attachment: "rightcenter",
    217                  callout_attachment: "topleft",
    218                },
    219              },
    220            ],
    221            content: {
    222              position: "callout",
    223              width: "333px",
    224              padding: 16,
    225              logo: {
    226                imageURL:
    227                  "chrome://browser/content/asrouter/assets/tabgroups/vert-animated-light.svg",
    228                darkModeImageURL:
    229                  "chrome://browser/content/asrouter/assets/tabgroups/vert-animated-dark.svg",
    230                reducedMotionImageURL:
    231                  "chrome://browser/content/asrouter/assets/tabgroups/vert-static-light.svg",
    232                darkModeReducedMotionImageURL:
    233                  "chrome://browser/content/asrouter/assets/tabgroups/vert-static-dark.svg",
    234                height: "172px",
    235                width: "300px",
    236              },
    237              title: {
    238                string_id: "tab-groups-onboarding-feature-callout-title",
    239              },
    240              subtitle: {
    241                string_id: "tab-groups-onboarding-feature-callout-subtitle",
    242              },
    243              dismiss_button: {
    244                action: {
    245                  dismiss: true,
    246                },
    247                background: true,
    248                size: "small",
    249                marginInline: "0 20px",
    250                marginBlock: "20px 0",
    251              },
    252            },
    253          },
    254        ],
    255      },
    256      targeting:
    257        "tabsClosedCount >= 1 && currentTabsOpen >= 8 && ('browser.tabs.groups.enabled' | preferenceValue) && ('sidebar.revamp' | preferenceValue) && ('sidebar.verticalTabs' | preferenceValue) && currentTabGroups == 0 && savedTabGroups == 0 && !activeNotifications",
    258      trigger: {
    259        id: "nthTabClosed",
    260      },
    261      frequency: {
    262        lifetime: 1,
    263      },
    264      skip_in_tests: "it's not tested in automation",
    265    },
    266    // Appears the first time a user uses the "save and close" action on a tab group,
    267    // anchored to the alltabs-button. Will only show if at least an hour has passed
    268    // since the CREATE_TAB_GROUP callout showed.
    269    {
    270      id: "SAVE_TAB_GROUP_ONBOARDING_CALLOUT",
    271      template: "feature_callout",
    272      groups: [],
    273      content: {
    274        id: "SAVE_TAB_GROUP_ONBOARDING_CALLOUT",
    275        template: "multistage",
    276        backdrop: "transparent",
    277        transitions: false,
    278        screens: [
    279          {
    280            id: "SAVE_TAB_GROUP_ONBOARDING_CALLOUT_ALLTABS_BUTTON",
    281            anchors: [
    282              {
    283                selector: "#alltabs-button",
    284                panel_position: {
    285                  anchor_attachment: "bottomcenter",
    286                  callout_attachment: "topright",
    287                },
    288              },
    289            ],
    290            content: {
    291              position: "callout",
    292              padding: 16,
    293              width: "330px",
    294              title_logo: {
    295                imageURL:
    296                  "chrome://browser/content/asrouter/assets/smiling-fox-icon.svg",
    297                width: "24px",
    298                height: "24px",
    299                marginInline: "0 16px",
    300                alignment: "top",
    301              },
    302              title: {
    303                string_id: "tab-groups-onboarding-saved-groups-title-3",
    304              },
    305              primary_button: {
    306                label: {
    307                  string_id: "tab-groups-onboarding-dismiss",
    308                },
    309                action: {
    310                  dismiss: true,
    311                },
    312              },
    313            },
    314          },
    315        ],
    316      },
    317      targeting:
    318        "('browser.tabs.groups.enabled' | preferenceValue) && userPrefs.cfrFeatures && (!messageImpressions.CREATE_TAB_GROUP_ONBOARDING_CALLOUT[messageImpressions.CREATE_TAB_GROUP_ONBOARDING_CALLOUT | length - 1] || messageImpressions.CREATE_TAB_GROUP_ONBOARDING_CALLOUT[messageImpressions.CREATE_TAB_GROUP_ONBOARDING_CALLOUT | length - 1] < currentDate|date - 3600000) && alltabsButtonAreaType != null",
    319      trigger: {
    320        id: "tabGroupSaved",
    321      },
    322      frequency: {
    323        lifetime: 1,
    324      },
    325      skip_in_tests: "it's not tested in automation",
    326    },
    327    // Appears the first time a user uses the "save and close" action on a tab group,
    328    // if the alltabs-button has been removed. Anchored to the urlbar. Will only show
    329    // if CREATE_TAB_GROUP callout has not shown, or at least an hour has passed since
    330    // the CREATE_TAB_GROUP callout showed.
    331    {
    332      id: "SAVE_TAB_GROUP_ONBOARDING_CALLOUT",
    333      template: "feature_callout",
    334      groups: [],
    335      content: {
    336        id: "SAVE_TAB_GROUP_ONBOARDING_CALLOUT",
    337        template: "multistage",
    338        backdrop: "transparent",
    339        transitions: false,
    340        screens: [
    341          {
    342            id: "SAVE_TAB_GROUP_ONBOARDING_CALLOUT_URLBAR",
    343            anchors: [
    344              {
    345                selector: ".urlbar-input-box",
    346                panel_position: {
    347                  anchor_attachment: "bottomcenter",
    348                  callout_attachment: "topcenter",
    349                },
    350              },
    351            ],
    352            content: {
    353              position: "callout",
    354              padding: 16,
    355              width: "330px",
    356              title_logo: {
    357                imageURL:
    358                  "chrome://browser/content/asrouter/assets/smiling-fox-icon.svg",
    359                width: "24px",
    360                height: "24px",
    361                marginInline: "0 16px",
    362                alignment: "top",
    363              },
    364              title: {
    365                string_id:
    366                  "tab-groups-onboarding-saved-groups-no-alltabs-button-title-2",
    367              },
    368              primary_button: {
    369                label: {
    370                  string_id: "tab-groups-onboarding-dismiss",
    371                },
    372                action: {
    373                  dismiss: true,
    374                },
    375              },
    376            },
    377          },
    378        ],
    379      },
    380      targeting:
    381        "('browser.tabs.groups.enabled' | preferenceValue) && userPrefs.cfrFeatures && (!messageImpressions.CREATE_TAB_GROUP_ONBOARDING_CALLOUT[messageImpressions.CREATE_TAB_GROUP_ONBOARDING_CALLOUT | length - 1] || messageImpressions.CREATE_TAB_GROUP_ONBOARDING_CALLOUT[messageImpressions.CREATE_TAB_GROUP_ONBOARDING_CALLOUT | length - 1] < currentDate|date - 3600000) && alltabsButtonAreaType == null",
    382      trigger: {
    383        id: "tabGroupSaved",
    384      },
    385      frequency: {
    386        lifetime: 1,
    387      },
    388      skip_in_tests: "it's not tested in automation",
    389    },
    390    // Appears the first time a user creates a tab group, after clicking the "Done"
    391    // button. Anchored to the alltabs-button. Will only show if the SAVE_TAB_GROUP
    392    // callout has not shown, or if at least an hour has passed
    393    // since the SAVE_TAB_GROUP callout showed.
    394    {
    395      id: "CREATE_TAB_GROUP_ONBOARDING_CALLOUT",
    396      template: "feature_callout",
    397      groups: [],
    398      content: {
    399        id: "CREATE_TAB_GROUP_ONBOARDING_CALLOUT",
    400        template: "multistage",
    401        backdrop: "transparent",
    402        transitions: false,
    403        screens: [
    404          {
    405            id: "CREATE_TAB_GROUP_ONBOARDING_CALLOUT_ALLTABS_BUTTON",
    406            anchors: [
    407              {
    408                selector: "#alltabs-button",
    409                panel_position: {
    410                  anchor_attachment: "bottomcenter",
    411                  callout_attachment: "topright",
    412                },
    413              },
    414            ],
    415            content: {
    416              position: "callout",
    417              padding: 16,
    418              width: "330px",
    419              title_logo: {
    420                imageURL:
    421                  "chrome://browser/content/asrouter/assets/smiling-fox-icon.svg",
    422                width: "24px",
    423                height: "24px",
    424                marginInline: "0 16px",
    425                alignment: "top",
    426              },
    427              title: {
    428                string_id: "tab-groups-onboarding-create-group-title-3",
    429              },
    430              primary_button: {
    431                label: {
    432                  string_id: "tab-groups-onboarding-dismiss",
    433                },
    434                action: {
    435                  dismiss: true,
    436                },
    437              },
    438            },
    439          },
    440        ],
    441      },
    442      targeting:
    443        "('browser.tabs.groups.enabled' | preferenceValue) && userPrefs.cfrFeatures && (!messageImpressions.SAVE_TAB_GROUP_ONBOARDING_CALLOUT[messageImpressions.SAVE_TAB_GROUP_ONBOARDING_CALLOUT | length - 1] || messageImpressions.SAVE_TAB_GROUP_ONBOARDING_CALLOUT[messageImpressions.SAVE_TAB_GROUP_ONBOARDING_CALLOUT | length - 1] < currentDate|date - 3600000) && alltabsButtonAreaType != null",
    444      trigger: {
    445        id: "tabGroupCreated",
    446      },
    447      frequency: {
    448        lifetime: 1,
    449      },
    450      skip_in_tests: "it's not tested in automation",
    451    },
    452    // Appears the first time a user creates a tab group, after clicking the "Done"
    453    // button, if the alltabs-button has been removed. Anchored to the urlbar. Will
    454    // only show if the SAVE_TAB_GROUP callout has not shown, or if at least an hour
    455    // has passed since the SAVE_TAB_GROUP callout showed.
    456    {
    457      id: "CREATE_TAB_GROUP_ONBOARDING_CALLOUT",
    458      template: "feature_callout",
    459      groups: [],
    460      content: {
    461        id: "CREATE_TAB_GROUP_ONBOARDING_CALLOUT",
    462        template: "multistage",
    463        backdrop: "transparent",
    464        transitions: false,
    465        screens: [
    466          {
    467            id: "CREATE_TAB_GROUP_ONBOARDING_CALLOUT_URLBAR",
    468            anchors: [
    469              {
    470                selector: ".urlbar-input-box",
    471                panel_position: {
    472                  anchor_attachment: "bottomcenter",
    473                  callout_attachment: "topcenter",
    474                },
    475              },
    476            ],
    477            content: {
    478              position: "callout",
    479              padding: 16,
    480              width: "330px",
    481              title_logo: {
    482                imageURL:
    483                  "chrome://browser/content/asrouter/assets/smiling-fox-icon.svg",
    484                width: "24px",
    485                height: "24px",
    486                marginInline: "0 16px",
    487                alignment: "top",
    488              },
    489              title: {
    490                string_id:
    491                  "tab-groups-onboarding-create-group-no-alltabs-button-title",
    492              },
    493              primary_button: {
    494                label: {
    495                  string_id: "tab-groups-onboarding-dismiss",
    496                },
    497                action: {
    498                  dismiss: true,
    499                },
    500              },
    501            },
    502          },
    503        ],
    504      },
    505      targeting:
    506        "('browser.tabs.groups.enabled' | preferenceValue) && userPrefs.cfrFeatures && (!messageImpressions.SAVE_TAB_GROUP_ONBOARDING_CALLOUT[messageImpressions.SAVE_TAB_GROUP_ONBOARDING_CALLOUT | length - 1] || messageImpressions.SAVE_TAB_GROUP_ONBOARDING_CALLOUT[messageImpressions.SAVE_TAB_GROUP_ONBOARDING_CALLOUT | length - 1] < currentDate|date - 3600000) && alltabsButtonAreaType == null",
    507      trigger: {
    508        id: "tabGroupCreated",
    509      },
    510      frequency: {
    511        lifetime: 1,
    512      },
    513      skip_in_tests: "it's not tested in automation",
    514    },
    515    // Appears after a browser restart if Session Restore is disabled, to direct
    516    // users to tab groups that were saved automatically. Anchored to the alltabs-button.
    517    {
    518      id: "SESSION_RESTORE_TAB_GROUP_CALLOUT",
    519      template: "feature_callout",
    520      groups: [],
    521      content: {
    522        id: "SESSION_RESTORE_TAB_GROUP_CALLOUT",
    523        template: "multistage",
    524        backdrop: "transparent",
    525        transitions: false,
    526        screens: [
    527          {
    528            id: "SESSION_RESTORE_TAB_GROUP_CALLOUT_ALLTABS_BUTTON",
    529            anchors: [
    530              {
    531                selector: "#alltabs-button",
    532                panel_position: {
    533                  anchor_attachment: "bottomcenter",
    534                  callout_attachment: "topright",
    535                },
    536              },
    537            ],
    538            content: {
    539              position: "callout",
    540              padding: 16,
    541              width: "330px",
    542              title_logo: {
    543                imageURL:
    544                  "chrome://browser/content/asrouter/assets/smiling-fox-icon.svg",
    545                width: "24px",
    546                height: "24px",
    547                marginInline: "0 16px",
    548                alignment: "top",
    549              },
    550              title: {
    551                string_id: "tab-groups-onboarding-session-restore-title-2",
    552              },
    553              primary_button: {
    554                label: {
    555                  string_id: "tab-groups-onboarding-dismiss",
    556                },
    557                action: {
    558                  dismiss: true,
    559                },
    560              },
    561            },
    562          },
    563        ],
    564      },
    565      targeting:
    566        "('browser.tabs.groups.enabled' | preferenceValue) && userPrefs.cfrFeatures && previousSessionEnd && ('browser.startup.page' | preferenceValue != 3) && savedTabGroups >= 1 && alltabsButtonAreaType != null",
    567      trigger: {
    568        id: "defaultBrowserCheck",
    569      },
    570      priority: 2,
    571      frequency: {
    572        lifetime: 1,
    573      },
    574      skip_in_tests: "not tested in automation",
    575    },
    576    // Appears after a browser restart if Session Restore is disabled, to direct
    577    // users to tab groups that were saved automatically, for users who have
    578    // removed the alltabs button. Anchored to the urlbar.
    579    {
    580      id: "SESSION_RESTORE_TAB_GROUP_CALLOUT",
    581      template: "feature_callout",
    582      groups: [],
    583      content: {
    584        id: "SESSION_RESTORE_TAB_GROUP_CALLOUT",
    585        template: "multistage",
    586        backdrop: "transparent",
    587        transitions: false,
    588        screens: [
    589          {
    590            id: "SESSION_RESTORE_TAB_GROUP_CALLOUT_URLBAR",
    591            anchors: [
    592              {
    593                selector: ".urlbar-input-box",
    594                panel_position: {
    595                  anchor_attachment: "bottomcenter",
    596                  callout_attachment: "topcenter",
    597                },
    598              },
    599            ],
    600            content: {
    601              position: "callout",
    602              padding: 16,
    603              width: "330px",
    604              title_logo: {
    605                imageURL:
    606                  "chrome://browser/content/asrouter/assets/smiling-fox-icon.svg",
    607                width: "24px",
    608                height: "24px",
    609                marginInline: "0 16px",
    610                alignment: "top",
    611              },
    612              title: {
    613                string_id:
    614                  "tab-groups-onboarding-saved-groups-no-alltabs-button-title-2",
    615              },
    616              primary_button: {
    617                label: {
    618                  string_id: "tab-groups-onboarding-dismiss",
    619                },
    620                action: {
    621                  dismiss: true,
    622                },
    623              },
    624            },
    625          },
    626        ],
    627      },
    628      targeting:
    629        "('browser.tabs.groups.enabled' | preferenceValue) && userPrefs.cfrFeatures && previousSessionEnd && ('browser.startup.page' | preferenceValue != 3) && savedTabGroups >= 1 && alltabsButtonAreaType == null",
    630      trigger: {
    631        id: "defaultBrowserCheck",
    632      },
    633      priority: 2,
    634      frequency: {
    635        lifetime: 1,
    636      },
    637      skip_in_tests: "not tested in automation",
    638    },
    639    {
    640      id: "ADDONS_STAFF_PICK_PT_2",
    641      template: "feature_callout",
    642      groups: ["cfr"],
    643      content: {
    644        id: "ADDONS_STAFF_PICK_PT_2",
    645        template: "multistage",
    646        backdrop: "transparent",
    647        transitions: false,
    648        screens: [
    649          {
    650            id: "ADDONS_STAFF_PICK_PT_2_A",
    651            anchors: [
    652              {
    653                selector: "#unified-extensions-button",
    654                panel_position: {
    655                  anchor_attachment: "bottomcenter",
    656                  callout_attachment: "topright",
    657                },
    658                arrow_width: "26.9",
    659              },
    660            ],
    661            content: {
    662              position: "callout",
    663              width: "310px",
    664              padding: 16,
    665              title_logo: {
    666                imageURL:
    667                  "chrome://browser/content/asrouter/assets/smiling-fox-icon.svg",
    668                width: "24px",
    669                height: "24px",
    670                marginInline: "4px 14px",
    671              },
    672              title: {
    673                raw: "Give your browsing a boost",
    674                marginInline: "0 48px",
    675              },
    676              subtitle: {
    677                raw: "Make browsing faster, safer, or just plain fun with Firefox add-ons. See what our staff recommends!",
    678                paddingInline: "34px 0",
    679              },
    680              primary_button: {
    681                label: {
    682                  raw: "Explore add-ons",
    683                },
    684                action: {
    685                  dismiss: true,
    686                  type: "OPEN_URL",
    687                  data: {
    688                    args: "https://addons.mozilla.org/en-US/firefox/collections/4757633/36d285535db74c6986abbeeed3e214/?page=1&collection_sort=added",
    689                    where: "tabshifted",
    690                  },
    691                },
    692              },
    693              dismiss_button: {
    694                action: {
    695                  dismiss: true,
    696                },
    697                size: "small",
    698                marginInline: "0 14px",
    699                marginBlock: "14px 0",
    700              },
    701            },
    702          },
    703        ],
    704      },
    705      targeting:
    706        "userPrefs.cfrAddons && userPrefs.cfrFeatures && localeLanguageCode == 'en' && ((currentDate|date - profileAgeCreated|date) / 86400000 < 28) && !screenImpressions.AW_AMO_INTRODUCE && !willShowDefaultPrompt && !activeNotifications && source == 'newtab' && previousSessionEnd",
    707      trigger: {
    708        id: "defaultBrowserCheck",
    709      },
    710      frequency: {
    711        lifetime: 1,
    712      },
    713    },
    714    {
    715      id: "FIREFOX_VIEW_TAB_PICKUP_REMINDER",
    716      template: "feature_callout",
    717      content: {
    718        id: "FIREFOX_VIEW_TAB_PICKUP_REMINDER",
    719        template: "multistage",
    720        backdrop: "transparent",
    721        transitions: false,
    722        disableHistoryUpdates: true,
    723        screens: [
    724          {
    725            id: "FIREFOX_VIEW_TAB_PICKUP_REMINDER",
    726            anchors: [
    727              {
    728                selector: "#tab-pickup-container",
    729                arrow_position: "top",
    730              },
    731            ],
    732            content: {
    733              position: "callout",
    734              title: {
    735                string_id:
    736                  "continuous-onboarding-firefox-view-tab-pickup-title",
    737              },
    738              subtitle: {
    739                string_id:
    740                  "continuous-onboarding-firefox-view-tab-pickup-subtitle",
    741              },
    742              logo: {
    743                imageURL: "chrome://browser/content/callout-tab-pickup.svg",
    744                darkModeImageURL:
    745                  "chrome://browser/content/callout-tab-pickup-dark.svg",
    746                height: "128px",
    747              },
    748              primary_button: {
    749                label: {
    750                  string_id: "mr1-onboarding-get-started-primary-button-label",
    751                },
    752                style: "secondary",
    753                action: {
    754                  type: "CLICK_ELEMENT",
    755                  navigate: true,
    756                  data: {
    757                    selector:
    758                      "#tab-pickup-container button.primary:not(#error-state-button)",
    759                  },
    760                },
    761              },
    762              dismiss_button: {
    763                action: {
    764                  navigate: true,
    765                },
    766              },
    767              page_event_listeners: [
    768                {
    769                  params: {
    770                    type: "toggle",
    771                    selectors: "#tab-pickup-container",
    772                  },
    773                  action: { reposition: true },
    774                },
    775              ],
    776            },
    777          },
    778        ],
    779      },
    780      priority: 2,
    781      targeting: `source == "about:firefoxview" && "browser.firefox-view.view-count" | preferenceValue > 2
    782    && (("identity.fxaccounts.enabled" | preferenceValue == false) || !(("services.sync.engine.tabs" | preferenceValue == true) && ("services.sync.username" | preferenceValue))) && (!messageImpressions.FIREFOX_VIEW_SPOTLIGHT[messageImpressions.FIREFOX_VIEW_SPOTLIGHT | length - 1] || messageImpressions.FIREFOX_VIEW_SPOTLIGHT[messageImpressions.FIREFOX_VIEW_SPOTLIGHT | length - 1] < currentDate|date - ${ONE_DAY_IN_MS})`,
    783      frequency: {
    784        lifetime: 1,
    785      },
    786      trigger: { id: "featureCalloutCheck" },
    787    },
    788    {
    789      id: "PDFJS_FEATURE_TOUR_A",
    790      template: "feature_callout",
    791      content: {
    792        id: "PDFJS_FEATURE_TOUR",
    793        template: "multistage",
    794        backdrop: "transparent",
    795        transitions: false,
    796        disableHistoryUpdates: true,
    797        tour_pref_name: PDFJS_PREF,
    798        screens: [
    799          {
    800            id: "FEATURE_CALLOUT_1_A",
    801            anchors: [
    802              {
    803                selector: "hbox#browser",
    804                arrow_position: "top-end",
    805                absolute_position: { top: "43px", right: "51px" },
    806              },
    807            ],
    808            content: {
    809              position: "callout",
    810              title: {
    811                string_id: "callout-pdfjs-edit-title",
    812              },
    813              subtitle: {
    814                string_id: "callout-pdfjs-edit-body-a",
    815              },
    816              primary_button: {
    817                label: {
    818                  string_id: "callout-pdfjs-edit-button",
    819                },
    820                style: "secondary",
    821                action: {
    822                  type: "SET_PREF",
    823                  data: {
    824                    pref: {
    825                      name: PDFJS_PREF,
    826                      value: JSON.stringify({
    827                        screen: "FEATURE_CALLOUT_2_A",
    828                        complete: false,
    829                      }),
    830                    },
    831                  },
    832                },
    833              },
    834              dismiss_button: {
    835                action: {
    836                  type: "SET_PREF",
    837                  data: {
    838                    pref: {
    839                      name: PDFJS_PREF,
    840                      value: JSON.stringify({
    841                        screen: "",
    842                        complete: true,
    843                      }),
    844                    },
    845                  },
    846                },
    847              },
    848            },
    849          },
    850          {
    851            id: "FEATURE_CALLOUT_2_A",
    852            anchors: [
    853              {
    854                selector: "hbox#browser",
    855                arrow_position: "top-end",
    856                absolute_position: { top: "43px", right: "23px" },
    857              },
    858            ],
    859            content: {
    860              position: "callout",
    861              title: {
    862                string_id: "callout-pdfjs-draw-title",
    863              },
    864              subtitle: {
    865                string_id: "callout-pdfjs-draw-body-a",
    866              },
    867              primary_button: {
    868                label: {
    869                  string_id: "callout-pdfjs-draw-button",
    870                },
    871                style: "secondary",
    872                action: {
    873                  type: "SET_PREF",
    874                  data: {
    875                    pref: {
    876                      name: PDFJS_PREF,
    877                      value: JSON.stringify({
    878                        screen: "",
    879                        complete: true,
    880                      }),
    881                    },
    882                  },
    883                },
    884              },
    885              dismiss_button: {
    886                action: {
    887                  type: "SET_PREF",
    888                  data: {
    889                    pref: {
    890                      name: PDFJS_PREF,
    891                      value: JSON.stringify({
    892                        screen: "",
    893                        complete: true,
    894                      }),
    895                    },
    896                  },
    897                },
    898              },
    899            },
    900          },
    901        ],
    902      },
    903      priority: 1,
    904      targeting: `source == "open" && ${matchCurrentScreenTargeting(
    905        PDFJS_PREF,
    906        "FEATURE_CALLOUT_[0-9]_A"
    907      )} && ${matchIncompleteTargeting(PDFJS_PREF)}`,
    908      trigger: { id: "pdfJsFeatureCalloutCheck" },
    909    },
    910    {
    911      id: "PDFJS_FEATURE_TOUR_B",
    912      template: "feature_callout",
    913      content: {
    914        id: "PDFJS_FEATURE_TOUR",
    915        template: "multistage",
    916        backdrop: "transparent",
    917        transitions: false,
    918        disableHistoryUpdates: true,
    919        tour_pref_name: PDFJS_PREF,
    920        screens: [
    921          {
    922            id: "FEATURE_CALLOUT_1_B",
    923            anchors: [
    924              {
    925                selector: "hbox#browser",
    926                arrow_position: "top-end",
    927                absolute_position: { top: "43px", right: "51px" },
    928              },
    929            ],
    930            content: {
    931              position: "callout",
    932              title: {
    933                string_id: "callout-pdfjs-edit-title",
    934              },
    935              subtitle: {
    936                string_id: "callout-pdfjs-edit-body-b",
    937              },
    938              primary_button: {
    939                label: {
    940                  string_id: "callout-pdfjs-edit-button",
    941                },
    942                style: "secondary",
    943                action: {
    944                  type: "SET_PREF",
    945                  data: {
    946                    pref: {
    947                      name: PDFJS_PREF,
    948                      value: JSON.stringify({
    949                        screen: "FEATURE_CALLOUT_2_B",
    950                        complete: false,
    951                      }),
    952                    },
    953                  },
    954                },
    955              },
    956              dismiss_button: {
    957                action: {
    958                  type: "SET_PREF",
    959                  data: {
    960                    pref: {
    961                      name: PDFJS_PREF,
    962                      value: JSON.stringify({
    963                        screen: "",
    964                        complete: true,
    965                      }),
    966                    },
    967                  },
    968                },
    969              },
    970            },
    971          },
    972          {
    973            id: "FEATURE_CALLOUT_2_B",
    974            anchors: [
    975              {
    976                selector: "hbox#browser",
    977                arrow_position: "top-end",
    978                absolute_position: { top: "43px", right: "23px" },
    979              },
    980            ],
    981            content: {
    982              position: "callout",
    983              title: {
    984                string_id: "callout-pdfjs-draw-title",
    985              },
    986              subtitle: {
    987                string_id: "callout-pdfjs-draw-body-b",
    988              },
    989              primary_button: {
    990                label: {
    991                  string_id: "callout-pdfjs-draw-button",
    992                },
    993                style: "secondary",
    994                action: {
    995                  type: "SET_PREF",
    996                  data: {
    997                    pref: {
    998                      name: PDFJS_PREF,
    999                      value: JSON.stringify({
   1000                        screen: "",
   1001                        complete: true,
   1002                      }),
   1003                    },
   1004                  },
   1005                },
   1006              },
   1007              dismiss_button: {
   1008                action: {
   1009                  type: "SET_PREF",
   1010                  data: {
   1011                    pref: {
   1012                      name: PDFJS_PREF,
   1013                      value: JSON.stringify({
   1014                        screen: "",
   1015                        complete: true,
   1016                      }),
   1017                    },
   1018                  },
   1019                },
   1020              },
   1021            },
   1022          },
   1023        ],
   1024      },
   1025      priority: 1,
   1026      targeting: `source == "open" && ${matchCurrentScreenTargeting(
   1027        PDFJS_PREF,
   1028        "FEATURE_CALLOUT_[0-9]_B"
   1029      )} && ${matchIncompleteTargeting(PDFJS_PREF)}`,
   1030      trigger: { id: "pdfJsFeatureCalloutCheck" },
   1031    },
   1032    // cookie banner reduction onboarding
   1033    {
   1034      id: "CFR_COOKIEBANNER",
   1035      groups: ["cfr"],
   1036      template: "feature_callout",
   1037      content: {
   1038        id: "CFR_COOKIEBANNER",
   1039        template: "multistage",
   1040        backdrop: "transparent",
   1041        transitions: false,
   1042        disableHistoryUpdates: true,
   1043        screens: [
   1044          {
   1045            id: "COOKIEBANNER_CALLOUT",
   1046            anchors: [
   1047              {
   1048                selector: "#tracking-protection-icon-container",
   1049                panel_position: {
   1050                  callout_attachment: "topleft",
   1051                  anchor_attachment: "bottomcenter",
   1052                },
   1053              },
   1054            ],
   1055            content: {
   1056              position: "callout",
   1057              autohide: true,
   1058              title: {
   1059                string_id: "cookie-banner-blocker-onboarding-header",
   1060                paddingInline: "12px 0",
   1061              },
   1062              subtitle: {
   1063                string_id: "cookie-banner-blocker-onboarding-body",
   1064                paddingInline: "34px 0",
   1065              },
   1066              title_logo: {
   1067                alignment: "top",
   1068                height: "20px",
   1069                width: "20px",
   1070                imageURL:
   1071                  "chrome://browser/skin/controlcenter/3rdpartycookies-blocked.svg",
   1072              },
   1073              dismiss_button: {
   1074                size: "small",
   1075                action: { dismiss: true },
   1076              },
   1077              additional_button: {
   1078                label: {
   1079                  string_id: "cookie-banner-blocker-onboarding-learn-more",
   1080                  marginInline: "34px 0",
   1081                },
   1082                style: "link",
   1083                alignment: "start",
   1084                action: {
   1085                  type: "OPEN_URL",
   1086                  data: {
   1087                    args: "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/cookie-banner-reduction",
   1088                    where: "tabshifted",
   1089                  },
   1090                },
   1091              },
   1092            },
   1093          },
   1094        ],
   1095      },
   1096      frequency: {
   1097        lifetime: 1,
   1098      },
   1099      skip_in_tests: "it's not tested in automation",
   1100      trigger: {
   1101        id: "cookieBannerHandled",
   1102      },
   1103      targeting: `'cookiebanners.ui.desktop.enabled'|preferenceValue == true && 'cookiebanners.ui.desktop.showCallout'|preferenceValue == true && 'browser.newtabpage.activity-stream.asrouter.userprefs.cfr.features' | preferenceValue != false`,
   1104    },
   1105    {
   1106      id: "FX_VIEW_DISCOVERABILITY_ALL_USERS",
   1107      template: "feature_callout",
   1108      groups: ["cfr"],
   1109      content: {
   1110        id: "FX_VIEW_DISCOVERABILITY_ALL_USERS",
   1111        template: "multistage",
   1112        backdrop: "transparent",
   1113        transitions: false,
   1114        screens: [
   1115          {
   1116            id: "FX_VIEW_DISCOVERABILITY_ALL_USERS_SCREEN",
   1117            anchors: [
   1118              {
   1119                selector: "#firefox-view-button",
   1120                panel_position: {
   1121                  anchor_attachment: "bottomcenter",
   1122                  callout_attachment: "topleft",
   1123                },
   1124                no_open_on_anchor: true,
   1125                arrow_width: "15.5563",
   1126              },
   1127            ],
   1128            content: {
   1129              position: "callout",
   1130              width: "342px",
   1131              padding: 16,
   1132              page_event_listeners: [
   1133                {
   1134                  params: {
   1135                    type: "click",
   1136                    selectors: "#firefox-view-button",
   1137                  },
   1138                  action: {
   1139                    dismiss: true,
   1140                  },
   1141                },
   1142              ],
   1143              title_logo: {
   1144                imageURL:
   1145                  "chrome://browser/content/asrouter/assets/fox-question-mark-icon.svg",
   1146                width: "25px",
   1147                height: "29px",
   1148                marginInline: "4px 14px",
   1149                alignment: "top",
   1150              },
   1151              title: {
   1152                string_id: "fx-view-discoverability-title",
   1153                marginInline: "0 16px",
   1154              },
   1155              subtitle: {
   1156                string_id: "fx-view-discoverability-subtitle",
   1157                paddingInline: "34px 0",
   1158                marginBlock: "-8px -4px",
   1159              },
   1160              additional_button: {
   1161                label: {
   1162                  string_id: "fx-view-discoverability-secondary-button-label",
   1163                },
   1164                style: "secondary",
   1165                action: {
   1166                  type: "BLOCK_MESSAGE",
   1167                  data: {
   1168                    id: "FX_VIEW_DISCOVERABILITY_ALL_USERS",
   1169                  },
   1170                  dismiss: true,
   1171                },
   1172              },
   1173              secondary_button: {
   1174                label: {
   1175                  string_id: "fx-view-discoverability-primary-button-label",
   1176                },
   1177                style: "primary",
   1178                action: {
   1179                  type: "OPEN_FIREFOX_VIEW",
   1180                  navigate: true,
   1181                },
   1182              },
   1183              submenu_button: {
   1184                submenu: [
   1185                  {
   1186                    type: "action",
   1187                    label: {
   1188                      string_id: "split-dismiss-button-dont-show-option",
   1189                    },
   1190                    action: {
   1191                      type: "BLOCK_MESSAGE",
   1192                      data: {
   1193                        id: "FX_VIEW_DISCOVERABILITY_ALL_USERS",
   1194                      },
   1195                      dismiss: true,
   1196                    },
   1197                    id: "block_recommendation",
   1198                  },
   1199                  {
   1200                    type: "action",
   1201                    label: {
   1202                      string_id: "split-dismiss-button-show-fewer-option",
   1203                    },
   1204                    action: {
   1205                      type: "MULTI_ACTION",
   1206                      dismiss: true,
   1207                      data: {
   1208                        actions: [
   1209                          {
   1210                            type: "SET_PREF",
   1211                            data: {
   1212                              pref: {
   1213                                name: "messaging-system-action.firefox-view-recommendations",
   1214                                value: true,
   1215                              },
   1216                            },
   1217                          },
   1218                          {
   1219                            type: "BLOCK_MESSAGE",
   1220                            data: {
   1221                              id: "FX_VIEW_DISCOVERABILITY_ALL_USERS",
   1222                            },
   1223                          },
   1224                        ],
   1225                      },
   1226                    },
   1227                    id: "show_fewer_recommendations",
   1228                  },
   1229                  {
   1230                    type: "separator",
   1231                  },
   1232                  {
   1233                    type: "action",
   1234                    label: {
   1235                      string_id: "split-dismiss-button-manage-settings-option",
   1236                    },
   1237                    action: {
   1238                      type: "OPEN_ABOUT_PAGE",
   1239                      data: {
   1240                        args: "preferences#general-cfrfeatures",
   1241                        where: "tab",
   1242                      },
   1243                      dismiss: true,
   1244                    },
   1245                    id: "manage_settings",
   1246                  },
   1247                ],
   1248                attached_to: "additional_button",
   1249              },
   1250            },
   1251          },
   1252        ],
   1253      },
   1254      frequency: {
   1255        lifetime: 1,
   1256      },
   1257      skip_in_tests: "it's not tested in automation",
   1258      targeting:
   1259        "!isMajorUpgrade && !willShowDefaultPrompt && !activeNotifications && previousSessionEnd && fxViewButtonAreaType != null && tabsClosedCount >= 5 && (currentDate|date - profileAgeCreated|date) / 86400000 >= 7 && 'browser.newtabpage.activity-stream.asrouter.userprefs.cfr.features' | preferenceValue != false",
   1260      trigger: {
   1261        id: "nthTabClosed",
   1262      },
   1263    },
   1264    {
   1265      id: "NEW_PROFILE_APP_MENU_TOUR",
   1266      groups: [],
   1267      profileScope: "single",
   1268      targeting:
   1269        "'browser.profiles.profile-name.updated' | preferenceValue == true && userPrefs.cfrFeatures",
   1270      trigger: {
   1271        id: "preferenceObserver",
   1272        params: ["browser.profiles.profile-name.updated"],
   1273      },
   1274      frequency: {
   1275        lifetime: 1,
   1276      },
   1277      skip_in_tests: "it's not tested in automation",
   1278      template: "feature_callout",
   1279      content: {
   1280        id: "NEW_PROFILE_APP_MENU_TOUR",
   1281        template: "multistage",
   1282        backdrop: "transparent",
   1283        transitions: false,
   1284        disableHistoryUpdates: true,
   1285        screens: [
   1286          {
   1287            id: "NEW_PROFILE_APP_MENU_TOUR",
   1288            anchors: [
   1289              {
   1290                selector: "#PanelUI-button",
   1291                panel_position: {
   1292                  anchor_attachment: "leftcenter",
   1293                  callout_attachment: "topright",
   1294                },
   1295              },
   1296            ],
   1297            content: {
   1298              position: "callout",
   1299              logo: {
   1300                imageURL:
   1301                  "chrome://browser/content/asrouter/assets/fox-with-profiles.svg",
   1302                height: "100%",
   1303                width: "100%",
   1304              },
   1305              title: {
   1306                string_id: "profiles-appmenu-callout-tour-title",
   1307                paddingBlock: "8px",
   1308              },
   1309              subtitle: {
   1310                string_id: "profiles-appmenu-callout-tour-subtitle",
   1311              },
   1312              dismiss_button: {
   1313                size: "small",
   1314                background: true,
   1315                marginInline: "0 21px",
   1316                marginBlock: "21px 0",
   1317                action: {
   1318                  dismiss: true,
   1319                },
   1320              },
   1321              primary_button: {
   1322                label: {
   1323                  string_id: "profiles-appmenu-callout-tour-primary-button",
   1324                },
   1325                action: {
   1326                  navigate: true,
   1327                  type: "HIGHLIGHT_FEATURE",
   1328                  data: { args: "profilesAppMenuButton" },
   1329                },
   1330              },
   1331            },
   1332          },
   1333        ],
   1334      },
   1335    },
   1336  ];
   1337  messages = add24HourImpressionJEXLTargeting(
   1338    ["FIREFOX_VIEW_TAB_PICKUP_REMINDER"],
   1339    "FIREFOX_VIEW",
   1340    messages
   1341  );
   1342  return messages;
   1343 };
   1344 
   1345 export const FeatureCalloutMessages = {
   1346  getMessages() {
   1347    return MESSAGES();
   1348  },
   1349 };