feat: improve video URL detection to handle query parameters

Enhanced the `isVideoUrl` function to more accurately detect video URLs by:
- Adding support for URL query parameters and fragments
- Creating helper function `extractExtension` to handle URI decoding
- Checking multiple candidate values from different parts of the URL
- Maintaining backward compatibility with existing video detection

This improves reliability when detecting video URLs that contain query parameters or encoded characters.
This commit is contained in:
Will Miao
2025-10-27 12:21:51 +08:00
parent 136d3153fa
commit 8508763831
2 changed files with 212 additions and 5 deletions

View File

@@ -19,19 +19,77 @@ function escapeHtml(value) {
.replace(/'/g, ''');
}
function extractExtension(value) {
if (value == null) {
return '';
}
const targets = [];
const stringValue = String(value);
if (stringValue) {
targets.push(stringValue);
stringValue.split(/[?&=]/).forEach(fragment => {
if (fragment) {
targets.push(fragment);
}
});
}
for (const target of targets) {
let candidate = target;
try {
candidate = decodeURIComponent(candidate);
} catch (error) {
// ignoring malformed sequences, fallback to raw value
}
const lastDot = candidate.lastIndexOf('.');
if (lastDot === -1) {
continue;
}
const extension = candidate.slice(lastDot).toLowerCase();
if (extension.includes('/') || extension.includes('\\')) {
continue;
}
return extension;
}
return '';
}
function isVideoUrl(url) {
if (!url || typeof url !== 'string') {
return false;
}
const candidates = new Set();
const addCandidate = value => {
if (value == null) {
return;
}
const stringValue = String(value);
if (!stringValue) {
return;
}
candidates.add(stringValue);
};
addCandidate(url);
try {
const parsed = new URL(url, window.location.origin);
const pathname = parsed.pathname || '';
const extension = pathname.slice(pathname.lastIndexOf('.')).toLowerCase();
return VIDEO_EXTENSIONS.includes(extension);
addCandidate(parsed.pathname);
parsed.searchParams.forEach(value => addCandidate(value));
} catch (error) {
const normalized = url.split('?')[0].toLowerCase();
return VIDEO_EXTENSIONS.some(ext => normalized.endsWith(ext));
// ignore parse errors and rely on fallbacks below
}
for (const candidate of candidates) {
const extension = extractExtension(candidate);
if (extension && VIDEO_EXTENSIONS.includes(extension)) {
return true;
}
}
return false;
}
function formatDateLabel(value) {