[SharePoint 2010] JavaScript Errors in sp.ui.rte.js and sp.ui.rte.debug.js

In SharePoint 2010, there is a bug in the SP.UI.RTE.js file (and it’s debug version) that causes a JavaScript error in a few different situations. For myself, it was occurring when using the TaxonomyWebTaggingControl on a custom application page. Others have noticed the error with form validation.

The issue is caused by a null reference exception that isn’t caught in a try-catch block or other type of error handling.

James Boman posted a solution that involves editing these files on the hard drive. I agree with his sentiment in the post that this is a really bad idea for a few reasons: 1) Microsoft doesn’t support your environment if you mess with their files, 2) any updates to SharePoint (and sometimes Windows) will override your changes, and 3) you could do more damage than good.

With that said, however, using his modified code, we can override the offending code with some additional JavaScript rather than editing Microsoft’s code. In this function, we first ensure that the function is not undefined. Then, we replace the specific function with a fixed version of the function. It’s not the prettiest fix, however it sure beats editing Microsoft’s files.

function fixRTEBug () {
    if ((typeof (RTE) !== 'undefined') && (typeof (RTE.Range) !== 'undefined') && (typeof (RTE.Range.prototype) !== 'undefined') && (typeof (RTE.Range.prototype.parentElement) !== 'undefined')) {
        RTE.Range.prototype.parentElement = (function () {
            ULSkay: ;
            var $v_0 = this.$8;
            if ($v_0.parentElement) {
                var $v_2 = $v_0.parentElement();
                var $v_3 = RTE.DomHelper.createRange(window.document);
                if ($v_2) {
                    try { // Added Try-Catch block around code that causes the JavaScript error to occur
                        $v_3.moveToElementText($v_2);
                    }
                    catch (err) {
                        // DO NOTHING!
                    }
                }
                while ($v_2 && !$v_3.inRange($v_0)) {
                    $v_2 = $v_2.parentNode;
                    try {
                        $v_3.moveToElementText($v_2);
                    }
                    catch ($$e_3_0) {
                    }
                }
                if ($v_2) {
                    var $v_4 = true;
                    while ($v_4) {
                        $v_4 = false;
                        var $v_5 = $v_2.childNodes.length;
                        for (var $v_6 = 0; $v_6 < $v_5; $v_6++) {
                            if (!SP.UI.UIUtility.isTextNode($v_2.childNodes[$v_6])) {
                                $v_3.moveToElementText($v_2.childNodes[$v_6]);
                                if ($v_3.inRange($v_0)) {
                                    $v_2 = $v_2.childNodes[$v_6];
                                    $v_4 = true;
                                    break;
                                }
                            }
                        }
                    }
                }
                return $v_2;
            }
            var $v_1 = $v_0.commonAncestorContainer;
            if ($v_1) {
                return $v_1;
            }
            return null;
        });
    }
}

ExecuteOrDelayUntilScriptLoaded(fixRTEBug, "sp.ui.rte.js");

In my project, I am loading this JavaScript on every page using an AdditionalPageHead control.

Hopefully you find this useful.

John Chapman

Hello, I'm John Chapman. I am a SharePoint Developer for Sitrion (formerly NewsGator) living in Denver, Colorado. I develop solutions using SharePoint and .NET, and I thrive on the challenge of writing code to overcome the impossible, annoying, or otherwise difficult obstacles.

More Posts - Website - Twitter - LinkedIn - Google Plus

  • Pingback: Share Point |

  • Pingback: Dynamic Forms for SharePoint: Now with side-by-side « SharePoint JavaScripts

  • dantuck

    A slightly better solution which us CU proof for the part that is fixed according to this blog but also adds in a fix for RTE.Canvas.checkCurrentFocus to fix error in console.

    function fixRTEBug() {

    if (typeof ngSharepointVersion === ‘undefined’ || ngSharepointVersion !== 14)

    return;

    if (typeof RTE.Canvas.checkCurrentFocus !== ‘undefined’) {

    RTE.Canvas.checkCurrentFocus = function() {ULSkay:;

    var $v_0 = RTE.Selection.getSelectionRange();

    if ($v_0) { //this is different from SP to avoid error in console

    var $v_1 = $v_0.parentElement();

    if (RTE.Canvas.isInEditable($v_1) && !RTE.Cursor.get_range().isValid()) {

    RTE.Cursor.updateRangeToCurrentSelection();

    RTE.Cursor.update();

    }

    }

    }

    }

    // This Fix for parentElement bug in RTE should survive Service Packs and CU’s

    function SubstituteRTERangeParentElement() {

    var originalRTERangeParentElement = RTE.Range.prototype.parentElement;

    RTE.Range.prototype.parentElement = function () {

    try {

    originalRTERangeParentElement();

    } catch (e) { }

    }

    }

    SubstituteRTERangeParentElement();

    }

    • Robbert Helling

      dantuck: Nice! +1