@internetarchive/bookreader 5.0.0-67 → 5.0.0-68

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. package/BookReader/BookReader.css +53 -891
  2. package/BookReader/BookReader.js +1 -1
  3. package/BookReader/BookReader.js.map +1 -1
  4. package/BookReader/ia-bookreader-bundle.js +50 -48
  5. package/BookReader/ia-bookreader-bundle.js.map +1 -1
  6. package/BookReader/plugins/plugin.autoplay.js +1 -1
  7. package/BookReader/plugins/plugin.autoplay.js.map +1 -1
  8. package/BookReader/plugins/plugin.chapters.js +1 -1
  9. package/BookReader/plugins/plugin.chapters.js.map +1 -1
  10. package/BookReader/plugins/plugin.search.js +1 -1
  11. package/BookReader/plugins/plugin.search.js.map +1 -1
  12. package/BookReader/plugins/plugin.text_selection.js +1 -1
  13. package/BookReader/plugins/plugin.text_selection.js.map +1 -1
  14. package/BookReader/plugins/plugin.tts.js +1 -1
  15. package/BookReader/plugins/plugin.tts.js.map +1 -1
  16. package/BookReaderDemo/BookReaderDemo.css +0 -18
  17. package/BookReaderDemo/BookReaderJSAdvanced.js +0 -3
  18. package/BookReaderDemo/demo-autoplay.html +0 -2
  19. package/BookReaderDemo/demo-fullscreen-mobile.html +1 -4
  20. package/BookReaderDemo/demo-fullscreen.html +0 -3
  21. package/BookReaderDemo/demo-iiif.js +0 -1
  22. package/BookReaderDemo/demo-vendor-fullscreen.html +0 -3
  23. package/BookReaderDemo/immersion-1up.html +0 -1
  24. package/BookReaderDemo/immersion-mode.html +0 -3
  25. package/CHANGELOG.md +5 -0
  26. package/package.json +7 -8
  27. package/src/BookReader/BookModel.js +0 -12
  28. package/src/BookReader/Mode1Up.js +1 -1
  29. package/src/BookReader/Mode1UpLit.js +1 -1
  30. package/src/BookReader/events.js +0 -1
  31. package/src/BookReader.js +1 -2
  32. package/src/css/BookReader.scss +1 -5
  33. package/src/css/_BRnav.scss +0 -8
  34. package/src/plugins/plugin.autoplay.js +1 -2
  35. package/src/plugins/search/plugin.search.js +0 -3
  36. package/tests/e2e/base.test.js +3 -11
  37. package/tests/e2e/helpers/base.js +26 -26
  38. package/tests/e2e/helpers/rightToLeft.js +4 -4
  39. package/tests/e2e/helpers/{desktopSearch.js → search.js} +19 -19
  40. package/tests/e2e/models/Navigation.js +16 -42
  41. package/tests/e2e/viewmode.test.js +3 -3
  42. package/tests/jest/plugins/plugin.chapters.test.js +0 -1
  43. package/tests/jest/plugins/search/plugin.search.view.test.js +0 -1
  44. package/webpack.config.js +0 -1
  45. package/BookReader/plugins/plugin.mobile_nav.js +0 -2
  46. package/BookReader/plugins/plugin.mobile_nav.js.map +0 -1
  47. package/src/css/_MobileNav.scss +0 -168
  48. package/src/plugins/plugin.mobile_nav.js +0 -288
  49. package/tests/e2e/helpers/mobileSearch.js +0 -85
  50. package/tests/jest/plugins/plugin.mobile_nav.test.js +0 -66
