@internetarchive/bookreader 5.0.0-24-sortingstate-11 → 5.0.0-24-sortingstate-final

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 (81) hide show
  1. package/BookReader/BookReader.js +2 -32145
  2. package/BookReader/BookReader.js.map +1 -1
  3. package/BookReader/bookreader-component-bundle.js +1286 -11256
  4. package/BookReader/bookreader-component-bundle.js.map +1 -1
  5. package/BookReader/icons/1up.svg +1 -12
  6. package/BookReader/icons/2up.svg +1 -15
  7. package/BookReader/icons/advance.svg +3 -26
  8. package/BookReader/icons/chevron-right.svg +1 -1
  9. package/BookReader/icons/close-circle-dark.svg +1 -1
  10. package/BookReader/icons/close-circle.svg +1 -1
  11. package/BookReader/icons/fullscreen.svg +1 -17
  12. package/BookReader/icons/fullscreen_exit.svg +1 -17
  13. package/BookReader/icons/hamburger.svg +1 -15
  14. package/BookReader/icons/left-arrow.svg +1 -12
  15. package/BookReader/icons/magnify-minus.svg +1 -16
  16. package/BookReader/icons/magnify-plus.svg +1 -17
  17. package/BookReader/icons/magnify.svg +1 -15
  18. package/BookReader/icons/pause.svg +1 -23
  19. package/BookReader/icons/play.svg +1 -22
  20. package/BookReader/icons/playback-speed.svg +1 -34
  21. package/BookReader/icons/read-aloud.svg +1 -22
  22. package/BookReader/icons/review.svg +3 -22
  23. package/BookReader/icons/thumbnails.svg +1 -17
  24. package/BookReader/icons/voice.svg +1 -1
  25. package/BookReader/icons/volume-full.svg +1 -22
  26. package/BookReader/images/BRicons.svg +5 -94
  27. package/BookReader/images/books_graphic.svg +1 -177
  28. package/BookReader/images/icon_book.svg +1 -12
  29. package/BookReader/images/icon_bookmark.svg +1 -12
  30. package/BookReader/images/icon_gear.svg +1 -14
  31. package/BookReader/images/icon_hamburger.svg +1 -20
  32. package/BookReader/images/icon_home.svg +1 -21
  33. package/BookReader/images/icon_info.svg +1 -11
  34. package/BookReader/images/icon_one_page.svg +1 -8
  35. package/BookReader/images/icon_pause.svg +1 -1
  36. package/BookReader/images/icon_play.svg +1 -1
  37. package/BookReader/images/icon_playback-rate.svg +1 -15
  38. package/BookReader/images/icon_search_button.svg +1 -8
  39. package/BookReader/images/icon_share.svg +1 -9
  40. package/BookReader/images/icon_skip-ahead.svg +1 -6
  41. package/BookReader/images/icon_skip-back.svg +2 -13
  42. package/BookReader/images/icon_speaker.svg +1 -18
  43. package/BookReader/images/icon_speaker_open.svg +1 -10
  44. package/BookReader/images/icon_thumbnails.svg +1 -12
  45. package/BookReader/images/icon_toc.svg +1 -5
  46. package/BookReader/images/icon_two_pages.svg +1 -9
  47. package/BookReader/images/marker_chap-off.svg +1 -11
  48. package/BookReader/images/marker_chap-on.svg +1 -11
  49. package/BookReader/images/marker_srch-on.svg +1 -11
  50. package/BookReader/jquery-1.10.1.js +2 -108
  51. package/BookReader/plugins/plugin.archive_analytics.js +1 -170
  52. package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
  53. package/BookReader/plugins/plugin.autoplay.js +1 -163
  54. package/BookReader/plugins/plugin.autoplay.js.map +1 -1
  55. package/BookReader/plugins/plugin.chapters.js +1 -333
  56. package/BookReader/plugins/plugin.chapters.js.map +1 -1
  57. package/BookReader/plugins/plugin.iframe.js +1 -72
  58. package/BookReader/plugins/plugin.iframe.js.map +1 -1
  59. package/BookReader/plugins/plugin.mobile_nav.js +1 -332
  60. package/BookReader/plugins/plugin.mobile_nav.js.map +1 -1
  61. package/BookReader/plugins/plugin.resume.js +1 -241
  62. package/BookReader/plugins/plugin.resume.js.map +1 -1
  63. package/BookReader/plugins/plugin.search.js +1 -1263
  64. package/BookReader/plugins/plugin.search.js.map +1 -1
  65. package/BookReader/plugins/plugin.text_selection.js +1 -839
  66. package/BookReader/plugins/plugin.text_selection.js.map +1 -1
  67. package/BookReader/plugins/plugin.tts.js +2 -9114
  68. package/BookReader/plugins/plugin.tts.js.map +1 -1
  69. package/BookReader/plugins/plugin.url.js +1 -768
  70. package/BookReader/plugins/plugin.url.js.map +1 -1
  71. package/BookReader/plugins/plugin.vendor-fullscreen.js +1 -326
  72. package/BookReader/plugins/plugin.vendor-fullscreen.js.map +1 -1
  73. package/BookReader/webcomponents-bundle.js +2 -411
  74. package/BookReader/webcomponents-bundle.js.map +1 -1
  75. package/BookReaderDemo/demo-internetarchive.html +86 -4
  76. package/package.json +1 -1
  77. package/src/BookNavigator/volumes/volumes-provider.js +15 -16
  78. package/src/css/_controls.scss +4 -0
  79. package/src/plugins/plugin.url.js +6 -16
  80. package/tests/jest/plugins/plugin.url.test.js +11 -11
  81. package/tests/karma/BookNavigator/volumes/volumes-provider.test.js +6 -6
