scratch – Blame information for rev 125

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