html comments in JS are valid! Ugh.

110 views
Skip to first unread message

Kyle Simpson

unread,
Sep 5, 2013, 12:29:01 PM9/5/13
to js-t...@googlegroups.com
There's an interesting discussion going right now about HTML-style comments in JS code, such as `<!--` and `-->`. They aren't valid according to the ES spec, but they ARE valid according to the "Web ES" spec.

Related discussion threads:

https://github.com/getify/literalizer/issues/19

https://github.com/marijnh/acorn/issues/62


All browser JS engines, including v8, which also means node.js, allow them.

It seems most if not all JS tools, however, do not.

* esprima rejects them
* traceur rejects them
* acorn rejects them
* jslint rejects them
* uglifyjs rejects them
* jshint actually breaks completely on them (ugly).

I'm trying to figure out if I should support them in literalizer.

You may wonder why it matters. Well, if the JS tools don't support them, but the browsers, do, code such as this is going to be valid in both places, but interpreted quite differently:

var a = 1, b = 1; a <!--b;

So my question to the list is, how should the JS tooling arena handle this?

If we all reject them, we run the risk of code above. If we all accept them, we're diverging from the pure ES spec, which makes it a more "relative" thing which spec we in fact adhere to. If we all do different things, then tool interop is harmed greatly.

So, what do we do?


--Kyle

Rhys Brett-Bowen

unread,
Sep 5, 2013, 4:25:19 PM9/5/13
to js-t...@googlegroups.com
I believe they were put in originally for early browser that couldn't understand <script> tags.

Also related is:

