@internetarchive/bookreader 5.0.0-93 → 5.0.0-95

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 (224) hide show
  1. package/.github/workflows/npm-publish.yml +2 -12
  2. package/BookReaderDemo/IADemoBr.js +1 -24
  3. package/BookReaderDemo/demo-internetarchive.html +1 -0
  4. package/CHANGELOG.md +19 -1
  5. package/README.md +0 -2
  6. package/package.json +8 -4
  7. package/scripts/postversion.js +3 -2
  8. package/scripts/preversion.js +3 -1
  9. package/scripts/version.js +4 -6
  10. package/src/BookNavigator/book-navigator.js +38 -12
  11. package/src/BookNavigator/downloads/downloads-provider.js +2 -2
  12. package/src/BookNavigator/search/search-provider.js +5 -5
  13. package/src/BookNavigator/search/search-results.js +1 -1
  14. package/src/BookNavigator/sharing.js +2 -2
  15. package/src/BookNavigator/viewable-files.js +2 -2
  16. package/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js +3 -3
  17. package/src/BookNavigator/visual-adjustments/visual-adjustments.js +2 -2
  18. package/src/BookReader.js +57 -31
  19. package/src/assets/images/hypothesis.ico +0 -0
  20. package/src/css/_TextSelection.scss +3 -1
  21. package/src/plugins/plugin.autoplay.js +3 -3
  22. package/src/plugins/plugin.chapters.js +2 -2
  23. package/src/plugins/plugin.experiments.js +294 -0
  24. package/src/plugins/plugin.iiif.js +1 -1
  25. package/src/plugins/plugin.text_selection.js +112 -1
  26. package/src/plugins/search/view.js +5 -5
  27. package/src/plugins/tts/plugin.tts.js +3 -3
  28. package/src/plugins/url/plugin.url.js +2 -2
  29. package/tests/e2e/autoplay.test.js +1 -1
  30. package/tests/e2e/base.test.js +4 -4
  31. package/tests/e2e/helpers/base.js +2 -2
  32. package/tests/e2e/models/BookReader.js +1 -1
  33. package/tests/e2e/rightToLeft.test.js +4 -4
  34. package/tests/e2e/viewmode.test.js +2 -2
  35. package/tests/jest/BookNavigator/book-navigator.test.js +0 -13
  36. package/tests/jest/BookNavigator/downloads/downloads-provider.test.js +1 -1
  37. package/tests/jest/BookNavigator/downloads/downloads.test.js +1 -1
  38. package/tests/jest/BookNavigator/search/search-provider.test.js +5 -5
  39. package/tests/jest/BookReader.test.js +10 -10
  40. package/tests/jest/plugins/plugin.autoplay.test.js +6 -6
  41. package/tests/jest/plugins/plugin.chapters.test.js +2 -2
  42. package/tests/jest/plugins/plugin.resume.test.js +13 -13
  43. package/tests/jest/plugins/plugin.text_selection.test.js +155 -24
  44. package/tests/jest/plugins/search/plugin.search.test.js +7 -7
  45. package/tests/jest/plugins/search/plugin.search.view.test.js +8 -8
  46. package/tests/jest/plugins/search/utils.js +1 -1
  47. package/tests/jest/plugins/tts/PageChunkIterator.test.js +2 -2
  48. package/tests/jest/plugins/url/UrlPlugin.test.js +1 -1
  49. package/webpack.config.js +8 -3
  50. package/BookReader/BookReader.css +0 -2250
  51. package/BookReader/BookReader.js +0 -3
  52. package/BookReader/BookReader.js.LICENSE.txt +0 -72
  53. package/BookReader/BookReader.js.map +0 -1
  54. package/BookReader/ia-bookreader-bundle.js +0 -1782
  55. package/BookReader/ia-bookreader-bundle.js.LICENSE.txt +0 -7
  56. package/BookReader/ia-bookreader-bundle.js.map +0 -1
  57. package/BookReader/icons/1up.svg +0 -1
  58. package/BookReader/icons/2up.svg +0 -1
  59. package/BookReader/icons/advance.svg +0 -3
  60. package/BookReader/icons/chevron-right.svg +0 -1
  61. package/BookReader/icons/close-circle-dark.svg +0 -1
  62. package/BookReader/icons/close-circle.svg +0 -1
  63. package/BookReader/icons/fullscreen.svg +0 -1
  64. package/BookReader/icons/fullscreen_exit.svg +0 -1
  65. package/BookReader/icons/hamburger.svg +0 -1
  66. package/BookReader/icons/left-arrow.svg +0 -1
  67. package/BookReader/icons/magnify-minus.svg +0 -1
  68. package/BookReader/icons/magnify-plus.svg +0 -1
  69. package/BookReader/icons/magnify.svg +0 -1
  70. package/BookReader/icons/pause.svg +0 -1
  71. package/BookReader/icons/play.svg +0 -1
  72. package/BookReader/icons/playback-speed.svg +0 -1
  73. package/BookReader/icons/read-aloud.svg +0 -1
  74. package/BookReader/icons/review.svg +0 -3
  75. package/BookReader/icons/thumbnails.svg +0 -1
  76. package/BookReader/icons/voice.svg +0 -1
  77. package/BookReader/icons/volume-full.svg +0 -1
  78. package/BookReader/images/BRicons.png +0 -0
  79. package/BookReader/images/BRicons.svg +0 -5
  80. package/BookReader/images/BRicons_ia.png +0 -0
  81. package/BookReader/images/back_pages.png +0 -0
  82. package/BookReader/images/book_bottom_icon.png +0 -0
  83. package/BookReader/images/book_down_icon.png +0 -0
  84. package/BookReader/images/book_left_icon.png +0 -0
  85. package/BookReader/images/book_leftmost_icon.png +0 -0
  86. package/BookReader/images/book_right_icon.png +0 -0
  87. package/BookReader/images/book_rightmost_icon.png +0 -0
  88. package/BookReader/images/book_top_icon.png +0 -0
  89. package/BookReader/images/book_up_icon.png +0 -0
  90. package/BookReader/images/books_graphic.svg +0 -1
  91. package/BookReader/images/booksplit.png +0 -0
  92. package/BookReader/images/control_pause_icon.png +0 -0
  93. package/BookReader/images/control_play_icon.png +0 -0
  94. package/BookReader/images/embed_icon.png +0 -0
  95. package/BookReader/images/icon-home-ia.png +0 -0
  96. package/BookReader/images/icon_OL-logo-xs.png +0 -0
  97. package/BookReader/images/icon_alert-xs.png +0 -0
  98. package/BookReader/images/icon_book.svg +0 -1
  99. package/BookReader/images/icon_bookmark.svg +0 -1
  100. package/BookReader/images/icon_close-pop.png +0 -0
  101. package/BookReader/images/icon_download.png +0 -0
  102. package/BookReader/images/icon_gear.svg +0 -1
  103. package/BookReader/images/icon_hamburger.svg +0 -1
  104. package/BookReader/images/icon_home.png +0 -0
  105. package/BookReader/images/icon_home.svg +0 -1
  106. package/BookReader/images/icon_home_ia.png +0 -0
  107. package/BookReader/images/icon_indicator.png +0 -0
  108. package/BookReader/images/icon_info.svg +0 -1
  109. package/BookReader/images/icon_one_page.svg +0 -1
  110. package/BookReader/images/icon_pause.svg +0 -1
  111. package/BookReader/images/icon_play.svg +0 -1
  112. package/BookReader/images/icon_playback-rate.svg +0 -1
  113. package/BookReader/images/icon_return.png +0 -0
  114. package/BookReader/images/icon_search_button.svg +0 -1
  115. package/BookReader/images/icon_share.svg +0 -1
  116. package/BookReader/images/icon_skip-ahead.svg +0 -1
  117. package/BookReader/images/icon_skip-back.svg +0 -2
  118. package/BookReader/images/icon_speaker.svg +0 -1
  119. package/BookReader/images/icon_speaker_open.svg +0 -1
  120. package/BookReader/images/icon_thumbnails.svg +0 -1
  121. package/BookReader/images/icon_toc.svg +0 -1
  122. package/BookReader/images/icon_two_pages.svg +0 -1
  123. package/BookReader/images/icon_zoomer.png +0 -0
  124. package/BookReader/images/loading.gif +0 -0
  125. package/BookReader/images/logo_icon.png +0 -0
  126. package/BookReader/images/marker_chap-off.png +0 -0
  127. package/BookReader/images/marker_chap-off.svg +0 -1
  128. package/BookReader/images/marker_chap-off_ia.png +0 -0
  129. package/BookReader/images/marker_chap-on.png +0 -0
  130. package/BookReader/images/marker_chap-on.svg +0 -1
  131. package/BookReader/images/marker_srch-on.svg +0 -1
  132. package/BookReader/images/marker_srchchap-off.png +0 -0
  133. package/BookReader/images/marker_srchchap-on.png +0 -0
  134. package/BookReader/images/nav_control-dn.png +0 -0
  135. package/BookReader/images/nav_control-dn_ia.png +0 -0
  136. package/BookReader/images/nav_control-up.png +0 -0
  137. package/BookReader/images/nav_control-up_ia.png +0 -0
  138. package/BookReader/images/nav_control.png +0 -0
  139. package/BookReader/images/one_page_mode_icon.png +0 -0
  140. package/BookReader/images/paper-badge.png +0 -0
  141. package/BookReader/images/print_icon.png +0 -0
  142. package/BookReader/images/progressbar.gif +0 -0
  143. package/BookReader/images/right_edges.png +0 -0
  144. package/BookReader/images/slider.png +0 -0
  145. package/BookReader/images/slider_ia.png +0 -0
  146. package/BookReader/images/thumbnail_mode_icon.png +0 -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 +0 -2
  153. package/BookReader/jquery-3.js.LICENSE.txt +0 -24
  154. package/BookReader/plugins/plugin.archive_analytics.js +0 -2
  155. package/BookReader/plugins/plugin.archive_analytics.js.map +0 -1
  156. package/BookReader/plugins/plugin.autoplay.js +0 -2
  157. package/BookReader/plugins/plugin.autoplay.js.map +0 -1
  158. package/BookReader/plugins/plugin.chapters.js +0 -26
  159. package/BookReader/plugins/plugin.chapters.js.LICENSE.txt +0 -1
  160. package/BookReader/plugins/plugin.chapters.js.map +0 -1
  161. package/BookReader/plugins/plugin.iframe.js +0 -2
  162. package/BookReader/plugins/plugin.iframe.js.map +0 -1
  163. package/BookReader/plugins/plugin.iiif.js +0 -2
  164. package/BookReader/plugins/plugin.iiif.js.map +0 -1
  165. package/BookReader/plugins/plugin.resume.js +0 -2
  166. package/BookReader/plugins/plugin.resume.js.map +0 -1
  167. package/BookReader/plugins/plugin.search.js +0 -3
  168. package/BookReader/plugins/plugin.search.js.LICENSE.txt +0 -1
  169. package/BookReader/plugins/plugin.search.js.map +0 -1
  170. package/BookReader/plugins/plugin.text_selection.js +0 -3
  171. package/BookReader/plugins/plugin.text_selection.js.LICENSE.txt +0 -1
  172. package/BookReader/plugins/plugin.text_selection.js.map +0 -1
  173. package/BookReader/plugins/plugin.tts.js +0 -3
  174. package/BookReader/plugins/plugin.tts.js.LICENSE.txt +0 -29
  175. package/BookReader/plugins/plugin.tts.js.map +0 -1
  176. package/BookReader/plugins/plugin.url.js +0 -2
  177. package/BookReader/plugins/plugin.url.js.map +0 -1
  178. package/BookReader/plugins/plugin.vendor-fullscreen.js +0 -2
  179. package/BookReader/plugins/plugin.vendor-fullscreen.js.map +0 -1
  180. package/BookReader/webcomponents-bundle.js +0 -3
  181. package/BookReader/webcomponents-bundle.js.LICENSE.txt +0 -9
  182. package/BookReader/webcomponents-bundle.js.map +0 -1
  183. package/src/BookReader/BookModel.js +0 -554
  184. package/src/BookReader/DragScrollable.js +0 -233
  185. package/src/BookReader/ImageCache.js +0 -149
  186. package/src/BookReader/Mode1Up.js +0 -108
  187. package/src/BookReader/Mode1UpLit.js +0 -388
  188. package/src/BookReader/Mode2Up.js +0 -105
  189. package/src/BookReader/Mode2UpLit.js +0 -777
  190. package/src/BookReader/ModeCoordinateSpace.js +0 -29
  191. package/src/BookReader/ModeSmoothZoom.js +0 -312
  192. package/src/BookReader/ModeThumb.js +0 -342
  193. package/src/BookReader/Navbar/Navbar.js +0 -355
  194. package/src/BookReader/PageContainer.js +0 -169
  195. package/src/BookReader/ReduceSet.js +0 -26
  196. package/src/BookReader/Toolbar/Toolbar.js +0 -362
  197. package/src/BookReader/events.js +0 -19
  198. package/src/BookReader/options.js +0 -382
  199. package/src/BookReader/utils/HTMLDimensionsCacher.js +0 -44
  200. package/src/BookReader/utils/ScrollClassAdder.js +0 -31
  201. package/src/BookReader/utils/SelectionObserver.js +0 -45
  202. package/src/BookReader/utils/classes.js +0 -36
  203. package/src/BookReader/utils.js +0 -300
  204. package/tests/jest/BookReader/BookModel.test.js +0 -372
  205. package/tests/jest/BookReader/BookReaderPublicFunctions.test.js +0 -263
  206. package/tests/jest/BookReader/ImageCache.test.js +0 -150
  207. package/tests/jest/BookReader/Mode1UpLit.test.js +0 -73
  208. package/tests/jest/BookReader/Mode2Up.test.js +0 -98
  209. package/tests/jest/BookReader/Mode2UpLit.test.js +0 -190
  210. package/tests/jest/BookReader/ModeCoordinateSpace.test.js +0 -16
  211. package/tests/jest/BookReader/ModeSmoothZoom.test.js +0 -218
  212. package/tests/jest/BookReader/ModeThumb.test.js +0 -71
  213. package/tests/jest/BookReader/Navbar/Navbar.test.js +0 -182
  214. package/tests/jest/BookReader/PageContainer.test.js +0 -238
  215. package/tests/jest/BookReader/ReduceSet.test.js +0 -38
  216. package/tests/jest/BookReader/Toolbar/Toolbar.test.js +0 -26
  217. package/tests/jest/BookReader/utils/HTMLDimensionsCacher.test.js +0 -59
  218. package/tests/jest/BookReader/utils/ScrollClassAdder.test.js +0 -49
  219. package/tests/jest/BookReader/utils/SelectionObserver.test.js +0 -57
  220. package/tests/jest/BookReader/utils/classes.test.js +0 -88
  221. package/tests/jest/BookReader/utils.test.js +0 -250
  222. /package/{.eslintrc.js → .eslintrc.cjs} +0 -0
  223. /package/{.testcaferc.js → .testcaferc.cjs} +0 -0
  224. /package/{babel.config.js → babel.config.cjs} +0 -0
