@internetarchive/bookreader 5.0.0-44 → 5.0.0-46-no-right-click-2
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/BookReader/BookReader.js +1 -1
- package/BookReader/BookReader.js.map +1 -1
- package/BookReader/ia-bookreader-bundle.js +11 -11
- package/BookReader/ia-bookreader-bundle.js.map +1 -1
- package/BookReaderDemo/demo-internetarchive.html +7 -0
- package/CHANGELOG.md +3 -3
- package/package.json +2 -2
- package/src/BookNavigator/book-navigator.js +23 -0
- package/src/BookReader/Mode2Up.js +7 -0
- package/src/util/manifestGenerator.js +0 -0
- package/tests/jest/BookNavigator/book-navigator.test.js +114 -0
- package/tests/jest/BookReader/Mode2Up.test.js +23 -0
@@ -126,6 +126,13 @@
|
|
126
126
|
const placeholder = document.querySelector('#placeholder');
|
127
127
|
placeholder.innerHTML = 'Dependencies are complete, bookreader has loaded';
|
128
128
|
});
|
129
|
+
|
130
|
+
// analytics stub
|
131
|
+
window.archive_analytics = {
|
132
|
+
send_event_no_sampling: (category, action, label) => console.log('~~~ NO SAMPLE EVENT CALLED: ', { category, action, label }),
|
133
|
+
send_event: (category, action, label) => console.log('~~~ send_event SAMPLE EVENT CALLED: ', { category, action, label }),
|
134
|
+
send_ping: (category, action, label) => console.log('~~~ send_ping SAMPLE EVENT CALLED: ', { category, action, label }),
|
135
|
+
}
|
129
136
|
</script>
|
130
137
|
|
131
138
|
<!-- IA fetch demo -->
|
package/CHANGELOG.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
+
# 5.0.0-45
|
1
2
|
# 5.0.0-44
|
2
3
|
Fix: dynamic `q=<term>` url parameter @iisa
|
3
|
-
Fix: lcp download links @iisa
|
4
4
|
Dev: dependency updates @renovate
|
5
5
|
|
6
6
|
# 5.0.0-43
|
@@ -51,12 +51,12 @@ Dev: Re-enable testcafe tests in GH action @iisa
|
|
51
51
|
Fix: Search results bar clears and closes properly @iisa
|
52
52
|
|
53
53
|
# 5.0.0-35
|
54
|
-
Fix: global
|
54
|
+
Fix: global style leak specify colorbox styles @iisa
|
55
55
|
Fix: br menu reinits with shared ro load @iisa
|
56
56
|
Fix: url plugin does not rewrite with multiple slashes @iisa
|
57
57
|
|
58
58
|
# 5.0.0-34
|
59
|
-
Dev:
|
59
|
+
Dev: update test dependencies @cdrini
|
60
60
|
Fix: Update hyphen stitching regex to include dangling "¬" @cdrini
|
61
61
|
Fix: pop open multiple files menu at proper width @iisa
|
62
62
|
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@internetarchive/bookreader",
|
3
|
-
"version": "5.0.0-
|
3
|
+
"version": "5.0.0-46-no-right-click-2",
|
4
4
|
"description": "The Internet Archive BookReader.",
|
5
5
|
"repository": {
|
6
6
|
"type": "git",
|
@@ -46,7 +46,7 @@
|
|
46
46
|
"@babel/plugin-proposal-class-properties": "7.16.7",
|
47
47
|
"@babel/plugin-proposal-decorators": "7.17.9",
|
48
48
|
"@babel/preset-env": "7.16.11",
|
49
|
-
"@open-wc/testing-helpers": "^2.1.
|
49
|
+
"@open-wc/testing-helpers": "^2.1.3",
|
50
50
|
"@types/jest": "^27.5.1",
|
51
51
|
"@webcomponents/webcomponentsjs": "^2.6.0",
|
52
52
|
"babel-loader": "8.2.5",
|
@@ -443,6 +443,29 @@ export class BookNavigator extends LitElement {
|
|
443
443
|
this.downloadableTypes = downloadURLs;
|
444
444
|
this.bookIsRestricted = isRestricted;
|
445
445
|
});
|
446
|
+
window.addEventListener('contextmenu', (e) => this.manageContextMenuVisibility(e), { capture: true });
|
447
|
+
}
|
448
|
+
|
449
|
+
/** Display an element's context menu */
|
450
|
+
manageContextMenuVisibility(e) {
|
451
|
+
if (window.archive_analytics) {
|
452
|
+
window.archive_analytics?.send_event_no_sampling(
|
453
|
+
'BookReader',
|
454
|
+
`contextmenu-${this.bookIsRestricted ? 'restricted' : 'unrestricted'}`,
|
455
|
+
e.target.classList.value
|
456
|
+
);
|
457
|
+
}
|
458
|
+
if (!this.bookIsRestricted) {
|
459
|
+
return;
|
460
|
+
}
|
461
|
+
|
462
|
+
const imagePane = e.target.classList.value.match(/BRscreen|BRpageimage/g);
|
463
|
+
if (!imagePane) {
|
464
|
+
return;
|
465
|
+
}
|
466
|
+
|
467
|
+
e.preventDefault();
|
468
|
+
return false;
|
446
469
|
}
|
447
470
|
|
448
471
|
loadSharedObserver() {
|
@@ -843,6 +843,13 @@ export class Mode2Up {
|
|
843
843
|
this.pageContainers[this.br.twoPage.currentIndexR].$container.animate({width: '0px'}, speed, 'easeInSine', () => {
|
844
844
|
this.br.$('BRgutter').css({left: `${gutter - this.br.twoPage.bookSpineDivWidth * 0.5}px`});
|
845
845
|
$(this.br.leafEdgeTmp).animate({left: `${gutter - newWidthL - leafEdgeTmpW}px`}, speed, 'easeOutSine');
|
846
|
+
|
847
|
+
// Ensure the new left leaf is right-positioned before animating its width.
|
848
|
+
// Otherwise, it animates in the wrong direction.
|
849
|
+
this.pageContainers[newIndexL].$container.css({
|
850
|
+
right: `${$twoPageViewEl.prop('clientWidth') - gutter}px`,
|
851
|
+
left: ''
|
852
|
+
});
|
846
853
|
this.pageContainers[newIndexL].$container.animate({width: `${newWidthL}px`}, speed, 'easeOutSine', () => {
|
847
854
|
this.pageContainers[newIndexR].$container.css('zIndex', 2);
|
848
855
|
|
File without changes
|
@@ -513,4 +513,118 @@ describe('<book-navigator>', () => {
|
|
513
513
|
expect(el.manageFullScreenBehavior.callCount).toEqual(1);
|
514
514
|
});
|
515
515
|
});
|
516
|
+
describe('Handles Restricted Books', () => {
|
517
|
+
describe('contextMenu is prevented when book is restricted', () => {
|
518
|
+
it('watches on `div.BRscreen`', async () => {
|
519
|
+
window.archive_analytics = { send_event_no_sampling: sinon.fake() };
|
520
|
+
|
521
|
+
const el = fixtureSync(container());
|
522
|
+
const brStub = {
|
523
|
+
options: { restricted: true },
|
524
|
+
};
|
525
|
+
|
526
|
+
el.bookreader = brStub;
|
527
|
+
el.bookIsRestricted = true;
|
528
|
+
|
529
|
+
const elSpy = sinon.spy(el.manageContextMenuVisibility);
|
530
|
+
await el.elementUpdated;
|
531
|
+
|
532
|
+
expect(window.archive_analytics.send_event_no_sampling.called).toEqual(
|
533
|
+
false
|
534
|
+
);
|
535
|
+
expect(elSpy.called).toEqual(false);
|
536
|
+
|
537
|
+
const body = document.querySelector('body');
|
538
|
+
|
539
|
+
const divBRscreen = document.createElement('div');
|
540
|
+
divBRscreen.classList.add('BRscreen');
|
541
|
+
body.appendChild(divBRscreen);
|
542
|
+
|
543
|
+
const contextMenuEvent = new Event('contextmenu', { bubbles: true });
|
544
|
+
|
545
|
+
// Set spy on contextMenuEvent to check if `preventDefault` is called
|
546
|
+
const preventDefaultSpy = sinon.spy(contextMenuEvent, 'preventDefault');
|
547
|
+
expect(preventDefaultSpy.called).toEqual(false);
|
548
|
+
|
549
|
+
divBRscreen.dispatchEvent(contextMenuEvent);
|
550
|
+
|
551
|
+
// analytics fires
|
552
|
+
expect(window.archive_analytics.send_event_no_sampling.called).toEqual(
|
553
|
+
true
|
554
|
+
);
|
555
|
+
// we prevent default
|
556
|
+
expect(preventDefaultSpy.called).toEqual(true);
|
557
|
+
});
|
558
|
+
it('watches on `img.BRpageimage`', async () => {
|
559
|
+
window.archive_analytics = { send_event_no_sampling: sinon.fake() };
|
560
|
+
|
561
|
+
const el = fixtureSync(container());
|
562
|
+
const brStub = {
|
563
|
+
options: { restricted: true },
|
564
|
+
};
|
565
|
+
|
566
|
+
el.bookreader = brStub;
|
567
|
+
el.bookIsRestricted = true;
|
568
|
+
|
569
|
+
await el.elementUpdated;
|
570
|
+
|
571
|
+
expect(window.archive_analytics.send_event_no_sampling.called).toEqual(
|
572
|
+
false
|
573
|
+
);
|
574
|
+
|
575
|
+
const body = document.querySelector('body');
|
576
|
+
// const element stub for img.BRpageimage
|
577
|
+
const imgBRpageimage = document.createElement('img');
|
578
|
+
imgBRpageimage.classList.add('BRpageimage');
|
579
|
+
body.appendChild(imgBRpageimage);
|
580
|
+
const contextMenuEvent = new Event('contextmenu', { bubbles: true });
|
581
|
+
|
582
|
+
// Set spy on contextMenuEvent to check if `preventDefault` is called
|
583
|
+
const preventDefaultSpy = sinon.spy(contextMenuEvent, 'preventDefault');
|
584
|
+
expect(preventDefaultSpy.called).toEqual(false);
|
585
|
+
|
586
|
+
imgBRpageimage.dispatchEvent(contextMenuEvent);
|
587
|
+
|
588
|
+
// analytics fires
|
589
|
+
expect(window.archive_analytics.send_event_no_sampling.called).toEqual(true);
|
590
|
+
// we prevent default
|
591
|
+
expect(preventDefaultSpy.called).toEqual(true);
|
592
|
+
});
|
593
|
+
});
|
594
|
+
it('Allows unrestricted books access to context menu', async () => {
|
595
|
+
window.archive_analytics = { send_event_no_sampling: sinon.fake() };
|
596
|
+
|
597
|
+
const el = fixtureSync(container());
|
598
|
+
const brStub = {
|
599
|
+
options: { restricted: false },
|
600
|
+
};
|
601
|
+
|
602
|
+
el.bookreader = brStub;
|
603
|
+
el.bookIsRestricted = false;
|
604
|
+
|
605
|
+
await el.elementUpdated;
|
606
|
+
|
607
|
+
expect(window.archive_analytics.send_event_no_sampling.called).toEqual(
|
608
|
+
false
|
609
|
+
);
|
610
|
+
|
611
|
+
const body = document.querySelector('body');
|
612
|
+
// const element stub for img.BRpageimage
|
613
|
+
const imgBRpageimage = document.createElement('img');
|
614
|
+
imgBRpageimage.classList.add('not-targeted-element');
|
615
|
+
body.appendChild(imgBRpageimage);
|
616
|
+
const contextMenuEvent = new Event('contextmenu', { bubbles: true });
|
617
|
+
|
618
|
+
// Set spy on contextMenuEvent to check if `preventDefault` is called
|
619
|
+
const preventDefaultSpy = sinon.spy(contextMenuEvent, 'preventDefault');
|
620
|
+
expect(preventDefaultSpy.called).toEqual(false);
|
621
|
+
|
622
|
+
imgBRpageimage.dispatchEvent(contextMenuEvent);
|
623
|
+
|
624
|
+
// analytics fires
|
625
|
+
expect(window.archive_analytics.send_event_no_sampling.called).toEqual(true);
|
626
|
+
// we do not prevent default
|
627
|
+
expect(preventDefaultSpy.called).toEqual(false);
|
628
|
+
});
|
629
|
+
});
|
516
630
|
});
|
@@ -47,6 +47,29 @@ describe('zoom', () => {
|
|
47
47
|
});
|
48
48
|
});
|
49
49
|
|
50
|
+
describe('page flip directions', () => {
|
51
|
+
test('animates the left page in the correct direction', () => {
|
52
|
+
const br = new BookReader({ data: SAMPLE_DATA });
|
53
|
+
br.init();
|
54
|
+
|
55
|
+
const fake = sinon.fake();
|
56
|
+
const fakeAnimWithCB = sinon.fake.yields();
|
57
|
+
const fakeAnim = sinon.fake((...args) =>
|
58
|
+
typeof args[args.length - 1] === 'function' ? fakeAnimWithCB(...args) : fake
|
59
|
+
);
|
60
|
+
sinon.replace(jQuery.prototype, 'animate', fakeAnim);
|
61
|
+
|
62
|
+
const fakeCSS = sinon.spy(jQuery.prototype, 'css');
|
63
|
+
|
64
|
+
br.next();
|
65
|
+
|
66
|
+
expect(fakeAnimWithCB.callCount).toBe(2);
|
67
|
+
// Find the call to .css() immediately preceding the second animation with a callback (i.e., the left page animation)
|
68
|
+
const preSecondAnimCssCallIndex = fakeCSS.getCalls().findIndex(call => call.calledAfter(fakeAnimWithCB.getCall(1))) - 1;
|
69
|
+
expect(fakeCSS.getCall(preSecondAnimCssCallIndex).args[0].left).toBe('');
|
70
|
+
});
|
71
|
+
});
|
72
|
+
|
50
73
|
describe('prefetch', () => {
|
51
74
|
test('loads nearby pages', () => {
|
52
75
|
const br = new BookReader({ data: SAMPLE_DATA });
|