From 6ede1e4d51216dbdbebc67c0f6ce484d048c1b88 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 28 Nov 2018 17:38:00 +0100 Subject: [PATCH] complete refactoring of api --- .kick.yml | 2 +- README.md | 42 ++++++++++----- src/Elements/DocumentNode.php | 2 +- src/Elements/HtmlContainerElement.php | 8 +-- src/Fhtml/FHtml.php | 49 +++++++++--------- src/Fhtml/FHtmlMacro.php | 30 ----------- src/Fhtml/_FHtmlTemplateTrait.php | 12 ++--- src/functions.inc.php | 15 ++++-- tests/integration/AlterElementsTest.php | 16 ++++-- tests/integration/CreatingElementsTest.php | 47 ++++++++++++++--- tests/integration/QueryingElementsTest.php | 59 ++++++++++++++++++++-- 11 files changed, 182 insertions(+), 100 deletions(-) delete mode 100644 src/Fhtml/FHtmlMacro.php diff --git a/.kick.yml b/.kick.yml index 4e7090e..465613c 100644 --- a/.kick.yml +++ b/.kick.yml @@ -8,4 +8,4 @@ command: - "composer update" test: - - "phpunit /opt/tests" \ No newline at end of file + - "phpunit --testdox /opt/tests" \ No newline at end of file diff --git a/README.md b/README.md index e370329..582b8c2 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,40 @@ # Phore HTML Toolkit - Fluent API for creating HTML Elements +- Create, alter, render ## Basic example +```php +// Create a div element: +$elem = fhtml("div @id=main @class=website"); + +// Append a
to the +$elem[] = [ + "div @id=content" => "Some Content" +]; + +// Append paragraph to content div: +$elem["?#content"][] = ["p" => "Some escaped content"]; + +// Render full page including html-header +echo $elem->renderPage(); ``` -$elem = fhtml("div @class=someClass @id=abc"); -$elem->elem("a @href=:url", ["http://some.url"])->content("Click me"); -$elem->render(); // Render partial -$elem->renderPage(); // Render full page including html-header +will output: + +```html +
+
+ Some Content +

Some escaped content

