The link definition names are stored in an Array. Arrays have reduce
as a method, which seems to be the source of the problem. You can reproduce it with concat
or filter
or any other Array
method, too. I'm no Javascript expert, and I haven't dug far enough into the problem to figure out just why it happens -- especially because it begins working again if you include the optional title for the link -- but you can see for yourself that it affects the base WMD implementation, too, not just SO's version.
EDIT:
So the problem is that indexing any object in Javascript with a method name returns the function itself. The structure of the Markdown editor is such that it stores URLs and link titles in two arrays, both of which are indexed by the link definition name. The markdown converter craps out when attempting to escape characters on the function code returned when the index is a function name. You have to have the optional title, because if you omit it, it still thinks it has a title and attempts to escape characters on the function. It begins working when you have the URL and option text in place, because the function gets overwritten in the two arrays with the proper strings.
EDIT 2:
Here is some of the code in question from the SO branch of WMD:
if (g_urls[link_id] != undefined) {
url = g_urls[link_id];
if (g_titles[link_id] != undefined) {
title = g_titles[link_id];
}
}
The above code uses link_id
(which would be "reduce") in order to index into g_urls
and g_titles
. As I mentioned before, these will not be undefined
, even when they "should" be. Instead, they'll be the reduce
functions themselves. Note that, because of the structure here, unless both the URL and title are defined, one or both will be set to the function.
Next is the code that actually creates the problem:
url = escapeCharacters(url,"*_");
var result = "<a href=\"" + url + "\"";
if (title != "") {
title = title.replace(/"/g,""");
title = escapeCharacters(title,"*_");
result += " title=\"" + title + "\"";
}
The code attempts to escape characters on url
and title
(which, again, will not be ""
even when it should be). This kills the code, because you obviously can't escape characters on a function (Wouldn't that be cool if you could, though? Like, it actually stripped the characters from the function code? Pointless? Sure. But cool.). So until both url
and title
have actual string values, the conversion process craps out, which is why it seems like it freezes.
So how to solve it? The simplest way would be to change the first block of code to something like this:
if (g_urls[link_id] != undefined && typeof g_urls[link_id] != 'function') {
url = g_urls[link_id];
if (g_titles[link_id] != undefined && typeof g_titles[link_id] != 'function') {
title = g_titles[link_id];
}
}
Maybe a Javascript ninja will know of an even better way, but that should work. I'd submit it as a patch, but my git skill is even more limited than my Javascript.
EDIT 3:
Blixt has suggested this alternate solution, which appears to work just as well, is less of a workaround, and is probably better semantically. In lieu of the above change, instead change these lines (lines 105-106):
g_urls = new Array();
g_titles = new Array();
to this:
g_urls = {};
g_titles = {};
I haven't done especially rigorous testing, but it appears to be working like a charm.