@internetarchive/bookreader 5.0.0-28-remove-url-defaults → 5.0.0-29

Sign up to get free protection for your applications and to get access to all the features.
Files changed (226) hide show
  1. package/.husky/_/husky.sh +30 -0
  2. package/BookReader/BookReader.css +1 -1
  3. package/BookReader/BookReader.js +1 -1
  4. package/BookReader/BookReader.js.map +1 -1
  5. package/BookReader/bookreader-component-bundle.js +570 -542
  6. package/BookReader/bookreader-component-bundle.js.LICENSE.txt +23 -0
  7. package/BookReader/bookreader-component-bundle.js.map +1 -1
  8. package/BookReader/plugins/plugin.search.js +1 -1
  9. package/BookReader/plugins/plugin.search.js.map +1 -1
  10. package/BookReaderDemo/BookReaderDemo.css +14 -1
  11. package/BookReaderDemo/IADemoBr.js +104 -0
  12. package/BookReaderDemo/demo-internetarchive.html +65 -98
  13. package/CHANGELOG.md +4 -0
  14. package/package.json +9 -6
  15. package/src/BookNavigator/assets/ia-logo.js +17 -0
  16. package/src/BookNavigator/book-navigator.js +521 -0
  17. package/src/BookNavigator/bookmarks/bookmark-button.js +2 -1
  18. package/src/BookNavigator/bookmarks/bookmarks-provider.js +20 -8
  19. package/src/BookNavigator/bookmarks/ia-bookmarks.js +84 -51
  20. package/src/BookNavigator/downloads/downloads-provider.js +5 -9
  21. package/src/BookNavigator/downloads/downloads.js +1 -0
  22. package/src/BookNavigator/search/search-provider.js +15 -8
  23. package/src/BookNavigator/sharing.js +27 -0
  24. package/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js +9 -8
  25. package/src/BookNavigator/volumes/volumes-provider.js +3 -4
  26. package/src/BookReader/options.js +6 -0
  27. package/src/BookReader.js +20 -8
  28. package/src/BookReaderComponent/BookReaderComponent.js +53 -32
  29. package/src/css/_BRComponent.scss +1 -1
  30. package/src/plugins/search/plugin.search.js +9 -9
  31. package/{src → stat}/BookNavigator/BookModel.js +0 -0
  32. package/{src → stat}/BookNavigator/BookNavigator.js +109 -102
  33. package/stat/BookNavigator/assets/bookmark-colors.js +15 -0
  34. package/stat/BookNavigator/assets/button-base.js +61 -0
  35. package/stat/BookNavigator/assets/ia-logo.js +17 -0
  36. package/stat/BookNavigator/assets/icon_checkmark.js +6 -0
  37. package/stat/BookNavigator/assets/icon_close.js +3 -0
  38. package/stat/BookNavigator/assets/icon_sort_asc.js +5 -0
  39. package/stat/BookNavigator/assets/icon_sort_desc.js +5 -0
  40. package/stat/BookNavigator/assets/icon_sort_neutral.js +5 -0
  41. package/stat/BookNavigator/assets/icon_volumes.js +11 -0
  42. package/stat/BookNavigator/bookmarks/bookmark-button.js +64 -0
  43. package/stat/BookNavigator/bookmarks/bookmark-edit.js +215 -0
  44. package/stat/BookNavigator/bookmarks/bookmarks-list.js +285 -0
  45. package/stat/BookNavigator/bookmarks/bookmarks-loginCTA.js +28 -0
  46. package/stat/BookNavigator/bookmarks/bookmarks-provider.js +56 -0
  47. package/stat/BookNavigator/bookmarks/ia-bookmarks.js +523 -0
  48. package/{src → stat}/BookNavigator/br-fullscreen-mgr.js +1 -2
  49. package/stat/BookNavigator/delete-modal-actions.js +49 -0
  50. package/stat/BookNavigator/downloads/downloads-provider.js +72 -0
  51. package/stat/BookNavigator/downloads/downloads.js +139 -0
  52. package/stat/BookNavigator/provider-config.js +0 -0
  53. package/stat/BookNavigator/search/a-search-result.js +55 -0
  54. package/stat/BookNavigator/search/search-provider.js +180 -0
  55. package/stat/BookNavigator/search/search-results.js +360 -0
  56. package/{src/ItemNavigator/providers → stat/BookNavigator}/sharing.js +3 -5
  57. package/stat/BookNavigator/visual-adjustments/visual-adjustments-provider.js +94 -0
  58. package/stat/BookNavigator/visual-adjustments/visual-adjustments.js +280 -0
  59. package/stat/BookNavigator/volumes/volumes-provider.js +83 -0
  60. package/stat/BookNavigator/volumes/volumes.js +178 -0
  61. package/stat/BookReader/BookModel.js +518 -0
  62. package/stat/BookReader/DebugConsole.js +54 -0
  63. package/stat/BookReader/DragScrollable.js +233 -0
  64. package/stat/BookReader/ImageCache.js +116 -0
  65. package/stat/BookReader/Mode1Up.js +102 -0
  66. package/stat/BookReader/Mode1UpLit.js +434 -0
  67. package/stat/BookReader/Mode2Up.js +1372 -0
  68. package/stat/BookReader/ModeSmoothZoom.js +177 -0
  69. package/stat/BookReader/ModeThumb.js +344 -0
  70. package/stat/BookReader/Navbar/Navbar.js +310 -0
  71. package/stat/BookReader/PageContainer.js +120 -0
  72. package/stat/BookReader/ReduceSet.js +26 -0
  73. package/stat/BookReader/Toolbar/Toolbar.js +384 -0
  74. package/stat/BookReader/events.js +20 -0
  75. package/stat/BookReader/options.js +324 -0
  76. package/stat/BookReader/utils/HTMLDimensionsCacher.js +44 -0
  77. package/stat/BookReader/utils/classes.js +36 -0
  78. package/stat/BookReader/utils.js +240 -0
  79. package/stat/BookReader.js +2550 -0
  80. package/stat/BookReaderComponent/BookReaderComponent.js +117 -0
  81. package/stat/assets/icons/1up.svg +12 -0
  82. package/stat/assets/icons/2up.svg +15 -0
  83. package/stat/assets/icons/advance.svg +26 -0
  84. package/stat/assets/icons/chevron-right.svg +1 -0
  85. package/stat/assets/icons/close-circle-dark.svg +1 -0
  86. package/stat/assets/icons/close-circle.svg +1 -0
  87. package/stat/assets/icons/fullscreen.svg +17 -0
  88. package/stat/assets/icons/fullscreen_exit.svg +17 -0
  89. package/stat/assets/icons/hamburger.svg +15 -0
  90. package/stat/assets/icons/left-arrow.svg +12 -0
  91. package/stat/assets/icons/magnify-minus.svg +16 -0
  92. package/stat/assets/icons/magnify-plus.svg +17 -0
  93. package/stat/assets/icons/magnify.svg +15 -0
  94. package/stat/assets/icons/pause.svg +23 -0
  95. package/stat/assets/icons/play.svg +22 -0
  96. package/stat/assets/icons/playback-speed.svg +34 -0
  97. package/stat/assets/icons/read-aloud.svg +22 -0
  98. package/stat/assets/icons/review.svg +22 -0
  99. package/stat/assets/icons/thumbnails.svg +17 -0
  100. package/stat/assets/icons/voice.svg +1 -0
  101. package/stat/assets/icons/volume-full.svg +22 -0
  102. package/stat/assets/images/BRicons.png +0 -0
  103. package/stat/assets/images/BRicons.svg +94 -0
  104. package/stat/assets/images/BRicons_ia.png +0 -0
  105. package/stat/assets/images/back_pages.png +0 -0
  106. package/stat/assets/images/book_bottom_icon.png +0 -0
  107. package/stat/assets/images/book_down_icon.png +0 -0
  108. package/stat/assets/images/book_left_icon.png +0 -0
  109. package/stat/assets/images/book_leftmost_icon.png +0 -0
  110. package/stat/assets/images/book_right_icon.png +0 -0
  111. package/stat/assets/images/book_rightmost_icon.png +0 -0
  112. package/stat/assets/images/book_top_icon.png +0 -0
  113. package/stat/assets/images/book_up_icon.png +0 -0
  114. package/stat/assets/images/books_graphic.svg +177 -0
  115. package/stat/assets/images/booksplit.png +0 -0
  116. package/stat/assets/images/control_pause_icon.png +0 -0
  117. package/stat/assets/images/control_play_icon.png +0 -0
  118. package/stat/assets/images/embed_icon.png +0 -0
  119. package/stat/assets/images/icon-home-ia.png +0 -0
  120. package/stat/assets/images/icon_OL-logo-xs.png +0 -0
  121. package/stat/assets/images/icon_alert-xs.png +0 -0
  122. package/stat/assets/images/icon_book.svg +12 -0
  123. package/stat/assets/images/icon_bookmark.svg +12 -0
  124. package/stat/assets/images/icon_close-pop.png +0 -0
  125. package/stat/assets/images/icon_download.png +0 -0
  126. package/stat/assets/images/icon_gear.svg +14 -0
  127. package/stat/assets/images/icon_hamburger.svg +20 -0
  128. package/stat/assets/images/icon_home.png +0 -0
  129. package/stat/assets/images/icon_home.svg +21 -0
  130. package/stat/assets/images/icon_home_ia.png +0 -0
  131. package/stat/assets/images/icon_indicator.png +0 -0
  132. package/stat/assets/images/icon_info.svg +11 -0
  133. package/stat/assets/images/icon_one_page.svg +8 -0
  134. package/stat/assets/images/icon_pause.svg +1 -0
  135. package/stat/assets/images/icon_play.svg +1 -0
  136. package/stat/assets/images/icon_playback-rate.svg +15 -0
  137. package/stat/assets/images/icon_return.png +0 -0
  138. package/stat/assets/images/icon_search_button.svg +8 -0
  139. package/stat/assets/images/icon_share.svg +9 -0
  140. package/stat/assets/images/icon_skip-ahead.svg +6 -0
  141. package/stat/assets/images/icon_skip-back.svg +13 -0
  142. package/stat/assets/images/icon_speaker.svg +18 -0
  143. package/stat/assets/images/icon_speaker_open.svg +10 -0
  144. package/stat/assets/images/icon_thumbnails.svg +12 -0
  145. package/stat/assets/images/icon_toc.svg +5 -0
  146. package/stat/assets/images/icon_two_pages.svg +9 -0
  147. package/stat/assets/images/icon_zoomer.png +0 -0
  148. package/stat/assets/images/loading.gif +0 -0
  149. package/stat/assets/images/logo_icon.png +0 -0
  150. package/stat/assets/images/marker_chap-off.png +0 -0
  151. package/stat/assets/images/marker_chap-off.svg +11 -0
  152. package/stat/assets/images/marker_chap-off_ia.png +0 -0
  153. package/stat/assets/images/marker_chap-on.png +0 -0
  154. package/stat/assets/images/marker_chap-on.svg +11 -0
  155. package/stat/assets/images/marker_srch-on.svg +11 -0
  156. package/stat/assets/images/marker_srchchap-off.png +0 -0
  157. package/stat/assets/images/marker_srchchap-on.png +0 -0
  158. package/stat/assets/images/nav_control-dn.png +0 -0
  159. package/stat/assets/images/nav_control-dn_ia.png +0 -0
  160. package/stat/assets/images/nav_control-up.png +0 -0
  161. package/stat/assets/images/nav_control-up_ia.png +0 -0
  162. package/stat/assets/images/nav_control.png +0 -0
  163. package/stat/assets/images/one_page_mode_icon.png +0 -0
  164. package/stat/assets/images/paper-badge.png +0 -0
  165. package/stat/assets/images/print_icon.png +0 -0
  166. package/stat/assets/images/progressbar.gif +0 -0
  167. package/stat/assets/images/right_edges.png +0 -0
  168. package/stat/assets/images/slider.png +0 -0
  169. package/stat/assets/images/slider_ia.png +0 -0
  170. package/stat/assets/images/thumbnail_mode_icon.png +0 -0
  171. package/stat/assets/images/transparent.png +0 -0
  172. package/stat/assets/images/two_page_mode_icon.png +0 -0
  173. package/stat/assets/images/zoom_in_icon.png +0 -0
  174. package/stat/assets/images/zoom_out_icon.png +0 -0
  175. package/stat/css/BookReader.scss +89 -0
  176. package/stat/css/_BRBookmarks.scss +29 -0
  177. package/stat/css/_BRComponent.scss +13 -0
  178. package/stat/css/_BRfloat.scss +197 -0
  179. package/stat/css/_BRicon.scss +48 -0
  180. package/stat/css/_BRmain.scss +251 -0
  181. package/stat/css/_BRnav.scss +359 -0
  182. package/stat/css/_BRpages.scss +139 -0
  183. package/stat/css/_BRsearch.scss +226 -0
  184. package/stat/css/_BRtoolbar.scss +84 -0
  185. package/stat/css/_BRvendor.scss +5 -0
  186. package/stat/css/_MobileNav.scss +194 -0
  187. package/stat/css/_TextSelection.scss +32 -0
  188. package/stat/css/_colorbox.scss +52 -0
  189. package/stat/css/_controls.scss +253 -0
  190. package/stat/css/_icons.scss +121 -0
  191. package/stat/jquery-wrapper.js +4 -0
  192. package/stat/plugins/plugin.archive_analytics.js +86 -0
  193. package/stat/plugins/plugin.autoplay.js +129 -0
  194. package/stat/plugins/plugin.chapters.js +248 -0
  195. package/stat/plugins/plugin.iframe.js +48 -0
  196. package/stat/plugins/plugin.mobile_nav.js +288 -0
  197. package/stat/plugins/plugin.resume.js +68 -0
  198. package/stat/plugins/plugin.text_selection.js +291 -0
  199. package/stat/plugins/plugin.url.js +198 -0
  200. package/stat/plugins/plugin.vendor-fullscreen.js +247 -0
  201. package/stat/plugins/search/plugin.search.js +439 -0
  202. package/stat/plugins/search/view.js +439 -0
  203. package/stat/plugins/tts/AbstractTTSEngine.js +249 -0
  204. package/stat/plugins/tts/FestivalTTSEngine.js +169 -0
  205. package/stat/plugins/tts/PageChunk.js +107 -0
  206. package/stat/plugins/tts/PageChunkIterator.js +163 -0
  207. package/stat/plugins/tts/WebTTSEngine.js +357 -0
  208. package/stat/plugins/tts/plugin.tts.js +357 -0
  209. package/stat/plugins/tts/tooltip_dict.js +15 -0
  210. package/stat/plugins/tts/utils.js +91 -0
  211. package/stat/util/browserSniffing.js +30 -0
  212. package/stat/util/debouncer.js +26 -0
  213. package/stat/util/docCookies.js +67 -0
  214. package/stat/util/strings.js +34 -0
  215. package/tests/e2e/viewmode.test.js +30 -30
  216. package/tests/jest/BookReader/BookReaderPublicFunctions.test.js +64 -52
  217. package/tests/karma/BookNavigator/book-navigator.test.js +413 -108
  218. package/tests/karma/BookNavigator/bookmarks/bookmark-button.test.js +44 -0
  219. package/tests/karma/BookNavigator/downloads/downloads-provider.test.js +6 -3
  220. package/tests/karma/BookNavigator/search/search-provider.test.js +106 -6
  221. package/tests/karma/BookNavigator/search/search-results.test.js +0 -2
  222. package/tests/karma/BookNavigator/sharing/sharing-provider.test.js +29 -20
  223. package/tests/karma/BookNavigator/volumes/volumes-provider.test.js +41 -17
  224. package/.nvmrc +0 -1
  225. package/src/BookNavigator/assets/book-loader.js +0 -27
  226. package/src/ItemNavigator/ItemNavigator.js +0 -377
