Index: typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js	(révision 7230)
+++ typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js	(copie de travail)
@@ -3081,7 +3081,49 @@
 	}
 	return null;
 };
-
+/*
+ * Get the node whose contents are currently fully selected
+ *
+ * @param 	array		selection: the current selection
+ * @param 	array		range: the range of the current selection
+ * @param 	array		ancestors: the array of ancestors node of the current selection
+ *
+ * @return	object		the fully selected node, if any, null otherwise
+ */
+HTMLArea.Editor.prototype.getFullySelectedNode = function (selection, range, ancestors) {
+	var node, fullNodeSelected = false;
+	if (!selection) {
+		var selection = this._getSelection();
+	}
+	if (!this._selectionEmpty(selection)) {
+		if (!range) {
+			var range = this._createRange(selection);
+		}
+		if (!ancestors) {
+			var ancestors = this.getAllAncestors();
+		}
+		Ext.each(ancestors, function (ancestor) {
+			if (Ext.isIE) {
+				fullNodeSelected = (selection.type !== 'Control' && ancestor.innerText == range.text) || (selection.type === 'Control' && ancestor.innerText == range.item(0).text);
+			} else {
+				fullNodeSelected = (ancestor.textContent == range.toString());
+			}
+			if (fullNodeSelected) {
+				node = ancestor;
+				return false;
+			}
+		});
+			// Working around bug with WebKit selection
+		if (Ext.isWebKit && !fullNodeSelected) {
+			var statusBarSelection = this.statusBar ? this.statusBar.getSelection() : null;
+			if (statusBarSelection && statusBarSelection.textContent == range.toString()) {
+				fullNodeSelected = true;
+				node = statusBarSelection;
+			}
+		}
+	}
+	return fullNodeSelected ? node : null;
+};
 /***************************************************
  *  Category: EVENT HANDLERS
  ***************************************************/
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/InlineElements/inline-elements.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/InlineElements/inline-elements.js	(révision 7230)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/InlineElements/inline-elements.js	(copie de travail)
@@ -224,13 +224,13 @@
 	 * This function applies to the selection the markup chosen in the drop-down list or corresponding to the button pressed
 	 */
 	applyInlineElement : function (editor, element) {
-		editor.focusEditor();
+		editor.focus();
 		var selection = editor._getSelection();
 		var range = editor._createRange(selection);
 		var parent = editor.getParentElement(selection, range);
 		var ancestors = editor.getAllAncestors();
 		var elementIsAncestor = false;
-		var selectionEmpty = editor._selectionEmpty(selection);
+		var fullNodeSelected = false;
 		if (HTMLArea.is_ie) {
 			var bookmark = editor.getBookmark(range);
 		}
@@ -242,30 +242,13 @@
 				break;
 			}
 		}
