Skip to content

Commit

Permalink
Fix Issue #5
Browse files Browse the repository at this point in the history
  • Loading branch information
theseer committed Dec 7, 2017
1 parent 26a20da commit 2caac0c
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 7 deletions.
1 change: 1 addition & 0 deletions src/Templado.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class Templado {
public static function loadHtmlFile(FileName $fileName): Html {
libxml_use_internal_errors(true);
$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
$tmp = $dom->load($fileName->asString());
if (!$tmp || libxml_get_last_error()) {
throw new TempladoException(
Expand Down
28 changes: 22 additions & 6 deletions src/viewmodel/SnapshotDOMNodelist.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* takes a snapshot of the list first and then turns that into an
* iterator.
*/
class SnapshotDOMNodelist implements Iterator {
class SnapshotDOMNodelist implements Iterator, \Countable {

/**
* @var DOMNode[]
Expand All @@ -24,6 +24,10 @@ public function __construct(DOMNodeList $list) {
$this->extractItemsFromNodeList($list);
}

public function count() {
return count($this->items);
}

public function hasNode(DOMNode $node) {
foreach($this->items as $pos => $item) {
if ($item->isSameNode($node)) {
Expand All @@ -38,30 +42,32 @@ public function removeNode(DOMNode $node) {
foreach($this->items as $pos => $item) {
if ($item->isSameNode($node)) {
array_splice($this->items, $pos, 1);

if ($pos <= $this->pos) {
$this->pos--;
}
return;
}
}
throw new SnapshotDOMNodelistException('Node not found in list');
}

public function current() {
public function current(): DOMNode {
return $this->items[$this->pos];
}

public function next() {
public function next(): void {
$this->pos++;
}

public function key() {
public function key(): int {
return $this->pos;
}

public function valid(): bool {
return count($this->items) > $this->pos;
}

public function rewind() {
public function rewind(): void {
$this->pos = 0;
}

Expand All @@ -70,4 +76,14 @@ private function extractItemsFromNodeList(DOMNodeList $list) {
$this->items[] = $item;
}
}

public function hasNext(): bool {
return $this->pos < count($this->items);
}

public function getNext(): DOMNode {
$node = $this->current();
$this->next();
return $node;
}
}
4 changes: 3 additions & 1 deletion src/viewmodel/ViewModelRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ private function walk(DOMNode $context) {
if ($context->hasChildNodes()) {
$list = new SnapshotDOMNodelist($context->childNodes);
$this->listStack[] = $list;
foreach($list as $pos => $childNode) {

while($list->hasNext()) {
$childNode = $list->getNext();
/** @var \DOMNode $childNode */
$this->walk($childNode);
}
Expand Down
23 changes: 23 additions & 0 deletions tests/issues/issue-#5/Issue5Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php declare(strict_types = 1);
namespace Templado\Engine;

use PHPUnit\Framework\TestCase;

require __DIR__ . '/viewmodel.php';

class Issue5Test extends TestCase {

public function testIssueIsNoLongerReproduceable() {

$templadoFile = new FileName(__DIR__ . '/formTest.xhtml');
$html = Templado::loadHtmlFile($templadoFile);
$html->applyViewModel(new Issue5_ViewData());

$this->assertXmlStringEqualsXmlString(
file_get_contents(__DIR__ . '/expected.html'),
$html->asString()
);

}
}

18 changes: 18 additions & 0 deletions tests/issues/issue-#5/expected.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Title</title>
</head>
<body>
<div id="include">
<div>
<form name="form1" action="/">
<button property="button1" formaction="/target1">Changed action to: /target1</button>
<button property="button2" formaction="/target2">Changed action to: /target2</button>
<button property="button3" formaction="/target3">Changed action to: /target3</button>
<button property="button4" formaction="/target4">Changed action to: /target4</button>
</form>
</div>
</div>
</body>
</html>
22 changes: 22 additions & 0 deletions tests/issues/issue-#5/formTest.xhtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xml:lang="en" lang="en">
<head>
<title>Title</title>
</head>
<body>

<div id="include">
<div>
<form name="form1" action="/">
<button property="button1" formaction="">button 1</button>
<button property="button2" formaction="">button 2</button>
<button property="button3" formaction="">button 3</button>
<button property="button4" formaction="">button 4</button>
</form>
</div>
</div>


</body>
</html>
31 changes: 31 additions & 0 deletions tests/issues/issue-#5/viewmodel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php declare(strict_types = 1);
namespace Templado\Engine;

class Issue5_Button {
private $action;
public function __construct(string $action) {
$this->action = $action;
}
public function getFormaction() {
return $this->action;
}

public function asString(): string {
return 'Changed action to: ' . $this->action;
}
}

class Issue5_ViewData {
public function getButton1() {
return new Issue5_Button('/target1');
}
public function getButton2() {
return new Issue5_Button('/target2');
}
public function getButton3() {
return new Issue5_Button('/target3');
}
public function getButton4() {
return new Issue5_Button('/target4');
}
}

0 comments on commit 2caac0c

Please sign in to comment.