function filterDOM(PHPTAL_Dom_Element $root) { // let xml:space=preserve preserve attributes as well if ($root->getAttributeNS("http://www.w3.org/XML/1998/namespace", 'space') == 'preserve') { $this->findElementToFilter($root); return; } $this->normalizeAttributes($root); // <pre> may have attributes normalized if ($this->isSpaceSensitiveInXHTML($root)) { $this->findElementToFilter($root); return; } $lastTextNode = null; foreach ($root->childNodes as $node) { // CDATA is not normalized by design if ($node instanceof PHPTAL_Dom_Text) { $norm = $this->normalizeSpace($node->getValueEscaped(), $node->getEncoding()); $node->setValueEscaped($norm); if ('' === $norm) { $root->removeChild($node); } else { if ($lastTextNode) { // "foo " . " bar" gives 2 spaces. $norm = $lastTextNode->getValueEscaped() . ltrim($norm, ' '); $lastTextNode->setValueEscaped($norm); // assumes all nodes use same encoding (they do) $root->removeChild($node); } else { $lastTextNode = $node; } } } else { $lastTextNode = null; if ($node instanceof PHPTAL_Dom_Element) { $this->filterDOM($node); } } } }
/** * HTML5 doesn't care about boilerplate */ private function elementSpecificOptimizations(PHPTAL_Dom_Element $element) { if ($element->getNamespaceURI() !== 'http://www.w3.org/1999/xhtml' && $element->getNamespaceURI() !== '') { return; } if ($this->getPHPTAL()->getOutputMode() !== PHPTAL::HTML5) { return; } // <meta charset> if ('meta' === $element->getLocalName() && $element->getAttributeNS('', 'http-equiv') === 'Content-Type') { $element->removeAttributeNS('', 'http-equiv'); $element->removeAttributeNS('', 'content'); $element->setAttributeNS('', 'charset', strtolower($this->getPHPTAL()->getEncoding())); } elseif ('link' === $element->getLocalName() && $element->getAttributeNS('', 'rel') === 'stylesheet' || 'style' === $element->getLocalName()) { // There's only one type of stylesheets that works. $element->removeAttributeNS('', 'type'); } elseif ('script' === $element->getLocalName()) { $element->removeAttributeNS('', 'language'); // Only remove type that matches default. E4X, vbscript, coffeescript, etc. must be preserved $type = $element->getAttributeNS('', 'type'); $is_std = preg_match('/^(?:text|application)\\/(?:ecma|java)script(\\s*;\\s*charset\\s*=\\s*[^;]*)?$/', $type); // Remote scripts should have type specified in HTTP headers. if ($is_std || $element->getAttributeNS('', 'src')) { $element->removeAttributeNS('', 'type'); } } }