[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/webroot/rsrc/externals/javelin/core/ -> Event.js (source)

   1  /**
   2   * @requires javelin-install
   3   * @provides javelin-event
   4   * @javelin
   5   */
   6  
   7  /**
   8   * A generic event, routed by @{class:JX.Stratcom}. All events within Javelin
   9   * are represented by a {@class:JX.Event}, regardless of whether they originate
  10   * from a native DOM event (like a mouse click) or are custom application
  11   * events.
  12   *
  13   * See @{article:Concepts: Event Delegation} for an introduction to Javelin's
  14   * event delegation model.
  15   *
  16   * Events have a propagation model similar to native Javascript events, in that
  17   * they can be stopped with stop() (which stops them from continuing to
  18   * propagate to other handlers) or prevented with prevent() (which prevents them
  19   * from taking their default action, like following a link). You can do both at
  20   * once with kill().
  21   *
  22   * @task stop Stopping Event Behaviors
  23   * @task info Getting Event Information
  24   */
  25  JX.install('Event', {
  26    members : {
  27  
  28      /**
  29       * Stop an event from continuing to propagate. No other handler will
  30       * receive this event, but its default behavior will still occur. See
  31       * ""Using Events"" for more information on the distinction between
  32       * 'stopping' and 'preventing' an event. See also prevent() (which prevents
  33       * an event but does not stop it) and kill() (which stops and prevents an
  34       * event).
  35       *
  36       * @return this
  37       * @task stop
  38       */
  39      stop : function() {
  40        var r = this.getRawEvent();
  41        if (r) {
  42          r.cancelBubble = true;
  43          r.stopPropagation && r.stopPropagation();
  44        }
  45        this.setStopped(true);
  46        return this;
  47      },
  48  
  49  
  50      /**
  51       * Prevent an event's default action. This depends on the event type, but
  52       * the common default actions are following links, submitting forms,
  53       * and typing text. Event prevention is generally used when you have a link
  54       * or form which work properly without Javascript but have a specialized
  55       * Javascript behavior. When you intercept the event and make the behavior
  56       * occur, you prevent it to keep the browser from following the link.
  57       *
  58       * Preventing an event does not stop it from propagating, so other handlers
  59       * will still receive it. See ""Using Events"" for more information on the
  60       * distinction between 'stopping' and 'preventing' an event. See also
  61       * stop() (which stops an event but does not prevent it) and kill()
  62       * (which stops and prevents an event).
  63       *
  64       * @return this
  65       * @task stop
  66       */
  67      prevent : function() {
  68        var r = this.getRawEvent();
  69        if (r) {
  70          r.returnValue = false;
  71          r.preventDefault && r.preventDefault();
  72        }
  73        this.setPrevented(true);
  74        return this;
  75      },
  76  
  77  
  78      /**
  79       * Stop and prevent an event, which stops it from propagating and prevents
  80       * its defualt behavior. This is a convenience function, see stop() and
  81       * prevent() for information on what it means to stop or prevent an event.
  82       *
  83       * @return this
  84       * @task stop
  85       */
  86      kill : function() {
  87        this.prevent();
  88        this.stop();
  89        return this;
  90      },
  91  
  92  
  93      /**
  94       * Get the special key (like tab or return), if any,  associated with this
  95       * event. Browsers report special keys differently;  this method allows you
  96       * to identify a keypress in a browser-agnostic way. Note that this detects
  97       * only some special keys: delete, tab, return escape, left, up, right,
  98       * down.
  99       *
 100       * For example, if you want to react to the escape key being pressed, you
 101       * could install a listener like this:
 102       *
 103       *  JX.Stratcom.listen('keydown', 'example', function(e) {
 104       *    if (e.getSpecialKey() == 'esc') {
 105       *      JX.log("You pressed 'Escape'! Well done! Bravo!");
 106       *    }
 107       *  });
 108       *
 109       * @return string|null ##null## if there is no associated special key,
 110       *                     or one of the strings 'delete', 'tab', 'return',
 111       *                     'esc', 'left', 'up', 'right', or 'down'.
 112       * @task info
 113       */
 114      getSpecialKey : function() {
 115        var r = this.getRawEvent();
 116        if (!r) {
 117          return null;
 118        }
 119  
 120        return JX.Event._keymap[r.keyCode] || null;
 121      },
 122  
 123  
 124      /**
 125       * Get whether the mouse button associated with the mouse event is the
 126       * right-side button in a browser-agnostic way.
 127       *
 128       * @return bool
 129       * @task info
 130       */
 131      isRightButton : function() {
 132        var r = this.getRawEvent();
 133        return r.which == 3 || r.button == 2;
 134      },
 135  
 136      /**
 137       * Determine if a mouse event is a normal event (left mouse button, no
 138       * modifier keys).
 139       *
 140       * @return bool
 141       * @task info
 142       */
 143      isNormalMouseEvent : function() {
 144        var supportedEvents = {'click': 1, 'mouseup': 1, 'mousedown': 1};
 145        if (!(this.getType() in supportedEvents)) {
 146          return false;
 147        }
 148  
 149        var r = this.getRawEvent();
 150  
 151        if (r.metaKey || r.altKey || r.ctrlKey || r.shiftKey) {
 152          return false;
 153        }
 154  
 155        if (('which' in r) && (r.which != 1)) {
 156          return false;
 157        }
 158  
 159        if (('button' in r) && r.button) {
 160          if ('which' in r) {
 161            return false;
 162          // IE won't have which and has left click == 1 here
 163          } else if (r.button != 1) {
 164            return false;
 165          }
 166        }
 167  
 168        return true;
 169      },
 170  
 171  
 172      /**
 173       * Determine if a click event is a normal click (left mouse button, no
 174       * modifier keys).
 175       *
 176       * @return bool
 177       * @task info
 178       */
 179      isNormalClick : function() {
 180        if (this.getType() != 'click') {
 181          return false;
 182        }
 183  
 184        return this.isNormalMouseEvent();
 185      },
 186  
 187  
 188      /**
 189       * Get the node corresponding to the specified key in this event's node map.
 190       * This is a simple helper method that makes the API for accessing nodes
 191       * less ugly.
 192       *
 193       *  JX.Stratcom.listen('click', 'tag:a', function(e) {
 194       *    var a = e.getNode('tag:a');
 195       *    // do something with the link that was clicked
 196       *  });
 197       *
 198       * @param  string     sigil or stratcom node key
 199       * @return node|null  Node mapped to the specified key, or null if it the
 200       *                    key does not exist. The available keys include:
 201       *                    - 'tag:'+tag - first node of each type
 202       *                    - 'id:'+id - all nodes with an id
 203       *                    - sigil - first node of each sigil
 204       * @task info
 205       */
 206      getNode : function(key) {
 207        return this.getNodes()[key] || null;
 208      },
 209  
 210  
 211      /**
 212       * Get the metadata associated with the node that corresponds to the key
 213       * in this event's node map. This is a simple helper method that makes
 214       * the API for accessing metadata associated with specific nodes less ugly.
 215       *
 216       *  JX.Stratcom.listen('click', 'tag:a', function(event) {
 217       *    var anchorData = event.getNodeData('tag:a');
 218       *    // do something with the metadata of the link that was clicked
 219       *  });
 220       *
 221       * @param  string   sigil or stratcom node key
 222       * @return dict     dictionary of the node's metadata
 223       * @task info
 224       */
 225      getNodeData : function(key) {
 226        // Evade static analysis - JX.Stratcom
 227        return JX['Stratcom'].getData(this.getNode(key));
 228      }
 229    },
 230  
 231    statics : {
 232      _keymap : {
 233        8     : 'delete',
 234        9     : 'tab',
 235        // On Windows and Linux, Chrome sends '10' for return. On Mac OS X, it
 236        // sends 13. Other browsers evidence varying degrees of diversity in their
 237        // behavior. Treat '10' and '13' identically.
 238        10    : 'return',
 239        13    : 'return',
 240        27    : 'esc',
 241        37    : 'left',
 242        38    : 'up',
 243        39    : 'right',
 244        40    : 'down',
 245        63232 : 'up',
 246        63233 : 'down',
 247        62234 : 'left',
 248        62235 : 'right'
 249      }
 250    },
 251  
 252    properties : {
 253  
 254      /**
 255       * Native Javascript event which generated this @{class:JX.Event}. Not every
 256       * event is generated by a native event, so there may be ##null## in
 257       * this field.
 258       *
 259       * @type Event|null
 260       * @task info
 261       */
 262      rawEvent : null,
 263  
 264      /**
 265       * String describing the event type, like 'click' or 'mousedown'. This
 266       * may also be an application or object event.
 267       *
 268       * @type string
 269       * @task info
 270       */
 271      type : null,
 272  
 273      /**
 274       * If available, the DOM node where this event occurred. For example, if
 275       * this event is a click on a button, the target will be the button which
 276       * was clicked. Application events will not have a target, so this property
 277       * will return the value ##null##.
 278       *
 279       * @type DOMNode|null
 280       * @task info
 281       */
 282      target : null,
 283  
 284      /**
 285       * Metadata attached to nodes associated with this event.
 286       *
 287       * For native events, the DOM is walked from the event target to the root
 288       * element. Each sigil which is encountered while walking up the tree is
 289       * added to the map as a key. If the node has associated metainformation,
 290       * it is set as the value; otherwise, the value is null.
 291       *
 292       * @type dict<string, *>
 293       * @task info
 294       */
 295      data : null,
 296  
 297      /**
 298       * Sigil path this event was activated from. TODO: explain this
 299       *
 300       * @type list<string>
 301       * @task info
 302       */
 303      path : [],
 304  
 305      /**
 306       * True if propagation of the event has been stopped. See stop().
 307       *
 308       * @type bool
 309       * @task stop
 310       */
 311      stopped : false,
 312  
 313      /**
 314       * True if default behavior of the event has been prevented. See prevent().
 315       *
 316       * @type bool
 317       * @task stop
 318       */
 319      prevented : false,
 320  
 321      /**
 322       * @task info
 323       */
 324      nodes : {},
 325  
 326      /**
 327       * @task info
 328       */
 329      nodeDistances : {}
 330    },
 331  
 332    /**
 333     * @{class:JX.Event} installs a toString() method in ##__DEV__## which allows
 334     * you to log or print events and get a reasonable representation of them:
 335     *
 336     *  Event<'click', ['path', 'stuff'], [object HTMLDivElement]>
 337     */
 338    initialize : function() {
 339      if (__DEV__) {
 340        JX.Event.prototype.toString = function() {
 341          var path = '['+this.getPath().join(', ')+']';
 342          return 'Event<'+this.getType()+', '+path+', '+this.getTarget()+'>';
 343        };
 344      }
 345    }
 346  });


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1