@internetarchive/bookreader 5.0.0-36 → 5.0.0-39

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 (280) hide show
  1. package/.github/workflows/node.js.yml +69 -7
  2. package/.github/workflows/npm-publish.yml +2 -16
  3. package/BookReader/BookReader.css +8 -0
  4. package/BookReader/BookReader.js +1 -1
  5. package/BookReader/BookReader.js.LICENSE.txt +8 -29
  6. package/BookReader/BookReader.js.map +1 -1
  7. package/BookReader/ia-bookreader-bundle.js +144 -119
  8. package/BookReader/ia-bookreader-bundle.js.LICENSE.txt +15 -12
  9. package/BookReader/ia-bookreader-bundle.js.map +1 -1
  10. package/BookReader/icons/magnify-minus.svg +1 -1
  11. package/BookReader/icons/magnify-plus.svg +1 -1
  12. package/BookReader/plugins/plugin.autoplay.js +1 -1
  13. package/BookReader/plugins/plugin.autoplay.js.map +1 -1
  14. package/BookReader/plugins/plugin.chapters.js +1 -1
  15. package/BookReader/plugins/plugin.chapters.js.map +1 -1
  16. package/BookReader/plugins/plugin.mobile_nav.js +1 -1
  17. package/BookReader/plugins/plugin.mobile_nav.js.map +1 -1
  18. package/BookReader/plugins/plugin.resume.js +1 -1
  19. package/BookReader/plugins/plugin.resume.js.map +1 -1
  20. package/BookReader/plugins/plugin.search.js +1 -1
  21. package/BookReader/plugins/plugin.search.js.map +1 -1
  22. package/BookReader/plugins/plugin.text_selection.js +1 -1
  23. package/BookReader/plugins/plugin.text_selection.js.map +1 -1
  24. package/BookReader/plugins/plugin.tts.js +1 -1
  25. package/BookReader/plugins/plugin.tts.js.map +1 -1
  26. package/BookReader/plugins/plugin.url.js +1 -1
  27. package/BookReader/plugins/plugin.url.js.map +1 -1
  28. package/CHANGELOG.md +26 -0
  29. package/README.md +14 -1
  30. package/codecov.yml +6 -0
  31. package/package.json +30 -33
  32. package/renovate.json +43 -0
  33. package/src/BookNavigator/assets/bookmark-colors.js +1 -1
  34. package/src/BookNavigator/assets/button-base.js +1 -1
  35. package/src/BookNavigator/assets/ia-logo.js +1 -1
  36. package/src/BookNavigator/assets/icon_checkmark.js +1 -1
  37. package/src/BookNavigator/assets/icon_close.js +1 -1
  38. package/src/BookNavigator/assets/icon_sort_asc.js +1 -1
  39. package/src/BookNavigator/assets/icon_sort_desc.js +1 -1
  40. package/src/BookNavigator/assets/icon_sort_neutral.js +1 -1
  41. package/src/BookNavigator/assets/icon_volumes.js +1 -1
  42. package/src/BookNavigator/book-navigator.js +1 -2
  43. package/src/BookNavigator/bookmarks/bookmark-button.js +1 -1
  44. package/src/BookNavigator/bookmarks/bookmark-edit.js +2 -3
  45. package/src/BookNavigator/bookmarks/bookmarks-list.js +2 -3
  46. package/src/BookNavigator/bookmarks/bookmarks-loginCTA.js +1 -1
  47. package/src/BookNavigator/bookmarks/bookmarks-provider.js +1 -1
  48. package/src/BookNavigator/bookmarks/ia-bookmarks.js +4 -7
  49. package/src/BookNavigator/delete-modal-actions.js +1 -1
  50. package/src/BookNavigator/downloads/downloads-provider.js +1 -1
  51. package/src/BookNavigator/downloads/downloads.js +1 -2
  52. package/src/BookNavigator/search/a-search-result.js +2 -3
  53. package/src/BookNavigator/search/search-provider.js +1 -2
  54. package/src/BookNavigator/search/search-results.js +1 -2
  55. package/src/BookNavigator/sharing.js +1 -1
  56. package/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js +1 -1
  57. package/src/BookNavigator/visual-adjustments/visual-adjustments.js +3 -3
  58. package/src/BookNavigator/volumes/volumes-provider.js +1 -1
  59. package/src/BookNavigator/volumes/volumes.js +2 -3
  60. package/src/BookReader/Mode1Up.js +2 -1
  61. package/src/BookReader/Mode1UpLit.js +10 -3
  62. package/src/BookReader/Mode2Up.js +11 -0
  63. package/src/BookReader/ModeSmoothZoom.js +2 -0
  64. package/src/BookReader/PageContainer.js +10 -4
  65. package/src/BookReader/utils/ScrollClassAdder.js +31 -0
  66. package/src/BookReader.js +4 -2
  67. package/src/assets/icons/magnify-minus.svg +3 -7
  68. package/src/assets/icons/magnify-plus.svg +3 -7
  69. package/src/css/_TextSelection.scss +13 -0
  70. package/src/ia-bookreader/ia-bookreader.js +1 -1
  71. package/src/plugins/plugin.chapters.js +11 -15
  72. package/src/plugins/plugin.text_selection.js +9 -10
  73. package/src/plugins/search/plugin.search.js +8 -18
  74. package/src/plugins/search/view.js +2 -0
  75. package/src/plugins/tts/AbstractTTSEngine.js +9 -4
  76. package/src/plugins/tts/FestivalTTSEngine.js +10 -11
  77. package/src/plugins/tts/PageChunk.js +11 -20
  78. package/src/plugins/tts/WebTTSEngine.js +22 -26
  79. package/tests/e2e/base.test.js +4 -5
  80. package/tests/e2e/helpers/desktopSearch.js +13 -12
  81. package/tests/e2e/models/Navigation.js +12 -3
  82. package/tests/e2e/rightToLeft.test.js +1 -1
  83. package/tests/e2e/viewmode.test.js +37 -31
  84. package/tests/jest/BookReader/Mode1UpLit.test.js +2 -1
  85. package/tests/jest/BookReader/PageContainer.test.js +5 -4
  86. package/tests/jest/BookReader/utils/ScrollClassAdder.test.js +49 -0
  87. package/tests/jest/plugins/plugin.text_selection.test.js +25 -23
  88. package/tests/jest/plugins/search/plugin.search.test.js +12 -20
  89. package/tests/jest/plugins/tts/AbstractTTSEngine.test.js +3 -3
  90. package/tests/karma/BookNavigator/bookmarks/bookmarks-list.test.js +2 -2
  91. package/tests/karma/BookNavigator/downloads/downloads.test.js +1 -1
  92. package/tests/karma/BookNavigator/volumes/volumes-provider.test.js +3 -3
  93. package/webpack.config.js +1 -1
  94. package/.github/dependabot.yml +0 -8
  95. package/.husky/_/husky.sh +0 -30
  96. package/BookReaderDemo/bookreader-template-bundle.js +0 -7178
  97. package/stat/BookNavigator/BookModel.js +0 -14
  98. package/stat/BookNavigator/BookNavigator.js +0 -482
  99. package/stat/BookNavigator/assets/bookmark-colors.js +0 -15
  100. package/stat/BookNavigator/assets/button-base.js +0 -61
  101. package/stat/BookNavigator/assets/ia-logo.js +0 -17
  102. package/stat/BookNavigator/assets/icon_checkmark.js +0 -6
  103. package/stat/BookNavigator/assets/icon_close.js +0 -3
  104. package/stat/BookNavigator/assets/icon_sort_asc.js +0 -5
  105. package/stat/BookNavigator/assets/icon_sort_desc.js +0 -5
  106. package/stat/BookNavigator/assets/icon_sort_neutral.js +0 -5
  107. package/stat/BookNavigator/assets/icon_volumes.js +0 -11
  108. package/stat/BookNavigator/bookmarks/bookmark-button.js +0 -64
  109. package/stat/BookNavigator/bookmarks/bookmark-edit.js +0 -215
  110. package/stat/BookNavigator/bookmarks/bookmarks-list.js +0 -285
  111. package/stat/BookNavigator/bookmarks/bookmarks-loginCTA.js +0 -28
  112. package/stat/BookNavigator/bookmarks/bookmarks-provider.js +0 -56
  113. package/stat/BookNavigator/bookmarks/ia-bookmarks.js +0 -523
  114. package/stat/BookNavigator/br-fullscreen-mgr.js +0 -82
  115. package/stat/BookNavigator/delete-modal-actions.js +0 -49
  116. package/stat/BookNavigator/downloads/downloads-provider.js +0 -72
  117. package/stat/BookNavigator/downloads/downloads.js +0 -139
  118. package/stat/BookNavigator/provider-config.js +0 -0
  119. package/stat/BookNavigator/search/a-search-result.js +0 -55
  120. package/stat/BookNavigator/search/search-provider.js +0 -180
  121. package/stat/BookNavigator/search/search-results.js +0 -360
  122. package/stat/BookNavigator/sharing.js +0 -31
  123. package/stat/BookNavigator/visual-adjustments/visual-adjustments-provider.js +0 -94
  124. package/stat/BookNavigator/visual-adjustments/visual-adjustments.js +0 -280
  125. package/stat/BookNavigator/volumes/volumes-provider.js +0 -83
  126. package/stat/BookNavigator/volumes/volumes.js +0 -178
  127. package/stat/BookReader/BookModel.js +0 -518
  128. package/stat/BookReader/DebugConsole.js +0 -54
  129. package/stat/BookReader/DragScrollable.js +0 -233
  130. package/stat/BookReader/ImageCache.js +0 -116
  131. package/stat/BookReader/Mode1Up.js +0 -102
  132. package/stat/BookReader/Mode1UpLit.js +0 -434
  133. package/stat/BookReader/Mode2Up.js +0 -1372
  134. package/stat/BookReader/ModeSmoothZoom.js +0 -177
  135. package/stat/BookReader/ModeThumb.js +0 -344
  136. package/stat/BookReader/Navbar/Navbar.js +0 -310
  137. package/stat/BookReader/PageContainer.js +0 -120
  138. package/stat/BookReader/ReduceSet.js +0 -26
  139. package/stat/BookReader/Toolbar/Toolbar.js +0 -384
  140. package/stat/BookReader/events.js +0 -20
  141. package/stat/BookReader/options.js +0 -324
  142. package/stat/BookReader/utils/HTMLDimensionsCacher.js +0 -44
  143. package/stat/BookReader/utils/classes.js +0 -36
  144. package/stat/BookReader/utils.js +0 -240
  145. package/stat/BookReader.js +0 -2550
  146. package/stat/BookReaderComponent/BookReaderComponent.js +0 -117
  147. package/stat/assets/icons/1up.svg +0 -12
  148. package/stat/assets/icons/2up.svg +0 -15
  149. package/stat/assets/icons/advance.svg +0 -26
  150. package/stat/assets/icons/chevron-right.svg +0 -1
  151. package/stat/assets/icons/close-circle-dark.svg +0 -1
  152. package/stat/assets/icons/close-circle.svg +0 -1
  153. package/stat/assets/icons/fullscreen.svg +0 -17
  154. package/stat/assets/icons/fullscreen_exit.svg +0 -17
  155. package/stat/assets/icons/hamburger.svg +0 -15
  156. package/stat/assets/icons/left-arrow.svg +0 -12
  157. package/stat/assets/icons/magnify-minus.svg +0 -16
  158. package/stat/assets/icons/magnify-plus.svg +0 -17
  159. package/stat/assets/icons/magnify.svg +0 -15
  160. package/stat/assets/icons/pause.svg +0 -23
  161. package/stat/assets/icons/play.svg +0 -22
  162. package/stat/assets/icons/playback-speed.svg +0 -34
  163. package/stat/assets/icons/read-aloud.svg +0 -22
  164. package/stat/assets/icons/review.svg +0 -22
  165. package/stat/assets/icons/thumbnails.svg +0 -17
  166. package/stat/assets/icons/voice.svg +0 -1
  167. package/stat/assets/icons/volume-full.svg +0 -22
  168. package/stat/assets/images/BRicons.png +0 -0
  169. package/stat/assets/images/BRicons.svg +0 -94
  170. package/stat/assets/images/BRicons_ia.png +0 -0
  171. package/stat/assets/images/back_pages.png +0 -0
  172. package/stat/assets/images/book_bottom_icon.png +0 -0
  173. package/stat/assets/images/book_down_icon.png +0 -0
  174. package/stat/assets/images/book_left_icon.png +0 -0
  175. package/stat/assets/images/book_leftmost_icon.png +0 -0
  176. package/stat/assets/images/book_right_icon.png +0 -0
  177. package/stat/assets/images/book_rightmost_icon.png +0 -0
  178. package/stat/assets/images/book_top_icon.png +0 -0
  179. package/stat/assets/images/book_up_icon.png +0 -0
  180. package/stat/assets/images/books_graphic.svg +0 -177
  181. package/stat/assets/images/booksplit.png +0 -0
  182. package/stat/assets/images/control_pause_icon.png +0 -0
  183. package/stat/assets/images/control_play_icon.png +0 -0
  184. package/stat/assets/images/embed_icon.png +0 -0
  185. package/stat/assets/images/icon-home-ia.png +0 -0
  186. package/stat/assets/images/icon_OL-logo-xs.png +0 -0
  187. package/stat/assets/images/icon_alert-xs.png +0 -0
  188. package/stat/assets/images/icon_book.svg +0 -12
  189. package/stat/assets/images/icon_bookmark.svg +0 -12
  190. package/stat/assets/images/icon_close-pop.png +0 -0
  191. package/stat/assets/images/icon_download.png +0 -0
  192. package/stat/assets/images/icon_gear.svg +0 -14
  193. package/stat/assets/images/icon_hamburger.svg +0 -20
  194. package/stat/assets/images/icon_home.png +0 -0
  195. package/stat/assets/images/icon_home.svg +0 -21
  196. package/stat/assets/images/icon_home_ia.png +0 -0
  197. package/stat/assets/images/icon_indicator.png +0 -0
  198. package/stat/assets/images/icon_info.svg +0 -11
  199. package/stat/assets/images/icon_one_page.svg +0 -8
  200. package/stat/assets/images/icon_pause.svg +0 -1
  201. package/stat/assets/images/icon_play.svg +0 -1
  202. package/stat/assets/images/icon_playback-rate.svg +0 -15
  203. package/stat/assets/images/icon_return.png +0 -0
  204. package/stat/assets/images/icon_search_button.svg +0 -8
  205. package/stat/assets/images/icon_share.svg +0 -9
  206. package/stat/assets/images/icon_skip-ahead.svg +0 -6
  207. package/stat/assets/images/icon_skip-back.svg +0 -13
  208. package/stat/assets/images/icon_speaker.svg +0 -18
  209. package/stat/assets/images/icon_speaker_open.svg +0 -10
  210. package/stat/assets/images/icon_thumbnails.svg +0 -12
  211. package/stat/assets/images/icon_toc.svg +0 -5
  212. package/stat/assets/images/icon_two_pages.svg +0 -9
  213. package/stat/assets/images/icon_zoomer.png +0 -0
  214. package/stat/assets/images/loading.gif +0 -0
  215. package/stat/assets/images/logo_icon.png +0 -0
  216. package/stat/assets/images/marker_chap-off.png +0 -0
  217. package/stat/assets/images/marker_chap-off.svg +0 -11
  218. package/stat/assets/images/marker_chap-off_ia.png +0 -0
  219. package/stat/assets/images/marker_chap-on.png +0 -0
  220. package/stat/assets/images/marker_chap-on.svg +0 -11
  221. package/stat/assets/images/marker_srch-on.svg +0 -11
  222. package/stat/assets/images/marker_srchchap-off.png +0 -0
  223. package/stat/assets/images/marker_srchchap-on.png +0 -0
  224. package/stat/assets/images/nav_control-dn.png +0 -0
  225. package/stat/assets/images/nav_control-dn_ia.png +0 -0
  226. package/stat/assets/images/nav_control-up.png +0 -0
  227. package/stat/assets/images/nav_control-up_ia.png +0 -0
  228. package/stat/assets/images/nav_control.png +0 -0
  229. package/stat/assets/images/one_page_mode_icon.png +0 -0
  230. package/stat/assets/images/paper-badge.png +0 -0
  231. package/stat/assets/images/print_icon.png +0 -0
  232. package/stat/assets/images/progressbar.gif +0 -0
  233. package/stat/assets/images/right_edges.png +0 -0
  234. package/stat/assets/images/slider.png +0 -0
  235. package/stat/assets/images/slider_ia.png +0 -0
  236. package/stat/assets/images/thumbnail_mode_icon.png +0 -0
  237. package/stat/assets/images/transparent.png +0 -0
  238. package/stat/assets/images/two_page_mode_icon.png +0 -0
  239. package/stat/assets/images/zoom_in_icon.png +0 -0
  240. package/stat/assets/images/zoom_out_icon.png +0 -0
  241. package/stat/css/BookReader.scss +0 -89
  242. package/stat/css/_BRBookmarks.scss +0 -29
  243. package/stat/css/_BRComponent.scss +0 -13
  244. package/stat/css/_BRfloat.scss +0 -197
  245. package/stat/css/_BRicon.scss +0 -48
  246. package/stat/css/_BRmain.scss +0 -251
  247. package/stat/css/_BRnav.scss +0 -359
  248. package/stat/css/_BRpages.scss +0 -139
  249. package/stat/css/_BRsearch.scss +0 -226
  250. package/stat/css/_BRtoolbar.scss +0 -84
  251. package/stat/css/_BRvendor.scss +0 -5
  252. package/stat/css/_MobileNav.scss +0 -194
  253. package/stat/css/_TextSelection.scss +0 -32
  254. package/stat/css/_colorbox.scss +0 -52
  255. package/stat/css/_controls.scss +0 -253
  256. package/stat/css/_icons.scss +0 -121
  257. package/stat/jquery-wrapper.js +0 -4
  258. package/stat/plugins/plugin.archive_analytics.js +0 -86
  259. package/stat/plugins/plugin.autoplay.js +0 -129
  260. package/stat/plugins/plugin.chapters.js +0 -248
  261. package/stat/plugins/plugin.iframe.js +0 -48
  262. package/stat/plugins/plugin.mobile_nav.js +0 -288
  263. package/stat/plugins/plugin.resume.js +0 -68
  264. package/stat/plugins/plugin.text_selection.js +0 -291
  265. package/stat/plugins/plugin.url.js +0 -198
  266. package/stat/plugins/plugin.vendor-fullscreen.js +0 -247
  267. package/stat/plugins/search/plugin.search.js +0 -439
  268. package/stat/plugins/search/view.js +0 -439
  269. package/stat/plugins/tts/AbstractTTSEngine.js +0 -249
  270. package/stat/plugins/tts/FestivalTTSEngine.js +0 -169
  271. package/stat/plugins/tts/PageChunk.js +0 -107
  272. package/stat/plugins/tts/PageChunkIterator.js +0 -163
  273. package/stat/plugins/tts/WebTTSEngine.js +0 -357
  274. package/stat/plugins/tts/plugin.tts.js +0 -357
  275. package/stat/plugins/tts/tooltip_dict.js +0 -15
  276. package/stat/plugins/tts/utils.js +0 -91
  277. package/stat/util/browserSniffing.js +0 -30
  278. package/stat/util/debouncer.js +0 -26
  279. package/stat/util/docCookies.js +0 -67
  280. 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
- };