FireFox document.exeCommand('copy') not working - javascript

I have the following code :
var doc = window.document;
var copyFrom = doc.createElement("textarea");
copyFrom.textContent = str;
var body = document.getElementsByTagName('body')[0];
body.appendChild(copyFrom);
copyFrom.select();
document.execCommand('copy');
body.removeChild(copyFrom);
This seems to work fine on Chrome as I am able to paste the contents on my 'str' variable. However this doesn't seem to work on FireFox/Safari.

Safari does not give clipboard access without user generated event. So only user initiated actions ( e.g Ctrl + C/ Cmd + C) can work to copy items.
About Firefox, can you give some details regarding the version. There has been a change post 44.0 where copy to clipboard has been enabled.

Related

Javascript issue, clipboardData.items and clipboardData.files are empty when pasting an image copied from the Windows clipboard when using Firefox

I have Javascript code that attempts to paste an image file, which has been copied from the Windows clipboard.
This code works perfectly well in Chrome and Edge but not in Firefox.
It will only work in Firefox, if the image is copied from an image-editing program, e.g. Paint.
A fragment of the event handler is similar to this:
var items = (e.clipboardData || e.originalEvent.clipboardData).items;
When executed using Firefox, the files collection in e.clipboardData is empty, as is the items collection.
I am aware that this is a duplicate question, that was asked 3 years ago:
Javascript clipboardData.items and clipboardData.files are empty when pasting an image
I'm asking it again in the hope that someone knows of a work-around to this issue, or at least, an admission from Firefox that they do not support this functionality.
I found eclipboardData.items not to be helpful and needed to use file_input.files = e.clipboardData.files.
I'm having additional issue in Firefox, specifically when using a form and script that are dynamically added to the page and shown in a modal (no iframes). I found that the File object is available DURING the paste event, but is no longer available after.
I tried using FileReader and creating a new File, but ended up with the same result. I used a (bad) workaround that auto-submits the form during the paste event, which won't be sufficient for all cases.
I have no issues with the File object later disappearing if the form & script load in the initial page request, but I want to include this just in case you're having the 'disappears after paste event' issue.
Example:
//setup the paste listener
document.body.addEventListener('paste',
async function (e){
const form = document.querySelector('form[action="/files/upload/"]');
const file_input = form.querySelector('input[type="file"]');
// display error if no files to paste
const err = form.querySelector('.file_input_error');
if (e.clipboardData.files.length == 0){
err.innerText = 'No images in the clipboard. Copy an image and try again.';
err.style.display = "block";
return;
}
file_input.files = e.clipboardData.files;
// show_file(file_input); // custom function to display the image in the form
// fire the change event
const changeEvent = new Event("change");
file_input.dispatchEvent(changeEvent);
}
);
//use a file_input change event to submit the form, so it works for both copy+paste & regularly adding the file
file_input.addEventListener('change',
function (e){
const form = document.querySelector('form[action="/files/upload/"]');
form.querySelector('input[type="submit"]').click();
}
);

Copy Paste is not working in Mozilla Firefox

Here, I am not able to copy the data from clipboard in Mozilla Firefox.
{
var cTxt = "abc"; // here it is dynamic data - i have given abc as static here
var contInp = document.createElement("input");
contInp.setAttribute("value", cTxt);
document.body.appendChild(contInp);
contInp.focus();
contInp.select();
document.execCommand("copy");
document.body.removeChild(contInp);
}
Can anyone please help me sort out this problem? It is working fine in Chrome.

How do I put the contents of a variable to the clipboard using javascript?

function Copy() // this function will be latched to a button later on.
{
var text = writePreview(); // this pours in the formatted string by the writePreview() function to the variable 'text'
text = br2nl(text); //variable 'text' is purified from <br/> and is replaced by a carriage return
//I need some code here to pour in the contents of the variable 'text' to the clipboard. That way the user could paste the processed data to a 3rd party application
}
I'm building an offline client-side web application. The main purpose of this is to have user's input to fields, format the text such that it fits a certain criteria, then click copy so they can paste it to a 3rd party CRM.
The only available browser for this is Google Chrome. I've scoured the internet hoping to find a simple solution for this.
I'm not concerned about security as this application is not going to be published and is meant just for offline use.
I want to keep it as simple as possible and adding invisible textarea ruin the layout. Flash is not allowed in my current environment.
Look at clipboard.js
A modern approach to copy text to clipboard
No Flash. No dependencies. Just 2kb gzipped
https://clipboardjs.com/
this was solved by updating my browser (Google Chrome v49). I was using a lower version (v34).
found that later versions (v42+) of Google Chrome supports document.execCommand('copy')
I hope it helps people
here are the functions I used:
function SelectAll(id)
{
document.getElementById(id).focus();
document.getElementById(id).select();
}
function copy()
{
SelectAll('textAreaID');
document.execCommand("Copy", false, null);
}
According to this article "In javascript, copying a value from variable to clipboard is not straightforward as there is no direct command.".
Hence as suggested there I did the following:
defined the following in html file - I added at the bottom ( I never noticed element being added and being removed ):
<div id="container"/>
then in Javascript I added:
.
function copyQ() {
var container = document.getElementById("container");
var inp = document.createElement("input");
inp.type = "text";
container.appendChild(inp);
inp.value = "TEST_XYZ";
inp.select();
document.execCommand("Copy");
container.removeChild(container.lastChild);
alert("Copied the text: " + inp.value);
}
May be there is a better way, but it works for me.
UPDATE:
Further, I found that if your text is multiline and if you use input of type text all text is converted to one line text.
To keep paragraphs / separate lines I tried to use textarea and text is copied as is - multi line:
var inp = document.createElement("textarea");
//inp.type = "text";
Hope it helps someone.

