@readium/navigator-html-injectables 1.3.3 → 2.0.0-beta.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/dist/index.js +980 -1211
- package/dist/index.umd.cjs +9 -9
- package/package.json +7 -8
- package/src/comms/keys.ts +2 -0
- package/src/helpers/color.ts +114 -0
- package/src/helpers/css.ts +37 -0
- package/src/helpers/document.ts +61 -23
- package/src/modules/Decorator.ts +3 -5
- package/src/modules/setup/ReflowableSetup.ts +12 -1
- package/src/modules/snapper/ColumnSnapper.ts +35 -9
- package/src/modules/snapper/ScrollSnapper.ts +24 -17
- package/types/src/comms/keys.d.ts +1 -1
- package/types/src/helpers/color.d.ts +16 -0
- package/types/src/helpers/css.d.ts +6 -0
- package/types/src/helpers/document.d.ts +12 -3
- package/types/src/modules/snapper/ScrollSnapper.d.ts +3 -3
- package/src/helpers/scrollSnapperHelper.ts +0 -43
package/src/helpers/css.ts
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
import { ReadiumWindow } from "./dom";
|
|
2
2
|
|
|
3
|
+
export function getProperties(wnd: ReadiumWindow) {
|
|
4
|
+
const cssProperties: { [key: string]: string } = {};
|
|
5
|
+
|
|
6
|
+
const rootStyle = wnd.document.documentElement.style;
|
|
7
|
+
|
|
8
|
+
for (const prop in wnd.document.documentElement.style) {
|
|
9
|
+
// We check if the property belongs to the CSSStyleDeclaration instance
|
|
10
|
+
// We also ensure that the property is a numeric index (indicating an inline style)
|
|
11
|
+
if (
|
|
12
|
+
Object.hasOwn(rootStyle, prop) &&
|
|
13
|
+
!Number.isNaN(Number.parseInt(prop))
|
|
14
|
+
) {
|
|
15
|
+
cssProperties[rootStyle[prop]] = rootStyle.getPropertyValue(rootStyle[prop]);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return cssProperties;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function updateProperties(wnd: ReadiumWindow, properties: { [key: string]: string }) {
|
|
23
|
+
const currentProperties = getProperties(wnd);
|
|
24
|
+
|
|
25
|
+
// Remove properties
|
|
26
|
+
Object.keys(currentProperties).forEach((key) => {
|
|
27
|
+
if (!properties.hasOwnProperty(key)) {
|
|
28
|
+
removeProperty(wnd, key);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Update properties
|
|
33
|
+
Object.entries(properties).forEach(([key, value]) => {
|
|
34
|
+
if (currentProperties[key] !== value) {
|
|
35
|
+
setProperty(wnd, key, value);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
3
40
|
// Easy way to get a CSS property
|
|
4
41
|
export function getProperty(wnd: ReadiumWindow, key: string) {
|
|
5
42
|
return wnd.document.documentElement.style.getPropertyValue(key);
|
package/src/helpers/document.ts
CHANGED
|
@@ -4,7 +4,7 @@ export function isRTL(wnd: ReadiumWindow): boolean {
|
|
|
4
4
|
return wnd.document.body.dir.toLowerCase() === "rtl";
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
export function getColumnCountPerScreen(wnd: ReadiumWindow) {
|
|
7
|
+
export function getColumnCountPerScreen(wnd: ReadiumWindow): number {
|
|
8
8
|
return parseInt(
|
|
9
9
|
wnd.getComputedStyle(
|
|
10
10
|
wnd.document.documentElement
|
|
@@ -12,32 +12,70 @@ export function getColumnCountPerScreen(wnd: ReadiumWindow) {
|
|
|
12
12
|
);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Returns the "content height" of an element, which is its clientHeight
|
|
17
|
+
* minus any vertical padding.
|
|
18
|
+
*
|
|
19
|
+
* @param el - The element to measure.
|
|
20
|
+
*/
|
|
21
|
+
export function getContentHeight(el: Element): number {
|
|
22
|
+
const cStyle = getComputedStyle(el);
|
|
23
|
+
const paddingTop = parseFloat(cStyle.paddingTop || "0");
|
|
24
|
+
const paddingBottom = parseFloat(cStyle.paddingBottom || "0");
|
|
25
|
+
return el.clientHeight - paddingTop - paddingBottom;
|
|
26
|
+
}
|
|
27
|
+
|
|
15
28
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
29
|
+
* We have to make sure that the total number of columns is a multiple
|
|
30
|
+
* of the number of columns per screen.
|
|
31
|
+
* Otherwise it causes snapping and page turning issues.
|
|
32
|
+
* To fix this, we insert and remove blank virtual columns at the end of the resource.
|
|
18
33
|
*/
|
|
19
|
-
export function appendVirtualColumnIfNeeded(wnd: ReadiumWindow) {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
if (
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
export function appendVirtualColumnIfNeeded(wnd: ReadiumWindow): boolean {
|
|
35
|
+
const colCountPerScreen = getColumnCountPerScreen(wnd);
|
|
36
|
+
|
|
37
|
+
if (!colCountPerScreen) {
|
|
38
|
+
// This has been triggered while in scroll mode
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const virtualCols = wnd.document.querySelectorAll("div[id^='readium-virtual-page']");
|
|
43
|
+
// Remove first so that we don’t end up with an incorrect scrollWidth
|
|
44
|
+
// Even when removing their width we risk having an incorrect scrollWidth
|
|
45
|
+
// so removing them entirely is the most robust solution
|
|
46
|
+
for (const virtualCol of virtualCols) {
|
|
47
|
+
virtualCol.remove();
|
|
48
|
+
}
|
|
49
|
+
const virtualColsCount = virtualCols.length
|
|
50
|
+
|
|
51
|
+
const documentWidth = wnd.document.scrollingElement!.scrollWidth;
|
|
52
|
+
const windowWidth = wnd.visualViewport!.width
|
|
53
|
+
|
|
54
|
+
const totalColCount = Math.round((documentWidth / windowWidth) * colCountPerScreen);
|
|
55
|
+
|
|
56
|
+
const lonelyColCount = totalColCount % colCountPerScreen;
|
|
57
|
+
|
|
58
|
+
const needed = colCountPerScreen === 1 || lonelyColCount === 0
|
|
59
|
+
? 0
|
|
60
|
+
: colCountPerScreen - lonelyColCount;
|
|
61
|
+
|
|
62
|
+
if (needed > 0) {
|
|
63
|
+
for (let i = 0; i < needed; i++) {
|
|
64
|
+
const virtualCol = wnd.document.createElement("div");
|
|
65
|
+
virtualCol.setAttribute("id", `readium-virtual-page-${ i }`);
|
|
66
|
+
virtualCol.dataset.readium = "true";
|
|
67
|
+
if (CSS.supports("break-before", "column")) {
|
|
37
68
|
virtualCol.style.breakBefore = "column";
|
|
38
|
-
|
|
39
|
-
|
|
69
|
+
} else if (CSS.supports("break-inside", "avoid-column")) {
|
|
70
|
+
virtualCol.style.breakInside = "avoid-column";
|
|
71
|
+
virtualCol.style.height = getContentHeight(wnd.document.documentElement) + "px";
|
|
72
|
+
} else {
|
|
73
|
+
virtualCol.style.height = getContentHeight(wnd.document.documentElement) + "px";
|
|
40
74
|
}
|
|
75
|
+
virtualCol.innerHTML = "​"; // zero-width space
|
|
76
|
+
wnd.document.body.appendChild(virtualCol);
|
|
41
77
|
}
|
|
42
78
|
}
|
|
79
|
+
|
|
80
|
+
return virtualColsCount !== needed;
|
|
43
81
|
}
|
package/src/modules/Decorator.ts
CHANGED
|
@@ -4,12 +4,9 @@ import { Module } from "./Module";
|
|
|
4
4
|
import { rangeFromLocator } from "../helpers/locator";
|
|
5
5
|
import { ModuleName } from "./ModuleLibrary";
|
|
6
6
|
import { Rect, getClientRectsNoOverlap } from "../helpers/rect";
|
|
7
|
-
import { ResizeObserver as Polyfill } from '@juggle/resize-observer';
|
|
8
7
|
import { getProperty } from "../helpers/css";
|
|
9
8
|
import { ReadiumWindow } from "../helpers/dom";
|
|
10
|
-
|
|
11
|
-
// Necessary for iOS 13 and below
|
|
12
|
-
const ResizeObserver = window.ResizeObserver || Polyfill;
|
|
9
|
+
import { isDarkColor } from "../helpers/color";
|
|
13
10
|
|
|
14
11
|
export enum Width {
|
|
15
12
|
Wrap = "wrap", // Smallest width fitting the CSS border box.
|
|
@@ -254,7 +251,8 @@ class DecorationGroup {
|
|
|
254
251
|
// template.innerHTML = item.decoration.element.trim();
|
|
255
252
|
// TODO more styles logic
|
|
256
253
|
|
|
257
|
-
const isDarkMode = getProperty(this.wnd, "--USER__appearance") === "readium-night-on"
|
|
254
|
+
const isDarkMode = getProperty(this.wnd, "--USER__appearance") === "readium-night-on" ||
|
|
255
|
+
isDarkColor(getProperty(this.wnd, "--USER__backgroundColor"));
|
|
258
256
|
|
|
259
257
|
template.innerHTML = `
|
|
260
258
|
<div
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Comms } from "../../comms/comms";
|
|
2
2
|
import { Setup } from "./Setup";
|
|
3
|
-
import { removeProperty, setProperty } from "../../helpers/css";
|
|
3
|
+
import { getProperties, removeProperty, setProperty, updateProperties } from "../../helpers/css";
|
|
4
4
|
import { ReadiumWindow } from "../../helpers/dom";
|
|
5
5
|
|
|
6
6
|
const VIEWPORT_META_TAG_ID = "readium-viewport";
|
|
@@ -35,6 +35,17 @@ export class ReflowableSetup extends Setup {
|
|
|
35
35
|
target: wnd
|
|
36
36
|
} as any); // Cheat!
|
|
37
37
|
|
|
38
|
+
comms.register("get_properties", ReflowableSetup.moduleName, (_, ack) => {
|
|
39
|
+
getProperties(wnd);
|
|
40
|
+
ack(true);
|
|
41
|
+
});
|
|
42
|
+
comms.register("update_properties", ReflowableSetup.moduleName, (data, ack) => {
|
|
43
|
+
// In order to keep the viewport width that is added in the setup itself,
|
|
44
|
+
// and don’t have EpubNavigator concerned with this, we need to add it there
|
|
45
|
+
(data as { [key: string]: string })["--RS__viewportWidth"] = `${ wnd.innerWidth }px`;
|
|
46
|
+
updateProperties(wnd, data as { [key: string]: string });
|
|
47
|
+
ack(true);
|
|
48
|
+
})
|
|
38
49
|
comms.register("set_property", ReflowableSetup.moduleName, (data, ack) => {
|
|
39
50
|
const kv = data as string[];
|
|
40
51
|
setProperty(wnd, kv[0], kv[1]);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { ResizeObserver as Polyfill } from '@juggle/resize-observer';
|
|
2
1
|
import { Comms } from "../../comms";
|
|
3
2
|
import { Snapper } from "./Snapper";
|
|
4
3
|
import { getColumnCountPerScreen, isRTL, appendVirtualColumnIfNeeded } from "../../helpers/document";
|
|
@@ -272,18 +271,43 @@ export class ColumnSnapper extends Snapper {
|
|
|
272
271
|
`;
|
|
273
272
|
wnd.document.head.appendChild(d);
|
|
274
273
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
})
|
|
274
|
+
this.resizeObserver = new ResizeObserver(() => {
|
|
275
|
+
wnd.requestAnimationFrame(() => {
|
|
276
|
+
wnd && appendVirtualColumnIfNeeded(wnd);
|
|
277
|
+
});
|
|
278
|
+
this.onWidthChange();
|
|
279
|
+
});
|
|
281
280
|
this.resizeObserver.observe(wnd.document.body);
|
|
282
|
-
|
|
283
|
-
|
|
281
|
+
|
|
282
|
+
this.mutationObserver = new MutationObserver((mutations) => {
|
|
283
|
+
for (const mutation of mutations) {
|
|
284
|
+
// We have to check it’s not onTouchMove + snapOffset setting transforms
|
|
285
|
+
if (mutation.target === this.wnd.document.documentElement) {
|
|
286
|
+
const oldValue = mutation.oldValue as string;
|
|
287
|
+
const newValue = (mutation.target as HTMLElement).getAttribute("style") as string;
|
|
288
|
+
const transformRegex = /transform\s*:\s*([^;]+)/;
|
|
289
|
+
const oldValueTransform = oldValue?.match(transformRegex);
|
|
290
|
+
const newValueTransform = newValue?.match(transformRegex);
|
|
291
|
+
if (
|
|
292
|
+
(!oldValueTransform && !newValueTransform) ||
|
|
293
|
+
(oldValueTransform && !newValueTransform) ||
|
|
294
|
+
(oldValueTransform && newValueTransform && oldValueTransform[1] !== newValueTransform[1])
|
|
295
|
+
) {
|
|
296
|
+
wnd.requestAnimationFrame(() => {
|
|
297
|
+
wnd && appendVirtualColumnIfNeeded(wnd);
|
|
298
|
+
});
|
|
299
|
+
this.onWidthChange();
|
|
300
|
+
}
|
|
301
|
+
} else {
|
|
302
|
+
wnd.requestAnimationFrame(() => this.cachedScrollWidth = this.doc().scrollWidth!);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
284
305
|
});
|
|
285
306
|
wnd.frameElement && this.mutationObserver.observe(wnd.frameElement, {attributes: true, attributeFilter: ["style"]});
|
|
286
307
|
this.mutationObserver.observe(wnd.document, {attributes: true, attributeFilter: ["style"]});
|
|
308
|
+
// For cases the resizeObserver is not able to detect cos body is not resizing despite colCount,
|
|
309
|
+
// we need to check the syle attribute on the documentElement (ReadiumCSS props)
|
|
310
|
+
this.mutationObserver.observe(wnd.document.documentElement, {attributes: true, attributeFilter: ["style"]});
|
|
287
311
|
|
|
288
312
|
const scrollToOffset = (offset: number): boolean => {
|
|
289
313
|
const oldScrollLeft = this.doc().scrollLeft;
|
|
@@ -387,6 +411,7 @@ export class ColumnSnapper extends Snapper {
|
|
|
387
411
|
|
|
388
412
|
comms.register("go_prev", ColumnSnapper.moduleName, (_, ack) => {
|
|
389
413
|
this.wnd.requestAnimationFrame(() => {
|
|
414
|
+
this.cachedScrollWidth = this.doc().scrollWidth!;
|
|
390
415
|
const offset = wnd.scrollX - wnd.innerWidth;
|
|
391
416
|
const minOffset = isRTL(wnd) ? - (this.cachedScrollWidth - wnd.innerWidth) : 0;
|
|
392
417
|
const change = scrollToOffset(Math.max(offset, minOffset));
|
|
@@ -400,6 +425,7 @@ export class ColumnSnapper extends Snapper {
|
|
|
400
425
|
|
|
401
426
|
comms.register("go_next", ColumnSnapper.moduleName, (_, ack) => {
|
|
402
427
|
this.wnd.requestAnimationFrame(() => {
|
|
428
|
+
this.cachedScrollWidth = this.doc().scrollWidth!;
|
|
403
429
|
const offset = wnd.scrollX + wnd.innerWidth;
|
|
404
430
|
const maxOffset = isRTL(wnd) ? 0 : this.cachedScrollWidth - wnd.innerWidth;
|
|
405
431
|
const change = scrollToOffset(Math.min(offset, maxOffset));
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Locator, LocatorLocations, LocatorText } from "@readium/shared";
|
|
2
2
|
import { Comms } from "../../comms";
|
|
3
3
|
import { ReadiumWindow, deselect, findFirstVisibleLocator } from "../../helpers/dom";
|
|
4
|
-
import { AnchorObserver, helperCreateAnchorElements, helperRemoveAnchorElements } from '../../helpers/scrollSnapperHelper';
|
|
5
4
|
import { ModuleName } from "../ModuleLibrary";
|
|
6
5
|
import { Snapper } from "./Snapper";
|
|
7
6
|
import { rangeFromLocator } from "../../helpers/locator";
|
|
@@ -12,28 +11,28 @@ export class ScrollSnapper extends Snapper {
|
|
|
12
11
|
static readonly moduleName: ModuleName = "scroll_snapper";
|
|
13
12
|
private wnd!: ReadiumWindow;
|
|
14
13
|
private comms!: Comms;
|
|
14
|
+
private resizeObserver!: ResizeObserver;
|
|
15
|
+
private isScrolling = false;
|
|
15
16
|
|
|
16
17
|
private doc() {
|
|
17
18
|
return this.wnd.document.scrollingElement as HTMLElement;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
private createAnchorElements = () => {
|
|
21
|
-
helperCreateAnchorElements(this.doc());
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
private removeAnchorElements = () => {
|
|
25
|
-
helperRemoveAnchorElements(this.doc());
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
private createCustomElement = () => {
|
|
29
|
-
customElements.get("anchor-observer") ||
|
|
30
|
-
customElements.define("anchor-observer", AnchorObserver);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
21
|
private reportProgress(data: { progress: number, reference: number }) {
|
|
34
22
|
this.comms.send("progress", data);
|
|
35
23
|
}
|
|
36
24
|
|
|
25
|
+
private handleScroll = () => {
|
|
26
|
+
if (!this.isScrolling) {
|
|
27
|
+
this.isScrolling = true;
|
|
28
|
+
this.wnd.requestAnimationFrame(() => {
|
|
29
|
+
const progress = this.doc().scrollTop / this.doc().offsetHeight;
|
|
30
|
+
this.reportProgress({ progress: progress, reference: this.wnd.innerHeight / this.doc().scrollHeight });
|
|
31
|
+
this.isScrolling = false;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
37
36
|
mount(wnd: ReadiumWindow, comms: Comms): boolean {
|
|
38
37
|
this.wnd = wnd;
|
|
39
38
|
this.comms = comms;
|
|
@@ -55,6 +54,15 @@ export class ScrollSnapper extends Snapper {
|
|
|
55
54
|
`;
|
|
56
55
|
wnd.document.head.appendChild(style);
|
|
57
56
|
|
|
57
|
+
this.resizeObserver = new ResizeObserver(() => {
|
|
58
|
+
this.comms.ready && this.handleScroll();
|
|
59
|
+
});
|
|
60
|
+
this.resizeObserver.observe(wnd.document.body);
|
|
61
|
+
|
|
62
|
+
wnd.addEventListener("scroll", this.handleScroll, {
|
|
63
|
+
passive: true
|
|
64
|
+
});
|
|
65
|
+
|
|
58
66
|
comms.register("go_progression", ScrollSnapper.moduleName, (data, ack) => {
|
|
59
67
|
const position = data as number;
|
|
60
68
|
|
|
@@ -158,14 +166,13 @@ export class ScrollSnapper extends Snapper {
|
|
|
158
166
|
});
|
|
159
167
|
|
|
160
168
|
comms.log("ScrollSnapper Mounted");
|
|
161
|
-
this.createCustomElement();
|
|
162
|
-
this.createAnchorElements();
|
|
163
169
|
return true;
|
|
164
170
|
}
|
|
165
171
|
|
|
166
172
|
unmount(wnd: ReadiumWindow, comms: Comms): boolean {
|
|
167
173
|
comms.unregisterAll(ScrollSnapper.moduleName);
|
|
168
|
-
this.
|
|
174
|
+
this.resizeObserver.disconnect();
|
|
175
|
+
if (this.handleScroll) wnd.removeEventListener("scroll", this.handleScroll);
|
|
169
176
|
wnd.document.getElementById(SCROLL_SNAPPER_STYLE_ID)?.remove();
|
|
170
177
|
comms.log("ScrollSnapper Unmounted");
|
|
171
178
|
return true;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export type CommsEventKey = "_pong" | "_unhandled" | "_ack" | "log" | "error" | "click" | "tap" | "tap_more" | "no_more" | "no_less" | "swipe" | "progress" | "first_visible_locator" | "text_selected" | "media_play" | "media_pause";
|
|
2
|
-
export type CommsCommandKey = "_ping" | "go_prev" | "go_next" | "go_id" | "go_text" | "go_end" | "go_start" | "go_progression" | "set_property" | "remove_property" | "first_visible_locator" | "decorate" | "protect" | "unprotect" | "unfocus" | "focus" | "activate" | "shake";
|
|
2
|
+
export type CommsCommandKey = "_ping" | "go_prev" | "go_next" | "go_id" | "go_text" | "go_end" | "go_start" | "go_progression" | "get_properties" | "update_properties" | "set_property" | "remove_property" | "first_visible_locator" | "decorate" | "protect" | "unprotect" | "unfocus" | "focus" | "activate" | "shake";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const colorToRgba: (color: string) => {
|
|
2
|
+
r: number;
|
|
3
|
+
g: number;
|
|
4
|
+
b: number;
|
|
5
|
+
a: number;
|
|
6
|
+
};
|
|
7
|
+
export declare const getLuminance: (color: {
|
|
8
|
+
r: number;
|
|
9
|
+
g: number;
|
|
10
|
+
b: number;
|
|
11
|
+
a: number;
|
|
12
|
+
}) => number;
|
|
13
|
+
export declare const isDarkColor: (color: string) => boolean;
|
|
14
|
+
export declare const isLightColor: (color: string) => boolean;
|
|
15
|
+
export declare const checkContrast: (color1: string, color2: string) => number;
|
|
16
|
+
export declare const ensureContrast: (color1: string, color2: string, contrast?: number) => string[];
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { ReadiumWindow } from "./dom";
|
|
2
|
+
export declare function getProperties(wnd: ReadiumWindow): {
|
|
3
|
+
[key: string]: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function updateProperties(wnd: ReadiumWindow, properties: {
|
|
6
|
+
[key: string]: string;
|
|
7
|
+
}): void;
|
|
2
8
|
export declare function getProperty(wnd: ReadiumWindow, key: string): string;
|
|
3
9
|
export declare function setProperty(wnd: ReadiumWindow, key: string, value: string): void;
|
|
4
10
|
export declare function removeProperty(wnd: ReadiumWindow, key: string): void;
|
|
@@ -2,7 +2,16 @@ import { ReadiumWindow } from "./dom";
|
|
|
2
2
|
export declare function isRTL(wnd: ReadiumWindow): boolean;
|
|
3
3
|
export declare function getColumnCountPerScreen(wnd: ReadiumWindow): number;
|
|
4
4
|
/**
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
* Returns the "content height" of an element, which is its clientHeight
|
|
6
|
+
* minus any vertical padding.
|
|
7
|
+
*
|
|
8
|
+
* @param el - The element to measure.
|
|
9
|
+
*/
|
|
10
|
+
export declare function getContentHeight(el: Element): number;
|
|
11
|
+
/**
|
|
12
|
+
* We have to make sure that the total number of columns is a multiple
|
|
13
|
+
* of the number of columns per screen.
|
|
14
|
+
* Otherwise it causes snapping and page turning issues.
|
|
15
|
+
* To fix this, we insert and remove blank virtual columns at the end of the resource.
|
|
7
16
|
*/
|
|
8
|
-
export declare function appendVirtualColumnIfNeeded(wnd: ReadiumWindow):
|
|
17
|
+
export declare function appendVirtualColumnIfNeeded(wnd: ReadiumWindow): boolean;
|
|
@@ -6,11 +6,11 @@ export declare class ScrollSnapper extends Snapper {
|
|
|
6
6
|
static readonly moduleName: ModuleName;
|
|
7
7
|
private wnd;
|
|
8
8
|
private comms;
|
|
9
|
+
private resizeObserver;
|
|
10
|
+
private isScrolling;
|
|
9
11
|
private doc;
|
|
10
|
-
private createAnchorElements;
|
|
11
|
-
private removeAnchorElements;
|
|
12
|
-
private createCustomElement;
|
|
13
12
|
private reportProgress;
|
|
13
|
+
private handleScroll;
|
|
14
14
|
mount(wnd: ReadiumWindow, comms: Comms): boolean;
|
|
15
15
|
unmount(wnd: ReadiumWindow, comms: Comms): boolean;
|
|
16
16
|
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
const iframeAnchors = {
|
|
2
|
-
top: "js-iframe-reader-top-anchor",
|
|
3
|
-
bottom: "js-iframe-reader-bottom-anchor",
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
export class AnchorObserver extends HTMLElement {
|
|
7
|
-
connectedCallback() {
|
|
8
|
-
this.setAttribute("aria-hidden", "true");
|
|
9
|
-
this.style.setProperty("display", "block", "important");
|
|
10
|
-
this.style.setProperty("padding", "0", "important");
|
|
11
|
-
this.style.setProperty("margin", "0", "important");
|
|
12
|
-
this.style.setProperty("visibility", "hidden", "important");
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function helperCreateAnchorElements(iframeElement: HTMLElement) {
|
|
17
|
-
const body = iframeElement.getElementsByTagName("body")[0];
|
|
18
|
-
const anchorTop = document.createElement("anchor-observer");
|
|
19
|
-
const anchorBottom = document.createElement("anchor-observer");
|
|
20
|
-
anchorTop.dataset.readium = "true";
|
|
21
|
-
anchorBottom.dataset.readium = "true";
|
|
22
|
-
|
|
23
|
-
anchorTop?.setAttribute("id", iframeAnchors.top);
|
|
24
|
-
anchorTop?.style.setProperty("height", "115px", "important");
|
|
25
|
-
|
|
26
|
-
anchorBottom?.setAttribute("id", iframeAnchors.bottom);
|
|
27
|
-
anchorBottom?.style.setProperty("height", "80px", "important");
|
|
28
|
-
|
|
29
|
-
body?.insertBefore(anchorTop, body.firstChild);
|
|
30
|
-
body?.appendChild(anchorBottom);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function helperRemoveAnchorElements(iframeElement: HTMLElement) {
|
|
34
|
-
const body = iframeElement.getElementsByTagName("body")[0];
|
|
35
|
-
const anchorTop = body?.querySelector(`#${iframeAnchors.top}`);
|
|
36
|
-
const anchorBottom = body?.querySelector(`#${iframeAnchors.bottom}`);
|
|
37
|
-
if (anchorTop) {
|
|
38
|
-
anchorTop.parentElement?.removeChild(anchorTop);
|
|
39
|
-
}
|
|
40
|
-
if (anchorBottom) {
|
|
41
|
-
anchorBottom.parentElement?.removeChild(anchorBottom);
|
|
42
|
-
}
|
|
43
|
-
}
|