@internetarchive/bookreader 5.0.0-118-alpha2 → 5.0.0-119

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 (232) hide show
  1. package/BookReader/474.js +2 -0
  2. package/BookReader/474.js.map +1 -0
  3. package/BookReader/BookReader.css +2451 -0
  4. package/BookReader/bergamot-translator-worker.js +2966 -0
  5. package/BookReader/bergamot-translator-worker.wasm +0 -0
  6. package/BookReader/hypothesis/LICENSE +50 -0
  7. package/BookReader/hypothesis/README.md +55 -0
  8. package/BookReader/hypothesis/build/boot-template.js +1 -0
  9. package/BookReader/hypothesis/build/boot.js +1 -0
  10. package/BookReader/hypothesis/build/manifest.json +20 -0
  11. package/BookReader/hypothesis/build/scripts/annotator.bundle.js +199 -0
  12. package/BookReader/hypothesis/build/scripts/annotator.bundle.js.map +1 -0
  13. package/BookReader/hypothesis/build/scripts/sidebar.bundle.js +811 -0
  14. package/BookReader/hypothesis/build/scripts/sidebar.bundle.js.map +1 -0
  15. package/BookReader/hypothesis/build/scripts/ui-playground.bundle.js +437 -0
  16. package/BookReader/hypothesis/build/scripts/ui-playground.bundle.js.map +1 -0
  17. package/BookReader/hypothesis/build/styles/annotator.css +4 -0
  18. package/BookReader/hypothesis/build/styles/annotator.css.map +1 -0
  19. package/BookReader/hypothesis/build/styles/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  20. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  21. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  22. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  23. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  24. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Main-Bold.woff2 +0 -0
  25. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  26. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Main-Italic.woff2 +0 -0
  27. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Main-Regular.woff2 +0 -0
  28. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  29. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Math-Italic.woff2 +0 -0
  30. package/BookReader/hypothesis/build/styles/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  31. package/BookReader/hypothesis/build/styles/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  32. package/BookReader/hypothesis/build/styles/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  33. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Script-Regular.woff2 +0 -0
  34. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  35. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  36. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  37. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  38. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  39. package/BookReader/hypothesis/build/styles/highlights.css +2 -0
  40. package/BookReader/hypothesis/build/styles/highlights.css.map +1 -0
  41. package/BookReader/hypothesis/build/styles/katex.min.css +3 -0
  42. package/BookReader/hypothesis/build/styles/katex.min.css.map +1 -0
  43. package/BookReader/hypothesis/build/styles/pdfjs-overrides.css +14 -0
  44. package/BookReader/hypothesis/build/styles/pdfjs-overrides.css.map +1 -0
  45. package/BookReader/hypothesis/build/styles/sidebar.css +4 -0
  46. package/BookReader/hypothesis/build/styles/sidebar.css.map +1 -0
  47. package/BookReader/hypothesis/build/styles/ui-playground.css +4 -0
  48. package/BookReader/hypothesis/build/styles/ui-playground.css.map +1 -0
  49. package/BookReader/hypothesis/package.json +126 -0
  50. package/BookReader/ia-bookreader.js +1886 -0
  51. package/BookReader/ia-bookreader.js.LICENSE.txt +78 -0
  52. package/BookReader/ia-bookreader.js.map +1 -0
  53. package/BookReader/icons/1up.svg +1 -0
  54. package/BookReader/icons/2up.svg +1 -0
  55. package/BookReader/icons/advance.svg +3 -0
  56. package/BookReader/icons/chevron-right.svg +1 -0
  57. package/BookReader/icons/close-circle-dark.svg +1 -0
  58. package/BookReader/icons/close-circle.svg +1 -0
  59. package/BookReader/icons/fullscreen.svg +1 -0
  60. package/BookReader/icons/fullscreen_exit.svg +1 -0
  61. package/BookReader/icons/hamburger.svg +1 -0
  62. package/BookReader/icons/left-arrow.svg +1 -0
  63. package/BookReader/icons/magnify-minus.svg +1 -0
  64. package/BookReader/icons/magnify-plus.svg +1 -0
  65. package/BookReader/icons/magnify.svg +1 -0
  66. package/BookReader/icons/pause.svg +1 -0
  67. package/BookReader/icons/play.svg +1 -0
  68. package/BookReader/icons/playback-speed.svg +1 -0
  69. package/BookReader/icons/read-aloud.svg +1 -0
  70. package/BookReader/icons/review.svg +3 -0
  71. package/BookReader/icons/slider-toggle.svg +1 -0
  72. package/BookReader/icons/thumbnails.svg +1 -0
  73. package/BookReader/icons/voice.svg +1 -0
  74. package/BookReader/icons/volume-full.svg +1 -0
  75. package/BookReader/images/BRicons.png +0 -0
  76. package/BookReader/images/BRicons.svg +5 -0
  77. package/BookReader/images/BRicons_ia.png +0 -0
  78. package/BookReader/images/back_pages.png +0 -0
  79. package/BookReader/images/book_bottom_icon.png +0 -0
  80. package/BookReader/images/book_down_icon.png +0 -0
  81. package/BookReader/images/book_left_icon.png +0 -0
  82. package/BookReader/images/book_leftmost_icon.png +0 -0
  83. package/BookReader/images/book_right_icon.png +0 -0
  84. package/BookReader/images/book_rightmost_icon.png +0 -0
  85. package/BookReader/images/book_top_icon.png +0 -0
  86. package/BookReader/images/book_up_icon.png +0 -0
  87. package/BookReader/images/books_graphic.svg +1 -0
  88. package/BookReader/images/booksplit.png +0 -0
  89. package/BookReader/images/control_pause_icon.png +0 -0
  90. package/BookReader/images/control_play_icon.png +0 -0
  91. package/BookReader/images/embed_icon.png +0 -0
  92. package/BookReader/images/hypothesis.ico +0 -0
  93. package/BookReader/images/icon-home-ia.png +0 -0
  94. package/BookReader/images/icon_OL-logo-xs.png +0 -0
  95. package/BookReader/images/icon_alert-xs.png +0 -0
  96. package/BookReader/images/icon_book.svg +1 -0
  97. package/BookReader/images/icon_bookmark.svg +1 -0
  98. package/BookReader/images/icon_close-pop.png +0 -0
  99. package/BookReader/images/icon_download.png +0 -0
  100. package/BookReader/images/icon_experiment.svg +1 -0
  101. package/BookReader/images/icon_gear.svg +1 -0
  102. package/BookReader/images/icon_hamburger.svg +1 -0
  103. package/BookReader/images/icon_home.png +0 -0
  104. package/BookReader/images/icon_home.svg +1 -0
  105. package/BookReader/images/icon_home_ia.png +0 -0
  106. package/BookReader/images/icon_indicator.png +0 -0
  107. package/BookReader/images/icon_info.svg +1 -0
  108. package/BookReader/images/icon_one_page.svg +1 -0
  109. package/BookReader/images/icon_pause.svg +1 -0
  110. package/BookReader/images/icon_play.svg +1 -0
  111. package/BookReader/images/icon_playback-rate.svg +1 -0
  112. package/BookReader/images/icon_return.png +0 -0
  113. package/BookReader/images/icon_search_button.svg +1 -0
  114. package/BookReader/images/icon_share.svg +1 -0
  115. package/BookReader/images/icon_skip-ahead.svg +1 -0
  116. package/BookReader/images/icon_skip-back.svg +2 -0
  117. package/BookReader/images/icon_speaker.svg +1 -0
  118. package/BookReader/images/icon_speaker_open.svg +1 -0
  119. package/BookReader/images/icon_thumbnails.svg +1 -0
  120. package/BookReader/images/icon_toc.svg +1 -0
  121. package/BookReader/images/icon_two_pages.svg +1 -0
  122. package/BookReader/images/icon_zoomer.png +0 -0
  123. package/BookReader/images/loading.gif +0 -0
  124. package/BookReader/images/logo_icon.png +0 -0
  125. package/BookReader/images/marker_chap-off.png +0 -0
  126. package/BookReader/images/marker_chap-off.svg +1 -0
  127. package/BookReader/images/marker_chap-off_ia.png +0 -0
  128. package/BookReader/images/marker_chap-on.png +0 -0
  129. package/BookReader/images/marker_chap-on.svg +1 -0
  130. package/BookReader/images/marker_srch-on.svg +1 -0
  131. package/BookReader/images/marker_srchchap-off.png +0 -0
  132. package/BookReader/images/marker_srchchap-on.png +0 -0
  133. package/BookReader/images/nav_control-dn.png +0 -0
  134. package/BookReader/images/nav_control-dn_ia.png +0 -0
  135. package/BookReader/images/nav_control-up.png +0 -0
  136. package/BookReader/images/nav_control-up_ia.png +0 -0
  137. package/BookReader/images/nav_control.png +0 -0
  138. package/BookReader/images/one_page_mode_icon.png +0 -0
  139. package/BookReader/images/paper-badge.png +0 -0
  140. package/BookReader/images/print_icon.png +0 -0
  141. package/BookReader/images/progressbar.gif +0 -0
  142. package/BookReader/images/right_edges.png +0 -0
  143. package/BookReader/images/slider.png +0 -0
  144. package/BookReader/images/slider_ia.png +0 -0
  145. package/BookReader/images/thumbnail_mode_icon.png +0 -0
  146. package/BookReader/images/translate.svg +1 -0
  147. package/BookReader/images/transparent.png +0 -0
  148. package/BookReader/images/two_page_mode_icon.png +0 -0
  149. package/BookReader/images/unviewable_page.png +0 -0
  150. package/BookReader/images/zoom_in_icon.png +0 -0
  151. package/BookReader/images/zoom_out_icon.png +0 -0
  152. package/BookReader/jquery-3.js +2 -0
  153. package/BookReader/jquery-3.js.LICENSE.txt +24 -0
  154. package/BookReader/plugins/plugin.archive_analytics.js +2 -0
  155. package/BookReader/plugins/plugin.archive_analytics.js.map +1 -0
  156. package/BookReader/plugins/plugin.autoplay.js +2 -0
  157. package/BookReader/plugins/plugin.autoplay.js.map +1 -0
  158. package/BookReader/plugins/plugin.chapters.js +23 -0
  159. package/BookReader/plugins/plugin.chapters.js.LICENSE.txt +1 -0
  160. package/BookReader/plugins/plugin.chapters.js.map +1 -0
  161. package/BookReader/plugins/plugin.experiments.js +3 -0
  162. package/BookReader/plugins/plugin.experiments.js.LICENSE.txt +1 -0
  163. package/BookReader/plugins/plugin.experiments.js.map +1 -0
  164. package/BookReader/plugins/plugin.iframe.js +2 -0
  165. package/BookReader/plugins/plugin.iframe.js.map +1 -0
  166. package/BookReader/plugins/plugin.iiif.js +2 -0
  167. package/BookReader/plugins/plugin.iiif.js.map +1 -0
  168. package/BookReader/plugins/plugin.resume.js +2 -0
  169. package/BookReader/plugins/plugin.resume.js.map +1 -0
  170. package/BookReader/plugins/plugin.search.js +3 -0
  171. package/BookReader/plugins/plugin.search.js.LICENSE.txt +1 -0
  172. package/BookReader/plugins/plugin.search.js.map +1 -0
  173. package/BookReader/plugins/plugin.text_selection.js +3 -0
  174. package/BookReader/plugins/plugin.text_selection.js.LICENSE.txt +1 -0
  175. package/BookReader/plugins/plugin.text_selection.js.map +1 -0
  176. package/BookReader/plugins/plugin.translate.js +3 -0
  177. package/BookReader/plugins/plugin.translate.js.LICENSE.txt +1 -0
  178. package/BookReader/plugins/plugin.translate.js.map +1 -0
  179. package/BookReader/plugins/plugin.tts.js +3 -0
  180. package/BookReader/plugins/plugin.tts.js.LICENSE.txt +29 -0
  181. package/BookReader/plugins/plugin.tts.js.map +1 -0
  182. package/BookReader/plugins/plugin.url.js +2 -0
  183. package/BookReader/plugins/plugin.url.js.map +1 -0
  184. package/BookReader/plugins/plugin.vendor-fullscreen.js +2 -0
  185. package/BookReader/plugins/plugin.vendor-fullscreen.js.map +1 -0
  186. package/BookReader/plugins/translator-worker.js +2 -0
  187. package/BookReader/plugins/translator-worker.js.map +1 -0
  188. package/BookReader/silence.mp3 +0 -0
  189. package/BookReader/translator-worker.js +475 -0
  190. package/BookReader/webcomponents-bundle.js +3 -0
  191. package/BookReader/webcomponents-bundle.js.LICENSE.txt +9 -0
  192. package/BookReader/webcomponents-bundle.js.map +1 -0
  193. package/dist/esm/ia-bookreader.js +3 -0
  194. package/dist/esm/ia-bookreader.js.LICENSE.txt +17 -0
  195. package/dist/esm/ia-bookreader.js.map +1 -0
  196. package/dist/esm/plugins/plugin.archive_analytics.js +2 -0
  197. package/dist/esm/plugins/plugin.archive_analytics.js.map +1 -0
  198. package/dist/esm/plugins/plugin.autoplay.js +2 -0
  199. package/dist/esm/plugins/plugin.autoplay.js.map +1 -0
  200. package/dist/esm/plugins/plugin.chapters.js +2 -0
  201. package/dist/esm/plugins/plugin.chapters.js.map +1 -0
  202. package/dist/esm/plugins/plugin.experiments.js +2 -0
  203. package/dist/esm/plugins/plugin.experiments.js.map +1 -0
  204. package/dist/esm/plugins/plugin.iframe.js +2 -0
  205. package/dist/esm/plugins/plugin.iframe.js.map +1 -0
  206. package/dist/esm/plugins/plugin.iiif.js +2 -0
  207. package/dist/esm/plugins/plugin.iiif.js.map +1 -0
  208. package/dist/esm/plugins/plugin.resume.js +2 -0
  209. package/dist/esm/plugins/plugin.resume.js.map +1 -0
  210. package/dist/esm/plugins/plugin.search.js +2 -0
  211. package/dist/esm/plugins/plugin.search.js.map +1 -0
  212. package/dist/esm/plugins/plugin.text_selection.js +2 -0
  213. package/dist/esm/plugins/plugin.text_selection.js.map +1 -0
  214. package/dist/esm/plugins/plugin.translate.js +2 -0
  215. package/dist/esm/plugins/plugin.translate.js.map +1 -0
  216. package/dist/esm/plugins/plugin.tts.js +2 -0
  217. package/dist/esm/plugins/plugin.tts.js.map +1 -0
  218. package/dist/esm/plugins/plugin.url.js +2 -0
  219. package/dist/esm/plugins/plugin.url.js.map +1 -0
  220. package/dist/esm/plugins/plugin.vendor-fullscreen.js +2 -0
  221. package/dist/esm/plugins/plugin.vendor-fullscreen.js.map +1 -0
  222. package/package.json +19 -13
  223. package/src/BookReader/Navbar/Navbar.js +8 -12
  224. package/src/BookReader/options.js +1 -1
  225. package/src/BookReader/utils/SelectionObserver.js +19 -2
  226. package/src/ia-bookreader/ia-bookreader.js +12 -3
  227. package/src/plugins/search/view.js +1 -1
  228. package/src/plugins/translate/plugin.translate.js +3 -2
  229. package/src/plugins/tts/PageChunk.js +92 -10
  230. package/src/plugins/tts/plugin.tts.js +0 -24
  231. package/src/plugins/url/UrlPlugin.js +4 -1
  232. package/src/plugins/url/plugin.url.js +4 -1
