annotate vendor/masterminds/html5/src/HTML5/Parser/TreeBuildingRules.php @ 2:92f882872392

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