FluentDOM Package
Current file: /tmp/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% 57 / 57
100.00%100.00%
100.00% 707 / 707
 
FluentDOM
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 56 / 56
100.00%100.00%
100.00% 703 / 703
 public function __call($name, $arguments)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 8 / 8
 public function each($function)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 6 / 6
 public function toArray()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 public function eq($position)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 8 / 8
 public function filter($expr)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 13 / 13
 public function get($position = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 8 / 8
 public function index($expr = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 24 / 24
 public function has($expr)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 16 / 16
 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% 20 / 20
 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, $context = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 16 / 16
 public function children($expr = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 13 / 13
 public function contents()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 6 / 6
 public function find($expr, $useDocumentContext = FALSE)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 9 / 9
 public function next($expr = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 14 / 14
 public function nextAll($expr = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 13 / 13
 public function nextUntil($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% 8 / 8
 public function parents($expr = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 11 / 11
 public function parentsUntil($expr = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 11 / 11
 public function prev($expr = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 14 / 14
 public function prevAll($expr = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 13 / 13
 public function prevUntil($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 closest($expr, $context = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 11 / 11
 public function first()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 public function last()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 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% 33 / 33
 public function text($text = NULL)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 14 / 14
 public function append($content)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 20 / 20
 public function appendTo($selector)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 13 / 13
 public function prepend($content)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 9 / 9
 public function prependTo($selector)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 13 / 13
 public function after($content)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 7 / 7
 public function before($content)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 7 / 7
 public function insertAfter($selector)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 13 / 13
 public function insertBefore($selector)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 13 / 13
 protected function _wrap($elements, $content)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 32 / 32
 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% 5 / 5
 public function replaceAll($selector)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 12 / 12
 protected 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
 protected 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% 23 / 23
 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% 43 / 43
Functions
  
   
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 0 / 0
 function FluentDOM($source = NULL, $contentType = 'text/xml')
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 4 / 4


       1                 : <?php                                                                                               
       2                 : /**                                                                                                 
       3                 : * FluentDOM implements a jQuery like replacement for DOMNodeList                                    
       4                 : *                                                                                                   
       5                 : * @version $Id: FluentDOM.php 440 2010-04-16 17:21:08Z subjective $                                 
       6                 : * @license http://www.opensource.org/licenses/mit-license.php The MIT License                       
       7                 : * @copyright Copyright (c) 2009 Bastian Feder, Thomas Weinert                                       
       8                 : *                                                                                                   
       9                 : * @tutorial FluentDOM.pkg                                                                           
      10                 : * @package FluentDOM                                                                                
      11                 : */                                                                                                  
      12                 :                                                                                                     
      13                 : /**                                                                                                 
      14                 : * Include the core class                                                                            
      15                 : */                                                                                                  
      16                 : require_once(dirname(__FILE__).'/FluentDOM/Core.php');                                              
      17                 : /**                                                                                                 
      18                 : * Include the handler helper class                                                                  
      19                 : */                                                                                                  
      20                 : require_once(dirname(__FILE__).'/FluentDOM/Handler.php');                                           
      21                 :                                                                                                     
      22                 : /**                                                                                                 
      23                 : * Function to create a new FluentDOM instance and loads data into it if                             
      24                 : * a valid $source is provided.                                                                      
      25                 : *                                                                                                   
      26                 : * @param mixed $source                                                                              
      27                 : * @param string $contentType optional, default value 'text/xml'                                     
      28                 : * @return FluentDOM                                                                                 
      29                 : */                                                                                                  
      30                 : function FluentDOM($source = NULL, $contentType = 'text/xml') {                                     
      31               2 :   $result = new FluentDOM();                                                                        
      32               2 :   if (isset($source)) {                                                                             
      33               1 :     return $result->load($source, $contentType);                                                    
      34                 :   } else {                                                                                          
      35               1 :     return $result;                                                                                 
      36                 :   }                                                                                                 
      37                 : }                                                                                                   
      38                 :                                                                                                     
      39                 : /**                                                                                                 
      40                 : * FluentDOM implements a jQuery like replacement for DOMNodeList                                    
      41                 : **                                                                                                  
      42                 : * @method bool empty() Remove all child nodes from the set of matched elements.                     
      43                 : * @method DOMDocument clone() Clone matched DOM Elements and select the clones.                     
      44                 : *                                                                                                   
      45                 : * @package FluentDOM                                                                                
      46                 : */                                                                                                  
      47                 : class FluentDOM extends FluentDOMCore {                                                             
      48                 :                                                                                                     
      49                 :   /**                                                                                               
      50                 :   * declaring an empty() or clone() method will crash the parser so we use some magic               
      51                 :   *                                                                                                 
      52                 :   * @param string $name                                                                             
      53                 :   * @param array $arguments                                                                         
      54                 :   * @return mixed                                                                                   
      55                 :   */                                                                                                
      56                 :   public function __call($name, $arguments) {                                                       
      57               3 :     switch (strtolower($name)) {                                                                    
      58               3 :     case 'empty' :                                                                                  
      59               1 :       return $this->_emptyNodes();                                                                  
      60               2 :     case 'clone' :                                                                                  
      61               1 :       return $this->_cloneNodes();                                                                  
      62               1 :     default :                                                                                       
      63               1 :       throw new BadMethodCallException('Unknown method '.get_class($this).'::'.$name);              
      64               1 :     }                                                                                               
      65                 :   }                                                                                                 
      66                 :   /*                                                                                                
      67                 :   * Object Accessors                                                                                
      68                 :   */                                                                                                
      69                 :                                                                                                     
      70                 :   /**                                                                                               
      71                 :   * Execute a function within the context of every matched element.                                 
      72                 :   *                                                                                                 
      73                 :   * @param callback $function                                                                       
      74                 :   * @return FluentDOM                                                                               
      75                 :   */                                                                                                
      76                 :   public function each($function) {                                                                 
      77               2 :     if ($this->_isCallback($function, TRUE, FALSE)) {                                               
      78               1 :       foreach ($this->_array as $index => $node) {                                                  
      79               1 :         call_user_func($function, $node, $index);                                                   
      80               1 :       }                                                                                             
      81               1 :     }                                                                                               
      82               1 :     return $this;                                                                                   
      83                 :   }                                                                                                 
      84                 :                                                                                                     
      85                 :   /*                                                                                                
      86                 :   * Miscellaneous                                                                                   
      87                 :   */                                                                                                
      88                 :                                                                                                     
      89                 :   /**                                                                                               
      90                 :   * Retrieve the matched DOM elements in an array.                                                  
      91                 :   *                                                                                                 
      92                 :   * @return array                                                                                   
      93                 :   */                                                                                                
      94                 :   public function toArray() {                                                                       
      95               1 :     return $this->_array;                                                                           
      96                 :   }                                                                                                 
      97                 :                                                                                                     
      98                 :   /*                                                                                                
      99                 :   * Traversing - Filtering                                                                          
     100                 :   */                                                                                                
     101                 :                                                                                                     
     102                 :   /**                                                                                               
     103                 :   * Reduce the set of matched elements to a single element.                                         
     104                 :   *                                                                                                 
     105                 :   * @example eq.php Usage Example: FluentDOM::eq()                                                  
     106                 :   * @param integer $position Element index (start with 0)                                           
     107                 :   * @return FluentDOM                                                                               
     108                 :   */                                                                                                
     109                 :   public function eq($position) {                                                                   
     110               2 :     $result = $this->spawn();                                                                       
     111               2 :     if ($position < 0) {                                                                            
     112               1 :       $position = count($this->_array) + $position;                                                 
     113               1 :     }                                                                                               
     114               2 :     if (isset($this->_array[$position])) {                                                          
     115               2 :       $result->push($this->_array[$position]);                                                      
     116               2 :     }                                                                                               
     117               2 :     return $result;                                                                                 
     118                 :   }                                                                                                 
     119                 :                                                                                                     
     120                 :   /**                                                                                               
     121                 :   * Removes all elements from the set of matched elements that do not match                         
     122                 :   * the specified expression(s).                                                                    
     123                 :   *                                                                                                 
     124                 :   * @example filter-expr.php Usage Example: FluentDOM::filter() with XPath expression               
     125                 :   * @example filter-fn.php Usage Example: FluentDOM::filter() with Closure                          
     126                 :   * @param string|callback $expr XPath expression or callback function                              
     127                 :   * @return FluentDOM                                                                               
     128                 :   */                                                                                                
     129                 :   public function filter($expr) {                                                                   
     130               2 :     $result = $this->spawn();                                                                       
     131               2 :     foreach ($this->_array as $index => $node) {                                                    
     132               2 :       $check = TRUE;                                                                                
     133               2 :       if (is_string($expr)) {                                                                       
     134               1 :         $check = $this->_test($expr, $node, $index);                                                
     135               2 :       } elseif ($this->_isCallback($expr, TRUE, FALSE)) {                                           
     136               1 :         $check = call_user_func($expr, $node, $index);                                              
     137               1 :       }                                                                                             
     138               2 :       if ($check) {                                                                                 
     139               2 :         $result->push($node);                                                                       
     140               2 :       }                                                                                             
     141               2 :     }                                                                                               
     142               2 :     return $result;                                                                                 
     143                 :   }                                                                                                 
     144                 :                                                                                                     
     145                 :   /**                                                                                               
     146                 :   * Retrieve the matched DOM elements in an array. A negative position will be counted from the end.
     147                 :   *                                                                                                 
     148                 :   * @param integer|NULL optional offset of a single element to get.                                 
     149                 :   * @return array()                                                                                 
     150                 :   */                                                                                                
     151                 :   public function get($position = NULL) {                                                           
     152               4 :     if (!isset($position)) {                                                                        
     153               1 :       return $this->_array;                                                                         
     154                 :     }                                                                                               
     155               3 :     if ($position < 0) {                                                                            
     156               1 :       $position = count($this->_array) + $position;                                                 
     157               1 :     }                                                                                               
     158               3 :     if (isset($this->_array[$position])) {                                                          
     159               2 :       return array($this->_array[$position]);                                                       
     160                 :     } else {                                                                                        
     161               1 :       return array();                                                                               
     162                 :     }                                                                                               
     163                 :   }                                                                                                 
     164                 :                                                                                                     
     165                 :   /**                                                                                               
     166                 :   * Search for a given element from among the matched elements.                                     
     167                 :   *                                                                                                 
     168                 :   * @param NULL|string|DOMNode|DOMNodelist|Iterator $expr                                           
     169                 :   * @return integer                                                                                 
     170                 :   */                                                                                                
     171                 :   public function index($expr = NULL) {                                                             
     172               5 :     if (count($this->_array) > 0) {                                                                 
     173               4 :       if (is_null($expr)) {                                                                         
     174               1 :         $counter = -1;                                                                              
     175               1 :         $targetNode = $this->_array[0];                                                             
     176               1 :         $nodeList = $this->_match('preceding-sibling::node()', $targetNode);                        
     177               1 :         foreach ($nodeList as $node) {                                                              
     178               1 :           if ($this->_isNode($node)) {                                                              
     179               1 :             $counter++;                                                                             
     180               1 :           }                                                                                         
     181               1 :         }                                                                                           
     182               1 :         return $counter + 1;                                                                        
     183               3 :       } elseif (is_string($expr)) {                                                                 
     184               2 :         foreach ($this->_array as $index => $node) {                                                
     185               2 :           if ($this->_test($expr, $node)) {                                                         
     186               1 :             return $index;                                                                          
     187                 :           }                                                                                         
     188               2 :         }                                                                                           
     189               1 :       } else {                                                                                      
     190               1 :         $targetNode = $this->_getContentElement($expr);                                             
     191               1 :         foreach ($this->_array as $index => $node) {                                                
     192               1 :           if ($node->isSameNode($targetNode)) {                                                     
     193               1 :             return $index;                                                                          
     194                 :           }                                                                                         
     195               1 :         }                                                                                           
     196                 :       }                                                                                             
     197               1 :     }                                                                                               
     198               2 :     return -1;                                                                                      
     199                 :   }                                                                                                 
     200                 :                                                                                                     
     201                 :   /**                                                                                               
     202                 :   * Reduce the set of matched elements to those that have                                           
     203                 :   * a descendant that matches the selector or DOM element.                                          
     204                 :   *                                                                                                 
     205                 :   * @param string|DOMNode $expr XPath expression or DOMNode                                         
     206                 :   * @return boolean                                                                                 
     207                 :   */                                                                                                
     208                 :   public function has($expr) {                                                                      
     209               2 :     $result = $this->spawn();                                                                       
     210               2 :     foreach ($this->_array as $node) {                                                              
     211               2 :       if ($node instanceof DOMElement &&                                                            
     212               2 :           $node->hasChildNodes()) {                                                                 
     213               2 :         foreach ($node->childNodes as $childNode) {                                                 
     214               2 :           if ($expr instanceof DOMNode) {                                                           
     215               1 :             if ($expr === $childNode) {                                                             
     216               1 :               $result->push($node);                                                                 
     217               1 :               return $result;                                                                       
     218                 :             }                                                                                       
     219               2 :           } elseif ($this->_test($expr, $childNode)) {                                              
     220               1 :             $result->push($node);                                                                   
     221               1 :           }                                                                                         
     222               2 :         }                                                                                           
     223               2 :       }                                                                                             
     224               2 :     }                                                                                               
     225               1 :     return $result;                                                                                 
     226                 :   }                                                                                                 
     227                 :                                                                                                     
     228                 :   /**                                                                                               
     229                 :   * Checks the current selection against an expression and returns true,                            
     230                 :   * if at least one element of the selection fits the given expression.                             
     231                 :   *                                                                                                 
     232                 :   * @example is.php Usage Example: FluentDOM::is()                                                  
     233                 :   * @param string $expr XPath expression                                                            
     234                 :   * @return boolean                                                                                 
     235                 :   */                                                                                                
     236                 :   public function is($expr) {                                                                       
     237               2 :     foreach ($this->_array as $node) {                                                              
     238               1 :       return $this->_test($expr, $node);                                                            
     239               1 :     }                                                                                               
     240               1 :     return FALSE;                                                                                   
     241                 :   }                                                                                                 
     242                 :                                                                                                     
     243                 :   /**                                                                                               
     244                 :   * Translate a set of elements in the FluentDOM object into                                        
     245                 :   * another set of values in an array (which may, or may not contain elements).                     
     246                 :   *                                                                                                 
     247                 :   * If the callback function returns an array each element of the array will be added to the        
     248                 :   * result array. All other variable types are put directly into the result array.                  
     249                 :   *                                                                                                 
     250                 :   * @example map.php Usage Example: FluentDOM::map()                                                
     251                 :   * @param callback $function                                                                       
     252                 :   * @return array                                                                                   
     253                 :   */                                                                                                
     254                 :   public function map($function) {                                                                  
     255               3 :     $result = array();                                                                              
     256               3 :     foreach ($this->_array as $index => $node) {                                                    
     257               3 :       if ($this->_isCallback($function, TRUE, FALSE)) {                                             
     258               2 :         $mapped = call_user_func($function, $node, $index);                                         
     259               2 :       }                                                                                             
     260               2 :       if ($mapped === NULL) {                                                                       
     261               1 :         continue;                                                                                   
     262               2 :       } elseif ($mapped instanceof DOMNodeList ||                                                   
     263               2 :                 $mapped instanceof Iterator ||                                                      
     264               2 :                 $mapped instanceof IteratorAggregate ||                                             
     265               2 :                 is_array($mapped)) {                                                                
     266               1 :         foreach ($mapped as $element) {                                                             
     267               1 :           if ($element !== NULL) {                                                                  
     268               1 :             $result[] = $element;                                                                   
     269               1 :           }                                                                                         
     270               1 :         }                                                                                           
     271               1 :       } else {                                                                                      
     272               2 :         $result[] = $mapped;                                                                        
     273                 :       }                                                                                             
     274               2 :     }                                                                                               
     275               2 :     return $result;                                                                                 
     276                 :   }                                                                                                 
     277                 :                                                                                                     
     278                 :   /**                                                                                               
     279                 :   * Removes elements matching the specified expression from the set of matched elements.            
     280                 :   *                                                                                                 
     281                 :   * @example not.php Usage Example: FluentDOM::not()                                                
     282                 :   * @param string|callback $expr XPath expression or callback function                              
     283                 :   * @return FluentDOM                                                                               
     284                 :   */                                                                                                
     285                 :   public function not($expr) {                                                                      
     286               2 :     $result = $this->spawn();                                                                       
     287               2 :     foreach ($this->_array as $index => $node) {                                                    
     288               2 :       $check = FALSE;                                                                               
     289               2 :       if (is_string($expr)) {                                                                       
     290               1 :         $check = $this->_test($expr, $node, $index);                                                
     291               2 :       } elseif ($this->_isCallback($expr, TRUE, FALSE)) {                                           
     292               1 :         $check = call_user_func($expr, $node, $index);                                              
     293               1 :       }                                                                                             
     294               2 :       if (!$check) {                                                                                
     295               2 :         $result->push($node);                                                                       
     296               2 :       }                                                                                             
     297               2 :     }                                                                                               
     298               2 :     return $result;                                                                                 
     299                 :   }                                                                                                 
     300                 :                                                                                                     
     301                 :   /**                                                                                               
     302                 :   * Selects a subset of the matched elements.                                                       
     303                 :   *                                                                                                 
     304                 :   * @example slice.php Usage Example: FluentDOM::slice()                                            
     305                 :   * @param integer $start                                                                           
     306                 :   * @param integer $end                                                                             
     307                 :   * @return FluentDOM                                                                               
     308                 :   */                                                                                                
     309                 :   public function slice($start, $end = NULL) {                                                      
     310               4 :     $result = $this->spawn();                                                                       
     311               4 :     if ($end === NULL) {                                                                            
     312               1 :       $result->push(array_slice($this->_array, $start));                                            
     313               4 :     } elseif ($end < 0) {                                                                           
     314               1 :       $result->push(array_slice($this->_array, $start, $end));                                      
     315               3 :     } elseif ($end > $start) {                                                                      
     316               1 :       $result->push(array_slice($this->_array, $start, $end - $start));                             
     317               1 :     } else {                                                                                        
     318               1 :       $result->push(array_slice($this->_array, $end, $start - $end));                               
     319                 :     }                                                                                               
     320               4 :     return $result;                                                                                 
     321                 :   }                                                                                                 
     322                 :                                                                                                     
     323                 :   /*                                                                                                
     324                 :   * Traversing - Finding                                                                            
     325                 :   */                                                                                                
     326                 :                                                                                                     
     327                 :   /**                                                                                               
     328                 :   * Adds more elements, matched by the given expression, to the set of matched elements.            
     329                 :   *                                                                                                 
     330                 :   * @example add.php Usage Examples: FluentDOM::add()                                               
     331                 :   * @param string $expr XPath expression                                                            
     332                 :   * @return FluentDOM                                                                               
     333                 :   */                                                                                                
     334                 :   public function add($expr, $context = NULL) {                                                     
     335               4 :     $result = $this->spawn();                                                                       
     336               4 :     $result->push($this->_array);                                                                   
     337               4 :     if (isset($context)) {                                                                          
     338               1 :       $targetNodes = $this->_getTargetNodes($context);                                              
     339               1 :       if (!empty($targetNodes)) {                                                                   
     340               1 :         foreach ($targetNodes as $node) {                                                           
     341               1 :           $result->push($this->_match($expr, $context));                                            
     342               1 :         }                                                                                           
     343               1 :       }                                                                                             
     344               4 :     } elseif (is_object($expr) ||                                                                   
     345               3 :               (is_string($expr) && substr(ltrim($expr), 0, 1) == '<')) {                            
     346               1 :       $result->push($this->_getContentNodes($expr));                                                
     347               1 :     } else {                                                                                        
     348               2 :       $result->push($this->find($expr));                                                            
     349                 :     }                                                                                               
     350               4 :     $result->_uniqueSort();                                                                         
     351               4 :     return $result;                                                                                 
     352                 :   }                                                                                                 
     353                 :                                                                                                     
     354                 :   /**                                                                                               
     355                 :   * Get a set of elements containing of the unique immediate                                        
     356                 :   * childnodes including only elements (not textnodes) of each                                      
     357                 :   * of the matched set of elements.                                                                 
     358                 :   *                                                                                                 
     359                 :   * @example children.php Usage Examples: FluentDOM::children()                                     
     360                 :   * @param string $expr XPath expression                                                            
     361                 :   * @return FluentDOM                                                                               
     362                 :   */                                                                                                
     363                 :   public function children($expr = NULL) {                                                          
     364               2 :     $result = $this->spawn();                                                                       
     365               2 :     foreach ($this->_array as $node) {                                                              
     366               2 :       if (empty($expr)) {                                                                           
     367               1 :         $result->push($node->childNodes, TRUE);                                                     
     368               1 :       } else {                                                                                      
     369               1 :         foreach ($node->childNodes as $childNode) {                                                 
     370               1 :           if ($this->_test($expr, $childNode)) {                                                    
     371               1 :             $result->push($childNode, TRUE);                                                        
     372               1 :           }                                                                                         
     373               1 :         }                                                                                           
     374                 :       }                                                                                             
     375               2 :     }                                                                                               
     376               2 :     $result->_uniqueSort();                                                                         
     377               2 :     return $result;                                                                                 
     378                 :   }                                                                                                 
     379                 :                                                                                                     
     380                 :   /**                                                                                               
     381                 :   * Get a set of elements containing all of the unique immediate                                    
     382                 :   * childnodes including elements and textnodes of each of the matched set of elements.             
     383                 :   *                                                                                                 
     384                 :   * @return FluentDOM                                                                               
     385                 :   */                                                                                                
     386                 :   public function contents() {                                                                      
     387               1 :     $result = $this->spawn();                                                                       
     388               1 :     foreach ($this->_array as $node) {                                                              
     389               1 :       $result->push($node->childNodes, FALSE);                                                      
     390               1 :     }                                                                                               
     391               1 :     $result->_uniqueSort();                                                                         
     392               1 :     return $result;                                                                                 
     393                 :   }                                                                                                 
     394                 :                                                                                                     
     395                 :   /**                                                                                               
     396                 :   * Searches for descendent elements that match the specified expression.                           
     397                 :   *                                                                                                 
     398                 :   * @example find.php Usage Example: FluentDOM::find()                                              
     399                 :   * @param string $expr XPath expression                                                            
     400                 :   * @param boolean $useDocumentContext ignore current node list                                     
     401                 :   * @return FluentDOM                                                                               
     402                 :   */                                                                                                
     403                 :   public function find($expr, $useDocumentContext = FALSE) {                                        
     404               4 :     $result = $this->spawn();                                                                       
     405               4 :     if ($useDocumentContext ||                                                                      
     406               4 :         $this->_useDocumentContext) {                                                               
     407               4 :       $result->push($this->_match($expr));                                                          
     408               4 :     } else {                                                                                        
     409               1 :       foreach ($this->_array as $contextNode) {                                                     
     410               1 :         $result->push($this->_match($expr, $contextNode));                                          
     411               1 :       }                                                                                             
     412                 :     }                                                                                               
     413               4 :     return $result;                                                                                 
     414                 :   }                                                                                                 
     415                 :                                                                                                     
     416                 :   /**                                                                                               
     417                 :   * Get a set of elements containing the unique next siblings of each of the                        
     418                 :   * given set of elements.                                                                          
     419                 :   *                                                                                                 
     420                 :   * @example next.php Usage Example: FluentDOM::next()                                              
     421                 :   * @param string $expr XPath expression                                                            
     422                 :   * @return FluentDOM                                                                               
     423                 :   */                                                                                                
     424                 :   public function next($expr = NULL) {                                                              
     425               1 :     $result = $this->spawn();                                                                       
     426               1 :     foreach ($this->_array as $node) {                                                              
     427               1 :       $next = $node->nextSibling;                                                                   
     428               1 :       while ($next instanceof DOMNode && !$this->_isNode($next)) {                                  
     429               1 :         $next = $next->nextSibling;                                                                 
     430               1 :       }                                                                                             
     431               1 :       if (!empty($next)) {                                                                          
     432               1 :         if (empty($expr) || $this->_test($expr, $next)) {                                           
     433               1 :           $result->push($next);                                                                     
     434               1 :         }                                                                                           
     435               1 :       }                                                                                             
     436               1 :     }                                                                                               
     437               1 :     $result->_uniqueSort();                                                                         
     438               1 :     return $result;                                                                                 
     439                 :   }                                                                                                 
     440                 :                                                                                                     
     441                 :   /**                                                                                               
     442                 :   * Find all sibling elements after the current element.                                            
     443                 :   *                                                                                                 
     444                 :   * @example nextAll.php Usage Example: FluentDOM::nextAll()                                        
     445                 :   * @param string $expr XPath expression                                                            
     446                 :   * @return FluentDOM                                                                               
     447                 :   */                                                                                                
     448                 :   public function nextAll($expr = NULL) {                                                           
     449               1 :     $result = $this->spawn();                                                                       
     450               1 :     foreach ($this->_array as $node) {                                                              
     451               1 :       $next = $node->nextSibling;                                                                   
     452               1 :       while ($next instanceof DOMNode) {                                                            
     453               1 :         if ($this->_isNode($next)) {                                                                
     454               1 :           if (empty($expr) || $this->_test($expr, $next)) {                                         
     455               1 :             $result->push($next);                                                                   
     456               1 :           }                                                                                         
     457               1 :         }                                                                                           
     458               1 :         $next = $next->nextSibling;                                                                 
     459               1 :       }                                                                                             
     460               1 :     }                                                                                               
     461               1 :     return $result;                                                                                 
     462                 :   }                                                                                                 
     463                 :                                                                                                     
     464                 :   /**                                                                                               
     465                 :   * Get all following siblings of each element up to but                                            
     466                 :   * not including the element matched by the selector.                                              
     467                 :   *                                                                                                 
     468                 :   * @param string $expr XPath expression                                                            
     469                 :   * @return FluentDOM                                                                               
     470                 :   */                                                                                                
     471                 :   public function nextUntil($expr = NULL) {                                                         
     472               1 :     $result = $this->spawn();                                                                       
     473               1 :     foreach ($this->_array as $node) {                                                              
     474               1 :       $next = $node->nextSibling;                                                                   
     475               1 :       while ($next instanceof DOMNode) {                                                            
     476               1 :         if ($this->_isNode($next)) {                                                                
     477               1 :           if (isset($expr) && $this->_test($expr, $next)) {                                         
     478               1 :             break;                                                                                  
     479                 :           } else {                                                                                  
     480               1 :             $result->push($next);                                                                   
     481                 :           }                                                                                         
     482               1 :         }                                                                                           
     483               1 :         $next = $next->nextSibling;                                                                 
     484               1 :       }                                                                                             
     485               1 :     }                                                                                               
     486               1 :     return $result;                                                                                 
     487                 :   }                                                                                                 
     488                 :                                                                                                     
     489                 :   /**                                                                                               
     490                 :   * Get a set of elements containing the unique parents of the matched set of elements.             
     491                 :   *                                                                                                 
     492                 :   * @example parent.php Usage Example: FluentDOM::parent()                                          
     493                 :   * @return FluentDOM                                                                               
     494                 :   */                                                                                                
     495                 :   public function parent() {                                                                        
     496               1 :     $result = $this->spawn();                                                                       
     497               1 :     foreach ($this->_array as $node) {                                                              
     498               1 :       if (isset($node->parentNode)) {                                                               
     499               1 :         $result->push($node->parentNode);                                                           
     500               1 :       }                                                                                             
     501               1 :     }                                                                                               
     502               1 :     $result->_uniqueSort();                                                                         
     503               1 :     return $result;                                                                                 
     504                 :   }                                                                                                 
     505                 :                                                                                                     
     506                 :   /**                                                                                               
     507                 :   * Get the ancestors of each element in the current set of matched elements,                       
     508                 :   * optionally filtered by a selector.                                                              
     509                 :   *                                                                                                 
     510                 :   * @example parents.php Usage Example: FluentDOM::parents()                                        
     511                 :   * @param string $expr XPath expression                                                            
     512                 :   * @return FluentDOM                                                                               
     513                 :   */                                                                                                
     514                 :   public function parents($expr = NULL) {                                                           
     515               1 :     $result = $this->spawn();                                                                       
     516               1 :     foreach ($this->_array as $node) {                                                              
     517               1 :       $parents = $this->_match('ancestor::*', $node);                                               
     518               1 :       for ($i = $parents->length - 1; $i >= 0; --$i) {                                              
     519               1 :         $parentNode = $parents->item($i);                                                           
     520               1 :         if (empty($expr) || $this->_test($expr, $parentNode)) {                                     
     521               1 :           $result->push($parentNode);                                                               
     522               1 :         }                                                                                           
     523               1 :       }                                                                                             
     524               1 :     }                                                                                               
     525               1 :     return $result;                                                                                 
     526                 :   }                                                                                                 
     527                 :                                                                                                     
     528                 :   /**                                                                                               
     529                 :   * Get the ancestors of each element in the current set of matched elements,                       
     530                 :   * up to but not including the element matched by the selector.                                    
     531                 :   *                                                                                                 
     532                 :   * @param string $expr XPath expression                                                            
     533                 :   * @return FluentDOM                                                                               
     534                 :   */                                                                                                
     535                 :   public function parentsUntil($expr = NULL) {                                                      
     536               1 :     $result = $this->spawn();                                                                       
     537               1 :     foreach ($this->_array as $node) {                                                              
     538               1 :       $parents = $this->_match('ancestor::*', $node);                                               
     539               1 :       for ($i = $parents->length - 1; $i >= 0; --$i) {                                              
     540               1 :         $parentNode = $parents->item($i);                                                           
     541               1 :         if (!empty($expr) && $this->_test($expr, $parentNode)) {                                    
     542               1 :           break;                                                                                    
     543                 :         }                                                                                           
     544               1 :         $result->push($parentNode);                                                                 
     545               1 :       }                                                                                             
     546               1 :     }                                                                                               
     547               1 :     return $result;                                                                                 
     548                 :   }                                                                                                 
     549                 :                                                                                                     
     550                 :   /**                                                                                               
     551                 :   * Get a set of elements containing the unique previous siblings of each of the                    
     552                 :   * matched set of elements.                                                                        
     553                 :   *                                                                                                 
     554                 :   * @example prev.php Usage Example: FluentDOM::prev()                                              
     555                 :   * @param string $expr XPath expression                                                            
     556                 :   * @return FluentDOM                                                                               
     557                 :   */                                                                                                
     558                 :   public function prev($expr = NULL) {                                                              
     559               2 :     $result = $this->spawn();                                                                       
     560               2 :     foreach ($this->_array as $node) {                                                              
     561               2 :       $previous = $node->previousSibling;                                                           
     562               2 :       while ($previous instanceof DOMNode && !$this->_isNode($previous)) {                          
     563               2 :         $previous = $previous->previousSibling;                                                     
     564               2 :       }                                                                                             
     565               2 :       if (!empty($previous)) {                                                                      
     566               2 :         if (empty($expr) || $this->_test($expr, $previous)) {                                       
     567               2 :           $result->push($previous);                                                                 
     568               2 :         }                                                                                           
     569               2 :       }                                                                                             
     570               2 :     }                                                                                               
     571               2 :     $result->_uniqueSort();                                                                         
     572               2 :     return $result;                                                                                 
     573                 :   }                                                                                                 
     574                 :                                                                                                     
     575                 :   /**                                                                                               
     576                 :   * Find all sibling elements in front of the current element.                                      
     577                 :   *                                                                                                 
     578                 :   * @example prevAll.php Usage Example: FluentDOM::prevAll()                                        
     579                 :   * @param string $expr XPath expression                                                            
     580                 :   * @return FluentDOM                                                                               
     581                 :   */                                                                                                
     582                 :   public function prevAll($expr = NULL) {                                                           
     583               1 :     $result = $this->spawn();                                                                       
     584               1 :     foreach ($this->_array as $node) {                                                              
     585               1 :       $previous = $node->previousSibling;                                                           
     586               1 :       while ($previous instanceof DOMNode) {                                                        
     587               1 :         if ($this->_isNode($previous)) {                                                            
     588               1 :           if (empty($expr) || $this->_test($expr, $previous)) {                                     
     589               1 :             $result->push($previous);                                                               
     590               1 :           }                                                                                         
     591               1 :         }                                                                                           
     592               1 :         $previous = $previous->previousSibling;                                                     
     593               1 :       }                                                                                             
     594               1 :     }                                                                                               
     595               1 :     return $result;                                                                                 
     596                 :   }                                                                                                 
     597                 :                                                                                                     
     598                 :   /**                                                                                               
     599                 :   * Get all preceding siblings of each element up to but not including                              
     600                 :   * the element matched by the selector.                                                            
     601                 :   *                                                                                                 
     602                 :   * @param string $expr XPath expression                                                            
     603                 :   * @return FluentDOM                                                                               
     604                 :   */                                                                                                
     605                 :   public function prevUntil($expr = NULL) {                                                         
     606               1 :     $result = $this->spawn();                                                                       
     607               1 :     foreach ($this->_array as $node) {                                                              
     608               1 :       $previous = $node->previousSibling;                                                           
     609               1 :       while ($previous instanceof DOMNode) {                                                        
     610               1 :         if (isset($expr) && $this->_isNode($previous)) {                                            
     611               1 :           if ($this->_test($expr, $previous)) {                                                     
     612               1 :             break;                                                                                  
     613                 :           } else {                                                                                  
     614               1 :             $result->push($previous);                                                               
     615                 :           }                                                                                         
     616               1 :         }                                                                                           
     617               1 :         $previous = $previous->previousSibling;                                                     
     618               1 :       }                                                                                             
     619               1 :     }                                                                                               
     620               1 :     return $result;                                                                                 
     621                 :   }                                                                                                 
     622                 :                                                                                                     
     623                 :   /**                                                                                               
     624                 :   * Get a set of elements containing all of the unique siblings of each of the                      
     625                 :   * matched set of elements.                                                                        
     626                 :   *                                                                                                 
     627                 :   * @example siblings.php Usage Example: FluentDOM::siblings()                                      
     628                 :   * @param string $expr XPath expression                                                            
     629                 :   * @return FluentDOM                                                                               
     630                 :   */                                                                                                
     631                 :   public function siblings($expr = NULL) {                                                          
     632               1 :     $result = $this->spawn();                                                                       
     633               1 :     foreach ($this->_array as $node) {                                                              
     634               1 :       if (isset($node->parentNode)) {                                                               
     635               1 :         foreach ($node->parentNode->childNodes as $childNode) {                                     
     636               1 :           if ($this->_isNode($childNode) &&                                                         
     637               1 :               $childNode !== $node) {                                                               
     638               1 :             if (empty($expr) || $this->_test($expr, $childNode)) {                                  
     639               1 :               $result->push($childNode);                                                            
     640               1 :             }                                                                                       
     641               1 :           }                                                                                         
     642               1 :         }                                                                                           
     643               1 :       }                                                                                             
     644               1 :     }                                                                                               
     645               1 :     $result->_uniqueSort();                                                                         
     646               1 :     return $result;                                                                                 
     647                 :   }                                                                                                 
     648                 :                                                                                                     
     649                 :   /**                                                                                               
     650                 :   * Get a set of elements containing the closest parent element that matches the specified          
     651                 :   * selector, the starting element included.                                                        
     652                 :   *                                                                                                 
     653                 :   * @example closest.php Usage Example: FluentDOM::closest()                                        
     654                 :   * @param string $expr XPath expression                                                            
     655                 :   * @return FluentDOM                                                                               
     656                 :   */                                                                                                
     657                 :   public function closest($expr, $context = NULL) {                                                 
     658               2 :     $result = $this->spawn();                                                                       
     659               2 :     $context = $this->_getContextNodes($context);                                                   
     660               2 :     foreach ($context as $node) {                                                                   
     661               2 :       while (isset($node)) {                                                                        
     662               2 :         if ($this->_test($expr, $node)) {                                                           
     663               2 :           $result->push($node);                                                                     
     664               2 :           break;                                                                                    
     665                 :         }                                                                                           
     666               2 :         $node = $node->parentNode;                                                                  
     667               2 :       }                                                                                             
     668               2 :     }                                                                                               
     669               2 :     return $result;                                                                                 
     670                 :   }                                                                                                 
     671                 :                                                                                                     
     672                 :   /**                                                                                               
     673                 :   * Get a set of elements containing only the first of the currently selected elements.             
     674                 :   *                                                                                                 
     675                 :   * @return FluentDOM                                                                               
     676                 :   */                                                                                                
     677                 :   public function first() {                                                                         
     678               1 :     return $this->eq(0);                                                                            
     679                 :   }                                                                                                 
     680                 :                                                                                                     
     681                 :   /**                                                                                               
     682                 :   * Get a set of elements containing only the last of the currently selected elements.              
     683                 :   *                                                                                                 
     684                 :   * @return FluentDOM                                                                               
     685                 :   */                                                                                                
     686                 :   public function last() {                                                                          
     687               1 :     return $this->eq(-1);                                                                           
     688                 :   }                                                                                                 
     689                 :                                                                                                     
     690                 :   /*                                                                                                
     691                 :   * Traversing - Chaining                                                                           
     692                 :   */                                                                                                
     693                 :                                                                                                     
     694                 :   /**                                                                                               
     695                 :   * Add the previous selection to the current selection.                                            
     696                 :   *                                                                                                 
     697                 :   * @return FluentDOM                                                                               
     698                 :   */                                                                                                
     699                 :   public function andSelf() {                                                                       
     700               1 :     $result = $this->spawn();                                                                       
     701               1 :     $result->push($this->_array);                                                                   
     702               1 :     $result->push($this->_parent);                                                                  
     703               1 :     return $result;                                                                                 
     704                 :   }                                                                                                 
     705                 :                                                                                                     
     706                 :   /**                                                                                               
     707                 :   * Revert the most recent traversing operation,                                                    
     708                 :   * changing the set of matched elements to its previous state.                                     
     709                 :   *                                                                                                 
     710                 :   * @return FluentDOM                                                                               
     711                 :   */                                                                                                
     712                 :   public function end() {                                                                           
     713               1 :     if ($this->_parent instanceof FluentDOM) {                                                      
     714               1 :       return $this->_parent;                                                                        
     715                 :     } else {                                                                                        
     716               1 :       return $this;                                                                                 
     717                 :     }                                                                                               
     718                 :   }                                                                                                 
     719                 :                                                                                                     
     720                 :   /*                                                                                                
     721                 :   * Manipulation - Changing Contents                                                                
     722                 :   */                                                                                                
     723                 :                                                                                                     
     724                 :   /**                                                                                               
     725                 :   * Get or set the xml contents of the first matched element.                                       
     726                 :   *                                                                                                 
     727                 :   * @example xml.php Usage Example: FluentDOM::xml()                                                
     728                 :   * @param string|Callback|Closure $xml XML fragment                                                
     729                 :   * @return string|FluentDOM                                                                        
     730                 :   */                                                                                                
     731                 :   public function xml($xml = NULL) {                                                                
     732               5 :     if (isset($xml)) {                                                                              
     733               3 :       $isCallback = $this->_isCallback($xml, FALSE, TRUE);                                          
     734               3 :       if ($isCallback) {                                                                            
     735               1 :         foreach ($this->_array as $index => $node) {                                                
     736               1 :           $xmlString = call_user_func(                                                              
     737               1 :             $xml,                                                                                   
     738               1 :             $node,                                                                                  
     739               1 :             $index,                                                                                 
     740               1 :             $this->_getInnerXml($node)                                                              
     741               1 :           );                                                                                        
     742               1 :           $node->nodeValue = '';                                                                    
     743               1 :           if (!empty($xmlString)) {                                                                 
     744               1 :             $fragment = $this->_getContentFragment($xmlString, TRUE);                               
     745               1 :             foreach ($fragment as $contentNode) {                                                   
     746               1 :               $node->appendChild($contentNode->cloneNode(TRUE));                                    
     747               1 :             }                                                                                       
     748               1 :           }                                                                                         
     749               1 :         }                                                                                           
     750               1 :       } else {                                                                                      
     751               2 :         if (!empty($xml)) {                                                                         
     752               1 :           $fragment = $this->_getContentFragment($xml, TRUE);                                       
     753               1 :         } else {                                                                                    
     754               1 :           $fragment = array();                                                                      
     755                 :         }                                                                                           
     756               2 :         foreach ($this->_array as $node) {                                                          
     757               2 :           $node->nodeValue = '';                                                                    
     758               2 :           foreach ($fragment as $contentNode) {                                                     
     759               1 :             $node->appendChild($contentNode->cloneNode(TRUE));                                      
     760               2 :           }                                                                                         
     761               2 :         }                                                                                           
     762                 :       }                                                                                             
     763               3 :       return $this;                                                                                 
     764                 :     } else {                                                                                        
     765               2 :       if (isset($this->_array[0])) {                                                                
     766               1 :         return $this->_getInnerXml($this->_array[0]);                                               
     767                 :       }                                                                                             
     768               1 :       return '';                                                                                    
     769                 :     }                                                                                               
     770                 :   }                                                                                                 
     771                 :                                                                                                     
     772                 :   /**                                                                                               
     773                 :   * Get the combined text contents of all matched elements or                                       
     774                 :   * set the text contents of all matched elements.                                                  
     775                 :   *                                                                                                 
     776                 :   * @example text.php Usage Example: FluentDOM::text()                                              
     777                 :   * @param string|callback|Closure $text                                                            
     778                 :   * @return string|FluentDOM                                                                        
     779                 :   */                                                                                                
     780                 :   public function text($text = NULL) {                                                              
     781               3 :     if (isset($text)) {                                                                             
     782               2 :       $isCallback = $this->_isCallback($text, FALSE, TRUE);                                         
     783               2 :       foreach ($this->_array as $index => $node) {                                                  
     784               2 :         if ($isCallback) {                                                                          
     785               1 :           $node->nodeValue = call_user_func($text, $node, $index, $node->nodeValue);                
     786               1 :         } else {                                                                                    
     787               1 :           $node->nodeValue = $text;                                                                 
     788                 :         }                                                                                           
     789               2 :       }                                                                                             
     790               2 :       return $this;                                                                                 
     791                 :     } else {                                                                                        
     792               1 :       $result = '';                                                                                 
     793               1 :       foreach ($this->_array as $node) {                                                            
     794               1 :         $result .= $node->textContent;                                                              
     795               1 :       }                                                                                             
     796               1 :       return $result;                                                                               
     797                 :     }                                                                                               
     798                 :   }                                                                                                 
     799                 :                                                                                                     
     800                 :   /*                                                                                                
     801                 :   * Manipulation - Inserting Inside                                                                 
     802                 :   */                                                                                                
     803                 :                                                                                                     
     804                 :   /**                                                                                               
     805                 :   * Append content to the inside of every matched element.                                          
     806                 :   *                                                                                                 
     807                 :   * @example append.php Usage Example: FluentDOM::append()                                          
     808                 :   * @param string|array|DOMNode|Iterator $content DOMNode or DOMNodeList or xml fragment string     
     809                 :   * @return FluentDOM                                                                               
     810                 :   */                                                                                                
     811                 :   public function append($content) {                                                                
     812               5 :     $result = $this->spawn();                                                                       
     813               5 :     if (empty($this->_array) &&                                                                     
     814               2 :         $this->_useDocumentContext &&                                                               
     815               5 :         !isset($this->_document->documentElement)) {                                                
     816               2 :       if ($this->_isCallback($content, FALSE, TRUE)) {                                              
     817               1 :         $contentNode = $this->_getContentElement(                                                   
     818               1 :           $this->_executeEasySetter($content, NULL, 0, '')                                          
     819               1 :         );                                                                                          
     820               1 :       } else {                                                                                      
     821               1 :         $contentNode = $this->_getContentElement($content);                                         
     822                 :       }                                                                                             
     823               2 :       $result->push($this->_document->appendChild($contentNode));                                   
     824               2 :     } else {                                                                                        
     825               3 :       $result->push(                                                                                
     826               3 :         $this->_applyContentToNodes(                                                                
     827               3 :           $this->_array,                                                                            
     828               3 :           $content,                                                                                 
     829               3 :           array($this->_getHandler(), 'appendChildren')                                             
     830               3 :         )                                                                                           
     831               3 :       );                                                                                            
     832                 :     }                                                                                               
     833               5 :     return $result;                                                                                 
     834                 :   }                                                                                                 
     835                 :                                                                                                     
     836                 :   /**                                                                                               
     837                 :   * Append all of the matched elements to another, specified, set of elements.                      
     838                 :   * Returns all of the inserted elements.                                                           
     839                 :   *                                                                                                 
     840                 :   * @example appendTo.php Usage Example: FluentDOM::appendTo()                                      
     841                 :   * @param string|array|DOMNode|DOMNodeList|FluentDOM $selector                                     
     842                 :   * @return FluentDOM                                                                               
     843                 :   */                                                                                                
     844                 :   public function appendTo($selector) {                                                             
     845               1 :     $result = $this->spawn();                                                                       
     846               1 :     $targetNodes = $this->_getTargetNodes($selector);                                               
     847               1 :     if (!empty($targetNodes)) {                                                                     
     848               1 :       $result->push(                                                                                
     849               1 :         $this->_applyContentToNodes(                                                                
     850               1 :           $targetNodes,                                                                             
     851               1 :           $this->_array,                                                                            
     852               1 :           array($this->_getHandler(), 'appendChildren')                                             
     853               1 :         )                                                                                           
     854               1 :       );                                                                                            
     855               1 :       $this->_removeNodes($this->_array);                                                           
     856               1 :     }                                                                                               
     857               1 :     return $result;                                                                                 
     858                 :   }                                                                                                 
     859                 :                                                                                                     
     860                 :   /**                                                                                               
     861                 :   * Prepend content to the inside of every matched element.                                         
     862                 :   *                                                                                                 
     863                 :   * @example prepend.php Usage Example: FluentDOM::prepend()                                        
     864                 :   * @param string|array|DOMNode|Iterator $content                                                   
     865                 :   * @return FluentDOM                                                                               
     866                 :   */                                                                                                
     867                 :   public function prepend($content) {                                                               
     868               2 :     $result = $this->spawn();                                                                       
     869               2 :     $result->push(                                                                                  
     870               2 :       $this->_applyContentToNodes(                                                                  
     871               2 :         $this->_array,                                                                              
     872               2 :         $content,                                                                                   
     873               2 :         array($this->_getHandler(), 'insertChildrenBefore')                                         
     874               2 :       )                                                                                             
     875               2 :     );                                                                                              
     876               2 :     return $result;                                                                                 
     877                 :   }                                                                                                 
     878                 :                                                                                                     
     879                 :   /**                                                                                               
     880                 :   * Prepend all of the matched elements to another, specified, set of elements.                     
     881                 :   * Returns all of the inserted elements.                                                           
     882                 :   *                                                                                                 
     883                 :   * @example prependTo.php Usage Example: FluentDOM::prependTo()                                    
     884                 :   * @param string|array|DOMNode|DOMNodeList|FluentDOM $selector                                     
     885                 :   * @return FluentDOM list of all new elements                                                      
     886                 :   */                                                                                                
     887                 :   public function prependTo($selector) {                                                            
     888               1 :     $result = $this->spawn();                                                                       
     889               1 :     $targetNodes = $this->_getTargetNodes($selector);                                               
     890               1 :     if (!empty($targetNodes)) {                                                                     
     891               1 :       $result->push(                                                                                
     892               1 :         $this->_applyContentToNodes(                                                                
     893               1 :           $targetNodes,                                                                             
     894               1 :           $this->_array,                                                                            
     895               1 :           array($this->_getHandler(), 'insertChildrenBefore')                                       
     896               1 :         )                                                                                           
     897               1 :       );                                                                                            
     898               1 :       $this->_removeNodes($this->_array);                                                           
     899               1 :     }                                                                                               
     900               1 :     return $result;                                                                                 
     901                 :   }                                                                                                 
     902                 :                                                                                                     
     903                 :   /*                                                                                                
     904                 :   * Manipulation - Inserting Outside                                                                
     905                 :   */                                                                                                
     906                 :                                                                                                     
     907                 :   /**                                                                                               
     908                 :   * Insert content after each of the matched elements.                                              
     909                 :   *                                                                                                 
     910                 :   * @example after.php Usage Example: FluentDOM::after()                                            
     911                 :   * @param string|array|DOMNode|DOMNodeList|Iterator|callback|Closure $content                      
     912                 :   * @return FluentDOM                                                                               
     913                 :   */                                                                                                
     914                 :   public function after($content) {                                                                 
     915               2 :     $result = $this->spawn();                                                                       
     916               2 :     $result->push(                                                                                  
     917               2 :       $this->_applyContentToNodes(                                                                  
     918               2 :         $this->_array, $content, array($this->_getHandler(), 'insertNodesAfter')                    
     919               2 :       )                                                                                             
     920               2 :     );                                                                                              
     921               2 :     return $result;                                                                                 
     922                 :   }                                                                                                 
     923                 :                                                                                                     
     924                 :   /**                                                                                               
     925                 :   * Insert content before each of the matched elements.                                             
     926                 :   *                                                                                                 
     927                 :   * @example before.php Usage Example: FluentDOM::before()                                          
     928                 :   * @param string|array|DOMNode|DOMNodeList|Iterator|callback|Closure $content                      
     929                 :   * @return FluentDOM                                                                               
     930                 :   */                                                                                                
     931                 :   public function before($content) {                                                                
     932               2 :     $result = $this->spawn();                                                                       
     933               2 :     $result->push(                                                                                  
     934               2 :       $this->_applyContentToNodes(                                                                  
     935               2 :         $this->_array, $content, array($this->_getHandler(), 'insertNodesBefore')                   
     936               2 :       )                                                                                             
     937               2 :     );                                                                                              
     938               2 :     return $result;                                                                                 
     939                 :   }                                                                                                 
     940                 :                                                                                                     
     941                 :   /**                                                                                               
     942                 :   * Insert all of the matched elements after another, specified, set of elements.                   
     943                 :   *                                                                                                 
     944                 :   * @example insertAfter.php Usage Example: FluentDOM::insertAfter()                                
     945                 :   * @param string|array|DOMNode|DOMNodeList|Iterator $selector                                      
     946                 :   * @return FluentDOM                                                                               
     947                 :   */                                                                                                
     948                 :   public function insertAfter($selector) {                                                          
     949               1 :     $result = $this->spawn();                                                                       
     950               1 :     $targetNodes = $this->_getTargetNodes($selector);                                               
     951               1 :     if (!empty($targetNodes)) {                                                                     
     952               1 :       $result->push(                                                                                
     953               1 :         $this->_applyContentToNodes(                                                                
     954               1 :           $targetNodes,                                                                             
     955               1 :           $this->_array,                                                                            
     956               1 :           array($this->_getHandler(), 'insertNodesAfter')                                           
     957               1 :         )                                                                                           
     958               1 :       );                                                                                            
     959               1 :       $this->_removeNodes($this->_array);                                                           
     960               1 :     }                                                                                               
     961               1 :     return $result;                                                                                 
     962                 :   }                                                                                                 
     963                 :                                                                                                     
     964                 :   /**                                                                                               
     965                 :   * Insert all of the matched elements before another, specified, set of elements.                  
     966                 :   *                                                                                                 
     967                 :   * @example insertBefore.php Usage Example: FluentDOM::insertBefore()                              
     968                 :   * @param string|array|DOMNode|DOMNodeList|Iterator $selector                                      
     969                 :   * @return FluentDOM                                                                               
     970                 :   */                                                                                                
     971                 :   public function insertBefore($selector) {                                                         
     972               1 :     $result = $this->spawn();                                                                       
     973               1 :     $targetNodes = $this->_getTargetNodes($selector);                                               
     974               1 :     if (!empty($targetNodes)) {                                                                     
     975               1 :       $result->push(                                                                                
     976               1 :         $this->_applyContentToNodes(                                                                
     977               1 :           $targetNodes,                                                                             
     978               1 :           $this->_array,                                                                            
     979               1 :           array($this->_getHandler(), 'insertNodesBefore')                                          
     980               1 :         )                                                                                           
     981               1 :       );                                                                                            
     982               1 :       $this->_removeNodes($this->_array);                                                           
     983               1 :     }                                                                                               
     984               1 :     return $result;                                                                                 
     985                 :   }                                                                                                 
     986                 :                                                                                                     
     987                 :   /*                                                                                                
     988                 :   * Manipulation - Inserting Around                                                                 
     989                 :   */                                                                                                
     990                 :                                                                                                     
     991                 :   /**                                                                                               
     992                 :   * Wrap $content around a set of elements                                                          
     993                 :   *                                                                                                 
     994                 :   * @param array $elements                                                                          
     995                 :   * @param string|array|DOMNode|DOMNodeList|Iterator|callback|Closure $content                      
     996                 :   * @return FluentDOM                                                                               
     997                 :   */                                                                                                
     998                 :   protected function _wrap($elements, $content) {                                                   
     999               8 :     $result = array();                                                                              
    1000               8 :     $isCallback = $this->_isCallback($content, FALSE, TRUE);                                        
    1001               8 :     if (!$isCallback) {                                                                             
    1002               6 :       $wrapperTemplate = $this->_getContentElement($content);                                       
    1003               5 :     }                                                                                               
    1004               7 :     $simple = FALSE;                                                                                
    1005               7 :     foreach ($elements as $index => $node) {                                                        
    1006               7 :       if ($isCallback) {                                                                            
    1007               2 :         $wrapperTemplate = NULL;                                                                    
    1008               2 :         $wrapContent = call_user_func($content, $node, $index);                                     
    1009               2 :         if (!empty($wrapContent)) {                                                                 
    1010               2 :           $wrapperTemplate = $this->_getContentElement($wrapContent);                               
    1011               2 :         }                                                                                           
    1012               2 :       }                                                                                             
    1013               7 :       if ($wrapperTemplate instanceof DOMElement) {                                                 
    1014               7 :         $wrapper = $wrapperTemplate->cloneNode(TRUE);                                               
    1015               7 :         if (!$simple) {                                                                             
    1016               7 :           $targets = $this->_match('.//*[count(*) = 0]', $wrapper);                                 
    1017               7 :         }                                                                                           
    1018               7 :         if ($simple || $targets->length == 0) {                                                     
    1019               6 :           $target = $wrapper;                                                                       
    1020               6 :           $simple = TRUE;                                                                           
    1021               6 :         } else {                                                                                    
    1022               1 :           $target = $targets->item(0);                                                              
    1023                 :         }                                                                                           
    1024               7 :         if (isset($node->parentNode)) {                                                             
    1025               7 :           $node->parentNode->insertBefore($wrapper, $node);                                         
    1026               7 :         }                                                                                           
    1027               7 :         $target->appendChild($node);                                                                
    1028               7 :         $result[] = $node;                                                                          
    1029               7 :       }                                                                                             
    1030               7 :     }                                                                                               
    1031               7 :     return $result;                                                                                 
    1032                 :   }                                                                                                 
    1033                 :                                                                                                     
    1034                 :   /**                                                                                               
    1035                 :   * Wrap each matched element with the specified content.                                           
    1036                 :   *                                                                                                 
    1037                 :   * If $content contains several elements the first one is used                                     
    1038                 :   *                                                                                                 
    1039                 :   * @example wrap.php Usage Example: FluentDOM::wrap()                                              
    1040                 :   * @param string|array|DOMNode|DOMNodeList|Iterator|callback|Closure $content                      
    1041                 :   * @return FluentDOM                                                                               
    1042                 :   */                                                                                                
    1043                 :   public function wrap($content) {                                                                  
    1044               6 :     $result = $this->spawn();                                                                       
    1045               6 :     $result->push($this->_wrap($this->_array, $content));                                           
    1046               5 :     return $result;                                                                                 
    1047                 :   }                                                                                                 
    1048                 :                                                                                                     
    1049                 :   /**                                                                                               
    1050                 :   * Wrap al matched elements with the specified content                                             
    1051                 :   *                                                                                                 
    1052                 :   * If the matched elemetns are not siblings, wrap each group of siblings.                          
    1053                 :   *                                                                                                 
    1054                 :   * @example wrapAll.php Usage Example: FluentDOM::wrapAll()                                        
    1055                 :   * @param string|array|DOMNode|Iterator $content                                                   
    1056                 :   * @return FluentDOM                                                                               
    1057                 :   */                                                                                                
    1058                 :   public function wrapAll($content) {                                                               
    1059               2 :     $result = $this->spawn();                                                                       
    1060               2 :     $current = NULL;                                                                                
    1061               2 :     $counter = 0;                                                                                   
    1062               2 :     $groups = array();                                                                              
    1063                 :     //group elements by previous node - ignore whitespace text nodes                                
    1064               2 :     foreach ($this->_array as $node) {                                                              
    1065               2 :       $previous = $node->previousSibling;                                                           
    1066               2 :       while ($previous instanceof DOMText && $previous->isWhitespaceInElementContent()) {           
    1067               2 :         $previous = $previous->previousSibling;                                                     
    1068               2 :       }                                                                                             
    1069               2 :       if ($previous !== $current) {                                                                 
    1070               2 :         $counter++;                                                                                 
    1071               2 :       }                                                                                             
    1072               2 :       $groups[$counter][] = $node;                                                                  
    1073               2 :       $current = $node;                                                                             
    1074               2 :     }                                                                                               
    1075               2 :     if (count($groups) > 0) {                                                                       
    1076               2 :       $wrapperTemplate = $this->_getContentElement($content);                                       
    1077               2 :       $simple = FALSE;                                                                              
    1078               2 :       foreach ($groups as $group) {                                                                 
    1079               2 :         if (isset($group[0])) {                                                                     
    1080               2 :           $node = $group[0];                                                                        
    1081               2 :           $wrapper = $wrapperTemplate->cloneNode(TRUE);                                             
    1082               2 :           if (!$simple) {                                                                           
    1083               2 :             $targets = $this->_match('.//*[count(*) = 0]', $wrapper);                               
    1084               2 :           }                                                                                         
    1085               2 :           if ($simple || $targets->length == 0) {                                                   
    1086               1 :             $target = $wrapper;                                                                     
    1087               1 :             $simple = TRUE;                                                                         
    1088               1 :           } else {                                                                                  
    1089               1 :             $target = $targets->item(0);                                                            
    1090                 :           }                                                                                         
    1091               2 :           if (isset($node->parentNode)) {                                                           
    1092               2 :             $node->parentNode->insertBefore($wrapper, $node);                                       
    1093               2 :           }                                                                                         
    1094               2 :           foreach ($group as $node) {                                                               
    1095               2 :             $target->appendChild($node);                                                            
    1096               2 :           }                                                                                         
    1097               2 :           $result->push($node);                                                                     
    1098               2 :         }                                                                                           
    1099               2 :       }                                                                                             
    1100               2 :     }                                                                                               
    1101               2 :     return $result;                                                                                 
    1102                 :   }                                                                                                 
    1103                 :                                                                                                     
    1104                 :   /**                                                                                               
    1105                 :   * Wrap the inner child contents of each matched element                                           
    1106                 :   * (including text nodes) with an XML structure.                                                   
    1107                 :   *                                                                                                 
    1108                 :   * @example wrapInner.php Usage Example: FluentDOM::wrapInner()                                    
    1109                 :   * @param string|array|DOMNode|DOMNodeList|Iterator $content                                       
    1110                 :   * @return FluentDOM                                                                               
    1111                 :   */                                                                                                
    1112                 :   public function wrapInner($content) {                                                             
    1113               2 :     $result = $this->spawn();                                                                       
    1114               2 :     $elements = array();                                                                            
    1115               2 :     foreach ($this->_array as $node) {                                                              
    1116               2 :       foreach ($node->childNodes as $childNode) {                                                   
    1117               2 :         if ($this->_isNode($childNode)) {                                                           
    1118               2 :           $elements[] = $childNode;                                                                 
    1119               2 :         }                                                                                           
    1120               2 :       }                                                                                             
    1121               2 :     }                                                                                               
    1122               2 :     $result->push($this->_wrap($elements, $content));                                               
    1123               2 :     return $result;                                                                                 
    1124                 :   }                                                                                                 
    1125                 :                                                                                                     
    1126                 :   /*                                                                                                
    1127                 :   * Manipulation - Replacing                                                                        
    1128                 :   */                                                                                                
    1129                 :                                                                                                     
    1130                 :   /**                                                                                               
    1131                 :   * Replaces all matched elements with the specified HTML or DOM elements.                          
    1132                 :   * This returns the JQuery element that was just replaced,                                         
    1133                 :   * which has been removed from the DOM.                                                            
    1134                 :   *                                                                                                 
    1135                 :   * @example replaceWith.php Usage Example: FluentDOM::replaceWith()                                
    1136                 :   * @param string|array|DOMNode|DOMNodeList|Iterator|callback|Closure $content                      
    1137                 :   * @return FluentDOM                                                                               
    1138                 :   */                                                                                                
    1139                 :   public function replaceWith($content) {                                                           
    1140               2 :     $this->_applyContentToNodes(                                                                    
    1141               2 :       $this->_array, $content, array($this->_getHandler(), 'insertNodesBefore')                     
    1142               2 :     );                                                                                              
    1143               2 :     $this->_removeNodes($this->_array);                                                             
    1144               2 :     return $this;                                                                                   
    1145                 :   }                                                                                                 
    1146                 :                                                                                                     
    1147                 :                                                                                                     
    1148                 :   /**                                                                                               
    1149                 :   * Replaces the elements matched by the specified selector with the matched elements.              
    1150                 :   *                                                                                                 
    1151                 :   * @example replaceAll.php Usage Example: FluentDOM::replaceAll()                                  
    1152                 :   * @param string|array|DOMNode|DOMNodeList|Iterator $selector                                      
    1153                 :   * @return FluentDOM                                                                               
    1154                 :   */                                                                                                
    1155                 :   public function replaceAll($selector) {                                                           
    1156               4 :     $result = $this->spawn();                                                                       
    1157               4 :     $targetNodes = $this->_getTargetNodes($selector);                                               
    1158               3 :     if (!empty($targetNodes)) {                                                                     
    1159               3 :       $this->_applyContentToNodes(                                                                  
    1160               3 :         $targetNodes,                                                                               
    1161               3 :         $this->_array,                                                                              
    1162               3 :         array($this->_getHandler(), 'insertNodesBefore')                                            
    1163               3 :       );                                                                                            
    1164               3 :       $this->_removeNodes($targetNodes);                                                            
    1165               3 :     }                                                                                               
    1166               3 :     $this->_removeNodes($this->_array);                                                             
    1167               3 :     return $result;                                                                                 
    1168                 :   }                                                                                                 
    1169                 :                                                                                                     
    1170                 :   /*                                                                                                
    1171                 :   * Manipulation - Removing                                                                         
    1172                 :   */                                                                                                
    1173                 :                                                                                                     
    1174                 :   /**                                                                                               
    1175                 :   * Remove all child nodes from the set of matched elements.                                        
    1176                 :   *                                                                                                 
    1177                 :   * This is the empty() method - but because empty                                                  
    1178                 :   * is a reserved word we can no declare it directly                                                
    1179                 :   * @see __call                                                                                     
    1180                 :   *                                                                                                 
    1181                 :   * @example empty.php Usage Example: FluentDOM:empty()                                             
    1182                 :   * @return FluentDOM                                                                               
    1183                 :   */                                                                                                
    1184                 :   protected function _emptyNodes() {                                                                
    1185               1 :     foreach ($this->_array as $node) {                                                              
    1186               1 :       if ($node instanceof DOMElement ||                                                            
    1187               1 :           $node instanceof DOMText) {                                                               
    1188               1 :         $node->nodeValue = '';                                                                      
    1189               1 :       }                                                                                             
    1190               1 :     }                                                                                               
    1191               1 :     return $this;                                                                                   
    1192                 :   }                                                                                                 
    1193                 :                                                                                                     
    1194                 :   /**                                                                                               
    1195                 :   * Removes all matched elements from the DOM.                                                      
    1196                 :   *                                                                                                 
    1197                 :   * @example remove.php Usage Example: FluentDOM::remove()                                          
    1198                 :   * @param string $expr XPath expression                                                            
    1199                 :   * @return FluentDOM removed elements                                                              
    1200                 :   */                                                                                                
    1201                 :   public function remove($expr = NULL) {                                                            
    1202               2 :     $result = $this->spawn();                                                                       
    1203               2 :     foreach ($this->_array as $node) {                                                              
    1204               2 :       if (isset($node->parentNode)) {                                                               
    1205               2 :         if (empty($expr) || $this->_test($expr, $node)) {                                           
    1206               2 :           $result->push($node->parentNode->removeChild($node));                                     
    1207               2 :         }                                                                                           
    1208               2 :       }                                                                                             
    1209               2 :     }                                                                                               
    1210               2 :     return $result;                                                                                 
    1211                 :   }                                                                                                 
    1212                 :                                                                                                     
    1213                 :   /*                                                                                                
    1214                 :   * Manipulation - Creation                                                                         
    1215                 :   */                                                                                                
    1216                 :                                                                                                     
    1217                 :   /*                                                                                                
    1218                 :   * Manipulation - Copying                                                                          
    1219                 :   */                                                                                                
    1220                 :                                                                                                     
    1221                 :   /**                                                                                               
    1222                 :   * Clone matched DOM Elements and select the clones.                                               
    1223                 :   *                                                                                                 
    1224                 :   * This is the clone() method - but because clone                                                  
    1225                 :   * is a reserved word we can no declare it directly                                                
    1226                 :   * @see __call                                                                                     
    1227                 :   *                                                                                                 
    1228                 :   * @example clone.php Usage Example: FluentDOM:clone()                                             
    1229                 :   * @return FluentDOM                                                                               
    1230                 :   */                                                                                                
    1231                 :   protected function _cloneNodes() {                                                                
    1232               1 :     $result = $this->spawn();                                                                       
    1233               1 :     foreach ($this->_array as $node) {                                                              
    1234               1 :       $result->push($node->cloneNode(TRUE));                                                        
    1235               1 :     }                                                                                               
    1236               1 :     return $result;                                                                                 
    1237                 :   }                                                                                                 
    1238                 :                                                                                                     
    1239                 :   /*                                                                                                
    1240                 :   * Attributes - General                                                                            
    1241                 :   */                                                                                                
    1242                 :                                                                                                     
    1243                 :   /**                                                                                               
    1244                 :   * Access a property on the first matched element or set the attribute(s) of all matched elements  
    1245                 :   *                                                                                                 
    1246                 :   * @example attr.php Usage Example: FluentDOM:attr() Read an attribute value.                      
    1247                 :   * @param string|array $attribute attribute name or attribute list                                 
    1248                 :   * @param string|callback|Closure $value function callback($index, $value) or value                
    1249                 :   * @return string|FluentDOM attribute value or $this                                               
    1250                 :   */                                                                                                
    1251                 :   public function attr($attribute, $value = NULL) {                                                 
    1252              16 :     if (is_array($attribute) && count($attribute) > 0) {                                            
    1253                 :       //expr is an array of attributes and values - set on each element                             
    1254               1 :       foreach ($attribute as $key => $value) {                                                      
    1255               1 :         if ($this->_isQName($key)) {                                                                
    1256               1 :           foreach ($this->_array as $node) {                                                        
    1257               1 :             if ($node instanceof DOMElement) {                                                      
    1258               1 :               $node->setAttribute($key, $value);                                                    
    1259               1 :             }                                                                                       
    1260               1 :           }                                                                                         
    1261               1 :         }                                                                                           
    1262               1 :       }                                                                                             
    1263              16 :     } elseif (is_null($value)) {                                                                    
    1264                 :       //empty value - read attribute from first element in list                                     
    1265               8 :       if ($this->_isQName($attribute) &&                                                            
    1266               7 :           count($this->_array) > 0) {                                                               
    1267               6 :         $node = $this->_array[0];                                                                   
    1268               6 :         if ($node instanceof DOMElement) {                                                          
    1269               5 :           return $node->getAttribute($attribute);                                                   
    1270                 :         }                                                                                           
    1271               1 :       }                                                                                             
    1272               2 :       return NULL;                                                                                  
    1273              10 :     } elseif (is_array($value) ||                                                                   
    1274              10 :               $value instanceof Closure) {                                                          
    1275                 :       //value is function callback - execute it and set result on each element                      
    1276               1 :       if ($this->_isQName($attribute)) {                                                            
    1277               1 :         foreach ($this->_array as $index => $node) {                                                
    1278               1 :           if ($node instanceof DOMElement) {                                                        
    1279                 :             $newValue =                                                                             
    1280               1 :             $node->setAttribute(                                                                    
    1281               1 :               $attribute,                                                                           
    1282               1 :               call_user_func($value, $node, $index, $node->getAttribute($attribute))                
    1283               1 :             );                                                                                      
    1284               1 :           }                                                                                         
    1285               1 :         }                                                                                           
    1286               1 :       }                                                                                             
    1287               1 :     } else {                                                                                        
    1288                 :       // set attribute value of each element                                                        
    1289               9 :       if ($this->_isQName($attribute)) {                                                            
    1290               3 :         foreach ($this->_array as $node) {                                                          
    1291               3 :           if ($node instanceof DOMElement) {                                                        
    1292               3 :             $node->setAttribute($attribute, (string)$value);                                        
    1293               3 :           }                                                                                         
    1294               3 :         }                                                                                           
    1295               3 :       }                                                                                             
    1296                 :     }                                                                                               
    1297               5 :     return $this;                                                                                   
    1298                 :   }                                                                                                 
    1299                 :                                                                                                     
    1300                 :   /**                                                                                               
    1301                 :   * Remove an attribute from each of the matched elements.                                          
    1302                 :   *                                                                                                 
    1303                 :   * @example removeAttr.php Usage Example: FluentDOM::removeAttr()                                  
    1304                 :   * @param string $name                                                                             
    1305                 :   * @return FluentDOM                                                                               
    1306                 :   */                                                                                                
    1307                 :   public function removeAttr($name) {                                                               
    1308               4 :     if (!empty($name)) {                                                                            
    1309               4 :       if (is_string($name) && $name !== '*') {                                                      
    1310               1 :         $attributes = array($name);                                                                 
    1311               4 :       } elseif (is_array($name)) {                                                                  
    1312               1 :         $attributes = $name;                                                                        
    1313               3 :       } elseif ($name !== '*') {                                                                    
    1314               1 :         throw new InvalidArgumentException();                                                       
    1315                 :       }                                                                                             
    1316               3 :       foreach ($this->_array as $node) {                                                            
    1317               3 :         if ($node instanceof DOMElement) {                                                          
    1318               3 :           if ($name === '*') {                                                                      
    1319               1 :             for ($i = $node->attributes->length - 1; $i >= 0; $i--) {                               
    1320               1 :               $node->removeAttribute($node->attributes->item($i)->name);                            
    1321               1 :             }                                                                                       
    1322               1 :           } else {                                                                                  
    1323               2 :             foreach ($attributes as $attribute) {                                                   
    1324               2 :               if ($node->hasAttribute($attribute)) {                                                
    1325               2 :                 $node->removeAttribute($attribute);                                                 
    1326               2 :               }                                                                                     
    1327               2 :             }                                                                                       
    1328                 :           }                                                                                         
    1329               3 :         }                                                                                           
    1330               3 :       }                                                                                             
    1331               3 :     }                                                                                               
    1332               3 :     return $this;                                                                                   
    1333                 :   }                                                                                                 
    1334                 :                                                                                                     
    1335                 :   /*                                                                                                
    1336                 :   * Attributes - Classes                                                                            
    1337                 :   */                                                                                                
    1338                 :                                                                                                     
    1339                 :   /**                                                                                               
    1340                 :   * Adds the specified class(es) to each of the set of matched elements.                            
    1341                 :   *                                                                                                 
    1342                 :   * @param string|callback|Closure $class                                                           
    1343                 :   * @return FluentDOM                                                                               
    1344                 :   */                                                                                                
    1345                 :   public function addClass($class) {                                                                
    1346               1 :     return $this->toggleClass($class, TRUE);                                                        
    1347                 :   }                                                                                                 
    1348                 :                                                                                                     
    1349                 :   /**                                                                                               
    1350                 :   * Returns true if the specified class is present on at least one of the set of matched elements.  
    1351                 :   *                                                                                                 
    1352                 :   * @param string|callback|Closure $class                                                           
    1353                 :   * @return boolean                                                                                 
    1354                 :   */                                                                                                
    1355                 :   public function hasClass($class) {                                                                
    1356               2 :     foreach ($this->_array as $node) {                                                              
    1357               2 :       if ($node instanceof DOMElement &&                                                            
    1358               2 :           $node->hasAttribute('class')) {                                                           
    1359               2 :         $classes = preg_split('(\s+)', trim($node->getAttribute('class')));                         
    1360               2 :         if (in_array($class, $classes)) {                                                           
    1361               1 :           return TRUE;                                                                              
    1362                 :         }                                                                                           
    1363               1 :       }                                                                                             
    1364               1 :     }                                                                                               
    1365               1 :     return FALSE;                                                                                   
    1366                 :   }                                                                                                 
    1367                 :                                                                                                     
    1368                 :   /**                                                                                               
    1369                 :   * Removes all or the specified class(es) from the set of matched elements.                        
    1370                 :   *                                                                                                 
    1371                 :   * @param string|callback|Closure $class                                                           
    1372                 :   * @return FluentDOM                                                                               
    1373                 :   */                                                                                                
    1374                 :   public function removeClass($class = '') {                                                        
    1375               2 :     return $this->toggleClass($class, FALSE);                                                       
    1376                 :   }                                                                                                 
    1377                 :                                                                                                     
    1378                 :   /**                                                                                               
    1379                 :   * Adds the specified class if the switch is TRUE,                                                 
    1380                 :   * removes the specified class if the switch is FALSE,                                             
    1381                 :   * toggles the specified class if the switch is NULL.                                              
    1382                 :   *                                                                                                 
    1383                 :   * @example toggleClass.php Usage Example: FluentDOM::toggleClass()                                
    1384                 :   * @param string|callback|Closure $class                                                           
    1385                 :   * @param NULL|boolean $switch toggle if NULL, add if TRUE, remove if FALSE                        
    1386                 :   * @return FluentDOM                                                                               
    1387                 :   */                                                                                                
    1388                 :   public function toggleClass($class, $switch = NULL) {                                             
    1389               6 :     foreach ($this->_array as $index => $node) {                                                    
    1390               6 :       if ($node instanceof DOMElement) {                                                            
    1391               6 :         $isCallback = $this->_isCallback($class, FALSE, TRUE);                                      
    1392               6 :         if ($isCallback) {                                                                          
    1393               1 :           $classString = call_user_func(                                                            
    1394               1 :             $class, $node, $index, $node->getAttribute('class')                                     
    1395               1 :           );                                                                                        
    1396               1 :         } else {                                                                                    
    1397               5 :           $classString = $class;                                                                    
    1398                 :         }                                                                                           
    1399               6 :         if (empty($classString) && $switch == FALSE) {                                              
    1400               1 :           if ($node->hasAttribute('class')) {                                                       
    1401               1 :             $node->removeAttribute('class');                                                        
    1402               1 :           }                                                                                         
    1403               1 :         } else {                                                                                    
    1404               5 :           if ($node->hasAttribute('class')) {                                                       
    1405               5 :             $currentClasses = array_flip(                                                           
    1406               5 :               preg_split('(\s+)', trim($node->getAttribute('class')))                               
    1407               5 :             );                                                                                      
    1408               5 :           } else {                                                                                  
    1409               5 :             $currentClasses = array();                                                              
    1410                 :           }                                                                                         
    1411               5 :           $toggledClasses = array_unique(preg_split('(\s+)', trim($classString)));                  
    1412               5 :           $modified = FALSE;                                                                        
    1413               5 :           foreach ($toggledClasses as $toggledClass) {                                              
    1414               5 :             if (isset($currentClasses[$toggledClass])) {                                            
    1415               4 :               if ($switch === FALSE || is_null($switch)) {                                          
    1416               4 :                 unset($currentClasses[$toggledClass]);                                              
    1417               4 :                 $modified = TRUE;                                                                   
    1418               4 :               }                                                                                     
    1419               4 :             } else {                                                                                
    1420               5 :               if ($switch === TRUE || is_null($switch)) {                                           
    1421               4 :                 $currentClasses[$toggledClass] = TRUE;                                              
    1422               4 :                 $modified = TRUE;                                                                   
    1423               4 :               }                                                                                     
    1424                 :             }                                                                                       
    1425               5 :           }                                                                                         
    1426               5 :           if ($modified) {                                                                          
    1427               5 :             if (empty($currentClasses)) {                                                           
    1428               1 :               $node->removeAttribute('class');                                                      
    1429               1 :             } else {                                                                                
    1430               5 :               $node->setAttribute('class', implode(' ', array_keys($currentClasses)));              
    1431                 :             }                                                                                       
    1432               5 :           }                                                                                         
    1433                 :         }                                                                                           
    1434               6 :       }                                                                                             
    1435               6 :     }                                                                                               
    1436               6 :     return $this;                                                                                   
    1437                 :   }                                                                                                 

Generated by PHPUnit 3.4.12 and Xdebug 2.0.5 using PHP 5.2.13 at Tue Sep 7 1:00:21 CEST 2010.