src/cm/media/js/lib/yui/yui3-3.15.0/build/event-flick/event-flick.js
changeset 602 e16a97fb364a
equal deleted inserted replaced
601:d334a616c023 602:e16a97fb364a
       
     1 YUI.add('event-flick', function (Y, NAME) {
       
     2 
       
     3 /**
       
     4  * The gestures module provides gesture events such as "flick", which normalize user interactions
       
     5  * across touch and mouse or pointer based input devices. This layer can be used by application developers
       
     6  * to build input device agnostic components which behave the same in response to either touch or mouse based
       
     7  * interaction.
       
     8  *
       
     9  * <p>Documentation for events added by this module can be found in the event document for the <a href="../classes/YUI.html#events">YUI</a> global.</p>
       
    10  *
       
    11  *
       
    12  @example
       
    13 
       
    14      YUI().use('event-flick', function (Y) {
       
    15          Y.one('#myNode').on('flick', function (e) {
       
    16          });
       
    17      });
       
    18 
       
    19  *
       
    20  * @module event-gestures
       
    21  */
       
    22 
       
    23 /**
       
    24  * Adds support for a "flick" event, which is fired at the end of a touch or mouse based flick gesture, and provides
       
    25  * velocity of the flick, along with distance and time information.
       
    26  *
       
    27  * <p>Documentation for the flick event can be found on the <a href="../classes/YUI.html#event_flick">YUI</a> global,
       
    28  * along with the other supported events.</p>
       
    29  *
       
    30  * @module event-gestures
       
    31  * @submodule event-flick
       
    32  */
       
    33 var GESTURE_MAP = Y.Event._GESTURE_MAP,
       
    34     EVENT = {
       
    35         start: GESTURE_MAP.start,
       
    36         end: GESTURE_MAP.end,
       
    37         move: GESTURE_MAP.move
       
    38     },
       
    39     START = "start",
       
    40     END = "end",
       
    41     MOVE = "move",
       
    42 
       
    43     OWNER_DOCUMENT = "ownerDocument",
       
    44     MIN_VELOCITY = "minVelocity",
       
    45     MIN_DISTANCE = "minDistance",
       
    46     PREVENT_DEFAULT = "preventDefault",
       
    47 
       
    48     _FLICK_START = "_fs",
       
    49     _FLICK_START_HANDLE = "_fsh",
       
    50     _FLICK_END_HANDLE = "_feh",
       
    51     _FLICK_MOVE_HANDLE = "_fmh",
       
    52 
       
    53     NODE_TYPE = "nodeType";
       
    54 
       
    55 /**
       
    56  * Sets up a "flick" event, that is fired whenever the user initiates a flick gesture on the node
       
    57  * where the listener is attached. The subscriber can specify a minimum distance or velocity for
       
    58  * which the event is to be fired. The subscriber can also specify if there is a particular axis which
       
    59  * they are interested in - "x" or "y". If no axis is specified, the axis along which there was most distance
       
    60  * covered is used.
       
    61  *
       
    62  * <p>It is recommended that you use Y.bind to set up context and additional arguments for your event handler,
       
    63  * however if you want to pass the context and arguments as additional signature arguments to "on",
       
    64  * you need to provide a null value for the configuration object, e.g: <code>node.on("flick", fn, null, context, arg1, arg2, arg3)</code></p>
       
    65  *
       
    66  * @event flick
       
    67  * @for YUI
       
    68  * @param type {string} "flick"
       
    69  * @param fn {function} The method the event invokes. It receives an event facade with an e.flick object containing the flick related properties: e.flick.time, e.flick.distance, e.flick.velocity and e.flick.axis, e.flick.start.
       
    70  * @param cfg {Object} Optional. An object which specifies any of the following:
       
    71  * <dl>
       
    72  * <dt>minDistance (in pixels, defaults to 10)</dt>
       
    73  * <dd>The minimum distance between start and end points, which would qualify the gesture as a flick.</dd>
       
    74  * <dt>minVelocity (in pixels/ms, defaults to 0)</dt>
       
    75  * <dd>The minimum velocity which would qualify the gesture as a flick.</dd>
       
    76  * <dt>preventDefault (defaults to false)</dt>
       
    77  * <dd>Can be set to true/false to prevent default behavior as soon as the touchstart/touchend or mousedown/mouseup is received so that things like scrolling or text selection can be
       
    78  * prevented. This property can also be set to a function, which returns true or false, based on the event facade passed to it.</dd>
       
    79  * <dt>axis (no default)</dt>
       
    80  * <dd>Can be set to "x" or "y" if you want to constrain the flick velocity and distance to a single axis. If not
       
    81  * defined, the axis along which the maximum distance was covered is used.</dd>
       
    82  * </dl>
       
    83  * @return {EventHandle} the detach handle
       
    84  */
       
    85 
       
    86 Y.Event.define('flick', {
       
    87 
       
    88     on: function (node, subscriber, ce) {
       
    89 
       
    90         var startHandle = node.on(EVENT[START],
       
    91             this._onStart,
       
    92             this,
       
    93             node,
       
    94             subscriber,
       
    95             ce);
       
    96 
       
    97         subscriber[_FLICK_START_HANDLE] = startHandle;
       
    98     },
       
    99 
       
   100     detach: function (node, subscriber, ce) {
       
   101 
       
   102         var startHandle = subscriber[_FLICK_START_HANDLE],
       
   103             endHandle = subscriber[_FLICK_END_HANDLE];
       
   104 
       
   105         if (startHandle) {
       
   106             startHandle.detach();
       
   107             subscriber[_FLICK_START_HANDLE] = null;
       
   108         }
       
   109 
       
   110         if (endHandle) {
       
   111             endHandle.detach();
       
   112             subscriber[_FLICK_END_HANDLE] = null;
       
   113         }
       
   114     },
       
   115 
       
   116     processArgs: function(args) {
       
   117         var params = (args.length > 3) ? Y.merge(args.splice(3, 1)[0]) : {};
       
   118 
       
   119         if (!(MIN_VELOCITY in params)) {
       
   120             params[MIN_VELOCITY] = this.MIN_VELOCITY;
       
   121         }
       
   122 
       
   123         if (!(MIN_DISTANCE in params)) {
       
   124             params[MIN_DISTANCE] = this.MIN_DISTANCE;
       
   125         }
       
   126 
       
   127         if (!(PREVENT_DEFAULT in params)) {
       
   128             params[PREVENT_DEFAULT] = this.PREVENT_DEFAULT;
       
   129         }
       
   130 
       
   131         return params;
       
   132     },
       
   133 
       
   134     _onStart: function(e, node, subscriber, ce) {
       
   135 
       
   136         var start = true, // always true for mouse
       
   137             endHandle,
       
   138             moveHandle,
       
   139             doc,
       
   140             preventDefault = subscriber._extra.preventDefault,
       
   141             origE = e;
       
   142 
       
   143         if (e.touches) {
       
   144             start = (e.touches.length === 1);
       
   145             e = e.touches[0];
       
   146         }
       
   147 
       
   148         if (start) {
       
   149 
       
   150             if (preventDefault) {
       
   151                 // preventDefault is a boolean or function
       
   152                 if (!preventDefault.call || preventDefault(e)) {
       
   153                     origE.preventDefault();
       
   154                 }
       
   155             }
       
   156 
       
   157             e.flick = {
       
   158                 time : new Date().getTime()
       
   159             };
       
   160 
       
   161             subscriber[_FLICK_START] = e;
       
   162 
       
   163             endHandle = subscriber[_FLICK_END_HANDLE];
       
   164 
       
   165             doc = (node.get(NODE_TYPE) === 9) ? node : node.get(OWNER_DOCUMENT);
       
   166             if (!endHandle) {
       
   167                 endHandle = doc.on(EVENT[END], Y.bind(this._onEnd, this), null, node, subscriber, ce);
       
   168                 subscriber[_FLICK_END_HANDLE] = endHandle;
       
   169             }
       
   170 
       
   171             subscriber[_FLICK_MOVE_HANDLE] = doc.once(EVENT[MOVE], Y.bind(this._onMove, this), null, node, subscriber, ce);
       
   172         }
       
   173     },
       
   174 
       
   175     _onMove: function(e, node, subscriber, ce) {
       
   176         var start = subscriber[_FLICK_START];
       
   177 
       
   178         // Start timing from first move.
       
   179         if (start && start.flick) {
       
   180             start.flick.time = new Date().getTime();
       
   181         }
       
   182     },
       
   183 
       
   184     _onEnd: function(e, node, subscriber, ce) {
       
   185 
       
   186         var endTime = new Date().getTime(),
       
   187             start = subscriber[_FLICK_START],
       
   188             valid = !!start,
       
   189             endEvent = e,
       
   190             startTime,
       
   191             time,
       
   192             preventDefault,
       
   193             params,
       
   194             xyDistance,
       
   195             distance,
       
   196             velocity,
       
   197             axis,
       
   198             moveHandle = subscriber[_FLICK_MOVE_HANDLE];
       
   199 
       
   200         if (moveHandle) {
       
   201             moveHandle.detach();
       
   202             delete subscriber[_FLICK_MOVE_HANDLE];
       
   203         }
       
   204 
       
   205         if (valid) {
       
   206 
       
   207             if (e.changedTouches) {
       
   208                 if (e.changedTouches.length === 1 && e.touches.length === 0) {
       
   209                     endEvent = e.changedTouches[0];
       
   210                 } else {
       
   211                     valid = false;
       
   212                 }
       
   213             }
       
   214 
       
   215             if (valid) {
       
   216 
       
   217                 params = subscriber._extra;
       
   218                 preventDefault = params[PREVENT_DEFAULT];
       
   219 
       
   220                 if (preventDefault) {
       
   221                     // preventDefault is a boolean or function
       
   222                     if (!preventDefault.call || preventDefault(e)) {
       
   223                         e.preventDefault();
       
   224                     }
       
   225                 }
       
   226 
       
   227                 startTime = start.flick.time;
       
   228                 endTime = new Date().getTime();
       
   229                 time = endTime - startTime;
       
   230 
       
   231                 xyDistance = [
       
   232                     endEvent.pageX - start.pageX,
       
   233                     endEvent.pageY - start.pageY
       
   234                 ];
       
   235 
       
   236                 if (params.axis) {
       
   237                     axis = params.axis;
       
   238                 } else {
       
   239                     axis = (Math.abs(xyDistance[0]) >= Math.abs(xyDistance[1])) ? 'x' : 'y';
       
   240                 }
       
   241 
       
   242                 distance = xyDistance[(axis === 'x') ? 0 : 1];
       
   243                 velocity = (time !== 0) ? distance/time : 0;
       
   244 
       
   245                 if (isFinite(velocity) && (Math.abs(distance) >= params[MIN_DISTANCE]) && (Math.abs(velocity)  >= params[MIN_VELOCITY])) {
       
   246 
       
   247                     e.type = "flick";
       
   248                     e.flick = {
       
   249                         time:time,
       
   250                         distance: distance,
       
   251                         velocity:velocity,
       
   252                         axis: axis,
       
   253                         start : start
       
   254                     };
       
   255 
       
   256                     ce.fire(e);
       
   257 
       
   258                 }
       
   259 
       
   260                 subscriber[_FLICK_START] = null;
       
   261             }
       
   262         }
       
   263     },
       
   264 
       
   265     MIN_VELOCITY : 0,
       
   266     MIN_DISTANCE : 0,
       
   267     PREVENT_DEFAULT : false
       
   268 });
       
   269 
       
   270 
       
   271 }, '@VERSION@', {"requires": ["node-base", "event-touch", "event-synthetic"]});