@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.
- package/dist/index.js +3079 -3225
- package/dist/index.umd.cjs +80 -87
- package/package.json +5 -4
- package/src/Navigator.ts +76 -0
- package/src/epub/EpubNavigator.ts +93 -10
- package/src/epub/css/Properties.ts +8 -8
- package/src/epub/css/ReadiumCSS.ts +7 -5
- package/src/epub/frame/FrameManager.ts +38 -2
- package/src/epub/frame/FramePoolManager.ts +9 -2
- package/src/epub/fxl/FXLFrameManager.ts +31 -2
- package/src/epub/fxl/FXLFramePoolManager.ts +9 -3
- package/src/epub/preferences/EpubDefaults.ts +6 -6
- package/src/epub/preferences/EpubPreferences.ts +6 -6
- package/src/epub/preferences/EpubPreferencesEditor.ts +1 -3
- package/src/epub/preferences/EpubSettings.ts +5 -7
- package/src/helpers/lineLength.ts +4 -6
- package/src/injection/epubInjectables.ts +11 -3
- package/src/injection/webpubInjectables.ts +12 -2
- package/src/peripherals/KeyboardPeripherals.ts +53 -0
- package/src/protection/AutomationDetector.ts +66 -0
- package/src/protection/ContextMenuProtector.ts +46 -0
- package/src/protection/DevToolsDetector.ts +290 -0
- package/src/protection/IframeEmbeddingDetector.ts +73 -0
- package/src/protection/NavigatorProtector.ts +95 -0
- package/src/protection/PrintProtector.ts +58 -0
- package/src/protection/utils/WorkerConsole.ts +84 -0
- package/src/protection/utils/console.ts +16 -0
- package/src/protection/utils/match.ts +18 -0
- package/src/protection/utils/platform.ts +22 -0
- package/src/webpub/WebPubFrameManager.ts +38 -5
- package/src/webpub/WebPubFramePoolManager.ts +9 -2
- package/src/webpub/WebPubNavigator.ts +87 -7
- package/types/src/Navigator.d.ts +14 -0
- package/types/src/epub/EpubNavigator.d.ts +14 -2
- package/types/src/epub/css/Properties.d.ts +4 -0
- package/types/src/epub/frame/FrameManager.d.ts +5 -1
- package/types/src/epub/frame/FramePoolManager.d.ts +4 -1
- package/types/src/epub/fxl/FXLFrameManager.d.ts +5 -1
- package/types/src/epub/fxl/FXLFramePoolManager.d.ts +4 -2
- package/types/src/epub/preferences/EpubDefaults.d.ts +4 -0
- package/types/src/epub/preferences/EpubPreferences.d.ts +4 -0
- package/types/src/epub/preferences/EpubPreferencesEditor.d.ts +2 -0
- package/types/src/epub/preferences/EpubSettings.d.ts +4 -0
- package/types/src/helpers/lineLength.d.ts +2 -3
- package/types/src/injection/epubInjectables.d.ts +2 -2
- package/types/src/injection/webpubInjectables.d.ts +2 -1
- package/types/src/peripherals/KeyboardPeripherals.d.ts +13 -0
- package/types/src/protection/AutomationDetector.d.ts +14 -0
- package/types/src/protection/ContextMenuProtector.d.ts +11 -0
- package/types/src/protection/DevToolsDetector.d.ts +75 -0
- package/types/src/protection/IframeEmbeddingDetector.d.ts +14 -0
- package/types/src/protection/NavigatorProtector.d.ts +12 -0
- package/types/src/protection/PrintProtector.d.ts +13 -0
- package/types/src/protection/utils/WorkerConsole.d.ts +15 -0
- package/types/src/protection/utils/console.d.ts +6 -0
- package/types/src/protection/utils/match.d.ts +8 -0
- package/types/src/protection/utils/platform.d.ts +4 -0
- package/types/src/webpub/WebPubFrameManager.d.ts +5 -1
- package/types/src/webpub/WebPubFramePoolManager.d.ts +4 -1
- package/types/src/webpub/WebPubNavigator.d.ts +13 -1
- package/dist/ar-DyHX_uy2-DyHX_uy2.js +0 -7
- package/dist/assets/AccessibleDfA-Bold.woff2 +0 -0
- package/dist/assets/AccessibleDfA-Italic.woff2 +0 -0
- package/dist/assets/AccessibleDfA-Regular.woff +0 -0
- package/dist/assets/AccessibleDfA-Regular.woff2 +0 -0
- package/dist/assets/iAWriterDuospace-Regular.ttf +0 -0
- package/dist/da-Dct0PS3E-Dct0PS3E.js +0 -7
- package/dist/fr-C5HEel98-C5HEel98.js +0 -7
- package/dist/it-DFOBoXGy-DFOBoXGy.js +0 -7
- package/dist/pt_PT-Di3sVjze-Di3sVjze.js +0 -7
- package/dist/sv-BfzAFsVN-BfzAFsVN.js +0 -7
- package/types/src/epub/preferences/guards.d.ts +0 -9
- package/types/src/web/WebPubBlobBuilder.d.ts +0 -10
- package/types/src/web/WebPubFrameManager.d.ts +0 -20
- package/types/src/web/WebPubNavigator.d.ts +0 -48
- package/types/src/web/index.d.ts +0 -3
- package/types/src/webpub/css/WebPubStylesheet.d.ts +0 -1
- /package/dist/{ar-DyHX_uy2-DyHX_uy2-DyHX_uy2.js → ar-DyHX_uy2.js} +0 -0
- /package/dist/{da-Dct0PS3E-Dct0PS3E-Dct0PS3E.js → da-Dct0PS3E.js} +0 -0
- /package/dist/{fr-C5HEel98-C5HEel98-C5HEel98.js → fr-C5HEel98.js} +0 -0
- /package/dist/{it-DFOBoXGy-DFOBoXGy-DFOBoXGy.js → it-DFOBoXGy.js} +0 -0
- /package/dist/{pt_PT-Di3sVjze-Di3sVjze-Di3sVjze.js → pt_PT-Di3sVjze.js} +0 -0
- /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(
|
|
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
|
-
|
|
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 ===
|
|
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(
|
|
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 ===
|
|
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 ===
|
|
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
|
package/types/src/Navigator.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
+
}
|