@asteasolutions/epub-reader 1.0.0

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.
Files changed (98) hide show
  1. package/.prettierrc.js +6 -0
  2. package/README.md +104 -0
  3. package/dist/array.d.ts +1 -0
  4. package/dist/array.js +19 -0
  5. package/dist/array.js.map +1 -0
  6. package/dist/audio-player.d.ts +28 -0
  7. package/dist/audio-player.js +77 -0
  8. package/dist/audio-player.js.map +1 -0
  9. package/dist/book-loaders/ajax-unpacked.d.ts +12 -0
  10. package/dist/book-loaders/ajax-unpacked.js +46 -0
  11. package/dist/book-loaders/ajax-unpacked.js.map +1 -0
  12. package/dist/book-loaders/index.d.ts +13 -0
  13. package/dist/book-loaders/index.js +15 -0
  14. package/dist/book-loaders/index.js.map +1 -0
  15. package/dist/book-loaders/zip.d.ts +12 -0
  16. package/dist/book-loaders/zip.js +67 -0
  17. package/dist/book-loaders/zip.js.map +1 -0
  18. package/dist/book.d.ts +16 -0
  19. package/dist/book.js +60 -0
  20. package/dist/book.js.map +1 -0
  21. package/dist/content-controller/reflowable-content.d.ts +24 -0
  22. package/dist/content-controller/reflowable-content.js +115 -0
  23. package/dist/content-controller/reflowable-content.js.map +1 -0
  24. package/dist/content-controller.d.ts +10 -0
  25. package/dist/content-controller.js +2 -0
  26. package/dist/content-controller.js.map +1 -0
  27. package/dist/epub-types/container.d.ts +19 -0
  28. package/dist/epub-types/container.js +2 -0
  29. package/dist/epub-types/container.js.map +1 -0
  30. package/dist/epub-types/package/collection.d.ts +13 -0
  31. package/dist/epub-types/package/collection.js +2 -0
  32. package/dist/epub-types/package/collection.js.map +1 -0
  33. package/dist/epub-types/package/index.d.ts +18 -0
  34. package/dist/epub-types/package/index.js +2 -0
  35. package/dist/epub-types/package/index.js.map +1 -0
  36. package/dist/epub-types/package/manifest.d.ts +12 -0
  37. package/dist/epub-types/package/manifest.js +2 -0
  38. package/dist/epub-types/package/manifest.js.map +1 -0
  39. package/dist/epub-types/package/metadata.d.ts +44 -0
  40. package/dist/epub-types/package/metadata.js +2 -0
  41. package/dist/epub-types/package/metadata.js.map +1 -0
  42. package/dist/epub-types/package/spine.d.ts +11 -0
  43. package/dist/epub-types/package/spine.js +2 -0
  44. package/dist/epub-types/package/spine.js.map +1 -0
  45. package/dist/epub-types/smil.d.ts +97 -0
  46. package/dist/epub-types/smil.js +2 -0
  47. package/dist/epub-types/smil.js.map +1 -0
  48. package/dist/epub-types/xml.d.ts +9 -0
  49. package/dist/epub-types/xml.js +2 -0
  50. package/dist/epub-types/xml.js.map +1 -0
  51. package/dist/index.d.ts +6 -0
  52. package/dist/index.js +4 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/media-overlay.d.ts +32 -0
  55. package/dist/media-overlay.js +177 -0
  56. package/dist/media-overlay.js.map +1 -0
  57. package/dist/package-parser/index.d.ts +27 -0
  58. package/dist/package-parser/index.js +72 -0
  59. package/dist/package-parser/index.js.map +1 -0
  60. package/dist/package-parser/nav-parser.d.ts +17 -0
  61. package/dist/package-parser/nav-parser.js +30 -0
  62. package/dist/package-parser/nav-parser.js.map +1 -0
  63. package/dist/package-parser/overlay-parser.d.ts +10 -0
  64. package/dist/package-parser/overlay-parser.js +35 -0
  65. package/dist/package-parser/overlay-parser.js.map +1 -0
  66. package/dist/plugin.d.ts +7 -0
  67. package/dist/plugin.js +2 -0
  68. package/dist/plugin.js.map +1 -0
  69. package/dist/plugins/chapter-links-plugin.d.ts +11 -0
  70. package/dist/plugins/chapter-links-plugin.js +36 -0
  71. package/dist/plugins/chapter-links-plugin.js.map +1 -0
  72. package/dist/plugins/reader-events-plugin.d.ts +14 -0
  73. package/dist/plugins/reader-events-plugin.js +32 -0
  74. package/dist/plugins/reader-events-plugin.js.map +1 -0
  75. package/dist/plugins/text-highlighter-plugin.d.ts +11 -0
  76. package/dist/plugins/text-highlighter-plugin.js +32 -0
  77. package/dist/plugins/text-highlighter-plugin.js.map +1 -0
  78. package/dist/reader-events-listener.d.ts +4 -0
  79. package/dist/reader-events-listener.js +2 -0
  80. package/dist/reader-events-listener.js.map +1 -0
  81. package/dist/reader.d.ts +51 -0
  82. package/dist/reader.js +179 -0
  83. package/dist/reader.js.map +1 -0
  84. package/dist/smil/helper.d.ts +25 -0
  85. package/dist/smil/helper.js +71 -0
  86. package/dist/smil/helper.js.map +1 -0
  87. package/dist/smil/index.d.ts +21 -0
  88. package/dist/smil/index.js +105 -0
  89. package/dist/smil/index.js.map +1 -0
  90. package/dist/styles.d.ts +2 -0
  91. package/dist/styles.js +6 -0
  92. package/dist/styles.js.map +1 -0
  93. package/dist/uri.d.ts +5 -0
  94. package/dist/uri.js +19 -0
  95. package/dist/uri.js.map +1 -0
  96. package/eslint.config.mjs +31 -0
  97. package/package.json +32 -0
  98. package/tsconfig.json +19 -0
