event.js 24 KB

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