tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }