UNPKG

4.79 kBJavaScriptView Raw
1/*!
2 * (C) Ionic http://ionicframework.com - MIT License
3 */
4class 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 * Creates a gesture delegate based on the GestureConfig passed
13 */
14 createGesture(config) {
15 return new GestureDelegate(this, this.newID(), config.name, config.priority || 0, !!config.disableScroll);
16 }
17 /**
18 * Creates a blocker that will block any other gesture events from firing. Set in the ion-gesture component.
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 // a gesture already captured
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}
110class 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}
153class 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}
191const BACKDROP_NO_SCROLL = 'backdrop-no-scroll';
192const GESTURE_CONTROLLER = new GestureController();
193
194export { GESTURE_CONTROLLER as G };