StatusCode.js (3775B)
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 Component, 9 } = require("resource://devtools/client/shared/vendor/react.mjs"); 10 const dom = require("resource://devtools/client/shared/vendor/react-dom-factories.js"); 11 const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.mjs"); 12 const { 13 L10N, 14 } = require("resource://devtools/client/netmonitor/src/utils/l10n.js"); 15 const { 16 propertiesEqual, 17 } = require("resource://devtools/client/netmonitor/src/utils/request-utils.js"); 18 19 const { div, span } = dom; 20 21 const UPDATED_STATUS_PROPS = [ 22 "earlyHintsStatus", 23 "fromCache", 24 "fromServiceWorker", 25 "status", 26 "statusText", 27 "blockedReason", 28 ]; 29 30 /** 31 * Status code component 32 * Displays HTTP status code icon 33 * Used in RequestListColumnStatus and HeadersPanel 34 */ 35 class StatusCode extends Component { 36 static get propTypes() { 37 return { 38 item: PropTypes.object.isRequired, 39 }; 40 } 41 42 shouldComponentUpdate(nextProps) { 43 return !propertiesEqual( 44 UPDATED_STATUS_PROPS, 45 this.props.item, 46 nextProps.item 47 ); 48 } 49 50 render() { 51 const { item } = this.props; 52 const { 53 fromCache, 54 fromServiceWorker, 55 status, 56 statusText, 57 earlyHintsStatus, 58 blockedReason, 59 } = item; 60 let code; 61 62 if (status) { 63 if (fromCache) { 64 code = "cached"; 65 } else if (fromServiceWorker) { 66 code = "service worker"; 67 } else { 68 code = status; 69 } 70 } 71 72 if (blockedReason) { 73 return div( 74 { 75 className: 76 "requests-list-status-code status-code status-code-blocked", 77 title: L10N.getStr("networkMenu.blockedTooltip"), 78 }, 79 div({ 80 className: "status-code-blocked-icon", 81 }) 82 ); 83 } 84 85 const statusInfo = [ 86 { 87 status, 88 statusText, 89 code, 90 }, 91 ]; 92 if (earlyHintsStatus) { 93 statusInfo.unshift({ 94 status: earlyHintsStatus, 95 statusText: "", 96 code: earlyHintsStatus, 97 }); 98 } 99 100 // `data-code` refers to the status-code 101 // `data-status-code` can be one of "cached", "service worker" 102 // or the status-code itself 103 // For example - if a resource is cached, `data-code` would be 200 104 // and the `data-status-code` would be "cached" 105 return div( 106 {}, 107 statusInfo.map(info => { 108 if (!info.status) { 109 return null; 110 } 111 return span( 112 { 113 className: "requests-list-status-code status-code", 114 onMouseOver({ target }) { 115 if (info.status && info.statusText && !target.title) { 116 target.title = getStatusTooltip(item); 117 } 118 }, 119 "data-status-code": info.code, 120 "data-code": info.status, 121 }, 122 info.status 123 ); 124 }) 125 ); 126 } 127 } 128 129 function getStatusTooltip(item) { 130 const { fromCache, fromServiceWorker, status, statusText } = item; 131 let title; 132 if (fromCache && fromServiceWorker) { 133 title = L10N.getFormatStr( 134 "netmonitor.status.tooltip.cachedworker", 135 status, 136 statusText 137 ); 138 } else if (fromCache) { 139 title = L10N.getFormatStr( 140 "netmonitor.status.tooltip.cached", 141 status, 142 statusText 143 ); 144 } else if (fromServiceWorker) { 145 title = L10N.getFormatStr( 146 "netmonitor.status.tooltip.worker", 147 status, 148 statusText 149 ); 150 } else { 151 title = L10N.getFormatStr( 152 "netmonitor.status.tooltip.simple", 153 status, 154 statusText 155 ); 156 } 157 return title; 158 } 159 160 module.exports = StatusCode;