refactor: scope reader module

This commit is contained in:
mARTin-B78 2026-09-04 12:40:09 +02:00
parent cc59a3504a
commit 0ee43421b7
6 changed files with 72 additions and 12 deletions

View File

@ -8,6 +8,8 @@ Follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) · versioned wi
## [Unreleased] ## [Unreleased]
### Changed ### Changed
- **Reader namespace migration.** PDF/TXT document state, playback, search, synthesis, and library APIs now use a
private implementation scope with explicit compatibility exports and a tested `window.TTVC.reader` surface.
- **Audiobook parser compatibility boundary.** Speech-heuristic constants consumed by the scoped Audiobook core are now - **Audiobook parser compatibility boundary.** Speech-heuristic constants consumed by the scoped Audiobook core are now
exported explicitly, preventing load-order regressions while preserving the parser namespace. exported explicitly, preventing load-order regressions while preserving the parser namespace.
- **Audiobook core namespace migration.** Reader-side audiobook state, attribution helpers, quote controls, and Rehearser - **Audiobook core namespace migration.** Reader-side audiobook state, attribution helpers, quote controls, and Rehearser

View File

@ -124,9 +124,9 @@ architecture change: the larger Audiobook/Rehearser/style split.
voice design, I/O, library, stage, and recording blocks plus Audiobook casting, preview, export, and feature styles voice design, I/O, library, stage, and recording blocks plus Audiobook casting, preview, export, and feature styles
are isolated. Core Reader state and compatibility event wiring remain ordered in the legacy entry points. are isolated. Core Reader state and compatibility event wiring remain ordered in the legacy entry points.
- [x] Extract Rehearser stage display and cast-sidebar controls into `rehearser-stage.js`. - [x] Extract Rehearser stage display and cast-sidebar controls into `rehearser-stage.js`.
- [ ] Replace broad globals with namespaces such as `window.TTVC.audiobook`; pure leaves, Audiobook state modules, and - [ ] Replace broad globals with namespaces such as `window.TTVC.audiobook`; pure leaves, Audiobook state/core modules,
Rehearser playback now use private scopes with explicit compatibility exports. Remaining Rehearser state modules still Reader, and Rehearser state modules now use private scopes with explicit compatibility exports. Remaining utility and
require the same responsibility-by-responsibility migration. library modules still require the same responsibility-by-responsibility migration.
- [x] Generate the feature-module list for `loader.js` and `scripts/minify.mjs` from one shared manifest; - [x] Generate the feature-module list for `loader.js` and `scripts/minify.mjs` from one shared manifest;
larger responsibility splits remain. larger responsibility splits remain.
- [x] Add a dependency-free frontend syntax and top-level declaration collision gate (`npm run check:frontend`); - [x] Add a dependency-free frontend syntax and top-level declaration collision gate (`npm run check:frontend`);

View File

@ -1 +1 @@
1.24.64 1.24.65

View File

@ -54,6 +54,7 @@ Done incrementally as global-scope ordered files (no ES-module change needed)
- ✅ Rehearser recording uses a private scope with explicit microphone/overlay compatibility exports. - ✅ Rehearser recording uses a private scope with explicit microphone/overlay compatibility exports.
- ✅ Rehearser core uses a private scope with explicit state, pagination, and cast-management compatibility exports. - ✅ Rehearser core uses a private scope with explicit state, pagination, and cast-management compatibility exports.
- ✅ Audiobook core uses a private scope with explicit reader-side state and handoff compatibility exports. - ✅ Audiobook core uses a private scope with explicit reader-side state and handoff compatibility exports.
- ✅ Reader uses a private scope with explicit document, playback, and search compatibility exports.
- ✅ `static/css/resource-diagnostics.css` — isolated Performance/resource diagnostic panel styles. - ✅ `static/css/resource-diagnostics.css` — isolated Performance/resource diagnostic panel styles.
- ✅ `static/css/background-jobs.css` — isolated background-job history and retry-panel styles. - ✅ `static/css/background-jobs.css` — isolated background-job history and retry-panel styles.
- ✅ `static/css/voice-design.css` — isolated Voice Design form, samples, and preview-match styles. - ✅ `static/css/voice-design.css` — isolated Voice Design form, samples, and preview-match styles.

View File

