Index: typo3/sysext/rtehtmlarea/extensions/BlockElements/class.tx_rtehtmlarea_blockelements.php
===================================================================
--- typo3/sysext/rtehtmlarea/extensions/BlockElements/class.tx_rtehtmlarea_blockelements.php	(révision 6632)
+++ typo3/sysext/rtehtmlarea/extensions/BlockElements/class.tx_rtehtmlarea_blockelements.php	(copie de travail)
@@ -98,6 +98,7 @@
 			}
 				// Default block elements
 			$hideItems = array();
+			$addItems = array();
 			$restrictTo = array('*');
 			$blockElementsOrder = $this->defaultBlockElementsOrder;
 			$prefixLabelWithTag = false;
@@ -109,6 +110,10 @@
 				if ($this->thisConfig['buttons.']['formatblock.']['removeItems']) {
 					$hideItems =  t3lib_div::trimExplode(',', $this->htmlAreaRTE->cleanList(t3lib_div::strtolower($this->thisConfig['buttons.']['formatblock.']['removeItems'])), 1);
 				}
+					// Adding elements
+				if ($this->thisConfig['buttons.']['formatblock.']['addItems']) {
+					$addItems =  t3lib_div::trimExplode(',', $this->htmlAreaRTE->cleanList(t3lib_div::strtolower($this->thisConfig['buttons.']['formatblock.']['addItems'])), 1);
+				}
 					// Restriction clause
 				if ($this->thisConfig['buttons.']['formatblock.']['restrictToItems']) {
 					$restrictTo =  t3lib_div::trimExplode(',', $this->htmlAreaRTE->cleanList('none,'.t3lib_div::strtolower($this->thisConfig['buttons.']['formatblock.']['restrictToItems'])), 1);
@@ -124,8 +129,10 @@
 			if ($this->thisConfig['hidePStyleItems']) {
 				$hideItems = array_merge($hideItems, t3lib_div::trimExplode(',', $this->htmlAreaRTE->cleanList(t3lib_div::strtolower($this->thisConfig['hidePStyleItems'])), 1));
 			}
+				// Adding custom items
+			$blockElementsOrder = array_merge(t3lib_div::trimExplode(',', $this->htmlAreaRTE->cleanList($blockElementsOrder), 1), $addItems);
 				// Applying User TSConfig restriction
-			$blockElementsOrder = array_diff(t3lib_div::trimExplode(',', $this->htmlAreaRTE->cleanList($blockElementsOrder), 1), $hideItems);
+			$blockElementsOrder = array_diff($blockElementsOrder, $hideItems);
 			if (!in_array('*', $restrictTo)) {
 				$blockElementsOrder = array_intersect($blockElementsOrder, $restrictTo);
 			}
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/BlockElements/block-elements.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/BlockElements/block-elements.js	(révision 6632)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/BlockElements/block-elements.js	(copie de travail)
@@ -74,12 +74,39 @@
 			this.addAllowedAttribute("className");
 		}
 		this.indentedList = null;
