Skip to content

Commit

Permalink
Expand nested components
Browse files Browse the repository at this point in the history
Closes #1
  • Loading branch information
g105b committed Dec 22, 2017
1 parent 9daa9fd commit c88e73e
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 26 deletions.
10 changes: 8 additions & 2 deletions src/Document.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
<?php
namespace Gt\DomTemplate;

use DOMElement;
use Gt\Dom\Document as BaseDocument;
use DOMNode;
use DOMElement;
use DOMDocumentFragment;


class Document extends BaseDocument {
public function __construct($document = null) {
parent::__construct($document);
$this->registerNodeClass(DOMElement::class, Node::class);

$this->registerNodeClass(DOMNode::class, Node::class);
$this->registerNodeClass(DOMElement::class, Element::class);
$this->registerNodeClass(DOMDocumentFragment::class, DocumentFragment::class);
}
}
8 changes: 8 additions & 0 deletions src/DocumentFragment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php
namespace Gt\DomTemplate;

use Gt\Dom\DocumentFragment as BaseDocumentFragment;

class DocumentFragment extends BaseDocumentFragment {
use TemplateParent;
}
7 changes: 7 additions & 0 deletions src/DomTemplateException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace Gt\DomTemplate;

use RuntimeException;

class DomTemplateException extends RuntimeException {}
1 change: 1 addition & 0 deletions src/Element.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@

class Element extends BaseElement {
use Bindable;
use TemplateParent;
}
11 changes: 7 additions & 4 deletions src/HTMLDocument.php
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
<?php
namespace Gt\DomTemplate;

use DOMElement;
use DOMNode;
use Gt\Dom\DocumentFragment;
use Gt\Dom\HTMLDocument as BaseHTMLDocument;
use Gt\Dom\DocumentFragment as BaseDocumentFragment;
use DOMNode;
use DOMElement;
use DOMDocumentFragment;

