Recently I was contracted to develop a new plugin for FileField Sources to allow pasting from clipboard. The newer versions of Chrome have supported this for a while (per this GMail blog post) while Firefox has an interesting behavior when pasting into contentEditable HTML areas that allows you to intercept image files (it pastes files from clipboard as an IMG tag with a data:image/png src attribute).
Combined, we get pretty good browser coverage. The Chrome implementation is following the W3C draft specification for clipboards, so hopefully more browsers will be supported in the future.
Here's an initial patch which adds this functionality for Firefox and Chrome. It doesn't currently hide the field for IE versions, but it *should* notify the user that clipboard support is not available; which in many ways is better than mysteriously hiding the options entirely.
| Comment | File | Size | Author |
|---|---|---|---|
| #17 | filefield_sources_clipboard.patch | 13.8 KB | quicksketch |
| #16 | filefield_sources_clipboard.patch | 6.28 KB | quicksketch |
| #13 | filefield_sources_clipboard.patch | 13.77 KB | quicksketch |
| #8 | filefield_sources_clipboard.patch | 13.76 KB | quicksketch |
| #7 | filefield_sources_clipboard.patch | 19.13 KB | quicksketch |
Comments
Comment #1
RandalK commentedApplying this patch gives me this error:
I have worked around this by adding "\ No newline at end of file" to the end of the patch directly.
Upon selecting the "tab" and doing as instructed it fails if there is more then one item in the clipboard array e.g.:
Attached patch adds a loop that tries to find the first kind of file in the array.
Comment #2
quicksketchI thought about adding a loop also, but that had the odd side effect when copy/pasting an actual file from the desktop, the first item is the file name (in text) and the second item is the *icon* of the file (not the file itself unfortunately). Considering this isn't expected behavior, I stuck with just keeping the first item. In what situation do you have a second item that is the file you want instead of it being the first item?
Comment #3
RandalK commentedI have just been copying files from another browser tab with right-click copy image, the first appears as the html that wraps the image and the second being the image as a file object.
Comment #4
quicksketchAh, nice! Well lets add the loop back in there then. Kind of unfortunate that Macs have the unfortunate effect of pasting the file icon. No idea how that's supposed to be helpful. :\
Otherwise though, sounds like the source works pretty well? Any further comments?
Comment #5
RandalK commentedHad a try in afew browsers now Chrome support is good.
Managed to upload a file on Firefox from a desktop copy, although there is a missing function Drupal.fileFieldSources.moveCaretToEnd.
In older browsers that have no support for the paste event do not show any indication that it failed might need a check for this:
Not sure if this should support copying from the desktop, on linux you just get the file path "/home/username/Desktop/myfile.ext"
Comment #6
quicksketchThanks for testing! Yeah that moveCaretToEnd() function I had added at one point but it didn't work on the contentEditable we're using to capture pastes, so I took it out.
Regarding the check, most browsers have support for onPaste I believe (including IE): http://www.quirksmode.org/dom/events/cutcopypaste.html
We might need to do some testing to see if this testing is necessary and how accurately we can target it.
Comment #7
quicksketchSo, some real-world testing makes feature detection even more difficult:
- Safari supports onpaste events and event clipboardData at the event level, however it does not include DataTransfer objects that contain any files. Seems like support may be there entirely but disabled (which would make sense if it's built into core Webkit). I've added an extra check so that Safari won't accidentally attempt to access non-existent properties and the error reports properly.
- IE supports onpaste events, but *will not allow pasting of images*. The entire option to paste both from right-click and the Edit menu is simply grayed out.
- Opera doesn't seem to support onpaste events at all, doh. The option to paste is also disabled like it is in IE when the clipboard contains images.
So in IE and Opera don't even have the opportunity to report an error, since the paste event either isn't allowed or it's not supported.
We *could* simply check $.browser.msie and $.browser.opera and show a warning, but attempt to process the clipboard anyway. I personally am inclined just to put a note on the feature with a link to Drupal.org where we can update information as it becomes available.
Here's a revised patch that includes your for() loop, adds better error checking, removes that moveCaretToEnd call, and adds this warning.
Comment #8
quicksketchThat last patch had an unrelated file in it.
Comment #9
RandalK commentedNot had time to test this, hopefully I will over the weekend but just eyeing the patch this looks off:
I'd agree with browser support being sketchy the notice would probably be best.
Comment #10
quicksketchSo jQuery attempts to standardized the normal event (or "e") variable when it comes into an event handler, so e.originalEvent actually means the raw browser event with all the discrepancies between browsers. e.originalEvent.clipboardData is the check for event-level clipboardData support, which both Safari and Chrome match. However e.originalEvent.clipboardData.items is only populated by Chrome, which is where the actual contents of the clipboard are stored.
As you probably know, you can't just check e.originalEvent.clipboardData.items directly, because if e.originalEvent.clipboardData is not present, you get an unknown variable error when checking for the child property of a parent that doesn't exist.
That said, there may be a better set of properties to be checking, but I think it's all necessary, other than maybe the check for e.originalEvent, since we know jQuery is going to make that.
Comment #11
RandalK commentedOh I understand why the check is there but what does not look right is this "clipboardData = e.originalEvent;" which looks like it should be "clipboardData = e.originalEvent.clipboardData;"
Comment #12
quicksketchOh, right you are. I'll take another look.
Comment #13
quicksketchUpdated patch. The change doesn't have any effect though, since no browsers currently actually use that event location (yet).
Comment #14
RandalK commentedMore testing in Windows browsers:
IE 9: no paste, message shown = good
Safari (win) 5.1: no paste, message shown = good
Chrome (win) 21.0: works
Firefox (win) 15.0: works, but if you click "Clipboard" then "Upload" then back to "Clipboard" and paste as to error the hint text copies into the div. This might happen because the event listeners get attached on click each time.
I don't own a Mac but we should probably test that platform also.
Comment #15
quicksketchThanks! I've done all my testing on Mac (except the IE browsers) with good results. I'll look into that Firefox issue.
Comment #16
quicksketchSorry I rerolled this patch after restructuring the code in #1547356: Browse option for IMCE disapear after an image has been uploaded in another imce image field and accidentally introduced the double-binding in the process. Simply moving the .bind() events outside the click handler again makes everything work properly.
Comment #17
quicksketchGar, with the new clipboard.inc included.
Comment #18
quicksketchCommitted #17 and it's in the 1.7 release (for Drupal 7 only).