+			// Standard block formating items
+		var standardElements = new Array("address", "blockquote", "div", "h1", "h2", "h3", "h4", "h5", "h6", "p", "pre");
+		this.standardBlockElements = new RegExp( "^(" + standardElements.join("|") + ")$", "i");
+			// Process block formating customization configuration
+		this.formatBlockItems = {};
+		if (this.buttonsConfiguration
+			&& this.buttonsConfiguration.formatblock
+			&& this.buttonsConfiguration.formatblock.items) {
+				this.formatBlockItems = this.buttonsConfiguration.formatblock.items;
+		}
+			// Build lists of mutually exclusive class names
+		for (var tagName in this.formatBlockItems) {
+			if (this.formatBlockItems.hasOwnProperty(tagName) && this.formatBlockItems[tagName].tagName && this.formatBlockItems[tagName].addClass) {
+				if (!this.formatBlockItems[this.formatBlockItems[tagName].tagName]) {
+					this.formatBlockItems[this.formatBlockItems[tagName].tagName] = {};
+				}
+				if (!this.formatBlockItems[this.formatBlockItems[tagName].tagName].classList) {
+					this.formatBlockItems[this.formatBlockItems[tagName].tagName].classList = new Array();
+				}
+				this.formatBlockItems[this.formatBlockItems[tagName].tagName].classList.push(this.formatBlockItems[tagName].addClass);
+			}
+		}
+		for (var tagName in this.formatBlockItems) {
+			if (this.formatBlockItems.hasOwnProperty(tagName) && this.formatBlockItems[tagName].classList) {
+				this.formatBlockItems[tagName].classList = new RegExp( "^(" + this.formatBlockItems[tagName].classList.join("|") + ")$");
+			}
+		}
 		
 		/*
 		 * Registering plugin "About" information
 		 */
 		var pluginInformation = {
-			version		: "1.2",
+			version		: "1.3",
 			developer	: "Stanislas Rolland",
 			developerUrl	: "http://www.sjbr.ca/",
 			copyrightOwner	: "Stanislas Rolland",
@@ -214,30 +241,43 @@
 	},
 	
 	applyBlockElement : function(buttonId, blockElement) {
-		switch (blockElement) {
-			case "blockquote" :
-				this.onButtonPress(this.editor, "Blockquote");
-				break;
-			case "div"     :
-			case "address" :
-			case "none"    :
-				this.onButtonPress(this.editor, blockElement);
-				break;
-			default	:
-				var element = blockElement;
-				if (HTMLArea.is_ie) {
-					element = "<" + element + ">";
-				}
-				this.editor.focusEditor();
-				if (HTMLArea.is_safari && !this.editor._doc.body.hasChildNodes()) {
-					this.editor._doc.body.appendChild((this.editor._doc.createElement("br")));
-				}
-				try {
-					this.editor._doc.execCommand(buttonId, false, element);
-				} catch(e) {
-					this.appendToLog("applyBlockElement", e + "\n\nby execCommand(" + buttonId + ");");
-				}
+		var tagName = blockElement;
+		var className = null;
+		if (this.formatBlockItems[tagName]) {
+			if (this.formatBlockItems[tagName].addClass) {
+				className = this.formatBlockItems[tagName].addClass;
+			}
+			if (this.formatBlockItems[tagName].tagName) {
+				tagName = this.formatBlockItems[tagName].tagName;
+			}
 		}
+		if (this.standardBlockElements.test(tagName) || tagName == "none") {
+			switch (tagName) {
+				case "blockquote" :
+					this.onButtonPress(this.editor, "Blockquote", null, className);
+					break;
+				case "div"     :
+				case "address" :
+				case "none"    :
+					this.onButtonPress(this.editor, tagName, null, className);
+					break;
+				default	:
+					var element = tagName;
+					if (HTMLArea.is_ie) {
+						element = "<" + element + ">";
+					}
+					this.editor.focusEditor();
+					if (HTMLArea.is_safari && !this.editor._doc.body.hasChildNodes()) {
+						this.editor._doc.body.appendChild((this.editor._doc.createElement("br")));
+					}
+					try {
+						this.editor._doc.execCommand(buttonId, false, element);
+					} catch(e) {
+						this.appendToLog("applyBlockElement", e + "\n\nby execCommand(" + buttonId + ");");
+					}
+					this.addClassOnBlockElements(tagName, className);
+			}
+		}
 	},
 	
 	/*
@@ -246,10 +286,11 @@
 	 * @param	object		editor: the editor instance
 	 * @param	string		id: the button id or the key
 	 * @param	object		target: the target element of the contextmenu event, when invoked from the context menu
+	 * @param	string		className: the className to be assigned to the element
 	 *
 	 * @return	boolean		false if action is completed
 	 */
-	onButtonPress : function (editor, id, target) {
+	onButtonPress : function (editor, id, target, className) {
 			// Could be a button or its hotkey
 		var buttonId = this.translateHotKey(id);
 		buttonId = buttonId ? buttonId : id;
@@ -466,14 +507,14 @@
 				}
 				if (!commandState) {
 					var bookmark = this.editor.getBookmark(range);
-					var newBlock = this.wrapSelectionInBlockElement("blockquote", null, null, true);
+					var newBlock = this.wrapSelectionInBlockElement("blockquote", className, null, true);
 					this.editor.selectRange(this.editor.moveToBookmark(bookmark));
 				}
 				break;
 			case "address" :
 			case "div"     :
 				var bookmark = this.editor.getBookmark(range);
-				var newBlock = this.wrapSelectionInBlockElement(buttonId, null, null, true);
+				var newBlock = this.wrapSelectionInBlockElement(buttonId, className, null, true);
 				this.editor.selectRange(this.editor.moveToBookmark(bookmark));
 				break;
 			case "JustifyLeft"   :
@@ -595,7 +636,7 @@
 	/*
 	 * This function adds a class attribute on blocks sibling of the block containing the start container of the selection
 	 */
-	addClassOnBlockElements : function(buttonId) {
+	addClassOnBlockElements : function(buttonId, className) {
 		var selection = this.editor._getSelection();
 		var endBlocks = this.editor.getEndBlocks(selection);
 		var startAncestors = this.getBlockAncestors(endBlocks.start);
@@ -627,6 +668,12 @@
 						this.toggleAlignmentClass(block, buttonId);
 						break;
 					default :
+						if (this.standardBlockElements.test(buttonId.toLowerCase()) && buttonId.toLowerCase() == block.nodeName.toLowerCase()) {
+							this.cleanClasses(block);
+							if (className) {
+								HTMLArea._addClass(block, className);
+							}
+						}
 						break;
 				}
 			}
@@ -921,6 +968,30 @@
 	},
 	
 	/*
+	 * This function removes any disallowed class or mutually exclusive classes from the class attribute of the node
+	 */
+	cleanClasses : function(node) {
+		var classNames = node.className.trim().split(" ");
+		var nodeName = node.nodeName.toLowerCase();
+		for (var i = classNames.length; --i >= 0;) {
+			if (!HTMLArea.reservedClassNames.test(classNames[i])) {
+				if (this.tags && this.tags[nodeName] && this.tags[nodeName].allowedClasses) {
+					if (!this.tags[nodeName].allowedClasses.test(classNames[i])) {
+						HTMLArea._removeClass(node, classNames[i]);
+					}
+				} else if (this.tags && this.tags.all && this.tags.all.allowedClasses) {
+					if (!this.tags.all.allowedClasses.test(classNames[i])) {
+						HTMLArea._removeClass(node, classNames[i]);
+					}
+				}
+				if (this.formatBlockItems[nodeName] && this.formatBlockItems[nodeName].classList && this.formatBlockItems[nodeName].classList.test(classNames[i])) {
+					HTMLArea._removeClass(node, classNames[i]);
+				}
+			}
+		}
+	},
+	
+	/*
 	 * This function gets called when the toolbar is updated
 	 */
 	onUpdateToolbar : function () {
@@ -1034,8 +1105,8 @@
 	},
 	
 	/*
-	* This function updates the drop-down list of block elemenents
-	*/
+	 * This function updates the drop-down list of block elements
+	 */
 	updateDropDown : function(dropDownConfiguration, deepestBlockAncestor, startAncestor) {
 		
 		var select = document.getElementById(this.editor._toolbarObjects[dropDownConfiguration.id].elementId);
@@ -1051,13 +1122,24 @@
 		if (deepestBlockAncestor) {
 			var nodeName = deepestBlockAncestor.nodeName.toLowerCase();
 			for (i = options.length; --i >= 0;) {
-				if (nodeName === options[i].value.toLowerCase()) {
+				var item = this.formatBlockItems[options[i].value];
+				if (item && item.tagName == nodeName && item.addClass && HTMLArea._hasClass(deepestBlockAncestor, item.addClass)) {
 					options[i].selected = true;
 					select.selectedIndex = i;
 					options[0].text = this.localize("Remove block");
 					break;
 				}
 			}
+			if (!select.selectedIndex) {
+				for (i = options.length; --i >= 0;) {
+					if (nodeName === options[i].value.toLowerCase()) {
+						options[i].selected = true;
+						select.selectedIndex = i;
+						options[0].text = this.localize("Remove block");
+						break;
+					}
+				}
+			}
 		}
 	},
 	
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/DefinitionList/definition-list.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/DefinitionList/definition-list.js	(révision 6632)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/DefinitionList/definition-list.js	(copie de travail)
@@ -51,12 +51,14 @@
 		this.useAlignAttribute = parentPlugin.useAlignAttribute;
 		this.allowedBlockElements = parentPlugin.allowedBlockElements;
 		this.indentedList = null;
+		this.standardBlockElements = parentPlugin.standardBlockElements;
+		this.formatBlockItems = parentPlugin.formatBlockItems;
 		
 		/*
 		 * Registering plugin "About" information
 		 */
 		var pluginInformation = {
-			version		: "0.4",
+			version		: "1.0",
 			developer	: "Stanislas Rolland",
 			developerUrl	: "http://www.sjbr.ca/",
 			copyrightOwner	: "Stanislas Rolland",
@@ -102,10 +104,11 @@
 	 * @param	object		editor: the editor instance
 	 * @param	string		id: the button id or the key
 	 * @param	object		target: the target element of the contextmenu event, when invoked from the context menu
+	 * @param	string		className: the className to be assigned to the element
 	 *
 	 * @return	boolean		false if action is completed
 	 */
-	onButtonPress : function (editor, id, target) {
+	onButtonPress : function (editor, id, target, className) {
 			// Could be a button or its hotkey
 		var buttonId = this.translateHotKey(id);
 		buttonId = buttonId ? buttonId : id;
@@ -126,14 +129,14 @@
 				if (/^(dd|dt)$/i.test(parentElement.nodeName) && this.indentDefinitionList(parentElement, range)) {
 					break;
 				} else {
-					this.base(editor, id, target);
+					this.base(editor, id, target, className);
 				}
 				break;
 			case "Outdent" :
 				if (/^(dt)$/i.test(parentElement.nodeName) && this.outdentDefinitionList(selection, range)) {
 					break;
 				} else {
-					this.base(editor, id, target);
+					this.base(editor, id, target, className);
 				}
 				break;
 			case "DefinitionList":
@@ -147,7 +150,7 @@
 				this.editor.selectRange(this.editor.moveToBookmark(bookmark));
 				break;
 			default:
-				this.base(editor, id, target);
+				this.base(editor, id, target, className);
 		}
 		return false;
 	},
