From b6f3d9f8869082fd32cf9f9c94139b5b7aad3172 Mon Sep 17 00:00:00 2001 From: Stanislas Rolland <typo3@sjbr.ca> Date: Tue, 20 Nov 2007 22:48:36 +0000 Subject: [PATCH] * Feature #6769 continued: Further adjustments and workarounds to enable htmlArea RTE in Safari git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@2742 709f56b5-9817-0410-a4d7-c38de5d9e867 --- ChangeLog | 4 + typo3/sysext/rtehtmlarea/ChangeLog | 4 + .../rtehtmlarea/htmlarea/htmlarea-gecko.js | 97 ++++++++++--------- typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js | 15 ++- .../pi2/class.tx_rtehtmlarea_pi2.php | 2 +- 5 files changed, 65 insertions(+), 57 deletions(-) diff --git a/ChangeLog b/ChangeLog index e9dcc5cfba58..5b01eab66339 100755 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2007-11-20 Stanislas Rolland <stanislas.rolland@fructifor.ca> + + * Feature #6769 continued: Further adjustments and workarounds to enable htmlArea RTE in Safari + 2007-11-20 Dmitry Dulepov <dmitry@typo3.org> * Restored typo3/sysext/lang/locallang_mod_doc.xml because it was zero length and broke translations diff --git a/typo3/sysext/rtehtmlarea/ChangeLog b/typo3/sysext/rtehtmlarea/ChangeLog index 49159f0d8850..f4e127bb4746 100644 --- a/typo3/sysext/rtehtmlarea/ChangeLog +++ b/typo3/sysext/rtehtmlarea/ChangeLog @@ -1,3 +1,7 @@ +2007-11-20 Stanislas Rolland <stanislas.rolland@fructifor.ca> + + * Feature #6769 continued: Further adjustments and workarounds to enable htmlArea RTE in Safari + 2007-11-19 Stanislas Rolland <stanislas.rolland@fructifor.ca> * Feature #6769: Enable htmlArea RTE in Safari diff --git a/typo3/sysext/rtehtmlarea/htmlarea/htmlarea-gecko.js b/typo3/sysext/rtehtmlarea/htmlarea/htmlarea-gecko.js index 3095b6af6f02..4db2f57a12b0 100644 --- a/typo3/sysext/rtehtmlarea/htmlarea/htmlarea-gecko.js +++ b/typo3/sysext/rtehtmlarea/htmlarea/htmlarea-gecko.js @@ -95,6 +95,28 @@ HTMLArea.prototype._getSelection = function() { return this._iframe.contentWindow.getSelection(); }; +/* + * Empty the selection object + */ +HTMLArea.prototype.emptySelection = function(sel) { + if (HTMLArea.is_safari) { + sel.empty(); + } else { + sel.removeAllRanges(); + } +}; + +/* + * Add a range to the selection + */ +HTMLArea.prototype.addRangeToSelection = function(sel, range) { + if (HTMLArea.is_safari) { + sel.setBaseAndExtent(range.startContainer, range.startOffset, range.endContainer, range.endOffset); + } else { + sel.addRange(range); + } +}; + /* * Create a range for the current selection */ @@ -135,13 +157,8 @@ HTMLArea.prototype.selectNode = function(node,pos) { if (node.nodeType == 1 && node.tagName.toLowerCase() == "body") range.selectNodeContents(node); else range.selectNode(node); if ((typeof(pos) != "undefined")) range.collapse(pos); - if (HTMLArea.is_safari) { - sel.empty(); - sel.setBaseAndExtent(range.startContainer,range.startOffset,range.endContainer,range.endOffset); - } else { - sel.removeAllRanges(); - sel.addRange(range); - } + this.emptySelection(sel); + this.addRangeToSelection(sel, range); }; /* @@ -153,13 +170,8 @@ HTMLArea.prototype.selectNodeContents = function(node,pos) { var range = this._doc.createRange(); range.selectNodeContents(node); if ((typeof(pos) != "undefined")) range.collapse(pos); - if (HTMLArea.is_safari) { - sel.empty(); - sel.setBaseAndExtent(range.startContainer,range.startOffset,range.endContainer,range.endOffset); - } else { - sel.removeAllRanges(); - sel.addRange(range); - } + this.emptySelection(sel); + this.addRangeToSelection(sel, range); }; /* @@ -192,19 +204,11 @@ HTMLArea.prototype.getParentElement = function(sel,range) { if (typeof(range) === "undefined") { var range = this._createRange(sel); } - try { - var p = range.commonAncestorContainer; - if (!range.collapsed && range.startContainer == range.endContainer && - range.startOffset - range.endOffset <= 1 && range.startContainer.hasChildNodes()) { - p = range.startContainer.childNodes[range.startOffset]; - } - while (p.nodeType == 3) { - p = p.parentNode; - } - return p; - } catch (e) { - return this._doc.body; + var p = range.commonAncestorContainer; + while (p.nodeType == 3) { + p = p.parentNode; } + return p; }; /* @@ -246,8 +250,7 @@ HTMLArea.prototype.insertNodeAtSelection = function(toBeInserted) { node = range.startContainer, pos = range.startOffset, selnode = toBeInserted; - if (HTMLArea.is_safari) sel.empty(); - else sel.removeAllRanges(); + this.emptySelection(sel); range.deleteContents(); switch (node.nodeType) { case 3: // Node.TEXT_NODE: we have to split it at the caret position. @@ -256,8 +259,7 @@ HTMLArea.prototype.insertNodeAtSelection = function(toBeInserted) { range = this._createRange(); range.setEnd(node, pos + toBeInserted.length); range.setStart(node, pos + toBeInserted.length); - if (HTMLArea.is_safari) sel.setBaseAndExtent(range.startContainer, range.startOffset, range.endContainer, range.endOffset); - else sel.addRange(range); + this.addRangeToSelection(sel, range); } else { node = node.splitText(pos); if (toBeInserted.nodeType == 11) selnode = selnode.lastChild; @@ -345,6 +347,7 @@ HTMLArea.statusBarHandler = function (ev) { var editor = target.editor; target.blur(); editor.selectNode(target.el); + editor._statusBarTree.selected = target.el; editor.updateToolbar(true); switch (ev.type) { case "click" : @@ -426,13 +429,8 @@ HTMLArea.prototype._checkBackspace = function() { r.setStartBefore(newr); r.setEndAfter(newr); r.extractContents(); - if(HTMLArea.is_safari) { - sel.empty(); - sel.setBaseAndExtent(r.startContainer,r.startOffset,r.endContainer,r.endOffset); - } else { - sel.removeAllRanges(); - sel.addRange(r); - } + this.emptySelection(sel); + this.addRangeToSelection(sel, r); return true; } },10); @@ -442,7 +440,7 @@ HTMLArea.prototype._checkBackspace = function() { /* * Enter event handler */ -HTMLArea.prototype._checkInsertP = function(ev) { +HTMLArea.prototype._checkInsertP = function() { var editor = this; this.focusEditor(); var i, left, right, rangeClone, @@ -459,9 +457,10 @@ HTMLArea.prototype._checkInsertP = function(ev) { break; } } - if (!range.collapsed) range.deleteContents(); - if (HTMLArea.is_safari) sel.empty(); - else sel.removeAllRanges(); + if (!range.collapsed) { + range.deleteContents(); + } + this.emptySelection(sel); if (!block || /^(td|div)$/i.test(block.tagName)) { if (!block) var block = doc.body; if (/\S/.test(HTMLArea.getInnerText(block))) { @@ -475,8 +474,13 @@ HTMLArea.prototype._checkInsertP = function(ev) { left.appendChild(doc.createElement('br')); } left.normalize(); + range.setStartAfter(left); range.setEndAfter(block.lastChild); - range.surroundContents(right = doc.createElement('p')); + // Working around Safari issue: The following gives a range exception + // range.surroundContents(right = doc.createElement('p')); + right = doc.createElement('p'); + right.appendChild(range.extractContents()); + block.appendChild(right); // Remove any element created empty a = right.previousSibling; if (a && !/\S/.test(HTMLArea.getInnerText(a))) HTMLArea.removeFromParent(a); @@ -490,9 +494,9 @@ HTMLArea.prototype._checkInsertP = function(ev) { } else { range = doc.createRange(); var first = block.firstChild; - block.removeChild(first); + if (first) block.removeChild(first); block.appendChild(right = doc.createElement('p')); - right.appendChild(first); + if (first) right.appendChild(first); } range.selectNodeContents(right); } else { @@ -523,10 +527,9 @@ HTMLArea.prototype._checkInsertP = function(ev) { } } range.collapse(true); - if (HTMLArea.is_safari) sel.setBaseAndExtent(r.startContainer,r.startOffset,r.endContainer,r.endOffset); - else sel.addRange(range); + this.emptySelection(sel); + this.addRangeToSelection(sel, range); this.scrollToCaret(); - return true; }; /* diff --git a/typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js b/typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js index 66585f20f8cb..bab835f78c6b 100644 --- a/typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js +++ b/typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js @@ -2298,13 +2298,8 @@ HTMLArea.prototype.execCommand = function(cmdID, UI, param) { sel = this._getSelection(); var r = this._createRange(sel).cloneRange(); r.collapse(false); - if(HTMLArea.is_safari) { - sel.empty(); - sel.setBaseAndExtent(r.startContainer,r.startOffset,r.endContainer,r.endOffset); - } else { - sel.removeAllRanges(); - sel.addRange(r); - } + this.emptySelection(sel); + this.addRangeToSelection(sel, r); } } break; @@ -2327,7 +2322,7 @@ HTMLArea._editorEvent = function(ev) { while (owner.parentElement) { owner = owner.parentElement; } } var editor = RTEarea[owner._editorNo]["editor"]; - var keyEvent = ((HTMLArea.is_ie || HTMLArea.is_safari) && ev.type == "keydown") || (!HTMLArea.is_ie && ev.type == "keypress"); + var keyEvent = (HTMLArea.is_ie && ev.type == "keydown") || (HTMLArea.is_gecko && ev.type == "keypress"); editor.focusEditor(); if(keyEvent) { @@ -2428,10 +2423,12 @@ HTMLArea._editorEvent = function(ev) { switch (ev.keyCode) { case 13 : // KEY enter if (HTMLArea.is_gecko && !ev.shiftKey && !editor.config.disableEnterParagraphs) { - if (editor._checkInsertP(ev)) HTMLArea._stopEvent(ev); + editor._checkInsertP(); + HTMLArea._stopEvent(ev); // update the toolbar state after some time if (editor._timerToolbar) window.clearTimeout(editor._timerToolbar); editor._timerToolbar = window.setTimeout("HTMLArea.updateToolbar(" + editor._editorNumber + ");", 50); + return false; } break; case 8 : // KEY backspace diff --git a/typo3/sysext/rtehtmlarea/pi2/class.tx_rtehtmlarea_pi2.php b/typo3/sysext/rtehtmlarea/pi2/class.tx_rtehtmlarea_pi2.php index 18716336c6be..018ac48141d6 100644 --- a/typo3/sysext/rtehtmlarea/pi2/class.tx_rtehtmlarea_pi2.php +++ b/typo3/sysext/rtehtmlarea/pi2/class.tx_rtehtmlarea_pi2.php @@ -229,7 +229,7 @@ class tx_rtehtmlarea_pi2 extends tx_rtehtmlarea_base { // Preloading the pageStyle $filename = trim($this->thisConfig['contentCSS']) ? trim($this->thisConfig['contentCSS']) : 'EXT:' . $this->ID . '/htmlarea/plugins/DynamicCSS/dynamiccss.css'; $additionalCode_loadCSS = ' - <link rel="alternate stylesheet" type="text/css" href="' . $this->getFullFileName($filename) . '" />'; + <link rel="alternate stylesheet" type="text/css" href="' . $this->getFullFileName($filename) . '" title="HTMLArea RTE Content CSS" />'; // Loading the editor skin $skinFilename = trim($this->thisConfig['skin']) ? trim($this->thisConfig['skin']) : 'EXT:' . $this->ID . '/htmlarea/skins/default/htmlarea.css'; -- GitLab