@internetarchive/bookreader 5.0.0-38 → 5.0.0-39

Sign up to get free protection for your applications and to get access to all the features.
Files changed (222) hide show
  1. package/BookReader/BookReader.css +8 -0
  2. package/BookReader/BookReader.js +1 -1
  3. package/BookReader/BookReader.js.map +1 -1
  4. package/BookReader/ia-bookreader-bundle.js +99 -75
  5. package/BookReader/ia-bookreader-bundle.js.map +1 -1
  6. package/BookReader/icons/magnify-minus.svg +1 -1
  7. package/BookReader/icons/magnify-plus.svg +1 -1
  8. package/BookReader/plugins/plugin.autoplay.js +1 -1
  9. package/BookReader/plugins/plugin.autoplay.js.map +1 -1
  10. package/BookReader/plugins/plugin.chapters.js +1 -1
  11. package/BookReader/plugins/plugin.chapters.js.map +1 -1
  12. package/BookReader/plugins/plugin.mobile_nav.js +1 -1
  13. package/BookReader/plugins/plugin.mobile_nav.js.map +1 -1
  14. package/BookReader/plugins/plugin.resume.js +1 -1
  15. package/BookReader/plugins/plugin.resume.js.map +1 -1
  16. package/BookReader/plugins/plugin.search.js +1 -1
  17. package/BookReader/plugins/plugin.search.js.map +1 -1
  18. package/BookReader/plugins/plugin.text_selection.js +1 -1
  19. package/BookReader/plugins/plugin.text_selection.js.map +1 -1
  20. package/BookReader/plugins/plugin.tts.js +1 -1
  21. package/BookReader/plugins/plugin.tts.js.map +1 -1
  22. package/BookReader/plugins/plugin.url.js +1 -1
  23. package/BookReader/plugins/plugin.url.js.map +1 -1
  24. package/CHANGELOG.md +5 -0
  25. package/README.md +13 -0
  26. package/package.json +14 -14
  27. package/renovate.json +1 -1
  28. package/src/BookReader/Mode1UpLit.js +7 -1
  29. package/src/BookReader/Mode2Up.js +11 -0
  30. package/src/BookReader/ModeSmoothZoom.js +2 -0
  31. package/src/BookReader/PageContainer.js +10 -4
  32. package/src/BookReader/utils/ScrollClassAdder.js +31 -0
  33. package/src/assets/icons/magnify-minus.svg +3 -7
  34. package/src/assets/icons/magnify-plus.svg +3 -7
  35. package/src/css/_TextSelection.scss +13 -0
  36. package/tests/jest/BookReader/PageContainer.test.js +5 -4
  37. package/tests/jest/BookReader/utils/ScrollClassAdder.test.js +49 -0
  38. package/.husky/_/husky.sh +0 -30
  39. package/stat/BookNavigator/BookModel.js +0 -14
  40. package/stat/BookNavigator/BookNavigator.js +0 -524
  41. package/stat/BookNavigator/assets/bookmark-colors.js +0 -15
  42. package/stat/BookNavigator/assets/button-base.js +0 -61
  43. package/stat/BookNavigator/assets/ia-logo.js +0 -17
  44. package/stat/BookNavigator/assets/icon_checkmark.js +0 -6
  45. package/stat/BookNavigator/assets/icon_close.js +0 -3
  46. package/stat/BookNavigator/assets/icon_sort_asc.js +0 -5
  47. package/stat/BookNavigator/assets/icon_sort_desc.js +0 -5
  48. package/stat/BookNavigator/assets/icon_sort_neutral.js +0 -5
  49. package/stat/BookNavigator/assets/icon_volumes.js +0 -11
  50. package/stat/BookNavigator/bookmarks/bookmark-button.js +0 -64
  51. package/stat/BookNavigator/bookmarks/bookmark-edit.js +0 -215
  52. package/stat/BookNavigator/bookmarks/bookmarks-list.js +0 -285
  53. package/stat/BookNavigator/bookmarks/bookmarks-loginCTA.js +0 -28
  54. package/stat/BookNavigator/bookmarks/bookmarks-provider.js +0 -56
  55. package/stat/BookNavigator/bookmarks/ia-bookmarks.js +0 -523
  56. package/stat/BookNavigator/br-fullscreen-mgr.js +0 -82
  57. package/stat/BookNavigator/delete-modal-actions.js +0 -49
  58. package/stat/BookNavigator/downloads/downloads-provider.js +0 -72
  59. package/stat/BookNavigator/downloads/downloads.js +0 -139
  60. package/stat/BookNavigator/provider-config.js +0 -0
  61. package/stat/BookNavigator/search/a-search-result.js +0 -55
  62. package/stat/BookNavigator/search/search-provider.js +0 -180
  63. package/stat/BookNavigator/search/search-results.js +0 -360
  64. package/stat/BookNavigator/sharing.js +0 -31
  65. package/stat/BookNavigator/visual-adjustments/visual-adjustments-provider.js +0 -94
  66. package/stat/BookNavigator/visual-adjustments/visual-adjustments.js +0 -280
  67. package/stat/BookNavigator/volumes/volumes-provider.js +0 -83
  68. package/stat/BookNavigator/volumes/volumes.js +0 -178
  69. package/stat/BookReader/BookModel.js +0 -518
  70. package/stat/BookReader/DebugConsole.js +0 -54
  71. package/stat/BookReader/DragScrollable.js +0 -233
  72. package/stat/BookReader/ImageCache.js +0 -116
  73. package/stat/BookReader/Mode1Up.js +0 -102
  74. package/stat/BookReader/Mode1UpLit.js +0 -434
  75. package/stat/BookReader/Mode2Up.js +0 -1372
  76. package/stat/BookReader/ModeSmoothZoom.js +0 -177
  77. package/stat/BookReader/ModeThumb.js +0 -344
  78. package/stat/BookReader/Navbar/Navbar.js +0 -310
  79. package/stat/BookReader/PageContainer.js +0 -120
  80. package/stat/BookReader/ReduceSet.js +0 -26
  81. package/stat/BookReader/Toolbar/Toolbar.js +0 -384
  82. package/stat/BookReader/events.js +0 -20
  83. package/stat/BookReader/options.js +0 -324
  84. package/stat/BookReader/utils/HTMLDimensionsCacher.js +0 -44
  85. package/stat/BookReader/utils/classes.js +0 -36
  86. package/stat/BookReader/utils.js +0 -240
  87. package/stat/BookReader.js +0 -2550
  88. package/stat/BookReaderComponent/BookReaderComponent.js +0 -117
  89. package/stat/assets/icons/1up.svg +0 -12
  90. package/stat/assets/icons/2up.svg +0 -15
  91. package/stat/assets/icons/advance.svg +0 -26
  92. package/stat/assets/icons/chevron-right.svg +0 -1
  93. package/stat/assets/icons/close-circle-dark.svg +0 -1
  94. package/stat/assets/icons/close-circle.svg +0 -1
  95. package/stat/assets/icons/fullscreen.svg +0 -17
  96. package/stat/assets/icons/fullscreen_exit.svg +0 -17
  97. package/stat/assets/icons/hamburger.svg +0 -15
  98. package/stat/assets/icons/left-arrow.svg +0 -12
  99. package/stat/assets/icons/magnify-minus.svg +0 -16
  100. package/stat/assets/icons/magnify-plus.svg +0 -17
  101. package/stat/assets/icons/magnify.svg +0 -15
  102. package/stat/assets/icons/pause.svg +0 -23
  103. package/stat/assets/icons/play.svg +0 -22
  104. package/stat/assets/icons/playback-speed.svg +0 -34
  105. package/stat/assets/icons/read-aloud.svg +0 -22
  106. package/stat/assets/icons/review.svg +0 -22
  107. package/stat/assets/icons/thumbnails.svg +0 -17
  108. package/stat/assets/icons/voice.svg +0 -1
  109. package/stat/assets/icons/volume-full.svg +0 -22
  110. package/stat/assets/images/BRicons.png +0 -0
  111. package/stat/assets/images/BRicons.svg +0 -94
  112. package/stat/assets/images/BRicons_ia.png +0 -0
  113. package/stat/assets/images/back_pages.png +0 -0
  114. package/stat/assets/images/book_bottom_icon.png +0 -0
  115. package/stat/assets/images/book_down_icon.png +0 -0
  116. package/stat/assets/images/book_left_icon.png +0 -0
  117. package/stat/assets/images/book_leftmost_icon.png +0 -0
  118. package/stat/assets/images/book_right_icon.png +0 -0
  119. package/stat/assets/images/book_rightmost_icon.png +0 -0
  120. package/stat/assets/images/book_top_icon.png +0 -0
  121. package/stat/assets/images/book_up_icon.png +0 -0
  122. package/stat/assets/images/books_graphic.svg +0 -177
  123. package/stat/assets/images/booksplit.png +0 -0
  124. package/stat/assets/images/control_pause_icon.png +0 -0
  125. package/stat/assets/images/control_play_icon.png +0 -0
  126. package/stat/assets/images/embed_icon.png +0 -0
  127. package/stat/assets/images/icon-home-ia.png +0 -0
  128. package/stat/assets/images/icon_OL-logo-xs.png +0 -0
  129. package/stat/assets/images/icon_alert-xs.png +0 -0
  130. package/stat/assets/images/icon_book.svg +0 -12
  131. package/stat/assets/images/icon_bookmark.svg +0 -12
  132. package/stat/assets/images/icon_close-pop.png +0 -0
  133. package/stat/assets/images/icon_download.png +0 -0
  134. package/stat/assets/images/icon_gear.svg +0 -14
  135. package/stat/assets/images/icon_hamburger.svg +0 -20
  136. package/stat/assets/images/icon_home.png +0 -0
  137. package/stat/assets/images/icon_home.svg +0 -21
  138. package/stat/assets/images/icon_home_ia.png +0 -0
  139. package/stat/assets/images/icon_indicator.png +0 -0
  140. package/stat/assets/images/icon_info.svg +0 -11
  141. package/stat/assets/images/icon_one_page.svg +0 -8
  142. package/stat/assets/images/icon_pause.svg +0 -1
  143. package/stat/assets/images/icon_play.svg +0 -1
  144. package/stat/assets/images/icon_playback-rate.svg +0 -15
  145. package/stat/assets/images/icon_return.png +0 -0
  146. package/stat/assets/images/icon_search_button.svg +0 -8
  147. package/stat/assets/images/icon_share.svg +0 -9
  148. package/stat/assets/images/icon_skip-ahead.svg +0 -6
  149. package/stat/assets/images/icon_skip-back.svg +0 -13
  150. package/stat/assets/images/icon_speaker.svg +0 -18
  151. package/stat/assets/images/icon_speaker_open.svg +0 -10
  152. package/stat/assets/images/icon_thumbnails.svg +0 -12
  153. package/stat/assets/images/icon_toc.svg +0 -5
  154. package/stat/assets/images/icon_two_pages.svg +0 -9
  155. package/stat/assets/images/icon_zoomer.png +0 -0
  156. package/stat/assets/images/loading.gif +0 -0
  157. package/stat/assets/images/logo_icon.png +0 -0
  158. package/stat/assets/images/marker_chap-off.png +0 -0
  159. package/stat/assets/images/marker_chap-off.svg +0 -11
  160. package/stat/assets/images/marker_chap-off_ia.png +0 -0
  161. package/stat/assets/images/marker_chap-on.png +0 -0
  162. package/stat/assets/images/marker_chap-on.svg +0 -11
  163. package/stat/assets/images/marker_srch-on.svg +0 -11
  164. package/stat/assets/images/marker_srchchap-off.png +0 -0
  165. package/stat/assets/images/marker_srchchap-on.png +0 -0
  166. package/stat/assets/images/nav_control-dn.png +0 -0
  167. package/stat/assets/images/nav_control-dn_ia.png +0 -0
  168. package/stat/assets/images/nav_control-up.png +0 -0
  169. package/stat/assets/images/nav_control-up_ia.png +0 -0
  170. package/stat/assets/images/nav_control.png +0 -0
  171. package/stat/assets/images/one_page_mode_icon.png +0 -0
  172. package/stat/assets/images/paper-badge.png +0 -0
  173. package/stat/assets/images/print_icon.png +0 -0
  174. package/stat/assets/images/progressbar.gif +0 -0
  175. package/stat/assets/images/right_edges.png +0 -0
  176. package/stat/assets/images/slider.png +0 -0
  177. package/stat/assets/images/slider_ia.png +0 -0
  178. package/stat/assets/images/thumbnail_mode_icon.png +0 -0
  179. package/stat/assets/images/transparent.png +0 -0
  180. package/stat/assets/images/two_page_mode_icon.png +0 -0
  181. package/stat/assets/images/zoom_in_icon.png +0 -0
  182. package/stat/assets/images/zoom_out_icon.png +0 -0
  183. package/stat/css/BookReader.scss +0 -89
  184. package/stat/css/_BRBookmarks.scss +0 -29
  185. package/stat/css/_BRComponent.scss +0 -13
  186. package/stat/css/_BRfloat.scss +0 -197
  187. package/stat/css/_BRicon.scss +0 -48
  188. package/stat/css/_BRmain.scss +0 -251
  189. package/stat/css/_BRnav.scss +0 -359
  190. package/stat/css/_BRpages.scss +0 -139
  191. package/stat/css/_BRsearch.scss +0 -226
  192. package/stat/css/_BRtoolbar.scss +0 -84
  193. package/stat/css/_BRvendor.scss +0 -5
  194. package/stat/css/_MobileNav.scss +0 -194
  195. package/stat/css/_TextSelection.scss +0 -32
  196. package/stat/css/_colorbox.scss +0 -52
  197. package/stat/css/_controls.scss +0 -253
  198. package/stat/css/_icons.scss +0 -121
  199. package/stat/jquery-wrapper.js +0 -4
  200. package/stat/plugins/plugin.archive_analytics.js +0 -86
  201. package/stat/plugins/plugin.autoplay.js +0 -129
  202. package/stat/plugins/plugin.chapters.js +0 -248
  203. package/stat/plugins/plugin.iframe.js +0 -48
  204. package/stat/plugins/plugin.mobile_nav.js +0 -288
  205. package/stat/plugins/plugin.resume.js +0 -68
  206. package/stat/plugins/plugin.text_selection.js +0 -291
  207. package/stat/plugins/plugin.url.js +0 -198
  208. package/stat/plugins/plugin.vendor-fullscreen.js +0 -247
  209. package/stat/plugins/search/plugin.search.js +0 -439
  210. package/stat/plugins/search/view.js +0 -439
  211. package/stat/plugins/tts/AbstractTTSEngine.js +0 -249
  212. package/stat/plugins/tts/FestivalTTSEngine.js +0 -169
  213. package/stat/plugins/tts/PageChunk.js +0 -107
  214. package/stat/plugins/tts/PageChunkIterator.js +0 -163
  215. package/stat/plugins/tts/WebTTSEngine.js +0 -357
  216. package/stat/plugins/tts/plugin.tts.js +0 -357
  217. package/stat/plugins/tts/tooltip_dict.js +0 -15
  218. package/stat/plugins/tts/utils.js +0 -91
  219. package/stat/util/browserSniffing.js +0 -30
  220. package/stat/util/debouncer.js +0 -26
  221. package/stat/util/docCookies.js +0 -67
  222. package/stat/util/strings.js +0 -34
