Skip to content

Commit 0113889

Browse files
committed
fix: 新增B站原始顶栏的登录按钮跳转 #436
1 parent 8d69a54 commit 0113889

File tree

4 files changed

+82
-58
lines changed

4 files changed

+82
-58
lines changed

src/contentScripts/index.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { setupApp } from '~/logic/common-setup'
1010
import { useTopBarStore } from '~/stores/topBarStore'
1111
import RESET_BEWLY_CSS from '~/styles/reset.css?raw'
1212
import { cleanupBilibiliScripts } from '~/utils/bilibiliScriptCleanup'
13-
import { captureOriginalBilibiliTopBar, ensureOriginalBilibiliTopBarAppended, resetBilibiliTopBarInlineStyles } from '~/utils/bilibiliTopBar'
13+
import { captureOriginalBilibiliTopBar, ensureOriginalBilibiliTopBarAppended, resetBilibiliTopBarInlineStyles, setupLoginButtonClickHandlers } from '~/utils/bilibiliTopBar'
1414
import { initFavoriteDialogEnhancement } from '~/utils/favoriteDialog'
1515
import { runWhenIdle } from '~/utils/lazyLoad'
1616
import { getLocalWallpaper, hasLocalWallpaper, isLocalWallpaperUrl } from '~/utils/localWallpaper'
@@ -433,6 +433,9 @@ async function onDOMLoaded() {
433433

434434
ensureOriginalBilibiliTopBarAppended(document)
435435

436+
// Setup login button click handlers for the original Bilibili top bar
437+
setupLoginButtonClickHandlers(document)
438+
436439
// 如果要使用方案1(删除DOM),取消注释以下代码并注释掉上面的 CSS 方案:
437440
/*
438441
// 清理 B 站脚本资源,避免内存泄漏和性能问题
@@ -686,8 +689,11 @@ window.addEventListener('message', (event) => {
686689
return
687690

688691
document.documentElement.classList.toggle('remove-top-bar', !useOriginalBilibiliTopBar)
689-
if (useOriginalBilibiliTopBar)
692+
if (useOriginalBilibiliTopBar) {
690693
resetBilibiliTopBarInlineStyles(document)
694+
// Setup login button click handlers when switching to original top bar
695+
setupLoginButtonClickHandlers(document)
696+
}
691697
}
692698
}, { passive: true })
693699

src/contentScripts/views/App.vue

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import UpdateLogNotifier from '~/components/UpdateLogNotifier.vue'
77
import type { BewlyAppProvider } from '~/composables/useAppProvider'
88
import { DrawerType, UndoForwardState } from '~/composables/useAppProvider'
99
import { useDark } from '~/composables/useDark'
10-
import { BEWLY_MOUNTED, DRAWER_VIDEO_ENTER_PAGE_FULL, DRAWER_VIDEO_EXIT_PAGE_FULL, IFRAME_PAGE_SWITCH_BEWLY, IFRAME_PAGE_SWITCH_BILI, OVERLAY_SCROLL_BAR_SCROLL } from '~/constants/globalEvents'
10+
import { BEWLY_MOUNTED, DRAWER_VIDEO_ENTER_PAGE_FULL, DRAWER_VIDEO_EXIT_PAGE_FULL, IFRAME_PAGE_SWITCH_BEWLY, IFRAME_PAGE_SWITCH_BILI, OVERLAY_SCROLL_BAR_SCROLL, OVERLAY_SCROLL_STATE_CHANGE } from '~/constants/globalEvents'
1111
import { HomeSubPage } from '~/contentScripts/views/Home/types'
1212
import { AppPage } from '~/enums/appEnums'
1313
import { settings } from '~/logic'
@@ -514,6 +514,7 @@ function handleBackToTop(targetScrollTop = 0 as number) {
514514
515515
// 添加滚动结束检测
516516
let scrollEndTimer: ReturnType<typeof setTimeout> | null = null
517+
let scrollStateTimer: ReturnType<typeof setTimeout> | null = null
517518
let lastScrollTop = 0
518519
let rafId: number | null = null
519520
@@ -522,6 +523,9 @@ function handleOsScroll() {
522523
if (rafId !== null)
523524
return
524525
526+
// 发出滚动开始信号(用于 useGlobalScrollState)
527+
emitter.emit(OVERLAY_SCROLL_STATE_CHANGE, true)
528+
525529
// 使用 RAF 将所有 DOM 读取合并到下一帧
526530
rafId = requestAnimationFrame(() => {
527531
const osInstance = scrollbarRef.value?.osInstance()
@@ -560,6 +564,16 @@ function handleOsScroll() {
560564
clearTimeout(scrollEndTimer)
561565
}
562566
567+
// 清除之前的滚动状态定时器
568+
if (scrollStateTimer) {
569+
clearTimeout(scrollStateTimer)
570+
}
571+
572+
// 设置滚动状态结束检测,150ms后发出滚动结束信号
573+
scrollStateTimer = setTimeout(() => {
574+
emitter.emit(OVERLAY_SCROLL_STATE_CHANGE, false)
575+
}, 150)
576+
563577
// 设置滚动结束检测,在滚动停止150ms后再检查一次
564578
// 缓存当前的滚动值,避免在 setTimeout 中再次读取 DOM
565579
const cachedScrollTop = scrollTop

src/utils/bilibiliScriptCleanup.ts

Lines changed: 1 addition & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,6 @@
33
* 用于在替换首页时减少B站原生脚本的性能影响,避免内存泄漏
44
*/
55

6-
/**
7-
* 清理 B 站特定的定时器
8-
* 使用更温和的策略,只清理已知的 B 站定时器
9-
*/
10-
function clearBilibiliTimers() {
11-
// 不再清理所有定时器,因为可能会影响插件自身
12-
// 改为记录一个基准 ID,后续可以选择性清理
13-
const baseTimerId = setTimeout(() => {}, 0)
14-
clearTimeout(baseTimerId)
15-
16-
console.log('[BewlyBewly] Recorded base timer ID:', baseTimerId)
17-
18-
// 返回基准 ID 供后续使用
19-
return baseTimerId
20-
}
21-
226
/**
237
* 清理 B 站的全局变量和对象
248
*/
@@ -49,38 +33,6 @@ function cleanupGlobalObjects() {
4933
}
5034
}
5135

