Alec said:
I have a few questions about this though (I'm not a web developer, so sorry if these questions are stupid)
np, the XML standard is a mess; I don't understand half of it myself
(</disclaimer>)
Alec said:
From my understanding, the CDATA tag is tells the XML parser to take the contents literally, and not search for any tags until it reaches the closing "]]>" tag. So, because for the XML parser, Javascript is just data, it wouldn't care about the "/*". On the Javascript side, the js parser sees the "/*" tag and ignores everything up to the closing "*/" tag, and does not care about whether it contains CDATA or not. Isn't that how it works?
Yes excatly, but the problem here lies elsewhere.
The archetypical standards-compliant XML parser, roughly speaking, has 4 types of nodes:
- nodes (that contain *multiple* other nodes/elements e.g. <a><b/><c>...</c>...</a>)
- elements (that only contain data (single text nodes) e.g. <a href="hello">hello</a>)
- text nodes (raw text e.g. hello)
- comments (e.g. <!-- hello -->)
The names for the kinds of elements (and their number, granularity etc) vary between parsers.
Now, the problem that many old XML parsers have is that they don't merge adjacent text nodes. So, if we study this snippet for a second:
Code:
<script type="text/javascript">/*<![CDATA[*/
window.onload=function(){/*omitted*/}
//]]></script>
Strictly speaking, we can say that the "script" node contains two text nodes: one raw text node and one CDATA text node.
A
standards-aware XML parser would parse this as the following tree:
- node("script")
- elem("@type")
- text("/**/\nwindow.onload=function(){/*omitted*/}\n//")
However,
faulty XML parsers will not perform the optimization of merging the two text nodes, and will spit out this tree instead (note: two text nodes):
- node("script")
- elem("@type")
- text("/*")
- text("*/\nwindow.onload=function(){/*omitted*/}\n//")
Both are sent to the ECMAScript parser. The first snippet doesn't make sense (it's just an open-comment token) and is discarded. The second snippet contains a close-comment ("*/") token without an open-comment token and is also discarded (remember: this is the kind of parser we expect to find in IE; no fault tolerance). So, no Javascript gets loaded.
Now, let's say that we use this instead:
Code:
<script type="text/javascript">//<![CDATA[
window.onload=function(){/*omitted*/}
//]]></script>
The faulty parser now reads:
- node("script")
- elem("@type")
- text("//")
- text("window.onload=function(){/*omitted*/}\n//")
The first text node now contains valid ECMAScript (A complete one-liner comment) and the second text node too (→ there are no random comment tokens in the way). The code thus parses successfully.
Alec said:
So you're saying the proper way is to do:
new Date(document.getElementById('updated_date').innerHTML)).getTime()?
Yes. As it is now, you're subtracting an object from an integer. You should subtract an integer from an integer instead.
Alec said:
Should I use semicolons? I thought Javascript was like bash in that regard, where you need a semicolon only if you have two things on one line.
Javascript has the following parsing rules:
- Tokenise the file by splitting it up by semicolons
- If one statement doesn't compile, replace the first occurence of '\n' by ';' and try again.
There are a number of pitfalls with this approach, especially when some parsers become overzealous when it comes to semicolons (an error at the end of a script can trigger the insertion of semicolons at every line in the file). Examples:
- If you have stuff that spans over multiple lines and that has an unfortunate structure. E.g.:
Code:
if(true)
{
alert("You have found the truth!")
}
...becomes:
Code:
if(true); //if true do nothing
{//start new scope block
alert("You have found the truth!"); //invoke alert function
};//end scope block
- If you have long expressions that chain in an awkward way:
Code:
var x = 1 + 2 + 3
+ 5 - 4 - 17
- 2
Becomes:
Code:
var x = 1 + 2 + 3; //evaluate to 6 and store in x
+ 5 - 4 - 17; //evaluate to -16 and discard
- 2; //evaluate to -2 and discard
- etc...
It's better to just use semicolons and be on the safe side of the standards compliance border.