@@ -0,0 +1,248 @@
1
+ /* global BookReader */
2
+ /**
3
+ * Plugin for chapter markers in BookReader. Fetches from openlibrary.org
4
+ * Could be forked, or extended to alter behavior
5
+ */
6
+
7
+ jQuery.extend(BookReader.defaultOptions, {
8
+ olHost: 'https://openlibrary.org',
9
+ enableChaptersPlugin: true,
10
+ bookId: '',
11
+ });
12
+
13
+ /** @override Extend the constructor to add search properties */
14
+ BookReader.prototype.setup = (function (super_) {
15
+ return function (options) {
16
+ super_.call(this, options);
17
+
18
+ this.olHost = options.olHost;
19
+ this.enableChaptersPlugin = options.enableChaptersPlugin;
20
+ this.bookId = options.bookId;
21
+ };
22
+ })(BookReader.prototype.setup);
23
+
24
+ /** @override Extend to call Open Library for TOC */
25
+ BookReader.prototype.init = (function(super_) {
26
+ return function() {
27
+ super_.call(this);
28
+ if (this.enableChaptersPlugin && this.ui !== 'embed') {
29
+ this.getOpenLibraryRecord();
30
+ }
31
+ if (this.enableMobileNav) {
32
+ this.bind(BookReader.eventNames.mobileNavOpen,
33
+ () => {
34
+ this.updateTOCState(this.firstIndex, this._tocEntries);
35
+ if ($('table-contents-list').parent().hasClass('mm-opened')) {
36
+ this.updateTOCState(this.firstIndex, this._tocEntries);
37
+ }
38
+ }
39
+ );
40
+ $(".BRmobileMenu__tableContents").on("click", () => {
41
+ this.updateTOCState(this.firstIndex, this._tocEntries);
42
+ });
43
+ }
44
+ };
45
+ })(BookReader.prototype.init);
46
+
47
+ /**
48
+ * Adds chapter marker to navigation scrubber
49
+ *
50
+ * @param {string} chapterTitle
51
+ * @param {string} pageNumber
52
+ * @param {number} pageIndex
53
+ */
54
+ BookReader.prototype.addChapter = function(chapterTitle, pageNumber, pageIndex) {
55
+ const uiStringPage = 'Page'; // i18n
56
+ const percentThrough = BookReader.util.cssPercentage(pageIndex, this.getNumLeafs() - 1);
57
+ const jumpToChapter = (event) => {
58
+ this.jumpToIndex($(event.delegateTarget).data('pageIndex'));
59
+ $('.current-chapter').removeClass('current-chapter');
60
+ $(event.delegateTarget).addClass('current-chapter');
61
+ };
62
+ const title = `${chapterTitle} | `;
63
+ const pageStr = `${uiStringPage} ${pageNumber}`;
64
+
65
+ //adding items to mobile table of contents
66
+ const mobileChapter = $(`<li></li>`).append($(`<span class='BRTOCElementTitle'></span>`).text(title))
67
+ .append($(`<span class='BRTOCElementPage'></span>`).text(pageStr));
68
+ mobileChapter.addClass('BRtable-contents-el')
69
+ .appendTo(this.$('.table-contents-list'))
70
+ .data({ pageIndex });
71
+
72
+ //adds .BRchapters to the slider only if pageIndex exists
73
+ if (pageIndex != undefined) {
74
+ $(`<div></div>`)
75
+ .append($('<div />').text(title + pageStr))
76
+ .addClass('BRchapter')
77
+ .css({ left: percentThrough })
78
+ .appendTo(this.$('.BRnavline'))
79
+ .data({ pageIndex })
80
+ .on("mouseenter", event => {
81
+ // remove hover effect from other markers then turn on just for this
82
+ const marker = event.currentTarget;
83
+ const tooltip = marker.querySelector('div');
84
+ const tooltipOffset = tooltip.getBoundingClientRect();
85
+ const targetOffset = marker.getBoundingClientRect();
86
+ const boxSizeAdjust = parseInt(getComputedStyle(tooltip).paddingLeft) * 2;
87
+ if (tooltipOffset.x - boxSizeAdjust < 0) {
88
+ tooltip.style.setProperty('transform', `translateX(-${targetOffset.left - boxSizeAdjust}px)`);
89
+ }
90
+ this.$('.BRsearch,.BRchapter').removeClass('front');
91
+ $(event.target).addClass('front');
92
+ })
93
+ .on("mouseleave", event => $(event.target).removeClass('front'))
94
+ .on('click', jumpToChapter);
95
+
96
+ //adding clickable properties to mobile chapters
97
+ mobileChapter.bind('click', jumpToChapter)
98
+ .addClass('chapter-clickable')
99
+ .attr("data-event-click-tracking","BRTOCPanel|GoToChapter");
100
+ }
101
+
102
+ };
103
+
104
+ /*
105
+ * Remove all chapters.
106
+ */
107
+ BookReader.prototype.removeChapters = function() {
108
+ this.$('.BRnavpos .BRchapter').remove();
109
+ };
110
+
111
+ /**
112
+ * Update the table of contents based on array of TOC entries.
113
+ * @param {TocEntry[]} tocEntries
114
+ */
115
+ BookReader.prototype.updateTOC = function(tocEntries) {
116
+ this.removeChapters();
117
+ if (this.enableMobileNav && tocEntries.length > 0) {
118
+ this.$(".BRmobileMenu__tableContents").show();
119
+ }
120
+ for (let i = 0; i < tocEntries.length; i++) {
121
+ this.addChapterFromEntry(tocEntries[i]);
122
+ }
123
+ this._tocEntries = tocEntries;
124
+ $('.table-contents-list').children().each((i, el) => {
125
+ tocEntries[i].mobileHTML = el;
126
+ });
127
+ };
128
+
129
+ /**
130
+ * @typedef {Object} TocEntry
131
+ * Table of contents entry as defined -- format is defined by Open Library
132
+ * @property {string} pagenum
133
+ * @property {number} level
134
+ * @property {string} label
135
+ * @property {{type: '/type/toc_item'}} type
136
+ * @property {string} title
137
+ * @property {HTMLElement} mobileHTML
138
+ * @property {number} pageIndex
139
+
140
+ *
141
+ * @example {
142
+ * "pagenum": "17",
143
+ * "level": 1,
144
+ * "label": "CHAPTER I",
145
+ * "type": {"key": "/type/toc_item"},
146
+ * "title": "THE COUNTRY AND THE MISSION"
147
+ * }
148
+ */
149
+
150
+ /**
151
+ * @param {TocEntry} tocEntryObject
152
+ */
153
+ BookReader.prototype.addChapterFromEntry = function(tocEntryObject) {
154
+ tocEntryObject.pageIndex = this.getPageIndex(tocEntryObject['pagenum']);
155
+ //creates a string with non-void tocEntryObject.label and tocEntryObject.title
156
+ const chapterStr = [tocEntryObject.label, tocEntryObject.title]
157
+ .filter(x => x)
158
+ .join(' ');
159
+ this.addChapter(chapterStr, tocEntryObject['pagenum'], tocEntryObject.pageIndex);
160
+ this.$('.BRchapter, .BRsearch').each((i, el) => {
161
+ const $el = $(el);
162
+ $el
163
+ .on("mouseenter", () => $el.addClass('front'))
164
+ .on("mouseleave", () => $el.removeClass('front'));
165
+ });
166
+ };
167
+
168
+ /**
169
+ * getOpenLibraryRecord
170
+ *
171
+ * The bookreader is designed to call openlibrary API and constructs the
172
+ * "Return book" button using the response.
173
+ *
174
+ * This makes a call to OL API and calls the given callback function with the
175
+ * response from the API.
176
+ */
177
+ BookReader.prototype.getOpenLibraryRecord = function () {
178
+ // Try looking up by ocaid first, then by source_record
179
+ const baseURL = `${this.olHost}/query.json?type=/type/edition&*=`;
180
+ const fetchUrlByBookId = `${baseURL}&ocaid=${this.bookId}`;
181
+
182
+ /*
183
+ * Update Chapter markers based on received record from Open Library.
184
+ * Notes that Open Library record is used for extra metadata, and also for lending
185
+ */
186
+ const setUpChapterMarkers = (olObject) => {
187
+ if (olObject && olObject.table_of_contents) {
188
+ // XXX check here that TOC is valid
189
+ this.updateTOC(olObject.table_of_contents);
190
+ }
191
+ };
192
+
193
+ $.ajax({ url: fetchUrlByBookId, dataType: 'jsonp' })
194
+ .then(data => {
195
+ if (data && data.length > 0) {
196
+ return data;
197
+ } else {
198
+ // try sourceid
199
+ return $.ajax({ url: `${baseURL}&source_records=ia:${this.bookId}`, dataType: 'jsonp' });
200
+ }
201
+ })
202
+ .then(data => {
203
+ if (data && data.length > 0) {
204
+ setUpChapterMarkers(data[0]);
205
+ }
206
+ });
207
+ };
208
+
209
+ // Extend buildMobileDrawerElement with table of contents list
210
+ BookReader.prototype.buildMobileDrawerElement = (function (super_) {
211
+ return function () {
212
+ const $el = super_.call(this);
213
+ if (this.enableMobileNav && this.options.enableChaptersPlugin) {
214
+ $el.find('.BRmobileMenu__moreInfoRow').after($(`
215
+ <li class="BRmobileMenu__tableContents" data-event-click-tracking="BRSidebar|TOCPanel">
216
+ <span>
217
+ <span class="DrawerIconWrapper">
218
+ <img class="DrawerIcon" src="${this.imagesBaseURL}icon_toc.svg" alt="toc-icon"/>
219
+ </span>
220
+ Table of Contents
221
+ </span>
222
+ <div>
223
+ <ol class="table-contents-list">
224
+ </ol>
225
+ </div>
226
+ </li>`).hide());
227
+ }
228
+ return $el;
229
+ };
230
+ })(BookReader.prototype.buildMobileDrawerElement);
231
+
232
+ /**
233
+ * highlights the current chapter based on current page
234
+ * @private
235
+ * @param {TocEntry[]} tocEntries
236
+ * @param {number} tocEntries
237
+ */
238
+ BookReader.prototype.updateTOCState = function(currIndex, tocEntries) {
239
+ //this function won't have any effects if called before OpenLibrary request is finished
240
+ if (!tocEntries) {return;}
241
+ $('.current-chapter').removeClass('current-chapter');
242
+ const tocEntriesIndexed = tocEntries.filter((el) => el.pageIndex != undefined).reverse();
243
+ const currChapter = tocEntriesIndexed[tocEntriesIndexed.findIndex(
244
+ (el) => el.pageIndex <= currIndex)];
245
+ if (currChapter != undefined) {
246
+ $(currChapter.mobileHTML).addClass('current-chapter');
247
+ }
248
+ };
@@ -0,0 +1,48 @@
1
+ /* global BookReader */
2
+ /**
3
+ * Plugin for two-way communication between a BookReader in an IFrame and the
4
+ * parent web page
5
+ */
6
+
7
+ const MESSAGE_TYPE_FRAGMENT_CHANGE = 'bookReaderFragmentChange';
8
+
9
+ BookReader.prototype.init = (function (super_) {
10
+ return function () {
11
+ super_.call(this);
12
+ _attachEventListeners(this);
13
+ };
14
+ })(BookReader.prototype.init);
15
+
16
+ /**
17
+ * @private
18
+ * Using window.postMessage() and event listeners, the plugin notifies the
19
+ * parent window when pages change, and the parent window can also
20
+ * explicitly request a page change by sending its own message.
21
+ *
22
+ * @param {BookReader} br
23
+ * @param {Window?} [parent]
24
+ */
25
+ export function _attachEventListeners(br, parent = window.parent) {
26
+ // Not embedded, abort
27
+ if (!parent) {
28
+ return;
29
+ }
30
+
31
+ br.bind(BookReader.eventNames.fragmentChange, () => {
32
+ const fragment = br.fragmentFromParams(br.paramsFromCurrent());
33
+
34
+ parent.postMessage(
35
+ { type: MESSAGE_TYPE_FRAGMENT_CHANGE, fragment },
36
+ '*'
37
+ );
38
+ });
39
+
40
+ window.addEventListener('message', event => {
41
+ // Not a recognized message type, abort
42
+ if (!event.data || event.data.type !== MESSAGE_TYPE_FRAGMENT_CHANGE) {
43
+ return;
44
+ }
45
+
46
+ br.updateFromParams(br.paramsFromFragment(event.data.fragment));
47
+ });
48
+ }
@@ -0,0 +1,288 @@
1
+ /* global BookReader */
2
+ /**
3
+ * Adds mobile navigation at responsive breakpoint
4
+ */
5
+
6
+ import * as utils from '../BookReader/utils.js';
7
+ import 'jquery.mmenu/dist/js/jquery.mmenu.min.js';
8
+ import 'jquery.mmenu/dist/addons/navbars/jquery.mmenu.navbars.min.js';
9
+
10
+ //contains all filters and labels for checkboxs
11
+ const FILTERLIST = [
12
+ {
13
+ filter: "grayscale(100%)",
14
+ label: "Grayscale"
15
+ },
16
+ {
17
+ filter: "brightness(120%)",
18
+ label: "High brightness"
19
+ },
20
+ {
21
+ filter: "invert(100%)",
22
+ label: "Inverted (dark mode)"
23
+ },
24
+ {
25
+ filter: "contrast(120%)",
26
+ label: "High contrast"
27
+ },
28
+ ];
29
+
30
+ jQuery.extend(BookReader.defaultOptions, {
31
+ enableMobileNav: true,
32
+ mobileNavTitle: 'Internet Archive',
33
+ mobileNavFullscreenOnly: false,
34
+ });
35
+
36
+ BookReader.prototype.setup = (function(super_) {
37
+ return function (options) {
38
+ super_.call(this, options);
39
+
40
+ this.enableMobileNav = options.enableMobileNav;
41
+ this.mobileNavTitle = options.mobileNavTitle;
42
+ this.mobileNavFullscreenOnly = options.mobileNavFullscreenOnly;
43
+
44
+ this.refs.$mmenu = null;
45
+ };
46
+ })(BookReader.prototype.setup);
47
+
48
+
49
+ // Extend initToolbar
50
+ BookReader.prototype.initToolbar = (function (super_) {
51
+ return function (mode, ui) {
52
+ let $mmenuEl;
53
+ if (this.enableMobileNav) {
54
+ const $drawerEl = this.buildMobileDrawerElement();
55
+ this.refs.$br.append($drawerEl);
56
+
57
+ // Render info into mobile info before mmenu
58
+ this.buildInfoDiv(this.$('.BRmobileInfo'));
59
+ this.buildShareDiv(this.$('.BRmobileShare'));
60
+
61
+ $mmenuEl = $drawerEl;
62
+ $mmenuEl.mmenu({
63
+ navbars: [
64
+ { "position": "top" },
65
+ ],
66
+ navbar: {
67
+ add: true,
68
+ title: this.mobileNavTitle,
69
+ titleLink: 'panel'
70
+ },
71
+ extensions: [ "panelshadow" ],
72
+ }, {
73
+ offCanvas: {
74
+ wrapPageIfNeeded: false,
75
+ zposition: 'next',
76
+ pageSelector: this.el,
77
+ }
78
+ });
79
+
80
+ const $BRpageviewField = $mmenuEl.find('.BRpageviewValue');
81
+ $mmenuEl.data('mmenu').bind('opened', () => {
82
+ // Update "Link to this page view" link
83
+ if ($BRpageviewField.length) {
84
+ $BRpageviewField.val(window.location.href);
85
+ }
86
+ });
87
+
88
+ //apply filters when checkboxs clicked
89
+ $drawerEl.find('.BRcheckbox-filters')
90
+ .on("click", () => applyFilters($drawerEl, this));
91
+
92
+ // Bind mobile switch buttons
93
+ $drawerEl.find('.DrawerLayoutButton.one_page_mode')
94
+ .on("click", () => this.switchMode(this.constMode1up));
95
+ $drawerEl.find('.DrawerLayoutButton.two_page_mode')
96
+ .on("click", () => this.switchMode(this.constMode2up));
97
+ $drawerEl.find('.DrawerLayoutButton.thumbnail_mode')
98
+ .on("click", () => this.switchMode(this.constModeThumb));
99
+
100
+ if (this.mobileNavFullscreenOnly) {
101
+ $(document.body).addClass('BRbodyMobileNavEnabledFullscreen');
102
+ } else {
103
+ $(document.body).addClass('BRbodyMobileNavEnabled');
104
+ }
105
+
106
+ this.refs.$mmenu = $mmenuEl;
107
+
108
+ }
109
+
110
+ // Call the parent method at the end, because it binds events to DOM
111
+ super_.apply(this, arguments);
112
+
113
+
114
+ if (this.enableMobileNav) {
115
+ // Need to bind more, console after toolbar is initialized
116
+ this.$('.BRmobileHamburger').click(() => {
117
+ if ($mmenuEl.data('mmenu').getInstance().vars.opened) {
118
+ $mmenuEl.data('mmenu').close();
119
+ } else {
120
+ $mmenuEl.data('mmenu').open();
121
+ this.trigger("mobileNavOpen");
122
+ }
123
+ });
124
+
125
+
126
+ const closeMobileMenu = (e) => {
127
+ // Need to close the mobile menu to reset DOM & Style
128
+ // driven by menu plugin
129
+ const width = $( window ).width();
130
+ const mobileMenuIsOpen = $mmenuEl.data('mmenu').getInstance().vars.opened;
131
+ // $brBreakPointMobile: 800px;
132
+ if (mobileMenuIsOpen && (width >= 800)) {
133
+ $mmenuEl.data('mmenu').close ();
134
+ }
135
+ };
136
+
137
+ window.addEventListener('resize', utils.debounce(closeMobileMenu, 900));
138
+ }
139
+ };
140
+ })(BookReader.prototype.initToolbar);
141
+
142
+
143
+ BookReader.prototype.buildToolbarElement = (function (super_) {
144
+ return function () {
145
+ const $el = super_.call(this);
146
+ if (this.enableMobileNav) {
147
+ const escapedTitle = BookReader.util.escapeHTML(this.bookTitle);
148
+ const toolbar = `
149
+ <span class="BRmobileHamburgerWrapper">
150
+ <button class="BRmobileHamburger"></button>
151
+ <span class="BRtoolbarMobileTitle" title="${escapedTitle}">${escapedTitle}</span>
152
+ </span>
153
+ `;
154
+ $el
155
+ .addClass('responsive')
156
+ .prepend($(toolbar));
157
+ }
158
+ return $el;
159
+ };
160
+ })(BookReader.prototype.buildToolbarElement);
161
+
162
+ /**
163
+ * This method builds the html for the mobile drawer. It can be decorated to
164
+ * extend the default drawer.
165
+ * @return {jqueryElement}
166
+ */
167
+ BookReader.prototype.buildMobileDrawerElement = function() {
168
+ let experimentalHtml = '';
169
+ //builds filters checkbox html
170
+ if (this.enableExperimentalControls) {
171
+ experimentalHtml = `
172
+ <p class="DrawerSettingsTitle">Visual Adjustment</p>
173
+ <div class="BRcheckbox-group-filters">
174
+ `;
175
+ FILTERLIST.forEach( (el, i) => {
176
+ const checkboxHtml = `
177
+ <input type="checkbox" class="BRcheckbox-filters" id="filter${i}">
178
+ <label for="filter${i}" class="BRcheckbox-label-filters">${el.label}</label><br>
179
+
180
+ `;
181
+ experimentalHtml = experimentalHtml.concat(checkboxHtml);
182
+ });
183
+ experimentalHtml = experimentalHtml.concat("</div>");
184
+ }
185
+
186
+
187
+ const settingsSection = `
188
+ <span>
189
+ <span class="DrawerIconWrapper">
190
+ <img class="DrawerIcon" src="${`${this.imagesBaseURL}icon_gear.svg`}" alt="settings-icon"/>
191
+ </span>
192
+ Settings
193
+ </span>
194
+ <div class=DrawerSettingsWrapper>
195
+ <div class="DrawerSettingsLayoutWrapper">
196
+ <button class="DrawerLayoutButton one_page_mode">
197
+ <img src="${this.imagesBaseURL}icon_one_page.svg" alt="Single Page"/>
198
+ <br>
199
+ One Page
200
+ </button>
201
+ <button class="DrawerLayoutButton two_page_mode TwoPagesButton">
202
+ <img src="${this.imagesBaseURL}icon_two_pages.svg" alt="Two Pages"/>
203
+ <br>
204
+ Two Pages
205
+ </button>
206
+ <button class="DrawerLayoutButton thumbnail_mode">
207
+ <img src="${this.imagesBaseURL}icon_thumbnails.svg" alt="Thumbnails"/>
208
+ <br>
209
+ Thumbnails
210
+ </button>
211
+ </div>
212
+ <br>
213
+ <div class="DrawerSettingsTitle">Zoom</div>
214
+ <button class='BRicon zoom_out'></button>
215
+ <button class='BRicon zoom_in'></button>
216
+ <br style="clear:both"><br><br>
217
+ ${experimentalHtml}
218
+ </div>
219
+ `;
220
+ const moreInfo = `
221
+ <span>
222
+ <span class="DrawerIconWrapper ">
223
+ <img class="DrawerIcon" src="${this.imagesBaseURL}icon_info.svg" alt="info-icon"/>
224
+ </span>
225
+ About This Book
226
+ </span>
227
+ <div class="BRmobileInfo"></div>
228
+ `;
229
+ const share = `
230
+ <span>
231
+ <span class="DrawerIconWrapper">
232
+ <img class="DrawerIcon" src="${this.imagesBaseURL}icon_share.svg" alt="info-share"/>
233
+ </span>
234
+ Share This Book
235
+ </span>
236
+ <div class="BRmobileShare"></div>
237
+ `;
238
+ const navMenu = `
239
+ <nav id="BRmobileMenu" class="BRmobileMenu">
240
+ <ul>
241
+ <li class="BRmobileMenu__settings">${settingsSection}</li>
242
+ <li class="BRmobileMenu__moreInfoRow">${moreInfo}</li>
243
+ <li class="BRmobileMenu__share">${share}</li>
244
+ </ul>
245
+ </nav>
246
+ `;
247
+
248
+ const $el = $(navMenu);
249
+ return $el;
250
+ };
251
+
252
+ /**
253
+ * Mmenu moves itself out side of the root BookReader element, so we need to
254
+ * include it in the scoped $ function.
255
+ */
256
+ BookReader.prototype.$ = (function (super_) {
257
+ return function (arg) {
258
+ let $results = super_.call(this, arg);
259
+ if (this.refs.$mmenu) {
260
+ $results = $results.add(this.refs.$mmenu.find(arg));
261
+ }
262
+ return $results;
263
+ };
264
+ })(BookReader.prototype.$);
265
+
266
+ /**
267
+ * Dynamically creates styles combining different filters for BookReaders imgs
268
+ * based on filters checkbox
269
+ */
270
+ const applyFilters = (drawerEl, br) => {
271
+ let filterStr = "";
272
+
273
+ $('.BRcheckbox-filters').each(
274
+ (i, el) => {
275
+ br.refs.$br.removeClass("filter-applied");
276
+ if ($(el).is(':checked')) {
277
+ br.refs.$br.addClass($(el).attr("filter-applied"));
278
+ filterStr = filterStr + FILTERLIST[i].filter;
279
+ }
280
+ }
281
+ );
282
+ const filtersSheet = $("#filtersStyle")[0] || document.createElement('style');
283
+ filtersSheet.id = "filtersStyle";
284
+ filtersSheet.innerHTML = `.BRpagecontainer img {
285
+ filter: ${filterStr};
286
+ -webkit-filter: ${filterStr};}`;
287
+ document.body.appendChild(filtersSheet);
288
+ };
@@ -0,0 +1,68 @@
1
+ import * as docCookies from '../util/docCookies.js';
2
+
3
+ /* global BookReader */
4
+
5
+ /** @deprecated Exposed for backward compatibility */
6
+ BookReader.docCookies = docCookies;
7
+
8
+ /**
9
+ * Plugin to remember the current page number in a cookie
10
+ */
11
+ jQuery.extend(BookReader.defaultOptions, {
12
+ enablePageResume: true,
13
+ /** @type {string|null} eg '/', '/details/id' */
14
+ resumeCookiePath: null,
15
+ });
16
+
17
+ /** @override */
18
+ BookReader.prototype.init = (function(super_) {
19
+ return function() {
20
+ super_.call(this);
21
+ if (this.options.enablePageResume) {
22
+ this.bind(BookReader.eventNames.fragmentChange, () => {
23
+ const params = this.paramsFromCurrent();
24
+ this.updateResumeValue(params.index);
25
+ });
26
+ }
27
+ };
28
+ })(BookReader.prototype.init);
29
+
30
+ /**
31
+ * Gets page resume value, for remembering reader's page
32
+ * Can be overridden for different implementation
33
+ *
34
+ * @return {number|null}
35
+ */
36
+ BookReader.prototype.getResumeValue = function() {
37
+ const val = BookReader.docCookies.getItem('br-resume');
38
+ if (val !== null) return parseInt(val);
39
+ else return null;
40
+ };
41
+
42
+ /**
43
+ * Return cookie path using pathname up to /page/... or /mode/...
44
+ * using window.location.pathname for urlPathPart:
45
+ * - matches encoding
46
+ * - ignores querystring part
47
+ * - ignores fragment part (after #)
48
+ * @param {string} urlPathPart - window.location.pathname
49
+ */
50
+ BookReader.prototype.getCookiePath = function(urlPathPart) {
51
+ return urlPathPart.match('.+?(?=/page/|/mode/|$)')[0];
52
+ };
53
+
54
+ /**
55
+ * Sets page resume value, for remembering reader's page
56
+ * Can be overridden for different implementation
57
+ *
58
+ * @param {Number} index leaf index
59
+ * @param {string} [cookieName]
60
+ */
61
+ BookReader.prototype.updateResumeValue = function(index, cookieName) {
62
+ const ttl = new Date(+new Date + 12096e5); // 2 weeks
63
+ // For multiple files in item, leave resumeCookiePath blank
64
+ // It's likely we can remove resumeCookiePath using getCookiePath()
65
+ const path = this.options.resumeCookiePath
66
+ || this.getCookiePath(window.location.pathname);
67
+ BookReader.docCookies.setItem(cookieName || 'br-resume', index, ttl, path, null, false);
68
+ };