Repository navigation
Expand file tree
/
Copy pathreader-inputs.mjs
More file actions
123 lines (115 loc) · 3.59 KB
/
Copy pathreader-inputs.mjs
File metadata and controls
123 lines (115 loc) · 3.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import {
createScrubInput,
formatPercentValue,
parsePercentValue,
} from '../../ui/inputs/scrub-input.mjs';
import { clampZoom } from './zoom-motion.mjs';
export function createReaderInputs({ session, motion, shell, view, actions }) {
function nativeReaderInput(control) {
const input = control?.getInput?.() || control;
if (input && control?.el) {
input.inputMode = control.el.getAttribute('inputmode') || 'text';
input.dataset.scrub = control.el.dataset.scrub;
}
return input;
}
function syncScrubInputs() {
const specs = [
[
'page',
nativeReaderInput(shell.pageInput.value),
{
getValue: () => Number(view.pageEntry.value) || view.active.value,
setValue: (value) => {
view.pageEntry.value = Math.round(value);
},
min: 1,
max: Math.max(1, session.pages.value.length),
step: 1,
pixelsPerStep: 18,
deltaToValue: (value, delta) => Math.round(value + delta),
onCommit: submitPage,
},
],
[
'zoom',
nativeReaderInput(shell.zoomInput.value),
{
getValue: () => view.zoom.value,
setValue: (value) => {
view.zoomEntry.value = formatPercentValue(value);
view.fitMode.value = 'manual';
localStorage.setItem('readerFit', 'manual');
actions.readerZoom.requestZoom(value, { animate: false });
},
min: 0.1,
max: 4,
step: 0.01,
pixelsPerStep: 18,
deltaToValue: (value, delta) => clampZoom(value * Math.exp(delta * 0.06)),
onCommit: () => actions.preferencePersistence.saveView(),
},
],
];
const live = new Set();
for (const [name, input, options] of specs) {
if (!input) continue;
live.add(name);
if (motion.scrubbers.get(name)?.input === input) continue;
motion.scrubbers.get(name)?.controller.destroy();
motion.scrubbers.set(name, { input, controller: createScrubInput(input, options) });
}
for (const [name, entry] of motion.scrubbers)
if (!live.has(name)) {
entry.controller.destroy();
motion.scrubbers.delete(name);
}
}
function hideNavigatorLater() {
clearTimeout(motion.navigatorTimer);
motion.navigatorTimer = setTimeout(() => {
if (
!shell.navigator.value?.contains(document.activeElement) &&
!shell.navigator.value?.matches(':hover')
)
motion.navigatorVisible.value = false;
}, 1000);
}
function holdNavigator() {
clearTimeout(motion.navigatorTimer);
}
function showNavigator() {
motion.navigatorVisible.value = !!session.pages.value.length;
hideNavigatorLater();
}
function submitPage() {
actions.pageNavigation.go(Number(view.pageEntry.value), { animate: true });
}
function zoomEntryInput(event) {
view.zoomEntry.value = event.target.value;
}
function submitZoom(event) {
const target = parsePercentValue(view.zoomEntry.value, {
min: 0.1,
max: 4,
fallback: view.zoom.value,
});
view.fitMode.value = 'manual';
localStorage.setItem('readerFit', 'manual');
actions.readerZoom.requestZoom(target);
view.zoomEntry.value = formatPercentValue(target);
actions.preferencePersistence.saveView();
if (event?.target && event.target.value !== view.zoomEntry.value)
event.target.value = view.zoomEntry.value;
}
return {
nativeReaderInput,
syncScrubInputs,
hideNavigatorLater,
holdNavigator,
showNavigator,
submitPage,
zoomEntryInput,
submitZoom,
};
}