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

TreeBuildingRules::evaluate()   C

Complexity

Conditions 15
Paths 15

Size

Total Lines 43

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 15.6565

Importance

Changes 0
Metric Value
dl 0
loc 43
ccs 30
cts 35
cp 0.8571
rs 5.9166
c 0
b 0
f 0
cc 15
nc 15
nop 2
crap 15.6565

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace Masterminds\HTML5\Parser;
3
4
/**
5
 * Handles special-case rules for the DOM tree builder.
6
 *
7
 * Many tags have special rules that need to be accomodated on an
8
 * individual basis. This class handles those rules.
9
 *
10
 * See section 8.1.2.4 of the spec.
11
 *
12
 * @todo - colgroup and col special behaviors
13
 *       - body and head special behaviors
14
 */
15
class TreeBuildingRules
16
{
17
18
    protected static $tags = array(
19
        'li' => 1,
20
        'dd' => 1,
21
        'dt' => 1,
22
        'rt' => 1,
23
        'rp' => 1,
24
        'tr' => 1,
25
        'th' => 1,
26
        'td' => 1,
27
        'thead' => 1,
28
        'tfoot' => 1,
29
        'tbody' => 1,
30
        'table' => 1,
31
        'optgroup' => 1,
32
        'option' => 1
33
    );
34
35
    /**
36
     * Build a new rules engine.
37
     *
38
     * @param \DOMDocument $doc
39
     *            The DOM document to use for evaluation and modification.
40
     */
41 111
    public function __construct($doc)
42
    {
43 111
        $this->doc = $doc;
44 111
    }
45
46
    /**
47
     * Returns true if the given tagname has special processing rules.
48
     */
49 107
    public function hasRules($tagname)
50
    {
51 107
        return isset(static::$tags[$tagname]);
52
    }
53
54
    /**
55
     * Evaluate the rule for the current tag name.
56
     *
57
     * This may modify the existing DOM.
58
     *
59
     * @return \DOMElement The new Current DOM element.
60
     */
61 6
    public function evaluate($new, $current)
62
    {
63 6
        switch ($new->tagName) {
64 6
            case 'li':
65 2
                return $this->handleLI($new, $current);
66 4
            case 'dt':
67 4
            case 'dd':
68 1
                return $this->handleDT($new, $current);
69 3
            case 'rt':
70 3
            case 'rp':
71
                return $this->handleRT($new, $current);
72 3
            case 'optgroup':
73 2
                return $this->closeIfCurrentMatches($new, $current, array(
74
                    'optgroup'
75 2
                ));
76 3
            case 'option':
77 2
                return $this->closeIfCurrentMatches($new, $current, array(
78 2
                    'option',
79 2
                ));
80 1
            case 'tr':
81
                return $this->closeIfCurrentMatches($new, $current, array(
82
                    'tr'
83
                ));
84 1
            case 'td':
85 1
            case 'th':
86 1
                return $this->closeIfCurrentMatches($new, $current, array(
87 1
                    'th',
88
                    'td'
89 1
                ));
90 1
            case 'tbody':
91 1
            case 'thead':
92 1
            case 'tfoot':
93 1
            case 'table': // Spec isn't explicit about this, but it's necessary.
94
95 1
                return $this->closeIfCurrentMatches($new, $current, array(
96 1
                    'thead',
97 1
                    'tfoot',
98
                    'tbody'
99 1
                ));
100
        }
101
102
        return $current;
103
    }
104
105 2
    protected function handleLI($ele, $current)
106
    {
107 2
        return $this->closeIfCurrentMatches($ele, $current, array(
108
            'li'
109 2
        ));
110
    }
111
112 1
    protected function handleDT($ele, $current)
113
    {
114 1
        return $this->closeIfCurrentMatches($ele, $current, array(
115 1
            'dt',
116
            'dd'
117 1
        ));
118
    }
119
120
    protected function handleRT($ele, $current)
121
    {
122
        return $this->closeIfCurrentMatches($ele, $current, array(
123
            'rt',
124
            'rp'
125
        ));
126
    }
127
128 6
    protected function closeIfCurrentMatches($ele, $current, $match)
129
    {
130 6
        if (in_array($current->tagName, $match)) {
131 4
            $current->parentNode->appendChild($ele);
132 4
        } else {
133 6
            $current->appendChild($ele);
134
        }
135
136 6
        return $ele;
137
    }
138
}
139