Is there an equivalent to window.clipboardData in Microsoft Edge? - javascript

In our application, we have a custom paste function that calls window.clipboardData.getData("Text") to get the current clipboard data. It then performs some functions on this data. In Edge, window.clipboardData is undefined. It does seem that getData works when used within the "paste" event though such as the following.
document.addEventListener("paste", function(e) {
var test = e.clipboardData.getData("text/plain");
});
I potentially can design a workaround that will involve this overriding of the paste event, but it would be non-ideal. A solution that can be called outside of an event would be preferable.
As an aside, I read that Edge did not support the clipboard API at one point, but my understanding is that this is fixed, so please find something specifically sustantiating the current functionality (e.clipboardData working but no equivalent to window.clipboardData existing if that is your answer.

Edge, like all modern browsers uses the official ClipboardEvent::clipboardData:
inp.onpaste = evt =>
console.log(evt.clipboardData.getData('text'));
<input id="inp">
Go with it. The deprecated and non-standard window::clipboardData should only be used as a mean of legacy support, for older versions of IE.
As to what you wish to do, (paste without user interaction), that goes against the specs recommendations for privacy. You won't be able to do from web-content. You'll need to run your script from an high-privilege script, like an extension.
• Implementations must not let scripts create synthetic clipboard events to get access to real clipboard data (unless the user has configured it to do so).

As Kaiido noted, it is not possible to get at the pasted content outside of the paste event in Edge (and Chrome for that matter).
Users previously used a custom right-click menu to access "Paste From Excel" functionality to replace content in an editable grid with tab-delimited content from the clipboard. If window.clipboardData is undefined the user received a message saying that you must use the standard CTRL+V paste in this browser.
I then added the listener below which essentially determined if the content was tab-delimited and treated it as a "Paste from Excel" whereas it treated other data layouts as a standard "Paste". This was sufficient for my deployment, but for others, it may be worthwhile to launch a confirm window to verify intention.
document.getElementById(myGridID).addEventListener("paste", function(e) {
var clipboardContent = window.clipboardData ? window.clipboardData.getData("Text") : (e.clipboardData ? e.clipboardData.getData("text/plain") : "");
if(clipboardContent != null && clipboardContent.indexOf('\t') >= 0)
{
MyExcelPasteFunction(myGridID, clipboardContent);
e.preventDefault();
}
});

Related

javascript execCommand("paste") not working

document.execCommand("Paste") doesn't work!
"Copy" and "cut" works fine.
var editor = document.getElementById("ta1");
editor.focus();
editor.select();
var successful = document.execCommand("Paste");
var msg = successful ? 'successful' : 'unsuccessful';
alert('Pasting text command was ' + msg);
This alerts "unsuccessful" on paste, but "successful" on copy and cut..
I use the "copy" another place on my webpage, and the whole thing works like a charm, but I need to get "paste" working as well..
I'm using Chrome (no extension, just a regular webpage).
Any ideas?
For security reason, it is blocked in chrome.
Even office 365 asks to their users to use shortcuts ctrl+c/ctrl+v instead of copy.
this function is only available for chrome extension now.
if the text you want to copy has to be paste on the same page then just store the text in a variable, you can then use the following command to paste
document.execCommand('insertText'
but you need to focus the textarea first
and to copy the selection https://developer.mozilla.org/fr/docs/Web/API/Window/getSelection
full example
https://jsfiddle.net/bormat/9a8nuzse/2/
This is clearly mentioned in Mozilla Documentation of Document.execCommand()
that:
paste
Pastes the clipboard contents at the insertion point (replaces current selection). Clipboard capability must be enabled in the user.js preference file. See 1.
1 Before Firefox 41, clipboard capability needed to be enabled in the user.js preference file. See A brief guide to Mozilla preferences for more information. If the command wasn't supported or enabled, execCommand was raising an exception instead of returning false.In Firefox 41 and later, clipboard capability are enabled by default in any event handler that is able to pop-up a window (semi-trusted scripts).
I had a same issue. hence as work around I used below code, its working with some limitation. give a try :)
navigator.clipboard.readText().then(function(text){
document.execCommand( "insertHTML", false, text || "");
});

How much of the Clipboard API can I use within the Paste event of CKEDITOR?

I'm trying to read the clipboardData attribute of a paste event for a plugin that I'm developing for CKEditor 4.
I've established that, in Chrome, if I listen to the document object for a paste event, then the event object I get passed in the handler will contain the clipboardData attribute. I was surprised to see the same is not true of Firefox (v20).
This is the code I'm using in my CKEditor plugin, although I don't believe this to be an question relevant only to CKEditor. In Chrome I see the clipboardData object, in Firefox I do not.
editor.document.on('paste', function(event) {
var clipboardData = event.data.$.clipboardData;
if (clipboardData) {
console.log(clipboardData);
}
});
I can't see anything on the MDN site confirming if this is yet supported, I also believe that IE10 is meant to support this, but will it work on a standard API?
Edit:
I should have made this clear from the start, but I'm trying to develop support for pasting images, so I need to read the clipboard data as a file.
If you want to get clipboard data in paste event,these can help you:
The W3C Standard (Chrome):
event.clipboardData.getData(type)
You cant get type frome event.clipboardData.types,which is usually "text/plain".
http://www.w3.org/TR/clipboard-apis/
IE:
window.clipboardData.getData(type)
Type can only be "Text" or "URL":http://msdn.microsoft.com/en-us/library/ie/ms536436%28v=vs.85%29.aspx
Firefox:
There is no api to access clipboard in ff.If you want to realize it,you can try some other way,which is depending on what you want to do.
It is indeed a CKEditor only question. The thing is that your reading the base Javascript event. But your missing the CKEditor layer that the developers of CKEditor made for you..
They already took care of the difference between the browsers. And the only thing that you need to do:
var clipboardData = ev.data.dataValue
You should play with clipboard data on paste event:
editor.on( 'paste', function( event ) {
console.log( event.data.dataValue );
});
You can modify event.data.dataValue to manipulate pasted content. Also note that priority matters because pasted data is pre-processed during pasting phases. So you can "inject" your changes at different stages by specifying a numerical listener priority:
editor.on( 'paste', function( event ) {
console.log( event.data.dataValue );
}, null, null, priority );
In Ie,We can use all clipboard API ,while in chrome and firefox can only be used where fire paste event.So users can't user clipboard api to copy something from the website while use in there office,msn..

Event triggered by bookmark drag and drop

I need to capture the event triggered by dragging and dropping a bookmark onto the window, preferably in all browsers. What I actually need is the target url of the bookmark. onbeforeunload does get triggered, but the event has no information about the target URL and I can't stop the page from loading it either. mouseup also does not work.
The FileReader API seems viable, but I'm not sure whether it's appropriate. Ideally this would also work in at least IE9 (which does not support FileReader).
I have a solution to part one of this problem, but I myself would like some help with the second part of it, so if this serves as a bump for your question it'd be much appreciated.
NOTE: Most of this is based off of my personal experience, so I'll make notes about compatibility before we get too far in.
The drop event is supported on Microsoft Edge 12+, and has a field, dataTransfer, that contains information about the element being dragged/dropped. This field was added to IE in is always null, and for that reason I won't be talking about a solution I found for it. From the timing of your post, it seems like you're using the latest Microsoft browser, which means that the features I talk about below will be supported.
The first event you'll want to take a look at is drop. This event, fairly logically, is an event that is fired when you drop an element onto a page, be it a file, another element, or in our case, a bookmark.
The second event, rather confusingly, is dragover. For some unknown reason, suppressing default behavior of the drop event on its own does not seem to completely negate the effect of going to a new webpage, instead redirecting me (using Chrome 94) to about:blank#blocked in a new tab, which might interfere with UX.
The files attribute of dataTransfer for the drop event usually contains the information about the data that is being transferred, and as I have experimented with, I've gotten this data from it:
{
items: DataTransferItemList {0: DataTransferItem {'kind': 'string', 'type': 'text/plain'}, 1: DataTransferItem {'kind': 'string', 'type': 'text/uri-list'}, length: 2},
types: ['text/plain', 'text/uri-list'],
files: FileList {length: 0}
}
I'm rather frustrated by the fact that files contains no data, and it's currently got me stuck to a point where I can't get any further. I'll see if I remember to post back here when/if it gets fixed, but until then, there's another thing I'd like to point out.
On Windows computers, internet shortcuts are actually small files with the .url extension. So, it's possible to obtain both a name for a site and its address if the user simply drags in a shortcut from their homepage. My code for getting the data is below.
element.addEventListener('drag', function(event)) {
event.preventDefault();
// in case you haven't put this in already; having multiple has
// the same effect as one
let shortcutFile = event.dataTransfer.files[0];
// This assumes the user is only dragging a single file, but it can be
// expanded to others by simply detecting the extension of the file.
let fileName = shortcutFile.name;
let fileLines = fileContent.split('\n');
// the last line of the file has a pattern that looks like this:
// URL=<url to site>
// this is what i'm going to be using to get the address.
//
// the better solution to the first index below would be to use
// Array.prototype.at(-1), however doing so would require a polyfill
// on all versions of Opera, IE, and Safari, not to mention that even somewhat
// recent browsers don't have this method implemented.
let siteUrl = fileLines[fileLines.length - 1].match(/(?<=URL=)/)[0];
// going to use one of my favorite JS features here: object destructuring!
// it's not supported in some older browsers, or in IE at all, but it's a VERY
// cool feature nonetheless, so I use it when i really shouldn't a lot of the time
//
// i know stuff is supposed to be cross-compatible but what's the point
// in browsers getting new APIs/interfaces like this if you don't use
// them?
return {fileName, siteUrl};
// oh yeah explanation of how it works
// it's basically the same thing as saying {fileName: fileName, siteUrl: siteUrl}
// looks very nice right?
}
Hope this information and workaround helps, and that the exact issue we both have gets resolved!
I found the solution! You have to use this method to get the actual URL: DataTransfer.getData(). Try putting
console.log(e.dataTransfer.getData("text/plain"));
into your "drop" event - it shows the URL for both Firefox and Chrome.

the proper use of execcommand("paste") in a chrome extension

I'm trying to paste clipboard data into a textarea using execcommand("paste") with a chome extension, but i cannot seem to get it to work.
permissions are set.
I have tried to set focus() on the textarea, but document.execCommand("paste") does nothing, and I get no error.
calling execcommand("paste") from background page also does nothing.
<form>
<textarea id="ta"></textarea>
</form>
<script type="text/javascript">
document.findElemetById("ta").focus();
document.execCommand("paste");
</script>
Clipboard functionality is a key part of my extension so I've seen all the normal problems. On my background page I expose a copy and a paste function and the page itself contains <textarea id="sandbox"></textarea>;
function copy(str) {
var sandbox = $('#sandbox').val(str).select();
document.execCommand('copy');
sandbox.val('');
}
function paste() {
var result = '',
sandbox = $('#sandbox').val('').select();
if (document.execCommand('paste')) {
result = sandbox.val();
}
sandbox.val('');
return result;
}
I'm using jQuery for simplicity but you get the idea. Now any time I want to use the clipboard functionality I simply call the relevant function. Other pages in my extension can access this API via chrome.extension.getBackgroundPage() but you can also use chrome.runtime.getBackgroundPage(callback) if your background page is an event page.
I'm not sure if this is best practice or if such a thing even exists for this functionality yet but this definitely works for me and is very clean.
This is too long for a comment on Alasdair's excellent response, so I'm creating another answer. Alasdair's answer is excellent and worked great for me, but as a newcomer to Chrome extensions it still took me a while to get it working. For anyone in a similar position, here is an expansion on his answer.
Background/event pages are able to interact with the system clipboard, provided you've requested the appropriate permissions. They are not able to interact with the DOM of pages the user has loaded. Content scripts cannot interact with the system clipboard, but they can interact with the DOM of pages the user has loaded. Take a look at the explanation of the extension architecture for a good overview of all this.
This essentially means you need to do the copy/paste actions from the system clipboard in your event/background pages, which is what Alasdair has outlined above. Any pasting or copying from the DOM of the page the user is viewing has to occur in your content script. The two scripts are able to communicate pretty easily with message passing.
I have an extension whose only purpose is to paste, and the architecture came largely from this post. If you want to see the above technique in practice, take a look at the code. In particular, background.html, background.js, and contentscript.js.
If you're in a real hurry, here is a gist.
function PasteString() {
var editor = document.getElementById("TemplateSubPage");
editor.focus();
// editor.select();
document.execCommand('Paste');
}
function CopyString() {
var input = document.getElementById("TemplateSubPage");
input.focus();
// input..select();
document.execCommand('Copy');
if (document.selection) {
document.selection.empty();
} else if (window.getSelection) {
window.getSelection().removeAllRanges();
}
}
Hope this will work for you

Override IE email auto-formatting in rich-text editor

Our site makes use of FreeTextBox, a web-based, rich-text editor. In IE, but in not Firefox, if a user types in something like:
someone#blah
IE automatically creates a mailto hyperlink. I have tested this with other text editors out there and the story is the same with all of them.
Can I override this browser behavior somehow from within my application?
This has to do with the MSHTML editor, which (I'm guessing all) Windows browsers use to instantiate rich text editors. There's a setting called IDM_AUTOURLDETECT_MODE that lets you decide if the autolinking will take place, and the default is true (other browsers apparently set it to false on instantiation, hence no autolinking in Firefox.)
Unfortunately, until recently Microsoft didn't have a mapping from the command ID to a command identifier string, so the function wasn't accessible via Javascript prior to IE9.
I just tried it out in IE9 and can confirm that, for that version and presumably all future ones, you can override the feature by calling
document.execCommand("AutoUrlDetect", false, false);
Note that it's IE9+ only, so you're still stuck for previous versions, and that you'll want to wait until the DOM is loaded before you call it and have some error handling around it, etc, etc.
There's a good summary of the original issue here, and a discussion of the fix in the minor change list here.

Categories

Resources