Skip to content

Commit

Permalink
DEP Use masterminds/html5 for HTMLValue
Browse files Browse the repository at this point in the history
  • Loading branch information
emteknetnz committed Jan 16, 2023
1 parent 6d45425 commit df04994
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 64 deletions.
3 changes: 0 additions & 3 deletions _config/html.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@
Name: corehtml
---
SilverStripe\Core\Injector\Injector:
SilverStripe\View\Parsers\HTMLValue:
class: SilverStripe\View\Parsers\HTML4Value
# Shorthand
HTMLValue: '%$SilverStripe\View\Parsers\HTMLValue'
SilverStripe\Forms\HTMLEditor\HTMLEditorConfig:
class: SilverStripe\Forms\HTMLEditor\TinyMCEConfig
SilverStripe\Forms\HTMLEditor\TinyMCEScriptGenerator: '%$SilverStripe\Forms\HTMLEditor\TinyMCECombinedGenerator'
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"embed/embed": "^4.4.7",
"league/csv": "^9.8.0",
"m1/env": "^2.2.0",
"masterminds/html5": "^2.7",
"monolog/monolog": "^3.2.0",
"nikic/php-parser": "^4.15.0",
"psr/container": "^2.0",
Expand Down
31 changes: 0 additions & 31 deletions src/View/Parsers/HTML4Value.php

This file was deleted.

30 changes: 24 additions & 6 deletions src/View/Parsers/HTMLValue.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use SilverStripe\Core\Convert;
use SilverStripe\View\ViewableData;
use Masterminds\HTML5;
use DOMNodeList;
use DOMXPath;
use DOMDocument;
Expand All @@ -12,14 +13,10 @@
* This class handles the converting of HTML fragments between a string and a DOMDocument based
* representation.
*
* It's designed to allow dependency injection to replace the standard HTML4 version with one that
* handles XHTML or HTML5 instead
*
* @mixin DOMDocument
*/
abstract class HTMLValue extends ViewableData
class HTMLValue extends ViewableData
{

public function __construct($fragment = null)
{
if ($fragment) {
Expand All @@ -28,7 +25,25 @@ public function __construct($fragment = null)
parent::__construct();
}

abstract public function setContent($fragment);
/**
* @param string $content
* @return bool
*/
public function setContent($content)
{
$content = preg_replace('#</?(html|head|body)[^>]*>#si', '', $content);
$html5 = new HTML5();
$document = $html5->loadHTML(
'<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head>' .
"<body>$content</body></html>"
);
if ($document) {
$this->setDocument($document);
return true;
}
$this->valid = false;
return false;
}

/**
* @return string
Expand Down Expand Up @@ -77,6 +92,9 @@ public function getContent()
// Possible alternative solution: http://stackoverflow.com/questions/2142120/php-encoding-with-domdocument
$from = mb_convert_encoding('&nbsp;', 'utf-8', 'html-entities');
$res = str_replace($from ?? '', '&nbsp;', $res ?? '');

// remove closing </meta> tags when they're not required
$res = preg_replace('#(<meta[^>]*>)</meta>#', '$1', $res);

return $res;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
namespace SilverStripe\View\Tests\Parsers;

use SilverStripe\Dev\SapphireTest;
use SilverStripe\View\Parsers\HTML4Value;
use SilverStripe\View\Parsers\HTMLValue;

class HTML4ValueTest extends SapphireTest
class HTMLValueTest extends SapphireTest
{
public function testInvalidHTMLSaving()
{
$value = new HTML4Value();
$value = new HTMLValue();

$invalid = [
'<p>Enclosed Value</p></p>'
Expand All @@ -32,35 +32,40 @@ public function testInvalidHTMLSaving()

public function testUtf8Saving()
{
$value = new HTML4Value();
$value = new HTMLValue();

$value->setContent('<p>ö ß ā い 家</p>');
$this->assertEquals('<p>ö ß ā い 家</p>', $value->getContent());
}

public function testInvalidHTMLTagNames()
/**
* @dataProvider provideInvalidHTMLTagNames
*/
public function testInvalidHTMLTagNames(string $input)
{
$value = new HTML4Value();
$value = new HTMLValue();
$value->setContent($input);
$link = $value->getElementsByTagName('a')->item(0);
$this->assertNotNull($link);
$this->assertEquals(
'test-link',
$link->getAttribute('href'),
'Link data can be extracted from malformed HTML'
);
}

$invalid = [
'<p><div><a href="test-link"></p></div>',
'<html><div><a href="test-link"></a></a></html_>',
'""\'\'\'"""\'""<<<>/</<htmlbody><a href="test-link"<<>'
public function provideInvalidHTMLTagNames()
{
return [
['<p><div><a href="test-link"></p></div>'],
['<html><div><a href="test-link"></a></a></html_>'],
['<x<b<c c=\'"\'><htmlbody><a href="test-link">']
];

foreach ($invalid as $input) {
$value->setContent($input);
$this->assertEquals(
'test-link',
$value->getElementsByTagName('a')->item(0)->getAttribute('href'),
'Link data can be extracted from malformed HTML'
);
}
}

public function testMixedNewlines()
{
$value = new HTML4Value();
$value = new HTMLValue();

$value->setContent("<p>paragraph</p>\n<ul><li>1</li>\r\n</ul>");
$this->assertEquals(
Expand All @@ -72,18 +77,18 @@ public function testMixedNewlines()

public function testAttributeEscaping()
{
$value = new HTML4Value();
$value = new HTMLValue();

$value->setContent('<a href="[]"></a>');
$this->assertEquals('<a href="[]"></a>', $value->getContent(), "'[' character isn't escaped");

$value->setContent('<a href="&quot;"></a>');
$this->assertEquals('<a href="&quot;"></a>', $value->getContent(), "'\"' character is escaped");
$value->setContent('<a href="\'&quot;"></a>');
$this->assertEquals('<a href="\'&quot;"></a>', $value->getContent(), "'\"' character is escaped");
}

public function testGetContent()
{
$value = new HTML4Value();
$value = new HTMLValue();

$value->setContent('<p>This is valid</p>');
$this->assertEquals('<p>This is valid</p>', $value->getContent(), "Valid content is returned");
Expand Down

0 comments on commit df04994

Please sign in to comment.