Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
YUI.add('event-move', function (Y, NAME) {
2
 
3
/**
4
 * Adds lower level support for "gesturemovestart", "gesturemove" and "gesturemoveend" events, which can be used to create drag/drop
5
 * interactions which work across touch and mouse input devices. They correspond to "touchstart", "touchmove" and "touchend" on a touch input
6
 * device, and "mousedown", "mousemove", "mouseup" on a mouse based input device.
7
 *
8
 * <p>Documentation for the gesturemove triplet of events can be found on the <a href="../classes/YUI.html#event_gesturemove">YUI</a> global,
9
 * along with the other supported events.</p>
10
 
11
 @example
12
 
13
     YUI().use('event-move', function (Y) {
14
         Y.one('#myNode').on('gesturemovestart', function (e) {
15
             Y.log('gesturemovestart Fired.');
16
         });
17
         Y.one('#myNode').on('gesturemove', function (e) {
18
             Y.log('gesturemove Fired.');
19
         });
20
         Y.one('#myNode').on('gesturemoveend', function (e) {
21
             Y.log('gesturemoveend Fired.');
22
         });
23
     });
24
 
25
 * @module event-gestures
26
 * @submodule event-move
27
 */
28
 
29
 
30
 var GESTURE_MAP = Y.Event._GESTURE_MAP,
31
     EVENT = {
32
         start: GESTURE_MAP.start,
33
         end: GESTURE_MAP.end,
34
         move: GESTURE_MAP.move
35
     },
36
    START = "start",
37
    MOVE = "move",
38
    END = "end",
39
 
40
    GESTURE_MOVE = "gesture" + MOVE,
41
    GESTURE_MOVE_END = GESTURE_MOVE + END,
42
    GESTURE_MOVE_START = GESTURE_MOVE + START,
43
 
44
    _MOVE_START_HANDLE = "_msh",
45
    _MOVE_HANDLE = "_mh",
46
    _MOVE_END_HANDLE = "_meh",
47
 
48
    _DEL_MOVE_START_HANDLE = "_dmsh",
49
    _DEL_MOVE_HANDLE = "_dmh",
50
    _DEL_MOVE_END_HANDLE = "_dmeh",
51
 
52
    _MOVE_START = "_ms",
53
    _MOVE = "_m",
54
 
55
    MIN_TIME = "minTime",
56
    MIN_DISTANCE = "minDistance",
57
    PREVENT_DEFAULT = "preventDefault",
58
    BUTTON = "button",
59
    OWNER_DOCUMENT = "ownerDocument",
60
 
61
    CURRENT_TARGET = "currentTarget",
62
    TARGET = "target",
63
 
64
    NODE_TYPE = "nodeType",
65
    _getTouchAction = function(win) {
66
        var touchAction;
67
        if(win) {
68
            if("PointerEvent" in win) {
69
                touchAction = "touchAction";
70
            } else if("msPointerEnabled" in win.navigator) {
71
                touchAction = "msTouchAction";
72
            }
73
        }
74
        return touchAction;
75
    },
76
    TOUCH_ACTION = _getTouchAction(Y.config.win),
77
    SUPPORTS_POINTER = (TOUCH_ACTION === "msTouchAction" || TOUCH_ACTION === "touchAction"),
78
    MS_TOUCH_ACTION_COUNT = 'msTouchActionCount',
79
    MS_INIT_TOUCH_ACTION = 'msInitTouchAction',
80
 
81
    _defArgsProcessor = function(se, args, delegate) {
82
        var iConfig = (delegate) ? 4 : 3,
83
            config = (args.length > iConfig) ? Y.merge(args.splice(iConfig,1)[0]) : {};
84
 
85
        if (!(PREVENT_DEFAULT in config)) {
86
            config[PREVENT_DEFAULT] = se.PREVENT_DEFAULT;
87
        }
88
 
89
        return config;
90
    },
91
 
92
    _getRoot = function(node, subscriber) {
93
        return subscriber._extra.root || (node.get(NODE_TYPE) === 9) ? node : node.get(OWNER_DOCUMENT);
94
    },
95
 
96
    //Checks to see if the node is the document, and if it is, returns the documentElement.
97
    _checkDocumentElem = function(node) {
98
        var elem = node.getDOMNode();
99
        if (node.compareTo(Y.config.doc) && elem.documentElement) {
100
            return elem.documentElement;
101
        }
102
        else {
103
            return false;
104
        }
105
    },
106
 
107
    _normTouchFacade = function(touchFacade, touch, params) {
108
        touchFacade.pageX = touch.pageX;
109
        touchFacade.pageY = touch.pageY;
110
        touchFacade.screenX = touch.screenX;
111
        touchFacade.screenY = touch.screenY;
112
        touchFacade.clientX = touch.clientX;
113
        touchFacade.clientY = touch.clientY;
114
        touchFacade[TARGET] = touchFacade[TARGET] || touch[TARGET];
115
        touchFacade[CURRENT_TARGET] = touchFacade[CURRENT_TARGET] || touch[CURRENT_TARGET];
116
 
117
        touchFacade[BUTTON] = (params && params[BUTTON]) || 1; // default to left (left as per vendors, not W3C which is 0)
118
    },
119
 
120
    /*
121
    In IE10 touch mode, gestures will not work properly unless the -ms-touch-action CSS property is set to something other than 'auto'. Read http://msdn.microsoft.com/en-us/library/windows/apps/hh767313.aspx for more info. To get around this, we set -ms-touch-action: none which is the same as e.preventDefault() on touch environments. This tells the browser to fire DOM events for all touch events, and not perform any default behavior.
122
 
123
    The user can over-ride this by setting a more lenient -ms-touch-action property on a node (such as pan-x, pan-y, etc.) via CSS when subscribing to the 'gesturemovestart' event.
124
    */
125
    _setTouchActions = function (node) {
126
        var elem = node.getDOMNode(),
127
            num = node.getData(MS_TOUCH_ACTION_COUNT);
128
 
129
        //Checks to see if msTouchAction is supported.
130
        if (SUPPORTS_POINTER) {
131
            if (!num) {
132
                num = 0;
133
                node.setData(MS_INIT_TOUCH_ACTION, elem.style[TOUCH_ACTION]);
134
            }
135
            elem.style[TOUCH_ACTION] = Y.Event._DEFAULT_TOUCH_ACTION;
136
            num++;
137
            node.setData(MS_TOUCH_ACTION_COUNT, num);
138
        }
139
    },
140
 
141
    /*
142
    Resets the element's -ms-touch-action property back to the original value, This is called on detach() and detachDelegate().
143
    */
144
    _unsetTouchActions = function (node) {
145
        var elem = node.getDOMNode(),
146
            num = node.getData(MS_TOUCH_ACTION_COUNT),
147
            initTouchAction = node.getData(MS_INIT_TOUCH_ACTION);
148
 
149
        if (SUPPORTS_POINTER) {
150
            num--;
151
            node.setData(MS_TOUCH_ACTION_COUNT, num);
152
            if (num === 0 && elem.style[TOUCH_ACTION] !== initTouchAction) {
153
                elem.style[TOUCH_ACTION] = initTouchAction;
154
            }
155
        }
156
    },
157
 
158
    _prevent = function(e, preventDefault) {
159
        if (preventDefault) {
160
            // preventDefault is a boolean or a function
161
            if (!preventDefault.call || preventDefault(e)) {
162
                e.preventDefault();
163
            }
164
        }
165
    },
166
 
167
    define = Y.Event.define;
168
    Y.Event._DEFAULT_TOUCH_ACTION = 'none';
169
 
170
/**
171
 * Sets up a "gesturemovestart" event, that is fired on touch devices in response to a single finger "touchstart",
172
 * and on mouse based devices in response to a "mousedown". The subscriber can specify the minimum time
173
 * and distance thresholds which should be crossed before the "gesturemovestart" is fired and for the mouse,
174
 * which button should initiate a "gesturemovestart". This event can also be listened for using node.delegate().
175
 *
176
 * <p>It is recommended that you use Y.bind to set up context and additional arguments for your event handler,
177
 * however if you want to pass the context and arguments as additional signature arguments to on/delegate,
178
 * you need to provide a null value for the configuration object, e.g: <code>node.on("gesturemovestart", fn, null, context, arg1, arg2, arg3)</code></p>
179
 *
180
 * @event gesturemovestart
181
 * @for YUI
182
 * @param type {string} "gesturemovestart"
183
 * @param fn {function} The method the event invokes. It receives the event facade of the underlying DOM event (mousedown or touchstart.touches[0]) which contains position co-ordinates.
184
 * @param cfg {Object} Optional. An object which specifies:
185
 *
186
 * <dl>
187
 * <dt>minDistance (defaults to 0)</dt>
188
 * <dd>The minimum distance threshold which should be crossed before the gesturemovestart is fired</dd>
189
 * <dt>minTime (defaults to 0)</dt>
190
 * <dd>The minimum time threshold for which the finger/mouse should be help down before the gesturemovestart is fired</dd>
191
 * <dt>button (no default)</dt>
192
 * <dd>In the case of a mouse input device, if the event should only be fired for a specific mouse button.</dd>
193
 * <dt>preventDefault (defaults to false)</dt>
194
 * <dd>Can be set to true/false to prevent default behavior as soon as the touchstart or mousedown is received (that is before minTime or minDistance thresholds are crossed, and so before the gesturemovestart listener is notified) so that things like text selection and context popups (on touch devices) can be
195
 * prevented. This property can also be set to a function, which returns true or false, based on the event facade passed to it (for example, DragDrop can determine if the target is a valid handle or not before preventing default).</dd>
196
 * </dl>
197
 *
198
 * @return {EventHandle} the detach handle
199
 */
200
 
201
define(GESTURE_MOVE_START, {
202
 
203
    on: function (node, subscriber, ce) {
204
 
205
        //Set -ms-touch-action on IE10 and set preventDefault to true
206
        if (!_checkDocumentElem(node)) {
207
            _setTouchActions(node);
208
        }
209
 
210
        subscriber[_MOVE_START_HANDLE] = node.on(EVENT[START],
211
            this._onStart,
212
            this,
213
            node,
214
            subscriber,
215
            ce);
216
    },
217
 
218
    delegate : function(node, subscriber, ce, filter) {
219
 
220
        var se = this;
221
 
222
        subscriber[_DEL_MOVE_START_HANDLE] = node.delegate(EVENT[START],
223
            function(e) {
224
                se._onStart(e, node, subscriber, ce, true);
225
            },
226
            filter);
227
    },
228
 
229
    detachDelegate : function(node, subscriber, ce, filter) {
230
        var handle = subscriber[_DEL_MOVE_START_HANDLE];
231
 
232
        if (handle) {
233
            handle.detach();
234
            subscriber[_DEL_MOVE_START_HANDLE] = null;
235
        }
236
 
237
        if (!_checkDocumentElem(node)) {
238
            _unsetTouchActions(node);
239
        }
240
    },
241
 
242
    detach: function (node, subscriber, ce) {
243
        var startHandle = subscriber[_MOVE_START_HANDLE];
244
 
245
        if (startHandle) {
246
            startHandle.detach();
247
            subscriber[_MOVE_START_HANDLE] = null;
248
        }
249
 
250
        if (!_checkDocumentElem(node)) {
251
            _unsetTouchActions(node);
252
        }
253
    },
254
 
255
    processArgs : function(args, delegate) {
256
        var params = _defArgsProcessor(this, args, delegate);
257
 
258
        if (!(MIN_TIME in params)) {
259
            params[MIN_TIME] = this.MIN_TIME;
260
        }
261
 
262
        if (!(MIN_DISTANCE in params)) {
263
            params[MIN_DISTANCE] = this.MIN_DISTANCE;
264
        }
265
 
266
        return params;
267
    },
268
 
269
    _onStart : function(e, node, subscriber, ce, delegate) {
270
 
271
        if (delegate) {
272
            node = e[CURRENT_TARGET];
273
        }
274
 
275
        var params = subscriber._extra,
276
            fireStart = true,
277
            minTime = params[MIN_TIME],
278
            minDistance = params[MIN_DISTANCE],
279
            button = params.button,
280
            preventDefault = params[PREVENT_DEFAULT],
281
            root = _getRoot(node, subscriber),
282
            startXY;
283
 
284
        if (e.touches) {
285
            if (e.touches.length === 1) {
286
                _normTouchFacade(e, e.touches[0], params);
287
            } else {
288
                fireStart = false;
289
            }
290
        } else {
291
            fireStart = (button === undefined) || (button === e.button);
292
        }
293
 
294
        Y.log("gesturemovestart: params = button:" + button + ", minTime = " + minTime + ", minDistance = " + minDistance, "event-gestures");
295
 
296
        if (fireStart) {
297
 
298
            _prevent(e, preventDefault);
299
 
300
            if (minTime === 0 || minDistance === 0) {
301
                Y.log("gesturemovestart: No minTime or minDistance. Firing immediately", "event-gestures");
302
                this._start(e, node, ce, params);
303
 
304
            } else {
305
 
306
                startXY = [e.pageX, e.pageY];
307
 
308
                if (minTime > 0) {
309
 
310
                    Y.log("gesturemovestart: minTime specified. Setup timer.", "event-gestures");
311
                    Y.log("gesturemovestart: initialTime for minTime = " + new Date().getTime(), "event-gestures");
312
 
313
                    params._ht = Y.later(minTime, this, this._start, [e, node, ce, params]);
314
 
315
                    params._hme = root.on(EVENT[END], Y.bind(function() {
316
                        this._cancel(params);
317
                    }, this));
318
                }
319
 
320
                if (minDistance > 0) {
321
 
322
                    Y.log("gesturemovestart: minDistance specified. Setup native mouse/touchmove listener to measure distance.", "event-gestures");
323
                    Y.log("gesturemovestart: initialXY for minDistance = " + startXY, "event-gestures");
324
 
325
                    params._hm = root.on(EVENT[MOVE], Y.bind(function(em) {
326
                        if (Math.abs(em.pageX - startXY[0]) > minDistance || Math.abs(em.pageY - startXY[1]) > minDistance) {
327
                            Y.log("gesturemovestart: minDistance hit.", "event-gestures");
328
                            this._start(e, node, ce, params);
329
                        }
330
                    }, this));
331
                }
332
            }
333
        }
334
    },
335
 
336
    _cancel : function(params) {
337
        if (params._ht) {
338
            params._ht.cancel();
339
            params._ht = null;
340
        }
341
        if (params._hme) {
342
            params._hme.detach();
343
            params._hme = null;
344
        }
345
        if (params._hm) {
346
            params._hm.detach();
347
            params._hm = null;
348
        }
349
    },
350
 
351
    _start : function(e, node, ce, params) {
352
 
353
        if (params) {
354
            this._cancel(params);
355
        }
356
 
357
        e.type = GESTURE_MOVE_START;
358
 
359
        Y.log("gesturemovestart: Firing start: " + new Date().getTime(), "event-gestures");
360
 
361
        node.setData(_MOVE_START, e);
362
        ce.fire(e);
363
    },
364
 
365
    MIN_TIME : 0,
366
    MIN_DISTANCE : 0,
367
    PREVENT_DEFAULT : false
368
});
369
 
370
/**
371
 * Sets up a "gesturemove" event, that is fired on touch devices in response to a single finger "touchmove",
372
 * and on mouse based devices in response to a "mousemove".
373
 *
374
 * <p>By default this event is only fired when the same node
375
 * has received a "gesturemovestart" event. The subscriber can set standAlone to true, in the configuration properties,
376
 * if they want to listen for this event without an initial "gesturemovestart".</p>
377
 *
378
 * <p>By default this event sets up it's internal "touchmove" and "mousemove" DOM listeners on the document element. The subscriber
379
 * can set the root configuration property, to specify which node to attach DOM listeners to, if different from the document.</p>
380
 *
381
 * <p>This event can also be listened for using node.delegate().</p>
382
 *
383
 * <p>It is recommended that you use Y.bind to set up context and additional arguments for your event handler,
384
 * however if you want to pass the context and arguments as additional signature arguments to on/delegate,
385
 * you need to provide a null value for the configuration object, e.g: <code>node.on("gesturemove", fn, null, context, arg1, arg2, arg3)</code></p>
386
 *
387
 * @event gesturemove
388
 * @for YUI
389
 * @param type {string} "gesturemove"
390
 * @param fn {function} The method the event invokes. It receives the event facade of the underlying DOM event (mousemove or touchmove.touches[0]) which contains position co-ordinates.
391
 * @param cfg {Object} Optional. An object which specifies:
392
 * <dl>
393
 * <dt>standAlone (defaults to false)</dt>
394
 * <dd>true, if the subscriber should be notified even if a "gesturemovestart" has not occured on the same node.</dd>
395
 * <dt>root (defaults to document)</dt>
396
 * <dd>The node to which the internal DOM listeners should be attached.</dd>
397
 * <dt>preventDefault (defaults to false)</dt>
398
 * <dd>Can be set to true/false to prevent default behavior as soon as the touchmove or mousemove is received. As with gesturemovestart, can also be set to function which returns true/false based on the event facade passed to it.</dd>
399
 * </dl>
400
 *
401
 * @return {EventHandle} the detach handle
402
 */
403
define(GESTURE_MOVE, {
404
 
405
    on : function (node, subscriber, ce) {
406
        var moveHandle,
407
            root;
408
 
409
        // if the passed node is NOT the document itself, modify the ms-pointer
410
        // behavior to prevent scrolling, highlighting, etc.
411
        if (!_checkDocumentElem(node)) {
412
            _setTouchActions(node);
413
        }
414
 
415
        root = _getRoot(node, subscriber, EVENT[MOVE]);
416
 
417
        moveHandle = root.on(EVENT[MOVE],
418
            this._onMove,
419
            this,
420
            node,
421
            subscriber,
422
            ce);
423
 
424
        subscriber[_MOVE_HANDLE] = moveHandle;
425
 
426
    },
427
 
428
    delegate : function(node, subscriber, ce, filter) {
429
 
430
        var se = this;
431
 
432
        subscriber[_DEL_MOVE_HANDLE] = node.delegate(EVENT[MOVE],
433
            function(e) {
434
                se._onMove(e, node, subscriber, ce, true);
435
            },
436
            filter);
437
    },
438
 
439
    detach : function (node, subscriber, ce) {
440
        var moveHandle = subscriber[_MOVE_HANDLE];
441
 
442
        if (moveHandle) {
443
            moveHandle.detach();
444
            subscriber[_MOVE_HANDLE] = null;
445
        }
446
 
447
        if (!_checkDocumentElem(node)) {
448
            _unsetTouchActions(node);
449
        }
450
    },
451
 
452
    detachDelegate : function(node, subscriber, ce, filter) {
453
        var handle = subscriber[_DEL_MOVE_HANDLE];
454
 
455
        if (handle) {
456
            handle.detach();
457
            subscriber[_DEL_MOVE_HANDLE] = null;
458
        }
459
 
460
        if (!_checkDocumentElem(node)) {
461
            _unsetTouchActions(node);
462
        }
463
 
464
    },
465
 
466
    processArgs : function(args, delegate) {
467
        return _defArgsProcessor(this, args, delegate);
468
    },
469
 
470
    _onMove : function(e, node, subscriber, ce, delegate) {
471
 
472
        if (delegate) {
473
            node = e[CURRENT_TARGET];
474
        }
475
 
476
        var fireMove = subscriber._extra.standAlone || node.getData(_MOVE_START),
477
            preventDefault = subscriber._extra.preventDefault;
478
 
479
        Y.log("onMove initial fireMove check:" + fireMove,"event-gestures");
480
 
481
        if (fireMove) {
482
 
483
            if (e.touches) {
484
                if (e.touches.length === 1) {
485
                    _normTouchFacade(e, e.touches[0]);
486
                } else {
487
                    fireMove = false;
488
                }
489
            }
490
 
491
            if (fireMove) {
492
 
493
                _prevent(e, preventDefault);
494
 
495
                Y.log("onMove second fireMove check:" + fireMove,"event-gestures");
496
 
497
                e.type = GESTURE_MOVE;
498
                ce.fire(e);
499
            }
500
        }
501
    },
502
 
503
    PREVENT_DEFAULT : false
504
});
505
 
506
/**
507
 * Sets up a "gesturemoveend" event, that is fired on touch devices in response to a single finger "touchend",
508
 * and on mouse based devices in response to a "mouseup".
509
 *
510
 * <p>By default this event is only fired when the same node
511
 * has received a "gesturemove" or "gesturemovestart" event. The subscriber can set standAlone to true, in the configuration properties,
512
 * if they want to listen for this event without a preceding "gesturemovestart" or "gesturemove".</p>
513
 *
514
 * <p>By default this event sets up it's internal "touchend" and "mouseup" DOM listeners on the document element. The subscriber
515
 * can set the root configuration property, to specify which node to attach DOM listeners to, if different from the document.</p>
516
 *
517
 * <p>This event can also be listened for using node.delegate().</p>
518
 *
519
 * <p>It is recommended that you use Y.bind to set up context and additional arguments for your event handler,
520
 * however if you want to pass the context and arguments as additional signature arguments to on/delegate,
521
 * you need to provide a null value for the configuration object, e.g: <code>node.on("gesturemoveend", fn, null, context, arg1, arg2, arg3)</code></p>
522
 *
523
 *
524
 * @event gesturemoveend
525
 * @for YUI
526
 * @param type {string} "gesturemoveend"
527
 * @param fn {function} The method the event invokes. It receives the event facade of the underlying DOM event (mouseup or touchend.changedTouches[0]).
528
 * @param cfg {Object} Optional. An object which specifies:
529
 * <dl>
530
 * <dt>standAlone (defaults to false)</dt>
531
 * <dd>true, if the subscriber should be notified even if a "gesturemovestart" or "gesturemove" has not occured on the same node.</dd>
532
 * <dt>root (defaults to document)</dt>
533
 * <dd>The node to which the internal DOM listeners should be attached.</dd>
534
 * <dt>preventDefault (defaults to false)</dt>
535
 * <dd>Can be set to true/false to prevent default behavior as soon as the touchend or mouseup is received. As with gesturemovestart, can also be set to function which returns true/false based on the event facade passed to it.</dd>
536
 * </dl>
537
 *
538
 * @return {EventHandle} the detach handle
539
 */
540
define(GESTURE_MOVE_END, {
541
 
542
    on : function (node, subscriber, ce) {
543
        var endHandle,
544
            root;
545
 
546
        if (!_checkDocumentElem(node)) {
547
            _setTouchActions(node);
548
        }
549
 
550
        root = _getRoot(node, subscriber);
551
        endHandle = root.on(EVENT[END],
552
            this._onEnd,
553
            this,
554
            node,
555
            subscriber,
556
            ce);
557
 
558
        subscriber[_MOVE_END_HANDLE] = endHandle;
559
    },
560
 
561
    delegate : function(node, subscriber, ce, filter) {
562
 
563
        var se = this;
564
 
565
        subscriber[_DEL_MOVE_END_HANDLE] = node.delegate(EVENT[END],
566
            function(e) {
567
                se._onEnd(e, node, subscriber, ce, true);
568
            },
569
            filter);
570
    },
571
 
572
    detachDelegate : function(node, subscriber, ce, filter) {
573
        var handle = subscriber[_DEL_MOVE_END_HANDLE];
574
 
575
        if (handle) {
576
            handle.detach();
577
            subscriber[_DEL_MOVE_END_HANDLE] = null;
578
        }
579
 
580
        if (!_checkDocumentElem(node)) {
581
            _unsetTouchActions(node);
582
        }
583
 
584
    },
585
 
586
    detach : function (node, subscriber, ce) {
587
        var endHandle = subscriber[_MOVE_END_HANDLE];
588
 
589
        if (endHandle) {
590
            endHandle.detach();
591
            subscriber[_MOVE_END_HANDLE] = null;
592
        }
593
 
594
        if (!_checkDocumentElem(node)) {
595
            _unsetTouchActions(node);
596
        }
597
    },
598
 
599
    processArgs : function(args, delegate) {
600
        return _defArgsProcessor(this, args, delegate);
601
    },
602
 
603
    _onEnd : function(e, node, subscriber, ce, delegate) {
604
 
605
        if (delegate) {
606
            node = e[CURRENT_TARGET];
607
        }
608
 
609
        var fireMoveEnd = subscriber._extra.standAlone || node.getData(_MOVE) || node.getData(_MOVE_START),
610
            preventDefault = subscriber._extra.preventDefault;
611
 
612
        if (fireMoveEnd) {
613
 
614
            if (e.changedTouches) {
615
                if (e.changedTouches.length === 1) {
616
                    _normTouchFacade(e, e.changedTouches[0]);
617
                } else {
618
                    fireMoveEnd = false;
619
                }
620
            }
621
 
622
            if (fireMoveEnd) {
623
 
624
                _prevent(e, preventDefault);
625
 
626
                e.type = GESTURE_MOVE_END;
627
                ce.fire(e);
628
 
629
                node.clearData(_MOVE_START);
630
                node.clearData(_MOVE);
631
            }
632
        }
633
    },
634
 
635
    PREVENT_DEFAULT : false
636
});
637
 
638
 
639
}, '3.18.1', {"requires": ["node-base", "event-touch", "event-synthetic"]});