From 896f5f8c534b9315314ca7945d0f60faa7151633 Mon Sep 17 00:00:00 2001 From: Alan Ye Date: Sun, 6 Apr 2025 00:23:58 +0800 Subject: [PATCH 1/4] feat(components): Active Video Links --- .../utils/active-video-links/index.md | 5 + .../utils/active-video-links/index.ts | 115 ++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 registry/lib/components/utils/active-video-links/index.md create mode 100644 registry/lib/components/utils/active-video-links/index.ts diff --git a/registry/lib/components/utils/active-video-links/index.md b/registry/lib/components/utils/active-video-links/index.md new file mode 100644 index 000000000..7f6220abd --- /dev/null +++ b/registry/lib/components/utils/active-video-links/index.md @@ -0,0 +1,5 @@ +这个组件会将视频简介中的普通网址转换为可点击的链接,并将被 Bilibili 抛弃已失效的 `acg.tv` 跳转链接修复为 `nicovideo.jp` 链接。 + +例如: `https://acg.tv/sm37507315` → `https://www.nicovideo.jp/watch/sm37507315` + +本组件不会保证目标链接的安全性,因此在点击前请自行验证其是否可信 diff --git a/registry/lib/components/utils/active-video-links/index.ts b/registry/lib/components/utils/active-video-links/index.ts new file mode 100644 index 000000000..efb5c3def --- /dev/null +++ b/registry/lib/components/utils/active-video-links/index.ts @@ -0,0 +1,115 @@ +import { defineComponentMetadata } from '@/components/define' +import { useScopedConsole } from '@/core/utils/log' +import { videoUrls } from '@/core/utils/urls' + +const console = useScopedConsole('activeVideoLinks') +let observer: MutationObserver | null = null +const webRegex = /(?|'|"|\/))(http:\/\/|https:\/\/|www\.)[^(\s,;())]+/g + +const processAcgLinks = () => { + const links = document.querySelectorAll('a[href*="acg.tv"][href*="sm"]') + links.forEach(link => { + const originalHref = link.getAttribute('href') + if (originalHref) { + const newHref = originalHref.replace('acg.tv', 'nicovideo.jp/watch') + link.setAttribute('href', newHref) + console.log(`Niconico Fix: ${originalHref} → ${newHref}`) + } + }) +} + +const isTextInsideLink = (html: string, position: number): boolean => { + const beforeText = html.substring(0, position) + const lastOpenTag = beforeText.lastIndexOf('') + return lastOpenTag > lastCloseTag +} + +const processDescLinks = () => { + const descContainer = document.querySelector('.desc-info-text') + if (!descContainer) { + return + } + + const content = descContainer.innerHTML + let newContent = content + + const matches = [...content.matchAll(webRegex)] + for (let i = matches.length - 1; i >= 0; i--) { + const match = matches[i] + const matchText = match[0] + const startIndex = match.index ?? 0 + + if (isTextInsideLink(content, startIndex)) { + continue + } + + const link = matchText.includes('http') ? matchText : `http://${matchText}` + const replacement = `${matchText}` + + newContent = + newContent.substring(0, startIndex) + + replacement + + newContent.substring(startIndex + matchText.length) + } + + if (newContent !== content) { + descContainer.innerHTML = newContent + } +} + +const processLinks = () => { + try { + processAcgLinks() + processDescLinks() + } catch (error) { + console.error('处理链接时遇到 Error:', error) + } +} + +const setupObservers = () => { + if (observer) { + observer.disconnect() + } + + observer = new MutationObserver(processLinks) + + observer.observe(document.documentElement, { + childList: true, + subtree: true, + }) + + console.log('已设置 Observer') +} + +const entry = () => { + console.log('视频链接增强已启用') + processLinks() + setupObservers() +} + +export const component = defineComponentMetadata({ + name: 'activeVideoLinks', + displayName: '视频链接增强', + description: { + 'zh-CN': '将视频简介中的普通网址转换为可点击的链接,同时修复 acg.tv 链接', + }, + tags: [componentsTags.utils], + entry, + reload: entry, + unload: () => { + if (observer) { + observer.disconnect() + observer = null + } + }, + urlInclude: videoUrls, + author: { + name: 'Alan Ye', + link: 'https://github.com/at-wr', + }, +}) From c0d23af50060dd7085c52cc6b35a32c08adea483 Mon Sep 17 00:00:00 2001 From: Alan Ye Date: Sun, 6 Apr 2025 00:40:52 +0800 Subject: [PATCH 2/4] fix(components): use protocol-relative URLs --- registry/lib/components/utils/active-video-links/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/registry/lib/components/utils/active-video-links/index.ts b/registry/lib/components/utils/active-video-links/index.ts index efb5c3def..4934ea19c 100644 --- a/registry/lib/components/utils/active-video-links/index.ts +++ b/registry/lib/components/utils/active-video-links/index.ts @@ -48,7 +48,8 @@ const processDescLinks = () => { continue } - const link = matchText.includes('http') ? matchText : `http://${matchText}` + // Use protocol-relative URL with // instead of http:// or https:// + const link = matchText.startsWith('www.') ? `//${matchText}` : matchText.replace(/^https?:/, '') const replacement = `${matchText}` newContent = From ec77980db869b16dd82c662439983029a0544dfa Mon Sep 17 00:00:00 2001 From: Alan Ye Date: Sun, 6 Apr 2025 13:04:29 +0800 Subject: [PATCH 3/4] fix(components): use protocol-relative URLs --- registry/lib/components/utils/active-video-links/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/registry/lib/components/utils/active-video-links/index.ts b/registry/lib/components/utils/active-video-links/index.ts index 4934ea19c..2f1954f09 100644 --- a/registry/lib/components/utils/active-video-links/index.ts +++ b/registry/lib/components/utils/active-video-links/index.ts @@ -48,8 +48,7 @@ const processDescLinks = () => { continue } - // Use protocol-relative URL with // instead of http:// or https:// - const link = matchText.startsWith('www.') ? `//${matchText}` : matchText.replace(/^https?:/, '') + const link = matchText.replace(/^https?:\/\//, '//').replace(/^www\./, '//') const replacement = `${matchText}` newContent = From 68ce22291fe884f5b7ef92664720c0a9ca636030 Mon Sep 17 00:00:00 2001 From: Alan Ye Date: Sun, 6 Apr 2025 20:32:51 +0800 Subject: [PATCH 4/4] docs(components): remove duplicate descripiton in `index.ts` --- registry/lib/components/utils/active-video-links/index.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/registry/lib/components/utils/active-video-links/index.ts b/registry/lib/components/utils/active-video-links/index.ts index 2f1954f09..42bac6ac2 100644 --- a/registry/lib/components/utils/active-video-links/index.ts +++ b/registry/lib/components/utils/active-video-links/index.ts @@ -95,9 +95,6 @@ const entry = () => { export const component = defineComponentMetadata({ name: 'activeVideoLinks', displayName: '视频链接增强', - description: { - 'zh-CN': '将视频简介中的普通网址转换为可点击的链接,同时修复 acg.tv 链接', - }, tags: [componentsTags.utils], entry, reload: entry,