@@ -1,357 +0,0 @@
1
- /* global BookReader */
2
- /**
3
- * Plugin for Text to Speech in BookReader
4
- */
5
- import FestivalTTSEngine from './FestivalTTSEngine.js';
6
- import WebTTSEngine from './WebTTSEngine.js';
7
- import { toISO6391, approximateWordCount } from './utils.js';
8
- import { en as tooltips } from './tooltip_dict.js';
9
- import { renderBoxesInPageContainerLayer } from '../../BookReader/PageContainer.js';
10
- /** @typedef {import('./PageChunk.js').default} PageChunk */
11
- /** @typedef {import("./AbstractTTSEngine.js").default} AbstractTTSEngine */
12
-
13
- // Default options for TTS
14
- jQuery.extend(BookReader.defaultOptions, {
15
- server: 'ia600609.us.archive.org',
16
- bookPath: '',
17
- enableTtsPlugin: true,
18
- });
19
-
20
- // Extend the constructor to add TTS properties
21
- BookReader.prototype.setup = (function (super_) {
22
- return function (options) {
23
- super_.call(this, options);
24
-
25
- if (this.options.enableTtsPlugin) {
26
- /** @type { {[pageIndex: number]: Array<{ l: number, r: number, t: number, b: number }>} } */
27
- this._ttsBoxesByIndex = {};
28
-
29
- let TTSEngine = WebTTSEngine.isSupported() ? WebTTSEngine :
30
- FestivalTTSEngine.isSupported() ? FestivalTTSEngine :
31
- null;
32
-
33
- if (/_forceTTSEngine=(festival|web)/.test(location.toString())) {
34
- const engineName = location.toString().match(/_forceTTSEngine=(festival|web)/)[1];
35
- TTSEngine = { festival: FestivalTTSEngine, web: WebTTSEngine }[engineName];
36
- }
37
-
38
- if (TTSEngine) {
39
- /** @type {AbstractTTSEngine} */
40
- this.ttsEngine = new TTSEngine({
41
- server: options.server,
42
- bookPath: options.bookPath,
43
- bookLanguage: toISO6391(options.bookLanguage),
44
- onLoadingStart: this.showProgressPopup.bind(this, 'Loading audio...'),
45
- onLoadingComplete: this.removeProgressPopup.bind(this),
46
- onDone: this.ttsStop.bind(this),
47
- beforeChunkPlay: this.ttsBeforeChunkPlay.bind(this),
48
- afterChunkPlay: this.ttsSendChunkFinishedAnalyticsEvent.bind(this),
49
- });
50
- }
51
- }
52
- };
53
- })(BookReader.prototype.setup);
54
-
55
- BookReader.prototype.init = (function(super_) {
56
- return function() {
57
- if (this.options.enableTtsPlugin) {
58
- // Bind to events
59
-
60
- this.bind(BookReader.eventNames.PostInit, () => {
61
- this.$('.BRicon.read').click(() => {
62
- this.ttsToggle();
63
- return false;
64
- });
65
- if (this.ttsEngine) {
66
- this.ttsEngine.init();
67
- if (/[?&]_autoReadAloud=show/.test(location.toString())) {
68
- this.ttsStart(false); // false flag is to initiate read aloud controls
69
- }
70
- }
71
- });
72
-
73
- // This is fired when the hash changes by one of the other plugins!
74
- // i.e. it will fire every time the page changes -_-
75
- // this.bind(BookReader.eventNames.stop, function(e, br) {
76
- // this.ttsStop();
77
- // }.bind(this));
78
- }
79
- super_.call(this);
80
- };
81
- })(BookReader.prototype.init);
82
-
83
- /** @override */
84
- BookReader.prototype._createPageContainer = (function (super_) {
85
- return function (index) {
86
- const pageContainer = super_.call(this, index);
87
- if (this.options.enableTtsPlugin && pageContainer.page && index in this._ttsBoxesByIndex) {
88
- const pageIndex = pageContainer.page.index;
89
- renderBoxesInPageContainerLayer('ttsHiliteLayer', this._ttsBoxesByIndex[pageIndex], pageContainer.page, pageContainer.$container[0]);
90
- }
91
- return pageContainer;
92
- };
93
- })(BookReader.prototype._createPageContainer);
94
-
95
- // Extend buildMobileDrawerElement
96
- BookReader.prototype.buildMobileDrawerElement = (function (super_) {
97
- return function () {
98
- const $el = super_.call(this);
99
- if (this.options.enableTtsPlugin && this.ttsEngine) {
100
- $el.find('.BRmobileMenu__moreInfoRow').after($(`
101
- <li>
102
- <span>
103
- <span class="DrawerIconWrapper"><img class="DrawerIcon" src="${this.imagesBaseURL}icon_speaker_open.svg" alt="info-speaker"/></span>
104
- Read Aloud
105
- </span>
106
- <div>
107
- <span class="larger">Press to toggle read aloud</span>
108
- <br/>
109
- <button class="BRicon read"></button>
110
- </div>
111
- </li>`));
112
- }
113
- return $el;
114
- };
115
- })(BookReader.prototype.buildMobileDrawerElement);
116
-
117
- // Extend initNavbar
118
- BookReader.prototype.initNavbar = (function (super_) {
119
- return function () {
120
- const $el = super_.call(this);
121
- if (this.options.enableTtsPlugin && this.ttsEngine) {
122
- this.refs.$BRReadAloudToolbar = $(`
123
- <ul class="read-aloud">
124
- <li>
125
- <select class="playback-speed" name="playback-speed" title="${tooltips.playbackSpeed}">
126
- <option value="0.25">0.25x</option>
127
- <option value="0.5">0.5x</option>
128
- <option value="0.75">0.75x</option>
129
- <option value="1.0" selected>1.0x</option>
130
- <option value="1.25">1.25x</option>
131
- <option value="1.5">1.5x</option>
132
- <option value="1.75">1.75x</option>
133
- <option value="2">2x</option>
134
- </select>
135
- </li>
136
- <li>
137
- <button type="button" name="review" title="${tooltips.review}">
138
- <div class="icon icon-review"></div>
139
- </button>
140
- </li>
141
- <li>
142
- <button type="button" name="play" title="${tooltips.play}">
143
- <div class="icon icon-play"></div>
144
- <div class="icon icon-pause"></div>
145
- </button>
146
- </li>
147
- <li>
148
- <button type="button" name="advance" title="${tooltips.advance}">
149
- <div class="icon icon-advance"></div>
150
- </button>
151
- </li>
152
- <li>
153
- <select class="playback-voices" name="playback-voice" style="display: none" title="Change read aloud voices">
154
- </select>
155
- </li>
156
- </ul>
157
- `);
158
-
159
- $el.find('.BRcontrols').prepend(this.refs.$BRReadAloudToolbar);
160
-
161
- const renderVoicesMenu = (voicesMenu) => {
162
- voicesMenu.empty();
163
- if (this.ttsEngine.getVoices().length > 1) {
164
- voicesMenu.append(this.ttsEngine.getVoices().map(
165
- voice =>
166
- $(`<option value="${voice.voiceURI}">${voice.lang} - ${voice.name}</option>`)));
167
- voicesMenu.val(this.ttsEngine.voice.voiceURI);
168
- voicesMenu.show();
169
- } else {
170
- voicesMenu.hide();
171
- }
172
- };
173
- const voicesMenu = this.refs.$BRReadAloudToolbar.find('[name=playback-voice]');
174
- renderVoicesMenu(voicesMenu);
175
- voicesMenu.on("change", ev => this.ttsEngine.setVoice(voicesMenu.val()));
176
- this.ttsEngine.events.on('pause resume start', () => this.ttsUpdateState());
177
- this.ttsEngine.events.on('voiceschanged', () => renderVoicesMenu(voicesMenu));
178
- this.refs.$BRReadAloudToolbar.find('[name=play]').on("click", this.ttsPlayPause.bind(this));
179
- this.refs.$BRReadAloudToolbar.find('[name=advance]').on("click", this.ttsJumpForward.bind(this));
180
- this.refs.$BRReadAloudToolbar.find('[name=review]').on("click", this.ttsJumpBackward.bind(this));
181
- const $rateSelector = this.refs.$BRReadAloudToolbar.find('select[name="playback-speed"]');
182
- $rateSelector.on("change", ev => this.ttsEngine.setPlaybackRate(parseFloat($rateSelector.val())));
183
- $(`<li>
184
- <button class="BRicon read js-tooltip" title="${tooltips.readAloud}">
185
- <div class="icon icon-read-aloud"></div>
186
- <span class="tooltip">${tooltips.readAloud}</span>
187
- </button>
188
- </li>`).insertBefore($el.find('.BRcontrols .BRicon.zoom_out').closest('li'));
189
- }
190
- return $el;
191
- };
192
- })(BookReader.prototype.initNavbar);
193
-
194
- // ttsToggle()
195
- //______________________________________________________________________________
196
- BookReader.prototype.ttsToggle = function () {
197
- if (this.autoStop) this.autoStop();
198
- if (this.ttsEngine.playing) {
199
- this.ttsStop();
200
- } else {
201
- this.ttsStart();
202
- }
203
- };
204
-
205
- // ttsStart(
206
- //______________________________________________________________________________
207
- BookReader.prototype.ttsStart = function (startTTSEngine = true) {
208
- if (this.constModeThumb == this.mode)
209
- this.switchMode(this.constMode1up);
210
-
211
- this.refs.$BRReadAloudToolbar.addClass('visible');
212
- this.$('.BRicon.read').addClass('unread active');
213
- this.ttsSendAnalyticsEvent('Start');
214
- if (startTTSEngine)
215
- this.ttsEngine.start(this.currentIndex(), this.getNumLeafs());
216
- };
217
-
218
- BookReader.prototype.ttsJumpForward = function () {
219
- if (this.ttsEngine.paused) {
220
- this.ttsEngine.resume();
221
- }
222
- this.ttsEngine.jumpForward();
223
- };
224
-
225
- BookReader.prototype.ttsJumpBackward = function () {
226
- if (this.ttsEngine.paused) {
227
- this.ttsEngine.resume();
228
- }
229
- this.ttsEngine.jumpBackward();
230
- };
231
-
232
- BookReader.prototype.ttsUpdateState = function() {
233
- const isPlaying = !(this.ttsEngine.paused || !this.ttsEngine.playing);
234
- this.$('.read-aloud [name=play]').toggleClass('playing', isPlaying);
235
- };
236
-
237
- BookReader.prototype.ttsPlayPause = function() {
238
- if (!this.ttsEngine.playing) {
239
- this.ttsToggle();
240
- } else {
241
- this.ttsEngine.togglePlayPause();
242
- this.ttsUpdateState(this.ttsEngine.paused);
243
- }
244
- };
245
-
246
- // ttsStop()
247
- //______________________________________________________________________________
248
- BookReader.prototype.ttsStop = function () {
249
- this.refs.$BRReadAloudToolbar.removeClass('visible');
250
- this.$('.BRicon.read').removeClass('unread active');
251
- this.ttsSendAnalyticsEvent('Stop');
252
- this.ttsEngine.stop();
253
- this.ttsRemoveHilites();
254
- this.removeProgressPopup();
255
- };
256
-
257
- /**
258
- * @param {PageChunk} chunk
259
- * @return {PromiseLike<void>} returns once the flip is done
260
- */
261
- BookReader.prototype.ttsBeforeChunkPlay = async function(chunk) {
262
- await this.ttsMaybeFlipToIndex(chunk.leafIndex);
263
- this.ttsHighlightChunk(chunk);
264
- // This appears not to work; ttsMaybeFlipToIndex causes a scroll to the top of
265
- // the active page :/ Disabling cause the extra scroll just adds an odd jitter.
266
- // this.ttsScrollToChunk(chunk);
267
- };
268
-
269
- /**
270
- * @param {PageChunk} chunk
271
- */
272
- BookReader.prototype.ttsSendChunkFinishedAnalyticsEvent = function(chunk) {
273
- this.ttsSendAnalyticsEvent('ChunkFinished-Words', approximateWordCount(chunk.text));
274
- };
275
-
276
- /**
277
- * Flip the page if the provided leaf index is not visible
278
- * @param {Number} leafIndex
279
- * @return {PromiseLike<void>} resolves once the flip animation has completed
280
- */
281
- BookReader.prototype.ttsMaybeFlipToIndex = function (leafIndex) {
282
- const in2PageMode = this.constMode2up == this.mode;
283
- let resolve = null;
284
- const promise = new Promise(res => resolve = res);
285
-
286
- if (!in2PageMode) {
287
- this.jumpToIndex(leafIndex);
288
- resolve();
289
- } else {
290
- const leafVisible = leafIndex == this.twoPage.currentIndexR || leafIndex == this.twoPage.currentIndexL;
291
- if (leafVisible) {
292
- resolve();
293
- } else {
294
- this.animationFinishedCallback = resolve;
295
- const mustGoNext = leafIndex > Math.max(this.twoPage.currentIndexR, this.twoPage.currentIndexL);
296
- if (mustGoNext) this.next();
297
- else this.prev();
298
- promise.then(this.ttsMaybeFlipToIndex.bind(this, leafIndex));
299
- }
300
- }
301
-
302
- return promise;
303
- };
304
-
305
- /**
306
- * @param {PageChunk} chunk
307
- */
308
- BookReader.prototype.ttsHighlightChunk = function(chunk) {
309
- // The poorly-named variable leafIndex
310
- const pageIndex = chunk.leafIndex;
311
-
312
- this.ttsRemoveHilites();
313
-
314
- // group by index; currently only possible to have chunks on one page :/
315
- this._ttsBoxesByIndex = {
316
- [pageIndex]: chunk.lineRects.map(([l, b, r, t]) => ({l, r, b, t}))
317
- };
318
-
319
- // update any already created pages
320
- for (const [pageIndexString, boxes] of Object.entries(this._ttsBoxesByIndex)) {
321
- const pageIndex = parseFloat(pageIndexString);
322
- const page = this._models.book.getPage(pageIndex);
323
- const pageContainers = this.getActivePageContainerElementsForIndex(pageIndex);
324
- pageContainers.forEach(container => renderBoxesInPageContainerLayer('ttsHiliteLayer', boxes, page, container));
325
- }
326
- };
327
-
328
- /**
329
- * @param {PageChunk} chunk
330
- */
331
- BookReader.prototype.ttsScrollToChunk = function(chunk) {
332
- if (this.constMode1up != this.mode) return;
333
-
334
- $(`.pagediv${chunk.leafIndex} .ttsHiliteLayer rect`)[0]?.scrollIntoView();
335
- };
336
-
337
- // ttsRemoveHilites()
338
- //______________________________________________________________________________
339
- BookReader.prototype.ttsRemoveHilites = function () {
340
- $(this.getActivePageContainerElements()).find('.ttsHiliteLayer').remove();
341
- this._ttsBoxesByIndex = {};
342
- };
343
-
344
- /**
345
- * @private
346
- * Send an analytics event with an optional value. Also attaches the book's language.
347
- * @param {string} action
348
- * @param {number} [value]
349
- */
350
- BookReader.prototype.ttsSendAnalyticsEvent = function(action, value) {
351
- if (this.archiveAnalyticsSendEvent) {
352
- const extraValues = {};
353
- const mediaLanguage = this.ttsEngine.opts.bookLanguage;
354
- if (mediaLanguage) extraValues.mediaLanguage = mediaLanguage;
355
- this.archiveAnalyticsSendEvent('BRReadAloud', action, value, extraValues);
356
- }
357
- };
@@ -1,15 +0,0 @@
1
- export const en = {
2
- advance: 'Advance 10 seconds',
3
- play: 'Play',
4
- playbackSpeed: 'Playback speed',
5
- readAloud: 'Read this book aloud',
6
- review: 'Review 10 seconds',
7
- };
8
-
9
- export const es = {
10
- advance: 'Avance 10 segundos',
11
- play: 'Jugar',
12
- playbackSpeed: 'Velocidad de reproducción',
13
- readAloud: 'Lee este libro en voz alta',
14
- review: 'Revisar 10 segundos',
15
- };
@@ -1,91 +0,0 @@
1
- import langs from 'iso-language-codes/js/data.js';
2
-
3
- /**
4
- * Convert a EventTarget style event into a promise
5
- * @param {EventTarget} target
6
- * @param {string} eventType
7
- * @return {Promise<Event>}
8
- */
9
- export function promisifyEvent(target, eventType) {
10
- return new Promise(res => {
11
- const resolver = ev => {
12
- target.removeEventListener(eventType, resolver);
13
- res(ev);
14
- };
15
- target.addEventListener(eventType, resolver);
16
- });
17
- }
18
-
19
- /**
20
- * Use regex to approximate word count in a string
21
- * @param {string} text
22
- * @return {number}
23
- */
24
- export function approximateWordCount(text) {
25
- const m = text.match(/\S+/g);
26
- return m ? m.length : 0;
27
- }
28
-
29
- /**
30
- * Waits the provided number of ms and then resolves with a promise
31
- * @param {number} ms
32
- * @return {Promise}
33
- */
34
- export function sleep(ms) {
35
- return new Promise(res => setTimeout(res, ms));
36
- }
37
-
38
- /**
39
- * Checks whether the current browser is on android
40
- * @param {string} [userAgent]
41
- * @return {boolean}
42
- */
43
- export function isAndroid(userAgent = navigator.userAgent) {
44
- return /android/i.test(userAgent);
45
- }
46
-
47
- /**
48
- * @typedef {string} ISO6391
49
- * Language code in ISO 639-1 format. e.g. en, fr, zh
50
- **/
51
-
52
- /** Each lang is an array, with each index mapping to a different property */
53
- const COLUMN_TO_LANG_INDEX = {
54
- 'Name': 0,
55
- 'Endonym': 1,
56
- 'ISO 639-1': 2,
57
- 'ISO 639-2/T': 3,
58
- 'ISO 639-2/B': 4
59
- };
60
-
61
- /**
62
- * @param {string} language in some format
63
- * @return {ISO6391?}
64
- */
65
- export function toISO6391(language) {
66
- if (!language) return null;
67
- language = language.toLowerCase();
68
-
69
- return searchForISO6391(language, ['ISO 639-1']) ||
70
- searchForISO6391(language, ['ISO 639-2/B']) ||
71
- searchForISO6391(language, ['ISO 639-2/T', 'Endonym', 'Name']);
72
- }
73
-
74
- /**
75
- * Searches for the given long in the given columns.
76
- * @param {string} language
77
- * @param {Array<keyof COLUMN_TO_LANG_INDEX>} columnsToSearch
78
- * @return {ISO6391?}
79
- */
80
- function searchForISO6391(language, columnsToSearch) {
81
- for (let i = 0; i < langs.length; i++) {
82
- for (let colI = 0; colI < columnsToSearch.length; colI++) {
83
- const column = columnsToSearch[colI];
84
- const columnValue = langs[i][COLUMN_TO_LANG_INDEX[column]];
85
- if (columnValue.split(', ').map(x => x.toLowerCase()).indexOf(language) != -1) {
86
- return langs[i][COLUMN_TO_LANG_INDEX['ISO 639-1']];
87
- }
88
- }
89
- }
90
- return null;
91
- }
@@ -1,30 +0,0 @@
1
-
2
- /**
3
- * Checks whether the current browser is a Chrome/Chromium browser
4
- * Code from https://stackoverflow.com/a/4565120/2317712
5
- * @param {string} [userAgent]
6
- * @param {string} [vendor]
7
- * @return {boolean}
8
- */
9
- export function isChrome(userAgent = navigator.userAgent, vendor = navigator.vendor) {
10
- return /chrome/i.test(userAgent) && /google inc/i.test(vendor);
11
- }
12
-
13
- /**
14
- * Checks whether the current browser is firefox
15
- * @param {string} [userAgent]
16
- * @return {boolean}
17
- */
18
- export function isFirefox(userAgent = navigator.userAgent) {
19
- return /firefox/i.test(userAgent);
20
- }
21
-
22
- /**
23
- * Checks whether the current browser is safari
24
- * https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent#Browser_Name
25
- * @param {string} [userAgent]
26
- * @return {boolean}
27
- */
28
- export function isSafari(userAgent = navigator.userAgent) {
29
- return /safari/i.test(userAgent) && !/chrome|chromium/i.test(userAgent);
30
- }
@@ -1,26 +0,0 @@
1
- /**
2
- * Wait until some time has passed before executing a callback.
3
- *
4
- * @param {Function} callback
5
- * @param {Number} threshhold - in milliseconds
6
- * @param {*} context - will be bound to callback as its "this" value
7
- */
8
- class Debouncer {
9
- constructor(callback, threshhold = 250, context = undefined) {
10
- this.callback = callback;
11
- this.threshhold = threshhold;
12
- this.context = context;
13
- this.deferTimeout = undefined;
14
- }
15
-
16
- execute() {
17
- clearTimeout(this.deferTimeout);
18
- this.deferTimeout = setTimeout(this.executeCallback.bind(this), this.threshhold);
19
- }
20
-
21
- executeCallback() {
22
- this.callback.apply(this.context);
23
- }
24
- }
25
-
26
- export { Debouncer as default };
@@ -1,67 +0,0 @@
1
- /**
2
- * Helper module use to get, set and remove item from cookie
3
- *
4
- * See more:
5
- * https://developer.mozilla.org/en-US/docs/Web/API/document.cookie
6
- * https://developer.mozilla.org/User:fusionchess
7
- * https://github.com/madmurphy/cookies.js
8
- * This framework is released under the GNU Public License, version 3 or later.
9
- * http://www.gnu.org/licenses/gpl-3.0-standalone.html
10
- */
11
-
12
- /**
13
- * Get specific key's value stored in cookie
14
- *
15
- * @param {string} sKey
16
- *
17
- * @returns {string|null}
18
- */
19
- export function getItem(sKey) {
20
- if (!sKey) return null;
21
-
22
- return decodeURIComponent(
23
- // eslint-disable-next-line no-useless-escape
24
- document.cookie.replace(new RegExp('(?:(?:^|.*;)\\s*' + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, '\\$&') + '\\s*\\=\\s*([^;]*).*$)|^.*$'), '$1')) || null;
25
- }
26
-
27
- /**
28
- * Set specific key's value in cookie
29
- *
30
- * @param {string} sKey cookie name
31
- * @param {string} sValue cookie value
32
- * @param {string} [vEnd] expire|max-age
33
- * @param {string} [sPath] path of current item
34
- * @param {string} [sDomain] domain name
35
- * @param {boolean} [bSecure]
36
- *
37
- * @returns {true}
38
- */
39
- export function setItem(sKey, sValue, vEnd, sPath, sDomain, bSecure) {
40
- document.cookie = encodeURIComponent(sKey) + '=' + encodeURIComponent(sValue)
41
- + (vEnd ? `; expires=${vEnd.toUTCString()}` : '')
42
- + (sDomain ? `; domain=${sDomain}` : '')
43
- + (sPath ? `; path=${sPath}` : '')
44
- + (bSecure ? `; secure` : '');
45
-
46
- return true;
47
- }
48
-
49
- /**
50
- * BROKEN Remove specific key's value from cookie
51
- * @fixme hasItem isn't even implemented! This will always error.
52
- * @param {string} sKey cookie name
53
- * @param {string} [sPath] path of current item
54
- * @param {string} [sDomain]
55
- *
56
- * @returns {boolean}
57
- */
58
- export function removeItem(sKey, sPath, sDomain) {
59
- // eslint-disable-next-line
60
- if (!hasItem(sKey)) return false;
61
-
62
- document.cookie = encodeURIComponent(sKey) + `=; expires=Thu, 01 Jan 1970 00:00:00 GMT`
63
- + (sDomain ? `; domain=${sDomain}` : '')
64
- + (sPath ? `; path=${sPath}` : '');
65
-
66
- return true;
67
- }
@@ -1,34 +0,0 @@
1
- /**
2
- * @typedef {String} StringWithVars
3
- * A template string with {{foo}} style variables
4
- * Also supports filters, like {{bookPath|urlencode}} (See APPLY_FILTERS for the
5
- * supported list of filters)
6
- **/
7
-
8
- /**
9
- * @param {StringWithVars|String} template
10
- * @param { {[varName: string]: { toString: () => string} } } vars
11
- * @param { {[varName: string]: { toString: () => string} } } [overrides]
12
- */
13
- export function applyVariables(template, vars, overrides = {}, possibleFilters = APPLY_FILTERS) {
14
- return template?.replace(/\{\{([^}]*?)\}\}/g, ($0, $1) => {
15
- if (!$1) return $0;
16
- /** @type {string} */
17
- const expression = $1;
18
- const [varName, ...filterNames] = expression.split('|').map(x => x.trim());
19
- const defined = varName in overrides || varName in vars;
20
-
21
- // If it's not defined, don't expand it at all
22
- if (!defined) return $0;
23
-
24
- const value = varName in overrides ? overrides[varName]
25
- : varName in vars ? vars[varName] : null;
26
- const filters = filterNames.map(n => possibleFilters[n]);
27
- return filters.reduce((acc, cur) => cur(acc), value && value.toString());
28
- });
29
- }
30
-
31
- /** @type { {[filterName: String]:( string => string)} } */
32
- export const APPLY_FILTERS = {
33
- urlencode: encodeURIComponent,
34
- };