@@ -1,5 +1,5 @@
1
1
  # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2
- # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
2
+ # For more information see: https://docs.github.com/en/actions/use-cases-and-examples/publishing-packages/publishing-nodejs-packages
3
3
 
4
4
  name: Node.js Package
5
5
 
@@ -8,18 +8,7 @@ on:
8
8
  types: [created]
9
9
 
10
10
  jobs:
11
- build:
12
- runs-on: ubuntu-latest
13
- steps:
14
- - uses: actions/checkout@v4
15
- - uses: actions/setup-node@v4
16
- with:
17
- node-version: 20
18
- - run: npm ci
19
- - run: npm test
20
-
21
11
  publish-npm:
22
- needs: build
23
12
  runs-on: ubuntu-latest
24
13
  steps:
25
14
  - uses: actions/checkout@v4
@@ -28,6 +17,7 @@ jobs:
28
17
  node-version: 20
29
18
  registry-url: https://registry.npmjs.org/
30
19
  - run: npm ci
20
+ - run: npm run build
31
21
  - run: npm publish --tag next
32
22
  env:
33
23
  NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
@@ -45,23 +45,6 @@ BookReader.optionOverrides.imagesBaseURL = '/BookReader/images/';
45
45
  const initializeBookReader = (brManifest) => {
46
46
  console.log('initializeBookReader', brManifest);
47
47
 
48
- const {bookPath, subPrefix} = brManifest.data.brOptions;
49
- let path = bookPath;
50
- const subPrefixWithSlash = `/${subPrefix}`;
51
- if (bookPath.length - bookPath.lastIndexOf(subPrefixWithSlash) == subPrefixWithSlash.length) {
52
- path = bookPath.substr(0, bookPath.length - subPrefixWithSlash.length);
53
- }
54
-
55
- const searchInsideUrl = '//{{server}}/fulltext/inside.php?' + [
56
- 'item_id={{bookId|urlencode}}',
57
- 'doc={{subPrefix|urlencode}}',
58
- 'q={{query|urlencode}}',
59
- // This endpoint doesn't expect the path to be url encoded
60
- `path=${encodeURIComponent(path).replace(/%2F/g, '/')}`,
61
- 'pre_tag={{preTag|urlencode}}',
62
- 'post_tag={{postTag|urlencode}}',
63
- ].join('&');
64
-
65
48
  const options = {
66
49
  el: '#BookReader',
67
50
  /* Url plugin - IA uses History mode for URL */
@@ -74,6 +57,7 @@ const initializeBookReader = (brManifest) => {
74
57
  // urlTrackedParams: ['page', 'search', 'mode'],
75
58
  /* End url plugin */
76
59
  enableBookTitleLink: false,
60
+ bookUri: `https://archive.org/details/${ocaid}`,
77
61
  bookUrlText: null,
78
62
  startFullscreen: openFullImmersionTheater,
79
63
  // leaving this option commented out bc we change given user agent on archive.org
@@ -86,16 +70,9 @@ const initializeBookReader = (brManifest) => {
86
70
  /* End multiple volumes */
87
71
  enableBookmarks: true, // turn this on
88
72
  enableFSLogoShortcut: true,
89
-
90
- // TMP: To be replaced once BookReaderJSIA is updated to provide
91
- // these in the right spot.
92
73
  plugins: {
93
74
  search: {
94
- enabled: true,
95
75
  initialSearchTerm: searchTerm ? searchTerm : '',
96
- searchInsideUrl,
97
- preTag: brManifest.data.brOptions.searchInsidePreTag,
98
- postTag: brManifest.data.brOptions.searchInsidePostTag,
99
76
  },
100
77
  },
101
78
  };
@@ -30,6 +30,7 @@
30
30
  <script src="../BookReader/plugins/plugin.resume.js"></script>
31
31
  <script src="../BookReader/plugins/plugin.archive_analytics.js"></script>
32
32
  <script src="../BookReader/plugins/plugin.text_selection.js"></script>
33
+ <script src="../BookReader/plugins/plugin.experiments.js"></script>
33
34
 
34
35
  <script type="module" src="../BookReader/ia-bookreader-bundle.js"></script>
35
36
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
+ # 5.0.0-95
2
+ - Breaking change: Remove BookReader/ build directory from repo @cdrini
3
+ - This pattern has become increasingly rare (even jQuery is no longer doing this). If someone was relying on this somehow, you should be able to achieve the same effect using unpkg, or jsdelivr, or similar, eg:
4
+ - https://unpkg.com/@internetarchive/bookreader@5.0.0-94/BookReader/BookReader.js
5
+ - https://cdn.jsdelivr.net/npm/@internetarchive/bookreader@5.0.0-94/BookReader/BookReader.js
6
+ - And so on.
7
+
8
+ # 5.0.0-94
9
+ - Refactor: Make bookreader package type: module @cdrini
10
+ - Fix: Search icon being fetched from wrong path @cdrini
11
+ - Refactor: Move BookReader._plugins -> BookReader.plugins , making it public @cdrini
12
+ - Feature: Add length restrictions for protected text selection @cdrini
13
+ - Extend BR to work correctly with Hypothesis @cdrini
14
+ - Creates new experiments plugin, with a Hypothesis experiment
15
+ - Adds no `bookUri` option for saving Hypothesis annotations
16
+ - Adds new public HTML attributes to the PageContainer DOM, `data-index` for `PageIndex`, and `data-page-num` for `PageNumString`
17
+ - Improves some of BookReader's public APIs. BookReader.bind/unbind are now deprecated in favor of BookReader.on/off
18
+
1
19
  # 5.0.0-93
2
- - Fix: Clicking on search result not making request_page requst correctly @cdrini
20
+ - Fix: Clicking on search result not making request_page request correctly @cdrini
3
21
 
4
22
  # 5.0.0-92
5
23
  - Refactor: Migrate search plugin to BookReaderPlugin system @cdrini
package/README.md CHANGED
@@ -147,8 +147,6 @@ The Fragment Change message is sent to the parent window when the embedded BookR
147
147
 
148
148
  The source JavaScript is written in ES6 (located in the `src/js` directory) and in ES5 (located in `BookReader`). `npm run serve-dev` starts an auto-reloading dev server, that builds js/css that has been edited at `localhost:8000`.
149
149
 
150
- Until the next major version bump, we have to store the build files inside the repo to maintain backwards compatibility. Please _DO NOT_ include these files in your PR. Anything in the `BookReader/` directory should not be committed.
151
-
152
150
  ### Developing icons
153
151
  To see local icon package changes in bookreader, you'll need to install core-js into the icon package and link into bookreader.
154
152
 
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@internetarchive/bookreader",
3
- "version": "5.0.0-93",
3
+ "version": "5.0.0-95",
4
4
  "description": "The Internet Archive BookReader.",
5
+ "type": "module",
5
6
  "repository": {
6
7
  "type": "git",
7
8
  "url": "git+https://github.com/internetarchive/bookreader.git"
@@ -58,6 +59,7 @@
58
59
  "eslint-plugin-no-jquery": "^2.7.0",
59
60
  "eslint-plugin-testcafe": "^0.2.1",
60
61
  "http-server": "14.1.1",
62
+ "hypothesis": "^1.1627.0",
61
63
  "interactjs": "^1.10.18",
62
64
  "iso-language-codes": "1.1.0",
63
65
  "jest": "29.7.0",
@@ -99,16 +101,18 @@
99
101
  "preversion": "npm run test && node scripts/preversion.js",
100
102
  "version": "node scripts/version.js",
101
103
  "postversion": "node scripts/postversion.js",
102
- "build": "npm run clean && npx concurrently --group npm:build-js npm:build-css npm:build-assets",
104
+ "build": "npm run clean && npx concurrently --group npm:build-js npm:build-css npm:build-assets npm:build-hypothesis",
103
105
  "build-assets": "npx cpx \"src/assets/**/*\" BookReader && npx svgo -f BookReader/icons && npx svgo -f BookReader/images",
104
106
  "build-assets:watch": "npx cpx --watch --verbose \"src/assets/**/*\" BookReader",
107
+ "build-hypothesis": "npx cpx \"node_modules/hypothesis/**/*\" BookReader/hypothesis",
108
+ "build-hypothesis:watch": "npx cpx --watch --verbose \"node_modules/hypothesis/**/*\" BookReader/hypothesis",
105
109
  "build-js": "npx webpack",
106
110
  "build-js:watch": "npx webpack --mode=development --watch",
107
111
  "build-css": "npx sass --no-source-map ./src/css/BookReader.scss ./BookReader/BookReader.css",
108
112
  "build-css:watch": "npx sass --watch --no-source-map ./src/css/BookReader.scss ./BookReader/BookReader.css",
109
113
  "clean": "rm -r BookReader/ || true",
110
- "lint": "npx eslint src/ tests/ *.js",
111
- "lint:fix": "npx eslint --fix src/ tests/ *.js",
114
+ "lint": "npx eslint src/ tests/ *.js *.cjs",
115
+ "lint:fix": "npx eslint --fix src/ tests/ *.js *.cjs",
112
116
  "serve": "npx http-server . --port=8000",
113
117
  "serve-live": "npx live-server . --cors --port=8000 --watch=index.html,BookReader,BookReaderDemo",
114
118
  "serve-dev": "env NODE_ENV='development' npm run build-css && env NODE_ENV='development' npx concurrently --kill-others npm:serve-live npm:build-*:watch",
@@ -1,5 +1,6 @@
1
- const fs = require('fs');
2
- const { version: NEW_VERSION } = require('../package.json');
1
+ import fs from 'fs';
2
+ import PACKAGE_JSON from '../package.json' assert { type: 'json' };
3
+ const NEW_VERSION = PACKAGE_JSON.version;
3
4
 
4
5
  const tag = `v${NEW_VERSION}`;
5
6
  const releaseBody = fs.readFileSync('CHANGELOG.md').toString()
@@ -1,4 +1,6 @@
1
- const { version: OLD_VERSION } = require('../package.json');
1
+ import PACKAGE_JSON from '../package.json' assert { type: 'json' };
2
+
3
+ const OLD_VERSION = PACKAGE_JSON.version;
2
4
  const OLD_RELEASE_URL = `https://api.github.com/repos/internetarchive/bookreader/releases/tags/v${OLD_VERSION}`;
3
5
 
4
6
  async function main() {
@@ -1,6 +1,7 @@
1
- const fs = require('fs');
2
- const { execSync } = require('child_process');
3
- const { version: NEW_VERSION } = require('../package.json');
1
+ import fs from 'fs';
2
+ import { execSync } from 'child_process';
3
+ import PACKAGE_JSON from '../package.json' assert { type: 'json' };
4
+ const NEW_VERSION = PACKAGE_JSON.version;
4
5
 
5
6
  async function main() {
6
7
  // Update the changelog
@@ -18,9 +19,6 @@ async function main() {
18
19
 
19
20
  // build
20
21
  execSync('npm run build', { stdio: "inherit" });
21
-
22
- // Add build files
23
- execSync('git add ./BookReader');
24
22
  }
25
23
 
26
24
  main().then(() => process.exit());
@@ -10,6 +10,7 @@ import BookmarksProvider from './bookmarks/bookmarks-provider.js';
10
10
  import SharingProvider from './sharing.js';
11
11
  import ViewableFilesProvider from './viewable-files.js';
12
12
  import iaLogo from './assets/ia-logo.js';
13
+ import { sortBy } from '../BookReader/utils.js';
13
14
  /** @typedef {import('@/src/BookReader.js').default} BookReader */
14
15
 
15
16
  const events = {
@@ -51,7 +52,20 @@ export class BookNavigator extends LitElement {
51
52
  this.isAdmin = false;
52
53
  this.lendingInitialized = false;
53
54
  this.lendingStatus = {};
54
- this.menuProviders = {};
55
+ this.menuProviders = {
56
+ /** @type {BookmarksProvider} */
57
+ bookmarks: null,
58
+ /** @type {SearchProvider} */
59
+ search: null,
60
+ /** @type {DownloadProvider} */
61
+ downloads: null,
62
+ /** @type {VisualAdjustmentProvider} */
63
+ visualAdjustments: null,
64
+ /** @type {SharingProvider} */
65
+ share: null,
66
+ /** @type {ViewableFilesProvider} */
67
+ volumes: null,
68
+ };
55
69
  this.menuShortcuts = [];
56
70
  this.signedIn = false;
57
71
  /** @type {ModalManager} */
@@ -73,6 +87,10 @@ export class BookNavigator extends LitElement {
73
87
  'chapters',
74
88
  'search',
75
89
  'bookmarks',
90
+ 'downloads',
91
+ 'visualAdjustments',
92
+ 'share',
93
+ 'experiments',
76
94
  ];
77
95
  }
78
96
 
@@ -313,14 +331,20 @@ export class BookNavigator extends LitElement {
313
331
  * Sets order of menu and emits custom event when done
314
332
  */
315
333
  updateMenuContents() {
316
- const {
317
- search, downloads, visualAdjustments, share, bookmarks, volumes, chapters,
318
- } = this.menuProviders;
319
- const availableMenus = [volumes, chapters, search, bookmarks, visualAdjustments, share].filter((menu) => !!menu);
334
+ const availableMenus = sortBy(
335
+ Object.entries(this.menuProviders)
336
+ .filter(([id, menu]) => !!menu)
337
+ .filter(([id, menu]) => {
338
+ return id === 'downloads' ? this.shouldShowDownloadsMenu() : true;
339
+ }),
340
+ ([id, menu]) => {
341
+ const index = this.shortcutOrder.indexOf(id);
342
+ return index === -1 ? this.shortcutOrder.length : index;
343
+ },
344
+ ).map(([id, menu]) => menu);
320
345
 
321
346
  if (this.shouldShowDownloadsMenu()) {
322
- downloads?.update(this.downloadableTypes);
323
- availableMenus.splice(-2, 0, downloads);
347
+ this.menuProviders.downloads?.update(this.downloadableTypes);
324
348
  }
325
349
 
326
350
  const event = new CustomEvent(
@@ -387,11 +411,13 @@ export class BookNavigator extends LitElement {
387
411
  * the id in each iteration over the shortcutOrder array.
388
412
  */
389
413
  sortMenuShortcuts() {
390
- this.menuShortcuts = this.shortcutOrder.reduce((shortcuts, id) => {
391
- const menu = this.menuShortcuts.find((m) => m.id === id);
392
- if (menu) { shortcuts.push(menu); }
393
- return shortcuts;
394
- }, []);
414
+ this.menuShortcuts = sortBy(
415
+ this.menuShortcuts,
416
+ (shortcut) => {
417
+ const index = this.shortcutOrder.indexOf(shortcut.id);
418
+ return index === -1 ? this.shortcutOrder.length : index;
419
+ },
420
+ );
395
421
  }
396
422
 
397
423
  emitMenuShortcutsUpdated() {
@@ -1,6 +1,6 @@
1
1
  import { html } from 'lit';
2
- import '@internetarchive/icon-dl/icon-dl';
3
- import './downloads';
2
+ import '@internetarchive/icon-dl/icon-dl.js';
3
+ import './downloads.js';
4
4
 
5
5
  const menuBase = {
6
6
  pdf: {
@@ -1,7 +1,7 @@
1
1
  // @ts-check
2
2
  import { html, nothing } from 'lit';
3
- import '@internetarchive/icon-search/icon-search';
4
- import './search-results';
3
+ import '@internetarchive/icon-search/icon-search.js';
4
+ import './search-results.js';
5
5
  /** @typedef {import('@/src/plugins/search/plugin.search.js').SearchInsideMatch} SearchInsideMatch */
6
6
  /** @typedef {import('@/src/plugins/search/plugin.search.js').SearchInsideResults} SearchInsideResults */
7
7
  /** @typedef {import('@/src/BookReader.js').default} BookReader */
@@ -143,7 +143,7 @@ export default class SearchProvider {
143
143
  }
144
144
 
145
145
  searchCanceledInMenu() {
146
- this.bookreader._plugins.search.cancelSearchRequest();
146
+ this.bookreader.plugins.search.cancelSearchRequest();
147
147
  }
148
148
 
149
149
  onSearchResultsCleared() {
@@ -155,7 +155,7 @@ export default class SearchProvider {
155
155
  errorMessage: '',
156
156
  };
157
157
  this.updateMenu({ openMenu: false });
158
- this.bookreader._plugins.search.searchView.clearSearchFieldAndResults(false);
158
+ this.bookreader.plugins.search.searchView.clearSearchFieldAndResults(false);
159
159
  if (this.bookreader.urlPlugin) {
160
160
  this.updateSearchInUrl();
161
161
  }
@@ -204,6 +204,6 @@ export default class SearchProvider {
204
204
  * @param {{ detail: {match: SearchInsideMatch} }} param0
205
205
  */
206
206
  onSearchResultsClicked({ detail }) {
207
- this.bookreader._plugins.search.jumpToMatch(detail.match.matchIndex);
207
+ this.bookreader.plugins.search.jumpToMatch(detail.match.matchIndex);
208
208
  }
209
209
  }
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable class-methods-use-this */
2
2
  import { unsafeHTML } from 'lit/directives/unsafe-html.js';
3
3
  import { css, html, LitElement, nothing } from 'lit';
4
- import '@internetarchive/ia-activity-indicator/ia-activity-indicator';
4
+ import '@internetarchive/ia-activity-indicator/ia-activity-indicator.js';
5
5
  import checkmarkIcon from '../assets/icon_checkmark.js';
6
6
  import closeIcon from '../assets/icon_close.js';
7
7
  import buttonCSS from '../assets/button-base.js';
@@ -1,6 +1,6 @@
1
1
  import { html } from 'lit';
2
- import { iauxShareIcon } from '@internetarchive/ia-item-navigator/dist/src/menus/share-panel';
3
- import '@internetarchive/ia-item-navigator/dist/src/menus/share-panel';
2
+ import { iauxShareIcon } from '@internetarchive/ia-item-navigator/dist/src/menus/share-panel.js';
3
+ import '@internetarchive/ia-item-navigator/dist/src/menus/share-panel.js';
4
4
 
5
5
  export default class SharingProvider {
6
6
  constructor({
@@ -1,7 +1,7 @@
1
1
  import { html } from 'lit';
2
2
 
3
- import { viewableFilesIcon } from '@internetarchive/ia-item-navigator/dist/src/menus/viewable-files';
4
- import '@internetarchive/ia-item-navigator/dist/src/menus/viewable-files';
3
+ import { viewableFilesIcon } from '@internetarchive/ia-item-navigator/dist/src/menus/viewable-files.js';
4
+ import '@internetarchive/ia-item-navigator/dist/src/menus/viewable-files.js';
5
5
 
6
6
  /**
7
7
  * * @typedef { 'title_asc' | 'title_desc' | 'default'} SortTypesT
@@ -1,6 +1,6 @@
1
1
  import { html } from 'lit';
2
- import '@internetarchive/icon-visual-adjustment/icon-visual-adjustment';
3
- import './visual-adjustments';
2
+ import '@internetarchive/icon-visual-adjustment/icon-visual-adjustment.js';
3
+ import './visual-adjustments.js';
4
4
 
5
5
  const visualAdjustmentOptions = [{
6
6
  id: 'brightness',
@@ -45,7 +45,7 @@ export default class VisualAdjustmentsProvider {
45
45
  this.icon = html`<ia-icon-visual-adjustment style="width: var(--iconWidth); height: var(--iconHeight);"></ia-icon-visual-adjustment>`;
46
46
  this.label = 'Visual Adjustments';
47
47
  this.menuDetails = this.updateOptionsCount();
48
- this.id = 'adjustment';
48
+ this.id = 'visualAdjustments';
49
49
  this.component = html`
50
50
  <ia-book-visual-adjustments
51
51
  .options=${visualAdjustmentOptions}
@@ -2,8 +2,8 @@ import { css, html, LitElement } from "lit";
2
2
  import { repeat } from "lit/directives/repeat.js";
3
3
  import { nothing } from "lit";
4
4
  import checkmarkIcon from '../assets/icon_checkmark.js';
5
- import "@internetarchive/icon-magnify-minus/icon-magnify-minus";
6
- import "@internetarchive/icon-magnify-plus/icon-magnify-plus";
5
+ import "@internetarchive/icon-magnify-minus/icon-magnify-minus.js";
6
+ import "@internetarchive/icon-magnify-plus/icon-magnify-plus.js";
7
7
 
8
8
  const namespacedEvent = (eventName) => `visualAdjustment${eventName}`;
9
9
 
package/src/BookReader.js CHANGED
@@ -37,10 +37,10 @@ import { Toolbar } from './BookReader/Toolbar/Toolbar.js';
37
37
  import { BookModel } from './BookReader/BookModel.js';
38
38
  import { Mode1Up } from './BookReader/Mode1Up.js';
39
39
  import { Mode2Up } from './BookReader/Mode2Up.js';
40
- import { ModeThumb } from './BookReader/ModeThumb';
40
+ import { ModeThumb } from './BookReader/ModeThumb.js';
41
41
  import { ImageCache } from './BookReader/ImageCache.js';
42
42
  import { PageContainer } from './BookReader/PageContainer.js';
43
- import { NAMED_REDUCE_SETS } from './BookReader/ReduceSet';
43
+ import { NAMED_REDUCE_SETS } from './BookReader/ReduceSet.js';
44
44
 
45
45
  /**
46
46
  * BookReader
@@ -134,7 +134,7 @@ BookReader.prototype.setup = function(options) {
134
134
  this.bookPath = options.bookPath;
135
135
 
136
136
  // Construct the usual plugins first to get type hints
137
- this._plugins = {
137
+ this.plugins = {
138
138
  archiveAnalytics: BookReader.PLUGINS.archiveAnalytics ? new BookReader.PLUGINS.archiveAnalytics(this) : null,
139
139
  autoplay: BookReader.PLUGINS.autoplay ? new BookReader.PLUGINS.autoplay(this) : null,
140
140
  chapters: BookReader.PLUGINS.chapters ? new BookReader.PLUGINS.chapters(this) : null,
@@ -145,18 +145,18 @@ BookReader.prototype.setup = function(options) {
145
145
  };
146
146
 
147
147
  // Delete anything that's null
148
- for (const [pluginName, plugin] of Object.entries(this._plugins)) {
149
- if (!plugin) delete this._plugins[pluginName];
148
+ for (const [pluginName, plugin] of Object.entries(this.plugins)) {
149
+ if (!plugin) delete this.plugins[pluginName];
150
150
  }
151
151
 
152
152
  // Now construct the rest of the plugins
153
153
  for (const [pluginName, PluginClass] of Object.entries(BookReader.PLUGINS)) {
154
- if (this._plugins[pluginName] || !PluginClass) continue;
155
- this._plugins[pluginName] = new PluginClass(this);
154
+ if (this.plugins[pluginName] || !PluginClass) continue;
155
+ this.plugins[pluginName] = new PluginClass(this);
156
156
  }
157
157
 
158
158
  // And call setup on them
159
- for (const [pluginName, plugin] of Object.entries(this._plugins)) {
159
+ for (const [pluginName, plugin] of Object.entries(this.plugins)) {
160
160
  try {
161
161
  plugin.setup(this.options.plugins?.[pluginName] ?? {});
162
162
  // Write the options back; this way the plugin is the source of truth,
@@ -167,9 +167,9 @@ BookReader.prototype.setup = function(options) {
167
167
  }
168
168
  }
169
169
 
170
- if (this._plugins.search?.options.enabled) {
170
+ if (this.plugins.search?.options.enabled) {
171
171
  // Expose the search method for convenience / backward compat
172
- this.search = this._plugins.search.search.bind(this._plugins.search);
172
+ this.search = this.plugins.search.search.bind(this.plugins.search);
173
173
  }
174
174
 
175
175
  /** @type {number} @deprecated some past iterations set this */
@@ -426,9 +426,9 @@ BookReader.prototype.initParams = function() {
426
426
  }
427
427
 
428
428
  // Check for Resume plugin
429
- if (this._plugins.resume?.options.enabled) {
429
+ if (this.plugins.resume?.options.enabled) {
430
430
  // Check cookies
431
- const val = this._plugins.resume.getResumeValue();
431
+ const val = this.plugins.resume.getResumeValue();
432
432
  if (val !== null) {
433
433
  // If page index different from default
434
434
  if (params.index !== val) {
@@ -462,8 +462,8 @@ BookReader.prototype.initParams = function() {
462
462
  }
463
463
 
464
464
  // Check for Search plugin
465
- if (this._plugins.search?.options.enabled) {
466
- const sp = this._plugins.search;
465
+ if (this.plugins.search?.options.enabled) {
466
+ const sp = this.plugins.search;
467
467
  // Go to first result only if no default or URL page
468
468
  sp.options.goToFirstResult = !params.pageFound;
469
469
 
@@ -619,7 +619,7 @@ BookReader.prototype.init = function() {
619
619
  const $navBar = this.initNavbar();
620
620
 
621
621
  // extend navbar with plugins
622
- for (const plugin of Object.values(this._plugins)) {
622
+ for (const plugin of Object.values(this.plugins)) {
623
623
  plugin.extendNavBar($navBar);
624
624
  }
625
625
  }
@@ -660,7 +660,7 @@ BookReader.prototype.init = function() {
660
660
  }
661
661
 
662
662
  // If not searching, set to allow on-going fragment changes
663
- if (!this._plugins.search?.options.initialSearchTerm) {
663
+ if (!this.plugins.search?.options.initialSearchTerm) {
664
664
  this.suppressFragmentChange = false;
665
665
  }
666
666
 
@@ -669,7 +669,7 @@ BookReader.prototype.init = function() {
669
669
  }
670
670
 
671
671
  // Init plugins
672
- for (const [pluginName, plugin] of Object.entries(this._plugins)) {
672
+ for (const [pluginName, plugin] of Object.entries(this.plugins)) {
673
673
  try {
674
674
  plugin.init();
675
675
  }
@@ -702,14 +702,28 @@ BookReader.prototype.trigger = function(name, props = this) {
702
702
  $(document).trigger(eventName, props);
703
703
  };
704
704
 
705
- BookReader.prototype.bind = function(name, callback) {
705
+ BookReader.prototype.on = function(name, callback) {
706
706
  $(document).on('BookReader:' + name, callback);
707
707
  };
708
708
 
709
- BookReader.prototype.unbind = function(name, callback) {
709
+ BookReader.prototype.off = function(name, callback) {
710
710
  $(document).off('BookReader:' + name, callback);
711
711
  };
712
712
 
713
+ /**
714
+ * @deprecated Use .on and .off instead
715
+ */
716
+ BookReader.prototype.bind = function(name, callback) {
717
+ return this.on(name, callback);
718
+ };
719
+
720
+ /**
721
+ * @deprecated Use .on and .off instead
722
+ */
723
+ BookReader.prototype.unbind = function(name, callback) {
724
+ return this.off(name, callback);
725
+ };
726
+
713
727
  /**
714
728
  * Resizes based on the container width and height
715
729
  */
@@ -874,7 +888,7 @@ BookReader.prototype._createPageContainer = function(index) {
874
888
  });
875
889
 
876
890
  // Call plugin handlers
877
- for (const plugin of Object.values(this._plugins)) {
891
+ for (const plugin of Object.values(this.plugins)) {
878
892
  plugin._configurePageContainer(pageContainer);
879
893
  }
880
894
 
@@ -927,7 +941,7 @@ BookReader.prototype.zoom = function(direction) {
927
941
  } else {
928
942
  this.activeMode.zoom('out');
929
943
  }
930
- this._plugins.textSelection?.stopPageFlip(this.refs.$brContainer);
944
+ this.plugins.textSelection?.stopPageFlip(this.refs.$brContainer);
931
945
  return;
932
946
  };
933
947
 
@@ -1105,7 +1119,7 @@ BookReader.prototype.getPrevReadMode = function(mode) {
1105
1119
 
1106
1120
  /**
1107
1121
  * Switches the mode (eg 1up 2up thumb)
1108
- * @param {number}
1122
+ * @param {number|'1up' | '2up' | 'thumb'}
1109
1123
  * @param {object} [options]
1110
1124
  * @param {boolean} [options.suppressFragmentChange = false]
1111
1125
  * @param {boolean} [options.onInit = false] - this
@@ -1118,6 +1132,18 @@ BookReader.prototype.switchMode = function(
1118
1132
  pageFound = false,
1119
1133
  } = {},
1120
1134
  ) {
1135
+ if (typeof mode === 'string') {
1136
+ mode = {
1137
+ '1up': this.constMode1up,
1138
+ '2up': this.constMode2up,
1139
+ 'thumb': this.constModeThumb,
1140
+ }[mode];
1141
+ }
1142
+
1143
+ if (!mode) {
1144
+ throw new Error(`Invalid mode: ${mode}`);
1145
+ }
1146
+
1121
1147
  // Skip checks before init() complete
1122
1148
  if (this.init.initComplete) {
1123
1149
  if (mode === this.mode) {
@@ -1162,7 +1188,7 @@ BookReader.prototype.switchMode = function(
1162
1188
  const eventName = mode + 'PageViewSelected';
1163
1189
  this.trigger(BookReader.eventNames[eventName]);
1164
1190
 
1165
- this._plugins.textSelection?.stopPageFlip(this.refs.$brContainer);
1191
+ this.plugins.textSelection?.stopPageFlip(this.refs.$brContainer);
1166
1192
  };
1167
1193
 
1168
1194
  BookReader.prototype.updateBrClasses = function() {
@@ -1234,7 +1260,7 @@ BookReader.prototype.enterFullscreen = async function(bindKeyboardControls = tru
1234
1260
  }
1235
1261
  this.jumpToIndex(currentIndex);
1236
1262
 
1237
- this._plugins.textSelection?.stopPageFlip(this.refs.$brContainer);
1263
+ this.plugins.textSelection?.stopPageFlip(this.refs.$brContainer);
1238
1264
  // Add "?view=theater"
1239
1265
  this.trigger(BookReader.eventNames.fragmentChange);
1240
1266
  // trigger event here, so that animations,
@@ -1280,7 +1306,7 @@ BookReader.prototype.exitFullScreen = async function () {
1280
1306
  await this.activeMode.mode1UpLit.updateComplete;
1281
1307
  }
1282
1308
 
1283
- this._plugins.textSelection?.stopPageFlip(this.refs.$brContainer);
1309
+ this.plugins.textSelection?.stopPageFlip(this.refs.$brContainer);
1284
1310
  // Remove "?view=theater"
1285
1311
  this.trigger(BookReader.eventNames.fragmentChange);
1286
1312
  this.refs.$br.removeClass('BRfullscreenAnimation');
@@ -1324,7 +1350,7 @@ BookReader.prototype.updateFirstIndex = function(
1324
1350
  // If there's an initial search we stop suppressing global URL changes
1325
1351
  // when local suppression ends
1326
1352
  // This seems to correctly handle multiple calls during mode/1up
1327
- if (this._plugins.search.options.initialSearchTerm && !suppressFragmentChange) {
1353
+ if (this.plugins.search?.options.initialSearchTerm && !suppressFragmentChange) {
1328
1354
  this.suppressFragmentChange = false;
1329
1355
  }
1330
1356
 
@@ -1601,7 +1627,7 @@ BookReader.prototype.bindNavigationHandlers = function() {
1601
1627
  });
1602
1628
 
1603
1629
  // Call _bindNavigationHandlers on the plugins
1604
- for (const plugin of Object.values(this._plugins)) {
1630
+ for (const plugin of Object.values(this.plugins)) {
1605
1631
  plugin._bindNavigationHandlers();
1606
1632
  }
1607
1633
  };
@@ -1653,8 +1679,8 @@ BookReader.prototype.updateFromParams = function(params) {
1653
1679
  // process /search
1654
1680
  // @deprecated for urlMode 'history'
1655
1681
  // Continues to work for urlMode 'hash'
1656
- if (this._plugins.search?.enabled && 'undefined' != typeof(params.search)) {
1657
- if (this._plugins.search.searchTerm !== params.search) {
1682
+ if (this.plugins.search?.enabled && 'undefined' != typeof(params.search)) {
1683
+ if (this.plugins.search.searchTerm !== params.search) {
1658
1684
  this.$('.BRsearchInput').val(params.search);
1659
1685
  }
1660
1686
  }
@@ -1858,8 +1884,8 @@ BookReader.prototype.paramsFromCurrent = function() {
1858
1884
  params.view = fullscreenView;
1859
1885
  }
1860
1886
  // Search
1861
- if (this._plugins.search?.enabled) {
1862
- params.search = this._plugins.search.searchTerm;
1887
+ if (this.plugins.search?.enabled) {
1888
+ params.search = this.plugins.search.searchTerm;
1863
1889
  }
1864
1890
 
1865
1891
  return params;
Binary file