forked from akai/readest
feat(cjk): support inline annotation(warichu, Gezhu) layout (#3934)
* feat(warichu): support warichu (割注) inline annotation layout
- Add warichu HTML transformer that converts <span class="warichu"> and
<warichu> elements into .warichu-pending placeholders during content load
- Implement runtime layout (layoutWarichu / relayoutWarichu) that measures
column position and splits text into small inline-block chunks (2 chars
each) so CSS column boundaries can break between them, preventing large
blank gaps in vertical-rl pagination
- Use column stride (column-width + column-gap) for accurate position
measurement across column boundaries
- Hook into stabilized event for initial layout and relayout on resize
- Add warichu CSS styles (inline-block chunks, half-size font, vertical align)
* fix(warichu): correct HTML slicing edge cases
- sliceHtml: re-emit tags that were already open before the slice start
so the result stays well-formed. Previously a slice past an opening
tag produced an orphan closing tag (e.g. "<b>Hello</b>"[3,5] →
"lo</b>" instead of "<b>lo</b>").
- sliceHtml / removeFirstVisibleChar / removeLastVisibleChar: treat HTML
entities (e.g. &) as one visible character so they aren't split or
truncated mid-entity (e.g. removeFirstVisibleChar("&rest") →
"amp;rest").
- buildNodes: drop a duplicate chunk.appendChild(l2).
- Add unit tests covering the above for the three pure helpers.
---------
Co-authored-by: Huang Xin <chrox.huang@gmail.com>
This commit is contained in:
@@ -35,6 +35,7 @@ import {
|
||||
transformStylesheet,
|
||||
} from '@/utils/style';
|
||||
import { mountAdditionalFonts, mountCustomFont } from '@/styles/fonts';
|
||||
import { layoutWarichu, relayoutWarichu } from '@/utils/warichu';
|
||||
import { getBookDirFromLanguage, getBookDirFromWritingMode } from '@/utils/book';
|
||||
import { getIndexFromCfi } from '@/utils/cfi';
|
||||
import { useUICSS } from '@/hooks/useUICSS';
|
||||
@@ -175,6 +176,7 @@ const FoliateViewer: React.FC<{
|
||||
'sanitizer',
|
||||
'simplecc',
|
||||
'proofread',
|
||||
'warichu',
|
||||
],
|
||||
};
|
||||
return Promise.resolve(transformContent(ctx));
|
||||
@@ -329,6 +331,19 @@ const FoliateViewer: React.FC<{
|
||||
|
||||
const stabilizedHandler = useCallback(() => {
|
||||
setLoading(false);
|
||||
// Layout/relayout warichu after paginator has set column-width via columnize()
|
||||
const contents = viewRef.current?.renderer?.getContents?.() || [];
|
||||
for (const { doc } of contents) {
|
||||
if (doc) {
|
||||
const hasPending = doc.querySelectorAll('.warichu-pending').length > 0;
|
||||
const hasExisting = doc.querySelectorAll('.warichu-head').length > 0;
|
||||
if (hasPending) {
|
||||
layoutWarichu(doc);
|
||||
} else if (hasExisting) {
|
||||
relayoutWarichu(doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
const docRelocateHandler = (event: Event) => {
|
||||
|
||||
Reference in New Issue
Block a user