diff --git a/src/contentScripts/index.ts b/src/contentScripts/index.ts index d1e53da5..89582cc6 100644 --- a/src/contentScripts/index.ts +++ b/src/contentScripts/index.ts @@ -8,6 +8,17 @@ import { SVG_ICONS } from '~/utils/svgIcons' import { injectCSS } from '~/utils/main' import { settings } from '~/logic' import { runWhenIdle } from '~/utils/lazyLoad' +import { isFirefox } from '~/utils/env' + +// Fix `OverlayScrollbars` not working in Firefox +if (isFirefox) { + window.requestIdleCallback = window.requestIdleCallback.bind(window) + window.cancelIdleCallback = window.cancelIdleCallback.bind(window) + window.requestAnimationFrame = window.requestAnimationFrame.bind(window) + window.cancelAnimationFrame = window.cancelAnimationFrame.bind(window) + window.setTimeout = window.setTimeout.bind(window) + window.clearTimeout = window.clearTimeout.bind(window) +} const currentUrl = document.URL @@ -51,8 +62,6 @@ function isSupportedPage() { return false } -const isFirefox: boolean = /Firefox/i.test(navigator.userAgent) - let beforeLoadedStyleEl: HTMLStyleElement // Since using runWhenIdle does not instantly inject the app to the page, a style class cannot be injected immediately to the tag @@ -83,28 +92,9 @@ if (settings.value.adaptToOtherPageStyles && isSupportedPage()) { `) } -if (isFirefox) { - let isFirstScriptExecute = true - document.addEventListener('beforescriptexecute', () => { - if (!isFirstScriptExecute) - return - - // runWhenIdle(() => { - injectApp() - // }) - isFirstScriptExecute = false - }) -} -else { - document.addEventListener('DOMContentLoaded', () => { - // runWhenIdle(() => { - injectApp() - // }) - }) -} - -async function injectApp() { - const currentUrl = document.URL +document.addEventListener('DOMContentLoaded', () => { + if (isFirefox) + document.querySelector('meta[name="referrer"]')?.setAttribute('content', 'no-referrer') if (isSupportedPage()) { if ( @@ -121,49 +111,67 @@ async function injectApp() { if (originalPageContent) originalPageContent.innerHTML = '' } + } +}) - // Inject style first - const newStyleEl = document.createElement('link') - newStyleEl.setAttribute('rel', 'stylesheet') - newStyleEl.setAttribute('href', browser.runtime.getURL('dist/contentScripts/style.css')) - document.documentElement.appendChild(newStyleEl) - newStyleEl.onload = async () => { - // To prevent abrupt style transitions caused by sudden style changes +if (isFirefox) { + let isFirstScriptExecute = true + document.addEventListener('beforescriptexecute', () => { + if (!isFirstScriptExecute) + return + + injectApp() + isFirstScriptExecute = false + }) +} +else { + document.addEventListener('DOMContentLoaded', () => { + injectApp() + }) +} + +function injectApp() { + // Inject style first + const newStyleEl = document.createElement('link') + newStyleEl.setAttribute('rel', 'stylesheet') + newStyleEl.setAttribute('href', browser.runtime.getURL('dist/contentScripts/style.css')) + document.documentElement.appendChild(newStyleEl) + newStyleEl.onload = () => { + // To prevent abrupt style transitions caused by sudden style changes + setTimeout(() => { + document.documentElement.removeChild(beforeLoadedStyleEl) + }, 500) + } + + // Inject app when idle + runWhenIdle(async () => { + // mount component to context window + const container = document.createElement('div') + container.id = 'bewly' + const root = document.createElement('div') + const styleEl = document.createElement('link') + const shadowDOM = container.attachShadow?.({ mode: __DEV__ ? 'open' : 'closed' }) || container + styleEl.setAttribute('rel', 'stylesheet') + styleEl.setAttribute('href', browser.runtime.getURL('dist/contentScripts/style.css')) + shadowDOM.appendChild(styleEl) + shadowDOM.appendChild(root) + container.style.opacity = '0' + container.style.transition = 'opacity 0.5s' + styleEl.onload = () => { setTimeout(() => { - document.documentElement.removeChild(beforeLoadedStyleEl) + container.style.opacity = '1' }, 500) } - // Inject app when idle - runWhenIdle(() => { - // mount component to context window - const container = document.createElement('div') - container.id = 'bewly' - const root = document.createElement('div') - const styleEl = document.createElement('link') - const shadowDOM = container.attachShadow?.({ mode: __DEV__ ? 'open' : 'closed' }) || container - styleEl.setAttribute('rel', 'stylesheet') - styleEl.setAttribute('href', browser.runtime.getURL('dist/contentScripts/style.css')) - shadowDOM.appendChild(styleEl) - shadowDOM.appendChild(root) - container.style.opacity = '0' - container.style.transition = 'opacity 0.5s' - styleEl.onload = () => { - setTimeout(() => { - container.style.opacity = '1' - }, 500) - } + // inject svg icons + const svgDiv = document.createElement('div') + svgDiv.innerHTML = SVG_ICONS + shadowDOM.appendChild(svgDiv) - // inject svg icons - const svgDiv = document.createElement('div') - svgDiv.innerHTML = SVG_ICONS - shadowDOM.appendChild(svgDiv) + document.body.appendChild(container) - document.body.appendChild(container) - - const app = createApp(App) - setupApp(app) - app.mount(root) - }) - } + const app = createApp(App) + await setupApp(app) + app.mount(root) + }) } diff --git a/src/logic/common-setup.ts b/src/logic/common-setup.ts index 1c760522..ce8b2a33 100644 --- a/src/logic/common-setup.ts +++ b/src/logic/common-setup.ts @@ -2,14 +2,13 @@ import type { App } from 'vue' import { getCurrentContext } from 'webext-bridge' import Toast, { POSITION } from 'vue-toastification' import { createPinia } from 'pinia' -import { OverlayScrollbarsComponent } from 'overlayscrollbars-vue' import { i18n } from '~/utils/i18n' import 'vue-toastification/dist/index.css' import 'overlayscrollbars/overlayscrollbars.css' const pinia = createPinia() -export function setupApp(app: App) { +export async function setupApp(app: App) { const context = getCurrentContext() // Inject a globally available `$app` object in template @@ -30,5 +29,6 @@ export function setupApp(app: App) { position: POSITION.TOP_CENTER, }) app.use(pinia) + const { OverlayScrollbarsComponent } = await import('overlayscrollbars-vue') app.component('OverlayScrollbarsComponent', OverlayScrollbarsComponent) } diff --git a/src/manifest.ts b/src/manifest.ts index 8e55d023..0b062d28 100644 --- a/src/manifest.ts +++ b/src/manifest.ts @@ -36,7 +36,13 @@ export async function getManifest() { 'scripting', 'declarativeNetRequest', ], - host_permissions: ['*://*.bilibili.com/*', '*://*.mcbbs.net/*'], + host_permissions: [ + '*://*.bilibili.com/*', + '*://*.mcbbs.net/*', + '*://api.bilibili.com/*', + '*://*.hdslb.com/*', + '*://*.bilivideo.com/*', + ], content_scripts: [ { matches: ['*://www.bilibili.com/*', '*://search.bilibili.com/*', '*://t.bilibili.com/*', '*://space.bilibili.com/*', '*://message.bilibili.com/*'], diff --git a/src/utils/env.ts b/src/utils/env.ts new file mode 100644 index 00000000..03c23a8b --- /dev/null +++ b/src/utils/env.ts @@ -0,0 +1 @@ +export const isFirefox: boolean = /Firefox/i.test(navigator.userAgent)