Index: t3lib/class.t3lib_tceforms.php
===================================================================
--- t3lib/class.t3lib_tceforms.php	(Revision 2190)
+++ t3lib/class.t3lib_tceforms.php	(Arbeitskopie)
@@ -285,7 +285,7 @@
 	var $requiredElements=array();				// Used to register the min and max number of elements for selectorboxes where that apply (in the "group" type for instance)
 	var $renderDepth=0;							// Keeps track of the rendering depth of nested records.
 	var $savedSchemes=array();					// Color scheme buffer.
-	var $dynTabLevelStack = array();			// holds tab dividers which were cascaded, required for RTE&IRRE
+	var $dynNestedStack = array();				// holds the path an element is nested in (e.g. required for RTEhtmlarea)
 
 		// Internal, registers for user defined functions etc.
 	var $additionalCode_pre = array();			// Additional HTML code, printed before the form.
@@ -497,7 +497,6 @@
 					if (strstr($itemList, '--div--') !== false && $this->enableTabMenu && $TCA[$table]['ctrl']['dividers2tabs']) {
 						$tabIdentString = 'TCEforms:'.$table.':'.$row['uid'];
 						$tabIdentStringMD5 = $GLOBALS['TBE_TEMPLATE']->getDynTabMenuId('TCEforms:'.$table.':'.$row['uid']);
-						$this->dynTabLevelStack[$tabIdentStringMD5] = 1;
 					}
 
 						// Explode the field list and possibly rearrange the order of the fields, if configured for
@@ -551,14 +550,21 @@
 
 									if ($this->enableTabMenu && $TCA[$table]['ctrl']['dividers2tabs'])	{
 										$this->wrapBorder($out_array[$out_sheet],$out_pointer);
+											// Remove last tab entry from the dynNestedStack:
 										$out_sheet++;
-											// remember what sheet we're currently in
-										$this->dynTabLevelStack[$tabIdentStringMD5] = $out_sheet+1;
+											// Remove the previous sheet from stack (if any):
+										$this->popFromDynNestedStack('tab', $tabIdentStringMD5.'-'.($out_sheet));
+											// Remember on which sheet we're currently working:
+										$this->pushToDynNestedStack('tab', $tabIdentStringMD5.'-'.($out_sheet+1));
 										$out_array[$out_sheet] = array();
 										$out_array_meta[$out_sheet]['title'] = $this->sL($parts[1]);
 									}
 								} else {	// Setting alternative title for "General" tab if "--div--" is the very first element.
 									$out_array_meta[$out_sheet]['title'] = $this->sL($parts[1]);
+										// Only add the first tab to the dynNestedStack if there are more tabs:
+									if (strpos($itemList, '--div--', strlen($fieldInfo))) {
+										$this->pushToDynNestedStack('tab', $tabIdentStringMD5.'-1');
+									}
 								}
 							} elseif($theField=='--palette--')	{
 								if ($parts[2] && !isset($this->palettesRendered[$this->renderDepth][$table][$parts[2]]))	{
@@ -627,8 +633,8 @@
 				);
 			}
 
-				// unset the current level of tab menus
-			unset($this->dynTabLevelStack[$tabIdentStringMD5]);
+				// Unset the current level of tab menus:
+			$this->popFromDynNestedStack('tab', $tabIdentStringMD5.'-'.($out_sheet+1));
 
 			return '
 				<tr>
@@ -5428,19 +5434,70 @@
 	}
 	
 	/**
-	 * Get a list, depending on $this->dynTabLevelStack, that has the information
-	 * in which tab (--div--) fields are inserted.
+	 * Push a new element to the dynNestedStack. Thus, every object know, if it's
+	 * nested in a tab or IRRE level and in which order this was processed.
 	 *
-	 * @param	string		$appendString: String to append for each item
-	 * @return	string		A list of cascaded tab divs, like "DTM-2e8791854a-1,DTM-f3c79a0523-4"
+	 * @param	string		$type: Type of the level, e.g. "tab" or "inline"
+	 * @param	string		$ident: Identifier of the level
+	 * @return	void
 	 */
