tor-browser

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

breakableLines.js (3844B)


      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 import {
      6  getBreakableLines,
      7  getSourceActorBreakableLines,
      8  getSourceActorsForSource,
      9 } from "../../selectors/index";
     10 import { setBreakpointPositions } from "../breakpoints/breakpointPositions";
     11 
     12 function calculateBreakableLines(positions) {
     13  const lines = [];
     14  for (const line in positions) {
     15    if (positions[line].length) {
     16      lines.push(Number(line));
     17    }
     18  }
     19 
     20  return lines;
     21 }
     22 
     23 /**
     24 * Ensure that breakable lines for a given source are fetched.
     25 *
     26 * This method is memoized, so that if concurrent calls are dispatched,
     27 * it will return the first async promise processing the breakable lines.
     28 *
     29 * @param Object location
     30 */
     31 export function setBreakableLines(location) {
     32  return async ({ getState, dispatch, client }) => {
     33    if (location.source.isOriginal) {
     34      // Original sources have a dedicated codepath to fetch locations
     35      // from the generated source actor and then map them to "positions"
     36      // in the original source.
     37      let promise = getBreakableLines(getState(), location.source.id);
     38      if (promise) {
     39        return promise;
     40      }
     41      promise = (async () => {
     42        const positions = await dispatch(setBreakpointPositions(location));
     43        return calculateBreakableLines(positions);
     44      })();
     45      dispatch({
     46        type: "SET_ORIGINAL_BREAKABLE_LINES",
     47        source: location.source,
     48        promise,
     49      });
     50      const breakableLines = await promise;
     51      dispatch({
     52        type: "SET_ORIGINAL_BREAKABLE_LINES",
     53        source: location.source,
     54        breakableLines,
     55      });
     56    } else if (location.source.isHTML) {
     57      // For a given HTML page, we get a unique Source (for the html page),
     58      // but many Source Actors (one per inline <script> tag and inlined event listeners).
     59      // So that we have to get the breakable lines for each of them.
     60      //
     61      // Whereas, for regular source (with a url), when we have more than one source actor,
     62      // it means that we evaled the source more than once.
     63      const sourceActors = getSourceActorsForSource(
     64        getState(),
     65        location.source.id
     66      );
     67      if (!sourceActors) {
     68        return null;
     69      }
     70      for (const sourceActor of sourceActors) {
     71        let promise = getSourceActorBreakableLines(getState(), sourceActor.id);
     72        if (promise) {
     73          await promise;
     74        } else {
     75          promise = client.getSourceActorBreakableLines(sourceActor);
     76          dispatch({
     77            type: "SET_SOURCE_ACTOR_BREAKABLE_LINES",
     78            sourceActor,
     79            promise,
     80          });
     81          const breakableLines = await promise;
     82          dispatch({
     83            type: "SET_SOURCE_ACTOR_BREAKABLE_LINES",
     84            sourceActor,
     85            breakableLines,
     86          });
     87        }
     88      }
     89    } else {
     90      // Here is the handling of regular non-source-mapped non-html sources.
     91      // We do fetch the breakable position for the specific source actor passed as argument.
     92      // In case there is many source actors for the same URL, it will only affect one instance.
     93      let promise = getSourceActorBreakableLines(
     94        getState(),
     95        location.sourceActor.id
     96      );
     97      if (promise) {
     98        return promise;
     99      }
    100      promise = client.getSourceActorBreakableLines(location.sourceActor);
    101      dispatch({
    102        type: "SET_SOURCE_ACTOR_BREAKABLE_LINES",
    103        sourceActor: location.sourceActor,
    104        promise,
    105      });
    106      const breakableLines = await promise;
    107      dispatch({
    108        type: "SET_SOURCE_ACTOR_BREAKABLE_LINES",
    109        sourceActor: location.sourceActor,
    110        breakableLines,
    111      });
    112    }
    113    return null;
    114  };
    115 }