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

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

Related

Editing Javascript using Chrome Developer Tools

I am trying to edit javascript on a site using Chrome's Developer Tools. I have read about 30 accounts of how to do this as well as watched a few videos. The fact is, when I go to the sources tab and open the file I want to edit, I can't do anything to it. Is there some step I am missing?
I can create break points, step through, etc... I just can't edit. Was this functionality removed recently?
I know this question is stale, but I just had a similar problem and found the solution.
If you have the file prettified, Chrome will not allow edits. I turned it off and was able to edit. Willing to bet this is/was your problem.
You can edit javascript in the developer tools on the "Sources" tab, BUT it will only allow you to edit javascript in its own file. Script embedded in an HTML (or PHP) file will remain read-only.
It has some limitations:
has to be a JS file. can't be embeded tags in a html page.
it cannot be prettified.
I don't know if you need this to save permanently, but if you need to just temporarily modify the js:
I can copy that javascript I want to modify into a text editor, edit it, then paste it in the console and it will redefine any functions or whatever that I need to be redefined.
for instance, if the page has:
<script>
var foo = function() { console.log("Hi"); }
</script>
I can take the content between the script, edit it, then enter it into the debugger like:
foo = function() { console.log("DO SOMETHING DIFFERENT"); }
and it will work for me.
Or if you have like,
function foo() {
doAThing();
}
You can just enter
function foo() {
doSomethingElse();
}
and foo will be redefined.
Probably not the best workaround, but it works. Will last until you reload the page.
I did search "chrome dev tool edit javascript". This page is the first search result. But it is too outdated, it does not help me.
I am using Chrome 73, this version of Chrome has "Enable Local Overrides" option. Using the function, I could edit a javascript and could run and debug.
My solution:
In the devtools preferences check the Enable local overrides.
Go to network tab, find the file you want to edit, rigth click on it and select Save for overrides (on the sources/overrides tab you need to add a local folder)
The file appears in a new tab on the Sources tab as local copy, so you can edit this file, and after site reload the new (and edited) override file will load on the site!

Evernote Bookmarklet

I'm integrating a button that will launch the Evernote Bookmarklet in my project. The code for the bookmarklet is:
javascript:(function() {
EN_CLIP_HOST='http://www.evernote.com';
try{
var x=document.createElement('SCRIPT');
x.type='text/javascript';
x.src=EN_CLIP_HOST+'/public/bookmarkClipper.js?'+ (new Date().getTime()/100000);
document.getElementsByTagName('head')[0].appendChild(x);
}catch(e) {
location.href=EN_CLIP_HOST+'/clip.action?url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title);
}
})();
The code is called with an onClick event on a HTML link. My problem is what is the best way to strip off the styling for when the Evernote clips it and saves it? So that it readable?
Stripping the styling is never safe and never will be. If Evernote changes its response, your code will probably break.
You should take a look at their API instead.

Can I paste image data with JavaScript? [duplicate]

This question already has answers here:
How does the paste image from clipboard functionality work in Gmail and Google Chrome 12+?
(3 answers)
Closed 3 years ago.
How do we paste an image from clipboard into a custom rich text editor using javascript? (ctrl+c and ctrl+v or a snapshot).
Has anyone used Ajax's rich text editor? Does pasting an image from clipboard to Ajax RTE work?
Because this question still often shows up in Google's search results, I want to point out this is possible today, at least in Google Chrome (2011) in all modern browsers (2018). They implemented it to use in GMail, but it is available for all websites.
How does the paste image from clipboard functionality work in Gmail and Google Chrome 12+?
To help others, I'll leave the link here with the answer made by Nick Rattalack
// window.addEventListener('paste', ... or
document.onpaste = function(event){
var items = (event.clipboardData || event.originalEvent.clipboardData).items;
console.log(JSON.stringify(items)); // will give you the mime types
for (index in items) {
var item = items[index];
if (item.kind === 'file') {
var blob = item.getAsFile();
var reader = new FileReader();
reader.onload = function(event){
console.log(event.target.result)}; // data url!
reader.readAsDataURL(blob);
}
}
}
How does the paste image from clipboard functionality work in Gmail and Google Chrome 12+?
This is definitely possible now in Chrome and Firefox. I'm not so sure about IE/Safari.
Look at imgur.com, onpaste, and pasteboard.co as examples, and see the code for pasteboard on github as well as Joel's excellent write up on his blog
For the record, you need the user to press Ctrl+V on your element, and then you can capture the data in the paste event handler by reading from event.clipboardData but to make it work down-level, you need to be sure focus is on an empty contenteditable element, and pull the results from there, which doesn't work well in Firefox 22. See here
New browsers, like Firefox 4, support pasting of image data from clipboard into a RTE as Data URI with encoded PNG Data. However, most web applications incorrectly parse these Data URIs and discard it. Yahoo mail properly handles. However Gmail and Hotmail discard it. I have notified Google and Microsoft about this.
For now i found the clipboardData Object .
But it retrieve only text format or URL from clipboard.
clipboardData is IE only, it works with character string and return null if we paste an image.
a test example
<form>
<input type="text" id="context" onClick="paste();">
</form>
<script type="text/javascript">
function paste() {
var sRetrieveData = clipboardData.getData("Text");
document.getElementById('context').value = sRetrieveData;
}
</script>
By default clipboard access is not enabled on firefox, explanation here.
On the other way, execCommand() only process text values and is not Firefox compliant.
Like the others said, the fact that code works on IE is a security risk, any site can access your clipboard text.
The easiest way to copy images relative URL is to use a java applet, windows activeX plugin, .net code or drag and drop it.
Unfortunately, It's not possible to paste an image from your clipboard to the RTE.
If you copy a blob from a desktop app like Microsoft Word that contains an image and some text, the image will turn up as a broken reference (though the proportions will be correct) and the text will be pasted correctly (formatting will be lost).
The only thing that is possible is to copy an image within the RTE and paste back within the RTE.

