Strip now removes whitespaces after comment (#582)

* Mark text sections as to be stripped, but do not strip them right away. Combine equivalent sections in chunks at the template level and strip combined chunks where possible.
- simplified Smarty_Internal_TemplateCompilerBase::processText along the way
Fixes #447
This commit is contained in:
Simon Wisselink
2020-04-13 22:27:42 +02:00
committed by GitHub
parent 4f89f6d84f
commit 19ef8342aa
7 changed files with 165 additions and 119 deletions

13
TODO.md
View File

@@ -1,18 +1,5 @@
# Todo # Todo
## Add unit test for strip issue in correct branch
tests/UnitTests/TemplateSource/TagTests/Strip/CompileStripTest.php
```
@@ -76,6 +76,7 @@ class CompileStripTest extends PHPUnit_Smarty
array("{'Var'}\n <b></b> <c></c>", 'Var<b></b> <c></c>', '', $i ++),
array("\n<b></b> <c></c>", '<b></b> <c></c>', '', $i ++),
array("\n<b></b>\n <c></c>", '<b></b><c></c>', '', $i ++),
+ array("\n<b>\n {* a comment *}\n <c>", '<b><c>', '', $i ++),
);
}
```
## Add unit test for isset issue in correct branch ## Add unit test for isset issue in correct branch
tests/UnitTests/TemplateSource/ValueTests/PHPfunctions/PhpFunctionTest.php tests/UnitTests/TemplateSource/ValueTests/PHPfunctions/PhpFunctionTest.php
```php ```php

View File

@@ -1,3 +1,4 @@
- remove whitespaces after comments https://github.com/smarty-php/smarty/issues/447
- fix foreachelse on arrayiterators https://github.com/smarty-php/smarty/issues/506 - fix foreachelse on arrayiterators https://github.com/smarty-php/smarty/issues/506
- throw SmartyException when setting caching attributes for cacheable plugin https://github.com/smarty-php/smarty/issues/457 - throw SmartyException when setting caching attributes for cacheable plugin https://github.com/smarty-php/smarty/issues/457
- fix errors that occured where isset was replaced with null check such as https://github.com/smarty-php/smarty/issues/453 - fix errors that occured where isset was replaced with null check such as https://github.com/smarty-php/smarty/issues/453

View File

@@ -85,45 +85,85 @@ class Smarty_Internal_ParseTree_Template extends Smarty_Internal_ParseTree
public function to_smarty_php(Smarty_Internal_Templateparser $parser) public function to_smarty_php(Smarty_Internal_Templateparser $parser)
{ {
$code = ''; $code = '';
for ($key = 0, $cnt = count($this->subtrees); $key < $cnt; $key++) {
if ($this->subtrees[ $key ] instanceof Smarty_Internal_ParseTree_Text) { foreach ($this->getChunkedSubtrees() as $chunk) {
$subtree = $this->subtrees[ $key ]->to_smarty_php($parser); $text = '';
while ($key + 1 < $cnt && ($this->subtrees[ $key + 1 ] instanceof Smarty_Internal_ParseTree_Text || switch ($chunk['mode']) {
$this->subtrees[ $key + 1 ]->data === '')) { case 'textstripped':
$key++; foreach ($chunk['subtrees'] as $subtree) {
if ($this->subtrees[ $key ]->data === '') { $text .= $subtree->to_smarty_php($parser);
continue;
}
$subtree .= $this->subtrees[ $key ]->to_smarty_php($parser);
}
if ($subtree === '') {
continue;
} }
$code .= preg_replace( $code .= preg_replace(
'/((<%)|(%>)|(<\?php)|(<\?)|(\?>)|(<\/?script))/', '/((<%)|(%>)|(<\?php)|(<\?)|(\?>)|(<\/?script))/',
"<?php echo '\$1'; ?>\n", "<?php echo '\$1'; ?>\n",
$subtree $parser->compiler->processText($text)
); );
continue; break;
case 'text':
foreach ($chunk['subtrees'] as $subtree) {
$text .= $subtree->to_smarty_php($parser);
} }
if ($this->subtrees[ $key ] instanceof Smarty_Internal_ParseTree_Tag) { $code .= preg_replace(
$subtree = $this->subtrees[ $key ]->to_smarty_php($parser); '/((<%)|(%>)|(<\?php)|(<\?)|(\?>)|(<\/?script))/',
while ($key + 1 < $cnt && ($this->subtrees[ $key + 1 ] instanceof Smarty_Internal_ParseTree_Tag || "<?php echo '\$1'; ?>\n",
$this->subtrees[ $key + 1 ]->data === '')) { $text
$key++; );
if ($this->subtrees[ $key ]->data === '') { break;
continue; case 'tag':
foreach ($chunk['subtrees'] as $subtree) {
$text = $parser->compiler->appendCode($text, $subtree->to_smarty_php($parser));
} }
$subtree = $parser->compiler->appendCode($subtree, $this->subtrees[ $key ]->to_smarty_php($parser)); $code .= $text;
break;
default:
foreach ($chunk['subtrees'] as $subtree) {
$text = $subtree->to_smarty_php($parser);
} }
if ($subtree === '') { $code .= $text;
continue;
} }
$code .= $subtree;
continue;
}
$code .= $this->subtrees[ $key ]->to_smarty_php($parser);
} }
return $code; return $code;
} }
private function getChunkedSubtrees() {
$chunks = [];
$currentMode = null;
$currentChunk = [];
for ($key = 0, $cnt = count($this->subtrees); $key < $cnt; $key++) {
if ($this->subtrees[ $key ]->data === '' && in_array($currentMode, ['textstripped', 'text', 'tag'])) {
continue;
}
if ($this->subtrees[ $key ] instanceof Smarty_Internal_ParseTree_Text
&& $this->subtrees[ $key ]->isToBeStripped()) {
$newMode = 'textstripped';
} elseif ($this->subtrees[ $key ] instanceof Smarty_Internal_ParseTree_Text) {
$newMode = 'text';
} elseif ($this->subtrees[ $key ] instanceof Smarty_Internal_ParseTree_Tag) {
$newMode = 'tag';
} else {
$newMode = 'other';
}
if ($newMode == $currentMode) {
$currentChunk[] = $this->subtrees[ $key ];
} else {
$chunks[] = [
'mode' => $currentMode,
'subtrees' => $currentChunk
];
$currentMode = $newMode;
$currentChunk = [$this->subtrees[ $key ]];
}
}
if ($currentMode && $currentChunk) {
$chunks[] = [
'mode' => $currentMode,
'subtrees' => $currentChunk
];
}
return $chunks;
}
} }