@@ -242,8 +242,9 @@ export class TranslatePlugin extends BookReaderPlugin {
242
242
  }
243
243
 
244
244
  clearAllTranslations() {
245
- document.querySelectorAll('.BRtranslateLayer').forEach(el => el.remove());
246
- document.querySelectorAll('.showingTranslation').forEach(el => el.classList.remove('showingTranslation'));
245
+ const brEl = this.br.refs.$br[0];
246
+ brEl.querySelectorAll('.BRtranslateLayer').forEach(el => el.remove());
247
+ brEl.querySelectorAll('.showingTranslation').forEach(el => el.classList.remove('showingTranslation'));
247
248
  }
248
249
 
249
250
  /**
@@ -1,5 +1,10 @@
1
1
  import { applyVariables } from "../../util/strings.js";
2
2
 
3
+ /** A chunk ends at the first sentence end after this many words */
4
+ const MIN_WORDS_IN_CHUNK = 25;
5
+ /** A chunk with no sentence end is cut at the first line end after this many words */
6
+ const MAX_WORDS_IN_CHUNK = 50;
7
+
3
8
  /**
4
9
  * Class to manage a 'chunk' (approximately a paragraph) of text on a page.
5
10
  */
@@ -40,16 +45,38 @@ export default class PageChunk {
40
45
  pageChunks.push(placeholder);
41
46
  }
