@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.
Files changed (77) hide show
  1. package/README.MD +13 -0
  2. package/dist/index.js +3144 -0
  3. package/dist/index.umd.cjs +69 -0
  4. package/package.json +58 -0
  5. package/src/Loader.ts +85 -0
  6. package/src/comms/comms.ts +168 -0
  7. package/src/comms/index.ts +3 -0
  8. package/src/comms/keys.ts +42 -0
  9. package/src/comms/mid.ts +5 -0
  10. package/src/helpers/animation.ts +5 -0
  11. package/src/helpers/css.ts +16 -0
  12. package/src/helpers/document.ts +43 -0
  13. package/src/helpers/dom.ts +126 -0
  14. package/src/helpers/locator.ts +67 -0
  15. package/src/helpers/rect.ts +301 -0
  16. package/src/helpers/scrollSnapperHelper.ts +43 -0
  17. package/src/index.ts +3 -0
  18. package/src/modules/Decorator.ts +462 -0
  19. package/src/modules/Module.ts +23 -0
  20. package/src/modules/ModuleLibrary.ts +44 -0
  21. package/src/modules/Peripherals.ts +148 -0
  22. package/src/modules/index.ts +3 -0
  23. package/src/modules/setup/FixedSetup.ts +73 -0
  24. package/src/modules/setup/ReflowableSetup.ts +65 -0
  25. package/src/modules/setup/Setup.ts +131 -0
  26. package/src/modules/snapper/ColumnSnapper.ts +468 -0
  27. package/src/modules/snapper/ScrollSnapper.ts +168 -0
  28. package/src/modules/snapper/Snapper.ts +49 -0
  29. package/src/vendor/approx-string-match/LICENSE +21 -0
  30. package/src/vendor/approx-string-match/README.MD +1 -0
  31. package/src/vendor/approx-string-match/index.ts +362 -0
  32. package/src/vendor/hypothesis/README.MD +1 -0
  33. package/src/vendor/hypothesis/anchoring/api-types.ts +309 -0
  34. package/src/vendor/hypothesis/anchoring/html.ts +134 -0
  35. package/src/vendor/hypothesis/anchoring/match-quote.ts +163 -0
  36. package/src/vendor/hypothesis/anchoring/placeholder.ts +59 -0
  37. package/src/vendor/hypothesis/anchoring/text-range.ts +327 -0
  38. package/src/vendor/hypothesis/anchoring/trim-range.ts +220 -0
  39. package/src/vendor/hypothesis/anchoring/types.ts +377 -0
  40. package/src/vendor/hypothesis/anchoring/xpath.ts +164 -0
  41. package/src/vendor/hypothesis/tsconfig.json +33 -0
  42. package/src/vendor/hypothesis/types/shared.ts +40 -0
  43. package/types/src/Loader.d.ts +33 -0
  44. package/types/src/comms/comms.d.ts +40 -0
  45. package/types/src/comms/index.d.ts +3 -0
  46. package/types/src/comms/keys.d.ts +2 -0
  47. package/types/src/comms/mid.d.ts +1 -0
  48. package/types/src/helpers/animation.d.ts +1 -0
  49. package/types/src/helpers/css.d.ts +4 -0
  50. package/types/src/helpers/document.d.ts +8 -0
  51. package/types/src/helpers/dom.d.ts +15 -0
  52. package/types/src/helpers/locator.d.ts +2 -0
  53. package/types/src/helpers/rect.d.ts +10 -0
  54. package/types/src/helpers/scrollSnapperHelper.d.ts +5 -0
  55. package/types/src/index.d.ts +3 -0
  56. package/types/src/modules/Decorator.d.ts +43 -0
  57. package/types/src/modules/Module.d.ts +11 -0
  58. package/types/src/modules/ModuleLibrary.d.ts +5 -0
  59. package/types/src/modules/Peripherals.d.ts +39 -0
  60. package/types/src/modules/ReflowablePeripherals.d.ts +37 -0
  61. package/types/src/modules/index.d.ts +3 -0
  62. package/types/src/modules/setup/FixedSetup.d.ts +9 -0
  63. package/types/src/modules/setup/ReflowableSetup.d.ts +9 -0
  64. package/types/src/modules/setup/Setup.d.ts +17 -0
  65. package/types/src/modules/snapper/ColumnSnapper.d.ts +41 -0
  66. package/types/src/modules/snapper/ScrollSnapper.d.ts +16 -0
  67. package/types/src/modules/snapper/Snapper.d.ts +11 -0
  68. package/types/src/vendor/approx-string-match/index.d.ts +54 -0
  69. package/types/src/vendor/hypothesis/anchoring/api-types.d.ts +266 -0
  70. package/types/src/vendor/hypothesis/anchoring/html.d.ts +17 -0
  71. package/types/src/vendor/hypothesis/anchoring/match-quote.d.ts +30 -0
  72. package/types/src/vendor/hypothesis/anchoring/placeholder.d.ts +32 -0
  73. package/types/src/vendor/hypothesis/anchoring/text-range.d.ts +103 -0
  74. package/types/src/vendor/hypothesis/anchoring/trim-range.d.ts +17 -0
  75. package/types/src/vendor/hypothesis/anchoring/types.d.ts +102 -0
  76. package/types/src/vendor/hypothesis/anchoring/xpath.d.ts +15 -0
  77. 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
+ }