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