From 59ed16b1e13a6c86e0ce1cc7055bddaa1836abf9 Mon Sep 17 00:00:00 2001 From: Dan Schaefer Date: Tue, 28 Dec 2010 08:49:24 -0500 Subject: [PATCH 1/3] Re-wrote a few __toString methods to account for CSSSize and CSSColor types where calling "implode" would fail Created a few CSSDocument helper methods to return a style when given a selector --- CSSParser.php | 92 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/CSSParser.php b/CSSParser.php index 77eb3faf..696304d9 100644 --- a/CSSParser.php +++ b/CSSParser.php @@ -465,6 +465,28 @@ protected function allValues($oElement, &$aResult, $sSearchString = null) { } } } + + /** + * Does the same thing as $this->allRuleSets except it creates + * an associative array with the selector as the keys. If there + * are multiple selectors in the rule set, then each one will + * have their own array element. + * + * @param array $aResult + * + * @author dschaefer 12/23/2010 + */ + protected function allUniqueRuleSets(&$aResult){ + foreach($this->aContents as $mContent) { + if($mContent instanceof CSSRuleSet) { + foreach($mContent->getSelector() as $aSelector){ + $aResult[$aSelector] = $mContent; + } + } else if($mContent instanceof CSSList) { + $mContent->allRuleSets($aResult); + } + } + } } class CSSDocument extends CSSList { @@ -492,6 +514,44 @@ public function getAllValues($mElement = null) { $this->allValues($mElement, $aResult, $sSearchString); return $aResult; } + + /** + * Does the same thing as $this->getAllRuleSets except it uses + * CSSList->allUniqueRuleSets. This will generate an associative + * array of rule sets with the selector as the key. + * + * @return array + */ + public function getAllUniqueRuleSets(){ + $aResult = array(); + $this->allUniqueRuleSets($aResult); + return $aResult; + } + + /** + * Gets just the style, not the entire rule set of the given + * selector + * @param string $sSelector + * @return string + */ + public function getStyle($sSelector=""){ + $sResult = ""; + if($sSelector){ + $aRuleSets = $this->getAllUniqueRuleSets(); + $aSelectors = explode(",", $sSelector); + foreach($aSelectors as $sSelector){ + $sSelector = trim($sSelector); + if(isset($aRuleSets[$sSelector])){ + $oRuleSet = $aRuleSets[$sSelector]; + $aRules = $oRuleSet->getRules(); + foreach($aRules as $oRule){ + $sResult .= $oRule->__toString()." "; + } + } + } + } + return $sResult; + } } class CSSMediaQuery extends CSSList { @@ -704,11 +764,24 @@ public function getIsImportant() { public function __toString() { $sResult = "{$this->sRule}: "; foreach($this->aValues as $aValues) { - $sResult .= implode(', ', $aValues).' '; + //Rewrote to account for CSSSize and CSSColor- dschaefer 12/22/2010 + reset($aValues); + while($mValue = current($aValues)){ + if(gettype($mValue) != 'object' && gettype($mValue) != 'array'){ + $sResult .= $mValue." "; + }else if(gettype($mValue) == 'object'){ + $sResult .= $mValue->__toString()." "; + } + if(next($aValues)){ + $sResult .= ', '; + } + } + //$sResult .= implode(', ', $aValues).' '; } if($this->bIsImportant) { $sResult .= '!important'; } else { + //What does this accomplish? Should this remove any semi-colons instead of removing the last character? $sResult = substr($sResult, 0, -1); } $sResult .= ';'; @@ -780,7 +853,22 @@ public function getColorDescription() { } public function __toString() { - return $this->getColorDescription().'('.implode(', ', $this->aColor).')'; + //Rewrote to account for CSSSize - dschaefer 12/22/2010 + $sResult = $this->getColorDescription().'('; + reset($this->aColor); + while($mColor = current($this->aColor)){ + if(gettype($mColor) != "object"){ + $sResult .= $mColor; + }else{ + $sResult .= $mColor->__toString(); + } + if(next($this->aColor)){ + $sResult .= ', '; + } + } + $sResult .= ')'; + return $sResult; + //return $this->getColorDescription().'('.implode(', ', $this->aColor).')'; } } From 01d149feacf383c9d9a3781a7394bfad58bb08f2 Mon Sep 17 00:00:00 2001 From: Dan Schaefer Date: Thu, 30 Dec 2010 10:53:35 -0500 Subject: [PATCH 2/3] Fixed Bug: The CSSSelector->aSelector is not being set correctly Added CSSParser->append to allow you to add multiple strings before parsing --- CSSParser.php | 92 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/CSSParser.php b/CSSParser.php index 77eb3faf..696304d9 100644 --- a/CSSParser.php +++ b/CSSParser.php @@ -465,6 +465,28 @@ protected function allValues($oElement, &$aResult, $sSearchString = null) { } } } + + /** + * Does the same thing as $this->allRuleSets except it creates + * an associative array with the selector as the keys. If there + * are multiple selectors in the rule set, then each one will + * have their own array element. + * + * @param array $aResult + * + * @author dschaefer 12/23/2010 + */ + protected function allUniqueRuleSets(&$aResult){ + foreach($this->aContents as $mContent) { + if($mContent instanceof CSSRuleSet) { + foreach($mContent->getSelector() as $aSelector){ + $aResult[$aSelector] = $mContent; + } + } else if($mContent instanceof CSSList) { + $mContent->allRuleSets($aResult); + } + } + } } class CSSDocument extends CSSList { @@ -492,6 +514,44 @@ public function getAllValues($mElement = null) { $this->allValues($mElement, $aResult, $sSearchString); return $aResult; } + + /** + * Does the same thing as $this->getAllRuleSets except it uses + * CSSList->allUniqueRuleSets. This will generate an associative + * array of rule sets with the selector as the key. + * + * @return array + */ + public function getAllUniqueRuleSets(){ + $aResult = array(); + $this->allUniqueRuleSets($aResult); + return $aResult; + } + + /** + * Gets just the style, not the entire rule set of the given + * selector + * @param string $sSelector + * @return string + */ + public function getStyle($sSelector=""){ + $sResult = ""; + if($sSelector){ + $aRuleSets = $this->getAllUniqueRuleSets(); + $aSelectors = explode(",", $sSelector); + foreach($aSelectors as $sSelector){ + $sSelector = trim($sSelector); + if(isset($aRuleSets[$sSelector])){ + $oRuleSet = $aRuleSets[$sSelector]; + $aRules = $oRuleSet->getRules(); + foreach($aRules as $oRule){ + $sResult .= $oRule->__toString()." "; + } + } + } + } + return $sResult; + } } class CSSMediaQuery extends CSSList { @@ -704,11 +764,24 @@ public function getIsImportant() { public function __toString() { $sResult = "{$this->sRule}: "; foreach($this->aValues as $aValues) { - $sResult .= implode(', ', $aValues).' '; + //Rewrote to account for CSSSize and CSSColor- dschaefer 12/22/2010 + reset($aValues); + while($mValue = current($aValues)){ + if(gettype($mValue) != 'object' && gettype($mValue) != 'array'){ + $sResult .= $mValue." "; + }else if(gettype($mValue) == 'object'){ + $sResult .= $mValue->__toString()." "; + } + if(next($aValues)){ + $sResult .= ', '; + } + } + //$sResult .= implode(', ', $aValues).' '; } if($this->bIsImportant) { $sResult .= '!important'; } else { + //What does this accomplish? Should this remove any semi-colons instead of removing the last character? $sResult = substr($sResult, 0, -1); } $sResult .= ';'; @@ -780,7 +853,22 @@ public function getColorDescription() { } public function __toString() { - return $this->getColorDescription().'('.implode(', ', $this->aColor).')'; + //Rewrote to account for CSSSize - dschaefer 12/22/2010 + $sResult = $this->getColorDescription().'('; + reset($this->aColor); + while($mColor = current($this->aColor)){ + if(gettype($mColor) != "object"){ + $sResult .= $mColor; + }else{ + $sResult .= $mColor->__toString(); + } + if(next($this->aColor)){ + $sResult .= ', '; + } + } + $sResult .= ')'; + return $sResult; + //return $this->getColorDescription().'('.implode(', ', $this->aColor).')'; } } From a7c00b5b406322ade4c8f7a18b9e9d031845c973 Mon Sep 17 00:00:00 2001 From: Dan Schaefer Date: Thu, 30 Dec 2010 11:02:57 -0500 Subject: [PATCH 3/3] I did not commit the changes in the last commit Fixed Bug: The CSSSelector->aSelector is not being set correctly Added CSSParser->append to allow you to add multiple strings before parsing --- CSSParser.php | 47 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/CSSParser.php b/CSSParser.php index 696304d9..bb723d45 100644 --- a/CSSParser.php +++ b/CSSParser.php @@ -403,6 +403,34 @@ private function consumeUntil($sEnd) { private function inputLeft() { return mb_substr($this->sText, $this->iCurrentPosition, -1, $this->sCharset); } + + /** + * Appends a string to the sText CSS string. + * This allows you to add multiple strings before parsing + * @param string $sText + * + * @author dschaefer + * @since 12/30/2010 + * + * @example $CSSParser = new CSSParser(file_get_contents("css/default.css")); + * $CSSParser->append(file_get_contents("css/custom.css")); + */ + public function append($sText, $sCharest=NULL){ + if(!isset($sCharest)){ $sCharest = $this->sCharset; } + $this->sText .= $sText; + $this->setCharset($sCharest); + } + + /** + * Simply returns the private $sText variable + * @return string + * + * @author dschaefer + * @since 12/30/2010 + */ + public function getContents(){ + return $this->sText; + } } abstract class CSSList { @@ -472,18 +500,27 @@ protected function allValues($oElement, &$aResult, $sSearchString = null) { * are multiple selectors in the rule set, then each one will * have their own array element. * + * Fixed Bug: The CSSSelector->aSelector is not being set correctly + * * @param array $aResult * - * @author dschaefer 12/23/2010 + * @author dschaefer + * @since 12/23/2010 */ protected function allUniqueRuleSets(&$aResult){ - foreach($this->aContents as $mContent) { + foreach($this->aContents as $mContent){ if($mContent instanceof CSSRuleSet) { - foreach($mContent->getSelector() as $aSelector){ - $aResult[$aSelector] = $mContent; + foreach($mContent->getSelector() as $sSelector){ + if(!isset($aResult[$sSelector])){ + $aResult[$sSelector] = new CSSSelector(); + } + $aResult[$sSelector]->setSelector($sSelector); + foreach($mContent->getRules() as $oRule){ + $aResult[$sSelector]->addRule($oRule); + } } } else if($mContent instanceof CSSList) { - $mContent->allRuleSets($aResult); + $mContent->allUniqueRuleSets($aResult); } } }