tor-browser

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

index.js (11203B)


      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 * Redux actions for breakpoints
      7 *
      8 * @module actions/breakpoints
      9 */
     10 
     11 const {
     12  PROMISE,
     13 } = require("resource://devtools/client/shared/redux/middleware/promise.js");
     14 import { asyncStore } from "../../utils/prefs";
     15 import { createLocation } from "../../utils/location";
     16 import {
     17  getBreakpointsList,
     18  getXHRBreakpoints,
     19  getSelectedSource,
     20  getBreakpointAtLocation,
     21  getBreakpointsForSource,
     22  getBreakpointsAtLine,
     23 } from "../../selectors/index";
     24 import { createXHRBreakpoint } from "../../utils/breakpoint/index";
     25 import {
     26  addBreakpoint,
     27  removeBreakpoint,
     28  enableBreakpoint,
     29  disableBreakpoint,
     30 } from "./modify";
     31 import { getOriginalLocation } from "../../utils/source-maps";
     32 import { setSkipPausing } from "../pause/skipPausing";
     33 
     34 export * from "./breakpointPositions";
     35 export * from "./modify";
     36 export * from "./syncBreakpoint";
     37 
     38 export function addHiddenBreakpoint(location) {
     39  return ({ dispatch }) => {
     40    return dispatch(addBreakpoint(location, { hidden: true }));
     41  };
     42 }
     43 
     44 /**
     45 * Disable all breakpoints in a source
     46 *
     47 * @memberof actions/breakpoints
     48 * @static
     49 */
     50 export function disableBreakpointsInSource(source) {
     51  return async ({ dispatch, getState }) => {
     52    const breakpoints = getBreakpointsForSource(getState(), source);
     53    for (const breakpoint of breakpoints) {
     54      if (!breakpoint.disabled) {
     55        dispatch(disableBreakpoint(breakpoint));
     56      }
     57    }
     58  };
     59 }
     60 
     61 /**
     62 * Enable all breakpoints in a source
     63 *
     64 * @memberof actions/breakpoints
     65 * @static
     66 */
     67 export function enableBreakpointsInSource(source) {
     68  return async ({ dispatch, getState }) => {
     69    const breakpoints = getBreakpointsForSource(getState(), source);
     70    for (const breakpoint of breakpoints) {
     71      if (breakpoint.disabled) {
     72        dispatch(enableBreakpoint(breakpoint));
     73      }
     74    }
     75  };
     76 }
     77 
     78 /**
     79 * Toggle All Breakpoints
     80 *
     81 * @memberof actions/breakpoints
     82 * @static
     83 */
     84 export function toggleAllBreakpoints(shouldDisableBreakpoints) {
     85  return async ({ dispatch, getState }) => {
     86    const breakpoints = getBreakpointsList(getState());
     87 
     88    for (const breakpoint of breakpoints) {
     89      if (shouldDisableBreakpoints) {
     90        dispatch(disableBreakpoint(breakpoint));
     91      } else {
     92        dispatch(enableBreakpoint(breakpoint));
     93      }
     94    }
     95  };
     96 }
     97 
     98 /**
     99 * Toggle Breakpoints
    100 *
    101 * @memberof actions/breakpoints
    102 * @static
    103 */
    104 export function toggleBreakpoints(shouldDisableBreakpoints, breakpoints) {
    105  return async ({ dispatch }) => {
    106    const promises = breakpoints.map(breakpoint =>
    107      shouldDisableBreakpoints
    108        ? dispatch(disableBreakpoint(breakpoint))
    109        : dispatch(enableBreakpoint(breakpoint))
    110    );
    111 
    112    await Promise.all(promises);
    113  };
    114 }
    115 
    116 export function toggleBreakpointsAtLine(shouldDisableBreakpoints, line) {
    117  return async ({ dispatch, getState }) => {
    118    const breakpoints = getBreakpointsAtLine(getState(), line);
    119    return dispatch(toggleBreakpoints(shouldDisableBreakpoints, breakpoints));
    120  };
    121 }
    122 
    123 /**
    124 * Removes all breakpoints
    125 *
    126 * @memberof actions/breakpoints
    127 * @static
    128 */
    129 export function removeAllBreakpoints() {
    130  return async ({ dispatch, getState }) => {
    131    const breakpointList = getBreakpointsList(getState());
    132    await Promise.all(breakpointList.map(bp => dispatch(removeBreakpoint(bp))));
    133    dispatch({ type: "CLEAR_BREAKPOINTS" });
    134  };
    135 }
    136 
    137 /**
    138 * Removes breakpoints
    139 *
    140 * @memberof actions/breakpoints
    141 * @static
    142 */
    143 export function removeBreakpoints(breakpoints) {
    144  return async ({ dispatch }) => {
    145    return Promise.all(breakpoints.map(bp => dispatch(removeBreakpoint(bp))));
    146  };
    147 }
    148 
    149 /**
    150 * Removes all breakpoints in a source
    151 *
    152 * @memberof actions/breakpoints
    153 * @static
    154 */
    155 export function removeBreakpointsInSource(source) {
    156  return async ({ dispatch, getState }) => {
    157    const breakpoints = getBreakpointsForSource(getState(), source);
    158    for (const breakpoint of breakpoints) {
    159      dispatch(removeBreakpoint(breakpoint));
    160    }
    161  };
    162 }
    163 
    164 /**
    165 * Update the original location information of breakpoints.
    166 
    167 /*
    168 * Update breakpoints for a source that just got pretty printed.
    169 * This method maps the breakpoints currently set only against the
    170 * non-pretty-printed (generated) source to the related pretty-printed
    171 * (original) source by querying the SourceMap service.
    172 *
    173 * @param {string} source - the generated source
    174 */
    175 export function updateBreakpointsForNewPrettyPrintedSource(source) {
    176  return async thunkArgs => {
    177    const { dispatch, getState } = thunkArgs;
    178    if (source.isOriginal) {
    179      console.error("Can't update breakpoints on original sources");
    180      return;
    181    }
    182    const breakpoints = getBreakpointsForSource(getState(), source);
    183    // Remap the breakpoints with the original location information from
    184    // the pretty-printed source.
    185    const newBreakpoints = await Promise.all(
    186      breakpoints.map(async breakpoint => {
    187        const location = await getOriginalLocation(
    188          breakpoint.generatedLocation,
    189          thunkArgs
    190        );
    191        return { ...breakpoint, location };
    192      })
    193    );
    194 
    195    // Normally old breakpoints will be clobbered if we re-add them, but when
    196    // remapping we have changed the source maps and the old breakpoints will
    197    // have different locations than the new ones. Manually remove the
    198    // old breakpoints before adding the new ones.
    199    for (const bp of breakpoints) {
    200      dispatch(removeBreakpoint(bp));
    201    }
    202 
    203    for (const bp of newBreakpoints) {
    204      await dispatch(addBreakpoint(bp.location, bp.options, bp.disabled));
    205    }
    206  };
    207 }
    208 
    209 export function toggleBreakpointAtLine(line) {
    210  return async ({ dispatch, getState }) => {
    211    const state = getState();
    212    const selectedSource = getSelectedSource(state);
    213 
    214    if (!selectedSource) {
    215      return null;
    216    }
    217 
    218    const bp = getBreakpointAtLocation(state, { line, column: undefined });
    219    if (bp) {
    220      return dispatch(removeBreakpoint(bp));
    221    }
    222 
    223    // Only if we re-enable a breakpoint, ensure re-enabling breakpoints globally
    224    await dispatch(setSkipPausing(false));
    225 
    226    return dispatch(
    227      addBreakpoint(
    228        createLocation({
    229          source: selectedSource,
    230          line,
    231        })
    232      )
    233    );
    234  };
    235 }
    236 
    237 export function addBreakpointAtLine(line, shouldLog = false, disabled = false) {
    238  return async ({ dispatch, getState }) => {
    239    const state = getState();
    240    const source = getSelectedSource(state);
    241 
    242    if (!source) {
    243      return null;
    244    }
    245    const breakpointLocation = createLocation({
    246      source,
    247      column: undefined,
    248      line,
    249    });
    250 
    251    const options = {};
    252    if (shouldLog) {
    253      options.logValue = "displayName";
    254    }
    255 
    256    // Ensure re-enabling breakpoints globally
    257    await dispatch(setSkipPausing(false));
    258 
    259    return dispatch(addBreakpoint(breakpointLocation, options, disabled));
    260  };
    261 }
    262 
    263 export function removeBreakpointsAtLine(source, line) {
    264  return ({ dispatch, getState }) => {
    265    const breakpointsAtLine = getBreakpointsForSource(getState(), source, line);
    266    return dispatch(removeBreakpoints(breakpointsAtLine));
    267  };
    268 }
    269 
    270 export function disableBreakpointsAtLine(source, line) {
    271  return ({ dispatch, getState }) => {
    272    const breakpointsAtLine = getBreakpointsForSource(getState(), source, line);
    273    return dispatch(toggleBreakpoints(true, breakpointsAtLine));
    274  };
    275 }
    276 
    277 export function enableBreakpointsAtLine(source, line) {
    278  return ({ dispatch, getState }) => {
    279    const breakpointsAtLine = getBreakpointsForSource(getState(), source, line);
    280    return dispatch(toggleBreakpoints(false, breakpointsAtLine));
    281  };
    282 }
    283 
    284 export function toggleDisabledBreakpoint(breakpoint) {
    285  return ({ dispatch }) => {
    286    if (!breakpoint.disabled) {
    287      return dispatch(disableBreakpoint(breakpoint));
    288    }
    289    return dispatch(enableBreakpoint(breakpoint));
    290  };
    291 }
    292 
    293 export function enableXHRBreakpoint(index, bp) {
    294  return ({ dispatch, getState, client }) => {
    295    const xhrBreakpoints = getXHRBreakpoints(getState());
    296    const breakpoint = bp || xhrBreakpoints[index];
    297    const enabledBreakpoint = {
    298      ...breakpoint,
    299      disabled: false,
    300    };
    301 
    302    return dispatch({
    303      type: "ENABLE_XHR_BREAKPOINT",
    304      breakpoint: enabledBreakpoint,
    305      index,
    306      [PROMISE]: client.setXHRBreakpoint(breakpoint.path, breakpoint.method),
    307    });
    308  };
    309 }
    310 
    311 export function disableXHRBreakpoint(index, bp) {
    312  return ({ dispatch, getState, client }) => {
    313    const xhrBreakpoints = getXHRBreakpoints(getState());
    314    const breakpoint = bp || xhrBreakpoints[index];
    315    const disabledBreakpoint = {
    316      ...breakpoint,
    317      disabled: true,
    318    };
    319 
    320    return dispatch({
    321      type: "DISABLE_XHR_BREAKPOINT",
    322      breakpoint: disabledBreakpoint,
    323      index,
    324      [PROMISE]: client.removeXHRBreakpoint(breakpoint.path, breakpoint.method),
    325    });
    326  };
    327 }
    328 
    329 export function updateXHRBreakpoint(index, path, method) {
    330  return ({ dispatch, getState, client }) => {
    331    const xhrBreakpoints = getXHRBreakpoints(getState());
    332    const breakpoint = xhrBreakpoints[index];
    333 
    334    const updatedBreakpoint = {
    335      ...breakpoint,
    336      path,
    337      method,
    338      text: L10N.getFormatStr("xhrBreakpoints.item.label", path),
    339    };
    340 
    341    return dispatch({
    342      type: "UPDATE_XHR_BREAKPOINT",
    343      breakpoint: updatedBreakpoint,
    344      index,
    345      [PROMISE]: Promise.all([
    346        client.removeXHRBreakpoint(breakpoint.path, breakpoint.method),
    347        client.setXHRBreakpoint(path, method),
    348      ]),
    349    });
    350  };
    351 }
    352 export function togglePauseOnAny() {
    353  return ({ dispatch, getState }) => {
    354    const xhrBreakpoints = getXHRBreakpoints(getState());
    355    const index = xhrBreakpoints.findIndex(({ path }) => path.length === 0);
    356    if (index < 0) {
    357      return dispatch(setXHRBreakpoint("", "ANY"));
    358    }
    359 
    360    const bp = xhrBreakpoints[index];
    361    if (bp.disabled) {
    362      return dispatch(enableXHRBreakpoint(index, bp));
    363    }
    364 
    365    return dispatch(disableXHRBreakpoint(index, bp));
    366  };
    367 }
    368 
    369 export function setXHRBreakpoint(path, method) {
    370  return ({ dispatch, client }) => {
    371    const breakpoint = createXHRBreakpoint(path, method);
    372 
    373    return dispatch({
    374      type: "SET_XHR_BREAKPOINT",
    375      breakpoint,
    376      [PROMISE]: client.setXHRBreakpoint(path, method),
    377    });
    378  };
    379 }
    380 
    381 export function removeAllXHRBreakpoints() {
    382  return async ({ dispatch, getState, client }) => {
    383    const xhrBreakpoints = getXHRBreakpoints(getState());
    384    const promises = xhrBreakpoints.map(breakpoint =>
    385      client.removeXHRBreakpoint(breakpoint.path, breakpoint.method)
    386    );
    387    await dispatch({
    388      type: "CLEAR_XHR_BREAKPOINTS",
    389      [PROMISE]: Promise.all(promises),
    390    });
    391    asyncStore.xhrBreakpoints = [];
    392  };
    393 }
    394 
    395 export function removeXHRBreakpoint(index) {
    396  return ({ dispatch, getState, client }) => {
    397    const xhrBreakpoints = getXHRBreakpoints(getState());
    398    const breakpoint = xhrBreakpoints[index];
    399    return dispatch({
    400      type: "REMOVE_XHR_BREAKPOINT",
    401      breakpoint,
    402      index,
    403      [PROMISE]: client.removeXHRBreakpoint(breakpoint.path, breakpoint.method),
    404    });
    405  };
    406 }