I am trying to sanitize a paste in a contentEditable div. That is, the code should look something like the following:
$('#content').bind('paste',function(e)
{
// Ensure pasted markup is valid
});
Ideally, I would be able to parse through the pasted text and re-format it in a way that is appropriate to the site, but I don't know how to do this.
Alternatively, I would be comfortable pasting as plain text (as opposed to HTML), but I don't know how to do this either.
I am slightly less comfortable with the solution of having a box pop up with a textarea, asking the user to paste into this text area and then putting the text into the content at the previous cursor position. I know how to do this, but want to avoid it.
And I am completely uncomfortable with just preventing the user from pasting by using e.preventDefault().
There is no direct way in most browsers to access the content pasted before it goes into the DOM. There is, however, a fairly elaborate way to do this that only works for pastes triggered by the keyboard. See my answer here:
JavaScript get clipboard data on paste event (Cross browser)
I've been able to achieve this with the rangy javascript library allowing me to save and restore the caret position after sanitizing the content.
https://github.com/timdown/rangy
Tested in chrome and safari.
$("#content").on('paste', function(){
sanitize();
});
function sanitize(){
setTimeout(function(){
var savedSelection = rangy.saveSelection();
$("#content *").removeAttr("style"); // Do your parsing here.
rangy.restoreSelection(savedSelection);
}, 0);
}
Could you not verify the content once it is already in the field some how? Let the content paste in, save the original content first and if the new content is not valid, replace it back with the old. It's just a theory but I'm just going to have to experiment too for now.
Related
I'm writing a chrome extension which helps the user type things on twitter. When writing a tweet on twitter, twitter opens an editable div container. When the user types into it, twitter (which is using some web-framework presumably) generates sub-divs and spans with the text the user types and places them within the content-editable div.
The thing is when one manually changes the span value (for instance, through inspect elements), and then types something again, the value in the span will just revert back to what it previously was (before the inspect elements edit). This is probably because the actually typed string is stored somewhere in javascript, and everything gets overwritten again when the user types into the div.
I've been trying to find a way around this using JQuery but with no success. I don't really know how to start. If it were just a regular input tag, you could call something like $("input").val("new value"), easy-peasy... but I don't know how one could go about doing that for an editable div that gets updated by javascript running somewhere on the page.
For a while, I just thought it would be impossible...
BUT NOW I do know it is possible. If you download the Grammarly extension and use the Grammarly popup-editor (which opens a new window to edit text), then submit that, the twitter editable-content div updates appropriately and everything works like magic.
Sorry if this isn't a standard programming question, but I couldn't find anything on the web that comes close to what I'm trying to do. Maybe I'm just not experienced enough and am missing something really obvious. I tried looking at the twitter and Grammarly source code but it's all minified garbled javascript that I can't read...
Thanks for any help and insight!
EDIT: the twitter url in question is: https://twitter.com/compose/tweet The div in question is the one with contenteditable="true" attribute (you can search it in the inspector)
I've got a script that deals with pasted text in a text area. I would like to write some tests for it. The first step would be to copy some text in the clipboard so after reading a lot about the topic I ended up with something like this:
Add a text Area to the DOM with the text you want to copy.
Add a button to the DOM that runs document.execCommant("copy") on click.
Remove the text area & the button from the DOM.
Please take into account before marking this question as a duplicate, that all the other solutions I've seen involve the user performing the click action. I am asking about how to do this strictly programmatically.
document.execCommant("copy") does not work if it's not triggered by any user action due to security reasons. In my case, the tests are clicking on the button, but document.execCommant("copy") simply won't work.
Is there any way of doing this without using any new libraries? (jQuery is fine).
I am interested in a solution that works on Chrome/Firefox.
Here you can see a fiddle with the step I mentioned above: https://jsfiddle.net/7b40ma0q/
I have a small templating webapp, where the authors can add placeholders within their richttext editor. To prevent errors I want to provide a list of valid placeholders which then can be copied and pasted. My problem here is the way I can restrict what get's copied.
I tried two approaches, both failed.
First of all how the list of placeholders looks like:
<ul class="placeholders">
<li>${address.name}</li>
<li>${address.street}</li>
<li>${address.city}</li>
<li>${address.zip}</li>
</ul>
Copy to clipboard with JS:
This doesn't work as the clipboard cannot be accessed because of security concerns. I tried the ZeroClipboard but it's documentation is not clear for me and even the examples I found here at SO weren't helpful. I want to copy the content of the <li> if the user clicks on it. I tried to set instantiate with new ZeroClipboard(jQuery('ul.placeholders li'). But this didn't work at all. In Firefox as soon as I hover over an li the loading wheel appears.
Just select the whole text with a range object:
This basically works with the selection, but when I paste it in the Rich Text Editor, Firefox und IE also paste the li tag. Again as I don't have access to the clipboard I can't control, what gets copied. And as it is a RTE, I don't have much control over how it gets pasted.
Has anyone an idea on how I could make either of the approaches work?
I have placed labels in my input fields to have explanatory text display in the background and when the user types in the field, the text disappears. I'm using the example explained here: How to create a label inside an <input> element?
and specifically at http://attardi.org/
When the password though is saved by the browser such as in Google chrome, the text becomes garbled as in this image (this is currently on my local computer):
The background text is not disappearing for saved passwords. Any help would be appreciative - thanks.
You could also take advantage of the new placeholder attribute. Read about it here.
No IE support, though.
Option 2 would be using Jquery. Since you're already using Jquery for the label solution, you could add code that checks the value of the input after the document has loaded then show or hide the label accordingly.
This code would go inside the document ready function:
$(function() {
// Handler for .ready() called.
});
Just use the placeholder attribute – it's so simple:
<input type="email" placeholder="email" />
Literally, that's it; the browser will take care of the behavior.
Yes, it won't work in IE (until IE10 is released) – but you've already got labels next to the fields anyway, so it's not like IE users won't be able to tell which fields are which.
I investigated further, and this only occurred in Google Chrome and not Mozilla Firefox. My setup was correct and looks like it might in fact be a bug in Chrome. See issue log: http://code.google.com/p/chromium/issues/detail?id=117661
This also looks like it will occur for the placeholder attribute too when Chrome tries to do password autosave process and doesn't look to see if there is a previous inputted value.
Thanks for the input from all.
I'm trying for two days now several JavaScript lightweight Rich Text Editors (rte) such as nicEdit, mooEditable, MooRTE (the two last ones were considered because they use the mootools framework which I'm using for this project).
My problem is that with all of them, when I copy a pre-formated text from a web page (with words in bold, links etc...) and then paste it into the editor, it appears already formated.
This could be nice but that's a security problem because if I copy/paste a whole web page it will render the whole web page in the editor.
I just want my users to be able to do some basic formatting with the editor such as putting some text in bold, italic, add a link and indent their paragraphs.
An alternative could be showdown (which - I would bet - is used by stackoverflow), because this type of editors (with a preview box) don't suffer from the aforementioned issue (when you paste something in the textarea, it is unformatted text).
However, I'm not sure this would be appropriated to my case because the editor would be used to write long articles (much longer than most of the stackoverflow posts). In that case I think it would be better to have a proper editor that renders things instantly (I mean right in the textarea, not in a preview box). And a real WYSIWYG editor is more enticing and easy to use, in my opinion.
Is there a easy way to modify a RTE so that when I paste some text it is rendered unformatted?
Or do you think I should use the sort of solution that stackoverflow uses? (showdown or similar) Or do you know a RTE that doesn't have the copy-paste issue that I mentioned?
Note that I didn't try CKeditor, FCKEditor and TinyMCE because they are far too complex(heavy) and the one from YUI looks good but needs the whole library to work.
Thanks,
FuzzyTern
You are copying from a rich text source and pasting into a rich text destination. By default you will get rich text in the destination. The only way around this is to capture the paste event somehow, redirect the paste operation into a plain text field, then copy the unformatted text out of the plain text field into your rich text destination.
Use the onPaste handler to capture
paste events (doesn't work in
Firefox or Opera)
Use a hidden field to paste the
selected text into.
Insert the value of the hidden field
into the rich destination at the
cursor location.
Not sure where the profit comes from, but there you go.