/**
  * 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;
 }