PageRenderTime 51ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/closure-library/closure/goog/events/pastehandler_test.html

https://github.com/illandril/box2dweb-closure
HTML | 414 lines | 359 code | 47 blank | 8 comment | 0 complexity | 527093b50515b3f375e70eb371c92f2d MD5 | raw file
  1. <!DOCTYPE html>
  2. <html>
  3. <!--
  4. Copyright 2009 The Closure Library Authors. All Rights Reserved.
  5. Use of this source code is governed by the Apache License, Version 2.0.
  6. See the COPYING file for details.
  7. -->
  8. <!--
  9. -->
  10. <head>
  11. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  12. <title>Closure Unit Tests - goog.events.PasteHandler</title>
  13. <script src="../base.js"></script>
  14. <script>
  15. goog.require('goog.events.PasteHandler');
  16. goog.require('goog.testing.MockClock');
  17. goog.require('goog.testing.MockUserAgent');
  18. goog.require('goog.testing.jsunit');
  19. goog.require('goog.events.EventTarget');
  20. goog.require('goog.events.EventType');
  21. goog.require('goog.dom');
  22. </script>
  23. </head>
  24. <body>
  25. <textarea id="foo"></textarea>
  26. <script>
  27. function setUp() {
  28. // TODO(user): fix {@code goog.testing.MockUserAgent} to do the right thing.
  29. // the code doesn't seem to be updating the variables with
  30. // goog.userAgent.init_(), which means it is not allowing me to mock the
  31. // user agent variables.
  32. goog.userAgent.GECKO = true;
  33. goog.userAgent.IE = false;
  34. goog.userAgent.WEBKIT = false;
  35. goog.userAgent.VERSION = '1.8';
  36. textarea = new goog.events.EventTarget();
  37. textarea.value = '';
  38. clock = new goog.testing.MockClock(true);
  39. mockUserAgent = new goog.testing.MockUserAgent();
  40. handler = new goog.events.PasteHandler(textarea);
  41. pasted = false;
  42. goog.events.listen(handler, goog.events.PasteHandler.EventType.PASTE,
  43. function() {
  44. pasted = true;
  45. });
  46. }
  47. function tearDown() {
  48. textarea.dispose();
  49. handler.dispose();
  50. clock.dispose();
  51. mockUserAgent.dispose();
  52. }
  53. function newBrowserEvent(type) {
  54. if (goog.isString(type)) {
  55. return new goog.events.BrowserEvent({type: type});
  56. } else {
  57. return new goog.events.BrowserEvent(type);
  58. }
  59. }
  60. function testDispatchingPasteEventSupportedByAFewBrowsersWork() {
  61. goog.userAgent.IE = true;
  62. var handlerThatSupportsPasteEvents =
  63. new goog.events.PasteHandler(textarea);
  64. // user clicks on the textarea and give it focus
  65. goog.events.listen(handlerThatSupportsPasteEvents,
  66. goog.events.PasteHandler.EventType.PASTE,
  67. function() {
  68. pasted = true;
  69. });
  70. textarea.dispatchEvent(newBrowserEvent('paste'));
  71. assertTrue(pasted);
  72. }
  73. function testJustTypingDoesntFirePasteEvent() {
  74. // user clicks on the textarea and give it focus
  75. textarea.dispatchEvent(newBrowserEvent(goog.events.EventType.FOCUS));
  76. assertFalse(pasted);
  77. // user starts typing
  78. textarea.dispatchEvent(newBrowserEvent({
  79. type: goog.events.EventType.KEYDOWN,
  80. keyCode: goog.events.KeyCodes.A
  81. }));
  82. textarea.value = 'a';
  83. assertFalse(pasted);
  84. // still typing
  85. textarea.dispatchEvent({
  86. type: goog.events.EventType.KEYDOWN,
  87. keyCode: goog.events.KeyCodes.B
  88. });
  89. textarea.value = 'ab';
  90. assertFalse(pasted);
  91. // ends typing
  92. textarea.dispatchEvent({
  93. type: goog.events.EventType.KEYDOWN,
  94. keyCode: goog.events.KeyCodes.C
  95. });
  96. textarea.value = 'abc';
  97. assertFalse(pasted);
  98. }
  99. function testStartsOnInitialState() {
  100. assertTrue(handler.getState() == goog.events.PasteHandler.State.INIT);
  101. assertFalse(pasted);
  102. }
  103. function testBlurOnInit() {
  104. textarea.dispatchEvent(goog.events.EventType.BLUR);
  105. assertTrue(handler.getState() == goog.events.PasteHandler.State.INIT);
  106. assertFalse(pasted);
  107. }
  108. function testFocusOnInit() {
  109. textarea.dispatchEvent(goog.events.EventType.FOCUS);
  110. assertTrue(handler.getState() == goog.events.PasteHandler.State.FOCUSED);
  111. assertFalse(pasted);
  112. }
  113. function testInputOnFocus() {
  114. // user clicks on the textarea
  115. textarea.dispatchEvent(newBrowserEvent(goog.events.EventType.FOCUS));
  116. clock.tick(
  117. goog.events.PasteHandler.MANDATORY_MS_BETWEEN_INPUT_EVENTS_TIE_BREAKER +
  118. 1);
  119. // and right click -> paste a text!
  120. textarea.dispatchEvent(newBrowserEvent('input'));
  121. assertTrue(handler.getState() == goog.events.PasteHandler.State.FOCUSED);
  122. // make sure we detected it
  123. assertTrue(pasted);
  124. }
  125. function testKeyPressOnFocus() {
  126. // user clicks on the textarea
  127. textarea.dispatchEvent(newBrowserEvent(goog.events.EventType.FOCUS));
  128. // starts typing something
  129. textarea.dispatchEvent(newBrowserEvent({
  130. type: goog.events.EventType.KEYDOWN,
  131. keyCode: goog.events.KeyCodes.A
  132. }));
  133. assertTrue(handler.getState() == goog.events.PasteHandler.State.TYPING);
  134. assertFalse(pasted);
  135. // and then presses ctrl+v
  136. textarea.dispatchEvent(newBrowserEvent({
  137. type: goog.events.EventType.KEYDOWN,
  138. keyCode: goog.events.KeyCodes.V,
  139. ctrlKey: true
  140. }));
  141. assertTrue(handler.getState() == goog.events.PasteHandler.State.TYPING);
  142. // makes sure we detected it
  143. assertTrue(pasted);
  144. }
  145. function testMouseOverOnInit() {
  146. // user has something on the events
  147. textarea.value = 'pasted string';
  148. // and right click -> paste it on the textarea, WITHOUT giving focus
  149. textarea.dispatchEvent(newBrowserEvent(goog.events.EventType.MOUSEOVER));
  150. assertTrue(handler.getState() == goog.events.PasteHandler.State.INIT);
  151. // makes sure we detect it
  152. assertTrue(pasted);
  153. pasted = false;
  154. // user normaly mouseovers the textarea, with no text change
  155. textarea.dispatchEvent(goog.events.EventType.MOUSEOVER);
  156. assertTrue(handler.getState() == goog.events.PasteHandler.State.INIT);
  157. // text area value doesnt change
  158. assertFalse(pasted);
  159. }
  160. function testMouseOverAfterTyping() {
  161. textarea.dispatchEvent(goog.events.EventType.FOCUS);
  162. assertFalse(pasted);
  163. textarea.dispatchEvent(
  164. {type: goog.events.EventType.KEYDOWN, keyCode: goog.events.KeyCodes.A});
  165. assertFalse(pasted);
  166. textarea.value = 'a';
  167. textarea.dispatchEvent('input');
  168. assertFalse(pasted);
  169. assertEquals('a', handler.oldValue_);
  170. textarea.dispatchEvent(goog.events.EventType.MOUSEOVER);
  171. assertFalse(pasted);
  172. }
  173. function testTypingAndThenRightClickPaste() {
  174. textarea.dispatchEvent(goog.events.EventType.FOCUS);
  175. textarea.dispatchEvent(
  176. {type: goog.events.EventType.KEYDOWN, keyCode: goog.events.KeyCodes.A});
  177. assertFalse(pasted);
  178. textarea.value = 'a';
  179. clock.tick(
  180. goog.events.PasteHandler.MANDATORY_MS_BETWEEN_INPUT_EVENTS_TIE_BREAKER +
  181. 1);
  182. textarea.dispatchEvent('input');
  183. assertFalse(pasted);
  184. assertEquals('a', handler.oldValue_);
  185. textarea.value = 'ab';
  186. clock.tick(
  187. goog.events.PasteHandler.MANDATORY_MS_BETWEEN_INPUT_EVENTS_TIE_BREAKER +
  188. 1);
  189. textarea.dispatchEvent(newBrowserEvent('input'));
  190. assertTrue(pasted);
  191. }
  192. function testTypingReallyFastDispatchesTwoInputEventsBeforeTheKeyDownEvent() {
  193. textarea.dispatchEvent(goog.events.EventType.FOCUS);
  194. // keydown and input events seems to be fired indepently: even though input
  195. // should happen after the key event, it doens't if the user types fast
  196. // enough. FF2 + linux doesn't fire keydown events for every key pressed when
  197. // you type fast enough. if one of the keydown events gets swallowed, two
  198. // input events are fired consecutively. notice that there is a similar
  199. // scenario, that actually does produce a valid paste action.
  200. // {@see testRightClickRightClickAlsoDispatchesTwoConsecutiveInputEvents}
  201. textarea.dispatchEvent(
  202. {type: goog.events.EventType.KEYDOWN, keyCode: goog.events.KeyCodes.A});
  203. assertFalse(pasted);
  204. textarea.value = 'a';
  205. clock.tick(
  206. goog.events.PasteHandler.MANDATORY_MS_BETWEEN_INPUT_EVENTS_TIE_BREAKER -
  207. 1);
  208. textarea.dispatchEvent('input');
  209. assertFalse(pasted);
  210. // second key down events gets fired on a different order
  211. textarea.value = 'ab';
  212. clock.tick(
  213. goog.events.PasteHandler.MANDATORY_MS_BETWEEN_INPUT_EVENTS_TIE_BREAKER -
  214. 1);
  215. textarea.dispatchEvent('input');
  216. assertFalse(pasted);
  217. }
  218. function testRightClickRightClickAlsoDispatchesTwoConsecutiveInputEvents() {
  219. textarea.dispatchEvent(goog.events.EventType.FOCUS);
  220. // there is also another case that two consecutive INPUT events are fired,
  221. // but in a valid paste action: if the user edit -> paste -> edit -> paste,
  222. // it is a valid paste action.
  223. textarea.value = 'a';
  224. clock.tick(
  225. goog.events.PasteHandler.MANDATORY_MS_BETWEEN_INPUT_EVENTS_TIE_BREAKER +
  226. 1);
  227. textarea.dispatchEvent(newBrowserEvent('input'));
  228. assertTrue(pasted);
  229. // second key down events gets fired on a different order
  230. textarea.value = 'ab';
  231. clock.tick(
  232. goog.events.PasteHandler.MANDATORY_MS_BETWEEN_INPUT_EVENTS_TIE_BREAKER +
  233. 1);
  234. textarea.dispatchEvent(newBrowserEvent('input'));
  235. assertTrue(pasted);
  236. }
  237. function testMiddleClickWithoutFocusTriggersPasteEvent() {
  238. // if the textarea is NOT selected, and then we use the middle button,
  239. // FF2+linux pastes what was last highlighted, causing a paste action.
  240. textarea.dispatchEvent(goog.events.EventType.FOCUS);
  241. textarea.dispatchEvent(newBrowserEvent('input'));
  242. assertTrue(pasted);
  243. }
  244. function testMacRightClickPasteRequiresToPressCtrlBecauseItDoesntHaveTwoMouseButtons() {
  245. // Macs don't have two buttons mouse: this means that you need to press
  246. // ctrl + click to get to the menu, and then you can click paste.
  247. // The sequences of events fired on Opera are:
  248. // focus -> keydown (keyCode == 0, not e.ctrlKey) -> input
  249. goog.userAgent.OPERA = true;
  250. goog.userAgent.MAC = true;
  251. var handler = new goog.events.PasteHandler(textarea);
  252. // user clicks on the textarea and give it focus
  253. goog.events.listen(handler,
  254. goog.events.PasteHandler.EventType.PASTE,
  255. function() {
  256. pasted = true;
  257. });
  258. textarea.dispatchEvent(goog.events.EventType.FOCUS);
  259. assertFalse(pasted);
  260. textarea.dispatchEvent({type: goog.events.EventType.KEYDOWN, keyCode: 0});
  261. assertFalse(pasted);
  262. clock.tick(
  263. goog.events.PasteHandler.MANDATORY_MS_BETWEEN_INPUT_EVENTS_TIE_BREAKER +
  264. 1);
  265. textarea.dispatchEvent(newBrowserEvent('input'));
  266. assertTrue(pasted);
  267. }
  268. function testOperaOnMacFiresKeyCode17WhenAppleKeyIsPressedButDoesNotFireAnKeyDownOnVLater() {
  269. // Opera on Macs fires keycode 17 when apple key is pressed, and then it does
  270. // not fire a keydown event when the V is pressed.
  271. goog.userAgent.OPERA = true;
  272. goog.userAgent.MAC = true;
  273. var handler = new goog.events.PasteHandler(textarea);
  274. // user clicks on the textarea and give it focus
  275. goog.events.listen(handler,
  276. goog.events.PasteHandler.EventType.PASTE,
  277. function() {
  278. pasted = true;
  279. });
  280. textarea.dispatchEvent(goog.events.EventType.FOCUS);
  281. assertFalse(pasted);
  282. // apple key is pressed, generating a keydown event
  283. textarea.dispatchEvent({type: goog.events.EventType.KEYDOWN, keyCode: 17});
  284. assertFalse(pasted);
  285. clock.tick(
  286. goog.events.PasteHandler.MANDATORY_MS_BETWEEN_INPUT_EVENTS_TIE_BREAKER +
  287. 1);
  288. // and then text is added magically without any extra keydown events.
  289. textarea.dispatchEvent(newBrowserEvent('input'));
  290. assertTrue(pasted);
  291. }
  292. function testScriptingDoesntTriggerPasteEvents() {
  293. var handlerUsedToListenForScriptingChanges =
  294. new goog.events.PasteHandler(textarea);
  295. pasted = false;
  296. // user clicks on the textarea and give it focus
  297. goog.events.listen(handlerUsedToListenForScriptingChanges,
  298. goog.events.PasteHandler.EventType.PASTE,
  299. function() {
  300. pasted = true;
  301. });
  302. goog.dom.getElement('foo').value = 'dear paste handler,';
  303. assertFalse(pasted);
  304. goog.dom.getElement('foo').value = 'please dont misunderstand script changes';
  305. assertFalse(pasted);
  306. goog.dom.getElement('foo').value = 'with user generated paste events';
  307. assertFalse(pasted);
  308. goog.dom.getElement('foo').value = 'thanks!';
  309. assertFalse(pasted);
  310. }
  311. function testAfterPaste() {
  312. goog.userAgent.IE = true;
  313. var handlerThatSupportsPasteEvents =
  314. new goog.events.PasteHandler(textarea);
  315. pasted = false;
  316. goog.events.listen(handlerThatSupportsPasteEvents,
  317. goog.events.PasteHandler.EventType.PASTE,
  318. function() {
  319. pasted = true;
  320. });
  321. var afterPasteFired = false;
  322. goog.events.listen(handlerThatSupportsPasteEvents,
  323. goog.events.PasteHandler.EventType.AFTER_PASTE,
  324. function() {
  325. afterPasteFired = true;
  326. });
  327. // Initial paste event comes before AFTER_PASTE has fired.
  328. textarea.dispatchEvent(newBrowserEvent('paste'));
  329. assertTrue(pasted);
  330. assertFalse(afterPasteFired);
  331. // Once text is pasted, it takes a bit to detect it, at which point
  332. // AFTER_PASTE is fired.
  333. clock.tick(goog.events.PasteHandler.PASTE_POLLING_PERIOD_MS_);
  334. textarea.value = 'text';
  335. clock.tick(goog.events.PasteHandler.PASTE_POLLING_PERIOD_MS_);
  336. assertTrue(afterPasteFired);
  337. }
  338. function testAfterPasteNotFiredIfDelayTooLong() {
  339. goog.userAgent.IE = true;
  340. var handlerThatSupportsPasteEvents =
  341. new goog.events.PasteHandler(textarea);
  342. pasted = false;
  343. goog.events.listen(handlerThatSupportsPasteEvents,
  344. goog.events.PasteHandler.EventType.PASTE,
  345. function() {
  346. pasted = true;
  347. });
  348. var afterPasteFired = false;
  349. goog.events.listen(handlerThatSupportsPasteEvents,
  350. goog.events.PasteHandler.EventType.AFTER_PASTE,
  351. function() {
  352. afterPasteFired = true;
  353. });
  354. // Initial paste event comes before AFTER_PASTE has fired.
  355. textarea.dispatchEvent(newBrowserEvent('paste'));
  356. assertTrue(pasted);
  357. assertFalse(afterPasteFired);
  358. // If the new text doesn't show up in time, we never fire AFTER_PASTE.
  359. clock.tick(goog.events.PasteHandler.PASTE_POLLING_TIMEOUT_MS_);
  360. textarea.value = 'text';
  361. clock.tick(goog.events.PasteHandler.PASTE_POLLING_PERIOD_MS_);
  362. assertFalse(afterPasteFired);
  363. }
  364. </script>
  365. </body>
  366. </html>