Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

File Drag 'n Drop is not detectable... #57

Closed
paulirish opened this Issue · 26 comments

10 participants

@paulirish
Owner

http://twitter.com/paulrouget/status/9587929569

if ("files" in DataTransfer.prototype) {...}
@paulirish
Owner

also related is support for multiple files..

var input = document.createElement('input');
input.type = 'file';
return ('files' in input);

spec http://www.w3.org/TR/html5/forms.html#dom-input-files

@paulirish
Owner

fwiw if ("files" in DataTransfer.prototype) {...} doesnt work in Chrome as no DataTransfer object is exposed globally.
:(

@devongovett

Also not in Safari.

@KuraFire
Owner

Correct me if I'm wrong, but wouldn't this indicate an omission in implementation in Webkit? Whether or not a bug already has been filed for this, isn't it safe to assume that this API will at some point be exposed at least?

@paulirish
Owner

Specifically the DataTransfer interface is not exposed to the global object. The spec is unclear whether this is a requirement. And right now there's no solid reason it SHOULD be exposed other than feature detection.

Regardless, webkit has the feature, so even though it's inconvenient, Modernizr should be able to detect it.

@antimatter15

This is only tangentially related, but from some testing, it seems that some versions of Firefox and Chrome on Windows XP (but not Vista or 7) and Firefox 3 on Ubuntu (but not Fx4) seem to pause the page's rendering. For instance, if you changed the page's background color when someone was dragging a file (during ondragover), on XP, that background color change would only be visible after the file has been dragged away or dropped. As far as I'm aware, this bug is also undetectable.

@paulirish paulirish closed this
@danielchatfield

WordPress successfully manages to detect so why can't Modernizr?

@paulirish
Owner

Hmmm... good question! would love to see wordpress's code..

but for now

this detect is basically equivalent: Modernizr.draganddrop && window.FileReader

@timdown

Safari 5 is a problem here because drag-and-drop works but Safari has no FileReader API.

@timdown

You could test for FormData but it's a really terrible inference.

@chriskeeble

@paulirish Although it is documented as you say, it states:

I think Modernizr.draganddrop && window.FileReader is good enough these days.

But that doesn't work for Safari (which doesn't make use of window.FileReader) so returns false but does support file drag and drop.

We need a reliable solution for detecting whether (specifically) file drag and drop is supported by the current browser. Any suggestions?

@stucox
Owner

Which Safari versions does file drag & drop work in?

@chriskeeble

It definitely works in Safari 5.1.7 (7534.57.2) - I've just tested it to confirm.

FYI - Currently using the following functions (implementing Modernizr) in a specific application to detect browser support for File Drag and Drop.

function isSafari5() {
    return !!navigator.userAgent.match(' Safari/') && !navigator.userAgent.match(' Chrom') && !!navigator.userAgent.match(' Version/5.');
};

function isFileAPIEnabled () {
    return !!window.FileReader;
};

function isFileDragAndDropSupported() {
    var isiOS = !!navigator.userAgent.match('iPhone OS') || !!navigator.userAgent.match('iPad');
    return (Modernizr.draganddrop && !isiOS && (isFileAPIEnabled() || isSafari5()));
};
@stucox
Owner

How about older versions? Caniuse says that Drag & Drop is supported back as far as 3.1, but doesn't say anything specific about file drag & drop...

@chriskeeble

I'm sorry, I don't know and don't have access to a test environment with older versions of Safari currently.

I would hesitate before interpreting Drag & Drop support as File Drag & Drop support though, as you rightly indicate.

@stucox
Owner

Ok, I did a bit of testing and found Safari 4, 5.0 and 5.1 all seem to support file drag & drop — in so much as a drag event has a dataTransfer.files property (I was doing this via BrowserStack so not so easy to test if it actually allowed files to be dragged and dropped!). They don't offer window.FileReader, but they do offer window.FileList...

So maybe Modernizr.draganddrop && window.FileList would be a more accurate detect for file drag & drop?

IE9 (which supports D&D, but not file D&D) fails this test.

Do we know of any browsers which support the Files API, and D&D, but don't support file D&D?

@pusewicz

It would be great to get this sorted out.

@stucox
Owner

From what I've seen in my own testing (which I'll admit hasn't been entirely thorough), I'd be happy to add a Modernizr.draganddropfiles detect which uses Modernizr.draganddrop && window.FileList, if others are happy with this – @paulirish?

Slightly apprehensive as it feels a bit like a heuristic rather than a proper detect, but most detects are to some degree.

@paulirish
Owner

I'm happy with that approach. @pusewicz and @chriskeeble can you do testing across your target browsers/devices once stu finishes the impl of this?

@pusewicz

Yup.

@stucox stucox was assigned
@stucox
Owner

Assigned to me. No promises on when this'll get done – v3 stuff is taking priority.

@patrickkettner patrickkettner referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@patrickkettner patrickkettner referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@patrickkettner patrickkettner referenced this issue from a commit in patrickkettner/Modernizr
@patrickkettner patrickkettner add drag and drop files test - fixes #57 17f2faa
@jimmywarting

@danielchatfield I did lookup who Wordpress tackles this in the code

if ( up.features.dragdrop && ! $(document.body).hasClass('mobile') ) {
uploaddiv.addClass('drag-drop');

And that is the same as if("draggable" in div" && browser sniffing)

how the mobile class gets there is by this usar agent sniffing:

function wp_is_mobile() {
        static $is_mobile;

        if ( isset($is_mobile) )
                return $is_mobile;

        if ( empty($_SERVER['HTTP_USER_AGENT']) ) {
                $is_mobile = false;
        } elseif ( strpos($_SERVER['HTTP_USER_AGENT'], 'Mobile') !== false // many mobile devices (all iPhone, iPad, etc.)
                || strpos($_SERVER['HTTP_USER_AGENT'], 'Android') !== false
                || strpos($_SERVER['HTTP_USER_AGENT'], 'Silk/') !== false
                || strpos($_SERVER['HTTP_USER_AGENT'], 'Kindle') !== false
                || strpos($_SERVER['HTTP_USER_AGENT'], 'BlackBerry') !== false
                || strpos($_SERVER['HTTP_USER_AGENT'], 'Opera Mini') !== false
                || strpos($_SERVER['HTTP_USER_AGENT'], 'Opera Mobi') !== false ) {
                        $is_mobile = true;
        } else {
                $is_mobile = false;
        }

        return $is_mobile;
}

if ( wp_is_mobile() ) :
   $body_class .= ' mobile';
@stucox
Owner

Cheers @jimmywarting, good to have the reference. i.e. “we’re not alone”.

@jimmywarting

Here is a equivalent method in vanilla js if you are interested to do the same control as Wordpress

var draganddrop = "draggable" in document.createElement("div") && !/Mobile|Android|Slick\/|Kindle|BlackBerry|Opera Mini|Opera Mobi/i.test(navigator.userAgent)
@stucox
Owner

I think we’re leaving this as undetectable. I don’t think anyone wants to have to maintain a list of every “mobile” browser, which as you pointed out on #993 might just take a UI update for one of these browsers to support drag & drop all of a sudden.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.