@readium/navigator 2.2.8 → 2.3.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 (83) hide show
  1. package/dist/index.js +3079 -3225
  2. package/dist/index.umd.cjs +80 -87
  3. package/package.json +5 -4
  4. package/src/Navigator.ts +76 -0
  5. package/src/epub/EpubNavigator.ts +93 -10
  6. package/src/epub/css/Properties.ts +8 -8
  7. package/src/epub/css/ReadiumCSS.ts +7 -5
  8. package/src/epub/frame/FrameManager.ts +38 -2
  9. package/src/epub/frame/FramePoolManager.ts +9 -2
  10. package/src/epub/fxl/FXLFrameManager.ts +31 -2
  11. package/src/epub/fxl/FXLFramePoolManager.ts +9 -3
  12. package/src/epub/preferences/EpubDefaults.ts +6 -6
  13. package/src/epub/preferences/EpubPreferences.ts +6 -6
  14. package/src/epub/preferences/EpubPreferencesEditor.ts +1 -3
  15. package/src/epub/preferences/EpubSettings.ts +5 -7
  16. package/src/helpers/lineLength.ts +4 -6
  17. package/src/injection/epubInjectables.ts +11 -3
  18. package/src/injection/webpubInjectables.ts +12 -2
  19. package/src/peripherals/KeyboardPeripherals.ts +53 -0
  20. package/src/protection/AutomationDetector.ts +66 -0
  21. package/src/protection/ContextMenuProtector.ts +46 -0
  22. package/src/protection/DevToolsDetector.ts +290 -0
  23. package/src/protection/IframeEmbeddingDetector.ts +73 -0
  24. package/src/protection/NavigatorProtector.ts +95 -0
  25. package/src/protection/PrintProtector.ts +58 -0
  26. package/src/protection/utils/WorkerConsole.ts +84 -0
  27. package/src/protection/utils/console.ts +16 -0
  28. package/src/protection/utils/match.ts +18 -0
  29. package/src/protection/utils/platform.ts +22 -0
  30. package/src/webpub/WebPubFrameManager.ts +38 -5
  31. package/src/webpub/WebPubFramePoolManager.ts +9 -2
  32. package/src/webpub/WebPubNavigator.ts +87 -7
  33. package/types/src/Navigator.d.ts +14 -0
  34. package/types/src/epub/EpubNavigator.d.ts +14 -2
  35. package/types/src/epub/css/Properties.d.ts +4 -0
  36. package/types/src/epub/frame/FrameManager.d.ts +5 -1
  37. package/types/src/epub/frame/FramePoolManager.d.ts +4 -1
  38. package/types/src/epub/fxl/FXLFrameManager.d.ts +5 -1
  39. package/types/src/epub/fxl/FXLFramePoolManager.d.ts +4 -2
  40. package/types/src/epub/preferences/EpubDefaults.d.ts +4 -0
  41. package/types/src/epub/preferences/EpubPreferences.d.ts +4 -0
  42. package/types/src/epub/preferences/EpubPreferencesEditor.d.ts +2 -0
  43. package/types/src/epub/preferences/EpubSettings.d.ts +4 -0
  44. package/types/src/helpers/lineLength.d.ts +2 -3
  45. package/types/src/injection/epubInjectables.d.ts +2 -2
  46. package/types/src/injection/webpubInjectables.d.ts +2 -1
  47. package/types/src/peripherals/KeyboardPeripherals.d.ts +13 -0
  48. package/types/src/protection/AutomationDetector.d.ts +14 -0
  49. package/types/src/protection/ContextMenuProtector.d.ts +11 -0
  50. package/types/src/protection/DevToolsDetector.d.ts +75 -0
  51. package/types/src/protection/IframeEmbeddingDetector.d.ts +14 -0
  52. package/types/src/protection/NavigatorProtector.d.ts +12 -0
  53. package/types/src/protection/PrintProtector.d.ts +13 -0
  54. package/types/src/protection/utils/WorkerConsole.d.ts +15 -0
  55. package/types/src/protection/utils/console.d.ts +6 -0
  56. package/types/src/protection/utils/match.d.ts +8 -0
  57. package/types/src/protection/utils/platform.d.ts +4 -0
  58. package/types/src/webpub/WebPubFrameManager.d.ts +5 -1
  59. package/types/src/webpub/WebPubFramePoolManager.d.ts +4 -1
  60. package/types/src/webpub/WebPubNavigator.d.ts +13 -1
  61. package/dist/ar-DyHX_uy2-DyHX_uy2.js +0 -7
  62. package/dist/assets/AccessibleDfA-Bold.woff2 +0 -0
  63. package/dist/assets/AccessibleDfA-Italic.woff2 +0 -0
  64. package/dist/assets/AccessibleDfA-Regular.woff +0 -0
  65. package/dist/assets/AccessibleDfA-Regular.woff2 +0 -0
  66. package/dist/assets/iAWriterDuospace-Regular.ttf +0 -0
  67. package/dist/da-Dct0PS3E-Dct0PS3E.js +0 -7
  68. package/dist/fr-C5HEel98-C5HEel98.js +0 -7
  69. package/dist/it-DFOBoXGy-DFOBoXGy.js +0 -7
  70. package/dist/pt_PT-Di3sVjze-Di3sVjze.js +0 -7
  71. package/dist/sv-BfzAFsVN-BfzAFsVN.js +0 -7
  72. package/types/src/epub/preferences/guards.d.ts +0 -9
  73. package/types/src/web/WebPubBlobBuilder.d.ts +0 -10
  74. package/types/src/web/WebPubFrameManager.d.ts +0 -20
  75. package/types/src/web/WebPubNavigator.d.ts +0 -48
  76. package/types/src/web/index.d.ts +0 -3
  77. package/types/src/webpub/css/WebPubStylesheet.d.ts +0 -1
  78. /package/dist/{ar-DyHX_uy2-DyHX_uy2-DyHX_uy2.js → ar-DyHX_uy2.js} +0 -0
  79. /package/dist/{da-Dct0PS3E-Dct0PS3E-Dct0PS3E.js → da-Dct0PS3E.js} +0 -0
  80. /package/dist/{fr-C5HEel98-C5HEel98-C5HEel98.js → fr-C5HEel98.js} +0 -0
  81. /package/dist/{it-DFOBoXGy-DFOBoXGy-DFOBoXGy.js → it-DFOBoXGy.js} +0 -0
  82. /package/dist/{pt_PT-Di3sVjze-Di3sVjze-Di3sVjze.js → pt_PT-Di3sVjze.js} +0 -0
  83. /package/dist/{sv-BfzAFsVN-BfzAFsVN-BfzAFsVN.js → sv-BfzAFsVN.js} +0 -0
