/** * Recursively adds {@link FrameParser} objects to the tree * * Recursively build a tree of FrameParser objects based on a dom tree. * No layout information is calculated at this time, although the * tree may be adjusted (i.e. nodes and frames for generated content * and images may be created). * * @param DomNode $node the current DomNode being considered * @return FrameParser */ protected function _build_tree_r(DomNode $node) { $frame = new FrameParser($node); $id = $frame->get_id(); $this->_registry[$id] = $frame; if (!$node->hasChildNodes()) { return $frame; } // Fixes 'cannot access undefined property for object with // overloaded access', fix by Stefan radulian // <*****@*****.**> //foreach ($node->childNodes as $child) { // Store the children in an array so that the tree can be modified $children = array(); for ($i = 0; $i < $node->childNodes->length; $i++) { $children[] = $node->childNodes->item($i); } foreach ($children as $child) { $node_name = mb_strtolower($child->nodeName); // Skip non-displaying nodes if (in_array($node_name, self::$_HIDDEN_TAGS)) { if ($node_name !== "head" && $node_name !== "style") { $child->parentNode->removeChild($child); } continue; } // Skip empty text nodes if ($node_name === "#text" && $child->nodeValue == "") { $child->parentNode->removeChild($child); continue; } // Skip empty image nodes if ($node_name === "img" && $child->getAttribute("src") == "") { $child->parentNode->removeChild($child); continue; } $frame->append_child($this->_build_tree_r($child), false); } return $frame; }
/** * Render frames recursively * * @param FrameParser $frame The frame to render */ private function _render(FrameParser $frame, $filter = false) { $aDompdfTree = array(); $node = $frame->get_node(); switch ($node->nodeName) { case 'caption': //ignore these tags //ignore these tags case 'meta': case 'script': case 'title': break; case 'div': //converts floating divs to floating tables /*$nodeTable = false; $attributes = $this->getProperties($frame->get_style()); if(isset($attributes['float']) && ($attributes['float'] == 'right' || $attributes['float'] == 'left')){ $nodeTable = true; }*/ if ($this->parseDivs == 'table') { //TODO move float childs /*foreach($frame->get_children() as $child){ $attributes = $this->getProperties($child->get_style()); if(isset($attributes['float']) && ($attributes['float'] == 'right' || $attributes['float'] == 'left')){ // $childNode = $child->get_node(); // $childNode = $node->removeChild($childNode); // $node->appendChild($childNode); //$frame->append_child($child); } }*/ $aDompdfTree['nodeName'] = 'table'; //$aDompdfTree['nodeValue'] = $node->nodeValue; $aDompdfTree['attributes'] = $this->getAttributes($node); $aDompdfTree['properties'] = $this->getProperties($frame->get_style()); $filter = $filter == '*' || isset($aDompdfTree['attributes']['class']) && in_array('_phpdocx_filter_paint_', $aDompdfTree['attributes']['class']) ? '*' : false; $sTempFilter = $filter != '*' ? '_noPaint' : ''; $aDompdfTree['nodeName'] .= $sTempFilter; $aDompdfTree['children'][] = array('nodeName' => 'tr' . $sTempFilter, 'attributes' => array('border' => 0), 'properties' => array('background_color' => 'transparent')); $aDompdfTree['children'][0]['children'][] = array('nodeName' => 'td' . $sTempFilter, 'nodeValue' => $node->nodeValue, 'attributes' => array('colspan' => '1', 'rowspan' => '1', 'border' => 0), 'properties' => array('background_color' => 'transparent')); $aTempTree = array(); foreach ($frame->get_children() as $child) { /*$attributes = $this->getProperties($child->get_style()); //TODO extract to parent; make next sibling of this if(isset($attributes['float']) && ($attributes['float'] == 'right' || $attributes['float'] == 'left')){ var_dump($attributes['float'], $child->get_node()); $node->parentNode->appendChild($child->get_node()); continue; }*/ $aTemp = $this->_render($child, $filter); if (!empty($aTemp)) { $aTempTree[] = $aTemp; } } $aDompdfTree['children'][0]['children'][0]['children'] = empty($aTempTree) ? array() : $aTempTree; return $aDompdfTree; break; } //elseif($this->parseDivs) $aDompdfTree['nodeName'] = 'p';/**/ //elseif($this->parseDivs) $aDompdfTree['nodeName'] = 'p';/**/ case '#text': case 'a': case 'br': case 'dd': case 'dl': case 'dt': case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6': case 'img': case 'img_inner': case 'input': case 'label': case 'li': case 'ol': case 'option': case 'p': case 'samp': case 'select': case 'span': case 'sub': case 'sup': case 'table': case 'td': case 'th': case 'tr': case 'u': case 'ul': if ($this->parseDivs == 'paragraph' && $node->nodeName == 'div') { if (!in_array($node->parentNode->nodeName, self::$noDiv)) { $aDompdfTree['nodeName'] = 'p'; } } else { $aDompdfTree['nodeName'] = $node->nodeName; } $aDompdfTree['nodeValue'] = $node->nodeValue; $aDompdfTree['attributes'] = $this->getAttributes($node); $aDompdfTree['properties'] = $this->getProperties($frame->get_style()); $filter = $filter == '*' || isset($aDompdfTree['attributes']['class']) && in_array('_phpdocx_filter_paint_', $aDompdfTree['attributes']['class']) ? '*' : false; if ($filter != '*') { $aDompdfTree['nodeName'] .= '_noPaint'; } $aTempTree = array(); foreach ($frame->get_children() as $child) { $aTemp = $this->_render($child, $filter); if (!empty($aTemp)) { $aTempTree[] = $aTemp; } } $aDompdfTree['children'] = empty($aTempTree) ? array() : $aTempTree; return $aDompdfTree; break; case 'close': $aDompdfTree['nodeName'] = $node->nodeName; foreach ($frame->get_children() as $child) { $aTemp = $this->_render($child, false); if (!empty($aTemp)) { $aTempTree[] = $aTemp; } } $aDompdfTree['children'] = empty($aTempTree) ? array() : $aTempTree; return $aDompdfTree; break; default: $aDompdfTree['nodeName'] = $node->nodeName; $aDompdfTree['attributes'] = $this->getAttributes($node); $filter = $filter == '*' || isset($aDompdfTree['attributes']['class']) && in_array('_phpdocx_filter_paint_', $aDompdfTree['attributes']['class']) ? '*' : false; if ($filter != '*') { $aDompdfTree['nodeName'] .= '_noPaint'; } foreach ($frame->get_children() as $child) { $aTemp = $this->_render($child, $filter); if (!empty($aTemp)) { $aTempTree[] = $aTemp; } } $aDompdfTree['children'] = empty($aTempTree) ? array() : $aTempTree; return $aDompdfTree; break; } return false; }
/** * @return FrameParser */ function next() { $ret = $this->_cur; if (!$ret) { return null; } $this->_cur = $this->_cur->get_next_sibling(); $this->_num++; return $ret; }