Browser Copy/Paste the components - javascript

We are using new clipboard API to implement the browser/operating system wide copy paste.
We have a set of components (Assume it like a flow charts which have connected div) and that is build from a simple json.
Our goal is to implement Copy and paste. We have a underlying JsON in hand, i tried to save the Json file in clipboard.
Now the real problem starts:
1: Copy and Paste is operating system wide, so how can i know that, currently copied element is json and that is what we needed to build the flow. Eg: a user can copy whatever they want, but i only want the data which my system can parse.
2: How generally these type of applications works, for example, on Slack, i copied a formatted markdown message into my clipboard and i pasted the same into a text editor, but i don't see any markdown command on the selected text, but somehow i pasted the same thing in slack, i got the same message which i copied earlier.
Is anyone have done Copy/Paste of components,
Any help highly appreciated.

Here's a basic example for how to do clipboard manipulation. Read up on paste and copy events for more detailed info. You could also try to set a different content-type for the clipboard data. This is probably how Slack does it: Set one clipboard entry in plain text (without markdown formatting) and one in Markdown.
const input = document.getElementById("testInput");
input.addEventListener("copy", (e) => {
console.log("copied!");
e.clipboardData.setData('text/plain', JSON.stringify({
test: "value"
}));
e.preventDefault();
});
input.addEventListener("paste", (e) => {
console.log("pasted!");
//console.log(e);
if (e.clipboardData.types[0] == "text/plain") {
const txt = e.clipboardData.getData('text')
try {
const json = JSON.parse(txt);
// TODO: validate that object has correct keys
console.log(json);
e.preventDefault();
// I added prevent default, since you probably want to have your own logic for rendering the clipboard content
} catch (e) {
console.error("text is not JSON parseable: " + txt);
}
}
});
<input id="testInput"></input>

Related

When I "copy" a file where do I retrieve the file name and path?