@@ -1,288 +0,0 @@
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
- };
@@ -1,85 +0,0 @@
1
- import { ClientFunction, RequestMock } from 'testcafe';
2
- import { SEARCH_INSIDE_URL_RE , mockResponseFound, mockResponseNotFound,
3
- TEST_TEXT_FOUND, TEST_TEXT_NOT_FOUND, PAGE_FIRST_RESULT } from './mockSearch';
4
-
5
-
6
- export function runMobileSearchTests(br) {
7
- //building mock response for successful and unsuccessful search
8
- const mockFound = RequestMock()
9
- .onRequestTo(SEARCH_INSIDE_URL_RE )
10
- .respond(mockResponseFound, 202);
11
-
12
- const mockNotFound = RequestMock()
13
- .onRequestTo(SEARCH_INSIDE_URL_RE )
14
- .respond(mockResponseNotFound, 202);
15
-
16
- test
17
- .requestHooks(mockFound)('Mobile search - successful search', async t => {
18
- await t.resizeWindowToFitDevice('Sony Xperia Z', {portraitOrientation: true});
19
- const nav = br.nav.mobile;
20
-
21
- //opening side menu and search
22
- await t.expect(nav.hamburgerButton.visible).ok();
23
- await t.click(nav.hamburgerButton);
24
- await t.expect(nav.menuSearchButton.visible).ok();
25
- await t.click(nav.menuSearchButton);
26
-
27
- //assuring that the search bar is enabled
28
- await t.expect(nav.searchBox.visible).ok();
29
-
30
- //testing successful search
31
- await t
32
- .selectText(nav.searchBox.find('[name="query"]'))
33
- .pressKey('delete');
34
- await t
35
- .typeText(nav.searchBox.find('[name="query"]'), TEST_TEXT_FOUND)
36
- .pressKey('enter');
37
- await t.expect(nav.searchResults.visible).ok();
38
- await t.expect(nav.searchResultText.exists).ok();
39
- await t.expect(nav.searchResultText.innerText).contains(TEST_TEXT_FOUND);
40
-
41
- //checking url
42
- const getPageUrl = ClientFunction(() => window.location.href);
43
- await t.expect(getPageUrl()).contains(TEST_TEXT_FOUND);
44
-
45
- //checks clicking on first search result opens correct page
46
- await t.click(nav.searchResults.child(0));
47
- await t.expect(getPageUrl()).contains(PAGE_FIRST_RESULT);
48
-
49
- //checks highlight on result page is visible
50
- const highlight = br.shell.find(".searchHiliteLayer rect");
51
- await t.expect(highlight.visible).ok();
52
-
53
- await t.maximizeWindow();
54
- });
55
-
56
- test
57
- .requestHooks(mockNotFound)('Mobile search - unsuccessful search', async t => {
58
- await t.resizeWindowToFitDevice('Sony Xperia Z', {portraitOrientation: true});
59
- const nav = br.nav.mobile;
60
-
61
- //opening side menu and search
62
- await t.expect(nav.hamburgerButton.visible).ok();
63
- await t.click(nav.hamburgerButton);
64
- await t.expect(nav.menuSearchButton.visible).ok();
65
- await t.click(nav.menuSearchButton);
66
-
67
- //assuring that the search bar is enabled
68
- await t.expect(nav.searchBox.visible).ok();
69
-
70
- //testing unsuccessful search
71
- await t
72
- .selectText(nav.searchBox.find('[name="query"]'))
73
- .pressKey('delete');
74
- await t
75
- .typeText(nav.searchBox.find('[name="query"]'), TEST_TEXT_NOT_FOUND)
76
- .pressKey('enter');
77
- await t.expect(nav.searchResultText.withText(TEST_TEXT_NOT_FOUND).exists).notOk();
78
-
79
- //checking url
80
- const getPageUrl = ClientFunction(() => window.location.href.toString());
81
- await t.expect(getPageUrl()).contains(TEST_TEXT_NOT_FOUND);
82
- await t.maximizeWindow();
83
- });
84
-
85
- }
@@ -1,66 +0,0 @@
1
-
2
- import BookReader from '@/src/BookReader.js';
3
- import '@/src/plugins/plugin.mobile_nav.js';
4
-
5
- /** @type {BookReader} */
6
- let br;
7
- beforeEach(() => {
8
- document.body.innerHTML = '<div id="BookReader">';
9
- br = new BookReader();
10
- br.init();
11
- });
12
-
13
- afterEach(() => {
14
- jest.clearAllMocks();
15
- });
16
-
17
- describe('Plugin: Mobile Nav', () => {
18
- test('has option flag', () => {
19
- expect(BookReader.defaultOptions.enableMobileNav).toEqual(true);
20
- });
21
- test('has added BR property: mobileNavTitle', () => {
22
- expect(br).toHaveProperty('mobileNavTitle');
23
- expect(br.mobileNavTitle).toBeTruthy();
24
- });
25
- test('has added BR property: mobileNavFullscreenOnly', () => {
26
- expect(br).toHaveProperty('mobileNavFullscreenOnly');
27
- expect(br.mobileNavFullscreenOnly).toEqual(false);
28
- });
29
- test('has a referenced copy of nav in BookReader', () => {
30
- expect(br.refs).toHaveProperty('$mmenu');
31
- });
32
- test('draws toolbar on init', () => {
33
- let callCount = 0;
34
- // Since we have a custom setter set in utils/classes.js, we can't
35
- // use regular spying; need to "override" the function with a watcher.
36
- BookReader.prototype.initToolbar = function(_super) {
37
- return function() {
38
- callCount++;
39
- _super.apply(this, arguments);
40
- };
41
- }(BookReader.prototype.initToolbar);
42
- const br = new BookReader();
43
- br.init();
44
- expect(callCount).toBe(1);
45
- });
46
- test('sets a class on body to signal it has attached', () => {
47
- expect($(document.body).hasClass('BRbodyMobileNavEnabled')).toEqual(true);
48
- });
49
- test('loads the navbar on init', () => {
50
- expect($('#BRmobileMenu')).toHaveLength(1);
51
- });
52
- test('There is a Settings Section', () => {
53
- expect($('.BRmobileMenu__settings')).toHaveLength(1);
54
- });
55
- test('There is a More Info Section', () => {
56
- expect($('.BRmobileMenu__moreInfoRow')).toHaveLength(1);
57
- });
58
- test('There is a Sharing Section', () => {
59
- expect($('.BRmobileMenu__share')).toHaveLength(1);
60
- });
61
- test('clicking on hamburger opens menu', () => {
62
- expect($('html').hasClass('mm-opened')).toEqual(false);
63
- $('.BRmobileHamburger').trigger("click");
64
- expect($('html').hasClass('mm-opened')).toEqual(true);
65
- });
66
- });