Custom mark up language breaks html - javascript

I am using document.write to output HTML to the browser ( I plan to change to .innerHTML soon).
When using view source I can only see the markup, I can not see the HTML output. However I verified visually that rows 1 and 2 of 0 through 6 are completely missing and commented as such below.
When I inspect the mark up below I see that these two rows have many special characters which leads me to believe this might be the problem.
Note:
Each row is divided by a || and each field is divided by a |. The markup lanaguage is properly escaped as you can see there are no superfulous | or ||.
Actually I just noticed the tag is being cropped for some reason:
https://www.google.com/#hl=en&sclient=psy-ab&q=new+york+city+venture+capitalists&pbx=1&oq=new+york+city+venture+capitalists&aq=f&aqi=&aql=&gs_sm=12&gs_upl=0l0l0l98460l0l0l0l0l0l0l0l0ll0l0&bav=on.2,or.r_gc.r_pw.r_qf.,cf.osb&fp=94def8e69f73d3d7&biw=1214&bih=852
becomes
<a class=\'bookmark_tweet\' target=\'_blank\' href=\'https://www.google.com/#hl=en&sclient=psy-ab&q=new+york+city+venture+cap
I'll post relevant code once I get it:

View source shows you what was received from the server. If you add to it using document.write() you won't see that unless you use a DOM inspector in your browser, such as firebug (Firefox). I know there is one for IE but never use IE so I don't know what it's called.

Javascript strings don't span lines. You can't open a quote on one line, then close it on another.

Related

Text renders blank in Chrome, reappears when selected

The problem
I'm using innerHTML to put HTML-formatted text in a <div>. At a consistent, seemingly random point in the text, the fonts stop being rendered and display blank. When I select the invisible text, it reappears.
Description of the code
We have a single <div id="text" inner-h-t-m-l="[[markup]]">.
The initial markup doesn't contain any data apart from empty segments with IDs:
<div id="segment-1"></div><div id="segment-2"></div>... etc
In Javascript, we loop over the IDs using querySelector (this is slow) and insert HTML into the each segment's innerHTML.
The framework used is Polymer 2.
Additional info; video
In the Chrome Dev Tools, the invisible text is shown as present in the DOM and seems to be no different from the text that renders correctly.
The font in the video is non-standard, but the problem also occurs when using system fonts.
Here's a video to illustrate the problem.
Here's a screenshot of a Chrome profiler run:
Edit:
After a discussion in the comments, I thought I should link the actual code.
Here's the element in question.
The relevant parts are:
<div id="segmented_text_content" inner-h-t-m-l="[[markup]]"></div>
_addPrimaryText(textStrings) {...}
_addSecondaryText(textStrings) {...}
Edit 2:
I found two potential workarounds for this, but neither one works well enough.
If I run this.querySelector('#text').innerHTML = this.querySelector('#text').innerHTML with a timeout of 3 seconds, it paints the text correctly.
When adding the text, if I use the async processArray function from this comment, it renders the text correctly, albeit very slowly because it updates the layout after every insertion.
With these two points, my working theory now is that Chrome updates the layout before the innerHTML attribute is fully assigned.
I also forgot to mention this project uses Shady DOM.

Strange json.stringify fail

Strange is not the error itself but the way it happens. In my content editor while editing everything gets saved with unique id's in a javascript object and after you save in the end it gets json stringified. That work's for 99,99% of my users perfect but sometimes json.stringify didn't escape the quotes and its always happens with the same beginning. I really don't have a clue how this happens. Here is a picture of the javascript object:
http://cl.ly/image/3B3Z2e413M3r
Off course the marked line is the error but the whole thing (no escaped quotes) only occures if the content starts with this line. I should mention if you load a wysiwyg element in the editor there is a pre equipped < h3 >...< /h3 > and a < p >...< /p > with some sample data. (the h3 is not centered per default)
<h3 style="text-align: center;">Sample Headline</h3>
My problem is that i can't reproduce it. If i align my heading to get the same code, everything works well. Users got the last chrome version and there is no other plugin then jQuery.
Any ideas would be great because iam exhausted...
Cliffnotes:
json.stringify failes to escape quotes and....
everytime the error occurs to a user i see that it starts with the aligned heading so i guess it has something to do with it
Thanks a lot. :)
What you have shown is a normal JS object and not a JSON (so it has nothing to do with JSON.stringify()). The quotes must be only escaped in string literals in code, so that interpreter did not confuse it with delimiting quotes.
After it's parsed - they are stored in memory as-is without any escape characters.
Example: http://jsfiddle.net/83GUe/
Guide: open developer tools, press Run and see the Scope variables
Conclusion: what you provided on a screenshot is a 100% expected and correct behaviour.

How to prevent & conversion to & when using JavaScript? (browser specifc)

