github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/web/src/PathBuilder.tsx (about)

     1  import React, { useContext } from "react"
     2  
     3  // A little helper class for building paths relative to the root of the app.
     4  class PathBuilder {
     5    private protocol: string
     6    private host: string
     7    private snapId: string = ""
     8  
     9    static forTesting(host: string, pathname: string) {
    10      return new PathBuilder({
    11        protocol: "http:",
    12        host: host,
    13        pathname: pathname,
    14      })
    15    }
    16  
    17    constructor(loc: { protocol: string; host: string; pathname: string }) {
    18      this.host = loc.host
    19      this.protocol = loc.protocol
    20  
    21      const snapshotRe = new RegExp("^/snapshot/([^/]+)")
    22      let snapMatch = snapshotRe.exec(loc.pathname)
    23      if (snapMatch) {
    24        this.snapId = snapMatch[1]
    25      }
    26    }
    27  
    28    getDataUrl() {
    29      if (this.isSnapshot()) {
    30        return this.snapshotDataUrl()
    31      }
    32      return this.isSecure()
    33        ? `wss://${this.host}/ws/view`
    34        : `ws://${this.host}/ws/view`
    35    }
    36  
    37    isSecure(): boolean {
    38      return this.protocol === "https:"
    39    }
    40  
    41    isSnapshot(): boolean {
    42      return this.snapId !== ""
    43    }
    44  
    45    private snapshotDataUrl(): string {
    46      return `/api/snapshot/${this.snapId}`
    47    }
    48  
    49    private snapshotPathBase(): string {
    50      return `/snapshot/${this.snapId}`
    51    }
    52  
    53    rootPath() {
    54      if (this.isSnapshot()) {
    55        return this.snapshotPathBase()
    56      }
    57      return ""
    58    }
    59  
    60    path(relPath: string): string {
    61      if (relPath[0] !== "/") {
    62        throw new Error('relPath should start with "/", actual:' + relPath)
    63      }
    64      return this.rootPath() + relPath
    65    }
    66  
    67    // A template literal function for encoding paths.
    68    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
    69    encpath(strings: TemplateStringsArray, ...values: string[]): string {
    70      let result = [strings[0]]
    71      for (let i = 0; i < values.length; i++) {
    72        result.push(encodeURIComponent(values[i]), strings[i + 1])
    73      }
    74      return this.path(result.join(""))
    75    }
    76  }
    77  
    78  export default PathBuilder
    79  
    80  const pathBuilderContext = React.createContext<PathBuilder>(
    81    new PathBuilder(window.location)
    82  )
    83  
    84  export function usePathBuilder(): PathBuilder {
    85    return useContext(pathBuilderContext)
    86  }
    87  export const PathBuilderProvider = pathBuilderContext.Provider