0
|
1 define( [
|
|
2 "./core",
|
|
3 "./var/document",
|
|
4 "./var/documentElement",
|
|
5 "./var/isFunction",
|
|
6 "./var/rnothtmlwhite",
|
|
7 "./var/slice",
|
|
8 "./data/var/dataPriv",
|
|
9 "./core/nodeName",
|
|
10
|
|
11 "./core/init",
|
|
12 "./selector"
|
|
13 ], function( jQuery, document, documentElement, isFunction, rnothtmlwhite,
|
|
14 slice, dataPriv, nodeName ) {
|
|
15
|
|
16 "use strict";
|
|
17
|
|
18 var
|
|
19 rkeyEvent = /^key/,
|
|
20 rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
|
|
21 rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
|
|
22
|
|
23 function returnTrue() {
|
|
24 return true;
|
|
25 }
|
|
26
|
|
27 function returnFalse() {
|
|
28 return false;
|
|
29 }
|
|
30
|
|
31 // Support: IE <=9 only
|
|
32 // See #13393 for more info
|
|
33 function safeActiveElement() {
|
|
34 try {
|
|
35 return document.activeElement;
|
|
36 } catch ( err ) { }
|
|
37 }
|
|
38
|
|
39 function on( elem, types, selector, data, fn, one ) {
|
|
40 var origFn, type;
|
|
41
|
|
42 // Types can be a map of types/handlers
|
|
43 if ( typeof types === "object" ) {
|
|
44
|
|
45 // ( types-Object, selector, data )
|
|
46 if ( typeof selector !== "string" ) {
|
|
47
|
|
48 // ( types-Object, data )
|
|
49 data = data || selector;
|
|
50 selector = undefined;
|
|
51 }
|
|
52 for ( type in types ) {
|
|
53 on( elem, type, selector, data, types[ type ], one );
|
|
54 }
|
|
55 return elem;
|
|
56 }
|
|
57
|
|
58 if ( data == null && fn == null ) {
|
|
59
|
|
60 // ( types, fn )
|
|
61 fn = selector;
|
|
62 data = selector = undefined;
|
|
63 } else if ( fn == null ) {
|
|
64 if ( typeof selector === "string" ) {
|
|
65
|
|
66 // ( types, selector, fn )
|
|
67 fn = data;
|
|
68 data = undefined;
|
|
69 } else {
|
|
70
|
|
71 // ( types, data, fn )
|
|
72 fn = data;
|
|
73 data = selector;
|
|
74 selector = undefined;
|
|
75 }
|
|
76 }
|
|
77 if ( fn === false ) {
|
|
78 fn = returnFalse;
|
|
79 } else if ( !fn ) {
|
|
80 return elem;
|
|
81 }
|
|
82
|
|
83 if ( one === 1 ) {
|
|
84 origFn = fn;
|
|
85 fn = function( event ) {
|
|
86
|
|
87 // Can use an empty set, since event contains the info
|
|
88 jQuery().off( event );
|
|
89 return origFn.apply( this, arguments );
|
|
90 };
|
|
91
|
|
92 // Use same guid so caller can remove using origFn
|
|
93 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
|
|
94 }
|
|
95 return elem.each( function() {
|
|
96 jQuery.event.add( this, types, fn, data, selector );
|
|
97 } );
|
|
98 }
|
|
99
|
|
100 /*
|
|
101 * Helper functions for managing events -- not part of the public interface.
|
|
102 * Props to Dean Edwards' addEvent library for many of the ideas.
|
|
103 */
|
|
104 jQuery.event = {
|
|
105
|
|
106 global: {},
|
|
107
|
|
108 add: function( elem, types, handler, data, selector ) {
|
|
109
|
|
110 var handleObjIn, eventHandle, tmp,
|
|
111 events, t, handleObj,
|
|
112 special, handlers, type, namespaces, origType,
|
|
113 elemData = dataPriv.get( elem );
|
|
114
|
|
115 // Don't attach events to noData or text/comment nodes (but allow plain objects)
|
|
116 if ( !elemData ) {
|
|
117 return;
|
|
118 }
|
|
119
|
|
120 // Caller can pass in an object of custom data in lieu of the handler
|
|
121 if ( handler.handler ) {
|
|
122 handleObjIn = handler;
|
|
123 handler = handleObjIn.handler;
|
|
124 selector = handleObjIn.selector;
|
|
125 }
|
|
126
|
|
127 // Ensure that invalid selectors throw exceptions at attach time
|
|
128 // Evaluate against documentElement in case elem is a non-element node (e.g., document)
|
|
129 if ( selector ) {
|
|
130 jQuery.find.matchesSelector( documentElement, selector );
|
|
131 }
|
|
132
|
|
133 // Make sure that the handler has a unique ID, used to find/remove it later
|
|
134 if ( !handler.guid ) {
|
|
135 handler.guid = jQuery.guid++;
|
|
136 }
|
|
137
|
|
138 // Init the element's event structure and main handler, if this is the first
|
|
139 if ( !( events = elemData.events ) ) {
|
|
140 events = elemData.events = {};
|
|
141 }
|
|
142 if ( !( eventHandle = elemData.handle ) ) {
|
|
143 eventHandle = elemData.handle = function( e ) {
|
|
144
|
|
145 // Discard the second event of a jQuery.event.trigger() and
|
|
146 // when an event is called after a page has unloaded
|
|
147 return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
|
|
148 jQuery.event.dispatch.apply( elem, arguments ) : undefined;
|
|
149 };
|
|
150 }
|
|
151
|
|
152 // Handle multiple events separated by a space
|
|
153 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
|
|
154 t = types.length;
|
|
155 while ( t-- ) {
|
|
156 tmp = rtypenamespace.exec( types[ t ] ) || [];
|
|
157 type = origType = tmp[ 1 ];
|
|
158 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
|
|
159
|
|
160 // There *must* be a type, no attaching namespace-only handlers
|
|
161 if ( !type ) {
|
|
162 continue;
|
|
163 }
|
|
164
|
|
165 // If event changes its type, use the special event handlers for the changed type
|
|
166 special = jQuery.event.special[ type ] || {};
|
|
167
|
|
168 // If selector defined, determine special event api type, otherwise given type
|
|
169 type = ( selector ? special.delegateType : special.bindType ) || type;
|
|
170
|
|
171 // Update special based on newly reset type
|
|
172 special = jQuery.event.special[ type ] || {};
|
|
173
|
|
174 // handleObj is passed to all event handlers
|
|
175 handleObj = jQuery.extend( {
|
|
176 type: type,
|
|
177 origType: origType,
|
|
178 data: data,
|
|
179 handler: handler,
|
|
180 guid: handler.guid,
|
|
181 selector: selector,
|
|
182 needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
|
|
183 namespace: namespaces.join( "." )
|
|
184 }, handleObjIn );
|
|
185
|
|
186 // Init the event handler queue if we're the first
|
|
187 if ( !( handlers = events[ type ] ) ) {
|
|
188 handlers = events[ type ] = [];
|
|
189 handlers.delegateCount = 0;
|
|
190
|
|
191 // Only use addEventListener if the special events handler returns false
|
|
192 if ( !special.setup ||
|
|
193 special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
|
|
194
|
|
195 if ( elem.addEventListener ) {
|
|
196 elem.addEventListener( type, eventHandle );
|
|
197 }
|
|
198 }
|
|
199 }
|
|
200
|
|
201 if ( special.add ) {
|
|
202 special.add.call( elem, handleObj );
|
|
203
|
|
204 if ( !handleObj.handler.guid ) {
|
|
205 handleObj.handler.guid = handler.guid;
|
|
206 }
|
|
207 }
|
|
208
|
|
209 // Add to the element's handler list, delegates in front
|
|
210 if ( selector ) {
|
|
211 handlers.splice( handlers.delegateCount++, 0, handleObj );
|
|
212 } else {
|
|
213 handlers.push( handleObj );
|
|
214 }
|
|
215
|
|
216 // Keep track of which events have ever been used, for event optimization
|
|
217 jQuery.event.global[ type ] = true;
|
|
218 }
|
|
219
|
|
220 },
|
|
221
|
|
222 // Detach an event or set of events from an element
|
|
223 remove: function( elem, types, handler, selector, mappedTypes ) {
|
|
224
|
|
225 var j, origCount, tmp,
|
|
226 events, t, handleObj,
|
|
227 special, handlers, type, namespaces, origType,
|
|
228 elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
|
|
229
|
|
230 if ( !elemData || !( events = elemData.events ) ) {
|
|
231 return;
|
|
232 }
|
|
233
|
|
234 // Once for each type.namespace in types; type may be omitted
|
|
235 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
|
|
236 t = types.length;
|
|
237 while ( t-- ) {
|
|
238 tmp = rtypenamespace.exec( types[ t ] ) || [];
|
|
239 type = origType = tmp[ 1 ];
|
|
240 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
|
|
241
|
|
242 // Unbind all events (on this namespace, if provided) for the element
|
|
243 if ( !type ) {
|
|
244 for ( type in events ) {
|
|
245 jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
|
|
246 }
|
|
247 continue;
|
|
248 }
|
|
249
|
|
250 special = jQuery.event.special[ type ] || {};
|
|
251 type = ( selector ? special.delegateType : special.bindType ) || type;
|
|
252 handlers = events[ type ] || [];
|
|
253 tmp = tmp[ 2 ] &&
|
|
254 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
|
|
255
|
|
256 // Remove matching events
|
|
257 origCount = j = handlers.length;
|
|
258 while ( j-- ) {
|
|
259 handleObj = handlers[ j ];
|
|
260
|
|
261 if ( ( mappedTypes || origType === handleObj.origType ) &&
|
|
262 ( !handler || handler.guid === handleObj.guid ) &&
|
|
263 ( !tmp || tmp.test( handleObj.namespace ) ) &&
|
|
264 ( !selector || selector === handleObj.selector ||
|
|
265 selector === "**" && handleObj.selector ) ) {
|
|
266 handlers.splice( j, 1 );
|
|
267
|
|
268 if ( handleObj.selector ) {
|
|
269 handlers.delegateCount--;
|
|
270 }
|
|
271 if ( special.remove ) {
|
|
272 special.remove.call( elem, handleObj );
|
|
273 }
|
|
274 }
|
|
275 }
|
|
276
|
|
277 // Remove generic event handler if we removed something and no more handlers exist
|
|
278 // (avoids potential for endless recursion during removal of special event handlers)
|
|
279 if ( origCount && !handlers.length ) {
|
|
280 if ( !special.teardown ||
|
|
281 special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
|
|
282
|
|
283 jQuery.removeEvent( elem, type, elemData.handle );
|
|
284 }
|
|
285
|
|
286 delete events[ type ];
|
|
287 }
|
|
288 }
|
|
289
|
|
290 // Remove data and the expando if it's no longer used
|
|
291 if ( jQuery.isEmptyObject( events ) ) {
|
|
292 dataPriv.remove( elem, "handle events" );
|
|
293 }
|
|
294 },
|
|
295
|
|
296 dispatch: function( nativeEvent ) {
|
|
297
|
|
298 // Make a writable jQuery.Event from the native event object
|
|
299 var event = jQuery.event.fix( nativeEvent );
|
|
300
|
|
301 var i, j, ret, matched, handleObj, handlerQueue,
|
|
302 args = new Array( arguments.length ),
|
|
303 handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
|
|
304 special = jQuery.event.special[ event.type ] || {};
|
|
305
|
|
306 // Use the fix-ed jQuery.Event rather than the (read-only) native event
|
|
307 args[ 0 ] = event;
|
|
308
|
|
309 for ( i = 1; i < arguments.length; i++ ) {
|
|
310 args[ i ] = arguments[ i ];
|
|
311 }
|
|
312
|
|
313 event.delegateTarget = this;
|
|
314
|
|
315 // Call the preDispatch hook for the mapped type, and let it bail if desired
|
|
316 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
|
|
317 return;
|
|
318 }
|
|
319
|
|
320 // Determine handlers
|
|
321 handlerQueue = jQuery.event.handlers.call( this, event, handlers );
|
|
322
|
|
323 // Run delegates first; they may want to stop propagation beneath us
|
|
324 i = 0;
|
|
325 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
|
|
326 event.currentTarget = matched.elem;
|
|
327
|
|
328 j = 0;
|
|
329 while ( ( handleObj = matched.handlers[ j++ ] ) &&
|
|
330 !event.isImmediatePropagationStopped() ) {
|
|
331
|
|
332 // Triggered event must either 1) have no namespace, or 2) have namespace(s)
|
|
333 // a subset or equal to those in the bound event (both can have no namespace).
|
|
334 if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
|
|
335
|
|
336 event.handleObj = handleObj;
|
|
337 event.data = handleObj.data;
|
|
338
|
|
339 ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
|
|
340 handleObj.handler ).apply( matched.elem, args );
|
|
341
|
|
342 if ( ret !== undefined ) {
|
|
343 if ( ( event.result = ret ) === false ) {
|
|
344 event.preventDefault();
|
|
345 event.stopPropagation();
|
|
346 }
|
|
347 }
|
|
348 }
|
|
349 }
|
|
350 }
|
|
351
|
|
352 // Call the postDispatch hook for the mapped type
|
|
353 if ( special.postDispatch ) {
|
|
354 special.postDispatch.call( this, event );
|
|
355 }
|
|
356
|
|
357 return event.result;
|
|
358 },
|
|
359
|
|
360 handlers: function( event, handlers ) {
|
|
361 var i, handleObj, sel, matchedHandlers, matchedSelectors,
|
|
362 handlerQueue = [],
|
|
363 delegateCount = handlers.delegateCount,
|
|
364 cur = event.target;
|
|
365
|
|
366 // Find delegate handlers
|
|
367 if ( delegateCount &&
|
|
368
|
|
369 // Support: IE <=9
|
|
370 // Black-hole SVG <use> instance trees (trac-13180)
|
|
371 cur.nodeType &&
|
|
372
|
|
373 // Support: Firefox <=42
|
|
374 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
|
|
375 // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
|
|
376 // Support: IE 11 only
|
|
377 // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
|
|
378 !( event.type === "click" && event.button >= 1 ) ) {
|
|
379
|
|
380 for ( ; cur !== this; cur = cur.parentNode || this ) {
|
|
381
|
|
382 // Don't check non-elements (#13208)
|
|
383 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
|
|
384 if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
|
|
385 matchedHandlers = [];
|
|
386 matchedSelectors = {};
|
|
387 for ( i = 0; i < delegateCount; i++ ) {
|
|
388 handleObj = handlers[ i ];
|
|
389
|
|
390 // Don't conflict with Object.prototype properties (#13203)
|
|
391 sel = handleObj.selector + " ";
|
|
392
|
|
393 if ( matchedSelectors[ sel ] === undefined ) {
|
|
394 matchedSelectors[ sel ] = handleObj.needsContext ?
|
|
395 jQuery( sel, this ).index( cur ) > -1 :
|
|
396 jQuery.find( sel, this, null, [ cur ] ).length;
|
|
397 }
|
|
398 if ( matchedSelectors[ sel ] ) {
|
|
399 matchedHandlers.push( handleObj );
|
|
400 }
|
|
401 }
|
|
402 if ( matchedHandlers.length ) {
|
|
403 handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
|
|
404 }
|
|
405 }
|
|
406 }
|
|
407 }
|
|
408
|
|
409 // Add the remaining (directly-bound) handlers
|
|
410 cur = this;
|
|
411 if ( delegateCount < handlers.length ) {
|
|
412 handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
|
|
413 }
|
|
414
|
|
415 return handlerQueue;
|
|
416 },
|
|
417
|
|
418 addProp: function( name, hook ) {
|
|
419 Object.defineProperty( jQuery.Event.prototype, name, {
|
|
420 enumerable: true,
|
|
421 configurable: true,
|
|
422
|
|
423 get: isFunction( hook ) ?
|
|
424 function() {
|
|
425 if ( this.originalEvent ) {
|
|
426 return hook( this.originalEvent );
|
|
427 }
|
|
428 } :
|
|
429 function() {
|
|
430 if ( this.originalEvent ) {
|
|
431 return this.originalEvent[ name ];
|
|
432 }
|
|
433 },
|
|
434
|
|
435 set: function( value ) {
|
|
436 Object.defineProperty( this, name, {
|
|
437 enumerable: true,
|
|
438 configurable: true,
|
|
439 writable: true,
|
|
440 value: value
|
|
441 } );
|
|
442 }
|
|
443 } );
|
|
444 },
|
|
445
|
|
446 fix: function( originalEvent ) {
|
|
447 return originalEvent[ jQuery.expando ] ?
|
|
448 originalEvent :
|
|
449 new jQuery.Event( originalEvent );
|
|
450 },
|
|
451
|
|
452 special: {
|
|
453 load: {
|
|
454
|
|
455 // Prevent triggered image.load events from bubbling to window.load
|
|
456 noBubble: true
|
|
457 },
|
|
458 focus: {
|
|
459
|
|
460 // Fire native event if possible so blur/focus sequence is correct
|
|
461 trigger: function() {
|
|
462 if ( this !== safeActiveElement() && this.focus ) {
|
|
463 this.focus();
|
|
464 return false;
|
|
465 }
|
|
466 },
|
|
467 delegateType: "focusin"
|
|
468 },
|
|
469 blur: {
|
|
470 trigger: function() {
|
|
471 if ( this === safeActiveElement() && this.blur ) {
|
|
472 this.blur();
|
|
473 return false;
|
|
474 }
|
|
475 },
|
|
476 delegateType: "focusout"
|
|
477 },
|
|
478 click: {
|
|
479
|
|
480 // For checkbox, fire native event so checked state will be right
|
|
481 trigger: function() {
|
|
482 if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) {
|
|
483 this.click();
|
|
484 return false;
|
|
485 }
|
|
486 },
|
|
487
|
|
488 // For cross-browser consistency, don't fire native .click() on links
|
|
489 _default: function( event ) {
|
|
490 return nodeName( event.target, "a" );
|
|
491 }
|
|
492 },
|
|
493
|
|
494 beforeunload: {
|
|
495 postDispatch: function( event ) {
|
|
496
|
|
497 // Support: Firefox 20+
|
|
498 // Firefox doesn't alert if the returnValue field is not set.
|
|
499 if ( event.result !== undefined && event.originalEvent ) {
|
|
500 event.originalEvent.returnValue = event.result;
|
|
501 }
|
|
502 }
|
|
503 }
|
|
504 }
|
|
505 };
|
|
506
|
|
507 jQuery.removeEvent = function( elem, type, handle ) {
|
|
508
|
|
509 // This "if" is needed for plain objects
|
|
510 if ( elem.removeEventListener ) {
|
|
511 elem.removeEventListener( type, handle );
|
|
512 }
|
|
513 };
|
|
514
|
|
515 jQuery.Event = function( src, props ) {
|
|
516
|
|
517 // Allow instantiation without the 'new' keyword
|
|
518 if ( !( this instanceof jQuery.Event ) ) {
|
|
519 return new jQuery.Event( src, props );
|
|
520 }
|
|
521
|
|
522 // Event object
|
|
523 if ( src && src.type ) {
|
|
524 this.originalEvent = src;
|
|
525 this.type = src.type;
|
|
526
|
|
527 // Events bubbling up the document may have been marked as prevented
|
|
528 // by a handler lower down the tree; reflect the correct value.
|
|
529 this.isDefaultPrevented = src.defaultPrevented ||
|
|
530 src.defaultPrevented === undefined &&
|
|
531
|
|
532 // Support: Android <=2.3 only
|
|
533 src.returnValue === false ?
|
|
534 returnTrue :
|
|
535 returnFalse;
|
|
536
|
|
537 // Create target properties
|
|
538 // Support: Safari <=6 - 7 only
|
|
539 // Target should not be a text node (#504, #13143)
|
|
540 this.target = ( src.target && src.target.nodeType === 3 ) ?
|
|
541 src.target.parentNode :
|
|
542 src.target;
|
|
543
|
|
544 this.currentTarget = src.currentTarget;
|
|
545 this.relatedTarget = src.relatedTarget;
|
|
546
|
|
547 // Event type
|
|
548 } else {
|
|
549 this.type = src;
|
|
550 }
|
|
551
|
|
552 // Put explicitly provided properties onto the event object
|
|
553 if ( props ) {
|
|
554 jQuery.extend( this, props );
|
|
555 }
|
|
556
|
|
557 // Create a timestamp if incoming event doesn't have one
|
|
558 this.timeStamp = src && src.timeStamp || Date.now();
|
|
559
|
|
560 // Mark it as fixed
|
|
561 this[ jQuery.expando ] = true;
|
|
562 };
|
|
563
|
|
564 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
|
|
565 // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
|
|
566 jQuery.Event.prototype = {
|
|
567 constructor: jQuery.Event,
|
|
568 isDefaultPrevented: returnFalse,
|
|
569 isPropagationStopped: returnFalse,
|
|
570 isImmediatePropagationStopped: returnFalse,
|
|
571 isSimulated: false,
|
|
572
|
|
573 preventDefault: function() {
|
|
574 var e = this.originalEvent;
|
|
575
|
|
576 this.isDefaultPrevented = returnTrue;
|
|
577
|
|
578 if ( e && !this.isSimulated ) {
|
|
579 e.preventDefault();
|
|
580 }
|
|
581 },
|
|
582 stopPropagation: function() {
|
|
583 var e = this.originalEvent;
|
|
584
|
|
585 this.isPropagationStopped = returnTrue;
|
|
586
|
|
587 if ( e && !this.isSimulated ) {
|
|
588 e.stopPropagation();
|
|
589 }
|
|
590 },
|
|
591 stopImmediatePropagation: function() {
|
|
592 var e = this.originalEvent;
|
|
593
|
|
594 this.isImmediatePropagationStopped = returnTrue;
|
|
595
|
|
596 if ( e && !this.isSimulated ) {
|
|
597 e.stopImmediatePropagation();
|
|
598 }
|
|
599
|
|
600 this.stopPropagation();
|
|
601 }
|
|
602 };
|
|
603
|
|
604 // Includes all common event props including KeyEvent and MouseEvent specific props
|
|
605 jQuery.each( {
|
|
606 altKey: true,
|
|
607 bubbles: true,
|
|
608 cancelable: true,
|
|
609 changedTouches: true,
|
|
610 ctrlKey: true,
|
|
611 detail: true,
|
|
612 eventPhase: true,
|
|
613 metaKey: true,
|
|
614 pageX: true,
|
|
615 pageY: true,
|
|
616 shiftKey: true,
|
|
617 view: true,
|
|
618 "char": true,
|
|
619 charCode: true,
|
|
620 key: true,
|
|
621 keyCode: true,
|
|
622 button: true,
|
|
623 buttons: true,
|
|
624 clientX: true,
|
|
625 clientY: true,
|
|
626 offsetX: true,
|
|
627 offsetY: true,
|
|
628 pointerId: true,
|
|
629 pointerType: true,
|
|
630 screenX: true,
|
|
631 screenY: true,
|
|
632 targetTouches: true,
|
|
633 toElement: true,
|
|
634 touches: true,
|
|
635
|
|
636 which: function( event ) {
|
|
637 var button = event.button;
|
|
638
|
|
639 // Add which for key events
|
|
640 if ( event.which == null && rkeyEvent.test( event.type ) ) {
|
|
641 return event.charCode != null ? event.charCode : event.keyCode;
|
|
642 }
|
|
643
|
|
644 // Add which for click: 1 === left; 2 === middle; 3 === right
|
|
645 if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
|
|
646 if ( button & 1 ) {
|
|
647 return 1;
|
|
648 }
|
|
649
|
|
650 if ( button & 2 ) {
|
|
651 return 3;
|
|
652 }
|
|
653
|
|
654 if ( button & 4 ) {
|
|
655 return 2;
|
|
656 }
|
|
657
|
|
658 return 0;
|
|
659 }
|
|
660
|
|
661 return event.which;
|
|
662 }
|
|
663 }, jQuery.event.addProp );
|
|
664
|
|
665 // Create mouseenter/leave events using mouseover/out and event-time checks
|
|
666 // so that event delegation works in jQuery.
|
|
667 // Do the same for pointerenter/pointerleave and pointerover/pointerout
|
|
668 //
|
|
669 // Support: Safari 7 only
|
|
670 // Safari sends mouseenter too often; see:
|
|
671 // https://bugs.chromium.org/p/chromium/issues/detail?id=470258
|
|
672 // for the description of the bug (it existed in older Chrome versions as well).
|
|
673 jQuery.each( {
|
|
674 mouseenter: "mouseover",
|
|
675 mouseleave: "mouseout",
|
|
676 pointerenter: "pointerover",
|
|
677 pointerleave: "pointerout"
|
|
678 }, function( orig, fix ) {
|
|
679 jQuery.event.special[ orig ] = {
|
|
680 delegateType: fix,
|
|
681 bindType: fix,
|
|
682
|
|
683 handle: function( event ) {
|
|
684 var ret,
|
|
685 target = this,
|
|
686 related = event.relatedTarget,
|
|
687 handleObj = event.handleObj;
|
|
688
|
|
689 // For mouseenter/leave call the handler if related is outside the target.
|
|
690 // NB: No relatedTarget if the mouse left/entered the browser window
|
|
691 if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
|
|
692 event.type = handleObj.origType;
|
|
693 ret = handleObj.handler.apply( this, arguments );
|
|
694 event.type = fix;
|
|
695 }
|
|
696 return ret;
|
|
697 }
|
|
698 };
|
|
699 } );
|
|
700
|
|
701 jQuery.fn.extend( {
|
|
702
|
|
703 on: function( types, selector, data, fn ) {
|
|
704 return on( this, types, selector, data, fn );
|
|
705 },
|
|
706 one: function( types, selector, data, fn ) {
|
|
707 return on( this, types, selector, data, fn, 1 );
|
|
708 },
|
|
709 off: function( types, selector, fn ) {
|
|
710 var handleObj, type;
|
|
711 if ( types && types.preventDefault && types.handleObj ) {
|
|
712
|
|
713 // ( event ) dispatched jQuery.Event
|
|
714 handleObj = types.handleObj;
|
|
715 jQuery( types.delegateTarget ).off(
|
|
716 handleObj.namespace ?
|
|
717 handleObj.origType + "." + handleObj.namespace :
|
|
718 handleObj.origType,
|
|
719 handleObj.selector,
|
|
720 handleObj.handler
|
|
721 );
|
|
722 return this;
|
|
723 }
|
|
724 if ( typeof types === "object" ) {
|
|
725
|
|
726 // ( types-object [, selector] )
|
|
727 for ( type in types ) {
|
|
728 this.off( type, selector, types[ type ] );
|
|
729 }
|
|
730 return this;
|
|
731 }
|
|
732 if ( selector === false || typeof selector === "function" ) {
|
|
733
|
|
734 // ( types [, fn] )
|
|
735 fn = selector;
|
|
736 selector = undefined;
|
|
737 }
|
|
738 if ( fn === false ) {
|
|
739 fn = returnFalse;
|
|
740 }
|
|
741 return this.each( function() {
|
|
742 jQuery.event.remove( this, types, fn, selector );
|
|
743 } );
|
|
744 }
|
|
745 } );
|
|
746
|
|
747 return jQuery;
|
|
748 } );
|