Fix escaping of tags with multiple slashes

This commit is contained in:
Dmitriy Simushev 2015-06-01 15:15:52 +00:00
parent 04f963a21f
commit 824ae885c6
2 changed files with 20 additions and 2 deletions

View File

@ -149,7 +149,15 @@ class Tokenizer
switch ($this->state) {
case self::IN_TEXT:
if ($this->tagChange($this->otag. self::T_TRIM, $text, $i) and !$this->escaped) {
// Handlebars.js does not think that openning curly brace in
// "\\\{{data}}" template is escaped. Instead it removes one
// slash and leaves others "as is". To emulate similar behavior
// we have to check the last character in the buffer. If it's a
// slash we actually does not need to escape openning curly
// brace.
$prev_slash = substr($this->buffer, -1) == '\\';
if ($this->tagChange($this->otag. self::T_TRIM, $text, $i) and (!$this->escaped || $prev_slash)) {
$this->flushBuffer();
$this->state = self::IN_TAG_TYPE;
$this->trimLeft = true;
@ -157,7 +165,7 @@ class Tokenizer
$this->buffer .= "{{{";
$i += 2;
continue;
} elseif ($this->tagChange($this->otag, $text, $i) and !$this->escaped) {
} elseif ($this->tagChange($this->otag, $text, $i) and (!$this->escaped || $prev_slash)) {
$i--;
$this->flushBuffer();
$this->state = self::IN_TAG_TYPE;

View File

@ -127,6 +127,16 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase
array('data' => 'foo'),
'\\foo' // is equals to \foo in output
),
array(
'\\\\\\{{data}}', // is equal to \\\{{data}} in template file
array('data' => 'foo'),
'\\\\foo' // is equals to \\foo in output
),
array(
'\\\\\\\\{{data}}', // is equal to \\\\{{data}} in template file
array('data' => 'foo'),
'\\\\\\foo' // is equals to \\\foo in output
),
array(
'\{{{data}}}', // is equal to \{{{data}}} in template file
array('data' => 'foo'),