public function element($ele) { $name = $ele->tagName; // Per spec: // If the element has a declared namespace in the HTML, MathML or // SVG namespaces, we use the lname instead of the tagName. if ($this->traverser->isLocalElement($ele)) { $name = $ele->localName; } // If we are in SVG or MathML there is special handling. // Using if/elseif instead of switch because it's faster in PHP. if ($name == 'svg') { $this->outputMode = static::IM_IN_SVG; $name = Elements::normalizeSvgElement($name); } elseif ($name == 'math') { $this->outputMode = static::IM_IN_MATHML; } $this->openTag($ele); if (Elements::isA($name, Elements::TEXT_RAW)) { foreach ($ele->childNodes as $child) { $this->wr($child->data); } } else { // Handle children. if ($ele->hasChildNodes()) { $this->traverser->children($ele->childNodes); } // Close out the SVG or MathML special handling. if ($name == 'svg' || $name == 'math') { $this->outputMode = static::IM_IN_HTML; } } // If not unary, add a closing tag. if (!Elements::isA($name, Elements::VOID_TAG)) { $this->closeTag($ele); } }
public function endTag($name) { $lname = $this->normalizeTagName($name); // Ignore closing tags for unary elements. if (Elements::isA($name, Elements::VOID_TAG)) { return; } if ($this->insertMode <= static::IM_BEFORE_HTML) { // 8.2.5.4.2 if (in_array($name, array('html', 'br', 'head', 'title'))) { $this->startTag('html'); $this->endTag($name); $this->insertMode = static::IM_BEFORE_HEAD; return; } // Ignore the tag. $this->parseError("Illegal closing tag at global scope."); return; } // Special case handling for SVG. if ($this->insertMode == static::IM_IN_SVG) { $lname = Elements::normalizeSvgElement($lname); } // See https://github.com/facebook/hhvm/issues/2962 if (defined('HHVM_VERSION') && ($cid = $this->current->getAttribute('html5-php-fake-id-attribute'))) { $this->current->removeAttribute('html5-php-fake-id-attribute'); } else { $cid = spl_object_hash($this->current); } // XXX: Not sure whether we need this anymore. // if ($name != $lname) { // return $this->quirksTreeResolver($lname); // } // XXX: HTML has no parent. What do we do, though, // if this element appears in the wrong place? if ($lname == 'html') { return; } // remove the namespaced definded by current node if (isset($this->pushes[$cid])) { for ($i = 0; $i < $this->pushes[$cid][0]; $i++) { array_shift($this->nsStack); } unset($this->pushes[$cid]); } if (!$this->autoclose($lname)) { $this->parseError('Could not find closing tag for ' . $lname); } // switch ($this->insertMode) { switch ($lname) { case "head": $this->insertMode = static::IM_AFTER_HEAD; break; case "body": $this->insertMode = static::IM_AFTER_BODY; break; case "svg": case "mathml": $this->insertMode = static::IM_IN_BODY; break; } }
public function testNormalizeSvgElement() { $tests = array('foo' => 'foo', 'altglyph' => 'altGlyph', 'BAR' => 'bar', 'fespecularlighting' => 'feSpecularLighting', 'bAz' => 'baz', 'foreignobject' => 'foreignObject'); foreach ($tests as $input => $expected) { $this->assertEquals($expected, Elements::normalizeSvgElement($input)); } }