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 <rt> text in the DOM for TTS, in-page find, and
screen readers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Huang Xin <chrox.huang@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
JustADeer
2026-05-13 21:39:57 +07:00
committed by GitHub
parent 11469d1e95
commit 9a05935caf
2 changed files with 13 additions and 2 deletions
@@ -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],
+12 -1
View File
@@ -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) => {