diff --git a/tests/templates/SSViewerTestCommentsFullSource.ss b/tests/templates/SSViewerTestComments/SSViewerTestCommentsFullSource.ss similarity index 100% rename from tests/templates/SSViewerTestCommentsFullSource.ss rename to tests/templates/SSViewerTestComments/SSViewerTestCommentsFullSource.ss diff --git a/tests/templates/SSViewerTestComments/SSViewerTestCommentsFullSourceHTML4Doctype.ss b/tests/templates/SSViewerTestComments/SSViewerTestCommentsFullSourceHTML4Doctype.ss new file mode 100644 index 000000000..ec38777ce --- /dev/null +++ b/tests/templates/SSViewerTestComments/SSViewerTestCommentsFullSourceHTML4Doctype.ss @@ -0,0 +1,6 @@ + + + + + diff --git a/tests/templates/SSViewerTestComments/SSViewerTestCommentsFullSourceIfIE.ss b/tests/templates/SSViewerTestComments/SSViewerTestCommentsFullSourceIfIE.ss new file mode 100644 index 000000000..676405f4a --- /dev/null +++ b/tests/templates/SSViewerTestComments/SSViewerTestCommentsFullSourceIfIE.ss @@ -0,0 +1,7 @@ + + + + + + + diff --git a/tests/templates/SSViewerTestComments/SSViewerTestCommentsFullSourceIfIENoDoctype.ss b/tests/templates/SSViewerTestComments/SSViewerTestCommentsFullSourceIfIENoDoctype.ss new file mode 100644 index 000000000..a34df2c3e --- /dev/null +++ b/tests/templates/SSViewerTestComments/SSViewerTestCommentsFullSourceIfIENoDoctype.ss @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/templates/SSViewerTestComments/SSViewerTestCommentsFullSourceNoDoctype.ss b/tests/templates/SSViewerTestComments/SSViewerTestCommentsFullSourceNoDoctype.ss new file mode 100644 index 000000000..2cb856a7f --- /dev/null +++ b/tests/templates/SSViewerTestComments/SSViewerTestCommentsFullSourceNoDoctype.ss @@ -0,0 +1,4 @@ + + + + diff --git a/tests/templates/SSViewerTestCommentsInclude.ss b/tests/templates/SSViewerTestComments/SSViewerTestCommentsInclude.ss similarity index 100% rename from tests/templates/SSViewerTestCommentsInclude.ss rename to tests/templates/SSViewerTestComments/SSViewerTestCommentsInclude.ss diff --git a/tests/templates/SSViewerTestCommentsPartialSource.ss b/tests/templates/SSViewerTestComments/SSViewerTestCommentsPartialSource.ss similarity index 100% rename from tests/templates/SSViewerTestCommentsPartialSource.ss rename to tests/templates/SSViewerTestComments/SSViewerTestCommentsPartialSource.ss diff --git a/tests/templates/SSViewerTestCommentsWithInclude.ss b/tests/templates/SSViewerTestComments/SSViewerTestCommentsWithInclude.ss similarity index 100% rename from tests/templates/SSViewerTestCommentsWithInclude.ss rename to tests/templates/SSViewerTestComments/SSViewerTestCommentsWithInclude.ss diff --git a/tests/view/SSViewerTest.php b/tests/view/SSViewerTest.php index a82ecee21..92b181b28 100644 --- a/tests/view/SSViewerTest.php +++ b/tests/view/SSViewerTest.php @@ -1062,43 +1062,98 @@ after') $origEnv = Config::inst()->get('Director', 'environment_type'); Config::inst()->update('Director', 'environment_type', 'dev'); Config::inst()->update('SSViewer', 'source_file_comments', true); - - $view = new SSViewer(array('SSViewerTestCommentsFullSource')); - $data = new ArrayData(array()); - - $result = $view->process($data); - $expected = ' - - - - -'; - $this->assertEquals($result, $expected); - - $view = new SSViewer(array('SSViewerTestCommentsPartialSource')); - $data = new ArrayData(array()); - - $result = $view->process($data); - $expected = '' - . '
'; - $this->assertEquals($result, $expected); - - $view = new SSViewer(array('SSViewerTestCommentsWithInclude')); - $data = new ArrayData(array()); - - $result = $view->process($data); - $expected = '' - . '
Included' - . '
'; - $this->assertEquals($result, $expected); - + $f = FRAMEWORK_PATH . '/tests/templates/SSViewerTestComments'; + $templates = array( + array( + 'name' => 'SSViewerTestCommentsFullSource', + 'expected' => "" + . "" + . "" + . "" + . "\t" + . "\t" + . "" + . "", + ), + array( + 'name' => 'SSViewerTestCommentsFullSourceHTML4Doctype', + 'expected' => "" + . "" + . "" + . "" + . "\t" + . "\t" + . "" + . "", + ), + array( + 'name' => 'SSViewerTestCommentsFullSourceNoDoctype', + 'expected' => "" + . "" + . "\t" + . "\t" + . "", + ), + array( + 'name' => 'SSViewerTestCommentsFullSourceIfIE', + 'expected' => "" + . "" + . "" + . "" + . "" + . " " + . "\t" + . "\t" + . "" + . "", + ), + array( + 'name' => 'SSViewerTestCommentsFullSourceIfIENoDoctype', + 'expected' => "" + . "" + . "" + . " " + . "" + . " " + . "\t" + . "\t" + . "", + ), + array( + 'name' => 'SSViewerTestCommentsPartialSource', + 'expected' => + "" + . "
" + . "", + ), + array( + 'name' => 'SSViewerTestCommentsWithInclude', + 'expected' => + "" + . "
" + . "" + . "" + . "Included" + . "" + . "" + . "
" + . "", + ), + ); + foreach ($templates as $template) { + $this->_renderWithSourceFileComments($template['name'], $template['expected']); + } Config::inst()->update('SSViewer', 'source_file_comments', false); Config::inst()->update('Director', 'environment_type', $origEnv); } + private function _renderWithSourceFileComments($name, $expected) { + $viewer = new SSViewer(array($name)); + $data = new ArrayData(array()); + $result = $viewer->process($data); + $expected = str_replace(array("\r", "\n"), '', $expected); + $result = str_replace(array("\r", "\n"), '', $result); + $this->assertEquals($result, $expected); + } public function testLoopIteratorIterator() { $list = new PaginatedList(new ArrayList()); diff --git a/view/SSTemplateParser.php b/view/SSTemplateParser.php index 9c48c8e7f..c3e3532b6 100644 --- a/view/SSTemplateParser.php +++ b/view/SSTemplateParser.php @@ -4590,23 +4590,47 @@ class SSTemplateParser extends Parser { // Get the result $code = $result['php']; } - + // Include top level debugging comments if desired if($includeDebuggingComments && $templateName && stripos($code, "]*>)/i', "\\1", $code); - $code = preg_replace('/(<\/html[^>]*>)/i', "\\1", $code); - } else { - $code = str_replace('\';' . "\n", $code); - $code .= "\n" . '$val .= \'\';'; - } + $code = $parser->includeDebuggingComments($code, $templateName); } return $code; } + + /** + * @param string $code + * @return string $code + */ + protected function includeDebuggingComments($code, $templateName) { + // If this template contains a doctype, put it right after it, + // if not, put it after the tag to avoid IE glitches + if(stripos($code, "]*("[^"]")*[^>]*>)/im', "$1\r\n", $code); + $code .= "\r\n" . '$val .= \'\';'; + } elseif(stripos($code, "]*>)(.*)/i', function($matches) use ($templateName) { + if (stripos($matches[3], '') !== false) { + // after this tag there is a comment close but no comment has been opened + // this most likely means that this tag is inside a comment + // we should not add a comment inside a comment (invalid html) + // lets append it at the end of the comment + // an example case for this is the html5boilerplate: + return $matches[0]; + } else { + // all other cases, add the comment and return it + return "{$matches[1]}{$matches[2]}{$matches[3]}"; + } + }, $code); + $code = preg_replace('/(<\/html[^>]*>)/i', "$1", $code); + } else { + $code = str_replace('\';' . "\r\n", $code); + $code .= "\r\n" . '$val .= \'\';'; + } + return $code; + } /** * Compiles some file that contains template source code, and returns the php code that will execute as per that diff --git a/view/SSTemplateParser.php.inc b/view/SSTemplateParser.php.inc index ea01957c4..68249b3ed 100644 --- a/view/SSTemplateParser.php.inc +++ b/view/SSTemplateParser.php.inc @@ -1044,23 +1044,47 @@ class SSTemplateParser extends Parser { // Get the result $code = $result['php']; } - + // Include top level debugging comments if desired if($includeDebuggingComments && $templateName && stripos($code, "]*>)/i', "\\1", $code); - $code = preg_replace('/(<\/html[^>]*>)/i', "\\1", $code); - } else { - $code = str_replace('\';' . "\n", $code); - $code .= "\n" . '$val .= \'\';'; - } + $code = $parser->includeDebuggingComments($code, $templateName); } return $code; } + + /** + * @param string $code + * @return string $code + */ + protected function includeDebuggingComments($code, $templateName) { + // If this template contains a doctype, put it right after it, + // if not, put it after the tag to avoid IE glitches + if(stripos($code, "]*("[^"]")*[^>]*>)/im', "$1\r\n", $code); + $code .= "\r\n" . '$val .= \'\';'; + } elseif(stripos($code, "]*>)(.*)/i', function($matches) use ($templateName) { + if (stripos($matches[3], '') !== false) { + // after this tag there is a comment close but no comment has been opened + // this most likely means that this tag is inside a comment + // we should not add a comment inside a comment (invalid html) + // lets append it at the end of the comment + // an example case for this is the html5boilerplate: + return $matches[0]; + } else { + // all other cases, add the comment and return it + return "{$matches[1]}{$matches[2]}{$matches[3]}"; + } + }, $code); + $code = preg_replace('/(<\/html[^>]*>)/i', "$1", $code); + } else { + $code = str_replace('\';' . "\r\n", $code); + $code .= "\r\n" . '$val .= \'\';'; + } + return $code; + } /** * Compiles some file that contains template source code, and returns the php code that will execute as per that