tor-browser

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

compatibility.js (9670B)


      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 "use strict";
      6 
      7 const nodeConstants = require("resource://devtools/shared/dom-node-constants.js");
      8 
      9 const UserSettings = require("resource://devtools/shared/compatibility/compatibility-user-settings.js");
     10 
     11 const {
     12  COMPATIBILITY_APPEND_NODE_START,
     13  COMPATIBILITY_APPEND_NODE_SUCCESS,
     14  COMPATIBILITY_APPEND_NODE_FAILURE,
     15  COMPATIBILITY_APPEND_NODE_COMPLETE,
     16  COMPATIBILITY_CLEAR_DESTROYED_NODES,
     17  COMPATIBILITY_INIT_USER_SETTINGS_START,
     18  COMPATIBILITY_INIT_USER_SETTINGS_SUCCESS,
     19  COMPATIBILITY_INIT_USER_SETTINGS_FAILURE,
     20  COMPATIBILITY_INIT_USER_SETTINGS_COMPLETE,
     21  COMPATIBILITY_INTERNAL_APPEND_NODE,
     22  COMPATIBILITY_INTERNAL_NODE_UPDATE,
     23  COMPATIBILITY_INTERNAL_REMOVE_NODE,
     24  COMPATIBILITY_INTERNAL_UPDATE_SELECTED_NODE_ISSUES,
     25  COMPATIBILITY_REMOVE_NODE_START,
     26  COMPATIBILITY_REMOVE_NODE_SUCCESS,
     27  COMPATIBILITY_REMOVE_NODE_FAILURE,
     28  COMPATIBILITY_REMOVE_NODE_COMPLETE,
     29  COMPATIBILITY_UPDATE_NODE_START,
     30  COMPATIBILITY_UPDATE_NODE_SUCCESS,
     31  COMPATIBILITY_UPDATE_NODE_FAILURE,
     32  COMPATIBILITY_UPDATE_NODE_COMPLETE,
     33  COMPATIBILITY_UPDATE_NODES_START,
     34  COMPATIBILITY_UPDATE_NODES_SUCCESS,
     35  COMPATIBILITY_UPDATE_NODES_FAILURE,
     36  COMPATIBILITY_UPDATE_NODES_COMPLETE,
     37  COMPATIBILITY_UPDATE_SELECTED_NODE_START,
     38  COMPATIBILITY_UPDATE_SELECTED_NODE_SUCCESS,
     39  COMPATIBILITY_UPDATE_SELECTED_NODE_FAILURE,
     40  COMPATIBILITY_UPDATE_SELECTED_NODE_COMPLETE,
     41  COMPATIBILITY_UPDATE_SETTINGS_VISIBILITY,
     42  COMPATIBILITY_UPDATE_TARGET_BROWSERS_START,
     43  COMPATIBILITY_UPDATE_TARGET_BROWSERS_SUCCESS,
     44  COMPATIBILITY_UPDATE_TARGET_BROWSERS_FAILURE,
     45  COMPATIBILITY_UPDATE_TARGET_BROWSERS_COMPLETE,
     46  COMPATIBILITY_UPDATE_TOP_LEVEL_TARGET_START,
     47  COMPATIBILITY_UPDATE_TOP_LEVEL_TARGET_SUCCESS,
     48  COMPATIBILITY_UPDATE_TOP_LEVEL_TARGET_FAILURE,
     49  COMPATIBILITY_UPDATE_TOP_LEVEL_TARGET_COMPLETE,
     50 } = require("resource://devtools/client/inspector/compatibility/actions/index.js");
     51 
     52 function appendNode(node) {
     53  return async ({ dispatch, getState }) => {
     54    dispatch({ type: COMPATIBILITY_APPEND_NODE_START });
     55 
     56    try {
     57      const { targetBrowsers, topLevelTarget } = getState().compatibility;
     58      const { walker } = await topLevelTarget.getFront("inspector");
     59      await _inspectNode(node, targetBrowsers, walker, dispatch);
     60      dispatch({ type: COMPATIBILITY_APPEND_NODE_SUCCESS });
     61    } catch (error) {
     62      dispatch({
     63        type: COMPATIBILITY_APPEND_NODE_FAILURE,
     64        error,
     65      });
     66    }
     67 
     68    dispatch({ type: COMPATIBILITY_APPEND_NODE_COMPLETE });
     69  };
     70 }
     71 
     72 function clearDestroyedNodes() {
     73  return { type: COMPATIBILITY_CLEAR_DESTROYED_NODES };
     74 }
     75 
     76 function initUserSettings() {
     77  return async ({ dispatch }) => {
     78    dispatch({ type: COMPATIBILITY_INIT_USER_SETTINGS_START });
     79 
     80    try {
     81      const [defaultTargetBrowsers, targetBrowsers] = await Promise.all([
     82        UserSettings.getBrowsersList(),
     83        UserSettings.getTargetBrowsers(),
     84      ]);
     85 
     86      dispatch({
     87        type: COMPATIBILITY_INIT_USER_SETTINGS_SUCCESS,
     88        defaultTargetBrowsers,
     89        targetBrowsers,
     90      });
     91    } catch (error) {
     92      dispatch({
     93        type: COMPATIBILITY_INIT_USER_SETTINGS_FAILURE,
     94        error,
     95      });
     96    }
     97 
     98    dispatch({ type: COMPATIBILITY_INIT_USER_SETTINGS_COMPLETE });
     99  };
    100 }
    101 
    102 function removeNode(node) {
    103  return async ({ dispatch, getState }) => {
    104    dispatch({ type: COMPATIBILITY_REMOVE_NODE_START });
    105 
    106    try {
    107      const { topLevelTarget } = getState().compatibility;
    108      const { walker } = await topLevelTarget.getFront("inspector");
    109      await _removeNode(node, walker, dispatch);
    110      dispatch({ type: COMPATIBILITY_REMOVE_NODE_SUCCESS });
    111    } catch (error) {
    112      dispatch({
    113        type: COMPATIBILITY_REMOVE_NODE_FAILURE,
    114        error,
    115      });
    116    }
    117 
    118    dispatch({ type: COMPATIBILITY_REMOVE_NODE_COMPLETE });
    119  };
    120 }
    121 
    122 function updateNodes(selector) {
    123  return async ({ dispatch, getState }) => {
    124    dispatch({ type: COMPATIBILITY_UPDATE_NODES_START });
    125 
    126    try {
    127      const { selectedNode, topLevelTarget, targetBrowsers } =
    128        getState().compatibility;
    129      const { walker } = await topLevelTarget.getFront("inspector");
    130      const nodeList = await walker.querySelectorAll(walker.rootNode, selector);
    131 
    132      for (const node of await nodeList.items()) {
    133        await _updateNode(node, selectedNode, targetBrowsers, dispatch);
    134      }
    135      dispatch({ type: COMPATIBILITY_UPDATE_NODES_SUCCESS });
    136    } catch (error) {
    137      dispatch({
    138        type: COMPATIBILITY_UPDATE_NODES_FAILURE,
    139        error,
    140      });
    141    }
    142 
    143    dispatch({ type: COMPATIBILITY_UPDATE_NODES_COMPLETE });
    144  };
    145 }
    146 
    147 function updateSelectedNode(node) {
    148  return async ({ dispatch, getState }) => {
    149    dispatch({ type: COMPATIBILITY_UPDATE_SELECTED_NODE_START });
    150 
    151    try {
    152      const { targetBrowsers } = getState().compatibility;
    153      await _updateSelectedNodeIssues(node, targetBrowsers, dispatch);
    154 
    155      dispatch({
    156        type: COMPATIBILITY_UPDATE_SELECTED_NODE_SUCCESS,
    157        node,
    158      });
    159    } catch (error) {
    160      dispatch({
    161        type: COMPATIBILITY_UPDATE_SELECTED_NODE_FAILURE,
    162        error,
    163      });
    164    }
    165 
    166    dispatch({ type: COMPATIBILITY_UPDATE_SELECTED_NODE_COMPLETE });
    167  };
    168 }
    169 
    170 function updateSettingsVisibility(visibility) {
    171  return {
    172    type: COMPATIBILITY_UPDATE_SETTINGS_VISIBILITY,
    173    visibility,
    174  };
    175 }
    176 
    177 function updateTargetBrowsers(targetBrowsers) {
    178  return async ({ dispatch, getState }) => {
    179    dispatch({ type: COMPATIBILITY_UPDATE_TARGET_BROWSERS_START });
    180 
    181    try {
    182      UserSettings.setTargetBrowsers(targetBrowsers);
    183 
    184      const { selectedNode, topLevelTarget } = getState().compatibility;
    185 
    186      if (selectedNode) {
    187        await _updateSelectedNodeIssues(selectedNode, targetBrowsers, dispatch);
    188      }
    189 
    190      if (topLevelTarget) {
    191        await _updateTopLevelTargetIssues(
    192          topLevelTarget,
    193          targetBrowsers,
    194          dispatch
    195        );
    196      }
    197 
    198      dispatch({
    199        type: COMPATIBILITY_UPDATE_TARGET_BROWSERS_SUCCESS,
    200        targetBrowsers,
    201      });
    202    } catch (error) {
    203      dispatch({ type: COMPATIBILITY_UPDATE_TARGET_BROWSERS_FAILURE, error });
    204    }
    205 
    206    dispatch({ type: COMPATIBILITY_UPDATE_TARGET_BROWSERS_COMPLETE });
    207  };
    208 }
    209 
    210 function updateTopLevelTarget(target) {
    211  return async ({ dispatch, getState }) => {
    212    dispatch({ type: COMPATIBILITY_UPDATE_TOP_LEVEL_TARGET_START });
    213 
    214    try {
    215      const { targetBrowsers } = getState().compatibility;
    216      await _updateTopLevelTargetIssues(target, targetBrowsers, dispatch);
    217 
    218      dispatch({ type: COMPATIBILITY_UPDATE_TOP_LEVEL_TARGET_SUCCESS, target });
    219    } catch (error) {
    220      dispatch({ type: COMPATIBILITY_UPDATE_TOP_LEVEL_TARGET_FAILURE, error });
    221    }
    222 
    223    dispatch({ type: COMPATIBILITY_UPDATE_TOP_LEVEL_TARGET_COMPLETE });
    224  };
    225 }
    226 
    227 function updateNode(node) {
    228  return async ({ dispatch, getState }) => {
    229    dispatch({ type: COMPATIBILITY_UPDATE_NODE_START });
    230 
    231    try {
    232      const { selectedNode, targetBrowsers } = getState().compatibility;
    233      await _updateNode(node, selectedNode, targetBrowsers, dispatch);
    234      dispatch({ type: COMPATIBILITY_UPDATE_NODE_SUCCESS });
    235    } catch (error) {
    236      dispatch({
    237        type: COMPATIBILITY_UPDATE_NODE_FAILURE,
    238        error,
    239      });
    240    }
    241 
    242    dispatch({ type: COMPATIBILITY_UPDATE_NODE_COMPLETE });
    243  };
    244 }
    245 
    246 async function _getNodeIssues(node, targetBrowsers) {
    247  const compatibility = await node.inspectorFront.getCompatibilityFront();
    248  const declarationBlocksIssues = await compatibility.getNodeCssIssues(
    249    node,
    250    targetBrowsers
    251  );
    252 
    253  return declarationBlocksIssues;
    254 }
    255 
    256 async function _inspectNode(node, targetBrowsers, walker, dispatch) {
    257  if (node.nodeType !== nodeConstants.ELEMENT_NODE) {
    258    return;
    259  }
    260 
    261  const issues = await _getNodeIssues(node, targetBrowsers);
    262 
    263  if (issues.length) {
    264    dispatch({
    265      type: COMPATIBILITY_INTERNAL_APPEND_NODE,
    266      node,
    267      issues,
    268    });
    269  }
    270 
    271  const { nodes: children } = await walker.children(node);
    272  for (const child of children) {
    273    await _inspectNode(child, targetBrowsers, walker, dispatch);
    274  }
    275 }
    276 
    277 async function _removeNode(node, walker, dispatch) {
    278  if (node.nodeType !== nodeConstants.ELEMENT_NODE) {
    279    return;
    280  }
    281 
    282  dispatch({
    283    type: COMPATIBILITY_INTERNAL_REMOVE_NODE,
    284    node,
    285  });
    286 
    287  const { nodes: children } = await walker.children(node);
    288  for (const child of children) {
    289    await _removeNode(child, walker, dispatch);
    290  }
    291 }
    292 
    293 async function _updateNode(node, selectedNode, targetBrowsers, dispatch) {
    294  if (selectedNode.actorID === node.actorID) {
    295    await _updateSelectedNodeIssues(node, targetBrowsers, dispatch);
    296  }
    297 
    298  const issues = await _getNodeIssues(node, targetBrowsers);
    299  dispatch({
    300    type: COMPATIBILITY_INTERNAL_NODE_UPDATE,
    301    node,
    302    issues,
    303  });
    304 }
    305 
    306 async function _updateSelectedNodeIssues(node, targetBrowsers, dispatch) {
    307  const issues = await _getNodeIssues(node, targetBrowsers);
    308 
    309  dispatch({
    310    type: COMPATIBILITY_INTERNAL_UPDATE_SELECTED_NODE_ISSUES,
    311    issues,
    312  });
    313 }
    314 
    315 async function _updateTopLevelTargetIssues(target, targetBrowsers, dispatch) {
    316  const { walker } = await target.getFront("inspector");
    317  const documentElement = await walker.documentElement();
    318  await _inspectNode(documentElement, targetBrowsers, walker, dispatch);
    319 }
    320 
    321 module.exports = {
    322  appendNode,
    323  clearDestroyedNodes,
    324  initUserSettings,
    325  removeNode,
    326  updateNodes,
    327  updateSelectedNode,
    328  updateSettingsVisibility,
    329  updateTargetBrowsers,
    330  updateTopLevelTarget,
    331  updateNode,
    332 };