feat: compat Firefox

This commit is contained in:
starknt
2024-01-05 16:57:53 +08:00
parent 68667c7cbb
commit 4f2246cf7f
4 changed files with 80 additions and 65 deletions

View File

@@ -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 <html> 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)
})
}

View File

@@ -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)
}

View File

@@ -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/*'],

1
src/utils/env.ts Normal file
View File

@@ -0,0 +1 @@
export const isFirefox: boolean = /Firefox/i.test(navigator.userAgent)