From 2283a216a32493450adf1b35462e985767b5bf54 Mon Sep 17 00:00:00 2001 From: Fabian Meyer <3982806+meyfa@users.noreply.github.com> Date: Wed, 31 Jan 2018 13:48:10 +0100 Subject: [PATCH] Add getElementsByTagName method to nodes --- src/Nodes/SVGNode.php | 19 +++++++++++++++ src/Nodes/SVGNodeContainer.php | 12 ++++++++++ tests/Nodes/SVGNodeContainerTest.php | 36 ++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/src/Nodes/SVGNode.php b/src/Nodes/SVGNode.php index 7125dab..e4a8a4a 100644 --- a/src/Nodes/SVGNode.php +++ b/src/Nodes/SVGNode.php @@ -263,4 +263,23 @@ public function getViewBox() * @return void */ abstract public function rasterize(SVGRasterizer $rasterizer); + + /** + * Returns all descendants of this node (excluding this node) having the + * given tag name. '*' matches all nodes. + * + * Example: getElementsByTagName('rect') + * would return all nodes that are descendants of this node. + * + * @param string $tagName The tag name to search for ('*' to match all). + * @param SVGNode[] $result The array to fill. Can be omitted. + * + * @return SVGNode[] An array of matching elements. + * + * @SuppressWarnings("unused") + */ + public function getElementsByTagName($tagName, array &$result = array()) + { + return $result; + } } diff --git a/src/Nodes/SVGNodeContainer.php b/src/Nodes/SVGNodeContainer.php index 6aba95b..ef09098 100644 --- a/src/Nodes/SVGNodeContainer.php +++ b/src/Nodes/SVGNodeContainer.php @@ -196,4 +196,16 @@ private function pregGrepStyle($pattern) { return preg_grep($pattern, array_keys($this->containerStyles)); } + + public function getElementsByTagName($tagName, array &$result = array()) + { + foreach ($this->children as $child) { + if ($tagName === '*' || $child->getName() === $tagName) { + $result[] = $child; + } + $child->getElementsByTagName($tagName, $result); + } + + return $result; + } } diff --git a/tests/Nodes/SVGNodeContainerTest.php b/tests/Nodes/SVGNodeContainerTest.php index 60f2212..4f7473e 100644 --- a/tests/Nodes/SVGNodeContainerTest.php +++ b/tests/Nodes/SVGNodeContainerTest.php @@ -80,4 +80,40 @@ public function testRasterize() $obj->setStyle('display', 'none'); $obj->rasterize($rast); } + + public function testGetElementsByTagName() + { + $obj = new SVGNodeContainerSubclass(); + $obj->addChild( + ($root_0 = new \SVG\Nodes\Structures\SVGGroup())->addChild( + $root_0_0 = new \SVG\Nodes\Shapes\SVGLine() + )->addChild( + $root_0_1 = new \SVG\Nodes\Shapes\SVGRect() + ) + ); + $obj->addChild( + ($root_1 = new \SVG\Nodes\Structures\SVGGroup())->addChild( + ($root_1_0 = new \SVG\Nodes\Structures\SVGGroup())->addChild( + $root_1_0_0 = new \SVG\Nodes\Shapes\SVGRect() + ) + )->addChild( + $root_1_1 = new \SVG\Nodes\Shapes\SVGRect() + ) + ); + + // should not return itself + $this->assertSame(array(), $obj->getElementsByTagName('test_subclass')); + $this->assertNotContains($obj, $obj->getElementsByTagName('*')); + + // should return specific tags + $this->assertSame(array( + $root_0_1, $root_1_0_0, $root_1_1, + ), $obj->getElementsByTagName('rect')); + + // should return all descendants for '*' + $this->assertSame(array( + $root_0, $root_0_0, $root_0_1, + $root_1, $root_1_0, $root_1_0_0, $root_1_1, + ), $obj->getElementsByTagName('*')); + } }