@prose-reader/enhancer-gestures 1.261.0 → 1.263.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/gestures/pan.d.ts +2 -5
- package/dist/gestures/pinch.d.ts +2 -2
- package/dist/gestures/swipe.d.ts +3 -2
- package/dist/gestures/taps/registerTaps.d.ts +2 -1
- package/dist/index.js +105 -62
- package/dist/index.js.map +1 -1
- package/dist/index.umd.cjs +104 -61
- package/dist/index.umd.cjs.map +1 -1
- package/dist/types.d.ts +12 -1
- package/package.json +3 -3
package/dist/gestures/pan.d.ts
CHANGED
|
@@ -8,9 +8,6 @@ export declare const registerPan: ({ reader, recognizer, settingsManager, }: {
|
|
|
8
8
|
hookManager: HookManager<Hook>;
|
|
9
9
|
settingsManager: GesturesSettingsManager;
|
|
10
10
|
}) => import('rxjs').Observable<{
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} | {
|
|
14
|
-
event: import('gesturx').PanEvent;
|
|
15
|
-
handled: boolean;
|
|
11
|
+
type: "pan";
|
|
12
|
+
gestureEvent: import('gesturx').PanEvent;
|
|
16
13
|
}>;
|
package/dist/gestures/pinch.d.ts
CHANGED
|
@@ -8,6 +8,6 @@ export declare const registerPinch: ({ reader, recognizable, settingsManager, }:
|
|
|
8
8
|
hookManager: HookManager<Hook>;
|
|
9
9
|
settingsManager: GesturesSettingsManager;
|
|
10
10
|
}) => import('rxjs').Observable<{
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
type: "pinch";
|
|
12
|
+
gestureEvent: PinchEvent;
|
|
13
13
|
}>;
|
package/dist/gestures/swipe.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { HookManager, Reader } from '@prose-reader/core';
|
|
2
|
+
import { SwipeEvent } from 'gesturx';
|
|
2
3
|
import { GesturesSettingsManager } from '../SettingsManager';
|
|
3
4
|
import { GestureRecognizable, Hook } from '../types';
|
|
4
5
|
export declare const registerSwipe: ({ reader, recognizable, settingsManager, }: {
|
|
@@ -7,6 +8,6 @@ export declare const registerSwipe: ({ reader, recognizable, settingsManager, }:
|
|
|
7
8
|
hookManager: HookManager<Hook>;
|
|
8
9
|
settingsManager: GesturesSettingsManager;
|
|
9
10
|
}) => import('rxjs').Observable<{
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
type: "swipe";
|
|
12
|
+
gestureEvent: SwipeEvent;
|
|
12
13
|
}>;
|
|
@@ -9,6 +9,7 @@ export declare const registerTaps: ({ reader, recognizable, hookManager, setting
|
|
|
9
9
|
recognizer: TapRecognizer;
|
|
10
10
|
settingsManager: GesturesSettingsManager;
|
|
11
11
|
}) => import('rxjs').Observable<{
|
|
12
|
-
|
|
12
|
+
type: "tap";
|
|
13
|
+
gestureEvent: import('gesturx').TapEvent;
|
|
13
14
|
handled: boolean;
|
|
14
15
|
}>;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isHtmlElement, SettingsManager, HookManager } from "@prose-reader/core";
|
|
2
2
|
import { PinchRecognizer, PanRecognizer, TapRecognizer, SwipeRecognizer, Recognizable } from "gesturx";
|
|
3
|
-
import { switchMap, EMPTY, filter, merge, map, of, withLatestFrom,
|
|
3
|
+
import { switchMap, EMPTY, filter, merge, map, of, withLatestFrom, throttleTime, animationFrameScheduler, tap, takeUntil, combineLatest, first, share } from "rxjs";
|
|
4
|
+
const name = "@prose-reader/enhancer-gestures";
|
|
4
5
|
const registerPan = ({
|
|
5
6
|
reader,
|
|
6
7
|
recognizer,
|
|
@@ -20,48 +21,55 @@ const registerPan = ({
|
|
|
20
21
|
);
|
|
21
22
|
const pan$ = panStart$.pipe(
|
|
22
23
|
switchMap((panStartEvent) => {
|
|
23
|
-
|
|
24
|
+
let lastDelta = { x: 0, y: 0 };
|
|
24
25
|
const moveAndEnd$ = merge(panMove$, panEnd$).pipe(
|
|
25
26
|
map((event) => {
|
|
26
27
|
const isZooming = reader.zoom.state.isZooming;
|
|
27
|
-
const
|
|
28
|
-
if (isZooming &&
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
x,
|
|
33
|
-
y
|
|
34
|
-
}
|
|
35
|
-
|
|
28
|
+
const isZoomingIn = reader.zoom.state.currentScale > 1;
|
|
29
|
+
if (isZooming && isZoomingIn) {
|
|
30
|
+
const deltaX = event.deltaX - lastDelta.x;
|
|
31
|
+
const deltaY = event.deltaY - lastDelta.y;
|
|
32
|
+
lastDelta = {
|
|
33
|
+
x: event.deltaX,
|
|
34
|
+
y: event.deltaY
|
|
35
|
+
};
|
|
36
|
+
reader.zoom.move(
|
|
37
|
+
{
|
|
38
|
+
x: reader.zoom.state.currentPosition.x + deltaX,
|
|
39
|
+
y: reader.zoom.state.currentPosition.y + deltaY
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
constrain: "within-viewport"
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
return event;
|
|
36
46
|
}
|
|
37
47
|
if (event.type === `panMove`) {
|
|
38
|
-
reader.navigation.
|
|
48
|
+
if (!reader.navigation.panNavigator.value.isStarted) {
|
|
49
|
+
reader.navigation.panNavigator.start({
|
|
50
|
+
x: event.deltaX,
|
|
51
|
+
y: event.deltaY
|
|
52
|
+
});
|
|
53
|
+
return event;
|
|
54
|
+
}
|
|
55
|
+
reader.navigation.panNavigator.panMoveTo({
|
|
39
56
|
x: event.deltaX,
|
|
40
57
|
y: event.deltaY
|
|
41
58
|
});
|
|
42
|
-
return
|
|
59
|
+
return event;
|
|
43
60
|
}
|
|
44
|
-
if (event.type === `panEnd`) {
|
|
45
|
-
reader.navigation.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
);
|
|
49
|
-
return
|
|
61
|
+
if (event.type === `panEnd` && reader.navigation.panNavigator.value.isStarted) {
|
|
62
|
+
reader.navigation.panNavigator.stop({
|
|
63
|
+
x: event.deltaX,
|
|
64
|
+
y: event.deltaY
|
|
65
|
+
});
|
|
66
|
+
return event;
|
|
50
67
|
}
|
|
51
|
-
return
|
|
68
|
+
return event;
|
|
52
69
|
})
|
|
53
70
|
);
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
reader?.navigation.moveTo({ x: 0, y: 0 }, { start: true });
|
|
57
|
-
return merge(
|
|
58
|
-
of({ event: panStartEvent, handled: true }),
|
|
59
|
-
moveAndEnd$
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
return merge(
|
|
63
|
-
of({ event: panStartEvent, handled: false }),
|
|
64
|
-
moveAndEnd$
|
|
71
|
+
return merge(of(panStartEvent), moveAndEnd$).pipe(
|
|
72
|
+
map((event) => ({ type: "pan", gestureEvent: event }))
|
|
65
73
|
);
|
|
66
74
|
})
|
|
67
75
|
);
|
|
@@ -92,28 +100,34 @@ const registerPinch = ({
|
|
|
92
100
|
return settingsManager.values$.pipe(
|
|
93
101
|
switchMap(({ fontScalePinchEnabled, fontScalePinchThrottleTime }) => {
|
|
94
102
|
const zoomGestures$ = pinchStart$.pipe(
|
|
95
|
-
|
|
96
|
-
switchMap(([event, viewportState]) => {
|
|
97
|
-
const target = event.event.target;
|
|
103
|
+
switchMap(() => {
|
|
98
104
|
const startScale = reader.zoom.state.currentScale;
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
105
|
+
return pinchMove$.pipe(
|
|
106
|
+
withLatestFrom(reader.viewportState$),
|
|
107
|
+
map(([event, viewportState]) => {
|
|
108
|
+
const newScale = startScale * event.scale;
|
|
109
|
+
if (viewportState === "busy") {
|
|
110
|
+
return event;
|
|
111
|
+
}
|
|
112
|
+
if (!reader.zoom.state.isZooming && event.scale > 1) {
|
|
113
|
+
reader.zoom.enter({ animate: false, scale: newScale });
|
|
114
|
+
return event;
|
|
115
|
+
}
|
|
116
|
+
if (reader.zoom.state.isZooming) {
|
|
117
|
+
if (newScale < 1) {
|
|
118
|
+
reader.zoom.exit();
|
|
119
|
+
} else {
|
|
120
|
+
reader.zoom.scaleAt(
|
|
121
|
+
Math.min(newScale, settingsManager.values.zoomMaxScale),
|
|
122
|
+
{
|
|
123
|
+
constrain: "within-viewport"
|
|
124
|
+
}
|
|
125
|
+
);
|
|
114
126
|
}
|
|
115
|
-
|
|
116
|
-
|
|
127
|
+
return event;
|
|
128
|
+
}
|
|
129
|
+
return event;
|
|
130
|
+
})
|
|
117
131
|
);
|
|
118
132
|
})
|
|
119
133
|
);
|
|
@@ -151,11 +165,15 @@ const registerPinch = ({
|
|
|
151
165
|
})
|
|
152
166
|
);
|
|
153
167
|
return merge(zoomGestures$, watchForFontScaleChange$).pipe(
|
|
154
|
-
map((event) => ({
|
|
168
|
+
map((event) => ({
|
|
169
|
+
type: "pinch",
|
|
170
|
+
gestureEvent: event
|
|
171
|
+
}))
|
|
155
172
|
);
|
|
156
173
|
})
|
|
157
174
|
);
|
|
158
175
|
};
|
|
176
|
+
const isSwipeEvent = (event) => event.type === "swipe";
|
|
159
177
|
const registerSwipe = ({
|
|
160
178
|
reader,
|
|
161
179
|
recognizable,
|
|
@@ -164,8 +182,9 @@ const registerSwipe = ({
|
|
|
164
182
|
const gestures$ = settingsManager.values$.pipe(
|
|
165
183
|
switchMap(
|
|
166
184
|
({ panNavigation }) => panNavigation !== "swipe" ? EMPTY : recognizable.events$.pipe(
|
|
167
|
-
|
|
168
|
-
|
|
185
|
+
map(({ event }) => event),
|
|
186
|
+
filter(isSwipeEvent),
|
|
187
|
+
tap((event) => {
|
|
169
188
|
const { computedPageTurnDirection } = reader.settings.values;
|
|
170
189
|
if (computedPageTurnDirection === "vertical") {
|
|
171
190
|
if (event.velocityY < -0.5) {
|
|
@@ -183,7 +202,7 @@ const registerSwipe = ({
|
|
|
183
202
|
}
|
|
184
203
|
}
|
|
185
204
|
}),
|
|
186
|
-
map((
|
|
205
|
+
map((event) => ({ type: "swipe", gestureEvent: event }))
|
|
187
206
|
)
|
|
188
207
|
)
|
|
189
208
|
);
|
|
@@ -314,8 +333,15 @@ const registerTaps = ({
|
|
|
314
333
|
first(),
|
|
315
334
|
filter((results) => !results.some((result) => result === false)),
|
|
316
335
|
map(() => {
|
|
317
|
-
if (computedPageTurnMode === "scrollable"
|
|
318
|
-
|
|
336
|
+
if (computedPageTurnMode === "scrollable" || /**
|
|
337
|
+
* We don't want to navigate from gestures when the user is zooming.
|
|
338
|
+
*/
|
|
339
|
+
reader.zoom.state.isZooming) {
|
|
340
|
+
return {
|
|
341
|
+
type: "tap",
|
|
342
|
+
gestureEvent: event,
|
|
343
|
+
handled: false
|
|
344
|
+
};
|
|
319
345
|
}
|
|
320
346
|
if (computedPageTurnDirection === "horizontal" && isPositionInArea(
|
|
321
347
|
positionInContainer,
|
|
@@ -342,9 +368,17 @@ const registerTaps = ({
|
|
|
342
368
|
)) {
|
|
343
369
|
reader.navigation.turnRightOrBottom();
|
|
344
370
|
} else {
|
|
345
|
-
return {
|
|
371
|
+
return {
|
|
372
|
+
type: "tap",
|
|
373
|
+
gestureEvent: event,
|
|
374
|
+
handled: false
|
|
375
|
+
};
|
|
346
376
|
}
|
|
347
|
-
return {
|
|
377
|
+
return {
|
|
378
|
+
type: "tap",
|
|
379
|
+
gestureEvent: event,
|
|
380
|
+
handled: true
|
|
381
|
+
};
|
|
348
382
|
})
|
|
349
383
|
);
|
|
350
384
|
}
|
|
@@ -379,22 +413,30 @@ class GesturesSettingsManager extends SettingsManager {
|
|
|
379
413
|
fontScalePinchThrottleTime: 500,
|
|
380
414
|
fontScaleMaxScale: 5,
|
|
381
415
|
fontScaleMinScale: 0.2,
|
|
416
|
+
zoomMaxScale: Infinity,
|
|
382
417
|
ignore: []
|
|
383
418
|
};
|
|
384
419
|
}
|
|
385
420
|
}
|
|
421
|
+
const styles = '[data-prose-reader-container="${id}"] * {\n /* Make sure that touche actions are correctly dispatched no matter where the user interact */\n touch-action: inherit;\n}\n';
|
|
386
422
|
const gesturesEnhancer = (next) => (options) => {
|
|
387
423
|
const { gestures = {}, ...rest } = options;
|
|
388
424
|
const reader = next(rest);
|
|
425
|
+
const removeStylesheet = reader.utils.injectScopedCSS(
|
|
426
|
+
document,
|
|
427
|
+
name,
|
|
428
|
+
styles
|
|
429
|
+
);
|
|
389
430
|
const settingsManager = new GesturesSettingsManager(gestures, reader);
|
|
390
431
|
const hookManager = new HookManager();
|
|
391
432
|
const pinchRecognizer = new PinchRecognizer({
|
|
392
433
|
options: {
|
|
393
434
|
/**
|
|
394
435
|
* @important
|
|
395
|
-
*
|
|
436
|
+
* Ideally we want pinch to triggers before pan so we can
|
|
437
|
+
* capture zoom before starting panning.
|
|
396
438
|
*/
|
|
397
|
-
posThreshold:
|
|
439
|
+
posThreshold: 10
|
|
398
440
|
}
|
|
399
441
|
});
|
|
400
442
|
const failWithSelection = {
|
|
@@ -405,7 +447,7 @@ const gesturesEnhancer = (next) => (options) => {
|
|
|
405
447
|
failWith: [pinchRecognizer, failWithSelection],
|
|
406
448
|
options: {
|
|
407
449
|
// we want to have some margin to trigger zoom
|
|
408
|
-
posThreshold:
|
|
450
|
+
posThreshold: 20
|
|
409
451
|
}
|
|
410
452
|
});
|
|
411
453
|
const tapRecognizer = new TapRecognizer({
|
|
@@ -485,6 +527,7 @@ const gesturesEnhancer = (next) => (options) => {
|
|
|
485
527
|
return {
|
|
486
528
|
...reader,
|
|
487
529
|
destroy: () => {
|
|
530
|
+
removeStylesheet();
|
|
488
531
|
reader.destroy();
|
|
489
532
|
settingsManager.destroy();
|
|
490
533
|
},
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/gestures/pan.ts","../src/gestures/pinch.ts","../src/gestures/swipe.ts","../src/utils.ts","../src/gestures/taps/utils.ts","../src/gestures/taps/registerTaps.ts","../src/SettingsManager.ts","../src/index.ts"],"sourcesContent":["import type { HookManager, Reader } from \"@prose-reader/core\"\nimport type { PanRecognizer } from \"gesturx\"\nimport { EMPTY, filter, map, merge, of, switchMap } from \"rxjs\"\nimport type { GesturesSettingsManager } from \"../SettingsManager\"\nimport type { Hook } from \"../types\"\n\nexport const registerPan = ({\n reader,\n recognizer,\n settingsManager,\n}: {\n recognizer: PanRecognizer\n reader: Reader\n hookManager: HookManager<Hook>\n settingsManager: GesturesSettingsManager\n}) => {\n const gestures$ = settingsManager.values$.pipe(\n switchMap(({ panNavigation }) => {\n if (panNavigation !== \"pan\") return EMPTY\n\n const panStart$ = recognizer.events$.pipe(\n filter((event) => event.type === `panStart`),\n )\n const panMove$ = recognizer.events$.pipe(\n filter((event) => event.type === `panMove`),\n )\n const panEnd$ = recognizer.events$.pipe(\n filter((event) => event.type === `panEnd`),\n )\n\n const pan$ = panStart$.pipe(\n switchMap((panStartEvent) => {\n const startZoomPosition = reader.zoom.state.currentPosition\n\n const moveAndEnd$ = merge(panMove$, panEnd$).pipe(\n map((event) => {\n const isZooming = reader.zoom.state.isZooming\n const isZoomingIn = reader.zoom.state.currentScale > 1\n\n if (isZooming && isZoomingIn) {\n const x = startZoomPosition.x + Math.floor(event.deltaX)\n const y = startZoomPosition.y + Math.floor(event.deltaY)\n\n reader.zoom.move({\n x,\n y,\n })\n\n return { event, handled: true }\n }\n\n if (event.type === `panMove`) {\n reader.navigation.moveTo({\n x: event.deltaX,\n y: event.deltaY,\n })\n\n return { event, handled: true }\n }\n\n if (event.type === `panEnd`) {\n reader.navigation.moveTo(\n { x: event.deltaX, y: event.deltaY },\n { final: true },\n )\n\n return { event, handled: true }\n }\n\n return { event, handled: false }\n }),\n )\n\n const isZoomingIn = reader.zoom.state.currentScale > 1\n\n if (!isZoomingIn) {\n reader?.navigation.moveTo({ x: 0, y: 0 }, { start: true })\n\n return merge(\n of({ event: panStartEvent, handled: true }),\n moveAndEnd$,\n )\n }\n\n return merge(\n of({ event: panStartEvent, handled: false }),\n moveAndEnd$,\n )\n }),\n )\n\n return pan$\n }),\n )\n\n return gestures$\n}\n","import {\n type HookManager,\n isHtmlElement,\n type Reader,\n} from \"@prose-reader/core\"\nimport type { PinchEvent } from \"gesturx\"\nimport {\n animationFrameScheduler,\n EMPTY,\n filter,\n map,\n merge,\n switchMap,\n takeUntil,\n tap,\n throttleTime,\n withLatestFrom,\n} from \"rxjs\"\nimport type { GesturesSettingsManager } from \"../SettingsManager\"\nimport type { GestureRecognizable, Hook } from \"../types\"\n\nconst isHtmlImageElement = (\n target: EventTarget | null,\n): target is HTMLImageElement =>\n isHtmlElement(target) &&\n !!target.ownerDocument.defaultView &&\n target instanceof target.ownerDocument.defaultView.HTMLImageElement\n\nexport const registerPinch = ({\n reader,\n recognizable,\n settingsManager,\n}: {\n recognizable: GestureRecognizable\n reader: Reader\n hookManager: HookManager<Hook>\n settingsManager: GesturesSettingsManager\n}) => {\n const pinchStart$ = recognizable.events$.pipe(\n map(({ event }) => event),\n filter((event): event is PinchEvent => event.type === \"pinchStart\"),\n )\n\n const pinchMove$ = recognizable.events$.pipe(\n map(({ event }) => event),\n filter((event): event is PinchEvent => event.type === \"pinchMove\"),\n )\n\n const pinchEnd$ = recognizable.events$.pipe(\n map(({ event }) => event),\n filter((event): event is PinchEvent => event.type === \"pinchEnd\"),\n )\n\n const shouldStartZoom = (\n target: EventTarget | null,\n ): target is HTMLImageElement =>\n isHtmlImageElement(target) && !reader.zoom.state.isZooming\n\n return settingsManager.values$.pipe(\n switchMap(({ fontScalePinchEnabled, fontScalePinchThrottleTime }) => {\n const zoomGestures$ = pinchStart$.pipe(\n withLatestFrom(reader.viewportState$),\n switchMap(([event, viewportState]) => {\n const target = event.event.target\n const startScale = reader.zoom.state.currentScale\n\n if (viewportState === \"busy\") return EMPTY\n\n if (shouldStartZoom(target)) {\n reader.zoom.enter({ element: target })\n }\n\n if (!reader.zoom.state.isZooming) return EMPTY\n\n return merge(\n pinchMove$.pipe(\n tap((event) => {\n if (reader.zoom.state.isZooming) {\n const newScale = startScale + (event.scale - 1)\n\n if (newScale < 1) {\n reader.zoom.exit()\n } else {\n reader.zoom.scaleAt(newScale)\n }\n }\n }),\n ),\n )\n }),\n )\n\n const watchForFontScaleChange$ = !fontScalePinchEnabled\n ? EMPTY\n : pinchStart$.pipe(\n withLatestFrom(reader.viewportState$),\n switchMap(([pinchStartEvent, viewportState]) => {\n if (\n viewportState === \"busy\" ||\n shouldStartZoom(pinchStartEvent.event.target) ||\n reader.zoom.state.isZooming\n )\n return EMPTY\n\n const lastFontScaleOnPinchStart = reader.settings.values.fontScale\n\n return pinchMove$.pipe(\n throttleTime(\n fontScalePinchThrottleTime,\n animationFrameScheduler,\n {\n trailing: true,\n },\n ),\n tap((event) => {\n const newScale = Number.parseFloat(\n (lastFontScaleOnPinchStart + (event.scale - 1)).toFixed(2),\n )\n\n const newMinMaxedFontScale = Math.max(\n Math.min(\n newScale,\n settingsManager.values.fontScaleMaxScale,\n ),\n settingsManager.values.fontScaleMinScale,\n )\n\n reader.settings.update({\n fontScale: newMinMaxedFontScale,\n })\n }),\n takeUntil(pinchEnd$),\n )\n }),\n )\n\n return merge(zoomGestures$, watchForFontScaleChange$).pipe(\n map((event) => ({ event, handled: true })),\n )\n }),\n )\n}\n","import type { HookManager, Reader } from \"@prose-reader/core\"\nimport { EMPTY, filter, map, switchMap, tap } from \"rxjs\"\nimport type { GesturesSettingsManager } from \"../SettingsManager\"\nimport type { GestureRecognizable, Hook } from \"../types\"\n\nexport const registerSwipe = ({\n reader,\n recognizable,\n settingsManager,\n}: {\n recognizable: GestureRecognizable\n reader: Reader\n hookManager: HookManager<Hook>\n settingsManager: GesturesSettingsManager\n}) => {\n const gestures$ = settingsManager.values$.pipe(\n switchMap(({ panNavigation }) =>\n panNavigation !== \"swipe\"\n ? EMPTY\n : recognizable.events$.pipe(\n filter(({ event }) => event.type === \"swipe\"),\n tap(({ event }) => {\n const { computedPageTurnDirection } = reader.settings.values\n\n if (computedPageTurnDirection === \"vertical\") {\n if (event.velocityY < -0.5) {\n reader?.navigation.turnRight()\n }\n if (event.velocityY > 0.5) {\n reader?.navigation.turnLeft()\n }\n } else {\n if (event.velocityX < -0.5) {\n reader?.navigation.turnRight()\n }\n if (event.velocityX > 0.5) {\n reader?.navigation.turnLeft()\n }\n }\n }),\n map(({ event }) => ({ event, handled: true })),\n ),\n ),\n )\n\n return gestures$\n}\n","import { isHtmlElement } from \"@prose-reader/core\"\nimport type { GestureEvent } from \"./types\"\n\nexport const isNotLink = (event: GestureEvent[\"event\"]) => {\n const target = event.event.target\n\n if (isHtmlElement(target) && target.tagName === \"a\") return false\n\n return true\n}\n\nexport const getPositionRelativeToContainer = (\n event: { x: number; y: number },\n containerElementRect: DOMRectReadOnly,\n) => {\n const { x, y } = event\n const { left, top } = containerElementRect\n\n return {\n x: x - left,\n y: y - top,\n }\n}\n\nexport const istMatchingSelectors = (\n selectors: string[],\n event: GestureEvent[\"event\"],\n): boolean => {\n const target = event.event.target\n\n if (!isHtmlElement(target)) return false\n\n const match = selectors.find((selector) => {\n // Check if the target matches the selector directly\n if (target.matches(selector)) return true\n\n // Check if the target is within an element matching the selector\n if (target.closest(selector)) return true\n\n return false\n })\n\n return !!match\n}\n","import type { TapArea } from \"./types\"\n\nexport const isPositionInArea = (\n position: { x: number; y: number },\n area: TapArea,\n containerSize: { width: number; height: number },\n): boolean => {\n const { x, y } = position\n const { width, height } = containerSize\n\n switch (area.type) {\n case \"margins\": {\n const { top, bottom, left, right } = area\n const inTop = top !== undefined ? y < height * top : true\n const inBottom = bottom !== undefined ? y > height * (1 - bottom) : true\n const inLeft = left !== undefined ? x < width * left : true\n const inRight = right !== undefined ? x > width * (1 - right) : true\n\n return (\n (top !== undefined && inTop) ||\n (bottom !== undefined && inBottom) ||\n (left !== undefined && inLeft) ||\n (right !== undefined && inRight)\n )\n }\n\n case \"rectangle\": {\n const {\n x: rectX,\n y: rectY,\n width: rectWidth,\n height: rectHeight,\n unit = \"%\",\n } = area\n const actualX = unit === \"%\" ? width * (rectX / 100) : rectX\n const actualY = unit === \"%\" ? height * (rectY / 100) : rectY\n const actualWidth = unit === \"%\" ? width * (rectWidth / 100) : rectWidth\n const actualHeight =\n unit === \"%\" ? height * (rectHeight / 100) : rectHeight\n\n return (\n x >= actualX &&\n x <= actualX + actualWidth &&\n y >= actualY &&\n y <= actualY + actualHeight\n )\n }\n\n case \"corner\": {\n const { corner, size, unit = \"%\" } = area\n const actualSize =\n unit === \"%\" ? Math.min(width, height) * (size / 100) : size\n\n switch (corner) {\n case \"top-left\":\n return x < actualSize && y < actualSize\n case \"top-right\":\n return x > width - actualSize && y < actualSize\n case \"bottom-left\":\n return x < actualSize && y > height - actualSize\n case \"bottom-right\":\n return x > width - actualSize && y > height - actualSize\n default:\n return false\n }\n }\n\n case \"center\": {\n const { width: centerWidth, height: centerHeight, unit = \"%\" } = area\n const actualWidth =\n unit === \"%\" ? width * (centerWidth / 100) : centerWidth\n const actualHeight =\n unit === \"%\" ? height * (centerHeight / 100) : centerHeight\n const centerX = width / 2\n const centerY = height / 2\n\n return (\n x >= centerX - actualWidth / 2 &&\n x <= centerX + actualWidth / 2 &&\n y >= centerY - actualHeight / 2 &&\n y <= centerY + actualHeight / 2\n )\n }\n\n default:\n return false\n }\n}\n\nexport const calculatePageTurnLinearMargin = (screenWidth: number): number => {\n const minMargin = 0.15\n const maxMargin = 0.2\n const minWidth = 320\n const maxWidth = 1200\n\n if (screenWidth <= minWidth) return maxMargin\n if (screenWidth >= maxWidth) return minMargin\n\n // Linear interpolation between min and max\n const ratio = (screenWidth - minWidth) / (maxWidth - minWidth)\n return maxMargin - ratio * (maxMargin - minMargin)\n}\n","import type { HookManager, Reader } from \"@prose-reader/core\"\nimport type { TapRecognizer } from \"gesturx\"\nimport {\n combineLatest,\n EMPTY,\n filter,\n first,\n map,\n of,\n switchMap,\n withLatestFrom,\n} from \"rxjs\"\nimport type { GesturesSettingsManager } from \"../../SettingsManager\"\nimport type { GestureRecognizable, Hook } from \"../../types\"\nimport {\n getPositionRelativeToContainer,\n isNotLink,\n istMatchingSelectors,\n} from \"../../utils\"\nimport { calculatePageTurnLinearMargin, isPositionInArea } from \"./utils\"\n\nexport const registerTaps = ({\n reader,\n recognizable,\n hookManager,\n settingsManager,\n recognizer,\n}: {\n recognizable: GestureRecognizable\n reader: Reader\n hookManager: HookManager<Hook>\n recognizer: TapRecognizer\n settingsManager: GesturesSettingsManager\n}) => {\n const gestures$ = recognizable.events$.pipe(\n filter((event) => event.recognizer === recognizer),\n withLatestFrom(reader.context.watch(`rootElement`), reader.spine.element$),\n switchMap(([{ event }, containerElement, spineElement]) => {\n if (!containerElement || !spineElement) return EMPTY\n\n const normalizedEvent = event.event\n const { computedPageTurnDirection, computedPageTurnMode } =\n reader.settings.values\n\n if (\n event.type === \"tap\" &&\n isNotLink(event) &&\n !istMatchingSelectors(settingsManager.values.ignore, event)\n ) {\n if (`x` in normalizedEvent) {\n const containerElementRect = containerElement.getBoundingClientRect()\n const width = containerElementRect.width\n const pageTurnMargin = calculatePageTurnLinearMargin(width)\n const positionInContainer = getPositionRelativeToContainer(\n normalizedEvent,\n containerElementRect,\n )\n\n const positionInSpineNonTransformed =\n reader.coordinates.getSpinePositionFromClientPosition(\n normalizedEvent,\n )\n\n const spineItemPageInfo = positionInSpineNonTransformed\n ? reader.spine.locator.getSpineItemPagePositionFromSpinePosition(\n positionInSpineNonTransformed,\n )\n : undefined\n\n const beforeTapResults$ = hookManager.execute(\n \"beforeTapGesture\",\n undefined,\n { event$: of({ event, page: spineItemPageInfo }) },\n )\n\n return combineLatest([...beforeTapResults$, of(true)]).pipe(\n first(),\n filter((results) => !results.some((result) => result === false)),\n map(() => {\n if (computedPageTurnMode === \"scrollable\") {\n return { event, handled: false }\n }\n\n if (\n computedPageTurnDirection === \"horizontal\" &&\n isPositionInArea(\n positionInContainer,\n { type: \"margins\", left: pageTurnMargin },\n containerElementRect,\n )\n ) {\n reader.navigation.turnLeftOrTop()\n } else if (\n computedPageTurnDirection === \"vertical\" &&\n isPositionInArea(\n positionInContainer,\n { type: \"margins\", top: pageTurnMargin },\n containerElementRect,\n )\n ) {\n reader.navigation.turnLeftOrTop()\n } else if (\n computedPageTurnDirection === \"vertical\" &&\n isPositionInArea(\n positionInContainer,\n { type: \"margins\", bottom: pageTurnMargin },\n containerElementRect,\n )\n ) {\n reader.navigation.turnRightOrBottom()\n } else if (\n computedPageTurnDirection === \"horizontal\" &&\n isPositionInArea(\n positionInContainer,\n { type: \"margins\", right: pageTurnMargin },\n containerElementRect,\n )\n ) {\n reader.navigation.turnRightOrBottom()\n } else {\n return { event, handled: false }\n }\n\n return { event, handled: true }\n }),\n )\n }\n }\n\n return EMPTY\n }),\n )\n\n return gestures$\n}\n","import { type Reader, SettingsManager } from \"@prose-reader/core\"\nimport type { InputSettings, OutputSettings } from \"./types\"\nimport { takeUntil, tap } from \"rxjs\"\n\nexport class GesturesSettingsManager extends SettingsManager<\n InputSettings,\n OutputSettings\n> {\n constructor(\n initialSettings: Partial<InputSettings>,\n private reader: Reader,\n ) {\n super(initialSettings)\n\n /**\n * Since we have settings that may be locked due to some reader settings\n * we need to update as soon as they update as well.\n */\n reader.settings.values$\n .pipe(\n tap(() => {\n this.update({})\n }),\n takeUntil(this.destroy$),\n )\n .subscribe()\n }\n\n getOutputSettings(inputSettings: InputSettings): OutputSettings {\n return {\n ...inputSettings,\n panNavigation:\n this.reader.settings.values.computedPageTurnMode === `scrollable`\n ? false\n : inputSettings.panNavigation,\n }\n }\n\n getDefaultSettings(): InputSettings {\n return {\n panNavigation: \"pan\",\n pinchCancelPan: true,\n fontScalePinchEnabled: true,\n fontScalePinchThrottleTime: 500,\n fontScaleMaxScale: 5,\n fontScaleMinScale: 0.2,\n ignore: [],\n }\n }\n}\n","import { HookManager, type Reader } from \"@prose-reader/core\"\nimport {\n PanRecognizer,\n PinchRecognizer,\n Recognizable,\n SwipeRecognizer,\n TapRecognizer,\n} from \"gesturx\"\nimport { combineLatest, merge, share, takeUntil, tap } from \"rxjs\"\nimport { registerPan } from \"./gestures/pan\"\nimport { registerPinch } from \"./gestures/pinch\"\nimport { registerSwipe } from \"./gestures/swipe\"\nimport { registerTaps } from \"./gestures/taps/registerTaps\"\nimport { GesturesSettingsManager } from \"./SettingsManager\"\nimport type { EnhancerAPI, Hook, InputSettings } from \"./types\"\n\nexport { isPositionInArea } from \"./gestures/taps/utils\"\nexport * from \"./types\"\n\nexport const gesturesEnhancer =\n <InheritOptions, InheritOutput extends Reader>(\n next: (options: InheritOptions) => InheritOutput,\n ) =>\n (\n options: InheritOptions & {\n gestures?: Partial<InputSettings>\n },\n ): InheritOutput & EnhancerAPI => {\n const { gestures = {}, ...rest } = options\n const reader = next(rest as InheritOptions)\n\n const settingsManager = new GesturesSettingsManager(gestures, reader)\n\n const hookManager = new HookManager<Hook>()\n\n const pinchRecognizer = new PinchRecognizer({\n options: {\n /**\n * @important\n * To be less than pan otherwise it will not fail before it starts\n */\n posThreshold: 20,\n },\n })\n\n const failWithSelection = {\n start$: reader.selection.selectionStart$,\n end$: reader.selection.selectionEnd$,\n }\n\n const panRecognizer = new PanRecognizer({\n failWith: [pinchRecognizer, failWithSelection],\n options: {\n // we want to have some margin to trigger zoom\n posThreshold: 15,\n },\n })\n\n const tapRecognizer = new TapRecognizer({\n failWith: [panRecognizer],\n })\n\n const swipeRecognizer = new SwipeRecognizer({\n failWith: [failWithSelection],\n })\n\n const recognizable = new Recognizable({\n recognizers: [\n tapRecognizer,\n panRecognizer,\n swipeRecognizer,\n pinchRecognizer,\n ],\n disableTextSelection: false,\n })\n\n const tapGestures$ = registerTaps({\n hookManager,\n reader,\n recognizable,\n settingsManager,\n recognizer: tapRecognizer,\n })\n\n const panGestures$ = registerPan({\n hookManager,\n reader,\n recognizer: panRecognizer,\n settingsManager,\n })\n\n const swipeGestures$ = registerSwipe({\n hookManager,\n reader,\n recognizable,\n settingsManager,\n })\n\n const pinchGestures$ = registerPinch({\n hookManager,\n reader,\n recognizable,\n settingsManager,\n })\n\n const containerUpdate$ = reader.context.watch(`rootElement`).pipe(\n tap((container) => {\n recognizable.update({\n container,\n })\n }),\n )\n\n const watchSettings$ = combineLatest([\n settingsManager.values$,\n panRecognizer.config$,\n ]).pipe(\n tap(([{ pinchCancelPan }, panRecognizerConfig]) => {\n const pinchAlreadyInFailWith =\n panRecognizerConfig.failWith?.includes(pinchRecognizer)\n\n if (pinchCancelPan && !pinchAlreadyInFailWith) {\n panRecognizer.update({\n failWith: [\n ...(panRecognizerConfig.failWith ?? []),\n pinchRecognizer,\n ],\n })\n }\n\n if (!pinchCancelPan && pinchAlreadyInFailWith) {\n panRecognizer.update({\n failWith: panRecognizerConfig.failWith?.filter(\n (recognizer) => recognizer !== pinchRecognizer,\n ),\n })\n }\n }),\n )\n\n const gestures$ = merge(\n pinchGestures$,\n tapGestures$,\n swipeGestures$,\n panGestures$,\n ).pipe(share())\n\n merge(containerUpdate$, watchSettings$, gestures$)\n .pipe(takeUntil(reader.$.destroy$))\n .subscribe()\n\n return {\n ...reader,\n destroy: () => {\n reader.destroy()\n settingsManager.destroy()\n },\n gestures: {\n settings: settingsManager,\n gestures$,\n hooks: hookManager,\n },\n }\n }\n"],"names":["isZoomingIn","event"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/gestures/pan.ts","../src/gestures/pinch.ts","../src/gestures/swipe.ts","../src/utils.ts","../src/gestures/taps/utils.ts","../src/gestures/taps/registerTaps.ts","../src/SettingsManager.ts","../src/index.ts"],"sourcesContent":["import type { HookManager, Reader } from \"@prose-reader/core\"\nimport type { PanRecognizer } from \"gesturx\"\nimport { EMPTY, filter, map, merge, of, switchMap } from \"rxjs\"\nimport type { GesturesSettingsManager } from \"../SettingsManager\"\nimport type { Hook } from \"../types\"\n\nexport const registerPan = ({\n reader,\n recognizer,\n settingsManager,\n}: {\n recognizer: PanRecognizer\n reader: Reader\n hookManager: HookManager<Hook>\n settingsManager: GesturesSettingsManager\n}) => {\n const gestures$ = settingsManager.values$.pipe(\n switchMap(({ panNavigation }) => {\n if (panNavigation !== \"pan\") return EMPTY\n\n const panStart$ = recognizer.events$.pipe(\n filter((event) => event.type === `panStart`),\n )\n const panMove$ = recognizer.events$.pipe(\n filter((event) => event.type === `panMove`),\n )\n const panEnd$ = recognizer.events$.pipe(\n filter((event) => event.type === `panEnd`),\n )\n\n const pan$ = panStart$.pipe(\n switchMap((panStartEvent) => {\n /**\n * We use the last cumulative delta to derive the new event atomic delta.\n * This is because panning the zoom does not necessarily means the zoom position\n * will always changes. If the user keep dragging while the zoom is blocked, we want\n * it to move the other direction when he start dragging the other way.\n * We cannot use the `reader.zoom.state.currentPosition` as previous position\n * and the event.deltaX to compute the new zoom position.\n */\n let lastDelta = { x: 0, y: 0 }\n\n const moveAndEnd$ = merge(panMove$, panEnd$).pipe(\n map((event) => {\n const isZooming = reader.zoom.state.isZooming\n const isZoomingIn = reader.zoom.state.currentScale > 1\n\n /**\n * When user is zooming in, we don't navigate anymore.\n * The gestures is gonna be handled by the pinch and viewport.\n */\n if (isZooming && isZoomingIn) {\n const deltaX = event.deltaX - lastDelta.x\n const deltaY = event.deltaY - lastDelta.y\n\n lastDelta = {\n x: event.deltaX,\n y: event.deltaY,\n }\n\n reader.zoom.move(\n {\n x: reader.zoom.state.currentPosition.x + deltaX,\n y: reader.zoom.state.currentPosition.y + deltaY,\n },\n {\n constrain: \"within-viewport\",\n },\n )\n\n return event\n }\n\n if (event.type === `panMove`) {\n if (!reader.navigation.panNavigator.value.isStarted) {\n reader.navigation.panNavigator.start({\n x: event.deltaX,\n y: event.deltaY,\n })\n\n return event\n }\n\n reader.navigation.panNavigator.panMoveTo({\n x: event.deltaX,\n y: event.deltaY,\n })\n\n return event\n }\n\n if (\n event.type === `panEnd` &&\n reader.navigation.panNavigator.value.isStarted\n ) {\n reader.navigation.panNavigator.stop({\n x: event.deltaX,\n y: event.deltaY,\n })\n\n return event\n }\n\n return event\n }),\n )\n\n return merge(of(panStartEvent), moveAndEnd$).pipe(\n map((event) => ({ type: \"pan\" as const, gestureEvent: event })),\n )\n }),\n )\n\n return pan$\n }),\n )\n\n return gestures$\n}\n","import {\n type HookManager,\n isHtmlElement,\n type Reader,\n} from \"@prose-reader/core\"\nimport type { PinchEvent } from \"gesturx\"\nimport {\n animationFrameScheduler,\n EMPTY,\n filter,\n map,\n merge,\n switchMap,\n takeUntil,\n tap,\n throttleTime,\n withLatestFrom,\n} from \"rxjs\"\nimport type { GesturesSettingsManager } from \"../SettingsManager\"\nimport type { GestureRecognizable, Hook } from \"../types\"\n\nconst isHtmlImageElement = (\n target: EventTarget | null,\n): target is HTMLImageElement =>\n isHtmlElement(target) &&\n !!target.ownerDocument.defaultView &&\n target instanceof target.ownerDocument.defaultView.HTMLImageElement\n\nexport const registerPinch = ({\n reader,\n recognizable,\n settingsManager,\n}: {\n recognizable: GestureRecognizable\n reader: Reader\n hookManager: HookManager<Hook>\n settingsManager: GesturesSettingsManager\n}) => {\n const pinchStart$ = recognizable.events$.pipe(\n map(({ event }) => event),\n filter((event): event is PinchEvent => event.type === \"pinchStart\"),\n )\n\n const pinchMove$ = recognizable.events$.pipe(\n map(({ event }) => event),\n filter((event): event is PinchEvent => event.type === \"pinchMove\"),\n )\n\n const pinchEnd$ = recognizable.events$.pipe(\n map(({ event }) => event),\n filter((event): event is PinchEvent => event.type === \"pinchEnd\"),\n )\n\n const shouldStartZoom = (\n target: EventTarget | null,\n ): target is HTMLImageElement =>\n isHtmlImageElement(target) && !reader.zoom.state.isZooming\n\n return settingsManager.values$.pipe(\n switchMap(({ fontScalePinchEnabled, fontScalePinchThrottleTime }) => {\n const zoomGestures$ = pinchStart$.pipe(\n switchMap(() => {\n const startScale = reader.zoom.state.currentScale\n\n return pinchMove$.pipe(\n withLatestFrom(reader.viewportState$),\n map(([event, viewportState]) => {\n // symmetric scaling calculation\n const newScale = startScale * event.scale\n\n /**\n * @important\n * We don't want to trigger zoom gestures if there is a pan navigation\n * in progress. This can happens if the user start panning and then adds\n * another finger triggering a pinch.\n */\n if (viewportState === \"busy\") {\n return event\n }\n\n if (!reader.zoom.state.isZooming && event.scale > 1) {\n reader.zoom.enter({ animate: false, scale: newScale })\n\n return event\n }\n\n if (reader.zoom.state.isZooming) {\n if (newScale < 1) {\n reader.zoom.exit()\n } else {\n reader.zoom.scaleAt(\n Math.min(newScale, settingsManager.values.zoomMaxScale),\n {\n constrain: \"within-viewport\",\n },\n )\n }\n\n return event\n }\n\n return event\n }),\n )\n }),\n )\n\n const watchForFontScaleChange$ = !fontScalePinchEnabled\n ? EMPTY\n : pinchStart$.pipe(\n withLatestFrom(reader.viewportState$),\n switchMap(([pinchStartEvent, viewportState]) => {\n if (\n viewportState === \"busy\" ||\n shouldStartZoom(pinchStartEvent.event.target) ||\n reader.zoom.state.isZooming\n )\n return EMPTY\n\n const lastFontScaleOnPinchStart = reader.settings.values.fontScale\n\n return pinchMove$.pipe(\n throttleTime(\n fontScalePinchThrottleTime,\n animationFrameScheduler,\n {\n trailing: true,\n },\n ),\n tap((event) => {\n const newScale = Number.parseFloat(\n (lastFontScaleOnPinchStart + (event.scale - 1)).toFixed(2),\n )\n\n const newMinMaxedFontScale = Math.max(\n Math.min(\n newScale,\n settingsManager.values.fontScaleMaxScale,\n ),\n settingsManager.values.fontScaleMinScale,\n )\n\n reader.settings.update({\n fontScale: newMinMaxedFontScale,\n })\n }),\n takeUntil(pinchEnd$),\n )\n }),\n )\n\n return merge(zoomGestures$, watchForFontScaleChange$).pipe(\n map((event) => ({\n type: \"pinch\" as const,\n gestureEvent: event,\n })),\n )\n }),\n )\n}\n","import type { HookManager, Reader } from \"@prose-reader/core\"\nimport type { SwipeEvent } from \"gesturx\"\nimport { EMPTY, filter, map, switchMap, tap } from \"rxjs\"\nimport type { GesturesSettingsManager } from \"../SettingsManager\"\nimport type { GestureEvent, GestureRecognizable, Hook } from \"../types\"\n\nconst isSwipeEvent = (event: GestureEvent[\"event\"]): event is SwipeEvent =>\n event.type === \"swipe\"\n\nexport const registerSwipe = ({\n reader,\n recognizable,\n settingsManager,\n}: {\n recognizable: GestureRecognizable\n reader: Reader\n hookManager: HookManager<Hook>\n settingsManager: GesturesSettingsManager\n}) => {\n const gestures$ = settingsManager.values$.pipe(\n switchMap(({ panNavigation }) =>\n panNavigation !== \"swipe\"\n ? EMPTY\n : recognizable.events$.pipe(\n map(({ event }) => event),\n filter(isSwipeEvent),\n tap((event) => {\n const { computedPageTurnDirection } = reader.settings.values\n\n if (computedPageTurnDirection === \"vertical\") {\n if (event.velocityY < -0.5) {\n reader?.navigation.turnRight()\n }\n if (event.velocityY > 0.5) {\n reader?.navigation.turnLeft()\n }\n } else {\n if (event.velocityX < -0.5) {\n reader?.navigation.turnRight()\n }\n if (event.velocityX > 0.5) {\n reader?.navigation.turnLeft()\n }\n }\n }),\n map((event) => ({ type: \"swipe\" as const, gestureEvent: event })),\n ),\n ),\n )\n\n return gestures$\n}\n","import { isHtmlElement } from \"@prose-reader/core\"\nimport type { GestureEvent } from \"./types\"\n\nexport const isNotLink = (event: GestureEvent[\"event\"]) => {\n const target = event.event.target\n\n if (isHtmlElement(target) && target.tagName === \"a\") return false\n\n return true\n}\n\nexport const getPositionRelativeToContainer = (\n event: { x: number; y: number },\n containerElementRect: DOMRectReadOnly,\n) => {\n const { x, y } = event\n const { left, top } = containerElementRect\n\n return {\n x: x - left,\n y: y - top,\n }\n}\n\nexport const istMatchingSelectors = (\n selectors: string[],\n event: GestureEvent[\"event\"],\n): boolean => {\n const target = event.event.target\n\n if (!isHtmlElement(target)) return false\n\n const match = selectors.find((selector) => {\n // Check if the target matches the selector directly\n if (target.matches(selector)) return true\n\n // Check if the target is within an element matching the selector\n if (target.closest(selector)) return true\n\n return false\n })\n\n return !!match\n}\n","import type { TapArea } from \"./types\"\n\nexport const isPositionInArea = (\n position: { x: number; y: number },\n area: TapArea,\n containerSize: { width: number; height: number },\n): boolean => {\n const { x, y } = position\n const { width, height } = containerSize\n\n switch (area.type) {\n case \"margins\": {\n const { top, bottom, left, right } = area\n const inTop = top !== undefined ? y < height * top : true\n const inBottom = bottom !== undefined ? y > height * (1 - bottom) : true\n const inLeft = left !== undefined ? x < width * left : true\n const inRight = right !== undefined ? x > width * (1 - right) : true\n\n return (\n (top !== undefined && inTop) ||\n (bottom !== undefined && inBottom) ||\n (left !== undefined && inLeft) ||\n (right !== undefined && inRight)\n )\n }\n\n case \"rectangle\": {\n const {\n x: rectX,\n y: rectY,\n width: rectWidth,\n height: rectHeight,\n unit = \"%\",\n } = area\n const actualX = unit === \"%\" ? width * (rectX / 100) : rectX\n const actualY = unit === \"%\" ? height * (rectY / 100) : rectY\n const actualWidth = unit === \"%\" ? width * (rectWidth / 100) : rectWidth\n const actualHeight =\n unit === \"%\" ? height * (rectHeight / 100) : rectHeight\n\n return (\n x >= actualX &&\n x <= actualX + actualWidth &&\n y >= actualY &&\n y <= actualY + actualHeight\n )\n }\n\n case \"corner\": {\n const { corner, size, unit = \"%\" } = area\n const actualSize =\n unit === \"%\" ? Math.min(width, height) * (size / 100) : size\n\n switch (corner) {\n case \"top-left\":\n return x < actualSize && y < actualSize\n case \"top-right\":\n return x > width - actualSize && y < actualSize\n case \"bottom-left\":\n return x < actualSize && y > height - actualSize\n case \"bottom-right\":\n return x > width - actualSize && y > height - actualSize\n default:\n return false\n }\n }\n\n case \"center\": {\n const { width: centerWidth, height: centerHeight, unit = \"%\" } = area\n const actualWidth =\n unit === \"%\" ? width * (centerWidth / 100) : centerWidth\n const actualHeight =\n unit === \"%\" ? height * (centerHeight / 100) : centerHeight\n const centerX = width / 2\n const centerY = height / 2\n\n return (\n x >= centerX - actualWidth / 2 &&\n x <= centerX + actualWidth / 2 &&\n y >= centerY - actualHeight / 2 &&\n y <= centerY + actualHeight / 2\n )\n }\n\n default:\n return false\n }\n}\n\nexport const calculatePageTurnLinearMargin = (screenWidth: number): number => {\n const minMargin = 0.15\n const maxMargin = 0.2\n const minWidth = 320\n const maxWidth = 1200\n\n if (screenWidth <= minWidth) return maxMargin\n if (screenWidth >= maxWidth) return minMargin\n\n // Linear interpolation between min and max\n const ratio = (screenWidth - minWidth) / (maxWidth - minWidth)\n return maxMargin - ratio * (maxMargin - minMargin)\n}\n","import type { HookManager, Reader } from \"@prose-reader/core\"\nimport type { TapRecognizer } from \"gesturx\"\nimport {\n combineLatest,\n EMPTY,\n filter,\n first,\n map,\n of,\n switchMap,\n withLatestFrom,\n} from \"rxjs\"\nimport type { GesturesSettingsManager } from \"../../SettingsManager\"\nimport type { GestureRecognizable, Hook } from \"../../types\"\nimport {\n getPositionRelativeToContainer,\n isNotLink,\n istMatchingSelectors,\n} from \"../../utils\"\nimport { calculatePageTurnLinearMargin, isPositionInArea } from \"./utils\"\n\nexport const registerTaps = ({\n reader,\n recognizable,\n hookManager,\n settingsManager,\n recognizer,\n}: {\n recognizable: GestureRecognizable\n reader: Reader\n hookManager: HookManager<Hook>\n recognizer: TapRecognizer\n settingsManager: GesturesSettingsManager\n}) => {\n const gestures$ = recognizable.events$.pipe(\n filter((event) => event.recognizer === recognizer),\n withLatestFrom(reader.context.watch(`rootElement`), reader.spine.element$),\n switchMap(([{ event }, containerElement, spineElement]) => {\n if (!containerElement || !spineElement) return EMPTY\n\n const normalizedEvent = event.event\n const { computedPageTurnDirection, computedPageTurnMode } =\n reader.settings.values\n\n if (\n event.type === \"tap\" &&\n isNotLink(event) &&\n !istMatchingSelectors(settingsManager.values.ignore, event)\n ) {\n if (`x` in normalizedEvent) {\n const containerElementRect = containerElement.getBoundingClientRect()\n const width = containerElementRect.width\n const pageTurnMargin = calculatePageTurnLinearMargin(width)\n const positionInContainer = getPositionRelativeToContainer(\n normalizedEvent,\n containerElementRect,\n )\n\n const positionInSpineNonTransformed =\n reader.coordinates.getSpinePositionFromClientPosition(\n normalizedEvent,\n )\n\n const spineItemPageInfo = positionInSpineNonTransformed\n ? reader.spine.locator.getSpineItemPagePositionFromSpinePosition(\n positionInSpineNonTransformed,\n )\n : undefined\n\n const beforeTapResults$ = hookManager.execute(\n \"beforeTapGesture\",\n undefined,\n { event$: of({ event, page: spineItemPageInfo }) },\n )\n\n return combineLatest([...beforeTapResults$, of(true)]).pipe(\n first(),\n filter((results) => !results.some((result) => result === false)),\n map(() => {\n if (\n computedPageTurnMode === \"scrollable\" ||\n /**\n * We don't want to navigate from gestures when the user is zooming.\n */\n reader.zoom.state.isZooming\n ) {\n return {\n type: \"tap\" as const,\n gestureEvent: event,\n handled: false,\n }\n }\n\n if (\n computedPageTurnDirection === \"horizontal\" &&\n isPositionInArea(\n positionInContainer,\n { type: \"margins\", left: pageTurnMargin },\n containerElementRect,\n )\n ) {\n reader.navigation.turnLeftOrTop()\n } else if (\n computedPageTurnDirection === \"vertical\" &&\n isPositionInArea(\n positionInContainer,\n { type: \"margins\", top: pageTurnMargin },\n containerElementRect,\n )\n ) {\n reader.navigation.turnLeftOrTop()\n } else if (\n computedPageTurnDirection === \"vertical\" &&\n isPositionInArea(\n positionInContainer,\n { type: \"margins\", bottom: pageTurnMargin },\n containerElementRect,\n )\n ) {\n reader.navigation.turnRightOrBottom()\n } else if (\n computedPageTurnDirection === \"horizontal\" &&\n isPositionInArea(\n positionInContainer,\n { type: \"margins\", right: pageTurnMargin },\n containerElementRect,\n )\n ) {\n reader.navigation.turnRightOrBottom()\n } else {\n return {\n type: \"tap\" as const,\n gestureEvent: event,\n handled: false,\n }\n }\n\n return {\n type: \"tap\" as const,\n gestureEvent: event,\n handled: true,\n }\n }),\n )\n }\n }\n\n return EMPTY\n }),\n )\n\n return gestures$\n}\n","import { type Reader, SettingsManager } from \"@prose-reader/core\"\nimport { takeUntil, tap } from \"rxjs\"\nimport type { InputSettings, OutputSettings } from \"./types\"\n\nexport class GesturesSettingsManager extends SettingsManager<\n InputSettings,\n OutputSettings\n> {\n constructor(\n initialSettings: Partial<InputSettings>,\n private reader: Reader,\n ) {\n super(initialSettings)\n\n /**\n * Since we have settings that may be locked due to some reader settings\n * we need to update as soon as they update as well.\n */\n reader.settings.values$\n .pipe(\n tap(() => {\n this.update({})\n }),\n takeUntil(this.destroy$),\n )\n .subscribe()\n }\n\n getOutputSettings(inputSettings: InputSettings): OutputSettings {\n return {\n ...inputSettings,\n panNavigation:\n this.reader.settings.values.computedPageTurnMode === `scrollable`\n ? false\n : inputSettings.panNavigation,\n }\n }\n\n getDefaultSettings(): InputSettings {\n return {\n panNavigation: \"pan\",\n pinchCancelPan: true,\n fontScalePinchEnabled: true,\n fontScalePinchThrottleTime: 500,\n fontScaleMaxScale: 5,\n fontScaleMinScale: 0.2,\n zoomMaxScale: Infinity,\n ignore: [],\n }\n }\n}\n","import { HookManager, type Reader } from \"@prose-reader/core\"\nimport {\n PanRecognizer,\n PinchRecognizer,\n Recognizable,\n SwipeRecognizer,\n TapRecognizer,\n} from \"gesturx\"\nimport { combineLatest, merge, share, takeUntil, tap } from \"rxjs\"\nimport { name as packageName } from \"../package.json\"\nimport { registerPan } from \"./gestures/pan\"\nimport { registerPinch } from \"./gestures/pinch\"\nimport { registerSwipe } from \"./gestures/swipe\"\nimport { registerTaps } from \"./gestures/taps/registerTaps\"\nimport { GesturesSettingsManager } from \"./SettingsManager\"\nimport styles from \"./style.css?inline\"\nimport type { EnhancerAPI, Hook, InputSettings } from \"./types\"\n\nexport { isPositionInArea } from \"./gestures/taps/utils\"\nexport * from \"./types\"\n\nexport const gesturesEnhancer =\n <InheritOptions, InheritOutput extends Reader>(\n next: (options: InheritOptions) => InheritOutput,\n ) =>\n (\n options: InheritOptions & {\n gestures?: Partial<InputSettings>\n },\n ): InheritOutput & EnhancerAPI => {\n const { gestures = {}, ...rest } = options\n const reader = next(rest as InheritOptions)\n\n const removeStylesheet = reader.utils.injectScopedCSS(\n document,\n packageName,\n styles,\n )\n\n const settingsManager = new GesturesSettingsManager(gestures, reader)\n\n const hookManager = new HookManager<Hook>()\n\n const pinchRecognizer = new PinchRecognizer({\n options: {\n /**\n * @important\n * Ideally we want pinch to triggers before pan so we can\n * capture zoom before starting panning.\n */\n posThreshold: 10,\n },\n })\n\n const failWithSelection = {\n start$: reader.selection.selectionStart$,\n end$: reader.selection.selectionEnd$,\n }\n\n const panRecognizer = new PanRecognizer({\n failWith: [pinchRecognizer, failWithSelection],\n options: {\n // we want to have some margin to trigger zoom\n posThreshold: 20,\n },\n })\n\n const tapRecognizer = new TapRecognizer({\n failWith: [panRecognizer],\n })\n\n const swipeRecognizer = new SwipeRecognizer({\n failWith: [failWithSelection],\n })\n\n const recognizable = new Recognizable({\n recognizers: [\n tapRecognizer,\n panRecognizer,\n swipeRecognizer,\n pinchRecognizer,\n ],\n disableTextSelection: false,\n })\n\n const tapGestures$ = registerTaps({\n hookManager,\n reader,\n recognizable,\n settingsManager,\n recognizer: tapRecognizer,\n })\n\n const panGestures$ = registerPan({\n hookManager,\n reader,\n recognizer: panRecognizer,\n settingsManager,\n })\n\n const swipeGestures$ = registerSwipe({\n hookManager,\n reader,\n recognizable,\n settingsManager,\n })\n\n const pinchGestures$ = registerPinch({\n hookManager,\n reader,\n recognizable,\n settingsManager,\n })\n\n const containerUpdate$ = reader.context.watch(`rootElement`).pipe(\n tap((container) => {\n recognizable.update({\n container,\n })\n }),\n )\n\n const watchSettings$ = combineLatest([\n settingsManager.values$,\n panRecognizer.config$,\n ]).pipe(\n tap(([{ pinchCancelPan }, panRecognizerConfig]) => {\n const pinchAlreadyInFailWith =\n panRecognizerConfig.failWith?.includes(pinchRecognizer)\n\n if (pinchCancelPan && !pinchAlreadyInFailWith) {\n panRecognizer.update({\n failWith: [\n ...(panRecognizerConfig.failWith ?? []),\n pinchRecognizer,\n ],\n })\n }\n\n if (!pinchCancelPan && pinchAlreadyInFailWith) {\n panRecognizer.update({\n failWith: panRecognizerConfig.failWith?.filter(\n (recognizer) => recognizer !== pinchRecognizer,\n ),\n })\n }\n }),\n )\n\n const gestures$ = merge(\n pinchGestures$,\n tapGestures$,\n swipeGestures$,\n panGestures$,\n ).pipe(share())\n\n merge(containerUpdate$, watchSettings$, gestures$)\n .pipe(takeUntil(reader.$.destroy$))\n .subscribe()\n\n return {\n ...reader,\n destroy: () => {\n removeStylesheet()\n reader.destroy()\n settingsManager.destroy()\n },\n gestures: {\n settings: settingsManager,\n gestures$,\n hooks: hookManager,\n },\n }\n }\n"],"names":["packageName"],"mappings":"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"}
|
package/dist/index.umd.cjs
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("@prose-reader/core"), require("gesturx"), require("rxjs")) : typeof define === "function" && define.amd ? define(["exports", "@prose-reader/core", "gesturx", "rxjs"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global["prose-reader-enhancer-gestures"] = {}, global.core, global.gesturx, global.rxjs));
|
|
3
3
|
})(this, (function(exports2, core, gesturx, rxjs) {
|
|
4
4
|
"use strict";
|
|
5
|
+
const name = "@prose-reader/enhancer-gestures";
|
|
5
6
|
const registerPan = ({
|
|
6
7
|
reader,
|
|
7
8
|
recognizer,
|
|
@@ -21,48 +22,55 @@
|
|
|
21
22
|
);
|
|
22
23
|
const pan$ = panStart$.pipe(
|
|
23
24
|
rxjs.switchMap((panStartEvent) => {
|
|
24
|
-
|
|
25
|
+
let lastDelta = { x: 0, y: 0 };
|
|
25
26
|
const moveAndEnd$ = rxjs.merge(panMove$, panEnd$).pipe(
|
|
26
27
|
rxjs.map((event) => {
|
|
27
28
|
const isZooming = reader.zoom.state.isZooming;
|
|
28
|
-
const
|
|
29
|
-
if (isZooming &&
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
x,
|
|
34
|
-
y
|
|
35
|
-
}
|
|
36
|
-
|
|
29
|
+
const isZoomingIn = reader.zoom.state.currentScale > 1;
|
|
30
|
+
if (isZooming && isZoomingIn) {
|
|
31
|
+
const deltaX = event.deltaX - lastDelta.x;
|
|
32
|
+
const deltaY = event.deltaY - lastDelta.y;
|
|
33
|
+
lastDelta = {
|
|
34
|
+
x: event.deltaX,
|
|
35
|
+
y: event.deltaY
|
|
36
|
+
};
|
|
37
|
+
reader.zoom.move(
|
|
38
|
+
{
|
|
39
|
+
x: reader.zoom.state.currentPosition.x + deltaX,
|
|
40
|
+
y: reader.zoom.state.currentPosition.y + deltaY
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
constrain: "within-viewport"
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
return event;
|
|
37
47
|
}
|
|
38
48
|
if (event.type === `panMove`) {
|
|
39
|
-
reader.navigation.
|
|
49
|
+
if (!reader.navigation.panNavigator.value.isStarted) {
|
|
50
|
+
reader.navigation.panNavigator.start({
|
|
51
|
+
x: event.deltaX,
|
|
52
|
+
y: event.deltaY
|
|
53
|
+
});
|
|
54
|
+
return event;
|
|
55
|
+
}
|
|
56
|
+
reader.navigation.panNavigator.panMoveTo({
|
|
40
57
|
x: event.deltaX,
|
|
41
58
|
y: event.deltaY
|
|
42
59
|
});
|
|
43
|
-
return
|
|
60
|
+
return event;
|
|
44
61
|
}
|
|
45
|
-
if (event.type === `panEnd`) {
|
|
46
|
-
reader.navigation.
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
);
|
|
50
|
-
return
|
|
62
|
+
if (event.type === `panEnd` && reader.navigation.panNavigator.value.isStarted) {
|
|
63
|
+
reader.navigation.panNavigator.stop({
|
|
64
|
+
x: event.deltaX,
|
|
65
|
+
y: event.deltaY
|
|
66
|
+
});
|
|
67
|
+
return event;
|
|
51
68
|
}
|
|
52
|
-
return
|
|
69
|
+
return event;
|
|
53
70
|
})
|
|
54
71
|
);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
reader?.navigation.moveTo({ x: 0, y: 0 }, { start: true });
|
|
58
|
-
return rxjs.merge(
|
|
59
|
-
rxjs.of({ event: panStartEvent, handled: true }),
|
|
60
|
-
moveAndEnd$
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
return rxjs.merge(
|
|
64
|
-
rxjs.of({ event: panStartEvent, handled: false }),
|
|
65
|
-
moveAndEnd$
|
|
72
|
+
return rxjs.merge(rxjs.of(panStartEvent), moveAndEnd$).pipe(
|
|
73
|
+
rxjs.map((event) => ({ type: "pan", gestureEvent: event }))
|
|
66
74
|
);
|
|
67
75
|
})
|
|
68
76
|
);
|
|
@@ -93,28 +101,34 @@
|
|
|
93
101
|
return settingsManager.values$.pipe(
|
|
94
102
|
rxjs.switchMap(({ fontScalePinchEnabled, fontScalePinchThrottleTime }) => {
|
|
95
103
|
const zoomGestures$ = pinchStart$.pipe(
|
|
96
|
-
rxjs.
|
|
97
|
-
rxjs.switchMap(([event, viewportState]) => {
|
|
98
|
-
const target = event.event.target;
|
|
104
|
+
rxjs.switchMap(() => {
|
|
99
105
|
const startScale = reader.zoom.state.currentScale;
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
106
|
+
return pinchMove$.pipe(
|
|
107
|
+
rxjs.withLatestFrom(reader.viewportState$),
|
|
108
|
+
rxjs.map(([event, viewportState]) => {
|
|
109
|
+
const newScale = startScale * event.scale;
|
|
110
|
+
if (viewportState === "busy") {
|
|
111
|
+
return event;
|
|
112
|
+
}
|
|
113
|
+
if (!reader.zoom.state.isZooming && event.scale > 1) {
|
|
114
|
+
reader.zoom.enter({ animate: false, scale: newScale });
|
|
115
|
+
return event;
|
|
116
|
+
}
|
|
117
|
+
if (reader.zoom.state.isZooming) {
|
|
118
|
+
if (newScale < 1) {
|
|
119
|
+
reader.zoom.exit();
|
|
120
|
+
} else {
|
|
121
|
+
reader.zoom.scaleAt(
|
|
122
|
+
Math.min(newScale, settingsManager.values.zoomMaxScale),
|
|
123
|
+
{
|
|
124
|
+
constrain: "within-viewport"
|
|
125
|
+
}
|
|
126
|
+
);
|
|
115
127
|
}
|
|
116
|
-
|
|
117
|
-
|
|
128
|
+
return event;
|
|
129
|
+
}
|
|
130
|
+
return event;
|
|
131
|
+
})
|
|
118
132
|
);
|
|
119
133
|
})
|
|
120
134
|
);
|
|
@@ -152,11 +166,15 @@
|
|
|
152
166
|
})
|
|
153
167
|
);
|
|
154
168
|
return rxjs.merge(zoomGestures$, watchForFontScaleChange$).pipe(
|
|
155
|
-
rxjs.map((event) => ({
|
|
169
|
+
rxjs.map((event) => ({
|
|
170
|
+
type: "pinch",
|
|
171
|
+
gestureEvent: event
|
|
172
|
+
}))
|
|
156
173
|
);
|
|
157
174
|
})
|
|
158
175
|
);
|
|
159
176
|
};
|
|
177
|
+
const isSwipeEvent = (event) => event.type === "swipe";
|
|
160
178
|
const registerSwipe = ({
|
|
161
179
|
reader,
|
|
162
180
|
recognizable,
|
|
@@ -165,8 +183,9 @@
|
|
|
165
183
|
const gestures$ = settingsManager.values$.pipe(
|
|
166
184
|
rxjs.switchMap(
|
|
167
185
|
({ panNavigation }) => panNavigation !== "swipe" ? rxjs.EMPTY : recognizable.events$.pipe(
|
|
168
|
-
rxjs.
|
|
169
|
-
rxjs.
|
|
186
|
+
rxjs.map(({ event }) => event),
|
|
187
|
+
rxjs.filter(isSwipeEvent),
|
|
188
|
+
rxjs.tap((event) => {
|
|
170
189
|
const { computedPageTurnDirection } = reader.settings.values;
|
|
171
190
|
if (computedPageTurnDirection === "vertical") {
|
|
172
191
|
if (event.velocityY < -0.5) {
|
|
@@ -184,7 +203,7 @@
|
|
|
184
203
|
}
|
|
185
204
|
}
|
|
186
205
|
}),
|
|
187
|
-
rxjs.map((
|
|
206
|
+
rxjs.map((event) => ({ type: "swipe", gestureEvent: event }))
|
|
188
207
|
)
|
|
189
208
|
)
|
|
190
209
|
);
|
|
@@ -315,8 +334,15 @@
|
|
|
315
334
|
rxjs.first(),
|
|
316
335
|
rxjs.filter((results) => !results.some((result) => result === false)),
|
|
317
336
|
rxjs.map(() => {
|
|
318
|
-
if (computedPageTurnMode === "scrollable"
|
|
319
|
-
|
|
337
|
+
if (computedPageTurnMode === "scrollable" || /**
|
|
338
|
+
* We don't want to navigate from gestures when the user is zooming.
|
|
339
|
+
*/
|
|
340
|
+
reader.zoom.state.isZooming) {
|
|
341
|
+
return {
|
|
342
|
+
type: "tap",
|
|
343
|
+
gestureEvent: event,
|
|
344
|
+
handled: false
|
|
345
|
+
};
|
|
320
346
|
}
|
|
321
347
|
if (computedPageTurnDirection === "horizontal" && isPositionInArea(
|
|
322
348
|
positionInContainer,
|
|
@@ -343,9 +369,17 @@
|
|
|
343
369
|
)) {
|
|
344
370
|
reader.navigation.turnRightOrBottom();
|
|
345
371
|
} else {
|
|
346
|
-
return {
|
|
372
|
+
return {
|
|
373
|
+
type: "tap",
|
|
374
|
+
gestureEvent: event,
|
|
375
|
+
handled: false
|
|
376
|
+
};
|
|
347
377
|
}
|
|
348
|
-
return {
|
|
378
|
+
return {
|
|
379
|
+
type: "tap",
|
|
380
|
+
gestureEvent: event,
|
|
381
|
+
handled: true
|
|
382
|
+
};
|
|
349
383
|
})
|
|
350
384
|
);
|
|
351
385
|
}
|
|
@@ -380,22 +414,30 @@
|
|
|
380
414
|
fontScalePinchThrottleTime: 500,
|
|
381
415
|
fontScaleMaxScale: 5,
|
|
382
416
|
fontScaleMinScale: 0.2,
|
|
417
|
+
zoomMaxScale: Infinity,
|
|
383
418
|
ignore: []
|
|
384
419
|
};
|
|
385
420
|
}
|
|
386
421
|
}
|
|
422
|
+
const styles = '[data-prose-reader-container="${id}"] * {\n /* Make sure that touche actions are correctly dispatched no matter where the user interact */\n touch-action: inherit;\n}\n';
|
|
387
423
|
const gesturesEnhancer = (next) => (options) => {
|
|
388
424
|
const { gestures = {}, ...rest } = options;
|
|
389
425
|
const reader = next(rest);
|
|
426
|
+
const removeStylesheet = reader.utils.injectScopedCSS(
|
|
427
|
+
document,
|
|
428
|
+
name,
|
|
429
|
+
styles
|
|
430
|
+
);
|
|
390
431
|
const settingsManager = new GesturesSettingsManager(gestures, reader);
|
|
391
432
|
const hookManager = new core.HookManager();
|
|
392
433
|
const pinchRecognizer = new gesturx.PinchRecognizer({
|
|
393
434
|
options: {
|
|
394
435
|
/**
|
|
395
436
|
* @important
|
|
396
|
-
*
|
|
437
|
+
* Ideally we want pinch to triggers before pan so we can
|
|
438
|
+
* capture zoom before starting panning.
|
|
397
439
|
*/
|
|
398
|
-
posThreshold:
|
|
440
|
+
posThreshold: 10
|
|
399
441
|
}
|
|
400
442
|
});
|
|
401
443
|
const failWithSelection = {
|
|
@@ -406,7 +448,7 @@
|
|
|
406
448
|
failWith: [pinchRecognizer, failWithSelection],
|
|
407
449
|
options: {
|
|
408
450
|
// we want to have some margin to trigger zoom
|
|
409
|
-
posThreshold:
|
|
451
|
+
posThreshold: 20
|
|
410
452
|
}
|
|
411
453
|
});
|
|
412
454
|
const tapRecognizer = new gesturx.TapRecognizer({
|
|
@@ -486,6 +528,7 @@
|
|
|
486
528
|
return {
|
|
487
529
|
...reader,
|
|
488
530
|
destroy: () => {
|
|
531
|
+
removeStylesheet();
|
|
489
532
|
reader.destroy();
|
|
490
533
|
settingsManager.destroy();
|
|
491
534
|
},
|
package/dist/index.umd.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.umd.cjs","sources":["../src/gestures/pan.ts","../src/gestures/pinch.ts","../src/gestures/swipe.ts","../src/utils.ts","../src/gestures/taps/utils.ts","../src/gestures/taps/registerTaps.ts","../src/SettingsManager.ts","../src/index.ts"],"sourcesContent":["import type { HookManager, Reader } from \"@prose-reader/core\"\nimport type { PanRecognizer } from \"gesturx\"\nimport { EMPTY, filter, map, merge, of, switchMap } from \"rxjs\"\nimport type { GesturesSettingsManager } from \"../SettingsManager\"\nimport type { Hook } from \"../types\"\n\nexport const registerPan = ({\n reader,\n recognizer,\n settingsManager,\n}: {\n recognizer: PanRecognizer\n reader: Reader\n hookManager: HookManager<Hook>\n settingsManager: GesturesSettingsManager\n}) => {\n const gestures$ = settingsManager.values$.pipe(\n switchMap(({ panNavigation }) => {\n if (panNavigation !== \"pan\") return EMPTY\n\n const panStart$ = recognizer.events$.pipe(\n filter((event) => event.type === `panStart`),\n )\n const panMove$ = recognizer.events$.pipe(\n filter((event) => event.type === `panMove`),\n )\n const panEnd$ = recognizer.events$.pipe(\n filter((event) => event.type === `panEnd`),\n )\n\n const pan$ = panStart$.pipe(\n switchMap((panStartEvent) => {\n const startZoomPosition = reader.zoom.state.currentPosition\n\n const moveAndEnd$ = merge(panMove$, panEnd$).pipe(\n map((event) => {\n const isZooming = reader.zoom.state.isZooming\n const isZoomingIn = reader.zoom.state.currentScale > 1\n\n if (isZooming && isZoomingIn) {\n const x = startZoomPosition.x + Math.floor(event.deltaX)\n const y = startZoomPosition.y + Math.floor(event.deltaY)\n\n reader.zoom.move({\n x,\n y,\n })\n\n return { event, handled: true }\n }\n\n if (event.type === `panMove`) {\n reader.navigation.moveTo({\n x: event.deltaX,\n y: event.deltaY,\n })\n\n return { event, handled: true }\n }\n\n if (event.type === `panEnd`) {\n reader.navigation.moveTo(\n { x: event.deltaX, y: event.deltaY },\n { final: true },\n )\n\n return { event, handled: true }\n }\n\n return { event, handled: false }\n }),\n )\n\n const isZoomingIn = reader.zoom.state.currentScale > 1\n\n if (!isZoomingIn) {\n reader?.navigation.moveTo({ x: 0, y: 0 }, { start: true })\n\n return merge(\n of({ event: panStartEvent, handled: true }),\n moveAndEnd$,\n )\n }\n\n return merge(\n of({ event: panStartEvent, handled: false }),\n moveAndEnd$,\n )\n }),\n )\n\n return pan$\n }),\n )\n\n return gestures$\n}\n","import {\n type HookManager,\n isHtmlElement,\n type Reader,\n} from \"@prose-reader/core\"\nimport type { PinchEvent } from \"gesturx\"\nimport {\n animationFrameScheduler,\n EMPTY,\n filter,\n map,\n merge,\n switchMap,\n takeUntil,\n tap,\n throttleTime,\n withLatestFrom,\n} from \"rxjs\"\nimport type { GesturesSettingsManager } from \"../SettingsManager\"\nimport type { GestureRecognizable, Hook } from \"../types\"\n\nconst isHtmlImageElement = (\n target: EventTarget | null,\n): target is HTMLImageElement =>\n isHtmlElement(target) &&\n !!target.ownerDocument.defaultView &&\n target instanceof target.ownerDocument.defaultView.HTMLImageElement\n\nexport const registerPinch = ({\n reader,\n recognizable,\n settingsManager,\n}: {\n recognizable: GestureRecognizable\n reader: Reader\n hookManager: HookManager<Hook>\n settingsManager: GesturesSettingsManager\n}) => {\n const pinchStart$ = recognizable.events$.pipe(\n map(({ event }) => event),\n filter((event): event is PinchEvent => event.type === \"pinchStart\"),\n )\n\n const pinchMove$ = recognizable.events$.pipe(\n map(({ event }) => event),\n filter((event): event is PinchEvent => event.type === \"pinchMove\"),\n )\n\n const pinchEnd$ = recognizable.events$.pipe(\n map(({ event }) => event),\n filter((event): event is PinchEvent => event.type === \"pinchEnd\"),\n )\n\n const shouldStartZoom = (\n target: EventTarget | null,\n ): target is HTMLImageElement =>\n isHtmlImageElement(target) && !reader.zoom.state.isZooming\n\n return settingsManager.values$.pipe(\n switchMap(({ fontScalePinchEnabled, fontScalePinchThrottleTime }) => {\n const zoomGestures$ = pinchStart$.pipe(\n withLatestFrom(reader.viewportState$),\n switchMap(([event, viewportState]) => {\n const target = event.event.target\n const startScale = reader.zoom.state.currentScale\n\n if (viewportState === \"busy\") return EMPTY\n\n if (shouldStartZoom(target)) {\n reader.zoom.enter({ element: target })\n }\n\n if (!reader.zoom.state.isZooming) return EMPTY\n\n return merge(\n pinchMove$.pipe(\n tap((event) => {\n if (reader.zoom.state.isZooming) {\n const newScale = startScale + (event.scale - 1)\n\n if (newScale < 1) {\n reader.zoom.exit()\n } else {\n reader.zoom.scaleAt(newScale)\n }\n }\n }),\n ),\n )\n }),\n )\n\n const watchForFontScaleChange$ = !fontScalePinchEnabled\n ? EMPTY\n : pinchStart$.pipe(\n withLatestFrom(reader.viewportState$),\n switchMap(([pinchStartEvent, viewportState]) => {\n if (\n viewportState === \"busy\" ||\n shouldStartZoom(pinchStartEvent.event.target) ||\n reader.zoom.state.isZooming\n )\n return EMPTY\n\n const lastFontScaleOnPinchStart = reader.settings.values.fontScale\n\n return pinchMove$.pipe(\n throttleTime(\n fontScalePinchThrottleTime,\n animationFrameScheduler,\n {\n trailing: true,\n },\n ),\n tap((event) => {\n const newScale = Number.parseFloat(\n (lastFontScaleOnPinchStart + (event.scale - 1)).toFixed(2),\n )\n\n const newMinMaxedFontScale = Math.max(\n Math.min(\n newScale,\n settingsManager.values.fontScaleMaxScale,\n ),\n settingsManager.values.fontScaleMinScale,\n )\n\n reader.settings.update({\n fontScale: newMinMaxedFontScale,\n })\n }),\n takeUntil(pinchEnd$),\n )\n }),\n )\n\n return merge(zoomGestures$, watchForFontScaleChange$).pipe(\n map((event) => ({ event, handled: true })),\n )\n }),\n )\n}\n","import type { HookManager, Reader } from \"@prose-reader/core\"\nimport { EMPTY, filter, map, switchMap, tap } from \"rxjs\"\nimport type { GesturesSettingsManager } from \"../SettingsManager\"\nimport type { GestureRecognizable, Hook } from \"../types\"\n\nexport const registerSwipe = ({\n reader,\n recognizable,\n settingsManager,\n}: {\n recognizable: GestureRecognizable\n reader: Reader\n hookManager: HookManager<Hook>\n settingsManager: GesturesSettingsManager\n}) => {\n const gestures$ = settingsManager.values$.pipe(\n switchMap(({ panNavigation }) =>\n panNavigation !== \"swipe\"\n ? EMPTY\n : recognizable.events$.pipe(\n filter(({ event }) => event.type === \"swipe\"),\n tap(({ event }) => {\n const { computedPageTurnDirection } = reader.settings.values\n\n if (computedPageTurnDirection === \"vertical\") {\n if (event.velocityY < -0.5) {\n reader?.navigation.turnRight()\n }\n if (event.velocityY > 0.5) {\n reader?.navigation.turnLeft()\n }\n } else {\n if (event.velocityX < -0.5) {\n reader?.navigation.turnRight()\n }\n if (event.velocityX > 0.5) {\n reader?.navigation.turnLeft()\n }\n }\n }),\n map(({ event }) => ({ event, handled: true })),\n ),\n ),\n )\n\n return gestures$\n}\n","import { isHtmlElement } from \"@prose-reader/core\"\nimport type { GestureEvent } from \"./types\"\n\nexport const isNotLink = (event: GestureEvent[\"event\"]) => {\n const target = event.event.target\n\n if (isHtmlElement(target) && target.tagName === \"a\") return false\n\n return true\n}\n\nexport const getPositionRelativeToContainer = (\n event: { x: number; y: number },\n containerElementRect: DOMRectReadOnly,\n) => {\n const { x, y } = event\n const { left, top } = containerElementRect\n\n return {\n x: x - left,\n y: y - top,\n }\n}\n\nexport const istMatchingSelectors = (\n selectors: string[],\n event: GestureEvent[\"event\"],\n): boolean => {\n const target = event.event.target\n\n if (!isHtmlElement(target)) return false\n\n const match = selectors.find((selector) => {\n // Check if the target matches the selector directly\n if (target.matches(selector)) return true\n\n // Check if the target is within an element matching the selector\n if (target.closest(selector)) return true\n\n return false\n })\n\n return !!match\n}\n","import type { TapArea } from \"./types\"\n\nexport const isPositionInArea = (\n position: { x: number; y: number },\n area: TapArea,\n containerSize: { width: number; height: number },\n): boolean => {\n const { x, y } = position\n const { width, height } = containerSize\n\n switch (area.type) {\n case \"margins\": {\n const { top, bottom, left, right } = area\n const inTop = top !== undefined ? y < height * top : true\n const inBottom = bottom !== undefined ? y > height * (1 - bottom) : true\n const inLeft = left !== undefined ? x < width * left : true\n const inRight = right !== undefined ? x > width * (1 - right) : true\n\n return (\n (top !== undefined && inTop) ||\n (bottom !== undefined && inBottom) ||\n (left !== undefined && inLeft) ||\n (right !== undefined && inRight)\n )\n }\n\n case \"rectangle\": {\n const {\n x: rectX,\n y: rectY,\n width: rectWidth,\n height: rectHeight,\n unit = \"%\",\n } = area\n const actualX = unit === \"%\" ? width * (rectX / 100) : rectX\n const actualY = unit === \"%\" ? height * (rectY / 100) : rectY\n const actualWidth = unit === \"%\" ? width * (rectWidth / 100) : rectWidth\n const actualHeight =\n unit === \"%\" ? height * (rectHeight / 100) : rectHeight\n\n return (\n x >= actualX &&\n x <= actualX + actualWidth &&\n y >= actualY &&\n y <= actualY + actualHeight\n )\n }\n\n case \"corner\": {\n const { corner, size, unit = \"%\" } = area\n const actualSize =\n unit === \"%\" ? Math.min(width, height) * (size / 100) : size\n\n switch (corner) {\n case \"top-left\":\n return x < actualSize && y < actualSize\n case \"top-right\":\n return x > width - actualSize && y < actualSize\n case \"bottom-left\":\n return x < actualSize && y > height - actualSize\n case \"bottom-right\":\n return x > width - actualSize && y > height - actualSize\n default:\n return false\n }\n }\n\n case \"center\": {\n const { width: centerWidth, height: centerHeight, unit = \"%\" } = area\n const actualWidth =\n unit === \"%\" ? width * (centerWidth / 100) : centerWidth\n const actualHeight =\n unit === \"%\" ? height * (centerHeight / 100) : centerHeight\n const centerX = width / 2\n const centerY = height / 2\n\n return (\n x >= centerX - actualWidth / 2 &&\n x <= centerX + actualWidth / 2 &&\n y >= centerY - actualHeight / 2 &&\n y <= centerY + actualHeight / 2\n )\n }\n\n default:\n return false\n }\n}\n\nexport const calculatePageTurnLinearMargin = (screenWidth: number): number => {\n const minMargin = 0.15\n const maxMargin = 0.2\n const minWidth = 320\n const maxWidth = 1200\n\n if (screenWidth <= minWidth) return maxMargin\n if (screenWidth >= maxWidth) return minMargin\n\n // Linear interpolation between min and max\n const ratio = (screenWidth - minWidth) / (maxWidth - minWidth)\n return maxMargin - ratio * (maxMargin - minMargin)\n}\n","import type { HookManager, Reader } from \"@prose-reader/core\"\nimport type { TapRecognizer } from \"gesturx\"\nimport {\n combineLatest,\n EMPTY,\n filter,\n first,\n map,\n of,\n switchMap,\n withLatestFrom,\n} from \"rxjs\"\nimport type { GesturesSettingsManager } from \"../../SettingsManager\"\nimport type { GestureRecognizable, Hook } from \"../../types\"\nimport {\n getPositionRelativeToContainer,\n isNotLink,\n istMatchingSelectors,\n} from \"../../utils\"\nimport { calculatePageTurnLinearMargin, isPositionInArea } from \"./utils\"\n\nexport const registerTaps = ({\n reader,\n recognizable,\n hookManager,\n settingsManager,\n recognizer,\n}: {\n recognizable: GestureRecognizable\n reader: Reader\n hookManager: HookManager<Hook>\n recognizer: TapRecognizer\n settingsManager: GesturesSettingsManager\n}) => {\n const gestures$ = recognizable.events$.pipe(\n filter((event) => event.recognizer === recognizer),\n withLatestFrom(reader.context.watch(`rootElement`), reader.spine.element$),\n switchMap(([{ event }, containerElement, spineElement]) => {\n if (!containerElement || !spineElement) return EMPTY\n\n const normalizedEvent = event.event\n const { computedPageTurnDirection, computedPageTurnMode } =\n reader.settings.values\n\n if (\n event.type === \"tap\" &&\n isNotLink(event) &&\n !istMatchingSelectors(settingsManager.values.ignore, event)\n ) {\n if (`x` in normalizedEvent) {\n const containerElementRect = containerElement.getBoundingClientRect()\n const width = containerElementRect.width\n const pageTurnMargin = calculatePageTurnLinearMargin(width)\n const positionInContainer = getPositionRelativeToContainer(\n normalizedEvent,\n containerElementRect,\n )\n\n const positionInSpineNonTransformed =\n reader.coordinates.getSpinePositionFromClientPosition(\n normalizedEvent,\n )\n\n const spineItemPageInfo = positionInSpineNonTransformed\n ? reader.spine.locator.getSpineItemPagePositionFromSpinePosition(\n positionInSpineNonTransformed,\n )\n : undefined\n\n const beforeTapResults$ = hookManager.execute(\n \"beforeTapGesture\",\n undefined,\n { event$: of({ event, page: spineItemPageInfo }) },\n )\n\n return combineLatest([...beforeTapResults$, of(true)]).pipe(\n first(),\n filter((results) => !results.some((result) => result === false)),\n map(() => {\n if (computedPageTurnMode === \"scrollable\") {\n return { event, handled: false }\n }\n\n if (\n computedPageTurnDirection === \"horizontal\" &&\n isPositionInArea(\n positionInContainer,\n { type: \"margins\", left: pageTurnMargin },\n containerElementRect,\n )\n ) {\n reader.navigation.turnLeftOrTop()\n } else if (\n computedPageTurnDirection === \"vertical\" &&\n isPositionInArea(\n positionInContainer,\n { type: \"margins\", top: pageTurnMargin },\n containerElementRect,\n )\n ) {\n reader.navigation.turnLeftOrTop()\n } else if (\n computedPageTurnDirection === \"vertical\" &&\n isPositionInArea(\n positionInContainer,\n { type: \"margins\", bottom: pageTurnMargin },\n containerElementRect,\n )\n ) {\n reader.navigation.turnRightOrBottom()\n } else if (\n computedPageTurnDirection === \"horizontal\" &&\n isPositionInArea(\n positionInContainer,\n { type: \"margins\", right: pageTurnMargin },\n containerElementRect,\n )\n ) {\n reader.navigation.turnRightOrBottom()\n } else {\n return { event, handled: false }\n }\n\n return { event, handled: true }\n }),\n )\n }\n }\n\n return EMPTY\n }),\n )\n\n return gestures$\n}\n","import { type Reader, SettingsManager } from \"@prose-reader/core\"\nimport type { InputSettings, OutputSettings } from \"./types\"\nimport { takeUntil, tap } from \"rxjs\"\n\nexport class GesturesSettingsManager extends SettingsManager<\n InputSettings,\n OutputSettings\n> {\n constructor(\n initialSettings: Partial<InputSettings>,\n private reader: Reader,\n ) {\n super(initialSettings)\n\n /**\n * Since we have settings that may be locked due to some reader settings\n * we need to update as soon as they update as well.\n */\n reader.settings.values$\n .pipe(\n tap(() => {\n this.update({})\n }),\n takeUntil(this.destroy$),\n )\n .subscribe()\n }\n\n getOutputSettings(inputSettings: InputSettings): OutputSettings {\n return {\n ...inputSettings,\n panNavigation:\n this.reader.settings.values.computedPageTurnMode === `scrollable`\n ? false\n : inputSettings.panNavigation,\n }\n }\n\n getDefaultSettings(): InputSettings {\n return {\n panNavigation: \"pan\",\n pinchCancelPan: true,\n fontScalePinchEnabled: true,\n fontScalePinchThrottleTime: 500,\n fontScaleMaxScale: 5,\n fontScaleMinScale: 0.2,\n ignore: [],\n }\n }\n}\n","import { HookManager, type Reader } from \"@prose-reader/core\"\nimport {\n PanRecognizer,\n PinchRecognizer,\n Recognizable,\n SwipeRecognizer,\n TapRecognizer,\n} from \"gesturx\"\nimport { combineLatest, merge, share, takeUntil, tap } from \"rxjs\"\nimport { registerPan } from \"./gestures/pan\"\nimport { registerPinch } from \"./gestures/pinch\"\nimport { registerSwipe } from \"./gestures/swipe\"\nimport { registerTaps } from \"./gestures/taps/registerTaps\"\nimport { GesturesSettingsManager } from \"./SettingsManager\"\nimport type { EnhancerAPI, Hook, InputSettings } from \"./types\"\n\nexport { isPositionInArea } from \"./gestures/taps/utils\"\nexport * from \"./types\"\n\nexport const gesturesEnhancer =\n <InheritOptions, InheritOutput extends Reader>(\n next: (options: InheritOptions) => InheritOutput,\n ) =>\n (\n options: InheritOptions & {\n gestures?: Partial<InputSettings>\n },\n ): InheritOutput & EnhancerAPI => {\n const { gestures = {}, ...rest } = options\n const reader = next(rest as InheritOptions)\n\n const settingsManager = new GesturesSettingsManager(gestures, reader)\n\n const hookManager = new HookManager<Hook>()\n\n const pinchRecognizer = new PinchRecognizer({\n options: {\n /**\n * @important\n * To be less than pan otherwise it will not fail before it starts\n */\n posThreshold: 20,\n },\n })\n\n const failWithSelection = {\n start$: reader.selection.selectionStart$,\n end$: reader.selection.selectionEnd$,\n }\n\n const panRecognizer = new PanRecognizer({\n failWith: [pinchRecognizer, failWithSelection],\n options: {\n // we want to have some margin to trigger zoom\n posThreshold: 15,\n },\n })\n\n const tapRecognizer = new TapRecognizer({\n failWith: [panRecognizer],\n })\n\n const swipeRecognizer = new SwipeRecognizer({\n failWith: [failWithSelection],\n })\n\n const recognizable = new Recognizable({\n recognizers: [\n tapRecognizer,\n panRecognizer,\n swipeRecognizer,\n pinchRecognizer,\n ],\n disableTextSelection: false,\n })\n\n const tapGestures$ = registerTaps({\n hookManager,\n reader,\n recognizable,\n settingsManager,\n recognizer: tapRecognizer,\n })\n\n const panGestures$ = registerPan({\n hookManager,\n reader,\n recognizer: panRecognizer,\n settingsManager,\n })\n\n const swipeGestures$ = registerSwipe({\n hookManager,\n reader,\n recognizable,\n settingsManager,\n })\n\n const pinchGestures$ = registerPinch({\n hookManager,\n reader,\n recognizable,\n settingsManager,\n })\n\n const containerUpdate$ = reader.context.watch(`rootElement`).pipe(\n tap((container) => {\n recognizable.update({\n container,\n })\n }),\n )\n\n const watchSettings$ = combineLatest([\n settingsManager.values$,\n panRecognizer.config$,\n ]).pipe(\n tap(([{ pinchCancelPan }, panRecognizerConfig]) => {\n const pinchAlreadyInFailWith =\n panRecognizerConfig.failWith?.includes(pinchRecognizer)\n\n if (pinchCancelPan && !pinchAlreadyInFailWith) {\n panRecognizer.update({\n failWith: [\n ...(panRecognizerConfig.failWith ?? []),\n pinchRecognizer,\n ],\n })\n }\n\n if (!pinchCancelPan && pinchAlreadyInFailWith) {\n panRecognizer.update({\n failWith: panRecognizerConfig.failWith?.filter(\n (recognizer) => recognizer !== pinchRecognizer,\n ),\n })\n }\n }),\n )\n\n const gestures$ = merge(\n pinchGestures$,\n tapGestures$,\n swipeGestures$,\n panGestures$,\n ).pipe(share())\n\n merge(containerUpdate$, watchSettings$, gestures$)\n .pipe(takeUntil(reader.$.destroy$))\n .subscribe()\n\n return {\n ...reader,\n destroy: () => {\n reader.destroy()\n settingsManager.destroy()\n },\n gestures: {\n settings: settingsManager,\n gestures$,\n hooks: hookManager,\n },\n }\n }\n"],"names":["switchMap","EMPTY","filter","merge","map","isZoomingIn","of","isHtmlElement","withLatestFrom","tap","event","throttleTime","animationFrameScheduler","takeUntil","combineLatest","first","SettingsManager","HookManager","PinchRecognizer","PanRecognizer","TapRecognizer","SwipeRecognizer","Recognizable","share"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.umd.cjs","sources":["../src/gestures/pan.ts","../src/gestures/pinch.ts","../src/gestures/swipe.ts","../src/utils.ts","../src/gestures/taps/utils.ts","../src/gestures/taps/registerTaps.ts","../src/SettingsManager.ts","../src/index.ts"],"sourcesContent":["import type { HookManager, Reader } from \"@prose-reader/core\"\nimport type { PanRecognizer } from \"gesturx\"\nimport { EMPTY, filter, map, merge, of, switchMap } from \"rxjs\"\nimport type { GesturesSettingsManager } from \"../SettingsManager\"\nimport type { Hook } from \"../types\"\n\nexport const registerPan = ({\n reader,\n recognizer,\n settingsManager,\n}: {\n recognizer: PanRecognizer\n reader: Reader\n hookManager: HookManager<Hook>\n settingsManager: GesturesSettingsManager\n}) => {\n const gestures$ = settingsManager.values$.pipe(\n switchMap(({ panNavigation }) => {\n if (panNavigation !== \"pan\") return EMPTY\n\n const panStart$ = recognizer.events$.pipe(\n filter((event) => event.type === `panStart`),\n )\n const panMove$ = recognizer.events$.pipe(\n filter((event) => event.type === `panMove`),\n )\n const panEnd$ = recognizer.events$.pipe(\n filter((event) => event.type === `panEnd`),\n )\n\n const pan$ = panStart$.pipe(\n switchMap((panStartEvent) => {\n /**\n * We use the last cumulative delta to derive the new event atomic delta.\n * This is because panning the zoom does not necessarily means the zoom position\n * will always changes. If the user keep dragging while the zoom is blocked, we want\n * it to move the other direction when he start dragging the other way.\n * We cannot use the `reader.zoom.state.currentPosition` as previous position\n * and the event.deltaX to compute the new zoom position.\n */\n let lastDelta = { x: 0, y: 0 }\n\n const moveAndEnd$ = merge(panMove$, panEnd$).pipe(\n map((event) => {\n const isZooming = reader.zoom.state.isZooming\n const isZoomingIn = reader.zoom.state.currentScale > 1\n\n /**\n * When user is zooming in, we don't navigate anymore.\n * The gestures is gonna be handled by the pinch and viewport.\n */\n if (isZooming && isZoomingIn) {\n const deltaX = event.deltaX - lastDelta.x\n const deltaY = event.deltaY - lastDelta.y\n\n lastDelta = {\n x: event.deltaX,\n y: event.deltaY,\n }\n\n reader.zoom.move(\n {\n x: reader.zoom.state.currentPosition.x + deltaX,\n y: reader.zoom.state.currentPosition.y + deltaY,\n },\n {\n constrain: \"within-viewport\",\n },\n )\n\n return event\n }\n\n if (event.type === `panMove`) {\n if (!reader.navigation.panNavigator.value.isStarted) {\n reader.navigation.panNavigator.start({\n x: event.deltaX,\n y: event.deltaY,\n })\n\n return event\n }\n\n reader.navigation.panNavigator.panMoveTo({\n x: event.deltaX,\n y: event.deltaY,\n })\n\n return event\n }\n\n if (\n event.type === `panEnd` &&\n reader.navigation.panNavigator.value.isStarted\n ) {\n reader.navigation.panNavigator.stop({\n x: event.deltaX,\n y: event.deltaY,\n })\n\n return event\n }\n\n return event\n }),\n )\n\n return merge(of(panStartEvent), moveAndEnd$).pipe(\n map((event) => ({ type: \"pan\" as const, gestureEvent: event })),\n )\n }),\n )\n\n return pan$\n }),\n )\n\n return gestures$\n}\n","import {\n type HookManager,\n isHtmlElement,\n type Reader,\n} from \"@prose-reader/core\"\nimport type { PinchEvent } from \"gesturx\"\nimport {\n animationFrameScheduler,\n EMPTY,\n filter,\n map,\n merge,\n switchMap,\n takeUntil,\n tap,\n throttleTime,\n withLatestFrom,\n} from \"rxjs\"\nimport type { GesturesSettingsManager } from \"../SettingsManager\"\nimport type { GestureRecognizable, Hook } from \"../types\"\n\nconst isHtmlImageElement = (\n target: EventTarget | null,\n): target is HTMLImageElement =>\n isHtmlElement(target) &&\n !!target.ownerDocument.defaultView &&\n target instanceof target.ownerDocument.defaultView.HTMLImageElement\n\nexport const registerPinch = ({\n reader,\n recognizable,\n settingsManager,\n}: {\n recognizable: GestureRecognizable\n reader: Reader\n hookManager: HookManager<Hook>\n settingsManager: GesturesSettingsManager\n}) => {\n const pinchStart$ = recognizable.events$.pipe(\n map(({ event }) => event),\n filter((event): event is PinchEvent => event.type === \"pinchStart\"),\n )\n\n const pinchMove$ = recognizable.events$.pipe(\n map(({ event }) => event),\n filter((event): event is PinchEvent => event.type === \"pinchMove\"),\n )\n\n const pinchEnd$ = recognizable.events$.pipe(\n map(({ event }) => event),\n filter((event): event is PinchEvent => event.type === \"pinchEnd\"),\n )\n\n const shouldStartZoom = (\n target: EventTarget | null,\n ): target is HTMLImageElement =>\n isHtmlImageElement(target) && !reader.zoom.state.isZooming\n\n return settingsManager.values$.pipe(\n switchMap(({ fontScalePinchEnabled, fontScalePinchThrottleTime }) => {\n const zoomGestures$ = pinchStart$.pipe(\n switchMap(() => {\n const startScale = reader.zoom.state.currentScale\n\n return pinchMove$.pipe(\n withLatestFrom(reader.viewportState$),\n map(([event, viewportState]) => {\n // symmetric scaling calculation\n const newScale = startScale * event.scale\n\n /**\n * @important\n * We don't want to trigger zoom gestures if there is a pan navigation\n * in progress. This can happens if the user start panning and then adds\n * another finger triggering a pinch.\n */\n if (viewportState === \"busy\") {\n return event\n }\n\n if (!reader.zoom.state.isZooming && event.scale > 1) {\n reader.zoom.enter({ animate: false, scale: newScale })\n\n return event\n }\n\n if (reader.zoom.state.isZooming) {\n if (newScale < 1) {\n reader.zoom.exit()\n } else {\n reader.zoom.scaleAt(\n Math.min(newScale, settingsManager.values.zoomMaxScale),\n {\n constrain: \"within-viewport\",\n },\n )\n }\n\n return event\n }\n\n return event\n }),\n )\n }),\n )\n\n const watchForFontScaleChange$ = !fontScalePinchEnabled\n ? EMPTY\n : pinchStart$.pipe(\n withLatestFrom(reader.viewportState$),\n switchMap(([pinchStartEvent, viewportState]) => {\n if (\n viewportState === \"busy\" ||\n shouldStartZoom(pinchStartEvent.event.target) ||\n reader.zoom.state.isZooming\n )\n return EMPTY\n\n const lastFontScaleOnPinchStart = reader.settings.values.fontScale\n\n return pinchMove$.pipe(\n throttleTime(\n fontScalePinchThrottleTime,\n animationFrameScheduler,\n {\n trailing: true,\n },\n ),\n tap((event) => {\n const newScale = Number.parseFloat(\n (lastFontScaleOnPinchStart + (event.scale - 1)).toFixed(2),\n )\n\n const newMinMaxedFontScale = Math.max(\n Math.min(\n newScale,\n settingsManager.values.fontScaleMaxScale,\n ),\n settingsManager.values.fontScaleMinScale,\n )\n\n reader.settings.update({\n fontScale: newMinMaxedFontScale,\n })\n }),\n takeUntil(pinchEnd$),\n )\n }),\n )\n\n return merge(zoomGestures$, watchForFontScaleChange$).pipe(\n map((event) => ({\n type: \"pinch\" as const,\n gestureEvent: event,\n })),\n )\n }),\n )\n}\n","import type { HookManager, Reader } from \"@prose-reader/core\"\nimport type { SwipeEvent } from \"gesturx\"\nimport { EMPTY, filter, map, switchMap, tap } from \"rxjs\"\nimport type { GesturesSettingsManager } from \"../SettingsManager\"\nimport type { GestureEvent, GestureRecognizable, Hook } from \"../types\"\n\nconst isSwipeEvent = (event: GestureEvent[\"event\"]): event is SwipeEvent =>\n event.type === \"swipe\"\n\nexport const registerSwipe = ({\n reader,\n recognizable,\n settingsManager,\n}: {\n recognizable: GestureRecognizable\n reader: Reader\n hookManager: HookManager<Hook>\n settingsManager: GesturesSettingsManager\n}) => {\n const gestures$ = settingsManager.values$.pipe(\n switchMap(({ panNavigation }) =>\n panNavigation !== \"swipe\"\n ? EMPTY\n : recognizable.events$.pipe(\n map(({ event }) => event),\n filter(isSwipeEvent),\n tap((event) => {\n const { computedPageTurnDirection } = reader.settings.values\n\n if (computedPageTurnDirection === \"vertical\") {\n if (event.velocityY < -0.5) {\n reader?.navigation.turnRight()\n }\n if (event.velocityY > 0.5) {\n reader?.navigation.turnLeft()\n }\n } else {\n if (event.velocityX < -0.5) {\n reader?.navigation.turnRight()\n }\n if (event.velocityX > 0.5) {\n reader?.navigation.turnLeft()\n }\n }\n }),\n map((event) => ({ type: \"swipe\" as const, gestureEvent: event })),\n ),\n ),\n )\n\n return gestures$\n}\n","import { isHtmlElement } from \"@prose-reader/core\"\nimport type { GestureEvent } from \"./types\"\n\nexport const isNotLink = (event: GestureEvent[\"event\"]) => {\n const target = event.event.target\n\n if (isHtmlElement(target) && target.tagName === \"a\") return false\n\n return true\n}\n\nexport const getPositionRelativeToContainer = (\n event: { x: number; y: number },\n containerElementRect: DOMRectReadOnly,\n) => {\n const { x, y } = event\n const { left, top } = containerElementRect\n\n return {\n x: x - left,\n y: y - top,\n }\n}\n\nexport const istMatchingSelectors = (\n selectors: string[],\n event: GestureEvent[\"event\"],\n): boolean => {\n const target = event.event.target\n\n if (!isHtmlElement(target)) return false\n\n const match = selectors.find((selector) => {\n // Check if the target matches the selector directly\n if (target.matches(selector)) return true\n\n // Check if the target is within an element matching the selector\n if (target.closest(selector)) return true\n\n return false\n })\n\n return !!match\n}\n","import type { TapArea } from \"./types\"\n\nexport const isPositionInArea = (\n position: { x: number; y: number },\n area: TapArea,\n containerSize: { width: number; height: number },\n): boolean => {\n const { x, y } = position\n const { width, height } = containerSize\n\n switch (area.type) {\n case \"margins\": {\n const { top, bottom, left, right } = area\n const inTop = top !== undefined ? y < height * top : true\n const inBottom = bottom !== undefined ? y > height * (1 - bottom) : true\n const inLeft = left !== undefined ? x < width * left : true\n const inRight = right !== undefined ? x > width * (1 - right) : true\n\n return (\n (top !== undefined && inTop) ||\n (bottom !== undefined && inBottom) ||\n (left !== undefined && inLeft) ||\n (right !== undefined && inRight)\n )\n }\n\n case \"rectangle\": {\n const {\n x: rectX,\n y: rectY,\n width: rectWidth,\n height: rectHeight,\n unit = \"%\",\n } = area\n const actualX = unit === \"%\" ? width * (rectX / 100) : rectX\n const actualY = unit === \"%\" ? height * (rectY / 100) : rectY\n const actualWidth = unit === \"%\" ? width * (rectWidth / 100) : rectWidth\n const actualHeight =\n unit === \"%\" ? height * (rectHeight / 100) : rectHeight\n\n return (\n x >= actualX &&\n x <= actualX + actualWidth &&\n y >= actualY &&\n y <= actualY + actualHeight\n )\n }\n\n case \"corner\": {\n const { corner, size, unit = \"%\" } = area\n const actualSize =\n unit === \"%\" ? Math.min(width, height) * (size / 100) : size\n\n switch (corner) {\n case \"top-left\":\n return x < actualSize && y < actualSize\n case \"top-right\":\n return x > width - actualSize && y < actualSize\n case \"bottom-left\":\n return x < actualSize && y > height - actualSize\n case \"bottom-right\":\n return x > width - actualSize && y > height - actualSize\n default:\n return false\n }\n }\n\n case \"center\": {\n const { width: centerWidth, height: centerHeight, unit = \"%\" } = area\n const actualWidth =\n unit === \"%\" ? width * (centerWidth / 100) : centerWidth\n const actualHeight =\n unit === \"%\" ? height * (centerHeight / 100) : centerHeight\n const centerX = width / 2\n const centerY = height / 2\n\n return (\n x >= centerX - actualWidth / 2 &&\n x <= centerX + actualWidth / 2 &&\n y >= centerY - actualHeight / 2 &&\n y <= centerY + actualHeight / 2\n )\n }\n\n default:\n return false\n }\n}\n\nexport const calculatePageTurnLinearMargin = (screenWidth: number): number => {\n const minMargin = 0.15\n const maxMargin = 0.2\n const minWidth = 320\n const maxWidth = 1200\n\n if (screenWidth <= minWidth) return maxMargin\n if (screenWidth >= maxWidth) return minMargin\n\n // Linear interpolation between min and max\n const ratio = (screenWidth - minWidth) / (maxWidth - minWidth)\n return maxMargin - ratio * (maxMargin - minMargin)\n}\n","import type { HookManager, Reader } from \"@prose-reader/core\"\nimport type { TapRecognizer } from \"gesturx\"\nimport {\n combineLatest,\n EMPTY,\n filter,\n first,\n map,\n of,\n switchMap,\n withLatestFrom,\n} from \"rxjs\"\nimport type { GesturesSettingsManager } from \"../../SettingsManager\"\nimport type { GestureRecognizable, Hook } from \"../../types\"\nimport {\n getPositionRelativeToContainer,\n isNotLink,\n istMatchingSelectors,\n} from \"../../utils\"\nimport { calculatePageTurnLinearMargin, isPositionInArea } from \"./utils\"\n\nexport const registerTaps = ({\n reader,\n recognizable,\n hookManager,\n settingsManager,\n recognizer,\n}: {\n recognizable: GestureRecognizable\n reader: Reader\n hookManager: HookManager<Hook>\n recognizer: TapRecognizer\n settingsManager: GesturesSettingsManager\n}) => {\n const gestures$ = recognizable.events$.pipe(\n filter((event) => event.recognizer === recognizer),\n withLatestFrom(reader.context.watch(`rootElement`), reader.spine.element$),\n switchMap(([{ event }, containerElement, spineElement]) => {\n if (!containerElement || !spineElement) return EMPTY\n\n const normalizedEvent = event.event\n const { computedPageTurnDirection, computedPageTurnMode } =\n reader.settings.values\n\n if (\n event.type === \"tap\" &&\n isNotLink(event) &&\n !istMatchingSelectors(settingsManager.values.ignore, event)\n ) {\n if (`x` in normalizedEvent) {\n const containerElementRect = containerElement.getBoundingClientRect()\n const width = containerElementRect.width\n const pageTurnMargin = calculatePageTurnLinearMargin(width)\n const positionInContainer = getPositionRelativeToContainer(\n normalizedEvent,\n containerElementRect,\n )\n\n const positionInSpineNonTransformed =\n reader.coordinates.getSpinePositionFromClientPosition(\n normalizedEvent,\n )\n\n const spineItemPageInfo = positionInSpineNonTransformed\n ? reader.spine.locator.getSpineItemPagePositionFromSpinePosition(\n positionInSpineNonTransformed,\n )\n : undefined\n\n const beforeTapResults$ = hookManager.execute(\n \"beforeTapGesture\",\n undefined,\n { event$: of({ event, page: spineItemPageInfo }) },\n )\n\n return combineLatest([...beforeTapResults$, of(true)]).pipe(\n first(),\n filter((results) => !results.some((result) => result === false)),\n map(() => {\n if (\n computedPageTurnMode === \"scrollable\" ||\n /**\n * We don't want to navigate from gestures when the user is zooming.\n */\n reader.zoom.state.isZooming\n ) {\n return {\n type: \"tap\" as const,\n gestureEvent: event,\n handled: false,\n }\n }\n\n if (\n computedPageTurnDirection === \"horizontal\" &&\n isPositionInArea(\n positionInContainer,\n { type: \"margins\", left: pageTurnMargin },\n containerElementRect,\n )\n ) {\n reader.navigation.turnLeftOrTop()\n } else if (\n computedPageTurnDirection === \"vertical\" &&\n isPositionInArea(\n positionInContainer,\n { type: \"margins\", top: pageTurnMargin },\n containerElementRect,\n )\n ) {\n reader.navigation.turnLeftOrTop()\n } else if (\n computedPageTurnDirection === \"vertical\" &&\n isPositionInArea(\n positionInContainer,\n { type: \"margins\", bottom: pageTurnMargin },\n containerElementRect,\n )\n ) {\n reader.navigation.turnRightOrBottom()\n } else if (\n computedPageTurnDirection === \"horizontal\" &&\n isPositionInArea(\n positionInContainer,\n { type: \"margins\", right: pageTurnMargin },\n containerElementRect,\n )\n ) {\n reader.navigation.turnRightOrBottom()\n } else {\n return {\n type: \"tap\" as const,\n gestureEvent: event,\n handled: false,\n }\n }\n\n return {\n type: \"tap\" as const,\n gestureEvent: event,\n handled: true,\n }\n }),\n )\n }\n }\n\n return EMPTY\n }),\n )\n\n return gestures$\n}\n","import { type Reader, SettingsManager } from \"@prose-reader/core\"\nimport { takeUntil, tap } from \"rxjs\"\nimport type { InputSettings, OutputSettings } from \"./types\"\n\nexport class GesturesSettingsManager extends SettingsManager<\n InputSettings,\n OutputSettings\n> {\n constructor(\n initialSettings: Partial<InputSettings>,\n private reader: Reader,\n ) {\n super(initialSettings)\n\n /**\n * Since we have settings that may be locked due to some reader settings\n * we need to update as soon as they update as well.\n */\n reader.settings.values$\n .pipe(\n tap(() => {\n this.update({})\n }),\n takeUntil(this.destroy$),\n )\n .subscribe()\n }\n\n getOutputSettings(inputSettings: InputSettings): OutputSettings {\n return {\n ...inputSettings,\n panNavigation:\n this.reader.settings.values.computedPageTurnMode === `scrollable`\n ? false\n : inputSettings.panNavigation,\n }\n }\n\n getDefaultSettings(): InputSettings {\n return {\n panNavigation: \"pan\",\n pinchCancelPan: true,\n fontScalePinchEnabled: true,\n fontScalePinchThrottleTime: 500,\n fontScaleMaxScale: 5,\n fontScaleMinScale: 0.2,\n zoomMaxScale: Infinity,\n ignore: [],\n }\n }\n}\n","import { HookManager, type Reader } from \"@prose-reader/core\"\nimport {\n PanRecognizer,\n PinchRecognizer,\n Recognizable,\n SwipeRecognizer,\n TapRecognizer,\n} from \"gesturx\"\nimport { combineLatest, merge, share, takeUntil, tap } from \"rxjs\"\nimport { name as packageName } from \"../package.json\"\nimport { registerPan } from \"./gestures/pan\"\nimport { registerPinch } from \"./gestures/pinch\"\nimport { registerSwipe } from \"./gestures/swipe\"\nimport { registerTaps } from \"./gestures/taps/registerTaps\"\nimport { GesturesSettingsManager } from \"./SettingsManager\"\nimport styles from \"./style.css?inline\"\nimport type { EnhancerAPI, Hook, InputSettings } from \"./types\"\n\nexport { isPositionInArea } from \"./gestures/taps/utils\"\nexport * from \"./types\"\n\nexport const gesturesEnhancer =\n <InheritOptions, InheritOutput extends Reader>(\n next: (options: InheritOptions) => InheritOutput,\n ) =>\n (\n options: InheritOptions & {\n gestures?: Partial<InputSettings>\n },\n ): InheritOutput & EnhancerAPI => {\n const { gestures = {}, ...rest } = options\n const reader = next(rest as InheritOptions)\n\n const removeStylesheet = reader.utils.injectScopedCSS(\n document,\n packageName,\n styles,\n )\n\n const settingsManager = new GesturesSettingsManager(gestures, reader)\n\n const hookManager = new HookManager<Hook>()\n\n const pinchRecognizer = new PinchRecognizer({\n options: {\n /**\n * @important\n * Ideally we want pinch to triggers before pan so we can\n * capture zoom before starting panning.\n */\n posThreshold: 10,\n },\n })\n\n const failWithSelection = {\n start$: reader.selection.selectionStart$,\n end$: reader.selection.selectionEnd$,\n }\n\n const panRecognizer = new PanRecognizer({\n failWith: [pinchRecognizer, failWithSelection],\n options: {\n // we want to have some margin to trigger zoom\n posThreshold: 20,\n },\n })\n\n const tapRecognizer = new TapRecognizer({\n failWith: [panRecognizer],\n })\n\n const swipeRecognizer = new SwipeRecognizer({\n failWith: [failWithSelection],\n })\n\n const recognizable = new Recognizable({\n recognizers: [\n tapRecognizer,\n panRecognizer,\n swipeRecognizer,\n pinchRecognizer,\n ],\n disableTextSelection: false,\n })\n\n const tapGestures$ = registerTaps({\n hookManager,\n reader,\n recognizable,\n settingsManager,\n recognizer: tapRecognizer,\n })\n\n const panGestures$ = registerPan({\n hookManager,\n reader,\n recognizer: panRecognizer,\n settingsManager,\n })\n\n const swipeGestures$ = registerSwipe({\n hookManager,\n reader,\n recognizable,\n settingsManager,\n })\n\n const pinchGestures$ = registerPinch({\n hookManager,\n reader,\n recognizable,\n settingsManager,\n })\n\n const containerUpdate$ = reader.context.watch(`rootElement`).pipe(\n tap((container) => {\n recognizable.update({\n container,\n })\n }),\n )\n\n const watchSettings$ = combineLatest([\n settingsManager.values$,\n panRecognizer.config$,\n ]).pipe(\n tap(([{ pinchCancelPan }, panRecognizerConfig]) => {\n const pinchAlreadyInFailWith =\n panRecognizerConfig.failWith?.includes(pinchRecognizer)\n\n if (pinchCancelPan && !pinchAlreadyInFailWith) {\n panRecognizer.update({\n failWith: [\n ...(panRecognizerConfig.failWith ?? []),\n pinchRecognizer,\n ],\n })\n }\n\n if (!pinchCancelPan && pinchAlreadyInFailWith) {\n panRecognizer.update({\n failWith: panRecognizerConfig.failWith?.filter(\n (recognizer) => recognizer !== pinchRecognizer,\n ),\n })\n }\n }),\n )\n\n const gestures$ = merge(\n pinchGestures$,\n tapGestures$,\n swipeGestures$,\n panGestures$,\n ).pipe(share())\n\n merge(containerUpdate$, watchSettings$, gestures$)\n .pipe(takeUntil(reader.$.destroy$))\n .subscribe()\n\n return {\n ...reader,\n destroy: () => {\n removeStylesheet()\n reader.destroy()\n settingsManager.destroy()\n },\n gestures: {\n settings: settingsManager,\n gestures$,\n hooks: hookManager,\n },\n }\n }\n"],"names":["switchMap","EMPTY","filter","merge","map","of","isHtmlElement","withLatestFrom","throttleTime","animationFrameScheduler","tap","takeUntil","combineLatest","first","SettingsManager","packageName","HookManager","PinchRecognizer","PanRecognizer","TapRecognizer","SwipeRecognizer","Recognizable","share"],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export type InputSettings = {
|
|
|
18
18
|
fontScalePinchEnabled: boolean;
|
|
19
19
|
fontScaleMaxScale: number;
|
|
20
20
|
fontScaleMinScale: number;
|
|
21
|
+
zoomMaxScale: number;
|
|
21
22
|
fontScalePinchThrottleTime: number;
|
|
22
23
|
pinchCancelPan: boolean;
|
|
23
24
|
ignore: string[];
|
|
@@ -28,8 +29,18 @@ export type EnhancerAPI = {
|
|
|
28
29
|
settings: GesturesSettingsManager;
|
|
29
30
|
hooks: HookManager<Hook>;
|
|
30
31
|
gestures$: Observable<{
|
|
31
|
-
|
|
32
|
+
type: "tap";
|
|
33
|
+
gestureEvent: TapEvent;
|
|
32
34
|
handled: boolean;
|
|
35
|
+
} | {
|
|
36
|
+
type: "pan";
|
|
37
|
+
gestureEvent: PanEvent;
|
|
38
|
+
} | {
|
|
39
|
+
type: "swipe";
|
|
40
|
+
gestureEvent: SwipeEvent;
|
|
41
|
+
} | {
|
|
42
|
+
type: "pinch";
|
|
43
|
+
gestureEvent: PinchEvent;
|
|
33
44
|
}>;
|
|
34
45
|
};
|
|
35
46
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prose-reader/enhancer-gestures",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.263.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"test": "vitest run --coverage"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@prose-reader/core": "^1.
|
|
28
|
+
"@prose-reader/core": "^1.263.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"gesturx": "*",
|
|
@@ -35,5 +35,5 @@
|
|
|
35
35
|
"gesturx": "1.x",
|
|
36
36
|
"rxjs": "7.x"
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "6a44587b76a0bd45298a3713d11205843b4ab2e9"
|
|
39
39
|
}
|