DeviceAdder.js (6274B)
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 PureComponent, 10 } = require("resource://devtools/client/shared/vendor/react.mjs"); 11 const dom = require("resource://devtools/client/shared/vendor/react-dom-factories.js"); 12 const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.mjs"); 13 14 const ViewportDimension = createFactory( 15 require("resource://devtools/client/responsive/components/ViewportDimension.js") 16 ); 17 18 const { 19 getFormatStr, 20 getStr, 21 } = require("resource://devtools/client/responsive/utils/l10n.js"); 22 const Types = require("resource://devtools/client/responsive/types.js"); 23 24 class DeviceAdder extends PureComponent { 25 static get propTypes() { 26 return { 27 devices: PropTypes.shape(Types.devices).isRequired, 28 onAddCustomDevice: PropTypes.func.isRequired, 29 viewportTemplate: PropTypes.shape(Types.viewport).isRequired, 30 }; 31 } 32 33 constructor(props) { 34 super(props); 35 36 const { height, width } = this.props.viewportTemplate; 37 38 this.state = { 39 deviceAdderDisplayed: false, 40 height, 41 width, 42 }; 43 44 this.onChangeSize = this.onChangeSize.bind(this); 45 this.onDeviceAdderShow = this.onDeviceAdderShow.bind(this); 46 this.onDeviceAdderSave = this.onDeviceAdderSave.bind(this); 47 } 48 49 onChangeSize(_, width, height) { 50 this.setState({ 51 width, 52 height, 53 }); 54 } 55 56 onDeviceAdderShow() { 57 this.setState({ 58 deviceAdderDisplayed: true, 59 }); 60 } 61 62 onDeviceAdderSave() { 63 const { devices, onAddCustomDevice } = this.props; 64 65 if (!this.pixelRatioInput.checkValidity()) { 66 return; 67 } 68 69 if (devices.custom.find(device => device.name == this.nameInput.value)) { 70 this.nameInput.setCustomValidity("Device name already in use"); 71 return; 72 } 73 74 this.setState({ 75 deviceAdderDisplayed: false, 76 }); 77 78 onAddCustomDevice({ 79 name: this.nameInput.value, 80 width: this.state.width, 81 height: this.state.height, 82 pixelRatio: parseFloat(this.pixelRatioInput.value), 83 userAgent: this.userAgentInput.value, 84 touch: this.touchInput.checked, 85 }); 86 } 87 88 render() { 89 const { devices, viewportTemplate } = this.props; 90 91 const { deviceAdderDisplayed, height, width } = this.state; 92 93 if (!deviceAdderDisplayed) { 94 return dom.div( 95 { 96 id: "device-adder", 97 }, 98 dom.button( 99 { 100 id: "device-adder-show", 101 onClick: this.onDeviceAdderShow, 102 }, 103 getStr("responsive.addDevice") 104 ) 105 ); 106 } 107 108 // If a device is currently selected, fold its attributes into a single object for use 109 // as the starting values of the form. If no device is selected, use the values for 110 // the current window. 111 let deviceName; 112 const normalizedViewport = Object.assign({}, viewportTemplate); 113 if (viewportTemplate.device) { 114 const device = devices[viewportTemplate.deviceType].find(d => { 115 return d.name == viewportTemplate.device; 116 }); 117 deviceName = getFormatStr( 118 "responsive.customDeviceNameFromBase", 119 device.name 120 ); 121 Object.assign(normalizedViewport, { 122 pixelRatio: device.pixelRatio, 123 userAgent: device.userAgent, 124 touch: device.touch, 125 }); 126 } else { 127 deviceName = getStr("responsive.customDeviceName"); 128 Object.assign(normalizedViewport, { 129 pixelRatio: window.devicePixelRatio, 130 userAgent: navigator.userAgent, 131 touch: false, 132 }); 133 } 134 135 return dom.div( 136 { id: "device-adder" }, 137 dom.div( 138 { id: "device-adder-content" }, 139 dom.div( 140 { id: "device-adder-column-1" }, 141 dom.label( 142 { id: "device-adder-name" }, 143 dom.span( 144 { className: "device-adder-label" }, 145 getStr("responsive.deviceAdderName") 146 ), 147 dom.input({ 148 defaultValue: deviceName, 149 ref: input => { 150 this.nameInput = input; 151 }, 152 }) 153 ), 154 dom.label( 155 { id: "device-adder-size" }, 156 dom.span( 157 { className: "device-adder-label" }, 158 getStr("responsive.deviceAdderSize") 159 ), 160 ViewportDimension({ 161 viewport: { 162 width, 163 height, 164 }, 165 doResizeViewport: this.onChangeSize, 166 }) 167 ), 168 dom.label( 169 { id: "device-adder-pixel-ratio" }, 170 dom.span( 171 { className: "device-adder-label" }, 172 getStr("responsive.deviceAdderPixelRatio") 173 ), 174 dom.input({ 175 type: "number", 176 step: "any", 177 defaultValue: normalizedViewport.pixelRatio, 178 ref: input => { 179 this.pixelRatioInput = input; 180 }, 181 }) 182 ) 183 ), 184 dom.div( 185 { id: "device-adder-column-2" }, 186 dom.label( 187 { id: "device-adder-user-agent" }, 188 dom.span( 189 { className: "device-adder-label" }, 190 getStr("responsive.deviceAdderUserAgent") 191 ), 192 dom.input({ 193 defaultValue: normalizedViewport.userAgent, 194 ref: input => { 195 this.userAgentInput = input; 196 }, 197 }) 198 ), 199 dom.label( 200 { id: "device-adder-touch" }, 201 dom.span( 202 { className: "device-adder-label" }, 203 getStr("responsive.deviceAdderTouch") 204 ), 205 dom.input({ 206 defaultChecked: normalizedViewport.touch, 207 type: "checkbox", 208 ref: input => { 209 this.touchInput = input; 210 }, 211 }) 212 ) 213 ) 214 ), 215 dom.button( 216 { 217 id: "device-adder-save", 218 onClick: this.onDeviceAdderSave, 219 }, 220 getStr("responsive.deviceAdderSave") 221 ) 222 ); 223 } 224 } 225 226 module.exports = DeviceAdder;