InlinePreviews.js (3048B)
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 ReactDOM from "devtools/client/shared/vendor/react-dom"; 7 8 import actions from "../../actions/index"; 9 import PropTypes from "devtools/client/shared/vendor/react-prop-types"; 10 import InlinePreview from "./InlinePreview"; 11 import { connect } from "devtools/client/shared/vendor/react-redux"; 12 import { getInlinePreviews } from "../../selectors/index"; 13 14 function hasPreviews(previews) { 15 return !!previews && !!Object.keys(previews).length; 16 } 17 18 class InlinePreviews extends Component { 19 static get propTypes() { 20 return { 21 editor: PropTypes.object.isRequired, 22 previews: PropTypes.object, 23 }; 24 } 25 26 componentDidMount() { 27 this.renderInlinePreviewMarker(); 28 } 29 30 componentDidUpdate() { 31 this.renderInlinePreviewMarker(); 32 } 33 34 renderInlinePreviewMarker() { 35 const { 36 editor, 37 previews, 38 openElementInInspector, 39 highlightDomElement, 40 unHighlightDomElement, 41 } = this.props; 42 43 if (!previews) { 44 editor.removeLineContentMarker(editor.markerTypes.INLINE_PREVIEW_MARKER); 45 return; 46 } 47 48 editor.setLineContentMarker({ 49 id: editor.markerTypes.INLINE_PREVIEW_MARKER, 50 lines: Object.keys(previews).map(line => { 51 // CM6 line is 1-based. 52 // The preview keys line numbers as strings so cast to number 53 return { 54 line: Number(line), 55 value: previews[line], 56 }; 57 }), 58 createLineElementNode: (line, value) => { 59 const widgetNode = document.createElement("div"); 60 widgetNode.className = "inline-preview"; 61 62 ReactDOM.render( 63 React.createElement( 64 React.Fragment, 65 null, 66 value.map(preview => 67 React.createElement(InlinePreview, { 68 line, 69 key: `${line}-${preview.name}`, 70 type: preview.type, 71 variable: preview.name, 72 value: preview.value, 73 openElementInInspector, 74 highlightDomElement, 75 unHighlightDomElement, 76 }) 77 ) 78 ), 79 widgetNode 80 ); 81 return widgetNode; 82 }, 83 }); 84 } 85 86 componentWillUnmount() { 87 const { editor } = this.props; 88 editor.removeLineContentMarker(editor.markerTypes.INLINE_PREVIEW_MARKER); 89 } 90 91 render() { 92 return null; 93 } 94 } 95 96 const mapStateToProps = state => { 97 const previews = getInlinePreviews(state); 98 if (!hasPreviews(previews)) { 99 return { 100 previews: null, 101 }; 102 } 103 104 return { 105 previews, 106 }; 107 }; 108 109 export default connect(mapStateToProps, { 110 openElementInInspector: actions.openElementInInspectorCommand, 111 highlightDomElement: actions.highlightDomElement, 112 unHighlightDomElement: actions.unHighlightDomElement, 113 })(InlinePreviews);