-	function getDynTabLevelState($appendString = '') {
-		$levels = array();
-		foreach ($this->dynTabLevelStack as $tabIdent => $divId) {
-			$levels[] = $tabIdent.'-'.$divId.$appendString;
+	function pushToDynNestedStack($type, $ident) {
+		$this->dynNestedStack[] = array($type, $ident);
+	}
+
+	/**
+	 * Remove an element from the dynNestedStack. If $type and $ident
+	 * are set, the last element will only be removed, if it matches
+	 * what is expected to be removed.
+	 * 
+	 * @param	string		$type: Type of the level, e.g. "tab" or "inline"
+	 * @param	string		$ident: Identifier of the level
+	 * @return	void
+	 */
+	function popFromDynNestedStack($type=null, $ident=null) {
+		if ($type!=null && $ident!=null) {
+			$last = end($this->dynNestedStack);
+			if ($type==$last[0] && $ident==$last[1]) {
+				array_pop($this->dynNestedStack);
+			}
+		} else {
+			array_pop($this->dynNestedStack);
 		}
-		return implode(',', $levels);
 	}
+
+	/**
+	 * Get the dynNestedStack as associative array.
+	 * It has the keys raw, tab, inline and sorted.
+	 * The key "sorted" contains the levels in the sorting order they have been applied.
+	 *
+	 * @param	boolean		$json: Return a JSON string instead of an array
+	 * @param	string		$tabSuffix: Add a suffix (e.g. "-DIV") to each tab level
+	 * @param	string		$tabSuffix: Add a suffix to each inline level
+	 * @return	mixed		Returns an associative array (default), if $json is true, it will be returned as JSON string.
+	 */
+	function getDynNestedStack($json=false, $tabSuffix='', $inlineSuffix='') {
+		$tab = array();
+		$inline = array();
+		$sorted = array();
+		foreach ($this->dynNestedStack as $level) {
+			if ($level[0]=='tab') {
+				$tab[] = $level[1].$tabSuffix;
+				$sorted[] = $level[1].$tabSuffix;
+			} elseif ($level[0]=='inline') {
+				$inline[] = $level[1].$inlineSuffix;
+				$sorted[] = $level[1].$inlineSuffix;
+			}
+		}
+		$result = array(
+			// 'raw' => $this->dynNestedStack,
+			'tab' => $tab,
+			'inline' => $inline,
+			'sorted' => $sorted,
+			// 'tabSuffix' => $tabSuffix,
+			// 'inlineSuffix' => $inlineSuffix,
+		);
+		return ($json ? $this->inline->getJSON($result) : $result);
+	}
 }
 
 
Index: t3lib/class.t3lib_tceforms_inline.php
===================================================================
--- t3lib/class.t3lib_tceforms_inline.php	(Revision 2190)
+++ t3lib/class.t3lib_tceforms_inline.php	(Arbeitskopie)
@@ -1095,6 +1095,8 @@
 			'config' => $config,
 		);
 		$this->updateStructureNames();
+			// Put the current level also to the dynNestedStack of TCEforms:
+		$this->fObj->pushToDynNestedStack('inline', $this->inlineNames['object']);
 	}
 
 
@@ -1108,6 +1110,8 @@
 			$popItem = array_pop($this->inlineStructure['stable']);
 			$this->updateStructureNames();
 		}
+			// Remove the current level also from the dynNestedStack of TCEforms:
+		$this->fObj->popFromDynNestedStack();
 		return $popItem;
 	}
 
@@ -1732,7 +1736,7 @@
 	 * @return	integer		A pixel value for the margin of each new inline level.
 	 */
 	function getLevelMargin() {
-		$margin = $this->inlineStyles['margin-right'];
+		$margin = ($this->inlineStyles['margin-right']+1)*2;
 		return $margin;
 	}
  }