I have a problem concerning string output on HTML page when using Javascript and ASP. Logic of page generation goes like this:
We use asp page to generate HTML code using Response.Write(). If string contains numeric character reference (for example С) it would show on the user's side just fine as a character.
After that we add OnLoad event, which calls for a Javascript function. All this happens inside <body><\body> tags. Source for JavaScript added inside <script></script> tags. The function only adds document.href, which contains reference to the same asp page.
The asp logic loads again and adds some text to the page using Response.BinaryWrite() (Response.Write can be used all the same) All character references are shown as codes:С. Obviously all '&' symbols become &(asp automatic conversion), browser decodes it as & and we can only see a code С and not the symbol 'С'.
As far as I know such behaviour can be caused by <script> tags, as a precaution against xss attacks. In the end I want to stop encoding '&' as &.
However here is the most important part:
If I add header with "Content-Type" "text\html", IE (any version) starts encoding NCR symbols in a correct way. But Firefox, Chrome and Safari do not change behavior and keep encoding & as &. I can see several questions on Stack Overflow which looks like mine, yet the situation is not exactly the same (My strings are not inserted directly by JavaScript, so I cannot manipulate output string and change & to &, also my strings have correct symbols in the first place, they get changed by asp or by browser). Is there any elegant way to force Firefox or Chrome to decode page as IE? Maybe some settings or attributes in HTML tags? This problem looks like it depends on a browser to me, am I right?

Chrome rendering an alert() box with the last 2 words on 2 separate lines. How to fix?

I have the following JS that produces an alert box:
alert("You have selected the maximum number of funds available for comparison. Please ensure only five funds have been selected for your basket");
Chrome is rendering the alert box like this:
with the last 2 words wrapping onto separate lines.
Has anyone seen this before? Any ideas how to fix this?!
Wanted to add another screenshot since I am able to reproduce this error:
--Jeremy
This seems to be a bug with older verisons of Chrome.
http://code.google.com/p/chromium/issues/detail?id=83670
In Chrome 12 on linux it works fine, so I can't easily reproduce/debug. Have you tried putting in your own line breaks, say after every 70 characters like:
alert("You have selected the maximum number of funds \n"+
"available for comparison. Please ensure only five \n"+
"funds have been selected for your basket.");
I understand hard-coding linebreaks is a bad idea in general (in some cases they will be poor choices) or if the text ever changes the line breaks will have to be adjusted by you.
As a programmer/developer you can't fully account for chrome not working properly. Except maybe avoiding alert box entirely, and sending the error message another way (e.g., ajax or a custom alert from say jquery).
#DaveDev, here is the image you requested. I think it looks good enough.
The code is from #dr jimbob's answer.
I recommend to you that you, as a programmer, controll the length of each string. You can cut the line, by yourself, with a '\n' character, and control every line for yourself.
I suspect there is a line end in your document, because testing it in my Chrome (12, windows 7), the alert displays like it should. Are you using HTMLTidy or some HTML formatter?
[edit] Okay, seems to be a genuine Chrome issue. Here some related issues #code.google.com for Chrome
Lengthy alerts have weird line break in them
Long text messages get truncated on the Javascript Alert box
javascript alert popup truncates strings every 132 chars
The solution I have stumbled upon is to add +"\ " (backslash space) at the end of the string. Each of my text lines ends with a \n in any case, so effectively my string now ends with "\n\ "Then it seems I can use as many \n's that I want. Don't ask me why it works. Perhaps it will work for you? Just call me persistent!

innerHTML alternative for retrieving contents of page?

I'm currently using innerHTML to retrieve the contents of an HTML element and I've discovered that in some browsers it doesn't return exactly what is in the source.
For example, using innerHTML in Firefox on the following line:
<div id="test"><strong>Bold text</strong></strong></div>
Will return:
<strong>Bold text</strong>
In IE, it returns the original string, with two closing strong tags. I'm assuming in most cases it's not a problem (and may be a benefit) that Firefox cleans up the incorrect code. However, for what I'm trying to accomplish, I need the exact code as it appears in the original HTML source.
Is this at all possible? Is there another Javascript function I can us?
I don't think you can receive incorrect HTML code in modern browsers. And it's right behaviour, because you don't have source of dynamicly generated HTML. For example Firefox' innerHTML returns part of DOM tree represented in string. Not an HTML source. And this is not a problem because second </strong> tag is ignored by the browser anyway.
innerHTML is generated not from the actual source of the document ie. the HTML file but is derived from the DOM object that is rendered by the browser. So if IE somehow shows you incorrect HTML code then it's probably some kind of bug. There is no such method to retrieve the invalid HTML code in every browser.
You can't in general get the original invalid HTML for the reasons Ivan and Andris said.
IE is also “fixing” your code just like Firefox does, albeit in a way you don't notice on serialisation, by creating an Element node with the tagName /strong to correspond to the bogus end-tag. There is no guarantee at all that IE will happen to preserve other invalid markup structures through a parse/serialise cycle.
In fact even for valid code the output of innerHTML won't be exactly the same as the input. Attribute order isn't maintained, tagName case isn't maintained (IE gives you <STRONG>), whitespace is various places is lost, entity references aren't maintained, and so on. If you “need the exact code”, you will have to keep a copy of the exact code, for example in a JavaScript variable in a <script> block written after the content in question.
If you don't need the HTML to render (e.g., you're going to use it as a JS template or something) you can put it in a textarea and retrieve the contents with innerHTML.
<textarea id="myTemplate"><div id="test"><strong>Bold text</strong></strong></div></textarea>
And then:
$('#myTemplate').html() === '<div id="test"><strong>Bold text</strong></strong></div>'
Other than that, the browser gets to decide how to interpret the HTML and it will only return you it's interpretation, not the original.
innerTEXT ? or does that have the same eeffect?
You must use innerXML property. It does exactly what you want to achieve.

Categories