From 6382c1989027a87218a896e1081a34ad0643fe2a Mon Sep 17 00:00:00 2001 From: the1812 Date: Sun, 23 Jun 2024 21:09:16 +0800 Subject: [PATCH 01/30] Remove toast output --- .../video/download/DownloadVideo.vue | 2 -- .../video/download/outputs/toast.ts | 21 ------------------- 2 files changed, 23 deletions(-) delete mode 100644 registry/lib/components/video/download/outputs/toast.ts diff --git a/registry/lib/components/video/download/DownloadVideo.vue b/registry/lib/components/video/download/DownloadVideo.vue index 61b64505f6..1e66bc16ad 100644 --- a/registry/lib/components/video/download/DownloadVideo.vue +++ b/registry/lib/components/video/download/DownloadVideo.vue @@ -99,7 +99,6 @@ import { videoBatchInput, videoSeasonBatchInput } from './inputs/video/batch' import { videoSingleInput } from './inputs/video/input' import { videoDashAvc, videoDashHevc, videoDashAv1, videoAudioDash } from './apis/dash' import { videoFlv } from './apis/flv' -import { toastOutput } from './outputs/toast' import { streamSaverOutput } from './outputs/stream-saver' import { DownloadVideoAction, @@ -125,7 +124,6 @@ const [apis] = registerAndGetData('downloadVideo.apis', [ ] as DownloadVideoApi[]) const [assets] = registerAndGetData('downloadVideo.assets', [] as DownloadVideoAssets[]) const [outputs] = registerAndGetData('downloadVideo.outputs', [ - toastOutput, streamSaverOutput, ] as DownloadVideoOutput[]) const { basicConfig } = getComponentSettings('downloadVideo').options as { diff --git a/registry/lib/components/video/download/outputs/toast.ts b/registry/lib/components/video/download/outputs/toast.ts deleted file mode 100644 index 6040efe0a5..0000000000 --- a/registry/lib/components/video/download/outputs/toast.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Toast } from '@/core/toast' -import { DownloadVideoOutput } from '../types' - -export const toastOutput: DownloadVideoOutput = { - name: 'toast', - displayName: 'Toast', - description: - '弹一条消息显示出下载链接, 右键新标签页打开就可以下载. 链接有 referer 限制, 复制无用, 且不能保留视频文件名.', - runAction: async action => { - const fragments = action.infos.flatMap(it => it.titledFragments) - const urls = fragments.map(f => f.url).join('\n') - Toast.show( - fragments - .map(f => `${f.title}`) - .join('\n'), - '下载视频', - ) - console.log(urls) - console.log(action) - }, -} From 9b836b4ccac020a76bce8183e7c1f0967880a2dd Mon Sep 17 00:00:00 2001 From: the1812 Date: Sun, 23 Jun 2024 21:17:40 +0800 Subject: [PATCH 02/30] Add recommended rooms block (#4787) --- registry/lib/components/style/simplify/live/index.ts | 4 ++++ registry/lib/components/style/simplify/live/live.scss | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/registry/lib/components/style/simplify/live/index.ts b/registry/lib/components/style/simplify/live/index.ts index e6bab90fa4..ee2c8803e9 100644 --- a/registry/lib/components/style/simplify/live/index.ts +++ b/registry/lib/components/style/simplify/live/index.ts @@ -85,6 +85,10 @@ export const component = wrapSwitchOptions({ defaultValue: false, displayName: '高能榜提示', }, + recommendedRooms: { + defaultValue: false, + displayName: '推荐直播间', + }, skin: { defaultValue: false, displayName: '房间皮肤', diff --git a/registry/lib/components/style/simplify/live/live.scss b/registry/lib/components/style/simplify/live/live.scss index 98fd9952db..0bdf92d533 100644 --- a/registry/lib/components/style/simplify/live/live.scss +++ b/registry/lib/components/style/simplify/live/live.scss @@ -27,7 +27,8 @@ $prefix: 'simplifyLiveroom-switch'; &-pk .chaos-pk, &-pk .awesome-pk-box, &-topRank .chat-item.top3-notice, - &-topRank .chat-item .rank-icon { + &-topRank .chat-item .rank-icon, + &-recommendedRooms .left-container .room-info-ctnr { display: none !important; } } From b4904cc6d30f5867117490fd904ac8c72f311862 Mon Sep 17 00:00:00 2001 From: Liki4 Date: Sat, 6 Jul 2024 01:47:58 +0800 Subject: [PATCH 03/30] feature: live-remove-mask-panel --- .../live/remove-mask-panel/index.ts | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 registry/lib/components/live/remove-mask-panel/index.ts diff --git a/registry/lib/components/live/remove-mask-panel/index.ts b/registry/lib/components/live/remove-mask-panel/index.ts new file mode 100644 index 0000000000..177f38862f --- /dev/null +++ b/registry/lib/components/live/remove-mask-panel/index.ts @@ -0,0 +1,33 @@ +import { defineComponentMetadata } from '@/components/define' +import { liveUrls } from '@/core/utils/urls' + +const id = 'web-player-module-area-mask-panel' +const entry = async () => { + const observer = new MutationObserver(mutations => { + mutations.forEach(mutation => { + mutation.addedNodes.forEach(node => { + if ((node as Element).id === id) { + node.parentNode?.removeChild(node) + observer.disconnect() + } + }) + }) + }) + observer.observe(document.body, { childList: true, subtree: true }) +} + +export const component = defineComponentMetadata({ + name: 'removeLiveMaskPanel', + displayName: '删除直播马赛克遮罩', + author: { + name: 'Liki4', + link: 'https://github.com/Liki4', + }, + tags: [componentsTags.live, componentsTags.style], + description: { + 'zh-CN': '删除观看直播时某些分区的马赛克遮罩.', + }, + entry, + reload: entry, + urlInclude: liveUrls, +}) From f338e2f12477c5e3229afe42d6fdf9e89dc29cfd Mon Sep 17 00:00:00 2001 From: the1812 Date: Wed, 10 Jul 2024 22:46:45 +0800 Subject: [PATCH 04/30] Fix LaunchBar focus (fix #4808) --- src/components/launch-bar/focus-target.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/launch-bar/focus-target.ts b/src/components/launch-bar/focus-target.ts index 6207ecffd9..5c1d50bcc6 100644 --- a/src/components/launch-bar/focus-target.ts +++ b/src/components/launch-bar/focus-target.ts @@ -16,8 +16,11 @@ export class FocusTarget extends EventTarget { return this.itemIndex } private set index(value: number) { - this.itemIndex = lodash.clamp(value, -1, this.itemLength - 1) - this.dispatchEvent(new CustomEvent('index-change', { detail: this })) + const newIndex = lodash.clamp(value, -1, this.itemLength - 1) + if (this.itemIndex !== newIndex) { + this.itemIndex = newIndex + this.dispatchEvent(new CustomEvent('index-change', { detail: this })) + } } get hasFocus() { return this.itemIndex > -1 From fee12bee0b1f3343d60c56b15ca06bcfb4613d00 Mon Sep 17 00:00:00 2001 From: the1812 Date: Wed, 10 Jul 2024 23:18:36 +0800 Subject: [PATCH 05/30] Improve blocking for homepage --- .../components/utils/remove-promotions/remove-promotions.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/registry/lib/components/utils/remove-promotions/remove-promotions.scss b/registry/lib/components/utils/remove-promotions/remove-promotions.scss index eb076b350f..7843ccd597 100644 --- a/registry/lib/components/utils/remove-promotions/remove-promotions.scss +++ b/registry/lib/components/utils/remove-promotions/remove-promotions.scss @@ -87,6 +87,7 @@ body:not(.preserve-feed-goods) .bili-dyn-content__orig__additional:has(.dyn-good } .feed-card:has(.bili-video-card a[href*='cm.bilibili.com']), .bili-video-card.is-rcmd:has(a[href*='cm.bilibili.com']), -.bili-video-card__wrap:has(a[href*='cm.bilibili.com']) { +.bili-video-card__wrap:has(a[href*='cm.bilibili.com']), +.bili-video-card.is-rcmd:not(:has(.bili-video-card__wrap)) { display: none !important; } From 34353f31f12ffc0336b180eb96c883406041f871 Mon Sep 17 00:00:00 2001 From: the1812 Date: Thu, 11 Jul 2024 23:08:52 +0800 Subject: [PATCH 06/30] Update dark styles (fix #4768) --- registry/lib/components/style/dark-mode/dark-slice-16.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/registry/lib/components/style/dark-mode/dark-slice-16.scss b/registry/lib/components/style/dark-mode/dark-slice-16.scss index d8d3b7b436..ab28825ead 100644 --- a/registry/lib/components/style/dark-mode/dark-slice-16.scss +++ b/registry/lib/components/style/dark-mode/dark-slice-16.scss @@ -173,9 +173,9 @@ } } .bili-dyn-list { - &__notification { - @include theme-background-color(); - @include foreground-color(); + &-notification { + @include background-color('4'); + @include theme-color(); } } .bili-dyn-item { From 560d651d350e08b4488fde5176b56236b30d91b5 Mon Sep 17 00:00:00 2001 From: the1812 Date: Fri, 12 Jul 2024 22:44:05 +0800 Subject: [PATCH 07/30] Support copy image (#4806) --- README.md | 4 +- .../player/screenshot/VideoScreenshot.vue | 40 ++++++++++++++----- .../screenshot/VideoScreenshotContainer.vue | 4 +- .../video/player/screenshot/screenshot.ts | 3 +- 4 files changed, 36 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index a65be629de..7bc8aad691 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ ## 最低配置 - 操作系统: Windows 8.1 / macOS Big Sur - 分辨率: 1920x1080, 缩放 125% -- 浏览器: Chrome 105+ / Firefox 121+ / Safari 15.4+ (仅理论上能运行, 没测试过) +- 浏览器: Chrome 105+ / Firefox 127+ / Safari 15.4+ (仅理论上能运行, 没测试过) - 处理器: Intel Core i5-10500 / AMD Ryzen 5 3600 - 内存: 8GB - 脚本管理器: Tampermonkey 5.0 / Violentmonkey 2.18 @@ -84,7 +84,7 @@ ## 推荐配置 - 操作系统: Windows 10 / macOS Sonoma - 分辨率: 3840x2160, 缩放 200% -- 浏览器: Chrome 120+ / Firefox 121+ +- 浏览器: Chrome 120+ / Firefox 127+ - 处理器: Intel Core i7-11700 / AMD Ryzen 7 5800 - 内存: 32GB - 脚本管理器: Tampermonkey 5.0 / Violentmonkey 2.18 diff --git a/registry/lib/components/video/player/screenshot/VideoScreenshot.vue b/registry/lib/components/video/player/screenshot/VideoScreenshot.vue index 1215d64c62..c68ab458c7 100644 --- a/registry/lib/components/video/player/screenshot/VideoScreenshot.vue +++ b/registry/lib/components/video/player/screenshot/VideoScreenshot.vue @@ -13,7 +13,10 @@ - + {{ time }} @@ -23,29 +26,48 @@ - diff --git a/src/components/settings-panel/index.ts b/src/components/settings-panel/index.ts index c8c8952433..cf28504d5e 100644 --- a/src/components/settings-panel/index.ts +++ b/src/components/settings-panel/index.ts @@ -45,10 +45,12 @@ const options = defineOptionsMetadata({ filenameFormat: { defaultValue: '[title][ - ep]', displayName: '文件命名格式', + multiline: true, }, batchFilenameFormat: { defaultValue: '[n - ][ep]', displayName: '批量命名格式', + multiline: true, }, downloadPackageEmitMode: { defaultValue: DownloadPackageEmitMode.Packed, diff --git a/src/components/types.ts b/src/components/types.ts index 9e7ddb8c8c..3eaee6ebce 100644 --- a/src/components/types.ts +++ b/src/components/types.ts @@ -59,6 +59,8 @@ export interface OptionMetadata { hidden?: boolean /** 设为 `true` 时, 将用颜色选取器替代文本框 */ color?: boolean + /** 设为 `true` 时, 使用多行文本框 */ + multiline?: boolean /** 设置范围, 可以显示为一个滑动条 */ slider?: { min?: number diff --git a/src/ui/TextArea.vue b/src/ui/TextArea.vue index 48a9a27545..c906adb431 100644 --- a/src/ui/TextArea.vue +++ b/src/ui/TextArea.vue @@ -36,6 +36,7 @@ export default Vue.extend({ } textarea { resize: none; + field-sizing: content; width: 0; flex: 1 0 0; padding: 4px 6px; From 7fc04a2d23a9b388882e77e4cf35629326982b12 Mon Sep 17 00:00:00 2001 From: the1812 Date: Wed, 17 Jul 2024 21:20:37 +0800 Subject: [PATCH 12/30] Add multiline options --- registry/lib/components/utils/image-exporter/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/registry/lib/components/utils/image-exporter/index.ts b/registry/lib/components/utils/image-exporter/index.ts index e855bbfb90..f091430905 100644 --- a/registry/lib/components/utils/image-exporter/index.ts +++ b/registry/lib/components/utils/image-exporter/index.ts @@ -11,10 +11,12 @@ const options = defineOptionsMetadata({ columnFormat: { defaultValue: '[title][ - n]', displayName: '专栏图片命名格式', + multiline: true, }, feedFormat: { defaultValue: '[user][ - id][ - n]', displayName: '动态图片命名格式', + multiline: true, }, }) From b8121f7976cdb1fa46c1c09aafb4591f4be0c976 Mon Sep 17 00:00:00 2001 From: the1812 Date: Wed, 17 Jul 2024 21:32:34 +0800 Subject: [PATCH 13/30] Always show viewed tip (#4346) --- .../custom-navbar/history/NavbarHistory.vue | 64 ++++++++++--------- .../watchlater/NavbarWatchlater.vue | 13 ++-- 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/registry/lib/components/style/custom-navbar/history/NavbarHistory.vue b/registry/lib/components/style/custom-navbar/history/NavbarHistory.vue index a2c2afcbcc..f89f5969eb 100644 --- a/registry/lib/components/style/custom-navbar/history/NavbarHistory.vue +++ b/registry/lib/components/style/custom-navbar/history/NavbarHistory.vue @@ -60,16 +60,6 @@ class="progress" :style="{ width: h.progress * 100 + '%' }" > -
- {{ h.progress >= 1 ? '已看完' : h.progressText }} -
-
- {{ h.liveStatus === 1 ? '直播中' : '未开播' }} -
{{ h.durationText }}
{{ @@ -89,8 +79,25 @@ >
{{ h.upName }}
-
- {{ h.timeText }} +
+
+ {{ h.progress >= 1 ? '已看完' : h.progressText }} +
+
+ {{ h.liveStatus === 1 ? '直播中' : '未开播' }} +
+ | +
+ {{ h.timeText }} +
@@ -405,22 +412,6 @@ export default Vue.extend({ filter: invert(0.9); } } - .duration { - left: $padding; - bottom: $padding; - padding: 0 6px; - } - .live-status { - &.on { - background-color: var(--theme-color); - color: var(--foreground-color); - } - } - .progress-number { - left: $padding; - top: $padding; - padding: 0 6px; - } .progress { position: absolute; bottom: 0; @@ -448,7 +439,7 @@ export default Vue.extend({ } } .up, - .time { + .history-info { font-size: 11px; opacity: 0.75; align-self: center; @@ -479,10 +470,23 @@ export default Vue.extend({ } } } - .time { + .history-info { + @include h-center(4px); font-size: 11px; grid-area: time; padding-right: 6px; + &-separator { + margin: 0 4px; + } + } + .progress-number, + .live-status { + @include single-line(); + } + .live-status { + &.on { + color: var(--theme-color); + } } } } diff --git a/registry/lib/components/style/custom-navbar/watchlater/NavbarWatchlater.vue b/registry/lib/components/style/custom-navbar/watchlater/NavbarWatchlater.vue index f4f3540e22..d2f965f6d1 100644 --- a/registry/lib/components/style/custom-navbar/watchlater/NavbarWatchlater.vue +++ b/registry/lib/components/style/custom-navbar/watchlater/NavbarWatchlater.vue @@ -291,6 +291,11 @@ export default Vue.extend({ border-radius: 8px 0 0 8px; position: relative; $padding: 6px; + .floating { + position: absolute; + opacity: 0; + font-size: 11px; + } .remove { top: $padding; left: $padding; @@ -303,15 +308,11 @@ export default Vue.extend({ } .viewed { white-space: nowrap; + opacity: 1; right: $padding; - top: $padding; + bottom: $padding; padding: 0 6px; } - .floating { - position: absolute; - opacity: 0; - font-size: 11px; - } .cover { object-fit: cover; } From dc2a84757ff1cc32ef06123f1c34f956786f284d Mon Sep 17 00:00:00 2001 From: the1812 Date: Thu, 18 Jul 2024 09:31:46 +0800 Subject: [PATCH 14/30] Improve page and progress info display (#1866) --- .../favorites/NavbarFavorites.vue | 5 +- .../custom-navbar/history/NavbarHistory.vue | 2 +- .../style/custom-navbar/history/types.ts | 13 +-- .../watchlater/NavbarWatchlater.vue | 82 ++++++++++++------- 4 files changed, 64 insertions(+), 38 deletions(-) diff --git a/registry/lib/components/style/custom-navbar/favorites/NavbarFavorites.vue b/registry/lib/components/style/custom-navbar/favorites/NavbarFavorites.vue index de6905962f..a92531da03 100644 --- a/registry/lib/components/style/custom-navbar/favorites/NavbarFavorites.vue +++ b/registry/lib/components/style/custom-navbar/favorites/NavbarFavorites.vue @@ -103,7 +103,10 @@ const favoriteItemMapper = (item: any): FavoritesItemInfo => ({ title: item.title, description: item.intro, duration: item.duration, - durationText: formatDuration(item.duration), + durationText: + item.page > 1 + ? `${formatDuration(item.duration)} / ${item.page}P` + : formatDuration(item.duration), playCount: item.cnt_info.play, danmakuCount: item.cnt_info.danmaku, upName: item.upper.name, diff --git a/registry/lib/components/style/custom-navbar/history/NavbarHistory.vue b/registry/lib/components/style/custom-navbar/history/NavbarHistory.vue index f89f5969eb..4b50725dee 100644 --- a/registry/lib/components/style/custom-navbar/history/NavbarHistory.vue +++ b/registry/lib/components/style/custom-navbar/history/NavbarHistory.vue @@ -81,7 +81,7 @@
- {{ h.progress >= 1 ? '已看完' : h.progressText }} + {{ h.progress >= 0.95 ? '已看完' : h.progressText }}
{ } } const formatTime = (date: Date) => { - const { yesterday } = getTimeData() + const { yesterday, today } = getTimeData() const timestamp = Number(date) if (timestamp >= yesterday) { - return `${date.getHours().toString().padStart(2, '0')}:${date - .getMinutes() + return `${timestamp >= today ? '今天' : '昨天'} ${date + .getHours() .toString() - .padStart(2, '0')}` + .padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}` } return `${(date.getMonth() + 1).toString().padStart(2, '0')}-${date .getDate() @@ -154,7 +153,9 @@ const parseHistoryItem = (item: any): HistoryItem => { cover, covers: item.covers?.map(https) ?? [], progress, - progressText: Number.isNaN(progress) ? null : `${fixed(progress * 100, 1)}%`, + progressText: Number.isNaN(progress) + ? null + : `${formatDuration(item.progress)} / ${formatDuration(item.duration)}`, duration: item.duration, durationText: item.duration ? formatDuration(item.duration) : null, upName: item.author_name, diff --git a/registry/lib/components/style/custom-navbar/watchlater/NavbarWatchlater.vue b/registry/lib/components/style/custom-navbar/watchlater/NavbarWatchlater.vue index d2f965f6d1..84da52c192 100644 --- a/registry/lib/components/style/custom-navbar/watchlater/NavbarWatchlater.vue +++ b/registry/lib/components/style/custom-navbar/watchlater/NavbarWatchlater.vue @@ -34,18 +34,24 @@
{{ card.durationText }}
-
已观看
+
+ {{ card.currentPage }}P / {{ card.totalPages }}P +
+
@@ -73,6 +79,9 @@ interface WatchlaterCard { upName: string upFaceUrl: string upID: number + currentPage?: number + totalPages: number + percent: number } export default Vue.extend({ components: { @@ -125,28 +134,31 @@ export default Vue.extend({ return `https://www.bilibili.com/medialist/play/watchlater/${item.bvid}` } const cards = rawList.map(item => { + const currentPage = item.pages?.find(p => p.cid === item.cid) + const duration = currentPage?.duration ?? item.duration const href = (() => { - if (item.pages === undefined || !this.redirect) { + if (!currentPage || !this.redirect) { return getLink(item) } - const pages = item.pages.map(it => it.cid) - const page = item.cid === 0 ? 1 : pages.indexOf(item.cid) + 1 - + const { page } = currentPage return page <= 1 ? getLink(item) : `${getLink(item)}?p=${page}` })() - const percent = Math.round((1000 * item.progress) / item.duration) / 1000 + const percent = Math.round((1000 * item.progress) / duration) / 1000 + return { aid: item.aid, href, coverUrl: item.pic.replace('http:', 'https:'), - durationText: formatDuration(item.duration), - duration: item.duration, - // percent: `${fixed(percent * 100)}%`, + durationText: formatDuration(duration), + duration, complete: item.progress < 0 || percent > 0.95, // 进度过95%算看完, -1值表示100% title: item.title, upName: item.owner.name, upFaceUrl: item.owner.face.replace('http:', 'https:'), upID: item.owner.mid, + currentPage: currentPage?.page, + totalPages: item.videos, + percent, } as WatchlaterCard }) this.cards = cards @@ -306,16 +318,22 @@ export default Vue.extend({ bottom: $padding; padding: 0 6px; } - .viewed { - white-space: nowrap; - opacity: 1; + .pages { + top: $padding; right: $padding; - bottom: $padding; padding: 0 6px; } .cover { object-fit: cover; } + .progress { + position: absolute; + bottom: 0; + left: 0; + height: 2px; + border-radius: 1px; + background-color: var(--theme-color); + } } &:hover { .floating { @@ -334,17 +352,21 @@ export default Vue.extend({ color: var(--theme-color) !important; } } - // .info { - // grid-area: info; - // display: flex; - // align-items: center; - // justify-content: space-around; - // margin: 8px; - // } + .info { + display: flex; + justify-content: space-between; + align-items: flex-end; + grid-area: info; + margin: 6px 8px; + .viewed { + opacity: 0.75; + font-size: 11px; + margin: 2px 0; + } + } .up { flex: 0 1 auto; padding: 2px 10px 2px 2px; - margin: 0 8px 6px; justify-self: start; align-self: center; max-width: calc(100% - 16px); From 879de481efb033d01bb99cbf7c0844b7da574705 Mon Sep 17 00:00:00 2001 From: the1812 Date: Fri, 19 Jul 2024 22:51:49 +0800 Subject: [PATCH 15/30] Update version number --- src/client/common.meta.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/common.meta.json b/src/client/common.meta.json index c322001e58..43f6010a38 100644 --- a/src/client/common.meta.json +++ b/src/client/common.meta.json @@ -1,5 +1,5 @@ { - "version": "2.8.13", + "version": "2.9.0", "author": "Grant Howard, Coulomb-G", "copyright": "[year], Grant Howard (https://github.com/the1812) & Coulomb-G (https://github.com/Coulomb-G)", "license": "MIT", From 3aec810187ccfd8a3a5fa331aded3b3f6df42cc0 Mon Sep 17 00:00:00 2001 From: the1812 Date: Tue, 13 Aug 2024 23:50:16 +0800 Subject: [PATCH 16/30] Allow Node as target of MutationObserver --- src/core/observer.ts | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/core/observer.ts b/src/core/observer.ts index 729a28d6bd..a95d561096 100644 --- a/src/core/observer.ts +++ b/src/core/observer.ts @@ -3,17 +3,24 @@ import { select } from './spin-query' import { matchCurrentPage, playerUrls } from './utils/urls' type ObserverTarget = string | Element[] | Element -export const resolveTargets = (target: ObserverTarget) => { +type MutationObserverTarget = string | Node[] | Node +export const resolveTargets = < + T extends ObserverTarget | MutationObserverTarget, + ResultType = T extends ObserverTarget ? Element[] : Node[], +>( + target: T, +): ResultType => { if (typeof target === 'string') { - return dqa(target) + return dqa(target) as ResultType } if (Array.isArray(target)) { - return target + return target as ResultType } - return [target] + return [target] as ResultType } + export const mutationObserve = ( - targets: Element[], + targets: Node[], config: MutationObserverInit, callback: MutationCallback, ) => { @@ -26,7 +33,7 @@ export const mutationObserve = ( * @param target 监听目标 * @param callback 回调函数 */ -export const childList = (target: ObserverTarget, callback: MutationCallback) => +export const childList = (target: MutationObserverTarget, callback: MutationCallback) => mutationObserve( resolveTargets(target), { @@ -40,7 +47,7 @@ export const childList = (target: ObserverTarget, callback: MutationCallback) => * @param target 监听目标 * @param callback 回调函数 */ -export const childListSubtree = (target: ObserverTarget, callback: MutationCallback) => +export const childListSubtree = (target: MutationObserverTarget, callback: MutationCallback) => mutationObserve( resolveTargets(target), { @@ -54,7 +61,7 @@ export const childListSubtree = (target: ObserverTarget, callback: MutationCallb * @param target 监听目标 * @param callback 回调函数 */ -export const attributes = (target: ObserverTarget, callback: MutationCallback) => +export const attributes = (target: MutationObserverTarget, callback: MutationCallback) => mutationObserve( resolveTargets(target), { @@ -68,7 +75,7 @@ export const attributes = (target: ObserverTarget, callback: MutationCallback) = * @param target 监听目标 * @param callback 回调函数 */ -export const attributesSubtree = (target: ObserverTarget, callback: MutationCallback) => +export const attributesSubtree = (target: MutationObserverTarget, callback: MutationCallback) => mutationObserve( resolveTargets(target), { @@ -82,7 +89,7 @@ export const attributesSubtree = (target: ObserverTarget, callback: MutationCall * @param target 监听目标 * @param callback 回调函数 */ -export const characterData = (target: ObserverTarget, callback: MutationCallback) => +export const characterData = (target: MutationObserverTarget, callback: MutationCallback) => mutationObserve( resolveTargets(target), { @@ -97,7 +104,7 @@ export const characterData = (target: ObserverTarget, callback: MutationCallback * @param target 监听目标 * @param callback 回调函数 */ -export const characterDataSubtree = (target: ObserverTarget, callback: MutationCallback) => +export const characterDataSubtree = (target: MutationObserverTarget, callback: MutationCallback) => mutationObserve( resolveTargets(target), { @@ -114,7 +121,7 @@ export const characterDataSubtree = (target: ObserverTarget, callback: MutationC * @param target 监听目标 * @param callback 回调函数 */ -export const allMutationsOn = (target: ObserverTarget, callback: MutationCallback) => +export const allMutationsOn = (target: MutationObserverTarget, callback: MutationCallback) => mutationObserve( resolveTargets(target), { From 26a93cf50316f1f5d70cdbee6be728611caeecab Mon Sep 17 00:00:00 2001 From: the1812 Date: Tue, 13 Aug 2024 23:50:29 +0800 Subject: [PATCH 17/30] Add Shadow DOM API --- src/core/core-apis.ts | 3 + src/core/shadow-dom.ts | 185 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 188 insertions(+) create mode 100644 src/core/shadow-dom.ts diff --git a/src/core/core-apis.ts b/src/core/core-apis.ts index 9c874e46a9..aa400dfd19 100644 --- a/src/core/core-apis.ts +++ b/src/core/core-apis.ts @@ -17,6 +17,7 @@ import * as spinQuery from '@/core/spin-query' import * as style from '@/core/style' import * as textColor from '@/core/text-color' import * as settings from '@/core/settings' +import * as shadowDom from '@/core/shadow-dom' import * as userInfo from '@/core/user-info' import * as version from '@/core/version' import * as commonUtils from '@/core/utils' @@ -59,6 +60,7 @@ export const coreApis = { userInfo, version, settings, + shadowDom, toast, themeColor, utils: { @@ -99,6 +101,7 @@ export const externalApis = { ...textColor, ...userInfo, ...version, + ...shadowDom, settingsApis: settings, get settings() { return settings.settings diff --git a/src/core/shadow-dom.ts b/src/core/shadow-dom.ts new file mode 100644 index 0000000000..f6250de54c --- /dev/null +++ b/src/core/shadow-dom.ts @@ -0,0 +1,185 @@ +import { allMutations, childListSubtree } from './observer' +import { addStyle } from './style' +import { deleteValue, getRandomId } from './utils' + +enum ShadowRootEvents { + Added = 'shadowRootAdded', + Removed = 'shadowRootRemoved', + Updated = 'shadowRootUpdated', +} +interface ShadowRootEntry { + shadowRoot: ShadowRoot + observer: MutationObserver +} +export class ShadowDomObserver extends EventTarget { + static enforceOpenRoot() { + const originalAttachShadow = Element.prototype.attachShadow + Element.prototype.attachShadow = function attachShadow(options: ShadowRootInit) { + return originalAttachShadow.call(this, { + ...options, + mode: 'open', + }) + } + } + + entries: ShadowRootEntry[] = [] + + constructor() { + super() + this.observe() + } + + protected queryAllShadowRoots( + root: DocumentFragment | Element = document.body, + deep = false, + ): ShadowRoot[] { + return [root, ...root.querySelectorAll('*')] + .filter((e): e is Element => e instanceof Element && e.shadowRoot !== null) + .flatMap(e => { + if (deep) { + return [e.shadowRoot, ...this.queryAllShadowRoots(e.shadowRoot)] + } + return [e.shadowRoot] + }) + } + + protected mutationHandler(records: MutationRecord[]) { + records.forEach(record => { + record.removedNodes.forEach(node => { + if (node instanceof Element && node.shadowRoot !== null) { + this.removeEntry(node.shadowRoot) + } + }) + record.addedNodes.forEach(node => { + if (node instanceof Element) { + this.queryAllShadowRoots(node).forEach(shadowRoot => { + this.addEntry(shadowRoot) + }) + } + }) + }) + } + + protected addEntry(shadowRoot: ShadowRoot) { + if (this.shadowRoots.includes(shadowRoot)) { + return + } + const shadowRootChildren = this.queryAllShadowRoots(shadowRoot) + shadowRootChildren.forEach(child => this.addEntry(child)) + + const [observer] = childListSubtree(shadowRoot, records => this.mutationHandler(records)) + this.entries.push({ + shadowRoot, + observer, + }) + this.dispatchEvent(new CustomEvent('shadowRootAdded', { detail: shadowRoot })) + } + + protected removeEntry(shadowRoot: ShadowRoot) { + const children = this.shadowRoots.filter(it => shadowRoot.contains(it.host)) + children.forEach(child => this.removeEntry(child)) + + const entry = this.entries.find(it => it.shadowRoot === shadowRoot) + if (entry !== undefined) { + entry.observer.disconnect() + deleteValue(this.entries, it => it === entry) + } + } + + get shadowRoots() { + return this.entries.map(entry => entry.shadowRoot) + } + + addEventListener( + type: `${ShadowRootEvents}`, + callback: EventListenerOrEventListenerObject | null, + options?: AddEventListenerOptions | boolean, + ): void { + super.addEventListener(type, callback, options) + } + + removeEventListener( + type: `${ShadowRootEvents}`, + callback: EventListenerOrEventListenerObject | null, + options?: EventListenerOptions | boolean, + ): void { + super.removeEventListener(type, callback, options) + } + + forEachShadowRoot(callbacks: { + added?: (shadowRoot: ShadowRoot) => void + removed?: (shadowRoot: ShadowRoot) => void + }) { + this.shadowRoots.forEach(it => callbacks.added?.(it)) + const addedListener = (e: CustomEvent) => callbacks?.added(e.detail) + const removedListener = (e: CustomEvent) => callbacks?.removed(e.detail) + this.addEventListener(ShadowRootEvents.Added, addedListener) + this.addEventListener(ShadowRootEvents.Removed, removedListener) + return () => { + this.removeEventListener(ShadowRootEvents.Added, addedListener) + this.removeEventListener(ShadowRootEvents.Removed, removedListener) + } + } + + observe() { + const existingRoots = this.queryAllShadowRoots() + existingRoots.forEach(root => this.addEntry(root)) + allMutations(records => this.mutationHandler(records)) + } + + disconnect() { + this.entries.forEach(entry => entry.observer.disconnect()) + this.entries = [] + } +} + +export class ShadowDomStyles { + constructor(public observer: ShadowDomObserver) {} + + entries: ShadowRootEntry[] = [] + + get shadowRoots() { + return this.entries.map(entry => entry.shadowRoot) + } + + protected addEntry(shadowRoot: ShadowRoot, callback: (records: MutationRecord[]) => void) { + const [observer] = childListSubtree(shadowRoot, records => { + callback(records) + }) + this.entries.push({ + shadowRoot, + observer, + }) + } + + protected removeEntry(shadowRoot: ShadowRoot) { + const entry = this.entries.find(it => it.shadowRoot === shadowRoot) + if (entry !== undefined) { + entry.observer.disconnect() + deleteValue(this.entries, it => it === entry) + } + } + + addStyle(text: string) { + const id = `shadow-dom-style-${getRandomId()}` + const element = addStyle(text, id) + return this.observer.forEachShadowRoot({ + added: shadowRoot => { + if (this.shadowRoots.includes(shadowRoot)) { + return + } + const tryAddStyle = () => { + if (shadowRoot.getElementById(id) !== null) { + return + } + shadowRoot.appendChild(element.cloneNode(true)) + } + tryAddStyle() + this.addEntry(shadowRoot, () => tryAddStyle()) + }, + removed: shadowRoot => { + this.removeEntry(shadowRoot) + }, + }) + } +} From f5d2606b0743d277ceafc06644f945a24250758b Mon Sep 17 00:00:00 2001 From: the1812 Date: Tue, 13 Aug 2024 23:54:42 +0800 Subject: [PATCH 18/30] Update style clean up function --- src/core/shadow-dom.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/shadow-dom.ts b/src/core/shadow-dom.ts index f6250de54c..2e6b9b3bbf 100644 --- a/src/core/shadow-dom.ts +++ b/src/core/shadow-dom.ts @@ -163,7 +163,7 @@ export class ShadowDomStyles { addStyle(text: string) { const id = `shadow-dom-style-${getRandomId()}` const element = addStyle(text, id) - return this.observer.forEachShadowRoot({ + const destroy = this.observer.forEachShadowRoot({ added: shadowRoot => { if (this.shadowRoots.includes(shadowRoot)) { return @@ -178,8 +178,13 @@ export class ShadowDomStyles { this.addEntry(shadowRoot, () => tryAddStyle()) }, removed: shadowRoot => { + shadowRoot.getElementById(id)?.remove() this.removeEntry(shadowRoot) }, }) + return () => { + destroy() + element.remove() + } } } From d79147d6652d3f313367f9f3eb4541bb661826e5 Mon Sep 17 00:00:00 2001 From: the1812 Date: Tue, 13 Aug 2024 23:57:20 +0800 Subject: [PATCH 19/30] Lazy observe shadow dom --- src/core/shadow-dom.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/core/shadow-dom.ts b/src/core/shadow-dom.ts index 2e6b9b3bbf..9cffafaa7f 100644 --- a/src/core/shadow-dom.ts +++ b/src/core/shadow-dom.ts @@ -22,11 +22,12 @@ export class ShadowDomObserver extends EventTarget { } } + private observing = false + entries: ShadowRootEntry[] = [] constructor() { super() - this.observe() } protected queryAllShadowRoots( @@ -122,20 +123,26 @@ export class ShadowDomObserver extends EventTarget { } observe() { + if (this.observing) { + return + } const existingRoots = this.queryAllShadowRoots() existingRoots.forEach(root => this.addEntry(root)) allMutations(records => this.mutationHandler(records)) + this.observing = true } disconnect() { this.entries.forEach(entry => entry.observer.disconnect()) this.entries = [] + this.observing = false } } -export class ShadowDomStyles { - constructor(public observer: ShadowDomObserver) {} +const shadowDomObserver = new ShadowDomObserver() +export class ShadowDomStyles { + observer: ShadowDomObserver = shadowDomObserver entries: ShadowRootEntry[] = [] get shadowRoots() { @@ -161,6 +168,7 @@ export class ShadowDomStyles { } addStyle(text: string) { + this.observer.observe() const id = `shadow-dom-style-${getRandomId()}` const element = addStyle(text, id) const destroy = this.observer.forEachShadowRoot({ From f20eee4080bfa1d477b12017e366a4c60f3e9273 Mon Sep 17 00:00:00 2001 From: the1812 Date: Wed, 14 Aug 2024 22:44:54 +0800 Subject: [PATCH 20/30] Add shadow dom style support --- .../style/simplify/comments/comments-v3.scss | 55 +++++++++++++++++++ .../style/simplify/comments/index.ts | 9 ++- 2 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 registry/lib/components/style/simplify/comments/comments-v3.scss diff --git a/registry/lib/components/style/simplify/comments/comments-v3.scss b/registry/lib/components/style/simplify/comments/comments-v3.scss new file mode 100644 index 0000000000..ee956a332a --- /dev/null +++ b/registry/lib/components/style/simplify/comments/comments-v3.scss @@ -0,0 +1,55 @@ +@import 'common'; + +$prefix: 'simplifyComments-switch'; + +:host-context(.comment-m-v1) { + &:host(bili-rich-text) { + #contents img, #contents a i { + max-width: 1.4em; + max-height: 1.4em; + } + } + + &:host-context(body.#{$prefix}-replyEditor):host(bili-comment-box) { + #pub button { + font-size: 14px; + } + #label { + font-size: 15px; + } + } + &:host-context(body.#{$prefix}-replyEditor):host(bili-comment-textarea) { + #input { + font-size: 13px; + } + #input, + #input::placeholder { + line-height: normal; + } + } + &:host-context(body.#{$prefix}-userLevel):host(bili-comment-user-info) { + #user-level { + display: none; + } + } + &:host-context(body.#{$prefix}-decorateAndTime):host(bili-comment-renderer) { + bili-comment-user-sailing-card { + display: none; + } + } + &:host-context(body.#{$prefix}-fansMedal):host(bili-comment-user-info) { + bili-comment-user-medal { + display: none; + } + } + &:host-context(body.#{$prefix}-subReplyNewLine):host(bili-comment-reply-renderer) { + bili-comment-user-info { + display: block; + } + } + &:host-context(body.#{$prefix}-eventBanner):host(bili-comments-header-renderer) { + bili-comments-notice { + display: none; + } + } +} diff --git a/registry/lib/components/style/simplify/comments/index.ts b/registry/lib/components/style/simplify/comments/index.ts index 2f87ba0265..8efcf7e19a 100644 --- a/registry/lib/components/style/simplify/comments/index.ts +++ b/registry/lib/components/style/simplify/comments/index.ts @@ -50,14 +50,19 @@ export const component = wrapSwitchOptions({ }, true, ) + + const { ShadowDomStyles } = await import('@/core/shadow-dom') + const v3Styles = await import('./comments-v3.scss').then(m => m.default) + const shadowDom = new ShadowDomStyles() + shadowDom.addStyle(v3Styles) }, instantStyles: [ { - name, + name: `${name}v1`, style: () => import('./comments.scss'), }, { - name, + name: `${name}v2`, style: () => import('./comments-v2.scss'), }, ], From 5eae2c690ea6bb6903ebd6b6607a2a7f0390382c Mon Sep 17 00:00:00 2001 From: the1812 Date: Wed, 14 Aug 2024 22:45:11 +0800 Subject: [PATCH 21/30] Use adoptedStyleSheets to inject style --- src/core/shadow-dom.ts | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/src/core/shadow-dom.ts b/src/core/shadow-dom.ts index 9cffafaa7f..98c788d0f1 100644 --- a/src/core/shadow-dom.ts +++ b/src/core/shadow-dom.ts @@ -11,6 +11,9 @@ interface ShadowRootEntry { shadowRoot: ShadowRoot observer: MutationObserver } +interface ShadowRootStyleEntry { + shadowRoot: ShadowRoot +} export class ShadowDomObserver extends EventTarget { static enforceOpenRoot() { const originalAttachShadow = Element.prototype.attachShadow @@ -143,26 +146,21 @@ const shadowDomObserver = new ShadowDomObserver() export class ShadowDomStyles { observer: ShadowDomObserver = shadowDomObserver - entries: ShadowRootEntry[] = [] + entries: ShadowRootStyleEntry[] = [] get shadowRoots() { return this.entries.map(entry => entry.shadowRoot) } - protected addEntry(shadowRoot: ShadowRoot, callback: (records: MutationRecord[]) => void) { - const [observer] = childListSubtree(shadowRoot, records => { - callback(records) - }) + protected addEntry(shadowRoot: ShadowRoot) { this.entries.push({ shadowRoot, - observer, }) } protected removeEntry(shadowRoot: ShadowRoot) { const entry = this.entries.find(it => it.shadowRoot === shadowRoot) if (entry !== undefined) { - entry.observer.disconnect() deleteValue(this.entries, it => it === entry) } } @@ -172,18 +170,14 @@ export class ShadowDomStyles { const id = `shadow-dom-style-${getRandomId()}` const element = addStyle(text, id) const destroy = this.observer.forEachShadowRoot({ - added: shadowRoot => { + added: async shadowRoot => { if (this.shadowRoots.includes(shadowRoot)) { return } - const tryAddStyle = () => { - if (shadowRoot.getElementById(id) !== null) { - return - } - shadowRoot.appendChild(element.cloneNode(true)) - } - tryAddStyle() - this.addEntry(shadowRoot, () => tryAddStyle()) + this.addEntry(shadowRoot) + const sheet = new CSSStyleSheet() + await sheet.replace(element.innerHTML) + shadowRoot.adoptedStyleSheets.push(sheet) }, removed: shadowRoot => { shadowRoot.getElementById(id)?.remove() From d4579de53603a916c3615051a71e980b0e1cf7ac Mon Sep 17 00:00:00 2001 From: the1812 Date: Wed, 14 Aug 2024 23:06:14 +0800 Subject: [PATCH 22/30] Update reply editor styles --- .../style/simplify/comments/comments-v3.scss | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/registry/lib/components/style/simplify/comments/comments-v3.scss b/registry/lib/components/style/simplify/comments/comments-v3.scss index ee956a332a..b9c428e9a7 100644 --- a/registry/lib/components/style/simplify/comments/comments-v3.scss +++ b/registry/lib/components/style/simplify/comments/comments-v3.scss @@ -10,21 +10,25 @@ $prefix: 'simplifyComments-switch'; } } - &:host-context(body.#{$prefix}-replyEditor):host(bili-comment-box) { - #pub button { - font-size: 14px; - } - #label { - font-size: 15px; - } - } - &:host-context(body.#{$prefix}-replyEditor):host(bili-comment-textarea) { - #input { - font-size: 13px; - } - #input, - #input::placeholder { - line-height: normal; + &:host-context(body.#{$prefix}-replyEditor) { + &:host(bili-comment-box) { + #pub button { + font-size: 14px; + } + } + &:host(bili-checkbox) { + #label { + font-size: 15px; + } + } + &:host(bili-comment-textarea) { + #input { + font-size: 13px; + } + #input, + #input::placeholder { + line-height: normal; + } } } &:host-context(body.#{$prefix}-userLevel):host(bili-comment-user-info) { From 612790bda52d43f1c10c5f765ef6ce2f93d0e086 Mon Sep 17 00:00:00 2001 From: the1812 Date: Wed, 14 Aug 2024 23:21:24 +0800 Subject: [PATCH 23/30] Fix danmaku position --- .../style/special-danmaku/special-danmaku.scss | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/registry/lib/components/style/special-danmaku/special-danmaku.scss b/registry/lib/components/style/special-danmaku/special-danmaku.scss index dcae902312..0fd85e3dd7 100644 --- a/registry/lib/components/style/special-danmaku/special-danmaku.scss +++ b/registry/lib/components/style/special-danmaku/special-danmaku.scss @@ -1,9 +1,16 @@ body.disable-highlight-danmaku-style { .bili-danmaku-x-high, - .bili-danmaku-x-high-top, + .bili-danmaku-x-high-top { + display: flex !important; + } .bili-dm.bili-high, .b-danmaku-high { display: block !important; + } + .bili-danmaku-x-high, + .bili-danmaku-x-high-top, + .bili-dm.bili-high, + .b-danmaku-high { padding: 0 !important; line-height: 1.125 !important; .bili-danmaku-x-high-icon, From f9378718aeb7e7f013f68ebca2c6fa4d765aa983 Mon Sep 17 00:00:00 2001 From: the1812 Date: Thu, 15 Aug 2024 08:53:43 +0800 Subject: [PATCH 24/30] Fix toolbar actions --- registry/lib/components/utils/keymap/actions.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/registry/lib/components/utils/keymap/actions.ts b/registry/lib/components/utils/keymap/actions.ts index 7a3f6e5701..89c7add0c3 100644 --- a/registry/lib/components/utils/keymap/actions.ts +++ b/registry/lib/components/utils/keymap/actions.ts @@ -136,13 +136,13 @@ export const builtInActions: Record = { coin: { displayName: '投币', run: useClickElement( - '.video-toolbar .coin, .tool-bar .coin-info, .video-toolbar-module .coin-box, .play-options-ul > li:nth-child(2), .video-toolbar-v1 .coin, .toolbar .coin', + '.video-toolbar .coin, .tool-bar .coin-info, .video-toolbar-module .coin-box, .play-options-ul > li:nth-child(2), .video-toolbar-v1 .coin, .toolbar .coin, .video-toolbar-container .video-coin', ), }, favorite: { displayName: '收藏', run: useClickElement( - '.video-toolbar .collect, .video-toolbar-module .fav-box, .play-options-ul > li:nth-child(3), .video-toolbar-v1 .collect', + '.video-toolbar .collect, .video-toolbar-module .fav-box, .play-options-ul > li:nth-child(3), .video-toolbar-v1 .collect, .video-toolbar-container .video-fav', ), }, pause: { @@ -157,7 +157,7 @@ export const builtInActions: Record = { return (context: KeyBindingActionContext) => { const { event } = context const likeButton = dq( - '.video-toolbar .like, .tool-bar .like-info, .video-toolbar-v1 .like, .toolbar .like', + '.video-toolbar .like, .tool-bar .like-info, .video-toolbar-v1 .like, .toolbar .like, .video-toolbar-container .video-like', ) as HTMLSpanElement if (!likeButton) { return false From 61c411525a9a394d5b7189f0934a0669131ca7b0 Mon Sep 17 00:00:00 2001 From: the1812 Date: Thu, 15 Aug 2024 08:53:58 +0800 Subject: [PATCH 25/30] Fix danmaku airborne --- .../lib/components/video/danmaku/airborne/airborne.scss | 3 ++- registry/lib/components/video/danmaku/airborne/index.ts | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/registry/lib/components/video/danmaku/airborne/airborne.scss b/registry/lib/components/video/danmaku/airborne/airborne.scss index bd2bb4cf97..7e5e869462 100644 --- a/registry/lib/components/video/danmaku/airborne/airborne.scss +++ b/registry/lib/components/video/danmaku/airborne/airborne.scss @@ -1,5 +1,6 @@ .bili-dm, -.b-danmaku { +.b-danmaku, +.bili-danmaku-x-dm { &.airborne { text-decoration: underline; cursor: pointer; diff --git a/registry/lib/components/video/danmaku/airborne/index.ts b/registry/lib/components/video/danmaku/airborne/index.ts index ba1bca2ec4..ea07f9fe4b 100644 --- a/registry/lib/components/video/danmaku/airborne/index.ts +++ b/registry/lib/components/video/danmaku/airborne/index.ts @@ -51,7 +51,11 @@ export const component = defineComponentMetadata({ return } const target = e.target as HTMLElement - if (!['b-danmaku', 'bili-dm'].some(token => target.classList.contains(token))) { + if ( + !['b-danmaku', 'bili-dm', 'bili-danmaku-x-dm'].some(token => + target.classList.contains(token), + ) + ) { return } const time = getAirborneTime(target.textContent) From eebb358cbf81e6f1a78446c154ef61b7ac3b721d Mon Sep 17 00:00:00 2001 From: the1812 Date: Thu, 15 Aug 2024 23:04:33 +0800 Subject: [PATCH 26/30] Update changelog --- CHANGELOG.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e03557eee9..1f4844844b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,43 @@ # 更新日志 +## v2.9.1 / v2.9.1-preview + +
+正式版用户将获得 v2.9.0-preview 的所有改动 (新功能以及一项废弃), 点击展开查看 + +✨新增 +- `简化直播间` 支持屏蔽推荐直播间. (#4787) +- 新增功能 `删除直播马赛克遮罩` (#4634, PR #4814) +> 删除观看直播时某些分区的马赛克遮罩. + +- `启用视频截图` 截出来的图支持直接复制. (此功能需要 Firefox 127 版本以上) (#4806) +- `图片批量导出`, `下载视频` 支持更多变量, 详情可在更新组件后查看设置中的说明: (#3852) + - 动态 ID, 用户 ID, 动态发布时间, 被转发动态相关数据 + - 专栏 cv 号, 专栏发布时间 + - (仅对批量视频下载 (分P / 合集) 有效) up 主名称, up 主 ID, 视频发布时间 +- `自定义顶栏` 的稍后再看和历史面板现在始终显示 "已观看" 状态. (#4346) +- `自定义顶栏` 的稍后再看, 收藏和历史面板优化了分 P 数和观看进度的展示, 详见[此处](https://github.com/the1812/Bilibili-Evolved/discussions/1866#discussioncomment-10075203). (#1866) + +🗑️废弃 +- 删除 `下载视频` 的 Toast 输出方式. + +
+ +🐛修复 +- 部分修复 `简化评论区` 在新版评论区下失效. (#4843) + - 头像框目前还没找到比较好的方式隐藏, 暂不支持. + - 时间由于 Shadow DOM 限制, 无法再挪到右上角了, `装扮 & 时间` 只对装扮有效. + - 样式实现依赖 [:host-context](https://developer.mozilla.org/en-US/docs/Web/CSS/:host-context), 因此目前还不支持 Firefox. +- 修复 `删除视频弹窗` 和 `禁用特殊弹幕样式` 在新版播放器下失效. (#4843, #4823, PR #4839 by [festoney8](https://github.com/festoney8)) +- 修复 `快捷键扩展` 的部分操作和 `启用弹幕空降` 在新版播放器下失效. + +☕开发者相关 +- 新增 Shadow DOM 系列 API (`src/core/shadow-dom.ts`), 用于处理 Shadow DOM 相关的逻辑. + - `ShadowDomObserver`: 持续观测页面上的所有 Shadow DOM. + - `ShadowDomStyles`: 支持将样式注入页面, 包含所有 Shadow DOM 内部. +- `MutationObserver` 相关的 API 支持使用 `Node` 类型作为目标. + ## v2.9.0-preview `2024-07-19` From ae18e71158eb11d95413f08701249becc0fb0325 Mon Sep 17 00:00:00 2001 From: the1812 Date: Thu, 15 Aug 2024 23:05:20 +0800 Subject: [PATCH 27/30] Update version number --- src/client/common.meta.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/common.meta.json b/src/client/common.meta.json index c322001e58..0c3a9889f9 100644 --- a/src/client/common.meta.json +++ b/src/client/common.meta.json @@ -1,5 +1,5 @@ { - "version": "2.8.13", + "version": "2.9.1", "author": "Grant Howard, Coulomb-G", "copyright": "[year], Grant Howard (https://github.com/the1812) & Coulomb-G (https://github.com/Coulomb-G)", "license": "MIT", From 8eb37e38e705dff97b1917832cc4a7329a6d1b85 Mon Sep 17 00:00:00 2001 From: the1812 Date: Thu, 15 Aug 2024 23:08:25 +0800 Subject: [PATCH 28/30] Update donate history --- doc/donate.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/donate.md b/doc/donate.md index 3ec40d9f35..73930da0f7 100644 --- a/doc/donate.md +++ b/doc/donate.md @@ -26,9 +26,13 @@ https://afdian.net/@the1812?tab=sponsor + | 时间 | 用户名 | 单号后4位 | 金额 | | ------------------- | --------------------- | --------- | ------- | +| 2024.08.15 10:18:07 | *9 | 1653 | ¥10.00 | +| 2024.07.30 13:40:22 | Z*n | 2215 | ¥5.00 | +| 2024.07.24 09:38:46 | H*g | 7776 | ¥5.00 | | 2024.07.16 20:57:01 | *h | 4344 | ¥20.00 | | 2024.06.10 11:05:25 | *兽 | 6240 | ¥5.00 | | 2024.06.01 14:30:08 | R*0 | 8974 | ¥50.00 | From 7a0f971e47d0acbd0a217677b5ffcb2604f31670 Mon Sep 17 00:00:00 2001 From: the1812 Date: Thu, 15 Aug 2024 23:11:07 +0800 Subject: [PATCH 29/30] Update docs --- doc/features/features.json | 12 ++++++-- doc/features/features.md | 60 ++++++++++++++++++++++++++++++++++--- doc/features/pack/pack.json | 2 +- 3 files changed, 67 insertions(+), 7 deletions(-) diff --git a/doc/features/features.json b/doc/features/features.json index 781f178c5e..eb3ee9ee81 100644 --- a/doc/features/features.json +++ b/doc/features/features.json @@ -151,6 +151,14 @@ "fullRelativePath": "../../registry/dist/components/live/original.js", "fullAbsolutePath": "registry/dist/components/live/original.js" }, + { + "type": "component", + "name": "removeLiveMaskPanel", + "displayName": "删除直播马赛克遮罩", + "description": "by [@Liki4](https://github.com/Liki4)\n\n删除观看直播时某些分区的马赛克遮罩.", + "fullRelativePath": "../../registry/dist/components/live/remove-mask-panel.js", + "fullAbsolutePath": "registry/dist/components/live/remove-mask-panel.js" + }, { "type": "component", "name": "removeLiveWatermark", @@ -547,7 +555,7 @@ "type": "component", "name": "imageExporter", "displayName": "图片批量导出", - "description": "可以批量导出某个地方的图片, 目前支持动态和专栏.\r\n\r\n动态文件名变量:\r\n- `user`: 用户名\r\n- `originalUser`: 被转发用户名, 如果不是转发类型的动态则等于 `user`\r\n- `id`: 动态 ID\r\n- `n`: 第 n 张图\r\n\r\n专栏文件名变量:\r\n- `title`: 专栏标题\r\n- `n`: 第 n 张图", + "description": "可以批量导出某个地方的图片, 目前支持动态和专栏.\r\n\r\n动态文件名变量:\r\n- `n`: 第 n 张图\r\n- `id`: 动态 ID\r\n- `user`: 用户名\r\n- `userID`: 用户 ID\r\n- 动态发布时间:\r\n - `publishYear`\r\n - `publishMonth`\r\n - `publishDay`\r\n - `publishHour`\r\n - `publishMinute`\r\n - `publishSecond`\r\n - `publishMillisecond`\r\n- 被转发的数据 (如果不是转发类型的动态, 则和上面的对应变量相同):\r\n - `originalID`: 被转发的动态 ID\r\n - `originalUser`: 被转发的用户名\r\n - `originalUserID`: 被转发用户 ID\r\n - 被转发的动态发布时间:\r\n - `originalPublishYear`\r\n - `originalPublishMonth`\r\n - `originalPublishDay`\r\n - `originalPublishHour`\r\n - `originalPublishMinute`\r\n - `originalPublishSecond`\r\n - `originalPublishMillisecond`\r\n\r\n专栏文件名变量:\r\n- `n`: 第 n 张图\r\n- `title`: 专栏标题\r\n- `cv`: 专栏 cv 号\r\n- 专栏发布时间:\r\n - `publishYear`\r\n - `publishMonth`\r\n - `publishDay`\r\n - `publishHour`\r\n - `publishMinute`\r\n - `publishSecond`\r\n - `publishMillisecond`\r\n", "fullRelativePath": "../../registry/dist/components/utils/image-exporter.js", "fullAbsolutePath": "registry/dist/components/utils/image-exporter.js" }, @@ -707,7 +715,7 @@ "type": "component", "name": "downloadVideo", "displayName": "下载视频", - "description": "在功能面板中添加下载视频支持. 请注意:\r\n- 不能下载超出账号权限的视频, 例如非大会员下载大会员清晰度视频, 或者大陆地区网络下载港澳台地区番剧, 都是不可以的.\r\n- 请勿短时间进行大量下载, 以免遭到 b 站 IP 封禁.\r\n", + "description": "在功能面板中添加下载视频支持. 请注意:\r\n- 不能下载超出账号权限的视频, 例如非大会员下载大会员清晰度视频, 或者大陆地区网络下载港澳台地区番剧, 都是不可以的.\r\n- 请勿短时间进行大量下载, 以免遭到 b 站 IP 封禁.\r\n\r\n在使用视频 (非番剧) 批量下载时, 文件的批量命名格式中可以使用以下额外变量:\r\n- `user`: UP 主用户名\r\n- `userID`: UP 主用户 ID\r\n- 视频发布时间:\r\n - `publishYear`\r\n - `publishMonth`\r\n - `publishDay`\r\n - `publishHour`\r\n - `publishMinute`\r\n - `publishSecond`\r\n - `publishMillisecond`\r\n", "fullRelativePath": "../../registry/dist/components/video/download.js", "fullAbsolutePath": "registry/dist/components/video/download.js" }, diff --git a/doc/features/features.md b/doc/features/features.md index 810fc1d516..7e143954e2 100644 --- a/doc/features/features.md +++ b/doc/features/features.md @@ -188,6 +188,17 @@ by [@TimmyOVO](https://github.com/TimmyOVO) 在直播间中提供返回原版直播间的按钮, 原版直播间将无视活动皮肤, 强制使用标准的直播页面. +### [删除直播马赛克遮罩](../../registry/dist/components/live/remove-mask-panel.js) +`removeLiveMaskPanel` + +**jsDelivr:** [`Stable`](https://cdn.jsdelivr.net/gh/the1812/Bilibili-Evolved@master/registry/dist/components/live/remove-mask-panel.js) / [`Preview`](https://cdn.jsdelivr.net/gh/the1812/Bilibili-Evolved@preview/registry/dist/components/live/remove-mask-panel.js) + +**GitHub:** [`Stable`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/live/remove-mask-panel.js) / [`Preview`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/live/remove-mask-panel.js) + +by [@Liki4](https://github.com/Liki4) + +删除观看直播时某些分区的马赛克遮罩. + ### [删除直播水印](../../registry/dist/components/live/remove-watermark.js) `removeLiveWatermark` @@ -733,14 +744,43 @@ by [@snowraincloud](https://github.com/snowraincloud) 可以批量导出某个地方的图片, 目前支持动态和专栏. 动态文件名变量: -- `user`: 用户名 -- `originalUser`: 被转发用户名, 如果不是转发类型的动态则等于 `user` -- `id`: 动态 ID - `n`: 第 n 张图 +- `id`: 动态 ID +- `user`: 用户名 +- `userID`: 用户 ID +- 动态发布时间: + - `publishYear` + - `publishMonth` + - `publishDay` + - `publishHour` + - `publishMinute` + - `publishSecond` + - `publishMillisecond` +- 被转发的数据 (如果不是转发类型的动态, 则和上面的对应变量相同): + - `originalID`: 被转发的动态 ID + - `originalUser`: 被转发的用户名 + - `originalUserID`: 被转发用户 ID + - 被转发的动态发布时间: + - `originalPublishYear` + - `originalPublishMonth` + - `originalPublishDay` + - `originalPublishHour` + - `originalPublishMinute` + - `originalPublishSecond` + - `originalPublishMillisecond` 专栏文件名变量: -- `title`: 专栏标题 - `n`: 第 n 张图 +- `title`: 专栏标题 +- `cv`: 专栏 cv 号 +- 专栏发布时间: + - `publishYear` + - `publishMonth` + - `publishDay` + - `publishHour` + - `publishMinute` + - `publishSecond` + - `publishMillisecond` ### [高分辨率图片](../../registry/dist/components/utils/image-resolution.js) `imageResolution` @@ -948,6 +988,18 @@ by [@kdxcxs](https://github.com/kdxcxs) - 不能下载超出账号权限的视频, 例如非大会员下载大会员清晰度视频, 或者大陆地区网络下载港澳台地区番剧, 都是不可以的. - 请勿短时间进行大量下载, 以免遭到 b 站 IP 封禁. +在使用视频 (非番剧) 批量下载时, 文件的批量命名格式中可以使用以下额外变量: +- `user`: UP 主用户名 +- `userID`: UP 主用户 ID +- 视频发布时间: + - `publishYear` + - `publishMonth` + - `publishDay` + - `publishHour` + - `publishMinute` + - `publishSecond` + - `publishMillisecond` + ### [展开视频简介](../../registry/dist/components/video/full-description.js) `fullVideoDescription` diff --git a/doc/features/pack/pack.json b/doc/features/pack/pack.json index 51e258618e..0a9d4d3e98 100644 --- a/doc/features/pack/pack.json +++ b/doc/features/pack/pack.json @@ -123,7 +123,7 @@ "type": "component", "name": "downloadVideo", "displayName": "下载视频", - "description": "在功能面板中添加下载视频支持. 请注意:\r\n- 不能下载超出账号权限的视频, 例如非大会员下载大会员清晰度视频, 或者大陆地区网络下载港澳台地区番剧, 都是不可以的.\r\n- 请勿短时间进行大量下载, 以免遭到 b 站 IP 封禁.\r\n", + "description": "在功能面板中添加下载视频支持. 请注意:\r\n- 不能下载超出账号权限的视频, 例如非大会员下载大会员清晰度视频, 或者大陆地区网络下载港澳台地区番剧, 都是不可以的.\r\n- 请勿短时间进行大量下载, 以免遭到 b 站 IP 封禁.\r\n\r\n在使用视频 (非番剧) 批量下载时, 文件的批量命名格式中可以使用以下额外变量:\r\n- `user`: UP 主用户名\r\n- `userID`: UP 主用户 ID\r\n- 视频发布时间:\r\n - `publishYear`\r\n - `publishMonth`\r\n - `publishDay`\r\n - `publishHour`\r\n - `publishMinute`\r\n - `publishSecond`\r\n - `publishMillisecond`\r\n", "fullRelativePath": "../../registry/dist/components/video/download.js", "fullAbsolutePath": "registry/dist/components/video/download.js" }, From b61e74efbee58e2e95d731c89d45ee33f5c38c0e Mon Sep 17 00:00:00 2001 From: the1812 Date: Thu, 15 Aug 2024 23:21:47 +0800 Subject: [PATCH 30/30] Update changelog --- CHANGELOG.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f4844844b..d95254c066 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,26 @@ # 更新日志 -## v2.9.1 / v2.9.1-preview +## v2.9.1-preview +`2024-08-15` + +包含 [v2.9.1](https://github.com/the1812/Bilibili-Evolved/releases/tag/v2.9.1) 的所有更新内容. + +✨新增 +- `查看封面` 可以为 aria2 输出提供直接的封面下载. (PR #4798 by [Oxygenくん](https://github.com/oxygenkun)) +- 新增组件 `保存视频元数据`. (PR #4840 by [WakelessSloth56](https://github.com/WakelessSloth56)) +> - 保存视频元数据为 [FFMETADATA](https://ffmpeg.org/ffmpeg-formats.html#Metadata-2) 格式 +> - 使用组件 `下载视频` 时指定 `WASM` 输出方式(插件 `下载视频 - WASM 混流输出`)可选择是否直接混流入输出文件。 +> - 保存视频章节为 OGM 格式 (https://github.com/the1812/Bilibili-Evolved/discussions/2069#discussioncomment-10110916) + +- `简化首页` 支持隐藏轮播图. (PR #4852 by [Lime](https://github.com/Liumingxun)) +- 新增组件 `添加直播间用户超链接`. (PR #4856 by [Light_Quanta](https://github.com/LightQuanta)) +> 网页版直播间右上角的房间观众和大航海界面的用户列表只可查看用户名,不可进行点击。该组件为用户头像和用户名称处添加点击效果,允许通过点击直接查看用户空间。 + +- 插件 `下载视频 - WASM 混流输出` 支持并行下载库和音视频流. (PR #4864 by [WakelessSloth56](https://github.com/WakelessSloth56)) + +## v2.9.1 +`2024-08-15`
正式版用户将获得 v2.9.0-preview 的所有改动 (新功能以及一项废弃), 点击展开查看