tor-browser

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

pending-breakpoints.js (4107B)


      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 /**
      6 * Pending breakpoints reducer.
      7 *
      8 * Pending breakpoints are a more lightweight version compared to regular breakpoints objects.
      9 * They are meant to be persisted across Firefox restarts and stored into async-storage.
     10 * This reducer data is saved into asyncStore from bootstrap.js and restored from main.js.
     11 *
     12 * The main difference with pending breakpoints is that we only save breakpoints
     13 * against source with an URL as only them can be restored. (source IDs are different across reloads).
     14 * The second difference is that we don't store the whole source object but only the source URL.
     15 */
     16 
     17 import assert from "../utils/assert";
     18 
     19 function update(state = {}, action) {
     20  switch (action.type) {
     21    case "SET_BREAKPOINT":
     22      if (action.status === "start") {
     23        return setBreakpoint(state, action.breakpoint);
     24      }
     25      return state;
     26 
     27    case "REMOVE_BREAKPOINT":
     28      if (action.status === "start") {
     29        return removeBreakpoint(state, action.breakpoint);
     30      }
     31      return state;
     32 
     33    case "REMOVE_PENDING_BREAKPOINT":
     34      return removePendingBreakpoint(state, action.pendingBreakpoint);
     35 
     36    case "CLEAR_BREAKPOINTS": {
     37      return {};
     38    }
     39  }
     40 
     41  return state;
     42 }
     43 
     44 function shouldBreakpointBePersisted(breakpoint) {
     45  // We only save breakpoint for source with URL.
     46  // Source without URL can only be identified via their source actor ID
     47  // which isn't persisted across reloads.
     48  return !breakpoint.options.hidden && breakpoint.location.source.url;
     49 }
     50 
     51 function setBreakpoint(state, breakpoint) {
     52  if (!shouldBreakpointBePersisted(breakpoint)) {
     53    return state;
     54  }
     55 
     56  const id = makeIdFromBreakpoint(breakpoint);
     57  const pendingBreakpoint = createPendingBreakpoint(breakpoint);
     58 
     59  return { ...state, [id]: pendingBreakpoint };
     60 }
     61 
     62 function removeBreakpoint(state, breakpoint) {
     63  if (!shouldBreakpointBePersisted(breakpoint)) {
     64    return state;
     65  }
     66 
     67  const id = makeIdFromBreakpoint(breakpoint);
     68  state = { ...state };
     69 
     70  delete state[id];
     71  return state;
     72 }
     73 
     74 function removePendingBreakpoint(state, pendingBreakpoint) {
     75  const id = makeIdFromPendingBreakpoint(pendingBreakpoint);
     76  state = { ...state };
     77 
     78  delete state[id];
     79  return state;
     80 }
     81 
     82 /**
     83 * Return a unique identifier for a given breakpoint,
     84 * using its original location, or for pretty-printed sources,
     85 * its generated location.
     86 *
     87 * @param {object} breakpoint
     88 */
     89 function makeIdFromBreakpoint(breakpoint) {
     90  const location = breakpoint.location.source.isPrettyPrinted
     91    ? breakpoint.generatedLocation
     92    : breakpoint.location;
     93 
     94  const { source, line, column } = location;
     95  const sourceUrlString = source.url || "";
     96  const columnString = column || "";
     97 
     98  return `${sourceUrlString}:${line}:${columnString}`;
     99 }
    100 
    101 function makeIdFromPendingBreakpoint(pendingBreakpoint) {
    102  const { sourceUrl, line, column } = pendingBreakpoint.location;
    103  const sourceUrlString = sourceUrl || "";
    104  const columnString = column || "";
    105 
    106  return `${sourceUrlString}:${line}:${columnString}`;
    107 }
    108 
    109 /**
    110 * Convert typical debugger frontend location (created via location.js:createLocation)
    111 * to a more lightweight flavor of it which will be stored in async storage.
    112 */
    113 function createPendingLocation(location) {
    114  assert(location.hasOwnProperty("line"), "location must have a line");
    115  assert(location.hasOwnProperty("column"), "location must have a column");
    116 
    117  const { source, line, column } = location;
    118  assert(source.url !== undefined, "pending location must have a source url");
    119  return { sourceUrl: source.url, line, column };
    120 }
    121 
    122 /**
    123 * Create a new pending breakpoint, which is a more lightweight version of the regular breakpoint object.
    124 */
    125 function createPendingBreakpoint(bp) {
    126  return {
    127    options: bp.options,
    128    disabled: bp.disabled,
    129    location: createPendingLocation(bp.location),
    130    generatedLocation: createPendingLocation(bp.generatedLocation),
    131  };
    132 }
    133 
    134 export default update;