From 5d1a9113f94b0115393fdd9ed87cd2f1bd807c2e Mon Sep 17 00:00:00 2001 From: Neko Liu Date: Mon, 1 Dec 2025 12:49:57 +0800 Subject: [PATCH 1/6] fix: add more language entries to SUPPORTED_LANGUAGES for translation --- utils/language/detect.test.ts | 88 ++++++++++------------------------- utils/language/detect.ts | 40 ++++++++++++++++ 2 files changed, 65 insertions(+), 63 deletions(-) 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) From 83309cff8dd538b99fd50934b044cb88ccec844e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 1 Dec 2025 04:57:22 +0000 Subject: [PATCH 2/6] chore(release): v1.12.1-beta.0 --- CHANGELOG.md | 12 ++++++++++++ package.json | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97be4ff0..3c40b153 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 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/package.json b/package.json index d389c8b3..82815d6b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativemind-extension", - "version": "1.12.0", + "version": "1.12.1-beta.0", "private": false, "author": "NativeMind", "keywords": [ From 8c2b439a44559710fba04f3cdb5f2f294403f15e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 2 Dec 2025 08:43:44 +0000 Subject: [PATCH 3/6] chore(release): v1.12.1 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c40b153..343813b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 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) diff --git a/package.json b/package.json index 82815d6b..a9b36512 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativemind-extension", - "version": "1.12.1-beta.0", + "version": "1.12.1", "private": false, "author": "NativeMind", "keywords": [ From 5cec648519cacacd30f02643460b22d001f8dda8 Mon Sep 17 00:00:00 2001 From: Tony Hu Date: Sat, 14 Feb 2026 14:47:01 +0800 Subject: [PATCH 4/6] feat: 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 --- entrypoints/content/ui.ts | 33 +++++++- {assets => public}/fonts/Inter-Black.woff2 | Bin .../fonts/Inter-BlackItalic.woff2 | Bin {assets => public}/fonts/Inter-Bold.woff2 | Bin .../fonts/Inter-BoldItalic.woff2 | Bin .../fonts/Inter-ExtraBold.woff2 | Bin .../fonts/Inter-ExtraBoldItalic.woff2 | Bin .../fonts/Inter-ExtraLight.woff2 | Bin .../fonts/Inter-ExtraLightItalic.woff2 | Bin {assets => public}/fonts/Inter-Italic.woff2 | Bin {assets => public}/fonts/Inter-Light.woff2 | Bin .../fonts/Inter-LightItalic.woff2 | Bin {assets => public}/fonts/Inter-Medium.woff2 | Bin .../fonts/Inter-MediumItalic.woff2 | Bin {assets => public}/fonts/Inter-Regular.woff2 | Bin {assets => public}/fonts/Inter-SemiBold.woff2 | Bin .../fonts/Inter-SemiBoldItalic.woff2 | Bin {assets => public}/fonts/Inter-Thin.woff2 | Bin .../fonts/Inter-ThinItalic.woff2 | Bin .../fonts/InterDisplay-Black.woff2 | Bin .../fonts/InterDisplay-BlackItalic.woff2 | Bin .../fonts/InterDisplay-Bold.woff2 | Bin .../fonts/InterDisplay-BoldItalic.woff2 | Bin .../fonts/InterDisplay-ExtraBold.woff2 | Bin .../fonts/InterDisplay-ExtraBoldItalic.woff2 | Bin .../fonts/InterDisplay-ExtraLight.woff2 | Bin .../fonts/InterDisplay-ExtraLightItalic.woff2 | Bin .../fonts/InterDisplay-Italic.woff2 | Bin .../fonts/InterDisplay-Light.woff2 | Bin .../fonts/InterDisplay-LightItalic.woff2 | Bin .../fonts/InterDisplay-Medium.woff2 | Bin .../fonts/InterDisplay-MediumItalic.woff2 | Bin .../fonts/InterDisplay-Regular.woff2 | Bin .../fonts/InterDisplay-SemiBold.woff2 | Bin .../fonts/InterDisplay-SemiBoldItalic.woff2 | Bin .../fonts/InterDisplay-Thin.woff2 | Bin .../fonts/InterDisplay-ThinItalic.woff2 | Bin .../fonts/InterVariable-Italic.woff2 | Bin {assets => public}/fonts/InterVariable.woff2 | Bin styles/font-faces.css | 76 +++++++++--------- utils/css.ts | 10 +-- wxt.config.ts | 2 +- 42 files changed, 72 insertions(+), 49 deletions(-) rename {assets => public}/fonts/Inter-Black.woff2 (100%) rename {assets => public}/fonts/Inter-BlackItalic.woff2 (100%) rename {assets => public}/fonts/Inter-Bold.woff2 (100%) rename {assets => public}/fonts/Inter-BoldItalic.woff2 (100%) rename {assets => public}/fonts/Inter-ExtraBold.woff2 (100%) rename {assets => public}/fonts/Inter-ExtraBoldItalic.woff2 (100%) rename {assets => public}/fonts/Inter-ExtraLight.woff2 (100%) rename {assets => public}/fonts/Inter-ExtraLightItalic.woff2 (100%) rename {assets => public}/fonts/Inter-Italic.woff2 (100%) rename {assets => public}/fonts/Inter-Light.woff2 (100%) rename {assets => public}/fonts/Inter-LightItalic.woff2 (100%) rename {assets => public}/fonts/Inter-Medium.woff2 (100%) rename {assets => public}/fonts/Inter-MediumItalic.woff2 (100%) rename {assets => public}/fonts/Inter-Regular.woff2 (100%) rename {assets => public}/fonts/Inter-SemiBold.woff2 (100%) rename {assets => public}/fonts/Inter-SemiBoldItalic.woff2 (100%) rename {assets => public}/fonts/Inter-Thin.woff2 (100%) rename {assets => public}/fonts/Inter-ThinItalic.woff2 (100%) rename {assets => public}/fonts/InterDisplay-Black.woff2 (100%) rename {assets => public}/fonts/InterDisplay-BlackItalic.woff2 (100%) rename {assets => public}/fonts/InterDisplay-Bold.woff2 (100%) rename {assets => public}/fonts/InterDisplay-BoldItalic.woff2 (100%) rename {assets => public}/fonts/InterDisplay-ExtraBold.woff2 (100%) rename {assets => public}/fonts/InterDisplay-ExtraBoldItalic.woff2 (100%) rename {assets => public}/fonts/InterDisplay-ExtraLight.woff2 (100%) rename {assets => public}/fonts/InterDisplay-ExtraLightItalic.woff2 (100%) rename {assets => public}/fonts/InterDisplay-Italic.woff2 (100%) rename {assets => public}/fonts/InterDisplay-Light.woff2 (100%) rename {assets => public}/fonts/InterDisplay-LightItalic.woff2 (100%) rename {assets => public}/fonts/InterDisplay-Medium.woff2 (100%) rename {assets => public}/fonts/InterDisplay-MediumItalic.woff2 (100%) rename {assets => public}/fonts/InterDisplay-Regular.woff2 (100%) rename {assets => public}/fonts/InterDisplay-SemiBold.woff2 (100%) rename {assets => public}/fonts/InterDisplay-SemiBoldItalic.woff2 (100%) rename {assets => public}/fonts/InterDisplay-Thin.woff2 (100%) rename {assets => public}/fonts/InterDisplay-ThinItalic.woff2 (100%) rename {assets => public}/fonts/InterVariable-Italic.woff2 (100%) rename {assets => public}/fonts/InterVariable.woff2 (100%) diff --git a/entrypoints/content/ui.ts b/entrypoints/content/ui.ts index cd3aeacd..499686d2 100644 --- a/entrypoints/content/ui.ts +++ b/entrypoints/content/ui.ts @@ -1,24 +1,51 @@ 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) + // Content script stylesheets are parsed via new CSSStyleSheet() + replaceSync(), + // so @font-face URLs (e.g. /fonts/Inter.woff2) resolve against the page URL + // instead of the extension URL. Convert to absolute extension URLs. + replaceFontFaceUrl(fontFaceStyleSheet, (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/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..ffc63189 100644 --- a/utils/css.ts +++ b/utils/css.ts @@ -68,13 +68,9 @@ export function replaceFontFaceUrl(sheet: CSSStyleSheet, converter: (url: string 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(', ') + const newSrc = src.replace(/url\(['"]?([^'")]+)['"]?\)/g, (_match, url) => { + return `url('${converter(url)}')` + }) rule.style.setProperty('src', newSrc) } } 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 { From d9ab298833d445754c6230b62d6284d70ccc9bbf Mon Sep 17 00:00:00 2001 From: Tony Hu Date: Sat, 14 Feb 2026 14:59:35 +0800 Subject: [PATCH 5/6] refactor: streamline font face URL handling in stylesheets by consolidating extraction and replacement logic --- entrypoints/content/ui.ts | 6 +----- utils/css.ts | 16 ++++++++-------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/entrypoints/content/ui.ts b/entrypoints/content/ui.ts index 499686d2..64674cee 100644 --- a/entrypoints/content/ui.ts +++ b/entrypoints/content/ui.ts @@ -22,11 +22,7 @@ async function loadStyleSheet(shadowRoot: ShadowRoot) { ) injectStyleSheetToDocument(shadowRoot, styleSheet) // font-face can only be applied to the document, not the shadow root - const fontFaceStyleSheet = extractFontFace(styleSheet) - // Content script stylesheets are parsed via new CSSStyleSheet() + replaceSync(), - // so @font-face URLs (e.g. /fonts/Inter.woff2) resolve against the page URL - // instead of the extension URL. Convert to absolute extension URLs. - replaceFontFaceUrl(fontFaceStyleSheet, (url) => { + const fontFaceStyleSheet = replaceFontFaceUrl(extractFontFace(styleSheet), (url) => { if ( url.startsWith('data:') || url.startsWith('moz-extension://') diff --git a/utils/css.ts b/utils/css.ts index ffc63189..97346071 100644 --- a/utils/css.ts +++ b/utils/css.ts @@ -64,18 +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.replace(/url\(['"]?([^'")]+)['"]?\)/g, (_match, url) => { - return `url('${converter(url)}')` - }) - 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) { From 26eb6120b3f51fc0a6f78ba6609f2b9351181c67 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 14 Feb 2026 07:03:53 +0000 Subject: [PATCH 6/6] chore(release): v1.12.2 --- CHANGELOG.md | 16 ++++++++++++++++ package.json | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 343813b6..ca83963c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # 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) diff --git a/package.json b/package.json index a9b36512..763d57f1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativemind-extension", - "version": "1.12.1", + "version": "1.12.2", "private": false, "author": "NativeMind", "keywords": [