I'm currently working on a react/electron app and I want to be able to copy a file that's outside the app (could be any file type) using ctrl+c or right click copy.
How can I retrieve that file's name and path inside my app? I've tried navigator.clipboard.readText() and .read() and haven't had any luck.
Unfortunately in Electron, clipboard is still highly platform-dependant requiring different code depending on which platform you're running. Here's a snippet for a single file to get you started. If you need access to multiple files, see this snippet.
const { clipboard } = require('electron')
let text = null
if(process.platform === 'darwin') { // MacOS
text = clipboard.read('public.file-url')
} else { // Windows
text = clipboard.readBuffer('FileNameW').toString('ucs2')
} // TODO: Linux
console.log(text);
Depending on your presentation, you may need to convert to a human readable format (e.g. file:/// vs. C:\, etc)

Change element css class based on xml file value

Is this even a possibility? Never attempted or tried anything like this before, I have no idea where to start.
I have a local file that when a manual button is pressed, it updates an xml file changing
<status>live<\status>
to
<status>killed<\status>
I also have a HTML page that has Iframes pulling live camera feeds for IP cameras. I want to hide the iframe and show a graphic instead when the status is ‘killed’.
Does anyone know if this is possible and where I’d start? Somehow check the xml file regularly or somehow know it has been updated.
Then somehow apply classes or introduce elements such as a div to mask the iframe.
Yes, you can work with XML in JavaScript almost the same as if you were working with HTML. However, without a server-side component, writing the xml document back to the file system will not be possible. You can always download it for the user, but you can't write directly to the file system.
Here's a simple example of updating an XML document with JS. I put both the string of xml and the logic to parse string into an xml doc in the example since I'm not sure what your setup is.
const xmlString = `
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
`;
const xmlDoc = new DOMParser().parseFromString(xmlString, 'text/xml');
document.getElementById('btn').addEventListener('click', e => {
const to = xmlDoc.querySelector('note to');
to.innerHTML = 'Someone New';
console.log('The TO field is now ', xmlDoc.querySelector('note to').innerHTML);
// Set HTML Element from XML
const h1 = document.getElementById('fromXml');
h1.innerText = xmlDoc.querySelector('note heading').innerHTML;
});
<button id="btn">Set To</button>
<h1 id="fromXml"></h1>

Access fileEntry after dropping a file in a Chrome App

Is it possible to get a fileEntry object in Chrome Apps by opening a file via Drag'n'Drop? When I drop a file into my app I only get a file object which seems to be unrelated to the file system. I can't use that object to save the file after changing it.
I get the file like this:
document.body.addEventListener('drop', function (event) {
file = event.dataTransfer.files[0]
});
What I want to do
I'm developing a text editor and I want to add a feature to open a file by dragging it into my app.
As I said: I already get the content of the file, but I can't write changes back to the file since I need a fileEntry object in order to do so.
Okay, I just found it while inspecting the event object. In the event object there's a function called webkitGetAsEntry() to get the fileEntry object. Here's the correct code:
document.body.addEventListener('drop', function (event) {
fileEntry = event.dataTransfer.items[0].webkitGetAsEntry();
});
This is the object you can use to write changes back to the file system.
Code for reference:
// Of course this needs the "fileSystem" permission.
// Dropped files from the file system aren't writable by default.
// So we need to make it writable first.
chrome.fileSystem.getWritableEntry(fileEntry, function (writableEntry) {
writableEntry.createWriter(function (writer) {
// Here use `writer.write(blob)` to write changes to the file system.
// Very important detail when you write files:
// https://developer.chrome.com/apps/app_codelab_filesystem
// look for the part that reads `if (!truncated)`
// This also is very hard to find and causes an annoying error
// when you don't know how to correctly truncate files
// while writing content to the files...
});
});

Ensuring HTML5 FileReader Performs When .target Content Has Changed Since Last Use

In a website I am using HTML5, rather than .php/forms/ and clientside AJAX, to retrieve files
from my laptop's hard drive. The page, when it loads, has a textarea in which I display the files; but here I also should note that I have other functionality, which permits me to save the contents of the textarea as a new file. That, I do via AJAX. Back to the chase: the "Browse" opens the Dialogue, I select a file, and the HTML5 FileRead fetches the file, all is well.
I can perform that operation as many times as I wish, no problem. But if I then save a new file, when I next go to use the FileReader, it fails. I have been on this for about 14 hours now, trying to discover a reason why the code behaves that way.
Without putting up a wall of code, anyone encountered a similar problem? Ah, and the most annoying of all, is that the Dragonfly inspector is showing the textarea textContent as the proper data, from inside the event.target.result which works so well on the first operations after opening the page.
EDIT ::
Unlike most of the blogs, questions and answers examples and even some spec documentation,
.textContent did not work in the context of the script I am working in, but one change as to
what specifically the data was being written AS, and all the intermittent, on again off again
FileReader behaviour, was resolved and extensive testing shows it performing 100%.
In order to permit use of FileReader in between performing file saves out of the textarea, just had to change textContent to innerText:
reader.onloadend = function(evt) {
if (evt.target.readyState == FileReader.DONE) { // note: DONE == 2
console.log(">>>> 12 <<<< text is : "+event.target.result);
// the textarea being edited // saved from for new files...
// ... and used to display files read by FileReader
document.getElementById("TextAREAx1xMAIN").textContent = event.target.result;
}
};
reader.onloadend = function(evt) {
if (evt.target.readyState == FileReader.DONE) {
console.log(">>>> 12 <<<< text is : "+event.target.result);
// the textarea being edited // saved from for new files...
// ... and used to display files read by FileReader
document.getElementById("TextAREAx1xMAIN").innerText = event.target.result;
}
};

How do I copy image data to the clipboard in my XUL application?

I have a XULRunner application that needs to copy image data to the clipboard. I have figured out how to handle copying text to the clipboard, and I can paste PNG data from the clipboard. What I can't figure out is how to get data from a data URL into the clipboard so that it can be pasted into other applications.
This is the code I use to copy text (well, XUL):
var transferObject=Components.classes["#mozilla.org/widget/transferable;1"].
createInstance(Components.interfaces.nsITransferable);
var stringWrapper=Components.classes["#mozilla.org/supports-string;1"].
createInstance(Components.interfaces.nsISupportsString);
var systemClipboard=Components.classes["#mozilla.org/widget/clipboard;1"].
createInstance(Components.interfaces.nsIClipboard);
var objToSerialize=aDOMNode;
transferObject.addDataFlavor("text/xul");
var xmls=new XMLSerializer();
var serializedObj=xmls.serializeToString(objToSerialize);
stringWrapper.data=serializedObj;
transferObject.setTransferData("text/xul",stringWrapper,serializedObj.length*2);
And, as I said, the data I'm trying to transfer is a PNG as a data URL. So I'm looking for the equivalent to the above that will allow, e.g. Paint.NET to paste my app's data.
Here's a workaround that I ended up using that solves the problem pretty well. The variable dataURL is the image I was trying to get to the clipboard in the first place.
var newImg=document.createElement('img');
newImg.src=dataURL;
document.popupNode=newImg;
var command='cmd_copyImageContents'
var controller=document.commandDispatcher.getControllerForCommand(command);
if(controller && controller.isCommandEnabled(command)){
controller.doCommand(command);
}
That copies the image to the clipboard as an 'image/jpg'.
Neal Deakin has an article on manipulating the clipboard in xulrunner. I'm not sure if it answers your question specifically, but it's definitely worth checking out.

Categories