/** * Debug helper to print the tag tree in HTML format. * * @param XenForo_Html_Tag $tag Current/root tag * @param string $prefix Prefix for each line */ public function printTags(XenForo_Html_Tag $tag, $prefix = '') { echo $prefix . 'Tag: ' . $tag->tagName() . ' ' . json_encode($tag->attributes()) . "<br />\n"; $childPrefix = "{$prefix} "; foreach ($tag->children() as $child) { if ($child instanceof XenForo_Html_Tag) { $this->printTags($child, $childPrefix); } else { echo $childPrefix . "'" . htmlspecialchars($child) . "'<br />\n"; } } }
public function renderChildren(XenForo_Html_Tag $tag, array $state) { $output = array(); foreach ($tag->children() as $child) { if ($child instanceof XenForo_Html_Tag) { $output[] = $this->renderTag($child, $state); } else { if ($child instanceof XenForo_Html_Text) { $output[] = $this->renderText($child, $state); } } } return $output; }
protected function _handleListTag($listFormatter, $text, XenForo_Html_Tag $tag) { if (!strlen($text)) { // no children, just do a linebreak return "\n"; } $childList = 0; $childOtherTag = 0; $childText = 0; foreach ($tag->children() as $child) { if ($child instanceof XenForo_Html_Tag) { if ($child->tagName() == 'ol' || $child->tagName() == 'ul') { $childList++; } else { $childOtherTag++; } } else { if ($child instanceof XenForo_Html_Text) { if (strlen(trim($child->text())) > 0) { $childText++; } } } } if ($childList && !$childOtherTag && !$childText) { // just a list like <ul><ul><li>...</ul></ul>. This is how Chrome implements indent return "[INDENT]{$text}[/INDENT]"; } else { return sprintf($listFormatter, $text); } }
/** * Renders the specififed tag and all children. * * @param XenForo_Html_Tag $tag * * @return string */ public function renderTag(XenForo_Html_Tag $tag) { if (isset($this->_handlers[$tag->tagName()])) { $handler = $this->_handlers[$tag->tagName()]; } else { $handler = null; } $currentIsBlock = $tag->isBlock(); $output = array(); $children = $tag->children(); $lastKey = count($children) - 1; foreach ($children as $key => $child) { if ($child instanceof XenForo_Html_Tag) { if ($currentIsBlock && $key == $lastKey && $child->tagName() == 'br') { // ignore 1 trailing br of block tag continue; } else { if ($child->isBlock() && $child->isEmpty()) { // block with nothing worth rendering continue; } } $text = $this->renderTag($child); if ($text !== '' || $child->isBlock()) { $output[] = array('type' => $child->isBlock() ? 'block' : 'inline', 'text' => $text); } } else { if ($child instanceof XenForo_Html_Text) { $output[] = array('type' => 'text', 'text' => $this->renderText($child)); } } } $stringOutput = ''; $maxCounter = count($output) - 1; foreach ($output as $counter => $childOutput) { $text = $childOutput['text']; $hasPrevious = $counter > 0; $hasNext = $counter < $maxCounter; switch ($childOutput['type']) { case 'text': if ($currentIsBlock && !$hasPrevious) { // caused problems with leading spaces //$text = ltrim($text); } else { if ($hasPrevious && $output[$counter - 1]['type'] == 'block') { $text = "\n" . ltrim($text); } } if ($hasNext && $output[$counter + 1]['type'] == 'block') { $text = rtrim($text); } else { if (!$hasNext && $currentIsBlock) { $text = rtrim($text); } } break; case 'block': if ($hasPrevious) { $text = "\n" . $text; } break; } $stringOutput .= $text; } $preCssOutput = $stringOutput; if (!$handler || empty($handler['skipCss'])) { $stringOutput = $this->renderCss($tag, $stringOutput); } if (!empty($handler['filterCallback'])) { $callback = $handler['filterCallback']; if (is_array($callback) && $callback[0] == '$this') { $callback[0] = $this; } $stringOutput = call_user_func($callback, $stringOutput, $tag, $preCssOutput); } else { if (isset($handler['wrap'])) { $stringOutput = sprintf($handler['wrap'], $stringOutput); } } return $stringOutput; }