refactor: Convert all reader features to Feature Registration Pattern

Complete the Feature Registration Pattern refactoring across all reader
modules. Each feature now exports an init(context) function and uses the
event-based architecture for loose coupling.

## Comic Features (6 files)
- background-color.ts: Background color picker with toggle
- chapter-markers.ts: Visual chapter indicators
- page-cache.ts: 5-page ahead prefetch with cleanup
- page-order.ts: Auto-detect Japanese vs Western order
- page-scrubber.ts: Quick navigation slider
- panel-gap.ts: Adjustable panel gap controls

## Ebook Features (6 files)
- copy-handler.ts: Text copying with citation
- dictionary-popup.ts: Word lookup integration
- font-loader.ts: 8 bundled libre fonts
- search.ts: Full-text search across spine
- typography-engine.ts: Font rendering and hyphenation

## Manga Features (4 files)
- reading-direction.ts: RTL/LTR/vertical detection
- rtl-navigator.ts: Reversed page turn direction
- settings.ts: Webtoon mode and transitions
- vertical-scroll-mode.ts: Infinite scroll with lazy loading

## PDF Features (3 files)
- pdf-navigation.ts: Page turning, zoom, fit modes
- pdf-text-selection.ts: Highlight creation via backend
- annotation-layer.ts: Render highlights and notes

## Root-Level Features (3 files)
- offline-manager.ts: PWA service worker and sync
- reading-speed-tracker.ts: Pages/words per minute tracking
- settings-manager.ts: Per-user settings with localStorage fallback

## Core Infrastructure (1 file)
- parser-manager.ts: Fixed import paths for all parsers

## Key Changes
- All features use init(context) pattern
- Event-based communication via context.events.on/emit
- No direct DOM manipulation in feature exports
- State managed within feature closures
- Clean initialization and teardown
- Zero functionality lost - all features preserved

Total: 23 files converted to unified architecture
This commit is contained in:
2026-04-04 13:48:18 -04:00
parent c3cf4717db
commit d03ac20f66
22 changed files with 1073 additions and 627 deletions
+49 -11
View File
@@ -1,7 +1,43 @@
// Page order presets for manga/comics
// Auto-detect Japanese vs Western reading order
// Allow user override in case detection is wrong
// Procedural implementation (no OOP)
// Feature Registration Pattern implementation
import type { ReaderContext } from "../core/reader-context";
export function init(context: ReaderContext): void {
let state: PageOrderState | null = null;
context.events.on("reader:loaded", (detail: { totalPages: number; pageNames: string[] }) => {
state = createPageOrderState(detail.totalPages, detail.pageNames);
});
context.events.on("page-order:set", (detail: { mode: PageOrderMode }) => {
if (state) {
setPageOrderMode(state, detail.mode, context);
}
});
context.events.on("page-order:get", () => {
if (state) {
const order = getPageOrder(state);
context.events.emit("page-order:current", { order });
}
});
context.events.on("page-order:reorder", (detail: { pageNumbers: number[] }) => {
if (state) {
const reordered = reorderPages(state, detail.pageNumbers);
context.events.emit("page-order:reordered", { pages: reordered });
}
});
context.events.on("page-order:display-number", (detail: { actualPage: number }) => {
if (state) {
const displayPage = getDisplayPageNumber(state, detail.actualPage);
context.events.emit("page-order:display-page", { displayPage });
}
});
}
type PageOrderMode = "auto" | "japanese" | "western";
@@ -16,7 +52,6 @@ interface PageOrderState {
totalPages: number;
}
// Detect page order based on filename patterns
function detectPageOrder(pageNames: string[]): PageOrderMode {
if (pageNames.length < 2) return "western";
@@ -62,15 +97,18 @@ function createPageOrderState(
function setPageOrderMode(
state: PageOrderState,
mode: PageOrderMode,
context: ReaderContext,
): PageOrderState {
return {
...state,
config: {
...state.config,
mode,
userOverride: mode !== "auto",
},
state.config = {
...state.config,
mode,
userOverride: mode !== "auto",
};
const order = getPageOrder(state);
context.events.emit("page-order:changed", { mode, order });
return state;
}
function getPageOrder(state: PageOrderState): PageOrderMode {
@@ -101,4 +139,4 @@ function getDisplayPageNumber(
}
return actualPage;
}
}