event.js 27 KB

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