+
+
``` -## Altering Elements + +## Creating html structures + + ``` $doc = fhtml("div @id=name2 @class=bordered"); @@ -21,14 +44,7 @@ $doc->alter(); ## Rendering Templates -``` -$doc->tpl([ - "div @class=content" => [ - ["p" => "Hello World"], - ["p" => "And hello world 2"] - ] -]); -``` + ## Appending to Templates diff --git a/src/Elements/DocumentNode.php b/src/Elements/DocumentNode.php index b01d6f2..9ae13de 100644 --- a/src/Elements/DocumentNode.php +++ b/src/Elements/DocumentNode.php @@ -36,7 +36,7 @@ public function __addToIndex(HtmlElement $element) } } - public function getElementById ($id) : HtmlContainerElement + public function getElementById ($id) : HtmlElement { if ( ! isset ($this->indexById[$id])) throw new \InvalidArgumentException("Query element id '$id': No element found."); diff --git a/src/Elements/HtmlContainerElement.php b/src/Elements/HtmlContainerElement.php index 9212453..24cc616 100644 --- a/src/Elements/HtmlContainerElement.php +++ b/src/Elements/HtmlContainerElement.php @@ -22,15 +22,15 @@ public function add(HtmlElementNode $child) $this->children[] = $child; $child->_setParent($this); - if ($child instanceof DocumentNode) { - $this->getRootDocument()->__addToIndex($child); - return; - } + if ($child instanceof HtmlContainerElement) + $this->getRootDocument()->__addToIndex($child->getDocument()); + if ($child instanceof HtmlElement) { $id = $child->getAttrib("id"); if ($id !== null) $this->getRootDocument()->__addToIndex($child); } + } /** diff --git a/src/Fhtml/FHtml.php b/src/Fhtml/FHtml.php index 39fd847..ae568d4 100644 --- a/src/Fhtml/FHtml.php +++ b/src/Fhtml/FHtml.php @@ -43,13 +43,18 @@ class FHtml implements HtmlElementNode, \ArrayAccess protected $emptyTags = ["meta"=>true, "img"=>true, "br"=>true, "hr"=>true, "input"=>true, "link"=>true]; - public function __construct(array $template=null) + public function __construct($elementDef=null, $arguments=[]) { $this->documentNode = new DocumentNode(); $this->curNode = $this->documentNode; - if ($template !== null) - $this->tpl($template); + if (is_string($elementDef)) { + $elem = $this->elem($elementDef, $arguments); + $this->curNode = $elem->curNode; + + } + if (is_array($elementDef)) + $this->tpl($elementDef, $arguments); } @@ -125,17 +130,8 @@ protected function _parseElem (string $elemDef, $arrayArgs=[]) : array * @param array $arrayArgs * @return FHtml */ - public function elem(string $elemDef, $arrayArgs=[]) : self + protected function elem(string $elemDef, $arrayArgs=[]) : self { - if (strpos($elemDef, ">") !== false) { - // Multi-Element - $curElem = $this; - foreach (explode(">", $elemDef) as $curDef) { - $curElem = $curElem->elem(trim ($curDef)); - } - return $curElem; - } - [$tagName, $attrs] = $this->_parseElem($elemDef, $arrayArgs); if (isset ($this->emptyTags[$tagName])) { @@ -148,7 +144,7 @@ public function elem(string $elemDef, $arrayArgs=[]) : self } - public function content($child) : self + protected function content($child) : self { if ($child === null) return $this; @@ -163,13 +159,13 @@ public function content($child) : self return $this; } - public function text(string $textContent) : self + protected function text(string $textContent) : self { $this->curNode->add(new TextNode($textContent)); return $this; } - public function html__unescaped__(string $rawHtmlContent) : self + protected function html__unescaped__(string $rawHtmlContent) : self { $this->curNode->add(new RawHtmlNode($rawHtmlContent)); return $this; @@ -183,7 +179,7 @@ private function cloneit ($curNode) : FHtml return $new; } - public function end() : self + protected function end() : self { if ($this->curNode->getParent() === $this->curNode) throw new \InvalidArgumentException("end(): Node is document node."); @@ -229,7 +225,7 @@ public function __toString() * * @return FHtml */ - public function empty() : self + public function clear() : self { if ($this->curNode instanceof HtmlContainerElement) $this->curNode->clearChildren(); @@ -307,12 +303,6 @@ public function getNode() : HtmlElement } - public function macro(FHtmlMacro $macro) : self - { - return $macro->onAttach($this); - } - - public function _setParent(HtmlContainerElement $parent) { $this->parent = $parent; @@ -372,12 +362,19 @@ public function offsetGet($offset) */ public function offsetSet($offset, $value) { + $elem = $this; if ($offset !== null) { $elem = $this->elem($offset); - $elem->tpl($value); + } + if (is_array($value)) { + $elem->tpl($value, []); + return; + } + if ($value instanceof FHtml) { + $this->curNode->add($value->getDocument()); return; } - $this->tpl($value); + $elem->content($value); } /** diff --git a/src/Fhtml/FHtmlMacro.php b/src/Fhtml/FHtmlMacro.php deleted file mode 100644 index 8830345..0000000 --- a/src/Fhtml/FHtmlMacro.php +++ /dev/null @@ -1,30 +0,0 @@ -data = $data; - } - - - public static function Use(array $data=[]) : self - { - return static($data); - } - - abstract public function onAttach(FHtml $node) : FHtml; - -} \ No newline at end of file diff --git a/src/Fhtml/_FHtmlTemplateTrait.php b/src/Fhtml/_FHtmlTemplateTrait.php index 0079b84..be77a58 100644 --- a/src/Fhtml/_FHtmlTemplateTrait.php +++ b/src/Fhtml/_FHtmlTemplateTrait.php @@ -24,7 +24,7 @@ trait _FHtmlTemplateTrait { - private function _addStructRecursive ($node, FHtml $pointer) : void + private function _addStructRecursive ($node, FHtml $pointer, array $arguments) : void { if ($node instanceof HtmlElementNode) { $pointer->curNode->add($node); @@ -32,7 +32,7 @@ private function _addStructRecursive ($node, FHtml $pointer) : void } if (is_callable($node)) { $ret = $node($pointer); - $pointer->tpl($ret); + $pointer->tpl($ret, $arguments); return; } if (is_string($node)) { @@ -45,13 +45,13 @@ private function _addStructRecursive ($node, FHtml $pointer) : void foreach ($node as $key => $value) { if (is_string($key)) { - $this->_addStructRecursive($value, $pointer->elem($key)); + $this->_addStructRecursive($value, $pointer->elem($key, $arguments), $arguments); //if ($pointer->curNode !== $pointer->documentNode) // $pointer->end(); continue; } if (is_int($key)) { - $this->_addStructRecursive($value, $pointer); + $this->_addStructRecursive($value, $pointer, $arguments); continue; } if ($value instanceof HtmlElementNode) { @@ -64,9 +64,9 @@ private function _addStructRecursive ($node, FHtml $pointer) : void return; } - public function tpl($input) : self + protected function tpl($input, array $arguments) : self { - $this->_addStructRecursive($input, $this); + $this->_addStructRecursive($input, $this, $arguments); return $this; } } diff --git a/src/functions.inc.php b/src/functions.inc.php index 646cbf6..d167292 100644 --- a/src/functions.inc.php +++ b/src/functions.inc.php @@ -8,10 +8,15 @@ function fhtml($elem=null, $params=[]) : \Phore\Html\Fhtml\FHtml { - if ($elem === null) - return new \Phore\Html\Fhtml\FHtml(); - if (is_array($elem)) - return (new \Phore\Html\Fhtml\FHtml($elem)); - return (new \Phore\Html\Fhtml\FHtml())->elem($elem, $params); + /* + if (is_string($elem)) { + return (new \Phore\Html\Fhtml\FHtml())->elem($elem, $params); + } + */ + return new \Phore\Html\Fhtml\FHtml($elem, $params); } +/** + * FHTML Empty Element + */ +define("FE", null); \ No newline at end of file diff --git a/tests/integration/AlterElementsTest.php b/tests/integration/AlterElementsTest.php index 1b466a7..193b391 100644 --- a/tests/integration/AlterElementsTest.php +++ b/tests/integration/AlterElementsTest.php @@ -14,15 +14,25 @@ class AlterElementsTest extends TestCase { - public function testAlterElements() { $doc = fhtml("div"); - $doc->elem("p @id=abc @a @b"); + $doc[] = fhtml("p @id=abc @a @b"); - $doc->query("#abc")->alter("@class=-b +c"); + $doc["?#abc"]->alter("@class=-b +c"); $this->assertEquals('