-		if (!selectionEmpty) {
-			var statusBarSelection = (editor.statusBar ? editor.statusBar.getSelection() : null);
-				// The selection is not empty.
-			for (var i = 0; i < ancestors.length; ++i) {
-				fullNodeSelected = (HTMLArea.is_ie && ((selection.type !== "Control" && ancestors[i].innerText === range.text) || (selection.type === "Control" && ancestors[i].innerText === range.item(0).text)))
-							|| (HTMLArea.is_gecko && ((statusBarSelection === ancestors[i] && ancestors[i].textContent === range.toString()) || (!statusBarSelection && ancestors[i].textContent === range.toString())));
-				if (fullNodeSelected) {
-					if (!HTMLArea.isBlockElement(ancestors[i])) {
-						parent = ancestors[i];
-					}
-					break;
-				}
+		if (!editor._selectionEmpty(selection)) {
+			var fullySelectedNode = editor.getFullySelectedNode(selection, range, ancestors);
+			fullNodeSelected = this.isInlineElement(fullySelectedNode);
+			if (fullNodeSelected) {
+				parent = fullySelectedNode;
 			}
-				// Working around bug in Safari selectNodeContents
-			if (!fullNodeSelected && HTMLArea.is_safari && statusBarSelection && this.isInlineElement(statusBarSelection) && statusBarSelection.textContent === range.toString()) {
-				fullNodeSelected = true;
-				parent = statusBarSelection;
-			}
-			
-			var fullNodeTextSelected = (HTMLArea.is_gecko && parent.textContent === range.toString())
-							|| (HTMLArea.is_ie && parent.innerText === range.text);
-			if (fullNodeTextSelected && elementIsAncestor) {
-				fullNodeSelected = true;
-			}
+			var statusBarSelection = (editor.statusBar ? editor.statusBar.getSelection() : null);
 			if (element !== "none" && !(fullNodeSelected && elementIsAncestor)) {
 					// Add markup
 				var newElement = editor._doc.createElement(element);
@@ -274,17 +257,17 @@
 				}
 				if (HTMLArea.is_gecko) {
 					if (fullNodeSelected && statusBarSelection) {
-						if (HTMLArea.is_safari) {
-							editor.selectNode(parent);
-							selection = editor._getSelection();
-							range = editor._createRange(selection);
+						if (Ext.isWebKit) {
+							newElement = parent.parentNode.insertBefore(newElement, statusBarSelection);
+							newElement.appendChild(statusBarSelection);
+							newElement.normalize();
 						} else {
 							range.selectNode(parent);
+							editor.wrapWithInlineElement(newElement, selection, range);
 						}
-					}
-					editor.wrapWithInlineElement(newElement, selection, range);
-					if (fullNodeSelected && statusBarSelection && !HTMLArea.is_safari) {
 						editor.selectNodeContents(newElement.lastChild, false);
+					} else {
+						editor.wrapWithInlineElement(newElement, selection, range);
 					}
 					range.detach();
 				} else {
@@ -313,7 +296,11 @@
 					if (elementIsAncestor) {
 						parent = ancestors[elementAncestorIndex];
 					}
+					var parentElement = parent.parentNode;
 					editor.removeMarkup(parent);
+					if (Ext.isWebKit && this.isInlineElement(parentElement)) {
+						editor.selectNodeContents(parentElement, false);
+					}
 				}
 			}
 		} else {
@@ -378,37 +365,26 @@
 		}
 		return newElement;
 	},
-	
 	/*
 	* This function gets called when the toolbar is updated
 	*/
 	onUpdateToolbar : function (button, mode, selectionEmpty, ancestors, endPointsInSameBlock) {
 		var editor = this.editor;
 		if (mode === "wysiwyg" && editor.isEditable()) {
-			var tagName = false, fullNodeSelected = false;
-			var sel = editor._getSelection();
-			var range = editor._createRange(sel);
-			var parent = editor.getParentElement(sel);
+			var 	tagName = false,
+				fullNodeSelected = false;
+			var selection = editor._getSelection();
+			var range = editor._createRange(selection);
+			var parent = editor.getParentElement(selection);
 			if (parent && !HTMLArea.isBlockElement(parent)) {
 				tagName = parent.nodeName.toLowerCase();
 			}
 			if (!selectionEmpty) {
-				var statusBarSelection = editor.statusBar ? editor.statusBar.getSelection() : null;
-				for (var i = 0, n = ancestors.length; i < n; ++i) {
-					fullNodeSelected = (statusBarSelection === ancestors[i])
-						&& ((HTMLArea.is_gecko && ancestors[i].textContent === range.toString()) || (HTMLArea.is_ie && ((sel.type !== "Control" && ancestors[i].innerText === range.text) || (sel.type === "Control" && ancestors[i].innerText === range.item(0).text))));
-					if (fullNodeSelected) {
-						if (!HTMLArea.isBlockElement(ancestors[i])) {
-							tagName = ancestors[i].nodeName.toLowerCase();
-						}
-						break;
-					}
+				var fullySelectedNode = editor.getFullySelectedNode(selection, range, ancestors);
+				fullNodeSelected = this.isInlineElement(fullySelectedNode);
+				if (fullNodeSelected) {
+					tagName = fullySelectedNode.nodeName.toLowerCase();
 				}
-					// Working around bug in Safari selectNodeContents
-				if (!fullNodeSelected && HTMLArea.is_safari && statusBarSelection && this.isInlineElement(statusBarSelection) && statusBarSelection.textContent === range.toString()) {
-					fullNodeSelected = true;
-					tagName = statusBarSelection.nodeName.toLowerCase();
-				}
 			}
 			var selectionInInlineElement = tagName && this.REInlineElements.test(tagName);
 			var disabled = !endPointsInSameBlock || (fullNodeSelected && !tagName) || (selectionEmpty && !selectionInInlineElement);
@@ -426,13 +402,12 @@
 							return true;
 						}
 					}, this);
-					button.setInactive(!activeButton);
+					button.setInactive(!activeButton && this.convertBtn[button.itemId] !== tagName);
 					button.setDisabled(disabled);
 					break;
 			}
 		}
 	},
