Index: typo3/sysext/rtehtmlarea/class.tx_rtehtmlarea_base.php
===================================================================
--- typo3/sysext/rtehtmlarea/class.tx_rtehtmlarea_base.php	(revision 2734)
+++ typo3/sysext/rtehtmlarea/class.tx_rtehtmlarea_base.php	(working copy)
@@ -55,7 +55,7 @@
 			),
 			'safari' => array (
 				1 => array (
-					'version' => 312
+					'version' => 523
 				)
 			),
 			'opera' => array (
@@ -72,7 +72,7 @@
 	
 		// Hide toolbar buttons not implemented in client browsers
 	var $hideButtonsFromClient = array (
-		'safari'	=>	array('strikethrough', 'line', 'orderedlist', 'unorderedlist'),
+		'safari'	=>	array('paste'),
 		'opera'		=>	array('copy', 'cut', 'paste'),
  		);
 	
@@ -195,13 +195,13 @@
 		);
 	
 	var $defaultFontSizes_safari = array(
-		'1'	=>	'xx-small',
-		'2'	=>	'x-small',
-		'3'	=>	'small',
-		'4'	=>	'medium',
-		'5'	=>	'large',
-		'6'	=>	'x-large',
-		'7'	=>	'xx-large',
+		'1'	=>	'x-small (10px)',
+		'2'	=>	'small (13px)',
+		'3'	=>	'medium (16px)',
+		'4'	=>	'large (18px)',
+		'5'	=>	'x-large (24px)',
+		'6'	=>	'xx-large (32px)',
+		'7'	=>	'xxx-large (48px)',
 		);
 	
 	var $pluginList = 'TableOperations, ContextMenu, SpellChecker, SelectColor, TYPO3Browsers, InsertSmiley, FindReplace, RemoveFormat, CharacterMap, QuickTag, DynamicCSS, UserElements, Acronym, TYPO3HtmlParser';