logStringMessage function inside Firefox extension

I was developing a small extension for Firefox. I wanted to log messages while a part of my extension is executing.
CODE:
var aConsoleService = Components.classes["#mozilla.org/consoleservice;1"].getService (Components.interfaces.nsIConsoleService);
aConsoleService.logStringMessage("created");
Here "created" is message. But I am unable to see this message inside browser console. Am I missing something? I searched for it and got to know that you have to enable devtools.errorconsole.enabled inside about:config. I did that too. Please help me out.
Are you sure you're opening the browser console? Ctrl + Shift + J?
var {utils:Cu, interfaces:Ci} = Components;
Components.classes["#mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
consoleService.logStringMessage(text);
also can try this:
var {utils:Cu, interfaces:Ci} = Components;
Cu.import('resource://gre/modules/Services.jsm');
Services.console.logStringMessage(text);
can also try this
var {utils:Cu, interfaces:Ci} = Components;
Cu.import('resource://gre/modules/Services.jsm');
Services.appShell.hiddenDOMWindow.console.log('blah');
if you're using addon sdk then instead of var {utils:Cu, interfaces:Ci} = Components; you have to do var {Cu, Ci} = require('chrome');

Copy a HTML snippet of the page to a clipboard

I am developing web development tools and I'd like to copy of a part of current web page's HTML code to the clipboard using Javascript.
This probably would involve
Getting the piece of HTML in the question using DOM innerHTML
Copying this text to clipboard using Javascript
Is anyone aware of any gotchas here? E.g. related to clipboard handling - when one is not using documentEditable mode do I need to create a hidden where to put the HTML payload for copying?
Also if possible I'd like to make the interaction with WYSIWYG components, like TinyMCE, work so that when one pastes the HTML in the visual edit mode it comes through as formatted HTML instead of plain text.
It is enough if solution works in Chrome and Firefox. Internet Explorer does not need to be supported.
Javascript has no way of adding things to the clipboard. Well at least not any that works cross browser.
There is however a flash solution which works well. http://code.google.com/p/zeroclipboard/
We developed a small Firefox-AddOn to remove special characters (hyphens) when copy/pasting content from the editor. This has been necessary because there is no javascript way to fill anyting into the clipboard. I guess it should be possible to write an extension for Chrome too (googel is your friend here). This seems to be the only way to get what you want from my point of view.
Example:
Here is the necessary code snippet for a FireFox-Addon to remove special characters onCopy
// get Clipboard Object
var clip = Components.classes["#mozilla.org/widget/clipboard;1"].createInstance(Components.interfaces.nsIClipboard);
// get Transferable Object
var tr_unicode = new Transferable();
var tr_html = new Transferable();
// read "text/unicode flavors" (the clipboard has several "flavours" (html, plain text, ...))
tr_unicode.addDataFlavor("text/unicode");
tr_html.addDataFlavor("text/html");
clip.getData(tr_unicode, clip.kGlobalClipboard); // Systemclipboard
clip.getData(tr_html, clip.kGlobalClipboard); // Systemclipboard
// generate objects to write the contents into (used for the clipboard)
var unicode = { }, ulen = { }, html = { }, hlen = { };
tr_html.getTransferData("text/html", html, hlen);
tr_unicode.getTransferData("text/unicode", unicode, ulen);
var unicode_obj = unicode.value.QueryInterface(Components.interfaces.nsISupportsString);
var html_obj = html.value.QueryInterface(Components.interfaces.nsISupportsString);
// we remove Softhyphen and another control character here
var re = new RegExp('[\u200b' + String.fromCharCode(173)+ ']','g');
if (unicode_obj && html_obj)
{
var unicode_str = unicode_obj.data.replace(re, '');
var html_str = html_obj.data.replace(re, '');
// Neue Stringkomponenten für unicode und HTML-Content anlegen
var unicode_in = new StringComponent();
unicode_in.data = unicode_str;
var html_in = new StringComponent();
html_in.data = html_str;
// generate new transferable to write the data back to the clipboard
// fill html + unicode flavors
var tr_in = new Transferable();
tr_in.setTransferData("text/html", html_in, html_in.data.length * 2);
tr_in.setTransferData("text/unicode", unicode_in, unicode_in.data.length * 2);
// copy content from transferable back to clipboard
clip.setData(tr_in, null, clip.kGlobalClipboard);
}

Categories