diff --git a/CHANGELOG.md b/CHANGELOG.md index 97be4ff0..ca83963c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,37 @@ # Changelog +## v1.12.2 + +[compare changes](https://github.com/NativeMindBrowser/NativeMindExtension/compare/v1.12.1...v1.12.2) + +### 🚀 Enhancements + +- Add Inter and InterDisplay font families with various styles and weights; update font paths in CSS and config; enhance font face URL handling in stylesheets ([5cec648](https://github.com/NativeMindBrowser/NativeMindExtension/commit/5cec648)) + +### 💅 Refactors + +- Streamline font face URL handling in stylesheets by consolidating extraction and replacement logic ([d9ab298](https://github.com/NativeMindBrowser/NativeMindExtension/commit/d9ab298)) + +### ❤️ Contributors + +- Tony Hu ([@tonyhu-012](http://github.com/tonyhu-012)) + +## v1.12.1 + +[compare changes](https://github.com/NativeMindBrowser/NativeMindExtension/compare/v1.12.1-beta.0...v1.12.1) + +## v1.12.1-beta.0 + +[compare changes](https://github.com/NativeMindBrowser/NativeMindExtension/compare/v1.12.0...v1.12.1-beta.0) + +### 🩹 Fixes + +- Add more language entries to SUPPORTED_LANGUAGES for translation ([5d1a911](https://github.com/NativeMindBrowser/NativeMindExtension/commit/5d1a911)) + +### ❤️ Contributors + +- Neko Liu + ## v1.12.0 [compare changes](https://github.com/NativeMindBrowser/NativeMindExtension/compare/v1.12.0-beta.4...v1.12.0) diff --git a/entrypoints/content/ui.ts b/entrypoints/content/ui.ts index cd3aeacd..64674cee 100644 --- a/entrypoints/content/ui.ts +++ b/entrypoints/content/ui.ts @@ -1,24 +1,47 @@ import { createPinia } from 'pinia' import type { Component } from 'vue' import { createApp } from 'vue' +import { browser, PublicPath } from 'wxt/browser' import { ContentScriptContext } from 'wxt/utils/content-script-context' import { createShadowRootUi } from 'wxt/utils/content-script-ui/shadow-root' import { initToast } from '@/composables/useToast' import { CONTENT_UI_SHADOW_ROOT_NAME } from '@/utils/constants' -import { extractFontFace, injectStyleSheetToDocument, loadContentScriptStyleSheet } from '@/utils/css' +import { + extractFontFace, + injectStyleSheetToDocument, + loadContentScriptStyleSheet, + replaceFontFaceUrl, +} from '@/utils/css' import { createI18nInstance } from '@/utils/i18n/index' import logger from '@/utils/logger' async function loadStyleSheet(shadowRoot: ShadowRoot) { - const styleSheet = await loadContentScriptStyleSheet(import.meta.env.ENTRYPOINT) + const styleSheet = await loadContentScriptStyleSheet( + import.meta.env.ENTRYPOINT, + ) injectStyleSheetToDocument(shadowRoot, styleSheet) // font-face can only be applied to the document, not the shadow root - const fontFaceStyleSheet = extractFontFace(styleSheet) + const fontFaceStyleSheet = replaceFontFaceUrl(extractFontFace(styleSheet), (url) => { + if ( + url.startsWith('data:') + || url.startsWith('moz-extension://') + || url.startsWith('chrome-extension://') + || url.startsWith('http://') + || url.startsWith('https://') + || url.startsWith('blob:') + ) { + return url + } + return browser.runtime.getURL(url as PublicPath) + }) injectStyleSheetToDocument(document, fontFaceStyleSheet) } -export async function createShadowRootOverlay(ctx: ContentScriptContext, component: Component<{ rootElement: HTMLDivElement }>) { +export async function createShadowRootOverlay( + ctx: ContentScriptContext, + component: Component<{ rootElement: HTMLDivElement }>, +) { const existingUI = document.querySelector(CONTENT_UI_SHADOW_ROOT_NAME) if (existingUI) { try { diff --git a/package.json b/package.json index d389c8b3..763d57f1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativemind-extension", - "version": "1.12.0", + "version": "1.12.2", "private": false, "author": "NativeMind", "keywords": [ diff --git a/assets/fonts/Inter-Black.woff2 b/public/fonts/Inter-Black.woff2 similarity index 100% rename from assets/fonts/Inter-Black.woff2 rename to public/fonts/Inter-Black.woff2 diff --git a/assets/fonts/Inter-BlackItalic.woff2 b/public/fonts/Inter-BlackItalic.woff2 similarity index 100% rename from assets/fonts/Inter-BlackItalic.woff2 rename to public/fonts/Inter-BlackItalic.woff2 diff --git a/assets/fonts/Inter-Bold.woff2 b/public/fonts/Inter-Bold.woff2 similarity index 100% rename from assets/fonts/Inter-Bold.woff2 rename to public/fonts/Inter-Bold.woff2 diff --git a/assets/fonts/Inter-BoldItalic.woff2 b/public/fonts/Inter-BoldItalic.woff2 similarity index 100% rename from assets/fonts/Inter-BoldItalic.woff2 rename to public/fonts/Inter-BoldItalic.woff2 diff --git a/assets/fonts/Inter-ExtraBold.woff2 b/public/fonts/Inter-ExtraBold.woff2 similarity index 100% rename from assets/fonts/Inter-ExtraBold.woff2 rename to public/fonts/Inter-ExtraBold.woff2 diff --git a/assets/fonts/Inter-ExtraBoldItalic.woff2 b/public/fonts/Inter-ExtraBoldItalic.woff2 similarity index 100% rename from assets/fonts/Inter-ExtraBoldItalic.woff2 rename to public/fonts/Inter-ExtraBoldItalic.woff2 diff --git a/assets/fonts/Inter-ExtraLight.woff2 b/public/fonts/Inter-ExtraLight.woff2 similarity index 100% rename from assets/fonts/Inter-ExtraLight.woff2 rename to public/fonts/Inter-ExtraLight.woff2 diff --git a/assets/fonts/Inter-ExtraLightItalic.woff2 b/public/fonts/Inter-ExtraLightItalic.woff2 similarity index 100% rename from assets/fonts/Inter-ExtraLightItalic.woff2 rename to public/fonts/Inter-ExtraLightItalic.woff2 diff --git a/assets/fonts/Inter-Italic.woff2 b/public/fonts/Inter-Italic.woff2 similarity index 100% rename from assets/fonts/Inter-Italic.woff2 rename to public/fonts/Inter-Italic.woff2 diff --git a/assets/fonts/Inter-Light.woff2 b/public/fonts/Inter-Light.woff2 similarity index 100% rename from assets/fonts/Inter-Light.woff2 rename to public/fonts/Inter-Light.woff2 diff --git a/assets/fonts/Inter-LightItalic.woff2 b/public/fonts/Inter-LightItalic.woff2 similarity index 100% rename from assets/fonts/Inter-LightItalic.woff2 rename to public/fonts/Inter-LightItalic.woff2 diff --git a/assets/fonts/Inter-Medium.woff2 b/public/fonts/Inter-Medium.woff2 similarity index 100% rename from assets/fonts/Inter-Medium.woff2 rename to public/fonts/Inter-Medium.woff2 diff --git a/assets/fonts/Inter-MediumItalic.woff2 b/public/fonts/Inter-MediumItalic.woff2 similarity index 100% rename from assets/fonts/Inter-MediumItalic.woff2 rename to public/fonts/Inter-MediumItalic.woff2 diff --git a/assets/fonts/Inter-Regular.woff2 b/public/fonts/Inter-Regular.woff2 similarity index 100% rename from assets/fonts/Inter-Regular.woff2 rename to public/fonts/Inter-Regular.woff2 diff --git a/assets/fonts/Inter-SemiBold.woff2 b/public/fonts/Inter-SemiBold.woff2 similarity index 100% rename from assets/fonts/Inter-SemiBold.woff2 rename to public/fonts/Inter-SemiBold.woff2 diff --git a/assets/fonts/Inter-SemiBoldItalic.woff2 b/public/fonts/Inter-SemiBoldItalic.woff2 similarity index 100% rename from assets/fonts/Inter-SemiBoldItalic.woff2 rename to public/fonts/Inter-SemiBoldItalic.woff2 diff --git a/assets/fonts/Inter-Thin.woff2 b/public/fonts/Inter-Thin.woff2 similarity index 100% rename from assets/fonts/Inter-Thin.woff2 rename to public/fonts/Inter-Thin.woff2 diff --git a/assets/fonts/Inter-ThinItalic.woff2 b/public/fonts/Inter-ThinItalic.woff2 similarity index 100% rename from assets/fonts/Inter-ThinItalic.woff2 rename to public/fonts/Inter-ThinItalic.woff2 diff --git a/assets/fonts/InterDisplay-Black.woff2 b/public/fonts/InterDisplay-Black.woff2 similarity index 100% rename from assets/fonts/InterDisplay-Black.woff2 rename to public/fonts/InterDisplay-Black.woff2 diff --git a/assets/fonts/InterDisplay-BlackItalic.woff2 b/public/fonts/InterDisplay-BlackItalic.woff2 similarity index 100% rename from assets/fonts/InterDisplay-BlackItalic.woff2 rename to public/fonts/InterDisplay-BlackItalic.woff2 diff --git a/assets/fonts/InterDisplay-Bold.woff2 b/public/fonts/InterDisplay-Bold.woff2 similarity index 100% rename from assets/fonts/InterDisplay-Bold.woff2 rename to public/fonts/InterDisplay-Bold.woff2 diff --git a/assets/fonts/InterDisplay-BoldItalic.woff2 b/public/fonts/InterDisplay-BoldItalic.woff2 similarity index 100% rename from assets/fonts/InterDisplay-BoldItalic.woff2 rename to public/fonts/InterDisplay-BoldItalic.woff2 diff --git a/assets/fonts/InterDisplay-ExtraBold.woff2 b/public/fonts/InterDisplay-ExtraBold.woff2 similarity index 100% rename from assets/fonts/InterDisplay-ExtraBold.woff2 rename to public/fonts/InterDisplay-ExtraBold.woff2 diff --git a/assets/fonts/InterDisplay-ExtraBoldItalic.woff2 b/public/fonts/InterDisplay-ExtraBoldItalic.woff2 similarity index 100% rename from assets/fonts/InterDisplay-ExtraBoldItalic.woff2 rename to public/fonts/InterDisplay-ExtraBoldItalic.woff2 diff --git a/assets/fonts/InterDisplay-ExtraLight.woff2 b/public/fonts/InterDisplay-ExtraLight.woff2 similarity index 100% rename from assets/fonts/InterDisplay-ExtraLight.woff2 rename to public/fonts/InterDisplay-ExtraLight.woff2 diff --git a/assets/fonts/InterDisplay-ExtraLightItalic.woff2 b/public/fonts/InterDisplay-ExtraLightItalic.woff2 similarity index 100% rename from assets/fonts/InterDisplay-ExtraLightItalic.woff2 rename to public/fonts/InterDisplay-ExtraLightItalic.woff2 diff --git a/assets/fonts/InterDisplay-Italic.woff2 b/public/fonts/InterDisplay-Italic.woff2 similarity index 100% rename from assets/fonts/InterDisplay-Italic.woff2 rename to public/fonts/InterDisplay-Italic.woff2 diff --git a/assets/fonts/InterDisplay-Light.woff2 b/public/fonts/InterDisplay-Light.woff2 similarity index 100% rename from assets/fonts/InterDisplay-Light.woff2 rename to public/fonts/InterDisplay-Light.woff2 diff --git a/assets/fonts/InterDisplay-LightItalic.woff2 b/public/fonts/InterDisplay-LightItalic.woff2 similarity index 100% rename from assets/fonts/InterDisplay-LightItalic.woff2 rename to public/fonts/InterDisplay-LightItalic.woff2 diff --git a/assets/fonts/InterDisplay-Medium.woff2 b/public/fonts/InterDisplay-Medium.woff2 similarity index 100% rename from assets/fonts/InterDisplay-Medium.woff2 rename to public/fonts/InterDisplay-Medium.woff2 diff --git a/assets/fonts/InterDisplay-MediumItalic.woff2 b/public/fonts/InterDisplay-MediumItalic.woff2 similarity index 100% rename from assets/fonts/InterDisplay-MediumItalic.woff2 rename to public/fonts/InterDisplay-MediumItalic.woff2 diff --git a/assets/fonts/InterDisplay-Regular.woff2 b/public/fonts/InterDisplay-Regular.woff2 similarity index 100% rename from assets/fonts/InterDisplay-Regular.woff2 rename to public/fonts/InterDisplay-Regular.woff2 diff --git a/assets/fonts/InterDisplay-SemiBold.woff2 b/public/fonts/InterDisplay-SemiBold.woff2 similarity index 100% rename from assets/fonts/InterDisplay-SemiBold.woff2 rename to public/fonts/InterDisplay-SemiBold.woff2 diff --git a/assets/fonts/InterDisplay-SemiBoldItalic.woff2 b/public/fonts/InterDisplay-SemiBoldItalic.woff2 similarity index 100% rename from assets/fonts/InterDisplay-SemiBoldItalic.woff2 rename to public/fonts/InterDisplay-SemiBoldItalic.woff2 diff --git a/assets/fonts/InterDisplay-Thin.woff2 b/public/fonts/InterDisplay-Thin.woff2 similarity index 100% rename from assets/fonts/InterDisplay-Thin.woff2 rename to public/fonts/InterDisplay-Thin.woff2 diff --git a/assets/fonts/InterDisplay-ThinItalic.woff2 b/public/fonts/InterDisplay-ThinItalic.woff2 similarity index 100% rename from assets/fonts/InterDisplay-ThinItalic.woff2 rename to public/fonts/InterDisplay-ThinItalic.woff2 diff --git a/assets/fonts/InterVariable-Italic.woff2 b/public/fonts/InterVariable-Italic.woff2 similarity index 100% rename from assets/fonts/InterVariable-Italic.woff2 rename to public/fonts/InterVariable-Italic.woff2 diff --git a/assets/fonts/InterVariable.woff2 b/public/fonts/InterVariable.woff2 similarity index 100% rename from assets/fonts/InterVariable.woff2 rename to public/fonts/InterVariable.woff2 diff --git a/styles/font-faces.css b/styles/font-faces.css index 2c15e6c8..c9a2250e 100644 --- a/styles/font-faces.css +++ b/styles/font-faces.css @@ -8,14 +8,14 @@ font-style: normal; font-weight: 100 900; font-display: swap; - src: url("../../assets/fonts/InterVariable.woff2") format("woff2"); + src: url("/fonts/InterVariable.woff2") format("woff2"); } @font-face { font-family: InterVariable; font-style: italic; font-weight: 100 900; font-display: swap; - src: url("../../assets/fonts/InterVariable-Italic.woff2") format("woff2"); + src: url("/fonts/InterVariable-Italic.woff2") format("woff2"); } /* static fonts */ @@ -24,252 +24,252 @@ font-style: normal; font-weight: 100; font-display: swap; - src: url("../../assets/fonts/Inter-Thin.woff2") format("woff2"); + src: url("/fonts/Inter-Thin.woff2") format("woff2"); } @font-face { font-family: "Inter"; font-style: italic; font-weight: 100; font-display: swap; - src: url("../../assets/fonts/Inter-ThinItalic.woff2") format("woff2"); + src: url("/fonts/Inter-ThinItalic.woff2") format("woff2"); } @font-face { font-family: "Inter"; font-style: normal; font-weight: 200; font-display: swap; - src: url("../../assets/fonts/Inter-ExtraLight.woff2") format("woff2"); + src: url("/fonts/Inter-ExtraLight.woff2") format("woff2"); } @font-face { font-family: "Inter"; font-style: italic; font-weight: 200; font-display: swap; - src: url("../../assets/fonts/Inter-ExtraLightItalic.woff2") format("woff2"); + src: url("/fonts/Inter-ExtraLightItalic.woff2") format("woff2"); } @font-face { font-family: "Inter"; font-style: normal; font-weight: 300; font-display: swap; - src: url("../../assets/fonts/Inter-Light.woff2") format("woff2"); + src: url("/fonts/Inter-Light.woff2") format("woff2"); } @font-face { font-family: "Inter"; font-style: italic; font-weight: 300; font-display: swap; - src: url("../../assets/fonts/Inter-LightItalic.woff2") format("woff2"); + src: url("/fonts/Inter-LightItalic.woff2") format("woff2"); } @font-face { font-family: "Inter"; font-style: normal; font-weight: 400; font-display: swap; - src: url("../../assets/fonts/Inter-Regular.woff2") format("woff2"); + src: url("/fonts/Inter-Regular.woff2") format("woff2"); } @font-face { font-family: "Inter"; font-style: italic; font-weight: 400; font-display: swap; - src: url("../../assets/fonts/Inter-Italic.woff2") format("woff2"); + src: url("/fonts/Inter-Italic.woff2") format("woff2"); } @font-face { font-family: "Inter"; font-style: normal; font-weight: 500; font-display: swap; - src: url("../../assets/fonts/Inter-Medium.woff2") format("woff2"); + src: url("/fonts/Inter-Medium.woff2") format("woff2"); } @font-face { font-family: "Inter"; font-style: italic; font-weight: 500; font-display: swap; - src: url("../../assets/fonts/Inter-MediumItalic.woff2") format("woff2"); + src: url("/fonts/Inter-MediumItalic.woff2") format("woff2"); } @font-face { font-family: "Inter"; font-style: normal; font-weight: 600; font-display: swap; - src: url("../../assets/fonts/Inter-SemiBold.woff2") format("woff2"); + src: url("/fonts/Inter-SemiBold.woff2") format("woff2"); } @font-face { font-family: "Inter"; font-style: italic; font-weight: 600; font-display: swap; - src: url("../../assets/fonts/Inter-SemiBoldItalic.woff2") format("woff2"); + src: url("/fonts/Inter-SemiBoldItalic.woff2") format("woff2"); } @font-face { font-family: "Inter"; font-style: normal; font-weight: 700; font-display: swap; - src: url("../../assets/fonts/Inter-Bold.woff2") format("woff2"); + src: url("/fonts/Inter-Bold.woff2") format("woff2"); } @font-face { font-family: "Inter"; font-style: italic; font-weight: 700; font-display: swap; - src: url("../../assets/fonts/Inter-BoldItalic.woff2") format("woff2"); + src: url("/fonts/Inter-BoldItalic.woff2") format("woff2"); } @font-face { font-family: "Inter"; font-style: normal; font-weight: 800; font-display: swap; - src: url("../../assets/fonts/Inter-ExtraBold.woff2") format("woff2"); + src: url("/fonts/Inter-ExtraBold.woff2") format("woff2"); } @font-face { font-family: "Inter"; font-style: italic; font-weight: 800; font-display: swap; - src: url("../../assets/fonts/Inter-ExtraBoldItalic.woff2") format("woff2"); + src: url("/fonts/Inter-ExtraBoldItalic.woff2") format("woff2"); } @font-face { font-family: "Inter"; font-style: normal; font-weight: 900; font-display: swap; - src: url("../../assets/fonts/Inter-Black.woff2") format("woff2"); + src: url("/fonts/Inter-Black.woff2") format("woff2"); } @font-face { font-family: "Inter"; font-style: italic; font-weight: 900; font-display: swap; - src: url("../../assets/fonts/Inter-BlackItalic.woff2") format("woff2"); + src: url("/fonts/Inter-BlackItalic.woff2") format("woff2"); } @font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 100; font-display: swap; - src: url("../../assets/fonts/InterDisplay-Thin.woff2") format("woff2"); + src: url("/fonts/InterDisplay-Thin.woff2") format("woff2"); } @font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 100; font-display: swap; - src: url("../../assets/fonts/InterDisplay-ThinItalic.woff2") format("woff2"); + src: url("/fonts/InterDisplay-ThinItalic.woff2") format("woff2"); } @font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 200; font-display: swap; - src: url("../../assets/fonts/InterDisplay-ExtraLight.woff2") format("woff2"); + src: url("/fonts/InterDisplay-ExtraLight.woff2") format("woff2"); } @font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 200; font-display: swap; - src: url("../../assets/fonts/InterDisplay-ExtraLightItalic.woff2") format("woff2"); + src: url("/fonts/InterDisplay-ExtraLightItalic.woff2") format("woff2"); } @font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 300; font-display: swap; - src: url("../../assets/fonts/InterDisplay-Light.woff2") format("woff2"); + src: url("/fonts/InterDisplay-Light.woff2") format("woff2"); } @font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 300; font-display: swap; - src: url("../../assets/fonts/InterDisplay-LightItalic.woff2") format("woff2"); + src: url("/fonts/InterDisplay-LightItalic.woff2") format("woff2"); } @font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 400; font-display: swap; - src: url("../../assets/fonts/InterDisplay-Regular.woff2") format("woff2"); + src: url("/fonts/InterDisplay-Regular.woff2") format("woff2"); } @font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 400; font-display: swap; - src: url("../../assets/fonts/InterDisplay-Italic.woff2") format("woff2"); + src: url("/fonts/InterDisplay-Italic.woff2") format("woff2"); } @font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 500; font-display: swap; - src: url("../../assets/fonts/InterDisplay-Medium.woff2") format("woff2"); + src: url("/fonts/InterDisplay-Medium.woff2") format("woff2"); } @font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 500; font-display: swap; - src: url("../../assets/fonts/InterDisplay-MediumItalic.woff2") format("woff2"); + src: url("/fonts/InterDisplay-MediumItalic.woff2") format("woff2"); } @font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 600; font-display: swap; - src: url("../../assets/fonts/InterDisplay-SemiBold.woff2") format("woff2"); + src: url("/fonts/InterDisplay-SemiBold.woff2") format("woff2"); } @font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 600; font-display: swap; - src: url("../../assets/fonts/InterDisplay-SemiBoldItalic.woff2") format("woff2"); + src: url("/fonts/InterDisplay-SemiBoldItalic.woff2") format("woff2"); } @font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 700; font-display: swap; - src: url("../../assets/fonts/InterDisplay-Bold.woff2") format("woff2"); + src: url("/fonts/InterDisplay-Bold.woff2") format("woff2"); } @font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 700; font-display: swap; - src: url("../../assets/fonts/InterDisplay-BoldItalic.woff2") format("woff2"); + src: url("/fonts/InterDisplay-BoldItalic.woff2") format("woff2"); } @font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 800; font-display: swap; - src: url("../../assets/fonts/InterDisplay-ExtraBold.woff2") format("woff2"); + src: url("/fonts/InterDisplay-ExtraBold.woff2") format("woff2"); } @font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 800; font-display: swap; - src: url("../../assets/fonts/InterDisplay-ExtraBoldItalic.woff2") format("woff2"); + src: url("/fonts/InterDisplay-ExtraBoldItalic.woff2") format("woff2"); } @font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 900; font-display: swap; - src: url("../../assets/fonts/InterDisplay-Black.woff2") format("woff2"); + src: url("/fonts/InterDisplay-Black.woff2") format("woff2"); } @font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 900; font-display: swap; - src: url("../../assets/fonts/InterDisplay-BlackItalic.woff2") format("woff2"); + src: url("/fonts/InterDisplay-BlackItalic.woff2") format("woff2"); } @font-feature-values InterVariable { diff --git a/utils/css.ts b/utils/css.ts index 22f519e9..97346071 100644 --- a/utils/css.ts +++ b/utils/css.ts @@ -64,22 +64,18 @@ export function createStyleSheetByCssText(cssText: string) { } export function replaceFontFaceUrl(sheet: CSSStyleSheet, converter: (url: string) => string) { + let cssText = '' for (const rule of sheet.cssRules) { if (rule instanceof CSSFontFaceRule) { - const src = rule.style.getPropertyValue('src') - if (src) { - const newSrc = src.split(',').map((url) => { - const match = url.match(/url\(['"]?([^'"]+)['"]?\)/) - if (match && match[1]) { - return `url('${converter(match[1])}')` - } - return url - }).join(', ') - rule.style.setProperty('src', newSrc) - } + cssText += rule.cssText.replace(/url\(['"]?([^'")]+)['"]?\)/g, (_match, url) => { + return `url('${converter(url)}')` + }) + '\n' + } + else { + cssText += rule.cssText + '\n' } } - return sheet + return createStyleSheetByCssText(cssText) } export function extractFontFace(sheet: CSSStyleSheet) { diff --git a/utils/language/detect.test.ts b/utils/language/detect.test.ts index 756d6eb3..3cc1badb 100644 --- a/utils/language/detect.test.ts +++ b/utils/language/detect.test.ts @@ -1,78 +1,40 @@ -import { beforeEach, describe, expect, it } from 'vitest' +// @ts-expect-error -- guesslanguage has no types +import { guessLanguage } from 'guesslanguage' +import { afterAll, beforeEach, describe, expect, it, vi } from 'vitest' import { fakeBrowser } from 'wxt/testing' -import { detectLanguage } from './detect' +import type { LanguageCode } from './detect' +import { detectLanguage, getLanguageName, SUPPORTED_LANGUAGE_CODES } from './detect' -const englishSentences = [ - 'Hello, how are you?', - 'This is a test sentence.', - 'The quick brown fox jumps over the lazy dog.', - 'I love programming in JavaScript.', - 'What is your favorite color?', - 'The weather is nice today.', - 'I enjoy reading books in my free time.', - 'Can you help me with this problem?', - 'I am learning new things every day.', -] - -const chineseSentences = [ - '你好,今天怎么样?', - '我喜欢编程和学习新知识。', - '今天天气很好,我们去散步吧。', - '你最喜欢的食物是什么?', - '我正在学习中文,希望能流利地说。', - '这本书非常有趣,我很喜欢。', - '你能帮我解决这个问题吗?', - '你对未来有什么计划?', -] - -const japaneseSentences = [ - 'こんにちは、今日はどうですか?', - '私はプログラミングと新しい知識を学ぶのが好きです。', - '今日は天気が良いので、散歩に行きましょう。', - 'あなたの好きな食べ物は何ですか?', - '私は日本語を勉強しています。流暢に話せるようになりたいです。', - 'この本はとても面白いです。私はそれが大好きです。', - 'この問題を解決するのを手伝ってくれますか?', - 'あなたの将来の計画は何ですか?', -] - -const koreanSentences = [ - '안녕하세요, 오늘은 어때요?', - '저는 프로그래밍과 새로운 지식을 배우는 것을 좋아합니다.', - '오늘 날씨가 좋아서 산책하러 가요.', - '가장 좋아하는 음식은 무엇인가요?', - '저는 한국어를 배우고 있습니다. 유창하게 말할 수 있게 되고 싶어요.', - '이 책은 정말 재미있어요. 저는 그것을 좋아해요.', - '이 문제를 해결하는 데 도와줄 수 있나요?', - '당신의 미래 계획은 무엇인가요?', -] +const guessDetectSpy = vi.spyOn(guessLanguage, 'detect') describe('language detector', () => { beforeEach(() => { // See https://webext-core.aklinker1.io/fake-browser/reseting-state fakeBrowser.reset() + guessDetectSpy.mockReset() + guessDetectSpy.mockImplementation((_text: string, cb: (lang: string) => void) => cb('en')) + }) + + it.each(SUPPORTED_LANGUAGE_CODES)('returns the detected code when supported (%s)', async (code) => { + guessDetectSpy.mockImplementation((_text: string, cb: (lang: string) => void) => cb(code)) + + await expect(detectLanguage('sample text')).resolves.toBe(code) }) - it('should detect the language of input string', async () => { - for (const sentence of englishSentences) { - const lang = await detectLanguage(sentence) - expect(lang).toBe('en') - } + it('falls back to en when the detected code is not supported', async () => { + guessDetectSpy.mockImplementation((_text: string, cb: (lang: string) => void) => cb('xx')) - for (const sentence of chineseSentences) { - const lang = await detectLanguage(sentence) - expect(lang).toBe('zh') - } + await expect(detectLanguage('unknown language')).resolves.toBe('en') + }) - for (const sentence of japaneseSentences) { - const lang = await detectLanguage(sentence) - expect(lang).toBe('ja') - } + it('returns the language display name or defaults to English', () => { + expect(getLanguageName('zh')).toBe('简体中文') + expect(getLanguageName('en')).toBe('English') + expect(getLanguageName('xx' as LanguageCode)).toBe('English') + }) - for (const sentence of koreanSentences) { - const lang = await detectLanguage(sentence) - expect(lang).toBe('ko') - } + afterAll(() => { + guessDetectSpy.mockRestore() }) }) diff --git a/utils/language/detect.ts b/utils/language/detect.ts index cdc1fba1..c1648d33 100644 --- a/utils/language/detect.ts +++ b/utils/language/detect.ts @@ -10,6 +10,30 @@ export const SUPPORTED_LANGUAGES = [ name: 'Español', code: 'es', }, + { + name: 'Français', + code: 'fr', + }, + { + name: 'Deutsch', + code: 'de', + }, + { + name: 'Português', + code: 'pt', + }, + { + name: 'Italiano', + code: 'it', + }, + { + name: 'Русский', + code: 'ru', + }, + { + name: 'Nederlands', + code: 'nl', + }, { name: '日本語', code: 'ja', @@ -22,6 +46,22 @@ export const SUPPORTED_LANGUAGES = [ code: 'zh', name: '简体中文', }, + { + code: 'zh-TW', + name: '繁體中文', + }, + { + code: 'tr', + name: 'Türkçe', + }, + { + code: 'vi', + name: 'TiếngViệt', + }, + { + code: 'th', + name: 'ภาษาไทย', + }, ] as const export const SUPPORTED_LANGUAGE_CODES = SUPPORTED_LANGUAGES.map((lang) => lang.code) diff --git a/wxt.config.ts b/wxt.config.ts index 9339ae00..55776739 100644 --- a/wxt.config.ts +++ b/wxt.config.ts @@ -62,7 +62,7 @@ export default defineConfig({ artifactTemplate: '{{name}}-{{packageVersion}}-{{browser}}-{{mode}}.zip', }, exposeWebResources: { - paths: ['/assets/*.woff2', '/content-scripts/*.css', '/main-world-injected.js'], + paths: ['/assets/*.woff2', '/fonts/*.woff2', '/content-scripts/*.css', '/main-world-injected.js'], }, vite: (_env) => { return {