Category Archives: JavaScript

Prototype, tinyMCE, ‘too much recursion’

If you happen to be using TinyMCE and the Prototype library together and you’re getting a ‘too much recursion’ error in FireFox, make sure to upgrade to the latest version of Prototype, which at the time of this post is version 1.5.0. Near as I can tell, the only way to get version 1.5.0 is to either a) check it out of the subversion repository or b) download script.aculo.us, which contains version 1.5.0 in the lib directory of the distribution.

I think the ‘too much recursion’ Prototype / TinyMCE problem happens because Prototype stores a copy of the Array reverse function in a property called _reverse:

Array.prototype._reverse = Array.prototype.reverse;

and then redefines the reverse function, adding a argument ‘inline’:

reverse: function(inline) {
  return (inline !== false ? this : this.toArray())._reverse();
}

Somehow (and I’m not sure how this would happen) the copy happens again, which means that _reverse() would point to the redefined reverse() method function, which of course points to _reverse(), which leads to a infinite loop. Hence, ‘too much recursion’.

Regardless, the changelog from latest version of Prototype has a pointer to issue #3951 (but it doesn’t appear that the issues are public): in short, version 1.5.0 of Prototype does a check to make sure that _reverse() hasn’t been defined:

if (!Array.prototype._reverse)
  Array.prototype._reverse = Array.prototype.reverse;

In related news, if you’re using script.aculo.us with TinyMCE, make sure to embed the script.aculo.us js after the TinyMCE js.

Can’t add hyperlink with onclick to IE using DOM

Last week I was attempting to dynamically add hyperlinks that contained an onclick event to a document. The hyperlink, when written to the browser, would look something like this:

<a href="#" onclick="fireEvent(); return false;">fire away!</a>

and I was using code that looked something like this to produce the links (and yes, I know about real links):

<script>
function createLink(id) {
  var node = document.getElementById(id);
  var aNode = document.createElement("a");
  node.appendChild(aNode);
  aNode.setAttribute("href","#");
  aNode.setAttribute("onclick", "fireEvent(); return false;");
  aNode.appendChild(document.createTextNode("fire away!"));
}
function fireEvent() {
  alert('fire!');
}
</script>
<a href="#" onclick="createLink('mytable'); return false;">create link</a>
<table cellpadding="0" cellspacing="0" border="0" width="100%">
<tbody>
<tr>
  <td id="mytable"></td>
</tr>
</tbody>
</table>

Running the above code in Firefox worked fine, the fireEvent() method was invoked when you clicked the ‘fire away!’ link. The same exact code in IE didn’t work. Instead, it appeared that IE completely ignored the onclick event and just went with the value of the href attribute. The simple workaround, in this case at least, was to use the innerHTML property of the cell I was adding the link to, so the createLink() function became:

function createLink(id) {
  var node = document.getElementById(id);
  node.innerHTML = '<a href="#" onclick="fireEvent(); return false;">fire away!</a>';
}

Am I wrong in thinking that this is a bug?

Related:

Early event handlers
Javascript: createElement, innerHTML and IE security zones
can’t put a row into a table in IE using DOM methods


Updated 7/3/2006: My boss Bill sent a note mentioned the behaviors library which uses AOP techniques to reduce what the author calls ‘scattering’ and ‘tangling’ and would may also be a solution to the problem mentioned above.