class HTMLDocument extends BaseHTMLDocument {
use TemplateParent;

public function __construct($document = "") {
parent::__construct($document);

$this->registerNodeClass(DOMNode::class, Node::class);
$this->registerNodeClass(DOMElement::class, Element::class);
$this->registerNodeClass(DOMDocumentFragment::class, DocumentFragment::class);
}

protected function createTemplateFragment(DOMElement $templateElement):DocumentFragment {
protected function createTemplateFragment(DOMElement $templateElement):BaseDocumentFragment {
$fragment = $this->createDocumentFragment();

if($templateElement->tagName === "template") {
Expand Down
5 changes: 5 additions & 0 deletions src/TemplateComponentNotFoundException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

namespace Gt\DomTemplate;

class TemplateComponentNotFoundException extends DomTemplateException {}
50 changes: 33 additions & 17 deletions src/TemplateParent.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
namespace Gt\DomTemplate;

use DirectoryIterator;
use Gt\Dom\DocumentFragment;
use Gt\Dom\HTMLCollection;
use Gt\Dom\Element as BaseElement;
use Gt\Dom\DocumentFragment as BaseDocumentFragment;

trait TemplateParent {
protected $templateFragmentMap = [];
Expand Down Expand Up @@ -33,10 +33,6 @@ public function extractTemplates():int {
return $i + 1;
}

public function setTemplateFilePath(string $path):void {
$this->templateFilePath = $path;
}

public function getTemplate(string $name):?DocumentFragment {
if(isset($this->templateFragmentMap[$name])) {
return $this->templateFragmentMap[$name];
Expand All @@ -61,47 +57,67 @@ public function getTemplate(string $name):?DocumentFragment {
return null;
}

public function expandComponents():int {
$count = 0;

/** @var HTMLCollection $componentList*/
$componentList = $this->xPath("//*[contains(local-name(), '-')]");
public function expandComponents(string $templateFilePath):int {
// Any HTML element is considered a "custom element" if it contains a hyphen in its name:
// @see https://www.w3.org/TR/custom-elements/#valid-custom-element-name
/** @var HTMLCollection $componentList */
$componentList = $this->xPath(
"descendant-or-self::*[contains(local-name(), '-')]"
);

$count = 0;
foreach($componentList as $component) {
$name = $component->tagName;

if(!isset($this->templateFragmentMap[$name])) {
$this->templateFragmentMap[$name] = $this->loadComponent($name);
try {
$this->templateFragmentMap[$name] = $this->loadComponent(
$name,
$templateFilePath
);
}
catch(TemplateComponentNotFoundException $exception) {}
}

/** @var DocumentFragment $fragment */
$fragment = $this->templateFragmentMap[$name];

if(is_null($fragment)) {
continue;
}

$fragment->expandComponents($templateFilePath);
$component->replaceWith($fragment);
$count++;
}

return $count;
}

protected function loadComponent(string $name):?DocumentFragment {
$filePath = $this->getTemplateFilePath($name);
protected function loadComponent(string $name, string $path):BaseDocumentFragment {
$filePath = $this->getTemplateFilePath($name, $path);

if(is_null($filePath)) {
return null;
throw new TemplateComponentNotFoundException($filePath);
}

$html = file_get_contents($filePath);
/** @var DocumentFragment $fragment */
$fragment = $this->createDocumentFragment();
if(method_exists($this, "createDocumentFragment")) {
$fragment = $this->createDocumentFragment();
}
else {
/** @var HTMLDocument $ownerDocument */
$ownerDocument = $this->ownerDocument;
$fragment = $ownerDocument->createDocumentFragment();
}

$fragment->appendXML($html);
return $fragment;
}

protected function getTemplateFilePath(string $name):?string {
foreach(new DirectoryIterator($this->templateFilePath) as $fileInfo) {
protected function getTemplateFilePath(string $name, string $path):?string {
foreach(new DirectoryIterator($path) as $fileInfo) {
if(!$fileInfo->isFile()) {
continue;
}
Expand Down
28 changes: 25 additions & 3 deletions test/unit/TemplateParentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ public function testGetTemplate() {
}

public function testExpandComponentsNoComponents() {
$templateDir = self::TEST_DIR . "/" . self::TEMPLATE_PATH;
$document = new HTMLDocument(Helper::HTML_TEMPLATES);
$count = $document->expandComponents();
$count = $document->expandComponents($templateDir);
self::assertEquals(0, $count);
}

Expand All @@ -88,12 +89,33 @@ public function testExpandComponents() {

$elementBeforeOrderedList = $document->querySelector("ordered-list")->previousElementSibling;

$document->setTemplateFilePath($templateDir);
$count = $document->expandComponents();
$count = $document->expandComponents($templateDir);
self::assertEquals(2, $count);
self::assertNull($document->querySelector("title-definition-list"));
self::assertNull($document->querySelector("ordered-list"));

self::assertEquals("ol", $elementBeforeOrderedList->nextElementSibling->tagName);
}

public function testNestedComponentsExpand() {
// While the count of the expandCompnents > 0, do it again on the expanded component...
$templateDir = self::TEST_DIR . "/" . self::TEMPLATE_PATH;
file_put_contents(
"$templateDir/title-definition-list.html",
Helper::COMPONENT_TITLE_DEFINITION_LIST
);
file_put_contents(
"$templateDir/title-definition.html",
Helper::COMPONENT_TITLE_DEFINITION
);
$document = new HTMLDocument(Helper::HTML_COMPONENTS);
$document->expandComponents($templateDir);

$expandedComponent = $document->querySelector("dl");
self::assertInstanceOf(Element::class, $expandedComponent);
self::assertInstanceOf(Element::class, $expandedComponent->firstElementChild);
self::assertInstanceOf(Element::class, $expandedComponent->lastElementChild);
self::assertEquals("dt", $expandedComponent->firstElementChild->tagName);
self::assertEquals("dd", $expandedComponent->lastElementChild->tagName);
}
}

0 comments on commit c88e73e

Please sign in to comment.