@internetarchive/bookreader 5.0.0-35 → 5.0.0-36
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.
- package/.eslintrc.js +1 -11
- package/BookReader/BookReader.js +1 -1
- package/BookReader/BookReader.js.map +1 -1
- package/BookReader/ia-bookreader-bundle.js +25 -25
- package/BookReader/ia-bookreader-bundle.js.map +1 -1
- package/BookReader/plugins/plugin.tts.js +1 -1
- package/BookReader/plugins/plugin.tts.js.map +1 -1
- package/CHANGELOG.md +7 -0
- package/package.json +1 -1
- package/src/BookNavigator/book-navigator.js +7 -1
- package/src/BookNavigator/bookmarks/ia-bookmarks.js +26 -27
- package/src/BookNavigator/search/search-provider.js +2 -2
- package/src/BookReader.js +55 -55
- package/src/ia-bookreader/ia-bookreader.js +4 -1
- package/src/plugins/tts/AbstractTTSEngine.js +31 -34
- package/src/plugins/tts/PageChunkIterator.js +8 -12
- package/src/plugins/tts/WebTTSEngine.js +41 -46
- package/src/plugins/tts/plugin.tts.js +16 -10
- package/tests/e2e/base.test.js +7 -4
- package/tests/e2e/helpers/params.js +1 -1
- package/tests/e2e/viewmode.test.js +30 -30
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# 5.0.0-36
|
|
2
|
+
Fix: Readaloud scrolls along with dext @cdrini
|
|
3
|
+
Dev: ES6 var to let/const updates @sancodes
|
|
4
|
+
Dev: ES6 async/await updates @sancodes
|
|
5
|
+
Dev: Re-enable testcafe tests in GH action @iisa
|
|
6
|
+
Fix: Search results bar clears and closes properly @iisa
|
|
7
|
+
|
|
1
8
|
# 5.0.0-35
|
|
2
9
|
Fix: global syle leak specify colorbox styles @iisa
|
|
3
10
|
Fix: br menu reinits with shared ro load @iisa
|
package/package.json
CHANGED
|
@@ -185,13 +185,19 @@ export class BookNavigator extends LitElement {
|
|
|
185
185
|
/* refresh br instance reference */
|
|
186
186
|
this.bookreader = brInstance;
|
|
187
187
|
}
|
|
188
|
+
|
|
189
|
+
this.updateMenuContents();
|
|
190
|
+
|
|
191
|
+
if (searchUpdates.openMenu === false) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
188
195
|
if (this.isWideEnoughToOpenMenu && !searchUpdates?.searchCanceled) {
|
|
189
196
|
/* open side search menu */
|
|
190
197
|
setTimeout(() => {
|
|
191
198
|
this.updateSideMenu('search', 'open');
|
|
192
199
|
}, 0);
|
|
193
200
|
}
|
|
194
|
-
this.updateMenuContents();
|
|
195
201
|
},
|
|
196
202
|
});
|
|
197
203
|
}
|
|
@@ -229,36 +229,35 @@ class IABookmarks extends LitElement {
|
|
|
229
229
|
return bookmark;
|
|
230
230
|
}
|
|
231
231
|
|
|
232
|
-
fetchBookmarks() {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
return response;
|
|
241
|
-
}).then((response) => {
|
|
242
|
-
const {
|
|
243
|
-
success,
|
|
244
|
-
error = 'Something happened while fetching bookmarks.',
|
|
245
|
-
value: bkmrks = [],
|
|
246
|
-
} = response;
|
|
247
|
-
if (!success) {
|
|
248
|
-
console?.warn('Error fetching bookmarks', error);
|
|
249
|
-
}
|
|
232
|
+
async fetchBookmarks() {
|
|
233
|
+
const resText = await this.api.getAll().then(r=> r.text());
|
|
234
|
+
let parsedResponse;
|
|
235
|
+
try {
|
|
236
|
+
parsedResponse = JSON.parse(resText);
|
|
237
|
+
} catch (e) {
|
|
238
|
+
parsedResponse = {error : e.message};
|
|
239
|
+
}
|
|
250
240
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
bookmarks[leafNum] = formattedBookmark;
|
|
257
|
-
});
|
|
241
|
+
const {
|
|
242
|
+
success,
|
|
243
|
+
error = 'Something happened while fetching bookmarks.',
|
|
244
|
+
value: bkmrks = [],
|
|
245
|
+
} = parsedResponse;
|
|
258
246
|
|
|
259
|
-
|
|
260
|
-
|
|
247
|
+
if (!success) {
|
|
248
|
+
console?.warn('Error fetching bookmarks', error);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const bookmarks = {};
|
|
252
|
+
Object.keys(bkmrks).forEach((leafNum) => {
|
|
253
|
+
const bookmark = bkmrks[leafNum];
|
|
254
|
+
const formattedLeafNum = parseInt(leafNum, 10);
|
|
255
|
+
const formattedBookmark = this.formatBookmark({ ...bookmark, leafNum: formattedLeafNum });
|
|
256
|
+
bookmarks[leafNum] = formattedBookmark;
|
|
261
257
|
});
|
|
258
|
+
|
|
259
|
+
this.bookmarks = bookmarks;
|
|
260
|
+
return bookmarks;
|
|
262
261
|
}
|
|
263
262
|
|
|
264
263
|
emitBookmarksChanged() {
|
|
@@ -144,8 +144,8 @@ export default class SearchProvider {
|
|
|
144
144
|
queryInProgress: false,
|
|
145
145
|
errorMessage: '',
|
|
146
146
|
};
|
|
147
|
-
this.updateMenu();
|
|
148
|
-
this.bookreader?.searchView?.clearSearchFieldAndResults();
|
|
147
|
+
this.updateMenu({ openMenu: false });
|
|
148
|
+
this.bookreader?.searchView?.clearSearchFieldAndResults(false);
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
/**
|
package/src/BookReader.js
CHANGED
|
@@ -333,9 +333,9 @@ BookReader.util = utils;
|
|
|
333
333
|
* @private
|
|
334
334
|
*/
|
|
335
335
|
BookReader.prototype.extendParams = function(params, newParams) {
|
|
336
|
-
|
|
336
|
+
const modifiedNewParams = $.extend({}, newParams);
|
|
337
337
|
if ('undefined' != typeof(modifiedNewParams.page)) {
|
|
338
|
-
|
|
338
|
+
const pageIndex = this._models.book.parsePageString(modifiedNewParams.page);
|
|
339
339
|
if (!isNaN(pageIndex))
|
|
340
340
|
modifiedNewParams.index = pageIndex;
|
|
341
341
|
delete modifiedNewParams.page;
|
|
@@ -349,7 +349,7 @@ BookReader.prototype.extendParams = function(params, newParams) {
|
|
|
349
349
|
* @return {object} the parsed params
|
|
350
350
|
*/
|
|
351
351
|
BookReader.prototype.initParams = function() {
|
|
352
|
-
|
|
352
|
+
const params = {};
|
|
353
353
|
// Flag initializing for updateFromParams()
|
|
354
354
|
params.init = true;
|
|
355
355
|
|
|
@@ -398,7 +398,7 @@ BookReader.prototype.initParams = function() {
|
|
|
398
398
|
// Check for URL plugin
|
|
399
399
|
if (this.options.enableUrlPlugin) {
|
|
400
400
|
// Params explicitly set in URL take precedence over all other methods
|
|
401
|
-
|
|
401
|
+
let urlParams = this.paramsFromFragment(this.urlReadFragment());
|
|
402
402
|
|
|
403
403
|
// Get params if hash fragment available with 'history' urlMode
|
|
404
404
|
const hasHashURL = !Object.keys(urlParams).length && this.urlReadHashFragment();
|
|
@@ -481,8 +481,8 @@ BookReader.prototype.readQueryString = function() {
|
|
|
481
481
|
*/
|
|
482
482
|
BookReader.prototype.getInitialMode = function(params) {
|
|
483
483
|
// Use params or browser width to set view mode
|
|
484
|
-
|
|
485
|
-
|
|
484
|
+
const windowWidth = $(window).width();
|
|
485
|
+
let nextMode;
|
|
486
486
|
if ('undefined' != typeof(params.mode)) {
|
|
487
487
|
nextMode = params.mode;
|
|
488
488
|
} else if (this.ui == 'full'
|
|
@@ -509,7 +509,7 @@ BookReader.prototype.init = function() {
|
|
|
509
509
|
this.init.initComplete = false;
|
|
510
510
|
this.pageScale = this.reduce; // preserve current reduce
|
|
511
511
|
|
|
512
|
-
|
|
512
|
+
const params = this.initParams();
|
|
513
513
|
|
|
514
514
|
this.firstIndex = params.index ? params.index : 0;
|
|
515
515
|
|
|
@@ -653,8 +653,8 @@ BookReader.prototype.resize = function() {
|
|
|
653
653
|
} else {
|
|
654
654
|
// used when zoomed in
|
|
655
655
|
// Re-center if the scrollbars have disappeared
|
|
656
|
-
|
|
657
|
-
|
|
656
|
+
const center = this.twoPageGetViewCenter();
|
|
657
|
+
let doRecenter = false;
|
|
658
658
|
if (this.twoPage.totalWidth < this.refs.$brContainer.prop('clientWidth')) {
|
|
659
659
|
center.percentageX = 0.5;
|
|
660
660
|
doRecenter = true;
|
|
@@ -816,8 +816,8 @@ BookReader.prototype.bindGestures = function(jElement) {
|
|
|
816
816
|
// when you move the book with one finger and then add another
|
|
817
817
|
// finger to pinch. Gestures are aware of scroll state.
|
|
818
818
|
|
|
819
|
-
|
|
820
|
-
|
|
819
|
+
const self = this;
|
|
820
|
+
let numTouches = 1;
|
|
821
821
|
|
|
822
822
|
jElement.unbind('touchmove').bind('touchmove', function(e) {
|
|
823
823
|
if (e.originalEvent.cancelable) numTouches = e.originalEvent.touches.length;
|
|
@@ -901,8 +901,8 @@ BookReader.prototype.resizeBRcontainer = function(animate) {
|
|
|
901
901
|
};
|
|
902
902
|
|
|
903
903
|
BookReader.prototype.centerPageView = function() {
|
|
904
|
-
|
|
905
|
-
|
|
904
|
+
const scrollWidth = this.refs.$brContainer.prop('scrollWidth');
|
|
905
|
+
const clientWidth = this.refs.$brContainer.prop('clientWidth');
|
|
906
906
|
if (scrollWidth > clientWidth) {
|
|
907
907
|
this.refs.$brContainer.prop('scrollLeft', (scrollWidth - clientWidth) / 2);
|
|
908
908
|
}
|
|
@@ -990,7 +990,7 @@ BookReader.prototype._reduceSort = (a, b) => a.reduce - b.reduce;
|
|
|
990
990
|
* @return {boolean} Returns true if page could be found, false otherwise.
|
|
991
991
|
*/
|
|
992
992
|
BookReader.prototype.jumpToPage = function(pageNum) {
|
|
993
|
-
|
|
993
|
+
const pageIndex = this._models.book.parsePageString(pageNum);
|
|
994
994
|
|
|
995
995
|
if ('undefined' != typeof(pageIndex)) {
|
|
996
996
|
this.jumpToIndex(pageIndex);
|
|
@@ -1119,14 +1119,14 @@ BookReader.prototype.switchMode = function(
|
|
|
1119
1119
|
if (!(this.suppressFragmentChange || suppressFragmentChange)) {
|
|
1120
1120
|
this.trigger(BookReader.eventNames.fragmentChange);
|
|
1121
1121
|
}
|
|
1122
|
-
|
|
1122
|
+
const eventName = mode + 'PageViewSelected';
|
|
1123
1123
|
this.trigger(BookReader.eventNames[eventName]);
|
|
1124
1124
|
|
|
1125
1125
|
this.textSelectionPlugin?.stopPageFlip(this.refs.$brContainer);
|
|
1126
1126
|
};
|
|
1127
1127
|
|
|
1128
1128
|
BookReader.prototype.updateBrClasses = function() {
|
|
1129
|
-
|
|
1129
|
+
const modeToClass = {};
|
|
1130
1130
|
modeToClass[this.constMode1up] = 'BRmode1up';
|
|
1131
1131
|
modeToClass[this.constMode2up] = 'BRmode2Up';
|
|
1132
1132
|
modeToClass[this.constModeThumb] = 'BRmodeThumb';
|
|
@@ -1222,7 +1222,7 @@ BookReader.prototype.exitFullScreen = async function () {
|
|
|
1222
1222
|
|
|
1223
1223
|
$(document).off('keyup', this._fullscreenCloseHandler);
|
|
1224
1224
|
|
|
1225
|
-
|
|
1225
|
+
const windowWidth = $(window).width();
|
|
1226
1226
|
|
|
1227
1227
|
const canShow2up = this.options.controls.twoPage.visible;
|
|
1228
1228
|
if (canShow2up && (windowWidth <= this.onePageMinBreakpoint)) {
|
|
@@ -1706,7 +1706,7 @@ BookReader.prototype.bindNavigationHandlers = function() {
|
|
|
1706
1706
|
},
|
|
1707
1707
|
full: () => {
|
|
1708
1708
|
if (this.ui == 'embed') {
|
|
1709
|
-
|
|
1709
|
+
const url = this.$('.BRembedreturn a').attr('href');
|
|
1710
1710
|
window.open(url);
|
|
1711
1711
|
} else {
|
|
1712
1712
|
this.toggleFullscreen();
|
|
@@ -1725,12 +1725,12 @@ BookReader.prototype.bindNavigationHandlers = function() {
|
|
|
1725
1725
|
});
|
|
1726
1726
|
}
|
|
1727
1727
|
|
|
1728
|
-
|
|
1729
|
-
|
|
1728
|
+
const $brNavCntlBtmEl = this.$('.BRnavCntlBtm');
|
|
1729
|
+
const $brNavCntlTopEl = this.$('.BRnavCntlTop');
|
|
1730
1730
|
|
|
1731
1731
|
this.$('.BRnavCntl').click(
|
|
1732
1732
|
function() {
|
|
1733
|
-
|
|
1733
|
+
const promises = [];
|
|
1734
1734
|
// TODO don't use magic constants
|
|
1735
1735
|
// TODO move this to a function
|
|
1736
1736
|
if ($brNavCntlBtmEl.hasClass('BRdn')) {
|
|
@@ -1827,7 +1827,7 @@ BookReader.prototype.navigationMousemoveHandler = function(event) {
|
|
|
1827
1827
|
if (event.data['br'].uiAutoHide) {
|
|
1828
1828
|
// 77px is an approximate height of the Internet Archive Top Nav
|
|
1829
1829
|
// 75 & 76 (pixels) provide used in this context is checked against the IA top nav height
|
|
1830
|
-
|
|
1830
|
+
const navkey = $(document).height() - 75;
|
|
1831
1831
|
if ((event.pageY < 76) || (event.pageY > navkey)) {
|
|
1832
1832
|
// inside or near navigation elements
|
|
1833
1833
|
event.data['br'].hideNavigation();
|
|
@@ -1858,7 +1858,7 @@ BookReader.prototype.initSwipeData = function(clientX, clientY) {
|
|
|
1858
1858
|
};
|
|
1859
1859
|
|
|
1860
1860
|
BookReader.prototype.swipeMousedownHandler = function(event) {
|
|
1861
|
-
|
|
1861
|
+
const self = event.data['br'];
|
|
1862
1862
|
|
|
1863
1863
|
// We should be the last bubble point for the page images
|
|
1864
1864
|
// Disable image drag and select, but keep right-click
|
|
@@ -1888,8 +1888,8 @@ BookReader.prototype.swipeMousedownHandler = function(event) {
|
|
|
1888
1888
|
};
|
|
1889
1889
|
|
|
1890
1890
|
BookReader.prototype.swipeMousemoveHandler = function(event) {
|
|
1891
|
-
|
|
1892
|
-
|
|
1891
|
+
const self = event.data['br'];
|
|
1892
|
+
const _swipe = self._swipe;
|
|
1893
1893
|
if (! _swipe.mightBeSwiping) {
|
|
1894
1894
|
return;
|
|
1895
1895
|
}
|
|
@@ -1899,12 +1899,12 @@ BookReader.prototype.swipeMousemoveHandler = function(event) {
|
|
|
1899
1899
|
_swipe.deltaY = event.clientY - _swipe.startY;
|
|
1900
1900
|
_swipe.deltaT = (new Date).getTime() - _swipe.startTime;
|
|
1901
1901
|
|
|
1902
|
-
|
|
1903
|
-
|
|
1902
|
+
const absX = Math.abs(_swipe.deltaX);
|
|
1903
|
+
const absY = Math.abs(_swipe.deltaY);
|
|
1904
1904
|
|
|
1905
1905
|
// Minimum distance in the amount of tim to trigger the swipe
|
|
1906
|
-
|
|
1907
|
-
|
|
1906
|
+
const minSwipeLength = Math.min(self.refs.$br.width() / 5, 80);
|
|
1907
|
+
const maxSwipeTime = 400;
|
|
1908
1908
|
|
|
1909
1909
|
// Check for horizontal swipe
|
|
1910
1910
|
if (absX > absY && (absX > minSwipeLength) && _swipe.deltaT < maxSwipeTime) {
|
|
@@ -1938,7 +1938,7 @@ BookReader.prototype.swipeMousemoveHandler = function(event) {
|
|
|
1938
1938
|
};
|
|
1939
1939
|
|
|
1940
1940
|
BookReader.prototype.swipeMouseupHandler = function(event) {
|
|
1941
|
-
|
|
1941
|
+
const _swipe = event.data['br']._swipe;
|
|
1942
1942
|
_swipe.mightBeSwiping = false;
|
|
1943
1943
|
_swipe.mightBeDragging = false;
|
|
1944
1944
|
|
|
@@ -1955,7 +1955,7 @@ BookReader.prototype.swipeMouseupHandler = function(event) {
|
|
|
1955
1955
|
};
|
|
1956
1956
|
|
|
1957
1957
|
BookReader.prototype.bindMozTouchHandlers = function() {
|
|
1958
|
-
|
|
1958
|
+
const self = this;
|
|
1959
1959
|
|
|
1960
1960
|
// Currently only want touch handlers in 2up
|
|
1961
1961
|
this.refs.$br
|
|
@@ -1982,8 +1982,8 @@ BookReader.prototype.bindMozTouchHandlers = function() {
|
|
|
1982
1982
|
*/
|
|
1983
1983
|
BookReader.prototype.navigationIsVisible = function() {
|
|
1984
1984
|
// $$$ doesn't account for transitioning states, nav must be fully visible to return true
|
|
1985
|
-
|
|
1986
|
-
|
|
1985
|
+
const toolpos = this.refs.$BRtoolbar.position();
|
|
1986
|
+
const tooltop = toolpos.top;
|
|
1987
1987
|
return tooltop == 0;
|
|
1988
1988
|
};
|
|
1989
1989
|
|
|
@@ -1992,19 +1992,19 @@ BookReader.prototype.navigationIsVisible = function() {
|
|
|
1992
1992
|
* Defaults to SHOW the navigation chrome
|
|
1993
1993
|
*/
|
|
1994
1994
|
BookReader.prototype.setNavigationView = function brSetNavigationView(hide) {
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1995
|
+
const animationLength = this.constNavAnimationDuration;
|
|
1996
|
+
const animationType = 'linear';
|
|
1997
|
+
const resizePageContainer = function resizePageContainer () {
|
|
1998
1998
|
/* main page container fills whole container */
|
|
1999
1999
|
if (this.constMode2up !== this.mode) {
|
|
2000
|
-
|
|
2000
|
+
const animate = true;
|
|
2001
2001
|
this.resizeBRcontainer(animate);
|
|
2002
2002
|
}
|
|
2003
2003
|
this.trigger(BookReader.eventNames.navToggled);
|
|
2004
2004
|
}.bind(this);
|
|
2005
2005
|
|
|
2006
|
-
|
|
2007
|
-
|
|
2006
|
+
let toolbarHeight = 0;
|
|
2007
|
+
let navbarHeight = 0;
|
|
2008
2008
|
if (hide) {
|
|
2009
2009
|
toolbarHeight = this.getToolBarHeight() * -1;
|
|
2010
2010
|
navbarHeight = this.getFooterHeight() * -1;
|
|
@@ -2035,7 +2035,7 @@ BookReader.prototype.setNavigationView = function brSetNavigationView(hide) {
|
|
|
2035
2035
|
BookReader.prototype.hideNavigation = function() {
|
|
2036
2036
|
// Check if navigation is showing
|
|
2037
2037
|
if (this.navigationIsVisible()) {
|
|
2038
|
-
|
|
2038
|
+
const hide = true;
|
|
2039
2039
|
this.setNavigationView(hide);
|
|
2040
2040
|
}
|
|
2041
2041
|
};
|
|
@@ -2086,7 +2086,7 @@ BookReader.prototype.firstDisplayableIndex = function() {
|
|
|
2086
2086
|
*/
|
|
2087
2087
|
BookReader.prototype.lastDisplayableIndex = function() {
|
|
2088
2088
|
|
|
2089
|
-
|
|
2089
|
+
const lastIndex = this._models.book.getNumLeafs() - 1;
|
|
2090
2090
|
|
|
2091
2091
|
if (this.mode != this.constMode2up) {
|
|
2092
2092
|
return lastIndex;
|
|
@@ -2325,7 +2325,7 @@ BookReader.prototype.initUIStrings = function() {
|
|
|
2325
2325
|
// the toolbar and nav bar easier
|
|
2326
2326
|
|
|
2327
2327
|
// Setup tooltips -- later we could load these from a file for i18n
|
|
2328
|
-
|
|
2328
|
+
const titles = {
|
|
2329
2329
|
'.logo': 'Go to Archive.org', // $$$ update after getting OL record
|
|
2330
2330
|
'.zoom_in': 'Zoom in',
|
|
2331
2331
|
'.zoom_out': 'Zoom out',
|
|
@@ -2357,7 +2357,7 @@ BookReader.prototype.initUIStrings = function() {
|
|
|
2357
2357
|
titles['.book_rightmost'] = 'First page';
|
|
2358
2358
|
}
|
|
2359
2359
|
|
|
2360
|
-
for (
|
|
2360
|
+
for (const icon in titles) {
|
|
2361
2361
|
this.$(icon).prop('title', titles[icon]);
|
|
2362
2362
|
}
|
|
2363
2363
|
};
|
|
@@ -2368,7 +2368,7 @@ BookReader.prototype.initUIStrings = function() {
|
|
|
2368
2368
|
BookReader.prototype.reloadImages = function() {
|
|
2369
2369
|
this.refs.$brContainer.find('img').each(function(index, elem) {
|
|
2370
2370
|
if (!elem.complete || elem.naturalHeight === 0) {
|
|
2371
|
-
|
|
2371
|
+
const src = elem.src;
|
|
2372
2372
|
elem.src = '';
|
|
2373
2373
|
setTimeout(function() {
|
|
2374
2374
|
elem.src = src;
|
|
@@ -2382,10 +2382,10 @@ BookReader.prototype.reloadImages = function() {
|
|
|
2382
2382
|
* @return {number}
|
|
2383
2383
|
*/
|
|
2384
2384
|
BookReader.prototype.getFooterHeight = function() {
|
|
2385
|
-
|
|
2385
|
+
const $heightEl = this.mode == this.constMode2up ? this.refs.$BRfooter : this.refs.$BRnav;
|
|
2386
2386
|
if ($heightEl && this.refs.$BRfooter) {
|
|
2387
|
-
|
|
2388
|
-
|
|
2387
|
+
const outerHeight = $heightEl.outerHeight();
|
|
2388
|
+
const bottom = parseInt(this.refs.$BRfooter.css('bottom'));
|
|
2389
2389
|
if (!isNaN(outerHeight) && !isNaN(bottom)) {
|
|
2390
2390
|
return outerHeight + bottom;
|
|
2391
2391
|
}
|
|
@@ -2401,11 +2401,11 @@ BookReader.prototype.getFooterHeight = function() {
|
|
|
2401
2401
|
* @return {Object}
|
|
2402
2402
|
*/
|
|
2403
2403
|
BookReader.prototype.paramsFromCurrent = function() {
|
|
2404
|
-
|
|
2404
|
+
const params = {};
|
|
2405
2405
|
|
|
2406
2406
|
// Path params
|
|
2407
|
-
|
|
2408
|
-
|
|
2407
|
+
const index = this.currentIndex();
|
|
2408
|
+
const pageNum = this._models.book.getPageNum(index);
|
|
2409
2409
|
if ((pageNum === 0) || pageNum) {
|
|
2410
2410
|
params.page = pageNum;
|
|
2411
2411
|
}
|
|
@@ -2444,7 +2444,7 @@ BookReader.prototype.paramsFromCurrent = function() {
|
|
|
2444
2444
|
* @return {Object}
|
|
2445
2445
|
*/
|
|
2446
2446
|
BookReader.prototype.paramsFromFragment = function(fragment) {
|
|
2447
|
-
|
|
2447
|
+
const params = {};
|
|
2448
2448
|
|
|
2449
2449
|
// For backwards compatibility we allow an initial # character
|
|
2450
2450
|
// (as from window.location.hash) but don't require it
|
|
@@ -2453,7 +2453,7 @@ BookReader.prototype.paramsFromFragment = function(fragment) {
|
|
|
2453
2453
|
}
|
|
2454
2454
|
|
|
2455
2455
|
// Simple #nn syntax
|
|
2456
|
-
|
|
2456
|
+
const oldStyleLeafNum = parseInt( /^\d+$/.exec(fragment) );
|
|
2457
2457
|
if ( !isNaN(oldStyleLeafNum) ) {
|
|
2458
2458
|
params.index = oldStyleLeafNum;
|
|
2459
2459
|
|
|
@@ -2462,9 +2462,9 @@ BookReader.prototype.paramsFromFragment = function(fragment) {
|
|
|
2462
2462
|
}
|
|
2463
2463
|
|
|
2464
2464
|
// Split into key-value pairs
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
for (
|
|
2465
|
+
const urlArray = fragment.split('/');
|
|
2466
|
+
const urlHash = {};
|
|
2467
|
+
for (let i = 0; i < urlArray.length; i += 2) {
|
|
2468
2468
|
urlHash[urlArray[i]] = urlArray[i + 1];
|
|
2469
2469
|
}
|
|
2470
2470
|
|
|
@@ -40,6 +40,7 @@ export class IaBookReader extends LitElement {
|
|
|
40
40
|
this.loaded = false;
|
|
41
41
|
this.menuShortcuts = [];
|
|
42
42
|
this.menuContents = [];
|
|
43
|
+
this.openMenuName = '';
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
updated() {
|
|
@@ -98,10 +99,11 @@ export class IaBookReader extends LitElement {
|
|
|
98
99
|
return;
|
|
99
100
|
}
|
|
100
101
|
|
|
102
|
+
this.openMenuName = menuId;
|
|
103
|
+
|
|
101
104
|
if (action === 'open') {
|
|
102
105
|
this.itemNav?.openShortcut(menuId);
|
|
103
106
|
} else if (action === 'toggle') {
|
|
104
|
-
this.itemNav?.openMenu(menuId);
|
|
105
107
|
this.itemNav?.toggleMenu();
|
|
106
108
|
}
|
|
107
109
|
}
|
|
@@ -119,6 +121,7 @@ export class IaBookReader extends LitElement {
|
|
|
119
121
|
?signedIn=${this.signedIn}
|
|
120
122
|
.menuShortcuts=${this.menuShortcuts}
|
|
121
123
|
.menuContents=${this.menuContents}
|
|
124
|
+
.openMenu=${this.openMenuName}
|
|
122
125
|
>
|
|
123
126
|
<div slot="header">
|
|
124
127
|
<slot name="header"></slot>
|
|
@@ -125,13 +125,13 @@ export default class AbstractTTSEngine {
|
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
/** @public */
|
|
128
|
-
jumpBackward() {
|
|
129
|
-
Promise.all([
|
|
128
|
+
async jumpBackward() {
|
|
129
|
+
await Promise.all([
|
|
130
130
|
this.activeSound.stop(),
|
|
131
131
|
this._chunkIterator.decrement()
|
|
132
132
|
.then(() => this._chunkIterator.decrement())
|
|
133
|
-
])
|
|
134
|
-
|
|
133
|
+
]);
|
|
134
|
+
this.step();
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
/** @param {number} newRate */
|
|
@@ -147,36 +147,33 @@ export default class AbstractTTSEngine {
|
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
/** @private */
|
|
150
|
-
step() {
|
|
151
|
-
this._chunkIterator.next()
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
.then(() => {
|
|
178
|
-
if (this.playing) return this.step();
|
|
179
|
-
});
|
|
150
|
+
async step() {
|
|
151
|
+
const chunk = await this._chunkIterator.next();
|
|
152
|
+
if (chunk == PageChunkIterator.AT_END) {
|
|
153
|
+
this.stop();
|
|
154
|
+
this.opts.onDone();
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
this.opts.onLoadingStart();
|
|
158
|
+
const sound = this.createSound(chunk);
|
|
159
|
+
sound.chunk = chunk;
|
|
160
|
+
sound.rate = this.playbackRate;
|
|
161
|
+
sound.voice = this.voice;
|
|
162
|
+
sound.load(() => this.opts.onLoadingComplete());
|
|
163
|
+
|
|
164
|
+
this.opts.onLoadingComplete();
|
|
165
|
+
|
|
166
|
+
await this.opts.beforeChunkPlay(chunk);
|
|
167
|
+
|
|
168
|
+
if (!this.playing) return;
|
|
169
|
+
|
|
170
|
+
const playPromise = await this.playSound(sound)
|
|
171
|
+
.then(()=> this.opts.afterChunkPlay(sound.chunk));
|
|
172
|
+
|
|
173
|
+
if (this.paused) this.pause();
|
|
174
|
+
await playPromise;
|
|
175
|
+
|
|
176
|
+
if (this.playing) return this.step();
|
|
180
177
|
}
|
|
181
178
|
|
|
182
179
|
/**
|
|
@@ -53,22 +53,18 @@ export default class PageChunkIterator {
|
|
|
53
53
|
* in the correct order.
|
|
54
54
|
* @return {PromiseLike<"__PageChunkIterator.AT_END__" | PageChunk>}
|
|
55
55
|
*/
|
|
56
|
-
_nextUncontrolled() {
|
|
56
|
+
async _nextUncontrolled() {
|
|
57
57
|
if (this._cursor.page == this.pageCount) {
|
|
58
58
|
return Promise.resolve(PageChunkIterator.AT_END);
|
|
59
59
|
}
|
|
60
|
-
|
|
61
60
|
this._recenterBuffer(this._cursor.page);
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
return chunks[this._cursor.chunk++];
|
|
71
|
-
});
|
|
61
|
+
const chunks = await this._fetchPageChunks(this._cursor.page);
|
|
62
|
+
if (this._cursor.chunk == chunks.length) {
|
|
63
|
+
this._cursor.page++;
|
|
64
|
+
this._cursor.chunk = 0;
|
|
65
|
+
return this._nextUncontrolled();
|
|
66
|
+
}
|
|
67
|
+
return chunks[this._cursor.chunk++];
|
|
72
68
|
}
|
|
73
69
|
|
|
74
70
|
/**
|