-	
 	/*
 	* This function updates the drop-down list of inline elemenents
 	*/
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/SelectFont/select-font.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/SelectFont/select-font.js	(révision 7230)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/SelectFont/select-font.js	(copie de travail)
@@ -63,21 +63,19 @@
 				this.allowedAttributes.push("className");
 			}
 		}
-
 		/*
 		 * Registering plugin "About" information
 		 */
 		var pluginInformation = {
-			version		: "1.0",
-			developer	: "Stanislas Rolland",
-			developerUrl	: "http://www.sjbr.ca/",
-			copyrightOwner	: "Stanislas Rolland",
-			sponsor		: "SJBR",
-			sponsorUrl	: "http://www.sjbr.ca/",
-			license		: "GPL"
+			version		: '2.0',
+			developer	: 'Stanislas Rolland',
+			developerUrl	: 'http://www.sjbr.ca/',
+			copyrightOwner	: 'Stanislas Rolland',
+			sponsor		: 'SJBR',
+			sponsorUrl	: 'http://www.sjbr.ca/',
+			license		: 'GPL'
 		};
 		this.registerPluginInformation(pluginInformation);
-		
 		/*
 		 * Registering the dropdowns
 		 */
@@ -138,19 +136,29 @@
 		FontName	: "font-family",
 		FontSize	: "font-size"
 	},
-	 
 	/*
 	 * This function gets called when some font style or font size was selected from the dropdown lists
 	 */
