Index: tests/typo3/sysext/cms/tslib/tslib_content_testcase.php =================================================================== --- tests/typo3/sysext/cms/tslib/tslib_content_testcase.php (Revision 6395) +++ tests/typo3/sysext/cms/tslib/tslib_content_testcase.php (Arbeitskopie) @@ -124,5 +124,260 @@ return $imageResource; } + + /** + * Tests whether method "encapsLines" works properly + * + * @test + */ + public function check_encaps_lineSplit() { + $testValues = array( + // A single wrapped line should stay the same + 1 => array( + 'before' => '
Some text
', + 'after' => array( + 'conf1' => 'Some text
', + 'conf2' => 'Some text
', + ), + ), + // Multiple properly wrapped lines should stay the same + 2 => array( + 'before' => 'Some text
'.chr(10).'Another Text
', + 'after' => array( + 'conf1' => 'Some text
'.chr(10).'Another Text
', + 'conf2' => 'Some text
'.chr(10).'Another Text
', + ), + ), + // Check if single unwrapped line gets wrapped + 3 => array( + 'before' => 'Some text', + 'after' => array( + 'conf1' => 'Some text
', + 'conf2' => 'Some text
', + ) + ), + // Check if multiple unwrapped lines gets wrapped + 4 => array( + 'before' => 'Some text'.chr(10).'Another Text', + 'after' => array( + 'conf1' => 'Some text
'.chr(10).'Another Text
', + 'conf2' => 'Some text
'.chr(10).'Another Text
', + ), + ), + // Check if empty lines get wrapped properly + 5 => array( + 'before' => 'Some text
'.chr(10).chr(10).'Another Text
', + 'after' => array( + 'conf1' => 'Some text
'.chr(10).''.chr(10).'Another Text
', + 'conf2' => 'Some text
'.chr(10).''.chr(10).'Another Text
', + ), + ), + // Check if empty lines and non wrapped lines get wrapped properly + 6 => array( + 'before' => 'Some text'.chr(10).chr(10).'Another Text', + 'after' => array( + 'conf1' => 'Some text
'.chr(10).''.chr(10).'Another Text
', + 'conf2' => 'Some text
'.chr(10).''.chr(10).'Another Text
', + ), + ), + // Check if empty lines and non wrapped lines get wrapped properly + 7 => array( + 'before' => 'Some text
'.chr(10).chr(10).'Another Text', + 'after' => array( + 'conf1' => 'Some text
'.chr(10).''.chr(10).'Another Text
', + 'conf2' => 'Some text
'.chr(10).''.chr(10).'Another Text
', + ), + ), + // Check if+ 8 => array( + 'before' => '
Some text
'.chr(10).''.chr(10).'Another Text
', + 'conf2' => 'Some text
'.chr(10).''.chr(10).'Another Text
', + ), + ), + + // Check if single-tag is handled correct + 20 => array( + 'before' => 'Some text
'.chr(10).'Another Text
', + 'conf2' => 'Some text
'.chr(10).'Another Text
', + ), + 'singleTag' => true, + ), + // A single wrapped line should stay the same / Single-Tag + 25 => array( + 'before' => '|
', + ), + 'conf2' => array( + 'encapsTagList' => 'div, p, hr', + 'remapTag.' => array( + 'DIV' => 'P', + ), + 'addAttributes.' => array( + 'HR.' => array( + 'class' => 'changed', + ), + ), + 'nonWrappedTag' => 'P', + ), + ); + + // Running defined test-values using above configuration + foreach ($testValues as $key => $test) { + foreach ($conf as $confKey => $confArr) { + // Test new method + $result = $this->cObj->encaps_lineSplit($test['before'], $confArr); + // Test original method + $result_orig = $this->encaps_lineSplit($test['before'], $confArr); + + // Check if new method delivers expected result + $this->assertEquals($result, $test['after'][$confKey], 'Error #1 for test #'.$key.' using conf "'.$confKey.'" !'); + + // If this is a "singleTag" testcase old and new implementation have to differ + if ($test['singleTag']) { + $this->assertNotEquals($result, $result_orig, 'Error #2 for test #'.$key.' using conf "'.$confKey.'"'); + } else { + $this->assertEquals($result, $result_orig, 'Error #3 for test #'.$key.' using conf "'.$confKey.'"'); + } + } + } + + } + + + /** + * Original encaps_lineSplit method prior to "singleTag" patch. Remove in TYPO3 4.5 + * + * @param string The input value + * @param array TypoScript options + * @return string The processed input value being returned; Splitted lines imploded by chr(10) again. + * @access private + * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=323&cHash=a19312be78 + */ + function encaps_lineSplit($theValue, $conf) { + $lParts = explode(chr(10),$theValue); + + $encapTags = t3lib_div::trimExplode(',',strtolower($conf['encapsTagList']),1); + $nonWrappedTag = $conf['nonWrappedTag']; + $defaultAlign=trim($this->cObj->stdWrap($conf['defaultAlign'],$conf['defaultAlign.'])); + + if (!strcmp('',$theValue)) return ''; + + foreach ($lParts as $k => $l) { + $sameBeginEnd=0; + $l=trim($l); + $attrib=array(); + $nWrapped=0; + $byPass=0; + if (substr($l,0,1)=='<' && substr($l,-1)=='>') { + $fwParts = explode('>',substr($l,1),2); + $backParts = t3lib_div::revExplode('<', substr($fwParts[1],0,-1), 2); + $attrib = t3lib_div::get_tag_attributes('<'.$fwParts[0].'>'); + list($tagName) = explode(' ',$fwParts[0]); + $str_content = $backParts[0]; + $sameBeginEnd = (substr(strtolower($backParts[1]),1,strlen($tagName))==strtolower($tagName)); + } + + if ($sameBeginEnd && in_array(strtolower($tagName),$encapTags)) { + $uTagName = strtoupper($tagName); + $uTagName = strtoupper($conf['remapTag.'][$uTagName]?$conf['remapTag.'][$uTagName]:$uTagName); + } else { + $uTagName = strtoupper($nonWrappedTag); + $str_content = $lParts[$k]; + $nWrapped=1; + $attrib=array(); + } + + // Wrapping all inner-content: + if (is_array($conf['innerStdWrap_all.'])) {$str_content = $this->cObj->stdWrap($str_content,$conf['innerStdWrap_all.']);} + + if ($uTagName) { + // Setting common attributes + if (is_array($conf['addAttributes.'][$uTagName.'.'])) { + foreach ($conf['addAttributes.'][$uTagName.'.'] as $kk => $vv) { + if (!is_array($vv)) { + if ((string)$conf['addAttributes.'][$uTagName.'.'][$kk.'.']['setOnly']=='blank') { + if (!strcmp($attrib[$kk],'')) $attrib[$kk]=$vv; + } elseif ((string)$conf['addAttributes.'][$uTagName.'.'][$kk.'.']['setOnly']=='exists') { + if (!isset($attrib[$kk])) $attrib[$kk]=$vv; + } else { + $attrib[$kk]=$vv; + } + } + } + } + // Wrapping all inner-content: + if (is_array($conf['encapsLinesStdWrap.'][$uTagName.'.'])) {$str_content = $this->cObj->stdWrap($str_content,$conf['encapsLinesStdWrap.'][$uTagName.'.']);} + // Default align + if (!$attrib['align'] && $defaultAlign) $attrib['align']=$defaultAlign; + + $params = t3lib_div::implodeAttributes($attrib,1); + if ($conf['removeWrapping']) { + $str_content=$str_content; + } else { + $str_content='<'.strtolower($uTagName).(trim($params)?' '.trim($params):'').'>'.$str_content.''.strtolower($uTagName).'>'; + } + } + + if ($nWrapped && $conf['wrapNonWrappedLines']) {$str_content = $this->cObj->wrap($str_content,$conf['wrapNonWrappedLines']);} + $lParts[$k] = $str_content; + } + + return implode(chr(10),$lParts); + } + } ?> \ No newline at end of file Index: t3lib/class.t3lib_parsehtml.php =================================================================== --- t3lib/class.t3lib_parsehtml.php (Revision 6396) +++ t3lib/class.t3lib_parsehtml.php (Arbeitskopie) @@ -762,9 +762,13 @@ $tagContent = substr($tok,$endTag,$tagEnd-$endTag); $tagParts = preg_split('/\s+/s',$tagContent,2); $tagName = strtolower($tagParts[0]); + $singleTag = 0; if (isset($tags[$tagName])) { if (is_array($tags[$tagName])) { // If there is processing to do for the tag: + if (substr($tagParts[1], -1) == '/') { + $singleTag = 1; + } if (!$endTag) { // If NOT an endtag, do attribute processing (added dec. 2003) // Override attributes if (strcmp($tags[$tagName]['overrideAttribs'],'')) { @@ -900,11 +904,11 @@ if ($setTag) { // Setting the tag - $newContent[$c++]=$this->processTag($lt.($endTag?'/':'').trim($tagParts[0].' '.$tagParts[1]).$gt,$addConfig,$endTag,$lt=='<'); + $newContent[$c++]=$this->processTag($lt.($endTag?'/':'').trim($tagParts[0].' '.$tagParts[1]).($singleTag?' /':'').$gt,$addConfig,$endTag,$lt=='<'); } } } else { - $newContent[$c++]=$this->processTag('<'.($endTag?'/':'').$tagContent.'>',$addConfig,$endTag); + $newContent[$c++]=$this->processTag($x = '<'.($endTag?'/':'').$tagContent.'>',$addConfig,$endTag); } } elseif ($keepAll) { // This is if the tag was not defined in the array for processing: if (!strcmp($keepAll,'protect')) { Index: t3lib/class.t3lib_parsehtml_proc.php =================================================================== --- t3lib/class.t3lib_parsehtml_proc.php (Revision 6396) +++ t3lib/class.t3lib_parsehtml_proc.php (Arbeitskopie) @@ -102,7 +102,8 @@ class t3lib_parsehtml_proc extends t3lib_parsehtml { // Static: - var $blockElementList = 'PRE,UL,OL,H1,H2,H3,H4,H5,H6,HR,ADDRESS,DL,DD'; // List of tags for these elements + var $blockElementList = 'PRE,UL,OL,H1,H2,H3,H4,H5,H6,ADDRESS,DL,DD'; // List of tags for these elements + var $singleTagPatterns = '/(') { - // Only set p-tags if there is not already div or p tags: - $parts[$k]='<'.$dT.'>'.$parts[$k].''.$dT.'>'; + // Do not wrap single-tags like
tags + if (!preg_match($this->singleTagPatterns, $testStr)) { + if (substr($testStr,0,4)!='
') { + // Only set p-tags if there is not already div or p tags: + $parts[$k]='<'.$dT.'>'.$parts[$k].''.$dT.'>'; + } } } } - // Implode result: return implode(chr(10),$parts); } Index: typo3/sysext/cms/tslib/class.tslib_content.php =================================================================== --- typo3/sysext/cms/tslib/class.tslib_content.php (Revision 6395) +++ typo3/sysext/cms/tslib/class.tslib_content.php (Arbeitskopie) @@ -5119,20 +5119,31 @@ foreach ($lParts as $k => $l) { $sameBeginEnd=0; + $singleTag = 0; $l=trim($l); $attrib=array(); $nWrapped=0; - $byPass=0; if (substr($l,0,1)=='<' && substr($l,-1)=='>') { $fwParts = explode('>',substr($l,1),2); - $backParts = t3lib_div::revExplode('<', substr($fwParts[1],0,-1), 2); - $attrib = t3lib_div::get_tag_attributes('<'.$fwParts[0].'>'); - list($tagName) = explode(' ',$fwParts[0]); - $str_content = $backParts[0]; - $sameBeginEnd = (substr(strtolower($backParts[1]),1,strlen($tagName))==strtolower($tagName)); + list($tagName, $tagParams) = explode(' ',$fwParts[0], 2); + if (!$fwParts[1]) { + if (substr($tagName, -1) == '/') { + $tagName = substr($tagName, 0, -1); + } + if (substr($fwParts[0], -1) == '/') { + $sameBeginEnd = 1; + $singleTag = 1; + $attrib = t3lib_div::get_tag_attributes('<'.substr($fwParts[0], 0, -1).'>'); + } + } else { + $backParts = t3lib_div::revExplode('<', substr($fwParts[1],0,-1), 2); + $attrib = t3lib_div::get_tag_attributes('<'.$fwParts[0].'>'); + $str_content = $backParts[0]; + $sameBeginEnd = (substr(strtolower($backParts[1]),1,strlen($tagName))==strtolower($tagName)); + } } - if ($sameBeginEnd && in_array(strtolower($tagName),$encapTags)) { + if ($sameBeginEnd && in_array(strtolower($tagName), $encapTags)) { $uTagName = strtoupper($tagName); $uTagName = strtoupper($conf['remapTag.'][$uTagName]?$conf['remapTag.'][$uTagName]:$uTagName); } else { @@ -5143,7 +5154,7 @@ } // Wrapping all inner-content: - if (is_array($conf['innerStdWrap_all.'])) {$str_content = $this->stdWrap($str_content,$conf['innerStdWrap_all.']);} + if (is_array($conf['innerStdWrap_all.'])) {$str_content = $this->stdWrap($str_content, $conf['innerStdWrap_all.']);} if ($uTagName) { // Setting common attributes @@ -5151,9 +5162,13 @@ foreach ($conf['addAttributes.'][$uTagName.'.'] as $kk => $vv) { if (!is_array($vv)) { if ((string)$conf['addAttributes.'][$uTagName.'.'][$kk.'.']['setOnly']=='blank') { - if (!strcmp($attrib[$kk],'')) $attrib[$kk]=$vv; + if (!strcmp($attrib[$kk],'')) { + $attrib[$kk]=$vv; + } } elseif ((string)$conf['addAttributes.'][$uTagName.'.'][$kk.'.']['setOnly']=='exists') { - if (!isset($attrib[$kk])) $attrib[$kk]=$vv; + if (!isset($attrib[$kk])) { + $attrib[$kk]=$vv; + } } else { $attrib[$kk]=$vv; } @@ -5161,19 +5176,29 @@ } } // Wrapping all inner-content: - if (is_array($conf['encapsLinesStdWrap.'][$uTagName.'.'])) {$str_content = $this->stdWrap($str_content,$conf['encapsLinesStdWrap.'][$uTagName.'.']);} + if (is_array($conf['encapsLinesStdWrap.'][$uTagName.'.'])) { + $str_content = $this->stdWrap($str_content,$conf['encapsLinesStdWrap.'][$uTagName.'.']); + } // Default align - if (!$attrib['align'] && $defaultAlign) $attrib['align']=$defaultAlign; + if (!$attrib['align'] && $defaultAlign) { + $attrib['align']=$defaultAlign; + } $params = t3lib_div::implodeAttributes($attrib,1); - if ($conf['removeWrapping']) { + if ($conf['removeWrapping'] && !($singleTag && $conf['removeWrapping.']['keepSingleTag'])) { $str_content=$str_content; } else { - $str_content='<'.strtolower($uTagName).(trim($params)?' '.trim($params):'').'>'.$str_content.''.strtolower($uTagName).'>'; + if ($singleTag) { + $str_content='<'.strtolower($uTagName).(trim($params)?' '.trim($params):'').' />'; + } else { + $str_content='<'.strtolower($uTagName).(trim($params)?' '.trim($params):'').'>'.$str_content.''.strtolower($uTagName).'>'; + } } } - if ($nWrapped && $conf['wrapNonWrappedLines']) {$str_content = $this->wrap($str_content,$conf['wrapNonWrappedLines']);} + if ($nWrapped && $conf['wrapNonWrappedLines']) { + $str_content = $this->wrap($str_content,$conf['wrapNonWrappedLines']); + } $lParts[$k] = $str_content; }