42
47
  return pageChunks;
43
- } else {
44
- const chunks = await $.ajax({
45
- type: 'GET',
46
- url: applyVariables(pageChunkUrl, { pageIndex: leafIndex }),
47
- cache: true,
48
- xhrFields: {
49
- withCredentials: window.br.protected,
50
- },
51
- });
52
- return PageChunk._fromTextWrapperResponse(leafIndex, chunks);
48
+ }
49
+
50
+ const ocrPage = await PageChunk._getTextSelectionOcrPage(leafIndex);
51
+ if (ocrPage) {
52
+ return PageChunk._fromTextWrapperResponse(leafIndex, PageChunk._chunkOcrPage(ocrPage));
53
+ }
54
+
55
+ const chunks = await $.ajax({
56
+ type: 'GET',
57
+ url: applyVariables(pageChunkUrl, { pageIndex: leafIndex }),
58
+ cache: true,
59
+ xhrFields: {
60
+ withCredentials: window.br.protected,
61
+ },
62
+ });
63
+ return PageChunk._fromTextWrapperResponse(leafIndex, chunks);
64
+ }
65
+
66
+ /**
67
+ * The text selection plugin's OCR for the page, if it has any. It's cached
68
+ * and shared with the text layer, so using it avoids requesting the page's
69
+ * text a second time.
70
+ * @param {number} leafIndex
71
+ * @return {Promise<Element | undefined>}
72
+ */
73
+ static async _getTextSelectionOcrPage(leafIndex) {
74
+ const textSelection = window.br.plugins.textSelection;
75
+ if (!textSelection?.options.enabled) return undefined;
76
+ try {
77
+ return await textSelection.getPageText(leafIndex);
78
+ } catch (e) {
79
+ return undefined;
53
80
  }
54
81
  }
