tor-browser

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

AWScreenUtils.sys.mjs (3067B)


      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 const lazy = {};
      6 
      7 ChromeUtils.defineESModuleGetters(lazy, {
      8  ASRouter: "resource:///modules/asrouter/ASRouter.sys.mjs",
      9  ASRouterTargeting: "resource:///modules/asrouter/ASRouterTargeting.sys.mjs",
     10 });
     11 
     12 export const AWScreenUtils = {
     13  /**
     14   * Filter the given screens in place with a predicate.
     15   *
     16   * @param {object[]} screens - The screens to filter.
     17   * @param {Function} callback - The predicate for filtering the screens.
     18   */
     19  async removeScreens(screens, callback) {
     20    for (let i = 0; i < screens?.length; i++) {
     21      if (await callback(screens[i], i)) {
     22        screens.splice(i--, 1);
     23      }
     24    }
     25  },
     26  /**
     27   * Given a JEXL expression, returns the evaluation of the expression or returns
     28   * true if the expression did not evaluate successfully. This is also used for
     29   * attribute targeting for the checklist feature.
     30   *
     31   * @param {string} targeting - The JEXL expression that will be evaluated
     32   * @returns {boolean}
     33   */
     34  async evaluateScreenTargeting(targeting) {
     35    const result = await lazy.ASRouter.evaluateExpression({
     36      expression: targeting,
     37      context: lazy.ASRouterTargeting.Environment,
     38    });
     39    if (result?.evaluationStatus?.success) {
     40      return result.evaluationStatus.result;
     41    }
     42 
     43    return true;
     44  },
     45  /**
     46   * Returns the string identifier of an unhandled campaign action, if
     47   * applicable otherwise false.
     48   *
     49   * @returns {string|boolean}
     50   */
     51  async getUnhandledCampaignAction() {
     52    const UNHANDLED_CAMPAIGN_ACTION_TARGETING = "unhandledCampaignAction";
     53    let result = await lazy.ASRouter.evaluateExpression({
     54      expression: UNHANDLED_CAMPAIGN_ACTION_TARGETING,
     55      context: lazy.ASRouterTargeting.Environment,
     56    });
     57    return result?.evaluationStatus?.result || false;
     58  },
     59  /**
     60   * Filter out screens whose targeting do not match.
     61   *
     62   * Given an array of screens, each screen will have it's `targeting` property
     63   * evaluated, and removed if it's targeting evaluates to false
     64   *
     65   * @param {object[]} screens - An array of screens that will be looped
     66   * through to be evaluated for removal
     67   * @returns {object[]} - A new array containing the screens that were not removed
     68   */
     69  async evaluateTargetingAndRemoveScreens(screens) {
     70    const filteredScreens = [...screens];
     71    await this.removeScreens(filteredScreens, async screen => {
     72      if (screen.targeting === undefined) {
     73        // Don't remove the screen if we don't have a targeting property
     74        return false;
     75      }
     76 
     77      const result = await this.evaluateScreenTargeting(screen.targeting);
     78      // Flipping the value because a true evaluation means we
     79      // don't want to remove the screen, while false means we do
     80      return !result;
     81    });
     82 
     83    return filteredScreens;
     84  },
     85 
     86  async addScreenImpression(screen) {
     87    await lazy.ASRouter.addScreenImpression(screen);
     88  },
     89 };