[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 21:21:22 +0000 (23:21 +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 and avoid
reliance on order.

Change-Id: I7a1ecf4ad0a4343311ce5aea4edcb893c58750e4
Releases: 4.5, 4.6, 4.7, 6.0
Resolves: #38574
Reviewed-on: http://review.typo3.org/12560
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..7e8e6aa 100644 (file)
@@ -56,6 +56,10 @@ Ext.apply(HTMLArea, {
        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                                    *
         ***************************************************/
        localize: function (label, plural) {
@@ -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,7 +5291,7 @@ 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;
@@ -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 && styleSheet.href.indexOf('defaultPageStyle') === -1) {
                                                                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 {