<![CDATA[

for xml.

I thought these only worked if they were the first tokens on a line though...

Kyle Simpson

unread,
Sep 5, 2013, 5:33:00 PM9/5/13
to js-t...@googlegroups.com
Rhys- that's surely the "why".

But the question at hand is, if none of us tools authors are following that de-facto standard, however silly or ill-advised the practice is, what does that mean for the gap between the pure ES spec and the "Web ES" spec? Should we really just look the other way and pretend there's no gap?

BTW, it's apparently slated to standardize in ES6: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-B.1.3

That seems to provide a pretty strong argument for why JS tools should start handling them according to that expected standardization.



--Kyle



Mike Samuel

unread,
Sep 6, 2013, 11:46:14 AM9/6/13
to js-t...@googlegroups.com
2013/9/5 Kyle Simpson <get...@gmail.com>:
> There's an interesting discussion going right now about HTML-style comments
> in JS code, such as `<!--` and `-->`. They aren't valid according to the ES
> spec, but they ARE valid according to the "Web ES" spec.

In various versions of the HTML 5 spec, these weren't comments when
seen inside <script> or <style> elements, but were "escaping text
spans".
http://www.w3.org/TR/2008/WD-html5-20080610/syntax.html#escaping
That language has been removed in recent versions.


If <!--...--> is a comment or the delimiters are ignorable, what
should tools do with code like

var CDATA = window.extern;

window['f'] = function (a, b, c, d, x, y, z) {
return a < ! --b && c-- > d && x < ![CDATA[i]].indexOf('foo') ||
y[[1]] > z[2];
};

Closure compiler with simple optimizations produces

var CDATA=window.extern;window.f=function(a,b,c,d,e,f,g){return
a<!--b&&c-- >d&&e<![CDATA[i]].indexOf("foo")||f[[1]]>g[2]};

which includes the substring "<!--", "<![CDATA[", and "]]>" though it
splits the token "-->".

It's likely that other tools produce output that contain these
substrings even when not seen on input.

Michael Schwartz

unread,
Sep 6, 2013, 11:49:46 AM9/6/13
to js-t...@googlegroups.com
Everything after <!-- is a comment.

> return a < ! --b && c-- > d && x < ![CDATA[i]].indexOf('foo') ||

becomes

return a // --b && c-- > d && x < ![CDATA[i]].indexOf('foo') ||

If I read the spec right.
> --
> --
> http://clausreinke.github.com/js-tools/resources.html - tool information
> http://groups.google.com/group/js-tools - mailing list information
>
> ---
> You received this message because you are subscribed to the Google Groups "js-tools" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to js-tools+u...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

Mike Samuel

unread,
Sep 6, 2013, 12:18:03 PM9/6/13
to js-t...@googlegroups.com
2013/9/6 Michael Schwartz <myk...@gmail.com>:
> Everything after <!-- is a comment.
>
>> return a < ! --b && c-- > d && x < ![CDATA[i]].indexOf('foo') ||
>
> becomes
>
> return a // --b && c-- > d && x < ![CDATA[i]].indexOf('foo') ||
>
> If I read the spec right.

So to determine if you're running EcmaScript or Web EcmaScript you could use

function isWebEcmaScript() {
var x = 0;
return !(
0 <!-- x /* --> /**/
);
}

which is a valid function declaration in both but returns true only
when <!--...--> is elided from the token stream.

Mike Samuel

unread,
Sep 6, 2013, 12:20:18 PM9/6/13
to js-t...@googlegroups.com
2013/9/6 Mike Samuel <mikes...@gmail.com>:
> 2013/9/6 Michael Schwartz <myk...@gmail.com>:

Sorry, this should have read:

> function isWebEcmaScript() {
> var x = 1;

Kyle Simpson

unread,
Sep 6, 2013, 12:58:45 PM9/6/13
to js-t...@googlegroups.com
I think you may be missing something: both <!-- and --> are treated individually as // single line comments. They don't constitute a /* .. */ multi-line comment pair/block (like they do in HTML). Example:


var a = 2;
<!-- a = 3;
a = 4;
--> a = 5;
console.log(a); // 4


There's special rules around the --> token, that it has to be the first non-whitespace, non-multi-line-comment on a single line to be recognized as a comment delimiter. But otherwise, both act like a //.

----
As for doing a run-time check, I think it's quite possible you could construct such a check, but I think it would be moot, because AFAICT, all JS engines themselves do support this comment syntax. Chakra, Spidermonkey, JavaScriptCore, and v8 all do. Not sure about Rhino, but I've heard it does. Certainly any engine that remotely executes web focused content has to, for backwards compat.

Now, JS tools (like parsers, compilers, transpilers, minifiers, analyzers, etc…), those don't all support it. Up until this morning, I didn't know of any tools with support.

But Acorn and UglifyJS landed support this morning, and Esprima accepted the request and should land a patch at some point. Anton said that JSHint would accept a patch for it, but that he wouldn't write the patch. (however, JSHint is the only tool I've found that flat out breaks, throws an error and crashes, rather than reporting gracefully about the unsupported syntax, so given the more severity of their bug, I'd bet they have to fix one way or the other, and probably soon).

We could probably guess that Crockford won't land support in JSLint. I don't even want to ask him. BUT, perhaps after ES6 standardizes it, he will. Who knows?

But since only a JS engine actually executes at run-time, I think a run-time check for support wouldn't be fruitful, and would probably always return true. However, you COULD construct a check as to whether a piece of code was, at any point, processed by a tool that either did or didn't, and then perhaps I guess there's something you could do at run-time with the knowledge of your tooling stack. But again, this seems fairly niche/academic.

Given that several tools spoke up and agreed to start supporting these (because of the expected ES6 specification), I think all JS tools should seriously consider either automatic, or at least enabled with a config-flag, this kind of support.

If we have some tools with support and some without, that harms tool interop.



--Kyle
> --
> --
> http://clausreinke.github.com/js-tools/resources.html - tool information
> http://groups.google.com/group/js-tools - mailing list information
>
> ---
> You received this message because you are subscribed to a topic in the Google Groups "js-tools" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/topic/js-tools/kBJSzXOwSRU/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to js-tools+u...@googlegroups.com.

Mike Samuel

unread,
Sep 6, 2013, 2:09:45 PM9/6/13
to js-t...@googlegroups.com
2013/9/6 Kyle Simpson <get...@gmail.com>:
> I think you may be missing something: both <!-- and --> are treated individually as // single line comments. They don't constitute a /* .. */ multi-line comment pair/block (like they do in HTML). Example:
>
>
> var a = 2;
> <!-- a = 3;
> a = 4;
> --> a = 5;
> console.log(a); // 4
>
>
> There's special rules around the --> token, that it has to be the first non-whitespace, non-multi-line-comment on a single line to be recognized as a comment delimiter. But otherwise, both act like a //.

This doesn't seem true experimentally.

On Chrome, Firefox, and Safari, in SquareFree shell,

a = 0;
[ a <!-- 0 --> + 1
, a]

prints "0,0", which suggests that
1. you're right that "-->" doesn't end a section because then we'd see [1,0]
2. wrong that "<!--" has to be the first non-whitespace token because
otherwise we'd get a syntax error: 0 is not a valid left hand side to
pre-decrement.

Kyle Simpson

unread,
Sep 6, 2013, 2:16:29 PM9/6/13
to js-t...@googlegroups.com
> 2. wrong that "<!--" has to be the first non-whitespace token because
> otherwise we'd get a syntax error: 0 is not a valid left hand side to
> pre-decrement.

That's not what I said. :)

>> There's special rules around the --> token, that it has to be the first non-whitespace, non-multi-line-comment on a single line to be recognized as a comment delimiter. But otherwise, both act like a //.

The --> has to be first on a line, but <!-- can appear anywhere on the line.



--Kyle


Mike Samuel

unread,
Sep 6, 2013, 3:59:54 PM9/6/13
to js-t...@googlegroups.com
2013/9/6 Kyle Simpson <get...@gmail.com>:
Understood. Sorry for misquoting.

Dave Brown

unread,
Jul 23, 2015, 7:19:22 PM7/23/15
to js-t...@googlegroups.com
HTML comments will not break minifier on http://www.whak.ca/packer/JavaScript.htm (even the default demo has HTML comment in sample code)
Reply all
Reply to author
Forward
0 new messages