Chris@0: 1, Chris@0: 'dd' => 1, Chris@0: 'dt' => 1, Chris@0: 'rt' => 1, Chris@0: 'rp' => 1, Chris@0: 'tr' => 1, Chris@0: 'th' => 1, Chris@0: 'td' => 1, Chris@0: 'thead' => 1, Chris@0: 'tfoot' => 1, Chris@0: 'tbody' => 1, Chris@0: 'table' => 1, Chris@0: 'optgroup' => 1, Chris@17: 'option' => 1, Chris@0: ); Chris@0: Chris@0: /** Chris@0: * Returns true if the given tagname has special processing rules. Chris@0: */ Chris@0: public function hasRules($tagname) Chris@0: { Chris@0: return isset(static::$tags[$tagname]); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Evaluate the rule for the current tag name. Chris@0: * Chris@0: * This may modify the existing DOM. Chris@0: * Chris@0: * @return \DOMElement The new Current DOM element. Chris@0: */ Chris@0: public function evaluate($new, $current) Chris@0: { Chris@0: switch ($new->tagName) { Chris@0: case 'li': Chris@0: return $this->handleLI($new, $current); Chris@0: case 'dt': Chris@0: case 'dd': Chris@0: return $this->handleDT($new, $current); Chris@0: case 'rt': Chris@0: case 'rp': Chris@0: return $this->handleRT($new, $current); Chris@0: case 'optgroup': Chris@0: return $this->closeIfCurrentMatches($new, $current, array( Chris@17: 'optgroup', Chris@0: )); Chris@0: case 'option': Chris@0: return $this->closeIfCurrentMatches($new, $current, array( Chris@0: 'option', Chris@0: )); Chris@0: case 'tr': Chris@0: return $this->closeIfCurrentMatches($new, $current, array( Chris@17: 'tr', Chris@0: )); Chris@0: case 'td': Chris@0: case 'th': Chris@0: return $this->closeIfCurrentMatches($new, $current, array( Chris@0: 'th', Chris@17: 'td', Chris@0: )); Chris@0: case 'tbody': Chris@0: case 'thead': Chris@0: case 'tfoot': Chris@0: case 'table': // Spec isn't explicit about this, but it's necessary. Chris@0: Chris@0: return $this->closeIfCurrentMatches($new, $current, array( Chris@0: 'thead', Chris@0: 'tfoot', Chris@17: 'tbody', Chris@0: )); Chris@0: } Chris@0: Chris@0: return $current; Chris@0: } Chris@0: Chris@0: protected function handleLI($ele, $current) Chris@0: { Chris@0: return $this->closeIfCurrentMatches($ele, $current, array( Chris@17: 'li', Chris@0: )); Chris@0: } Chris@0: Chris@0: protected function handleDT($ele, $current) Chris@0: { Chris@0: return $this->closeIfCurrentMatches($ele, $current, array( Chris@0: 'dt', Chris@17: 'dd', Chris@0: )); Chris@0: } Chris@0: Chris@0: protected function handleRT($ele, $current) Chris@0: { Chris@0: return $this->closeIfCurrentMatches($ele, $current, array( Chris@0: 'rt', Chris@17: 'rp', Chris@0: )); Chris@0: } Chris@0: Chris@0: protected function closeIfCurrentMatches($ele, $current, $match) Chris@0: { Chris@17: if (in_array($current->tagName, $match, true)) { Chris@0: $current->parentNode->appendChild($ele); Chris@0: } else { Chris@0: $current->appendChild($ele); Chris@0: } Chris@0: Chris@0: return $ele; Chris@0: } Chris@0: }