Html: allow to wrap elements, needed for forms

This commit is contained in:
Thomas Gelf 2018-05-23 08:30:37 +02:00
parent 799a332c22
commit 3673daaa3c
2 changed files with 124 additions and 16 deletions

View File

@ -61,6 +61,7 @@ abstract class BaseHtmlElement extends HtmlDocument
public function setAttributes($attributes) public function setAttributes($attributes)
{ {
$this->attributes = Attributes::wantAttributes($attributes); $this->attributes = Attributes::wantAttributes($attributes);
return $this; return $this;
} }
@ -74,6 +75,7 @@ abstract class BaseHtmlElement extends HtmlDocument
public function setAttribute($key, $value) public function setAttribute($key, $value)
{ {
$this->getAttributes()->set($key, $value); $this->getAttributes()->set($key, $value);
return $this; return $this;
} }
@ -81,10 +83,12 @@ abstract class BaseHtmlElement extends HtmlDocument
* @param Attributes|array|null $attributes * @param Attributes|array|null $attributes
* @return $this * @return $this
* @throws \Icinga\Exception\ProgrammingError * @throws \Icinga\Exception\ProgrammingError
* @throws \Icinga\Exception\IcingaException
*/ */
public function addAttributes($attributes) public function addAttributes($attributes)
{ {
$this->getAttributes()->add($attributes); $this->getAttributes()->add($attributes);
return $this; return $this;
} }
@ -99,6 +103,7 @@ abstract class BaseHtmlElement extends HtmlDocument
public function setTag($tag) public function setTag($tag)
{ {
$this->tag = $tag; $this->tag = $tag;
return $this; return $this;
} }
@ -109,11 +114,7 @@ abstract class BaseHtmlElement extends HtmlDocument
public function renderContent() public function renderContent()
{ {
return parent::render(); return parent::renderUnwrapped();
}
protected function assemble()
{
} }
/** /**
@ -123,10 +124,7 @@ abstract class BaseHtmlElement extends HtmlDocument
*/ */
public function add($content) public function add($content)
{ {
if (! $this->hasBeenAssembled) { $this->ensureAssembled();
$this->hasBeenAssembled = true;
$this->assemble();
}
parent::add($content); parent::add($content);
@ -136,14 +134,12 @@ abstract class BaseHtmlElement extends HtmlDocument
/** /**
* @return string * @return string
* @throws \Icinga\Exception\ProgrammingError * @throws \Icinga\Exception\ProgrammingError
* @throws \Icinga\Exception\IcingaException
*/ */
public function render() public function renderUnwrapped()
{ {
$this->ensureAssembled();
$tag = $this->getTag(); $tag = $this->getTag();
if (! $this->hasBeenAssembled) {
$this->hasBeenAssembled = true;
$this->assemble();
}
$content = $this->renderContent(); $content = $this->renderContent();
if (strlen($content) || $this->wantsClosingTag()) { if (strlen($content) || $this->wantsClosingTag()) {
@ -166,6 +162,7 @@ abstract class BaseHtmlElement extends HtmlDocument
/** /**
* @return string * @return string
* @throws \Icinga\Exception\ProgrammingError * @throws \Icinga\Exception\ProgrammingError
* @throws \Icinga\Exception\IcingaException
*/ */
public function renderAttributes() public function renderAttributes()
{ {
@ -176,6 +173,17 @@ abstract class BaseHtmlElement extends HtmlDocument
} }
} }
/**
* @param HtmlDocument $document
* @return $this
*/
public function wrap(HtmlDocument $document)
{
$document->addWrapper($this);
return $this;
}
public function wantsClosingTag() public function wantsClosingTag()
{ {
// TODO: There is more. SVG and MathML namespaces // TODO: There is more. SVG and MathML namespaces

View File

@ -14,6 +14,9 @@ class HtmlDocument implements ValidHtml, Countable
{ {
protected $contentSeparator = ''; protected $contentSeparator = '';
/** @var BaseHtmlElement */
protected $wrapper;
/** @var ValidHtml[] */ /** @var ValidHtml[] */
private $content = []; private $content = [];
@ -40,6 +43,40 @@ class HtmlDocument implements ValidHtml, Countable
return $this; return $this;
} }
/**
* @param BaseHtmlElement $wrapper
* @return $this
*/
public function setWrapper(BaseHtmlElement $wrapper)
{
$this->wrapper = $wrapper;
return $this;
}
/**
* @param BaseHtmlElement $wrapper
* @return $this
*/
public function addWrapper(BaseHtmlElement $wrapper)
{
if ($this->wrapper === null) {
$this->setWrapper($wrapper);
} else {
$this->setWrapper($wrapper->wrap($this->wrapper));
}
return $this;
}
/**
* @return HtmlDocument|null
*/
public function getWrapper()
{
return $this->wrapper;
}
/** /**
* @return bool * @return bool
*/ */
@ -152,16 +189,70 @@ class HtmlDocument implements ValidHtml, Countable
} }
/** /**
* @inheritdoc * @return string
* @throws ProgrammingError
* @throws \Icinga\Exception\IcingaException
*/ */
public function render() public function render()
{ {
$html = []; if ($this->wrapper === null) {
return $this->renderUnwrapped();
} else {
return $this->renderWrapped();
}
}
/**
* @return string
* @throws ProgrammingError
* @throws \Icinga\Exception\IcingaException
*/
protected function renderWrapped()
{
// TODO: we don't like this, but have no better solution right now.
// However, it works as expected, tests are green
$wrapper = $this->wrapper;
$this->wrapper = null;
$result = $wrapper->renderWrappedDocument($this);
$this->wrapper = $wrapper;
return $result;
}
/**
* @param HtmlDocument $document
* @return string
* @throws ProgrammingError
* @throws \Icinga\Exception\IcingaException
*/
protected function renderWrappedDocument(HtmlDocument $document)
{
$wrapper = clone($this);
$wrapper->add($document);
return $wrapper->render();
}
/**
* @return $this
*/
public function ensureAssembled()
{
if (! $this->hasBeenAssembled) { if (! $this->hasBeenAssembled) {
$this->hasBeenAssembled = true; $this->hasBeenAssembled = true;
$this->assemble(); $this->assemble();
} }
return $this;
}
/**
* @return string
*/
public function renderUnwrapped()
{
$this->ensureAssembled();
$html = [];
foreach ($this->content as $element) { foreach ($this->content as $element) {
if (is_string($element)) { if (is_string($element)) {
var_dump($this->content); var_dump($this->content);
@ -227,4 +318,13 @@ class HtmlDocument implements ValidHtml, Countable
{ {
return $this->content; return $this->content;
} }
public function __clone()
{
foreach ($this->content as $key => $element) {
$this->content[$key] = clone($element);
}
$this->reIndexContent();
}
} }