Commit c037edd0 authored by Robert Knight's avatar Robert Knight

Support side-by-side mode in VitalSource PDF books

Support side-by-side mode in PDF books by simply resizing the content of
the page. This is similar to how side-by-side mode works in PDFs.

The width of the page in the VS PDF demo has been increased so that it
better matches the actual VS viewer, and also so that it triggers the
heuristics in the Guest class for detecting an iframe that fills the
parent frame.
parent d0e2ab41
......@@ -44,7 +44,7 @@
const styles = document.createElement('style');
styles.innerHTML = `
iframe {
width: 80%;
width: 100%;
height: 800px;
resize: both;
overflow: auto;
......
......@@ -350,6 +350,36 @@ describe('annotator/integrations/vitalsource', () => {
assert.calledOnce(fakeImageTextLayer.destroy);
});
context('when side-by-side mode is toggled', () => {
it('resizes page image', () => {
createPageImageAndData();
const integration = createIntegration();
// Activate side-by-side mode. Page image should be resized to fit
// alongside sidebar.
const sidebarWidth = 150;
const expectedWidth = window.innerWidth - sidebarWidth;
integration.fitSideBySide({ expanded: true, width: sidebarWidth });
assert.equal(fakePageImage.parentElement.style.textAlign, 'left');
assert.equal(fakePageImage.style.width, `${expectedWidth}px`);
// Deactivate side-by-side mode. Style overrides should be removed.
integration.fitSideBySide({ expanded: false });
assert.equal(fakePageImage.parentElement.style.textAlign, '');
assert.equal(fakePageImage.style.width, '');
});
it('does not resize page image if there is not enough space', () => {
createPageImageAndData();
const integration = createIntegration();
const sidebarWidth = window.innerWidth - 200;
integration.fitSideBySide({ expanded: true, width: sidebarWidth });
assert.equal(fakePageImage.parentElement.style.textAlign, '');
assert.equal(fakePageImage.style.width, '');
});
});
});
});
});
......@@ -129,6 +129,12 @@ export class VitalSourceInjector {
* @prop {string} words - The text in the page
*/
function getPDFPageImage() {
return /** @type {HTMLImageElement|null} */ (
document.querySelector('img#pbk-page')
);
}
/**
* Integration for the content frame in VitalSource's Bookshelf ebook reader.
*
......@@ -169,7 +175,7 @@ export class VitalSourceContentIntegration {
// If this is a PDF, create the hidden text layer above the rendered PDF
// image.
const bookImage = document.querySelector('#pbk-page');
const bookImage = getPDFPageImage();
/** @type {PDFTextData|undefined} */
const pageData = /** @type {any} */ (window).innerPageData;
......@@ -229,7 +235,32 @@ export class VitalSourceContentIntegration {
* @param {SidebarLayout} layout
*/
fitSideBySide(layout) {
return this._htmlIntegration.fitSideBySide(layout);
const bookImage = getPDFPageImage();
if (bookImage && this._textLayer) {
const bookContainer = /** @type {HTMLElement} */ (
bookImage.parentElement
);
// Update the PDF image size and alignment to fit alongside the sidebar.
// `ImageTextLayer` will handle adjusting the text layer to match.
const newWidth = window.innerWidth - layout.width;
const minWidth = 250;
if (layout.expanded && newWidth > minWidth) {
// The VS book viewer sets `text-align: center` on the <body> element
// by default, which centers the book image in the page. When the sidebar
// is open we need the image to be left-aligned.
bookContainer.style.textAlign = 'left';
bookImage.style.width = `${newWidth}px`;
} else {
bookContainer.style.textAlign = '';
bookImage.style.width = '';
}
return layout.expanded;
} else {
return this._htmlIntegration.fitSideBySide(layout);
}
}
async getMetadata() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment