tor-browser

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

DeviceForm.js (6602B)


      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 {
      8  createFactory,
      9  createRef,
     10  PureComponent,
     11 } = require("resource://devtools/client/shared/vendor/react.mjs");
     12 const dom = require("resource://devtools/client/shared/vendor/react-dom-factories.js");
     13 const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.mjs");
     14 
     15 const ViewportDimension = createFactory(
     16  require("resource://devtools/client/responsive/components/ViewportDimension.js")
     17 );
     18 
     19 const {
     20  getStr,
     21 } = require("resource://devtools/client/responsive/utils/l10n.js");
     22 const Types = require("resource://devtools/client/responsive/types.js");
     23 
     24 class DeviceForm extends PureComponent {
     25  static get propTypes() {
     26    return {
     27      formType: PropTypes.string.isRequired,
     28      device: PropTypes.shape(Types.device).isRequired,
     29      devices: PropTypes.shape(Types.devices).isRequired,
     30      onSave: PropTypes.func.isRequired,
     31      viewportTemplate: PropTypes.shape(Types.viewport).isRequired,
     32      onDeviceFormHide: PropTypes.func.isRequired,
     33    };
     34  }
     35 
     36  constructor(props) {
     37    super(props);
     38 
     39    const { height, width } = this.props.viewportTemplate;
     40 
     41    this.state = {
     42      height,
     43      width,
     44    };
     45 
     46    this.nameInputRef = createRef();
     47    this.pixelRatioInputRef = createRef();
     48    this.touchInputRef = createRef();
     49    this.userAgentInputRef = createRef();
     50 
     51    this.onChangeSize = this.onChangeSize.bind(this);
     52    this.onDeviceFormHide = this.onDeviceFormHide.bind(this);
     53    this.onDeviceFormSave = this.onDeviceFormSave.bind(this);
     54    this.onInputFocus = this.onInputFocus.bind(this);
     55    this.validateNameField = this.validateNameField.bind(this);
     56  }
     57 
     58  onChangeSize(_, width, height) {
     59    this.setState({
     60      width,
     61      height,
     62    });
     63  }
     64 
     65  onDeviceFormSave(e) {
     66    e.preventDefault();
     67 
     68    if (!this.pixelRatioInputRef.current.checkValidity()) {
     69      return;
     70    }
     71 
     72    if (
     73      !this.validateNameField(
     74        this.nameInputRef.current.value,
     75        this.props.device
     76      )
     77    ) {
     78      this.nameInputRef.current.setCustomValidity(
     79        getStr("responsive.deviceNameAlreadyInUse")
     80      );
     81      return;
     82    }
     83 
     84    this.props.onSave({
     85      name: this.nameInputRef.current.value.trim(),
     86      width: this.state.width,
     87      height: this.state.height,
     88      pixelRatio: parseFloat(this.pixelRatioInputRef.current.value),
     89      userAgent: this.userAgentInputRef.current.value,
     90      touch: this.touchInputRef.current.checked,
     91    });
     92 
     93    this.onDeviceFormHide();
     94  }
     95 
     96  onDeviceFormHide() {
     97    // Ensure that we have onDeviceFormHide before calling it.
     98    if (this.props.onDeviceFormHide) {
     99      this.props.onDeviceFormHide();
    100    }
    101  }
    102 
    103  onInputFocus(e) {
    104    // If the formType is "add", select all text in input field when focused.
    105    if (this.props.formType === "add") {
    106      e.target.select();
    107    }
    108  }
    109 
    110  /**
    111   * Validates the name field's value.
    112   *
    113   * @param  {string} value
    114   *         The input field value for the device name.
    115   * @return {boolean} true if device name is valid, false otherwise.
    116   */
    117  validateNameField(value) {
    118    const nameFieldValue = value.trim();
    119    let isValidDeviceName = false;
    120 
    121    // If the formType is "add", then we just need to check if a custom device with that
    122    // same name exists.
    123    if (this.props.formType === "add") {
    124      isValidDeviceName = !this.props.devices.custom.find(
    125        device => device.name == nameFieldValue
    126      );
    127    } else {
    128      // Otherwise, the formType is "edit". We'd have to find another device that
    129      // already has the same name, but not itself, so:
    130      // Find the index of the device being edited. Use this index value to distinguish
    131      // between the device being edited from other devices in the list.
    132      const deviceIndex = this.props.devices.custom.findIndex(({ name }) => {
    133        return name === this.props.device.name;
    134      });
    135 
    136      isValidDeviceName = !this.props.devices.custom.find((d, index) => {
    137        return d.name === nameFieldValue && index !== deviceIndex;
    138      });
    139    }
    140 
    141    return isValidDeviceName;
    142  }
    143 
    144  render() {
    145    const { device, formType } = this.props;
    146    const { width, height } = this.state;
    147 
    148    return dom.form(
    149      { id: "device-form" },
    150      dom.label(
    151        { id: "device-form-name" },
    152        dom.span(
    153          { className: "device-form-label" },
    154          getStr("responsive.deviceAdderName")
    155        ),
    156        dom.input({
    157          defaultValue: device.name,
    158          ref: this.nameInputRef,
    159          onFocus: this.onInputFocus,
    160        })
    161      ),
    162      dom.label(
    163        { id: "device-form-size" },
    164        dom.span(
    165          { className: "device-form-label" },
    166          getStr("responsive.deviceAdderSize")
    167        ),
    168        ViewportDimension({
    169          viewport: { width, height },
    170          doResizeViewport: this.onChangeSize,
    171        })
    172      ),
    173      dom.label(
    174        { id: "device-form-pixel-ratio" },
    175        dom.span(
    176          { className: "device-form-label" },
    177          getStr("responsive.deviceAdderPixelRatio2")
    178        ),
    179        dom.input({
    180          type: "number",
    181          step: "any",
    182          defaultValue: device.pixelRatio,
    183          ref: this.pixelRatioInputRef,
    184          onFocus: this.onInputFocus,
    185        })
    186      ),
    187      dom.label(
    188        { id: "device-form-user-agent" },
    189        dom.span(
    190          { className: "device-form-label" },
    191          getStr("responsive.deviceAdderUserAgent2")
    192        ),
    193        dom.input({
    194          defaultValue: device.userAgent,
    195          ref: this.userAgentInputRef,
    196          onFocus: this.onInputFocus,
    197        })
    198      ),
    199      dom.label(
    200        { id: "device-form-touch" },
    201        dom.input({
    202          defaultChecked: device.touch,
    203          type: "checkbox",
    204          ref: this.touchInputRef,
    205        }),
    206        dom.span(
    207          { className: "device-form-label" },
    208          getStr("responsive.deviceAdderTouch2")
    209        )
    210      ),
    211      dom.div(
    212        { className: "device-form-buttons" },
    213        dom.button(
    214          { id: "device-form-save", onClick: this.onDeviceFormSave },
    215          formType === "add"
    216            ? getStr("responsive.deviceAdderSave")
    217            : getStr("responsive.deviceFormUpdate")
    218        ),
    219        dom.button(
    220          { id: "device-form-cancel", onClick: this.onDeviceFormHide },
    221          getStr("responsive.deviceAdderCancel")
    222        )
    223      )
    224    );
    225  }
    226 }
    227 
    228 module.exports = DeviceForm;