55
82
 
@@ -67,6 +94,61 @@ export default class PageChunk {
67
94
  });
68
95
  }
69
96
 
97
+ /**
98
+ * Split a page of djvu xml OCR into roughly paragraph-sized chunks, in the
99
+ * same shape as BookReaderGetTextWrapper.php's response: each chunk is its
100
+ * text followed by a box per line (or part of a line) it covers. Running
101
+ * headers/footers are skipped.
102
+ * @param {Element} ocrPage djvu xml `OBJECT` element
103
+ * @return {Array<[String, ...DJVURect[]]>}
104
+ */
105
+ static _chunkOcrPage(ocrPage) {
106
+ /** @type {Array<[String, ...DJVURect[]]>} */
107
+ const chunks = [];
108
+ /** @type {string[]} */
109
+ let words = [];
110
+ /** @type {DJVURect[]} */
111
+ let rects = [];
112
+ /** @type {DJVURect | null} bounds of the current line's words in this chunk */
113
+ let lineRect = null;
114
+
115
+ const endChunk = () => {
116
+ if (lineRect) rects.push(lineRect);
117
+ chunks.push([words.join(' '), ...rects]);
118
+ words = [];
119
+ rects = [];
120
+ lineRect = null;
121
+ };
122
+
123
+ for (const line of ocrPage.querySelectorAll('LINE')) {
124
+ if (line.closest('PARAGRAPH')?.getAttribute('x-role') === 'header-footer') continue;
125
+
126
+ for (const word of line.querySelectorAll('WORD')) {
127
+ const [left, bottom, right, top] = (word.getAttribute('coords') ?? '').split(',').map(parseFloat);
128
+ const text = word.textContent.trim();
129
+ // Same words the text layer drops as unpositionable
130
+ if (!text || isNaN(top) || (left === 0 && top === 0)) continue;
131
+
132
+ lineRect = lineRect ? [
133
+ Math.min(lineRect[0], left),
134
+ Math.max(lineRect[1], bottom),
135
+ Math.max(lineRect[2], right),
136
+ Math.min(lineRect[3], top),
137
+ ] : [left, bottom, right, top];
138
+ words.push(text);
139
+
140
+ if (text.endsWith('.') && words.length > MIN_WORDS_IN_CHUNK) endChunk();
141
+ }
142
+
143
+ if (lineRect) rects.push(lineRect);
144
+ lineRect = null;
145
+ if (words.length > MAX_WORDS_IN_CHUNK) endChunk();
146
+ }
147
+
148
+ if (words.length) endChunk();
149
+ return chunks;
150
+ }
151
+
70
152
  /**
71
153
  * @private
72
154
  * Sometimes the first rectangle will be ridiculously wide/tall. Find those and fix them
@@ -5,7 +5,6 @@ import WebTTSEngine from './WebTTSEngine.js';
5
5
  import { toISO6391 } from './utils.js';
6
6
  import { en as tooltips } from './tooltip_dict.js';
7
7
  import { renderBoxesInPageContainerLayer } from '../../BookReader/PageContainer.js';
8
- import { throttle } from '../../BookReader/utils.js';
9
8
  import { BookReaderPlugin } from '../../BookReaderPlugin.js';
10
9
  import { applyVariables, countWords } from '../../util/strings.js';
11
10
  /** @typedef {import('./PageChunk.js').default} PageChunk */
