Bug #17448 » 0005913_v2_41.patch
t3lib/class.t3lib_tceforms.php (Arbeitskopie) | ||
---|---|---|
if ($TCA[$table]['types'][$typeNum]) {
|
||
$itemList = $TCA[$table]['types'][$typeNum]['showitem'];
|
||
if ($itemList) { // If such a list existed...
|
||
// if TCEforms will render a tab menu in the next step, push the name to the tab stack
|
||
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']);
|
||
}
|
||
// Explode the field list and possibly rearrange the order of the fields, if configured for
|
||
$fields = t3lib_div::trimExplode(',',$itemList,1);
|
||
if ($this->fieldOrder) {
|
||
... | ... | |
$excludeElements = $this->excludeElements = $this->getExcludeElements($table,$row,$typeNum);
|
||
$fields = $this->mergeFieldsWithAddedFields($fields,$this->getFieldsToAdd($table,$row,$typeNum));
|
||
// If TCEforms will render a tab menu in the next step, push the name to the tab stack:
|
||
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']);
|
||
// Remember that were currently working on the general tab:
|
||
if (isset($fields[0]) && strpos($fields[0], '--div--') !== 0) {
|
||
$this->pushToDynNestedStack('tab', $tabIdentStringMD5.'-1');
|
||
}
|
||
}
|
||
// Traverse the fields to render:
|
||
$cc=0;
|
||
foreach($fields as $fieldInfo) {
|
||
... | ... | |
/**
|
||
* 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.
|
||
* The result is e.g. ['tab','DTM-ABCD-1'], ['inline','data[13][table][uid][field]'], ['tab','DTM-DEFG-2'], ...
|
||
*
|
||
* @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.
|
||
* @param boolean $json: Return a JSON string instead of an array - default: false
|
||
* @param boolean $skipFirst: Skip the first element in the dynNestedStack - default: false
|
||
* @return mixed Returns an associative array by 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;
|
||
}
|
||
function getDynNestedStack($json=false, $skipFirst=false) {
|
||
$result = $this->dynNestedStack;
|
||
if ($skipFirst) {
|
||
array_shift($result);
|
||
}
|
||
$result = array(
|
||
// 'raw' => $this->dynNestedStack,
|
||
'tab' => $tab,
|
||
'inline' => $inline,
|
||
'sorted' => $sorted,
|
||
// 'tabSuffix' => $tabSuffix,
|
||
// 'inlineSuffix' => $inlineSuffix,
|
||
);
|
||
return ($json ? $this->inline->getJSON($result) : $result);
|
||
}
|
||
}
|
t3lib/jsfunc.inline.js (Arbeitskopie) | ||
---|---|---|
return $(objectId+'_div') && $(objectId+'_div').hasClassName('inlineIsNewRecord')
|
||
? true
|
||
: false;
|
||
},
|
||
// Find and fix nested of inline and tab levels if a new element was created dynamically (it doesn't know about its nesting):
|
||
findContinuedNestedLevel: function(nested, objectId) {
|
||
if (this.data.nested && this.data.nested[objectId]) {
|
||
// Remove the first element from the new nested stack, it's just a hint:
|
||
nested.shift();
|
||
nested = this.data.nested[objectId].concat(nested);
|
||
return nested;
|
||
} else {
|
||
return nested;
|
||
}
|
||
}
|
||
}
|
||
t3lib/class.t3lib_tceforms_inline.php (Arbeitskopie) | ||
---|---|---|
var $fObj; // Reference to the calling TCEforms instance
|
||
var $backPath; // Reference to $fObj->backPath
|
||
var $isAjaxCall = false; // Indicates if a field is rendered upon an AJAX call
|
||
var $inlineStructure = array(); // the structure/hierarchy where working in, e.g. cascading inline tables
|
||
var $inlineFirstPid; // the first call of an inline type appeared on this page (pid of record)
|
||
var $inlineNames = array(); // keys: form, object -> hold the name/id for each of them
|
||
... | ... | |
$config['inline']['first'] = $recordList[0]['uid'];
|
||
$config['inline']['last'] = $recordList[count($recordList)-1]['uid'];
|
||
// tell the browser what we have (using JSON later)
|
||
// Tell the browser what we have (using JSON later):
|
||
$top = $this->getStructureLevel(0);
|
||
$this->inlineData['config'][$nameObject] = array('table' => $foreign_table);
|
||
$this->inlineData['config'][$nameObject.'['.$foreign_table.']'] = array(
|
||
... | ... | |
'uid' => $top['uid'],
|
||
),
|
||
);
|
||
// Set a hint for nested IRRE and tab elements:
|
||
$this->inlineData['nested'][$nameObject] = $this->fObj->getDynNestedStack(false, $this->isAjaxCall);
|
||
// if relations are required to be unique, get the uids that have already been used on the foreign side of the relation
|
||
if ($config['foreign_unique']) {
|
||
... | ... | |
$nameObject = $this->inlineNames['object'];
|
||
$appendFormFieldNames = '['.$foreign_table.']['.$rec['uid'].']';
|
||
$formFieldNames = $nameObject.$appendFormFieldNames;
|
||
// Put the current level also to the dynNestedStack of TCEforms:
|
||
$this->fObj->pushToDynNestedStack('inline', $this->inlineNames['object'].$appendFormFieldNames);
|
||
$header = $this->renderForeignRecordHeader($parentUid, $foreign_table, $rec, $config);
|
||
$combination = $this->renderCombinationTable($rec, $appendFormFieldNames, $config);
|
||
... | ... | |
// wrap the header, fields and combination part of a child record with a div container
|
||
$out = '<div id="'.$formFieldNames.'_div"'.($isNewRecord ? ' class="inlineIsNewRecord"' : '').'>' . $out . '</div>';
|
||
// Remove the current level also from the dynNestedStack of TCEforms:
|
||
$this->fObj->popFromDynNestedStack();
|
||
return $out;
|
||
}
|
||
... | ... | |
* @return string A JSON string
|
||
*/
|
||
function createNewRecord($domObjectId, $foreignUid = 0) {
|
||
$this->isAjaxCall = true;
|
||
// parse the DOM identifier (string), add the levels to the structure stack (array) and load the TCA config
|
||
$this->parseStructureString($domObjectId, true);
|
||
// the current table - for this table we should add/import records
|
||
... | ... | |
$parent = $this->getStructureLevel(-1);
|
||
// get TCA 'config' of the parent table
|
||
$config = $parent['config'];
|
||
|
||
// Put the current level also to the dynNestedStack of TCEforms:
|
||
$this->fObj->pushToDynNestedStack('inline', $this->inlineNames['object']);
|
||
// dynamically create a new record using t3lib_transferData
|
||
if (!$foreignUid || !t3lib_div::testInt($foreignUid) || $config['foreign_selector']) {
|
||
$record = $this->getNewRecord($this->inlineFirstPid, $current['table']);
|
||
... | ... | |
// fade out and fade in the new record in the browser view to catch the user's eye
|
||
$jsonArray['scriptCall'][] = "inline.fadeOutFadeIn('".$objectId."_div');";
|
||
// Remove the current level also from the dynNestedStack of TCEforms:
|
||
$this->fObj->popFromDynNestedStack();
|
||
// return the JSON string
|
||
return $this->getJSON($jsonArray);
|
||
}
|
||
... | ... | |
'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;
|
||
}
|
||
typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js (Arbeitskopie) | ||
---|---|---|
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;
|
||
this.nested = {};
|
||
this.nested.all = RTEarea[this._editorNumber].tceformsNested;
|
||
this.nested.sorted = HTMLArea.simplifyNested(this.nested.all);
|
||
// 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:
|
||
... | ... | |
return result;
|
||
};
|
||
/**
|
||
* Simplify the array of nested levels. Create an indexed array with the correct names of the elements.
|
||
*
|
||
* @param object nested: The array with the nested levels
|
||
* @return object The simplified array
|
||
* @author Oliver Hader <oh@inpublica.de>
|
||
*/
|
||
HTMLArea.simplifyNested = function(nested) {
|
||
var i, type, level, max, simplifiedNested=[];
|
||
if (nested && nested.length) {
|
||
if (nested[0][0]=='inline') {
|
||
nested = inline.findContinuedNestedLevel(nested, nested[0][1]);
|
||
}
|
||
for (i=0, max=nested.length; i<max; i++) {
|
||
type = nested[i][0];
|
||
level = nested[i][1];
|
||
if (type=='tab') {
|
||
simplifiedNested.push(level+'-DIV');
|
||
} else if (type=='inline') {
|
||
simplifiedNested.push(level+'_fields');
|
||
}
|
||
}
|
||
}
|
||
return simplifiedNested;
|
||
};
|
||
/*
|
||
* Initialize the iframe
|
||
*/
|
typo3/sysext/rtehtmlarea/htmlarea/htmlarea-compressed.js (Arbeitskopie) | ||
---|---|---|
textarea.style.display="none";var htmlarea=document.createElement("div");htmlarea.className="htmlarea";htmlarea.style.width=textarea.style.width;this._htmlArea=htmlarea;textarea.parentNode.insertBefore(htmlarea,textarea);if(textarea.form){var f=textarea.form;if(typeof(f.onreset)=="function"){var funcref=f.onreset;if(typeof(f.__msh_prevOnReset)=="undefined")f.__msh_prevOnReset=[];f.__msh_prevOnReset.push(funcref);}
|
||
f._editorNumber=this._editorNumber;HTMLArea._addEvent(f,"reset",HTMLArea.resetHandler);}
|
||
this._createToolbar();HTMLArea._appendToLog("[HTMLArea::generate]: Toolbar successfully created.");var iframe=document.createElement("iframe");if(HTMLArea.is_ie||HTMLArea.is_safari||HTMLArea.is_wamcom){iframe.setAttribute("src",_editor_url+"popups/blank.html");}else if(HTMLArea.is_opera){iframe.setAttribute("src",_typo3_host_url+_editor_url+"popups/blank.html");}else{iframe.setAttribute("src","javascript:void(0);");}
|
||
iframe.className="editorIframe";if(!this.config.statusBar)iframe.className+=" noStatusBar";htmlarea.appendChild(iframe);this._iframe=iframe;this._createStatusBar();this.sizeIframe(2);HTMLArea._appendToLog("[HTMLArea::generate]: Editor iframe successfully created.");this.initIframe();return this;};HTMLArea.prototype.sizeIframe=function(diff){var height=(this.config.height=="auto"?(this._textArea.style.height):this.config.height);var textareaHeight=height;this.nested=RTEarea[this._editorNumber].tceformsNested;var parentElements=(this.nested.sorted&&this.nested.sorted.length?[].concat(this.nested.sorted):[]);var dimensions=this.accessParentElements(parentElements,'this.getDimensions()');if(height.indexOf("%")==-1){height=parseInt(height)-diff;if(this.config.sizeIncludesToolbar){this._initialToolbarOffsetHeight=dimensions.toolbar.height;height-=dimensions.toolbar.height;height-=dimensions.statusbar.height;}
|
||
iframe.className="editorIframe";if(!this.config.statusBar)iframe.className+=" noStatusBar";htmlarea.appendChild(iframe);this._iframe=iframe;this._createStatusBar();this.sizeIframe(2);HTMLArea._appendToLog("[HTMLArea::generate]: Editor iframe successfully created.");this.initIframe();return this;};HTMLArea.prototype.sizeIframe=function(diff){var height=(this.config.height=="auto"?(this._textArea.style.height):this.config.height);var textareaHeight=height;this.nested={};this.nested.all=RTEarea[this._editorNumber].tceformsNested;this.nested.sorted=HTMLArea.simplifyNested(this.nested.all);var parentElements=(this.nested.sorted&&this.nested.sorted.length?[].concat(this.nested.sorted):[]);var dimensions=this.accessParentElements(parentElements,'this.getDimensions()');if(height.indexOf("%")==-1){height=parseInt(height)-diff;if(this.config.sizeIncludesToolbar){this._initialToolbarOffsetHeight=dimensions.toolbar.height;height-=dimensions.toolbar.height;height-=dimensions.statusbar.height;}
|
||
if(height<0)height=0;textareaHeight=(height-4);if(textareaHeight<0)textareaHeight=0;height+="px";textareaHeight+="px";}
|
||
this._iframe.style.height=height;this._textArea.style.height=textareaHeight;var textareaWidth=(this.config.width=="auto"?this._textArea.style.width:this.config.width);var iframeWidth=textareaWidth;if(textareaWidth.indexOf("%")==-1){iframeWidth=parseInt(textareaWidth)+"px";textareaWidth=parseInt(textareaWidth)-diff;if(textareaWidth<0)textareaWidth=0;textareaWidth+='px';}
|
||
this._iframe.style.width="100%";if(HTMLArea.is_opera)this._iframe.style.width=iframeWidth;this._textArea.style.width=textareaWidth;};HTMLArea.prototype.getDimensions=function(){return{toolbar:{width:this._toolbar.offsetWidth,height:this._toolbar.offsetHeight},statusbar:{width:this._statusBar.offsetWidth,height:this._statusBar.offsetHeight}};};HTMLArea.prototype.accessParentElements=function(parentElements,callbackFunc){var result={};if(parentElements.length){var currentElement=parentElements.pop();var elementStyle=document.getElementById(currentElement).style;var actionRequired=(elementStyle.display=='none'?true:false);if(actionRequired){var originalVisibility=elementStyle.visibility;var originalPosition=elementStyle.position;elementStyle.visibility='hidden';elementStyle.position='absolute';elementStyle.display='';}
|
||
result=this.accessParentElements(parentElements,callbackFunc);if(actionRequired){elementStyle.display='none';elementStyle.position=originalPosition;elementStyle.visibility=originalVisibility;}}else{result=eval(callbackFunc);}
|
||
return result;};HTMLArea.initIframe=function(editorNumber){var editor=RTEarea[editorNumber]["editor"];editor.initIframe();};HTMLArea.prototype.initIframe=function(){if(this._initIframeTimer)window.clearTimeout(this._initIframeTimer);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){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){this._initIframeTimer=window.setTimeout("HTMLArea.initIframe("+this._editorNumber+");",50);return false;}
|
||
return result;};HTMLArea.simplifyNested=function(nested){var i,type,level,max,simplifiedNested=[];if(nested&&nested.length){if(nested[0][0]=='inline'){nested=inline.findContinuedNestedLevel(nested,nested[0][1]);}
|
||
for(i=0,max=nested.length;i<max;i++){type=nested[i][0];level=nested[i][1];if(type=='tab'){simplifiedNested.push(level+'-DIV');}else if(type=='inline'){simplifiedNested.push(level+'_fields');}}}
|
||
return simplifiedNested;};HTMLArea.initIframe=function(editorNumber){var editor=RTEarea[editorNumber]["editor"];editor.initIframe();};HTMLArea.prototype.initIframe=function(){if(this._initIframeTimer)window.clearTimeout(this._initIframeTimer);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){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){this._initIframeTimer=window.setTimeout("HTMLArea.initIframe("+this._editorNumber+");",50);return false;}
|
||
var doc=this._iframe.contentWindow?this._iframe.contentWindow.document:this._iframe.contentDocument;this._doc=doc;if(!this.config.fullPage){var head=doc.getElementsByTagName("head")[0];if(!head){head=doc.createElement("head");doc.documentElement.appendChild(head);}
|
||
if(this.config.baseURL&&!HTMLArea.is_opera){var base=doc.getElementsByTagName("base")[0];if(!base){base=doc.createElement("base");base.href=this.config.baseURL;head.appendChild(base);}
|
||
HTMLArea._appendToLog("[HTMLArea::initIframe]: Iframe baseURL set to: "+this.config.baseURL);}
|
typo3/sysext/rtehtmlarea/class.tx_rtehtmlarea_base.php (Arbeitskopie) | ||
---|---|---|
$this->TCEform = $pObj;
|
||
$inline =& $this->TCEform->inline;
|
||
|
||
$LANG->includeLLFile('EXT:' . $this->ID . '/locallang.xml');
|
||
$this->client = $this->clientInfo();
|
||
$this->typoVersion = t3lib_div::int_from_ver(TYPO3_version);
|
||
... | ... | |
function registerRTEinJS($number, $table='', $uid='', $field='') {
|
||
global $TSFE, $TYPO3_CONF_VARS;
|
||
// 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.'] = new Object();
|
||
... | ... | |
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.']["tceformsNested"] = ' . (is_object($this->TCEform) && method_exists($this->TCEform, 'getDynNestedStack') ? $this->TCEform->getDynNestedStack(true, $tabSuffix, $inlineSuffix) : '[]') . ';';
|
||
RTEarea['.$number.']["tceformsNested"] = ' . (is_object($this->TCEform) && method_exists($this->TCEform, 'getDynNestedStack') ? $this->TCEform->getDynNestedStack(true) : '[]') . ';';
|
||
// The following properties apply only to the backend
|
||
if (!is_object($TSFE)) {
|