annotate vendor/masterminds/html5/src/HTML5/Parser/TreeBuildingRules.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
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 }