', $doc->render(false)); } + + public function testRemoveElements() + { + $doc = fhtml("div"); + $doc[] = fhtml(["p @id=abc" => ["p" => "text"]]); + + $doc["?#abc"]->clear(); + + $this->assertEquals('

', $doc->render(false)); + } + } \ No newline at end of file diff --git a/tests/integration/CreatingElementsTest.php b/tests/integration/CreatingElementsTest.php index e8c35a9..6e21c41 100644 --- a/tests/integration/CreatingElementsTest.php +++ b/tests/integration/CreatingElementsTest.php @@ -14,27 +14,62 @@ class CreatingElementsTest extends TestCase { - public function testCreateDocument() { - $doc = fhtml(); - $doc->elem("div @cssClass @class=cssClass2"); - + $doc = fhtml("div @cssClass @class=cssClass2"); $this->assertEquals("
", $doc->render(false)); $doc = fhtml("div @cssClass"); $this->assertEquals('
',$doc->render(false)); } + public function testTemplate () + { + $doc = fhtml([ + "html" => [ + "p" => "abc" + ] + ]); + + $this->assertEquals('

abc

', $doc->render(false)); + } public function testAppendToDocument () { $doc = fhtml("div"); - $doc[] = fhtml("p"); + //This wont works - will return + $elem = (fhtml("p")[] = fhtml("img")); + + // Correct way to create + $doc["p"][] = fhtml("img"); $doc[] = fhtml("p"); - $this->assertEquals('

', $doc->render(false)); + $this->assertEquals('

', $doc->render(false)); } + public function testAppendArrayTemplateToDocument() + { + $doc = fhtml("div"); + $doc[] = [ + "p" => fhtml("b") + ]; + $this->assertEquals('

', $doc->render(false)); + } + public function testTemplateInTemplate() + { + $doc = fhtml([ + "p" => "Some escaped Content", + "p " => fhtml("img") + ]); + $this->assertEquals('

Some escaped Content

', $doc->render(false)); + } + + public function testCreateWithParameters() + { + $doc = fhtml([ + "p @class=:class" => "b" + ], ["class" => "x"]); + $this->assertEquals('

b

', $doc->render(false)); + } } \ No newline at end of file diff --git a/tests/integration/QueryingElementsTest.php b/tests/integration/QueryingElementsTest.php index 525e812..7eb312c 100644 --- a/tests/integration/QueryingElementsTest.php +++ b/tests/integration/QueryingElementsTest.php @@ -17,12 +17,61 @@ class QueryingElementsTest extends TestCase public function testQueryIdElements () { - $doc = fhtml("html"); - $div = $doc->elem("div @id=abc"); + $doc = fhtml([ + "html @id=ccd" => [ + "div @id=abc" => FE + ] + ] + ); - $this->assertEquals($div->getNode(), $doc->query("#abc")->getNode()); - $this->assertEquals($div->getNode(), $doc["?#abc"]->getNode()); + $this->assertEquals("div", $doc->query("#abc")->getNode()->getTag()); + $this->assertEquals("div", $doc["?#abc"]->getNode()->getTag()); } + public function testQueryIdOnAddedTemplate() + { + $doc = fhtml("div"); + $doc[] = [ + "p @id=abc" => "x" + ]; + + $this->assertEquals( + "p", + $doc["?#abc"]->getNode()->getTag() + ); + } + + + public function testQueryFindsSelfContainerElement() + { + $elem = fhtml("div @id=abc"); + $this->assertEquals( + "div", + $elem["?#abc"]->getNode()->getTag() + ); + } + + public function testQueryFindsSelfSimpleElement() + { + $elem = fhtml("img @id=abc"); + $this->assertEquals( + "img", + $elem["?#abc"]->getNode()->getTag() + ); + } + + public function testIdIndexIsWorkingOnElements() + { + $elem = fhtml("div"); + $elem[] = fhtml("div @id=abc"); + + $this->assertEquals( + "div", + $elem["?#abc"]->getNode()->getTag() + ); + } + + +} + -} \ No newline at end of file