/closure-library/closure/goog/events/pastehandler_test.html
HTML | 414 lines | 359 code | 47 blank | 8 comment | 0 complexity | 527093b50515b3f375e70eb371c92f2d MD5 | raw file
- <!DOCTYPE html>
- <html>
- <!--
- Copyright 2009 The Closure Library Authors. All Rights Reserved.
- Use of this source code is governed by the Apache License, Version 2.0.
- See the COPYING file for details.
- -->
- <!--
- -->
- <head>
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <title>Closure Unit Tests - goog.events.PasteHandler</title>
- <script src="../base.js"></script>
- <script>
- goog.require('goog.events.PasteHandler');
- goog.require('goog.testing.MockClock');
- goog.require('goog.testing.MockUserAgent');
- goog.require('goog.testing.jsunit');
- goog.require('goog.events.EventTarget');
- goog.require('goog.events.EventType');
- goog.require('goog.dom');
- </script>
- </head>
- <body>
- <textarea id="foo"></textarea>
- <script>
- function setUp() {
- // TODO(user): fix {@code goog.testing.MockUserAgent} to do the right thing.
- // the code doesn't seem to be updating the variables with
- // goog.userAgent.init_(), which means it is not allowing me to mock the
- // user agent variables.
- goog.userAgent.GECKO = true;
- goog.userAgent.IE = false;
- goog.userAgent.WEBKIT = false;
- goog.userAgent.VERSION = '1.8';
- textarea = new goog.events.EventTarget();
- textarea.value = '';
- clock = new goog.testing.MockClock(true);
- mockUserAgent = new goog.testing.MockUserAgent();
- handler = new goog.events.PasteHandler(textarea);
- pasted = false;
- goog.events.listen(handler, goog.events.PasteHandler.EventType.PASTE,
- function() {
- pasted = true;
- });
- }
- function tearDown() {
- textarea.dispose();
- handler.dispose();
- clock.dispose();
- mockUserAgent.dispose();
- }
- function newBrowserEvent(type) {
- if (goog.isString(type)) {
- return new goog.events.BrowserEvent({type: type});
- } else {
- return new goog.events.BrowserEvent(type);
- }
- }
- function testDispatchingPasteEventSupportedByAFewBrowsersWork() {
- goog.userAgent.IE = true;
- var handlerThatSupportsPasteEvents =
- new goog.events.PasteHandler(textarea);
- // user clicks on the textarea and give it focus
- goog.events.listen(handlerThatSupportsPasteEvents,
- goog.events.PasteHandler.EventType.PASTE,
- function() {
- pasted = true;
- });
- textarea.dispatchEvent(newBrowserEvent('paste'));
- assertTrue(pasted);
- }
- function testJustTypingDoesntFirePasteEvent() {
- // user clicks on the textarea and give it focus
- textarea.dispatchEvent(newBrowserEvent(goog.events.EventType.FOCUS));
- assertFalse(pasted);
- // user starts typing
- textarea.dispatchEvent(newBrowserEvent({
- type: goog.events.EventType.KEYDOWN,
- keyCode: goog.events.KeyCodes.A
- }));
- textarea.value = 'a';
- assertFalse(pasted);
- // still typing
- textarea.dispatchEvent({
- type: goog.events.EventType.KEYDOWN,
- keyCode: goog.events.KeyCodes.B
- });
- textarea.value = 'ab';
- assertFalse(pasted);
- // ends typing
- textarea.dispatchEvent({
- type: goog.events.EventType.KEYDOWN,
- keyCode: goog.events.KeyCodes.C
- });
- textarea.value = 'abc';
- assertFalse(pasted);
- }
- function testStartsOnInitialState() {
- assertTrue(handler.getState() == goog.events.PasteHandler.State.INIT);
- assertFalse(pasted);
- }
- function testBlurOnInit() {
- textarea.dispatchEvent(goog.events.EventType.BLUR);
- assertTrue(handler.getState() == goog.events.PasteHandler.State.INIT);
- assertFalse(pasted);
- }
- function testFocusOnInit() {
- textarea.dispatchEvent(goog.events.EventType.FOCUS);
- assertTrue(handler.getState() == goog.events.PasteHandler.State.FOCUSED);
- assertFalse(pasted);
- }
- function testInputOnFocus() {
- // user clicks on the textarea
- textarea.dispatchEvent(newBrowserEvent(goog.events.EventType.FOCUS));
- clock.tick(
- goog.events.PasteHandler.MANDATORY_MS_BETWEEN_INPUT_EVENTS_TIE_BREAKER +
- 1);
- // and right click -> paste a text!
- textarea.dispatchEvent(newBrowserEvent('input'));
- assertTrue(handler.getState() == goog.events.PasteHandler.State.FOCUSED);
- // make sure we detected it
- assertTrue(pasted);
- }
- function testKeyPressOnFocus() {
- // user clicks on the textarea
- textarea.dispatchEvent(newBrowserEvent(goog.events.EventType.FOCUS));
- // starts typing something
- textarea.dispatchEvent(newBrowserEvent({
- type: goog.events.EventType.KEYDOWN,
- keyCode: goog.events.KeyCodes.A
- }));
- assertTrue(handler.getState() == goog.events.PasteHandler.State.TYPING);
- assertFalse(pasted);
- // and then presses ctrl+v
- textarea.dispatchEvent(newBrowserEvent({
- type: goog.events.EventType.KEYDOWN,
- keyCode: goog.events.KeyCodes.V,
- ctrlKey: true
- }));
- assertTrue(handler.getState() == goog.events.PasteHandler.State.TYPING);
- // makes sure we detected it
- assertTrue(pasted);
- }
- function testMouseOverOnInit() {
- // user has something on the events
- textarea.value = 'pasted string';
- // and right click -> paste it on the textarea, WITHOUT giving focus
- textarea.dispatchEvent(newBrowserEvent(goog.events.EventType.MOUSEOVER));
- assertTrue(handler.getState() == goog.events.PasteHandler.State.INIT);
- // makes sure we detect it
- assertTrue(pasted);
- pasted = false;
- // user normaly mouseovers the textarea, with no text change
- textarea.dispatchEvent(goog.events.EventType.MOUSEOVER);
- assertTrue(handler.getState() == goog.events.PasteHandler.State.INIT);
- // text area value doesnt change
- assertFalse(pasted);
- }
- function testMouseOverAfterTyping() {
- textarea.dispatchEvent(goog.events.EventType.FOCUS);
- assertFalse(pasted);
- textarea.dispatchEvent(
- {type: goog.events.EventType.KEYDOWN, keyCode: goog.events.KeyCodes.A});
- assertFalse(pasted);
- textarea.value = 'a';
- textarea.dispatchEvent('input');
- assertFalse(pasted);
- assertEquals('a', handler.oldValue_);
- textarea.dispatchEvent(goog.events.EventType.MOUSEOVER);
- assertFalse(pasted);
- }
- function testTypingAndThenRightClickPaste() {
- textarea.dispatchEvent(goog.events.EventType.FOCUS);
- textarea.dispatchEvent(
- {type: goog.events.EventType.KEYDOWN, keyCode: goog.events.KeyCodes.A});
- assertFalse(pasted);
- textarea.value = 'a';
- clock.tick(
- goog.events.PasteHandler.MANDATORY_MS_BETWEEN_INPUT_EVENTS_TIE_BREAKER +
- 1);
- textarea.dispatchEvent('input');
- assertFalse(pasted);
- assertEquals('a', handler.oldValue_);
- textarea.value = 'ab';
- clock.tick(
- goog.events.PasteHandler.MANDATORY_MS_BETWEEN_INPUT_EVENTS_TIE_BREAKER +
- 1);
- textarea.dispatchEvent(newBrowserEvent('input'));
- assertTrue(pasted);
- }
- function testTypingReallyFastDispatchesTwoInputEventsBeforeTheKeyDownEvent() {
- textarea.dispatchEvent(goog.events.EventType.FOCUS);
- // keydown and input events seems to be fired indepently: even though input
- // should happen after the key event, it doens't if the user types fast
- // enough. FF2 + linux doesn't fire keydown events for every key pressed when
- // you type fast enough. if one of the keydown events gets swallowed, two
- // input events are fired consecutively. notice that there is a similar
- // scenario, that actually does produce a valid paste action.
- // {@see testRightClickRightClickAlsoDispatchesTwoConsecutiveInputEvents}
- textarea.dispatchEvent(
- {type: goog.events.EventType.KEYDOWN, keyCode: goog.events.KeyCodes.A});
- assertFalse(pasted);
- textarea.value = 'a';
- clock.tick(
- goog.events.PasteHandler.MANDATORY_MS_BETWEEN_INPUT_EVENTS_TIE_BREAKER -
- 1);
- textarea.dispatchEvent('input');
- assertFalse(pasted);
- // second key down events gets fired on a different order
- textarea.value = 'ab';
- clock.tick(
- goog.events.PasteHandler.MANDATORY_MS_BETWEEN_INPUT_EVENTS_TIE_BREAKER -
- 1);
- textarea.dispatchEvent('input');
- assertFalse(pasted);
- }
- function testRightClickRightClickAlsoDispatchesTwoConsecutiveInputEvents() {
- textarea.dispatchEvent(goog.events.EventType.FOCUS);
- // there is also another case that two consecutive INPUT events are fired,
- // but in a valid paste action: if the user edit -> paste -> edit -> paste,
- // it is a valid paste action.
- textarea.value = 'a';
- clock.tick(
- goog.events.PasteHandler.MANDATORY_MS_BETWEEN_INPUT_EVENTS_TIE_BREAKER +
- 1);
- textarea.dispatchEvent(newBrowserEvent('input'));
- assertTrue(pasted);
- // second key down events gets fired on a different order
- textarea.value = 'ab';
- clock.tick(
- goog.events.PasteHandler.MANDATORY_MS_BETWEEN_INPUT_EVENTS_TIE_BREAKER +
- 1);
- textarea.dispatchEvent(newBrowserEvent('input'));
- assertTrue(pasted);
- }
- function testMiddleClickWithoutFocusTriggersPasteEvent() {
- // if the textarea is NOT selected, and then we use the middle button,
- // FF2+linux pastes what was last highlighted, causing a paste action.
- textarea.dispatchEvent(goog.events.EventType.FOCUS);
- textarea.dispatchEvent(newBrowserEvent('input'));
- assertTrue(pasted);
- }
- function testMacRightClickPasteRequiresToPressCtrlBecauseItDoesntHaveTwoMouseButtons() {
- // Macs don't have two buttons mouse: this means that you need to press
- // ctrl + click to get to the menu, and then you can click paste.
- // The sequences of events fired on Opera are:
- // focus -> keydown (keyCode == 0, not e.ctrlKey) -> input
- goog.userAgent.OPERA = true;
- goog.userAgent.MAC = true;
- var handler = new goog.events.PasteHandler(textarea);
- // user clicks on the textarea and give it focus
- goog.events.listen(handler,
- goog.events.PasteHandler.EventType.PASTE,
- function() {
- pasted = true;
- });
- textarea.dispatchEvent(goog.events.EventType.FOCUS);
- assertFalse(pasted);
- textarea.dispatchEvent({type: goog.events.EventType.KEYDOWN, keyCode: 0});
- assertFalse(pasted);
- clock.tick(
- goog.events.PasteHandler.MANDATORY_MS_BETWEEN_INPUT_EVENTS_TIE_BREAKER +
- 1);
- textarea.dispatchEvent(newBrowserEvent('input'));
- assertTrue(pasted);
- }
- function testOperaOnMacFiresKeyCode17WhenAppleKeyIsPressedButDoesNotFireAnKeyDownOnVLater() {
- // Opera on Macs fires keycode 17 when apple key is pressed, and then it does
- // not fire a keydown event when the V is pressed.
- goog.userAgent.OPERA = true;
- goog.userAgent.MAC = true;
- var handler = new goog.events.PasteHandler(textarea);
- // user clicks on the textarea and give it focus
- goog.events.listen(handler,
- goog.events.PasteHandler.EventType.PASTE,
- function() {
- pasted = true;
- });
- textarea.dispatchEvent(goog.events.EventType.FOCUS);
- assertFalse(pasted);
- // apple key is pressed, generating a keydown event
- textarea.dispatchEvent({type: goog.events.EventType.KEYDOWN, keyCode: 17});
- assertFalse(pasted);
- clock.tick(
- goog.events.PasteHandler.MANDATORY_MS_BETWEEN_INPUT_EVENTS_TIE_BREAKER +
- 1);
- // and then text is added magically without any extra keydown events.
- textarea.dispatchEvent(newBrowserEvent('input'));
- assertTrue(pasted);
- }
- function testScriptingDoesntTriggerPasteEvents() {
- var handlerUsedToListenForScriptingChanges =
- new goog.events.PasteHandler(textarea);
- pasted = false;
- // user clicks on the textarea and give it focus
- goog.events.listen(handlerUsedToListenForScriptingChanges,
- goog.events.PasteHandler.EventType.PASTE,
- function() {
- pasted = true;
- });
- goog.dom.getElement('foo').value = 'dear paste handler,';
- assertFalse(pasted);
- goog.dom.getElement('foo').value = 'please dont misunderstand script changes';
- assertFalse(pasted);
- goog.dom.getElement('foo').value = 'with user generated paste events';
- assertFalse(pasted);
- goog.dom.getElement('foo').value = 'thanks!';
- assertFalse(pasted);
- }
- function testAfterPaste() {
- goog.userAgent.IE = true;
- var handlerThatSupportsPasteEvents =
- new goog.events.PasteHandler(textarea);
- pasted = false;
- goog.events.listen(handlerThatSupportsPasteEvents,
- goog.events.PasteHandler.EventType.PASTE,
- function() {
- pasted = true;
- });
- var afterPasteFired = false;
- goog.events.listen(handlerThatSupportsPasteEvents,
- goog.events.PasteHandler.EventType.AFTER_PASTE,
- function() {
- afterPasteFired = true;
- });
- // Initial paste event comes before AFTER_PASTE has fired.
- textarea.dispatchEvent(newBrowserEvent('paste'));
- assertTrue(pasted);
- assertFalse(afterPasteFired);
- // Once text is pasted, it takes a bit to detect it, at which point
- // AFTER_PASTE is fired.
- clock.tick(goog.events.PasteHandler.PASTE_POLLING_PERIOD_MS_);
- textarea.value = 'text';
- clock.tick(goog.events.PasteHandler.PASTE_POLLING_PERIOD_MS_);
- assertTrue(afterPasteFired);
- }
- function testAfterPasteNotFiredIfDelayTooLong() {
- goog.userAgent.IE = true;
- var handlerThatSupportsPasteEvents =
- new goog.events.PasteHandler(textarea);
- pasted = false;
- goog.events.listen(handlerThatSupportsPasteEvents,
- goog.events.PasteHandler.EventType.PASTE,
- function() {
- pasted = true;
- });
- var afterPasteFired = false;
- goog.events.listen(handlerThatSupportsPasteEvents,
- goog.events.PasteHandler.EventType.AFTER_PASTE,
- function() {
- afterPasteFired = true;
- });
- // Initial paste event comes before AFTER_PASTE has fired.
- textarea.dispatchEvent(newBrowserEvent('paste'));
- assertTrue(pasted);
- assertFalse(afterPasteFired);
- // If the new text doesn't show up in time, we never fire AFTER_PASTE.
- clock.tick(goog.events.PasteHandler.PASTE_POLLING_TIMEOUT_MS_);
- textarea.value = 'text';
- clock.tick(goog.events.PasteHandler.PASTE_POLLING_PERIOD_MS_);
- assertFalse(afterPasteFired);
- }
- </script>
- </body>
- </html>