jquery-simulate

Simulate events to help unit test user interactions

Script này sẽ không được không được cài đặt trực tiếp. Nó là một thư viện cho các script khác để bao gồm các chỉ thị meta // @require https://update.greatest.deepsurf.us/scripts/24819/157606/jquery-simulate.js

  1. /*!
  2. * jQuery Simulate v@VERSION - simulate browser mouse and keyboard events
  3. *
  4. *
  5. * Copyright jQuery Foundation and other contributors
  6. * Released under the MIT license.
  7. * http://jquery.org/license
  8. *
  9. * Date: @DATE
  10. */
  11.  
  12. ;(function( $, undefined ) {
  13.  
  14. var rkeyEvent = /^key/,
  15. rmouseEvent = /^(?:mouse|contextmenu)|click/;
  16.  
  17. $.fn.simulate = function( type, options ) {
  18. return this.each(function() {
  19. new $.simulate( this, type, options );
  20. });
  21. };
  22.  
  23. $.simulate = function( elem, type, options ) {
  24. var method = $.camelCase( "simulate-" + type );
  25.  
  26. this.target = elem;
  27. this.options = options;
  28.  
  29. if ( this[ method ] ) {
  30. this[ method ]();
  31. } else {
  32. this.simulateEvent( elem, type, options );
  33. }
  34. };
  35.  
  36. $.extend( $.simulate, {
  37.  
  38. keyCode: {
  39. BACKSPACE: 8,
  40. COMMA: 188,
  41. DELETE: 46,
  42. DOWN: 40,
  43. END: 35,
  44. ENTER: 13,
  45. ESCAPE: 27,
  46. HOME: 36,
  47. LEFT: 37,
  48. NUMPAD_ADD: 107,
  49. NUMPAD_DECIMAL: 110,
  50. NUMPAD_DIVIDE: 111,
  51. NUMPAD_ENTER: 108,
  52. NUMPAD_MULTIPLY: 106,
  53. NUMPAD_SUBTRACT: 109,
  54. PAGE_DOWN: 34,
  55. PAGE_UP: 33,
  56. PERIOD: 190,
  57. RIGHT: 39,
  58. SPACE: 32,
  59. TAB: 9,
  60. UP: 38
  61. },
  62.  
  63. buttonCode: {
  64. LEFT: 0,
  65. MIDDLE: 1,
  66. RIGHT: 2
  67. }
  68. });
  69.  
  70. $.extend( $.simulate.prototype, {
  71.  
  72. simulateEvent: function( elem, type, options ) {
  73. var event = this.createEvent( type, options );
  74. this.dispatchEvent( elem, type, event, options );
  75. },
  76.  
  77. createEvent: function( type, options ) {
  78. if ( rkeyEvent.test( type ) ) {
  79. return this.keyEvent( type, options );
  80. }
  81.  
  82. if ( rmouseEvent.test( type ) ) {
  83. return this.mouseEvent( type, options );
  84. }
  85. },
  86.  
  87. mouseEvent: function( type, options ) {
  88. var event, eventDoc, doc, body;
  89. options = $.extend({
  90. bubbles: true,
  91. cancelable: (type !== "mousemove"),
  92. view: window,
  93. detail: 0,
  94. screenX: 0,
  95. screenY: 0,
  96. clientX: 1,
  97. clientY: 1,
  98. ctrlKey: false,
  99. altKey: false,
  100. shiftKey: false,
  101. metaKey: false,
  102. button: 0,
  103. relatedTarget: undefined
  104. }, options );
  105.  
  106. if ( document.createEvent ) {
  107. event = document.createEvent( "MouseEvents" );
  108. event.initMouseEvent( type, options.bubbles, options.cancelable,
  109. options.view, options.detail,
  110. options.screenX, options.screenY, options.clientX, options.clientY,
  111. options.ctrlKey, options.altKey, options.shiftKey, options.metaKey,
  112. options.button, options.relatedTarget || document.body.parentNode );
  113.  
  114. // IE 9+ creates events with pageX and pageY set to 0.
  115. // Trying to modify the properties throws an error,
  116. // so we define getters to return the correct values.
  117. if ( event.pageX === 0 && event.pageY === 0 && Object.defineProperty ) {
  118. eventDoc = event.relatedTarget.ownerDocument || document;
  119. doc = eventDoc.documentElement;
  120. body = eventDoc.body;
  121.  
  122. Object.defineProperty( event, "pageX", {
  123. get: function() {
  124. return options.clientX +
  125. ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
  126. ( doc && doc.clientLeft || body && body.clientLeft || 0 );
  127. }
  128. });
  129. Object.defineProperty( event, "pageY", {
  130. get: function() {
  131. return options.clientY +
  132. ( doc && doc.scrollTop || body && body.scrollTop || 0 ) -
  133. ( doc && doc.clientTop || body && body.clientTop || 0 );
  134. }
  135. });
  136. }
  137. } else if ( document.createEventObject ) {
  138. event = document.createEventObject();
  139. $.extend( event, options );
  140. // standards event.button uses constants defined here: http://msdn.microsoft.com/en-us/library/ie/ff974877(v=vs.85).aspx
  141. // old IE event.button uses constants defined here: http://msdn.microsoft.com/en-us/library/ie/ms533544(v=vs.85).aspx
  142. // so we actually need to map the standard back to oldIE
  143. event.button = {
  144. 0: 1,
  145. 1: 4,
  146. 2: 2
  147. }[ event.button ] || ( event.button === -1 ? 0 : event.button );
  148. }
  149.  
  150. return event;
  151. },
  152.  
  153. keyEvent: function( type, options ) {
  154. var event;
  155. options = $.extend({
  156. bubbles: true,
  157. cancelable: true,
  158. view: window,
  159. ctrlKey: false,
  160. altKey: false,
  161. shiftKey: false,
  162. metaKey: false,
  163. keyCode: 0,
  164. charCode: undefined
  165. }, options );
  166.  
  167. if ( document.createEvent ) {
  168. try {
  169. event = document.createEvent( "KeyEvents" );
  170. event.initKeyEvent( type, options.bubbles, options.cancelable, options.view,
  171. options.ctrlKey, options.altKey, options.shiftKey, options.metaKey,
  172. options.keyCode, options.charCode );
  173. // initKeyEvent throws an exception in WebKit
  174. // see: http://stackoverflow.com/questions/6406784/initkeyevent-keypress-only-works-in-firefox-need-a-cross-browser-solution
  175. // and also https://bugs.webkit.org/show_bug.cgi?id=13368
  176. // fall back to a generic event until we decide to implement initKeyboardEvent
  177. } catch( err ) {
  178. event = document.createEvent( "Events" );
  179. event.initEvent( type, options.bubbles, options.cancelable );
  180. $.extend( event, {
  181. view: options.view,
  182. ctrlKey: options.ctrlKey,
  183. altKey: options.altKey,
  184. shiftKey: options.shiftKey,
  185. metaKey: options.metaKey,
  186. keyCode: options.keyCode,
  187. charCode: options.charCode
  188. });
  189. }
  190. } else if ( document.createEventObject ) {
  191. event = document.createEventObject();
  192. $.extend( event, options );
  193. }
  194.  
  195. if ( !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ) || (({}).toString.call( window.opera ) === "[object Opera]") ) {
  196. event.keyCode = (options.charCode > 0) ? options.charCode : options.keyCode;
  197. event.charCode = undefined;
  198. }
  199.  
  200. return event;
  201. },
  202.  
  203. dispatchEvent: function( elem, type, event ) {
  204. if ( elem.dispatchEvent ) {
  205. elem.dispatchEvent( event );
  206. } else if ( type === "click" && elem.click && elem.nodeName.toLowerCase() === "input" ) {
  207. elem.click();
  208. } else if ( elem.fireEvent ) {
  209. elem.fireEvent( "on" + type, event );
  210. }
  211. },
  212.  
  213. simulateFocus: function() {
  214. var focusinEvent,
  215. triggered = false,
  216. element = $( this.target );
  217.  
  218. function trigger() {
  219. triggered = true;
  220. }
  221.  
  222. element.bind( "focus", trigger );
  223. element[ 0 ].focus();
  224.  
  225. if ( !triggered ) {
  226. focusinEvent = $.Event( "focusin" );
  227. focusinEvent.preventDefault();
  228. element.trigger( focusinEvent );
  229. element.triggerHandler( "focus" );
  230. }
  231. element.unbind( "focus", trigger );
  232. },
  233.  
  234. simulateBlur: function() {
  235. var focusoutEvent,
  236. triggered = false,
  237. element = $( this.target );
  238.  
  239. function trigger() {
  240. triggered = true;
  241. }
  242.  
  243. element.bind( "blur", trigger );
  244. element[ 0 ].blur();
  245.  
  246. // blur events are async in IE
  247. setTimeout(function() {
  248. // IE won't let the blur occur if the window is inactive
  249. if ( element[ 0 ].ownerDocument.activeElement === element[ 0 ] ) {
  250. element[ 0 ].ownerDocument.body.focus();
  251. }
  252.  
  253. // Firefox won't trigger events if the window is inactive
  254. // IE doesn't trigger events if we had to manually focus the body
  255. if ( !triggered ) {
  256. focusoutEvent = $.Event( "focusout" );
  257. focusoutEvent.preventDefault();
  258. element.trigger( focusoutEvent );
  259. element.triggerHandler( "blur" );
  260. }
  261. element.unbind( "blur", trigger );
  262. }, 1 );
  263. }
  264. });
  265.  
  266.  
  267.  
  268. /** complex events **/
  269.  
  270. function findCenter( elem ) {
  271. var offset,
  272. document = $( elem.ownerDocument );
  273. elem = $( elem );
  274. offset = elem.offset();
  275.  
  276. return {
  277. x: offset.left + elem.outerWidth() / 2 - document.scrollLeft(),
  278. y: offset.top + elem.outerHeight() / 2 - document.scrollTop()
  279. };
  280. }
  281.  
  282. function findCorner( elem ) {
  283. var offset,
  284. document = $( elem.ownerDocument );
  285. elem = $( elem );
  286. offset = elem.offset();
  287.  
  288. return {
  289. x: offset.left - document.scrollLeft(),
  290. y: offset.top - document.scrollTop()
  291. };
  292. }
  293.  
  294. $.extend( $.simulate.prototype, {
  295. simulateDrag: function() {
  296. var i = 0,
  297. target = this.target,
  298. eventDoc = target.ownerDocument,
  299. options = this.options,
  300. center = options.handle === "corner" ? findCorner( target ) : findCenter( target ),
  301. x = Math.floor( center.x ),
  302. y = Math.floor( center.y ),
  303. coord = { clientX: x, clientY: y },
  304. dx = options.dx || ( options.x !== undefined ? options.x - x : 0 ),
  305. dy = options.dy || ( options.y !== undefined ? options.y - y : 0 ),
  306. moves = options.moves || 3;
  307.  
  308. this.simulateEvent( target, "mousedown", coord );
  309.  
  310. for ( ; i < moves ; i++ ) {
  311. x += dx / moves;
  312. y += dy / moves;
  313.  
  314. coord = {
  315. clientX: Math.round( x ),
  316. clientY: Math.round( y )
  317. };
  318.  
  319. this.simulateEvent( eventDoc, "mousemove", coord );
  320. }
  321.  
  322. if ( $.contains( eventDoc, target ) ) {
  323. this.simulateEvent( target, "mouseup", coord );
  324. this.simulateEvent( target, "click", coord );
  325. } else {
  326. this.simulateEvent( eventDoc, "mouseup", coord );
  327. }
  328. }
  329. });
  330.  
  331. })( jQuery );