Fixed bug #10086: Core uses deprecated function t3lib_db->sql()
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_tceforms.php
index 209eaa1..a34250d 100755 (executable)
@@ -214,7 +214,7 @@ class t3lib_TCEforms        {
        var $loadMD5_JS=1;
        var $prevBorderStyle='[nothing here...]';       // Something unique...
        var $allowUpload=0;                             // If set direct upload fields will be shown
-       var $titleLen=15;                                       // @deprecated: $BE_USER->uc['titleLen'] but what is default??
+       var $titleLen=15;                                       // @deprecated since TYPO3 4.1: $BE_USER->uc['titleLen'] but what is default??
        var $defaultLanguageData = array();     // Array where records in the default language is stored. (processed by transferdata)
        var $defaultLanguageData_diff = array();        // Array where records in the default language is stored (raw without any processing. used for making diff)
        var $additionalPreviewLanguageData = array();
@@ -301,6 +301,7 @@ class t3lib_TCEforms        {
        var $additionalJS_pre = array();                        // Additional JavaScript, printed before the form
        var $additionalJS_post = array();                       // Additional JavaScript printed after the form
        var $additionalJS_submit = array();                     // Additional JavaScript executed on submit; If you set "OK" variable it will raise an error about RTEs not being loaded and offer to block further submission.
+       var $additionalJS_delete = array();                     // Additional JavaScript executed when section element is deleted. This is neceessary, for example, to correctly clean up HTMLArea RTE (bug #8232)
 
        /**
         * Instance of t3lib_tceforms_inline
@@ -394,7 +395,7 @@ class t3lib_TCEforms        {
                $this->edit_showFieldHelp = $BE_USER->uc['edit_showFieldHelp'];
 
                $this->edit_docModuleUpload = $BE_USER->uc['edit_docModuleUpload'];
-               $this->titleLen = $BE_USER->uc['titleLen'];             // @deprecated
+               $this->titleLen = $BE_USER->uc['titleLen'];             // @deprecated since TYPO3 4.1
 
                $this->inline->init($this);
        }
@@ -974,6 +975,13 @@ class t3lib_TCEforms       {
        function getSingleField_SW($table,$field,$row,&$PA)     {
                $PA['fieldConf']['config']['form_type'] = $PA['fieldConf']['config']['form_type'] ? $PA['fieldConf']['config']['form_type'] : $PA['fieldConf']['config']['type'];       // Using "form_type" locally in this script
 
+               // Hook: getSingleField_beforeRender
+               foreach ($this->hookObjectsSingleField as $hookObject) {
+                       if (method_exists($hookObject, 'getSingleField_beforeRender')) {
+                               $hookObject->getSingleField_beforeRender($table, $field, $row, $PA);
+                       }
+               }
+
                switch($PA['fieldConf']['config']['form_type']) {
                        case 'input':
                                $item = $this->getSingleField_typeInput($table,$field,$row,$PA);
@@ -1111,11 +1119,11 @@ class t3lib_TCEforms    {
                                $checkSetValue = gmdate('Y');
                        }
                        $cOnClick = 'typo3form.fieldGet('.$paramsList.',1,\''.$checkSetValue.'\');'.implode('',$PA['fieldChangeFunc']);
-                       $item.='<input type="checkbox"'.$this->insertDefStyle('check').' name="'.$PA['itemFormElName'].'_cb" onclick="'.htmlspecialchars($cOnClick).'" />';
+                       $item .= '<input type="checkbox" class="' . $this->formElStyleClassValue('check', TRUE) . ' alignToInputText" name="' . $PA['itemFormElName'] . '_cb" onclick="' . htmlspecialchars($cOnClick) . '" />';
                }
-               if((in_array('date',$evalList) || in_array('datetime',$evalList)) && $PA['itemFormElValue']>0){
+               if ((in_array('date',$evalList) || in_array('datetime',$evalList)) && $PA['itemFormElValue']>0){
                                // Add server timezone offset to UTC to our stored date
-                       $PA['itemFormElValue'] += date('Z');
+                       $PA['itemFormElValue'] += date('Z', $PA['itemFormElValue']);
                }
 
                $PA['fieldChangeFunc'] = array_merge(array('typo3form.fieldGet'=>'typo3form.fieldGet('.$paramsList.');'), $PA['fieldChangeFunc']);
@@ -1253,7 +1261,7 @@ class t3lib_TCEforms      {
                                if (count($classes))    {
                                        $class = ' class="'.implode(' ',$classes).'"';
                                } else $class='';
-                               
+
                                $evalList = t3lib_div::trimExplode(',',$config['eval'],1);
                                foreach ($evalList as $func) {
                                        switch ($func) {
@@ -1274,7 +1282,7 @@ class t3lib_TCEforms      {
                                                        break;
                                        }
                                }
-                               
+
                                $iOnChange = implode('',$PA['fieldChangeFunc']);
                                $item.= '
                                                        <textarea name="'.$PA['itemFormElName'].'"'.$formWidthText.$class.' rows="'.$rows.'" wrap="'.$wrap.'" onchange="'.htmlspecialchars($iOnChange).'"'.$PA['onFocus'].'>'.
@@ -1346,7 +1354,7 @@ class t3lib_TCEforms      {
                                $cBID = $PA['itemFormElID'].'_'.$c;
                                $item.= ($c>0?'<br />':'').
                                                '<input type="checkbox"'.$this->insertDefStyle('check').' value="1" name="'.$cBName.'"'.$cBP.$PA['onFocus'].$disabled.' id="'.$cBID.'" />'.
-                                               htmlspecialchars($p[0]);
+                                               $this->wrapLabels('<label for="'.$cBID.'">'.htmlspecialchars($p[0]).'</label>');
                        }
                }
                if (!$disabled) {
@@ -1417,9 +1425,21 @@ class t3lib_TCEforms     {
                $specConf = $this->getSpecConfFromString($PA['extra'], $PA['fieldConf']['defaultExtras']);
 
                        // Getting the selector box items from the system
-               $selItems = $this->addSelectOptionsToItemArray($this->initItemArray($PA['fieldConf']),$PA['fieldConf'],$this->setTSconfig($table,$row),$field);
-               $selItems = $this->addItems($selItems,$PA['fieldTSConfig']['addItems.']);
-               if ($config['itemsProcFunc']) $selItems = $this->procItems($selItems,$PA['fieldTSConfig']['itemsProcFunc.'],$config,$table,$row,$field);
+               $selItems = $this->addSelectOptionsToItemArray(
+                       $this->initItemArray($PA['fieldConf']),
+                       $PA['fieldConf'],
+                       $this->setTSconfig($table, $row),
+                       $field
+               );
+                       // Possibly filter some items:
+               $keepItemsFunc = create_function('$value', 'return $value[1];');
+               $selItems = t3lib_div::keepItemsInArray($selItems, $PA['fieldTSConfig']['keepItems'], $keepItemsFunc);
+                       // Possibly add some items:
+               $selItems = $this->addItems($selItems, $PA['fieldTSConfig']['addItems.']);
+                       // Process items by a user function:
+               if (isset($config['itemsProcFunc']) && $config['itemsProcFunc']) {
+                       $selItems = $this->procItems($selItems, $PA['fieldTSConfig']['itemsProcFunc.'], $config, $table, $row, $field);
+               }
 
                        // Possibly remove some items:
                $removeItems = t3lib_div::trimExplode(',',$PA['fieldTSConfig']['removeItems'],1);
@@ -1537,7 +1557,7 @@ class t3lib_TCEforms      {
                                if ($sM) {
                                        list($selectIconFile,$selectIconInfo) = $this->getIcon($p[2]);
                                                if (!empty($selectIconInfo)) {
-                                                       $selectedStyle = ' style="background-image: url('.$selectIconFile.'); background-repeat: no-repeat; background-position: 0% 50%; padding: 1px; padding-left: 22px;"';
+                                                       $selectedStyle = ' style="background-image: url('.$selectIconFile.'); background-repeat: no-repeat; background-position: 0% 50%; padding: 1px; padding-left: 24px; -webkit-background-size: 0;"';
                                                }
                                }
                        }
@@ -1547,7 +1567,7 @@ class t3lib_TCEforms      {
                                if(!strcmp($p[1],'--div--')) {
                                        $optGroupStart[0] = $p[0];
                                        $optGroupStart[1] = $styleAttrValue;
-                                       
+
                                } else {
                                        if (count($optGroupStart)) {
                                                if($optGroupOpen) { // Closing last optgroup before next one starts
@@ -1596,11 +1616,12 @@ class t3lib_TCEforms    {
                if(!$disabled) {
                        $item.= '<input type="hidden" name="'.$PA['itemFormElName'].'_selIconVal" value="'.htmlspecialchars($sI).'" />';        // MUST be inserted before the selector - else is the value of the hiddenfield here mysteriously submitted...
                }
-               $item.= '<select'.$selectedStyle.' name="'.$PA['itemFormElName'].'"'.
-                                       $this->insertDefStyle('select').
-                                       ($size?' size="'.$size.'"':'').
-                                       ' onchange="'.htmlspecialchars($sOnChange).'"'.
-                                       $PA['onFocus'].$disabled.'>';
+               $item .= '<select' . $selectedStyle . ' name="' . $PA['itemFormElName'] . '"' .
+                                       ($config['iconsInOptionTags'] ? ' class="icon-select"' : '') .
+                                       $this->insertDefStyle('select') .
+                                       ($size ? ' size="' . $size . '"' : '') .
+                                       ' onchange="' . htmlspecialchars($sOnChange) . '"' .
+                                       $PA['onFocus'] . $disabled . '>';
                $item.= implode('',$opt);
                $item.= '</select>';
 
@@ -1663,18 +1684,22 @@ class t3lib_TCEforms    {
                                if (!strcmp($p[1],'--div--'))   {
                                        if (count($setAll))     {
                                                        $tRows[] = '
-                                                               <tr>
-                                                                       <td colspan="2">'.
-                                                                       '<a href="#" onclick="'.htmlspecialchars(implode('',$setAll).' return false;').'">'.
-                                                                       htmlspecialchars($this->getLL('l_setAllCheckboxes')).
-                                                                       '</a></td>
+                                                               <tr class="c-header-checkbox-controls">
+                                                                       <td colspan="3">' .
+                                                                               '<a href="#" onclick="' . htmlspecialchars(implode('', $setAll).' return false;') . '">' .
+                                                                               htmlspecialchars($this->getLL('l_checkAll')) .
+                                                                               '</a>
+                                                                               <a href="#" onclick="' . htmlspecialchars(implode('', $unSetAll).' return false;').'">' .
+                                                                               htmlspecialchars($this->getLL('l_uncheckAll')) .
+                                                                               '</a>
+                                                                       </td>
                                                                </tr>';
                                                        $setAll = array();
                                        }
 
                                        $tRows[] = '
                                                <tr class="c-header">
-                                                       <td colspan="2">'.htmlspecialchars($p[0]).'</td>
+                                                       <td colspan="3">'.htmlspecialchars($p[0]).'</td>
                                                </tr>';
                                } else {
                                                // Selected or not by default:
@@ -1691,17 +1716,39 @@ class t3lib_TCEforms    {
                                        }
 
                                                // Compile row:
-                                       $onClickCell = $this->elName($PA['itemFormElName'].'['.$c.']').'.checked=!'.$this->elName($PA['itemFormElName'].'['.$c.']').'.checked;';
-                                       $onClick = 'this.attributes.getNamedItem("class").nodeValue = '.$this->elName($PA['itemFormElName'].'['.$c.']').'.checked ? "c-selectedItem" : "";';
-                                       $setAll[] = $this->elName($PA['itemFormElName'].'['.$c.']').'.checked=1;';
+                                       $rowId = uniqid('select_checkbox_row_');
+                                       $onClickCell = $this->elName($PA['itemFormElName'] . '[' . $c . ']') . '.checked=!' . $this->elName($PA['itemFormElName'] . '[' . $c . ']') . '.checked;';
+                                       $onClick = 'this.attributes.getNamedItem("class").nodeValue = ' . $this->elName($PA['itemFormElName'] . '[' . $c . ']') . '.checked ? "c-selectedItem" : "c-unselectedItem";';
+                                       $setAll[] = $this->elName($PA['itemFormElName'] . '[' . $c . ']') . '.checked=1;';
+                                       $setAll[] .= '$(\'' . $rowId . '\').removeClassName(\'c-unselectedItem\');$(\'' . $rowId . '\').addClassName(\'c-selectedItem\');';
+                                       $unSetAll[] = $this->elName($PA['itemFormElName'].'['.$c.']').'.checked=0;';
+                                       $unSetAll[] .= '$(\'' . $rowId . '\').removeClassName(\'c-selectedItem\');$(\'' . $rowId . '\').addClassName(\'c-unselectedItem\');';
+                                       $restoreCmd[] = $this->elName($PA['itemFormElName'] . '[' . $c . ']') . '.checked=' . ($sM ? 1 : 0) . ';' .
+                                                               '$(\'' . $rowId . '\').removeClassName(\'c-selectedItem\');$(\'' . $rowId . '\').removeClassName(\'c-unselectedItem\');' .
+                                                               '$(\'' . $rowId . '\').addClassName(\'c-' . ($sM ? '' : 'un') . 'selectedItem\');';
+
+                                       $hasHelp = ($p[3] !='');
+
+                                       $label = t3lib_div::deHSCentities(htmlspecialchars($p[0]));
+                                       $help = $hasHelp ? '<span class="typo3-csh-inline show-right"><span class="header">' . $label . '</span>' .
+                                               '<span class="paragraph">' . $GLOBALS['LANG']->hscAndCharConv(nl2br(trim(htmlspecialchars($p[3]))), false) . '</span></span>' : '';
+
+                                       if ($hasHelp && $this->edit_showFieldHelp == 'icon') {
+                                               $helpIcon  = '<a class="typo3-csh-link" href="#">';
+                                               $helpIcon .= '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/helpbubble.gif', 'width="14" height="14"');
+                                               $helpIcon .= ' hspace="2" border="0" class="absmiddle"' . ($GLOBALS['CLIENT']['FORMSTYLE'] ? ' style="cursor:help;"' : '') . ' alt="" />' . $help;
+                                               $helpIcon .= '</a>';
+                                               $help = $helpIcon;
+                                       }
+
                                        $tRows[] = '
-                                               <tr class="'.($sM ? 'c-selectedItem' : '').'" onclick="'.htmlspecialchars($onClick).'" style="cursor: pointer;">
-                                                       <td><input type="checkbox"'.$this->insertDefStyle('check').' name="'.htmlspecialchars($PA['itemFormElName'].'['.$c.']').'" value="'.htmlspecialchars($p[1]).'"'.$sM.' onclick="'.htmlspecialchars($sOnChange).'"'.$PA['onFocus'].' /></td>
+                                               <tr id="' . $rowId . '" class="'.($sM ? 'c-selectedItem' : 'c-unselectedItem').'" onclick="'.htmlspecialchars($onClick).'" style="cursor: pointer;">
+                                                       <td width="12"><input type="checkbox"'.$this->insertDefStyle('check').' name="'.htmlspecialchars($PA['itemFormElName'].'['.$c.']').'" value="'.htmlspecialchars($p[1]).'"'.$sM.' onclick="'.htmlspecialchars($sOnChange).'"'.$PA['onFocus'].' /></td>
                                                        <td class="c-labelCell" onclick="'.htmlspecialchars($onClickCell).'">'.
                                                                ($selIconFile ? '<img src="'.$selIconFile.'" '.$selIconInfo[3].' vspace="2" border="0" class="absmiddle" style="margin-right: 4px;" alt="" />' : '').
-                                                               t3lib_div::deHSCentities(htmlspecialchars($p[0])).
-                                                               (strcmp($p[3],'') ? '<br/><p class="c-descr">'.nl2br(trim(htmlspecialchars($p[3]))).'</p>' : '').
+                                                               $label .
                                                                '</td>
+                                                               <td class="c-descr" onclick="'.htmlspecialchars($onClickCell).'">' . (strcmp($p[3],'') ? $help : '') . '</td>
                                                </tr>';
                                        $c++;
                                }
@@ -1710,11 +1757,15 @@ class t3lib_TCEforms    {
                                // Remaining checkboxes will get their set-all link:
                        if (count($setAll))     {
                                        $tRows[] = '
-                                               <tr>
-                                                       <td colspan="2">'.
-                                                       '<a href="#" onclick="'.htmlspecialchars(implode('',$setAll).' return false;').'">'.
-                                                       htmlspecialchars($this->getLL('l_setAllCheckboxes')).
-                                                       '</a></td>
+                                               <tr class="c-header-checkbox-controls">
+                                                       <td colspan="3">'.
+                                                               '<a href="#" onclick="' . htmlspecialchars(implode('', $setAll).' return false;') . '">' .
+                                                               htmlspecialchars($this->getLL('l_checkAll')) .
+                                                               '</a>
+                                                               <a href="#" onclick="' . htmlspecialchars(implode('', $unSetAll).' return false;') . '">' .
+                                                               htmlspecialchars($this->getLL('l_uncheckAll')) .
+                                                               '</a>
+                                                       </td>
                                                </tr>';
                        }
                }
@@ -1728,17 +1779,23 @@ class t3lib_TCEforms    {
                                                        <td><input type="checkbox"'.$this->insertDefStyle('check').' name="'.htmlspecialchars($PA['itemFormElName'].'['.$c.']').'" value="'.htmlspecialchars($theNoMatchValue).'" checked="checked" onclick="'.htmlspecialchars($sOnChange).'"'.$PA['onFocus'].$disabled.' /></td>
                                                        <td class="c-labelCell">'.
                                                                t3lib_div::deHSCentities(htmlspecialchars(@sprintf($nMV_label, $theNoMatchValue))).
-                                                               '</td>
+                                                               '</td><td>&nbsp;</td>
                                                </tr>');
                                $c++;
                        }
                }
 
                        // Add an empty hidden field which will send a blank value if all items are unselected.
-               $item.='<input type="hidden" name="'.htmlspecialchars($PA['itemFormElName']).'" value="" />';
+               $item .= '<input type="hidden" name="'.htmlspecialchars($PA['itemFormElName']) . '" value="" />';
 
+                       // Add revert icon
+               if (is_array($restoreCmd)) {
+                       $item .= '<a href="#" onclick="' . implode('', $restoreCmd).' return false;' . '">' .
+                               '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/undo.gif','width="13" height="12"') . ' title="' .
+                               htmlspecialchars($this->getLL('l_revertSelection')) . '" alt="" />' .'</a>';
+               }
                        // Implode rows in table:
-               $item.= '
+               $item .= '
                        <table border="0" cellpadding="0" cellspacing="0" class="typo3-TCEforms-select-checkbox">'.
                                implode('',$tRows).'
                        </table>
@@ -1847,7 +1904,7 @@ class t3lib_TCEforms      {
                                        </td>
                                        <td valign="top">
                                        <a href="#" onclick="'.htmlspecialchars($this->elName($PA['itemFormElName'].'[]').'.selectedIndex=-1;'.implode('',$restoreCmd).' return false;').'">'.
-                                               '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/history.gif','width="13" height="12"').' title="'.htmlspecialchars($this->getLL('l_revertSelection')).'" alt="" />'.
+                                               '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/undo.gif','width="13" height="12"').' title="'.htmlspecialchars($this->getLL('l_revertSelection')).'" alt="" />'.
                                                '</a>
                                        </td>
                                </tr>
@@ -1894,8 +1951,14 @@ class t3lib_TCEforms     {
                        // Get "removeItems":
                $removeItems = t3lib_div::trimExplode(',',$PA['fieldTSConfig']['removeItems'],1);
 
+                       // Get the array with selected items:
+               $itemArray = t3lib_div::trimExplode(',', $PA['itemFormElValue'], 1);
+
+                       // Possibly filter some items:
+               $keepItemsFunc = create_function('$value', '$parts=explode(\'|\',$value,2); return rawurldecode($parts[0]);');
+               $itemArray = t3lib_div::keepItemsInArray($itemArray, $PA['fieldTSConfig']['keepItems'], $keepItemsFunc);
+
                        // Perform modification of the selected items array:
-               $itemArray = t3lib_div::trimExplode(',',$PA['itemFormElValue'],1);
                foreach($itemArray as $tk => $tv) {
                        $tvP = explode('|',$tv,2);
                        $evalValue = rawurldecode($tvP[0]);
@@ -1984,8 +2047,8 @@ class t3lib_TCEforms      {
                $maxitems = t3lib_div::intInRange($config['maxitems'],0);
                if (!$maxitems) $maxitems=100000;
                $minitems = t3lib_div::intInRange($config['minitems'],0);
-               $allowed = $config['allowed'];
-               $disallowed = $config['disallowed'];
+               $allowed = trim($config['allowed']);
+               $disallowed = trim($config['disallowed']);
 
                $disabled = '';
                if($this->renderReadonly || $config['readOnly'])  {
@@ -2101,19 +2164,19 @@ class t3lib_TCEforms    {
                        case 'db':      // If the element is of the internal type "db":
 
                                        // Creating string showing allowed types:
-                               $tempFT = t3lib_div::trimExplode(',',$allowed,1);
-                               if (!strcmp(trim($tempFT[0]),'*'))      {
+                               $tempFT = t3lib_div::trimExplode(',', $allowed, true);
+                               if (!strcmp(trim($tempFT[0]), '*')) {
+                                       $onlySingleTableAllowed = false;
                                        $info.='<span class="nobr">&nbsp;&nbsp;&nbsp;&nbsp;'.
                                                        htmlspecialchars($this->getLL('l_allTables')).
                                                        '</span><br />';
-                               } else {
-                                       while(list(,$theT)=each($tempFT))       {
-                                               if ($theT)      {
-                                                       $info.='<span class="nobr">&nbsp;&nbsp;&nbsp;&nbsp;'.
-                                                                       t3lib_iconWorks::getIconImage($theT,array(),$this->backPath,'align="top"').
-                                                                       htmlspecialchars($this->sL($GLOBALS['TCA'][$theT]['ctrl']['title'])).
-                                                                       '</span><br />';
-                                               }
+                               } elseif ($tempFT) {
+                                       $onlySingleTableAllowed = (count($tempFT) == 1);
+                                       foreach ($tempFT as $theT) {
+                                               $info.= '<span class="nobr">&nbsp;&nbsp;&nbsp;&nbsp;' .
+                                                               t3lib_iconWorks::getIconImage($theT, array(), $this->backPath, 'align="top"') .
+                                                               htmlspecialchars($this->sL($GLOBALS['TCA'][$theT]['ctrl']['title'])) .
+                                                               '</span><br />';
                                        }
                                }
 
@@ -2126,6 +2189,10 @@ class t3lib_TCEforms     {
                                foreach($temp_itemArray as $dbRead)     {
                                        $recordParts = explode('|',$dbRead);
                                        list($this_table,$this_uid) = t3lib_BEfunc::splitTable_Uid($recordParts[0]);
+                                       // For the case that no table was found and only a single table is defined to be allowed, use that one:
+                                       if (!$this_table && $onlySingleTableAllowed) {
+                                               $this_table = $allowed;
+                                       }
                                        $itemArray[] = array('table'=>$this_table, 'id'=>$this_uid);
                                        if (!$disabled && $show_thumbs) {
                                                $rr = t3lib_BEfunc::getRecordWSOL($this_table,$this_uid);
@@ -2470,6 +2537,8 @@ class t3lib_TCEforms      {
                                                        // If it's a "section" containing other elements:
                                                if ($value['section'])  {
 
+                                                               // Load script.aculo.us if flexform sections can be moved by drag'n'drop:
+                                                       $this->loadJavascriptLib('contrib/scriptaculous/scriptaculous.js');
                                                                // Render header of section:
                                                        $output.= '<div class="bgColor2"><strong>'.$theTitle.'</strong></div>';
 
@@ -2510,6 +2579,10 @@ class t3lib_TCEforms     {
                                                                // Traversing possible types of new content in the section:
                                                        $newElementsLinks = array();
                                                        foreach($value['el'] as $nnKey => $nCfg)        {
+                                                               $additionalJS_post_saved = $this->additionalJS_post;
+                                                               $this->additionalJS_post = array();
+                                                               $additionalJS_submit_saved = $this->additionalJS_submit;
+                                                               $this->additionalJS_submit = array();
                                                                $newElementTemplate = $this->getSingleField_typeFlex_draw(
                                                                        array($nnKey => $nCfg),
                                                                        array(),
@@ -2523,7 +2596,17 @@ class t3lib_TCEforms     {
                                                                );
 
                                                                        // Makes a "Add new" link:
-                                                               $onClickInsert = 'new Insertion.Bottom($("'.$idTagPrefix.'"), unescape("'.rawurlencode($newElementTemplate).'").replace(/'.$idTagPrefix.'-/g,"'.$idTagPrefix.'-idx"+Math.floor(Math.random()*100000+1)+"-")); setActionStatus("'.$idTagPrefix.'"); return false;';      // Maybe there is a better way to do this than store the HTML for the new element in rawurlencoded format - maybe it even breaks with certain charsets? But for now this works...
+                                                               $var = uniqid('idvar');
+                                                               $replace = 'replace(/' . $idTagPrefix . '-/g,"' . $idTagPrefix . '"+' . $var . '+"-")';
+                                                               $onClickInsert = 'var ' . $var . ' = "' . $idTagPrefix . '-idx"+(new Date()).getTime();';
+                                                               // Do not replace $isTagPrefix in setActionStatus() because it needs section id!
+                                                               $onClickInsert .= 'new Insertion.Bottom($("'.$idTagPrefix.'"), unescape("'.rawurlencode($newElementTemplate).'").' . $replace . '); setActionStatus("'.$idTagPrefix.'");';
+                                                               $onClickInsert .= 'eval(unescape("' . rawurlencode(implode(';', $this->additionalJS_post)) . '").' . $replace . ');';
+                                                               $onClickInsert .= 'TBE_EDITOR.addActionChecks("submit", unescape("' . rawurlencode(implode(';', $this->additionalJS_submit)) . '").' . $replace . ');';
+                                                               $onClickInsert .= 'return false;';
+                                                               // Kasper's comment (kept for history): Maybe there is a better way to do this than store the HTML for the new element in rawurlencoded format - maybe it even breaks with certain charsets? But for now this works...
+                                                               $this->additionalJS_post = $additionalJS_post_saved;
+                                                               $this->additionalJS_submit = $additionalJS_submit_saved;
                                                                $newElementsLinks[]= '<a href="#" onclick="'.htmlspecialchars($onClickInsert).'"><img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/new_el.gif','width="11" height="12"').' alt="New" title="New" align="absmiddle" />'.htmlspecialchars(t3lib_div::fixed_lgd_cs($this->sL($nCfg['tx_templavoila']['title']),30)).'</a>';
                                                        }
 
@@ -2540,15 +2623,15 @@ class t3lib_TCEforms    {
 
                                                        <div id="'.$idTagPrefix.'" style="padding-left: 20px;">'.implode('',$tRows).'</div>';
                                                        $output.= $mayRestructureFlexforms ? '<div style="padding: 10px 5px 5px 20px;"><b>Add new:</b> '.implode(' | ',$newElementsLinks).'</div>' : '';
-                                                       // If it's a container:
                                                } else {
+                                                       // It is a container
 
                                                        $toggleIcon_open = '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/pil2down.gif','width="12" height="7"').' hspace="2" alt="Open" title="Open" />';
                                                        $toggleIcon_close = '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/pil2right.gif','width="7" height="12"').' hspace="2" alt="Close" title="Close" />';
 
                                                                // Create on-click actions.
-                                               #       $onClickCopy = 'new Insertion.After($("'.$idTagPrefix.'"), getOuterHTML("'.$idTagPrefix.'").replace(/'.$idTagPrefix.'-/g,"'.$idTagPrefix.'-copy"+Math.floor(Math.random()*100000+1)+"-")); return false;';      // Copied elements doesn't work (well) in Safari while they do in Firefox and MSIE! UPDATE: It turned out that copying doesn't work for any browser, simply because the data from the copied form never gets submitted to the server for some reason! So I decided to simply disable copying for now. If it's requested by customers we can look to enable it again and fix the issue. There is one un-fixable problem though; Copying an element like this will violate integrity if files are attached inside that element because the file reference doesn't get an absolute path prefixed to it which would be required to have TCEmain generate a new copy of the file.
-                                                       $onClickRemove = 'if (confirm("Are you sure?")){$("'.$idTagPrefix.'").hide();setActionStatus("'.$idPrefix.'");} return false;';
+                                                       //$onClickCopy = 'new Insertion.After($("'.$idTagPrefix.'"), getOuterHTML("'.$idTagPrefix.'").replace(/'.$idTagPrefix.'-/g,"'.$idTagPrefix.'-copy"+Math.floor(Math.random()*100000+1)+"-")); return false;';    // Copied elements doesn't work (well) in Safari while they do in Firefox and MSIE! UPDATE: It turned out that copying doesn't work for any browser, simply because the data from the copied form never gets submitted to the server for some reason! So I decided to simply disable copying for now. If it's requested by customers we can look to enable it again and fix the issue. There is one un-fixable problem though; Copying an element like this will violate integrity if files are attached inside that element because the file reference doesn't get an absolute path prefixed to it which would be required to have TCEmain generate a new copy of the file.
+                                                       $onClickRemove = 'if (confirm("Are you sure?")){/*###REMOVE###*/;$("'.$idTagPrefix.'").hide();setActionStatus("'.$idPrefix.'");} return false;';
                                                        $onClickToggle = 'flexFormToggle("'.$idTagPrefix.'"); return false;';
 
                                                        $onMove = 'flexFormSortable("'.$idPrefix.'")';
@@ -2579,6 +2662,7 @@ class t3lib_TCEforms      {
                                                        $actionFieldName = '_ACTION_FLEX_FORM'.$PA['itemFormElName'].$s[0].'][_ACTION]['.$s[1];
 
                                                                // Putting together the container:
+                                                       $this->additionalJS_delete = array();
                                                        $output.= '
                                                                <div id="'.$idTagPrefix.'" class="bgColor2">
                                                                        <input id="'.$idTagPrefix.'-action" type="hidden" name="'.htmlspecialchars($actionFieldName).'" value=""/>
@@ -2598,6 +2682,7 @@ class t3lib_TCEforms      {
                                                                        </div>
                                                                        <input id="'.$idTagPrefix.'-toggleClosed" type="hidden" name="'.htmlspecialchars('data['.$table.']['.$row['uid'].']['.$field.']'.$formPrefix.'[_TOGGLE]').'" value="'.($toggleClosed?1:0).'" />
                                                                </div>';
+                                                       $output = str_replace('/*###REMOVE###*/', t3lib_div::slashJS(htmlspecialchars(implode('', $this->additionalJS_delete))), $output);
                                                                        // NOTICE: We are saving the toggle-state directly in the flexForm XML and "unauthorized" according to the data structure. It means that flexform XML will report unclean and a cleaning operation will remove the recorded togglestates. This is not a fatal problem. Ideally we should save the toggle states in meta-data but it is much harder to do that. And this implementation was easy to make and with no really harmful impact.
                                                }
 
@@ -3469,7 +3554,6 @@ class t3lib_TCEforms      {
                                        <td>'.$this->wrapLabels($params['headers']['selector']).'</td>
                                        <td></td>
                                        <td></td>
-                                       <td></td>
                                        <td>'.($params['thumbnails'] ? $this->wrapLabels($params['headers']['items']) : '').'</td>
                                </tr>':'').
                        '
@@ -3478,12 +3562,11 @@ class t3lib_TCEforms    {
                                        $selector.
                                        ($params['noList'] ? '' : '<br />'.$this->wrapLabels($params['info'])) .
                                '</td>
-                               <td valign="top">'.
+                               <td valign="top" class="icons">'.
                                        implode('<br />',$icons['L']).'</td>
-                               <td valign="top">'.
+                               <td valign="top" class="icons">'.
                                        implode('<br />',$icons['R']).'</td>
-                               <td><img src="clear.gif" width="5" height="1" alt="" /></td>
-                               <td valign="top">'.
+                               <td valign="top" class="thumbnails">'.
                                        $this->wrapLabels($params['thumbnails']).
                                '</td>
                        </tr>
@@ -3904,7 +3987,7 @@ class t3lib_TCEforms      {
         * @param       string          The string which - if empty - will become the no-title string.
         * @param       array           Array with wrappin parts for the no-title output (in keys [0]/[1])
         * @return      string
-        * @deprecated
+        * @deprecated since TYPO3 4.1
         */
        function noTitle($str,$wrapParts=array())       {
                return strcmp($str,'') ? $str : $wrapParts[0].'['.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.no_title').']'.$wrapParts[1];
@@ -5013,18 +5096,18 @@ class t3lib_TCEforms    {
 
                if (!$update) {
                        if ($this->loadMD5_JS) {
-                               $jsFile[] =     '<script type="text/javascript" src="'.$this->backPath.'md5.js"></script>';
+                               $this->loadJavascriptLib('md5.js');
                        }
 
-                       $jsFile[] = '<script type="text/javascript" src="'.$this->backPath.'contrib/prototype/prototype.js"></script>';
-                       $jsFile[] = '<script type="text/javascript" src="'.$this->backPath.'contrib/scriptaculous/scriptaculous.js"></script>';
-                       $jsFile[] =     '<script type="text/javascript" src="'.$this->backPath.'../t3lib/jsfunc.evalfield.js"></script>';
-                       $jsFile[] =     '<script type="text/javascript" src="'.$this->backPath.'jsfunc.tbe_editor.js"></script>';
+                       $this->loadJavascriptLib('contrib/prototype/prototype.js');
+                       $this->loadJavascriptLib('../t3lib/jsfunc.evalfield.js');
+                       // @TODO: Change to loadJavascriptLib(), but fix "TS = new typoScript()" issue first - see bug #9494
+                       $jsFile[] = '<script type="text/javascript" src="'.$this->backPath.'jsfunc.tbe_editor.js"></script>';
 
                                // if IRRE fields were processed, add the JavaScript functions:
                        if ($this->inline->inlineCount) {
-                               $jsFile[] = '<script src="'.$this->backPath.'contrib/scriptaculous/scriptaculous.js" type="text/javascript"></script>';
-                               $jsFile[] = '<script src="'.$this->backPath.'../t3lib/jsfunc.inline.js" type="text/javascript"></script>';
+                               $this->loadJavascriptLib('contrib/scriptaculous/scriptaculous.js');
+                               $this->loadJavascriptLib('../t3lib/jsfunc.inline.js');
                                $out .= '
                                inline.setPrependFormFieldNames("'.$this->inline->prependNaming.'");
                                inline.setNoTitleString("'.addslashes(t3lib_BEfunc::getNoRecordTitle(true)).'");
@@ -5118,25 +5201,26 @@ class t3lib_TCEforms    {
                        TBE_EDITOR.labels.refresh_login = '.$GLOBALS['LANG']->JScharCode($this->getLL('m_refresh_login')).';
                        TBE_EDITOR.labels.onChangeAlert = '.$GLOBALS['LANG']->JScharCode($this->getLL('m_onChangeAlert')).';
                        evalFunc.USmode = '.($GLOBALS['TYPO3_CONF_VARS']['SYS']['USdateFormat']?'1':'0').';
+                       TBE_EDITOR.backend_interface = "'.$GLOBALS['BE_USER']->uc['interfaceSetup'].'";
                        ';
                }
 
                        // add JS required for inline fields
                if (count($this->inline->inlineData)) {
                        $out .= '
-                       inline.addToDataArray('.t3lib_div::array2json($this->inline->inlineData).');
+                       inline.addToDataArray(' . json_encode($this->inline->inlineData) . ');
                        ';
                }
                        // Registered nested elements for tabs or inline levels:
                if (count($this->requiredNested)) {
                        $out .= '
-                       TBE_EDITOR.addNested('.t3lib_div::array2json($this->requiredNested).');
+                       TBE_EDITOR.addNested(' . json_encode($this->requiredNested) . ');
                        ';
                }
                        // elements which are required or have a range definition:
                if (count($elements)) {
                        $out .= '
-                       TBE_EDITOR.addElements('.t3lib_div::array2json($elements).');
+                       TBE_EDITOR.addElements(' . json_encode($elements) . ');
                        TBE_EDITOR.initRequired();
                        ';
                }
@@ -5157,8 +5241,8 @@ class t3lib_TCEforms      {
 
                        // Regular direct output:
                if (!$update) {
-                       $spacer = chr(10).chr(9);
-                       $out  = $spacer.implode($spacer, $jsFile).t3lib_div::wrapJS($out);
+                       $spacer = chr(10) . chr(9);
+                       $out  = $spacer . implode($spacer, $jsFile) . t3lib_div::wrapJS($out);
                }
 
                return $out;
@@ -5424,6 +5508,18 @@ class t3lib_TCEforms     {
                return $out;
        }
 
+       /**
+        * Includes a javascript library that exists in the core /typo3/ directory. The
+        * backpath is automatically applied.
+        * This method acts as wrapper for $GLOBALS['SOBE']->doc->loadJavascriptLib($lib).
+        *
+        * @param       string          $lib: Library name. Call it with the full path like "contrib/prototype/prototype.js" to load it
+        * @return      void
+        */
+       public function loadJavascriptLib($lib) {
+               $GLOBALS['SOBE']->doc->loadJavascriptLib($lib);
+       }
+
 
 
 
@@ -5896,7 +5992,7 @@ class t3lib_TCEforms      {
                if ($skipFirst) {
                        array_shift($result);
                }
-               return ($json ? t3lib_div::array2json($result) : $result);
+               return ($json ? json_encode($result) : $result);
        }
 
        /**
@@ -5940,6 +6036,19 @@ class t3lib_TCEforms     {
                        );
                }
        }
+
+       /**
+        * Insert additional style sheet link
+        *
+        * @param       string          $key: some key identifying the style sheet
+        * @param       string          $href: uri to the style sheet file
+        * @param       string          $title: value for the title attribute of the link element
+        * @return      string          $relation: value for the rel attribute of the link element
+        * @return      void
+        */
+       public function addStyleSheet($key, $href, $title='', $relation='stylesheet') {
+               $GLOBALS['SOBE']->doc->addStyleSheet($key, $href, $title, $relation);
+        }
 }
 
 
@@ -6018,9 +6127,39 @@ class t3lib_TCEforms_FE extends t3lib_TCEforms {
                <td nowrap="nowrap" bgcolor="#F6F2E6"><font face="verdana" size="1" color="black"><b>###FIELD_HEADER###</b></font></td>
        </tr>   ';
        }
+
+       /**
+        * Includes a javascript library that exists in the core /typo3/ directory. The
+        * backpath is automatically applied.
+        * This method adds the library to $GLOBALS['TSFE']->additionalHeaderData[$lib].
+        *
+        * @param       string          $lib: Library name. Call it with the full path like "contrib/prototype/prototype.js" to load it
+        * @return      void
+        */
+       public function loadJavascriptLib($lib) {
+               if (!isset($GLOBALS['TSFE']->additionalHeaderData[$lib])) {
+                       $GLOBALS['TSFE']->additionalHeaderData[$lib] = '<script type="text/javascript" src="' . $this->backPath . $lib . '"></script>';
+               }
+       }
+
+       /**
+        * Insert additional style sheet link
+        *
+        * @param       string          $key: some key identifying the style sheet
+        * @param       string          $href: uri to the style sheet file
+        * @param       string          $title: value for the title attribute of the link element
+        * @return      string          $relation: value for the rel attribute of the link element
+        * @return      void
+        */
+       public function addStyleSheet($key, $href, $title='', $relation='stylesheet') {
+               if (!isset($GLOBALS['TSFE']->additionalHeaderData[$key])) {
+                       $GLOBALS['TSFE']->additionalHeaderData[$key] = '<link rel="' . $relation . '" type="text/css" href="' . $href . '"' . ($title ? (' title="' . $title . '"') : '') . ' />';
+               }
+        }
 }
 
 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_tceforms.php']) {
        include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_tceforms.php']);
 }
+
 ?>