Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
DomRenderSearch
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
72
0.00% covered (danger)
0.00%
0 / 1
 getMovementDirection
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
72
1<?php
2
3namespace pvc\html\dom;
4
5use pvc\interfaces\html\dom\DomNodeInterface;
6use pvc\interfaces\struct\treesearch\VisitStatus;
7use pvc\struct\treesearch\Direction;
8use pvc\struct\treesearch\SearchDepthFirstPreorder;
9
10/**
11 * @extends SearchDepthFirstPreorder<DomNodeInterface>
12 */
13class DomRenderSearch extends SearchDepthFirstPreorder
14{
15    /**
16     * getMovementDirection
17     *
18     * @return Direction
19     *
20     * returns MOVE_DOWN if we should keep iterating by recursing down through child nodes,
21     * returns STOP if we should stop moving through nodes
22     * returns MOVE_UP if we should continue moving by returning up to the parent
23     *
24     * the goal is to stop the first time we visit a node (status is never visited), and the
25     * last time we visit a node (status to be set top fully visited)
26     *
27     * This method also changes the visit status of the current node.
28     *
29     * if node never visited, we go to partially visited and stop.
30     *
31     * if a node is partially visited and not all the children are fully visited then we move down
32     *
33     * if node partially visited and if all the children are fully visited, we go to fully visited and stop.
34     *
35     * if node is fully visited we move up
36     *
37     */
38    protected function getMovementDirection(): Direction
39    {
40        assert(!is_null($this->current()));
41
42        switch ($this->current()->getVisitStatus()) {
43            /**
44             * stop when we first encounter a node.  There's an initialization condition to
45             * account for:  rewind is called in the first iteration and next for all subsequent iterations.
46             * Because current has been called before next the first time around, the start node has already been
47             * returned, so we do not want to return it again.
48             */
49            case VisitStatus::NEVER_VISITED:
50                $this->current()->setVisitStatus(
51                    VisitStatus::PARTIALLY_VISITED
52                );
53                $direction = ($this->current() == $this->getStartNode())
54                    ? Direction::MOVE_DOWN : Direction::DONT_MOVE;
55                break;
56
57            /**
58             * if all the children are fully visited, or we are at the max search level, then we move to fully visited
59             * otherwise we move down.  The default case should never be true, which is to say that we should never
60             * be moving into a node that is fully visited.  The default case is only there to satisfy the type checker
61             * that the $direction variable will have a value in all cases.
62             */
63            case VisitStatus::PARTIALLY_VISITED:
64                if ($this->allChildrenFullyVisited() || $this->atMaxLevels()) {
65                    $this->current()->setVisitStatus(
66                        VisitStatus::FULLY_VISITED
67                    );
68                    /**
69                     * stop if this is the last time we will visit this node
70                     */
71                    $direction = Direction::DONT_MOVE;
72                } else {
73                    $direction = Direction::MOVE_DOWN;
74                }
75                break;
76
77            case VisitStatus::FULLY_VISITED:
78            default:
79                $direction = Direction::MOVE_UP;
80                break;
81        }
82        return $direction;
83    }
84}