Home

# Class goog.events.PasteHandler

A paste event detector. Gets an {@code element} as parameter and fires {@code goog.events.PasteHandler.EventType.PASTE} events when text is pasted in the {@code element}. Uses heuristics to detect paste events in FF2. See more details of the heuristic on {@link #handleEvent_}.

extends goog.events.EventTarget

Instance Method Summary
| `checkUpdatedText_() ⇒ boolean` Checks whether the element.value property was updated, and if so, dispatches the event that let clients know that the text is available.
| `dispatch_(?goog.events.BrowserEvent e)` Dispatches the paste event.

`disposeInternal()`

Unattach listeners from this object. Classes that extend EventTarget may need to override this method in order to remove references to DOM Elements and additional listeners, it should be something like this:

    MyClass.prototype.disposeInternal = function() {
    MyClass.superClass_.disposeInternal.call(this);
    // Dispose logic for MyClass
    };

| `getEventHandler() ⇒ ?goog.events.EventHandler` Returns the event handler.
| `getState() ⇒ ?goog.events.PasteHandler.State` Returns the current state of the paste detection algorithm. Used mostly for testing.

`handleEvent_(?goog.events.BrowserEvent e)`

The main event handler which implements a state machine. To handle FF2, we enumerate and cover all the known ways a user can paste: 1) ctrl+v, shift+insert, cmd+v 2) right click -> paste 3) edit menu -> paste 4) drag and drop 5) middle click (1) is easy and can be detected by listening for key events and finding out which keys are pressed. (2), (3), (4) and (5) do not generate a key event, so we need to listen for more than that. (2-5) all generate 'input' events, but so does key events. So we need to have some sort of 'how did the input event was generated' history algorithm. (2) is an interesting case in Opera on a Mac: since Macs does not have two buttons, right clicking involves pressing the CTRL key. Even more interesting is the fact that opera does NOT set the e.ctrlKey bit. Instead, it sets e.keyCode = 0. {@link http://www.quirksmode.org/js/keys.html} (1) is also an interesting case in Opera on a Mac: Opera is the only browser covered by this class that can detect the cmd key (FF2 can't apparently). And it fires e.keyCode = 17, which is the CTRL key code. {@link http://www.quirksmode.org/js/keys.html} NOTE(user, pbarry): There is an interesting thing about (5): on Linux, (5) pastes the last thing that you highlighted, not the last thing that you ctrl+c'ed. This code will still generate a {@code PASTE} event though. We enumerate all the possible steps a user can take to paste text and we implemented the transition between the steps in a state machine. The following is the design of the state machine: matching paths: (1) happens on INIT -> FOCUSED -> TYPING -> [e.ctrlKey & e.keyCode = 'v'] (2-3) happens on INIT -> FOCUSED -> [input event happened] (4) happens on INIT -> [mouseover && text changed] non matching paths: user is typing normally INIT -> FOCUS -> TYPING -> INPUT -> INIT

`handleUnderFocused_(?goog.events.BrowserEvent e)`

{@code goog.events.PasteHandler.EventType.FOCUSED} is typically the second state the textarea will be, which is followed by the {@code INIT} state. On this state, users can paste in three different ways: edit -> paste, right click -> paste and drag and drop. The latter will generate a {@code goog.events.EventType.MOUSEOVER} event, which we match by making sure the textarea text changed. The first two will generate an 'input', which we match by making sure it was NOT generated by a key event (which also generates an 'input' event). Unfortunately, in Firefox, if you type fast, some KEYDOWN events are swallowed but an INPUT event may still happen. That means we need to differentiate between two consecutive INPUT events being generated either by swallowed key events OR by a valid edit -> paste -> edit -> paste action. We do this by checking a minimum time between the two events. This heuristic seems to work well, but it is obviously a heuristic :).

`handleUnderInit_(?goog.events.BrowserEvent e)`

{@code goog.events.PasteHandler.EventType.INIT} is the first initial state the textarea is found. You can only leave this state by setting focus on the textarea, which is how users will input text. You can also paste things using drag and drop, which will not generate a {@code goog.events.EventType.FOCUS} event, but will generate a {@code goog.events.EventType.MOUSEOVER}. For browsers that support the 'paste' event, we match it and stay on the same state.

`handleUnderTyping_(?goog.events.BrowserEvent e)`

{@code goog.events.PasteHandler.EventType.TYPING} is the third state this class can be. It exists because each KEYPRESS event will ALSO generate an INPUT event (because the textarea value changes), and we need to differentiate between an INPUT event generated by a key event and an INPUT event generated by edit -> paste actions. This is the state that we match the ctrl+v pattern.