[TASK] RTE: Migrate editor iframe to plain JavaScript 32/35332/3
authorStanislas Rolland <typo3@sjbr.ca>
Fri, 12 Dec 2014 00:38:34 +0000 (19:38 -0500)
committerStanislas Rolland <typo3@sjbr.ca>
Fri, 12 Dec 2014 02:05:18 +0000 (03:05 +0100)
Releases: master
Resolves: #63786
Change-Id: I3a01400a4790e173ed8e1d5410a708eedb23f63e
Reviewed-on: http://review.typo3.org/35332
Reviewed-by: Stanislas Rolland <typo3@sjbr.ca>
Tested-by: Stanislas Rolland <typo3@sjbr.ca>
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/DOM/DOM.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/DOM/Selection.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Editor/Editor.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Editor/Framework.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Editor/Iframe.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Editor/StatusBar.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Editor/Toolbar.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/ContextMenu.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/TextIndicator.js

index e9324b6..0163a3f 100644 (file)
@@ -269,7 +269,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/DOM/DOM',
                                var types = [types];
                        }
                        // Is types a non-empty array?
-                       if (types && toString.apply(types) === '[object Array]' && types.length > 0) {
+                       if (types && Object.prototype.toString.call(types) === '[object Array]' && types.length > 0) {
                                types = new RegExp( '^(' + types.join('|') + ')$', 'i');
                                while (parent && parent.nodeType === Dom.ELEMENT_NODE && !/^(body)$/i.test(parent.nodeName)) {
                                        if (types.test(parent.nodeName)) {
@@ -323,7 +323,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/DOM/DOM',
                                var allowedAttributes = [allowedAttributes];
                        }
                        // Is allowedAttributes an array?
-                       if (allowedAttributes && toString.apply(allowedAttributes) === '[object Array]') {
+                       if (allowedAttributes && Object.prototype.toString.call(allowedAttributes) === '[object Array]') {
                                for (var i = allowedAttributes.length; --i >= 0;) {
                                        value = node.getAttribute(allowedAttributes[i]);
                                        if (value) {
index 0176e70..00a78a8 100644 (file)
@@ -49,7 +49,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/DOM/Selection',
                /**
                 * Reference to the editor iframe window
                 */
-               this.window = this.editor.iframe.getEl().dom.contentWindow;
+               this.window = this.editor.iframe.getEl().contentWindow;
 
                // Set current selection
                this.get();
index 593a4e8..9e5c87c 100644 (file)
@@ -538,7 +538,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Editor',
        Editor.prototype.scrollToCaret = function () {
                if (!UserAgent.isIE) {
                        var e = this.getSelection().getParentElement(),
-                               w = this.iframe.getEl().dom.contentWindow ? this.iframe.getEl().dom.contentWindow : window,
+                               w = this.iframe.getEl().contentWindow ? this.iframe.getEl().contentWindow : window,
                                h = w.innerHeight || w.height,
                                d = this.document,
                                t = d.documentElement.scrollTop || d.body.scrollTop;
@@ -556,9 +556,8 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Editor',
                        this.iframe.startListening();
                }
                // Add unload handler
-               var iframe = this.iframe.getEl().dom;
                var self = this;
-               Event.one(iframe.contentWindow ? iframe.contentWindow : iframe.contentDocument, 'unload', function (event) { return self.onUnload(event); });
+               Event.one(this.iframe.getIframeWindow(), 'unload', function (event) { return self.onUnload(event); });
        };
 
        /**
@@ -595,8 +594,6 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Editor',
                }
                Event.off(this.textarea);
                RTEarea[this.editorId].editor = null;
-               // ExtJS is not releasing any resources when the iframe is unloaded
-               this.htmlArea.destroy();
                return true;
        };
 
index 83710d9..583d29f 100644 (file)
@@ -106,6 +106,8 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Framework',
                                }
                                Event.on(form, 'reset', function (event) { return self.onReset(event); });
                        }
+                       // Monitor editor being unloaded
+                       Event.one(this.iframe.getIframeWindow(), 'unload', function (event) { return self.onBeforeDestroy(); });
                },
 
                /**
@@ -264,7 +266,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Framework',
                 * Resize the framework components
                 */
                onFrameworkResize: function () {
-                       Dom.setSize(this.iframe.getEl().dom, { width: this.getInnerWidth(), height: this.getInnerHeight()});
+                       Dom.setSize(this.iframe.getEl(), { width: this.getInnerWidth(), height: this.getInnerHeight()});
                        Dom.setSize(this.textArea, { width: this.getInnerWidth(), height: this.getInnerHeight()});
                },
 
@@ -272,7 +274,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Framework',
                 * Adjust the height to the changing size of the statusbar when the textarea is shown
                 */
                onTextAreaShow: function () {
-                       Dom.setSize(this.iframe.getEl().dom, { height: this.getInnerHeight()});
+                       Dom.setSize(this.iframe.getEl(), { height: this.getInnerHeight()});
                        Dom.setSize(this.textArea, { width: this.getInnerWidth(), height: this.getInnerHeight()});
                },
 
@@ -284,7 +286,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Framework',
                                this.onWindowResize();
                        } else {
                                //this.iframe.setHeight(this.getInnerHeight());
-                               Dom.setSize(this.iframe.getEl().dom, { height: this.getInnerHeight()});
+                               Dom.setSize(this.iframe.getEl(), { height: this.getInnerHeight()});
                                Dom.setSize(this.textArea, { height: this.getInnerHeight()});
                        }
                },
@@ -349,8 +351,9 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Framework',
                /**
                 * Cleanup on framework destruction
                 */
-               destroy: function () {
+               onBeforeDestroy: function () {
                        Event.off(window);
+                       Event.off(this.iframe);
                        Event.off(this.textAreaContainer);
                        // Cleaning references to DOM in order to avoid IE memory leaks
                        var form = this.textArea.form;
@@ -358,12 +361,6 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Framework',
                                Event.off(form);
                                form.htmlAreaPreviousOnReset = null;
                        }
-                       // ExtJS is not releasing any resources when the iframe is unloaded
-                       this.toolbar.destroy();
-                       this.statusBar.destroy();
-                       while (this.el.firstChild) {
-                               this.el.removeChild(this.el.firstChild);
-                       }
                        if (this.resizer) {
                                Resizable.destroy(this.resizer);
                        }
index 50f583c..b0b0cc6 100644 (file)
  * The TYPO3 project - inspiring people to share!
  */
 /**
- * HTMLArea.Iframe extends Ext.BoxComponent
+ * The editor iframe
  */
 define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Iframe',
        ['TYPO3/CMS/Rtehtmlarea/HTMLArea/UserAgent/UserAgent',
        'TYPO3/CMS/Rtehtmlarea/HTMLArea/DOM/Walker',
        'TYPO3/CMS/Rtehtmlarea/HTMLArea/Util/TYPO3',
+       'TYPO3/CMS/Rtehtmlarea/HTMLArea/Util/Util',
        'TYPO3/CMS/Rtehtmlarea/HTMLArea/DOM/DOM',
        'TYPO3/CMS/Rtehtmlarea/HTMLArea/Event/Event',
        'TYPO3/CMS/Rtehtmlarea/HTMLArea/Event/KeyMap'],
-       function (UserAgent, Walker, Typo3, Dom, Event, KeyMap) {
+       function (UserAgent, Walker, Typo3, Util, Dom, Event, KeyMap) {
 
-       var Iframe = Ext.extend(Ext.BoxComponent, {
+       /**
+        * Editor iframe constructor
+        */
+       var Iframe = function (config) {
+               Util.apply(this, config);
+       };
+
+       Iframe.prototype = {
 
                /**
-                * Constructor
+                * Render the iframe (called by framework rendering)
+                *
+                * @param object container: the container into which to insert the iframe (that is the framework)
+                * @return void
                 */
-               initComponent: function () {
-                       Iframe.superclass.initComponent.call(this);
-                       this.addListener({
-                               afterrender: {
-                                       fn: this.initEventListeners,
-                                       single: true
-                               },
-                               show: {
-                                       fn: function (iframe) {
-                                               Event.trigger(iframe, 'HTMLAreaEventIframeShow');
-                                       }
-                               },
-                               beforedestroy: {
-                                       fn: this.onBeforeDestroy,
-                                       single: true
-                               }
-                       });
+               render: function (container) {
                        this.config = this.getEditor().config;
+                       this.createIframe(container);
                        this.htmlRenderer = new Walker({
                                keepComments: !this.config.htmlRemoveComments,
                                removeTags: this.config.htmlRemoveTags,
@@ -52,18 +48,30 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Iframe',
                                baseUrl: this.config.baseURL
                        });
                        if (!this.config.showStatusBar) {
-                               this.addClass('noStatusBar');
+                               Dom.addClass(this.getEl(), 'noStatusBar');
                        }
+                       this.initEventListeners();
+               },
+
+               /**
+                * Get the element to which the iframe is rendered
+                */
+               getEl: function () {
+                       return this.el;
                },
 
                /**
                 * Initialize event listeners and the document after the iframe has rendered
                 */
                initEventListeners: function () {
+                       var self = this;
                        this.initStyleChangeEventListener();
+                       // Monitor editor becoming ready
+                       var self = this;
+                       Event.one(this.getEditor(), 'HtmlAreaEventEditorReady', function (event) { Event.stopEvent(event); self.onEditorReady(); return false; });
                        if (UserAgent.isOpera) {
                                var self = this;
-                               Event.one(this.getEl().dom, 'load', function (event) { Event.stopEvent(event); self.initializeIframe(event); return false; })
+                               Event.one(iframe, 'load', function (event) { self.initializeIframe(event); return true; })
                        } else {
                                this.initializeIframe();
                        }
@@ -75,7 +83,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Iframe',
                 * In all browsers, it breaks the evaluation of the framework dimensions
                 */
                initStyleChangeEventListener: function () {
-                       if (this.isNested && UserAgent.isGecko) {
+                       if (this.isNested && !UserAgent.isWebKit) {
                                var self = this;
                                var options = {
                                        delay: 50
@@ -84,13 +92,13 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Iframe',
                                        var nestedElement = document.getElementById(this.nestedParentElements.sorted[i]);
                                        Event.on(
                                                nestedElement,
-                                               'DOMAttrModified',
+                                               UserAgent.isIEBeforeIE9 ? 'propertychange' : 'DOMAttrModified',
                                                function (event) { return self.onNestedShow(event); },
                                                options
                                        );
                                        Event.on(
                                                nestedElement.parentNode,
-                                               'DOMAttrModified',
+                                               UserAgent.isIEBeforeIE9 ? 'propertychange' : 'DOMAttrModified',
                                                function (event) { return self.onNestedShow(event); },
                                                options
                                        );
@@ -138,35 +146,39 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Iframe',
 
                /**
                 * Create the iframe element at rendering time
-                */
-               onRender: function (ct, position){
-                       // from Ext.Component
-                       if (!this.el && this.autoEl) {
-                               if (typeof this.autoEl === 'string' && this.autoEl.length > 0) {
-                                       this.el = document.createElement(this.autoEl);
-                               } else {
-                                       // ExtJS Default method will not work with iframe element
-                                       this.el = Ext.DomHelper.append(ct, this.autoEl, true);
+                *
+                * @param object container: the container into which to insert the iframe (that is the framework)
+                * @return void
+                */
+               createIframe: function (container) {
+                       if (this.autoEl && this.autoEl.tag) {
+                               this.el = document.createElement(this.autoEl.tag);
+                               if (this.autoEl.id) {
+                                       this.el.setAttribute('id', this.autoEl.id);
                                }
-                               if (!this.el.id) {
-                                       this.el.id = this.getId();
+                               if (this.autoEl.cls) {
+                                       this.el.setAttribute('class', this.autoEl.cls);
                                }
-                       }
-                       // from Ext.BoxComponent
-                       if (this.resizeEl){
-                               this.resizeEl = Ext.get(this.resizeEl);
-                       }
-                       if (this.positionEl){
-                               this.positionEl = Ext.get(this.positionEl);
+                               if (this.autoEl.src) {
+                                       this.el.setAttribute('src', this.autoEl.src);
+                               }
+                               this.el = container.appendChild(this.el);
                        }
                },
 
                /**
+                * Get the content window of the iframe
+                */
+               getIframeWindow: function () {
+                       return this.el.contentWindow ? this.el.contentWindow : this.el.contentDocument;
+               },
+
+               /**
                 * Proceed to build the iframe document head and ensure style sheets are available after the iframe document becomes available
                 */
                initializeIframe: function () {
                        var self = this;
-                       var iframe = this.getEl().dom;
+                       var iframe = this.getEl();
                        // All browsers
                        if (!iframe || (!iframe.contentWindow && !iframe.contentDocument)) {
                                window.setTimeout(function () {
@@ -207,6 +219,21 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Iframe',
                },
 
                /**
+                * Show the iframe
+                */
+               show: function () {
+                       this.getEl().style.display = '';
+                       Event.trigger(this, 'HTMLAreaEventIframeShow');
+               },
+
+               /**
+                * Hide the iframe
+                */
+               hide: function () {
+                       this.getEl().style.display = 'none';
+               },
+
+               /**
                 * Create one of each of the configured custom tags so they are properly parsed by the walker when using IE
                 * See: http://en.wikipedia.org/wiki/HTML5_Shiv
                 *
@@ -260,29 +287,32 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Iframe',
                                this.getEditor().appendToLog('HTMLArea.Iframe', 'createHead', 'Content CSS set to: ' + link.href, 'info');
                        }
                },
-               /*
+
+               /**
                 * Focus on the iframe
                 */
                focus: function () {
                        try {
                                if (UserAgent.isWebKit) {
-                                       this.getEl().dom.focus();
-                               } else {
-                                       this.getEl().dom.contentWindow.focus();
+                                       this.getEl().focus();
                                }
+                               this.getEl().contentWindow.focus();
                        } catch(e) { }
                },
-               /*
+
+               /**
                 * Flag indicating whether the framework is inside a tab or inline element that may be hidden
                 * Should be set in config
                 */
                isNested: false,
-               /*
+
+               /**
                 * All nested tabs and inline levels in the sorting order they were applied
                 * Should be set in config
                 */
                nestedParentElements: {},
-               /*
+
+               /**
                 * Set designMode
                 *
                 * @param       boolean         on: if true set designMode to on, otherwise set to off
@@ -315,7 +345,8 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Iframe',
                                }
                        }
                },
-               /*
+
+               /**
                 * Set editing mode options (if we can... raises exception in Firefox 3)
                 *
                 * @return      void
@@ -354,12 +385,10 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Iframe',
                        window.setTimeout(function () {
                                var styleEvent = true;
                                // In older versions of Gecko attrName is not set and refering to it causes a non-catchable crash
-                               if ((UserAgent.isGecko && navigator.productSub > 2007112700) || UserAgent.isOpera) {
-                                       //styleEvent = (event.browserEvent.attrName == 'style') || (event.browserEvent.attrName == 'className');
-                                       styleEvent = (event.attrName == 'style') || (event.attrName == 'className');
-                               } else if (UserAgent.isIE) {
-                                       //styleEvent = (event.browserEvent.propertyName == 'style.display');
-                                       styleEvent = (event.propertyName == 'style.display');
+                               if ((UserAgent.isGecko && navigator.productSub > 2007112700) || UserAgent.isOpera || (UserAgent.isIE && !UserAgent.isIEBeforeIE9)) {
+                                       styleEvent = (event.originalEvent.attrName === 'style') || (event.originalEvent.attrName === 'className') || (event.originalEvent.attrName === 'class');
+                               } else if (UserAgent.isIEBeforeIE9) {
+                                       styleEvent = (event.originalEvent.propertyName === 'style.display');
                                }
                                if (styleEvent && (self.nestedParentElements.sorted.indexOf(target.id) != -1 || self.nestedParentElements.sorted.indexOf(target.id.replace('_div', '_fields')) != -1)) {
                                        // Check if all container nested elements are displayed
@@ -368,7 +397,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Iframe',
                                                        if (UserAgent.isGecko) {
                                                                self.setDesignMode(true);
                                                        }
-                                                       self.fireEvent('show');
+                                                       Event.trigger(self, 'HTMLAreaEventIframeShow');
                                                } else {
                                                        self.framework.textAreaContainer.fireEvent('show');
                                                }
@@ -733,6 +762,15 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Iframe',
                },
 
                /**
+                * When the editor becomes ready
+                */
+               onEditorReady: function () {
+                       var self = this;
+                       // Monitor editor being unloaded
+                       Event.one(this.getIframeWindow(), 'unload', function (event) { return self.onBeforeDestroy(); });
+               },
+
+               /**
                 * Cleanup
                 */
                onBeforeDestroy: function () {
@@ -745,16 +783,17 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Iframe',
                                }
                        }
                        Event.off(this);
-                       Event.off(this.getEl().dom);
+                       Event.off(this.getEl());
                        Event.off(this.document.body);
                        Event.off(this.document.documentElement);
                        // Cleaning references to DOM in order to avoid IE memory leaks
                        this.document = null;
                        this.getEditor().document = null;
-                       Ext.destroy(this.autoEl, this.el, this.resizeEl, this.positionEl);
+                       this.el = null;
+                       delete this.el;
                        return true;
                }
-       });
+       };
 
        return Iframe;
 
index 8e67f35..0fde1a7 100644 (file)
@@ -32,7 +32,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/StatusBar',
                /**
                 * Render the status bar (called by framework rendering)
                 *
-                * @param object container: the container into which to insert the status bar (that is the farmework
+                * @param object container: the container into which to insert the status bar (that is the framework)
                 * @return void
                 */
                render: function (container) {
@@ -60,7 +60,9 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/StatusBar',
                        // Monitor editor changing mode
                        Event.on(this.getEditor(), 'HTMLAreaEventModeChange', function (event, mode) { Event.stopEvent(event); self.onModeChange(mode); return false; });
                        // Monitor word count change
-                       Event.on(this.framework.iframe, 'HTMLAreaEventWordCountChange', function (event, delay) { Event.stopEvent(event); self.onWordCountChange(delay); return false; });                      
+                       Event.on(this.framework.iframe, 'HTMLAreaEventWordCountChange', function (event, delay) { Event.stopEvent(event); self.onWordCountChange(delay); return false; });
+                       // Monitor editor being unloaded
+                       Event.one(this.framework.iframe.getIframeWindow(), 'unload', function (event) { return self.onBeforeDestroy(); });
                },
 
                /**
@@ -120,17 +122,14 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/StatusBar',
                 * Clear the status bar tree
                 */
                clear: function () {
-                       var node = this.statusBarTree.firstChild;
-                       while (node) {
+                       var node;
+                       while (node = this.statusBarTree.firstChild) {
                                if (/^(a)$/i.test(node.nodeName)) {
                                        Event.off(node);
-                                       var extNode = Ext.get(node);
-                                       Ext.QuickTips.unregister(extNode);
-                                       extNode.dom = null;
+                                       node.removeAttribute('ext:qtitle');
+                                       node.removeAttribute('ext:qtip');
                                }
-                               var nextNode = node.nextSibling;
                                Dom.removeFromParent(node);
-                               var node = nextNode;
                        }
                        this.setSelection(null);
                },
@@ -337,13 +336,16 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/StatusBar',
                /**
                 * Cleanup
                 */
-               destroy: function() {
+               onBeforeDestroy: function() {
                        this.clear();
-                       while (this.el.firstChild) {
-                               this.el.removeChild(this.el.firstChild);
+                       while (node = this.el.firstChild) {
+                               this.el.removeChild(node);
                        }
                        this.statusBarTree = null;
                        this.statusBarWordCount = null;
+                       this.el = null;
+                       delete this.el;
+                       return true;
                }
        };
 
index dc45186..4727860 100644 (file)
@@ -41,15 +41,9 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Toolbar',
                 * Initialize listeners
                 */
                initEventListeners: function () {
-                       this.addListener({
-                               beforedestroy: {
-                                       fn: this.onBeforeDestroy,
-                                       single: true
-                               }
-                       });
                        // Monitor editor becoming ready
                        var self = this;
-                       Event.one(this.getEditor(), 'HtmlAreaEventEditorReady', function (event) { Event.stopEvent(event); self.update(); return false; });
+                       Event.one(this.getEditor(), 'HtmlAreaEventEditorReady', function (event) { Event.stopEvent(event); self.onEditorReady(); return false; });
                },
 
                /**
@@ -181,6 +175,16 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Toolbar',
                },
 
                /**
+                * When the editor becomes ready
+                */
+               onEditorReady: function () {
+                       var self = this;
+                       // Monitor editor being unloaded
+                       Event.one(this.framework.iframe.getIframeWindow(), 'unload', function (event) { return self.onBeforeDestroy(); });
+                       this.update();
+               },
+
+               /**
                 * Cleanup
                 */
                onBeforeDestroy: function () {
index 7d219ba..6729e6f 100644 (file)
@@ -85,8 +85,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/ContextMenu',
                        // Monitor contextmenu clicks on the iframe
                        Event.on(this.editor.document.documentElement, 'contextmenu', function (event) { return self.show(event, event.target); });
                        // Monitor editor being unloaded
-                       var iframe = this.editor.iframe.getEl().dom;
-                       Event.one(iframe.contentWindow ? iframe.contentWindow : iframe.contentDocument, 'unload', function (event) { self.onBeforeDestroy(event); return  true; });
+                       Event.one(this.editor.iframe.getIframeWindow(), 'unload', function (event) { self.onBeforeDestroy(event); return  true; });
                },
 
                /**
@@ -192,9 +191,10 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/ContextMenu',
                        if (!UserAgent.isIEBeforeIE9) {
                                this.ranges = this.editor.getSelection().getRanges();
                        }
-                       var iframeEl = this.editor.iframe.getEl();
-                               // Show the context menu
-                       this.menu.showAt([Ext.fly(target).getX() + iframeEl.getX(), Ext.fly(target).getY() + iframeEl.getY()]);
+                       // Show the context menu
+                       var targetPosition = Dom.getPosition(target);
+                       var iframePosition = Dom.getPosition(this.editor.iframe.getEl());
+                       this.menu.showAt([targetPosition.x + iframePosition.x, targetPosition.y + iframePosition.y]);
                },
 
                /**
@@ -223,9 +223,9 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/ContextMenu',
                                                if (/^(html|body)$/i.test(target.nodeName)) {
                                                        this.deleteTarget = null;
                                                } else if (/^(table|thead|tbody|tr|td|th|tfoot)$/i.test(target.nodeName)) {
-                                                       this.deleteTarget = Ext.fly(target).findParent('table');
+                                                       this.deleteTarget = Dom.getFirstAncestorOfType(target, 'table');
                                                } else if (/^(ul|ol|dl|li|dd|dt)$/i.test(target.nodeName)) {
-                                                       this.deleteTarget = Ext.fly(target).findParent('ul') || Ext.fly(target).findParent('ol') || Ext.fly(target).findParent('dl');
+                                                       this.deleteTarget = Dom.getFirstAncestorOfType(target, ['ul', 'ol', 'dl']);
                                                }
                                                if (this.deleteTarget) {
                                                        menuItem.setVisible(true);
index a98b264..bfcd6b5 100644 (file)
@@ -111,7 +111,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/TextIndicator',
                                } catch (e) { }
                                // queryCommandValue does not work in Gecko
                                if (UserAgent.isGecko) {
-                                       var computedStyle = editor.iframe.getEl().dom.contentWindow.getComputedStyle(editor.getSelection().getParentElement(), null);
+                                       var computedStyle = editor.iframe.getIframeWindow().getComputedStyle(editor.getSelection().getParentElement(), null);
                                        if (computedStyle) {
                                                style.color = computedStyle.getPropertyValue('color');
                                                style.backgroundColor = computedStyle.getPropertyValue('background-color');