@readium/navigator-html-injectables 2.3.1-alpha.2 → 2.4.0-beta.1
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 +852 -701
- package/dist/index.umd.cjs +24 -13
- package/package.json +8 -8
- package/src/Loader.ts +3 -3
- package/src/comms/comms.ts +5 -5
- package/src/comms/index.ts +3 -3
- package/src/helpers/css.ts +2 -4
- package/src/helpers/document.ts +13 -10
- package/src/helpers/locator.ts +2 -2
- package/src/index.ts +4 -4
- package/src/modules/Decorator.ts +18 -18
- package/src/modules/Module.ts +4 -4
- package/src/modules/ModuleLibrary.ts +15 -11
- package/src/modules/Peripherals.ts +70 -61
- package/src/modules/index.ts +4 -4
- package/src/modules/setup/FixedSetup.ts +6 -6
- package/src/modules/setup/ReflowableSetup.ts +6 -6
- package/src/modules/setup/Setup.ts +5 -5
- package/src/modules/setup/WebPubSetup.ts +5 -5
- package/src/modules/snapper/CJKVerticalSnapper.ts +322 -0
- package/src/modules/snapper/ColumnSnapper.ts +161 -99
- package/src/modules/snapper/ScrollSnapper.ts +18 -18
- package/src/modules/snapper/Snapper.ts +5 -5
- package/src/modules/snapper/WebPubSnapper.ts +15 -15
- package/src/protection/BulkCopyProtector.ts +15 -15
- package/src/protection/KeyCombinationManager.ts +8 -8
- package/src/protection/PatternAnalyzer.ts +18 -18
- package/src/protection/PrintProtector.ts +12 -12
- package/src/protection/SelectionAnalyzer.ts +1 -1
- package/src/protection/config.ts +4 -4
- package/src/protection/index.ts +6 -6
- package/src/vendor/hypothesis/anchoring/html.ts +1 -1
- package/src/vendor/hypothesis/anchoring/types.ts +1 -1
- package/types/src/Loader.d.ts +2 -2
- package/types/src/comms/comms.d.ts +2 -2
- package/types/src/comms/index.d.ts +3 -3
- package/types/src/helpers/css.d.ts +1 -2
- package/types/src/helpers/document.d.ts +1 -1
- package/types/src/index.d.ts +4 -4
- package/types/src/modules/Decorator.d.ts +4 -4
- package/types/src/modules/Module.d.ts +3 -3
- package/types/src/modules/ModuleLibrary.d.ts +2 -2
- package/types/src/modules/Peripherals.d.ts +10 -9
- package/types/src/modules/index.d.ts +4 -4
- package/types/src/modules/setup/FixedSetup.d.ts +4 -4
- package/types/src/modules/setup/ReflowableSetup.d.ts +3 -3
- package/types/src/modules/setup/Setup.d.ts +4 -4
- package/types/src/modules/setup/WebPubSetup.d.ts +3 -3
- package/types/src/modules/snapper/CJKVerticalSnapper.d.ts +57 -0
- package/types/src/modules/snapper/ColumnSnapper.d.ts +16 -5
- package/types/src/modules/snapper/ScrollSnapper.d.ts +5 -5
- package/types/src/modules/snapper/Snapper.d.ts +4 -4
- package/types/src/modules/snapper/WebPubSnapper.d.ts +5 -5
- package/types/src/protection/BulkCopyProtector.d.ts +1 -1
- package/types/src/protection/KeyCombinationManager.d.ts +3 -3
- package/types/src/protection/PrintProtector.d.ts +4 -4
- package/types/src/protection/config.d.ts +3 -3
- package/types/src/protection/index.d.ts +6 -6
- package/types/src/vendor/hypothesis/anchoring/html.d.ts +1 -1
- package/types/src/vendor/hypothesis/anchoring/types.d.ts +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReadiumWindow } from "../helpers/dom";
|
|
1
|
+
import { ReadiumWindow } from "../helpers/dom.ts";
|
|
2
2
|
|
|
3
3
|
interface CopyAttempt {
|
|
4
4
|
timestamp: number;
|
|
@@ -33,7 +33,7 @@ export class BulkCopyProtector {
|
|
|
33
33
|
this.copyHistory = this.copyHistory.filter(
|
|
34
34
|
attempt => now - attempt.timestamp < historyWindow
|
|
35
35
|
);
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
// Trim to max history size
|
|
38
38
|
if (this.copyHistory.length > this.options.historySize) {
|
|
39
39
|
this.copyHistory = this.copyHistory.slice(-this.options.historySize);
|
|
@@ -42,17 +42,17 @@ export class BulkCopyProtector {
|
|
|
42
42
|
|
|
43
43
|
private isSuspiciousPattern(now: number): boolean {
|
|
44
44
|
if (this.copyHistory.length < 3) return false;
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
// Check for rapid successive copy attempts
|
|
47
47
|
const recentAttempts = this.copyHistory.filter(
|
|
48
48
|
attempt => now - attempt.timestamp < 2000 // Last 2 seconds
|
|
49
49
|
);
|
|
50
|
-
|
|
50
|
+
|
|
51
51
|
if (recentAttempts.length >= 3) {
|
|
52
52
|
// If multiple rapid copy attempts, it's suspicious
|
|
53
53
|
return true;
|
|
54
54
|
}
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
// Check for increasing selection sizes (bulk copy pattern)
|
|
57
57
|
const increasingSelections = this.copyHistory
|
|
58
58
|
.slice()
|
|
@@ -61,7 +61,7 @@ export class BulkCopyProtector {
|
|
|
61
61
|
if (i === 0) return true;
|
|
62
62
|
return attempt.length > arr[i - 1].length * 1.5; // Each selection is significantly larger
|
|
63
63
|
});
|
|
64
|
-
|
|
64
|
+
|
|
65
65
|
return increasingSelections;
|
|
66
66
|
}
|
|
67
67
|
|
|
@@ -70,7 +70,7 @@ export class BulkCopyProtector {
|
|
|
70
70
|
|
|
71
71
|
const selection = this.window.getSelection();
|
|
72
72
|
if (!selection) return true;
|
|
73
|
-
|
|
73
|
+
|
|
74
74
|
const selectedText = selection.toString();
|
|
75
75
|
const selectedLength = selectedText.length;
|
|
76
76
|
const docLength = this.window.document.body.innerText.length;
|
|
@@ -90,12 +90,12 @@ export class BulkCopyProtector {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
const timeSinceLastSelection = now - this.lastSelectionTime;
|
|
93
|
-
|
|
93
|
+
|
|
94
94
|
// Check for rapid successive selections
|
|
95
|
-
const isRapidSelection =
|
|
96
|
-
timeSinceLastSelection < 100 &&
|
|
95
|
+
const isRapidSelection =
|
|
96
|
+
timeSinceLastSelection < 100 &&
|
|
97
97
|
selectedLength > this.lastSelectionLength * 1.5;
|
|
98
|
-
|
|
98
|
+
|
|
99
99
|
const maxAllowedSelection = Math.min(
|
|
100
100
|
docLength * this.options.maxSelectionPercent,
|
|
101
101
|
this.options.absoluteMaxChars
|
|
@@ -103,9 +103,9 @@ export class BulkCopyProtector {
|
|
|
103
103
|
|
|
104
104
|
// Check if this matches a suspicious pattern
|
|
105
105
|
const isSuspicious = this.isSuspiciousPattern(now);
|
|
106
|
-
|
|
107
|
-
const shouldBlock = selectedLength > maxAllowedSelection ||
|
|
108
|
-
isRapidSelection ||
|
|
106
|
+
|
|
107
|
+
const shouldBlock = selectedLength > maxAllowedSelection ||
|
|
108
|
+
isRapidSelection ||
|
|
109
109
|
isSuspicious;
|
|
110
110
|
|
|
111
111
|
// Record this attempt in history
|
|
@@ -119,7 +119,7 @@ export class BulkCopyProtector {
|
|
|
119
119
|
event?.preventDefault();
|
|
120
120
|
return false;
|
|
121
121
|
}
|
|
122
|
-
|
|
122
|
+
|
|
123
123
|
this.lastSelectionLength = selectedLength;
|
|
124
124
|
this.lastSelectionTime = now;
|
|
125
125
|
return true;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { KeyCombo, KeyboardPeripheral } from "./KeyboardCombinations";
|
|
2
|
-
import { BaseKeyboardPeripheralEvent, KeyboardEventData, BasicTextSelection } from "../modules/Peripherals";
|
|
3
|
-
import { ReadiumWindow } from "../helpers/dom";
|
|
1
|
+
import { KeyCombo, KeyboardPeripheral } from "./KeyboardCombinations.ts";
|
|
2
|
+
import { BaseKeyboardPeripheralEvent, KeyboardEventData, BasicTextSelection } from "../modules/Peripherals.ts";
|
|
3
|
+
import { ReadiumWindow } from "../helpers/dom.ts";
|
|
4
4
|
|
|
5
5
|
export type KeyHandler = (event: KeyboardEvent) => void;
|
|
6
6
|
export type ActivityEventDispatcher = (event: KeyboardPeripheralEvent) => void;
|
|
@@ -24,7 +24,7 @@ export class KeyCombinationManager {
|
|
|
24
24
|
const shiftMatch = combo.shift === undefined || event.shiftKey === combo.shift;
|
|
25
25
|
const altMatch = combo.alt === undefined || event.altKey === combo.alt;
|
|
26
26
|
const metaMatch = combo.meta === undefined || event.metaKey === combo.meta;
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
if (keyMatch && ctrlMatch && shiftMatch && altMatch && metaMatch) {
|
|
29
29
|
return true;
|
|
30
30
|
}
|
|
@@ -49,7 +49,7 @@ export class KeyCombinationManager {
|
|
|
49
49
|
* Creates a standardized activity event for keyboard shortcuts
|
|
50
50
|
*/
|
|
51
51
|
private createActivityEvent(
|
|
52
|
-
event: KeyboardEvent,
|
|
52
|
+
event: KeyboardEvent,
|
|
53
53
|
type: string,
|
|
54
54
|
targetFrameSrc: string,
|
|
55
55
|
wnd?: ReadiumWindow,
|
|
@@ -61,7 +61,7 @@ export class KeyCombinationManager {
|
|
|
61
61
|
const selectedTextStr = selection?.toString() || '';
|
|
62
62
|
const domRectList = (selectedTextStr && selection?.rangeCount) ? selection.getRangeAt(0)?.getClientRects() : null;
|
|
63
63
|
const rect = domRectList?.[0];
|
|
64
|
-
|
|
64
|
+
|
|
65
65
|
if (rect && selectedTextStr) {
|
|
66
66
|
selectedText = {
|
|
67
67
|
text: selectedTextStr,
|
|
@@ -124,7 +124,7 @@ export class KeyCombinationManager {
|
|
|
124
124
|
wnd?: ReadiumWindow,
|
|
125
125
|
): (event: KeyboardEvent) => void {
|
|
126
126
|
const handlers = this.createKeyboardHandlers(targetFrameSrc, shortcuts, dispatcher, wnd);
|
|
127
|
-
|
|
127
|
+
|
|
128
128
|
return (event: KeyboardEvent) => {
|
|
129
129
|
for (const handlerConfig of handlers) {
|
|
130
130
|
if (this.match(event, [handlerConfig])) {
|
|
@@ -136,4 +136,4 @@ export class KeyCombinationManager {
|
|
|
136
136
|
}
|
|
137
137
|
};
|
|
138
138
|
}
|
|
139
|
-
}
|
|
139
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DEFAULT_PATTERN_ANALYZER_CONFIG } from "./config";
|
|
1
|
+
import { DEFAULT_PATTERN_ANALYZER_CONFIG } from "./config.ts";
|
|
2
2
|
|
|
3
3
|
type Direction = "left" | "right" | "up" | "down";
|
|
4
4
|
|
|
@@ -10,7 +10,7 @@ export interface PatternAnalyzerOptions {
|
|
|
10
10
|
maxConsistentScrolls?: number; // Maximum number of consistent scrolls before flagging
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
// TODO: Improve for scroll protection,
|
|
13
|
+
// TODO: Improve for scroll protection,
|
|
14
14
|
// currently disabled because of false positives
|
|
15
15
|
export class PatternAnalyzer {
|
|
16
16
|
private options: PatternAnalyzerOptions;
|
|
@@ -20,9 +20,9 @@ export class PatternAnalyzer {
|
|
|
20
20
|
velocity: number;
|
|
21
21
|
distance: number;
|
|
22
22
|
}> = [];
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
private consistentScrollCount = 0;
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
constructor(
|
|
27
27
|
options: Partial<PatternAnalyzerOptions> = {}
|
|
28
28
|
) {
|
|
@@ -32,18 +32,18 @@ export class PatternAnalyzer {
|
|
|
32
32
|
|
|
33
33
|
analyze(direction: Direction, distance: number, timeDelta: number): boolean {
|
|
34
34
|
if (timeDelta <= 0) return false;
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
const velocity = Math.abs(distance) / timeDelta;
|
|
37
37
|
const now = Date.now();
|
|
38
|
-
|
|
38
|
+
|
|
39
39
|
// Add new event
|
|
40
|
-
this.history.push({
|
|
41
|
-
timestamp: now,
|
|
42
|
-
direction,
|
|
40
|
+
this.history.push({
|
|
41
|
+
timestamp: now,
|
|
42
|
+
direction,
|
|
43
43
|
velocity,
|
|
44
44
|
distance: Math.abs(distance)
|
|
45
45
|
});
|
|
46
|
-
|
|
46
|
+
|
|
47
47
|
// Clean up old events (keep last 2 seconds of data or historySize, whichever is smaller)
|
|
48
48
|
this.history = this.history
|
|
49
49
|
.filter(h => now - h.timestamp < 2000)
|
|
@@ -61,19 +61,19 @@ export class PatternAnalyzer {
|
|
|
61
61
|
// 2. Check for consistent scrolling patterns
|
|
62
62
|
const velocities = this.history.map(h => h.velocity);
|
|
63
63
|
const distances = this.history.map(h => h.distance);
|
|
64
|
-
|
|
64
|
+
|
|
65
65
|
// Calculate mean and variance of velocities and distances
|
|
66
66
|
const meanVelocity = velocities.reduce((a, b) => a + b, 0) / velocities.length;
|
|
67
67
|
const meanDistance = distances.reduce((a, b) => a + b, 0) / distances.length;
|
|
68
|
-
|
|
68
|
+
|
|
69
69
|
const velocityVariance = velocities.reduce((a, b) => a + Math.pow(b - meanVelocity, 2), 0) / velocities.length;
|
|
70
70
|
const distanceVariance = distances.reduce((a, b) => a + Math.pow(b - meanDistance, 2), 0) / distances.length;
|
|
71
71
|
|
|
72
72
|
// Check for suspiciously consistent scrolling (low variance in speed and distance)
|
|
73
|
-
if (velocityVariance < this.options.minVariance &&
|
|
73
|
+
if (velocityVariance < this.options.minVariance &&
|
|
74
74
|
distanceVariance < (meanDistance * 0.1)) { // Allow 10% variance in distance
|
|
75
75
|
this.consistentScrollCount++;
|
|
76
|
-
|
|
76
|
+
|
|
77
77
|
// Only trigger if we've seen consistent scrolling for a while
|
|
78
78
|
if (this.consistentScrollCount >= (this.options.maxConsistentScrolls || 10)) {
|
|
79
79
|
this.resetAfterDetection();
|
|
@@ -87,14 +87,14 @@ export class PatternAnalyzer {
|
|
|
87
87
|
// 3. Check for rapid direction changes (unnatural back-and-forth scrolling)
|
|
88
88
|
let directionChanges = 0;
|
|
89
89
|
let lastDirection = this.history[0].direction;
|
|
90
|
-
|
|
90
|
+
|
|
91
91
|
for (let i = 1; i < this.history.length; i++) {
|
|
92
92
|
if (this.history[i].direction !== lastDirection) {
|
|
93
93
|
directionChanges++;
|
|
94
94
|
lastDirection = this.history[i].direction;
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
|
-
|
|
97
|
+
|
|
98
98
|
const directionChangeRatio = directionChanges / this.history.length;
|
|
99
99
|
if (directionChangeRatio > (this.options.minDirectionChanges || 0.3)) {
|
|
100
100
|
this.resetAfterDetection();
|
|
@@ -109,9 +109,9 @@ export class PatternAnalyzer {
|
|
|
109
109
|
this.history = this.history.slice(-3);
|
|
110
110
|
this.consistentScrollCount = 0;
|
|
111
111
|
}
|
|
112
|
-
|
|
112
|
+
|
|
113
113
|
clear(): void {
|
|
114
114
|
this.history = [];
|
|
115
115
|
this.consistentScrollCount = 0;
|
|
116
116
|
}
|
|
117
|
-
}
|
|
117
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Comms } from "../comms";
|
|
2
|
-
import { ReadiumWindow } from "../helpers/dom";
|
|
3
|
-
import { Module } from "../modules/Module";
|
|
4
|
-
import { ModuleName } from "../modules/ModuleLibrary";
|
|
1
|
+
import { Comms } from "../comms/index.ts";
|
|
2
|
+
import { ReadiumWindow } from "../helpers/dom.ts";
|
|
3
|
+
import { Module } from "../modules/Module.ts";
|
|
4
|
+
import { ModuleName } from "../modules/ModuleLibrary.ts";
|
|
5
5
|
|
|
6
6
|
export interface PrintProtectionConfig {
|
|
7
7
|
disable?: boolean;
|
|
@@ -10,7 +10,7 @@ export interface PrintProtectionConfig {
|
|
|
10
10
|
|
|
11
11
|
export class PrintProtector extends Module {
|
|
12
12
|
static readonly moduleName: ModuleName = "print_protection";
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
private comms!: Comms;
|
|
15
15
|
private wnd!: ReadiumWindow;
|
|
16
16
|
private styleElement: HTMLStyleElement | null = null;
|
|
@@ -46,16 +46,16 @@ export class PrintProtector extends Module {
|
|
|
46
46
|
wnd.addEventListener("beforeprint", this.beforePrintHandler);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
private registerPrintHandlers() {
|
|
49
|
+
private registerPrintHandlers() {
|
|
50
50
|
this.comms?.register("print_protection", PrintProtector.moduleName, (data: unknown) => {
|
|
51
51
|
const config = data as PrintProtectionConfig;
|
|
52
|
-
|
|
52
|
+
|
|
53
53
|
if (!this.configApplied) {
|
|
54
54
|
this.configApplied = true;
|
|
55
55
|
this.setupPrintProtection(this.wnd, config);
|
|
56
56
|
this.comms?.log("Print protection configuration applied");
|
|
57
57
|
}
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
return true;
|
|
60
60
|
});
|
|
61
61
|
}
|
|
@@ -72,16 +72,16 @@ export class PrintProtector extends Module {
|
|
|
72
72
|
wnd.removeEventListener("beforeprint", this.beforePrintHandler);
|
|
73
73
|
this.beforePrintHandler = null;
|
|
74
74
|
}
|
|
75
|
-
|
|
75
|
+
|
|
76
76
|
if (this.styleElement?.parentNode) {
|
|
77
77
|
this.styleElement.parentNode.removeChild(this.styleElement);
|
|
78
78
|
this.styleElement = null;
|
|
79
79
|
}
|
|
80
|
-
|
|
80
|
+
|
|
81
81
|
// Unregister all print protection handlers
|
|
82
82
|
this.comms?.unregisterAll(PrintProtector.moduleName);
|
|
83
|
-
|
|
83
|
+
|
|
84
84
|
this.configApplied = false;
|
|
85
85
|
return true;
|
|
86
86
|
}
|
|
87
|
-
}
|
|
87
|
+
}
|
|
@@ -10,7 +10,7 @@ export interface SelectionAnalyzerOptions {
|
|
|
10
10
|
historySize: number;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
import { SELECTION_ANALYZER_CONFIG } from './config';
|
|
13
|
+
import { SELECTION_ANALYZER_CONFIG } from './config.ts';
|
|
14
14
|
|
|
15
15
|
export class SelectionAnalyzer {
|
|
16
16
|
private events: SelectionEvent[] = [];
|
package/src/protection/config.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { BulkCopyProtectionOptions } from "./BulkCopyProtector";
|
|
2
|
-
import { PatternAnalyzerOptions } from "./PatternAnalyzer";
|
|
3
|
-
import { SelectionAnalyzerOptions } from "./SelectionAnalyzer";
|
|
1
|
+
import { BulkCopyProtectionOptions } from "./BulkCopyProtector.ts";
|
|
2
|
+
import { PatternAnalyzerOptions } from "./PatternAnalyzer.ts";
|
|
3
|
+
import { SelectionAnalyzerOptions } from "./SelectionAnalyzer.ts";
|
|
4
4
|
|
|
5
5
|
export const DEFAULT_PATTERN_ANALYZER_CONFIG: PatternAnalyzerOptions = {
|
|
6
6
|
maxVelocity: 200, // Reasonable default for human-like scrolling (pixels/ms)
|
|
@@ -30,4 +30,4 @@ export const BULK_COPY_CONFIG: BulkCopyProtectionOptions = {
|
|
|
30
30
|
minThreshold: 100,
|
|
31
31
|
absoluteMaxChars: 5000,
|
|
32
32
|
historySize: 20
|
|
33
|
-
}
|
|
33
|
+
}
|
package/src/protection/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export * from "./BulkCopyProtector";
|
|
2
|
-
export * from "./KeyCombinationManager";
|
|
3
|
-
export * from "./KeyboardCombinations";
|
|
4
|
-
export * from "./PatternAnalyzer";
|
|
5
|
-
export * from "./SelectionAnalyzer";
|
|
6
|
-
export * from "./PrintProtector";
|
|
1
|
+
export * from "./BulkCopyProtector.ts";
|
|
2
|
+
export * from "./KeyCombinationManager.ts";
|
|
3
|
+
export * from "./KeyboardCombinations.ts";
|
|
4
|
+
export * from "./PatternAnalyzer.ts";
|
|
5
|
+
export * from "./SelectionAnalyzer.ts";
|
|
6
|
+
export * from "./PrintProtector.ts";
|
|
@@ -12,7 +12,7 @@ import type {
|
|
|
12
12
|
RangeSelector,
|
|
13
13
|
TextPositionSelector,
|
|
14
14
|
TextQuoteSelector,
|
|
15
|
-
} from './api-types';
|
|
15
|
+
} from './api-types.ts';
|
|
16
16
|
import { matchQuote } from './match-quote';
|
|
17
17
|
import { TextRange, TextPosition } from './text-range';
|
|
18
18
|
import { nodeFromXPath, xpathFromNode } from './xpath';
|
package/types/src/Loader.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ReadiumWindow } from "./helpers/dom";
|
|
2
|
-
import { ModuleName } from "./modules";
|
|
1
|
+
import { ReadiumWindow } from "./helpers/dom.ts";
|
|
2
|
+
import { ModuleName } from "./modules/index.ts";
|
|
3
3
|
/**
|
|
4
4
|
* The Module loader. Handles initialization of the HTML injectables
|
|
5
5
|
* in the target Window, which could be an IFrame, or the current window).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ReadiumWindow } from "../helpers/dom";
|
|
2
|
-
import { CommsEventKey, CommsCommandKey } from "./keys";
|
|
1
|
+
import { ReadiumWindow } from "../helpers/dom.ts";
|
|
2
|
+
import { CommsEventKey, CommsCommandKey } from "./keys.ts";
|
|
3
3
|
export declare const COMMS_VERSION = 1;
|
|
4
4
|
export interface CommsMessage {
|
|
5
5
|
_readium: number;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from './comms';
|
|
2
|
-
export * from './keys';
|
|
3
|
-
export * from './mid';
|
|
1
|
+
export * from './comms.ts';
|
|
2
|
+
export * from './keys.ts';
|
|
3
|
+
export * from './mid.ts';
|
package/types/src/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from './comms';
|
|
2
|
-
export * from './modules';
|
|
3
|
-
export * from './Loader';
|
|
4
|
-
export * from './protection';
|
|
1
|
+
export * from './comms/index.ts';
|
|
2
|
+
export * from './modules/index.ts';
|
|
3
|
+
export * from './Loader.ts';
|
|
4
|
+
export * from './protection/index.ts';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Locator } from "@readium/shared";
|
|
2
|
-
import { Comms } from "../comms/comms";
|
|
3
|
-
import { Module } from "./Module";
|
|
4
|
-
import { ModuleName } from "./ModuleLibrary";
|
|
5
|
-
import { ReadiumWindow } from "../helpers/dom";
|
|
2
|
+
import { Comms } from "../comms/comms.ts";
|
|
3
|
+
import { Module } from "./Module.ts";
|
|
4
|
+
import { ModuleName } from "./ModuleLibrary.ts";
|
|
5
|
+
import { ReadiumWindow } from "../helpers/dom.ts";
|
|
6
6
|
export declare enum Width {
|
|
7
7
|
Wrap = "wrap",// Smallest width fitting the CSS border box.
|
|
8
8
|
Viewport = "viewport",// Fills the whole viewport.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Comms } from "../comms";
|
|
2
|
-
import { ReadiumWindow } from "../helpers/dom";
|
|
3
|
-
import { ModuleName } from "./ModuleLibrary";
|
|
1
|
+
import { Comms } from "../comms/index.ts";
|
|
2
|
+
import { ReadiumWindow } from "../helpers/dom.ts";
|
|
3
|
+
import { ModuleName } from "./ModuleLibrary.ts";
|
|
4
4
|
export declare abstract class Module {
|
|
5
5
|
static readonly moduleName: ModuleName;
|
|
6
6
|
abstract mount(wnd: ReadiumWindow, comms: Comms): boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ModuleDerived } from "./Module";
|
|
2
|
-
export type ModuleName = "setup" | "snapper" | "column_snapper" | "scroll_snapper" | "webpub_snapper" | "fixed_setup" | "decorator" | "reflowable_setup" | "peripherals" | "webpub_setup" | "print_protection";
|
|
1
|
+
import { ModuleDerived } from "./Module.ts";
|
|
2
|
+
export type ModuleName = "setup" | "snapper" | "column_snapper" | "scroll_snapper" | "cjk_vertical_snapper" | "webpub_snapper" | "fixed_setup" | "decorator" | "reflowable_setup" | "peripherals" | "webpub_setup" | "print_protection";
|
|
3
3
|
export declare const FXLModules: ModuleName[];
|
|
4
4
|
export declare const ReflowableModules: ModuleName[];
|
|
5
5
|
export declare const WebPubModules: ModuleName[];
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { Comms } from "../comms/comms";
|
|
2
|
-
import { Module } from "./Module";
|
|
3
|
-
import { ReadiumWindow } from "../helpers/dom";
|
|
4
|
-
import { BulkCopyProtectionOptions } from "../protection/BulkCopyProtector";
|
|
5
|
-
import { SelectionAnalyzerOptions } from "../protection/SelectionAnalyzer";
|
|
6
|
-
import { SuspiciousActivityType } from "../comms";
|
|
7
|
-
import { KeyboardPeripheralEvent } from "../protection/KeyCombinationManager";
|
|
8
|
-
import { SuspiciousScrollingEvent } from "./snapper/ScrollSnapper";
|
|
9
|
-
import { SuspiciousSnappingEvent } from "./snapper/ColumnSnapper";
|
|
1
|
+
import { Comms } from "../comms/comms.ts";
|
|
2
|
+
import { Module } from "./Module.ts";
|
|
3
|
+
import { ReadiumWindow } from "../helpers/dom.ts";
|
|
4
|
+
import { BulkCopyProtectionOptions } from "../protection/BulkCopyProtector.ts";
|
|
5
|
+
import { SelectionAnalyzerOptions } from "../protection/SelectionAnalyzer.ts";
|
|
6
|
+
import { SuspiciousActivityType } from "../comms/index.ts";
|
|
7
|
+
import { KeyboardPeripheralEvent } from "../protection/KeyCombinationManager.ts";
|
|
8
|
+
import { SuspiciousScrollingEvent } from "./snapper/ScrollSnapper.ts";
|
|
9
|
+
import { SuspiciousSnappingEvent } from "./snapper/ColumnSnapper.ts";
|
|
10
10
|
export interface FrameClickEvent {
|
|
11
11
|
defaultPrevented: boolean;
|
|
12
12
|
doNotDisturb: boolean;
|
|
@@ -122,6 +122,7 @@ export declare class Peripherals extends Module {
|
|
|
122
122
|
private handleSelection;
|
|
123
123
|
private addSelectionMonitoring;
|
|
124
124
|
private removeSelectionMonitoring;
|
|
125
|
+
private onDragOver;
|
|
125
126
|
private onDragStart;
|
|
126
127
|
private onDrop;
|
|
127
128
|
private onContext;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from './Decorator';
|
|
2
|
-
export * from './Module';
|
|
3
|
-
export * from './ModuleLibrary';
|
|
4
|
-
export * from './Peripherals';
|
|
1
|
+
export * from './Decorator.ts';
|
|
2
|
+
export * from './Module.ts';
|
|
3
|
+
export * from './ModuleLibrary.ts';
|
|
4
|
+
export * from './Peripherals.ts';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Comms } from "../../comms/comms";
|
|
2
|
-
import { Setup } from "./Setup";
|
|
3
|
-
import { ModuleName } from "../ModuleLibrary";
|
|
4
|
-
import { ReadiumWindow } from "../../helpers/dom";
|
|
1
|
+
import { Comms } from "../../comms/comms.ts";
|
|
2
|
+
import { Setup } from "./Setup.ts";
|
|
3
|
+
import { ModuleName } from "../ModuleLibrary.ts";
|
|
4
|
+
import { ReadiumWindow } from "../../helpers/dom.ts";
|
|
5
5
|
export declare class FixedSetup extends Setup {
|
|
6
6
|
static readonly moduleName: ModuleName;
|
|
7
7
|
mount(wnd: ReadiumWindow, comms: Comms): boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Comms } from "../../comms/comms";
|
|
2
|
-
import { Setup } from "./Setup";
|
|
3
|
-
import { ReadiumWindow } from "../../helpers/dom";
|
|
1
|
+
import { Comms } from "../../comms/comms.ts";
|
|
2
|
+
import { Setup } from "./Setup.ts";
|
|
3
|
+
import { ReadiumWindow } from "../../helpers/dom.ts";
|
|
4
4
|
export declare class ReflowableSetup extends Setup {
|
|
5
5
|
static readonly moduleName = "reflowable_setup";
|
|
6
6
|
onViewportWidthChanged(event: Event): void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Comms } from "../../comms/comms";
|
|
2
|
-
import { ReadiumWindow } from "../../helpers/dom";
|
|
3
|
-
import { Module } from "../Module";
|
|
4
|
-
import { ModuleName } from "../ModuleLibrary";
|
|
1
|
+
import { Comms } from "../../comms/comms.ts";
|
|
2
|
+
import { ReadiumWindow } from "../../helpers/dom.ts";
|
|
3
|
+
import { Module } from "../Module.ts";
|
|
4
|
+
import { ModuleName } from "../ModuleLibrary.ts";
|
|
5
5
|
export declare abstract class Setup extends Module {
|
|
6
6
|
static readonly moduleName: ModuleName;
|
|
7
7
|
private comms;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Comms } from "../../comms/comms";
|
|
2
|
-
import { ReadiumWindow } from "../../helpers/dom";
|
|
3
|
-
import { Module } from "../Module";
|
|
1
|
+
import { Comms } from "../../comms/comms.ts";
|
|
2
|
+
import { ReadiumWindow } from "../../helpers/dom.ts";
|
|
3
|
+
import { Module } from "../Module.ts";
|
|
4
4
|
export declare class WebPubSetup extends Module {
|
|
5
5
|
static readonly moduleName = "webpub_setup";
|
|
6
6
|
private comms;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Comms } from "../../comms/comms.ts";
|
|
2
|
+
import { ReadiumWindow } from "../../helpers/dom.ts";
|
|
3
|
+
import { ModuleName } from "../ModuleLibrary.ts";
|
|
4
|
+
import { Snapper } from "./Snapper.ts";
|
|
5
|
+
import { BaseSuspiciousActivityEvent } from "../Peripherals.ts";
|
|
6
|
+
export interface SuspiciousCJKScrollingEvent extends BaseSuspiciousActivityEvent {
|
|
7
|
+
type: "suspicious_scrolling";
|
|
8
|
+
scrollDelta: number;
|
|
9
|
+
scrollDirection: "left" | "right";
|
|
10
|
+
targetElement: {
|
|
11
|
+
tagName: string;
|
|
12
|
+
} | null;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Snapper for CJK vertical writing (writing-mode: vertical-rl).
|
|
16
|
+
*
|
|
17
|
+
* In vertical-rl, content overflows on the X axis, flowing from right (start)
|
|
18
|
+
* to left (end). This snapper is the horizontal counterpart of ScrollSnapper:
|
|
19
|
+
* it tracks scrollLeft / scrollWidth / innerWidth and reports progress
|
|
20
|
+
* accordingly.
|
|
21
|
+
*
|
|
22
|
+
* Progress convention:
|
|
23
|
+
* scrollLeft = 0 (right edge, document start) → progress 0
|
|
24
|
+
* scrollLeft = ±(scrollWidth − clientWidth) → progress 1 (document end, left edge)
|
|
25
|
+
*
|
|
26
|
+
* All modern browsers use negative scrollLeft for vertical-rl (range: [−scrollable, 0]).
|
|
27
|
+
* Read it with Math.abs() to get a non-negative offset from document start.
|
|
28
|
+
* Write absolute positions as negative values (go_progression, go_end).
|
|
29
|
+
* Write relative adjustments as viewport-coordinate deltas (go_id, go_text) — this
|
|
30
|
+
* is sign-agnostic and works regardless of browser convention.
|
|
31
|
+
*
|
|
32
|
+
* go_next / go_prev always return false so that the navigator advances to the
|
|
33
|
+
* next or previous spine item — this snapper intentionally provides free
|
|
34
|
+
* horizontal scroll without intra-resource page fragmentation.
|
|
35
|
+
*/
|
|
36
|
+
export declare class CJKVerticalSnapper extends Snapper {
|
|
37
|
+
static readonly moduleName: ModuleName;
|
|
38
|
+
private wnd;
|
|
39
|
+
private comms;
|
|
40
|
+
private resizeObserver;
|
|
41
|
+
private patternAnalyzer;
|
|
42
|
+
private lastScrollTime;
|
|
43
|
+
private isScrollProtectionEnabled;
|
|
44
|
+
private initialScrollHandled;
|
|
45
|
+
private isScrolling;
|
|
46
|
+
private lastScrollLeft;
|
|
47
|
+
private isResizing;
|
|
48
|
+
private resizeDebounce;
|
|
49
|
+
private doc;
|
|
50
|
+
/** Total horizontally scrollable distance (magnitude). */
|
|
51
|
+
private scrollable;
|
|
52
|
+
private reportProgress;
|
|
53
|
+
private handleScroll;
|
|
54
|
+
private enableScrollProtection;
|
|
55
|
+
mount(wnd: ReadiumWindow, comms: Comms): boolean;
|
|
56
|
+
unmount(wnd: ReadiumWindow, comms: Comms): boolean;
|
|
57
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Comms } from "../../comms";
|
|
2
|
-
import { Snapper } from "./Snapper";
|
|
3
|
-
import { ModuleName } from "../ModuleLibrary";
|
|
4
|
-
import { ReadiumWindow } from "../../helpers/dom";
|
|
5
|
-
import { BaseSuspiciousActivityEvent } from "../Peripherals";
|
|
1
|
+
import { Comms } from "../../comms/index.ts";
|
|
2
|
+
import { Snapper } from "./Snapper.ts";
|
|
3
|
+
import { ModuleName } from "../ModuleLibrary.ts";
|
|
4
|
+
import { ReadiumWindow } from "../../helpers/dom.ts";
|
|
5
|
+
import { BaseSuspiciousActivityEvent } from "../Peripherals.ts";
|
|
6
6
|
export interface SuspiciousSnappingEvent extends BaseSuspiciousActivityEvent {
|
|
7
7
|
type: "suspicious_snapping";
|
|
8
8
|
event: null;
|
|
@@ -22,6 +22,17 @@ export declare class ColumnSnapper extends Snapper {
|
|
|
22
22
|
private doc;
|
|
23
23
|
private scrollOffset;
|
|
24
24
|
snapOffset(offset: number): number;
|
|
25
|
+
/**
|
|
26
|
+
* Snap a non-negative normalized offset (distance from document start) to
|
|
27
|
+
* the nearest page boundary. Works identically regardless of reading direction.
|
|
28
|
+
*/
|
|
29
|
+
private snapNormOffset;
|
|
30
|
+
/**
|
|
31
|
+
* Normalized scroll position: distance from document start, always in
|
|
32
|
+
* [0, scrollWidth - innerWidth] regardless of reading direction.
|
|
33
|
+
* scrollLeft may be negative depending on the browser — Math.abs() normalizes it.
|
|
34
|
+
*/
|
|
35
|
+
private normScroll;
|
|
25
36
|
reportProgress(): void;
|
|
26
37
|
private shakeTimeout;
|
|
27
38
|
shake(): void;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Comms } from "../../comms";
|
|
2
|
-
import { ReadiumWindow } from "../../helpers/dom";
|
|
3
|
-
import { ModuleName } from "../ModuleLibrary";
|
|
4
|
-
import { Snapper } from "./Snapper";
|
|
5
|
-
import { BaseSuspiciousActivityEvent } from "../Peripherals";
|
|
1
|
+
import { Comms } from "../../comms/index.ts";
|
|
2
|
+
import { ReadiumWindow } from "../../helpers/dom.ts";
|
|
3
|
+
import { ModuleName } from "../ModuleLibrary.ts";
|
|
4
|
+
import { Snapper } from "./Snapper.ts";
|
|
5
|
+
import { BaseSuspiciousActivityEvent } from "../Peripherals.ts";
|
|
6
6
|
export interface SuspiciousScrollingEvent extends BaseSuspiciousActivityEvent {
|
|
7
7
|
type: "suspicious_scrolling";
|
|
8
8
|
scrollDelta: number;
|