UNPKG

10.1 kBJavaScriptView Raw
1import { Injectable } from '@angular/core';
2import { Activator } from './activator';
3import { App } from '../components/app/app';
4import { Config } from '../config/config';
5import { DomController } from '../platform/dom-controller';
6import { GestureController } from '../gestures/gesture-controller';
7import { Platform } from '../platform/platform';
8import { hasPointerMoved, pointerCoord } from '../util/dom';
9import { POINTER_EVENT_TYPE_TOUCH } from '../gestures/pointer-events';
10import { RippleActivator } from './ripple';
11import { UIEventManager } from '../gestures/ui-event-manager';
12/**
13 * @hidden
14 */
15var TapClick = (function () {
16 /**
17 * @param {?} config
18 * @param {?} plt
19 * @param {?} dom
20 * @param {?} app
21 * @param {?} gestureCtrl
22 */
23 function TapClick(config, plt, dom, app, gestureCtrl) {
24 this.plt = plt;
25 this.app = app;
26 this.gestureCtrl = gestureCtrl;
27 this.disableClick = 0;
28 this.events = new UIEventManager(plt);
29 var activator = config.get('activator');
30 if (activator === 'ripple') {
31 this.activator = new RippleActivator(app, config, dom);
32 }
33 else if (activator === 'highlight') {
34 this.activator = new Activator(app, config, dom);
35 }
36 this.usePolyfill = config.getBoolean('tapPolyfill');
37 (void 0) /* console.debug */;
38 var doc = plt.doc();
39 this.events.listen(doc, 'click', this.click.bind(this), { passive: false, capture: true });
40 this.pointerEvents = this.events.pointerEvents({
41 element: doc,
42 pointerDown: this.pointerStart.bind(this),
43 pointerMove: this.pointerMove.bind(this),
44 pointerUp: this.pointerEnd.bind(this),
45 passive: true
46 });
47 this.pointerEvents.mouseWait = DISABLE_NATIVE_CLICK_AMOUNT;
48 }
49 /**
50 * @param {?} ev
51 * @return {?}
52 */
53 TapClick.prototype.pointerStart = function (ev) {
54 if (this.startCoord) {
55 return false;
56 }
57 if (!this.app.isEnabled()) {
58 return false;
59 }
60 this.lastTouchEnd = 0;
61 this.dispatchClick = true;
62 if (this.plt.doc() === ev.target) {
63 this.startCoord = pointerCoord(ev);
64 return true;
65 }
66 var /** @type {?} */ activatableEle = getActivatableTarget(ev.target);
67 if (!activatableEle) {
68 this.startCoord = null;
69 return false;
70 }
71 this.startCoord = pointerCoord(ev);
72 this.activator && this.activator.downAction(ev, activatableEle, this.startCoord);
73 return true;
74 };
75 /**
76 * @param {?} ev
77 * @return {?}
78 */
79 TapClick.prototype.pointerMove = function (ev) {
80 if (this.startCoord && this.shouldCancelEvent(ev)) {
81 this.pointerCancel(ev);
82 }
83 };
84 /**
85 * @param {?} ev
86 * @param {?} pointerEventType
87 * @return {?}
88 */
89 TapClick.prototype.pointerEnd = function (ev, pointerEventType) {
90 if (!this.dispatchClick)
91 return;
92 (void 0) /* runInDev */;
93 if (!this.startCoord) {
94 return;
95 }
96 if (this.activator && ev.target !== this.plt.doc()) {
97 var /** @type {?} */ activatableEle = getActivatableTarget(ev.target);
98 if (activatableEle) {
99 this.activator.upAction(ev, activatableEle, this.startCoord);
100 }
101 }
102 if (this.usePolyfill && pointerEventType === POINTER_EVENT_TYPE_TOUCH && this.app.isEnabled()) {
103 this.handleTapPolyfill(ev);
104 }
105 this.startCoord = null;
106 };
107 /**
108 * @param {?} ev
109 * @return {?}
110 */
111 TapClick.prototype.pointerCancel = function (ev) {
112 (void 0) /* console.debug */;
113 this.startCoord = null;
114 this.dispatchClick = false;
115 this.activator && this.activator.clearState(false);
116 this.pointerEvents.stop();
117 };
118 /**
119 * @param {?} ev
120 * @return {?}
121 */
122 TapClick.prototype.shouldCancelEvent = function (ev) {
123 return (this.app.isScrolling() ||
124 this.gestureCtrl.isCaptured() ||
125 hasPointerMoved(POINTER_TOLERANCE, this.startCoord, pointerCoord(ev)));
126 };
127 /**
128 * @param {?} ev
129 * @return {?}
130 */
131 TapClick.prototype.click = function (ev) {
132 if (this.shouldCancelClick(ev)) {
133 ev.preventDefault();
134 ev.stopPropagation();
135 return;
136 }
137 if (this.activator && this.plt.doc() !== ev.target) {
138 // cool, a click is gonna happen, let's tell the activator
139 // so the element can get the given "active" style
140 var /** @type {?} */ activatableEle = getActivatableTarget(ev.target);
141 if (activatableEle) {
142 this.activator.clickAction(ev, activatableEle, this.startCoord);
143 }
144 }
145 (void 0) /* runInDev */;
146 };
147 /**
148 * @param {?} ev
149 * @return {?}
150 */
151 TapClick.prototype.shouldCancelClick = function (ev) {
152 if (this.usePolyfill) {
153 if (!ev.isIonicTap && this.isDisabledNativeClick()) {
154 (void 0) /* console.debug */;
155 return true;
156 }
157 }
158 else if (!this.dispatchClick) {
159 (void 0) /* console.debug */;
160 return true;
161 }
162 if (!this.app.isEnabled()) {
163 (void 0) /* console.debug */;
164 return true;
165 }
166 if (this.gestureCtrl.isCaptured()) {
167 (void 0) /* console.debug */;
168 return true;
169 }
170 return false;
171 };
172 /**
173 * @param {?} ev
174 * @return {?}
175 */
176 TapClick.prototype.profileClickDelay = function (ev) {
177 if (this.lastTouchEnd) {
178 var /** @type {?} */ diff = Date.now() - this.lastTouchEnd;
179 if (diff < 100) {
180 (void 0) /* console.debug */;
181 }
182 else {
183 console.warn("SLOW click dispatched. Delay(ms):", diff, ev);
184 }
185 this.lastTouchEnd = null;
186 }
187 else {
188 (void 0) /* console.debug */;
189 }
190 };
191 /**
192 * @param {?} ev
193 * @return {?}
194 */
195 TapClick.prototype.handleTapPolyfill = function (ev) {
196 (void 0) /* assert */;
197 // only dispatch mouse click events from a touchend event
198 // when tapPolyfill config is true, and the startCoordand endCoord
199 // are not too far off from each other
200 var /** @type {?} */ endCoord = pointerCoord(ev);
201 if (hasPointerMoved(POINTER_TOLERANCE, this.startCoord, endCoord)) {
202 (void 0) /* console.debug */;
203 return;
204 }
205 // prevent native mouse click events for XX amount of time
206 this.disableClick = Date.now() + DISABLE_NATIVE_CLICK_AMOUNT;
207 if (this.app.isScrolling()) {
208 // do not fire off a click event while the app was scrolling
209 (void 0) /* console.debug */;
210 }
211 else {
212 // dispatch a mouse click event
213 (void 0) /* console.debug */;
214 var /** @type {?} */ clickEvent = this.plt.doc().createEvent('MouseEvents');
215 clickEvent.initMouseEvent('click', true, true, this.plt.win(), 1, 0, 0, endCoord.x, endCoord.y, false, false, false, false, 0, null);
216 clickEvent.isIonicTap = true;
217 ev.target.dispatchEvent(clickEvent);
218 }
219 };
220 /**
221 * @return {?}
222 */
223 TapClick.prototype.isDisabledNativeClick = function () {
224 return this.disableClick > Date.now();
225 };
226 return TapClick;
227}());
228export { TapClick };
229TapClick.decorators = [
230 { type: Injectable },
231];
232/**
233 * @nocollapse
234 */
235TapClick.ctorParameters = function () { return [
236 { type: Config, },
237 { type: Platform, },
238 { type: DomController, },
239 { type: App, },
240 { type: GestureController, },
241]; };
242function TapClick_tsickle_Closure_declarations() {
243 /** @type {?} */
244 TapClick.decorators;
245 /**
246 * @nocollapse
247 * @type {?}
248 */
249 TapClick.ctorParameters;
250 /** @type {?} */
251 TapClick.prototype.disableClick;
252 /** @type {?} */
253 TapClick.prototype.usePolyfill;
254 /** @type {?} */
255 TapClick.prototype.activator;
256 /** @type {?} */
257 TapClick.prototype.startCoord;
258 /** @type {?} */
259 TapClick.prototype.events;
260 /** @type {?} */
261 TapClick.prototype.pointerEvents;
262 /** @type {?} */
263 TapClick.prototype.lastTouchEnd;
264 /** @type {?} */
265 TapClick.prototype.dispatchClick;
266 /** @type {?} */
267 TapClick.prototype.plt;
268 /** @type {?} */
269 TapClick.prototype.app;
270 /** @type {?} */
271 TapClick.prototype.gestureCtrl;
272}
273/**
274 * @param {?} ele
275 * @return {?}
276 */
277function getActivatableTarget(ele) {
278 var /** @type {?} */ targetEle = ele;
279 for (var /** @type {?} */ x = 0; x < 10; x++) {
280 if (!targetEle)
281 break;
282 if (isActivatable(targetEle)) {
283 return targetEle;
284 }
285 targetEle = targetEle.parentElement;
286 }
287 return null;
288}
289/**
290 * @hidden
291 * @param {?} ele
292 * @return {?}
293 */
294export function isActivatable(ele) {
295 if (ACTIVATABLE_ELEMENTS.indexOf(ele.tagName) > -1) {
296 return true;
297 }
298 for (var /** @type {?} */ i = 0, /** @type {?} */ l = ACTIVATABLE_ATTRIBUTES.length; i < l; i++) {
299 if (ele.hasAttribute && ele.hasAttribute(ACTIVATABLE_ATTRIBUTES[i])) {
300 return true;
301 }
302 }
303 return false;
304}
305var /** @type {?} */ ACTIVATABLE_ELEMENTS = ['A', 'BUTTON'];
306var /** @type {?} */ ACTIVATABLE_ATTRIBUTES = ['tappable', 'ion-button'];
307var /** @type {?} */ POINTER_TOLERANCE = 100;
308var /** @type {?} */ DISABLE_NATIVE_CLICK_AMOUNT = 2500;
309/**
310 * @hidden
311 * @param {?} config
312 * @param {?} plt
313 * @param {?} dom
314 * @param {?} app
315 * @param {?} gestureCtrl
316 * @return {?}
317 */
318export function setupTapClick(config, plt, dom, app, gestureCtrl) {
319 return function () {
320 return new TapClick(config, plt, dom, app, gestureCtrl);
321 };
322}
323//# sourceMappingURL=tap-click.js.map
\No newline at end of file