blob: c3769e1f1690863222a1094a883a04d4dd353de9 [file] [log] [blame]
Copybara botbe50d492023-11-30 00:16:42 +01001define( [
2 "../core",
3 "../var/document",
4 "../data/var/dataPriv",
5 "../data/var/acceptData",
6 "../var/hasOwn",
7 "../var/isFunction",
8 "../var/isWindow",
9 "../event"
10], function( jQuery, document, dataPriv, acceptData, hasOwn, isFunction, isWindow ) {
11
12"use strict";
13
14var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
15 stopPropagationCallback = function( e ) {
16 e.stopPropagation();
17 };
18
19jQuery.extend( jQuery.event, {
20
21 trigger: function( event, data, elem, onlyHandlers ) {
22
23 var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,
24 eventPath = [ elem || document ],
25 type = hasOwn.call( event, "type" ) ? event.type : event,
26 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
27
28 cur = lastElement = tmp = elem = elem || document;
29
30 // Don't do events on text and comment nodes
31 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
32 return;
33 }
34
35 // focus/blur morphs to focusin/out; ensure we're not firing them right now
36 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
37 return;
38 }
39
40 if ( type.indexOf( "." ) > -1 ) {
41
42 // Namespaced trigger; create a regexp to match event type in handle()
43 namespaces = type.split( "." );
44 type = namespaces.shift();
45 namespaces.sort();
46 }
47 ontype = type.indexOf( ":" ) < 0 && "on" + type;
48
49 // Caller can pass in a jQuery.Event object, Object, or just an event type string
50 event = event[ jQuery.expando ] ?
51 event :
52 new jQuery.Event( type, typeof event === "object" && event );
53
54 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
55 event.isTrigger = onlyHandlers ? 2 : 3;
56 event.namespace = namespaces.join( "." );
57 event.rnamespace = event.namespace ?
58 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
59 null;
60
61 // Clean up the event in case it is being reused
62 event.result = undefined;
63 if ( !event.target ) {
64 event.target = elem;
65 }
66
67 // Clone any incoming data and prepend the event, creating the handler arg list
68 data = data == null ?
69 [ event ] :
70 jQuery.makeArray( data, [ event ] );
71
72 // Allow special events to draw outside the lines
73 special = jQuery.event.special[ type ] || {};
74 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
75 return;
76 }
77
78 // Determine event propagation path in advance, per W3C events spec (#9951)
79 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
80 if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {
81
82 bubbleType = special.delegateType || type;
83 if ( !rfocusMorph.test( bubbleType + type ) ) {
84 cur = cur.parentNode;
85 }
86 for ( ; cur; cur = cur.parentNode ) {
87 eventPath.push( cur );
88 tmp = cur;
89 }
90
91 // Only add window if we got to document (e.g., not plain obj or detached DOM)
92 if ( tmp === ( elem.ownerDocument || document ) ) {
93 eventPath.push( tmp.defaultView || tmp.parentWindow || window );
94 }
95 }
96
97 // Fire handlers on the event path
98 i = 0;
99 while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
100 lastElement = cur;
101 event.type = i > 1 ?
102 bubbleType :
103 special.bindType || type;
104
105 // jQuery handler
Renovate botf591dcf2023-12-30 14:13:54 +0000106 handle = (
107 dataPriv.get( cur, "events" ) || Object.create( null )
108 )[ event.type ] &&
Copybara botbe50d492023-11-30 00:16:42 +0100109 dataPriv.get( cur, "handle" );
110 if ( handle ) {
111 handle.apply( cur, data );
112 }
113
114 // Native handler
115 handle = ontype && cur[ ontype ];
116 if ( handle && handle.apply && acceptData( cur ) ) {
117 event.result = handle.apply( cur, data );
118 if ( event.result === false ) {
119 event.preventDefault();
120 }
121 }
122 }
123 event.type = type;
124
125 // If nobody prevented the default action, do it now
126 if ( !onlyHandlers && !event.isDefaultPrevented() ) {
127
128 if ( ( !special._default ||
129 special._default.apply( eventPath.pop(), data ) === false ) &&
130 acceptData( elem ) ) {
131
132 // Call a native DOM method on the target with the same name as the event.
133 // Don't do default actions on window, that's where global variables be (#6170)
134 if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {
135
136 // Don't re-trigger an onFOO event when we call its FOO() method
137 tmp = elem[ ontype ];
138
139 if ( tmp ) {
140 elem[ ontype ] = null;
141 }
142
143 // Prevent re-triggering of the same event, since we already bubbled it above
144 jQuery.event.triggered = type;
145
146 if ( event.isPropagationStopped() ) {
147 lastElement.addEventListener( type, stopPropagationCallback );
148 }
149
150 elem[ type ]();
151
152 if ( event.isPropagationStopped() ) {
153 lastElement.removeEventListener( type, stopPropagationCallback );
154 }
155
156 jQuery.event.triggered = undefined;
157
158 if ( tmp ) {
159 elem[ ontype ] = tmp;
160 }
161 }
162 }
163 }
164
165 return event.result;
166 },
167
168 // Piggyback on a donor event to simulate a different one
169 // Used only for `focus(in | out)` events
170 simulate: function( type, elem, event ) {
171 var e = jQuery.extend(
172 new jQuery.Event(),
173 event,
174 {
175 type: type,
176 isSimulated: true
177 }
178 );
179
180 jQuery.event.trigger( e, null, elem );
181 }
182
183} );
184
185jQuery.fn.extend( {
186
187 trigger: function( type, data ) {
188 return this.each( function() {
189 jQuery.event.trigger( type, data, this );
190 } );
191 },
192 triggerHandler: function( type, data ) {
193 var elem = this[ 0 ];
194 if ( elem ) {
195 return jQuery.event.trigger( type, data, elem, true );
196 }
197 }
198} );
199
200return jQuery;
201} );