TinyMCE JavaScript error in Opera (getRangeAt, INDEX_SIZE_ERR)
Thursday, July 21, 2011 7:33:34 PM
TinyMCE 3.4.3.2
Opera 11.10
EDIT: TL;DR: Bug is fixed.
Jason Frame's bug fix, on November 08, 2011, recognized for Webkit browsers, also fixes the bug in Opera.
Fix exception in setRng for webkit browser where adding range isn't successful and causes an exception setting the selected range:
https://github.com/tinymce/tinymce/blob/347623591030c58bd06fd60c597dac93372d1921/jscripts/tiny_mce/classes/dom/Selection.js
Jason Frame's bug fix does what I did, in a similar fashion, by checking rangeCount to avoid an exception.
"t.selectedRange = s.rangeCount > 0 ? s.getRangeAt(0) : null;"
EDIT: See my pull request here: https://github.com/tinymce/tinymce/pull/77/
EDIT: This TinyMCE bug was previously reported from at least 2011-04-14, yet has not been fixed (until now, hopefully). See TinyMCE bug reports #4306 and #4372 (duplicate).
Introduction
On this webpage (http://demo.fengs.net/gplus/), there is a comments section powered by Livefyre. But how is this related to TinyMCE's JavaScript error? Livefyre uses TinyMCE.
I have discovered a JavaScript error, in Opera's error console, that left an underscore beside the name in the textbox.
@annedreshfield (Anne Dreshfield) is a community manager intern at Livefyre who wanted to get feedback. This is when I reported the issue:
@annedreshfield responded:@annedreshfield _ <--- Oh, and this underscore. What is it for? It shows up every time I reply.
After I heard that the JavaScript error could be an Opera issue, I decided to do some debugging. Eventually, I was able to solve the JavaScript error, which solved the underscore issue (and also the CTRL + V paste issue), so then, I posted this reply:[...] I checked in with our dev team and it looks like an issue with Opera. [...]
@annedreshfield, seems like I fixed the issue with the underscore. It was a problem with Livefyre's TinyMCE [...]
Analysis
The JavaScript for TinyMCE is hosted on Livefyre's server here:
http://livefyre.com/wjs/javascripts/tiny_mce/tiny_mce.js
In the "setRng" function, there is this:
if (h)
{
g.explicitRange = i;
h.removeAllRanges();
h.addRange(i);
g.selectedRange = h.getRangeAt(0)
}
Using some
#1
[7/21/2011 2:24:26 PM] JavaScript
Event thread: click
0) anchorNode: null; focusNode: null; Range c: 0
[7/21/2011 2:24:26 PM] JavaScript
Event thread: click
1) anchorNode: null; focusNode: null; Range c: 0
[7/21/2011 2:24:26 PM] JavaScript
Event thread: click
2) anchorNode: [object HTMLParagraphElement]; focusNode: [object HTMLParagraphElement]; Range c: 1
#2
[7/21/2011 2:24:26 PM] JavaScript
Timeout thread: delay 1 ms
0) anchorNode: null; focusNode: null; Range c: 0
[7/21/2011 2:24:26 PM] JavaScript
Timeout thread: delay 1 ms
1) anchorNode: null; focusNode: null; Range c: 0
[7/21/2011 2:24:26 PM] JavaScript
Timeout thread: delay 1 ms
2) anchorNode: [object HTMLParagraphElement]; focusNode: [object HTMLParagraphElement]; Range c: 1
#3
[7/21/2011 2:24:26 PM] JavaScript
Timeout thread: delay 50 ms
0) anchorNode: [object HTMLParagraphElement]; focusNode: [object HTMLParagraphElement]; Range c: 1
[7/21/2011 2:24:26 PM] JavaScript
Timeout thread: delay 50 ms
1) anchorNode: null; focusNode: null; Range c: 0
[7/21/2011 2:24:26 PM] JavaScript
Timeout thread: delay 50 ms
2) anchorNode: null; focusNode: null; Range c: 0
[7/21/2011 2:24:26 PM] JavaScript - http://demo.fengs.net/gplus/
Timeout thread: delay 50 ms
Uncaught exception: DOMException: INDEX_SIZE_ERR
Error thrown at line 5744, column 0 in <anonymous function: setRng>(i) in...
g.selectedRange = h.getRangeAt(0);
called from line 5221, column 16 in <anonymous function: setContent>(j, i) in...
g.setRng(k);
called from line 11731, column 16 in <anonymous function: mceInsertContent>(x, v, u) in...
p.setContent(u)
called from line 11506, column 16 in q(y, x, v) in...
u(y, x, v);
called from line 10640, column 12 in <anonymous function: execCommand>(x, v, z, p) in...
if (r.editorCommands.execCommand(x, v, z))
called from line 99, column 27083 in <anonymous function: showReplyForm>() in http://livefyre.com/wjs/v1.0/javascripts/livefyre.js?r=...:
d.execCommand("mceInsertContent",false,h);
See the pattern? For the third group, the "h" object already has the anchorNode and focusNode. Removing all ranges will set them to null. Apparently, "addRange(i)" doesn't help.
The fix is to pre-check / validate the "h" properties before doing stuff.
Fix
if (h)
{
if (h.anchorNode === null && h.focusNode === null)
{
g.explicitRange = i;
h.removeAllRanges();
h.addRange(i);
}
if (h.rangeCount > 0)
{
g.selectedRange = h.getRangeAt(0);
}
}
Conclusion
After I applied the fix with Opera's super-cool "edit this source file and 1-click apply" feature, I am happy to see that there are no more incorrectly placed underscores next to the name, and above all, no more JavaScript error!







