tor-browser

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

MainFrame.js (7543B)


      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 "use strict";
      5 
      6 // React & Redux
      7 const {
      8  Component,
      9  createFactory,
     10 } = require("resource://devtools/client/shared/vendor/react.mjs");
     11 const {
     12  span,
     13  div,
     14 } = require("resource://devtools/client/shared/vendor/react-dom-factories.js");
     15 const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.mjs");
     16 const {
     17  connect,
     18 } = require("resource://devtools/client/shared/vendor/react-redux.js");
     19 const {
     20  enable,
     21  reset,
     22  updateCanBeEnabled,
     23  updateCanBeDisabled,
     24 } = require("resource://devtools/client/accessibility/actions/ui.js");
     25 
     26 // Localization
     27 const FluentReact = require("resource://devtools/client/shared/vendor/fluent-react.js");
     28 const LocalizationProvider = createFactory(FluentReact.LocalizationProvider);
     29 
     30 // Constants
     31 const {
     32  SIDEBAR_WIDTH,
     33  PORTRAIT_MODE_WIDTH,
     34 } = require("resource://devtools/client/accessibility/constants.js");
     35 
     36 // Accessibility Panel
     37 const AccessibilityTree = createFactory(
     38  require("resource://devtools/client/accessibility/components/AccessibilityTree.js")
     39 );
     40 const AuditProgressOverlay = createFactory(
     41  require("resource://devtools/client/accessibility/components/AuditProgressOverlay.js")
     42 );
     43 const Description = createFactory(
     44  require("resource://devtools/client/accessibility/components/Description.js")
     45    .Description
     46 );
     47 const RightSidebar = createFactory(
     48  require("resource://devtools/client/accessibility/components/RightSidebar.js")
     49 );
     50 const Toolbar = createFactory(
     51  require("resource://devtools/client/accessibility/components/Toolbar.js")
     52    .Toolbar
     53 );
     54 const SplitBox = createFactory(
     55  require("resource://devtools/client/shared/components/splitter/SplitBox.js")
     56 );
     57 
     58 /**
     59 * Renders basic layout of the Accessibility panel. The Accessibility panel
     60 * content consists of two main parts: tree and sidebar.
     61 */
     62 class MainFrame extends Component {
     63  static get propTypes() {
     64    return {
     65      fluentBundles: PropTypes.array.isRequired,
     66      enabled: PropTypes.bool.isRequired,
     67      dispatch: PropTypes.func.isRequired,
     68      auditing: PropTypes.array.isRequired,
     69      supports: PropTypes.object,
     70      toolbox: PropTypes.object.isRequired,
     71      getAccessibilityTreeRoot: PropTypes.func.isRequired,
     72      startListeningForAccessibilityEvents: PropTypes.func.isRequired,
     73      stopListeningForAccessibilityEvents: PropTypes.func.isRequired,
     74      audit: PropTypes.func.isRequired,
     75      simulate: PropTypes.func,
     76      enableAccessibility: PropTypes.func.isRequired,
     77      resetAccessiblity: PropTypes.func.isRequired,
     78      startListeningForLifecycleEvents: PropTypes.func.isRequired,
     79      stopListeningForLifecycleEvents: PropTypes.func.isRequired,
     80      startListeningForParentLifecycleEvents: PropTypes.func.isRequired,
     81      stopListeningForParentLifecycleEvents: PropTypes.func.isRequired,
     82      highlightAccessible: PropTypes.func.isRequired,
     83      unhighlightAccessible: PropTypes.func.isRequired,
     84    };
     85  }
     86 
     87  constructor(props) {
     88    super(props);
     89 
     90    this.resetAccessibility = this.resetAccessibility.bind(this);
     91    this.onPanelWindowResize = this.onPanelWindowResize.bind(this);
     92    this.onCanBeEnabledChange = this.onCanBeEnabledChange.bind(this);
     93    this.onCanBeDisabledChange = this.onCanBeDisabledChange.bind(this);
     94  }
     95 
     96  componentDidMount() {
     97    this.props.startListeningForLifecycleEvents({
     98      init: this.resetAccessibility,
     99      shutdown: this.resetAccessibility,
    100    });
    101    this.props.startListeningForParentLifecycleEvents({
    102      "can-be-enabled-change": this.onCanBeEnabledChange,
    103      "can-be-disabled-change": this.onCanBeDisabledChange,
    104    });
    105    this.props.startListeningForAccessibilityEvents({
    106      "top-level-document-ready": this.resetAccessibility,
    107    });
    108    window.addEventListener("resize", this.onPanelWindowResize, true);
    109  }
    110 
    111  componentWillUnmount() {
    112    this.props.stopListeningForLifecycleEvents({
    113      init: this.resetAccessibility,
    114      shutdown: this.resetAccessibility,
    115    });
    116    this.props.stopListeningForParentLifecycleEvents({
    117      "can-be-enabled-change": this.onCanBeEnabledChange,
    118      "can-be-disabled-change": this.onCanBeDisabledChange,
    119    });
    120    this.props.stopListeningForAccessibilityEvents({
    121      "top-level-document-ready": this.resetAccessibility,
    122    });
    123    window.removeEventListener("resize", this.onPanelWindowResize, true);
    124  }
    125 
    126  resetAccessibility() {
    127    const { dispatch, resetAccessiblity, supports } = this.props;
    128    dispatch(reset(resetAccessiblity, supports));
    129  }
    130 
    131  onCanBeEnabledChange(canBeEnabled) {
    132    const { enableAccessibility, dispatch } = this.props;
    133    dispatch(updateCanBeEnabled(canBeEnabled));
    134    if (canBeEnabled) {
    135      dispatch(enable(enableAccessibility));
    136    }
    137  }
    138 
    139  onCanBeDisabledChange(canBeDisabled) {
    140    this.props.dispatch(updateCanBeDisabled(canBeDisabled));
    141  }
    142 
    143  get useLandscapeMode() {
    144    const { clientWidth } = document.getElementById("content");
    145    return clientWidth > PORTRAIT_MODE_WIDTH;
    146  }
    147 
    148  /**
    149   * If panel width is less than PORTRAIT_MODE_WIDTH px, the splitter changes
    150   * its mode to `horizontal` to support portrait view.
    151   */
    152  onPanelWindowResize() {
    153    if (this.refs.splitBox) {
    154      this.refs.splitBox.setState({ vert: this.useLandscapeMode });
    155    }
    156  }
    157 
    158  /**
    159   * Render Accessibility panel content
    160   */
    161  render() {
    162    const {
    163      fluentBundles,
    164      enabled,
    165      auditing,
    166      simulate,
    167      toolbox,
    168      getAccessibilityTreeRoot,
    169      startListeningForAccessibilityEvents,
    170      stopListeningForAccessibilityEvents,
    171      audit,
    172      highlightAccessible,
    173      unhighlightAccessible,
    174    } = this.props;
    175 
    176    if (!enabled) {
    177      return Description();
    178    }
    179 
    180    // Audit is currently running.
    181    const isAuditing = !!auditing.length;
    182 
    183    return LocalizationProvider(
    184      { bundles: fluentBundles },
    185      div(
    186        { className: "mainFrame", role: "presentation", tabIndex: "-1" },
    187        Toolbar({
    188          audit,
    189          simulate,
    190          toolboxDoc: toolbox.doc,
    191        }),
    192        isAuditing && AuditProgressOverlay(),
    193        span(
    194          {
    195            "aria-hidden": isAuditing,
    196            role: "presentation",
    197            style: { display: "contents" },
    198          },
    199          SplitBox({
    200            ref: "splitBox",
    201            initialSize: SIDEBAR_WIDTH,
    202            minSize: "10%",
    203            maxSize: "80%",
    204            splitterSize: 1,
    205            endPanelControl: true,
    206            startPanel: div(
    207              {
    208                className: "main-panel",
    209                role: "presentation",
    210                tabIndex: "-1",
    211              },
    212              AccessibilityTree({
    213                toolboxDoc: toolbox.doc,
    214                getAccessibilityTreeRoot,
    215                startListeningForAccessibilityEvents,
    216                stopListeningForAccessibilityEvents,
    217                highlightAccessible,
    218                unhighlightAccessible,
    219              })
    220            ),
    221            endPanel: RightSidebar({
    222              highlightAccessible,
    223              unhighlightAccessible,
    224              toolbox,
    225            }),
    226            vert: this.useLandscapeMode,
    227          })
    228        )
    229      )
    230    );
    231  }
    232 }
    233 
    234 const mapStateToProps = ({
    235  ui: { enabled, supports },
    236  audit: { auditing },
    237 }) => ({
    238  enabled,
    239  supports,
    240  auditing,
    241 });
    242 
    243 // Exports from this module
    244 module.exports = connect(mapStateToProps)(MainFrame);