From 9a05935cafe70b332e35b8b601c85d8eec4aaf37 Mon Sep 17 00:00:00 2001 From: JustADeer <109961289+JustADeer@users.noreply.github.com> Date: Wed, 13 May 2026 21:39:57 +0700 Subject: [PATCH] feat(reader): improve Japanese selection UX by disabling furigana selection (#4137) * feat: add default ruby rt styles with user-select: none * fix: prevent furigana text from being copied via ruby transformer * fix: register ruby transformer in FoliateViewer pipeline; use span wrapper for reliable ::before rendering * refactor(reader): simplify furigana copy exclusion Drop the ruby transformer and the .rt-text::before pseudo-element wrapping. Instead, pass ['rt'] to getTextFromRange unconditionally so furigana is excluded from annotator/translation/copy text extraction, and let `rt { user-select: none }` handle the native selection cursor. Avoids DOM rewriting and HTML-entity round-tripping in the data-text attribute, and keeps text in the DOM for TTS, in-page find, and screen readers. Co-Authored-By: Claude Opus 4.7 (1M context) --------- Co-authored-by: Huang Xin Co-authored-by: Claude Opus 4.7 (1M context) --- .../app/reader/components/annotator/Annotator.tsx | 2 +- apps/readest-app/src/utils/style.ts | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/apps/readest-app/src/app/reader/components/annotator/Annotator.tsx b/apps/readest-app/src/app/reader/components/annotator/Annotator.tsx index 2c3b4604..b1d2fed3 100644 --- a/apps/readest-app/src/app/reader/components/annotator/Annotator.tsx +++ b/apps/readest-app/src/app/reader/components/annotator/Annotator.tsx @@ -207,7 +207,7 @@ const Annotator: React.FC<{ bookKey: string }> = ({ bookKey }) => { const getAnnotationText = useCallback( async (range: Range) => { - transformCtx['content'] = getTextFromRange(range, primaryLang.startsWith('ja') ? ['rt'] : []); + transformCtx['content'] = getTextFromRange(range, ['rt']); return await transformContent(transformCtx); }, [primaryLang, transformCtx], diff --git a/apps/readest-app/src/utils/style.ts b/apps/readest-app/src/utils/style.ts index d300d541..15bb6ff3 100644 --- a/apps/readest-app/src/utils/style.ts +++ b/apps/readest-app/src/utils/style.ts @@ -618,6 +618,16 @@ const getWarichuStyles = () => ` } `; +const getRubyStyles = () => ` + rt { + user-select: none; + -webkit-user-select: none; + } + rp { + display: none !important; + } +`; + export interface ThemeCode { bg: string; fg: string; @@ -714,8 +724,9 @@ export const getStyles = (viewSettings: ViewSettings, themeCode?: ThemeCode) => ); const translationStyles = getTranslationStyles(viewSettings.showTranslateSource!); const warichuStyles = getWarichuStyles(); + const rubyStyles = getRubyStyles(); const userStylesheet = viewSettings.userStylesheet!; - return `${pageLayoutStyles}\n${paragraphLayoutStyles}\n${fontStyles}\n${colorStyles}\n${translationStyles}\n${warichuStyles}\n${userStylesheet}`; + return `${pageLayoutStyles}\n${paragraphLayoutStyles}\n${fontStyles}\n${colorStyles}\n${translationStyles}\n${warichuStyles}\n${rubyStyles}\n${userStylesheet}`; }; export const applyTranslationStyle = (viewSettings: ViewSettings) => {