@@ -73,10 +72,6 @@ export class TtsPlugin extends BookReaderPlugin {
73
72
  festivalUrl: applyVariables(this.options.remoteTtsUrl, this.br.options.vars),
74
73
  } : {}),
75
74
  });
76
-
77
- // Resuming picks up inside the current chunk, so it would otherwise wait for the
78
- // next one to register as activity.
79
- this.ttsEngine.events.on('resume', this.signalUserIsActive);
80
75
  }
81
76
  }
82
77
 
@@ -282,30 +277,11 @@ export class TtsPlugin extends BookReaderPlugin {
282
277
  this.br.removeProgressPopup();
283
278
  }
284
279
 
285
- /**
286
- * Tell the lending code the patron is still here.
287
- *
288
- * `userAction` is how ia-book-actions decides a browse loan is still in use, but it
289
- * is otherwise only triggered by an index change (see BookReader.prototype
290
- * .updateFirstIndex) or a navbar click. Read aloud holds someone's attention without
291
- * either: in 2up the engine reads both pages before it flips, so a spread can easily
292
- * outlast the window the loan renewal allows, and a listener would have their loan
293
- * auto-returned mid-playback. Driving the signal off chunk playback instead ties it
294
- * to actual progress through the book.
295
- *
296
- * Throttled because chunks are paragraphs -- short ones would otherwise signal every
297
- * few seconds, and the renewal only cares about minutes.
298
- */
299
- signalUserIsActive = throttle(() => {
300
- this.br.trigger(BookReader.eventNames.userAction);
301
- }, 60000, false);
302
-
303
280
  /**
304
281
  * @param {PageChunk} chunk
305
282
  * Returns once the flip is done
306
283
  */
