{"action":"created","issue":{"url":"https://api.github.com/repos/Modernizr/Modernizr/issues/659","labels_url":"https://api.github.com/repos/Modernizr/Modernizr/issues/659/labels{/name}","comments_url":"https://api.github.com/repos/Modernizr/Modernizr/issues/659/comments","events_url":"https://api.github.com/repos/Modernizr/Modernizr/issues/659/events","html_url":"https://github.com/Modernizr/Modernizr/pull/659","id":6303802,"number":659,"title":"fixes #605: Clipboard API feature-detection","user":{"login":"fivetanley","id":1275021,"avatar_url":"https://avatars.githubusercontent.com/u/1275021?v=3","gravatar_id":"","url":"https://api.github.com/users/fivetanley","html_url":"https://github.com/fivetanley","followers_url":"https://api.github.com/users/fivetanley/followers","following_url":"https://api.github.com/users/fivetanley/following{/other_user}","gists_url":"https://api.github.com/users/fivetanley/gists{/gist_id}","starred_url":"https://api.github.com/users/fivetanley/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fivetanley/subscriptions","organizations_url":"https://api.github.com/users/fivetanley/orgs","repos_url":"https://api.github.com/users/fivetanley/repos","events_url":"https://api.github.com/users/fivetanley/events{/privacy}","received_events_url":"https://api.github.com/users/fivetanley/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":32,"created_at":"2012-08-18T07:44:56Z","updated_at":"2015-04-25T04:05:56Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/Modernizr/Modernizr/pulls/659","html_url":"https://github.com/Modernizr/Modernizr/pull/659","diff_url":"https://github.com/Modernizr/Modernizr/pull/659.diff","patch_url":"https://github.com/Modernizr/Modernizr/pull/659.patch"},"body":"Specification: http://www.w3.org/TR/clipboard-apis/\r\nDataTransfer Interface: http://www.w3.org/TR/html5/dnd.html#the-datatransfer-interface\r\nEvent Interfaces: http://www.w3.org/TR/DOM-Level-3-Events/#event-interfaces\r\n\r\n**tl;dr: It's pretty much impossible, I think, to fakeout a real `paste` event from the user's clipboard, because the spec does not allow it.  We can't check for a `clipboardData` on the `paste` event because of this. So, we need to check for the `ClipboardEvent` constructor (which is spec'd), then we can check for the existence of `clipboardData` on a new `Event` (non-standard/not in spec).**\r\n\r\nThe best way to test this feature would to do it manually by hand:\r\n\r\n1. Attach some event listeners for a 'paste' event to a DOM element\r\n2. Paste something by hand into that DOM element.\r\n3. Capture the event, and see if its `clipboardData` propertyexists AND implements the `DataTransfer` Interface:\r\n\r\nOld Interface:\r\n\r\n* `setData` (function)\r\n* `getData` (function)\r\n* `clearData` (function)\r\n\r\nAnd/or the new one, which looks like it is meant for drag/drop only?\r\n\r\n* `setDragImage` (function)\r\n* `addElement` (function)\r\n\r\nFirefox supports `paste`, `copy`, and `cut` events, but there is no `clipboardData` property on the `Event` passed to event listeners.  Simply checking for `element.onpaste` won't work.\r\n\r\nThe best check would be a `for in` check for those properties, because they may be on the prototype chain (most likely native code). The spec for DataTransfer seems to be designed for Drag/Drop events, so the `setDragImage` function probably shouldn't *have* to implemented. `addElement` is questionable.\r\n\r\nChrome 21 and Safari 5.1 support the old interface, so we could test that.\r\n\r\nWhy manually test?  The specification allows for synthetic `ClipboardEvent`s, but, **does not allow for those synthetic events to read/write from the clipboard**.  They may only pass `data` and `dataType` properties on the passed `Event` object to the event listeners.  So, even if we manually dispatched events using `document.createEvent` and other methods, we couldn't mock the behavior to check for `clipboardData` on the passed `Event` object because:\r\n\r\n* No browsers currently implement the `ClipboardEvent` constructor anyway.\r\n* Using the `ClipboardEvent` constructor wouldn't pass the `clipboardData` property on the event, or would probably throw an exception depending on implementation.  The spec doesn't want these synthesized events to be able to read or modify clipboard data (for good reason).\r\n* Creating a `paste` event on an object doesn't create a `clipboardData` property, and creating that property on an event would make the detection work in browsers it shouldn't.\r\n\r\nLink to Clipboard Event Interfaces:\r\nhttp://www.w3.org/TR/clipboard-apis/#clipboard-event-interfaces\r\n\r\nLink to test: http://jsbin.com/igitud/14/edit\r\n \r\nUsing the test above, these browsers have been tested and found to implement the Clipboard API:\r\n\r\n* Chrome 21\r\n* Safari 5.1\r\n\r\nThese browsers have been tested and found to NOT implement Clipboard API:\r\n\r\n* Firefox 14\r\n* Firefox Aurora ( 15 ) ( [It may land soon...](https://bugzilla.mozilla.org/show_bug.cgi?id=407983) )\r\n\r\nThe test I comitted basically checks for the existence of a `ClipboardEvent` constructor, as per the spec.  Next, it checks to see if creating a new `Event` creates a `clipboardData` property on the created object; This may be a WebKit-specific detail, because the spec does not require a `clipboardData` property for the `Event` interface.\r\n\r\n-\r\n\r\nfixes #605 "},"comment":{"url":"https://api.github.com/repos/Modernizr/Modernizr/issues/comments/96126633","html_url":"https://github.com/Modernizr/Modernizr/pull/659#issuecomment-96126633","issue_url":"https://api.github.com/repos/Modernizr/Modernizr/issues/659","id":96126633,"user":{"login":"patrickkettner","id":465414,"avatar_url":"https://avatars.githubusercontent.com/u/465414?v=3","gravatar_id":"","url":"https://api.github.com/users/patrickkettner","html_url":"https://github.com/patrickkettner","followers_url":"https://api.github.com/users/patrickkettner/followers","following_url":"https://api.github.com/users/patrickkettner/following{/other_user}","gists_url":"https://api.github.com/users/patrickkettner/gists{/gist_id}","starred_url":"https://api.github.com/users/patrickkettner/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/patrickkettner/subscriptions","organizations_url":"https://api.github.com/users/patrickkettner/orgs","repos_url":"https://api.github.com/users/patrickkettner/repos","events_url":"https://api.github.com/users/patrickkettner/events{/privacy}","received_events_url":"https://api.github.com/users/patrickkettner/received_events","type":"User","site_admin":false},"created_at":"2015-04-25T04:05:55Z","updated_at":"2015-04-25T04:05:55Z","body":"@hallvors having a listener pickup on one of the events would work fine (though that does mean it becomes an async detection, is less than ideal since it has to include a setTimeout backup to ensure listeners area cleaned up and what not...). \r\n\r\nOut of curiosity, why would someone want listeners to fire for synthetic events?"}}