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