@@ -528,7 +528,7 @@
 				// Preloading the pageStyle
 			$filename = trim($this->thisConfig['contentCSS']) ? trim($this->thisConfig['contentCSS']) : 'EXT:' . $this->ID . '/htmlarea/plugins/DynamicCSS/dynamiccss.css';
 			$this->TCEform->additionalCode_pre['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';
@@ -1211,7 +1211,7 @@
 		
 		foreach ($this->defaultFontSizes as $FontSizeItem => $FontSizeLabel) {
 			if ($this->client['BROWSER'] == 'safari') {
-				$HTMLAreaFontSizes[$this->defaultFontSizes_safari[$FontSizeItem]] = $FontSizeLabel;
+				$HTMLAreaFontSizes[$FontSizeItem] = $this->defaultFontSizes_safari[$FontSizeItem];
 			} else {
 				$HTMLAreaFontSizes[$FontSizeItem] = $FontSizeLabel;
 			}
@@ -1220,13 +1220,7 @@
 			$hideFontSizes =  t3lib_div::trimExplode(',', $this->cleanList($this->thisConfig['hideFontSizes']), 1);
 			foreach ($hideFontSizes as $item)  {
 				if ($HTMLAreaFontSizes[strtolower($item)]) {
-					if ($this->client['BROWSER'] == 'safari') {
-						unset($HTMLAreaFontSizes[$this->defaultFontSizes_safari[strtolower($item)]]);
-					} else {
-						unset($HTMLAreaFontSizes[strtolower($item)]);
-					}
-				} else {
-					
+					unset($HTMLAreaFontSizes[strtolower($item)]);
 				}
 			}
 		}
@@ -1966,7 +1960,7 @@
 			$bInfo['BROWSER']= 'msie';
 		} elseif (strstr($useragent,'Gecko/'))	{
 			$bInfo['BROWSER']='gecko';
-		} elseif (strstr($useragent,'Safari/') &&  $TYPO3_CONF_VARS['EXTCONF']['rtehtmlarea']['safari_test'] == 1) {
+		} elseif (strstr($useragent,'Safari/')) {
 			$bInfo['BROWSER']='safari';
 		} elseif (strstr($useragent,'Mozilla/4')) {
 			$bInfo['BROWSER']='net';
Index: typo3/sysext/rtehtmlarea/ext_localconf.php
===================================================================
--- typo3/sysext/rtehtmlarea/ext_localconf.php	(revision 2734)
+++ typo3/sysext/rtehtmlarea/ext_localconf.php	(working copy)
@@ -77,7 +77,6 @@
 if ($_EXTCONF['plainImageMaxWidth']) $TYPO3_CONF_VARS['EXTCONF'][$_EXTKEY]['plainImageMaxWidth'] = intval($_EXTCONF['plainImageMaxWidth']);
 if ($_EXTCONF['plainImageMaxHeight']) $TYPO3_CONF_VARS['EXTCONF'][$_EXTKEY]['plainImageMaxHeight'] = intval($_EXTCONF['plainImageMaxHeight']);
 
-//$TYPO3_CONF_VARS['EXTCONF']['rtehtmlarea']['safari_test'] = 0;
 $TYPO3_CONF_VARS['EXTCONF'][$_EXTKEY]['enableInOpera9'] = $_EXTCONF['enableInOpera9'] ? $_EXTCONF['enableInOpera9'] : 0;
 
 	// Add default RTE transformation configuration
Index: typo3/sysext/rtehtmlarea/htmlarea/htmlarea-gecko.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/htmlarea-gecko.js	(revision 2734)
+++ typo3/sysext/rtehtmlarea/htmlarea/htmlarea-gecko.js	(working copy)
@@ -92,7 +92,6 @@
  * Get the current selection object
  */
 HTMLArea.prototype._getSelection = function() {
-	if (HTMLArea.is_safari) return window.getSelection();
 	return this._iframe.contentWindow.getSelection();
 };
 
@@ -102,21 +101,21 @@
 HTMLArea.prototype._createRange = function(sel) {
 	if (HTMLArea.is_safari) {
 		var range = this._doc.createRange();
-		if (typeof(sel) == "undefined") return range;
-		switch (sel.type) {
-			case "Range": 
-				range.setStart(sel.baseNode,sel.baseOffset);
-				range.setEnd(sel.extentNode,sel.extentOffset);
-				break;
-			case "Caret":
-				range.setStart(sel.baseNode,sel.baseOffset);
-				range.setEnd(sel.baseNode,sel.baseOffset);
-				break;
-			case "None":
-				range.setStart(this._doc.body,0);
-				range.setEnd(this._doc.body,0);
+		if (typeof(sel) == "undefined") {
+			return range;
+		} else if (sel.baseNode == null) {
+			range.setStart(this._doc.body,0);
+			range.setEnd(this._doc.body,0);
+			return range;
+		} else {
+			range.setStart(sel.baseNode, sel.baseOffset);
+			range.setEnd(sel.extentNode, sel.extentOffset);
+			if (range.collapsed != sel.isCollapsed) {
+				range.setStart(sel.extentNode, sel.extentOffset);
+				range.setEnd(sel.baseNode, sel.baseOffset);
+			}
+			return range;
 		}
-		return range;
 	}
 	if (typeof(sel) == "undefined") return this._doc.createRange();
 	try {
@@ -169,9 +168,11 @@
 HTMLArea.prototype.getSelectedHTML = function() {
 	var sel = this._getSelection();
 	var range = this._createRange(sel);
-	var cloneContents = "";
-	try {cloneContents = range.cloneContents();} catch(e) { }
-	return (cloneContents ? HTMLArea.getHTML(cloneContents,false,this) : "");
+	var cloneContents = range.cloneContents();
+	if (!cloneContents) {
+		cloneContents = this._doc.createDocumentFragment();
+	}
+	return HTMLArea.getHTML(cloneContents, false, this);
 };
 
 /*
@@ -185,14 +186,21 @@
  * Get the deepest node that contains both endpoints of the current selection.
  */
 HTMLArea.prototype.getParentElement = function(sel,range) {
-	if(!sel) var sel = this._getSelection();
-	if (typeof(range) == "undefined") var range = this._createRange(sel);
+	if (!sel) {
+		var sel = this._getSelection();
+	}
+	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())
+		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;}
+		}
+		while (p.nodeType == 3) {
+			p = p.parentNode;
+		}
 		return p;
 	} catch (e) {
 		return this._doc.body;
Index: typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js	(revision 2734)
+++ typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js	(working copy)
@@ -1031,12 +1031,12 @@
 	if (!this._iframe || (!this._iframe.contentWindow && !this._iframe.contentDocument)) {
 		this._initIframeTimer = window.setTimeout("HTMLArea.initIframe(" + this._editorNumber + ");", 50);
 		return false;
-	} else if (this._iframe.contentWindow) {
+	} else if (this._iframe.contentWindow && !HTMLArea.is_safari) {
 		if (!this._iframe.contentWindow.document || !this._iframe.contentWindow.document.documentElement) {
 			this._initIframeTimer = window.setTimeout("HTMLArea.initIframe(" + this._editorNumber + ");", 50);
 			return false;
 		}
-	} else if (!this._iframe.contentDocument.documentElement) {
+	} else if (!this._iframe.contentDocument.documentElement || !this._iframe.contentDocument.body) {
 		this._initIframeTimer = window.setTimeout("HTMLArea.initIframe(" + this._editorNumber + ");", 50);
 		return false;
 	}
@@ -1141,9 +1141,17 @@
 
 		// Set contents editable
 	if (docWellFormed) {
-		if (HTMLArea.is_gecko && !HTMLArea.is_safari && !HTMLArea.is_opera && !this._initEditMode()) return false;
-		if (HTMLArea.is_opera) doc.designMode = "on";
-		if (HTMLArea.is_ie || HTMLArea.is_safari) doc.body.contentEditable = true;
+		if (HTMLArea.is_gecko && !HTMLArea.is_safari && !HTMLArea.is_opera && !this._initEditMode()) {
+			return false;
+		}
+		if (HTMLArea.is_ie || HTMLArea.is_safari) {
+			doc.body.contentEditable = true;
+		}
+		if (HTMLArea.is_opera || HTMLArea.is_safari) {
+			doc.designMode = "on";
+			if (this._doc.queryCommandEnabled("insertbronreturn")) this._doc.execCommand("insertbronreturn", false, this.config.disableEnterParagraphs);
+			if (this._doc.queryCommandEnabled("styleWithCSS")) this._doc.execCommand("styleWithCSS", false, this.config.useCSS);
+		}
 		if (HTMLArea.is_ie) doc.selection.empty();
 		this._editMode = "wysiwyg";
 		if (doc.body.contentEditable || doc.designMode == "on") HTMLArea._appendToLog("[HTMLArea::initIframe]: Design mode successfully set.");
@@ -1274,7 +1282,7 @@
 			}
 			this._textArea.style.display = "none";
 			this._iframe.style.display = "block";
-			if(HTMLArea.is_gecko && !HTMLArea.is_safari && !HTMLArea.is_opera) this._doc.designMode = "on";
+			if (HTMLArea.is_gecko && !HTMLArea.is_safari && !HTMLArea.is_opera) this._doc.designMode = "on";
 			if(this.config.statusBar) {
 				this._statusBar.innerHTML = "";
 				this._statusBar.appendChild(this._statusBarTree);
@@ -1290,7 +1298,7 @@
 		default:
 			return false;
 	}
-	if (!(mode == "docnotwellformedmode")) this.focusEditor();
+	if (mode !== "docnotwellformedmode") this.focusEditor();
 	for (var pluginId in this.plugins) {
 		if (this.plugins.hasOwnProperty(pluginId)) {
 			var pluginInstance = this.plugins[pluginId].instance;
@@ -1513,7 +1521,7 @@
 		owner = owner.parentElement;
 	}
 		// if we dropped an image dragged from the TYPO3 Browser, let's close the browser window
-	if (typeof(browserWin) != "undefined") browserWin.close();
+	if (typeof(browserWin) != "undefined" && browserWin.close) browserWin.close();
 	window.setTimeout("HTMLArea.wordCleanLater(" + owner._editorNo + ", true);", 250);
 };
 
@@ -1528,9 +1536,14 @@
 HTMLArea.prototype.focusEditor = function() {
 	switch (this._editMode) {
 		case "wysiwyg" :
-			try { 
-				if (HTMLArea.is_safari || HTMLArea.is_opera) this._doc.focus();
-					else this._iframe.contentWindow.focus();
+			try {
+				if (HTMLArea.is_safari) {
+					this._iframe.focus();
+				} else if (HTMLArea.is_opera) {
+					this._doc.focus();
+				} else {
+					this._iframe.contentWindow.focus();
+				}
 			} catch(e) { };
 			break;
 		case "textmode":
@@ -1623,10 +1636,11 @@
 HTMLArea.prototype.updateToolbar = function(noStatus) {
 	var doc = this._doc,
 		text = (this._editMode == "textmode"),
-		selection = this.hasSelectedText(),
+		selection = false,
 		ancestors = null, cls = new Array(),
 		txt, txtClass, i, inContext, match, matchAny, k, j, n, commandState;
 	if(!text) {
+		selection = this.hasSelectedText();
 		ancestors = this.getAllAncestors();
 		if(this.config.statusBar && !noStatus) {
 				// Unhook previous events handlers
@@ -1721,7 +1735,7 @@
 				case "FontName":
 				case "FontSize":
 					if(!text) try {
-						var value = ("" + doc.queryCommandValue(cmd)).toLowerCase();
+						var value = ("" + doc.queryCommandValue(cmd)).trim().toLowerCase().replace(/\'/g, "");
 						if(!value) {
 							document.getElementById(btn.elementId).selectedIndex = 0;
 							break;
@@ -1731,7 +1745,9 @@
 						k = 0;
 						for (var j in options) {
 							if (options.hasOwnProperty(j)) {
-								if((j.toLowerCase() == value) || (options[j].substr(0, value.length).toLowerCase() == value)) {
+								if ((j.toLowerCase().indexOf(value) !== -1)
+										|| (options[j].trim().substr(0, value.length).toLowerCase() == value)
+										|| ((cmd === "FontName") && (options[j].toLowerCase().indexOf(value) !== -1))) {
 									document.getElementById(btn.elementId).selectedIndex = k;
 									throw "ok";
 								}
@@ -1742,19 +1758,21 @@
 					} catch(e) {}
 					break;
 				case "FormatBlock":
-					var blocks = [ ];
-					for (var j in this.config['FormatBlock']) {
-						if (this.config['FormatBlock'].hasOwnProperty(j)) {
-							blocks[blocks.length] = this.config['FormatBlock'][j];
+					if (!text) {
+						var blocks = [ ];
+						for (var j in this.config['FormatBlock']) {
+							if (this.config['FormatBlock'].hasOwnProperty(j)) {
+								blocks[blocks.length] = this.config['FormatBlock'][j];
+							}
 						}
-					}
-					var deepestAncestor = this._getFirstAncestor(this._getSelection(), blocks);
-					if(deepestAncestor) {
-						for(var x= 0; x < blocks.length; x++) {
-							if(blocks[x].toLowerCase() == deepestAncestor.tagName.toLowerCase()) document.getElementById(btn.elementId).selectedIndex = x;
+						var deepestAncestor = this._getFirstAncestor(this._getSelection(), blocks);
+						if(deepestAncestor) {
+							for(var x= 0; x < blocks.length; x++) {
+								if(blocks[x].toLowerCase() == deepestAncestor.tagName.toLowerCase()) document.getElementById(btn.elementId).selectedIndex = x;
+							}
+						} else {
+							document.getElementById(btn.elementId).selectedIndex = 0;
 						}
-					} else {
-						document.getElementById(btn.elementId).selectedIndex = 0;
 					}
 					break;
 				case "TextIndicator":
@@ -1778,9 +1796,16 @@
 				case "HtmlMode": btn.state("active", text); break;
 				case "LeftToRight":
 				case "RightToLeft":
-					var el = this.getParentElement();
-					while (el && !HTMLArea.isBlockElement(el)) { el = el.parentNode; }
-					if (el) btn.state("active",(el.style.direction == ((cmd == "RightToLeft") ? "rtl" : "ltr")));
+					if (!text) {
+						var el = this.getParentElement();
+						while (el && !HTMLArea.isBlockElement(el)) { el = el.parentNode; }
+						if (el) btn.state("active",(el.style.direction == ((cmd == "RightToLeft") ? "rtl" : "ltr")));
+						break;
+					}
+				case "Paste":
+					if(!text) {
+						btn.state("enabled", doc.queryCommandEnabled('Paste'));
+					}
 					break;
 				case "JustifyLeft":
 				case "JustifyCenter":
@@ -1887,7 +1912,7 @@
 HTMLArea.prototype.getAllAncestors = function() {
 	var p = this.getParentElement();
 	var a = [];
-	while (p && (p.nodeType == 1) && (p.tagName.toLowerCase() != 'body')) {
+	while (p && (p.nodeType === 1) && (p.nodeName.toLowerCase() !== "body")) {
 		a.push(p);
 		p = p.parentNode;
 	}
@@ -2228,7 +2253,7 @@
 	    case "Copy"		:
 	    case "Paste"	:
 		try {
-			this._doc.execCommand(cmdID,false,null);
+			this._doc.execCommand(cmdID, false, null);
 			if (cmdID == "Paste" && this.config.cleanWordOnPaste) HTMLArea._wordClean(this, this._doc.body);
 		} catch (e) {
 			if (HTMLArea.is_gecko && !HTMLArea.is_safari && !HTMLArea.is_opera) this._mozillaPasteException(cmdID, UI, param);
@@ -2460,9 +2485,13 @@
 HTMLArea.prototype.getHTML = function() {
 	switch (this._editMode) {
 		case "wysiwyg":
-			if(!this.config.fullPage) { return HTMLArea.getHTML(this._doc.body,false,this); }
-				else { return this.doctype + "\n" + HTMLArea.getHTML(this._doc.documentElement,true,this); }
-		case "textmode": return this._textArea.value;
+			if (!this.config.fullPage) {
+				return HTMLArea.getHTML(this._doc.body, false, this);
+			} else {
+				return this.doctype + "\n" + HTMLArea.getHTML(this._doc.documentElement,true,this);
+			}
+		case "textmode":
+			return this._textArea.value;
 	}
 	return false;
 };
@@ -2679,7 +2708,7 @@
  * Wrapper catches a Mozilla-Exception with non well-formed html source code.
  */
 HTMLArea.getHTML = function(root, outputRoot, editor){
-	try { 
+	try {
 		return HTMLArea.getHTMLWrapper(root,outputRoot,editor); 
 	} catch(e) {
 		HTMLArea._appendToLog("The HTML document is not well-formed.");
