@readium/navigator-html-injectables 1.2.0
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/README.MD +13 -0
- package/dist/index.js +3144 -0
- package/dist/index.umd.cjs +69 -0
- package/package.json +58 -0
- package/src/Loader.ts +85 -0
- package/src/comms/comms.ts +168 -0
- package/src/comms/index.ts +3 -0
- package/src/comms/keys.ts +42 -0
- package/src/comms/mid.ts +5 -0
- package/src/helpers/animation.ts +5 -0
- package/src/helpers/css.ts +16 -0
- package/src/helpers/document.ts +43 -0
- package/src/helpers/dom.ts +126 -0
- package/src/helpers/locator.ts +67 -0
- package/src/helpers/rect.ts +301 -0
- package/src/helpers/scrollSnapperHelper.ts +43 -0
- package/src/index.ts +3 -0
- package/src/modules/Decorator.ts +462 -0
- package/src/modules/Module.ts +23 -0
- package/src/modules/ModuleLibrary.ts +44 -0
- package/src/modules/Peripherals.ts +148 -0
- package/src/modules/index.ts +3 -0
- package/src/modules/setup/FixedSetup.ts +73 -0
- package/src/modules/setup/ReflowableSetup.ts +65 -0
- package/src/modules/setup/Setup.ts +131 -0
- package/src/modules/snapper/ColumnSnapper.ts +468 -0
- package/src/modules/snapper/ScrollSnapper.ts +168 -0
- package/src/modules/snapper/Snapper.ts +49 -0
- package/src/vendor/approx-string-match/LICENSE +21 -0
- package/src/vendor/approx-string-match/README.MD +1 -0
- package/src/vendor/approx-string-match/index.ts +362 -0
- package/src/vendor/hypothesis/README.MD +1 -0
- package/src/vendor/hypothesis/anchoring/api-types.ts +309 -0
- package/src/vendor/hypothesis/anchoring/html.ts +134 -0
- package/src/vendor/hypothesis/anchoring/match-quote.ts +163 -0
- package/src/vendor/hypothesis/anchoring/placeholder.ts +59 -0
- package/src/vendor/hypothesis/anchoring/text-range.ts +327 -0
- package/src/vendor/hypothesis/anchoring/trim-range.ts +220 -0
- package/src/vendor/hypothesis/anchoring/types.ts +377 -0
- package/src/vendor/hypothesis/anchoring/xpath.ts +164 -0
- package/src/vendor/hypothesis/tsconfig.json +33 -0
- package/src/vendor/hypothesis/types/shared.ts +40 -0
- package/types/src/Loader.d.ts +33 -0
- package/types/src/comms/comms.d.ts +40 -0
- package/types/src/comms/index.d.ts +3 -0
- package/types/src/comms/keys.d.ts +2 -0
- package/types/src/comms/mid.d.ts +1 -0
- package/types/src/helpers/animation.d.ts +1 -0
- package/types/src/helpers/css.d.ts +4 -0
- package/types/src/helpers/document.d.ts +8 -0
- package/types/src/helpers/dom.d.ts +15 -0
- package/types/src/helpers/locator.d.ts +2 -0
- package/types/src/helpers/rect.d.ts +10 -0
- package/types/src/helpers/scrollSnapperHelper.d.ts +5 -0
- package/types/src/index.d.ts +3 -0
- package/types/src/modules/Decorator.d.ts +43 -0
- package/types/src/modules/Module.d.ts +11 -0
- package/types/src/modules/ModuleLibrary.d.ts +5 -0
- package/types/src/modules/Peripherals.d.ts +39 -0
- package/types/src/modules/ReflowablePeripherals.d.ts +37 -0
- package/types/src/modules/index.d.ts +3 -0
- package/types/src/modules/setup/FixedSetup.d.ts +9 -0
- package/types/src/modules/setup/ReflowableSetup.d.ts +9 -0
- package/types/src/modules/setup/Setup.d.ts +17 -0
- package/types/src/modules/snapper/ColumnSnapper.d.ts +41 -0
- package/types/src/modules/snapper/ScrollSnapper.d.ts +16 -0
- package/types/src/modules/snapper/Snapper.d.ts +11 -0
- package/types/src/vendor/approx-string-match/index.d.ts +54 -0
- package/types/src/vendor/hypothesis/anchoring/api-types.d.ts +266 -0
- package/types/src/vendor/hypothesis/anchoring/html.d.ts +17 -0
- package/types/src/vendor/hypothesis/anchoring/match-quote.d.ts +30 -0
- package/types/src/vendor/hypothesis/anchoring/placeholder.d.ts +32 -0
- package/types/src/vendor/hypothesis/anchoring/text-range.d.ts +103 -0
- package/types/src/vendor/hypothesis/anchoring/trim-range.d.ts +17 -0
- package/types/src/vendor/hypothesis/anchoring/types.d.ts +102 -0
- package/types/src/vendor/hypothesis/anchoring/xpath.d.ts +15 -0
- package/types/src/vendor/hypothesis/types/shared.d.ts +32 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Comms } from "../../comms/comms";
|
|
2
|
+
import { Setup } from "./Setup";
|
|
3
|
+
import { removeProperty, setProperty } from "../../helpers/css";
|
|
4
|
+
import { ModuleName } from "../ModuleLibrary";
|
|
5
|
+
import { ReadiumWindow, deselect } from "../../helpers/dom";
|
|
6
|
+
|
|
7
|
+
const FIXED_STYLE_ID = "readium-fixed-style";
|
|
8
|
+
|
|
9
|
+
export class FixedSetup extends Setup {
|
|
10
|
+
static readonly moduleName: ModuleName = "fixed_setup";
|
|
11
|
+
|
|
12
|
+
mount(wnd: ReadiumWindow, comms: Comms): boolean {
|
|
13
|
+
if(!super.mount(wnd, comms)) return false;
|
|
14
|
+
|
|
15
|
+
const style = wnd.document.createElement("style");
|
|
16
|
+
style.id = FIXED_STYLE_ID;
|
|
17
|
+
style.dataset.readium = "true";
|
|
18
|
+
style.textContent = `
|
|
19
|
+
html, body {
|
|
20
|
+
text-size-adjust: none;
|
|
21
|
+
-ms-text-size-adjust: none;
|
|
22
|
+
-webkit-text-size-adjust: none;
|
|
23
|
+
-moz-text-size-adjust: none;
|
|
24
|
+
|
|
25
|
+
/* Fight Safari pinches */
|
|
26
|
+
touch-action: none !important;
|
|
27
|
+
min-height: 100%;
|
|
28
|
+
|
|
29
|
+
/*cursor: var() TODO*/
|
|
30
|
+
}`;
|
|
31
|
+
wnd.document.head.appendChild(style);
|
|
32
|
+
|
|
33
|
+
comms.register("set_property", FixedSetup.moduleName, (data, ack) => {
|
|
34
|
+
const kv = data as string[];
|
|
35
|
+
setProperty(wnd, kv[0], kv[1]);
|
|
36
|
+
ack(true);
|
|
37
|
+
})
|
|
38
|
+
comms.register("remove_property", FixedSetup.moduleName, (data, ack) => {
|
|
39
|
+
removeProperty(wnd, data as string);
|
|
40
|
+
ack(true);
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
comms.register("first_visible_locator", FixedSetup.moduleName, (_, ack) => ack(false))
|
|
44
|
+
|
|
45
|
+
comms.register("unfocus", FixedSetup.moduleName, (_, ack) => {
|
|
46
|
+
deselect(wnd);
|
|
47
|
+
ack(true);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
comms.register([
|
|
51
|
+
"focus", "go_next", "go_prev",
|
|
52
|
+
"go_id", "go_end", "go_start", "go_text",
|
|
53
|
+
"go_progression"
|
|
54
|
+
], FixedSetup.moduleName, (_, ack) => ack(true));
|
|
55
|
+
|
|
56
|
+
comms.register("activate", FixedSetup.moduleName, (_, ack) => {
|
|
57
|
+
this.unblock(wnd as ReadiumWindow);
|
|
58
|
+
ack(true);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
comms.log("FixedSetup Mounted");
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
unmount(wnd: ReadiumWindow, comms: Comms): boolean {
|
|
66
|
+
comms.unregisterAll(FixedSetup.moduleName);
|
|
67
|
+
|
|
68
|
+
wnd.document.getElementById(FIXED_STYLE_ID)?.remove();
|
|
69
|
+
|
|
70
|
+
comms.log("FixedSetup Unmounted");
|
|
71
|
+
return super.unmount(wnd, comms);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Comms } from "../../comms/comms";
|
|
2
|
+
import { Setup } from "./Setup";
|
|
3
|
+
import { removeProperty, setProperty } from "../../helpers/css";
|
|
4
|
+
import { ReadiumWindow } from "../../helpers/dom";
|
|
5
|
+
|
|
6
|
+
const VIEWPORT_META_TAG_ID = "readium-viewport";
|
|
7
|
+
|
|
8
|
+
export class ReflowableSetup extends Setup {
|
|
9
|
+
static readonly moduleName = "reflowable_setup";
|
|
10
|
+
|
|
11
|
+
onViewportWidthChanged(event: Event) {
|
|
12
|
+
const wnd = event.target as ReadiumWindow;
|
|
13
|
+
// const pageWidth = wnd.innerWidth / wnd.devicePixelRatio;
|
|
14
|
+
setProperty(wnd, "--RS__viewportWidth", `${wnd.innerWidth}px`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
mount(wnd: ReadiumWindow, comms: Comms): boolean {
|
|
18
|
+
if(!super.mount(wnd, comms)) return false;
|
|
19
|
+
|
|
20
|
+
// Add viewport tag
|
|
21
|
+
const meta = wnd.document.createElement("meta");
|
|
22
|
+
meta.dataset.readium = "true";
|
|
23
|
+
meta.setAttribute("name", "viewport");
|
|
24
|
+
meta.setAttribute("id", VIEWPORT_META_TAG_ID);
|
|
25
|
+
meta.setAttribute(
|
|
26
|
+
"content",
|
|
27
|
+
"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no"
|
|
28
|
+
);
|
|
29
|
+
wnd.document.head.appendChild(meta);
|
|
30
|
+
|
|
31
|
+
// Listen for resize/orientationchange to update viewport width
|
|
32
|
+
wnd.addEventListener("orientationchange", this.onViewportWidthChanged);
|
|
33
|
+
wnd.addEventListener("resize", this.onViewportWidthChanged);
|
|
34
|
+
this.onViewportWidthChanged({
|
|
35
|
+
target: wnd
|
|
36
|
+
} as any); // Cheat!
|
|
37
|
+
|
|
38
|
+
comms.register("set_property", ReflowableSetup.moduleName, (data, ack) => {
|
|
39
|
+
const kv = data as string[];
|
|
40
|
+
setProperty(wnd, kv[0], kv[1]);
|
|
41
|
+
ack(true);
|
|
42
|
+
});
|
|
43
|
+
comms.register("remove_property", ReflowableSetup.moduleName, (data, ack) => {
|
|
44
|
+
removeProperty(wnd, data as string);
|
|
45
|
+
ack(true);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
comms.register("activate", ReflowableSetup.moduleName, (_, ack) => {
|
|
49
|
+
this.unblock(wnd as ReadiumWindow);
|
|
50
|
+
ack(true);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
comms.log("ReflowableSetup Mounted");
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
unmount(wnd: ReadiumWindow, comms: Comms): boolean {
|
|
58
|
+
comms.unregisterAll(ReflowableSetup.moduleName);
|
|
59
|
+
wnd.document.head.querySelector(`#${VIEWPORT_META_TAG_ID}`)?.remove();
|
|
60
|
+
wnd.removeEventListener("orientationchange", this.onViewportWidthChanged);
|
|
61
|
+
|
|
62
|
+
comms.log("ReflowableSetup Unmounted");
|
|
63
|
+
return super.unmount(wnd, comms);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { Comms } from "../../comms/comms";
|
|
2
|
+
import { ReadiumWindow } from "../../helpers/dom";
|
|
3
|
+
import { Module } from "../Module";
|
|
4
|
+
import { ModuleName } from "../ModuleLibrary";
|
|
5
|
+
|
|
6
|
+
export abstract class Setup extends Module {
|
|
7
|
+
static readonly moduleName: ModuleName = "setup";
|
|
8
|
+
|
|
9
|
+
private comms!: Comms;
|
|
10
|
+
|
|
11
|
+
wndOnErr(event: ErrorEvent) {
|
|
12
|
+
this.comms?.send("error", {
|
|
13
|
+
message: event.message,
|
|
14
|
+
filename: event.filename,
|
|
15
|
+
lineno: event.lineno,
|
|
16
|
+
colno: event.colno
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
protected unblock(wnd: ReadiumWindow) {
|
|
21
|
+
wnd._readium_blockEvents = false;
|
|
22
|
+
while(wnd._readium_blockedEvents?.length > 0) {
|
|
23
|
+
const x = wnd._readium_blockedEvents.shift()!;
|
|
24
|
+
switch(x[0]) {
|
|
25
|
+
case 0:
|
|
26
|
+
Reflect.apply(x[1], x[2], x[3]);
|
|
27
|
+
break;
|
|
28
|
+
case 1:
|
|
29
|
+
const ev = x[1];
|
|
30
|
+
const evTarget = x[2];
|
|
31
|
+
wnd.removeEventListener(ev.type, wnd._readium_eventBlocker, true);
|
|
32
|
+
const evt = new Event(ev.type, {
|
|
33
|
+
bubbles: ev.bubbles,
|
|
34
|
+
cancelable: ev.cancelable
|
|
35
|
+
});
|
|
36
|
+
if(evTarget) evTarget.dispatchEvent(evt);
|
|
37
|
+
else wnd.dispatchEvent(evt);
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// <audio> & <video> playback handling
|
|
44
|
+
private mediaPlayingCount = 0;
|
|
45
|
+
|
|
46
|
+
private onMediaPlayEvent() {
|
|
47
|
+
this.mediaPlayingCount++;
|
|
48
|
+
this.comms?.send("media_play", this.mediaPlayingCount);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private onMediaPauseEvent() {
|
|
52
|
+
if(this.mediaPlayingCount > 0) this.mediaPlayingCount--;
|
|
53
|
+
this.comms?.send("media_pause", this.mediaPlayingCount);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private pauseAllMedia(wnd: ReadiumWindow) {
|
|
57
|
+
const avEls = wnd.document.querySelectorAll("audio,video");
|
|
58
|
+
for (let i = 0; i < avEls.length; i++) {
|
|
59
|
+
(avEls[i] as HTMLMediaElement).pause();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private allAnimations = new Set<Animation>();
|
|
64
|
+
|
|
65
|
+
mount(wnd: ReadiumWindow, comms: Comms): boolean {
|
|
66
|
+
this.comms = comms;
|
|
67
|
+
|
|
68
|
+
// Track all window errors
|
|
69
|
+
wnd.addEventListener(
|
|
70
|
+
"error",
|
|
71
|
+
this.wndOnErr,
|
|
72
|
+
false
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
// Add all currently active animations and cancel them
|
|
76
|
+
if("getAnimations" in wnd.document) {
|
|
77
|
+
wnd.document.getAnimations().forEach((a) => {
|
|
78
|
+
a.cancel();
|
|
79
|
+
this.allAnimations.add(a);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
comms.register("activate", Setup.moduleName, (_, ack) => {
|
|
84
|
+
// Restart all animations
|
|
85
|
+
this.allAnimations.forEach(a => {
|
|
86
|
+
a.cancel();
|
|
87
|
+
a.play();
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
ack(true);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
comms.register("unfocus", Setup.moduleName, (_, ack) => {
|
|
94
|
+
// When a document is unfocused, all media is paused
|
|
95
|
+
this.pauseAllMedia(wnd);
|
|
96
|
+
|
|
97
|
+
// ... and all animations are paused
|
|
98
|
+
// They *not* cancelled because the user can see the sudden jump back to start
|
|
99
|
+
this.allAnimations.forEach(a => a.pause());
|
|
100
|
+
|
|
101
|
+
ack(true);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Track play/pause of all <audio> and <video> elements
|
|
105
|
+
const avEls = wnd.document.querySelectorAll("audio,video");
|
|
106
|
+
for (let i = 0; i < avEls.length; i++) {
|
|
107
|
+
const e = avEls[i] as HTMLAudioElement | HTMLVideoElement;
|
|
108
|
+
e.addEventListener("play", this.onMediaPlayEvent, {
|
|
109
|
+
passive: true
|
|
110
|
+
});
|
|
111
|
+
e.addEventListener("pause", this.onMediaPauseEvent, {
|
|
112
|
+
passive: true
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
comms.log("Setup Mounted");
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
unmount(wnd: ReadiumWindow, comms: Comms): boolean {
|
|
121
|
+
wnd.removeEventListener("error", this.wndOnErr);
|
|
122
|
+
wnd.removeEventListener("play", this.onMediaPlayEvent);
|
|
123
|
+
wnd.removeEventListener("pause", this.onMediaPauseEvent);
|
|
124
|
+
|
|
125
|
+
this.allAnimations.forEach(a => a.cancel());
|
|
126
|
+
this.allAnimations.clear();
|
|
127
|
+
|
|
128
|
+
comms.log("Setup Unmounted");
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
}
|