Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates to support Offshoot integration #1367

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion BookReader/BookReader.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion BookReader/BookReader.js.map

Large diffs are not rendered by default.

195 changes: 108 additions & 87 deletions BookReader/ia-bookreader-bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion BookReader/ia-bookreader-bundle.js.map

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export type BookreaderOptions = typeof import('./src/BookReader/options').DEFAULT_OPTIONS;

export declare class Bookreader {
version: string;
constMode1up: number;
constMode2up: number;
constModeThumb: number;
constNavAnimationDuration: number;
constResizeAnimationDuration: number;
setup(options: BookreaderOptions): void;
trigger(name: string, props: object): void;
bind(name: string, callback: Function): void;
unbind(name: string, callback: Function): void;
resize(): void;
setupKeyListeners(): void;
drawLeafs(): void;
bindGestures(): void;
zoom(direction: number): void;
resizeBRcontainer(animated: boolean): void;
centerPageView(): void;
}
2 changes: 2 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as BookReader } from './src/BookReader.js';
export { IaBookReader } from './src/ia-bookreader/ia-bookreader.js';
4 changes: 3 additions & 1 deletion jsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
}
},
"include": [
"index.js",
"index.d.ts",
"src/**/*.js",
"tests/**/*.js",
],
"exclude": [
"node_modules",
"BookReader"
]
}
}
271 changes: 145 additions & 126 deletions package-lock.json

Large diffs are not rendered by default.

