[BUGFIX] In IE9, RTE does not work correctly in compat modes IE8/IE7
authorStanislas Rolland <typo3@sjbr.ca>
Tue, 3 Jul 2012 13:34:26 +0000 (09:34 -0400)
committerStanislas Rolland <typo3@sjbr.ca>
Tue, 3 Jul 2012 13:41:43 +0000 (15:41 +0200)
Problem: When using IE9, the RTE does not work correctly when using
compatibility modes IE8 or IE7. In particular, the style sheets are not
parsed, because they are not loaded in the same order as with the
specified compatibility version.
Solution: Check whether compatibility mode is activated.

Change-Id: I817658ef9338fc4cc35e4997102bfd5fd545b49e
Releases: 4.5, 4.6, 4.7, 6.0
Resolves: #38574
Reviewed-on: http://review.typo3.org/12534
Reviewed-by: Stanislas Rolland
Tested-by: Stanislas Rolland
typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js
typo3/sysext/rtehtmlarea/htmlarea/plugins/ContextMenu/context-menu.js
typo3/sysext/rtehtmlarea/htmlarea/plugins/TYPO3Link/typo3link.js

index 777df02..e6f04ac 100644 (file)
@@ -55,6 +55,10 @@ Ext.apply(HTMLArea, {
                // This expression is deprecated as of TYPO3 4.6
        RE_noClosingTag         : /^(area|base|br|col|command|embed|hr|img|input|keygen|meta|param|source|track|wbr)$/i,
        RE_numberOrPunctuation  : /[0-9.(),;:!¡?¿%#$'"_+=\\\/-]*/g,
+       /***************************************************
+        * BROWSER IDENTIFICATION                          *
+        ***************************************************/
+       isIEBeforeIE9: Ext.isIE6 || Ext.isIE7 || Ext.isIE8 || (Ext.isIE && typeof(document.documentMode) !== 'undefined' && document.documentMode < 9),
        /***************************************************
         * LOCALIZATION                                    *
         ***************************************************/
@@ -999,7 +1003,7 @@ HTMLArea.Iframe = Ext.extend(Ext.BoxComponent, {
         * @return      void
         */
        initializeCustomTags: function () {
-               if (Ext.isIE6 || Ext.isIE7 || Ext.isIE8 || (Ext.isIE && this.document.documentMode < 9)) {
+               if (HTMLArea.isIEBeforeIE9) {
                        Ext.each(this.config.customTags, function (tag) {
                                this.document.createElement(tag);
                        }, this);
@@ -3051,7 +3055,7 @@ HTMLArea.DOM = function () {
                 * @return      string          the text inside the node
                 */
                getInnerText: function (node) {
-                       return (Ext.isIE8 || Ext.isIE7 || Ext.isIE6) ? node.innerText : node.textContent;;
+                       return HTMLArea.isIEBeforeIE9 ? node.innerText : node.textContent;;
                },
                /*
                 * Get the block ancestors of a node within a given block
@@ -3177,7 +3181,7 @@ HTMLArea.DOM = function () {
                        var rangeIntersectsNode = false,
                                ownerDocument = node.ownerDocument;
                        if (ownerDocument) {
-                               if (Ext.isIE8 || Ext.isIE7 || Ext.isIE6) {
+                               if (HTMLArea.isIEBeforeIE9) {
                                        var nodeRange = ownerDocument.body.createTextRange();
                                        nodeRange.moveToElementText(node);
                                        rangeIntersectsNode = (range.compareEndPoints('EndToStart', nodeRange) == -1 && range.compareEndPoints('StartToEnd', nodeRange) == 1) ||
@@ -3608,7 +3612,7 @@ HTMLArea.DOM.Selection = Ext.extend(HTMLArea.DOM.Selection, {
                var isEmpty = true;
                this.get();
                if (!Ext.isEmpty(this.selection)) {
-                       if (Ext.isIE8 || Ext.isIE7 || Ext.isIE6) {
+                       if (HTMLArea.isIEBeforeIE9) {
                                switch (this.selection.type) {
                                        case 'None':
                                                isEmpty = true;
@@ -3634,7 +3638,7 @@ HTMLArea.DOM.Selection = Ext.extend(HTMLArea.DOM.Selection, {
        createRange: function () {
                var range;
                this.get();
-               if (Ext.isIE8 || Ext.isIE7 || Ext.isIE6) {
+               if (HTMLArea.isIEBeforeIE9) {
                        range = this.selection.createRange();
                } else {
                        if (Ext.isEmpty(this.selection)) {
@@ -3746,7 +3750,7 @@ HTMLArea.DOM.Selection = Ext.extend(HTMLArea.DOM.Selection, {
        selectNode: function (node, endPoint) {
                this.get();
                if (!Ext.isEmpty(this.selection)) {
-                       if (Ext.isIE8 || Ext.isIE7 || Ext.isIE6) {
+                       if (HTMLArea.isIEBeforeIE9) {
                                        // IE8/7/6 cannot set this type of selection
                                this.selectNodeContents(node, endPoint);
                        } else if (Ext.isWebKit && /^(img)$/i.test(node.nodeName)) {
@@ -3783,7 +3787,7 @@ HTMLArea.DOM.Selection = Ext.extend(HTMLArea.DOM.Selection, {
                var range;
                this.get();
                if (!Ext.isEmpty(this.selection)) {
-                       if (Ext.isIE8 || Ext.isIE7 || Ext.isIE6) {
+                       if (HTMLArea.isIEBeforeIE9) {
                                range = this.document.body.createTextRange();
                                range.moveToElementText(node);
                        } else {
@@ -3815,7 +3819,7 @@ HTMLArea.DOM.Selection = Ext.extend(HTMLArea.DOM.Selection, {
                var parentElement,
                        range;
                this.get();
-               if (Ext.isIE8 || Ext.isIE7 || Ext.isIE6) {
+               if (HTMLArea.isIEBeforeIE9) {
                        range = this.createRange();
                        switch (this.selection.type) {
                                case 'Text':
@@ -3944,7 +3948,7 @@ HTMLArea.DOM.Selection = Ext.extend(HTMLArea.DOM.Selection, {
                        var range = this.createRange();
                        var ancestors = this.getAllAncestors();
                        Ext.each(ancestors, function (ancestor) {
-                               if (Ext.isIE8 || Ext.isIE7 || Ext.isIE6) {
+                               if (HTMLArea.isIEBeforeIE9) {
                                        isFullySelected = (type !== 'Control' && ancestor.innerText == range.text) || (type === 'Control' && ancestor.innerText == range.item(0).text);
                                } else {
                                        isFullySelected = (ancestor.textContent == range.toString());
@@ -3974,7 +3978,7 @@ HTMLArea.DOM.Selection = Ext.extend(HTMLArea.DOM.Selection, {
                var range = this.createRange(),
                        parentStart,
                        parentEnd;
-               if (Ext.isIE8 || Ext.isIE7 || Ext.isIE6) {
+               if (HTMLArea.isIEBeforeIE9) {
                        if (this.getType() === 'Control') {
                                parentStart = range.item(0);
                                parentEnd = parentStart;
@@ -4029,7 +4033,7 @@ HTMLArea.DOM.Selection = Ext.extend(HTMLArea.DOM.Selection, {
        getHtml: function () {
                var range = this.createRange(),
                        html = '';
-               if (Ext.isIE8 || Ext.isIE7 || Ext.isIE6) {
+               if (HTMLArea.isIEBeforeIE9) {
                        if (this.getType() === 'Control') {
                                        // We have a controlRange collection
                                var bodyRange = this.document.body.createTextRange();
@@ -4057,7 +4061,7 @@ HTMLArea.DOM.Selection = Ext.extend(HTMLArea.DOM.Selection, {
         * @return      object          this
         */
        insertNode: function (toBeInserted) {
-               if (Ext.isIE8 || Ext.isIE7 || Ext.isIE6) {
+               if (HTMLArea.isIEBeforeIE9) {
                        this.insertHtml(toBeInserted.outerHTML);
                } else {
                        var range = this.createRange();
@@ -4077,7 +4081,7 @@ HTMLArea.DOM.Selection = Ext.extend(HTMLArea.DOM.Selection, {
         * @return      object          this
         */
        insertHtml: function (html) {
-               if (Ext.isIE8 || Ext.isIE7 || Ext.isIE6) {
+               if (HTMLArea.isIEBeforeIE9) {
                        this.get();
                        if (this.getType() === 'Control') {
                                this.selection.clear();
@@ -4138,7 +4142,7 @@ HTMLArea.DOM.Selection = Ext.extend(HTMLArea.DOM.Selection, {
         */
        handleBackSpace: function () {
                var range = this.createRange();
-               if (Ext.isIE8 || Ext.isIE7 || Ext.isIE6) {
+               if (HTMLArea.isIEBeforeIE9) {
                        if (this.getType() === 'Control') {
                                        // Deleting or backspacing on a control selection : delete the element
                                var element = this.getParentElement();
@@ -4568,7 +4572,7 @@ HTMLArea.DOM.BookMark = Ext.extend(HTMLArea.DOM.BookMark, {
         */
        get: function (range) {
                var bookMark;
-               if (Ext.isIE8 || Ext.isIE7 || Ext.isIE6) {
+               if (HTMLArea.isIEBeforeIE9) {
                                // Bookmarking will not work on control ranges
                        try {
                                bookMark = range.getBookmark();
@@ -4641,7 +4645,7 @@ HTMLArea.DOM.BookMark = Ext.extend(HTMLArea.DOM.BookMark, {
         */
        moveTo: function (bookMark) {
                var range = this.selection.createRange();
-               if (Ext.isIE8 || Ext.isIE7 || Ext.isIE6) {
+               if (HTMLArea.isIEBeforeIE9) {
                        if (bookMark) {
                                range.moveToBookmark(bookMark);
                        }
@@ -4735,7 +4739,7 @@ HTMLArea.DOM.Node = Ext.extend(HTMLArea.DOM.Node, {
         * @return      void
         */
        wrapWithInlineElement: function (element, range) {
-               if (Ext.isIE8 || Ext.isIE7 || Ext.isIE6) {
+               if (HTMLArea.isIEBeforeIE9) {
                        var nodeName = element.nodeName;
                        var bookMark = this.bookMark.get(range);
                        if (range.parentElement) {
@@ -5287,11 +5291,11 @@ HTMLArea.CSS.Parser = Ext.extend(Ext.util.Observable, {
                                this.error = 'Document.readyState not complete';
                        }
                } else {
-                       if (Ext.isIE) {
+                       if (HTMLArea.isIEBeforeIE9) {
                                try {
                                        var rules = this.editor.document.styleSheets[0].rules;
                                        var imports = this.editor.document.styleSheets[0].imports;
-                                       if (!rules.length && !imports.length) {
+                                       if (!rules.length && !imports.length && index != 1 && typeof(document.documentMode) === 'undefined') {
                                                this.cssLoaded = false;
                                                this.error = 'Empty rules and imports arrays';
                                        }
@@ -5313,11 +5317,11 @@ HTMLArea.CSS.Parser = Ext.extend(Ext.util.Observable, {
                        if (this.editor.document.styleSheets.length > 2) {
                                Ext.each(this.editor.document.styleSheets, function (styleSheet, index) {
                                        try {
-                                               if (Ext.isIE) {
+                                               if (HTMLArea.isIEBeforeIE9) {
                                                        var rules = styleSheet.rules;
                                                        var imports = styleSheet.imports;
                                                                // Default page style may contain only a comment
-                                                       if (!rules.length && !imports.length && index != 1) {
+                                                       if (!rules.length && !imports.length && index != 1 && typeof(document.documentMode) === 'undefined') {
                                                                this.cssLoaded = false;
                                                                this.error = 'Empty rules and imports arrays of styleSheets[' + index + ']';
                                                                return false;
index 13cf446..4841915 100644 (file)
@@ -177,7 +177,7 @@ HTMLArea.ContextMenu = Ext.extend(HTMLArea.Plugin, {
         */
        showMenu: function (target) {
                this.showContextItems(target);
-               if (!(Ext.isIE6 || Ext.isIE7 || Ext.isIE8)) {
+               if (!HTMLArea.isIEBeforeIE9) {
                        this.ranges = this.editor.getSelection().getRanges();
                }
                var iframeEl = this.editor.iframe.getEl();
@@ -236,7 +236,7 @@ HTMLArea.ContextMenu = Ext.extend(HTMLArea.Plugin, {
         * Handler invoked when a menu item is clicked on
         */
        onItemClick: function (item, event) {
-               if (!(Ext.isIE6 || Ext.isIE7 || Ext.isIE8)) {
+               if (!HTMLArea.isIEBeforeIE9) {
                        this.editor.getSelection().setRanges(this.ranges);
                }
                var button = this.getButton(item.getItemId());
index e88edc9..48d6648 100644 (file)
@@ -229,7 +229,7 @@ HTMLArea.TYPO3Link = Ext.extend(HTMLArea.Plugin, {
                                // Cleanup selected range
                        range = this.editor.getSelection().createRange();
                                // Clean existing anchors otherwise Mozilla may create nested anchors while IE may update existing link
-                       if (Ext.isIE8 || Ext.isIE7 || Ext.isIE6) {
+                       if (HTMLArea.isIEBeforeIE9) {
                                this.cleanAllLinks(node, range, true);
                                this.editor.getSelection().execCommand('UnLink', false, null);
                        } else {
@@ -285,7 +285,7 @@ HTMLArea.TYPO3Link = Ext.extend(HTMLArea.Plugin, {
                }
                if (HTMLArea.classesAnchorSetup) {
                        var range = this.editor.getSelection().createRange();
-                       if (!(Ext.isIE6 || Ext.isIE7 || Ext.isIE8)) {
+                       if (!HTMLArea.isIEBeforeIE9) {
                                this.cleanAllLinks(node, range, false);
                        } else {
                                this.cleanAllLinks(node, range, true);
@@ -316,7 +316,7 @@ HTMLArea.TYPO3Link = Ext.extend(HTMLArea.Plugin, {
        setLinkAttributes: function(node, range, cur_target, cur_class, cur_title, imageNode, addIconAfterLink, additionalValues) {
                if (/^a$/i.test(node.nodeName)) {
                        var nodeInRange = false;
-                       if (!(Ext.isIE6 || Ext.isIE7 || Ext.isIE8)) {
+                       if (!HTMLArea.isIEBeforeIE9) {
                                this.editor.focus();
                                nodeInRange = HTMLArea.DOM.rangeIntersectsNode(range, node);
                        } else {
@@ -347,7 +347,7 @@ HTMLArea.TYPO3Link = Ext.extend(HTMLArea.Plugin, {
                                } else {
                                        if (!Ext.isOpera) {
                                                node.removeAttribute('class');
-                                               if (Ext.isIE6 || Ext.isIE7 || Ext.isIE8) {
+                                               if (HTMLArea.isIEBeforeIE9) {
                                                        node.removeAttribute('className');
                                                }
                                        } else {
@@ -411,7 +411,7 @@ HTMLArea.TYPO3Link = Ext.extend(HTMLArea.Plugin, {
        cleanAllLinks: function(node, range, keepLinks) {
                if (/^a$/i.test(node.nodeName)) {
                        var intersection = false;
-                       if (!(Ext.isIE6 || Ext.isIE7 || Ext.isIE8)) {
+                       if (!HTMLArea.isIEBeforeIE9) {
                                this.editor.focus();
                                intersection = HTMLArea.DOM.rangeIntersectsNode(range, node);
                        } else {