@ -10,7 +10,7 @@
<meta name="format-detection" content="telephone=no"> <meta name="format-detection" content="telephone=no">
<meta name="color-scheme" content="light dark"> <meta name="color-scheme" content="light dark">
<meta name="theme-color" content="#2563EB"> <meta name="theme-color" content="#2563EB">
<meta name="app-version" content="1.24.64"> <meta name="app-version" content="1.24.65">
<link rel="manifest" href="/manifest.webmanifest"> <link rel="manifest" href="/manifest.webmanifest">
<link rel="icon" href="/static/icon.svg" type="image/svg+xml"> <link rel="icon" href="/static/icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/static/icon.svg"> <link rel="apple-touch-icon" href="/static/icon.svg">
@ -27,12 +27,12 @@
<!-- ── Core styles (local — no CDN dependency for first paint) ────────── --> <!-- ── Core styles (local — no CDN dependency for first paint) ────────── -->
<link rel="stylesheet" href="/static/vendor/mdi/materialdesignicons.min.css"> <link rel="stylesheet" href="/static/vendor/mdi/materialdesignicons.min.css">
<link rel="stylesheet" href="/static/style.css?v=1.24.64"> <link rel="stylesheet" href="/static/style.css?v=1.24.65">
<link rel="stylesheet" href="/static/css/resource-diagnostics.css?v=1.24.64"> <link rel="stylesheet" href="/static/css/resource-diagnostics.css?v=1.24.65">
<link rel="stylesheet" href="/static/css/background-jobs.css?v=1.24.64"> <link rel="stylesheet" href="/static/css/background-jobs.css?v=1.24.65">
<link rel="stylesheet" href="/static/css/voice-design.css?v=1.24.64"> <link rel="stylesheet" href="/static/css/voice-design.css?v=1.24.65">
<link rel="stylesheet" href="/static/css/rehearser.css?v=1.24.64"> <link rel="stylesheet" href="/static/css/rehearser.css?v=1.24.65">
<link rel="stylesheet" href="/static/css/audiobook.css?v=1.24.64"> <link rel="stylesheet" href="/static/css/audiobook.css?v=1.24.65">
<!-- ── Flag icons — non-blocking (loaded async, icons appear after JS) ── --> <!-- ── Flag icons — non-blocking (loaded async, icons appear after JS) ── -->
@ -397,7 +397,7 @@ window.toggleNavTree = function(treeId, chevronId) {
</script> </script>
<!-- loader.js: fetches sections → loads JS modules → removes skeleton --> <!-- loader.js: fetches sections → loads JS modules → removes skeleton -->
<script src="/static/loader.js?v=1.24.64"></script> <script src="/static/loader.js?v=1.24.65"></script>
</body> </body>
</html> </html>

View File

@ -1,4 +1,6 @@
// ── Read Aloud — PDF/TXT document reader with live word highlighting ──────── // ── Read Aloud — PDF/TXT document reader with live word highlighting ────────
(function (root) {
// //
// Imports a PDF (rendered to canvas via pdf.js with a highlight overlay on the // Imports a PDF (rendered to canvas via pdf.js with a highlight overlay on the
// real text) or a plain-text file, then reads it sentence-by-sentence with a // real text) or a plain-text file, then reads it sentence-by-sentence with a
@ -2226,3 +2228,58 @@ function _readerEnsureImportVisible() {
card.classList.remove('card-col-closed'); card.classList.remove('card-col-closed');
} }
} }
// Preserve the existing classic-script integration surface while keeping Reader
// state and implementation details inside one explicit module scope.
Object.assign(root, {
readerState, READER_RESUME_KEY, READER_FMT, READER_BUF_WINDOW, READER_CANVAS_MARGIN,
READER_IMPORT_YIELD_EVERY, READER_PDF_INITIAL_PAGES, READER_PDF_INITIAL_MAX_WITHOUT_TEXT,
READER_OCR_LANGS, READER_OCR_MIN_GAP_RATIO, READER_OCR_MIN_GAP_PX, READER_OCR_RENDER_SCALE,
READER_OCR_MIN_CONFIDENCE, readerCtx, readerYield, readerFetchVoices, readerUpdateBackendHint,
readerTitleFromText, readerUpdateToolbarVisibility, readerFinishLoadedDocument, readerImportFile,
readerImportPastedText, readerResetDoc, READER_NO_LEADING_SPACE_RE, readerBuildSentences,
readerGroupUnits, readerMarkParagraphBreaks, loadTesseract, readerGetOcrWorker, _readerTimeout,
_readerOcrAttempt, readerOcrPageHeading, readerLoadPdfSkeleton, readerExtractPdfText,
readerLoadPdf, readerShowParseProgress, readerComputeScale, readerApplyZoom, readerSetupLazyRaster,
readerRenderVisible, readerIsPageNearView, readerEvictCanvases, READER_MAX_CANVAS_PIXELS,
READER_MAX_CANVAS_SIDE, readerRenderPage, readerLoadText, readerSentBBox, readerBuildUnitIndex,
readerCreatePageStatus, readerEffectiveStatus, readerSetStatus, readerPaintStatus, _readerWordBox,
readerEnsureBox, readerClearHighlights, readerEnsureVisible, readerHighlightSentence,
readerHighlightWord, readerSetSelecting, readerSelHint, readerPickSentence, readerClearSelection,
readerSelRange, readerPaintSelection, readerScopeIndices, readerUpdateScopeLabel,
_readerTextForSynth, readerSynthIndices, readerSynthAll, readerSafeName, readerPad, readerPageOf,
readerDownload, _readerDelay, readerExport, readerRechunk, readerGenParams, readerComputeGain,
readerFetchServerAudio, readerGetBuffer, readerEvictBuffers, readerPrefetch, readerClearReading,
readerPlayCurrent, readerStopSource, readerStopPlayback, readerPlay, readerPause, readerJumpTo,
readerUpdatePlayBtn, readerUpdateProgress, readerSaveResume, readerLoadResume, READER_API,
readerSyntheticCount, readerSaveLibrary, readerPersistProgress, readerDeleteLibraryDoc,
readerOpenLibraryDoc, readerSetSelectValue, readerRenderLibrary, _readerSearchTerm,
_readerSearchHits, _readerSearchCurrent, _readerSearchTimer, READER_SEARCH_MAX_HITS,
readerSearchTextMap, readerFindSearchGroups, readerRemoveSearchHighlights, readerSetSearchStatus,
readerClearSearch, readerCollectSearchHits, readerPaintSearchHighlights, readerUpdateSearchStatus,
readerJumpToSearchHit, readerSearchApply, readerSearchStep, _readerEnsureImportVisible,
});
root.TTVC = root.TTVC || {};
root.TTVC.reader = root.TTVC.reader || {};
Object.assign(root.TTVC.reader, {
state: readerState,
document: {
loadText: readerLoadText,
loadPdf: readerLoadPdf,
reset: readerResetDoc,
saveLibrary: readerSaveLibrary,
openLibrary: readerOpenLibraryDoc,
},
playback: {
play: readerPlay,
pause: readerPause,
stop: readerStopPlayback,
jumpTo: readerJumpTo,
},
search: {
apply: readerSearchApply,
clear: readerClearSearch,
step: readerSearchStep,
},
});
})(window);