/** * parse regular CSS blocks * * _parse_properties() creates a new StyleParser object based on the provided * CSS rules. * * @param string $str CSS rules * @return StyleParser */ private function _parse_properties($str) { $properties = preg_split("/;(?=(?:[^\\(]*\\([^\\)]*\\))*(?![^\\)]*\\)))/", $str); // Create the style $style = new StyleParser($this); foreach ($properties as $prop) { // If the $prop contains an url, the regex may be wrong // @todo: fix the regex so that it works everytime /*if (strpos($prop, "url(") === false) { if (preg_match("/([a-z-]+)\s*:\s*[^:]+$/i", $prop, $m)) $prop = $m[0]; }*/ //A css property can have " ! important" appended (whitespace optional) //strip this off to decode core of the property correctly. //Pass on in the style to allow proper handling: //!important properties can only be overridden by other !important ones. //$style->$prop_name = is a shortcut of $style->__set($prop_name,$value);. //If no specific set function available, set _props["prop_name"] //style is always copied completely, or $_props handled separately //Therefore set a _important_props["prop_name"]=true to indicate the modifier /* Instead of short code, prefer the typical case with fast code $important = preg_match("/(.*?)!\s*important/",$prop,$match); if ( $important ) { $prop = $match[1]; } $prop = trim($prop); */ $important = false; $prop = trim($prop); if (substr($prop, -9) === 'important') { $prop_tmp = rtrim(substr($prop, 0, -9)); if (substr($prop_tmp, -1) === '!') { $prop = rtrim(substr($prop_tmp, 0, -1)); $important = true; } } if ($prop == "") { continue; } $i = mb_strpos($prop, ":"); if ($i === false) { continue; } $prop_name = rtrim(mb_strtolower(mb_substr($prop, 0, $i))); $value = ltrim(mb_substr($prop, $i + 1)); //New style, anyway empty //if ($important || !$style->important_get($prop_name) ) { //$style->$prop_name = array($value,$important); //assignment might be replaced by overloading through __set, //and overloaded functions might check _important_props, //therefore set _important_props first. if ($important) { $style->important_set($prop_name); } //For easier debugging, don't use overloading of assignments with __set $style->{$prop_name} = $value; //$style->props_set($prop_name, $value); } return $style; }