DOMMutationBreakpoints.js (5548B)
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 import React, { Component } from "devtools/client/shared/vendor/react"; 6 import { 7 div, 8 input, 9 li, 10 ul, 11 } from "devtools/client/shared/vendor/react-dom-factories"; 12 import PropTypes from "devtools/client/shared/vendor/react-prop-types"; 13 14 const Reps = ChromeUtils.importESModule( 15 "resource://devtools/client/shared/components/reps/index.mjs" 16 ); 17 const { 18 REPS: { Rep }, 19 MODE, 20 } = Reps; 21 import { translateNodeFrontToGrip } from "devtools/client/inspector/shared/utils"; 22 23 import { 24 deleteDOMMutationBreakpoint, 25 toggleDOMMutationBreakpointState, 26 } from "devtools/client/framework/actions/index"; 27 28 import actions from "../../actions/index"; 29 import { connect } from "devtools/client/shared/vendor/react-redux"; 30 31 import { CloseButton } from "../shared/Button/index"; 32 33 const localizationTerms = { 34 subtree: L10N.getStr("domMutationTypes.subtree"), 35 attribute: L10N.getStr("domMutationTypes.attribute"), 36 removal: L10N.getStr("domMutationTypes.removal"), 37 }; 38 39 class DOMMutationBreakpointsContents extends Component { 40 static get propTypes() { 41 return { 42 breakpoints: PropTypes.array.isRequired, 43 deleteBreakpoint: PropTypes.func.isRequired, 44 highlightDomElement: PropTypes.func.isRequired, 45 openElementInInspector: PropTypes.func.isRequired, 46 openInspector: PropTypes.func.isRequired, 47 setSkipPausing: PropTypes.func.isRequired, 48 toggleBreakpoint: PropTypes.func.isRequired, 49 unHighlightDomElement: PropTypes.func.isRequired, 50 }; 51 } 52 53 handleBreakpoint(breakpointId, shouldEnable) { 54 const { toggleBreakpoint, setSkipPausing } = this.props; 55 56 // The user has enabled a mutation breakpoint so we should no 57 // longer skip pausing 58 if (shouldEnable) { 59 setSkipPausing(false); 60 } 61 toggleBreakpoint(breakpointId, shouldEnable); 62 } 63 64 renderItem(breakpoint) { 65 const { 66 openElementInInspector, 67 highlightDomElement, 68 unHighlightDomElement, 69 deleteBreakpoint, 70 } = this.props; 71 const { enabled, id: breakpointId, nodeFront, mutationType } = breakpoint; 72 73 return li( 74 { 75 key: breakpoint.id, 76 }, 77 input({ 78 type: "checkbox", 79 checked: enabled, 80 onChange: () => this.handleBreakpoint(breakpointId, !enabled), 81 }), 82 div( 83 { 84 className: "dom-mutation-info", 85 }, 86 div( 87 { 88 className: "dom-mutation-label", 89 }, 90 Rep({ 91 object: translateNodeFrontToGrip(nodeFront), 92 mode: MODE.TINY, 93 onDOMNodeClick: () => openElementInInspector(nodeFront), 94 onInspectIconClick: () => openElementInInspector(nodeFront), 95 onDOMNodeMouseOver: () => highlightDomElement(nodeFront), 96 onDOMNodeMouseOut: () => unHighlightDomElement(), 97 }) 98 ), 99 div( 100 { 101 className: "dom-mutation-type", 102 }, 103 localizationTerms[mutationType] || mutationType 104 ) 105 ), 106 React.createElement(CloseButton, { 107 handleClick: () => deleteBreakpoint(nodeFront, mutationType), 108 }) 109 ); 110 } 111 112 /* eslint-disable react/no-danger */ 113 renderEmpty() { 114 const { openInspector } = this.props; 115 const text = L10N.getFormatStr( 116 "noDomMutationBreakpoints", 117 `<a>${L10N.getStr("inspectorTool")}</a>` 118 ); 119 return div( 120 { 121 className: "dom-mutation-empty", 122 }, 123 div({ 124 onClick: () => openInspector(), 125 dangerouslySetInnerHTML: { 126 __html: text, 127 }, 128 }) 129 ); 130 } 131 132 render() { 133 const { breakpoints } = this.props; 134 135 if (breakpoints.length === 0) { 136 return this.renderEmpty(); 137 } 138 return ul( 139 { 140 className: "dom-mutation-list", 141 }, 142 breakpoints.map(breakpoint => this.renderItem(breakpoint)) 143 ); 144 } 145 } 146 147 const mapStateToProps = state => ({ 148 breakpoints: state.domMutationBreakpoints.breakpoints, 149 }); 150 151 const DOMMutationBreakpointsPanel = connect( 152 mapStateToProps, 153 { 154 deleteBreakpoint: deleteDOMMutationBreakpoint, 155 toggleBreakpoint: toggleDOMMutationBreakpointState, 156 }, 157 undefined, 158 { storeKey: "toolbox-store" } 159 )(DOMMutationBreakpointsContents); 160 161 class DomMutationBreakpoints extends Component { 162 static get propTypes() { 163 return { 164 highlightDomElement: PropTypes.func.isRequired, 165 openElementInInspector: PropTypes.func.isRequired, 166 openInspector: PropTypes.func.isRequired, 167 setSkipPausing: PropTypes.func.isRequired, 168 unHighlightDomElement: PropTypes.func.isRequired, 169 }; 170 } 171 172 render() { 173 return React.createElement(DOMMutationBreakpointsPanel, { 174 openElementInInspector: this.props.openElementInInspector, 175 highlightDomElement: this.props.highlightDomElement, 176 unHighlightDomElement: this.props.unHighlightDomElement, 177 setSkipPausing: this.props.setSkipPausing, 178 openInspector: this.props.openInspector, 179 }); 180 } 181 } 182 183 export default connect(undefined, { 184 // the debugger-specific action bound to the debugger store 185 // since there is no `storeKey` 186 openElementInInspector: actions.openElementInInspectorCommand, 187 highlightDomElement: actions.highlightDomElement, 188 unHighlightDomElement: actions.unHighlightDomElement, 189 setSkipPausing: actions.setSkipPausing, 190 openInspector: actions.openInspector, 191 })(DomMutationBreakpoints);