Use URL.parse with polyfill
This commit is contained in:
parent
febd04dd54
commit
1f8a8f8928
|
@ -7,6 +7,7 @@
|
||||||
"^[^.].*.css$",
|
"^[^.].*.css$",
|
||||||
"index.css$",
|
"index.css$",
|
||||||
".css$",
|
".css$",
|
||||||
|
"./polyfills",
|
||||||
"<THIRD_PARTY_MODULES>",
|
"<THIRD_PARTY_MODULES>",
|
||||||
"/assets/",
|
"/assets/",
|
||||||
"^../",
|
"^../",
|
||||||
|
|
|
@ -231,7 +231,7 @@ function AccountInfo({
|
||||||
|
|
||||||
const accountInstance = useMemo(() => {
|
const accountInstance = useMemo(() => {
|
||||||
if (!url) return null;
|
if (!url) return null;
|
||||||
const domain = punycode.toUnicode(new URL(url).hostname);
|
const domain = punycode.toUnicode(URL.parse(url).hostname);
|
||||||
return domain;
|
return domain;
|
||||||
}, [url]);
|
}, [url]);
|
||||||
|
|
||||||
|
@ -1655,7 +1655,7 @@ function lightenRGB([r, g, b]) {
|
||||||
|
|
||||||
function niceAccountURL(url) {
|
function niceAccountURL(url) {
|
||||||
if (!url) return;
|
if (!url) return;
|
||||||
const urlObj = new URL(url);
|
const urlObj = URL.parse(url);
|
||||||
const { host, pathname } = urlObj;
|
const { host, pathname } = urlObj;
|
||||||
const path = pathname.replace(/\/$/, '').replace(/^\//, '');
|
const path = pathname.replace(/\/$/, '').replace(/^\//, '');
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -58,7 +58,7 @@ function AccountSheet({ account, instance: propInstance, onClose }) {
|
||||||
if (result.accounts.length) {
|
if (result.accounts.length) {
|
||||||
return result.accounts[0];
|
return result.accounts[0];
|
||||||
} else if (/https?:\/\/[^/]+\/@/.test(account)) {
|
} else if (/https?:\/\/[^/]+\/@/.test(account)) {
|
||||||
const accountURL = new URL(account);
|
const accountURL = URL.parse(account);
|
||||||
const { hostname, pathname } = accountURL;
|
const { hostname, pathname } = accountURL;
|
||||||
const acct =
|
const acct =
|
||||||
pathname.replace(/^\//, '').replace(/\/$/, '') +
|
pathname.replace(/^\//, '').replace(/\/$/, '') +
|
||||||
|
|
|
@ -3292,11 +3292,11 @@ function GIFPickerModal({ onClose = () => {}, onSelect = () => {} }) {
|
||||||
width = (width / height) * 100;
|
width = (width / height) * 100;
|
||||||
height = 100;
|
height = 100;
|
||||||
}
|
}
|
||||||
const urlObj = new URL(url);
|
const urlObj = URL.parse(url);
|
||||||
const strippedURL = urlObj.origin + urlObj.pathname;
|
const strippedURL = urlObj.origin + urlObj.pathname;
|
||||||
let strippedWebP;
|
let strippedWebP;
|
||||||
if (webp) {
|
if (webp) {
|
||||||
const webpObj = new URL(webp);
|
const webpObj = URL.parse(webp);
|
||||||
strippedWebP = webpObj.origin + webpObj.pathname;
|
strippedWebP = webpObj.origin + webpObj.pathname;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
@ -3306,7 +3306,7 @@ function GIFPickerModal({ onClose = () => {}, onSelect = () => {} }) {
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const { mp4, url } = original;
|
const { mp4, url } = original;
|
||||||
const theURL = mp4 || url;
|
const theURL = mp4 || url;
|
||||||
const urlObj = new URL(theURL);
|
const urlObj = URL.parse(theURL);
|
||||||
const strippedURL = urlObj.origin + urlObj.pathname;
|
const strippedURL = urlObj.origin + urlObj.pathname;
|
||||||
onClose();
|
onClose();
|
||||||
onSelect({
|
onSelect({
|
||||||
|
|
|
@ -22,15 +22,13 @@ const Link = forwardRef((props, ref) => {
|
||||||
|
|
||||||
// Handle encodeURIComponent of searchParams values
|
// Handle encodeURIComponent of searchParams values
|
||||||
if (!!hash && hash !== '/' && hash.includes('?')) {
|
if (!!hash && hash !== '/' && hash.includes('?')) {
|
||||||
try {
|
const parsedHash = URL.parse(hash, location.origin); // Fake base URL
|
||||||
const parsedHash = new URL(hash, location.origin); // Fake base URL
|
if (parsedHash?.searchParams?.size) {
|
||||||
if (parsedHash.searchParams.size) {
|
|
||||||
const searchParamsStr = Array.from(parsedHash.searchParams.entries())
|
const searchParamsStr = Array.from(parsedHash.searchParams.entries())
|
||||||
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
|
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
|
||||||
.join('&');
|
.join('&');
|
||||||
hash = parsedHash.pathname + '?' + searchParamsStr;
|
hash = parsedHash.pathname + '?' + searchParamsStr;
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const isActive = hash === to || decodeURIComponent(hash) === to;
|
const isActive = hash === to || decodeURIComponent(hash) === to;
|
||||||
|
|
|
@ -674,12 +674,8 @@ function Media({
|
||||||
}
|
}
|
||||||
|
|
||||||
function getURLObj(url) {
|
function getURLObj(url) {
|
||||||
try {
|
|
||||||
// Fake base URL if url doesn't have https:// prefix
|
// Fake base URL if url doesn't have https:// prefix
|
||||||
return new URL(url, location.origin);
|
return URL.parse(url, location.origin);
|
||||||
} catch (e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Media;
|
export default Media;
|
||||||
|
|
|
@ -2535,7 +2535,9 @@ function Card({ card, selfReferential, instance }) {
|
||||||
|
|
||||||
if (hasText && (image || (type === 'photo' && blurhash))) {
|
if (hasText && (image || (type === 'photo' && blurhash))) {
|
||||||
const domain = punycode.toUnicode(
|
const domain = punycode.toUnicode(
|
||||||
new URL(url).hostname.replace(/^www\./, '').replace(/\/$/, ''),
|
URL.parse(url)
|
||||||
|
.hostname.replace(/^www\./, '')
|
||||||
|
.replace(/\/$/, ''),
|
||||||
);
|
);
|
||||||
let blurhashImage;
|
let blurhashImage;
|
||||||
const rgbAverageColor =
|
const rgbAverageColor =
|
||||||
|
@ -2662,7 +2664,7 @@ function Card({ card, selfReferential, instance }) {
|
||||||
}
|
}
|
||||||
if (hasText && !image) {
|
if (hasText && !image) {
|
||||||
const domain = punycode.toUnicode(
|
const domain = punycode.toUnicode(
|
||||||
new URL(url).hostname.replace(/^www\./, ''),
|
URL.parse(url).hostname.replace(/^www\./, ''),
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
|
@ -2863,7 +2865,7 @@ function generateHTMLCode(post, instance, level = 0) {
|
||||||
const mediaURL = previewMediaURL || sourceMediaURL;
|
const mediaURL = previewMediaURL || sourceMediaURL;
|
||||||
|
|
||||||
const sourceMediaURLObj = sourceMediaURL
|
const sourceMediaURLObj = sourceMediaURL
|
||||||
? new URL(sourceMediaURL)
|
? URL.parse(sourceMediaURL)
|
||||||
: null;
|
: null;
|
||||||
const isVideoMaybe =
|
const isVideoMaybe =
|
||||||
type === 'unknown' &&
|
type === 'unknown' &&
|
||||||
|
@ -3188,7 +3190,7 @@ function StatusButton({
|
||||||
|
|
||||||
function nicePostURL(url) {
|
function nicePostURL(url) {
|
||||||
if (!url) return;
|
if (!url) return;
|
||||||
const urlObj = new URL(url);
|
const urlObj = URL.parse(url);
|
||||||
const { host, pathname } = urlObj;
|
const { host, pathname } = urlObj;
|
||||||
const path = pathname.replace(/\/$/, '');
|
const path = pathname.replace(/\/$/, '');
|
||||||
// split only first slash
|
// split only first slash
|
||||||
|
|
|
@ -2,6 +2,8 @@ import './index.css';
|
||||||
|
|
||||||
import './app.css';
|
import './app.css';
|
||||||
|
|
||||||
|
import './polyfills';
|
||||||
|
|
||||||
import { render } from 'preact';
|
import { render } from 'preact';
|
||||||
import { useEffect, useState } from 'preact/hooks';
|
import { useEffect, useState } from 'preact/hooks';
|
||||||
|
|
||||||
|
|
15
src/main.jsx
15
src/main.jsx
|
@ -2,6 +2,8 @@ import './index.css';
|
||||||
|
|
||||||
import './cloak-mode.css';
|
import './cloak-mode.css';
|
||||||
|
|
||||||
|
import './polyfills';
|
||||||
|
|
||||||
// Polyfill needed for Firefox < 122
|
// Polyfill needed for Firefox < 122
|
||||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1423593
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=1423593
|
||||||
// import '@formatjs/intl-segmenter/polyfill';
|
// import '@formatjs/intl-segmenter/polyfill';
|
||||||
|
@ -14,19 +16,6 @@ if (import.meta.env.DEV) {
|
||||||
import('preact/debug');
|
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(
|
render(
|
||||||
<HashRouter>
|
<HashRouter>
|
||||||
<App />
|
<App />
|
||||||
|
|
|
@ -467,7 +467,7 @@ function AccountStatuses() {
|
||||||
|
|
||||||
const accountInstance = useMemo(() => {
|
const accountInstance = useMemo(() => {
|
||||||
if (!account?.url) return null;
|
if (!account?.url) return null;
|
||||||
const domain = new URL(account.url).hostname;
|
const domain = URL.parse(account.url).hostname;
|
||||||
return domain;
|
return domain;
|
||||||
}, [account]);
|
}, [account]);
|
||||||
const sameInstance = instance === accountInstance;
|
const sameInstance = instance === accountInstance;
|
||||||
|
|
|
@ -1111,8 +1111,8 @@ function Catchup() {
|
||||||
publishedAt,
|
publishedAt,
|
||||||
} = card;
|
} = card;
|
||||||
const domain = punycode.toUnicode(
|
const domain = punycode.toUnicode(
|
||||||
new URL(url).hostname
|
URL.parse(url)
|
||||||
.replace(/^www\./, '')
|
.hostname.replace(/^www\./, '')
|
||||||
.replace(/\/$/, ''),
|
.replace(/\/$/, ''),
|
||||||
);
|
);
|
||||||
let accentColor;
|
let accentColor;
|
||||||
|
|
|
@ -569,7 +569,7 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
|
||||||
if (!heroStatus) return;
|
if (!heroStatus) return;
|
||||||
const { url } = heroStatus;
|
const { url } = heroStatus;
|
||||||
if (!url) return;
|
if (!url) return;
|
||||||
return new URL(url).hostname;
|
return URL.parse(url).hostname;
|
||||||
}, [heroStatus]);
|
}, [heroStatus]);
|
||||||
const postSameInstance = useMemo(() => {
|
const postSameInstance = useMemo(() => {
|
||||||
if (!postInstance) return;
|
if (!postInstance) return;
|
||||||
|
|
|
@ -178,7 +178,9 @@ function Trending({ columnMode, ...props }) {
|
||||||
width,
|
width,
|
||||||
} = link;
|
} = link;
|
||||||
const domain = punycode.toUnicode(
|
const domain = punycode.toUnicode(
|
||||||
new URL(url).hostname.replace(/^www\./, '').replace(/\/$/, ''),
|
URL.parse(url)
|
||||||
|
.hostname.replace(/^www\./, '')
|
||||||
|
.replace(/\/$/, ''),
|
||||||
);
|
);
|
||||||
let accentColor;
|
let accentColor;
|
||||||
if (blurhash) {
|
if (blurhash) {
|
||||||
|
|
24
src/polyfills.js
Normal file
24
src/polyfills.js
Normal 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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -11,7 +11,7 @@ const statusPostRegexes = [
|
||||||
|
|
||||||
export function getInstanceStatusObject(url) {
|
export function getInstanceStatusObject(url) {
|
||||||
// Regex /:username/:id, where username = @username or @username@domain, id = anything
|
// 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) || [];
|
// const [, username, domain, id] = pathname.match(statusRegex) || [];
|
||||||
for (const regex of statusPostRegexes) {
|
for (const regex of statusPostRegexes) {
|
||||||
const [, id] = pathname.match(regex) || [];
|
const [, id] = pathname.match(regex) || [];
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
export default function isMastodonLinkMaybe(url) {
|
export default function isMastodonLinkMaybe(url) {
|
||||||
try {
|
try {
|
||||||
const { pathname, hash } = new URL(url);
|
const { pathname, hash } = URL.parse(url);
|
||||||
return (
|
return (
|
||||||
/^\/.*\/\d+$/i.test(pathname) ||
|
/^\/.*\/\d+$/i.test(pathname) ||
|
||||||
/^\/(@[^/]+|users\/[^/]+)\/(statuses|posts)\/\w+\/?$/i.test(pathname) || // GoToSocial, Takahe
|
/^\/(@[^/]+|users\/[^/]+)\/(statuses|posts)\/\w+\/?$/i.test(pathname) || // GoToSocial, Takahe
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
export default function openCompose(opts) {
|
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 { width: screenWidth, height: screenHeight } = window.screen;
|
||||||
const left = Math.max(0, (screenWidth - 600) / 2);
|
const left = Math.max(0, (screenWidth - 600) / 2);
|
||||||
const top = Math.max(0, (screenHeight - 450) / 2);
|
const top = Math.max(0, (screenHeight - 450) / 2);
|
||||||
|
|
|
@ -59,12 +59,8 @@ function _unfurlMastodonLink(instance, url) {
|
||||||
theURL = `https://${finalURL}`;
|
theURL = `https://${finalURL}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
let urlObj;
|
const urlObj = URL.parse(theURL);
|
||||||
try {
|
if (!urlObj) return;
|
||||||
urlObj = new URL(theURL);
|
|
||||||
} catch (e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const domain = urlObj.hostname;
|
const domain = urlObj.hostname;
|
||||||
const path = urlObj.pathname;
|
const path = urlObj.pathname;
|
||||||
// Regex /:username/:id, where username = @username or @username@domain, id = post ID
|
// Regex /:username/:id, where username = @username or @username@domain, id = post ID
|
||||||
|
|
Loading…
Reference in a new issue