7

While reuploading a bunch of old ImageShack images to imgur, I noticed something funny: sometimes, after uploading an image from the web, I would no longer be able to paste anything into the edit box. A bit more investigation revealed that the following steps are needed to reproduce this bug:

  1. In the SE post editor, click the button to upload an image.

  2. In the image upload dialog, click "You can also provide a link from the web."

  3. Make sure the URL input box has the focus, and then close the dialog by pressing Esc.

    Alternatively, on Firefox, type or paste an image URL into the text box and submit the form by pressing Enter. (This does not seem to trigger the bug on Chrome; thanks, Chris Jester-Young.)

    Either way, the bug will not be triggered if you close the dialog by clicking something outside the URL input box, like the submit button or the close button.

  4. Once back in the Markdown editor, try pasting something into the edit box. Nothing will happen.

  5. Reopening and closing the image upload dialog will make paste work again.

Apparently, what happens is that the image upload dialog installs its own paste event handler onto the <body> element, in order to let you paste images into the dialog to upload them. This handler should be removed when the dialog closes, but the steps above break this, leaving the handler in place.

Why? Well, it turns out that the dialog itself removes the paste event handler when the URL entry box gains focus (so that you can paste an URL into it, of course), and adds it back when the box loses focus. But if you submit the upload form while the URL entry box still has focus, then the blur event handler on the box runs only after the dialog has closed. Thus, the sequence of events (no pun intended) runs like this:

  1. Open upload dialog. Paste event handler is added.
  2. URL entry box gets focus. Paste event handler is removed.
  3. Close upload dialog by pressing Esc. Paste event handler is (again, redundantly) removed.
  4. URL entry box loses focus as it disappears from the page. Paste event handler is added back. (Oops!)

How do we fix this? Well, I see a bunch of ways:

  • Have the code that closes the popup remove the blur event handler from the URL input, so that it cannot run any more, before removing the popup from the DOM.
  • Have the blur event handler itself check a flag to see if we've already closed the dialog, and if so, not add back the paste handler on <body>.
  • Have the paste handler itself check if the upload dialog is present, and if not, do nothing and let the event propagate.

Any of these should work. Heck, you could implement all of them, just to make sure. :)

  • Up and down arrows also stop working. I guess this might be related. – DavidPostill Sep 18 '15 at 9:53
  • @DavidPostill: That's odd, I can't seem to repro that one. It does sound like there might be a left-over keypress / keydown handler too. (And, in fact, there is one. It should only trigger on the escape key, but maybe there's some kind of a bug there too. BTW, what browser version are you using?) – Ilmari Karonen Sep 18 '15 at 11:33
  • I can't always repro it either. And I'm not sure if it's inserting images that triggers it. It might be selecting text and inserting a hyperlink. I do both of them a lot. It's definately one of the other (or both). Firefox 40 on Windows. Next time I see it I will let you know for sure which one it was. – DavidPostill Sep 18 '15 at 11:46
  • 1
    OK. It's different bug when adding hyperlinks. To repro select some text, press ctrl+l, paste hyperlink, press enter. Now up and down arrow keys don't work. Maybe you can fix that in SOUP as well (I'm a big fan of SOUP) ;) – DavidPostill Sep 18 '15 at 11:51
  • Switching to a different tab and back fixes the hyperlink bug if that helps. – DavidPostill Sep 18 '15 at 11:54
  • @DavidPostill: OK, I can repro it now. Just pressing Ctrl+L and then Esc seems to be enough to trigger it. And just un-focusing the textarea seems to fix it, which unfortunately also makes it annoying to debug. :( – Ilmari Karonen Sep 18 '15 at 13:13
  • @DavidPostill: I still have absolutely no idea what's causing the arrow key bug, and I'm starting to suspect it's a bug in Firefox. But I did at least find an earlier report of it. – Ilmari Karonen Sep 18 '15 at 18:35
  • I knew there was a bug report - I just couldn't find it ... :/ – DavidPostill Sep 18 '15 at 18:48
  • I can't reproduce this (I submitted the URL by pressing Enter, and was able to paste). I'm using Chrome 45.0.2454.101 on OS X 10.10.5. What browser are you using? – Chris Jester-Young Oct 3 '15 at 7:30
  • @ChrisJester-Young: Firefox 41.0 / Ubuntu. I just tested this on Chromium 45.0.2454.85, and can repro this bug there by closing the upload dialog using the Esc key while the URL input box has focus, but not by pressing Enter. Not sure why, although I suspect some event sequencing difference between Firefox and Chrome. – Ilmari Karonen Oct 3 '15 at 11:29
  • Can reproduce this with Iceweasel (firefox) 38.5.0esr-1~deb7u2 on Debian 7.9 (wheezy). Happens loads of times. – JoErNanO Dec 29 '15 at 13:29
  • 1
    To those regularly encountering this, it may be helpful to note that the information presented here also inspired a workaround: If you encounter this bug, paste functionality can be restored by opening the Upload Image popup again and then closing it. That'll set the input handlers back to a sane state. – FeRD Jan 28 '18 at 11:36
  • 1
    So, 2 years later this still happens. meta.stackexchange.com/questions/306323/… – Hobbes Jan 28 '18 at 12:27
2

What I came up with for the SOUP user script is this ugly hack:

$('#content').on('paste', function () {
    if ( $('.modal-dropzone').length > 0 ) return;
    ( $._data( document.body, 'events' ).paste || [] ).forEach( function ( h ) {
        if ( ! /\.modal-dropzone/.test( h.handler.toString() ) ) return;
        $('body').off( 'paste', h.handler );
    } );
} );

For those not some familiar with the internals of jQuery, what this code does is catch paste events just before they reach the <body> and the upload dialog's event handler. It then checks if the upload dialog seems to be present, and if not, digs into the guts of jQuery via $._data() to see if there are any paste event handlers defined for <body>. If there are, it then double-checks that they really look like the upload dialog handler (by looking for a specific class name in their source code) and, if so, removes them just before they can fire. (This should hopefully be a bit safer than just indiscriminately nuking all paste event handlers on <body>.)

Anyway, yeah, this is ugly even by SOUP standards. ;-) I'd really like to see this fixed properly instead. But until then, it's in SOUP as of the just released v1.38.

  • The popupClose event is a custom event we use for our popup system that fires when you click outside of the popup (it can also fire in other circumstances, such as hitting Esc, but for the purposes of our image uploader, that's the main place where it fires, since the image uploader has its own custom Esc handler). – Chris Jester-Young Oct 3 '15 at 7:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .