Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Markup #262

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from
61 changes: 34 additions & 27 deletions src/Main/Markup/Html/Cdata.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,64 +11,71 @@

namespace OnPHP\Main\Markup\Html;

use OnPHP\Core\Base\Assert;

/**
* @ingroup Html
* @ingroup Module
**/
final class Cdata extends SgmlToken
{
private $data = null;

private $strict = false;
const CDATA_STRICT_START = '<![CDATA[';
const CDATA_STRICT_END = ']]>';

/**
* @return Cdata
**/
public static function create()
{
return new self;
}
* @var string|null
*/
private ?string $data = null;
/**
* @var bool
*/
private bool $strict = false;

/**
* @return Cdata
**/
public function setData($data)
* @param string $data
* @return static
*/
public function setData(string $data): Cdata
{
$this->data = $data;

return $this;
}

public function getData()
/**
* @return string|null
*/
public function getData(): ?string
{
if ($this->strict)
return '<![CDATA['.$this->data.']]>';
else
if ($this->strict) {
return self::CDATA_STRICT_START . $this->data . self::CDATA_STRICT_END;
} else {
return $this->data;
}
}

public function getRawData()
/**
* @return string|null
*/
public function getRawData(): ?string
{
return $this->data;
}

/**
* @return Cdata
**/
public function setStrict($isStrict)
* @param bool $isStrict
* @return static
*/
public function setStrict(bool $isStrict): Cdata
{
Assert::isBoolean($isStrict);

$this->strict = $isStrict;

return $this;
}

public function isStrict()
/**
* @return bool
*/
public function isStrict(): bool
{
return $this->strict;
}
}
?>
}
184 changes: 104 additions & 80 deletions src/Main/Markup/Html/HtmlAssembler.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@

namespace OnPHP\Main\Markup\Html;

use DOMCharacterData;
use DOMElement;
use DOMNode;
use OnPHP\Core\Base\Assert;
use OnPHP\Core\Exception\WrongArgumentException;
use OnPHP\Core\Exception\UnimplementedFeatureException;
Expand All @@ -20,90 +23,104 @@
**/
final class HtmlAssembler
{
private $tags = null;

public function __construct($tags)
/**
* @var SgmlToken[]
*/
private array $tags = [];

/**
* @param SgmlToken[] $tags
* @throws WrongArgumentException
*/
public function __construct(array $tags)
{
Assert::isTrue(current($tags) instanceof SgmlToken);
array_map(function ($item) {
Assert::isInstance($item, SgmlToken::class);
}, $tags ?? []);

$this->tags = $tags;
}

/**
* @param SgmlToken $tag
* @return string|null
* @throws WrongArgumentException
*/
public static function makeTag(SgmlToken $tag)
{
if ($tag instanceof Cdata)
$result = $tag->getData();
elseif ($tag instanceof SgmlIgnoredTag) {
if ($tag instanceof Cdata) {
return $tag->getData();
} elseif ($tag instanceof SgmlIgnoredTag) {
Assert::isNotNull($tag->getId());

$result = '<'.$tag->getId()
.$tag->getCdata()->getData()
return '<'.$tag->getId()
.($tag->getCdata() instanceof Cdata ? $tag->getCdata()->getData() : '')
.$tag->getEndMark().'>';

} elseif ($tag instanceof SgmlOpenTag) {
Assert::isNotNull($tag->getId());

$attributes = self::getAttributes($tag);

$result = '<'.$tag->getId()
.($attributes ? ' '.$attributes : null)
.($tag->isEmpty() ? '/' : null).'>';

return '<'.$tag->getId()
.($attributes ? ' '.$attributes : '')
.($tag->isEmpty() ? '/' : '').'>';
} elseif ($tag instanceof SgmlEndTag) {
$result = '</'.$tag->getId().'>';
Assert::isNotNull($tag->getId());

} else
throw new WrongArgumentException(
"don't know how to assemble tag class '"
.get_class($tag)."'"
);
return '</'.$tag->getId().'>';
}

return $result;
throw new WrongArgumentException(
"don't know how to assemble tag class '"
.get_class($tag)."'"
);
}

public static function makeDomNode(\DOMNode $node)
/**
* @param DOMNode $node
* @return string|null
* @throws UnimplementedFeatureException
*/
public static function makeDomNode(DOMNode $node): ?string
{
$result = null;

if ($node instanceof \DOMElement) {

$result = '<'.$node->nodeName;
if ($node instanceof DOMElement) {
$result = '<' . $node->nodeName;
$attributes = self::getDomAttributes($node);

$attributes = self::getDomAttributes($node);

if ($attributes)
$result .= ' '.$attributes;

if (!$node->firstChild) {
$result .= ' />';
} else {
$result .= '>';
}

$childNode = $node->firstChild;

while ($childNode) {
$result .= self::makeDomNode($childNode);
$childNode = $childNode->nextSibling;
}

if ($node->firstChild)
$result .= '</'.$node->nodeName.'>';

} elseif ($node instanceof \DOMCharacterData) {

$result = $node->data;
if ($attributes) {
$result .= ' ' . $attributes;
}

if (null === $node->firstChild) {
$result .= ' />';
} else {
throw new UnimplementedFeatureException(
'assembling of '.get_class($node).' is not implemented yet'
);
$result .= '>';
}

$childNode = $node->firstChild;
while ($childNode) {
$result .= self::makeDomNode($childNode);
$childNode = $childNode->nextSibling;
}

if ($node->firstChild) {
$result .= '</' . $node->nodeName . '>';
}
return $result;
} elseif ($node instanceof DOMCharacterData) {
return $node->data;
}

throw new UnimplementedFeatureException(
'assembling of '.get_class($node).' is not implemented yet'
);
}

public function getHtml()
/**
* @return string|null
* @throws WrongArgumentException
*/
public function getHtml(): ?string
{
$result = null;

Expand All @@ -114,43 +131,50 @@ public function getHtml()
return $result;
}

private static function getAttributes(SgmlOpenTag $tag)
/**
* @param SgmlOpenTag $tag
* @return string
*/
private static function getAttributes(SgmlOpenTag $tag): string
{
$attributes = array();

foreach ($tag->getAttributesList() as $name => $value) {
if ($value === null)
$quotedValue = null;
else
// FIXME: is multibyte safe?
$quotedValue = '="'.preg_replace('/\"/u', '&quot;', $value).'"';

$attributes[] = $name.$quotedValue;
$attributes[] =
$name
. (
$value === null
? ''
: '="' . preg_replace('/\"/u', '&quot;', $value) . '"'
);
}

return implode(' ', $attributes);
}

private static function getDomAttributes(\DOMNode $node)
/**
* @param DOMNode $node
* @return string
*/
private static function getDomAttributes(DOMNode $node): string
{
$result = null;
if ($node->attributes->length === 0) {
return '';
}

$attributes = array();

if ($node->attributes) {
$i = 0;

while ($item = $node->attributes->item($i)) {
$attributes[] = $item->name.'="'.$item->value.'"';

++$i;
}
$i = 0;

while ($item = $node->attributes->item($i++)) {
$attributes[] =
$item->name
. (
$item->value
? '="' . preg_replace('/\"/u', '&quot;', $item->value) . '"'
: ''
);
}

if ($attributes)
$result = implode(' ', $attributes);

return $result;
return implode(' ', $attributes);
}
}
?>
}
Loading