|
1 | 1 | import { createPinia } from 'pinia' |
2 | 2 | import type { Component } from 'vue' |
3 | 3 | import { createApp } from 'vue' |
| 4 | +import { browser, PublicPath } from 'wxt/browser' |
4 | 5 | import { ContentScriptContext } from 'wxt/utils/content-script-context' |
5 | 6 | import { createShadowRootUi } from 'wxt/utils/content-script-ui/shadow-root' |
6 | 7 |
|
7 | 8 | import { initToast } from '@/composables/useToast' |
8 | 9 | import { CONTENT_UI_SHADOW_ROOT_NAME } from '@/utils/constants' |
9 | | -import { extractFontFace, injectStyleSheetToDocument, loadContentScriptStyleSheet } from '@/utils/css' |
| 10 | +import { |
| 11 | + extractFontFace, |
| 12 | + injectStyleSheetToDocument, |
| 13 | + loadContentScriptStyleSheet, |
| 14 | + replaceFontFaceUrl, |
| 15 | +} from '@/utils/css' |
10 | 16 | import { createI18nInstance } from '@/utils/i18n/index' |
11 | 17 | import logger from '@/utils/logger' |
12 | 18 |
|
13 | 19 | async function loadStyleSheet(shadowRoot: ShadowRoot) { |
14 | | - const styleSheet = await loadContentScriptStyleSheet(import.meta.env.ENTRYPOINT) |
| 20 | + const styleSheet = await loadContentScriptStyleSheet( |
| 21 | + import.meta.env.ENTRYPOINT, |
| 22 | + ) |
15 | 23 | injectStyleSheetToDocument(shadowRoot, styleSheet) |
16 | 24 | // font-face can only be applied to the document, not the shadow root |
17 | 25 | const fontFaceStyleSheet = extractFontFace(styleSheet) |
| 26 | + // Content script stylesheets are parsed via new CSSStyleSheet() + replaceSync(), |
| 27 | + // so @font-face URLs (e.g. /fonts/Inter.woff2) resolve against the page URL |
| 28 | + // instead of the extension URL. Convert to absolute extension URLs. |
| 29 | + replaceFontFaceUrl(fontFaceStyleSheet, (url) => { |
| 30 | + if ( |
| 31 | + url.startsWith('data:') |
| 32 | + || url.startsWith('moz-extension://') |
| 33 | + || url.startsWith('chrome-extension://') |
| 34 | + || url.startsWith('http://') |
| 35 | + || url.startsWith('https://') |
| 36 | + || url.startsWith('blob:') |
| 37 | + ) { |
| 38 | + return url |
| 39 | + } |
| 40 | + return browser.runtime.getURL(url as PublicPath) |
| 41 | + }) |
18 | 42 | injectStyleSheetToDocument(document, fontFaceStyleSheet) |
19 | 43 | } |
20 | 44 |
|
21 | | -export async function createShadowRootOverlay(ctx: ContentScriptContext, component: Component<{ rootElement: HTMLDivElement }>) { |
| 45 | +export async function createShadowRootOverlay( |
| 46 | + ctx: ContentScriptContext, |
| 47 | + component: Component<{ rootElement: HTMLDivElement }>, |
| 48 | +) { |
22 | 49 | const existingUI = document.querySelector(CONTENT_UI_SHADOW_ROOT_NAME) |
23 | 50 | if (existingUI) { |
24 | 51 | try { |
|
0 commit comments