307
284
  async beforeChunkPlay(chunk) {
308
- this.signalUserIsActive();
309
285
  await this.maybeFlipToIndex(chunk.leafIndex);
310
286
  this.highlightChunk(chunk);
311
287
  this.scrollToChunk(chunk);
@@ -163,7 +163,10 @@ export class UrlPlugin {
163
163
  }
164
164
 
165
165
  if (this.urlMode == 'hash') {
166
- window.location.replace('#' + concatenatedPath);
166
+ // Built from location.href so a <base href> on the page can't change
167
+ // the pathname, and replace() so page flips don't add history entries.
168
+ const [baseHref] = window.location.href.split('#');
169
+ window.location.replace(`${baseHref}#${concatenatedPath}`);
167
170
  }
168
171
  this.oldLocationHash = urlStrPath;
169
172
  }
@@ -173,7 +173,10 @@ BookReader.prototype.urlUpdateFragment = function() {
173
173
 
174
174
  if (this.options.urlMode === 'hash') {
175
175
  const newQueryStringSearch = this.urlParamsFiltersOnlySearch(this.readQueryString());
176
- window.location.replace('#' + newFragment + newQueryStringSearch);
176
+ // Built from location.href so a <base href> on the page can't change
177
+ // the pathname, and replace() so page flips don't add history entries.
178
+ const [baseHref] = window.location.href.split('#');
179
+ window.location.replace(`${baseHref}#${newFragment}${newQueryStringSearch}`);
177
180
  this.oldLocationHash = newFragment + newQueryStringSearch;
178
181
  }
179
182
  };