UNPKG

4.76 kBJavaScriptView Raw
1'use strict';
2
3class 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 * Creates a gesture delegate based on the GestureConfig passed
12 */
13 createGesture(config) {
14 return new GestureDelegate(this, this.newID(), config.name, config.priority || 0, !!config.disableScroll);
15 }
16 /**
17 * Creates a blocker that will block any other gesture events from firing. Set in the ion-gesture component.
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 // a gesture already captured
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}
109class 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}
152class 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}
190const BACKDROP_NO_SCROLL = 'backdrop-no-scroll';
191const GESTURE_CONTROLLER = new GestureController();
192
193exports.GESTURE_CONTROLLER = GESTURE_CONTROLLER;