24 changes: 13 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
"publishConfig": {
"access": "public"
},
"module": "src/ia-bookreader/ia-bookreader.js",
"main": "index.js",
"module": "index.js",
"types": "index.d.ts",
"keywords": [
"online",
"bookreader",
Expand All @@ -25,8 +27,8 @@
"homepage": "https://github.com/internetarchive/bookreader#readme",
"private": false,
"dependencies": {
"@internetarchive/ia-activity-indicator": "^0.0.4",
"@internetarchive/ia-item-navigator": "^2.1.2",
"@internetarchive/ia-activity-indicator": "^0.0.6",
"@internetarchive/ia-item-navigator": "^2.1.3-alpha.1",
"@internetarchive/icon-bookmark": "^1.3.4",
"@internetarchive/icon-dl": "^1.3.4",
"@internetarchive/icon-edit-pencil": "^1.3.4",
Expand All @@ -35,9 +37,15 @@
"@internetarchive/icon-search": "^1.3.4",
"@internetarchive/icon-toc": "^1.3.4",
"@internetarchive/icon-visual-adjustment": "^1.3.4",
"@internetarchive/modal-manager": "^0.2.12",
"@internetarchive/modal-manager": "^2.0.1",
"@internetarchive/shared-resize-observer": "^0.2.0",
"lit": "^2.5.0"
"interactjs": "^1.10.18",
"jquery": "3.6.1",
"jquery-colorbox": "1.6.4",
"jquery-ui": "^1.12.1",
"jquery-ui-touch-punch": "0.2.3",
"jquery.browser": "0.1.0",
"lit": "^2.8.0"
},
"devDependencies": {
"@babel/core": "7.25.8",
Expand All @@ -58,15 +66,9 @@
"eslint-plugin-no-jquery": "^2.7.0",
"eslint-plugin-testcafe": "^0.2.1",
"http-server": "14.1.1",
"interactjs": "^1.10.18",
"iso-language-codes": "1.1.0",
"jest": "29.7.0",
"jest-environment-jsdom": "^29.7.0",
"jquery": "3.6.1",
"jquery-colorbox": "1.6.4",
"jquery-ui": "1.12.1",
"jquery-ui-touch-punch": "0.2.3",
"jquery.browser": "0.1.0",
"live-server": "1.2.2",
"regenerator-runtime": "0.14.1",
"sass": "1.79.5",
Expand Down
2 changes: 1 addition & 1 deletion src/BookNavigator/search/search-results.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable class-methods-use-this */
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
import { css, html, LitElement, nothing } from 'lit';
import '@internetarchive/ia-activity-indicator/ia-activity-indicator';
import '@internetarchive/ia-activity-indicator';
import checkmarkIcon from '../assets/icon_checkmark.js';
import closeIcon from '../assets/icon_close.js';
import buttonCSS from '../assets/button-base.js';
Expand Down
142 changes: 86 additions & 56 deletions src/BookReader/Mode1UpLit.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// @ts-check
import { customElement, property, query } from 'lit/decorators.js';
import {LitElement, html} from 'lit';
import { property, query } from 'lit/decorators.js';
import { LitElement, html } from 'lit';
import { styleMap } from 'lit/directives/style-map.js';
import { ModeSmoothZoom } from './ModeSmoothZoom';
import { arrChanged, genToArray, sum, throttle } from './utils';
import { HTMLDimensionsCacher } from "./utils/HTMLDimensionsCacher";
import { HTMLDimensionsCacher } from './utils/HTMLDimensionsCacher';
import { ScrollClassAdder } from './utils/ScrollClassAdder';
import { ModeCoordinateSpace } from './ModeCoordinateSpace';
/** @typedef {import('./BookModel').BookModel} BookModel */
Expand All @@ -17,7 +17,6 @@ import { ModeCoordinateSpace } from './ModeCoordinateSpace';
// I _have_ to make this globally public, otherwise it won't let me call
// it's constructor :/
/** @implements {SmoothZoomable} */
@customElement('br-mode-1up')
export class Mode1UpLit extends LitElement {
/****************************************/
/************** PROPERTIES **************/
Expand Down Expand Up @@ -86,13 +85,15 @@ export class Mode1UpLit extends LitElement {
get worldStyle() {
const wToR = this.coordSpace.worldUnitsToRenderedPixels;
return {
width: wToR(this.worldDimensions.width) + "px",
height: wToR(this.worldDimensions.height) + "px",
width: wToR(this.worldDimensions.width) + 'px',
height: wToR(this.worldDimensions.height) + 'px',
};
}

/** @type {HTMLElement} */
get $container() { return this; }
get $container() {
return this;
}

/** @type {HTMLElement} */
@query('.br-mode-1up__visible-world')
Expand Down Expand Up @@ -128,10 +129,12 @@ export class Mode1UpLit extends LitElement {
if (smooth) {
this.style.scrollBehavior = 'smooth';
}
this.scrollTop = this.coordSpace.worldUnitsToVisiblePixels(this.pageTops[index] - this.SPACING_IN / 2);
this.scrollTop = this.coordSpace.worldUnitsToVisiblePixels(
this.pageTops[index] - this.SPACING_IN / 2,
);
// TODO: Also h center?
if (smooth) {
setTimeout(() => this.style.scrollBehavior = '', 100);
setTimeout(() => (this.style.scrollBehavior = ''), 100);
}
}

Expand Down Expand Up @@ -194,7 +197,7 @@ export class Mode1UpLit extends LitElement {
this.throttledUpdateRenderedPages();
if (this.visiblePages.length) {
// unclear why this is ever really happening
this.br.displayedIndices = this.visiblePages.map(p => p.index);
this.br.displayedIndices = this.visiblePages.map((p) => p.index);
this.br.updateFirstIndex(this.br.displayedIndices[0]);
this.br._components.navbar.updateNavIndexThrottled();
}
Expand All @@ -211,7 +214,9 @@ export class Mode1UpLit extends LitElement {
}

updatePages() {
this.pages = genToArray(this.book.pagesIterator({ combineConsecutiveUnviewables: true }));
this.pages = genToArray(
this.book.pagesIterator({ combineConsecutiveUnviewables: true }),
);
}

/** @override */
Expand Down Expand Up @@ -242,50 +247,59 @@ export class Mode1UpLit extends LitElement {

/** @override */
render() {
return html`
<div class="br-mode-1up__world" style=${styleMap(this.worldStyle)}></div>
return html` <div
class="br-mode-1up__world"
style=${styleMap(this.worldStyle)}
></div>
<div class="br-mode-1up__visible-world">
${this.renderedPages.map(p => this.renderPage(p))}
${this.renderedPages.map((p) => this.renderPage(p))}
</div>`;
}

/** @param {PageModel} page */
createPageContainer = (page) => {
return this.pageContainerCache[page.index] || (
this.pageContainerCache[page.index] = (
return (
this.pageContainerCache[page.index] ||
(this.pageContainerCache[page.index] =
// @ts-ignore I know it's protected, TS! But Mode1Up and BookReader are friends.
this.br._createPageContainer(page.index)
)
this.br._createPageContainer(page.index))
);
}
};

/** @param {PageModel} page */
renderPage = (page) => {
const wToR = this.coordSpace.worldUnitsToRenderedPixels;
const wToV = this.coordSpace.worldUnitsToVisiblePixels;
const containerWidth = this.coordSpace.visiblePixelsToWorldUnits(this.htmlDimensionsCacher.clientWidth);
const containerWidth = this.coordSpace.visiblePixelsToWorldUnits(
this.htmlDimensionsCacher.clientWidth,
);

const width = wToR(page.widthInches);
const height = wToR(page.heightInches);
const left = Math.max(this.SPACING_IN, (containerWidth - page.widthInches) / 2);
const left = Math.max(
this.SPACING_IN,
(containerWidth - page.widthInches) / 2,
);
const top = this.pageTops[page.index];

const transform = `translate(${wToR(left)}px, ${wToR(top)}px)`;
const pageContainerEl = this.createPageContainer(page)
.update({
dimensions: {
width,
height,
top: 0,
left: 0,
},
reduce: page.width / wToV(page.widthInches),
}).$container[0];
const pageContainerEl = this.createPageContainer(page).update({
dimensions: {
width,
height,
top: 0,
left: 0,
},
reduce: page.width / wToV(page.widthInches),
}).$container[0];

pageContainerEl.style.transform = transform;
pageContainerEl.classList.toggle('BRpage-visible', this.visiblePages.includes(page));
pageContainerEl.classList.toggle(
'BRpage-visible',
this.visiblePages.includes(page),
);
return pageContainerEl;
}
};

/************** VIRTUAL SCROLLING LOGIC **************/

Expand All @@ -306,28 +320,34 @@ export class Mode1UpLit extends LitElement {
left: vToW(scrollLeft),
width: vToW(clientWidth),
};
}
};

/**
* @returns {PageModel[]}
*/
computeRenderedPages() {
// Also render 1 page before/after
// @ts-ignore TS doesn't understand the filtering out of null values
return [
this.visiblePages[0]?.prev,
...this.visiblePages,
this.visiblePages[this.visiblePages.length - 1]?.next,
]
.filter(p => p)
// Never render more than 10 pages! Usually means something is wrong
.slice(0, 10);
return (
[
this.visiblePages[0]?.prev,
...this.visiblePages,
this.visiblePages[this.visiblePages.length - 1]?.next,
]
.filter((p) => p)
// Never render more than 10 pages! Usually means something is wrong
.slice(0, 10)
);
}

throttledUpdateRenderedPages = throttle(() => {
this.renderedPages = this.computeRenderedPages();
this.requestUpdate();
}, 100, null)
throttledUpdateRenderedPages = throttle(
() => {
this.renderedPages = this.computeRenderedPages();
this.requestUpdate();
},
100,
null,
);

/**
* @param {PageModel[]} pages
Expand All @@ -350,21 +370,29 @@ export class Mode1UpLit extends LitElement {
*/
computeDefaultScale(page) {
// Default to real size if it fits, otherwise default to full width
const containerWidthIn = this.coordSpace.renderedPixelsToWorldUnits(this.clientWidth);
return Math.min(1, containerWidthIn / (page.widthInches + 2 * this.SPACING_IN)) || 1;
const containerWidthIn = this.coordSpace.renderedPixelsToWorldUnits(
this.clientWidth,
);
return (
Math.min(
1,
containerWidthIn / (page.widthInches + 2 * this.SPACING_IN),
) || 1
);
}

computeWorldDimensions() {
return {
width: Math.max(...this.pages.map(p => p.widthInches)) + 2 * this.SPACING_IN,
width:
Math.max(...this.pages.map((p) => p.widthInches)) + 2 * this.SPACING_IN,
height:
sum(this.pages.map(p => p.heightInches)) +
(this.pages.length + 1) * this.SPACING_IN,
sum(this.pages.map((p) => p.heightInches)) +
(this.pages.length + 1) * this.SPACING_IN,
};
}

computeVisiblePages() {
return this.pages.filter(page => {
return this.pages.filter((page) => {
const PT = this.pageTops[page.index];
const PB = PT + page.heightInches;

Expand All @@ -377,12 +405,14 @@ export class Mode1UpLit extends LitElement {
/************** INPUT HANDLERS **************/

attachScrollListeners = () => {
this.addEventListener("scroll", this.updateVisibleRegion);
this.addEventListener('scroll', this.updateVisibleRegion);
this.scrollClassAdder.attach();
}
};

detachScrollListeners = () => {
this.removeEventListener("scroll", this.updateVisibleRegion);
this.removeEventListener('scroll', this.updateVisibleRegion);
this.scrollClassAdder.detach();
}
};
}

customElements.define('br-mode-1up', Mode1UpLit);
5 changes: 3 additions & 2 deletions src/BookReader/Mode2UpLit.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @ts-check
import { customElement, property, query } from 'lit/decorators.js';

Check failure on line 2 in src/BookReader/Mode2UpLit.js

View workflow job for this annotation

GitHub Actions / tests

'customElement' is defined but never used
import {LitElement, html} from 'lit';
import { styleMap } from 'lit/directives/style-map.js';
import { ModeSmoothZoom } from './ModeSmoothZoom';
Expand All @@ -16,7 +16,6 @@
// I _have_ to make this globally public, otherwise it won't let me call
// its constructor :/
/** @implements {SmoothZoomable} */
@customElement('br-mode-2up')
export class Mode2UpLit extends LitElement {
/****************************************/
/************** PROPERTIES **************/
Expand Down Expand Up @@ -676,7 +675,6 @@
}
}

@customElement('br-leaf-edges')
export class LeafEdges extends LitElement {
@property({ type: Number }) leftIndex = 0;
@property({ type: Number }) rightIndex = 0;
Expand Down Expand Up @@ -774,3 +772,6 @@
return Math.floor(this.leftIndex + (e.offsetX / this.offsetWidth) * (this.rightIndex - this.leftIndex + 1));
}
}

customElements.define('br-mode-2up', Mode2UpLit);
customElements.define('br-leaf-edges', LeafEdges);
Loading
Loading