package/.prettierrc.js ADDED
@@ -0,0 +1,6 @@
1
+ module.exports = {
2
+ singleQuote: true,
3
+ trailingComma: 'all',
4
+ printWidth: 120,
5
+ semi: false,
6
+ }
package/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # EPub Reader
2
+
3
+ A library that loads and renders ePub documents in the browser.
4
+
5
+ It provides support for:
6
+ * [Media Overlays](https://www.w3.org/TR/epub/#sec-media-overlays) - if the ePub has smil files the library plays the narration and highlights the corresponding html element. The client can also obtain the current time of the audio book and the total duration.
7
+ * [Navigation](https://www.w3.org/TR/epub-33/#sec-nav)
8
+ * For EPub 3.0 the manifest `<item properties="nav" />` element is parsed and provided in the form of a Table of contents (page list is also included).
9
+ * Support for EPub 2.0 `<item media-type="application/x-dtbncx+xml" />` is not yet implemented.
10
+ * Cover image
11
+ * For EPub 3.0 a manfiest `<item properties="cover-image" />` element is checked.
12
+ * For EPub 2.0 `<meta name="cover" />` is not yet implemented.
13
+ * Metadata
14
+ * Identifier (`<dc:identifier>`)
15
+ * Title (`<dc:title>`)
16
+ * Language (`<dc:language>`)
17
+ * Author (`<dc:creator>`)
18
+
19
+ ## Getting started
20
+
21
+ ### Installation
22
+
23
+ ```
24
+ npm i @asteasolutions/epub-reader
25
+ ```
26
+
27
+ ### Usage
28
+
29
+ First you need an HTML element where the content will be rendered
30
+
31
+ ```html
32
+ <div id="epub-reader"></div>
33
+ ```
34
+
35
+ Then you need to pass the epub document. The library provides two loaders which you can use depending on the source of the epub:
36
+ * `ZipLoader` - use this when you have a Blob/File (e.g. selected by the user from the file system or downloaded from a url) or a url to an epub file. In the case of a url the epub is streamed instead of being downloaded in its entirety.
37
+ * `AJAXUnpackedLoader` - use this when the epub is extracted and served statically from a url.
38
+
39
+ You can also use the `createLoader` function which will create a loader for you based on the parameters passed.
40
+ ```javascript
41
+ // This expects the epub files to be statically served on the corresponding path appended to the url - e.g. https://example-epub-library.com/awesome-epub/META-INF/container.xml
42
+ createLoader('https://example-epub-library.com/awesome-epub')
43
+
44
+ // This will create a ZipLoader
45
+ createLoader('https://example-epub-library.com/awesome-zipped-epub', { isZipURL: true })
46
+ // same as this
47
+ createLoader(file)
48
+ ```
49
+
50
+ Putting it all together
51
+ ```typescript
52
+ import { createLoader, Book, Reader } from '@asteasolutions/reader-core'
53
+
54
+ const container = document.getElementById('epub-reader')
55
+
56
+ const loader = await createLoader(source: Blob | string)
57
+ Book.open(loader).subscribe({
58
+ next: book => {
59
+ const reader = new Reader(container, book)
60
+
61
+ reader.loadContent().subscribe(() => {
62
+ // EPub is now rendered
63
+ })
64
+ }
65
+ })
66
+ ```
67
+
68
+ ### Events
69
+
70
+ Once initialized you can listen to the following `Reader` events:
71
+ | Property | Description |
72
+ | -------- | ----------- |
73
+ | `audioEvents.onPlaybackStateChanged` | Fired with a single argument `playing: boolean` |
74
+ | `audioEvents.onAudioEnded` | Fired when an audio file reached its end |
75
+ | `audioEvents.onPositionChanged` | Fired every 200 ms while a media overlay is playing. It is passed a single argument `currentTime: number`, indicating the current time (in seconds) within the audio file |
76
+ | `events.pageChange` | Fired when the reader navigates to a new page |
77
+ | `events.chapterChange` | Fired when a new chapter is loaded (new html from the epub is rendered) |
78
+ | `events.textSelected` | Fired when the user selects something in the epub's html. Passed a `range: DOMRange` argument |
79
+ | `mediaOverlayEvents.onGlobalPositionChanged` | Similar to the `audioEvents.onPositionChanged` but in the context of the entire book. Also the argument is in milliseconds |
80
+
81
+ ### API
82
+
83
+ | Object | Property | Description |
84
+ | ------ | -------- | ----------- |
85
+ | **Reader** | `currentChapterIndex` | The index of the current chapter as defined in the epub's `<spine>` tag |
86
+ | | `totalChapters` | The number of chapters in the epub |
87
+ | | `currentPage` | The index of the current page within the chapter. <br><br> *Note*: Since only a paginated layout is currently supported, the page properties are referring to the currently dispalyed pages and not the page list of the navigation document. This means that resizing the container holding the epub will cause the pages to be recalculated. |
88
+ | | `totalPages` | The number of pages within the chapter |
89
+ | | `playing` | Whether or not a media overlay is being played |
90
+ | | `togglePlayback()` | Turns the media overlay playback on/off |
91
+ | | `goToHref(href: string).subscribe()` | Navigates to an anchor within the epub. For example passing the `href` property from a `TocEntry` |
92
+ | | `previousChapter(goToEnd?: boolean)` | Navigates to the previous chapter. In case `true` is passed the epub will be navigated to the last page of the previous chapter, otherwise it will go to the beginning |
93
+ | | `previousPage()` | Navigates to the previous page in the chapter. If the user is on the first page of a chapter the epub is navigated to the last page of the previous chapter |
94
+ | | `nextPage()` | Navigates to the first page of the next chapter |
95
+ | | `nextPage()` | Navigates to the next page in the chapter. If the user is on the last page it will navigate to the first page of the next chapter |
96
+ | **Book** | `metadata` | The `Metadata` object for the epub |
97
+ | | `nav` | The `Navigation` object for the epub |
98
+ | | `cover` | The cover image url |
99
+ | | `overlayMetadata` | The `OverlayMetadata` object for the epub. Contains the total duration of the epub and the durations for each smil file |
100
+ | | `open(loader: BookLoader)` *static* | Creates the book object with the given loader |
101
+
102
+ ### Rendering
103
+
104
+ Currently on a paginated layout is supported.
@@ -0,0 +1 @@
1
+ export declare function binarySearch<T>(arr: T[], comp: (el: T) => number): T | undefined;
package/dist/array.js ADDED
@@ -0,0 +1,19 @@
1
+ export function binarySearch(arr, comp) {
2
+ let start = 0, end = arr.length - 1;
3
+ while (start <= end) {
4
+ const mid = Math.floor((start + end) / 2);
5
+ const elem = arr[mid];
6
+ const res = comp(elem);
7
+ if (res === 0) {
8
+ return elem;
9
+ }
10
+ if (res < 0) {
11
+ end = mid - 1;
12
+ }
13
+ else {
14
+ start = mid + 1;
15
+ }
16
+ }
17
+ return undefined;
18
+ }
19
+ //# sourceMappingURL=array.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"array.js","sourceRoot":"","sources":["../lib/array.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,YAAY,CAAI,GAAQ,EAAE,IAAuB;IAC/D,IAAI,KAAK,GAAG,CAAC,EACX,GAAG,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAA;IACtB,OAAO,KAAK,IAAI,GAAG,EAAE,CAAC;QACpB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;QACzC,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAE,CAAA;QACtB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAA;QACtB,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;YACd,OAAO,IAAI,CAAA;QACb,CAAC;QAED,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;YACZ,GAAG,GAAG,GAAG,GAAG,CAAC,CAAA;QACf,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,GAAG,GAAG,CAAC,CAAA;QACjB,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC"}
@@ -0,0 +1,28 @@
1
+ export default class AudioPlayer {
2
+ private player;
3
+ private positionChangedInterval?;
4
+ private playbackStateChangedSubject;
5
+ private positionChangedSubject;
6
+ private audioEndedSubject;
7
+ events: {
8
+ onPlaybackStateChanged: import("rxjs").Observable<boolean>;
9
+ onPositionChanged: import("rxjs").Observable<number>;
10
+ onAudioEnded: import("rxjs").Observable<void>;
11
+ };
12
+ constructor();
13
+ play(): void;
14
+ pause(): void;
15
+ get playing(): boolean;
16
+ togglePlayback(): void;
17
+ seekTo({ src, offset }: {
18
+ src: string;
19
+ offset: number;
20
+ }): void;
21
+ destroy(): void;
22
+ private onPlay;
23
+ private onPause;
24
+ private onEnded;
25
+ private onAbort;
26
+ private onError;
27
+ private resetState;
28
+ }
@@ -0,0 +1,77 @@
1
+ import { Subject } from 'rxjs';
2
+ export default class AudioPlayer {
3
+ constructor() {
4
+ this.playbackStateChangedSubject = new Subject();
5
+ this.positionChangedSubject = new Subject();
6
+ this.audioEndedSubject = new Subject();
7
+ this.events = {
8
+ onPlaybackStateChanged: this.playbackStateChangedSubject.asObservable(),
9
+ onPositionChanged: this.positionChangedSubject.asObservable(),
10
+ onAudioEnded: this.audioEndedSubject.asObservable(),
11
+ };
12
+ this.player = new Audio();
13
+ this.player.addEventListener('play', this.onPlay.bind(this));
14
+ this.player.addEventListener('pause', this.onPause.bind(this));
15
+ this.player.addEventListener('ended', this.onEnded.bind(this));
16
+ this.player.addEventListener('abort', this.onAbort.bind(this));
17
+ this.player.addEventListener('error', this.onError.bind(this));
18
+ }
19
+ play() {
20
+ this.player.play().catch(console.error);
21
+ }
22
+ pause() {
23
+ this.player.pause();
24
+ }
25
+ get playing() {
26
+ return !this.player.paused;
27
+ }
28
+ togglePlayback() {
29
+ if (this.playing) {
30
+ this.pause();
31
+ }
32
+ else {
33
+ this.play();
34
+ }
35
+ }
36
+ seekTo({ src, offset }) {
37
+ if (this.player.src !== src) {
38
+ this.player.src = src;
39
+ this.play();
40
+ }
41
+ this.player.currentTime = offset / 1000;
42
+ }
43
+ destroy() {
44
+ this.player.pause();
45
+ this.resetState();
46
+ this.player.removeEventListener('play', this.onPlay.bind(this));
47
+ this.player.removeEventListener('pause', this.onPause.bind(this));
48
+ this.player.removeEventListener('ended', this.onEnded.bind(this));
49
+ this.player.removeEventListener('abort', this.onAbort.bind(this));
50
+ this.player.removeEventListener('error', this.onError.bind(this));
51
+ }
52
+ onPlay() {
53
+ this.playbackStateChangedSubject.next(true);
54
+ this.positionChangedInterval = window.setInterval(() => {
55
+ this.positionChangedSubject.next(this.player.currentTime);
56
+ }, 200);
57
+ }
58
+ onPause() {
59
+ this.playbackStateChangedSubject.next(false);
60
+ this.resetState();
61
+ }
62
+ onEnded() {
63
+ this.resetState();
64
+ this.audioEndedSubject.next();
65
+ }
66
+ onAbort() {
67
+ this.resetState();
68
+ }
69
+ onError() {
70
+ console.error(this.player.error);
71
+ this.resetState();
72
+ }
73
+ resetState() {
74
+ clearInterval(this.positionChangedInterval);
75
+ }
76
+ }
77
+ //# sourceMappingURL=audio-player.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio-player.js","sourceRoot":"","sources":["../lib/audio-player.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAE9B,MAAM,CAAC,OAAO,OAAO,WAAW;IAc9B;QAVQ,gCAA2B,GAAG,IAAI,OAAO,EAAW,CAAA;QACpD,2BAAsB,GAAG,IAAI,OAAO,EAAU,CAAA;QAC9C,sBAAiB,GAAG,IAAI,OAAO,EAAQ,CAAA;QAExC,WAAM,GAAG;YACd,sBAAsB,EAAE,IAAI,CAAC,2BAA2B,CAAC,YAAY,EAAE;YACvE,iBAAiB,EAAE,IAAI,CAAC,sBAAsB,CAAC,YAAY,EAAE;YAC7D,YAAY,EAAE,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE;SACpD,CAAA;QAGC,IAAI,CAAC,MAAM,GAAG,IAAI,KAAK,EAAE,CAAA;QAEzB,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QAC5D,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QAC9D,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QAC9D,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QAC9D,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAChE,CAAC;IAEM,IAAI;QACT,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IACzC,CAAC;IAEM,KAAK;QACV,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAA;IACrB,CAAC;IAED,IAAW,OAAO;QAChB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAA;IAC5B,CAAC;IAEM,cAAc;QACnB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC,KAAK,EAAE,CAAA;QACd,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,EAAE,CAAA;QACb,CAAC;IACH,CAAC;IAEM,MAAM,CAAC,EAAE,GAAG,EAAE,MAAM,EAAmC;QAC5D,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;YAC5B,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,GAAG,CAAA;YACrB,IAAI,CAAC,IAAI,EAAE,CAAA;QACb,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,WAAW,GAAG,MAAM,GAAG,IAAI,CAAA;IACzC,CAAC;IAEM,OAAO;QACZ,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAA;QACnB,IAAI,CAAC,UAAU,EAAE,CAAA;QACjB,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QAC/D,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QACjE,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QACjE,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QACjE,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IACnE,CAAC;IAEO,MAAM;QACZ,IAAI,CAAC,2BAA2B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC3C,IAAI,CAAC,uBAAuB,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE;YACrD,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;QAC3D,CAAC,EAAE,GAAG,CAAC,CAAA;IACT,CAAC;IAEO,OAAO;QACb,IAAI,CAAC,2BAA2B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC5C,IAAI,CAAC,UAAU,EAAE,CAAA;IACnB,CAAC;IAEO,OAAO;QACb,IAAI,CAAC,UAAU,EAAE,CAAA;QACjB,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAA;IAC/B,CAAC;IAEO,OAAO;QACb,IAAI,CAAC,UAAU,EAAE,CAAA;IACnB,CAAC;IAEO,OAAO;QACb,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAChC,IAAI,CAAC,UAAU,EAAE,CAAA;IACnB,CAAC;IAEO,UAAU;QAChB,aAAa,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAA;IAC7C,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ import { Observable } from 'rxjs';
2
+ import { BookLoader } from '.';
3
+ export declare class AJAXUnpackedLoader implements BookLoader {
4
+ private url;
5
+ private abortController;
6
+ constructor(url: string);
7
+ fetch(path: string, asURL?: boolean): Observable<string>;
8
+ root(path: string): Observable<string>;
9
+ cancel(): void;
10
+ processChapterHTML(html: string, basePath: string): Observable<Document>;
11
+ private urlToPath;
12
+ }
@@ -0,0 +1,46 @@
1
+ import { map, Observable } from 'rxjs';
2
+ export class AJAXUnpackedLoader {
3
+ constructor(url) {
4
+ this.url = url;
5
+ this.abortController = new AbortController();
6
+ }
7
+ fetch(path, asURL = false) {
8
+ if (asURL) {
9
+ return this.root(path);
10
+ }
11
+ return new Observable((subscriber) => {
12
+ fetch(this.urlToPath(path), {
13
+ signal: this.abortController.signal,
14
+ })
15
+ // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
16
+ .then((response) => (response.ok ? response.text() : Promise.reject(response)))
17
+ .then((response) => {
18
+ subscriber.next(response);
19
+ subscriber.complete();
20
+ }, (error) => subscriber.error(error));
21
+ });
22
+ }
23
+ root(path) {
24
+ return new Observable((subscriber) => {
25
+ subscriber.next(this.urlToPath(path));
26
+ subscriber.complete();
27
+ });
28
+ }
29
+ cancel() {
30
+ this.abortController.abort('Load cancelled');
31
+ }
32
+ processChapterHTML(html, basePath) {
33
+ return this.root(basePath).pipe(map((root) => {
34
+ const parser = new DOMParser();
35
+ const content = parser.parseFromString(html, 'text/html');
36
+ const base = document.createElement('base');
37
+ base.href = `${root}/`;
38
+ content.head.prepend(base);
39
+ return content;
40
+ }));
41
+ }
42
+ urlToPath(path) {
43
+ return `${this.url.replace(/\/$/, '')}/${path.replace(/^\//, '')}`;
44
+ }
45
+ }
46
+ //# sourceMappingURL=ajax-unpacked.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ajax-unpacked.js","sourceRoot":"","sources":["../../lib/book-loaders/ajax-unpacked.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,MAAM,CAAA;AAGtC,MAAM,OAAO,kBAAkB;IAG7B,YAAoB,GAAW;QAAX,QAAG,GAAH,GAAG,CAAQ;QAFvB,oBAAe,GAAG,IAAI,eAAe,EAAE,CAAA;IAEb,CAAC;IAE5B,KAAK,CAAC,IAAY,EAAE,KAAK,GAAG,KAAK;QACtC,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACxB,CAAC;QACD,OAAO,IAAI,UAAU,CAAS,CAAC,UAAU,EAAE,EAAE;YAC3C,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;gBAC1B,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,MAAM;aACpC,CAAC;gBACA,2EAA2E;iBAC1E,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;iBAC9E,IAAI,CACH,CAAC,QAAQ,EAAE,EAAE;gBACX,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;gBACzB,UAAU,CAAC,QAAQ,EAAE,CAAA;YACvB,CAAC,EACD,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CACnC,CAAA;QACL,CAAC,CAAC,CAAA;IACJ,CAAC;IAEM,IAAI,CAAC,IAAY;QACtB,OAAO,IAAI,UAAU,CAAS,CAAC,UAAU,EAAE,EAAE;YAC3C,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAA;YACrC,UAAU,CAAC,QAAQ,EAAE,CAAA;QACvB,CAAC,CAAC,CAAA;IACJ,CAAC;IAEM,MAAM;QACX,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAA;IAC9C,CAAC;IAEM,kBAAkB,CAAC,IAAY,EAAE,QAAgB;QACtD,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAC7B,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACX,MAAM,MAAM,GAAG,IAAI,SAAS,EAAE,CAAA;YAC9B,MAAM,OAAO,GAAG,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;YAEzD,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAA;YAC3C,IAAI,CAAC,IAAI,GAAG,GAAG,IAAI,GAAG,CAAA;YACtB,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;YAC1B,OAAO,OAAO,CAAA;QAChB,CAAC,CAAC,CACH,CAAA;IACH,CAAC;IAEO,SAAS,CAAC,IAAY;QAC5B,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,CAAA;IACpE,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ import { Observable } from 'rxjs';
2
+ export interface BookLoader {
3
+ fetch(path: string, asURL?: boolean): Observable<string>;
4
+ root(path: string): Observable<string>;
5
+ cancel(): void;
6
+ processChapterHTML(html: string, basePath: string): Observable<Document>;
7
+ }
8
+ export interface CreateLoaderOptions {
9
+ isZipURL?: boolean;
10
+ }
11
+ export declare function createLoader(source: string | Blob, options?: CreateLoaderOptions): Promise<BookLoader>;
12
+ export * from './ajax-unpacked';
13
+ export * from './zip';
@@ -0,0 +1,15 @@
1
+ import { ZipLoader } from './zip';
2
+ import { AJAXUnpackedLoader } from './ajax-unpacked';
3
+ export async function createLoader(source, options = {}) {
4
+ if (source instanceof Blob || options.isZipURL) {
5
+ return new ZipLoader(source);
6
+ }
7
+ const response = await fetch(source, { method: 'HEAD' });
8
+ if (response.headers.get('content-type') === 'application/epub+zip') {
9
+ return new ZipLoader(source);
10
+ }
11
+ return new AJAXUnpackedLoader(source);
12
+ }
13
+ export * from './ajax-unpacked';
14
+ export * from './zip';
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/book-loaders/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAgBpD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAqB,EAAE,UAA+B,EAAE;IACzF,IAAI,MAAM,YAAY,IAAI,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QAC/C,OAAO,IAAI,SAAS,CAAC,MAAM,CAAC,CAAA;IAC9B,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IACxD,IAAI,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,KAAK,sBAAsB,EAAE,CAAC;QACpE,OAAO,IAAI,SAAS,CAAC,MAAM,CAAC,CAAA;IAC9B,CAAC;IACD,OAAO,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAA;AACvC,CAAC;AAED,cAAc,iBAAiB,CAAA;AAC/B,cAAc,OAAO,CAAA"}
@@ -0,0 +1,12 @@
1
+ import { Observable } from 'rxjs';
2
+ import { BookLoader } from '.';
3
+ export declare class ZipLoader implements BookLoader {
4
+ private entries;
5
+ private objectURLCache;
6
+ constructor(source: Blob | string);
7
+ fetch(path: string, asURL?: boolean): Observable<string>;
8
+ root(path: string): Observable<string>;
9
+ cancel(): void;
10
+ processChapterHTML(html: string, basePath: string): Observable<Document>;
11
+ private rewriteTagAttribute;
12
+ }
@@ -0,0 +1,67 @@
1
+ import { catchError, defaultIfEmpty, forkJoin, map, Observable, of, tap } from 'rxjs';
2
+ import { BlobReader, BlobWriter, HttpReader, TextWriter, ZipReader } from '@zip.js/zip.js';
3
+ import { absoluteOrPrefixed, normalize } from '../uri';
4
+ import { isString } from 'lodash';
5
+ export class ZipLoader {
6
+ constructor(source) {
7
+ this.objectURLCache = new Map();
8
+ const zipReader = new ZipReader(source instanceof Blob ? new BlobReader(source) : new HttpReader(source, { forceRangeRequests: true }));
9
+ this.entries = zipReader
10
+ .getEntries()
11
+ .catch((err) => {
12
+ console.error(`Error loading entry list for ${source instanceof File ? source.name : isString(source) ? source : 'blob'}`);
13
+ // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
14
+ return Promise.reject(err);
15
+ })
16
+ .finally(() => void zipReader.close());
17
+ }
18
+ fetch(path, asURL = false) {
19
+ path = normalize(path);
20
+ const cached = this.objectURLCache.get(path);
21
+ if (cached) {
22
+ return of(cached);
23
+ }
24
+ return new Observable((subscriber) => {
25
+ this.entries
26
+ .then((entries) => {
27
+ const entry = entries.find((e) => e.filename === path);
28
+ if (!entry) {
29
+ return Promise.reject(new Error(`Entry "${path}" not found`));
30
+ }
31
+ return asURL
32
+ ? entry.getData(new BlobWriter()).then((blob) => {
33
+ const url = URL.createObjectURL(blob);
34
+ this.objectURLCache.set(path, url);
35
+ return url;
36
+ })
37
+ : entry.getData(new TextWriter());
38
+ })
39
+ .then((data) => subscriber.next(data))
40
+ .catch((error) => subscriber.error(error))
41
+ .finally(() => subscriber.complete());
42
+ });
43
+ }
44
+ root(path) {
45
+ return of(path);
46
+ }
47
+ cancel() {
48
+ // Noop
49
+ }
50
+ processChapterHTML(html, basePath) {
51
+ const content = new DOMParser().parseFromString(html, 'text/html');
52
+ return forkJoin([
53
+ this.rewriteTagAttribute(content, 'img', 'src', true, basePath),
54
+ this.rewriteTagAttribute(content, 'link', 'href', true, basePath),
55
+ ]).pipe(map(() => content));
56
+ }
57
+ rewriteTagAttribute(content, tag, attr, asURL, basePath) {
58
+ return forkJoin(Array.from(content.querySelectorAll(`${tag}[${attr}]`)).map((elem) => forkJoin([
59
+ of(elem),
60
+ this.fetch(absoluteOrPrefixed(elem.getAttribute(attr), basePath), asURL).pipe(catchError((error) => {
61
+ console.warn(`Error rewriting ${tag}[${attr}=${elem.getAttribute(attr)}].`, error);
62
+ return of(null);
63
+ })),
64
+ ]))).pipe(defaultIfEmpty([]), tap((res) => res.forEach(([elem, url]) => (url ? elem.setAttribute(attr, url) : undefined))));
65
+ }
66
+ }
67
+ //# sourceMappingURL=zip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zip.js","sourceRoot":"","sources":["../../lib/book-loaders/zip.ts"],"names":[],"mappings":"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"}
package/dist/book.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import { Observable } from 'rxjs';
2
+ import { BookLoader } from './book-loaders';
3
+ import { PackageParser, Metadata } from './package-parser';
4
+ export declare class Book {
5
+ loader: BookLoader;
6
+ packageParser: PackageParser;
7
+ static open(loader: BookLoader): Observable<Book>;
8
+ constructor(loader: BookLoader, packageParser: PackageParser);
9
+ getSpineRefIds(): string[];
10
+ getChapterHTML(id: string): Observable<Document>;
11
+ private getItemParent;
12
+ get metadata(): Metadata;
13
+ get nav(): Observable<import(".").Navigation>;
14
+ get cover(): Observable<string | undefined>;
15
+ get overlayMetadata(): import(".").OverlayMetadata | null;
16
+ }
package/dist/book.js ADDED
@@ -0,0 +1,60 @@
1
+ import { map, of, switchMap, throwError } from 'rxjs';
2
+ import { XMLParser } from 'fast-xml-parser';
3
+ import { PackageParser } from './package-parser';
4
+ import { parentURI } from './uri';
5
+ const CONTAINER_PARSER = new XMLParser({
6
+ ignoreAttributes: false,
7
+ isArray: (tag) => tag === 'rootfile',
8
+ });
9
+ const PACKAGE_PARSER = new XMLParser({
10
+ ignoreAttributes: false,
11
+ isArray: (tag) => ['dc:identifier', 'dc:title', 'dc:language', 'dc:creator', 'meta'].includes(tag),
12
+ alwaysCreateTextNode: true,
13
+ });
14
+ export class Book {
15
+ static open(loader) {
16
+ return loader.fetch('META-INF/container.xml').pipe(map((content) => CONTAINER_PARSER.parse(content)), switchMap(({ container }) => {
17
+ const rootFilePath = container.rootfiles.rootfile[0]['@_full-path'];
18
+ return loader.fetch(rootFilePath).pipe(map((packageContent) => PACKAGE_PARSER.parse(packageContent)), switchMap((packageXml) => {
19
+ const packageParser = new PackageParser(packageXml, parentURI(rootFilePath), loader);
20
+ return of(new Book(loader, packageParser));
21
+ }));
22
+ }));
23
+ }
24
+ constructor(loader, packageParser) {
25
+ this.loader = loader;
26
+ this.packageParser = packageParser;
27
+ }
28
+ getSpineRefIds() {
29
+ return this.packageParser.getSpineRefIds();
30
+ }
31
+ getChapterHTML(id) {
32
+ const path = this.packageParser.getManifestItemPath(id);
33
+ if (!path) {
34
+ return throwError(() => `No chapter with id '${id}'`);
35
+ }
36
+ return this.loader
37
+ .fetch(path)
38
+ .pipe(switchMap((chapterHTML) => this.loader.processChapterHTML(chapterHTML, this.getItemParent(id))));
39
+ }
40
+ getItemParent(id) {
41
+ const path = this.packageParser.getManifestItemPath(id);
42
+ if (!path) {
43
+ return null;
44
+ }
45
+ return parentURI(path);
46
+ }
47
+ get metadata() {
48
+ return this.packageParser.metadata;
49
+ }
50
+ get nav() {
51
+ return this.packageParser.fetchNAV();
52
+ }
53
+ get cover() {
54
+ return this.packageParser.fetchCover();
55
+ }
56
+ get overlayMetadata() {
57
+ return this.packageParser.getOverlayMetadata();
58
+ }
59
+ }
60
+ //# sourceMappingURL=book.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"book.js","sourceRoot":"","sources":["../lib/book.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { ContentController } from '../content-controller';
2
+ export declare const DOCUMENT_CSS = "\n html, body {\n margin: 0;\n padding: 0;\n\n position: relative;\n }\n\n html {\n height: 100%;\n\n box-sizing: border-box;\n\n column-fill: auto;\n\n overflow: hidden;\n }\n";
3
+ export declare class ReflowableContent implements ContentController {
4
+ private iframe;
5
+ private document;
6
+ private page;
7
+ private columns;
8
+ private htmlPadding;
9
+ private columnGap;
10
+ private resizeObserver;
11
+ constructor(iframe: HTMLIFrameElement);
12
+ get currentPage(): number;
13
+ get totalPages(): number;
14
+ attach(): void;
15
+ detach(): void;
16
+ prepareChapter(): void;
17
+ private setColumnCount;
18
+ goToPage(page: number): void;
19
+ ensureVisible(elem: Element): void;
20
+ getFirstVisibleElement(): Element | null;
21
+ private updatePageOffset;
22
+ private get offset();
23
+ private updateStyles;
24
+ }