@@ -2,6 +2,7 @@ import { Loader, ModuleName } from "@readium/navigator-html-injectables";
2
2
  import { FrameComms } from "../epub/frame/FrameComms";
3
3
  import { ReadiumWindow } from "../../../navigator-html-injectables/types/src/helpers/dom";
4
4
  import { sML } from "../helpers";
5
+ import { IContentProtectionConfig, IKeyboardPeripheralsConfig } from "../Navigator";
5
6
 
6
7
  export class WebPubFrameManager {
7
8
  private frame: HTMLIFrameElement;
@@ -10,10 +11,15 @@ export class WebPubFrameManager {
10
11
  private comms: FrameComms | undefined;
11
12
  private hidden: boolean = true;
12
13
  private destroyed: boolean = false;
13
-
14
+ private readonly contentProtectionConfig: IContentProtectionConfig;
15
+ private readonly keyboardPeripheralsConfig: IKeyboardPeripheralsConfig;
14
16
  private currModules: ModuleName[] = [];
15
17
 
16
- constructor(source: string) {
18
+ constructor(
19
+ source: string,
20
+ contentProtectionConfig: IContentProtectionConfig = {},
21
+ keyboardPeripheralsConfig: IKeyboardPeripheralsConfig = []
22
+ ) {
17
23
  this.frame = document.createElement("iframe");
18
24
  this.frame.classList.add("readium-navigator-iframe");
19
25
  this.frame.style.visibility = "hidden";
@@ -25,14 +31,17 @@ export class WebPubFrameManager {
25
31
  // Protect against background color bleeding
26
32
  this.frame.style.backgroundColor = "#FFFFFF";
27
33
  this.source = source;
34
+
35
+ // Use the provided content protection config directly without overriding defaults
36
+ this.contentProtectionConfig = { ...contentProtectionConfig };
37
+ this.keyboardPeripheralsConfig = [...keyboardPeripheralsConfig];
28
38
  }
29
39
 
30
40
  async load(modules: ModuleName[] = []): Promise<Window> {
31
41
  return new Promise((res, rej) => {
32
- if(this.loader) {
42
+ if (this.loader) {
33
43
  const wnd = this.frame.contentWindow!;
34
- // Check if currently loaded modules are equal
35
- if([...this.currModules].sort().join("|") === [...modules].sort().join("|")) {
44
+ if ([...this.currModules].sort().join("|") === [...modules].sort().join("|")) {
36
45
  try { res(wnd); } catch (error) {};
37
46
  return;
38
47
  }
@@ -57,6 +66,28 @@ export class WebPubFrameManager {
57
66
  });
58
67
  }
59
68
 
69
+ private applyContentProtection() {
70
+ if (!this.comms) this.comms!.resume();
71
+
72
+ // Send content protection config
73
+ this.comms!.send("peripherals_protection", this.contentProtectionConfig);
74
+
75
+ // Send keyboard peripherals separately
76
+ if (this.keyboardPeripheralsConfig && this.keyboardPeripheralsConfig.length > 0) {
77
+ this.comms!.send("keyboard_peripherals", this.keyboardPeripheralsConfig);
78
+ }
79
+
80
+ // Apply scroll protection if enabled
81
+ if (this.contentProtectionConfig.monitorScrollingExperimental) {
82
+ this.comms!.send("scroll_protection", {});
83
+ }
84
+
85
+ // Apply print protection if configured
86
+ if (this.contentProtectionConfig.protectPrinting) {
87
+ this.comms!.send("print_protection", this.contentProtectionConfig.protectPrinting);
88
+ }
89
+ }
90
+
60
91
  async destroy() {
61
92
  await this.hide();
62
93
  this.loader?.destroy();
@@ -94,6 +125,8 @@ export class WebPubFrameManager {
94
125
  return new Promise((res, _) => {
95
126
  this.comms?.send("activate", undefined, () => {
96
127
  this.comms?.send("focus", undefined, () => {
128
+ // Apply content protection synchronously
129
+ this.applyContentProtection();
97
130
  const remove = () => {
98
131
  this.frame.style.removeProperty("visibility");
99
132
  this.frame.style.removeProperty("aria-hidden");
@@ -3,6 +3,7 @@ import { Locator, Publication } from "@readium/shared";
3
3
  import { WebPubBlobBuilder } from "./WebPubBlobBuilder";
4
4
  import { WebPubFrameManager } from "./WebPubFrameManager";
5
5
  import { Injector } from "../injection/Injector";
6
+ import { IContentProtectionConfig, IKeyboardPeripheralsConfig } from "../Navigator";
6
7
 
7
8
  export class WebPubFramePoolManager {
8
9
  private readonly container: HTMLElement;
@@ -14,15 +15,21 @@ export class WebPubFramePoolManager {
14
15
  private pendingUpdates: Map<string, { inPool: boolean }> = new Map();
15
16
  private currentBaseURL: string | undefined;
16
17
  private readonly injector?: Injector | null = null;
18
+ private readonly contentProtectionConfig: IContentProtectionConfig;
19
+ private readonly keyboardPeripheralsConfig: IKeyboardPeripheralsConfig;
17
20
 
18
21
  constructor(
19
22
  container: HTMLElement,
20
23
  cssProperties?: { [key: string]: string },
21
- injector?: Injector | null
24
+ injector?: Injector | null,
25
+ contentProtectionConfig: IContentProtectionConfig = {},
26
+ keyboardPeripheralsConfig: IKeyboardPeripheralsConfig = []
22
27
  ) {
23
28
  this.container = container;
24
29
  this.currentCssProperties = cssProperties;
25
30
  this.injector = injector;
31
+ this.contentProtectionConfig = contentProtectionConfig;
32
+ this.keyboardPeripheralsConfig = [...keyboardPeripheralsConfig];
26
33
  }
27
34
 
28
35
  async destroy() {
@@ -147,7 +154,7 @@ export class WebPubFramePoolManager {
147
154
  this.blobs.set(href, blobURL);
148
155
  }
149
156
 
150
- const fm = new WebPubFrameManager(this.blobs.get(href)!);
157
+ const fm = new WebPubFrameManager(this.blobs.get(href)!, this.contentProtectionConfig, this.keyboardPeripheralsConfig);
151
158
  if(href !== newHref) await fm.hide();
152
159
  this.container.appendChild(fm.iframe);
153
160
  await fm.load(modules);
@@ -2,7 +2,7 @@ import { Feature, Link, Locator, Publication, ReadingProgression, LocatorLocatio
2
2
  import { VisualNavigator, VisualNavigatorViewport, ProgressionRange } from "../Navigator";
3
3
  import { Configurable } from "../preferences/Configurable";
4
4
  import { WebPubFramePoolManager } from "./WebPubFramePoolManager";
5
- import { BasicTextSelection, CommsEventKey, FrameClickEvent, ModuleLibrary, ModuleName, WebPubModules } from "@readium/navigator-html-injectables";
5
+ import { BasicTextSelection, CommsEventKey, ContextMenuEvent, FrameClickEvent, KeyboardEventData, ModuleLibrary, ModuleName, SuspiciousActivityEvent, WebPubModules } from "@readium/navigator-html-injectables";
6
6
  import * as path from "path-browserify";
7
7
  import { WebPubFrameManager } from "./WebPubFrameManager";
8
8
 
@@ -17,11 +17,16 @@ import { WebPubPreferencesEditor } from "./preferences/WebPubPreferencesEditor";
17
17
  import { Injector } from "../injection/Injector";
18
18
  import { createReadiumWebPubRules } from "../injection/webpubInjectables";
19
19
  import { IInjectablesConfig } from "../injection/Injectable";
20
+ import { IContentProtectionConfig, IKeyboardPeripheralsConfig } from "../Navigator";
21
+ import { NavigatorProtector, NAVIGATOR_SUSPICIOUS_ACTIVITY_EVENT } from "../protection/NavigatorProtector";
22
+ import { KeyboardPeripherals, NAVIGATOR_KEYBOARD_PERIPHERAL_EVENT } from "../peripherals/KeyboardPeripherals";
20
23
 
21
24
  export interface WebPubNavigatorConfiguration {
22
25
  preferences: IWebPubPreferences;
23
26
  defaults: IWebPubDefaults;
24
27
  injectables?: IInjectablesConfig;
28
+ contentProtection?: IContentProtectionConfig;
29
+ keyboardPeripherals?: IKeyboardPeripheralsConfig;
25
30
  }
26
31
 
27
32
  export interface WebPubNavigatorListeners {
@@ -34,6 +39,9 @@ export interface WebPubNavigatorListeners {
34
39
  customEvent: (key: string, data: unknown) => void;
35
40
  handleLocator: (locator: Locator) => boolean;
36
41
  textSelected: (selection: BasicTextSelection) => void;
42
+ contentProtection: (type: string, data: SuspiciousActivityEvent) => void;
43
+ contextMenu: (data: ContextMenuEvent) => void;
44
+ peripheral: (data: KeyboardEventData) => void;
37
45
  }
38
46
 
39
47
  const defaultListeners = (listeners: WebPubNavigatorListeners): WebPubNavigatorListeners => ({
@@ -45,7 +53,10 @@ const defaultListeners = (listeners: WebPubNavigatorListeners): WebPubNavigatorL
45
53
  scroll: listeners.scroll || (() => {}),
46
54
  customEvent: listeners.customEvent || (() => {}),
47
55
  handleLocator: listeners.handleLocator || (() => false),
48
- textSelected: listeners.textSelected || (() => {})
56
+ textSelected: listeners.textSelected || (() => {}),
57
+ contentProtection: listeners.contentProtection || (() => {}),
58
+ contextMenu: listeners.contextMenu || (() => {}),
59
+ peripheral: listeners.peripheral || (() => {})
49
60
  })
50
61
 
51
62
  export class WebPubNavigator extends VisualNavigator implements Configurable<WebPubSettings, WebPubPreferences> {
@@ -62,6 +73,12 @@ export class WebPubNavigator extends VisualNavigator implements Configurable<Web
62
73
  private _css: WebPubCSS;
63
74
  private _preferencesEditor: WebPubPreferencesEditor | null = null;
64
75
  private readonly _injector: Injector | null = null;
76
+ private readonly _contentProtection: IContentProtectionConfig;
77
+ private readonly _keyboardPeripherals: IKeyboardPeripheralsConfig;
78
+ private readonly _navigatorProtector: NavigatorProtector | null = null;
79
+ private readonly _keyboardPeripheralsManager: KeyboardPeripherals | null = null;
80
+ private readonly _suspiciousActivityListener: ((event: Event) => void) | null = null;
81
+ private readonly _keyboardPeripheralListener: ((event: Event) => void) | null = null;
65
82
 
66
83
  private webViewport: VisualNavigatorViewport = {
67
84
  readingOrder: [],
@@ -85,7 +102,7 @@ export class WebPubNavigator extends VisualNavigator implements Configurable<Web
85
102
  });
86
103
 
87
104
  // Combine WebPub rules with user-provided injectables
88
- const webpubRules = createReadiumWebPubRules();
105
+ const webpubRules = createReadiumWebPubRules(pub.readingOrder.items);
89
106
  const userConfig = configuration.injectables || { rules: [], allowedDomains: [] };
90
107
 
91
108
  this._injector = new Injector({
@@ -93,8 +110,47 @@ export class WebPubNavigator extends VisualNavigator implements Configurable<Web
93
110
  allowedDomains: userConfig.allowedDomains
94
111
  });
95
112
 
113
+ // Initialize content protection with provided config or default values
114
+ this._contentProtection = configuration.contentProtection || {};
115
+
116
+ // Merge keyboard peripherals
117
+ this._keyboardPeripherals = this.mergeKeyboardPeripherals(
118
+ this._contentProtection,
119
+ configuration.keyboardPeripherals || []
120
+ );
121
+
122
+ // Initialize navigator protection if any protection is configured
123
+ if (this._contentProtection.disableContextMenu ||
124
+ this._contentProtection.checkAutomation ||
125
+ this._contentProtection.checkIFrameEmbedding ||
126
+ this._contentProtection.monitorDevTools ||
127
+ this._contentProtection.protectPrinting?.disable) {
128
+ this._navigatorProtector = new NavigatorProtector(this._contentProtection);
129
+
130
+ // Listen for custom events from NavigatorProtector
131
+ this._suspiciousActivityListener = (event: Event) => {
132
+ const customEvent = event as CustomEvent;
133
+ this.listeners.contentProtection(customEvent.detail.type, customEvent.detail);
134
+ };
135
+ window.addEventListener(NAVIGATOR_SUSPICIOUS_ACTIVITY_EVENT, this._suspiciousActivityListener);
136
+ }
137
+
138
+ // Initialize keyboard peripherals separately (works independently of protection)
139
+ if (this._keyboardPeripherals.length > 0) {
140
+ this._keyboardPeripheralsManager = new KeyboardPeripherals({
141
+ keyboardPeripherals: this._keyboardPeripherals
142
+ });
143
+
144
+ // Listen for keyboard peripheral events from main window
145
+ this._keyboardPeripheralListener = (event: Event) => {
146
+ const activity = (event as CustomEvent).detail;
147
+ this.listeners.peripheral(activity);
148
+ };
149
+ window.addEventListener(NAVIGATOR_KEYBOARD_PERIPHERAL_EVENT, this._keyboardPeripheralListener);
150
+ }
151
+
96
152
  // Initialize current location
97
- if (initialPosition && typeof initialPosition.copyWithLocations === 'function') {
153
+ if (initialPosition && typeof initialPosition.copyWithLocations === "function") {
98
154
  this.currentLocation = initialPosition;
99
155
  // Update currentIndex to match the initial position
100
156
  const index = this.pub.readingOrder.findIndexWithHref(initialPosition.href);
@@ -109,7 +165,13 @@ export class WebPubNavigator extends VisualNavigator implements Configurable<Web
109
165
  public async load() {
110
166
  await this.updateCSS(false);
111
167
  const cssProperties = this.compileCSSProperties(this._css);
112
- this.framePool = new WebPubFramePoolManager(this.container, cssProperties, this._injector);
168
+ this.framePool = new WebPubFramePoolManager(
169
+ this.container,
170
+ cssProperties,
171
+ this._injector,
172
+ this._contentProtection,
173
+ this._keyboardPeripherals
174
+ );
113
175
 
114
176
  await this.apply();
115
177
  }
@@ -282,6 +344,16 @@ export class WebPubNavigator extends VisualNavigator implements Configurable<Web
282
344
  case "progress":
283
345
  this.syncLocation(data as ProgressionRange);
284
346
  break;
347
+ case "content_protection":
348
+ const activity = data as SuspiciousActivityEvent;
349
+ this.listeners.contentProtection(activity.type, activity);
350
+ break;
351
+ case "context_menu":
352
+ this.listeners.contextMenu(data as ContextMenuEvent);
353
+ break;
354
+ case "keyboard_peripherals":
355
+ this.listeners.peripheral(data as KeyboardEventData);
356
+ break;
285
357
  case "log":
286
358
  console.log(this.framePool.currentFrames[0]?.source?.split("/")[3], ...(data as any[]));
287
359
  break;
@@ -317,6 +389,14 @@ export class WebPubNavigator extends VisualNavigator implements Configurable<Web
317
389
  }
318
390
 
319
391
  public async destroy() {
392
+ if (this._suspiciousActivityListener) {
393
+ window.removeEventListener(NAVIGATOR_SUSPICIOUS_ACTIVITY_EVENT, this._suspiciousActivityListener);
394
+ }
395
+ if (this._keyboardPeripheralListener) {
396
+ window.removeEventListener(NAVIGATOR_KEYBOARD_PERIPHERAL_EVENT, this._keyboardPeripheralListener);
397
+ }
398
+ this._navigatorProtector?.destroy();
399
+ this._keyboardPeripheralsManager?.destroy();
320
400
  await this.framePool?.destroy();
321
401
  }
322
402
 
@@ -419,7 +499,7 @@ export class WebPubNavigator extends VisualNavigator implements Configurable<Web
419
499
 
420
500
  private async loadLocator(locator: Locator, cb: (ok: boolean) => void) {
421
501
  let done = false;
422
- let cssSelector = (typeof locator.locations.getCssSelector === 'function') && locator.locations.getCssSelector();
502
+ let cssSelector = (typeof locator.locations.getCssSelector === "function") && locator.locations.getCssSelector();
423
503
  if(locator.text?.highlight) {
424
504
  done = await new Promise<boolean>((res, _) => {
425
505
  // Attempt to go to a highlighted piece of text in the resource
@@ -451,7 +531,7 @@ export class WebPubNavigator extends VisualNavigator implements Configurable<Web
451
531
  // This sanity check has to be performed because we're still passing non-locator class
452
532
  // locator objects to this function. This is not good and should eventually be forbidden
453
533
  // or the locator should be deserialized sometime before this function.
454
- const hid = (typeof locator.locations.htmlId === 'function') && locator.locations.htmlId();
534
+ const hid = (typeof locator.locations.htmlId === "function") && locator.locations.htmlId();
455
535
  if(hid)
456
536
  done = await new Promise<boolean>((res, _) => {
457
537
  // Attempt to go to an HTML ID in the resource
@@ -1,5 +1,9 @@
1
1
  import { Link, Locator, Publication, ReadingProgression } from "@readium/shared";
2
+ import { ContentProtectionConfig, PrintProtectionConfig, KeyboardPeripheral } from "@readium/navigator-html-injectables";
2
3
  type cbb = (ok: boolean) => void;
4
+ export type IKeyboardPeripheralsConfig = Array<Omit<KeyboardPeripheral, 'type'> & {
5
+ type: Exclude<string, 'developer_tools' | 'select_all' | 'print' | 'save'>;
6
+ }>;
3
7
  export interface ProgressionRange {
4
8
  start: number;
5
9
  end: number;
@@ -9,6 +13,11 @@ export interface VisualNavigatorViewport {
9
13
  progressions: Map<string, ProgressionRange>;
10
14
  positions: number[] | null;
11
15
  }
16
+ export interface IContentProtectionConfig extends ContentProtectionConfig {
17
+ protectPrinting?: PrintProtectionConfig;
18
+ checkAutomation?: boolean;
19
+ checkIFrameEmbedding?: boolean;
20
+ }
12
21
  export declare abstract class Navigator {
13
22
  abstract get publication(): Publication;
14
23
  abstract get currentLocator(): Locator;
@@ -32,6 +41,11 @@ export declare abstract class Navigator {
32
41
  * Destroy all resources associated with this navigator. Synonymous with "unmount"
33
42
  */
34
43
  abstract destroy(): void;
44
+ /**
45
+ * Merges keyboard peripherals from content protection config with user-provided peripherals
46
+ * Content protection peripherals are added first for priority, then user peripherals are added only if they don't conflict
47
+ */
48
+ protected mergeKeyboardPeripherals(config: IContentProtectionConfig, keyboardPeripherals?: IKeyboardPeripheralsConfig): IKeyboardPeripheralsConfig;
35
49
  }
36
50
  export declare abstract class VisualNavigator extends Navigator {
37
51
  /**
@@ -2,8 +2,8 @@ import { Layout, Link, Locator, Publication, ReadingProgression } from "@readium
2
2
  import { Configurable, ConfigurablePreferences, ConfigurableSettings, VisualNavigator, VisualNavigatorViewport } from "../";
3
3
  import { FramePoolManager } from "./frame/FramePoolManager";
4
4
  import { FXLFramePoolManager } from "./fxl/FXLFramePoolManager";
5
- import { CommsEventKey } from "@readium/navigator-html-injectables";
6
- import { BasicTextSelection, FrameClickEvent } from "@readium/navigator-html-injectables";
5
+ import { CommsEventKey, ContextMenuEvent, KeyboardEventData } from "@readium/navigator-html-injectables";
6
+ import { BasicTextSelection, FrameClickEvent, SuspiciousActivityEvent } from "@readium/navigator-html-injectables";
7
7
  import { FXLFrameManager } from "./fxl/FXLFrameManager";
8
8
  import { FrameManager } from "./frame/FrameManager";
9
9
  import { IEpubPreferences, EpubPreferences } from "./preferences/EpubPreferences";
@@ -11,11 +11,14 @@ import { IEpubDefaults } from "./preferences/EpubDefaults";
11
11
  import { EpubSettings } from "./preferences";
12
12
  import { EpubPreferencesEditor } from "./preferences/EpubPreferencesEditor";
13
13
  import { IInjectablesConfig } from "../injection/Injectable";
14
+ import { IContentProtectionConfig, IKeyboardPeripheralsConfig } from "../Navigator";
14
15
  export type ManagerEventKey = "zoom";
15
16
  export interface EpubNavigatorConfiguration {
16
17
  preferences: IEpubPreferences;
17
18
  defaults: IEpubDefaults;
18
19
  injectables?: IInjectablesConfig;
20
+ contentProtection?: IContentProtectionConfig;
21
+ keyboardPeripherals?: IKeyboardPeripheralsConfig;
19
22
  }
20
23
  export interface EpubNavigatorListeners {
21
24
  frameLoaded: (wnd: Window) => void;
@@ -28,6 +31,9 @@ export interface EpubNavigatorListeners {
28
31
  customEvent: (key: string, data: unknown) => void;
29
32
  handleLocator: (locator: Locator) => boolean;
30
33
  textSelected: (selection: BasicTextSelection) => void;
34
+ contentProtection: (type: string, data: SuspiciousActivityEvent) => void;
35
+ contextMenu: (data: ContextMenuEvent) => void;
36
+ peripheral: (data: KeyboardEventData) => void;
31
37
  }
32
38
  export declare class EpubNavigator extends VisualNavigator implements Configurable<ConfigurableSettings, ConfigurablePreferences> {
33
39
  private readonly pub;
@@ -45,6 +51,12 @@ export declare class EpubNavigator extends VisualNavigator implements Configurab
45
51
  private _css;
46
52
  private _preferencesEditor;
47
53
  private readonly _injector;
54
+ private readonly _contentProtection;
55
+ private readonly _keyboardPeripherals;
56
+ private readonly _navigatorProtector;
57
+ private readonly _keyboardPeripheralsManager;
58
+ private readonly _suspiciousActivityListener;
59
+ private readonly _keyboardPeripheralListener;
48
60
  private resizeObserver;
49
61
  private reflowViewport;
50
62
  constructor(container: HTMLElement, pub: Publication, listeners: EpubNavigatorListeners, positions?: Locator[], initialPosition?: Locator | undefined, configuration?: EpubNavigatorConfiguration);
@@ -104,6 +104,8 @@ export interface IRSProperties {
104
104
  sansSerifJaV?: string | null;
105
105
  sansTf?: string | null;
106
106
  scrollPaddingBottom?: number | null;
107
+ scrollPaddingLeft?: number | null;
108
+ scrollPaddingRight?: number | null;
107
109
  scrollPaddingTop?: number | null;
108
110
  secondaryColor?: string | null;
109
111
  selectionBackgroundColor?: string | null;
@@ -146,6 +148,8 @@ export declare class RSProperties extends Properties {
146
148
  sansSerifJaV: string | null;
147
149
  sansTf: string | null;
148
150
  scrollPaddingBottom: number | null;
151
+ scrollPaddingLeft: number | null;
152
+ scrollPaddingRight: number | null;
149
153
  scrollPaddingTop: number | null;
150
154
  secondaryColor: string | null;
151
155
  selectionBackgroundColor: string | null;
@@ -1,5 +1,6 @@
1
1
  import { Loader, ModuleName } from "@readium/navigator-html-injectables";
2
2
  import { FrameComms } from "./FrameComms";
3
+ import type { IContentProtectionConfig, IKeyboardPeripheralsConfig } from "../../Navigator";
3
4
  export declare class FrameManager {
4
5
  private frame;
5
6
  private loader;
@@ -7,9 +8,12 @@ export declare class FrameManager {
7
8
  private comms;
8
9
  private hidden;
9
10
  private destroyed;
11
+ private readonly contentProtectionConfig;
12
+ private readonly keyboardPeripheralsConfig;
10
13
  private currModules;
11
- constructor(source: string);
14
+ constructor(source: string, contentProtectionConfig?: IContentProtectionConfig, keyboardPeripheralsConfig?: IKeyboardPeripheralsConfig);
12
15
  load(modules: ModuleName[]): Promise<Window>;
16
+ private applyContentProtection;
13
17
  destroy(): Promise<void>;
14
18
  hide(): Promise<void>;
15
19
  show(atProgress?: number): Promise<void>;
@@ -2,6 +2,7 @@ import { ModuleName } from "@readium/navigator-html-injectables";
2
2
  import { Locator, Publication } from "@readium/shared";
3
3
  import { FrameManager } from "./FrameManager";
4
4
  import { Injector } from "../../injection/Injector";
5
+ import { IContentProtectionConfig, IKeyboardPeripheralsConfig } from "../../Navigator";
5
6
  export declare class FramePoolManager {
6
7
  private readonly container;
7
8
  private readonly positions;
@@ -13,9 +14,11 @@ export declare class FramePoolManager {
13
14
  private pendingUpdates;
14
15
  private currentBaseURL;
15
16
  private readonly injector;
17
+ private readonly contentProtectionConfig;
18
+ private readonly keyboardPeripheralsConfig;
16
19
  constructor(container: HTMLElement, positions: Locator[], cssProperties?: {
17
20
  [key: string]: string;
18
- }, injector?: Injector | null);
21
+ }, injector?: Injector | null, contentProtectionConfig?: IContentProtectionConfig, keyboardPeripheralsConfig?: IKeyboardPeripheralsConfig);
19
22
  destroy(): Promise<void>;
20
23
  update(pub: Publication, locator: Locator, modules: ModuleName[], force?: boolean): Promise<void>;
21
24
  setCSSProperties(properties: {
@@ -2,18 +2,21 @@ import { Loader, ModuleName } from "@readium/navigator-html-injectables";
2
2
  import { Page, ReadingProgression } from "@readium/shared";
3
3
  import { FrameComms } from "../frame/FrameComms";
4
4
  import { FXLPeripherals } from "./FXLPeripherals";
5
+ import { IContentProtectionConfig, IKeyboardPeripheralsConfig } from "../../Navigator";
5
6
  export declare class FXLFrameManager {
6
7
  private frame;
7
8
  private loader;
8
9
  source: string;
9
10
  private comms;
10
11
  private readonly peripherals;
12
+ private readonly contentProtectionConfig;
13
+ private readonly keyboardPeripheralsConfig;
11
14
  private currModules;
12
15
  wrapper: HTMLDivElement;
13
16
  debugHref: string;
14
17
  private loadPromise;
15
18
  private showPromise;
16
- constructor(peripherals: FXLPeripherals, direction: ReadingProgression, debugHref: string);
19
+ constructor(peripherals: FXLPeripherals, direction: ReadingProgression, debugHref: string, contentProtectionConfig?: IContentProtectionConfig, keyboardPeripheralsConfig?: IKeyboardPeripheralsConfig);
17
20
  load(modules: ModuleName[], source: string): Promise<Window>;
18
21
  loadPageSize(): {
19
22
  width: number;
@@ -24,6 +27,7 @@ export declare class FXLFrameManager {
24
27
  unload(): Promise<void>;
25
28
  deselect(): void;
26
29
  unfocus(): Promise<void>;
30
+ private applyContentProtection;
27
31
  private cachedPage;
28
32
  show(page: Page): Promise<void>;
29
33
  activate(): Promise<void>;
@@ -3,7 +3,7 @@ import { Locator, Publication, Page, Link } from "@readium/shared";
3
3
  import { FrameCommsListener } from "../frame";
4
4
  import { FXLFrameManager } from "./FXLFrameManager";
5
5
  import { FXLPeripherals } from "./FXLPeripherals";
6
- import { VisualNavigatorViewport } from "../../Navigator";
6
+ import { VisualNavigatorViewport, IContentProtectionConfig, IKeyboardPeripheralsConfig } from "../../Navigator";
7
7
  import { Injector } from "../../injection/Injector";
8
8
  export declare class FXLFramePoolManager {
9
9
  private readonly container;
@@ -16,6 +16,8 @@ export declare class FXLFramePoolManager {
16
16
  private currentBaseURL;
17
17
  private previousFrames;
18
18
  private readonly injector;
19
+ private readonly contentProtectionConfig;
20
+ private readonly keyboardPeripheralsConfig;
19
21
  private readonly bookElement;
20
22
  readonly spineElement: HTMLDivElement;
21
23
  private readonly pub;
@@ -30,7 +32,7 @@ export declare class FXLFramePoolManager {
30
32
  private containerHeightCached;
31
33
  private resizeTimeout;
32
34
  readonly peripherals: FXLPeripherals;
33
- constructor(container: HTMLElement, positions: Locator[], pub: Publication, injector?: Injector | null);
35
+ constructor(container: HTMLElement, positions: Locator[], pub: Publication, injector?: Injector | null, contentProtectionConfig?: IContentProtectionConfig, keyboardPeripheralsConfig?: IKeyboardPeripheralsConfig);
34
36
  private _listener;
35
37
  set listener(listener: FrameCommsListener);
36
38
  get listener(): FrameCommsListener;
@@ -31,6 +31,8 @@ export interface IEpubDefaults {
31
31
  scroll?: boolean | null;
32
32
  scrollPaddingTop?: number | null;
33
33
  scrollPaddingBottom?: number | null;
34
+ scrollPaddingLeft?: number | null;
35
+ scrollPaddingRight?: number | null;
34
36
  selectionBackgroundColor?: string | null;
35
37
  selectionTextColor?: string | null;
36
38
  textAlign?: TextAlignment | null;
@@ -72,6 +74,8 @@ export declare class EpubDefaults {
72
74
  scroll: boolean | null;
73
75
  scrollPaddingTop: number | null;
74
76
  scrollPaddingBottom: number | null;
77
+ scrollPaddingLeft: number | null;
78
+ scrollPaddingRight: number | null;
75
79
  selectionBackgroundColor: string | null;
76
80
  selectionTextColor: string | null;
77
81
  textAlign: TextAlignment | null;
@@ -32,6 +32,8 @@ export interface IEpubPreferences {
32
32
  scroll?: boolean | null;
33
33
  scrollPaddingTop?: number | null;
34
34
  scrollPaddingBottom?: number | null;
35
+ scrollPaddingLeft?: number | null;
36
+ scrollPaddingRight?: number | null;
35
37
  selectionBackgroundColor?: string | null;
36
38
  selectionTextColor?: string | null;
37
39
  textAlign?: TextAlignment | null;
@@ -72,6 +74,8 @@ export declare class EpubPreferences implements ConfigurablePreferences {
72
74
  scroll?: boolean | null;
73
75
  scrollPaddingTop?: number | null;
74
76
  scrollPaddingBottom?: number | null;
77
+ scrollPaddingLeft?: number | null;
78
+ scrollPaddingRight?: number | null;
75
79
  selectionBackgroundColor?: string | null;
76
80
  selectionTextColor?: string | null;
77
81
  textAlign?: TextAlignment | null;
@@ -43,6 +43,8 @@ export declare class EpubPreferencesEditor implements IPreferencesEditor {
43
43
  get scroll(): BooleanPreference;
44
44
  get scrollPaddingTop(): Preference<number>;
45
45
  get scrollPaddingBottom(): Preference<number>;
46
+ get scrollPaddingLeft(): Preference<number>;
47
+ get scrollPaddingRight(): Preference<number>;
46
48
  get selectionBackgroundColor(): Preference<string>;
47
49
  get selectionTextColor(): Preference<string>;
48
50
  get textAlign(): EnumPreference<TextAlignment>;
@@ -34,6 +34,8 @@ export interface IEpubSettings {
34
34
  scroll?: boolean | null;
35
35
  scrollPaddingTop?: number | null;
36
36
  scrollPaddingBottom?: number | null;
37
+ scrollPaddingLeft?: number | null;
38
+ scrollPaddingRight?: number | null;
37
39
  selectionBackgroundColor?: string | null;
38
40
  selectionTextColor?: string | null;
39
41
  textAlign?: TextAlignment | null;
@@ -75,6 +77,8 @@ export declare class EpubSettings implements ConfigurableSettings {
75
77
  scroll: boolean | null;
76
78
  scrollPaddingTop: number | null;
77
79
  scrollPaddingBottom: number | null;
80
+ scrollPaddingLeft: number | null;
81
+ scrollPaddingRight: number | null;
78
82
  selectionBackgroundColor: string | null;
79
83
  selectionTextColor: string | null;
80
84
  textAlign: TextAlignment | null;
@@ -8,7 +8,7 @@ export interface ILineLengthsConfig {
8
8
  maxChars?: number | null;
9
9
  baseFontSize?: number | null;
10
10
  sample?: string | null;
11
- pageGutter?: number | null;
11
+ padding?: number | null;
12
12
  fontFace?: string | ICustomFontFace | null;
13
13
  letterSpacing?: number | null;
14
14
  wordSpacing?: number | null;
@@ -29,12 +29,11 @@ export declare class LineLengths {
29
29
  private _baseFontSize;
30
30
  private _fontFace;
31
31
  private _sample;
32
- private _pageGutter;
32
+ private _padding;
33
33
  private _letterSpacing;
34
34
  private _wordSpacing;
35
35
  private _isCJK;
36
36
  private _getRelative;
37
- private _padding;
38
37
  private _minDivider;
39
38
  private _maxMultiplier;
40
39
  private _approximatedWordSpaces;
@@ -1,6 +1,6 @@
1
1
  import { IInjectableRule } from "../injection/Injectable";
2
- import { Metadata } from "@readium/shared";
2
+ import { Metadata, Link } from "@readium/shared";
3
3
  /**
4
4
  * Creates injectable rules for EPUB content documents
5
5
  */
6
- export declare function createReadiumEpubRules(metadata: Metadata): IInjectableRule[];
6
+ export declare function createReadiumEpubRules(metadata: Metadata, readingOrderItems: Link[]): IInjectableRule[];
@@ -1,5 +1,6 @@
1
1
  import { IInjectableRule } from "../injection/Injectable";
2
+ import { Link } from "@readium/shared";
2
3
  /**
3
4
  * Creates injectable rules for WebPub content documents
4
5
  */
5
- export declare function createReadiumWebPubRules(): IInjectableRule[];
6
+ export declare function createReadiumWebPubRules(readingOrderItems: Link[]): IInjectableRule[];
@@ -0,0 +1,13 @@
1
+ import { KeyboardPeripheral } from "@readium/navigator-html-injectables";
2
+ export declare const NAVIGATOR_KEYBOARD_PERIPHERAL_EVENT = "readium:navigator:keyboardPeripheral";
3
+ export interface KeyboardPeripheralOptions {
4
+ /** Array of keyboard peripherals to configure */
5
+ keyboardPeripherals?: KeyboardPeripheral[];
6
+ }
7
+ export declare class KeyboardPeripherals {
8
+ private keydownHandler?;
9
+ private keyManager;
10
+ constructor(options?: KeyboardPeripheralOptions);
11
+ private setupKeyboardPeripherals;
12
+ destroy(): void;
13
+ }
@@ -0,0 +1,14 @@
1
+ export interface AutomationDetectorOptions {
2
+ /** Callback when an automation tool is detected */
3
+ onDetected?: (tool: string) => void;
4
+ }
5
+ export declare class AutomationDetector {
6
+ private options;
7
+ private detectedTools;
8
+ private observer?;
9
+ constructor(options: AutomationDetectorOptions);
10
+ private isAutomationToolPresent;
11
+ private setupDetection;
12
+ private handleDetected;
13
+ destroy(): void;
14
+ }