function normalizeAttributes(PHPTAL_Dom_Element $element) { foreach ($element->getAttributeNodes() as $attrnode) { if ($attrnode->getReplacedState() !== PHPTAL_Dom_Attr::NOT_REPLACED) { continue; } $val = $this->normalizeSpace($attrnode->getValueEscaped(), $attrnode->getEncoding()); $attrnode->setValueEscaped(trim($val, ' ')); } }
public function generateCode(PHPTAL_Dom_Element $treeGen) { $codewriter = new PHPTAL_Php_CodeWriter($this->_state); $codewriter->doComment("\n*** DO NOT EDIT THIS FILE ***\n\nGenerated by PHPTAL from " . $this->_sourceFile . " (edit that file instead)"); $codewriter->doFunction($this->_functionName, '$tpl, $ctx'); $codewriter->setFunctionPrefix($this->_functionName . "_"); $codewriter->doSetVar('$_thistpl', '$tpl'); $codewriter->doSetVar('$_translator', '$tpl->getTranslator()'); $treeGen->generateCode($codewriter); $codewriter->doEnd(); return $codewriter->getResult(); }
function filterDOM(PHPTAL_Dom_Element $element) { $defs = PHPTAL_Dom_Defs::getInstance(); foreach ($element->childNodes as $node) { if ($node instanceof PHPTAL_Dom_Comment) { if ($defs->isCDATAElementInHTML($element->getNamespaceURI(), $element->getLocalName())) { $textNode = new PHPTAL_Dom_CDATASection($node->getValueEscaped(), $node->getEncoding()); $node->parentNode->replaceChild($textNode, $node); } else { $node->parentNode->removeChild($node); } } else { if ($node instanceof PHPTAL_Dom_Element) { $this->filterDOM($node); } } } }
public function generateCode(PHPTAL_Php_CodeWriter $codewriter) { // For backwards compatibility only! self::$_codewriter_bc_hack_ = $codewriter; // FIXME try { /// self-modifications if ($codewriter->getOutputMode() === PHPTAL::XHTML) { $this->replaceTextWithCDATA(); } /// code generation if ($this->getSourceLine()) { $codewriter->doComment('tag "' . $this->qualifiedName . '" from line ' . $this->getSourceLine()); } $this->generateSurroundHead($codewriter); if (count($this->replaceAttributes)) { foreach ($this->replaceAttributes as $att) { $att->before($codewriter); $att->after($codewriter); } } elseif (!$this->hidden) { // a surround tag may decide to hide us (tal:define for example) $this->generateHead($codewriter); $this->generateContent($codewriter); $this->generateFoot($codewriter); } $this->generateSurroundFoot($codewriter); } catch (PHPTAL_TemplateException $e) { $e->hintSrcPosition($this->getSourceFile(), $this->getSourceLine()); throw $e; } }
/** * @param bool $is_nested_in_repeat true if any parent element has tal:repeat * * @return rough guess */ private function estimateNumberOfBytesOutput(PHPTAL_Dom_Element $element, $is_nested_in_repeat) { // macros don't output anything on their own if ($element->hasAttributeNS('http://xml.zope.org/namespaces/metal', 'define-macro')) { return 0; } $estimated_bytes = 2 * (3 + strlen($element->getQualifiedName())); foreach ($element->getAttributeNodes() as $attr) { $estimated_bytes += 4 + strlen($attr->getQualifiedName()); if ($attr->getReplacedState() === PHPTAL_Dom_Attr::NOT_REPLACED) { $estimated_bytes += strlen($attr->getValueEscaped()); // this is shoddy for replaced attributes } } $has_repeat_attr = $element->hasAttributeNS('http://xml.zope.org/namespaces/tal', 'repeat'); if ($element->hasAttributeNS('http://xml.zope.org/namespaces/tal', 'content') || $element->hasAttributeNS('http://xml.zope.org/namespaces/tal', 'replace')) { // assume that output in loops is shorter (e.g. table rows) than outside (main content) $estimated_bytes += $has_repeat_attr || $is_nested_in_repeat ? 500 : 2000; } else { foreach ($element->childNodes as $node) { if ($node instanceof PHPTAL_Dom_Element) { $estimated_bytes += $this->estimateNumberOfBytesOutput($node, $has_repeat_attr || $is_nested_in_repeat); } else { $estimated_bytes += strlen($node->getValueEscaped()); } } } if ($element->hasAttributeNS('http://xml.zope.org/namespaces/metal', 'use-macro')) { $estimated_bytes += $has_repeat_attr || $is_nested_in_repeat ? 500 : 2000; } if ($element->hasAttributeNS('http://xml.zope.org/namespaces/tal', 'condition')) { $estimated_bytes /= 2; // naively assuming 50% chance, that works well with if/else pattern } if ($element->hasAttributeNS('http://xml.zope.org/namespaces/tal', 'repeat')) { // assume people don't write big nested loops $estimated_bytes *= $is_nested_in_repeat ? 5 : 10; } return $estimated_bytes; }
public function doTemplateFile($functionName, PHPTAL_Dom_Element $treeGen) { $this->doComment("\n*** DO NOT EDIT THIS FILE ***\n\nGenerated by PHPTAL from " . $treeGen->getSourceFile() . " (edit that file instead)"); $this->doFunction($functionName, 'PHPTAL $tpl, PHPTAL_Context $ctx'); $this->setFunctionPrefix($functionName . "_"); $this->doSetVar('$_thistpl', '$tpl'); $this->doInitTranslator(); $treeGen->generateCode($this); $this->doComment("end"); $this->doEnd('function'); }
/** * 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'); } } }
public function onElementStart($name, $attributes) { $this->_xmlns = PHPTAL_Dom_XmlnsState::newElement($this->_xmlns, $attributes); foreach ($attributes as $key => $value) { if (!$this->_xmlns->isValidAttribute($key)) { $this->raiseError(self::ERR_UNSUPPORTED_ATTRIBUTE, $key); } } $node = new PHPTAL_Dom_Element($name, $attributes); $node->setXmlnsState($this->getXmlnsState()); $this->pushNode($node); array_push($this->_stack, $this->_current); $this->_current = $node; }