4
4
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5
5
* Dual licensed under the MIT or GPL Version 2 licenses.
6
6
* http://jquery.org/license
7
- *
8
7
*/
9
8
10
9
; ( function ( $ ) {
11
10
12
- $ . fn . extend ( {
13
- simulate : function ( type , options ) {
14
- return this . each ( function ( ) {
15
- var opt = $ . extend ( { } , $ . simulate . defaults , options ) ;
16
- new $ . simulate ( this , type , opt ) ;
17
- } ) ;
18
- }
19
- } ) ;
11
+ var rkeyEvent = / ^ k e y / ,
12
+ rmouseEvent = / ^ (?: m o u s e | c o n t e x t m e n u ) | c l i c k / ;
20
13
21
- $ . simulate = function ( el , type , options ) {
22
- this . target = el ;
14
+ $ . fn . simulate = function ( type , options ) {
15
+ return this . each ( function ( ) {
16
+ new $ . simulate ( this , type , options ) ;
17
+ } ) ;
18
+ } ;
19
+
20
+ $ . simulate = function ( elem , type , options ) {
21
+ var method = $ . camelCase ( "simulate-" + type ) ;
22
+
23
+ this . target = elem ;
23
24
this . options = options ;
24
25
25
- if ( type === "drag" ) {
26
- this [ type ] . apply ( this , [ this . target , options ] ) ;
27
- } else if ( type === "focus" || type === "blur" ) {
28
- this [ type ] ( ) ;
26
+ if ( this [ method ] ) {
27
+ this [ method ] ( ) ;
29
28
} else {
30
- this . simulateEvent ( el , type , options ) ;
29
+ this . simulateEvent ( elem , type , options ) ;
31
30
}
32
31
} ;
33
32
34
33
$ . extend ( $ . simulate . prototype , {
35
- simulateEvent : function ( el , type , options ) {
36
- var evt = this . createEvent ( type , options ) ;
37
- this . dispatchEvent ( el , type , evt , options ) ;
38
- return evt ;
34
+ simulateEvent : function ( elem , type , options ) {
35
+ var event = this . createEvent ( type , options ) ;
36
+ this . dispatchEvent ( elem , type , event , options ) ;
39
37
} ,
38
+
40
39
createEvent : function ( type , options ) {
41
- if ( / ^ m o u s e ( o v e r | o u t | d o w n | u p | m o v e ) | ( d b l ) ? c l i c k $ / . test ( type ) ) {
40
+ if ( rkeyEvent . test ( type ) ) {
41
+ return this . keyEvent ( type , options ) ;
42
+ }
43
+
44
+ if ( rmouseEvent . test ( type ) ) {
42
45
return this . mouseEvent ( type , options ) ;
43
- } else if ( / ^ k e y ( u p | d o w n | p r e s s ) $ / . test ( type ) ) {
44
- return this . keyboardEvent ( type , options ) ;
45
46
}
46
47
} ,
48
+
47
49
mouseEvent : function ( type , options ) {
48
- var evt , eventDoc , doc , body ;
49
- var e = $ . extend ( {
50
+ var event , eventDoc , doc , body ;
51
+ options = $ . extend ( {
50
52
bubbles : true ,
51
53
cancelable : ( type !== "mousemove" ) ,
52
54
view : window ,
53
55
detail : 0 ,
54
56
screenX : 0 ,
55
57
screenY : 0 ,
56
- clientX : 0 ,
57
- clientY : 0 ,
58
+ // TODO: default clientX/Y to a position within the target element
59
+ clientX : 1 ,
60
+ clientY : 1 ,
58
61
ctrlKey : false ,
59
62
altKey : false ,
60
63
shiftKey : false ,
@@ -63,49 +66,50 @@ $.extend( $.simulate.prototype, {
63
66
relatedTarget : undefined
64
67
} , options ) ;
65
68
66
- var relatedTarget = $ ( e . relatedTarget ) [ 0 ] ;
69
+ if ( document . createEvent ) {
70
+ event = document . createEvent ( "MouseEvents" ) ;
71
+ event . initMouseEvent ( type , options . bubbles , options . cancelable ,
72
+ options . view , options . detail ,
73
+ options . screenX , options . screenY , options . clientX , options . clientY ,
74
+ options . ctrlKey , options . altKey , options . shiftKey , options . metaKey ,
75
+ options . button , options . relatedTarget || document . body . parentNode ) ;
67
76
68
- if ( $ . isFunction ( document . createEvent ) ) {
69
- evt = document . createEvent ( "MouseEvents" ) ;
70
- evt . initMouseEvent ( type , e . bubbles , e . cancelable , e . view , e . detail ,
71
- e . screenX , e . screenY , e . clientX , e . clientY ,
72
- e . ctrlKey , e . altKey , e . shiftKey , e . metaKey ,
73
- e . button , e . relatedTarget || document . body . parentNode ) ;
74
-
75
77
// IE 9+ creates events with pageX and pageY set to 0.
76
78
// Trying to modify the properties throws an error,
77
79
// so we define getters to return the correct values.
78
- if ( evt . pageX === 0 && evt . pageY === 0 && Object . defineProperty ) {
79
- eventDoc = evt . relatedTarget . ownerDocument || document ;
80
+ if ( event . pageX === 0 && event . pageY === 0 && Object . defineProperty ) {
81
+ eventDoc = event . relatedTarget . ownerDocument || document ;
80
82
doc = eventDoc . documentElement ;
81
83
body = eventDoc . body ;
82
84
83
- Object . defineProperty ( evt , "pageX" , {
85
+ Object . defineProperty ( event , "pageX" , {
84
86
get : function ( ) {
85
- return e . clientX +
87
+ return options . clientX +
86
88
( doc && doc . scrollLeft || body && body . scrollLeft || 0 ) -
87
89
( doc && doc . clientLeft || body && body . clientLeft || 0 ) ;
88
90
}
89
91
} ) ;
90
- Object . defineProperty ( evt , "pageY" , {
92
+ Object . defineProperty ( event , "pageY" , {
91
93
get : function ( ) {
92
- return e . clientY +
94
+ return options . clientY +
93
95
( doc && doc . scrollTop || body && body . scrollTop || 0 ) -
94
96
( doc && doc . clientTop || body && body . clientTop || 0 ) ;
95
97
}
96
98
} ) ;
97
99
}
98
100
} else if ( document . createEventObject ) {
99
- evt = document . createEventObject ( ) ;
100
- $ . extend ( evt , e ) ;
101
- evt . button = { 0 :1 , 1 :4 , 2 :2 } [ evt . button ] || evt . button ;
101
+ event = document . createEventObject ( ) ;
102
+ $ . extend ( event , options ) ;
103
+ // TODO: what is this mapping for?
104
+ event . button = { 0 :1 , 1 :4 , 2 :2 } [ event . button ] || event . button ;
102
105
}
103
- return evt ;
106
+
107
+ return event ;
104
108
} ,
105
- keyboardEvent : function ( type , options ) {
106
- var evt ;
107
109
108
- var e = $ . extend ( {
110
+ keyEvent : function ( type , options ) {
111
+ var event ;
112
+ options = $ . extend ( {
109
113
bubbles : true ,
110
114
cancelable : true ,
111
115
view : window ,
@@ -117,74 +121,51 @@ $.extend( $.simulate.prototype, {
117
121
charCode : undefined
118
122
} , options ) ;
119
123
120
- if ( $ . isFunction ( document . createEvent ) ) {
124
+ if ( document . createEvent ) {
121
125
try {
122
- evt = document . createEvent ( "KeyEvents" ) ;
123
- evt . initKeyEvent ( type , e . bubbles , e . cancelable , e . view ,
124
- e . ctrlKey , e . altKey , e . shiftKey , e . metaKey ,
125
- e . keyCode , e . charCode ) ;
126
+ event = document . createEvent ( "KeyEvents" ) ;
127
+ event . initKeyEvent ( type , options . bubbles , options . cancelable , options . view ,
128
+ options . ctrlKey , options . altKey , options . shiftKey , options . metaKey ,
129
+ options . keyCode , options . charCode ) ;
130
+ // TODO: what is this supporting?
126
131
} catch ( err ) {
127
- evt = document . createEvent ( "Events" ) ;
128
- evt . initEvent ( type , e . bubbles , e . cancelable ) ;
129
- $ . extend ( evt , {
130
- view : e . view ,
131
- ctrlKey : e . ctrlKey ,
132
- altKey : e . altKey ,
133
- shiftKey : e . shiftKey ,
134
- metaKey : e . metaKey ,
135
- keyCode : e . keyCode ,
136
- charCode : e . charCode
132
+ event = document . createEvent ( "Events" ) ;
133
+ event . initEvent ( type , options . bubbles , options . cancelable ) ;
134
+ $ . extend ( event , {
135
+ view : options . view ,
136
+ ctrlKey : options . ctrlKey ,
137
+ altKey : options . altKey ,
138
+ shiftKey : options . shiftKey ,
139
+ metaKey : options . metaKey ,
140
+ keyCode : options . keyCode ,
141
+ charCode : options . charCode
137
142
} ) ;
138
143
}
139
144
} else if ( document . createEventObject ) {
140
- evt = document . createEventObject ( ) ;
141
- $ . extend ( evt , e ) ;
145
+ event = document . createEventObject ( ) ;
146
+ $ . extend ( event , options ) ;
142
147
}
148
+
149
+ // TODO: can we hook into core's logic?
143
150
if ( $ . browser . msie || $ . browser . opera ) {
144
- evt . keyCode = ( e . charCode > 0 ) ? e . charCode : e . keyCode ;
145
- evt . charCode = undefined ;
151
+ // TODO: is charCode ever <0 ? Can we just use charCode || keyCode?
152
+ event . keyCode = ( options . charCode > 0 ) ? options . charCode : options . keyCode ;
153
+ event . charCode = undefined ;
146
154
}
147
- return evt ;
148
- } ,
149
155
150
- dispatchEvent : function ( el , type , evt ) {
151
- if ( el . dispatchEvent ) {
152
- el . dispatchEvent ( evt ) ;
153
- } else if ( el . fireEvent ) {
154
- el . fireEvent ( "on" + type , evt ) ;
155
- }
156
- return evt ;
156
+ return event ;
157
157
} ,
158
158
159
- drag : function ( el ) {
160
- var center = this . findCenter ( this . target ) ,
161
- options = this . options ,
162
- x = Math . floor ( center . x ) ,
163
- y = Math . floor ( center . y ) ,
164
- dx = options . dx || 0 ,
165
- dy = options . dy || 0 ,
166
- target = this . target ,
167
- coord = { clientX : x , clientY : y } ;
168
- this . simulateEvent ( target , "mousedown" , coord ) ;
169
- coord = { clientX : x + 1 , clientY : y + 1 } ;
170
- this . simulateEvent ( document , "mousemove" , coord ) ;
171
- coord = { clientX : x + dx , clientY : y + dy } ;
172
- this . simulateEvent ( document , "mousemove" , coord ) ;
173
- this . simulateEvent ( document , "mousemove" , coord ) ;
174
- this . simulateEvent ( target , "mouseup" , coord ) ;
175
- this . simulateEvent ( target , "click" , coord ) ;
176
- } ,
177
- findCenter : function ( el ) {
178
- var el = $ ( this . target ) ,
179
- o = el . offset ( ) ,
180
- d = $ ( document ) ;
181
- return {
182
- x : o . left + el . outerWidth ( ) / 2 - d . scrollLeft ( ) ,
183
- y : o . top + el . outerHeight ( ) / 2 - d . scrollTop ( )
184
- } ;
159
+ // TODO: does this need type? Can't we just check event.type?
160
+ dispatchEvent : function ( elem , type , event ) {
161
+ if ( elem . dispatchEvent ) {
162
+ elem . dispatchEvent ( event ) ;
163
+ } else if ( elem . fireEvent ) {
164
+ elem . fireEvent ( "on" + type , event ) ;
165
+ }
185
166
} ,
186
167
187
- focus : function ( ) {
168
+ simulateFocus : function ( ) {
188
169
var focusinEvent ,
189
170
triggered = false ,
190
171
element = $ ( this . target ) ;
@@ -205,7 +186,7 @@ $.extend( $.simulate.prototype, {
205
186
element . unbind ( "focus" , trigger ) ;
206
187
} ,
207
188
208
- blur : function ( ) {
189
+ simulateBlur : function ( ) {
209
190
var focusoutEvent ,
210
191
triggered = false ,
211
192
element = $ ( this . target ) ;
@@ -237,21 +218,42 @@ $.extend( $.simulate.prototype, {
237
218
}
238
219
} ) ;
239
220
240
- $ . extend ( $ . simulate , {
241
- defaults : {
242
- speed : "sync"
243
- } ,
244
- VK_TAB : 9 ,
245
- VK_ENTER : 13 ,
246
- VK_ESC : 27 ,
247
- VK_PGUP : 33 ,
248
- VK_PGDN : 34 ,
249
- VK_END : 35 ,
250
- VK_HOME : 36 ,
251
- VK_LEFT : 37 ,
252
- VK_UP : 38 ,
253
- VK_RIGHT : 39 ,
254
- VK_DOWN : 40
221
+
222
+
223
+ /** complex events **/
224
+
225
+ function findCenter ( elem ) {
226
+ var offset ,
227
+ document = $ ( elem . ownerDocument ) ;
228
+ elem = $ ( elem ) ;
229
+ offset = elem . offset ( ) ;
230
+
231
+ return {
232
+ x : offset . left + elem . outerWidth ( ) / 2 - document . scrollLeft ( ) ,
233
+ y : offset . top + elem . outerHeight ( ) / 2 - document . scrollTop ( )
234
+ } ;
235
+ }
236
+
237
+ $ . extend ( $ . simulate . prototype , {
238
+ simulateDrag : function ( ) {
239
+ var target = this . target ,
240
+ options = this . options ,
241
+ center = findCenter ( target ) ,
242
+ x = Math . floor ( center . x ) ,
243
+ y = Math . floor ( center . y ) ,
244
+ dx = options . dx || 0 ,
245
+ dy = options . dy || 0 ,
246
+ target = this . target ,
247
+ coord = { clientX : x , clientY : y } ;
248
+ this . simulateEvent ( target , "mousedown" , coord ) ;
249
+ coord = { clientX : x + 1 , clientY : y + 1 } ;
250
+ this . simulateEvent ( document , "mousemove" , coord ) ;
251
+ coord = { clientX : x + dx , clientY : y + dy } ;
252
+ this . simulateEvent ( document , "mousemove" , coord ) ;
253
+ this . simulateEvent ( document , "mousemove" , coord ) ;
254
+ this . simulateEvent ( target , "mouseup" , coord ) ;
255
+ this . simulateEvent ( target , "click" , coord ) ;
256
+ }
255
257
} ) ;
256
258
257
259
} ) ( jQuery ) ;
0 commit comments