Completed
Push — master ( 30aab1...cadcfa )
by Asmir
07:00
created

Traverser::children()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 5
cts 5
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2
1
<?php
2
namespace Masterminds\HTML5\Serializer;
3
4
/**
5
 * Traverser for walking a DOM tree.
6
 *
7
 * This is a concrete traverser designed to convert a DOM tree into an
8
 * HTML5 document. It is not intended to be a generic DOMTreeWalker
9
 * implementation.
10
 *
11
 * @see http://www.w3.org/TR/2012/CR-html5-20121217/syntax.html#serializing-html-fragments
12
 */
13
class Traverser
14
{
15
16
    /**
17
     * Namespaces that should be treated as "local" to HTML5.
18
     */
19
    static $local_ns = array(
20
        'http://www.w3.org/1999/xhtml' => 'html',
21
        'http://www.w3.org/1998/Math/MathML' => 'math',
22
        'http://www.w3.org/2000/svg' => 'svg'
23
    );
24
25
    protected $dom;
26
27
    protected $options;
28
29
    protected $encode = false;
30
31
    protected $rules;
32
33
    protected $out;
34
35
    /**
36
     * Create a traverser.
37
     *
38
     * @param DOMNode|DOMNodeList $dom
39
     *            The document or node to traverse.
40
     * @param resource $out
41
     *            A stream that allows writing. The traverser will output into this
42
     *            stream.
43
     * @param array $options
44
     *            An array or options for the traverser as key/value pairs. These include:
45
     *            - encode_entities: A bool to specify if full encding should happen for all named
46
     *            charachter references. Defaults to false which escapes &'<>".
47
     *            - output_rules: The path to the class handling the output rules.
48
     */
49 64
    public function __construct($dom, $out, RulesInterface $rules, $options = array())
50
    {
51 64
        $this->dom = $dom;
52 64
        $this->out = $out;
53 64
        $this->rules = $rules;
54 64
        $this->options = $options;
55
56 64
        $this->rules->setTraverser($this);
57 64
    }
58
59
    /**
60
     * Tell the traverser to walk the DOM.
61
     *
62
     * @return resource $out
63
     *         Returns the output stream.
64
     */
65 22
    public function walk()
66
    {
67 22
        if ($this->dom instanceof \DOMDocument) {
68 16
            $this->rules->document($this->dom);
69 22
        } elseif ($this->dom instanceof \DOMDocumentFragment) {
70
            // Document fragments are a special case. Only the children need to
71
            // be serialized.
72 13
            if ($this->dom->hasChildNodes()) {
73 13
                $this->children($this->dom->childNodes);
74 13
            }
75 13
        }        // If NodeList, loop
76
        elseif ($this->dom instanceof \DOMNodeList) {
77
            // If this is a NodeList of DOMDocuments this will not work.
78
            $this->children($this->dom);
79
        }         // Else assume this is a DOMNode-like datastructure.
80
        else {
81
            $this->node($this->dom);
82
        }
83
84 22
        return $this->out;
85
    }
86
87
    /**
88
     * Process a node in the DOM.
89
     *
90
     * @param mixed $node
91
     *            A node implementing \DOMNode.
92
     */
93 27
    public function node($node)
94
    {
95
        // A listing of types is at http://php.net/manual/en/dom.constants.php
96 27
        switch ($node->nodeType) {
97 27
            case XML_ELEMENT_NODE:
98 24
                $this->rules->element($node);
99 24
                break;
100 27
            case XML_TEXT_NODE:
101 23
                $this->rules->text($node);
102 23
                break;
103 19
            case XML_CDATA_SECTION_NODE:
104 1
                $this->rules->cdata($node);
105 1
                break;
106 19
            case XML_PI_NODE:
107 2
                $this->rules->processorInstruction($node);
108 2
                break;
109 17
            case XML_COMMENT_NODE:
110 2
                $this->rules->comment($node);
111 2
                break;
112
            // Currently we don't support embedding DTDs.
113 17
            default:
114
                //print '<!-- Skipped -->';
115 17
                break;
116 27
        }
117 27
    }
118
119
    /**
120
     * Walk through all the nodes on a node list.
121
     *
122
     * @param \DOMNodeList $nl
123
     *            A list of child elements to walk through.
124
     */
125 27
    public function children($nl)
126
    {
127 27
        foreach ($nl as $node) {
128 27
            $this->node($node);
129 27
        }
130 27
    }
131
132
    /**
133
     * Is an element local?
134
     *
135
     * @param mixed $ele
136
     *            An element that implement \DOMNode.
137
     *
138
     * @return bool True if local and false otherwise.
139
     */
140 28
    public function isLocalElement($ele)
141
    {
142 28
        $uri = $ele->namespaceURI;
143 28
        if (empty($uri)) {
144 2
            return false;
145
        }
146
147 28
        return isset(static::$local_ns[$uri]);
148
    }
149
}
150