getURL.js (5137B)
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 { parse } from "../url"; 6 7 const { 8 getUnicodeHostname, 9 getUnicodeUrlPath, 10 } = require("resource://devtools/client/shared/unicode-url.js"); 11 12 export function getFilenameFromPath(pathname) { 13 let filename = ""; 14 if (pathname) { 15 filename = pathname.substring(pathname.lastIndexOf("/") + 1); 16 // This file does not have a name. Default should be (index). 17 if (filename == "") { 18 filename = "(index)"; 19 } else if (filename == ":formatted") { 20 filename = "(index:formatted)"; 21 } 22 } 23 return filename; 24 } 25 26 function getFileExtension(path) { 27 if (!path) { 28 return ""; 29 } 30 31 const lastIndex = path.lastIndexOf("."); 32 return lastIndex !== -1 ? path.slice(lastIndex + 1).toLowerCase() : ""; 33 } 34 35 const bundlerGroups = { 36 "webpack:": "Webpack", 37 "ng:": "Angular", 38 "turbopack:": "Turbopack", 39 }; 40 41 const NoDomain = "(no domain)"; 42 const def = { 43 path: "", 44 search: "", 45 group: "", 46 filename: "", 47 fileExtension: "", 48 }; 49 50 /** 51 * Compute the URL which may be displayed in the Source Tree. 52 * 53 * @param {string} url 54 * The source absolute URL as a string 55 * @param {string} extensionName 56 * Optional, but mandatory when passing a moz-extension URL. 57 * Name of the extension serving this moz-extension source. 58 * @return URL Object 59 * A URL object to represent this source. 60 * 61 * Note that this isn't the standard URL object. 62 * This is augmented with custom properties like: 63 * - `group`, which is mostly the host of the source's URL. 64 * This is used to sort sources in the Source tree. 65 * - `filename` which may not be quite matching the URL. 66 * When files are loaded from "/", they won't have a real name, 67 * but instead this will report "(index)". 68 * - `fileExtension`, lowercased file extension of the source 69 * (if any extension is available) 70 * - `path` and `pathname` have some special behavior. 71 * See `parse` implementation. 72 */ 73 // eslint-disable-next-line complexity 74 export function getDisplayURL(url, extensionName = null) { 75 if (!url) { 76 return def; 77 } 78 79 let { pathname, search, protocol, host, origin } = parse(url); 80 81 // Decode encoded characters early so that all other code rely on decoded strings 82 pathname = getUnicodeUrlPath(pathname); 83 search = getUnicodeUrlPath(search); 84 host = getUnicodeHostname(host); 85 86 const filename = getFilenameFromPath(pathname); 87 88 switch (protocol) { 89 case "javascript:": 90 // Ignore `javascript:` URLs for now 91 return def; 92 93 case "moz-extension:": 94 return { 95 ...def, 96 path: pathname, 97 search, 98 filename, 99 fileExtension: getFileExtension(pathname), 100 // For moz-extension, we replace the uuid by the extension name 101 // that we receive from the SourceActor.extensionName attribute. 102 // `extensionName` might be null for content script of disabled add-ons. 103 group: extensionName || `${protocol}//${host}`, 104 origin: `${protocol}//${host}`, 105 }; 106 case "resource:": 107 return { 108 ...def, 109 path: pathname, 110 search, 111 filename, 112 fileExtension: getFileExtension(pathname), 113 group: `${protocol}//${host || ""}`, 114 origin: `${protocol}//${host || ""}`, 115 }; 116 117 case "about:": 118 // An about page is a special case 119 return { 120 ...def, 121 path: "/", 122 search, 123 filename, 124 fileExtension: getFileExtension("/"), 125 group: getUnicodeUrlPath(url), 126 origin: getUnicodeUrlPath(url), 127 }; 128 129 case "data:": 130 return { 131 ...def, 132 path: "/", 133 search, 134 filename: url, 135 fileExtension: getFileExtension("/"), 136 group: NoDomain, 137 origin: protocol, 138 }; 139 140 case "": 141 if (pathname && pathname.startsWith("/")) { 142 // use file protocol for a URL like "/foo/bar.js" 143 return { 144 ...def, 145 path: pathname, 146 search, 147 filename, 148 fileExtension: getFileExtension(pathname), 149 group: "file://", 150 origin: "file://", 151 }; 152 } else if (!host) { 153 return { 154 ...def, 155 path: pathname, 156 search, 157 filename, 158 fileExtension: getFileExtension(pathname), 159 group: "", 160 origin: "", 161 }; 162 } 163 break; 164 165 case "http:": 166 case "https:": 167 return { 168 ...def, 169 path: pathname, 170 search, 171 filename, 172 fileExtension: getFileExtension(pathname), 173 group: host, 174 origin, 175 }; 176 } 177 178 return { 179 ...def, 180 path: host + pathname, 181 search, 182 fileExtension: getFileExtension(pathname), 183 filename: filename ? filename : host, 184 group: protocol ? bundlerGroups[protocol] || `${protocol}//` : "", 185 origin: origin && origin !== "null" ? origin : `${protocol}//${host || ""}`, 186 }; 187 }