jQuery - escaping inline styles with HTML entities - javascript

I came across a curious problem when attempting to insert HTML edited by a Javascript editor (CKEditor) into some div. In the HTML to be inserted, double-quotes are replaced by the HTML entity " which works fine.
EXCEPT if the " appears in an inline style - then jQuery removes the entire inline sytyle.
I don't want them to be removed. I do prefer to keep the HTML entities if possible. The question is why does this happen? Any workaround?
In below example, I insert a text which should make the span red with regular quotes and with HTML-entity escaped quotes in an inline style.
The first line (div1) makes the span red, div2 is not red at all.
window.onload = function() {
$('#div1').html('<span style="color:red;">This text "here" is red</span>, while this is not.' );
$('#div2').html('<span style="color:red;">This text "here" is red</span>, while this is not.' ); }
See JSFiddle/L7cq2pfd here

jQuery inserts this as style=""color:red;"" - convert " to " with replace(/"/g, '"') before inserting as HTML :
$('#div2').html('<span style="color:red;">This text "here" is red</span>, while this is not.'.replace(/"/g, '"') );
http://jsfiddle.net/kb709s27/
Why? The automatically rendering of a " to " is a browser feature, not a javascript feature. jQuery seems to parse the inserted HTML and tries to correct malformed attributes. If you insert
$('#div2').html('<span style=color:red>');
then jQuery corrects this and inserts <span style="color:red">. In your case jQuery only see a malformed attribute and therefore tries to correct it, wrapping "color:red;" into quotes.

Related

Can't set innerHTML when using strings that start with '<'

I have a textarea that will populate another section with what the user inputs and my code works fine as long as I dont type anything starting with "<". Whenever I have a string like "<anything else can follow" that starts with "<", it wont set the innerhtml.
var text = "<i wont print"
text = "i will print!"
trans_txt.innerHTML = text;
Is "<" some kind of override character for innerhtml? I was wondering if anyone knew what was happening and if there is a way I could change the text var into purely string without having to worry about my string not showing up.
edit: I realized this because the default textarea message is "<text area"
<i followed by a space is HTML syntax for "Start an <i> (idiomatic/italic) tag" Since the parser doesn't see the end of the tag's definition (that is, a >), everything between the <i and the end is considered an error and dropped.
If you want to insert plain text only, use textContent instead:
var text = "<i wont print"
document.body.textContent = text;
textContent is also faster and safer. Only use innerHTML when deliberately inserting HTML markup.
Don't use innerText - best to prefer textContent instead in almost all situations.

Using HTML in a jQuery string

I'm not experienced with JS, so please excuse the presumably very beginner question.
I have this line:
$el.text(type + "|");
I need to wrap the "|" in span tags such as '<span class="">|</span>' though when I do so it simply prints out the tags as text as opposed to embedding them as HTML wraps.
How do I go about doing this?
Use .html() to print out HTML content, text prints out plain text.
$el.html(type + "<span class=''>|</span>");
or
$el.html(type).append($('<span/>',{text : '|'}));
You can dynamically create your span element using this syntax:
var $el = $('<span>').html('|');
This fiddle contains my solution. The fiddle uses a button to make it clear what is actually happening. I also added a style to the span so you can see it being added.
https://jsfiddle.net/g0n71se7/
$("#test").append("<span> | <span>");
By using the jQuery append you will insert content to the end of an element. You could alternatively use prepend to insert at the start of an element.

Javascript HTML escaping but preserving linebreaks

I have written a small jQuery script to help me build a styleguide. The script is used to copy and escape a piece of HTML and print it as documentation. My problem, however, is preversing linebreaks in the html. I would love for my escaped HTML to be formatted just like I have typed it. How is that possible?
$('.documentation-element').each(function() {
var HTML = $(this).html();
$(this).next().find('code').text(HTML).html();
});
See full example here:
http://jsfiddle.net/tolborg/nr7fs/
Change the text() method to html():
$(this).next().find('code').html(HTML);
JSFiddle
You're using a <code> tag, but that doesn't preserve line breaks. You need a <pre> tag for that. So wrap your <code> tag inside a <pre> tag and your code should work as is - except you don't need the extra .html() at the end (it doesn't hurt anything, it just doesn't do anything):
$('.documentation-element').each(function() {
var HTML = $(this).html();
$(this).next().find('code').text(HTML);
});
Here's an updated fiddle.
You may also want to tweak the leading whitespace on each line, but what you want there will depend on the output you want.
For example, here's a version that strips leading whitespace and also removes the extra newlines at the beginning and end:
$('.documentation-element').each(function() {
var HTML = $(this).html().trim().replace( /\n\s+/, '\n' );
$(this).next().find('code').text(HTML);
});

Quote in HTML attribute destroys layout

My site has user generated content. I noticed that if the user has quotes in some text and later I displayed that text in an HTML attribute, the layout would get screwed up in IE.
Hello
However, if I had generated the same anchor with Javascript (Prototype library), the layout would not be screwed up in IE:
$$('body').first().appendChild(
new Element(
'a', {
title: 'user "description" of link',
href: 'link.html'
}
).update('Hello')
);
Why is this so? The JS and the plain HTML versions both have the same intended result, but only the JS doesn't screw up IE. What's happening behind the scenes?
BTW, I do strip_tags() and clean XSS attacks from all user input, but I don't strip all HTML entities because I use a lot of form text input boxes to display back user generated text. Form elements literally display HTML entities, which looks ugly.
You need to escape all output that is user-specified (using entities). The DOM-methods do that automatically.
I don't know how you are processing the user generated content, but you could use a replace function to clean up the input something like string.replace("\"", "")
The answer to your question: 'Why is it so' is because in your JavaScript example set the title attribute with single quotes. So the double quotes in the user generated string are already escaped.
In you A tag example, single quotes around the text you use in the title attribute may be a way to solve the rendering problem.
However, Your HTML attributes should be in double quotes, so you would be better off using entities, as suggested by #elusive in his answer.

"<" sign not showing in javascript?

I have a div-element that I want to show the symbol '<'.
div-element.innerHMTL = '<';
The string actually do not appears, I think the problem lies in that the browser thinks that it is a beginning of a tag element
Anyone seen this problem before?
You should use an HTML entity - <. This will be displayed by the browser as <, rather than being interpreted as the start of an HTML tag.
Here's a handy list of common HTML entities: http://www.danshort.com/HTMLentities/
divElement.innerHTML = '<';
innerHTML sets does not encode and can be used to set html elements.
innerText sets encodes and cannot be used to set html elements.
You should use innerText when you just want to set text or you should encode the text when you want to mix html with text
This might be useful link which shows all symbols
http://www.w3schools.com/HTML/html_entities.asp

Categories