Use URL.parse with polyfill

This commit is contained in:
Lim Chee Aun 2024-06-14 08:34:50 +08:00
parent febd04dd54
commit 1f8a8f8928
18 changed files with 62 additions and 52 deletions

View file

@ -7,6 +7,7 @@
"^[^.].*.css$",
"index.css$",
".css$",
"./polyfills",
"<THIRD_PARTY_MODULES>",
"/assets/",
"^../",

View file

@ -231,7 +231,7 @@ function AccountInfo({
const accountInstance = useMemo(() => {
if (!url) return null;
const domain = punycode.toUnicode(new URL(url).hostname);
const domain = punycode.toUnicode(URL.parse(url).hostname);
return domain;
}, [url]);
@ -1655,7 +1655,7 @@ function lightenRGB([r, g, b]) {
function niceAccountURL(url) {
if (!url) return;
const urlObj = new URL(url);
const urlObj = URL.parse(url);
const { host, pathname } = urlObj;
const path = pathname.replace(/\/$/, '').replace(/^\//, '');
return (

View file

@ -58,7 +58,7 @@ function AccountSheet({ account, instance: propInstance, onClose }) {
if (result.accounts.length) {
return result.accounts[0];
} else if (/https?:\/\/[^/]+\/@/.test(account)) {
const accountURL = new URL(account);
const accountURL = URL.parse(account);
const { hostname, pathname } = accountURL;
const acct =
pathname.replace(/^\//, '').replace(/\/$/, '') +

View file

@ -3292,11 +3292,11 @@ function GIFPickerModal({ onClose = () => {}, onSelect = () => {} }) {
width = (width / height) * 100;
height = 100;
}
const urlObj = new URL(url);
const urlObj = URL.parse(url);
const strippedURL = urlObj.origin + urlObj.pathname;
let strippedWebP;
if (webp) {
const webpObj = new URL(webp);
const webpObj = URL.parse(webp);
strippedWebP = webpObj.origin + webpObj.pathname;
}
return (
@ -3306,7 +3306,7 @@ function GIFPickerModal({ onClose = () => {}, onSelect = () => {} }) {
onClick={() => {
const { mp4, url } = original;
const theURL = mp4 || url;
const urlObj = new URL(theURL);
const urlObj = URL.parse(theURL);
const strippedURL = urlObj.origin + urlObj.pathname;
onClose();
onSelect({

View file

@ -22,15 +22,13 @@ const Link = forwardRef((props, ref) => {
// Handle encodeURIComponent of searchParams values
if (!!hash && hash !== '/' && hash.includes('?')) {
try {
const parsedHash = new URL(hash, location.origin); // Fake base URL
if (parsedHash.searchParams.size) {
const parsedHash = URL.parse(hash, location.origin); // Fake base URL
if (parsedHash?.searchParams?.size) {
const searchParamsStr = Array.from(parsedHash.searchParams.entries())
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
.join('&');
hash = parsedHash.pathname + '?' + searchParamsStr;
}
} catch (e) {}
}
const isActive = hash === to || decodeURIComponent(hash) === to;

View file

@ -674,12 +674,8 @@ function Media({
}
function getURLObj(url) {
try {
// Fake base URL if url doesn't have https:// prefix
return new URL(url, location.origin);
} catch (e) {
return null;
}
return URL.parse(url, location.origin);
}
export default Media;

View file

@ -2535,7 +2535,9 @@ function Card({ card, selfReferential, instance }) {
if (hasText && (image || (type === 'photo' && blurhash))) {
const domain = punycode.toUnicode(
new URL(url).hostname.replace(/^www\./, '').replace(/\/$/, ''),
URL.parse(url)
.hostname.replace(/^www\./, '')
.replace(/\/$/, ''),
);
let blurhashImage;
const rgbAverageColor =
@ -2662,7 +2664,7 @@ function Card({ card, selfReferential, instance }) {
}
if (hasText && !image) {
const domain = punycode.toUnicode(
new URL(url).hostname.replace(/^www\./, ''),
URL.parse(url).hostname.replace(/^www\./, ''),
);
return (
<a
@ -2863,7 +2865,7 @@ function generateHTMLCode(post, instance, level = 0) {
const mediaURL = previewMediaURL || sourceMediaURL;
const sourceMediaURLObj = sourceMediaURL
? new URL(sourceMediaURL)
? URL.parse(sourceMediaURL)
: null;
const isVideoMaybe =
type === 'unknown' &&
@ -3188,7 +3190,7 @@ function StatusButton({
function nicePostURL(url) {
if (!url) return;
const urlObj = new URL(url);
const urlObj = URL.parse(url);
const { host, pathname } = urlObj;
const path = pathname.replace(/\/$/, '');
// split only first slash

View file

@ -2,6 +2,8 @@ import './index.css';
import './app.css';
import './polyfills';
import { render } from 'preact';
import { useEffect, useState } from 'preact/hooks';

View file

@ -2,6 +2,8 @@ import './index.css';
import './cloak-mode.css';
import './polyfills';
// Polyfill needed for Firefox < 122
// https://bugzilla.mozilla.org/show_bug.cgi?id=1423593
// import '@formatjs/intl-segmenter/polyfill';
@ -14,19 +16,6 @@ if (import.meta.env.DEV) {
import('preact/debug');
}
// AbortSignal.timeout polyfill
// Temporary fix from https://github.com/mo/abortcontroller-polyfill/issues/73#issuecomment-1541180943
// Incorrect implementation, but should be good enough for now
if ('AbortSignal' in window) {
AbortSignal.timeout =
AbortSignal.timeout ||
((duration) => {
const controller = new AbortController();
setTimeout(() => controller.abort(), duration);
return controller.signal;
});
}
render(
<HashRouter>
<App />

View file

@ -467,7 +467,7 @@ function AccountStatuses() {
const accountInstance = useMemo(() => {
if (!account?.url) return null;
const domain = new URL(account.url).hostname;
const domain = URL.parse(account.url).hostname;
return domain;
}, [account]);
const sameInstance = instance === accountInstance;

View file

@ -1111,8 +1111,8 @@ function Catchup() {
publishedAt,
} = card;
const domain = punycode.toUnicode(
new URL(url).hostname
.replace(/^www\./, '')
URL.parse(url)
.hostname.replace(/^www\./, '')
.replace(/\/$/, ''),
);
let accentColor;

View file

@ -569,7 +569,7 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
if (!heroStatus) return;
const { url } = heroStatus;
if (!url) return;
return new URL(url).hostname;
return URL.parse(url).hostname;
}, [heroStatus]);
const postSameInstance = useMemo(() => {
if (!postInstance) return;

View file

@ -178,7 +178,9 @@ function Trending({ columnMode, ...props }) {
width,
} = link;
const domain = punycode.toUnicode(
new URL(url).hostname.replace(/^www\./, '').replace(/\/$/, ''),
URL.parse(url)
.hostname.replace(/^www\./, '')
.replace(/\/$/, ''),
);
let accentColor;
if (blurhash) {

24
src/polyfills.js Normal file
View file

@ -0,0 +1,24 @@
// AbortSignal.timeout polyfill
// Temporary fix from https://github.com/mo/abortcontroller-polyfill/issues/73#issuecomment-1541180943
// Incorrect implementation, but should be good enough for now
if ('AbortSignal' in window) {
AbortSignal.timeout =
AbortSignal.timeout ||
((duration) => {
const controller = new AbortController();
setTimeout(() => controller.abort(), duration);
return controller.signal;
});
}
// URL.parse() polyfill
if ('URL' in window && typeof URL.parse !== 'function') {
URL.parse = function (url, base) {
if (!url) return null;
try {
return base ? new URL(url, base) : new URL(url);
} catch (e) {
return null;
}
};
}

View file

@ -11,7 +11,7 @@ const statusPostRegexes = [
export function getInstanceStatusObject(url) {
// Regex /:username/:id, where username = @username or @username@domain, id = anything
const { hostname, pathname } = new URL(url);
const { hostname, pathname } = URL.parse(url);
// const [, username, domain, id] = pathname.match(statusRegex) || [];
for (const regex of statusPostRegexes) {
const [, id] = pathname.match(regex) || [];

View file

@ -1,6 +1,6 @@
export default function isMastodonLinkMaybe(url) {
try {
const { pathname, hash } = new URL(url);
const { pathname, hash } = URL.parse(url);
return (
/^\/.*\/\d+$/i.test(pathname) ||
/^\/(@[^/]+|users\/[^/]+)\/(statuses|posts)\/\w+\/?$/i.test(pathname) || // GoToSocial, Takahe

View file

@ -1,5 +1,5 @@
export default function openCompose(opts) {
const url = new URL('/compose/', window.location);
const url = URL.parse('/compose/', window.location);
const { width: screenWidth, height: screenHeight } = window.screen;
const left = Math.max(0, (screenWidth - 600) / 2);
const top = Math.max(0, (screenHeight - 450) / 2);

View file

@ -59,12 +59,8 @@ function _unfurlMastodonLink(instance, url) {
theURL = `https://${finalURL}`;
}
let urlObj;
try {
urlObj = new URL(theURL);
} catch (e) {
return;
}
const urlObj = URL.parse(theURL);
if (!urlObj) return;
const domain = urlObj.hostname;
const path = urlObj.pathname;
// Regex /:username/:id, where username = @username or @username@domain, id = post ID