src/cm/media/js/lib/yui/yui_3.10.3/build/event-move/event-move-debug.js
changeset 525 89ef5ed3c48b
equal deleted inserted replaced
524:322d0feea350 525:89ef5ed3c48b
       
     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"]});