FluentDOM
[ class tree: FluentDOM ] [ index: FluentDOM ] [ all elements ]

Source for file Style.php

Documentation is available at Style.php

  1. <?php
  2. /**
  3. * FluentDOMStyle extends the FluentDOM class with a function to edit
  4. * the style attribute of html tags
  5. *
  6. @version $Id: Style.php 431 2010-03-29 20:42:04Z subjective $
  7. @license http://www.opensource.org/licenses/mit-license.php The MIT License
  8. @copyright Copyright (c) 2009 Bastian Feder, Thomas Weinert
  9. *
  10. @package FluentDOM
  11. */
  12.  
  13. /**
  14. * include the parent class (FluentDOM)
  15. */
  16. require_once(dirname(__FILE__).'/../FluentDOM.php');
  17.  
  18. /**
  19. * Function to create a new FluentDOMStyleinstance and loads data into it if
  20. * a valid $source is provided.
  21. *
  22. @param mixed $source 
  23. @param string $contentType optional, default value 'text/xml'
  24. @return object FluentDOMStyle 
  25. */
  26. function FluentDOMStyle($source NULL$contentType 'text/xml'{
  27.   $result new FluentDOMStyle();
  28.   if (isset($source)) {
  29.     return $result->load($source$contentType);
  30.   else {
  31.     return $result;
  32.   }
  33. }
  34.  
  35. /**
  36. * FluentDOMStyle extends the FluentDOM class with a function to edit
  37. * the style attribute of html tags
  38. *
  39. @package FluentDOM
  40. */
  41. class FluentDOMStyle extends FluentDOM {
  42.  
  43.   /**
  44.   * Pattern to decode the stlye property string
  45.   */
  46.   const STYLE_PATTERN = '((?:^|;)\s*(?P<name>[-\w]+)\s*:\s*(?P<value>[^;]+))';
  47.  
  48.   /**
  49.   * get or set CSS values in style attributes
  50.   *
  51.   * @param string|array$property 
  52.   * @param NULL|string|object Closure  $value 
  53.   * @return string|object FluentDOMStyle  
  54.   */
  55.   public function css($property$value NULL{
  56.     if (is_array($property)) {
  57.       //set list of properties to all elements
  58.       foreach ($this->_array as $node{
  59.         if ($node instanceof DOMElement{
  60.           $options $this->_decodeStyleAttribute($node->getAttribute('style'));
  61.           foreach ($property as $name => $value{
  62.             if ($this->_isCSSProperty($name)) {
  63.               if (isset($options[$name]&& empty($value)) {
  64.                 unset($options[$name]);
  65.               elseif (!empty($value)) {
  66.                 $options[$name$value;
  67.               }
  68.             else {
  69.               throw new InvalidArgumentException('Invalid css property name: '.$property);
  70.             }
  71.           }
  72.           $styleString $this->_encodeStyleAttribute($options);
  73.           if (empty($styleString&& $node->hasAttribute('style')) {
  74.             $node->removeAttribute('style');
  75.           elseif (!empty($styleString)) {
  76.             $node->setAttribute('style'$styleString);
  77.           }
  78.         }
  79.       }
  80.     elseif (is_null($value)) {
  81.       //get value from first DOMElement
  82.       $firstNode NULL;
  83.       foreach ($this->_array as $node{
  84.         if ($node instanceof DOMElement{
  85.           $firstNode $node;
  86.           break;
  87.         }
  88.       }
  89.       if (empty($firstNode)) {
  90.         return NULL;
  91.       else {
  92.         $options $this->_decodeStyleAttribute($firstNode->getAttribute('style'));
  93.         if (isset($options[$property])) {
  94.           return $options[$property];
  95.         }
  96.       }
  97.       return NULL;
  98.     else {
  99.       //set value to all nodes
  100.       if ($this->_isCSSProperty($property)) {
  101.         foreach ($this->_array as $index => $node{
  102.           if ($node instanceof DOMElement{
  103.             $options $this->_decodeStyleAttribute($node->getAttribute('style'));
  104.             if (empty($value)) {
  105.               if (isset($options[$property])) {
  106.                 unset($options[$property]);
  107.               }
  108.             elseif (is_string($value)) {
  109.               $options[$property$value;
  110.             elseif ($this->_isCallback($valueFALSEFALSE)) {
  111.               $options[$propertycall_user_func(
  112.                 $value,
  113.                 $node,
  114.                 $index,
  115.                 empty($options[$property]'' $options[$property]
  116.               );
  117.             }
  118.             $styleString $this->_encodeStyleAttribute($options);
  119.             if (empty($styleString&& $node->hasAttribute('style')) {
  120.               $node->removeAttribute('style');
  121.             elseif (!empty($styleString)) {
  122.               $node->setAttribute('style'$styleString);
  123.             }
  124.           }
  125.         }
  126.       else {
  127.         throw new InvalidArgumentException('Invalid css property name: '.$property);
  128.       }
  129.     }
  130.   }
  131.  
  132.   /**
  133.   * check if string is an valid css property name
  134.   *
  135.   * @param string $propertyName 
  136.   * @return boolean 
  137.   */
  138.   private function _isCSSProperty($propertyName{
  139.     $pattern '(^-?(?:[a-z]+-)*(?:[a-z]+)$)D';
  140.     if (preg_match($pattern$propertyName)) {
  141.       return TRUE;
  142.     }
  143.     return FALSE;
  144.   }
  145.  
  146.   /**
  147.   * decode style attribute to css properties array
  148.   *
  149.   * @param string $styleString 
  150.   * @return array 
  151.   */
  152.   private function _decodeStyleAttribute($styleString{
  153.     $result array();
  154.     if (!empty($styleString)) {
  155.       $matches array();
  156.       if (preg_match_all(self::STYLE_PATTERN$styleString$matchesPREG_SET_ORDER)) {
  157.         foreach ($matches as $match{
  158.           if (isset($match['name']&&
  159.               $this->_isCSSProperty($match['name']&&
  160.               !empty($match['value'])) {
  161.             $result[$match['name']] $match['value'];
  162.           }
  163.         }
  164.       }
  165.     }
  166.     return $result;
  167.   }
  168.  
  169.   /**
  170.   * encode css options array for the style string
  171.   *
  172.   * @param array $properties 
  173.   * @return string 
  174.   */
  175.   private function _encodeStyleAttribute($properties{
  176.     $result '';
  177.     if (is_array($properties&& count($properties0{
  178.       uksort($propertiesarray($this'_compareCSSProperties'));
  179.       foreach ($properties as $name => $value{
  180.         $result .= ' '.$name.': '.$value.';';
  181.       }
  182.     }
  183.     return substr($result1);
  184.   }
  185.  
  186.   /**
  187.   * compare to css property names
  188.   *
  189.   * by name, browser-prefix, level
  190.   *
  191.   * @param string $propertyNameOne 
  192.   * @param string $propertyNameTwo 
  193.   * @return integer 
  194.   */
  195.   private function _compareCSSProperties($propertyNameOne$propertyNameTwo{
  196.     $propertyOne $this->_getCSSPropertyElements($propertyNameOne);
  197.     $propertyTwo $this->_getCSSPropertyElements($propertyNameTwo);
  198.     $propertyOneLevels count($propertyOne);
  199.     $propertyTwoLevels count($propertyTwo);
  200.     $maxLevels ($propertyOneLevels $propertyTwoLevels)
  201.       ? $propertyOneLevels $propertyTwoLevels;
  202.     for ($i 0$i $maxLevels++$i{
  203.       if (isset($propertyOne[$i]&&
  204.           isset($propertyTwo[$i])) {
  205.         $compare strnatcasecmp(
  206.           $propertyOne[$i],
  207.           $propertyTwo[$i]
  208.         );
  209.         if ($compare != 0{
  210.           return $compare;
  211.         }
  212.       else {
  213.         break;
  214.       }
  215.     }
  216.     if ($propertyOneLevels $propertyTwoLevels{
  217.       return 1;
  218.     else {
  219.       return -1;
  220.     }
  221.   }
  222.  
  223.   /**
  224.   * decodes the css property name into an compareable array
  225.   *
  226.   * @return array 
  227.   */
  228.   private function _getCSSPropertyElements($propertyName{
  229.     if (substr($propertyName01== '-'{
  230.       $pos strpos($propertyName'-'1);
  231.       $items explode('-'substr($propertyName$pos 1));
  232.       $items[substr($propertyName1$pos);
  233.       return $items;
  234.     else {
  235.       $items explode('-'$propertyName);
  236.       return $items;
  237.     }
  238.   }
  239. }

Documentation generated on Thu, 09 Sep 2010 01:00:58 +0200 by phpDocumentor 1.4.3