Project

General

Profile

Bug #17101 » 0005177_v11.patch

Administrator Admin, 2007-03-16 16:22

View differences:

t3lib/class.t3lib_tceforms.php (Arbeitskopie)
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.
......
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
......
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]])) {
......
);
}
// 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>
......
}
/**
* 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);
}
}
t3lib/class.t3lib_tceforms_inline.php (Arbeitskopie)
'config' => $config,
);
$this->updateStructureNames();
// Put the current level also to the dynNestedStack of TCEforms:
$this->fObj->pushToDynNestedStack('inline', $this->inlineNames['object']);
}
......
$popItem = array_pop($this->inlineStructure['stable']);
$this->updateStructureNames();
}
// Remove the current level also from the dynNestedStack of TCEforms:
$this->fObj->popFromDynNestedStack();
return $popItem;
}
......
* @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;
}
}
typo3/sysext/rtehtmlarea/htmlarea/htmlarea-gecko.js (Arbeitskopie)
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);
......
// 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;
};
......
***************************************************/
/*
* 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;
typo3/sysext/rtehtmlarea/htmlarea/htmlarea-ie.js (Arbeitskopie)
* 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;
typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js (Arbeitskopie)
* 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;
......
* 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) {
......
};
/**
* 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".
......
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;
......
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);
......
* 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"];
......
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;
......
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();
};
/*
......
* 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;
......
* 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;
......
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;
};
typo3/sysext/rtehtmlarea/class.tx_rtehtmlarea_base.php (Arbeitskopie)
$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;
/* =======================================
......
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[*/') . '
......
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 .= '
......
RTEarea['.$number.']["enablePersonalDicts"] = ' . ($this->spellCheckerPersonalDicts ? 'true' : 'false') . ';
RTEarea['.$number.']["userUid"] = "' . $this->userUid . '";';
}
// Setting the plugin flags
$registerRTEinJSString .= '
RTEarea['.$number.']["plugin"] = new Object();';
(1-1/3)