Index: typo3/sysext/rtehtmlarea/htmlarea/htmlarea-gecko.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/htmlarea-gecko.js	(Revision 2190)
+++ typo3/sysext/rtehtmlarea/htmlarea/htmlarea-gecko.js	(Arbeitskopie)
@@ -43,25 +43,23 @@
 HTMLArea.prototype._initEditMode = function () {
 		// We can't set designMode when we are in a hidden TYPO3 tab
 		// Then we will set it when the tab comes in the front.
-	var inTYPO3Tab = false;
-	var DTMDiv = this._textArea;
-	while (DTMDiv && (DTMDiv.nodeType == 1) && (DTMDiv.tagName.toLowerCase() != "body")) {
-		if (DTMDiv.tagName.toLowerCase() == "div" && DTMDiv.id.indexOf("DTM-") != -1 && DTMDiv.id.indexOf("-DIV") != -1 && DTMDiv.className == "c-tablayer") {
-			inTYPO3Tab = true;
-			break;
-		} else {
-			DTMDiv = DTMDiv.parentNode;
-		}
+	var isNested = false;
+	var allDisplayed = true;
+	
+	if (this.nested.sorted && this.nested.sorted.length) {
+		isNested = true;
+		allDisplayed = HTMLArea.allElementsAreDisplayed(this.nested.sorted);
 	}
+
 	if (!HTMLArea.is_wamcom) {
 		try {
-			if (!(inTYPO3Tab && DTMDiv.style.display == "none")) this._doc.designMode = "on";
+			if (!isNested || allDisplayed) this._doc.designMode = "on";
 		} catch(e) { }
 	} else {
 		try { 
 			this._doc.designMode = "on"; 
 		} catch(e) {
-			if (!(inTYPO3Tab && DTMDiv.style.display == "none")) {
+			if (!isNested || allDisplayed) {
 				this._doc.open();
 				this._doc.close();
 				this._initIframeTimer = window.setTimeout("HTMLArea.initIframe(" + this._editorNumber + ");", 500);
@@ -72,7 +70,15 @@
 		// When the TYPO3 TCA feature div2tab is used, the editor iframe may become hidden with style.display = "none"
 		// This breaks the editor in Mozilla/Firefox browsers: the designMode attribute needs to be resetted after the style.display of the containing div is resetted to "block"
 		// Here we rely on TYPO3 naming conventions for the div id and class name
-	if (inTYPO3Tab) HTMLArea._addEvent(DTMDiv, "DOMAttrModified", HTMLArea.DTMDivHandler(this, DTMDiv));
+	if (this.nested.sorted && this.nested.sorted.length) {
+		var nestedObj, listenerFunction;
+		for (var i=0, length=this.nested.sorted.length; i < length; i++) {
+			nestedObj = document.getElementById(this.nested.sorted[i]);
+			listenerFunction = HTMLArea.NestedListener(this, nestedObj, false);
+			HTMLArea._addEvent(nestedObj, 'DOMAttrModified', listenerFunction);
+		}
+	}
+
 	return true;
 };
 
@@ -282,32 +288,52 @@
  ***************************************************/
 
 /*
- * TYPO3 hidden tab handler
+ * TYPO3 hidden tab and inline event listener (gets event calls)
  */
-HTMLArea.DTMDivHandler = function (editor,DTMDiv) {
+HTMLArea.NestedListener = function (editor,nestedObj,noOpenCloseAction) {
 	return (function(ev) {
+		if (HTMLArea.stopAllEvents) { return false; }
 		if(!ev) var ev = window.event;
+		HTMLArea.NestedHandler(ev,editor,nestedObj,noOpenCloseAction);
+	});
+};
+
+/*
+ * TYPO3 hidden tab and inline event handler (performs actions on event calls)
+ */
+HTMLArea.NestedHandler = function(ev,editor,nestedObj,noOpenCloseAction) {
+	window.setTimeout(function() {
 		var target = (ev.target) ? ev.target : ev.srcElement;
-		if(target == DTMDiv && editor._editMode == "wysiwyg" && DTMDiv.style.display == "block") {
-			window.setTimeout( function() {
-				try { 
-					editor._doc.designMode = "on";
-					if (editor.config.sizeIncludesToolbar && editor._initialToolbarOffsetHeight != editor._toolbar.offsetHeight) editor.sizeIframe(-2);
-				} catch(e) {
-					editor._doc.open();
-					editor._doc.close();
-					editor.initIframe();
-				}
-			}, 20);
+		if(target == nestedObj && editor._editMode == "wysiwyg" && ev.attrName=='style' && (target.style.display == '' || target.style.display == 'block')) {
+				// Check if all affected nested elements are displayed (style.display!='none'):
+			if (HTMLArea.allElementsAreDisplayed(editor.nested.sorted)) {
+				window.setTimeout(function() {
+					try { 
+						editor._doc.designMode = "on";
+						if (editor.config.sizeIncludesToolbar && editor._initialToolbarOffsetHeight != editor._toolbar.offsetHeight) {
+							editor.sizeIframe(-2);
+						}
+					} catch(e) {
+							// If an event of a parent tab ("nested tabs") is triggered, the following lines should not be
+							// processed, because this causes some trouble on all event handlers...
+						if (!noOpenCloseAction) {
+							editor._doc.open();
+							editor._doc.close();
+						}
+						editor.initIframe();
+					}
+				}, 50);
+			}
 			HTMLArea._stopEvent(ev);
 		}
-	});
+	}, 50);
 };
 
 /*
  * Handle statusbar element events
  */
 HTMLArea.statusBarHandler = function (ev) {
+	if (HTMLArea.stopAllEvents) { return false; }
 	if(!ev) var ev = window.event;
 	var target = (ev.target) ? ev.target : ev.srcElement;
 	var editor = target.editor;
Index: typo3/sysext/rtehtmlarea/htmlarea/htmlarea-ie.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/htmlarea-ie.js	(Revision 2190)
+++ typo3/sysext/rtehtmlarea/htmlarea/htmlarea-ie.js	(Arbeitskopie)
@@ -242,6 +242,7 @@
  * Handle statusbar element events
  */
 HTMLArea.statusBarHandler = function (ev) {
+	if (HTMLArea.stopAllEvents) { return false; }
 	if(!ev) var ev = window.event;
 	var target = (ev.target) ? ev.target : ev.srcElement;
 	var editor = target.editor;
Index: typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js	(Revision 2190)
+++ typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js	(Arbeitskopie)
@@ -742,6 +742,7 @@
  * Handle toolbar element events handler
  */
 HTMLArea.toolBarButtonHandler = function(ev) {
+	if (HTMLArea.stopAllEvents) { return false; }
 	if(!ev) var ev = window.event;
 	var target = (ev.target) ? ev.target : ev.srcElement;
 	while (target.tagName.toLowerCase() == "img" || target.tagName.toLowerCase() == "div") target = target.parentNode;
@@ -881,19 +882,15 @@
  * Size the iframe according to user's prefs or initial textarea
  */
 HTMLArea.prototype.sizeIframe = function(diff) {
-	var i;
 	var height = (this.config.height == "auto" ? (this._textArea.style.height) : this.config.height);
 	var textareaHeight = height;
+		// All nested tabs and inline levels in the sorting order they were applied:
+	this.nested = RTEarea[this._editorNumber].tceformsNested;
+		// Clone the array instead of using a reference (this.accessParentElements will change the array):
+	var parentElements = (this.nested.sorted && this.nested.sorted.length ? [].concat(this.nested.sorted) : []);
+		// Walk through all nested tabs and inline levels to make a correct positioning:
+	var dimensions = this.accessParentElements(parentElements, 'this.getDimensions()');
 
-	var inlineObject = RTEarea[this._editorNumber].tceformsInlineObject;
-	var dynTabs = RTEarea[this._editorNumber].tceformsDynTabs;
-
-	var parentElements = new Array();
-	if (dynTabs) parentElements = dynTabs.split(',');
-	if (inlineObject) parentElements.push(inlineObject);
-
-	var dimensions = this.accessParentElements(parentElements, 'this.getDimensions()');
-			
 	if(height.indexOf("%") == -1) {
 		height = parseInt(height) - diff;		
 		if (this.config.sizeIncludesToolbar) {
@@ -936,7 +933,7 @@
 };
 
 /**
- * Access an inline relational element and make it "accesible".
+ * Access an inline relational element or tab menu and make it "accesible".
  * If a parent object has the style "display: none", offsetWidth & offsetHeight are '0'.
  *
  * @params	object		callbackFunc: A function to be called, when the embedded objects are "accessible".
@@ -949,7 +946,7 @@
 	if (parentElements.length) {
 		var currentElement = parentElements.pop();
 		var elementStyle = document.getElementById(currentElement).style;
-		var actionRequired = elementStyle.display == 'none';
+		var actionRequired = (elementStyle.display == 'none' ? true : false);
 		
 		if (actionRequired) {
 			var originalVisibility = elementStyle.visibility;
@@ -1118,7 +1115,10 @@
 	HTMLArea._addEvents((HTMLArea.is_ie ? doc.body : doc), ["keydown","keypress","mousedown","mouseup","drag"], HTMLArea._editorEvent, true);
 	
 		// add unload handler
-	HTMLArea._addEvent((this._iframe.contentWindow ? this._iframe.contentWindow : this._iframe.contentDocument), "unload", HTMLArea.removeEditorEvents);
+	if (!HTMLArea.hasUnloadHandler) {
+		HTMLArea.hasUnloadHandler = true;
+		HTMLArea._addEvent((this._iframe.contentWindow ? this._iframe.contentWindow : this._iframe.contentDocument), "unload", HTMLArea.removeEditorEvents);
+	}
 	
 		// set cleanWordOnPaste and intercept paste, dragdrop and drop events for wordClean
 	if (this.config.cleanWordOnPaste) HTMLArea._addEvents((HTMLArea.is_ie ? doc.body : doc), ["paste","dragdrop","drop"], HTMLArea.cleanWordOnPaste, true);
@@ -1154,6 +1154,7 @@
  * When we have a form, on reset, re-initialize the HTMLArea content and update the toolbar
  */
 HTMLArea.resetHandler = function(ev) {
+	if (HTMLArea.stopAllEvents) { return false; }
 	if(!ev) var ev = window.event;
 	var form = (ev.target) ? ev.target : ev.srcElement;
 	var editor = RTEarea[form._editorNumber]["editor"];
@@ -1172,6 +1173,8 @@
 HTMLArea.removeEditorEvents = function(ev) {
 	if(!ev) var ev = window.event;
 	HTMLArea._stopEvent(ev);
+	if (HTMLArea.stopAllEvent) { return false; }
+	HTMLArea.stopAllEvents = true;
 	if (Dialog._modal) {
 		Dialog._modal.close();
 		Dialog._modal = null;
@@ -1186,10 +1189,10 @@
 			window.clearInterval(editor._timerUndo);
 			editor._undoQueue = null;
 				// release events
-			if (HTMLArea._eventCache && !HTMLArea.is_opera) HTMLArea._eventCache.flush();
 			if (HTMLArea.is_ie) HTMLArea._cleanup(editor);
 		}
 	}
+	if (HTMLArea._eventCache && !HTMLArea.is_opera) HTMLArea._eventCache.flush();
 };
 
 /*
@@ -1443,6 +1446,7 @@
  * Handler for paste, dragdrop and drop events
  */
 HTMLArea.cleanWordOnPaste = function(ev) {
+	if (HTMLArea.stopAllEvents) { return false; }
 	if(!ev) var ev = window.event;
 	var target = (ev.target) ? ev.target : ev.srcElement;
 	var owner = (target.ownerDocument) ? target.ownerDocument : target;
@@ -2206,6 +2210,7 @@
 * A generic event handler for things that happen in the IFRAME's document.
 */
 HTMLArea._editorEvent = function(ev) {
+	if (HTMLArea.stopAllEvents) { return false; }
 	if(!ev) var ev = window.event;
 	var target = (ev.target) ? ev.target : ev.srcElement;
 	var owner = (target.ownerDocument) ? target.ownerDocument : target;
@@ -3033,3 +3038,12 @@
 		document.getElementById('editorWrap' + editorNumber).style.visibility = 'visible';
 	}
 };
+
+HTMLArea.allElementsAreDisplayed = function(elements) {
+	for (var i=0, length=elements.length; i < length; i++) {
+		if (document.getElementById(elements[i]).style.display == 'none') {
+			return false;
+		}
+	}
+	return true;
+};
\ Kein Zeilenvorschub am Ende der Datei
Index: typo3/sysext/rtehtmlarea/class.tx_rtehtmlarea_base.php
===================================================================
--- typo3/sysext/rtehtmlarea/class.tx_rtehtmlarea_base.php	(Revision 2190)
+++ typo3/sysext/rtehtmlarea/class.tx_rtehtmlarea_base.php	(Arbeitskopie)
@@ -525,7 +525,7 @@
 			$RTEHeight = $RTEHeight + ($pObj->docLarge ?  (isset($BE_USER->userTS['options.']['RTELargeHeightIncrement']) ? $BE_USER->userTS['options.']['RTELargeHeightIncrement'] : 0) : 0);
 			$editorWrapWidth = $RTEWidth . 'px';
 			$editorWrapHeight = $RTEHeight . 'px';
-			$this->RTEdivStyle = $this->RTEdivStyle ? $this->RTEdivStyle : 'position:relative; left:0px; top:0px; height:' . $RTEHeight . 'px; width:'.$RTEWidth.'px; border: 1px solid black; padding: 2px 0px 2px 2px;';
+			$this->RTEdivStyle = 'position:relative; left:0px; top:0px; height:' . $RTEHeight . 'px; width:'.$RTEWidth.'px; border: 1px solid black; padding: 2px 0px 2px 2px;';
 			$this->toolbar_level_size = $RTEWidth;
 
 			/* =======================================
@@ -907,10 +907,9 @@
 	function registerRTEinJS($number, $table='', $uid='', $field='') {
 		global $TSFE, $TYPO3_CONF_VARS;
 
-			// if this RTE is shown inline of an IRRE record, the JS functions need to know about that
-		if ($this->TCEform->inline->inlineNames['object']) {
-			$tceformsInlineObject = $this->TCEform->inline->inlineNames['object'].'['.$table.']['.$uid.']_fields';
-		}
+			// if this RTE is shown inline of an IRRE record or a Tab sheet, the JS functions need to know about that
+		$tabSuffix = '-DIV';
+		$inlineSuffix = '['.$table.']['.$uid.']_fields';
 		
 		$registerRTEinJSString = (!is_object($TSFE) ? '' : '
 			' . '/*<![CDATA[*/') . '
@@ -928,9 +927,8 @@
 			RTEarea['.$number.']["showTagFreeClasses"] = ' . (trim($this->thisConfig['showTagFreeClasses'])?'true':'false') . ';
 			RTEarea['.$number.']["useHTTPS"] = ' . ((trim(stristr($this->siteURL, 'https')) || $this->thisConfig['forceHTTPS'])?'true':'false') . ';
 			RTEarea['.$number.']["enableMozillaExtension"] = ' . (($this->client['BROWSER'] == 'gecko' && $TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableMozillaExtension'])?'true':'false') . ';
-			RTEarea['.$number.']["tceformsInlineObject"] = "' . $tceformsInlineObject . '";
-			RTEarea['.$number.']["tceformsDynTabs"] = "' . $this->TCEform->getDynTabLevelState('-DIV') . '";';
-		
+			RTEarea['.$number.']["tceformsNested"] = ' . (is_object($this->TCEform) && method_exists($this->TCEform, 'getDynNestedStack') ? $this->TCEform->getDynNestedStack(true, $tabSuffix, $inlineSuffix) : '[]') . ';';
+
 			// The following properties apply only to the backend
 		if (!is_object($TSFE)) {
 			$registerRTEinJSString .= '
@@ -940,7 +938,6 @@
 			RTEarea['.$number.']["enablePersonalDicts"] = ' . ($this->spellCheckerPersonalDicts ? 'true' : 'false') . ';
 			RTEarea['.$number.']["userUid"] = "' . $this->userUid . '";';
 		}
-		
 			// Setting the plugin flags
 		$registerRTEinJSString .= '
 			RTEarea['.$number.']["plugin"] = new Object();';
