Settings.js (5767B)
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 connect, 9 } = require("resource://devtools/client/shared/vendor/react-redux.js"); 10 const { 11 createFactory, 12 PureComponent, 13 } = require("resource://devtools/client/shared/vendor/react.mjs"); 14 const dom = require("resource://devtools/client/shared/vendor/react-dom-factories.js"); 15 const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.mjs"); 16 17 const FluentReact = require("resource://devtools/client/shared/vendor/fluent-react.js"); 18 const Localized = createFactory(FluentReact.Localized); 19 20 const Types = require("resource://devtools/client/inspector/compatibility/types.js"); 21 22 const BrowserIcon = createFactory( 23 require("resource://devtools/client/inspector/compatibility/components/BrowserIcon.js") 24 ); 25 26 const { 27 updateSettingsVisibility, 28 updateTargetBrowsers, 29 } = require("resource://devtools/client/inspector/compatibility/actions/compatibility.js"); 30 31 const CLOSE_ICON = "chrome://devtools/skin/images/close.svg"; 32 33 class Settings extends PureComponent { 34 static get propTypes() { 35 return { 36 defaultTargetBrowsers: PropTypes.arrayOf(PropTypes.shape(Types.browser)) 37 .isRequired, 38 targetBrowsers: PropTypes.arrayOf(PropTypes.shape(Types.browser)) 39 .isRequired, 40 updateTargetBrowsers: PropTypes.func.isRequired, 41 updateSettingsVisibility: PropTypes.func.isRequired, 42 }; 43 } 44 45 constructor(props) { 46 super(props); 47 48 this._onTargetBrowserChanged = this._onTargetBrowserChanged.bind(this); 49 50 this.state = { 51 targetBrowsers: props.targetBrowsers, 52 }; 53 } 54 55 _onTargetBrowserChanged({ target }) { 56 const { id, status } = target.dataset; 57 let { targetBrowsers } = this.state; 58 59 if (target.checked) { 60 targetBrowsers = [...targetBrowsers, { id, status }]; 61 } else { 62 targetBrowsers = targetBrowsers.filter( 63 b => !(b.id === id && b.status === status) 64 ); 65 } 66 67 this.setState({ targetBrowsers }); 68 } 69 70 _renderTargetBrowsers() { 71 const { defaultTargetBrowsers } = this.props; 72 const { targetBrowsers } = this.state; 73 74 return dom.section( 75 { 76 className: "compatibility-settings__target-browsers", 77 }, 78 Localized( 79 { id: "compatibility-target-browsers-header" }, 80 dom.header( 81 { 82 className: "compatibility-settings__target-browsers-header", 83 }, 84 "compatibility-target-browsers-header" 85 ) 86 ), 87 dom.ul( 88 { 89 className: "compatibility-settings__target-browsers-list", 90 }, 91 defaultTargetBrowsers.map(({ id, name, status, version }) => { 92 const inputId = `${id}-${status}`; 93 const isTargetBrowser = !!targetBrowsers.find( 94 b => b.id === id && b.status === status 95 ); 96 return dom.li( 97 { 98 className: "compatibility-settings__target-browsers-item", 99 }, 100 dom.input({ 101 id: inputId, 102 type: "checkbox", 103 checked: isTargetBrowser, 104 onChange: this._onTargetBrowserChanged, 105 "data-id": id, 106 "data-status": status, 107 }), 108 dom.label( 109 { 110 className: "compatibility-settings__target-browsers-item-label", 111 htmlFor: inputId, 112 }, 113 BrowserIcon({ id, title: `${name} ${status}` }), 114 `${name} ${status} (${version})` 115 ) 116 ); 117 }) 118 ) 119 ); 120 } 121 122 _renderHeader() { 123 return dom.header( 124 { 125 className: "compatibility-settings__header", 126 }, 127 Localized( 128 { id: "compatibility-settings-header" }, 129 dom.label( 130 { 131 className: "compatibility-settings__header-label", 132 }, 133 "compatibility-settings-header" 134 ) 135 ), 136 Localized( 137 { 138 id: "compatibility-close-settings-button", 139 attrs: { title: true }, 140 }, 141 dom.button( 142 { 143 className: "compatibility-settings__header-button", 144 title: "compatibility-close-settings-button", 145 onClick: () => { 146 const { defaultTargetBrowsers } = this.props; 147 const { targetBrowsers } = this.state; 148 149 // Sort by ordering of default browsers. 150 const browsers = defaultTargetBrowsers.filter(b => 151 targetBrowsers.find(t => t.id === b.id && t.status === b.status) 152 ); 153 154 if ( 155 this.props.targetBrowsers.toString() !== browsers.toString() 156 ) { 157 this.props.updateTargetBrowsers(browsers); 158 } 159 160 this.props.updateSettingsVisibility(); 161 }, 162 }, 163 dom.img({ 164 className: "compatibility-settings__header-icon", 165 src: CLOSE_ICON, 166 }) 167 ) 168 ) 169 ); 170 } 171 172 render() { 173 return dom.section( 174 { 175 className: "compatibility-settings", 176 }, 177 this._renderHeader(), 178 this._renderTargetBrowsers() 179 ); 180 } 181 } 182 183 const mapStateToProps = state => { 184 return { 185 defaultTargetBrowsers: state.compatibility.defaultTargetBrowsers, 186 targetBrowsers: state.compatibility.targetBrowsers, 187 }; 188 }; 189 190 const mapDispatchToProps = dispatch => { 191 return { 192 updateTargetBrowsers: browsers => dispatch(updateTargetBrowsers(browsers)), 193 updateSettingsVisibility: () => dispatch(updateSettingsVisibility(false)), 194 }; 195 }; 196 197 module.exports = connect(mapStateToProps, mapDispatchToProps)(Settings);