Javascript error in a comment //#Deprecated in IE [duplicate] - javascript

So this post is not so much of a "please help me fix it" post as much as it is a "why would changing that make it work?". So I had some javascript/jquery written that was working in firefox and chrome, but IE threw errors.
I could not figure it out even with the helpful posts from users here at stackoverflow. I eventually stumbled upon the answer (as I seem to find myself doing a lot with coding).
I was doing a somewhat rigorous style of commenting taught to me by one of my computer science professors where a function would have commenting such as this:
//# describe function
//# params: param1 - function, param2 - function
//# etc....
So I foolishly threw this into my javascript only to find out that IE really did not care for this much at all. When I removed the # symbols the code worked perfectly.
So my question is why this caused errors in IE? Shouldn't whatever follows the '//' comments not matter?

It does indeed look like some kooky IE conditional comment support. It appears that if # is the first character of a comment (whether it starts with //# or /*#, then IE looks for a conditional comment directive after the # sign. See http://msdn.microsoft.com/en-us/library/8ka90k2e(v=vs.94).aspx for some examples.
AlienWebguy's suggestion should work because the first character of the comment is *. You could probably also just put a space before the # sign:
// # describe function
// # params: param1 - function, param2 - function
// # etc....

You might be thinking of docblock commenting, which you would want to wrap in block comment syntax:
/**
* Function does this
* #param <string> $str The string
* #param <array> $arr The array
* #return <bool> true if string is in array, false if not
*/
I can see IE just being stupid. Odds are even if there is an explanation for why your //# didn't work, it'll likely be a really stupid one, and odds are that only a small percentage of us would even be able to recreate it on our version of IE.
IE is the only browser to my knowledge that looks at conditional comments, so I can see them having a different comment parser than all other browsers which would conflict with otherwise proper code.

Related

Why does <!-- Not Throw a Syntax Error?

I noticed in some legacy code the following pattern:
<script>
<!--
// code
// -->
</script>
After some research, this appears to be a very old technique for hiding the contents of script elements from the DOM when the browser did not support the <script> element. More information can be found here.
My concern is this: why does <!-- not throw a Syntax Error? I've found on whatwg.org's website that <!-- should be functionally equivalent to //, and it links off to a snippet from the ECMAScript grammar about comments. The problem is, <!-- isn't defined by that grammar at all.
So this seems like undefined behavior that happens to be implemented by all major browsers. Is there a specification that allows for this, or is this a backwards-compatibility hack that people are bringing forward?
Officially: Because there's specific handling for it in the HTML spec. E.g., it's a "by fait" thing. It's not a JavaScript thing, you won't find it in the JavaScript grammar.
Unofficially, it would appear that at least some JavaScript engines handle it intrinsically, sometimes in ways that make what I believe is valid JavaScript invalid. For instance, on V8 in a browser, this fails:
eval("var a = 1; var n = 3; console.log(a<!--n);")
...with Unexpected end of input. I'm pretty sure it shouldn't, but I'm not a parsing lawyer. I'd expect it to log false to the console, like this does:
eval("var a = 1; var n = 3; console.log(a<! --n);")
// Note the space -------------------------^
Side note: Meteor's jsparser agrees with me, copy and paste just the bit inside the double quotes into it.
Note that the characters <! do not appear in the specification, nor does there appear to be anything near any of the 70 occurrences of the word "comment" in there, nor is it anywhere in the comment grammar, so it wouldn't seem to be an explicit in-spec exception. It's just something at least some JavaScript engines do to avoid getting messed up by people doing silly things. No great surprise. :-)
It is defined by the W3's docs for the user agents:
The JavaScript engine allows the string "<!--" to occur at the start of a SCRIPT element, and ignores further characters until the end of the line.
So browsers follow these standards

