From 5ead8ed9deee0d5356a633978d9dd4093a709845 Mon Sep 17 00:00:00 2001 From: Andy Burke Date: Fri, 25 Jul 2025 17:11:12 -0700 Subject: [PATCH] fix: regex issues in ECMAscript --- public/tabs/talk/talk.js | 80 +++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 22 deletions(-) diff --git a/public/tabs/talk/talk.js b/public/tabs/talk/talk.js index 09a9acd..d67bf62 100644 --- a/public/tabs/talk/talk.js +++ b/public/tabs/talk/talk.js @@ -1,17 +1,30 @@ const URL_MATCHING_REGEX = /(?:(?[a-zA-Z]+):\/\/)?(?:(?(?\S.+)\:(?.+))\@)?(?(?:(?[-a-zA-Z0-9\.]+)\.)?(?[-a-zA-Z0-9]+?\.(?[-a-zA-Z0-9]{2,64}))(?:\:(?[0-9]{1,6}))?)\b(?[-a-zA-Z0-9@:%_{}\[\]<>\(\)\+.~&\/="]*)(?:\?(?[a-zA-Z0-9!$%&<>()*+,-\.\/\:\;\=\?\@_~"]+))?(?:#(?[a-zA-Z0-9!$&'()*+,-\.\/\:\;\=\?\@_~"]*?))?/gm; +const VIDEO_ID_EXTRACTOR = + /(?https?)?(?::\/\/)?(?(?:(?.*?)\.)?(?vimeo\.com|youtu(?:be\.com|\.be|be\.googleapis\.com)))\/(?video|embed|watch|v)?\/?.*?\??(?:(?:v=)?(?[A-Za-z0-9._%-]*))\S+?/gi; +const SPOTIFY_EXTRACTOR = + /(?(?:spotify:.*|https?))?(?:\:(?:\/\/)?)?(?(?:(?.+)\.)?(?spotify\.com))?.*?\/?(?(?:album|artist|episode|playlist|tracks?))?\/?(?[a-zA-Z0-9]{22})/gi; +const TIDAL_EXTRACTOR = + /(?(?:tidal:track:|https?))?(?::\/\/)?(?(?:(?.+)\.)?(?tidal\.com|tidalhi\.fi)).*?\/(?(?:album|artist|tracks?))\/(?[0-9]+)/gi; + const URL_MATCH_HANDLERS = [ // Tidal (match) => { const original_url = match[0]; + + // wow https://stackoverflow.com/questions/3891641/regex-test-only-works-every-other-time + TIDAL_EXTRACTOR.lastIndex = 0; + const { groups: { item_type, item_id }, - } = - /(?(?:tidal:track:|https?))?(?::\/\/)?(?(?:(?.+)\.)?(?tidal\.com|tidalhi\.fi)).*?\/(?(?:album|artist|track))\/(?[0-9]+)/gi.exec( - original_url, - ) ?? { groups: {} }; + } = TIDAL_EXTRACTOR.exec(original_url) ?? { groups: {} }; + console.dir({ + original_url, + item_type, + item_id, + }); if (!(item_type && item_id)) { return; } @@ -35,20 +48,13 @@ const URL_MATCH_HANDLERS = [ // Spotify (match) => { const original_url = match[0]; + + SPOTIFY_EXTRACTOR.lastIndex = 0; + const { groups: { host, subdomain, item_type, item_id }, - } = - /^(?:spotify:track:|(?:https?:\/\/(?(?:(?.+)\.)?spotify\.com)\/(?.+)\/))(?[a-zA-Z0-9]{22})/gi.exec( - original_url, - ) ?? { groups: {} }; + } = SPOTIFY_EXTRACTOR.exec(original_url) ?? { groups: {} }; - console.dir({ - original_url, - host, - subdomain, - item_type, - item_id, - }); if (!item_id) { return; } @@ -70,14 +76,14 @@ const URL_MATCH_HANDLERS = [ // YouTube (match) => { const original_url = match[0]; - const { - groups: { video_id }, - } = - /(?:https?:)?(?:\/\/)?(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube(?:-nocookie)?\.com\S*?[^\w\s-])(?[\w-]{11})(?=[^\w-]|$)(?![?=&+%\w.-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/gi.exec( - original_url, - ) ?? { groups: {} }; - if (!video_id) { + VIDEO_ID_EXTRACTOR.lastIndex = 0; + + const { + groups: { domain, video_id }, + } = VIDEO_ID_EXTRACTOR.exec(original_url) ?? { groups: {} }; + + if (domain?.toLowerCase().indexOf("youtu") === -1 || !video_id) { return; } @@ -98,6 +104,36 @@ const URL_MATCH_HANDLERS = [ `; }, + // Vimeo + (match) => { + const original_url = match[0]; + + VIDEO_ID_EXTRACTOR.lastIndex = 0; + + const { + groups: { domain, video_id }, + } = VIDEO_ID_EXTRACTOR.exec(original_url) ?? { groups: {} }; + + if (domain?.toLowerCase().indexOf("vimeo") === -1 || !video_id) { + return; + } + + return ` +
+
+
+ +
`; + }, + // linkify generic url (match) => { // TODO: punycoding if something has unicode?