52-
/**
53-
* 禁用 B 站的 MutationObserver
54-
* 防止 B 站脚本监听 DOM 变化后尝试操作不存在的元素
55-
*/
56-
function disableBilibiliMutationObservers() {
57-
// 保存原始的 MutationObserver
58-
const OriginalMutationObserver = window.MutationObserver
59-
const observersToDisable: MutationObserver[] = []
60-
61-
// 代理 MutationObserver,记录所有创建的 observer
62-
window.MutationObserver = class extends OriginalMutationObserver {
63-
constructor(callback: MutationCallback) {
64-
super(callback)
65-
observersToDisable.push(this)
66-
}
67-
} as any
68-
69-
// 500ms 后断开所有 observer 并恢复原始构造函数
70-
setTimeout(() => {
71-
observersToDisable.forEach((observer) => {
72-
try {
73-
observer.disconnect()
74-
}
75-
catch {
76-
// 忽略错误
77-
}
78-
})
79-
window.MutationObserver = OriginalMutationObserver
80-
console.log('[BewlyBewly] Disconnected', observersToDisable.length, 'MutationObservers')
81-
}, 500)
82-
}
83-
8436
/**
8537
* 主清理函数(温和版本)
8638
* 在清空 DOM 之前调用,减少 B 站脚本的性能影响
@@ -89,15 +41,9 @@ export function cleanupBilibiliScripts() {
8941
console.log('[BewlyBewly] Starting gentle Bilibili script cleanup...')
9042

9143
try {
92-
// 1. 记录定时器基准(不清理)
93-
clearBilibiliTimers()
94-
95-
// 2. 清理全局对象
44+
// 清理全局对象
9645
cleanupGlobalObjects()
9746

98-
// 3. 禁用 MutationObserver
99-
disableBilibiliMutationObservers()
100-
10147
console.log('[BewlyBewly] Gentle cleanup completed')
10248
}
10349
catch (e) {

src/utils/bilibiliTopBar.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,61 @@ export function resetBilibiliTopBarInlineStyles(doc: Document) {
7070
})
7171
}
7272
}
73+
74+
/**
75+
* Add click event listeners to login buttons in the original Bilibili top bar
76+
* to redirect users to the login page.
77+
*/
78+
export function setupLoginButtonClickHandlers(doc: Document) {
79+
const LOGIN_URL = 'https://passport.bilibili.com/login'
80+
81+
// Function to handle login button binding
82+
function bindLoginButton(button: HTMLElement) {
83+
if (button.hasAttribute('data-bewly-login-handler'))
84+
return
85+
86+
button.setAttribute('data-bewly-login-handler', 'true')
87+
button.style.cursor = 'pointer'
88+
button.addEventListener('click', (e) => {
89+
e.preventDefault()
90+
e.stopPropagation()
91+
window.location.href = LOGIN_URL
92+
})
93+
}
94+
95+
// Bind existing login buttons
96+
const existingButtons = doc.querySelectorAll<HTMLElement>('.login-btn')
97+
existingButtons.forEach(bindLoginButton)
98+
99+
// Use MutationObserver to handle dynamically added popup elements
100+
const observer = new MutationObserver((mutations) => {
101+
mutations.forEach((mutation) => {
102+
mutation.addedNodes.forEach((node) => {
103+
// Check if the added node is an element
104+
if (node.nodeType === Node.ELEMENT_NODE) {
105+
const element = node as HTMLElement
106+
107+
// Check if the added node itself is a login button
108+
if (element.classList.contains('login-btn')) {
109+
bindLoginButton(element)
110+
}
111+
112+
// Check if the added node contains login buttons
113+
const loginButtons = element.querySelectorAll<HTMLElement>('.login-btn')
114+
loginButtons.forEach(bindLoginButton)
115+
}
116+
})
117+
})
118+
})
119+
120+
// Observe the entire document for popup elements
121+
observer.observe(doc.body, {
122+
childList: true,
123+
subtree: true,
124+
})
125+
126+
// Return cleanup function
127+
return () => {
128+
observer.disconnect()
129+
}
130+
}

0 commit comments

Comments
 (0)