In JavaScript does /** have any special meaning?

I know I can add comments like so:
//This is a comment,
/*so is this*/
But when I do this
/**comment?*/
It has a different color in my text editor (notepad++) and I was wondering whether it has any special meaning, or if it is just a random feature of notepad++.
Here is what it looks like in the text editor:
No, it has not any special meaning. It's more common to use that syntax when documenting code via comments.
The Java language supports three kinds of comments:
/* text /The compiler ignores everything from / to */.
/** documentation /
This indicates a documentation comment (doc comment, for short). The compiler ignores this kind of comment, just like it ignores comments that use / and */. The JDK javadoc tool uses doc comments when preparing automatically generated documentation. For more information on javadoc, see the Java tool documentation.
// text
The compiler ignores everything from // to the end of the line.
Not in JavaScript itself, but some editors will treat it like a JSDoc (https://github.com/jsdoc3/jsdoc) comment to help with autocomplete, etc.
You can also run your code through something like JSDoc to automatically generate HTML documentation for your codebase.
Probably notepad++ identifies it with two different colors just to diversify the type of comment. for a programmer a comment may be more or less important than another :)
might seem like a silly feature, but it is not

HTML5 History.pushState mangles URL's containing percent encoded non-Ascii (Unicode) chars

In an OSS web app, we have JS code that performs some Ajax update (uses jQuery, not relevant). After the page update, a call is made to the html5 history interface History.pushState, in the following code:
var updateHistory = function(url) {
var context = { state:1, rand:Math.random() };
/* -----> bedfore the problem call <------- */
History.pushState( context, "Questions", url );
/* -----> after the problem call <------- */
setTimeout(function (){
/* HACK: For some weird reson, sometimes something overrides the above pushState so we re-aplly it
This might be caused by some other JS plugin.
The delay of 10msec allows the other plugin to override the URL.
*/
History.replaceState( context, "Questions", url );
}, 10);
};
[Please note: the full code segment is provided for context, the HACK part is not the issue of this question]
The app is i18n'ed and is using URL encoded Unicode segments in the URL's, so just before the marked problem call in the above code, the URL argument contains (as inspected in Firebug):
"/%D8%A7%D9%84%D8%A3%D8%B3%D8%A6%D9%84%D8%A9/scope:all/sort:activity-desc/page:1/"
The encoded segment is utf-8 in percent encoding. The URL in the browser window is: (just for completeness, doesn't really matter)
http://<base-url>/%D8%A7%D9%84%D8%A3%D8%B3%D8%A6%D9%84%D8%A9/
Just after the call, the URL displayed in the browser window changes to:
http://<base-url>/%C3%98%C2%A7%C3%99%C2%84%C3%98%C2%A3%C3%98%C2%B3%C3%98%C2%A6%C3%99%C2%84%C3%98%C2%A9/scope:all/sort:activity-desc/page:1/
The URL encoded segment is just mojibake, the result of using the wrong encoding at some level. The correct URL would've been:
http://<base-url>/%D8%A7%D9%84%D8%A3%D8%B3%D8%A6%D9%84%D8%A9/scope:all/sort:activity-desc/page:1/
This behavior has been tested on both FF and Chrome.
The history interface specs don't mention anything about encoded URL's, but I assume the default standard for URL formation (utf-8 and percent encoding etc) would apply when using URL's in function calls for the interface.
Any idea on what's going on here.
Edit:
I wasn't paying attention to the uppercase H in History - this code is actually using the History.js wrapper for the history interface. I replaced with a direct call to history.pushState (notice the lowercase h) without going through the wrapper, and the code is working as expected as far as I can tell. The issue with the original code still stands - so an issue with the History.js library it seems.
Update
As Doug S explains in the comments below, the latest version of History.js includes a fix for this behaviour. He also found that my solution caused double-encoding when used in browsers (such as IE 9 and below) which require the hash fallback, so I recommend that instead of using the fix detailed below, just download the latest version.
I've kept my original answer below, since it does explain what's going on in much more detail.
Basel found a resolution of sorts, but there's still some confusion about what's happening under the hood. This answer goes into detail about the problem and suggests a better fix. (You can skip straight to the fix if you want.)
The problem
First, open your browser's JS console and run this:
window.encodeURI(window.unescape('%D8%A7%D9%84%D8%A3%D8%B3%D8%A6%D9%84%D8%A9'))
Does that look familiar? It should—that's what your URL is being mangled to. The problem lies in the implementation of History.unescapeString, specifically this line:
tmp = window.unescape(result);
window.unescape is a DOM Level 0 function—which is to say, an unstandardised relic from the hoary days of Netscape 2. It uses the escaping rules defined in RFC 2396, according to which characters outside of the unreserved range (alphanumerics and a small set of punctuation symbols) are encoded as octets.
This works fine for the US-ASCII range, but not all (indeed, the vast majority) of the characters in UTF-8 can be represented in a single byte. Since URIs do not have a built-in way of representing the character set being used, window.unescape just assumes each character maps to a single octet and blithely mangles any that don't.
In this example, the first letter in your URL is the Arabic letter alef (ا), represented by two bytes: 0xD8 0xA7. window.unescape interprets these as two separate characters: 0x00 0xD8 (Ø—capital O with stroke) and 0x00 0xA7 (§—section sign).
This is a known issue with History.js.
The fix
As noted above by the asker, the issue can be sidestepped by using the native implementation of the History API instead of the History.js wrapper, i.e. history.pushState instead of History.pushState.
This works for browsers that support the History API, but loses the benefit of having a polyfill for those that don't. Fortunately, there's a better fix. Open up the History.js source you're referencing and find this line (~1059 in my copy):
tmp = window.unescape(result);
Replace it with:
tmp = window.unescape(encodeURIComponent(result));
Or, if you're using the compressed source, replace a.unescape(c) with a.unescape(encodeURIComponent(c)).
To test this change, I ran the History.js HTML5 jQuery test suite on a local web server inside an Arabic-named directory. Before making the change, test 14 fails; after the change, all tests passed.
Credit
Though I found the problem and solution independently, Damien Antipa deserves credit for finding it first and making a pull request with the fix.
I'm still able to reproduce this in the following case:
History.pushState(null, null, "?" + some_Unicode_String_Or_A_String_With_Whitespace);
document.location.hash += "&someStuff";
In this case the _suid parameter gets removed and &someStuff as well. If the string is not unicode or doesn't have whitespaces (so no % chars) - this does not happen.
This workaround worked for me:
History.pushState(null, null, "?" + some_Unicode_String_Or_A_String_With_Whitespace + "&someStuff");

What does IE use //# in javascript for?

So, a bug in a piece of javascript revolved around code similar to :
<script>
(function() {
if (true) {
//#todo: do we need to set total or -- ?
alert('hello?');
}
})();
</script>
In the larger system IE complained "Expected ';' ". In the small scale example IE simply caused a warning about blocking ActiveX controls.
Obviously, "//#" has some context to activeX controls in IE. I was unable to find this as searching for the symbols was useless, and any search about special comments in IE result in the conditional html comments. I am just curious how the //# are supposed to be used in IE.
The IE JScript engine supports conditional comments which turn comments written in a particular way into code (partially). However, you are not using those.
In your case it seems to be a way to tell e.g. an IDE that there is a TODO item. The error you got is most likely unrelated.
Unless there's some quirk about IE that I don't know, the //#todo is just commenting fluff that some programmers use when they are too lazy/don't know how to implement something.

What does "!default" mean for a dependency

When I look at the source code of the dojo 1.7 amd dependency list, i see the following:
define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array",
"./_base/lang", "./selector/_loader", "./selector/_loader!default"],
The only use of an exclamation mark I know is for plugins, I haven't seen this "!default" before.
I read this page "https://github.com/amdjs/amdjs-api/wiki/AMD" and googled about it, but I did not find any answer.
Can anybody help me with that!
Thanks
Wolfgang
Update:
Thank you, Ates Goral, for your answer.
Now everything is clear to me.
Then, the irritating thing for me with this special case was, that "./selector/_loader" occurs twice in the above line, one time without parameters and the next time with a parameter. I saw people writing "dojo/domReady!", so I thought it was mandatory to write an exclamation mark for a plugin, even without parameters. Now I have learned that plugins don't need an "!" and I will write "dojo/domReady".
Another Update:
Today I found the following interesting statement (main.js of https://github.com/csnover/dojo-boilerplate):
The “!” after the module name indicates you want to use special plugin functionality; if you were to require just “dojo/domReady”, it would load that module just like any
other module, without any of the special plugin functionality.
I don't know if this statement is correct. It it is correct, then "./selector/_loader" would have some kind of hybrid functionality?
http://livedocs.dojotoolkit.org/loader/amd
When a module identifier passed to require or define contains an "!",
the loader splits the string in two at the exclamation point. The
string to the left of "!" is treated like a normal module ID and is
used as the identifier for the desired plugin; the string to the right
of "!" is passed to the plugin for processing.
In your case, "default" is being passed to the plugin.

Categories