FluentDOM Package
Current file: /fluentdom/releases/release_1.0/FluentDOM/FluentDOM.php
Legend: executed not executed dead code

  Coverage
  Classes Functions / Methods Lines
Total
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 82 / 82
99.87%99.87%
99.87% 774 / 775
 
FluentDOM
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 81 / 81
99.87%99.87%
99.87% 773 / 774
 public function __construct($source)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 17 / 17
 public function __get($name)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 9 / 9
 public function __set($name, $value)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 9 / 9
 public function __isset($name)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 6 / 6
 public function __call($name, $arguments)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 8 / 8
 public function __toString()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 public function item($position)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 3 / 3
 public function current()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 public function key()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 public function next()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 2 / 2
 public function rewind()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 2 / 2
 public function seek($position)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 5 / 5
 public function valid()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 public function getChildren()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 3 / 3
 public function hasChildren()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 public function count()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 public function offsetSet($offset, $value)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 public function offsetExists($offset)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 public function offsetUnset($offset)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 public function offsetGet($offset)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 protected function _spawn()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 private function _xpath()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 13 / 13
 private function _match($expr, $context = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 3 / 3
 private function _test($expr, $context)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 4 / 4
 private function _push($elements, $unique = false)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 23 / 23
 private function _inList($node)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 5 / 5
 private function _isQName($name)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 3 / 3
 private function _isNode($node)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 8 / 8
 protected function _isCallback($callback)
100.00%100.00%
100.00% 1 / 1
90.91%90.91%
90.91% 10 / 11
 private function _getContentNodes($content, $includeTextNodes = true, $limit = 0)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 40 / 40
 private function _getTargetNodes($selector)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 9 / 9
 private function _removeNodes($selector)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 9 / 9
 private function _getContentElement($content)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 4 / 4
 public function each($function)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 6 / 6
 public function formatOutput()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 8 / 8
 public function eq($position)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 5 / 5
 public function filter($expr)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 13 / 13
 public function is($expr)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 4 / 4
 public function map($function)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 19 / 19
 public function not($expr)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 13 / 13
 public function slice($start, $end = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 10 / 10
 public function add($expr)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 9 / 9
 public function children($expr = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 12 / 12
 public function find($expr)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 8 / 8
 public function nextSiblings($expr = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 13 / 13
 public function nextAllSiblings($expr = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 13 / 13
 public function parent()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 7 / 7
 public function parents($expr = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 11 / 11
 public function prevSiblings($expr = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 13 / 13
 public function prevAllSiblings($expr = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 13 / 13
 public function siblings($expr = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 15 / 15
 public function andSelf()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 4 / 4
 public function end()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 3 / 3
 public function xml($xml = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 20 / 20
 public function text($text = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 10 / 10
 public function append($content)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 public function appendTo($expr)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 public function prepend($content)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 public function prependTo($expr)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 private function _insertChild($content, $first)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 29 / 29
 private function _insertChildTo($selector, $first)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 19 / 19
 public function after($content)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 16 / 16
 public function before($content)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 15 / 15
 public function insertAfter($selector)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 18 / 18
 public function insertBefore($selector)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 17 / 17
 private function _wrap($elements, $content)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 22 / 22
 public function wrap($content)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 3 / 3
 public function wrapAll($content)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 41 / 41
 public function wrapInner($content)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 11 / 11
 public function replaceWith($content)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 12 / 12
 public function replaceAll($selector)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 16 / 16
 private function _emptyNodes()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 7 / 7
 public function remove($expr = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 9 / 9
 public function node($content)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 3 / 3
 private function _cloneNodes()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 5 / 5
 public function attr($attribute, $value = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 39 / 39
 public function removeAttr($name)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 9 / 9
 public function addClass($class)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 public function hasClass($class)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 9 / 9
 public function removeClass($class)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 public function toggleClass($class, $switch = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 32 / 32
Functions
  
   
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 0 / 0
 function FluentDOM($source)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1


       1                 : <?php                                                                                                           
       2                 : /**                                                                                                             
       3                 : * FluentDOM implements a jQuery like replacement for DOMNodeList                                                
       4                 : *                                                                                                               
       5                 : * @version $Id: FluentDOM.php 185 2009-06-16 21:59:30Z lapis $                                                  
       6                 : * @license http://www.opensource.org/licenses/mit-license.php The MIT License                                   
       7                 : * @copyright Copyright (c) 2009 Bastian Feder, Thomas Weinert                                                   
       8                 : */                                                                                                              
       9                 :                                                                                                                 
      10                 : /**                                                                                                             
      11                 : * Function to create a new FluentDOM instance                                                                   
      12                 : *                                                                                                               
      13                 : * This is a shortcut for "new FluentDOM($source)"                                                               
      14                 : *                                                                                                               
      15                 : * @param mixed $source                                                                                          
      16                 : * @access public                                                                                                
      17                 : * @return object FluentDOM                                                                                      
      18                 : */                                                                                                              
      19                 : function FluentDOM($source) {                                                                                   
      20              98 :   return new FluentDOM($source);                                                                                
      21                 : }                                                                                                               
      22                 :                                                                                                                 
      23                 : /**                                                                                                             
      24                 : * FluentDOM implements a jQuery like replacement for DOMNodeList                                                
      25                 : */                                                                                                              
      26                 : class FluentDOM implements RecursiveIterator, SeekableIterator, Countable, ArrayAccess {                        
      27                 :                                                                                                                 
      28                 :   /**                                                                                                           
      29                 :   * document object                                                                                             
      30                 :   * @var object DOMDocument                                                                                     
      31                 :   * @access private                                                                                             
      32                 :   */                                                                                                            
      33                 :   private $_document = NULL;                                                                                    
      34                 :                                                                                                                 
      35                 :   /**                                                                                                           
      36                 :   * use document context for expression                                                                         
      37                 :   * @var boolean                                                                                                
      38                 :   * @access private                                                                                             
      39                 :   */                                                                                                            
      40                 :   private $_useDocumentContext = FALSE;                                                                         
      41                 :                                                                                                                 
      42                 :   /**                                                                                                           
      43                 :   * parent node list (last selection in chain)                                                                  
      44                 :   * @var object FluentDOM                                                                                       
      45                 :   * @access private                                                                                             
      46                 :   */                                                                                                            
      47                 :   private $_parent = NULL;                                                                                      
      48                 :                                                                                                                 
      49                 :   /**                                                                                                           
      50                 :   * current iterator position                                                                                   
      51                 :   * @var integer                                                                                                
      52                 :   * @access private                                                                                             
      53                 :   */                                                                                                            
      54                 :   private $_position = 0;                                                                                       
      55                 :                                                                                                                 
      56                 :   /**                                                                                                           
      57                 :   * element nodes                                                                                               
      58                 :   * @var array                                                                                                  
      59                 :   * @access protected                                                                                           
      60                 :   */                                                                                                            
      61                 :   protected $_array = array();                                                                                  
      62                 :                                                                                                                 
      63                 :   /**                                                                                                           
      64                 :   * internal xpath instance                                                                                     
      65                 :   * @var object DOMXPath                                                                                        
      66                 :   * @access private                                                                                             
      67                 :   */                                                                                                            
      68                 :   private $_xpath = NULL;                                                                                       
      69                 :                                                                                                                 
      70                 :   /**                                                                                                           
      71                 :   * initialize the FluentDOM instance and set private properties                                                
      72                 :   *                                                                                                             
      73                 :   * @param object FluentDOM | object DOMElement | object DOMDocument $source                                    
      74                 :   * source to create FluentDOM from                                                                             
      75                 :   * @access public                                                                                              
      76                 :   */                                                                                                            
      77                 :   public function __construct($source) {                                                                        
      78             119 :     if ($source instanceof FluentDOM) {                                                                         
      79             106 :       $this->_document = $source->document;                                                                     
      80             106 :       $this->_xpath = $source->_xpath;                                                                          
      81             106 :       $this->_parent = $source;                                                                                 
      82             119 :     } elseif ($source instanceof DOMDocument) {                                                                 
      83               1 :       $this->_document = $source;                                                                               
      84               1 :       $this->_useDocumentContext = TRUE;                                                                        
      85             119 :     } elseif ($this->_isNode($source)) {                                                                        
      86               4 :       $this->_document = $source->ownerDocument;                                                                
      87               4 :       $this->_push($source);                                                                                    
      88             118 :     } elseif (is_string($source)) {                                                                             
      89             116 :       $this->_document = new DOMDocument();                                                                     
      90             116 :       $this->_document->loadXML($source);                                                                       
      91             116 :       $this->_useDocumentContext = TRUE;                                                                        
      92             116 :     } else {                                                                                                    
      93               1 :       throw new InvalidArgumentException('Invalid source object.');                                             
      94                 :     }                                                                                                           
      95             118 :   }                                                                                                             
      96                 :                                                                                                                 
      97                 :   /**                                                                                                           
      98                 :   * implement dynamic properties using magic methods                                                            
      99                 :   *                                                                                                             
     100                 :   * @param string $name                                                                                         
     101                 :   * @access public                                                                                              
     102                 :   * @return mixed                                                                                               
     103                 :   */                                                                                                            
     104                 :   public function __get($name) {                                                                                
     105                 :     switch ($name) {                                                                                            
     106             111 :     case 'length' :                                                                                             
     107              12 :       return count($this->_array);                                                                              
     108             110 :     case 'document' :                                                                                           
     109             108 :       return $this->_document;                                                                                  
     110               3 :     case 'xpath' :                                                                                              
     111               2 :       return $this->_xpath();                                                                                   
     112               1 :     default :                                                                                                   
     113               1 :       return NULL;                                                                                              
     114               1 :     }                                                                                                           
     115                 :   }                                                                                                             
     116                 :                                                                                                                 
     117                 :   /**                                                                                                           
     118                 :   * block changes of dynamic readonly property length                                                           
     119                 :   *                                                                                                             
     120                 :   * @param $name                                                                                                
     121                 :   * @param $value                                                                                               
     122                 :   * @access public                                                                                              
     123                 :   * @return void                                                                                                
     124                 :   */                                                                                                            
     125                 :   public function __set($name, $value) {                                                                        
     126                 :     switch ($name) {                                                                                            
     127               4 :     case 'length' :                                                                                             
     128               4 :     case 'document' :                                                                                           
     129               4 :     case 'xpath' :                                                                                              
     130               3 :       throw new BadMethodCallException('Can not set readonly value.');                                          
     131                 :       break;                                                                                                    
     132               1 :     default :                                                                                                   
     133               1 :       $this->$name = $value;                                                                                    
     134               1 :       break;                                                                                                    
     135               1 :     }                                                                                                           
     136               1 :   }                                                                                                             
     137                 :                                                                                                                 
     138                 :   /**                                                                                                           
     139                 :   * support isst for dynic properties length and document                                                       
     140                 :   *                                                                                                             
     141                 :   * @param $name                                                                                                
     142                 :   * @access public                                                                                              
     143                 :   * @return boolean                                                                                             
     144                 :   */                                                                                                            
     145                 :   public function __isset($name) {                                                                              
     146                 :     switch ($name) {                                                                                            
     147               4 :     case 'length' :                                                                                             
     148               4 :     case 'xpath' :                                                                                              
     149               2 :       return TRUE;                                                                                              
     150               2 :     case 'document' :                                                                                           
     151               1 :       return isset($this->_document);                                                                           
     152                 :     }                                                                                                           
     153               1 :     return FALSE;                                                                                               
     154                 :   }                                                                                                             
     155                 :                                                                                                                 
     156                 :   /**                                                                                                           
     157                 :   * declaring an empty() method will crash the parser so we use some magic                                      
     158                 :   *                                                                                                             
     159                 :   * @param string $name                                                                                         
     160                 :   * @param array $arguments                                                                                     
     161                 :   * @access public                                                                                              
     162                 :   * @return mixed                                                                                               
     163                 :   */                                                                                                            
     164                 :   public function __call($name, $arguments) {                                                                   
     165               3 :     switch (strtolower($name)) {                                                                                
     166               3 :     case 'empty' :                                                                                              
     167               1 :       return $this->_emptyNodes();                                                                              
     168               2 :     case 'clone' :                                                                                              
     169               1 :       return $this->_cloneNodes();                                                                              
     170               1 :     default :                                                                                                   
     171               1 :       throw new BadMethodCallException('Unknown method '.get_class($this).'::'.$name);                          
     172               1 :     }                                                                                                           
     173                 :   }                                                                                                             
     174                 :                                                                                                                 
     175                 :   /**                                                                                                           
     176                 :   * Return the XML output of the internal dom document                                                          
     177                 :   *                                                                                                             
     178                 :   * @access public                                                                                              
     179                 :   * @return string                                                                                              
     180                 :   */                                                                                                            
     181                 :   public function __toString() {                                                                                
     182              46 :     return $this->_document->saveXML();                                                                         
     183                 :   }                                                                                                             
     184                 :                                                                                                                 
     185                 :   /**                                                                                                           
     186                 :   * the item() method is used to access elements in the node list                                               
     187                 :   *                                                                                                             
     188                 :   * @param $position                                                                                            
     189                 :   * @access public                                                                                              
     190                 :   * @return object DOMNode                                                                                      
     191                 :   */                                                                                                            
     192                 :   public function item($position) {                                                                             
     193               3 :     if (isset($this->_array[$position])) {                                                                      
     194               3 :       return $this->_array[$position];                                                                          
     195                 :     }                                                                                                           
     196               1 :     return NULL;                                                                                                
     197                 :   }                                                                                                             
     198                 :                                                                                                                 
     199                 :   /*                                                                                                            
     200                 :   * Interface - Iterator, SeekableIterator                                                                      
     201                 :   */                                                                                                            
     202                 :                                                                                                                 
     203                 :   /**                                                                                                           
     204                 :   * Get current iterator element                                                                                
     205                 :   *                                                                                                             
     206                 :   * @access public                                                                                              
     207                 :   * @return DOMNode                                                                                             
     208                 :   */                                                                                                            
     209                 :   public function current() {                                                                                   
     210              11 :     return $this->_array[$this->_position];                                                                     
     211                 :   }                                                                                                             
     212                 :                                                                                                                 
     213                 :   /**                                                                                                           
     214                 :   * Get current iterator pointer                                                                                
     215                 :   *                                                                                                             
     216                 :   * @access public                                                                                              
     217                 :   * @return integer                                                                                             
     218                 :   */                                                                                                            
     219                 :   public function key() {                                                                                       
     220               3 :     return $this->_position;                                                                                    
     221                 :   }                                                                                                             
     222                 :                                                                                                                 
     223                 :   /**                                                                                                           
     224                 :   * Move iterator pointer to next element                                                                       
     225                 :   *                                                                                                             
     226                 :   * @access public                                                                                              
     227                 :   * @return void                                                                                                
     228                 :   */                                                                                                            
     229                 :   public function next() {                                                                                      
     230              10 :     ++$this->_position;                                                                                         
     231              10 :   }                                                                                                             
     232                 :                                                                                                                 
     233                 :   /**                                                                                                           
     234                 :   * Reset iterator pointer                                                                                      
     235                 :   *                                                                                                             
     236                 :   * @access public                                                                                              
     237                 :   * @return void                                                                                                
     238                 :   */                                                                                                            
     239                 :   public function rewind() {                                                                                    
     240              12 :     $this->_position = 0;                                                                                       
     241              12 :   }                                                                                                             
     242                 :                                                                                                                 
     243                 :   /**                                                                                                           
     244                 :   * Move iterator pointer to specified element                                                                  
     245                 :   *                                                                                                             
     246                 :   * @param integer $position                                                                                    
     247                 :   * @access public                                                                                              
     248                 :   * @return void                                                                                                
     249                 :   */                                                                                                            
     250                 :   public function seek($position) {                                                                             
     251               1 :     if (isset($this->_array[$position])) {                                                                      
     252               1 :       $this->_position = $position;                                                                             
     253               1 :     } else {                                                                                                    
     254               1 :       throw new InvalidArgumentException('Unknown position');                                                   
     255                 :     }                                                                                                           
     256               1 :   }                                                                                                             
     257                 :                                                                                                                 
     258                 :   /**                                                                                                           
     259                 :   * Check if current iterator pointer contains a valid element                                                  
     260                 :   *                                                                                                             
     261                 :   * @access public                                                                                              
     262                 :   * @return boolean                                                                                             
     263                 :   */                                                                                                            
     264                 :   public function valid() {                                                                                     
     265              11 :     return isset($this->_array[$this->_position]);                                                              
     266                 :   }                                                                                                             
     267                 :                                                                                                                 
     268                 :   /**                                                                                                           
     269                 :   * Get children of the current iterator element                                                                
     270                 :   *                                                                                                             
     271                 :   * @access public                                                                                              
     272                 :   * @return object FluentDOM                                                                                    
     273                 :   */                                                                                                            
     274                 :   public function getChildren() {                                                                               
     275               1 :     $result = $this->_spawn();                                                                                  
     276               1 :     $result->_push($this->_match('node()', $this->_array[$this->_position]));                                   
     277               1 :     return $result;                                                                                             
     278                 :   }                                                                                                             
     279                 :                                                                                                                 
     280                 :   /**                                                                                                           
     281                 :   * Check if the current iterator element has children                                                          
     282                 :   *                                                                                                             
     283                 :   * @access public                                                                                              
     284                 :   * @return object FluentDOM                                                                                    
     285                 :   */                                                                                                            
     286                 :   public function hasChildren() {                                                                               
     287               1 :     return $this->_test('node()', $this->_array[$this->_position]);                                             
     288                 :   }                                                                                                             
     289                 :                                                                                                                 
     290                 :   /*                                                                                                            
     291                 :   * Interface - Countable                                                                                       
     292                 :   */                                                                                                            
     293                 :                                                                                                                 
     294                 :   /**                                                                                                           
     295                 :   * get element count (Countable)                                                                               
     296                 :   *                                                                                                             
     297                 :   * @access public                                                                                              
     298                 :   * @return                                                                                                     
     299                 :   */                                                                                                            
     300                 :   public function count() {                                                                                     
     301               5 :     return count($this->_array);                                                                                
     302                 :   }                                                                                                             
     303                 :                                                                                                                 
     304                 :   /*                                                                                                            
     305                 :   * Interface - ArrayAccess                                                                                     
     306                 :   */                                                                                                            
     307                 :                                                                                                                 
     308                 :   /**                                                                                                           
     309                 :   * If somebody tries to modify the internal array throw an exception.                                          
     310                 :   *                                                                                                             
     311                 :   * @param integer $offset                                                                                      
     312                 :   * @param mixed $value                                                                                         
     313                 :   * @access public                                                                                              
     314                 :   * @return void                                                                                                
     315                 :   */                                                                                                            
     316                 :   public function offsetSet($offset, $value) {                                                                  
     317               1 :     throw new BadMethodCallException('List is read only');                                                      
     318                 :   }                                                                                                             
     319                 :                                                                                                                 
     320                 :   /**                                                                                                           
     321                 :   * Check if index exists in internal array                                                                     
     322                 :   *                                                                                                             
     323                 :   * @param integer $offset                                                                                      
     324                 :   * @access public                                                                                              
     325                 :   * @return boolean                                                                                             
     326                 :   */                                                                                                            
     327                 :   public function offsetExists($offset) {                                                                       
     328               1 :     return isset($this->_array[$offset]);                                                                       
     329                 :   }                                                                                                             
     330                 :                                                                                                                 
     331                 :   /**                                                                                                           
     332                 :   * If somebody tries to remove an element from the internal array throw an exception.                          
     333                 :   *                                                                                                             
     334                 :   * @param integer $offset                                                                                      
     335                 :   * @access public                                                                                              
     336                 :   * @return void                                                                                                
     337                 :   */                                                                                                            
     338                 :   public function offsetUnset($offset) {                                                                        
     339               1 :     throw new BadMethodCallException('List is read only');                                                      
     340                 :   }                                                                                                             
     341                 :                                                                                                                 
     342                 :   /**                                                                                                           
     343                 :   * Get element from internal array                                                                             
     344                 :   *                                                                                                             
     345                 :   * @param $offset                                                                                              
     346                 :   * @access public                                                                                              
     347                 :   * @return void                                                                                                
     348                 :   */                                                                                                            
     349                 :   public function offsetGet($offset) {                                                                          
     350              13 :     return isset($this->_array[$offset]) ? $this->_array[$offset] : null;                                       
     351                 :   }                                                                                                             
     352                 :                                                                                                                 
     353                 :   /*                                                                                                            
     354                 :   * Core functions                                                                                              
     355                 :   */                                                                                                            
     356                 :                                                                                                                 
     357                 :   /**                                                                                                           
     358                 :   * Create a new instance of the same class with the $this as the parent.                                       
     359                 :   *                                                                                                             
     360                 :   * This is used for the chaining and needs to be overloaded in child classes.                                  
     361                 :   *                                                                                                             
     362                 :   * @access private                                                                                             
     363                 :   * @return                                                                                                     
     364                 :   */                                                                                                            
     365                 :   protected function _spawn() {                                                                                 
     366              91 :     return new FluentDOM($this);                                                                                
     367                 :   }                                                                                                             
     368                 :                                                                                                                 
     369                 :   /**                                                                                                           
     370                 :   * create a new xpath object an register default namespaces from the current document                          
     371                 :   *                                                                                                             
     372                 :   * @access private                                                                                             
     373                 :   * @return object DOMXPath                                                                                     
     374                 :   */                                                                                                            
     375                 :   private function _xpath() {                                                                                   
     376             101 :     if (empty($this->_xpath) || $this->_xpath->document != $this->_document) {                                  
     377             101 :       $this->_xpath = new DOMXPath($this->_document);                                                           
     378             101 :       if ($this->_document->documentElement) {                                                                  
     379             101 :         $uri = $this->_document->documentElement->lookupnamespaceURI('_');                                      
     380             101 :         if (!isset($uri)) {                                                                                     
     381             101 :           $uri = $this->_document->documentElement->lookupnamespaceURI(NULL);                                   
     382             101 :           if (isset($uri)) {                                                                                    
     383               1 :             $this->_xpath->registerNamespace('_', $uri);                                                        
     384               1 :           }                                                                                                     
     385             101 :         }                                                                                                       
     386             101 :       }                                                                                                         
     387             101 :     }                                                                                                           
     388             101 :     return $this->_xpath;                                                                                       
     389                 :   }                                                                                                             
     390                 :                                                                                                                 
     391                 :   /**                                                                                                           
     392                 :   * match xpath expression agains context and return matched elements                                           
     393                 :   *                                                                                                             
     394                 :   * @param string$expr                                                                                          
     395                 :   * @param DOMElement $context optional, default value NULL                                                     
     396                 :   * @access private                                                                                             
     397                 :   * @return DOMNodeList                                                                                         
     398                 :   */                                                                                                            
     399                 :   private function _match($expr, $context = NULL) {                                                             
     400             100 :     if (isset($context)) {                                                                                      
     401              13 :       return $this->_xpath()->query($expr, $context);                                                           
     402                 :     } else {                                                                                                    
     403             100 :       return $this->_xpath()->query($expr);                                                                     
     404                 :     }                                                                                                           
     405                 :   }                                                                                                             
     406                 :                                                                                                                 
     407                 :   /**                                                                                                           
     408                 :   * test xpath expression against context and return true/false                                                 
     409                 :   *                                                                                                             
     410                 :   * @param string$expr                                                                                          
     411                 :   * @param DOMElement $context optional, default value NULL                                                     
     412                 :   * @access private                                                                                             
     413                 :   * @return boolean                                                                                             
     414                 :   */                                                                                                            
     415                 :   private function _test($expr, $context) {                                                                     
     416               6 :     $check = $this->_xpath()->evaluate($expr, $context);                                                        
     417               6 :     if ($check instanceof DOMNodeList) {                                                                        
     418               2 :       return $check->length > 0;                                                                                
     419                 :     } else {                                                                                                    
     420               4 :       return (bool)$check;                                                                                      
     421                 :     }                                                                                                           
     422                 :   }                                                                                                             
     423                 :                                                                                                                 
     424                 :   /**                                                                                                           
     425                 :   * push new elements an the list                                                                               
     426                 :   *                                                                                                             
     427                 :   * @param object DOMElement | object DOMNodeList | object FluentDOM $elements                                  
     428                 :   * @access private                                                                                             
     429                 :   * @return void                                                                                                
     430                 :   */                                                                                                            
     431                 :   private function _push($elements, $unique = FALSE) {                                                          
     432             104 :     if ($this->_isNode($elements)) {                                                                            
     433              39 :       if ($elements->ownerDocument === $this->_document) {                                                      
     434              38 :         if (!$unique || !$this->_inList($elements, $this->_array)) {                                            
     435              38 :           $this->_array[] = $elements;                                                                          
     436              38 :         }                                                                                                       
     437              38 :       } else {                                                                                                  
     438               1 :         throw new OutOfBoundsException('Node is not a part of this document');                                  
     439                 :       }                                                                                                         
     440             104 :     } elseif ($elements instanceof DOMNodeList ||                                                               
     441              22 :               $elements instanceof DOMDocumentFragment ||                                                       
     442              22 :               $elements instanceof Iterator ||                                                                  
     443             103 :               is_array($elements)) {                                                                            
     444             103 :       foreach ($elements as $node) {                                                                            
     445             101 :         if ($this->_isNode($node)) {                                                                            
     446             101 :           if ($node->ownerDocument === $this->_document) {                                                      
     447             101 :             if (!$unique || !$this->_inList($node, $this->_array)) {                                            
     448             101 :               $this->_array[] = $node;                                                                          
     449             101 :             }                                                                                                   
     450             101 :           } else {                                                                                              
     451               1 :             throw new OutOfBoundsException('Node is not a part of this document');                              
     452                 :           }                                                                                                     
     453             101 :         }                                                                                                       
     454             103 :       }                                                                                                         
     455             103 :     }                                                                                                           
     456             104 :   }                                                                                                             
     457                 :                                                                                                                 
     458                 :   /**                                                                                                           
     459                 :   * check if object is already in internal list                                                                 
     460                 :   *                                                                                                             
     461                 :   * @param object DOMElement $node                                                                              
     462                 :   * @access private                                                                                             
     463                 :   * @return boolean                                                                                             
     464                 :   */                                                                                                            
     465                 :   private function _inList($node) {                                                                             
     466              12 :     foreach ($this->_array as $compareNode) {                                                                   
     467               8 :       if ($compareNode === $node) {                                                                             
     468               2 :         return TRUE;                                                                                            
     469                 :       }                                                                                                         
     470              12 :     }                                                                                                           
     471              12 :     return FALSE;                                                                                               
     472                 :   }                                                                                                             
     473                 :                                                                                                                 
     474                 :   /**                                                                                                           
     475                 :   * validate string as qualified tag name                                                                       
     476                 :   *                                                                                                             
     477                 :   * @todo implement isQName                                                                                     
     478                 :   * @param string $name                                                                                         
     479                 :   * @access private                                                                                             
     480                 :   * @return boolean                                                                                             
     481                 :   */                                                                                                            
     482                 :   private function _isQName($name) {                                                                            
     483              11 :     if (preg_match('((\w[\w\d]*:)?(\w[\w\d-]*))', $name)) {                                                     
     484              10 :       return TRUE;                                                                                              
     485                 :     } else {                                                                                                    
     486               1 :       throw new UnexpectedValueException('Invalid QName');                                                      
     487                 :     }                                                                                                           
     488                 :   }                                                                                                             
     489                 :                                                                                                                 
     490                 :   /**                                                                                                           
     491                 :   * Check if the DOMNode is DOMElement or DOMText with content                                                  
     492                 :   *                                                                                                             
     493                 :   * @param DOMNode $node                                                                                        
     494                 :   * @access private                                                                                             
     495                 :   * @return boolean                                                                                             
     496                 :   */                                                                                                            
     497                 :   private function _isNode($node) {                                                                             
     498             118 :     if (is_object($node)) {                                                                                     
     499             104 :       if ($node instanceof DOMElement) {                                                                        
     500             100 :         return TRUE;                                                                                            
     501             101 :       } elseif ($node instanceof DOMText &&                                                                     
     502             101 :                 !$node->isWhitespaceInElementContent()) {                                                       
     503               9 :         return TRUE;                                                                                            
     504                 :       }                                                                                                         
     505             100 :     }                                                                                                           
     506             117 :     return FALSE;                                                                                               
     507                 :   }                                                                                                             
     508                 :                                                                                                                 
     509                 :   /**                                                                                                           
     510                 :   * check if parameter is a valid callback function                                                             
     511                 :   *                                                                                                             
     512                 :   * @param $callback                                                                                            
     513                 :   * @access protected                                                                                           
     514                 :   * @return boolean                                                                                             
     515                 :   */                                                                                                            
     516                 :   protected function _isCallback($callback) {                                                                   
     517              10 :     if ($callback instanceof Closure) {                                                                         
     518               0 :       return TRUE;                                                                                              
     519              10 :     } elseif (is_string($callback) &&                                                                           
     520              10 :               function_exists($callback)) {                                                                     
     521               5 :       return is_callable($callback);                                                                            
     522               5 :     } elseif (is_array($callback) &&                                                                            
     523               3 :               count($callback) == 2 &&                                                                          
     524               3 :               (is_object($callback[0]) || is_string($callback[0])) &&                                           
     525               5 :               is_string($callback[1])) {                                                                        
     526               3 :       return is_callable($callback);                                                                            
     527                 :     } else {                                                                                                    
     528               2 :       throw new BadFunctionCallException('Invalid callback argument');                                          
     529                 :     }                                                                                                           
     530                 :   }                                                                                                             
     531                 :                                                                                                                 
     532                 :   /**                                                                                                           
     533                 :   * Convert a given content into and array of nodes                                                             
     534                 :   *                                                                                                             
     535                 :   * @param string | object DOMElement | object DOMText | object Iterator $content                               
     536                 :   * @param boolean $includeTextNodes                                                                            
     537                 :   * @param integer $limit                                                                                       
     538                 :   * @access private                                                                                             
     539                 :   * @return array                                                                                               
     540                 :   */                                                                                                            
     541                 :   private function _getContentNodes($content, $includeTextNodes = TRUE, $limit = 0) {                           
     542              19 :     $result = array();                                                                                          
     543              19 :     if ($content instanceof DOMElement) {                                                                       
     544               1 :       $result = array($content);                                                                                
     545              19 :     } elseif ($includeTextNodes && $this->_isNode($content)) {                                                  
     546               1 :       $result = array($content);                                                                                
     547              18 :     } elseif (is_string($content)) {                                                                            
     548              11 :       $fragment = $this->_document->createDocumentFragment();                                                   
     549              11 :       if ($fragment->appendXML($content)) {                                                                     
     550              10 :         foreach ($fragment->childNodes as $element) {                                                           
     551              10 :           if ($element instanceof DOMElement ||                                                                 
     552              10 :               ($includeTextNodes && $this->_isNode($element))) {                                                
     553              10 :             $element->parentNode->removeChild($element);                                                        
     554              10 :             $result[] = $element;                                                                               
     555              10 :             if ($limit > 0 && count($result) >= $limit) {                                                       
     556               4 :               break;                                                                                            
     557                 :             }                                                                                                   
     558               6 :           }                                                                                                     
     559              10 :         }                                                                                                       
     560              10 :         return $result;                                                                                         
     561                 :       } else {                                                                                                  
     562               1 :         throw new UnexpectedValueException('Invalid document fragment');                                        
     563                 :       }                                                                                                         
     564               6 :     } elseif ($content instanceof DOMNodeList ||                                                                
     565               5 :               $content instanceof Iterator ||                                                                   
     566               6 :               is_array($content)) {                                                                             
     567               4 :       foreach ($content as $element) {                                                                          
     568               3 :         if ($element instanceof DOMElement ||                                                                   
     569               3 :             ($includeTextNodes && $this->_isNode($element))) {                                                  
     570               3 :           $result[] = $element;                                                                                 
     571               3 :           if ($limit > 0 && count($result) >= $limit) {                                                         
     572               2 :             break;                                                                                              
     573                 :           }                                                                                                     
     574               1 :         }                                                                                                       
     575               4 :       }                                                                                                         
     576               4 :     } else {                                                                                                    
     577               2 :       throw new InvalidArgumentException('Invalid content parameter');                                          
     578                 :     }                                                                                                           
     579               6 :     if (empty($result)) {                                                                                       
     580               1 :       throw new UnexpectedValueException('No element found');                                                   
     581                 :     } else {                                                                                                    
     582                 :       //if a node is not in the current document import it                                                      
     583               5 :       foreach ($result as $index => $node) {                                                                    
     584               5 :         if ($node->ownerDocument !== $this->_document) {                                                        
     585               1 :           $result[$index] = $this->_document->importNode($node, TRUE);                                          
     586               1 :         }                                                                                                       
     587               5 :       }                                                                                                         
     588                 :     }                                                                                                           
     589               5 :     return $result;                                                                                             
     590                 :   }                                                                                                             
     591                 :                                                                                                                 
     592                 :   private function _getTargetNodes($selector) {                                                                 
     593              13 :     if ($this->_isNode($selector)) {                                                                            
     594               1 :       return array($selector);                                                                                  
     595              13 :     } elseif (is_string($selector)) {                                                                           
     596              10 :       return $this->_match($selector);                                                                          
     597              13 :     } elseif (is_array($selector) ||                                                                            
     598               7 :               $selector instanceof Iterator ||                                                                  
     599              13 :               $selector instanceof DOMNodeList) {                                                               
     600              12 :       return $selector;                                                                                         
     601                 :     } else {                                                                                                    
     602               1 :       throw new InvalidArgumentException('Invalid selector');                                                   
     603                 :     }                                                                                                           
     604                 :   }                                                                                                             
     605                 :                                                                                                                 
     606                 :   /**                                                                                                           
     607                 :   * Remove nodes from document tree                                                                             
     608                 :   *                                                                                                             
     609                 :   * @param $selector                                                                                            
     610                 :   * @access private                                                                                             
     611                 :   * @return array removed nodes                                                                                 
     612                 :   */                                                                                                            
     613                 :   private function _removeNodes($selector) {                                                                    
     614              12 :     $targetNodes = $this->_getTargetNodes($selector);                                                           
     615              12 :     $result = array();                                                                                          
     616              12 :     foreach ($targetNodes as $node) {                                                                           
     617              12 :       if ($node instanceof DOMNode &&                                                                           
     618              12 :           isset($node->parentNode)) {                                                                           
     619              12 :         $result[] = $node->parentNode->removeChild($node);                                                      
     620              12 :       }                                                                                                         
     621              12 :     }                                                                                                           
     622              12 :     return $result;                                                                                             
     623                 :   }                                                                                                             
     624                 :                                                                                                                 
     625                 :   /**                                                                                                           
     626                 :   * Convert content to DOMElement                                                                               
     627                 :   *                                                                                                             
     628                 :   * @param string | array | object DOMElement | object FluentDOM $content                                       
     629                 :   * @access private                                                                                             
     630                 :   * @return object DOMElement                                                                                   
     631                 :   */                                                                                                            
     632                 :   private function _getContentElement($content) {                                                               
     633               8 :     if ($content instanceof DOMElement) {                                                                       
     634               1 :       return $content;                                                                                          
     635                 :     } else {                                                                                                    
     636               7 :       $contentNodes = $this->_getContentNodes($content, FALSE, 1);                                              
     637               6 :       return $contentNodes[0];                                                                                  
     638                 :     }                                                                                                           
     639                 :   }                                                                                                             
     640                 :                                                                                                                 
     641                 :   /*                                                                                                            
     642                 :   * Object Accessors                                                                                            
     643                 :   */                                                                                                            
     644                 :                                                                                                                 
     645                 :   /**                                                                                                           
     646                 :   * Execute a function within the context of every matched element.                                             
     647                 :   *                                                                                                             
     648                 :   * @param callback | object Closure $function                                                                  
     649                 :   * @access public                                                                                              
     650                 :   * @return object FluentDOM                                                                                    
     651                 :   */                                                                                                            
     652                 :   public function each($function) {                                                                             
     653               3 :     if ($this->_isCallback($function)) {                                                                        
     654               2 :       foreach ($this->_array as $index => $node) {                                                              
     655               2 :         call_user_func($function, $node, $index);                                                               
     656               2 :       }                                                                                                         
     657               2 :     }                                                                                                           
     658               2 :     return $this;                                                                                               
     659                 :   }                                                                                                             
     660                 :                                                                                                                 
     661                 :   /**                                                                                                           
     662                 :   * Formats the current document, resets internal node array and other properties.                              
     663                 :   *                                                                                                             
     664                 :   * The document is saved and reloaded, all variables with DOMNodes of this document will get invalid.          
     665                 :   *                                                                                                             
     666                 :   * @access public                                                                                              
     667                 :   * @return object FluentDOM                                                                                    
     668                 :   */                                                                                                            
     669                 :   public function formatOutput() {                                                                              
     670               3 :     $this->_array = array();                                                                                    
     671               3 :     $this->_position = 0;                                                                                       
     672               3 :     $this->_useDocumentContext = TRUE;                                                                          
     673               3 :     $this->_parent = NULL;                                                                                      
     674               3 :     $this->_document->preserveWhiteSpace = FALSE;                                                               
     675               3 :     $this->_document->formatOutput = TRUE;                                                                      
     676               3 :     $this->_document->loadXML($this->_document->saveXML());                                                     
     677               3 :     return $this;                                                                                               
     678                 :   }                                                                                                             
     679                 :                                                                                                                 
     680                 :   /*                                                                                                            
     681                 :   * Traversing - Filtering                                                                                      
     682                 :   */                                                                                                            
     683                 :                                                                                                                 
     684                 :   /**                                                                                                           
     685                 :   * Reduce the set of matched elements to a single element.                                                     
     686                 :   *                                                                                                             
     687                 :   * @param integer $position Element index (start with 0)                                                       
     688                 :   * @access public                                                                                              
     689                 :   * @return object FluentDOM                                                                                    
     690                 :   */                                                                                                            
     691                 :   public function eq($position) {                                                                               
     692               4 :     $result = $this->_spawn();                                                                                  
     693               4 :     if (isset($this->_array[$position])) {                                                                      
     694               4 :       $result->_push($this->_array[$position]);                                                                 
     695               4 :     }                                                                                                           
     696               4 :     return $result;                                                                                             
     697                 :   }                                                                                                             
     698                 :                                                                                                                 
     699                 :   /**                                                                                                           
     700                 :   * Removes all elements from the set of matched elements that do not match the specified expression(s).        
     701                 :   *                                                                                                             
     702                 :   * @param string $expr | callback | object Closure XPath expression or callback function                       
     703                 :   * @access public                                                                                              
     704                 :   * @return object FluentDOM                                                                                    
     705                 :   */                                                                                                            
     706                 :   public function filter($expr) {                                                                               
     707               2 :     $result = $this->_spawn();                                                                                  
     708               2 :     foreach ($this->_array as $index => $node) {                                                                
     709               2 :       $check = TRUE;                                                                                            
     710               2 :       if (is_string($expr)) {                                                                                   
     711               1 :         $check = $this->_test($expr, $node, $index);                                                            
     712               2 :       } elseif ($this->_isCallback($expr)) {                                                                    
     713               1 :         $check = call_user_func($expr, $node, $index);                                                          
     714               1 :       }                                                                                                         
     715               2 :       if ($check) {                                                                                             
     716               2 :         $result->_push($node);                                                                                  
     717               2 :       }                                                                                                         
     718               2 :     }                                                                                                           
     719               2 :     return $result;                                                                                             
     720                 :   }                                                                                                             
     721                 :                                                                                                                 
     722                 :   /**                                                                                                           
     723                 :   * Checks the current selection against an expression and returns true,                                        
     724                 :   * if at least one element of the selection fits the given expression.                                         
     725                 :   *                                                                                                             
     726                 :   * @param string $expr XPath expression                                                                        
     727                 :   * @access public                                                                                              
     728                 :   * @return boolean                                                                                             
     729                 :   */                                                                                                            
     730                 :   public function is($expr) {                                                                                   
     731               2 :     foreach ($this->_array as $node) {                                                                          
     732               1 :       return $this->_test($expr, $node);                                                                        
     733               1 :     }                                                                                                           
     734               1 :     return FALSE;                                                                                               
     735                 :   }                                                                                                             
     736                 :                                                                                                                 
     737                 :   /**                                                                                                           
     738                 :   * Translate a set of elements in the FluentDOM object into                                                    
     739                 :   * another set of values in an array (which may, or may not contain elements).                                 
     740                 :   *                                                                                                             
     741                 :   * @param callback | object Closure $function                                                                  
     742                 :   * @access public                                                                                              
     743                 :   * @return array                                                                                               
     744                 :   */                                                                                                            
     745                 :   public function map($function) {                                                                              
     746               4 :     $result = array();                                                                                          
     747               4 :     foreach ($this->_array as $index => $node) {                                                                
     748               4 :       if ($this->_isCallback($function)) {                                                                      
     749               3 :         $mapped = call_user_func($function, $node, $index);                                                     
     750               3 :       }                                                                                                         
     751               3 :       if ($mapped === NULL) {                                                                                   
     752               1 :         continue;                                                                                               
     753               3 :       } elseif ($mapped instanceof DOMNodeList ||                                                               
     754               3 :                 $mapped instanceof Iterator ||                                                                  
     755               3 :                 is_array($mapped)) {                                                                            
     756               1 :         foreach ($mapped as $element) {                                                                         
     757               1 :           if ($element !== NULL) {                                                                              
     758               1 :             $result[] = $element;                                                                               
     759               1 :           }                                                                                                     
     760               1 :         }                                                                                                       
     761               1 :       } else {                                                                                                  
     762               3 :         $result[] = $mapped;                                                                                    
     763                 :       }                                                                                                         
     764               3 :     }                                                                                                           
     765               3 :     return $result;                                                                                             
     766                 :   }                                                                                                             
     767                 :                                                                                                                 
     768                 :   /**                                                                                                           
     769                 :   * Removes elements matching the specified expression from the set of matched elements.                        
     770                 :   *                                                                                                             
     771                 :   * @param string $expr | callback | object Closure XPath expression or callback function                       
     772                 :   * @access public                                                                                              
     773                 :   * @return object FluentDOM                                                                                    
     774                 :   */                                                                                                            
     775                 :   public function not($expr) {                                                                                  
     776               2 :     $result = $this->_spawn();                                                                                  
     777               2 :     foreach ($this->_array as $index => $node) {                                                                
     778               2 :       $check = FALSE;                                                                                           
     779               2 :       if (is_string($expr)) {                                                                                   
     780               1 :         $check = $this->_test($expr, $node, $index);                                                            
     781               2 :       } elseif ($this->_isCallback($expr)) {                                                                    
     782               1 :         $check = call_user_func($expr, $node, $index);                                                          
     783               1 :       }                                                                                                         
     784               2 :       if (!$check) {                                                                                            
     785               2 :         $result->_push($node);                                                                                  
     786               2 :       }                                                                                                         
     787               2 :     }                                                                                                           
     788               2 :     return $result;                                                                                             
     789                 :   }                                                                                                             
     790                 :                                                                                                                 
     791                 :   /**                                                                                                           
     792                 :   * Selects a subset of the matched elements.                                                                   
     793                 :   *                                                                                                             
     794                 :   * @param integer $start                                                                                       
     795                 :   * @param integer $end                                                                                         
     796                 :   * @access public                                                                                              
     797                 :   * @return object FluentDOM                                                                                    
     798                 :   */                                                                                                            
     799                 :   public function slice($start, $end = NULL) {                                                                  
     800               4 :     $result = $this->_spawn();                                                                                  
     801               4 :     if ($end === NULL) {                                                                                        
     802               1 :       $result->_push(array_slice($this->_array, $start));                                                       
     803               4 :     } elseif ($end < 0) {                                                                                       
     804               1 :       $result->_push(array_slice($this->_array, $start, $end));                                                 
     805               3 :     } elseif ($end > $start) {                                                                                  
     806               1 :       $result->_push(array_slice($this->_array, $start, $end - $start));                                        
     807               1 :     } else {                                                                                                    
     808               1 :       $result->_push(array_slice($this->_array, $end, $start - $end));                                          
     809                 :     }                                                                                                           
     810               4 :     return $result;                                                                                             
     811                 :   }                                                                                                             
     812                 :                                                                                                                 
     813                 :   /*                                                                                                            
     814                 :   * Traversing - Finding                                                                                        
     815                 :   */                                                                                                            
     816                 :                                                                                                                 
     817                 :   /**                                                                                                           
     818                 :   * Adds more elements, matched by the given expression, to the set of matched elements.                        
     819                 :   *                                                                                                             
     820                 :   * @param string $expr XPath expression                                                                        
     821                 :   * @access public                                                                                              
     822                 :   * @return object FluentDOM                                                                                    
     823                 :   */                                                                                                            
     824                 :   public function add($expr) {                                                                                  
     825               5 :     $result = $this->_spawn();                                                                                  
     826               5 :     $result->_push($this->_array);                                                                              
     827               5 :     if (is_object($expr)) {                                                                                     
     828               3 :       $result->_push($expr);                                                                                    
     829               3 :     } elseif (isset($this->_parent)) {                                                                          
     830               1 :       $result->_push($this->_parent->find($expr));                                                              
     831               1 :     } else {                                                                                                    
     832               1 :       $result->_push($this->find($expr));                                                                       
     833                 :     }                                                                                                           
     834               3 :     return $result;                                                                                             
     835                 :   }                                                                                                             
     836                 :                                                                                                                 
     837                 :   /**                                                                                                           
     838                 :   * Get a set of elements containing all of the unique immediate                                                
     839                 :   * children of each of the matched set of elements.                                                            
     840                 :   *                                                                                                             
     841                 :   * @param string $expr XPath expression                                                                        
     842                 :   * @access public                                                                                              
     843                 :   * @return object FluentDOM                                                                                    
     844                 :   */                                                                                                            
     845                 :   public function children($expr = NULL) {                                                                      
     846               3 :     $result = $this->_spawn();                                                                                  
     847               3 :     foreach ($this->_array as $node) {                                                                          
     848               3 :       if (empty($expr)) {                                                                                       
     849               2 :         $result->_push($node->childNodes, TRUE);                                                                
     850               2 :       } else {                                                                                                  
     851               1 :         foreach ($node->childNodes as $childNode) {                                                             
     852               1 :           if ($this->_test($expr, $childNode)) {                                                                
     853               1 :             $result->_push($childNode, TRUE);                                                                   
     854               1 :           }                                                                                                     
     855               1 :         }                                                                                                       
     856                 :       }                                                                                                         
     857               3 :     }                                                                                                           
     858               3 :     return $result;                                                                                             
     859                 :   }                                                                                                             
     860                 :                                                                                                                 
     861                 :   /**                                                                                                           
     862                 :   * Searches for descendent elements that match the specified expression.                                       
     863                 :   *                                                                                                             
     864                 :   * @param string $expr XPath expression                                                                        
     865                 :   * @access public                                                                                              
     866                 :   * @return object FluentDOM                                                                                    
     867                 :   */                                                                                                            
     868                 :   public function find($expr) {                                                                                 
     869              99 :     $result = $this->_spawn();                                                                                  
     870              99 :     if ($this->_useDocumentContext) {                                                                           
     871              99 :       $result->_push($this->_match($expr));                                                                     
     872              99 :     } else {                                                                                                    
     873               4 :       foreach ($this->_array as $contextNode) {                                                                 
     874               4 :         $result->_push($this->_match($expr, $contextNode));                                                     
     875               4 :       }                                                                                                         
     876                 :     }                                                                                                           
     877              99 :     return $result;                                                                                             
     878                 :   }                                                                                                             
     879                 :                                                                                                                 
     880                 :   /**                                                                                                           
     881                 :   * Get a set of elements containing the unique next siblings of each of the given set of elements.             
     882                 :   *                                                                                                             
     883                 :   * Like jQuerys next() method but renamed because of a conflict with Iterator                                  
     884                 :   *                                                                                                             
     885                 :   * @param string $expr XPath expression                                                                        
     886                 :   * @access public                                                                                              
     887                 :   * @return FluentDOM                                                                                           
     888                 :   */                                                                                                            
     889                 :   public function nextSiblings($expr = NULL) {                                                                  
     890               1 :     $result = $this->_spawn();                                                                                  
     891               1 :     foreach ($this->_array as $node) {                                                                          
     892               1 :       $next = $node->nextSibling;                                                                               
     893               1 :       while ($next instanceof DOMNode && !$this->_isNode($next)) {                                              
     894               1 :         $next = $next->nextSibling;                                                                             
     895               1 :       }                                                                                                         
     896               1 :       if (!empty($next)) {                                                                                      
     897               1 :         if (empty($expr) || $this->_test($expr, $next)) {                                                       
     898               1 :           $result->_push($next, TRUE);                                                                          
     899               1 :         }                                                                                                       
     900               1 :       }                                                                                                         
     901               1 :     }                                                                                                           
     902               1 :     return $result;                                                                                             
     903                 :   }                                                                                                             
     904                 :                                                                                                                 
     905                 :   /**                                                                                                           
     906                 :   * Find all sibling elements after the current element.                                                        
     907                 :   *                                                                                                             
     908                 :   * Like jQuerys nextAll() method but renamed for consistency with nextSiblings()                               
     909                 :   *                                                                                                             
     910                 :   * @param string $expr XPath expression                                                                        
     911                 :   * @access public                                                                                              
     912                 :   * @return FluentDOM                                                                                           
     913                 :   */                                                                                                            
     914                 :   public function nextAllSiblings($expr = NULL) {                                                               
     915               1 :     $result = $this->_spawn();                                                                                  
     916               1 :     foreach ($this->_array as $node) {                                                                          
     917               1 :       $next = $node->nextSibling;                                                                               
     918               1 :       while ($next instanceof DOMNode) {                                                                        
     919               1 :         if ($this->_isNode($next)) {                                                                            
     920               1 :           if (empty($expr) || $this->_test($expr, $next)) {                                                     
     921               1 :             $result->_push($next, TRUE);                                                                        
     922               1 :           }                                                                                                     
     923               1 :         }                                                                                                       
     924               1 :         $next = $next->nextSibling;                                                                             
     925               1 :       }                                                                                                         
     926               1 :     }                                                                                                           
     927               1 :     return $result;                                                                                             
     928                 :   }                                                                                                             
     929                 :                                                                                                                 
     930                 :   /**                                                                                                           
     931                 :   * Get a set of elements containing the unique parents of the matched set of elements.                         
     932                 :   *                                                                                                             
     933                 :   * @access public                                                                                              
     934                 :   * @return FluentDOM                                                                                           
     935                 :   */                                                                                                            
     936                 :   public function parent() {                                                                                    
     937               1 :     $result = $this->_spawn();                                                                                  
     938               1 :     foreach ($this->_array as $node) {                                                                          
     939               1 :       if (isset($node->parentNode)) {                                                                           
     940               1 :         $result->_push($node->parentNode, TRUE);                                                                
     941               1 :       }                                                                                                         
     942               1 :     }                                                                                                           
     943               1 :     return $result;                                                                                             
     944                 :   }                                                                                                             
     945                 :                                                                                                                 
     946                 :   /**                                                                                                           
     947                 :   * Get a set of elements containing the unique ancestors of the matched set of elements.                       
     948                 :   *                                                                                                             
     949                 :   * @param string $expr XPath expression                                                                        
     950                 :   * @access public                                                                                              
     951                 :   * @return FluentDOM                                                                                           
     952                 :   */                                                                                                            
     953                 :   public function parents($expr = NULL) {                                                                       
     954               1 :     $result = $this->_spawn();                                                                                  
     955               1 :     foreach ($this->_array as $node) {                                                                          
     956               1 :       $parents = $this->_match('ancestor::*', $node);                                                           
     957               1 :       for ($i = $parents->length - 1; $i >= 0; --$i) {                                                          
     958               1 :         $parentNode = $parents->item($i);                                                                       
     959               1 :         if (empty($expr) || $this->_test($expr, $parentNode)) {                                                 
     960               1 :           $result->_push($parentNode, TRUE);                                                                    
     961               1 :         }                                                                                                       
     962               1 :       }                                                                                                         
     963               1 :     }                                                                                                           
     964               1 :     return $result;                                                                                             
     965                 :   }                                                                                                             
     966                 :                                                                                                                 
     967                 :   /**                                                                                                           
     968                 :   * Get a set of elements containing the unique previous siblings of each of the matched set of elements.       
     969                 :   *                                                                                                             
     970                 :   * Like jQuerys prev() method but renamed for consistency with nextSiblings()                                  
     971                 :   *                                                                                                             
     972                 :   * @param string $expr XPath expression                                                                        
     973                 :   * @access public                                                                                              
     974                 :   * @return object FluentDOM                                                                                    
     975                 :   */                                                                                                            
     976                 :   public function prevSiblings($expr = NULL) {                                                                  
     977               3 :     $result = $this->_spawn();                                                                                  
     978               3 :     foreach ($this->_array as $node) {                                                                          
     979               3 :       $previous = $node->previousSibling;                                                                       
     980               3 :       while ($previous instanceof DOMNode && !$this->_isNode($previous)) {                                      
     981               3 :         $previous = $previous->previousSibling;                                                                 
     982               3 :       }                                                                                                         
     983               3 :       if (!empty($previous)) {                                                                                  
     984               3 :         if (empty($expr) || $this->_test($expr, $previous)) {                                                   
     985               3 :           $result->_push($previous, TRUE);                                                                      
     986               3 :         }                                                                                                       
     987               3 :       }                                                                                                         
     988               3 :     }                                                                                                           
     989               3 :     return $result;                                                                                             
     990                 :   }                                                                                                             
     991                 :                                                                                                                 
     992                 :   /**                                                                                                           
     993                 :   * Find all sibling elements in front of the current element.                                                  
     994                 :   *                                                                                                             
     995                 :   * Like jQuerys prevAll() method but renamed for consistency with nextSiblings()                               
     996                 :   *                                                                                                             
     997                 :   * @param string $expr XPath expression                                                                        
     998                 :   * @access public                                                                                              
     999                 :   * @return object FluentDOM                                                                                    
    1000                 :   */                                                                                                            
    1001                 :   public function prevAllSiblings($expr = NULL) {                                                               
    1002               1 :     $result = $this->_spawn();                                                                                  
    1003               1 :     foreach ($this->_array as $node) {                                                                          
    1004               1 :       $previous = $node->previousSibling;                                                                       
    1005               1 :       while ($previous instanceof DOMNode) {                                                                    
    1006               1 :         if ($this->_isNode($previous)) {                                                                        
    1007               1 :           if (empty($expr) || $this->_test($expr, $previous)) {                                                 
    1008               1 :             $result->_push($previous, TRUE);                                                                    
    1009               1 :           }                                                                                                     
    1010               1 :         }                                                                                                       
    1011               1 :         $previous = $previous->previousSibling;                                                                 
    1012               1 :       }                                                                                                         
    1013               1 :     }                                                                                                           
    1014               1 :     return $result;                                                                                             
    1015                 :   }                                                                                                             
    1016                 :                                                                                                                 
    1017                 :   /**                                                                                                           
    1018                 :   * Get a set of elements containing all of the unique siblings of each of the matched set of elements.         
    1019                 :   *                                                                                                             
    1020                 :   * @param string $expr XPath expression                                                                        
    1021                 :   * @access public                                                                                              
    1022                 :   * @return object FluentDOM                                                                                    
    1023                 :   */                                                                                                            
    1024                 :   public function siblings($expr = NULL) {                                                                      
    1025               1 :     $result = $this->_spawn();                                                                                  
    1026               1 :     foreach ($this->_array as $node) {                                                                          
    1027               1 :       if (isset($node->parentNode)) {                                                                           
    1028               1 :         $siblings = $node->parentNode->childNodes;                                                              
    1029               1 :         foreach ($node->parentNode->childNodes as $childNode) {                                                 
    1030               1 :           if ($this->_isNode($childNode) &&                                                                     
    1031               1 :               $childNode !== $node) {                                                                           
    1032               1 :             if (empty($expr) || $this->_test($expr, $childNode)) {                                              
    1033               1 :               $result->_push($childNode, TRUE);                                                                 
    1034               1 :             }                                                                                                   
    1035               1 :           }                                                                                                     
    1036               1 :         }                                                                                                       
    1037               1 :       }                                                                                                         
    1038               1 :     }                                                                                                           
    1039               1 :     return $result;                                                                                             
    1040                 :   }                                                                                                             
    1041                 :                                                                                                                 
    1042                 :   /*                                                                                                            
    1043                 :   * Traversing - Chaining                                                                                       
    1044                 :   */                                                                                                            
    1045                 :                                                                                                                 
    1046                 :   /**                                                                                                           
    1047                 :   * Add the previous selection to the current selection.                                                        
    1048                 :   *                                                                                                             
    1049                 :   * @access public                                                                                              
    1050                 :   * @return object FluentDOM                                                                                    
    1051                 :   */                                                                                                            
    1052                 :   public function andSelf() {                                                                                   
    1053               2 :     $result = $this->_spawn();                                                                                  
    1054               2 :     $result->_push($this->_array);                                                                              
    1055               2 :     $result->_push($this->_parent);                                                                             
    1056               2 :     return $result;                                                                                             
    1057                 :   }                                                                                                             
    1058                 :                                                                                                                 
    1059                 :   /**                                                                                                           
    1060                 :   * Revert the most recent traversing operation,                                                                
    1061                 :   * changing the set of matched elements to its previous state.                                                 
    1062                 :   *                                                                                                             
    1063                 :   * @access public                                                                                              
    1064                 :   * @return object FluentDOM                                                                                    
    1065                 :   */                                                                                                            
    1066                 :   public function end() {                                                                                       
    1067               1 :     if ($this->_parent instanceof FluentDOM) {                                                                  
    1068               1 :       return $this->_parent;                                                                                    
    1069                 :     } else {                                                                                                    
    1070               1 :       return $this;                                                                                             
    1071                 :     }                                                                                                           
    1072                 :   }                                                                                                             
    1073                 :                                                                                                                 
    1074                 :   /*                                                                                                            
    1075                 :   * Manipulation - Changing Contents                                                                            
    1076                 :   */                                                                                                            
    1077                 :                                                                                                                 
    1078                 :   /**                                                                                                           
    1079                 :   * Get or set the xml contents of the first matched element.                                                   
    1080                 :   *                                                                                                             
    1081                 :   * @param string $xml XML fragment                                                                             
    1082                 :   * @access public                                                                                              
    1083                 :   * @return string | object FluentDOM                                                                           
    1084                 :   */                                                                                                            
    1085                 :   public function xml($xml = NULL) {                                                                            
    1086               2 :     if (isset($xml)) {                                                                                          
    1087               1 :       if (!empty($xml)) {                                                                                       
    1088               1 :         $fragment = $this->_document->createDocumentFragment();                                                 
    1089               1 :         if ($fragment->appendXML($xml)) {                                                                       
    1090               1 :           foreach ($this->_array as $node) {                                                                    
    1091               1 :             $node->nodeValue = '';                                                                              
    1092               1 :             $node->appendChild($fragment->cloneNode(TRUE));                                                     
    1093               1 :           }                                                                                                     
    1094               1 :         }                                                                                                       
    1095               1 :       }                                                                                                         
    1096               1 :       return $this;                                                                                             
    1097                 :     } else {                                                                                                    
    1098               1 :       $result = '';                                                                                             
    1099               1 :       if (isset($this->_array[0])) {                                                                            
    1100               1 :         foreach ($this->_array[0]->childNodes as $childNode) {                                                  
    1101               1 :           if ($this->_isNode($childNode)) {                                                                     
    1102               1 :             $result .= $this->_document->saveXML($childNode);                                                   
    1103               1 :           }                                                                                                     
    1104               1 :         }                                                                                                       
    1105               1 :       }                                                                                                         
    1106               1 :       return $result;                                                                                           
    1107                 :     }                                                                                                           
    1108                 :   }                                                                                                             
    1109                 :                                                                                                                 
    1110                 :   /**                                                                                                           
    1111                 :   * Get the combined text contents of all matched elements or                                                   
    1112                 :   * set the text contents of all matched elements.                                                              
    1113                 :   *                                                                                                             
    1114                 :   * @param string $text                                                                                         
    1115                 :   * @access public                                                                                              
    1116                 :   * @return string | object FluentDOM                                                                           
    1117                 :   */                                                                                                            
    1118                 :   public function text($text = NULL) {                                                                          
    1119               4 :     if (isset($text)) {                                                                                         
    1120               2 :       foreach ($this->_array as $node) {                                                                        
    1121               2 :         $node->nodeValue = $text;                                                                               
    1122               2 :       }                                                                                                         
    1123               2 :       return $this;                                                                                             
    1124                 :     } else {                                                                                                    
    1125               2 :       $result = '';                                                                                             
    1126               2 :       foreach ($this->_array as $node) {                                                                        
    1127               2 :         $result .= $node->textContent;                                                                          
    1128               2 :       }                                                                                                         
    1129               2 :       return $result;                                                                                           
    1130                 :     }                                                                                                           
    1131                 :   }                                                                                                             
    1132                 :                                                                                                                 
    1133                 :   /*                                                                                                            
    1134                 :   * Manipulation - Inserting Inside                                                                             
    1135                 :   */                                                                                                            
    1136                 :                                                                                                                 
    1137                 :   /**                                                                                                           
    1138                 :   * Append content to the inside of every matched element.                                                      
    1139                 :   *                                                                                                             
    1140                 :   * @param string | object DOMNode | object FluentDOM $content DOMNode or DOMNodeList or xml fragment string    
    1141                 :   * @access public                                                                                              
    1142                 :   * @return string | object FluentDOM                                                                           
    1143                 :   */                                                                                                            
    1144                 :   public function append($content) {                                                                            
    1145               5 :     return $this->_insertChild($content, FALSE);                                                                
    1146                 :   }                                                                                                             
    1147                 :                                                                                                                 
    1148                 :   /**                                                                                                           
    1149                 :   * Append all of the matched elements to another, specified, set of elements.                                  
    1150                 :   * Returns all of the inserted elements.                                                                       
    1151                 :   *                                                                                                             
    1152                 :   * @param string | object DOMElement | object FluentDOM $expr XPath expression, element or list of elements    
    1153                 :   * @access public                                                                                              
    1154                 :   * @return object FluentDOM                                                                                    
    1155                 :   */                                                                                                            
    1156                 :   public function appendTo($expr) {                                                                             
    1157               1 :     return $this->_insertChildTo($expr, FALSE);                                                                 
    1158                 :   }                                                                                                             
    1159                 :                                                                                                                 
    1160                 :   /**                                                                                                           
    1161                 :   * Prepend content to the inside of every matched element.                                                     
    1162                 :   *                                                                                                             
    1163                 :   * @param string | object DOMNode | object FluentDOM $content DOMNode or DOMNodeList or xml fragment string    
    1164                 :   * @access public                                                                                              
    1165                 :   * @return string | object FluentDOM                                                                           
    1166                 :   */                                                                                                            
    1167                 :   public function prepend($content) {                                                                           
    1168               3 :     return $this->_insertChild($content, TRUE);                                                                 
    1169                 :   }                                                                                                             
    1170                 :                                                                                                                 
    1171                 :   /**                                                                                                           
    1172                 :   * Prepend all of the matched elements to another, specified, set of elements.                                 
    1173                 :   * Returns all of the inserted elements.                                                                       
    1174                 :   *                                                                                                             
    1175                 :   * @param string | object DOMElement | object FluentDOM $expr XPath expression, element or list of elements    
    1176                 :   * @access public                                                                                              
    1177                 :   * @return object FluentDOM list of all new elements                                                           
    1178                 :   */                                                                                                            
    1179                 :   public function prependTo($expr) {                                                                            
    1180               1 :     return $this->_insertChildTo($expr, TRUE);                                                                  
    1181                 :   }                                                                                                             
    1182                 :                                                                                                                 
    1183                 :   /**                                                                                                           
    1184                 :   * Insert content to the inside of every matched element.                                                      
    1185                 :   *                                                                                                             
    1186                 :   * @param string | object DOMNode | object FluentDOM $content DOMNode or DOMNodeList or xml fragment string    
    1187                 :   * @param boolean $first insert at first position (or last)                                                    
    1188                 :   * @access private                                                                                             
    1189                 :   * @return object FluentDOM                                                                                    
    1190                 :   */                                                                                                            
    1191                 :   private function _insertChild($content, $first) {                                                             
    1192               8 :     if (!empty($content)) {                                                                                     
    1193               8 :       if ($content instanceof DOMNode) {                                                                        
    1194               1 :         foreach ($this->_array as $node) {                                                                      
    1195               1 :           $node->insertBefore(                                                                                  
    1196               1 :             $content->cloneNode(TRUE),                                                                          
    1197               1 :             ($first && $node->hasChildNodes()) ? $node->childNodes->item(0) : NULL                              
    1198               1 :           );                                                                                                    
    1199               1 :         }                                                                                                       
    1200               8 :       } elseif ($content instanceof FluentDOM) {                                                                
    1201               1 :         foreach ($this->_array as $node) {                                                                      
    1202               1 :           foreach ($content as $contentNode) {                                                                  
    1203               1 :             $node->insertBefore(                                                                                
    1204               1 :               $contentNode->cloneNode(TRUE),                                                                    
    1205               1 :               ($first && $node->hasChildNodes()) ? $node->childNodes->item(0) : NULL                            
    1206               1 :             );                                                                                                  
    1207               1 :           }                                                                                                     
    1208               1 :         }                                                                                                       
    1209               1 :       } else {                                                                                                  
    1210               6 :         $fragment = $this->_document->createDocumentFragment();                                                 
    1211               6 :         if ($fragment->appendXML($content)) {                                                                   
    1212               6 :           foreach ($this->_array as $node) {                                                                    
    1213               6 :             $node->insertBefore(                                                                                
    1214               6 :               $fragment->cloneNode(TRUE),                                                                       
    1215               6 :               ($first && $node->hasChildNodes()) ? $node->childNodes->item(0) : NULL                            
    1216               6 :             );                                                                                                  
    1217               6 :           }                                                                                                     
    1218               6 :         }                                                                                                       
    1219                 :       }                                                                                                         
    1220               8 :     }                                                                                                           
    1221               8 :     return $this;                                                                                               
    1222                 :   }                                                                                                             
    1223                 :                                                                                                                 
    1224                 :   /**                                                                                                           
    1225                 :   * Insert all of the matched elements to another, specified, set of elements.                                  
    1226                 :   * Returns all of the inserted elements.                                                                       
    1227                 :   *                                                                                                             
    1228                 :   * @param string | object DOMElement | object FluentDOM $selector XPath expression, element or list of elements
    1229                 :   * @param boolean $first insert at first position (or last)                                                    
    1230                 :   * @access public                                                                                              
    1231                 :   * @return object FluentDOM                                                                                    
    1232                 :   */                                                                                                            
    1233                 :   private function _insertChildTo($selector, $first) {                                                          
    1234               2 :     $result = $this->_spawn();                                                                                  
    1235               2 :     $targets = $this->_getTargetNodes($selector);                                                               
    1236               2 :     if (!empty($targets)) {                                                                                     
    1237               2 :       foreach ($targets as $targetNode) {                                                                       
    1238               2 :         if ($targetNode instanceof DOMElement) {                                                                
    1239               2 :           foreach ($this->_array as $node) {                                                                    
    1240               2 :             $result->_push(                                                                                     
    1241               2 :               $targetNode->insertBefore(                                                                        
    1242               2 :                 $node->cloneNode(TRUE),                                                                         
    1243               1 :                 ($first && $targetNode->hasChildNodes())                                                        
    1244               2 :                   ? $targetNode->childNodes->item(0) : NULL                                                     
    1245               2 :               )                                                                                                 
    1246               2 :             );                                                                                                  
    1247               2 :           }                                                                                                     
    1248               2 :         }                                                                                                       
    1249               2 :         $this->_removeNodes($this->_array);                                                                     
    1250               2 :       }                                                                                                         
    1251               2 :     }                                                                                                           
    1252               2 :     return $result;                                                                                             
    1253                 :   }                                                                                                             
    1254                 :                                                                                                                 
    1255                 :   /*                                                                                                            
    1256                 :   * Manipulation - Inserting Outside                                                                            
    1257                 :   */                                                                                                            
    1258                 :                                                                                                                 
    1259                 :   /**                                                                                                           
    1260                 :   * Insert content after each of the matched elements.                                                          
    1261                 :   *                                                                                                             
    1262                 :   * @param $content                                                                                             
    1263                 :   * @access public                                                                                              
    1264                 :   * @return                                                                                                     
    1265                 :   */                                                                                                            
    1266                 :   public function after($content) {                                                                             
    1267               1 :     $result = $this->_spawn();                                                                                  
    1268               1 :     if ($contentNodes = $this->_getContentNodes($content, TRUE)) {                                              
    1269               1 :       foreach ($this->_array as $node) {                                                                        
    1270               1 :         $beforeNode = $node->nextSibling;                                                                       
    1271               1 :         if (isset($node->parentNode)) {                                                                         
    1272               1 :           foreach ($contentNodes as $contentNode) {                                                             
    1273               1 :             $result->_push(                                                                                     
    1274               1 :               $node->parentNode->insertBefore(                                                                  
    1275               1 :                 $contentNode->cloneNode(TRUE),                                                                  
    1276                 :                 $beforeNode                                                                                     
    1277               1 :               )                                                                                                 
    1278               1 :             );                                                                                                  
    1279               1 :           }                                                                                                     
    1280               1 :         }                                                                                                       
    1281               1 :       }                                                                                                         
    1282               1 :     }                                                                                                           
    1283               1 :     return $result;                                                                                             
    1284                 :   }                                                                                                             
    1285                 :                                                                                                                 
    1286                 :   /**                                                                                                           
    1287                 :   * Insert content before each of the matched elements.                                                         
    1288                 :   *                                                                                                             
    1289                 :   * @param $content                                                                                             
    1290                 :   * @access public                                                                                              
    1291                 :   * @return object FluentDOM                                                                                    
    1292                 :   */                                                                                                            
    1293                 :   public function before($content) {                                                                            
    1294               1 :     $result = $this->_spawn();                                                                                  
    1295               1 :     if ($contentNodes = $this->_getContentNodes($content, TRUE)) {                                              
    1296               1 :       foreach ($this->_array as $node) {                                                                        
    1297               1 :         if (isset($node->parentNode)) {                                                                         
    1298               1 :           foreach ($contentNodes as $contentNode) {                                                             
    1299               1 :             $result->_push(                                                                                     
    1300               1 :               $node->parentNode->insertBefore(                                                                  
    1301               1 :                 $contentNode->cloneNode(TRUE),                                                                  
    1302                 :                 $node                                                                                           
    1303               1 :               )                                                                                                 
    1304               1 :             );                                                                                                  
    1305               1 :           }                                                                                                     
    1306               1 :         }                                                                                                       
    1307               1 :       }                                                                                                         
    1308               1 :     }                                                                                                           
    1309               1 :     return $result;                                                                                             
    1310                 :   }                                                                                                             
    1311                 :                                                                                                                 
    1312                 :   /**                                                                                                           
    1313                 :   * Insert all of the matched elements after another, specified, set of elements.                               
    1314                 :   *                                                                                                             
    1315                 :   * @param $selector                                                                                            
    1316                 :   * @access public                                                                                              
    1317                 :   * @return object FluentDOM                                                                                    
    1318                 :   */                                                                                                            
    1319                 :   public function insertAfter($selector) {                                                                      
    1320               1 :     $result = $this->_spawn();                                                                                  
    1321               1 :     $targets = $this->_getTargetNodes($selector);                                                               
    1322               1 :     if (!empty($targets)) {                                                                                     
    1323               1 :       foreach ($targets as $targetNode) {                                                                       
    1324               1 :         if ($this->_isNode($targetNode) && isset($targetNode->parentNode)) {                                    
    1325               1 :           $beforeNode = $targetNode->nextSibling;                                                               
    1326               1 :           foreach ($this->_array as $node) {                                                                    
    1327               1 :             $result->_push(                                                                                     
    1328               1 :               $targetNode->parentNode->insertBefore(                                                            
    1329               1 :                 $node->cloneNode(TRUE),                                                                         
    1330                 :                 $beforeNode                                                                                     
    1331               1 :               )                                                                                                 
    1332               1 :             );                                                                                                  
    1333               1 :           }                                                                                                     
    1334               1 :         }                                                                                                       
    1335               1 :         $this->_removeNodes($this->_array);                                                                     
    1336               1 :       }                                                                                                         
    1337               1 :     }                                                                                                           
    1338               1 :     return $result;                                                                                             
    1339                 :   }                                                                                                             
    1340                 :                                                                                                                 
    1341                 :   /**                                                                                                           
    1342                 :   * Insert all of the matched elements before another, specified, set of elements.                              
    1343                 :   *                                                                                                             
    1344                 :   * @param $selector                                                                                            
    1345                 :   * @access public                                                                                              
    1346                 :   * @return object FluentDOM                                                                                    
    1347                 :   */                                                                                                            
    1348                 :   public function insertBefore($selector) {                                                                     
    1349               1 :     $result = $this->_spawn();                                                                                  
    1350               1 :     $targets = $this->_getTargetNodes($selector);                                                               
    1351               1 :     if (!empty($targets)) {                                                                                     
    1352               1 :       foreach ($targets as $targetNode) {                                                                       
    1353               1 :         if ($this->_isNode($targetNode) && isset($targetNode->parentNode)) {                                    
    1354               1 :           foreach ($this->_array as $node) {                                                                    
    1355               1 :             $result->_push(                                                                                     
    1356               1 :               $targetNode->parentNode->insertBefore(                                                            
    1357               1 :                 $node->cloneNode(TRUE),                                                                         
    1358                 :                 $targetNode                                                                                     
    1359               1 :               )                                                                                                 
    1360               1 :             );                                                                                                  
    1361               1 :           }                                                                                                     
    1362               1 :         }                                                                                                       
    1363               1 :         $this->_removeNodes($this->_array);                                                                     
    1364               1 :       }                                                                                                         
    1365               1 :     }                                                                                                           
    1366               1 :     return $result;                                                                                             
    1367                 :   }                                                                                                             
    1368                 :                                                                                                                 
    1369                 :   /*                                                                                                            
    1370                 :   * Manipulation - Inserting Around                                                                             
    1371                 :   */                                                                                                            
    1372                 :                                                                                                                 
    1373                 :   /**                                                                                                           
    1374                 :   * Wrap $content around a set of elements                                                                      
    1375                 :   *                                                                                                             
    1376                 :   * @param array $elements                                                                                      
    1377                 :   * @param string | array | object DOMElement | object FluentDOM $content                                       
    1378                 :   * @access private                                                                                             
    1379                 :   * @return object FluentDOM                                                                                    
    1380                 :   */                                                                                                            
    1381                 :   private function _wrap($elements, $content) {                                                                 
    1382               6 :     $wrapperTemplate = $this->_getContentElement($content);                                                     
    1383               5 :     $result = array();                                                                                          
    1384               5 :     if ($wrapperTemplate instanceof DOMElement) {                                                               
    1385               5 :       $simple = FALSE;                                                                                          
    1386               5 :       foreach ($elements as $node) {                                                                            
    1387               5 :         $wrapper = $wrapperTemplate->cloneNode(TRUE);                                                           
    1388               5 :         if (!$simple) {                                                                                         
    1389               5 :           $targets = $this->_match('.//*[count(*) = 0]', $wrapper);                                             
    1390               5 :         }                                                                                                       
    1391               5 :         if ($simple || $targets->length == 0) {                                                                 
    1392               4 :           $target = $wrapper;                                                                                   
    1393               4 :           $simple = TRUE;                                                                                       
    1394               4 :         } else {                                                                                                
    1395               1 :           $target = $targets->item(0);                                                                          
    1396                 :         }                                                                                                       
    1397               5 :         if (isset($node->parentNode)) {                                                                         
    1398               5 :           $node->parentNode->insertBefore($wrapper, $node);                                                     
    1399               5 :         }                                                                                                       
    1400               5 :         $target->appendChild($node);                                                                            
    1401               5 :         $result[] = $node;                                                                                      
    1402               5 :       }                                                                                                         
    1403               5 :     }                                                                                                           
    1404               5 :     return $result;                                                                                             
    1405                 :   }                                                                                                             
    1406                 :                                                                                                                 
    1407                 :   /**                                                                                                           
    1408                 :   * Wrap each matched element with the specified content.                                                       
    1409                 :   *                                                                                                             
    1410                 :   * If $content contains several elements the first one is used                                                 
    1411                 :   *                                                                                                             
    1412                 :   * @param string | array | object DOMElement | object FluentDOM $content                                       
    1413                 :   * @access public                                                                                              
    1414                 :   * @return object FluentDOM                                                                                    
    1415                 :   */                                                                                                            
    1416                 :   public function wrap($content) {                                                                              
    1417               5 :     $result = $this->_spawn();                                                                                  
    1418               5 :     $result->_push($this->_wrap($this->_array, $content));                                                      
    1419               4 :     return $result;                                                                                             
    1420                 :   }                                                                                                             
    1421                 :                                                                                                                 
    1422                 :   /**                                                                                                           
    1423                 :   * Wrap al matched elements with the specified content                                                         
    1424                 :   *                                                                                                             
    1425                 :   * If the matched elemetns are not siblings, wrap each group of siblings.                                      
    1426                 :   *                                                                                                             
    1427                 :   * @param string | array | object DOMElement | object FluentDOM $content                                       
    1428                 :   * @access public                                                                                              
    1429                 :   * @return object FluentDOM                                                                                    
    1430                 :   */                                                                                                            
    1431                 :   public function wrapAll($content) {                                                                           
    1432               2 :     $result = $this->_spawn();                                                                                  
    1433               2 :     $current = NULL;                                                                                            
    1434               2 :     $counter = 0;                                                                                               
    1435               2 :     $groups = array();                                                                                          
    1436                 :     //group elements by previous node - ignore whitespace text nodes                                            
    1437               2 :     foreach ($this->_array as $node) {                                                                          
    1438               2 :       $previous = $node->previousSibling;                                                                       
    1439               2 :       while ($previous instanceof DOMText && $previous->isWhitespaceInElementContent()) {                       
    1440               2 :         $previous = $previous->previousSibling;                                                                 
    1441               2 :       }                                                                                                         
    1442               2 :       if ($previous !== $current) {                                                                             
    1443               2 :         $counter++;                                                                                             
    1444               2 :       }                                                                                                         
    1445               2 :       $groups[$counter][] = $node;                                                                              
    1446               2 :       $current = $node;                                                                                         
    1447               2 :     }                                                                                                           
    1448               2 :     if (count($groups) > 0) {                                                                                   
    1449               2 :       $wrapperTemplate = $this->_getContentElement($content);                                                   
    1450               2 :       $simple = FALSE;                                                                                          
    1451               2 :       foreach ($groups as $group) {                                                                             
    1452               2 :         if (isset($group[0])) {                                                                                 
    1453               2 :           $node = $group[0];                                                                                    
    1454               2 :           $wrapper = $wrapperTemplate->cloneNode(TRUE);                                                         
    1455               2 :           if (!$simple) {                                                                                       
    1456               2 :             $targets = $this->_match('.//*[count(*) = 0]', $wrapper);                                           
    1457               2 :           }                                                                                                     
    1458               2 :           if ($simple || $targets->length == 0) {                                                               
    1459               1 :             $target = $wrapper;                                                                                 
    1460               1 :             $simple = TRUE;                                                                                     
    1461               1 :           } else {                                                                                              
    1462               1 :             $target = $targets->item(0);                                                                        
    1463                 :           }                                                                                                     
    1464               2 :           if (isset($node->parentNode)) {                                                                       
    1465               2 :             $node->parentNode->insertBefore($wrapper, $node);                                                   
    1466               2 :           }                                                                                                     
    1467               2 :           foreach ($group as $node) {                                                                           
    1468               2 :             $target->appendChild($node);                                                                        
    1469               2 :           }                                                                                                     
    1470               2 :           $result->_push($node);                                                                                
    1471               2 :         }                                                                                                       
    1472               2 :       }                                                                                                         
    1473               2 :     }                                                                                                           
    1474               2 :     return $result;                                                                                             
    1475                 :   }                                                                                                             
    1476                 :                                                                                                                 
    1477                 :   /**                                                                                                           
    1478                 :   * Wrap the inner child contents of each matched element                                                       
    1479                 :   * (including text nodes) with an XML structure.                                                               
    1480                 :   *                                                                                                             
    1481                 :   * @param string | array | object DOMElement | object FluentDOM $content                                       
    1482                 :   * @access public                                                                                              
    1483                 :   * @return FluentDOM                                                                                           
    1484                 :   */                                                                                                            
    1485                 :   public function wrapInner($content) {                                                                         
    1486               1 :     $result = $this->_spawn();                                                                                  
    1487               1 :     $elements = array();                                                                                        
    1488               1 :     foreach ($this->_array as $node) {                                                                          
    1489               1 :       foreach ($node->childNodes as $childNode) {                                                               
    1490               1 :         if ($this->_isNode($childNode)) {                                                                       
    1491               1 :           $elements[] = $childNode;                                                                             
    1492               1 :         }                                                                                                       
    1493               1 :       }                                                                                                         
    1494               1 :     }                                                                                                           
    1495               1 :     $result->_push($this->_wrap($elements, $content));                                                          
    1496               1 :     return $result;                                                                                             
    1497                 :   }                                                                                                             
    1498                 :                                                                                                                 
    1499                 :   /*                                                                                                            
    1500                 :   * Manipulation - Replacing                                                                                    
    1501                 :   */                                                                                                            
    1502                 :                                                                                                                 
    1503                 :   /**                                                                                                           
    1504                 :   * Replaces all matched elements with the specified HTML or DOM elements.                                      
    1505                 :   * This returns the JQuery element that was just replaced,                                                     
    1506                 :   * which has been removed from the DOM.                                                                        
    1507                 :   *                                                                                                             
    1508                 :   * @param $content                                                                                             
    1509                 :   * @access public                                                                                              
    1510                 :   * @return                                                                                                     
    1511                 :   */                                                                                                            
    1512                 :   public function replaceWith($content) {                                                                       
    1513               1 :     $contentNodes = $this->_getContentNodes($content);                                                          
    1514               1 :     foreach ($this->_array as $node) {                                                                          
    1515               1 :       if (isset($node->parentNode)) {                                                                           
    1516               1 :         foreach ($contentNodes as $contentNode) {                                                               
    1517               1 :           $node->parentNode->insertBefore(                                                                      
    1518               1 :             $contentNode->cloneNode(TRUE),                                                                      
    1519                 :             $node                                                                                               
    1520               1 :           );                                                                                                    
    1521               1 :         }                                                                                                       
    1522               1 :       }                                                                                                         
    1523               1 :     }                                                                                                           
    1524               1 :     $this->_removeNodes($this->_array);                                                                         
    1525               1 :     return $this;                                                                                               
    1526                 :   }                                                                                                             
    1527                 :                                                                                                                 
    1528                 :   /**                                                                                                           
    1529                 :   * Replaces the elements matched by the specified selector with the matched elements.                          
    1530                 :   *                                                                                                             
    1531                 :   * @param $selector                                                                                            
    1532                 :   * @access public                                                                                              
    1533                 :   * @return object FluentDOM                                                                                    
    1534                 :   */                                                                                                            
    1535                 :   public function replaceAll($selector) {                                                                       
    1536               8 :     $result = $this->_spawn();                                                                                  
    1537               8 :     $targetNodes = $this->_getTargetNodes($selector);                                                           
    1538               7 :     foreach ($targetNodes as $targetNode) {                                                                     
    1539               7 :       if (isset($targetNode->parentNode)) {                                                                     
    1540               7 :         foreach ($this->_array as $node) {                                                                      
    1541               7 :           $result->_push(                                                                                       
    1542               7 :             $targetNode->parentNode->insertBefore(                                                              
    1543               7 :               $node->cloneNode(TRUE),                                                                           
    1544                 :               $targetNode                                                                                       
    1545               7 :             )                                                                                                   
    1546               7 :           );                                                                                                    
    1547               7 :         }                                                                                                       
    1548               7 :       }                                                                                                         
    1549               7 :     }                                                                                                           
    1550               7 :     $this->_removeNodes($targetNodes);                                                                          
    1551               7 :     $this->_removeNodes($this->_array);                                                                         
    1552               7 :     return $result;                                                                                             
    1553                 :   }                                                                                                             
    1554                 :                                                                                                                 
    1555                 :   /*                                                                                                            
    1556                 :   * Manipulation - Removing                                                                                     
    1557                 :   */                                                                                                            
    1558                 :                                                                                                                 
    1559                 :   /**                                                                                                           
    1560                 :   * this is the empty() method - but because empty                                                              
    1561                 :   * is a reserved word we can no declare it directly                                                            
    1562                 :   * @see __call                                                                                                 
    1563                 :   *                                                                                                             
    1564                 :   * @access private                                                                                             
    1565                 :   * @return object FluentDOM                                                                                    
    1566                 :   */                                                                                                            
    1567                 :   private function _emptyNodes() {                                                                              
    1568               1 :     foreach ($this->_array as $node) {                                                                          
    1569               1 :       if ($node instanceof DOMElement ||                                                                        
    1570               1 :           $node instanceof DOMText) {                                                                           
    1571               1 :         $node->nodeValue = '';                                                                                  
    1572               1 :       }                                                                                                         
    1573               1 :     }                                                                                                           
    1574               1 :     return $this;                                                                                               
    1575                 :   }                                                                                                             
    1576                 :                                                                                                                 
    1577                 :   /**                                                                                                           
    1578                 :   * Removes all matched elements from the DOM.                                                                  
    1579                 :   *                                                                                                             
    1580                 :   * @param string $expr XPath expression                                                                        
    1581                 :   * @access public                                                                                              
    1582                 :   * @return object FluentDOM removed elements                                                                   
    1583                 :   */                                                                                                            
    1584                 :   public function remove($expr = NULL) {                                                                        
    1585               1 :     $result = $this->_spawn();                                                                                  
    1586               1 :     foreach ($this->_array as $node) {                                                                          
    1587               1 :       if (isset($node->parentNode)) {                                                                           
    1588               1 :         if (empty($expr) || $this->test($expr, $node)) {                                                        
    1589               1 :           $result->_push($node->parentNode->removeChild($node));                                                
    1590               1 :         }                                                                                                       
    1591               1 :       }                                                                                                         
    1592               1 :     }                                                                                                           
    1593               1 :     return $result;                                                                                             
    1594                 :   }                                                                                                             
    1595                 :                                                                                                                 
    1596                 :   /*                                                                                                            
    1597                 :   * Manipulation - Creation                                                                                     
    1598                 :   */                                                                                                            
    1599                 :                                                                                                                 
    1600                 :   /**                                                                                                           
    1601                 :   * create nodes list from content, if $content contains node(s)                                                
    1602                 :   * from another document the are imported.                                                                     
    1603                 :   *                                                                                                             
    1604                 :   * @param $content                                                                                             
    1605                 :   * @access public                                                                                              
    1606                 :   * @return object FluentDOM                                                                                    
    1607                 :   */                                                                                                            
    1608                 :   public function node($content) {                                                                              
    1609               9 :     $result = $this->_spawn();                                                                                  
    1610               9 :     $result->_push($this->_getContentNodes($content));                                                          
    1611               6 :     return $result;                                                                                             
    1612                 :   }                                                                                                             
    1613                 :                                                                                                                 
    1614                 :   /*                                                                                                            
    1615                 :   * Manipulation - Copying                                                                                      
    1616                 :   */                                                                                                            
    1617                 :                                                                                                                 
    1618                 :   /**                                                                                                           
    1619                 :   * Clone matched DOM Elements and select the clones.                                                           
    1620                 :   *                                                                                                             
    1621                 :   * @access private                                                                                             
    1622                 :   * @return object FluentDOM                                                                                    
    1623                 :   */                                                                                                            
    1624                 :   private function _cloneNodes() {                                                                              
    1625               1 :     $result = $this->_spawn();                                                                                  
    1626               1 :     foreach ($this->_array as $node) {                                                                          
    1627               1 :       $result->_push($node->cloneNode(TRUE));                                                                   
    1628               1 :     }                                                                                                           
    1629               1 :     return $result;                                                                                             
    1630                 :   }                                                                                                             
    1631                 :                                                                                                                 
    1632                 :   /*                                                                                                            
    1633                 :   * Attributes - General                                                                                        
    1634                 :   */                                                                                                            
    1635                 :                                                                                                                 
    1636                 :   /**                                                                                                           
    1637                 :   * Access a property on the first matched element or set the attribute(s) of all matched elements              
    1638                 :   *                                                                                                             
    1639                 :   * @param string | array $expr attribute name or attribute list                                                
    1640                 :   * @param callback | string $value function callback or value                                                  
    1641                 :   * @access public                                                                                              
    1642                 :   * @return string | object FluentDOM attribute value or $this                                                  
    1643                 :   */                                                                                                            
    1644                 :   public function attr($attribute, $value = NULL) {                                                             
    1645              11 :     if (is_array($attribute) && count($attribute) > 0) {                                                        
    1646                 :       //expr is an array of attributes and values - set on each element                                         
    1647               1 :       foreach ($attribute as $key => $value) {                                                                  
    1648               1 :         if ($this->_isQName($key)) {                                                                            
    1649               1 :           foreach ($this->_array as $node) {                                                                    
    1650               1 :             if ($node instanceof DOMElement) {                                                                  
    1651               1 :               $node->setAttribute($key, $value);                                                                
    1652               1 :             }                                                                                                   
    1653               1 :           }                                                                                                     
    1654               1 :         }                                                                                                       
    1655               1 :       }                                                                                                         
    1656              11 :     } elseif (is_null($value)) {                                                                                
    1657                 :       //empty value - read attribute from first element in list                                                 
    1658              11 :       if ($this->_isQName($attribute) &&                                                                        
    1659              10 :           count($this->_array) > 0) {                                                                           
    1660               9 :         $node = $this->_array[0];                                                                               
    1661               9 :         if ($node instanceof DOMElement) {                                                                      
    1662               8 :           return $node->getAttribute($attribute);                                                               
    1663                 :         }                                                                                                       
    1664               1 :       }                                                                                                         
    1665               2 :       return NULL;                                                                                              
    1666               2 :     } elseif (is_array($value) ||                                                                               
    1667               2 :               $value instanceof Closure) {                                                                      
    1668                 :       //value is an array (function callback) - execute ist and set result on each element                      
    1669               1 :       if ($this->_isQName($attribute)) {                                                                        
    1670               1 :         foreach ($this->_array as $index => $node) {                                                            
    1671               1 :           if ($node instanceof DOMElement) {                                                                    
    1672               1 :             $node->setAttribute(                                                                                
    1673               1 :               $attribute,                                                                                       
    1674               1 :               call_user_func($value, $node, $index)                                                             
    1675               1 :             );                                                                                                  
    1676               1 :           }                                                                                                     
    1677               1 :         }                                                                                                       
    1678               1 :       }                                                                                                         
    1679               1 :     } else {                                                                                                    
    1680                 :       // set attribute value of each element                                                                    
    1681               1 :       if ($this->_isQName($attribute)) {                                                                        
    1682               1 :         foreach ($this->_array as $node) {                                                                      
    1683               1 :           if ($node instanceof DOMElement) {                                                                    
    1684               1 :             $node->setAttribute($attribute, (string)$value);                                                    
    1685               1 :           }                                                                                                     
    1686               1 :         }                                                                                                       
    1687               1 :       }                                                                                                         
    1688                 :     }                                                                                                           
    1689               3 :     return $this;                                                                                               
    1690                 :   }                                                                                                             
    1691                 :                                                                                                                 
    1692                 :   /**                                                                                                           
    1693                 :   * Remove an attribute from each of the matched elements.                                                      
    1694                 :   *                                                                                                             
    1695                 :   * @param string $name                                                                                         
    1696                 :   * @access public                                                                                              
    1697                 :   * @return object FluentDOM                                                                                    
    1698                 :   */                                                                                                            
    1699                 :   public function removeAttr($name) {                                                                           
    1700               2 :     if (!empty($name)) {                                                                                        
    1701               2 :       foreach ($t