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