diff --git a/src/Wes95/components/Link.tsx b/src/Wes95/components/Link.tsx index c8902a5..f413929 100644 --- a/src/Wes95/components/Link.tsx +++ b/src/Wes95/components/Link.tsx @@ -1,5 +1,6 @@ import type { JSX } from 'solid-js'; import { WindowManager } from '../lib/WindowManager'; +import { createURL } from '../utils/url'; export function Link( p: { alwaysExternal?: boolean } & JSX.AnchorHTMLAttributes, @@ -9,7 +10,7 @@ export function Link( return; } - const url = new URL(p.href); + const url = createURL(p.href); const isApp = url.protocol === 'app:' || url.protocol === 'system:'; const isHTTP = url.protocol === 'http:' || url.protocol === 'https:'; diff --git a/src/Wes95/lib/FileSystemManager.ts b/src/Wes95/lib/FileSystemManager.ts index 930cbe6..7dce7b3 100644 --- a/src/Wes95/lib/FileSystemManager.ts +++ b/src/Wes95/lib/FileSystemManager.ts @@ -1,6 +1,7 @@ import { trpc } from '../../trpc/client'; import type { MenuItem } from '../components/Menu'; import type { AstroContentEntry } from '../models/AstroContent'; +import { createURL } from '../utils/url'; let shared: FileSystemManager | undefined; @@ -253,7 +254,7 @@ export class FileSystemManager { return undefined; } - const url = new URL(file.url); + const url = createURL(file.url); if (url.protocol === 'astro-content:') { return trpc.wes95_fileSystem.getEntry.query({ diff --git a/src/Wes95/lib/SessionManager.ts b/src/Wes95/lib/SessionManager.ts index 57f4542..5f0934b 100644 --- a/src/Wes95/lib/SessionManager.ts +++ b/src/Wes95/lib/SessionManager.ts @@ -1,5 +1,6 @@ import { collect } from '../../utils/plausible'; import type { WindowState } from '../models/WindowState'; +import { createURL } from '../utils/url'; import { ScreenManager } from './ScreenManager'; import { WindowManager } from './WindowManager'; @@ -163,7 +164,7 @@ export class SessionManager { continue; } - const url = new URL('app://' + app); + const url = createURL('app://' + app); for (let i = 0; i < params.length; i += 2) { const key = Tokens.parameters[params[i]!]; diff --git a/src/Wes95/utils/Windows.ts b/src/Wes95/utils/Windows.ts index b1bbc24..50230c2 100644 --- a/src/Wes95/utils/Windows.ts +++ b/src/Wes95/utils/Windows.ts @@ -1,8 +1,9 @@ import type { JSX } from 'solid-js/jsx-runtime'; +import type { z } from 'zod'; import type { WindowLibrary, WindowManagerState } from '../lib/WindowManager'; import type { Rect } from '../models/Geometry'; import type { WindowState } from '../models/WindowState'; -import type { z } from 'zod'; +import { createURL, type URLObject } from './url'; export function addActiveWindowToHistory( windowId: string, @@ -25,7 +26,7 @@ export function createWindowURL( urlString: string, object: Record, ) { - const url = new URL(urlString); + const url = createURL(urlString); for (const [key, value] of Object.entries(object)) { if (typeof value === 'string' || typeof value === 'number') { @@ -148,11 +149,11 @@ export function parseWindowURL( }>) ), z.AnyZodObject, - URL, + URLObject, 'sync' | 'async', ] | never[] { - const url = new URL(urlString); + const url = createURL(urlString); const programName = url.hostname; const windowName = url.pathname.replace(/^\//, '').replace(/\\/g, '_'); diff --git a/src/Wes95/utils/url.ts b/src/Wes95/utils/url.ts index 1a28aaa..b12f9be 100644 --- a/src/Wes95/utils/url.ts +++ b/src/Wes95/utils/url.ts @@ -1,7 +1,43 @@ +export type URLObject = { + hash: string; + host: string; + hostname: string; + href: string; + origin: string; + password: string; + pathname: string; + port: string; + protocol: string; + search: string; + searchParams: URLSearchParams; + username: string; +}; + function adjustPath(path: string) { return path.replace('My Document', 'My_Document'); } +export const createURL = (urlString: string): URLObject => { + const url = new URL(urlString); + + if (url.hostname !== '' || !/^\/\//.test(url.pathname)) { + console.log(url); + return urlToObject(url); + } + + // Fuck Firefox + const matches = url.pathname.match(/\/\/(?[^/]+)(?.+)/); + if (!matches?.groups?.hostname || !matches?.groups?.pathname) { + throw new Error('Unable to infer hostname and pathname from pathname'); + } + + return { + ...urlToObject(url), + hostname: matches.groups.hostname, + pathname: matches.groups.pathname, + }; +}; + export function getRealPublicURL(path: string | undefined) { if (!path) { return; @@ -17,14 +53,31 @@ export function getRealPublicURL(path: string | undefined) { } export function getURLHostname(url: string) { - return new URL(url).hostname; + return createURL(url).hostname; } export function isAppURL(string: string) { try { - const url = new URL(string); + const url = createURL(string); return ['app:', 'system:'].includes(url.protocol) ? url : undefined; } catch { return; } } + +export const urlToObject = (url: URL) => { + return { + hash: url.hash, + host: url.host, + hostname: url.hostname, + href: url.href, + origin: url.origin, + password: url.password, + pathname: url.pathname, + port: url.port, + protocol: url.protocol, + search: url.search, + searchParams: url.searchParams, + username: url.username, + }; +};