diff options
Diffstat (limited to 'devtools/client/responsive.html/components/viewport-dimension.js')
-rw-r--r-- | devtools/client/responsive.html/components/viewport-dimension.js | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/devtools/client/responsive.html/components/viewport-dimension.js b/devtools/client/responsive.html/components/viewport-dimension.js new file mode 100644 index 000000000..a359cecf7 --- /dev/null +++ b/devtools/client/responsive.html/components/viewport-dimension.js @@ -0,0 +1,173 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const { DOM: dom, createClass, PropTypes } = + require("devtools/client/shared/vendor/react"); + +const Constants = require("../constants"); +const Types = require("../types"); + +module.exports = createClass({ + displayName: "ViewportDimension", + + propTypes: { + viewport: PropTypes.shape(Types.viewport).isRequired, + onRemoveDevice: PropTypes.func.isRequired, + onResizeViewport: PropTypes.func.isRequired, + }, + + getInitialState() { + let { width, height } = this.props.viewport; + + return { + width, + height, + isEditing: false, + isInvalid: false, + }; + }, + + componentWillReceiveProps(nextProps) { + let { width, height } = nextProps.viewport; + + this.setState({ + width, + height, + }); + }, + + validateInput(value) { + let isInvalid = true; + + // Check the value is a number and greater than MIN_VIEWPORT_DIMENSION + if (/^\d{3,4}$/.test(value) && + parseInt(value, 10) >= Constants.MIN_VIEWPORT_DIMENSION) { + isInvalid = false; + } + + this.setState({ + isInvalid, + }); + }, + + onInputBlur() { + let { width, height } = this.props.viewport; + + if (this.state.width != width || this.state.height != height) { + this.onInputSubmit(); + } + + this.setState({ + isEditing: false, + inInvalid: false, + }); + }, + + onInputChange({ target }) { + if (target.value.length > 4) { + return; + } + + if (this.refs.widthInput == target) { + this.setState({ width: target.value }); + this.validateInput(target.value); + } + + if (this.refs.heightInput == target) { + this.setState({ height: target.value }); + this.validateInput(target.value); + } + }, + + onInputFocus() { + this.setState({ + isEditing: true, + }); + }, + + onInputKeyUp({ target, keyCode }) { + // On Enter, submit the input + if (keyCode == 13) { + this.onInputSubmit(); + } + + // On Esc, blur the target + if (keyCode == 27) { + target.blur(); + } + }, + + onInputSubmit() { + if (this.state.isInvalid) { + let { width, height } = this.props.viewport; + + this.setState({ + width, + height, + isInvalid: false, + }); + + return; + } + + // Change the device selector back to an unselected device + // TODO: Bug 1332754: Logic like this probably belongs in the action creator. + if (this.props.viewport.device) { + this.props.onRemoveDevice(); + } + this.props.onResizeViewport(parseInt(this.state.width, 10), + parseInt(this.state.height, 10)); + }, + + render() { + let editableClass = "viewport-dimension-editable"; + let inputClass = "viewport-dimension-input"; + + if (this.state.isEditing) { + editableClass += " editing"; + inputClass += " editing"; + } + + if (this.state.isInvalid) { + editableClass += " invalid"; + } + + return dom.div( + { + className: "viewport-dimension", + }, + dom.div( + { + className: editableClass, + }, + dom.input({ + ref: "widthInput", + className: inputClass, + size: 4, + value: this.state.width, + onBlur: this.onInputBlur, + onChange: this.onInputChange, + onFocus: this.onInputFocus, + onKeyUp: this.onInputKeyUp, + }), + dom.span({ + className: "viewport-dimension-separator", + }, "×"), + dom.input({ + ref: "heightInput", + className: inputClass, + size: 4, + value: this.state.height, + onBlur: this.onInputBlur, + onChange: this.onInputChange, + onFocus: this.onInputFocus, + onKeyUp: this.onInputKeyUp, + }) + ) + ); + }, + +}); |