ExtensionDetail.js (6236B)
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 const { 14 connect, 15 } = require("resource://devtools/client/shared/vendor/react-redux.js"); 16 17 const FluentReact = require("resource://devtools/client/shared/vendor/fluent-react.js"); 18 const Localized = createFactory(FluentReact.Localized); 19 20 const { 21 getCurrentRuntimeDetails, 22 } = require("resource://devtools/client/aboutdebugging/src/modules/runtimes-state-helper.js"); 23 24 const DetailsLog = createFactory( 25 require("resource://devtools/client/aboutdebugging/src/components/shared/DetailsLog.js") 26 ); 27 const FieldPair = createFactory( 28 require("resource://devtools/client/aboutdebugging/src/components/debugtarget/FieldPair.js") 29 ); 30 const Message = createFactory( 31 require("resource://devtools/client/aboutdebugging/src/components/shared/Message.js") 32 ); 33 34 const { 35 EXTENSION_BGSCRIPT_STATUSES, 36 MESSAGE_LEVEL, 37 RUNTIMES, 38 } = require("resource://devtools/client/aboutdebugging/src/constants.js"); 39 const Types = require("resource://devtools/client/aboutdebugging/src/types/index.js"); 40 41 /** 42 * This component displays detail information for extension. 43 */ 44 class ExtensionDetail extends PureComponent { 45 static get propTypes() { 46 return { 47 children: PropTypes.node, 48 // Provided by wrapping the component with FluentReact.withLocalization. 49 getString: PropTypes.func.isRequired, 50 // Provided by redux state 51 runtimeDetails: Types.runtimeDetails.isRequired, 52 target: Types.debugTarget.isRequired, 53 }; 54 } 55 56 renderWarnings() { 57 const { warnings } = this.props.target.details; 58 59 if (!warnings.length) { 60 return null; 61 } 62 63 return dom.section( 64 { 65 className: "debug-target-item__messages", 66 }, 67 warnings.map((warning, index) => { 68 return Message( 69 { 70 level: MESSAGE_LEVEL.WARNING, 71 isCloseable: true, 72 key: `warning-${index}`, 73 }, 74 DetailsLog( 75 { 76 type: MESSAGE_LEVEL.WARNING, 77 }, 78 dom.p( 79 { 80 className: "technical-text", 81 }, 82 warning 83 ) 84 ) 85 ); 86 }) 87 ); 88 } 89 90 renderUUID() { 91 const { uuid } = this.props.target.details; 92 if (!uuid) { 93 return null; 94 } 95 96 return Localized( 97 { 98 id: "about-debugging-extension-uuid", 99 attrs: { label: true }, 100 }, 101 FieldPair({ 102 label: "Internal UUID", 103 value: uuid, 104 }) 105 ); 106 } 107 108 renderExtensionId() { 109 const { id } = this.props.target; 110 111 return Localized( 112 { 113 id: "about-debugging-extension-id", 114 attrs: { label: true }, 115 }, 116 FieldPair({ 117 label: "Extension ID", 118 value: id, 119 }) 120 ); 121 } 122 123 renderLocation() { 124 const { location } = this.props.target.details; 125 if (!location) { 126 return null; 127 } 128 129 return Localized( 130 { 131 id: "about-debugging-extension-location", 132 attrs: { label: true }, 133 }, 134 FieldPair({ 135 label: "Location", 136 value: location, 137 }) 138 ); 139 } 140 141 renderManifest() { 142 // Manifest links are only relevant when debugging the current Firefox 143 // instance. 144 if (this.props.runtimeDetails.info.type !== RUNTIMES.THIS_FIREFOX) { 145 return null; 146 } 147 148 const { manifestURL } = this.props.target.details; 149 const link = dom.a( 150 { 151 className: "qa-manifest-url", 152 href: manifestURL, 153 target: "_blank", 154 }, 155 manifestURL 156 ); 157 158 return Localized( 159 { 160 id: "about-debugging-extension-manifest-url", 161 attrs: { label: true }, 162 }, 163 FieldPair({ 164 label: "Manifest URL", 165 value: link, 166 }) 167 ); 168 } 169 170 renderBackgroundScriptStatus() { 171 // The status of the background script is only relevant if it is 172 // not persistent. 173 const { persistentBackgroundScript } = this.props.target.details; 174 if (!(persistentBackgroundScript === false)) { 175 return null; 176 } 177 178 const { backgroundScriptStatus } = this.props.target.details; 179 180 let status; 181 let statusLocalizationId; 182 let statusClassName; 183 184 if (backgroundScriptStatus === EXTENSION_BGSCRIPT_STATUSES.RUNNING) { 185 status = `extension-backgroundscript__status--running`; 186 statusLocalizationId = `about-debugging-extension-backgroundscript-status-running`; 187 statusClassName = `extension-backgroundscript__status--running`; 188 } else { 189 status = `extension-backgroundscript__status--stopped`; 190 statusLocalizationId = `about-debugging-extension-backgroundscript-status-stopped`; 191 statusClassName = `extension-backgroundscript__status--stopped`; 192 } 193 194 return Localized( 195 { 196 id: "about-debugging-extension-backgroundscript", 197 attrs: { label: true }, 198 }, 199 FieldPair({ 200 label: "Background Script", 201 value: Localized( 202 { 203 id: statusLocalizationId, 204 }, 205 dom.span( 206 { 207 className: `extension-backgroundscript__status qa-extension-backgroundscript-status ${statusClassName}`, 208 }, 209 status 210 ) 211 ), 212 }) 213 ); 214 } 215 216 render() { 217 return dom.section( 218 { 219 className: "debug-target-item__detail", 220 }, 221 this.renderWarnings(), 222 dom.dl( 223 {}, 224 this.renderLocation(), 225 this.renderExtensionId(), 226 this.renderUUID(), 227 this.renderManifest(), 228 this.renderBackgroundScriptStatus(), 229 this.props.children 230 ) 231 ); 232 } 233 } 234 235 const mapStateToProps = state => { 236 return { 237 runtimeDetails: getCurrentRuntimeDetails(state.runtimes), 238 }; 239 }; 240 241 module.exports = FluentReact.withLocalization( 242 connect(mapStateToProps)(ExtensionDetail) 243 );