@@ -29,6 +29,10 @@
29
29
  <script type="module" src="../BookReader/bookreader-component-bundle.js"></script>
30
30
 
31
31
  <link rel="stylesheet" href="BookReaderDemo.css"/>
32
+
33
+ <!-- IA scripts -->
34
+ <script src="https://archive.org/bookreader/BookReaderJSIA.js"></script>
35
+
32
36
  </head>
33
37
 
34
38
  <body>
@@ -59,16 +63,94 @@
59
63
  <script id="pageUrl" type="text/javascript"></script>
60
64
 
61
65
  <script>
62
- var ocaid = location.href.match(/ocaid=([^&#]+)/i)[1];
66
+ // gather params here
67
+ const urlParams = new URLSearchParams(window.location.search);
68
+
69
+ const ocaid = urlParams.get('ocaid');
70
+ const openFullImmersionTheater = urlParams.get('view') === 'theater';
71
+ const ui = urlParams.get('ui');
72
+ const autoflip = urlParams.get('autoflip');
73
+ const searchTerm = urlParams.get('q');
63
74
 
64
75
  // Override options coming from IA
65
76
  BookReader.optionOverrides.imagesBaseURL = '/BookReader/images/';
66
77
 
78
+ const initializeBookReader = (brManifest) => {
79
+ console.log('initializeBookReader', brManifest);
80
+ const br = new BookReader();
81
+ const iaBookManifestUrl = '';
82
+
83
+ const customAutoflipParams = {
84
+ autoflip: !!autoflip,
85
+ flipSpeed: urlParams.flipSpeed || 2000,
86
+ flipDelay: urlParams.flipDelay || 5000
87
+ };
88
+
89
+ const options = {
90
+ el: '#BookReader',
91
+ /* Url plugin - IA uses History mode for URL */
92
+ // commenting these out as demo uses hash mode
93
+ // keeping them here for reference
94
+ // urlHistoryBasePath: `/details/{$ocaid}/`,
95
+ // resumeCookiePath: `/details/{$ocaid}/`,
96
+ // urlMode: 'history',
97
+ // Only reflect these params onto the URL
98
+ // urlTrackedParams: ['page', 'search', 'mode'],
99
+ /* End url plugin */
100
+ enableBookTitleLink: false,
101
+ bookUrlText: null,
102
+ startFullscreen: urlParams.view === 'theater',
103
+ initialSearchTerm: searchTerm ? searchTerm : '',
104
+ // leaving this option commented out bc we change given user agent on archive.org
105
+ // onePage: { autofit: <?=json_encode($this->ios ? 'width' : 'auto')?> },
106
+ showToolbar: false,
107
+ /* Multiple volumes */
108
+ // To show multiple volumes:
109
+ enableMultipleBooks: false, // turn this on
110
+ multipleBooksList: [], // populate this // TODO: get sample blob and tie into demo
111
+ /* End multiple volumes */
112
+ };
113
+
114
+ // we want to show item as embedded when ?ui=embed is in URI
115
+ if (ui === 'embed') {
116
+ options.mode = 1;
117
+ options.ui = 'embed';
118
+ }
119
+
120
+ // we expect this at the global level
121
+ BookReaderJSIAinit(brManifest.data, { ...options });
122
+
123
+ if (customAutoflipParams.autoflip) {
124
+ br.autoToggle(customAutoflipParams);
125
+ }
126
+ }
127
+
128
+ const fetchBookManifestAndInitializeBookreader = async (iaMetadata) => {
129
+ const {
130
+ metadata: {
131
+ identifier
132
+ },
133
+ } = iaMetadata;
134
+
135
+ const locator =`https://archive.org/bookreader/BookReaderJSLocate.php?format=json&subPrefix=&id=${identifier}`;
136
+ // Todo: move from `locator` to create `iaManifestUrl` url from `iaMetadata`
137
+ // so we can support multiple volumes
138
+ // const iaManifestUrl = `https://${server}/BookReader/BookReaderJSIA.php?format=jsonp&itemPath=${dir}&id=${identifier}`;
139
+
140
+ const manifest = await fetch(locator)
141
+ .then(response => response.json())
142
+
143
+ initializeBookReader(manifest);
144
+ }
145
+
67
146
  // Temp; Circumvent bug in BookReaderJSIA code
68
147
  window.Sentry = null;
69
-
70
- var script_url = 'https://archive.org/bookreader/BookReaderJSLocate.php?subPrefix=&id=' + ocaid;
71
- document.getElementById('pageUrl').src = script_url;
148
+ window.logError = function(e) {
149
+ console.error(e);
150
+ };
151
+ fetch(`https://archive.org/metadata/${ocaid}`)
152
+ .then(response => response.json())
153
+ .then(iaMetadata => fetchBookManifestAndInitializeBookreader(iaMetadata));
72
154
  </script>
73
155
 
74
156
  </body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@internetarchive/bookreader",
3
- "version": "5.0.0-24-sortingstate-11",
3
+ "version": "5.0.0-24-sortingstate-final",
4
4
  "description": "The Internet Archive BookReader.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -36,14 +36,16 @@ export default class VolumesProvider {
36
36
  this.label = `Viewable files (${this.volumeCount})`;
37
37
  this.icon = html`${volumesIcon}`;
38
38
 
39
+ this.sortOrderBy = sortType.default;
40
+
39
41
  // get sort state from query param
40
- this.bookreader.urlPlugin.pullFromAddressBar();
41
- const urlSortValue = this.bookreader.urlPlugin.getUrlParam('sort');
42
- console.log('urlSortValue: ', urlSortValue);
43
- if (urlSortValue === sortType.title_asc || urlSortValue === sortType.title_desc) {
44
- this.sortOrderBy = urlSortValue;
45
- } else {
46
- this.sortOrderBy = sortType.default;
42
+ if (this.bookreader.urlPlugin) {
43
+ this.bookreader.urlPlugin.pullFromAddressBar();
44
+
45
+ const urlSortValue = this.bookreader.urlPlugin.getUrlParam('sort');
46
+ if (urlSortValue === sortType.title_asc || urlSortValue === sortType.title_desc) {
47
+ this.sortOrderBy = urlSortValue;
48
+ }
47
49
  }
48
50
  this.sortVolumes(this.sortOrderBy);
49
51
  }
@@ -81,17 +83,14 @@ export default class VolumesProvider {
81
83
  this.component.viewableFiles = [...sortedFiles];
82
84
  this.actionButton = this.sortButton;
83
85
 
84
- if (this.sortOrderBy !== sortType.default) {
85
- this.bookreader.urlPlugin.setUrlParam('sort', sortByType);
86
- } else {
87
- this.bookreader.urlPlugin.removeUrlParam('sort');
86
+ if (this.bookreader.urlPlugin) {
87
+ if (this.sortOrderBy !== sortType.default) {
88
+ this.bookreader.urlPlugin.setUrlParam('sort', sortByType);
89
+ } else {
90
+ this.bookreader.urlPlugin.removeUrlParam('sort');
91
+ }
88
92
  }
89
93
 
90
- const urlSchema = this.bookreader.urlPlugin.urlSchema;
91
- const urlState = this.bookreader.urlPlugin.urlState;
92
- this.bookreader.urlPlugin.urlStateToUrlString(urlSchema, urlState);
93
- this.bookreader.urlPlugin.pushToAddressBar();
94
-
95
94
  this.optionChange(this.bookreader);
96
95
 
97
96
  this.multipleFilesClicked(sortByType);
@@ -109,6 +109,10 @@
109
109
  &.visible {
110
110
  display: flex;
111
111
  animation: slideUp 0.2s;
112
+ button {
113
+ width: unset;
114
+ height: unset;
115
+ }
112
116
  }
113
117
 
114
118
  li {
@@ -247,8 +247,8 @@ export class UrlPlugin {
247
247
  .join('/');
248
248
 
249
249
  const strStrippedTrailingSlash = `${strPathParams.replace(/\/$/, '')}`;
250
- const concatenatedPath = `/${strStrippedTrailingSlash}?${searchParams.toString()}`;
251
- return searchParams.toString() ? concatenatedPath : `/${strStrippedTrailingSlash}`;
250
+ const concatenatedPath = `${strStrippedTrailingSlash}?${searchParams.toString()}`;
251
+ return searchParams.toString() ? concatenatedPath : `${strStrippedTrailingSlash}`;
252
252
  }
253
253
 
254
254
  /**
@@ -260,14 +260,11 @@ export class UrlPlugin {
260
260
  * @returns {object}
261
261
  */
262
262
  urlStringToUrlState(urlString) {
263
- console.log('urlString: ', urlString);
264
263
  const urlState = {};
265
264
 
266
- // Fetch searchParams from given {urlString}
267
- // Note: whole URL path is needed for URLSearchParams
265
+ // Fetch searchParams from given {str}
266
+ // Note: whole URL path is needed for URL parsing
268
267
  const urlPath = new URL(urlString, 'http://example.com');
269
- console.log('urlPath: ', urlPath);
270
- console.log('urlSearch: ', urlPath.searchParams, ' urlPath: ', urlPath.pathname);
271
268
  const urlSearchParamsObj = Object.fromEntries(urlPath.searchParams.entries());
272
269
  const urlStrSplitSlashObj = Object.fromEntries(urlPath.pathname
273
270
  .match(/[^\\/]+\/[^\\/]+/g)
@@ -299,11 +296,8 @@ export class UrlPlugin {
299
296
  });
300
297
 
301
298
  // Add searchParams to urlState
302
- // Check if Object value is a Boolean and convert value to Boolean
303
- // Otherwise, return Object value
304
- const isBooleanValue = value => value === 'true' || (value === 'false' ? false : value);
305
299
  Object.entries(urlSearchParamsObj).forEach(([key, value]) => {
306
- urlState[key] = isBooleanValue(value);
300
+ urlState[key] = value;
307
301
  });
308
302
 
309
303
  return urlState;
@@ -346,8 +340,7 @@ export class UrlPlugin {
346
340
  const urlStrPath = this.urlStateToUrlString(this.urlState);
347
341
  if (this.urlMode == 'history') {
348
342
  if (window.history && window.history.replaceState) {
349
- const newUrlPath = `${this.urlHistoryBasePath}${urlStrPath}`;
350
- console.log('newUrlPath: ', newUrlPath);
343
+ const newUrlPath = `${this.urlHistoryBasePath}/${urlStrPath}`;
351
344
  window.history.replaceState({}, null, newUrlPath);
352
345
  }
353
346
  } else {
@@ -386,13 +379,11 @@ export class UrlPlugin {
386
379
  const path = this.urlMode === 'history'
387
380
  ? (location.pathname.substr(this.urlHistoryBasePath.length) + location.search)
388
381
  : location.hash.substr(1);
389
- console.log('path: ', path);
390
382
  this.urlState = this.urlStringToUrlState(path);
391
383
  }
392
384
  }
393
385
 
394
386
  export class BookreaderUrlPlugin extends BookReader {
395
-
396
387
  init() {
397
388
  if (this.options.enableUrlPlugin) {
398
389
  this.urlPlugin = new UrlPlugin(this.options);
@@ -407,7 +398,6 @@ export class BookreaderUrlPlugin extends BookReader {
407
398
 
408
399
  super.init();
409
400
  }
410
-
411
401
  }
412
402
 
413
403
  window.BookReader = BookreaderUrlPlugin;
@@ -23,8 +23,8 @@ describe.only('UrlPlugin tests', () => {
23
23
  const urlState = { page: 'n7', mode: '1up', search: 'foo' };
24
24
  const urlStateWithQueries = { page: 'n7', mode: '1up', q: 'hello', view: 'theater', sort: 'title_asc' };
25
25
 
26
- const expectedUrlFromState = '/page/n7/mode/1up?q=foo';
27
- const expectedUrlFromStateWithQueries = '/page/n7/mode/1up?q=hello&view=theater&sort=title_asc';
26
+ const expectedUrlFromState = 'page/n7/mode/1up?q=foo';
27
+ const expectedUrlFromStateWithQueries = 'page/n7/mode/1up?q=hello&view=theater&sort=title_asc';
28
28
 
29
29
  expect(urlPlugin.urlStateToUrlString(urlState)).toBe(expectedUrlFromState);
30
30
  expect(urlPlugin.urlStateToUrlString(urlStateWithQueries)).toBe(expectedUrlFromStateWithQueries);
@@ -34,16 +34,16 @@ describe.only('UrlPlugin tests', () => {
34
34
  const urlState = { page: 'n7', mode: '1up' };
35
35
  const urlStateWithQueries = { page: 'n7', mode: '1up', q: 'hello', viewer: 'theater', sortBy: 'title_asc' };
36
36
 
37
- const expectedUrlFromState = '/page/n7/mode/1up';
38
- const expectedUrlFromStateWithQueries = '/page/n7/mode/1up?q=hello&viewer=theater&sortBy=title_asc';
37
+ const expectedUrlFromState = 'page/n7/mode/1up';
38
+ const expectedUrlFromStateWithQueries = 'page/n7/mode/1up?q=hello&viewer=theater&sortBy=title_asc';
39
39
 
40
40
  expect(urlPlugin.urlStateToUrlString(urlState)).toBe(expectedUrlFromState);
41
41
  expect(urlPlugin.urlStateToUrlString(urlStateWithQueries)).toBe(expectedUrlFromStateWithQueries);
42
42
  });
43
43
 
44
44
  test('urlStateToUrlString with boolean value', () => {
45
- const urlState = { page: 'n7', mode: '1up', search: 'foo', view: 'theater', wrapper: false };
46
- const expectedUrlFromState = '/page/n7/mode/1up?q=foo&view=theater&wrapper=false';
45
+ const urlState = { page: 'n7', mode: '1up', search: 'foo', view: 'theater', wrapper: 'false' };
46
+ const expectedUrlFromState = 'page/n7/mode/1up?q=foo&view=theater&wrapper=false';
47
47
 
48
48
  expect(urlPlugin.urlStateToUrlString(urlState)).toBe(expectedUrlFromState);
49
49
  });
@@ -72,7 +72,7 @@ describe.only('UrlPlugin tests', () => {
72
72
  {page: 'n7', mode: '2up', q: 'hello', view: 'theather', foo: 'bar', sort: 'title_asc'}
73
73
  );
74
74
  expect(urlPlugin.urlStringToUrlState(url1)).toEqual(
75
- {page: 'n0', mode: '2up', ref: 'ol', ui: 'embed', wrapper: false, view: 'theater'}
75
+ {page: 'n0', mode: '2up', ref: 'ol', ui: 'embed', wrapper: 'false', view: 'theater'}
76
76
  );
77
77
  });
78
78
 
@@ -114,22 +114,22 @@ describe.only('UrlPlugin tests', () => {
114
114
  urlPlugin.urlState = {};
115
115
  urlPlugin.urlMode = 'hash';
116
116
 
117
- urlPlugin.pullFromAddressBar({ pathname: '/page/12', search: '', hash: '' });
117
+ urlPlugin.pullFromAddressBar({ pathname: '', search: '', hash: '#page/12' });
118
118
  expect(urlPlugin.urlState).toEqual({page: '12', mode: '2up'});
119
119
 
120
120
  urlPlugin.pushToAddressBar();
121
- expect(window.location.hash).toEqual('#/page/12/mode/2up');
121
+ expect(window.location.hash).toEqual('#page/12/mode/2up');
122
122
  });
123
123
 
124
124
  test('url with query param', () => {
125
125
  urlPlugin.urlState = {};
126
126
  urlPlugin.urlMode = 'hash';
127
127
 
128
- urlPlugin.pullFromAddressBar({ pathname: '/page/12', search: '?q=hello&view=theater', hash: '' });
128
+ urlPlugin.pullFromAddressBar({ pathname: '', search: '', hash: '#page/12?q=hello&view=theater' });
129
129
  expect(urlPlugin.urlState).toEqual({page: '12', mode: '2up', q: 'hello', view: 'theater'});
130
130
 
131
131
  urlPlugin.pushToAddressBar();
132
- expect(window.location.hash).toEqual('#/page/12/mode/2up?q=hello&view=theater');
132
+ expect(window.location.hash).toEqual('#page/12/mode/2up?q=hello&view=theater');
133
133
  });
134
134
  });
135
135
 
@@ -64,7 +64,7 @@ describe('Volumes Provider', () => {
64
64
  const baseHost = "https://archive.org";
65
65
  const provider = new volumesProvider(baseHost, brOptions, onSortClick);
66
66
 
67
- expect(provider.sortOrderBy).to.equal("orig_sort");
67
+ expect(provider.sortOrderBy).to.equal("default");
68
68
 
69
69
  provider.sortVolumes("title_asc");
70
70
  expect(provider.sortOrderBy).to.equal("title_asc");
@@ -74,8 +74,8 @@ describe('Volumes Provider', () => {
74
74
  expect(provider.sortOrderBy).to.equal("title_desc");
75
75
  expect(provider.sortButton.getHTML()).includes("sort-by desc-icon");
76
76
 
77
- provider.sortVolumes("orig_sort");
78
- expect(provider.sortOrderBy).to.equal("orig_sort");
77
+ provider.sortVolumes("default");
78
+ expect(provider.sortOrderBy).to.equal("default");
79
79
  expect(provider.sortButton.getHTML()).includes("sort-by neutral-icon");
80
80
  });
81
81
 
@@ -88,9 +88,9 @@ describe('Volumes Provider', () => {
88
88
  const files = Object.keys(parsedFiles).map(item => parsedFiles[item]).sort((a, b) => a.orig_sort - b.orig_sort);
89
89
  const origSortTitles = files.map(item => item.title);
90
90
 
91
- provider.sortVolumes("orig_sort");
91
+ provider.sortVolumes("default");
92
92
 
93
- expect(provider.sortOrderBy).to.equal("orig_sort");
93
+ expect(provider.sortOrderBy).to.equal("default");
94
94
  expect(provider.actionButton).to.exist;
95
95
 
96
96
  const providerFileTitles = provider.viewableFiles.map(item => item.title);
@@ -144,7 +144,7 @@ describe('Volumes Provider', () => {
144
144
  const baseHost = "https://archive.org";
145
145
  const provider = new volumesProvider(baseHost, brOptions, onSortClick);
146
146
 
147
- provider.sortOrderBy = 'orig_sort';
147
+ provider.sortOrderBy = 'default';
148
148
  const origSortButton = await fixture(provider.sortButton);
149
149
  expect(origSortButton.classList.contains('neutral-icon')).to.be.true;
150
150