17

Scenario: I'm trying to intercept paste events inside a textarea/input text, and filter the content being pasted.

Webkit/IE are handled rather well, as I can attach code to the onpaste event, and then read from the clipboard what is being pasted. Plenty of examples around.

Gecko is trickier, because as far as I know it isn't possible to read the clipboard content on Firefox (unless somebody knows a workaround for that?)
I just use the input swap trick for that.

Opera is being annoying tho. I can trap CTRL+V and SHIFT+INS, but there's no onpaste event.
Not to mention any sort of clipboard interaction, apparently.

So, my question is:

Can I detect if the user clicked on paste in the context menu on Opera? Is there any other way to detect the event?

EDIT:

Thanks everybody for the answers - they all add a good input, even if there's no definitive solution.
Having to choose, I'll pick the only one that tried to address the original question, and that would probably work if it wasn't too much of an hack to even try.

Notes for those that have my same problem (input filtering):

  • it is possible to capture content being dragged: mouseup + setTimeout does the trick everywhere almost perfectly.
  • without flash, there is probably no solution bar polling. Even with flash, it's not a completely solid solution either. Too much effort to support 100% of the cases.
Brian Tompsett - 汤莱恩
  • 5,195
  • 62
  • 50
  • 120
Razor
  • 19,590
  • 7
  • 50
  • 73
  • 3
    +1 For teaching me about the tags for highlighting keyboard actions :-) – James Wiseman Aug 20 '10 at 12:19
  • In a browser without a `paste` event, the answer's a flat no, bounty or no bounty. – Tim Down Aug 24 '10 at 13:58
  • I've seen really smart hacks making what most people thought was impossible. Take cufon for instance. Or the other dozens of workarounds out there that implement what we now take for granted. One way to do what I ask would be polling an input, but that's a solution I would rather avoid, hence my question (and bounty) to see if somebody comes up with something better. – Razor Aug 24 '10 at 20:35
  • I see your point, but Cufon is not really comparable to this. The answer to your question as framed is still no. If there is no event fired when the user hits `paste` in the context menu (which there isn't in, for example, Firefox 2), then there's simply nothing to hook into to detect the paste. All you've got left to fall back on is polling the input's value. – Tim Down Aug 25 '10 at 09:18

5 Answers5

9

I ran into this last year. In short, no.

I ended up using an onchange handler and filtering the content after it's already been pasted into the text box.

Ollie Edwards
  • 12,080
  • 6
  • 26
  • 33
6

You can intercept the paste with jQuery using the bind('paste', function() {});, compare string before and after pasting and apply your formatting.

The following was tested in IE7/FF3.6/Chrome/Safari 5

$("#textarea").bind('paste', function(e){ 
    // Do whatever you needed to do with the code here.
});

Live Example http://jsfiddle.net/VSrTg/2/

Edit An approach would be something like this:

$("#textarea").bind('paste', function(e){ 
    var oldText = this.value;
    setTimeout(function() { 
        // Compare oldText to $("#textarea").val() and format accordingly.
    }, 1000);
});

Edit 2 Given your revisions to your original post, if you're worried about the giant market share that is Opera, you're going to have to monitor the value of your textbox with a setInterval() and compare it against itself for changes.

Ultimately there will always be a way around your script, even the above example is susceptible to simply dragging text from another text box (or the address bar) into it without triggering the paste event defined above.

Robert
  • 20,200
  • 8
  • 50
  • 64
  • I am already aware that there is an onpaste event fox gecko/IE/webkit, if you read my question and the linked pages you'll see that I stated it clearly. I am trying to find a way to deal with this problem in opera (where your code does absolutely nothing) – Razor Aug 27 '10 at 08:35
  • In your post you said you were doing fine with IE/WebKit, having problems with Gecko, this works with Gecko. Opera is a different beast and I don't believe you can hook the paste event in any way. You can use Firebug and use console.log(e) to see what's dumped when you paste fire the paste event, but nothing looks useful to Opera. – Robert Aug 27 '10 at 10:09
  • Firefox 2 also has no paste event. – Tim Down Aug 27 '10 at 22:55
3

I would like to point out DOJO menu widget that is creating context menus perfectly in different browsers. http://www.dojotoolkit.org/reference-guide/dijit/Menu.html#dijit-menu

What you can do is that detect paste event in browsers that are supporting it and override context menu in browsers that are not supporting this event like opera.

Once you create your own context menu then you can add copy paste menu item or create context menu similar to the default using css.

Edited Some browsers might not allow us to fetch clipboard content, in this case we can always revert back to flash for borrowing some of its features that are cross browser. See couple of links I posted in comments.

Its complete implementation might have more issues than anticipated but it is possible and we can always give it a try (I will for sure).

Ayaz Alavi
  • 4,697
  • 8
  • 48
  • 67
  • Not terribly helpful: browsers will generally not allow JavaScript to trigger a paste. The user has to explicitly perform a paste using built-in browser mechanisms (keyboard shortcut, context menu, edit menu). Therefore it will not be possible to trigger a paste from a Dojo faked context menu. – Tim Down Aug 30 '10 at 13:20
  • 1
    It is definitely possible except getting text from clipboard is tricky part, but look at http://ericphan.info/blog/2008/12/17/cross-browser-copy-and-paste-with-jquerycopy.html and http://code.google.com/p/yii-blogdemo-extended/source/browse/trunk/app/js/jquery.clipboard-2.0.1/jquery.clipboard.js?r=22 – Ayaz Alavi Aug 30 '10 at 18:18
  • I was discounting the use of Flash, which is what both of the solutions you linked to do. – Tim Down Aug 30 '10 at 19:26
  • 1
    flash can give some neatness to the application for being stable cross browser technology, and in this particular case it is almost required. – Ayaz Alavi Aug 31 '10 at 06:29
2

The answer to the question is a simple no. The main browsers that have no paste event are recent versions of Opera and Firefox 2. Given that there is no paste event, you need to find an alternative event or set of events to detect a paste from the context menu as it actually happens. You can add handlers for every event there is (I've done this) and you simply get nothing in the relevant browsers when a paste is triggered from the context menu by the user.

This only leaves polling the text input's value regularly, which is not the same thing. You could keep track of keypresses and observe in your polling code that the text input's value has changed by some means other than keyboard input and do a diff, but that's hacky and unreliable.

Tim Down
  • 292,637
  • 67
  • 429
  • 506
0

I use the setTimeout for paste events. But for context menu select nothing seems to work(as stated above). I bind a mousemove to the input's form which fires the update function. Then unbind/bind so they don't stack up.

This handles the context menu select and dragging value to input field.

If your form is small, say with only one input field and the mouse will not land on it after selecting from context menu, bind to the form's parent or document. Sure, it has to wait until the mouse moves but that is the general user action after selecting from context menu.

Works fine.