Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

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