~michael.nelson/ubuntu-webcatalog/1267731-import-sca-apps-error

« back to all changes in this revision

Viewing changes to src/webcatalog/static/yui/3.10.3/build/event-move/event-move-debug.js

  • Committer: Tarmac
  • Author(s): Stephen Stewart
  • Date: 2013-06-26 09:19:32 UTC
  • mfrom: (184.1.4 ubuntu-global-nav)
  • Revision ID: tarmac-20130626091932-8urtuli368k8p7ds
[r=beuno,jonas-drange] add ubuntu global nav to apps.ubuntu.com

Show diffs side-by-side

added added

removed removed

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