Merge pull request #793 from halkyon/htmlvalue_parsing_fixes

BUG HtmlEditorField doesn't save HTML fragments in HTMLValue correctly
This commit is contained in:
Ingo Schommer 2012-09-20 02:09:36 -07:00
commit e44a3558dd
3 changed files with 35 additions and 30 deletions

View File

@ -19,7 +19,7 @@ class SS_HTMLValue extends ViewableData {
public function __construct($content = null) { public function __construct($content = null) {
$this->document = new DOMDocument('1.0', 'UTF-8'); $this->document = new DOMDocument('1.0', 'UTF-8');
$this->document->scrictErrorChecking = false; $this->document->scrictErrorChecking = false;
$this->setContent($content); $this->setContent($content);
parent::__construct(); parent::__construct();
@ -29,14 +29,19 @@ class SS_HTMLValue extends ViewableData {
* @return string * @return string
*/ */
public function getContent() { public function getContent() {
// strip the body tags from the output (which are automatically added by DOMDocument) // strip any surrounding tags before the <body> and after the </body> which are automatically added by DOMDocument
return preg_replace ( // note that we can't use the argument to saveHTML() as it's only supported in PHP 5.3.6+, we support 5.3.2 as a minimum
array ( // in addition to the above, trim any surrounding newlines from the output
'/^\s*<body[^>]*>/i', return trim(
'/<\/body[^>]*>\s*$/i' preg_replace(
), array(
null, '/^<!DOCTYPE.+?>/i',
$this->getDocument()->saveXML($this->getDocument()->documentElement->lastChild) '/(.*)<body>/i',
'/<\/body>(.*)/i',
),
'',
$this->getDocument()->saveHTML()
)
); );
} }

View File

@ -30,7 +30,7 @@ class HtmlEditorFieldTest extends FunctionalTest {
public function testNullSaving() { public function testNullSaving() {
$obj = new HtmlEditorFieldTest_Object(); $obj = new HtmlEditorFieldTest_Object();
$editor = new HtmlEditorField('Content'); $editor = new HtmlEditorField('Content');
$editor->setValue(null); $editor->setValue(null);
$editor->saveInto($obj); $editor->saveInto($obj);
@ -39,29 +39,31 @@ class HtmlEditorFieldTest extends FunctionalTest {
public function testImageInsertion() { public function testImageInsertion() {
$obj = new HtmlEditorFieldTest_Object(); $obj = new HtmlEditorFieldTest_Object();
$editor = new HtmlEditorField('Content'); $editor = new HtmlEditorField('Content');
$editor->setValue('<img src="assets/example.jpg" />'); $editor->setValue('<img src="assets/example.jpg" />');
$editor->saveInto($obj); $editor->saveInto($obj);
$xml = new SimpleXMLElement($obj->Content); $parser = new CSSContentParser($obj->Content);
$this->assertNotNull($xml['alt'], 'Alt tags are added by default.'); $xml = $parser->getByXpath('//img');
$this->assertNotNull($xml['title'], 'Title tags are added by default.'); $this->assertEquals('', $xml[0]['alt'], 'Alt tags are added by default.');
$this->assertEquals('', $xml[0]['title'], 'Title tags are added by default.');
$editor->setValue('<img src="assets/example.jpg" alt="foo" title="bar" />'); $editor->setValue('<img src="assets/example.jpg" alt="foo" title="bar" />');
$editor->saveInto($obj); $editor->saveInto($obj);
$xml = new SimpleXMLElement($obj->Content); $parser = new CSSContentParser($obj->Content);
$this->assertNotNull('foo', $xml['alt'], 'Alt tags are preserved.'); $xml = $parser->getByXpath('//img');
$this->assertNotNull('bar', $xml['title'], 'Title tags are preserved.'); $this->assertEquals('foo', $xml[0]['alt'], 'Alt tags are preserved.');
$this->assertEquals('bar', $xml[0]['title'], 'Title tags are preserved.');
} }
public function testMultiLineSaving() { public function testMultiLineSaving() {
$obj = $this->objFromFixture('HtmlEditorFieldTest_Object', 'home'); $obj = $this->objFromFixture('HtmlEditorFieldTest_Object', 'home');
$editor = new HtmlEditorField('Content'); $editor = new HtmlEditorField('Content');
$editor->setValue("<p>First Paragraph</p><p>Second Paragraph</p>"); $editor->setValue('<p>First Paragraph</p><p>Second Paragraph</p>');
$editor->saveInto($obj); $editor->saveInto($obj);
$this->assertEquals("<p>First Paragraph</p><p>Second Paragraph</p>", $obj->Content); $this->assertEquals('<p>First Paragraph</p><p>Second Paragraph</p>', $obj->Content);
} }
public function testSavingLinksWithoutHref() { public function testSavingLinksWithoutHref() {
@ -72,7 +74,7 @@ class HtmlEditorFieldTest extends FunctionalTest {
$editor->saveInto($obj); $editor->saveInto($obj);
$this->assertEquals ( $this->assertEquals (
'<p><a name="example-anchor"/></p>', $obj->Content, 'Saving a link without a href attribute works' '<p><a name="example-anchor"></a></p>', $obj->Content, 'Saving a link without a href attribute works'
); );
} }

View File

@ -9,8 +9,8 @@ class SS_HTMLValueTest extends SapphireTest {
$value = new SS_HTMLValue(); $value = new SS_HTMLValue();
$invalid = array ( $invalid = array (
'<p>Enclosed Value</p></p>' => '<p>Enclosed Value</p>', '<p>Enclosed Value</p></p>' => '<p>Enclosed Value</p>',
'<p><div class="example"></div></p>' => '<p/><div class="example"/>', '<p><div class="example"></div></p>' => '<p></p><div class="example"></div>',
'<html><html><body><falsetag "attribute=""attribute""">' => '<falsetag/>', '<html><html><body><falsetag "attribute=""attribute""">' => '<falsetag></falsetag>',
'<body<body<body>/bodu>/body>' => '/bodu&gt;/body&gt;' '<body<body<body>/bodu>/body>' => '/bodu&gt;/body&gt;'
); );
@ -22,7 +22,7 @@ class SS_HTMLValueTest extends SapphireTest {
public function testInvalidHTMLTagNames() { public function testInvalidHTMLTagNames() {
$value = new SS_HTMLValue(); $value = new SS_HTMLValue();
$invalid = array ( $invalid = array(
'<p><div><a href="test-link"></p></div>', '<p><div><a href="test-link"></p></div>',
'<html><div><a href="test-link"></a></a></html_>', '<html><div><a href="test-link"></a></a></html_>',
'""\'\'\'"""\'""<<<>/</<htmlbody><a href="test-link"<<>' '""\'\'\'"""\'""<<<>/</<htmlbody><a href="test-link"<<>'
@ -40,11 +40,9 @@ class SS_HTMLValueTest extends SapphireTest {
public function testMixedNewlines() { public function testMixedNewlines() {
$value = new SS_HTMLValue(); $value = new SS_HTMLValue();
$eol = "\n"; $value->setContent("<p>paragraph</p>\n<ul><li>1</li>\r\n</ul>");
$platformEOL = PHP_EOL; // native EOL for platform. Windows is \r\n (CR-LF). UNIX is LF
$value->setContent("<p>paragraph</p>{$platformEOL}<ul><li>1</li>\r\n</ul>");
$this->assertEquals( $this->assertEquals(
"<p>paragraph</p>{$eol}<ul><li>1</li>{$eol}</ul>", "<p>paragraph</p>\n<ul><li>1</li>\n</ul>",
$value->getContent(), $value->getContent(),
'Newlines get converted' 'Newlines get converted'
); );