Example #1
0
 private function parseSelector()
 {
     $oResult = new CSSDeclarationBlock();
     $oResult->setSelector($this->consumeUntil('{'));
     $this->consume('{');
     $this->consumeWhiteSpace();
     $this->parseRuleSet($oResult);
     return $oResult;
 }
Example #2
0
 /**
  * Merge multiple CSS RuleSets by cascading according to the CSS 2.1 cascading rules 
  * (http://www.w3.org/TR/REC-CSS2/cascade.html#cascading-order).
  * 
  * @param array $aDeclarations An array of CSSDeclarationBlock objects.
  *
  * @return CSSDeclarationBlock.
  * 
  * ==== Cascading
  * If a CSSDeclarationBlock object has its +specificity+ defined, that specificity is 
  * used in the cascade calculations.  
  * 
  * If no specificity is explicitly set and the CSSDeclarationBlock has *one* selector, 
  * the specificity is calculated using that selector.
  * 
  * If no selectors or multiple selectors are present, the specificity is 
  * treated as 0.
  * 
  * ==== Example #1
  * <code>
  *   $oDecl_1 = new CSSDeclarationBlock();
  *   $oRule_1 = new CSSRule('color');
  *   $oRule_1->addValue(new CSSColor('#F00'));
  *   $oDecl_1->addRule($oRule_1);
  *   $oDecl_2 = new CSSDeclarationBlock();
  *   $oRule_2 = new CSSRule('margin');
  *   $oRule_2->addValue(
  *     new CSSSize(0, 'px')
  *   );
  *   $oDecl_2->addRule($oRule_2);
  * 
  *   $oMerged = CSSDocument::mergeDeclarations($oDecl_1, $oDecl_2);
  * 
  *   echo $oMerged;
  *   //=> "{ margin: 0px; color: rgb(255,0,0); }"
  * </code>
  * ==== Example #2
  * <code>
  *   $oDecl_1 = new CSSDeclarationBlock();
  *   $oRule_1 = new CSSRule('background-color');
  *   $oRule_1->addValue(new CSSColor('black'));
  *   $oDecl_1->addRule($oRule_1);
  *   $oDecl_2 = new CSSDeclarationBlock();
  *   $oRule_2 = new CSSRule('background-image');
  *   $oRule_2->addValue('none');
  *   $oDecl_2->addRule($oRule_2);
  * 
  *   $oMerged = CSSDocument::mergeDeclarations($oDecl_1, $oDecl_2);
  * 
  *   echo $oMerged;
  *   //=> "{ background: none rgb(0,0,0); }"
  * </code>
  **/
 static function mergeDeclarations(array $aDeclarations)
 {
     // Internal storage of CSS properties that we will keep
     $aProperties = array();
     foreach ($aDeclarations as $oDeclaration) {
         $oDeclaration->expandShorthands();
         $aSelectors = $oDeclaration->getSelectors();
         $iSpecificity = 0;
         if (count($aSelectors) == 1) {
             $iSpecificity = $aSelectors[0]->getSpecificity();
         }
         foreach ($oDeclaration->getRules() as $sProperty => $oRule) {
             // Add the property to the list to be folded per
             // http://www.w3.org/TR/CSS21/cascade.html#cascading-order
             if (!isset($aProperties[$sProperty])) {
                 $aProperties[$sProperty] = array('values' => $oRule->getValues(), 'specificity' => $iSpecificity, 'important' => $oRule->getIsImportant());
             } else {
                 $aProperty = $aProperties[$sProperty];
                 if ($aProperty['specificity'] <= $iSpecificity && !$aProperty['important']) {
                     $aProperties[$sProperty] = array('values' => $oRule->getValues(), 'specificity' => $iSpecificity, 'important' => $oRule->getIsImportant());
                 }
             }
             if ($oRule->getIsImportant()) {
                 $aProperties[$sProperty] = array('values' => $oRule->getValues(), 'specificity' => $iSpecificity, 'important' => $oRule->getIsImportant());
             }
         }
         // end foreach rules
     }
     // end foreach rulesets
     $oMerged = new CSSDeclarationBlock();
     foreach ($aProperties as $sProperty => $aDetails) {
         $oNewRule = new CSSRule($sProperty);
         foreach ($aDetails['values'] as $aValue) {
             $oNewRule->addvalue($aValue);
         }
         if ($aDetails['important']) {
             $oNewRule->setIsImportant(true);
         }
         $oMerged->addRule($oNewRule);
     }
     $oMerged->createShorthands();
     return $oMerged;
 }