Skip to content

Commit

Permalink
Add generic type for unknown nodes (fixes #41)
Browse files Browse the repository at this point in the history
  • Loading branch information
meyfa committed Mar 25, 2018
1 parent 48c3980 commit 5677a18
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 15 deletions.
31 changes: 31 additions & 0 deletions src/Nodes/SVGGenericNodeType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace SVG\Nodes;

use SVG\Nodes\SVGNodeContainer;
use SVG\Rasterization\SVGRasterizer;

/**
* NOT INTENDED FOR USER ACCESS. This is the class that gets instantiated for
* unknown nodes in input SVG.
*/
class SVGGenericNodeType extends SVGNodeContainer
{
private $tagName;

public function __construct($tagName)
{
parent::__construct();
$this->tagName = $tagName;
}

public function getName()
{
return $this->tagName;
}

public function rasterize(SVGRasterizer $rasterizer)
{
// do nothing
}
}
22 changes: 11 additions & 11 deletions src/Reading/SVGReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use SVG\SVGImage;
use SVG\Nodes\SVGNode;
use SVG\Nodes\SVGNodeContainer;
use SVG\Nodes\SVGGenericNodeType;
use SVG\Utilities\SVGStyleParser;

/**
Expand Down Expand Up @@ -207,33 +208,32 @@ private function addChildren(SVGNodeContainer $node, \SimpleXMLElement $xml,
array $namespaces)
{
foreach ($xml->children() as $child) {
$childNode = $this->parseNode($child, $namespaces);
if ($childNode) {
$node->addChild($childNode);
}
$node->addChild($this->parseNode($child, $namespaces));
}
}

/**
* Parses the given XML element into an instance of a SVGNode subclass.
* Passing an element of unknown type will return false.
* Unknown node types use a generic implementation.
*
* @param \SimpleXMLElement $xml The XML element to parse.
* @param string[] $namespaces Array of allowed namespace prefixes.
*
* @return SVGNode|false The parsed node, or false if type unknown.
* @return SVGNode The parsed node.
*
* @SuppressWarnings(PHPMD.ElseExpression)
*/
private function parseNode(\SimpleXMLElement $xml, array $namespaces)
{
$type = $xml->getName();

if (!isset(self::$nodeTypes[$type])) {
return false;
if (isset(self::$nodeTypes[$type])) {
$call = array(self::$nodeTypes[$type], 'constructFromAttributes');
$node = call_user_func($call, $xml);
} else {
$node = new SVGGenericNodeType($type);
}

$call = array(self::$nodeTypes[$type], 'constructFromAttributes');
$node = call_user_func($call, $xml);

$this->applyAttributes($node, $xml, $namespaces);
$this->applyStyles($node, $xml);
$node->setValue($xml);
Expand Down
17 changes: 13 additions & 4 deletions tests/Reading/SVGReaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -158,15 +158,24 @@ public function testShouldRecursivelyAddChildren()
), $ellipse->getSerializableAttributes());
}

public function testShouldIgnoreUnknownNodes()
public function testShouldRetrieveUnknownNodes()
{
// should skip unknown node types without failing
$svgReader = new SVGReader();
$result = $svgReader->parseString($this->xmlUnknown);
$doc = $result->getDocument();
$this->assertSame(2, $doc->countChildren());

// should include unknown nodes
$this->assertSame(3, $doc->countChildren());
$this->assertSame('circle', $doc->getChild(0)->getName());
$this->assertSame('ellipse', $doc->getChild(1)->getName());
$this->assertSame('unknown', $doc->getChild(1)->getName());
$this->assertSame('ellipse', $doc->getChild(2)->getName());

// should set attributes on unknown nodes
$this->assertSame('bar', $doc->getChild(1)->getAttribute('foo'));

// should include children of unknown nodes
$this->assertSame(1, $doc->getChild(1)->countChildren());
$this->assertSame('baz', $doc->getChild(1)->getChild(0)->getName());
}

public function testShouldSetValue()
Expand Down

0 comments on commit 5677a18

Please sign in to comment.