[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/event-tap/ -> event-tap-debug.js (source)

   1  /*
   2  YUI 3.17.2 (build 9c3c78e)
   3  Copyright 2014 Yahoo! Inc. All rights reserved.
   4  Licensed under the BSD License.
   5  http://yuilibrary.com/license/
   6  */
   7  
   8  YUI.add('event-tap', function (Y, NAME) {
   9  
  10  /**
  11  The tap module provides a gesture events, "tap", which normalizes user interactions
  12  across touch and mouse or pointer based input devices.  This can be used by application developers
  13  to build input device agnostic components which behave the same in response to either touch or mouse based
  14  interaction.
  15  
  16  'tap' is like a touchscreen 'click', only it requires much less finger-down time since it listens to touch events,
  17  but reverts to mouse events if touch is not supported.
  18  
  19  @example
  20  
  21      YUI().use('event-tap', function (Y) {
  22          Y.one('#my-button').on('tap', function (e) {
  23              Y.log('Button was tapped on');
  24          });
  25      });
  26  
  27  @module event
  28  @submodule event-tap
  29  @author Andres Garza, matuzak and tilo mitra
  30  @since 3.7.0
  31  
  32  */
  33  var doc = Y.config.doc,
  34      GESTURE_MAP = Y.Event._GESTURE_MAP,
  35      EVT_START = GESTURE_MAP.start,
  36      EVT_TAP = 'tap',
  37      POINTER_EVENT_TEST = /pointer/i,
  38  
  39      HANDLES = {
  40          START: 'Y_TAP_ON_START_HANDLE',
  41          END: 'Y_TAP_ON_END_HANDLE',
  42          CANCEL: 'Y_TAP_ON_CANCEL_HANDLE'
  43      };
  44  
  45  function detachHandles(subscription, handles) {
  46      handles = handles || Y.Object.values(HANDLES);
  47  
  48      Y.Array.each(handles, function (item) {
  49          var handle = subscription[item];
  50          if (handle) {
  51              handle.detach();
  52              subscription[item] = null;
  53          }
  54      });
  55  
  56  }
  57  
  58  
  59  /**
  60  Sets up a "tap" event, that is fired on touch devices in response to a tap event (finger down, finder up).
  61  This event can be used instead of listening for click events which have a 500ms delay on most touch devices.
  62  This event can also be listened for using node.delegate().
  63  
  64  @event tap
  65  @param type {string} "tap"
  66  @param fn {function} The method the event invokes. It receives the event facade of the underlying DOM event.
  67  @for Event
  68  @return {EventHandle} the detach handle
  69  */
  70  Y.Event.define(EVT_TAP, {
  71      publishConfig: {
  72          preventedFn: function (e) {
  73              var sub = e.target.once('click', function (click) {
  74                  click.preventDefault();
  75              });
  76  
  77              // Make sure to detach the subscription during the next event loop
  78              // so this doesn't `preventDefault()` on the wrong click event.
  79              setTimeout(function () {
  80                  sub.detach();
  81              //Setting this to `0` causes the detachment to occur before the click
  82              //comes in on Android 4.0.3-4.0.4. 100ms seems to be a reliable number here
  83              //that works across the board.
  84              }, 100);
  85          }
  86      },
  87  
  88      processArgs: function (args, isDelegate) {
  89  
  90          //if we return for the delegate use case, then the `filter` argument
  91          //returns undefined, and we have to get the filter from sub._extra[0] (ugly)
  92  
  93          if (!isDelegate) {
  94              var extra = args[3];
  95              // remove the extra arguments from the array as specified by
  96              // http://yuilibrary.com/yui/docs/event/synths.html
  97              args.splice(3,1);
  98              return extra;
  99          }
 100      },
 101      /**
 102      This function should set up the node that will eventually fire the event.
 103  
 104      Usage:
 105  
 106          node.on('tap', function (e) {
 107              Y.log('the node was tapped on');
 108          });
 109  
 110      @method on
 111      @param {Node} node
 112      @param {Array} subscription
 113      @param {Boolean} notifier
 114      @public
 115      @static
 116      **/
 117      on: function (node, subscription, notifier) {
 118          subscription[HANDLES.START] = node.on(EVT_START, this._start, this, node, subscription, notifier);
 119      },
 120  
 121      /**
 122      Detaches all event subscriptions set up by the event-tap module
 123  
 124      @method detach
 125      @param {Node} node
 126      @param {Array} subscription
 127      @param {Boolean} notifier
 128      @public
 129      @static
 130      **/
 131      detach: function (node, subscription, notifier) {
 132          detachHandles(subscription);
 133      },
 134  
 135      /**
 136      Event delegation for the 'tap' event. The delegated event will use a
 137      supplied selector or filtering function to test if the event references at least one
 138      node that should trigger the subscription callback.
 139  
 140      Usage:
 141  
 142          node.delegate('tap', function (e) {
 143              Y.log('li a inside node was tapped.');
 144          }, 'li a');
 145  
 146      @method delegate
 147      @param {Node} node
 148      @param {Array} subscription
 149      @param {Boolean} notifier
 150      @param {String | Function} filter
 151      @public
 152      @static
 153      **/
 154      delegate: function (node, subscription, notifier, filter) {
 155          subscription[HANDLES.START] = Y.delegate(EVT_START, function (e) {
 156              this._start(e, node, subscription, notifier, true);
 157          }, node, filter, this);
 158      },
 159  
 160      /**
 161      Detaches the delegated event subscriptions set up by the event-tap module.
 162      Only used if you use node.delegate(...) instead of node.on(...);
 163  
 164      @method detachDelegate
 165      @param {Node} node
 166      @param {Array} subscription
 167      @param {Boolean} notifier
 168      @public
 169      @static
 170      **/
 171      detachDelegate: function (node, subscription, notifier) {
 172          detachHandles(subscription);
 173      },
 174  
 175      /**
 176      Called when the monitor(s) are tapped on, either through touchstart or mousedown.
 177  
 178      @method _start
 179      @param {DOMEventFacade} event
 180      @param {Node} node
 181      @param {Array} subscription
 182      @param {Boolean} notifier
 183      @param {Boolean} delegate
 184      @protected
 185      @static
 186      **/
 187      _start: function (event, node, subscription, notifier, delegate) {
 188  
 189          var context = {
 190                  canceled: false,
 191                  eventType: event.type
 192              },
 193              preventMouse = subscription.preventMouse || false;
 194  
 195          //move ways to quit early to the top.
 196          // no right clicks
 197          if (event.button && event.button === 3) {
 198              return;
 199          }
 200  
 201          // for now just support a 1 finger count (later enhance via config)
 202          if (event.touches && event.touches.length !== 1) {
 203              return;
 204          }
 205  
 206          context.node = delegate ? event.currentTarget : node;
 207  
 208          //There is a double check in here to support event simulation tests, in which
 209          //event.touches can be undefined when simulating 'touchstart' on touch devices.
 210          if (event.touches) {
 211            context.startXY = [ event.touches[0].pageX, event.touches[0].pageY ];
 212          }
 213          else {
 214            context.startXY = [ event.pageX, event.pageY ];
 215          }
 216  
 217          //If `onTouchStart()` was called by a touch event, set up touch event subscriptions.
 218          //Otherwise, set up mouse/pointer event event subscriptions.
 219          if (event.touches) {
 220  
 221              subscription[HANDLES.END] = node.once('touchend', this._end, this, node, subscription, notifier, delegate, context);
 222              subscription[HANDLES.CANCEL] = node.once('touchcancel', this.detach, this, node, subscription, notifier, delegate, context);
 223  
 224              //Since this is a touch* event, there will be corresponding mouse events
 225              //that will be fired. We don't want these events to get picked up and fire
 226              //another `tap` event, so we'll set this variable to `true`.
 227              subscription.preventMouse = true;
 228          }
 229  
 230          //Only add these listeners if preventMouse is `false`
 231          //ie: not when touch events have already been subscribed to
 232          else if (context.eventType.indexOf('mouse') !== -1 && !preventMouse) {
 233              subscription[HANDLES.END] = node.once('mouseup', this._end, this, node, subscription, notifier, delegate, context);
 234              subscription[HANDLES.CANCEL] = node.once('mousecancel', this.detach, this, node, subscription, notifier, delegate, context);
 235          }
 236  
 237          //If a mouse event comes in after a touch event, it will go in here and
 238          //reset preventMouse to `true`.
 239          //If a mouse event comes in without a prior touch event, preventMouse will be
 240          //false in any case, so this block doesn't do anything.
 241          else if (context.eventType.indexOf('mouse') !== -1 && preventMouse) {
 242              subscription.preventMouse = false;
 243          }
 244  
 245          else if (POINTER_EVENT_TEST.test(context.eventType)) {
 246              subscription[HANDLES.END] = node.once(GESTURE_MAP.end, this._end, this, node, subscription, notifier, delegate, context);
 247              subscription[HANDLES.CANCEL] = node.once(GESTURE_MAP.cancel, this.detach, this, node, subscription, notifier, delegate, context);
 248          }
 249  
 250      },
 251  
 252  
 253      /**
 254      Called when the monitor(s) fires a touchend event (or the mouse equivalent).
 255      This method fires the 'tap' event if certain requirements are met.
 256  
 257      @method _end
 258      @param {DOMEventFacade} event
 259      @param {Node} node
 260      @param {Array} subscription
 261      @param {Boolean} notifier
 262      @param {Boolean} delegate
 263      @param {Object} context
 264      @protected
 265      @static
 266      **/
 267      _end: function (event, node, subscription, notifier, delegate, context) {
 268          var startXY = context.startXY,
 269              endXY,
 270              clientXY,
 271              sensitivity = 15;
 272  
 273          if (subscription._extra && subscription._extra.sensitivity >= 0) {
 274              sensitivity = subscription._extra.sensitivity;
 275          }
 276  
 277          //There is a double check in here to support event simulation tests, in which
 278          //event.touches can be undefined when simulating 'touchstart' on touch devices.
 279          if (event.changedTouches) {
 280            endXY = [ event.changedTouches[0].pageX, event.changedTouches[0].pageY ];
 281            clientXY = [event.changedTouches[0].clientX, event.changedTouches[0].clientY];
 282          }
 283          else {
 284            endXY = [ event.pageX, event.pageY ];
 285            clientXY = [event.clientX, event.clientY];
 286          }
 287  
 288          // make sure mouse didn't move
 289          if (Math.abs(endXY[0] - startXY[0]) <= sensitivity && Math.abs(endXY[1] - startXY[1]) <= sensitivity) {
 290  
 291              event.type = EVT_TAP;
 292              event.pageX = endXY[0];
 293              event.pageY = endXY[1];
 294              event.clientX = clientXY[0];
 295              event.clientY = clientXY[1];
 296              event.currentTarget = context.node;
 297  
 298              notifier.fire(event);
 299          }
 300  
 301          detachHandles(subscription, [HANDLES.END, HANDLES.CANCEL]);
 302      }
 303  });
 304  
 305  
 306  }, '3.17.2', {"requires": ["node-base", "event-base", "event-touch", "event-synthetic"]});


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1