Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I'd like to know a way to make my script detect the content of the clipboard and paste it into a text field when the page is opened, with no input from the user. How can it be done?
Use the new clipboard API, via navigator.clipboard. It can be used like this:
With async/await syntax:
const text = await navigator.clipboard.readText();
Or with Promise syntax:
navigator.clipboard.readText()
.then(text => {
console.log('Pasted content: ', text);
})
.catch(err => {
console.error('Failed to read clipboard contents: ', err);
});
Keep in mind that this will prompt the user with a permission request dialog box, so no funny business possible.
The above code will not work if called from the console. It only works when you run the code in an active tab. To run the code from your console you can set a timeout and click in the website window quickly:
setTimeout(async () => {
const text = await navigator.clipboard.readText();
console.log(text);
}, 2000);
Read more on the API and usage in the Google developer docs.
Spec
window.clipboardData.getData('Text') will work in some browsers. However, many browsers where it does work will prompt the user as to whether or not they wish the web page to have access to the clipboard.
You can use
window.clipboardData.getData('Text')
to get the content of user's clipboard in IE. However, in other browser you may need to use flash to get the content, since there is no standard interface to access the clipboard. May be you can have try this plugin Zero Clipboard
Following will give you the selected content as well as updating the clipboard.
Bind the element id with a copy event and then get the selected text. You can replace or modify the text. Get the clipboard and set the new text. To get the exact formatting you need to set the type as "text/html". You may also bind it to the document instead of element.
document.querySelector('element').bind('copy', function(event) {
var selectedText = window.getSelection().toString();
selectedText = selectedText.replace(/\u200B/g, "");
clipboardData = event.clipboardData || window.clipboardData || event.originalEvent.clipboardData;
clipboardData.setData('text/html', selectedText);
event.preventDefault();
});
Related
This sample code for copying plain text seems to work with most browsers…
navigator.clipboard.writeText(text).then(() => {
console.log("Copied.");
}).catch(err => {
console.log("Error.");
});
…whereas this sample code for copying HTML to the clipboard does NOT work with Mobile Chrome nor does it return an error…
navigator.permissions.query({name: "clipboard-write"}).then((result) => {
if (result.state === "granted" || result.state === "prompt") {
const blobInput = new Blob([exportContent], {type: "text/html"});
const clipboardItemInput = new ClipboardItem({"text/html" : blobInput});
navigator.clipboard.write([clipboardItemInput]).then(() => {
console.log("Copied");
}).catch(err => {
console.log("Error.");
});
}
else {
console.log("Permission denied.");
}
});
Is there another way to construct the second example to work in Android; and if not, how can I detect the failure given that navigator.clipboard.write does not return an error in Mobile Chrome?
UPDATE: Better-Than-Nothing Workaround
Given that I'm not hopeful that this can be resolved without Google addressing the issue, I at least wanted to: (1) find a way to not have users blame my website/app for the Clipboard being empty; (2) not get on the slippery slope of trying to detect the devices that have the problem along with writing special case code; and (3) ensure that the process immediately starts working if Google ever gets around to fixing the problem. So…
Since I can successfully write plain text to the keyboard, I now have two parts to the code:
I first write a plain text message like "[App name] sent HTML to the Clipboard. If this is what got pasted, it means your device is…[along with a suggested alternative of attaching the content in a file in lieu of pasting]."
I then attempt to write the HTML to the Clipboard.
When writing the HTML works, the user doesn't see the message from Part 1 when pasting. When it doesn't work, the user sees the message and at least knows more about the problem and an alternative.
FINAL UPDATE
I have come to believe the HTML is on the Clipboard but not consistently accessible. That explains the reason for no errors being thrown. If I can get Gmail in Android to display a context menu, which it only does 20% of the time, I can successfully paste the HTML. GBoard never shows the HTML content but always shows the plain text.
I can live with the aforementioned workaround. It's a minor hassle for users the first time they encounter the issue, but after they realize their device has a problem, they just start using the alternative (which actually has some benefits).
I had this issue and I tried hard to solve it till I found that some mobile browsers just don't support it. So your first simple code is the best solution but instead of showing an error, I suggest you show a prompt telling the user to copy the given text in case the browser can't do it or doesn't support it.
function copyText() {
navigator.clipboard.writeText(text).then(() => {
alert("text is copied to clipboard");
}, () => {
window.prompt("Please copy this text", text);
});
}
Edit: regarding your comment, for that you can just put the prompt block in try and catch:
function copyText() {
navigator.clipboard.writeText(text).then(() => {
alert("text is copied to clipboard");
}, () => {
try {
window.prompt("Please copy this text", text);
} catch (error) {
alert("Your browser doesn't support this function");
}
});
}
how can I get a text saved in the clipboard to a string using javascript? (or if it is to an image an image object) if it requires any permission just state which one (i use it in a chrome extension, so what should I add to the manifest in the permissions arrays?)
(don't worry, I know it sounds suspicious. I don't use the data in any form of abusive way, but for a clipboard chrome extension.)
Answer:
You can use the ClipBoard API
Per an example on MDN:
navigator.clipboard.readText().then(
clipText => document.querySelector(".editor").innerText += clipText);
Keep in mind that this is Asynchronous so you'll need to have your functions based on that Promise.
Aside:
Currently the ClipBoard API is not compatible with Internet Explorer, and other than FireFox with feature flags set, reading is the only thing allowed. This may change in the future, but just be aware that you can't expect to alter the ClipBoard through the API.
For fallback purposes you would have to use document.execCommand and most likely as follows:
let el = document.querySelector.bind(document);
let btn = el("button");
btn.addEventListener("click", function() {
let i = el("input");
//empty input
i.value = "";
//focus input
i.focus();
//paste into input
document.execCommand("paste");
//do something with pasted string
console.log(i.textContent);
});
.hidden { display: none; }
<input class="hidden">
<small>Note: This should only work in IE.</small>
<button>Get String</button>
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
The community is reviewing whether to reopen this question as of 29 days ago.
Improve this question
I'd like to know a way to make my script detect the content of the clipboard and paste it into a text field when the page is opened, with no input from the user. How can it be done?
Use the new clipboard API, via navigator.clipboard. It can be used like this:
With async/await syntax:
const text = await navigator.clipboard.readText();
Or with Promise syntax:
navigator.clipboard.readText()
.then(text => {
console.log('Pasted content: ', text);
})
.catch(err => {
console.error('Failed to read clipboard contents: ', err);
});
Keep in mind that this will prompt the user with a permission request dialog box, so no funny business possible.
The above code will not work if called from the console. It only works when you run the code in an active tab. To run the code from your console you can set a timeout and click in the website window quickly:
setTimeout(async () => {
const text = await navigator.clipboard.readText();
console.log(text);
}, 2000);
Read more on the API and usage in the Google developer docs.
Spec
window.clipboardData.getData('Text') will work in some browsers. However, many browsers where it does work will prompt the user as to whether or not they wish the web page to have access to the clipboard.
You can use
window.clipboardData.getData('Text')
to get the content of user's clipboard in IE. However, in other browser you may need to use flash to get the content, since there is no standard interface to access the clipboard. May be you can have try this plugin Zero Clipboard
Following will give you the selected content as well as updating the clipboard.
Bind the element id with a copy event and then get the selected text. You can replace or modify the text. Get the clipboard and set the new text. To get the exact formatting you need to set the type as "text/html". You may also bind it to the document instead of element.
document.querySelector('element').bind('copy', function(event) {
var selectedText = window.getSelection().toString();
selectedText = selectedText.replace(/\u200B/g, "");
clipboardData = event.clipboardData || window.clipboardData || event.originalEvent.clipboardData;
clipboardData.setData('text/html', selectedText);
event.preventDefault();
});
First of all, let me note that this works perfectly in Chrome.
I am trying to override the copy event in JavaScript and replace the clipboard contents with my own data. I extracted the essentials of the problem into this fiddle: https://jsfiddle.net/gxewmc2h/4/ (yes, I need to use global variables to set the data)
window.globalCopyObject = {};
window.globalCopyObject.clipboardDataText = "text value";
window.globalCopyObject.clipboardHtmlText = "html value";
document.addEventListener("copy", function (event) {
event.clipboardData.setData("text/plain", window.globalCopyObject.clipboardDataText);
event.clipboardData.setData("text/html", window.globalCopyObject.clipboardHtmlText);
event.preventDefault();
});
When you use Edge and try to copy the text on the page and paste it into the input, it does override the event since the clipboard is emptied, but it does not fill it with new data.
As far as I know, the latest Edge should support the clipboard API, is there something obvious I am missing?
Thank you in advance for any ideas.
Fiddle here: https://jsfiddle.net/chpaeeL9/1/
Microsoft Bot Framework has a webchat module that allows you to talk to your bot.
When the user clicks the Say Hi button, I want to place some text into the webchat's textbox, and click the Send button inside the webchat using JavaScript.
Sounds like something too easy, but it wasn't. Here's the code that I currently have, and it doesn't work: the click event somehow is not triggered.
$('#sayhibutton').click(function() {
$('.wc-console').addClass('has-text'); // works
$('.wc-shellinput').val("Hi bot!").change(); // works
$('.wc-send').click(); // doesn't work!
$('.wc-send svg').click(); // doesn't work either
});
Update: if that helps, it seems the interface is written using React.
Update: my question is different from my previous question about how to avoid iframes in webchat.
OK, for the lack of a better option my solution was a pretty dirty and ugly one.
Save the code in botchat.js into a file and reference that saved file from the HTML, rather than the CDN version.
Pretty-print the file in Chrome and find the line that says:
e.prototype.sendMessage = function() {
this.props.inputText.trim().length > 0 && this.props.sendMessage(this.props.inputText)
}
Replace the middle line with this:
this.textInput.value.trim().length > 0 && this.props.sendMessage(this.textInput.value)
This basically means to take the message text from this.textInput.value rather than from this.props.inputText, or in other words, take it directly from the textinput's DOM node.
Somehow triggering the change event on a textbox doesn't cause an actual change event on the textbox, which is why we need to do this.
this is an issue with react try this,
var input = document.getElementsByClassName("wc-shellinput")[0];
var lastValue = input.value;
input.value = 'YOUR MESSAGE';
var event = new CustomEvent('input', { bubbles: true });
// hack React15
event.simulated = true;
// hack React16
var tracker = input._valueTracker;
if (tracker) {
tracker.setValue(lastValue);
}
input.dispatchEvent(event);
//send the message
$(".wc-send:first").click();
to read more see this post: https://github.com/Microsoft/BotFramework-WebChat/issues/680