[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/event-contextmenu/ -> event-contextmenu.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-contextmenu', function (Y, NAME) {
   9  
  10  /**
  11   * Provides extended keyboard support for the "contextmenu" event such that:
  12   * <ul>
  13   * <li>The browser's default context menu is suppressed regardless of how the event is triggered.</li>
  14   * <li>On Windows the "contextmenu" event is fired consistently regardless of whether the user
  15   * pressed the Menu key or Shift + F10.</li>
  16   * <li>When the "contextmenu" event is fired via the keyboard, the pageX, pageY, clientX and clientY
  17   * properties reference the center of the event target. This makes it easy for "contextmenu" event listeners
  18   * to position an overlay in response to the event by not having to worry about special handling of the x
  19   * and y coordinates based on the device that fired the event.</li>
  20   * <li>For Webkit and Gecko on the Mac it enables the use of the Shift + Control + Option + M keyboard
  21   * shortcut to fire the "contextmenu" event, which (by default) is only available when VoiceOver
  22   * (the screen reader on the Mac) is enabled.</li>
  23   * <li>For Opera on the Mac it ensures the "contextmenu" event is fired when the user presses
  24   * Shift + Command + M (Opera's context menu keyboard shortcut).</li>
  25   * </ul>
  26   * @module event-contextmenu
  27   * @requires event
  28   */
  29  
  30  var Event = Y.Event,
  31      DOM = Y.DOM,
  32      UA = Y.UA,
  33      OS = Y.UA.os,
  34  
  35      ie = UA.ie,
  36      gecko = UA.gecko,
  37      webkit = UA.webkit,
  38      opera = UA.opera,
  39  
  40      isWin = (OS === "windows"),
  41      isMac = (OS === "macintosh"),
  42  
  43      eventData = {},
  44  
  45      conf = {
  46  
  47          on: function (node, subscription, notifier, filter) {
  48  
  49              var handles = [];
  50  
  51              handles.push(Event._attach(["contextmenu", function (e) {
  52  
  53                  // Any developer listening for the "contextmenu" event is likely
  54                  // going to call preventDefault() to prevent the display of
  55                  // the browser's context menu. So, you know, save them a step.
  56                  e.preventDefault();
  57  
  58                  var id = Y.stamp(node),
  59                      data = eventData[id];
  60  
  61                  if (data) {
  62                      e.clientX = data.clientX;
  63                      e.clientY = data.clientY;
  64                      e.pageX = data.pageX;
  65                      e.pageY = data.pageY;
  66                      delete eventData[id];
  67                  }
  68  
  69                  notifier.fire(e);
  70  
  71              }, node]));
  72  
  73  
  74              handles.push(node[filter ? "delegate" : "on"]("keydown", function (e) {
  75  
  76                  var target = this.getDOMNode(),
  77                      shiftKey = e.shiftKey,
  78                      keyCode = e.keyCode,
  79                      shiftF10 = (shiftKey && keyCode == 121),
  80                      menuKey = (isWin && keyCode == 93),
  81                      ctrlKey = e.ctrlKey,
  82                      mKey = (keyCode === 77),
  83                      macWebkitAndGeckoShortcut = (isMac && (webkit || gecko) && ctrlKey && shiftKey && e.altKey && mKey),
  84  
  85                      // Note: The context menu keyboard shortcut for Opera on the Mac is Shift + Cmd (metaKey) + M,
  86                      // but e.metaKey is false for Opera, and Opera sets e.ctrlKey to true instead.
  87                      macOperaShortcut = (isMac && opera && ctrlKey && shiftKey && mKey),
  88  
  89                      clientX = 0,
  90                      clientY = 0,
  91                      scrollX,
  92                      scrollY,
  93                      pageX,
  94                      pageY,
  95                      xy,
  96                      x,
  97                      y;
  98  
  99  
 100                  if ((isWin && (shiftF10 || menuKey)) ||
 101                          (macWebkitAndGeckoShortcut || macOperaShortcut)) {
 102  
 103                      // Need to call preventDefault() here b/c:
 104                      // 1) To prevent IE's menubar from gaining focus when the
 105                      // user presses Shift + F10
 106                      // 2) In Firefox and Opera for Win, Shift + F10 will display a
 107                      // context menu, but won't fire the "contextmenu" event. So, need
 108                      // to call preventDefault() to prevent the display of the
 109                      // browser's context menu
 110                      // 3) For Opera on the Mac the context menu keyboard shortcut
 111                      // (Shift + Cmd + M) will display a context menu, but like Firefox
 112                      // and Opera on windows, Opera doesn't fire a "contextmenu" event,
 113                      // so preventDefault() is just used to supress Opera's
 114                      // default context menu.
 115                      if (((ie || (isWin && (gecko || opera))) && shiftF10) || macOperaShortcut) {
 116                          e.preventDefault();
 117                      }
 118  
 119                      xy = DOM.getXY(target);
 120                      x = xy[0];
 121                      y = xy[1];
 122                      scrollX = DOM.docScrollX();
 123                      scrollY = DOM.docScrollY();
 124  
 125                      // Protect against instances where xy and might not be returned,
 126                      // for example if the target is the document.
 127                      if (!Y.Lang.isUndefined(x)) {
 128                          clientX = (x + (target.offsetWidth/2)) - scrollX;
 129                          clientY = (y + (target.offsetHeight/2)) - scrollY;
 130                      }
 131  
 132                      pageX = clientX + scrollX;
 133                      pageY = clientY + scrollY;
 134  
 135                      // When the "contextmenu" event is fired from the keyboard
 136                      // clientX, clientY, pageX or pageY aren't set to useful
 137                      // values. So, we follow Safari's model here of setting
 138                      // the x & x coords to the center of the event target.
 139  
 140                      if (menuKey || (isWin && webkit && shiftF10)) {
 141                          eventData[Y.stamp(node)] = {
 142                              clientX: clientX,
 143                              clientY: clientY,
 144                              pageX: pageX,
 145                              pageY: pageY
 146                          };
 147                      }
 148  
 149                      // Don't need to call notifier.fire(e) when the Menu key
 150                      // is pressed as it fires the "contextmenu" event by default.
 151                      //
 152                      // In IE the call to preventDefault() for Shift + F10
 153                      // prevents the "contextmenu" event from firing, so we need
 154                      // to call notifier.fire(e)
 155                      //
 156                      // Need to also call notifier.fire(e) for Gecko and Opera since
 157                      // neither Shift + F10 or Shift + Cmd + M fire the "contextmenu" event.
 158                      //
 159                      // Lastly, also need to call notifier.fire(e) for all Mac browsers
 160                      // since neither Shift + Ctrl + Option + M (Webkit and Gecko) or
 161                      // Shift + Command + M (Opera) fire the "contextmenu" event.
 162  
 163                      if (((ie || (isWin && (gecko || opera))) && shiftF10) || isMac) {
 164  
 165                          e.clientX = clientX;
 166                          e.clientY = clientY;
 167                          e.pageX = pageX;
 168                          e.pageY = pageY;
 169  
 170                          notifier.fire(e);
 171                      }
 172  
 173                  }
 174  
 175              }, filter));
 176  
 177              subscription._handles = handles;
 178  
 179          },
 180  
 181          detach: function (node, subscription, notifier) {
 182  
 183              Y.each(subscription._handles, function (handle) {
 184                  handle.detach();
 185              });
 186  
 187          }
 188  
 189      };
 190  
 191  
 192  conf.delegate = conf.on;
 193  conf.detachDelegate = conf.detach;
 194  
 195  
 196  Event.define("contextmenu", conf, true);
 197  
 198  
 199  }, '3.17.2', {"requires": ["event-synthetic", "dom-screen"]});


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