SimulationMenuButton.js (4954B)
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 7 const { 8 createFactory, 9 Component, 10 } = require("resource://devtools/client/shared/vendor/react.mjs"); 11 const { 12 hr, 13 span, 14 div, 15 } = require("resource://devtools/client/shared/vendor/react-dom-factories.js"); 16 const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.mjs"); 17 const { 18 L10N, 19 } = require("resource://devtools/client/accessibility/utils/l10n.js"); 20 const { 21 connect, 22 } = require("resource://devtools/client/shared/vendor/react-redux.js"); 23 const MenuButton = createFactory( 24 require("resource://devtools/client/shared/components/menu/MenuButton.js") 25 ); 26 const { openDocLink } = require("resource://devtools/client/shared/link.js"); 27 const { 28 A11Y_SIMULATION_DOCUMENTATION_LINK, 29 } = require("resource://devtools/client/accessibility/constants.js"); 30 const { 31 accessibility: { SIMULATION_TYPE }, 32 } = require("resource://devtools/shared/constants.js"); 33 const actions = require("resource://devtools/client/accessibility/actions/simulation.js"); 34 35 loader.lazyGetter(this, "MenuItem", function () { 36 return createFactory( 37 require("resource://devtools/client/shared/components/menu/MenuItem.js") 38 ); 39 }); 40 loader.lazyGetter(this, "MenuList", function () { 41 return createFactory( 42 require("resource://devtools/client/shared/components/menu/MenuList.js") 43 ); 44 }); 45 46 const SIMULATION_MENU_LABELS = { 47 NONE: "accessibility.filter.none", 48 [SIMULATION_TYPE.ACHROMATOPSIA]: "accessibility.simulation.achromatopsia", 49 [SIMULATION_TYPE.PROTANOPIA]: "accessibility.simulation.protanopia", 50 [SIMULATION_TYPE.DEUTERANOPIA]: "accessibility.simulation.deuteranopia", 51 [SIMULATION_TYPE.TRITANOPIA]: "accessibility.simulation.tritanopia", 52 [SIMULATION_TYPE.CONTRAST_LOSS]: "accessibility.simulation.contrastLoss", 53 DOCUMENTATION: "accessibility.documentation.label", 54 }; 55 56 class SimulationMenuButton extends Component { 57 static get propTypes() { 58 return { 59 simulate: PropTypes.func, 60 simulation: PropTypes.object.isRequired, 61 dispatch: PropTypes.func.isRequired, 62 toolboxDoc: PropTypes.object.isRequired, 63 }; 64 } 65 66 constructor(props) { 67 super(props); 68 69 this.disableSimulation = this.disableSimulation.bind(this); 70 } 71 72 disableSimulation() { 73 const { dispatch, simulate: simulateFunc } = this.props; 74 75 dispatch(actions.simulate(simulateFunc)); 76 } 77 78 toggleSimulation(simKey) { 79 const { dispatch, simulation, simulate: simulateFunc } = this.props; 80 81 if (!simulation[simKey]) { 82 Glean.devtoolsAccessibility.simulationActivated[simKey].add(1); 83 84 dispatch(actions.simulate(simulateFunc, [simKey])); 85 return; 86 } 87 88 this.disableSimulation(); 89 } 90 91 render() { 92 const { simulation, toolboxDoc } = this.props; 93 const simulationMenuButtonId = "simulation-menu-button"; 94 const toolbarLabelID = "accessibility-simulation-label"; 95 const currSimulation = Object.entries(simulation).find( 96 simEntry => simEntry[1] 97 ); 98 99 const items = [ 100 // No simulation option 101 MenuItem({ 102 key: "simulation-none", 103 label: L10N.getStr(SIMULATION_MENU_LABELS.NONE), 104 checked: !currSimulation, 105 onClick: this.disableSimulation, 106 }), 107 hr({ key: "hr-1" }), 108 // Simulation options 109 ...Object.keys(SIMULATION_TYPE).map(simType => 110 MenuItem({ 111 key: `simulation-${simType}`, 112 label: L10N.getStr(SIMULATION_MENU_LABELS[simType]), 113 checked: simulation[simType], 114 onClick: this.toggleSimulation.bind(this, simType), 115 }) 116 ), 117 hr({ key: "hr-2" }), 118 // Documentation link 119 MenuItem({ 120 className: "link", 121 key: "simulation-documentation", 122 label: L10N.getStr(SIMULATION_MENU_LABELS.DOCUMENTATION), 123 role: "link", 124 onClick: () => openDocLink(A11Y_SIMULATION_DOCUMENTATION_LINK), 125 }), 126 ]; 127 128 return div( 129 { 130 role: "group", 131 className: "accessibility-simulation", 132 "aria-labelledby": toolbarLabelID, 133 }, 134 span( 135 { id: toolbarLabelID, role: "presentation" }, 136 L10N.getStr("accessibility.simulation") 137 ), 138 MenuButton( 139 { 140 id: simulationMenuButtonId, 141 menuId: simulationMenuButtonId + "-menu", 142 className: `devtools-button toolbar-menu-button simulation${ 143 currSimulation ? " active" : "" 144 }`, 145 toolboxDoc, 146 label: L10N.getStr( 147 SIMULATION_MENU_LABELS[currSimulation ? currSimulation[0] : "NONE"] 148 ), 149 }, 150 MenuList({}, items) 151 ) 152 ); 153 } 154 } 155 156 const mapStateToProps = ({ simulation }) => { 157 return { simulation }; 158 }; 159 160 // Exports from this module 161 module.exports = connect(mapStateToProps)(SimulationMenuButton);