-	onChange : function (editor, combo, record, index) {
+	onChange: function (editor, combo, record, index) {
 		var param = combo.getValue();
-		editor.focusEditor();
-		var selection = editor._getSelection(),
-			range = editor._createRange(selection),
-			statusBarSelection = editor.statusBar ? editor.statusBar.getSelection() : null,
-			element;
-		if (editor._selectionEmpty(selection)) {
-			element = editor.getParentElement(selection, range);
+		editor.focus();
+		var 	element,
+			fullNodeSelected = false;
+		var selection = editor._getSelection();
+		var range = editor._createRange(selection);
+		var parent = editor.getParentElement(selection, range);
+		var selectionEmpty = editor._selectionEmpty(selection);
+		var statusBarSelection = editor.statusBar ? editor.statusBar.getSelection() : null;
+		if (!selectionEmpty) {
+			var ancestors = editor.getAllAncestors();
+			var fullySelectedNode = editor.getFullySelectedNode(selection, range, ancestors);
+			if (fullySelectedNode) {
+				fullNodeSelected = true;
+				parent = fullySelectedNode;
+			}
+		}
+		if (selectionEmpty || fullNodeSelected) {
+			element = parent;
 				// Set the style attribute
 			this.setStyle(element, combo.itemId, param);
 				// Remove the span tag if it has no more attribute
@@ -177,7 +185,6 @@
 		}
 		return false;
 	},
-
 	/*
 	 * This function sets the style attribute on the element
 	 *
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/TYPO3Color/typo3color.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/TYPO3Color/typo3color.js	(révision 7230)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/TYPO3Color/typo3color.js	(copie de travail)
@@ -30,51 +30,47 @@
  * TYPO3 SVN ID: $Id$
  */
 TYPO3Color = HTMLArea.Plugin.extend({
-	
-	constructor : function(editor, pluginName) {
+	constructor: function(editor, pluginName) {
 		this.base(editor, pluginName);
 	},
-	
 	/*
 	 * This function gets called by the class constructor
 	 */
-	configurePlugin : function(editor) {
-		
+	configurePlugin: function(editor) {
 		this.buttonsConfiguration = this.editorConfiguration.buttons;
 		this.colorsConfiguration = this.editorConfiguration.colors;
 		this.disableColorPicker = this.editorConfiguration.disableColorPicker;
-
 			// Coloring will use the style attribute
 		if (this.editor.plugins.TextStyle && this.editor.plugins.TextStyle.instance) {
-			this.editor.plugins.TextStyle.instance.addAllowedAttribute("style");
+			this.editor.plugins.TextStyle.instance.addAllowedAttribute('style');
 			this.allowedAttributes = this.editor.plugins.TextStyle.instance.allowedAttributes;
-		}			
+		}
 		if (this.editor.plugins.InlineElements && this.editor.plugins.InlineElements.instance) {
-			this.editor.plugins.InlineElements.instance.addAllowedAttribute("style");
+			this.editor.plugins.InlineElements.instance.addAllowedAttribute('style');
 			if (!this.allowedAllowedAttributes) {
 				this.allowedAttributes = this.editor.plugins.InlineElements.instance.allowedAttributes;
 			}
 		}
 		if (this.editor.plugins.BlockElements && this.editor.plugins.BlockElements.instance) {
-			this.editor.plugins.BlockElements.instance.addAllowedAttribute("style");
+			this.editor.plugins.BlockElements.instance.addAllowedAttribute('style');
 		}
 		if (!this.allowedAttributes) {
-			this.allowedAttributes = new Array("id", "title", "lang", "xml:lang", "dir", "class", "style");
+			this.allowedAttributes = new Array('id', 'title', 'lang', 'xml:lang', 'dir', 'class', 'style');
 			if (HTMLArea.is_ie) {
-				this.allowedAttributes.push("className");
+				this.allowedAttributes.push('className');
 			}
 		}
 		/*
 		 * Registering plugin "About" information
 		 */
 		var pluginInformation = {
-			version		: "4.0",
-			developer	: "Stanislas Rolland",
-			developerUrl	: "http://www.sjbr.ca/",
-			copyrightOwner	: "Stanislas Rolland",
-			sponsor		: "SJBR",
-			sponsorUrl	: "http://www.sjbr.ca/",
-			license		: "GPL"
+			version		: '4.0',
+			developer	: 'Stanislas Rolland',
+			developerUrl	: 'http://www.sjbr.ca/',
+			copyrightOwner	: 'Stanislas Rolland',
+			sponsor		: 'SJBR',
+			sponsorUrl	: 'http://www.sjbr.ca/',
+			license		: 'GPL'
 		};
 		this.registerPluginInformation(pluginInformation);
 		/*
@@ -87,7 +83,7 @@
 			var buttonConfiguration = {
 				id		: buttonId,
 				tooltip		: this.localize(buttonId),
-				action		: "onButtonPress",
+				action		: 'onButtonPress',
 				hotKey		: (this.buttonsConfiguration[button[1]] ? this.buttonsConfiguration[button[1]].hotKey : null),
 				dialog		: true
 			};
@@ -342,11 +338,24 @@
 		this.restoreSelection();
 		var buttonId = this.dialog.arguments.buttonId;
 		var color = '#' + this.dialog.find('itemId', 'color')[0].getValue();
+		this.editor.focus();
+		var 	element,
+			fullNodeSelected = false;
 		var selection = this.editor._getSelection();
+		var range = this.editor._createRange(selection);
+		var parent = this.editor.getParentElement(selection, range);
+		var selectionEmpty = this.editor._selectionEmpty(selection);
 		var statusBarSelection = this.editor.statusBar ? this.editor.statusBar.getSelection() : null;
-		var range = this.editor._createRange(selection);
-		if (this.editor._selectionEmpty(selection)) {
-			var element = this.editor.getParentElement(selection, range);
+		if (!selectionEmpty) {
+			var ancestors = this.editor.getAllAncestors();
+			var fullySelectedNode = this.editor.getFullySelectedNode(selection, range, ancestors);
+			if (fullySelectedNode) {
+				fullNodeSelected = true;
+				parent = fullySelectedNode;
+			}
+		}
+		if (selectionEmpty || fullNodeSelected) {
+			element = parent;
 				// Set the color in the style attribute
 			element.style[this.styleProperty[buttonId]] = color;
 				// Remove the span tag if it has no more attribute
