@caipira/vue-reader 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -24
- package/dist/src/composables/useEpubReader.d.ts +5 -27786
- package/dist/src/composables/useEpubReader.js +218 -4
- package/dist/src/composables/useEpubReaderLogging.d.ts +5 -0
- package/dist/src/composables/useEpubReaderLogging.js +27 -0
- package/dist/src/composables/useEpubReaderNavigation.d.ts +3 -3
- package/dist/src/composables/useEpubReaderNavigation.js +8 -15
- package/dist/src/composables/useEpubReaderState.d.ts +27794 -20
- package/dist/src/composables/useEpubReaderState.js +31 -21
- package/dist/{composables → src/composables}/useEpubReaderStrategy.d.ts +1 -1
- package/dist/src/composables/useEpubReaderWasm.d.ts +2 -0
- package/dist/{composables → src/composables}/useEpubReaderWasm.js +5 -5
- package/dist/src/composables/useEpubReaderZipFetcher.d.ts +2 -0
- package/dist/{composables → src/composables}/useEpubReaderZipFetcher.js +5 -5
- package/dist/src/composables/useReaderColors.d.ts +10 -0
- package/dist/src/composables/useReaderColors.js +38 -0
- package/dist/src/composables/useReaderSettings.d.ts +24 -13
- package/dist/src/composables/useReaderSettings.js +97 -38
- package/dist/src/index.d.ts +6 -9
- package/dist/src/index.js +5 -8
- package/dist/{services → src/services}/browser/epub.d.ts +1 -1
- package/dist/{services → src/services}/browser/manifest.d.ts +1 -1
- package/dist/{services → src/services}/browser/manifest.js +1 -1
- package/dist/{services → src/services}/browser/url-rewrite.d.ts +1 -1
- package/dist/{services → src/services}/browser/url-rewrite.js +1 -1
- package/dist/{services → src/services}/browser/zip-fetcher.d.ts +1 -1
- package/dist/{services → src/services}/browser/zip-fetcher.js +2 -2
- package/dist/{services → src/services}/common/progression.d.ts +3 -11
- package/dist/{services → src/services}/common/progression.js +1 -32
- package/dist/src/{core → services/common}/storage.d.ts +1 -1
- package/dist/src/{core → services/common}/storage.js +1 -2
- package/dist/{services → src/services}/common/title.d.ts +1 -1
- package/dist/{services → src/services}/common/word-decorations.d.ts +1 -1
- package/dist/{services → src/services}/common/word-decorations.js +2 -2
- package/dist/{services → src/services}/common/word-lookup.js +1 -1
- package/dist/{types → src/types}/common.d.ts +36 -1
- package/package.json +1 -1
- package/dist/composables/useEpubReaderWasm.d.ts +0 -2
- package/dist/composables/useEpubReaderZipFetcher.d.ts +0 -2
- package/dist/src/composables/useEpubReaderController.d.ts +0 -27787
- package/dist/src/composables/useEpubReaderController.js +0 -23
- package/dist/src/composables/useEpubReaderSettings.d.ts +0 -15
- package/dist/src/composables/useEpubReaderSettings.js +0 -8
- package/dist/src/composables/utils.d.ts +0 -2
- package/dist/src/composables/utils.js +0 -1
- package/dist/src/core/controller.d.ts +0 -27789
- package/dist/src/core/controller.js +0 -262
- package/dist/src/core/settings-store.d.ts +0 -16
- package/dist/src/core/settings-store.js +0 -58
- package/dist/src/settings/options.d.ts +0 -20
- package/dist/src/settings/options.js +0 -27
- package/dist/src/types.d.ts +0 -40
- package/dist/src/types.js +0 -1
- /package/dist/{composables → src/composables}/useEpubReaderStrategy.js +0 -0
- /package/dist/{services → src/services}/browser/epub.js +0 -0
- /package/dist/{services → src/services}/browser/url.d.ts +0 -0
- /package/dist/{services → src/services}/browser/url.js +0 -0
- /package/dist/src/{core → services/common}/fonts.d.ts +0 -0
- /package/dist/src/{core → services/common}/fonts.js +0 -0
- /package/dist/{services → src/services}/common/title.js +0 -0
- /package/dist/{services → src/services}/common/word-lookup.d.ts +0 -0
- /package/dist/{services → src/services}/wasm/frame-document-bridge.d.ts +0 -0
- /package/dist/{services → src/services}/wasm/frame-document-bridge.js +0 -0
- /package/dist/{services → src/services}/wasm/wasm-streamer.d.ts +0 -0
- /package/dist/{services → src/services}/wasm/wasm-streamer.js +0 -0
- /package/dist/{types → src/types}/browser.d.ts +0 -0
- /package/dist/{types → src/types}/browser.js +0 -0
- /package/dist/{types → src/types}/common.js +0 -0
|
@@ -1,8 +1,222 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Publication as RPublication } from '@readium/shared';
|
|
2
|
+
import { EpubDefaults, EpubNavigator, EpubPreferences } from '@readium/navigator';
|
|
3
|
+
import { toRaw, watch, toValue, nextTick, computed, onMounted, onBeforeUnmount, } from 'vue';
|
|
4
|
+
import { getCurrentTitle } from '../../src/services/common/title';
|
|
5
|
+
import { generatePositions } from '../../src/services/common/progression';
|
|
6
|
+
import { setWasmStreamerConfig } from '../../src/services/wasm/wasm-streamer';
|
|
7
|
+
import { createSessionStorageAdapter } from '../../src/services/common/storage';
|
|
8
|
+
import { injectCurrentFontIntoIframe } from '../../src/services/common/fonts';
|
|
9
|
+
import { createReadiumWordLookupController } from '../../src/services/common/word-lookup';
|
|
10
|
+
import { createReadiumWordDecorationsController } from '../../src/services/common/word-decorations';
|
|
11
|
+
import { useReaderSettings } from '../../src/composables/useReaderSettings';
|
|
12
|
+
import { useEpubReaderWasm } from '../../src/composables/useEpubReaderWasm';
|
|
13
|
+
import { useEpubReaderState } from '../../src/composables/useEpubReaderState';
|
|
14
|
+
import { hasReaderDictionary } from '../../src/composables/useReaderDictionary';
|
|
15
|
+
import { onReaderColorsChange } from '../../src/composables/useReaderColors';
|
|
16
|
+
import { useEpubReaderZipFetcher } from '../../src/composables/useEpubReaderZipFetcher';
|
|
17
|
+
const ENABLE_EDGE_TAP_PAGE_TURN = false;
|
|
2
18
|
export const useEpubReader = (src, containerRef, options) => {
|
|
3
|
-
const
|
|
19
|
+
const { error, loading, tocLinks, navigator, publication, totalPositions, currentPosition, currentChapterTitle, } = useEpubReaderState(containerRef);
|
|
20
|
+
const sourceRef = computed(() => toValue(src));
|
|
21
|
+
const storage = options?.storage ?? createSessionStorageAdapter();
|
|
22
|
+
const fontBaseUrl = options?.assets?.fontBaseUrl ?? '/fonts';
|
|
23
|
+
const { settings, onSettingsChange } = useReaderSettings(options?.preferences);
|
|
24
|
+
let stopSettingsWatcher = null;
|
|
25
|
+
let activeChapterHref = '';
|
|
26
|
+
let chapterProgressions = new Map();
|
|
27
|
+
let activeSource = null;
|
|
28
|
+
let strategyFrameLoaded = null;
|
|
29
|
+
let stopReaderColorsWatcher = onReaderColorsChange((colors) => {
|
|
30
|
+
settings.backgroundColor = colors.background;
|
|
31
|
+
settings.textColor = colors.text;
|
|
32
|
+
});
|
|
33
|
+
let getProgress = (_idx, rawProg) => ({
|
|
34
|
+
progress: rawProg ?? 0,
|
|
35
|
+
resourceProgression: rawProg ?? 0,
|
|
36
|
+
});
|
|
37
|
+
const wordDecorations = hasReaderDictionary()
|
|
38
|
+
? createReadiumWordDecorationsController(navigator, () => publication.value?.metadata?.languages?.[0])
|
|
39
|
+
: null;
|
|
40
|
+
const wordLookup = hasReaderDictionary()
|
|
41
|
+
? createReadiumWordLookupController(() => publication.value?.metadata?.languages?.[0])
|
|
42
|
+
: null;
|
|
43
|
+
const applyPreferences = async () => {
|
|
44
|
+
if (!navigator.value) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
await toRaw(navigator.value).submitPreferences(new EpubPreferences({
|
|
48
|
+
backgroundColor: settings.backgroundColor,
|
|
49
|
+
columnCount: settings.columnCount,
|
|
50
|
+
fontFamily: settings.fontFamily,
|
|
51
|
+
fontSize: settings.fontSize,
|
|
52
|
+
lineHeight: settings.lineHeight,
|
|
53
|
+
scroll: settings.scroll,
|
|
54
|
+
textAlign: settings.textAlign,
|
|
55
|
+
textColor: settings.textColor,
|
|
56
|
+
}));
|
|
57
|
+
await injectCurrentFontIntoIframe(containerRef.value, settings.fontFamily, fontBaseUrl);
|
|
58
|
+
};
|
|
59
|
+
const destroy = () => {
|
|
60
|
+
toRaw(navigator.value)?.destroy();
|
|
61
|
+
navigator.value = null;
|
|
62
|
+
publication.value = null;
|
|
63
|
+
tocLinks.value = [];
|
|
64
|
+
currentPosition.value = 0;
|
|
65
|
+
totalPositions.value = 0;
|
|
66
|
+
currentChapterTitle.value = '';
|
|
67
|
+
strategyFrameLoaded = null;
|
|
68
|
+
chapterProgressions = new Map();
|
|
69
|
+
activeChapterHref = '';
|
|
70
|
+
activeSource?.destroy();
|
|
71
|
+
activeSource = null;
|
|
72
|
+
wordDecorations?.destroy();
|
|
73
|
+
wordLookup?.destroy();
|
|
74
|
+
stopSettingsWatcher?.();
|
|
75
|
+
stopSettingsWatcher = null;
|
|
76
|
+
stopReaderColorsWatcher?.();
|
|
77
|
+
stopReaderColorsWatcher = null;
|
|
78
|
+
};
|
|
79
|
+
const selectStrategy = () => {
|
|
80
|
+
const strategy = options?.strategy ?? 'zip-fetcher';
|
|
81
|
+
if (strategy === 'wasm') {
|
|
82
|
+
setWasmStreamerConfig({
|
|
83
|
+
swUrl: options?.assets?.swUrl,
|
|
84
|
+
swScope: options?.assets?.swScope,
|
|
85
|
+
wasmUrl: options?.assets?.wasmUrl,
|
|
86
|
+
});
|
|
87
|
+
return useEpubReaderWasm();
|
|
88
|
+
}
|
|
89
|
+
return useEpubReaderZipFetcher();
|
|
90
|
+
};
|
|
91
|
+
const init = async () => {
|
|
92
|
+
if (!containerRef.value) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
loading.value = true;
|
|
96
|
+
error.value = null;
|
|
97
|
+
try {
|
|
98
|
+
const url = sourceRef.value;
|
|
99
|
+
const strategySource = selectStrategy();
|
|
100
|
+
const source = await strategySource.load(url);
|
|
101
|
+
activeSource = strategySource;
|
|
102
|
+
let pub;
|
|
103
|
+
let positions = [];
|
|
104
|
+
if (source.publication) {
|
|
105
|
+
pub = source.publication;
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
pub = new RPublication({
|
|
109
|
+
manifest: source.manifest,
|
|
110
|
+
fetcher: source.fetcher,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
getProgress = source.createProgressCalculator(pub);
|
|
114
|
+
chapterProgressions = source.chapterProgressions;
|
|
115
|
+
strategyFrameLoaded = source.onFrameLoaded ?? null;
|
|
116
|
+
positions = source.createPositions
|
|
117
|
+
? (await source.createPositions(pub))
|
|
118
|
+
: generatePositions(pub);
|
|
119
|
+
publication.value = pub;
|
|
120
|
+
if (pub.toc) {
|
|
121
|
+
tocLinks.value = pub.toc.items.map((link) => ({
|
|
122
|
+
title: link.title || link.href,
|
|
123
|
+
link,
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
if (positions.length === 0) {
|
|
127
|
+
positions = generatePositions(pub);
|
|
128
|
+
}
|
|
129
|
+
totalPositions.value = positions.length;
|
|
130
|
+
const initialLocator = storage.restorePosition(url, pub) ?? positions[0];
|
|
131
|
+
const listeners = {
|
|
132
|
+
positionChanged: (locator) => {
|
|
133
|
+
if (!locator) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
activeChapterHref = locator.href.split('#')[0] ?? locator.href;
|
|
137
|
+
wordDecorations?.onPositionChanged(activeChapterHref);
|
|
138
|
+
const idx = publication.value
|
|
139
|
+
? publication.value.readingOrder.findIndexWithHref(locator.href)
|
|
140
|
+
: -1;
|
|
141
|
+
if (idx < 0) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const { progress, resourceProgression } = getProgress(idx, locator.locations?.progression);
|
|
145
|
+
currentPosition.value = Math.round(Math.min(1, Math.max(0, progress)) * 100);
|
|
146
|
+
currentChapterTitle.value = getCurrentTitle(locator, chapterProgressions, tocLinks.value);
|
|
147
|
+
const persisted = locator.copyWithLocations({
|
|
148
|
+
position: idx + 1,
|
|
149
|
+
progression: resourceProgression,
|
|
150
|
+
});
|
|
151
|
+
storage.savePosition(url, persisted);
|
|
152
|
+
},
|
|
153
|
+
frameLoaded: async (wnd) => {
|
|
154
|
+
const nav = toRaw(navigator.value);
|
|
155
|
+
const currentHref = nav?.currentLocator?.href ?? activeChapterHref;
|
|
156
|
+
const chapterHref = (currentHref ?? '').split('#')[0] ?? '';
|
|
157
|
+
if (chapterHref) {
|
|
158
|
+
wordDecorations?.onFrameLoaded(wnd, chapterHref);
|
|
159
|
+
wordLookup?.onFrameLoaded(wnd);
|
|
160
|
+
}
|
|
161
|
+
if (chapterHref && strategyFrameLoaded) {
|
|
162
|
+
strategyFrameLoaded(wnd, chapterHref);
|
|
163
|
+
}
|
|
164
|
+
await injectCurrentFontIntoIframe(containerRef.value, settings.fontFamily, fontBaseUrl);
|
|
165
|
+
},
|
|
166
|
+
tap: () => !ENABLE_EDGE_TAP_PAGE_TURN,
|
|
167
|
+
click: () => !ENABLE_EDGE_TAP_PAGE_TURN,
|
|
168
|
+
zoom: () => { },
|
|
169
|
+
miscPointer: () => { },
|
|
170
|
+
scroll: () => { },
|
|
171
|
+
customEvent: () => { },
|
|
172
|
+
handleLocator: () => true,
|
|
173
|
+
textSelected: () => { },
|
|
174
|
+
contentProtection: () => { },
|
|
175
|
+
contextMenu: () => { },
|
|
176
|
+
peripheral: () => { },
|
|
177
|
+
};
|
|
178
|
+
navigator.value = new EpubNavigator(containerRef.value, pub, listeners, positions, initialLocator, {
|
|
179
|
+
preferences: new EpubPreferences(settings),
|
|
180
|
+
defaults: new EpubDefaults({}),
|
|
181
|
+
injectables: {
|
|
182
|
+
rules: [],
|
|
183
|
+
allowedDomains: [window.location.origin],
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
await toRaw(navigator.value).load();
|
|
187
|
+
await toRaw(navigator.value).submitPreferences(new EpubPreferences(settings));
|
|
188
|
+
stopSettingsWatcher = onSettingsChange(applyPreferences);
|
|
189
|
+
loading.value = false;
|
|
190
|
+
}
|
|
191
|
+
catch (e) {
|
|
192
|
+
error.value = e instanceof Error ? e.message : 'Unknown error loading EPUB';
|
|
193
|
+
loading.value = false;
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
const reload = async () => {
|
|
197
|
+
destroy();
|
|
198
|
+
await nextTick();
|
|
199
|
+
await init();
|
|
200
|
+
};
|
|
201
|
+
onMounted(async () => {
|
|
202
|
+
if (!sourceRef.value) {
|
|
203
|
+
error.value = 'No source URL provided';
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
await init();
|
|
207
|
+
});
|
|
208
|
+
onBeforeUnmount(() => {
|
|
209
|
+
destroy();
|
|
210
|
+
});
|
|
211
|
+
watch(() => sourceRef.value, async (next, prev) => {
|
|
212
|
+
if (!next || next === prev) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
await reload();
|
|
216
|
+
});
|
|
4
217
|
return {
|
|
5
|
-
|
|
6
|
-
|
|
218
|
+
init,
|
|
219
|
+
reload,
|
|
220
|
+
destroy,
|
|
7
221
|
};
|
|
8
222
|
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useEpubReaderState, LOG_MODES } from '../../src/composables/useEpubReaderState';
|
|
2
|
+
export const useEpubReaderLogging = (namespace) => {
|
|
3
|
+
const { logMode } = useEpubReaderState();
|
|
4
|
+
const debug = (message, payload) => {
|
|
5
|
+
if ([LOG_MODES.NONE, LOG_MODES.ERROR, LOG_MODES.WARNING].includes(logMode.value)) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
console.log(`[${namespace}] ${message}`, payload);
|
|
9
|
+
};
|
|
10
|
+
const warn = (message, payload) => {
|
|
11
|
+
if ([LOG_MODES.NONE, LOG_MODES.ERROR].includes(logMode.value)) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
console.warn(`[${namespace}] ${message}`, payload);
|
|
15
|
+
};
|
|
16
|
+
const error = (message, payload) => {
|
|
17
|
+
if ([LOG_MODES.NONE].includes(logMode.value)) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
console.error(`[${namespace}] ${message}`, payload);
|
|
21
|
+
};
|
|
22
|
+
return {
|
|
23
|
+
debug,
|
|
24
|
+
warn,
|
|
25
|
+
error,
|
|
26
|
+
};
|
|
27
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare const useEpubReaderNavigation: (
|
|
1
|
+
import type { TocEntry } from '../../src/types/common';
|
|
2
|
+
export declare const useEpubReaderNavigation: () => {
|
|
3
3
|
goForward: () => void;
|
|
4
4
|
goBackward: () => void;
|
|
5
|
-
goToLink: (link:
|
|
5
|
+
goToLink: (link: TocEntry["link"]) => void;
|
|
6
6
|
};
|
|
@@ -1,22 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
return {
|
|
6
|
-
goForward,
|
|
7
|
-
goBackward,
|
|
8
|
-
goToLink,
|
|
9
|
-
};
|
|
10
|
-
}
|
|
11
|
-
const activeEpubReader = useEpubReaderControllerRef();
|
|
1
|
+
import { toRaw } from 'vue';
|
|
2
|
+
import { useEpubReaderState } from '../../src/composables/useEpubReaderState';
|
|
3
|
+
export const useEpubReaderNavigation = () => {
|
|
4
|
+
const { navigator } = useEpubReaderState();
|
|
12
5
|
const goForward = () => {
|
|
13
|
-
|
|
6
|
+
toRaw(navigator.value)?.goForward(false, () => { });
|
|
14
7
|
};
|
|
15
8
|
const goBackward = () => {
|
|
16
|
-
|
|
9
|
+
toRaw(navigator.value)?.goBackward(false, () => { });
|
|
17
10
|
};
|
|
18
|
-
const goToLink = (
|
|
19
|
-
|
|
11
|
+
const goToLink = (link) => {
|
|
12
|
+
toRaw(navigator.value)?.goLink(link, false, () => { });
|
|
20
13
|
};
|
|
21
14
|
return {
|
|
22
15
|
goForward,
|