TinyMCE not working with Chrome when I dynamically setContent

I have a site that I put:
<body onload="ajaxLoad()" >
I have a Javascript function that then inserts data from my database into the text editor by using the setContent Javascript method of the textarea. It seems fine in Firefox and IE but in Chrome sometimes nothing shows up. There is no error, just a blank editor.
In the body section I have:
<textarea id="elm1" name="elm1" rows="40" cols="60" style="width: 100%">
</textarea>
In the head section I have:
function ajaxLoad() {
var ed = tinyMCE.get('elm1');
ed.setProgressState(1); // Show progress
window.setTimeout(function() {
ed.setProgressState(0); // Hide progress
ed.setContent('<p style="text-align: center;"><strong><br /><span style="font-size: small;">General Manager's Corner</span></strong></p><p style="text-align: center;">August 2009</p><p>It’s been 15<sup>th</sup> and so have a Steak Night (Saturday, 15<sup>th</sup>) and a shore Dinner planned (Saturday, 22<sup>nd</sup>) this month. urday, September 5<sup>th</sup>. e a can’t missed evening, shas extended it one additional week. The last clinic will be the week of August 11<sup>th</sup>. </p><p> Alt (Tuesday through Thursday) </p><p> I wouClub.</p><p> </p><p> </p><p> </p><p> <strong></strong></p>');
}, 1);
}
I am not sure if its some of the formatting that Chrome is rejecting but it seems like if TinyMCE can parse it in one browser, it should be able to do it in any browser, so I am confused.
Any suggestions?
Background:
For various reasons onload() is not considered the proper approach for loading Javascript, see for example Launching Code on Document Ready, with the most important/noticeable one being that Javascript code isn't run until the page has finished downloading entirely, including images and the like, which might take an eternity therefore (e.g. if an external banner ad server is down etc.).
Instead it is recommended to load Javascript as soon as the DOM is ready, but unfortunately there is no cross browser compatible native solution for this, see Getting notified when the page DOM has loaded (but before window.onload); please note that my entire answer is based upon the most excellent Javascript library jQuery, which offers a cross browser solution for this problem, consequently I'd definitely favor the two higher voted answers over the accepted solution myself.
Likely cause:
Your issue seems to be caused by the opposite behavior though: Chrome facilitates the WebKit rendering engine, just like Safari, and for the latter onload() is discussed to behave differently, see section When does onload fire? in Is Safari faster?. Another description of this problem specific to Chrome can be found in window.onload not working correctly in Chrome, without an explanation though.
In conclusion I suspect onload() to fire before the DOM is actually loaded completely, at least concerning the requirements of TinyMCE, which is notoriously fragile regarding issues like this and simply ceases to load.
Possible solution:
Just facilitating attribute defer on the script tag as outlined in window.onload not working correctly in Chrome is again not cross browser compatible, hence I'd simply go with the widely deployed and proven approach of using the already mentioned jQuery cross browser solution for the onload() problem, which is good practice anyway and should in principle take care of your inverse issue as well.
Update:
There are indeed some bugs filed against WebKit which could back my conclusion (no matter whether this behavior actually constitutes a bug or is intentional), see:
onload sometimes fired before all resources are loaded
window.onload fires before all subresources loaded
Window.onload is firing before image resources are loaded
I had a similar problem (editor not showing in chrome) and read in some forum, that if tinyMCE is unable to locate some files, it just stops loading. Try tracking down if everything is found using firebug's net tab (clear your cache first).
First of all; see to it that you have the latest version of TinyMCE.
I could not reproduce your problem given the information you provides. It seems just fine ( with the faked ajaxload ).
You could always try to go the "back entrance" in;
var myed = document.getElementById('elm1_ifr');
myed.contentDocument.getElementById('tinymce').innerHTML="<p style=\"text-align: center;\"><strong>hacking <span style=\"font-size: small;\">my</span> way in.</strong></p>";
Hope you good luck!
SOLUTION:
Ive been struggling with the TinyMCE toolbar not appearing in all kinds of secnarios....it would work in one user's IE browser, but not another. It would not work in Firefox or Chrome, etc.
Turns out if in the newest 3.3 version there are STILL bugs they have not fixed. This one occurs when in your webpage JavaScript code, where you instantiate the TinyMCE, if you added code for the plugin part where you load up two specific plugins, the toolbar fails to appear and you see HTML:
plugins:
"safari,spellchecker,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,
inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,
fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,**imagemanager,filemanager**",
Remove all references to imagemanager and filemanager in your web page, then refresh your browser...
When you do, retest in Chrome and Firefox and IE and the TinyMCE suddenly appears! Wow....a miracle, huh?
Turns out their "main developer" hasn't fixed the issue but does explain it as such, if you want to try and still use those plugins and yet fix the problem. His quote is as follows:
"If the ImageManager/FileManager are old they might not use the new
scriptloader api. And the new 3.3 version will load all dependent
scripts async instead of sync. - Spocke - Main developer of TinyMCE"
There are a few ways to set content in a TinyMCE editor. If you want the content to be there when the page first loads, you can just put it between the tags.
Otherwise, you can do this through script in the following way:
window.onload = function() {
tinyMCE.getInstanceById("ProfileText").setContent('test');
};
I have wrapped the code in a window.onload block. If you have other functions that set content dynamically through this way after the TinyMCE editor has already loaded, then you do not need that.
There is an option oninit for the function tinyMCE.init(), put your method there:
tinyMCE.init({
oninit: function(){
tinyMCE.activeEditor.setContent('blah');
}
});
It works this way.
The editor is not fully loaded on document load event, as it the editor loader will post-load a bunch of files.
same problem here, ie needs
var ed = tinyMCE.get('content');
ed.setContent('zzz');
other browsers
document.getElementById("content").innerHTML="zzz";
i am quite disapointed
will need to check browser in javascript to get it working properly, thats suxx

Paste an image from clipboard using JavaScript [duplicate]

This question already has answers here:
How does the paste image from clipboard functionality work in Gmail and Google Chrome 12+?
(3 answers)
Closed 3 years ago.
How do we paste an image from clipboard into a custom rich text editor using javascript? (ctrl+c and ctrl+v or a snapshot).
Has anyone used Ajax's rich text editor? Does pasting an image from clipboard to Ajax RTE work?
Because this question still often shows up in Google's search results, I want to point out this is possible today, at least in Google Chrome (2011) in all modern browsers (2018). They implemented it to use in GMail, but it is available for all websites.
How does the paste image from clipboard functionality work in Gmail and Google Chrome 12+?
To help others, I'll leave the link here with the answer made by Nick Rattalack
// window.addEventListener('paste', ... or
document.onpaste = function(event){
var items = (event.clipboardData || event.originalEvent.clipboardData).items;
console.log(JSON.stringify(items)); // will give you the mime types
for (index in items) {
var item = items[index];
if (item.kind === 'file') {
var blob = item.getAsFile();
var reader = new FileReader();
reader.onload = function(event){
console.log(event.target.result)}; // data url!
reader.readAsDataURL(blob);
}
}
}
How does the paste image from clipboard functionality work in Gmail and Google Chrome 12+?
This is definitely possible now in Chrome and Firefox. I'm not so sure about IE/Safari.
Look at imgur.com, onpaste, and pasteboard.co as examples, and see the code for pasteboard on github as well as Joel's excellent write up on his blog
For the record, you need the user to press Ctrl+V on your element, and then you can capture the data in the paste event handler by reading from event.clipboardData but to make it work down-level, you need to be sure focus is on an empty contenteditable element, and pull the results from there, which doesn't work well in Firefox 22. See here
New browsers, like Firefox 4, support pasting of image data from clipboard into a RTE as Data URI with encoded PNG Data. However, most web applications incorrectly parse these Data URIs and discard it. Yahoo mail properly handles. However Gmail and Hotmail discard it. I have notified Google and Microsoft about this.
For now i found the clipboardData Object .
But it retrieve only text format or URL from clipboard.
clipboardData is IE only, it works with character string and return null if we paste an image.
a test example
<form>
<input type="text" id="context" onClick="paste();">
</form>
<script type="text/javascript">
function paste() {
var sRetrieveData = clipboardData.getData("Text");
document.getElementById('context').value = sRetrieveData;
}
</script>
By default clipboard access is not enabled on firefox, explanation here.
On the other way, execCommand() only process text values and is not Firefox compliant.
Like the others said, the fact that code works on IE is a security risk, any site can access your clipboard text.
The easiest way to copy images relative URL is to use a java applet, windows activeX plugin, .net code or drag and drop it.
Unfortunately, It's not possible to paste an image from your clipboard to the RTE.
If you copy a blob from a desktop app like Microsoft Word that contains an image and some text, the image will turn up as a broken reference (though the proportions will be correct) and the text will be pasted correctly (formatting will be lost).
The only thing that is possible is to copy an image within the RTE and paste back within the RTE.

Categories

Resources