View File

@@ -16,14 +16,31 @@
*/ */
class Smarty_Internal_ParseTree_Text extends Smarty_Internal_ParseTree class Smarty_Internal_ParseTree_Text extends Smarty_Internal_ParseTree
{ {
/**
* Wether this section should be stripped on output to smarty php
* @var bool
*/
private $toBeStripped = false;
/** /**
* Create template text buffer * Create template text buffer
* *
* @param string $data text * @param string $data text
* @param bool $toBeStripped wether this section should be stripped on output to smarty php
*/ */
public function __construct($data) public function __construct($data, $toBeStripped = false)
{ {
$this->data = $data; $this->data = $data;
$this->toBeStripped = $toBeStripped;
}
/**
* Wether this section should be stripped on output to smarty php
* @return bool
*/
public function isToBeStripped() {
return $this->toBeStripped;
} }
/** /**

View File

@@ -680,21 +680,23 @@ abstract class Smarty_Internal_TemplateCompilerBase
} }
/** /**
* This method is called from parser to process a text content section * This method is called from parser to process a text content section if strip is enabled
* - remove text from inheritance child templates as they may generate output * - remove text from inheritance child templates as they may generate output
* - strip text if strip is enabled
* *
* @param string $text * @param string $text
* *
* @return null|\Smarty_Internal_ParseTree_Text * @return string
*/ */
public function processText($text) public function processText($text)
{ {
if ((string)$text != '') {
if (strpos($text, '<') === false) {
return preg_replace($this->stripRegEx, '', $text);
}
$store = array(); $store = array();
$_store = 0; $_store = 0;
if ($this->parser->strip) {
if (strpos($text, '<') !== false) {
// capture html elements not to be messed with // capture html elements not to be messed with
$_offset = 0; $_offset = 0;
if (preg_match_all( if (preg_match_all(
@@ -740,13 +742,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
$_store++; $_store++;
} }
} }
} else { return $text;
$text = preg_replace($this->stripRegEx, '', $text);
}
}
return new Smarty_Internal_ParseTree_Text($text);
}
return null;
} }
/** /**

View File

@@ -2169,8 +2169,13 @@ class Smarty_Internal_Templateparser
// line 255 "../smarty/lexer/smarty_internal_templateparser.y" // line 255 "../smarty/lexer/smarty_internal_templateparser.y"
public function yy_r2() public function yy_r2()
{ {
$this->current_buffer->append_subtree($this, $text = $this->yystack[ $this->yyidx + 0 ]->minor;
$this->compiler->processText($this->yystack[ $this->yyidx + 0 ]->minor));
if ((string)$text == '') {
$this->current_buffer->append_subtree($this, null);
}
$this->current_buffer->append_subtree($this, new Smarty_Internal_ParseTree_Text($text, $this->strip));
} }
// line 259 "../smarty/lexer/smarty_internal_templateparser.y" // line 259 "../smarty/lexer/smarty_internal_templateparser.y"

View File

@@ -76,7 +76,7 @@ class CompileStripTest extends PHPUnit_Smarty
array("{'Var'}\n <b></b> <c></c>", 'Var<b></b> <c></c>', '', $i ++), array("{'Var'}\n <b></b> <c></c>", 'Var<b></b> <c></c>', '', $i ++),
array("\n<b></b> <c></c>", '<b></b> <c></c>', '', $i ++), array("\n<b></b> <c></c>", '<b></b> <c></c>', '', $i ++),
array("\n<b></b>\n <c></c>", '<b></b><c></c>', '', $i ++), array("\n<b></b>\n <c></c>", '<b></b><c></c>', '', $i ++),
array("\n<b>\n {* a comment *}\n <c>", '<b><c>', '', $i ++),
); );
} }