1 |
|
2 |
|
3 |
|
4 | class GestureController {
|
5 | constructor() {
|
6 | this.gestureId = 0;
|
7 | this.requestedStart = new Map();
|
8 | this.disabledGestures = new Map();
|
9 | this.disabledScroll = new Set();
|
10 | }
|
11 | |
12 |
|
13 |
|
14 | createGesture(config) {
|
15 | return new GestureDelegate(this, this.newID(), config.name, config.priority || 0, !!config.disableScroll);
|
16 | }
|
17 | |
18 |
|
19 |
|
20 | createBlocker(opts = {}) {
|
21 | return new BlockerDelegate(this, this.newID(), opts.disable, !!opts.disableScroll);
|
22 | }
|
23 | start(gestureName, id, priority) {
|
24 | if (!this.canStart(gestureName)) {
|
25 | this.requestedStart.delete(id);
|
26 | return false;
|
27 | }
|
28 | this.requestedStart.set(id, priority);
|
29 | return true;
|
30 | }
|
31 | capture(gestureName, id, priority) {
|
32 | if (!this.start(gestureName, id, priority)) {
|
33 | return false;
|
34 | }
|
35 | const requestedStart = this.requestedStart;
|
36 | let maxPriority = -10000;
|
37 | requestedStart.forEach(value => {
|
38 | maxPriority = Math.max(maxPriority, value);
|
39 | });
|
40 | if (maxPriority === priority) {
|
41 | this.capturedId = id;
|
42 | requestedStart.clear();
|
43 | const event = new CustomEvent('ionGestureCaptured', { detail: { gestureName } });
|
44 | document.dispatchEvent(event);
|
45 | return true;
|
46 | }
|
47 | requestedStart.delete(id);
|
48 | return false;
|
49 | }
|
50 | release(id) {
|
51 | this.requestedStart.delete(id);
|
52 | if (this.capturedId === id) {
|
53 | this.capturedId = undefined;
|
54 | }
|
55 | }
|
56 | disableGesture(gestureName, id) {
|
57 | let set = this.disabledGestures.get(gestureName);
|
58 | if (set === undefined) {
|
59 | set = new Set();
|
60 | this.disabledGestures.set(gestureName, set);
|
61 | }
|
62 | set.add(id);
|
63 | }
|
64 | enableGesture(gestureName, id) {
|
65 | const set = this.disabledGestures.get(gestureName);
|
66 | if (set !== undefined) {
|
67 | set.delete(id);
|
68 | }
|
69 | }
|
70 | disableScroll(id) {
|
71 | this.disabledScroll.add(id);
|
72 | if (this.disabledScroll.size === 1) {
|
73 | document.body.classList.add(BACKDROP_NO_SCROLL);
|
74 | }
|
75 | }
|
76 | enableScroll(id) {
|
77 | this.disabledScroll.delete(id);
|
78 | if (this.disabledScroll.size === 0) {
|
79 | document.body.classList.remove(BACKDROP_NO_SCROLL);
|
80 | }
|
81 | }
|
82 | canStart(gestureName) {
|
83 | if (this.capturedId !== undefined) {
|
84 |
|
85 | return false;
|
86 | }
|
87 | if (this.isDisabled(gestureName)) {
|
88 | return false;
|
89 | }
|
90 | return true;
|
91 | }
|
92 | isCaptured() {
|
93 | return this.capturedId !== undefined;
|
94 | }
|
95 | isScrollDisabled() {
|
96 | return this.disabledScroll.size > 0;
|
97 | }
|
98 | isDisabled(gestureName) {
|
99 | const disabled = this.disabledGestures.get(gestureName);
|
100 | if (disabled && disabled.size > 0) {
|
101 | return true;
|
102 | }
|
103 | return false;
|
104 | }
|
105 | newID() {
|
106 | this.gestureId++;
|
107 | return this.gestureId;
|
108 | }
|
109 | }
|
110 | class GestureDelegate {
|
111 | constructor(ctrl, id, name, priority, disableScroll) {
|
112 | this.id = id;
|
113 | this.name = name;
|
114 | this.disableScroll = disableScroll;
|
115 | this.priority = priority * 1000000 + id;
|
116 | this.ctrl = ctrl;
|
117 | }
|
118 | canStart() {
|
119 | if (!this.ctrl) {
|
120 | return false;
|
121 | }
|
122 | return this.ctrl.canStart(this.name);
|
123 | }
|
124 | start() {
|
125 | if (!this.ctrl) {
|
126 | return false;
|
127 | }
|
128 | return this.ctrl.start(this.name, this.id, this.priority);
|
129 | }
|
130 | capture() {
|
131 | if (!this.ctrl) {
|
132 | return false;
|
133 | }
|
134 | const captured = this.ctrl.capture(this.name, this.id, this.priority);
|
135 | if (captured && this.disableScroll) {
|
136 | this.ctrl.disableScroll(this.id);
|
137 | }
|
138 | return captured;
|
139 | }
|
140 | release() {
|
141 | if (this.ctrl) {
|
142 | this.ctrl.release(this.id);
|
143 | if (this.disableScroll) {
|
144 | this.ctrl.enableScroll(this.id);
|
145 | }
|
146 | }
|
147 | }
|
148 | destroy() {
|
149 | this.release();
|
150 | this.ctrl = undefined;
|
151 | }
|
152 | }
|
153 | class BlockerDelegate {
|
154 | constructor(ctrl, id, disable, disableScroll) {
|
155 | this.id = id;
|
156 | this.disable = disable;
|
157 | this.disableScroll = disableScroll;
|
158 | this.ctrl = ctrl;
|
159 | }
|
160 | block() {
|
161 | if (!this.ctrl) {
|
162 | return;
|
163 | }
|
164 | if (this.disable) {
|
165 | for (const gesture of this.disable) {
|
166 | this.ctrl.disableGesture(gesture, this.id);
|
167 | }
|
168 | }
|
169 | if (this.disableScroll) {
|
170 | this.ctrl.disableScroll(this.id);
|
171 | }
|
172 | }
|
173 | unblock() {
|
174 | if (!this.ctrl) {
|
175 | return;
|
176 | }
|
177 | if (this.disable) {
|
178 | for (const gesture of this.disable) {
|
179 | this.ctrl.enableGesture(gesture, this.id);
|
180 | }
|
181 | }
|
182 | if (this.disableScroll) {
|
183 | this.ctrl.enableScroll(this.id);
|
184 | }
|
185 | }
|
186 | destroy() {
|
187 | this.unblock();
|
188 | this.ctrl = undefined;
|
189 | }
|
190 | }
|
191 | const BACKDROP_NO_SCROLL = 'backdrop-no-scroll';
|
192 | const GESTURE_CONTROLLER = new GestureController();
|
193 |
|
194 | export { GESTURE_CONTROLLER as G };
|