/**
* Various CSS data needed for correct optimisations etc.
- *
- * @version 1.3
*/
require('data.inc.php');
/**
* Contains a class for printing CSS code
- *
- * @version 1.0
*/
require('class.csstidy_print.php');
/**
* Contains a class for optimising CSS code
- *
- * @version 1.0
*/
require('class.csstidy_optimise.php');
* An online version should be available here: http://cdburnerxp.se/cssparse/css_optimiser.php
* @package csstidy
* @author Florian Schmitz (floele at gmail dot com) 2005-2006
- * @version 1.3
*/
class csstidy {
-/**
- * Saves the parsed CSS
- * @var array
- * @access public
- */
-var $css = array();
-
-/**
- * Saves the parsed CSS (raw)
- * @var array
- * @access private
- */
-var $tokens = array();
-
-/**
- * Printer class
- * @see csstidy_print
- * @var object
- * @access public
- */
-var $print;
-
-/**
- * Optimiser class
- * @see csstidy_optimise
- * @var object
- * @access private
- */
-var $optimise;
-
-/**
- * Saves the CSS charset (@charset)
- * @var string
- * @access private
- */
-var $charset = '';
-
-/**
- * Saves all @import URLs
- * @var array
- * @access private
- */
-var $import = array();
-
-/**
- * Saves the namespace
- * @var string
- * @access private
- */
-var $namespace = '';
-
-/**
- * Contains the version of csstidy
- * @var string
- * @access private
- */
-var $version = '1.3';
-
-/**
- * Stores the settings
- * @var array
- * @access private
- */
-var $settings = array();
-
-/**
- * Saves the parser-status.
- *
- * Possible values:
- * - is = in selector
- * - ip = in property
- * - iv = in value
- * - instr = in string (started at " or ' or ( )
- * - ic = in comment (ignore everything)
- * - at = in @-block
- *
- * @var string
- * @access private
- */
-var $status = 'is';
-
-
-/**
- * Saves the current at rule (@media)
- * @var string
- * @access private
- */
-var $at = '';
-
-/**
- * Saves the current selector
- * @var string
- * @access private
- */
-var $selector = '';
-
-/**
- * Saves the current property
- * @var string
- * @access private
- */
-var $property = '';
-
-/**
- * Saves the position of , in selectors
- * @var array
- * @access private
- */
-var $sel_separate = array();
-
-/**
- * Saves the current value
- * @var string
- * @access private
- */
-var $value = '';
-
-/**
- * Saves the current sub-value
- *
- * Example for a subvalue:
- * background:url(foo.png) red no-repeat;
- * "url(foo.png)", "red", and "no-repeat" are subvalues,
- * seperated by whitespace
- * @var string
- * @access private
- */
-var $sub_value = '';
+ /**
+ * Saves the parsed CSS
+ * @var array
+ * @access public
+ */
+ var $css = array();
+
+ /**
+ * Saves the parsed CSS (raw)
+ * @var array
+ * @access private
+ */
+ var $tokens = array();
+
+ /**
+ * Printer class
+ * @see csstidy_print
+ * @var object
+ * @access public
+ */
+ var $print;
+
+ /**
+ * Optimiser class
+ * @see csstidy_optimise
+ * @var object
+ * @access private
+ */
+ var $optimise;
+
+ /**
+ * Saves the CSS charset (@charset)
+ * @var string
+ * @access private
+ */
+ var $charset = '';
+
+ /**
+ * Saves all @import URLs
+ * @var array
+ * @access private
+ */
+ var $import = array();
+
+ /**
+ * Saves the namespace
+ * @var string
+ * @access private
+ */
+ var $namespace = '';
+
+ /**
+ * Stores the settings
+ * @var array
+ * @access private
+ */
+ var $settings = array();
+
+ /**
+ * Saves the parser-status.
+ *
+ * Possible values:
+ * - is = in selector
+ * - ip = in property
+ * - iv = in value
+ * - instr = in string (started at " or ' or ( )
+ * - ic = in comment (ignore everything)
+ * - at = in @-block
+ *
+ * @var string
+ * @access private
+ */
+ var $status = 'is';
+
+
+ /**
+ * Saves the current at rule (@media)
+ * @var string
+ * @access private
+ */
+ var $at = '';
+
+ /**
+ * Saves the current selector
+ * @var string
+ * @access private
+ */
+ var $selector = '';
+
+ /**
+ * Saves the current property
+ * @var string
+ * @access private
+ */
+ var $property = '';
+
+ /**
+ * Saves the position of , in selectors
+ * @var array
+ * @access private
+ */
+ var $sel_separate = array();
+
+ /**
+ * Saves the current value
+ * @var string
+ * @access private
+ */
+ var $value = '';
+
+ /**
+ * Saves the current sub-value
+ *
+ * Example for a subvalue:
+ * background:url(foo.png) red no-repeat;
+ * "url(foo.png)", "red", and "no-repeat" are subvalues,
+ * seperated by whitespace
+ * @var string
+ * @access private
+ */
+ var $sub_value = '';
+
+ /**
+ * Array which saves all subvalues for a property.
+ * @var array
+ * @see sub_value
+ * @access private
+ */
+ var $sub_value_arr = array();
+
+ /**
+ * Saves the char which opened the last string
+ * @var string
+ * @access private
+ */
+ var $str_char = '';
+ var $cur_string = '';
+
+ /**
+ * Status from which the parser switched to ic or instr
+ * @var string
+ * @access private
+ */
+ var $from = '';
+
+ /**
+ * Variable needed to manage string-in-strings, for example url("foo.png")
+ * @var string
+ * @access private
+ */
+ var $str_in_str = false;
+
+ /**
+ * =true if in invalid at-rule
+ * @var bool
+ * @access private
+ */
+ var $invalid_at = false;
+
+ /**
+ * =true if something has been added to the current selector
+ * @var bool
+ * @access private
+ */
+ var $added = false;
+
+ /**
+ * Array which saves the message log
+ * @var array
+ * @access private
+ */
+ var $log = array();
+
+ /**
+ * Saves the line number
+ * @var integer
+ * @access private
+ */
+ var $line = 1;
+
+ /**
+ * Loads standard template and sets default settings
+ * @access private
+ */
+ function csstidy()
+ {
+ $this->settings['remove_bslash'] = true;
+ $this->settings['compress_colors'] = true;
+ $this->settings['compress_font-weight'] = true;
+ $this->settings['lowercase_s'] = false;
+ $this->settings['optimise_shorthands'] = 1;
+ $this->settings['remove_last_;'] = false;
+ $this->settings['case_properties'] = 1;
+ $this->settings['sort_properties'] = false;
+ $this->settings['sort_selectors'] = false;
+ $this->settings['merge_selectors'] = 2;
+ $this->settings['discard_invalid_properties'] = false;
+ $this->settings['css_level'] = 'CSS2.1';
+ $this->settings['preserve_css'] = false;
+ $this->settings['timestamp'] = false;
+ $this->settings['log'] = false;
+
+ $this->load_template('default');
+ $this->print = new csstidy_print($this);
+ $this->optimise = new csstidy_optimise($this);
+ }
-/**
- * Array which saves all subvalues for a property.
- * @var array
- * @see sub_value
- * @access private
- */
-var $sub_value_arr = array();
+ /**
+ * Get the value of a setting.
+ * @param string $setting
+ * @access public
+ * @return mixed
+ */
+ function get_cfg($setting)
+ {
+ if(isset($this->settings[$setting]))
+ {
+ return $this->settings[$setting];
+ }
+ return false;
+ }
-/**
- * Saves the char which opened the last string
- * @var string
- * @access private
- */
-var $str_char = '';
-var $cur_string = '';
+ /**
+ * Set the value of a setting.
+ * @param string $setting
+ * @param mixed $value
+ * @access public
+ * @return bool
+ */
+ function set_cfg($setting,$value)
+ {
+ if(isset($this->settings[$setting]) && $value !== '')
+ {
+ $this->settings[$setting] = $value;
+ return true;
+ }
+ return false;
+ }
-/**
- * Status from which the parser switched to ic or instr
- * @var string
- * @access private
- */
-var $from = '';
+ /**
+ * Adds a token to $this->tokens
+ * @param mixed $type
+ * @param string $data
+ * @param bool $do add a token even if preserve_css is off
+ * @access private
+ */
+ function _add_token($type, $data, $do = false) {
+ if($this->get_cfg('preserve_css') || $do) {
+ $this->tokens[] = array($type, ($type == COMMENT) ? $data : trim($data));
+ }
+ }
-/**
- * Variable needed to manage string-in-strings, for example url("foo.png")
- * @var string
- * @access private
- */
-var $str_in_str = false;
+ /**
+ * Add a message to the message log
+ * @param string $message
+ * @param string $type
+ * @param integer $line
+ * @access private
+ */
+ function log($message,$type,$line = -1)
+ {
+ if (!$this->settings['log']) {
+ return;
+ }
-/**
- * =true if in invalid at-rule
- * @var bool
- * @access private
- */
-var $invalid_at = false;
+ if($line === -1)
+ {
+ $line = $this->line;
+ }
+ $line = intval($line);
+ $add = array('m' => $message, 't' => $type);
+ if(!isset($this->log[$line]) || !in_array($add,$this->log[$line]))
+ {
+ $this->log[$line][] = $add;
+ }
+ }
-/**
- * =true if something has been added to the current selector
- * @var bool
- * @access private
- */
-var $added = false;
+ /**
+ * Parse unicode notations and find a replacement character
+ * @param string $string
+ * @param integer $i
+ * @access private
+ * @return string
+ */
+ function _unicode(&$string, &$i)
+ {
+ ++$i;
+ $add = '';
+ $tokens =& $GLOBALS['csstidy']['tokens'];
+ $replaced = false;
-/**
- * Array which saves the message log
- * @var array
- * @access private
- */
-var $log = array();
+ while($i < strlen($string) && (ctype_xdigit($string{$i}) || ctype_space($string{$i})) && strlen($add) < 6)
+ {
+ $add .= $string{$i};
-/**
- * Saves the line number
- * @var integer
- * @access private
- */
-var $line = 1;
+ if(ctype_space($string{$i})) {
+ break;
+ }
+ $i++;
+ }
-/**
- * Loads standard template and sets default settings
- * @access private
- * @version 1.3
- */
-function csstidy()
-{
- $this->settings['remove_bslash'] = true;
- $this->settings['compress_colors'] = true;
- $this->settings['compress_font-weight'] = true;
- $this->settings['lowercase_s'] = false;
- $this->settings['optimise_shorthands'] = 1;
- $this->settings['remove_last_;'] = false;
- $this->settings['case_properties'] = 1;
- $this->settings['sort_properties'] = false;
- $this->settings['sort_selectors'] = false;
- $this->settings['merge_selectors'] = 2;
- $this->settings['discard_invalid_properties'] = false;
- $this->settings['css_level'] = 'CSS2.1';
- $this->settings['preserve_css'] = false;
- $this->settings['timestamp'] = false;
-
- $this->load_template('default');
- $this->print = new csstidy_print($this);
- $this->optimise = new csstidy_optimise($this);
-}
+ if(hexdec($add) > 47 && hexdec($add) < 58 || hexdec($add) > 64 && hexdec($add) < 91 || hexdec($add) > 96 && hexdec($add) < 123)
+ {
+ $this->log('Replaced unicode notation: Changed \\'. $add .' to ' . chr(hexdec($add)),'Information');
+ $add = chr(hexdec($add));
+ $replaced = true;
+ }
+ else {
+ $add = trim('\\'.$add);
+ }
-/**
- * Get the value of a setting.
- * @param string $setting
- * @access public
- * @return mixed
- * @version 1.0
- */
-function get_cfg($setting)
-{
- if(isset($this->settings[$setting]))
- {
- return $this->settings[$setting];
- }
- return false;
-}
+ if(@ctype_xdigit($string{$i+1}) && ctype_space($string{$i})
+ && !$replaced || !ctype_space($string{$i})) {
+ $i--;
+ }
-/**
- * Set the value of a setting.
- * @param string $setting
- * @param mixed $value
- * @access public
- * @return bool
- * @version 1.0
- */
-function set_cfg($setting,$value)
-{
- if(isset($this->settings[$setting]) && $value !== '')
- {
- $this->settings[$setting] = $value;
- return true;
- }
- return false;
-}
+ if($add != '\\' || !$this->get_cfg('remove_bslash') || strpos($tokens, $string{$i+1}) !== false) {
+ return $add;
+ }
-/**
- * Adds a token to $this->tokens
- * @param mixed $type
- * @param string $data
- * @param bool $do add a token even if preserve_css is off
- * @access private
- * @version 1.0
- */
-function _add_token($type, $data, $do = false) {
- if($this->get_cfg('preserve_css') || $do) {
- $this->tokens[] = array($type, ($type == COMMENT) ? $data : trim($data));
+ if($add == '\\') {
+ $this->log('Removed unnecessary backslash','Information');
+ }
+ return '';
}
-}
-/**
- * Add a message to the message log
- * @param string $message
- * @param string $type
- * @param integer $line
- * @access private
- * @version 1.0
- */
-function log($message,$type,$line = -1)
-{
- if($line === -1)
- {
- $line = $this->line;
- }
- $line = intval($line);
- $add = array('m' => $message, 't' => $type);
- if(!isset($this->log[$line]) || !in_array($add,$this->log[$line]))
- {
- $this->log[$line][] = $add;
- }
-}
+ /**
+ * Loads a new template
+ * @param string $content either filename (if $from_file == true), content of a template file, "high_compression", "highest_compression", "low_compression", or "default"
+ * @param bool $from_file uses $content as filename if true
+ * @access public
+ * @see http://csstidy.sourceforge.net/templates.php
+ */
+ function load_template($content, $from_file=true)
+ {
+ $predefined_templates =& $GLOBALS['csstidy']['predefined_templates'];
+ if($content == 'high_compression' || $content == 'default' || $content == 'highest_compression' || $content == 'low_compression')
+ {
+ $this->template = $predefined_templates[$content];
+ return;
+ }
-/**
- * Parse unicode notations and find a replacement character
- * @param string $string
- * @param integer $i
- * @access private
- * @return string
- * @version 1.2
- */
-function _unicode(&$string, &$i)
-{
- ++$i;
- $add = '';
- $tokens =& $GLOBALS['csstidy']['tokens'];
- $replaced = false;
-
- while($i < strlen($string) && (ctype_xdigit($string{$i}) || ctype_space($string{$i})) && strlen($add) < 6)
- {
- $add .= $string{$i};
-
- if(ctype_space($string{$i})) {
- break;
- }
- $i++;
- }
-
- if(hexdec($add) > 47 && hexdec($add) < 58 || hexdec($add) > 64 && hexdec($add) < 91 || hexdec($add) > 96 && hexdec($add) < 123)
- {
- $this->log('Replaced unicode notation: Changed \\'. $add .' to ' . chr(hexdec($add)),'Information');
- $add = chr(hexdec($add));
- $replaced = true;
- }
- else {
- $add = trim('\\'.$add);
- }
-
- if(@ctype_xdigit($string{$i+1}) && ctype_space($string{$i})
- && !$replaced || !ctype_space($string{$i})) {
- $i--;
- }
-
- if($add != '\\' || !$this->get_cfg('remove_bslash') || strpos($tokens, $string{$i+1}) !== false) {
- return $add;
- }
-
- if($add == '\\') {
- $this->log('Removed unnecessary backslash','Information');
- }
- return '';
-}
+ if($from_file)
+ {
+ $content = strip_tags(file_get_contents($content),'<span>');
+ }
+ $content = str_replace("\r\n","\n",$content); // Unify newlines (because the output also only uses \n)
+ $template = explode('|',$content);
-/**
- * Loads a new template
- * @param string $content either filename (if $from_file == true), content of a template file, "high_compression", "highest_compression", "low_compression", or "default"
- * @param bool $from_file uses $content as filename if true
- * @access public
- * @version 1.1
- * @see http://csstidy.sourceforge.net/templates.php
- */
-function load_template($content, $from_file=true)
-{
- $predefined_templates =& $GLOBALS['csstidy']['predefined_templates'];
- if($content == 'high_compression' || $content == 'default' || $content == 'highest_compression' || $content == 'low_compression')
- {
- $this->template = $predefined_templates[$content];
- return;
- }
-
- if($from_file)
- {
- $content = strip_tags(file_get_contents($content),'<span>');
- }
- $content = str_replace("\r\n","\n",$content); // Unify newlines (because the output also only uses \n)
- $template = explode('|',$content);
-
- for ($i = 0; $i < count($template); $i++ )
- {
- $this->template[$i] = $template[$i];
- }
-}
+ for ($i = 0; $i < count($template); $i++ )
+ {
+ $this->template[$i] = $template[$i];
+ }
+ }
-/**
- * Starts parsing from URL
- * @param string $url
- * @access public
- * @version 1.0
- */
-function parse_from_url($url)
-{
- return $this->parse(@file_get_contents($url));
-}
+ /**
+ * Starts parsing from URL
+ * @param string $url
+ * @access public
+ */
+ function parse_from_url($url)
+ {
+ return $this->parse(@file_get_contents($url));
+ }
-/**
- * Checks if there is a token at the current position
- * @param string $string
- * @param integer $i
- * @access public
- * @version 1.11
- */
-function is_token(&$string, $i)
-{
- $tokens =& $GLOBALS['csstidy']['tokens'];
- return (strpos($tokens, $string{$i}) !== false && !csstidy::escaped($string,$i));
-}
+ /**
+ * Checks if there is a token at the current position
+ * @param string $string
+ * @param integer $i
+ * @access public
+ */
+ function is_token(&$string, $i)
+ {
+ $tokens =& $GLOBALS['csstidy']['tokens'];
+ return (strpos($tokens, $string{$i}) !== false && !$this->escaped($string,$i));
+ }
-/**
- * Parses CSS in $string. The code is saved as array in $this->css
- * @param string $string the CSS code
- * @access public
- * @return bool
- * @version 1.1
- */
-function parse($string) {
- // PHP bug? Settings need to be refreshed in PHP4
- $this->print = new csstidy_print($this);
- $this->optimise = new csstidy_optimise($this);
+ /**
+ * Parses CSS in $string. The code is saved as array in $this->css
+ * @param string $string the CSS code
+ * @access public
+ * @return bool
+ */
+ function parse($string) {
+ // PHP bug? Settings need to be refreshed in PHP4
+ $this->print = new csstidy_print($this);
+ $this->optimise = new csstidy_optimise($this);
- $all_properties =& $GLOBALS['csstidy']['all_properties'];
- $at_rules =& $GLOBALS['csstidy']['at_rules'];
+ $all_properties =& $GLOBALS['csstidy']['all_properties'];
+ $at_rules =& $GLOBALS['csstidy']['at_rules'];
- $this->css = array();
- $this->print->input_css = $string;
- $string = str_replace("\r\n","\n",$string) . ' ';
- $cur_comment = '';
+ $this->css = array();
+ $this->print->input_css = $string;
+ $string = str_replace("\r\n","\n",$string) . ' ';
+ $cur_comment = '';
+ $s_id = 0;
- for ($i = 0, $size = strlen($string); $i < $size; $i++ )
- {
- if($string{$i} == "\n" || $string{$i} == "\r")
+ for ($i = 0, $size = strlen($string); $i < $size; $i++ )
{
- ++$this->line;
- }
+ if($string{$i} == "\n" || $string{$i} == "\r")
+ {
+ ++$this->line;
+ }
- switch($this->status)
- {
- /* Case in at-block */
- case 'at':
- if(csstidy::is_token($string,$i))
+ switch($this->status)
{
- if($string{$i} == '/' && @$string{$i+1} == '*')
- {
- $this->status = 'ic'; ++$i;
- $this->from = 'at';
- }
- elseif($string{$i} == '{')
- {
- $this->status = 'is';
- $this->_add_token(AT_START, $this->at);
- }
- elseif($string{$i} == ',')
- {
- $this->at = trim($this->at).',';
- }
- elseif($string{$i} == '\\')
+ /* Case in at-block */
+ case 'at':
+ if($this->is_token($string,$i))
{
- $this->at .= $this->_unicode($string,$i);
+ if($string{$i} == '/' && @$string{$i+1} == '*')
+ {
+ $this->status = 'ic'; ++$i;
+ $this->from = 'at';
+ }
+ elseif($string{$i} == '{')
+ {
+ $this->status = 'is';
+ $this->_add_token(AT_START, $this->at);
+ }
+ elseif($string{$i} == ',')
+ {
+ $this->at = trim($this->at).',';
+ }
+ elseif($string{$i} == '\\')
+ {
+ $this->at .= $this->_unicode($string,$i);
+ }
}
- }
- else
- {
- $lastpos = strlen($this->at)-1;
- if(!( (ctype_space($this->at{$lastpos}) || csstidy::is_token($this->at,$lastpos) && $this->at{$lastpos} == ',') && ctype_space($string{$i})))
+ else
{
- $this->at .= $string{$i};
+ $lastpos = strlen($this->at)-1;
+ if(!( (ctype_space($this->at{$lastpos}) || $this->is_token($this->at,$lastpos) && $this->at{$lastpos} == ',') && ctype_space($string{$i})))
+ {
+ $this->at .= $string{$i};
+ }
}
- }
- break;
+ break;
- /* Case in-selector */
+ /* Case in-selector */
case 'is':
- if(csstidy::is_token($string,$i))
- {
- if($string{$i} == '/' && @$string{$i+1} == '*' && trim($this->selector) == '')
- {
- $this->status = 'ic'; ++$i;
- $this->from = 'is';
- }
- elseif($string{$i} == '@' && trim($this->selector) == '')
+ if($this->is_token($string,$i))
{
- // Check for at-rule
- $this->invalid_at = true;
- foreach($at_rules as $name => $type)
+ if($string{$i} == '/' && @$string{$i+1} == '*' && trim($this->selector) == '')
{
- if(!strcasecmp(substr($string,$i+1,strlen($name)),$name))
+ $this->status = 'ic'; ++$i;
+ $this->from = 'is';
+ }
+ elseif($string{$i} == '@' && trim($this->selector) == '')
+ {
+ // Check for at-rule
+ $this->invalid_at = true;
+ foreach($at_rules as $name => $type)
{
- ($type == 'at') ? $this->at = '@'.$name : $this->selector = '@'.$name;
- $this->status = $type;
- $i += strlen($name);
- $this->invalid_at = false;
+ if(!strcasecmp(substr($string,$i+1,strlen($name)),$name))
+ {
+ ($type == 'at') ? $this->at = '@'.$name : $this->selector = '@'.$name;
+ $this->status = $type;
+ $i += strlen($name);
+ $this->invalid_at = false;
+ }
}
- }
- if($this->invalid_at)
- {
- $this->selector = '@';
- $invalid_at_name = '';
- for($j = $i+1; $j < $size; ++$j)
+ if($this->invalid_at)
{
- if(!ctype_alpha($string{$j}))
+ $this->selector = '@';
+ $invalid_at_name = '';
+ for($j = $i+1; $j < $size; ++$j)
{
- break;
+ if(!ctype_alpha($string{$j}))
+ {
+ break;
+ }
+ $invalid_at_name .= $string{$j};
}
- $invalid_at_name .= $string{$j};
+ $this->log('Invalid @-rule: '.$invalid_at_name.' (removed)','Warning');
}
- $this->log('Invalid @-rule: '.$invalid_at_name.' (removed)','Warning');
+ }
+ elseif(($string{$i} == '"' || $string{$i} == "'"))
+ {
+ $this->cur_string = $string{$i};
+ $this->status = 'instr';
+ $this->str_char = $string{$i};
+ $this->from = 'is';
+ }
+ elseif($this->invalid_at && $string{$i} == ';')
+ {
+ $this->invalid_at = false;
+ $this->status = 'is';
+ }
+ elseif($string{$i} == '{')
+ {
+ $this->status = 'ip';
+ $this->_add_token(SEL_START, $this->selector);
+ $this->added = false;
+ }
+ elseif($string{$i} == '}')
+ {
+ $this->_add_token(AT_END, $this->at);
+ $this->at = '';
+ $this->selector = '';
+ $this->sel_separate = array();
+ ++$s_id;
+ }
+ elseif($string{$i} == ',')
+ {
+ $this->selector = trim($this->selector).',';
+ $this->sel_separate[] = strlen($this->selector);
+ }
+ elseif($string{$i} == '\\')
+ {
+ $this->selector .= $this->_unicode($string,$i);
+ }
+ // remove unnecessary universal selector, FS#147
+ else if(!($string{$i} == '*' && @in_array($string{$i+1}, array('.', '#', '[', ':')))) {
+ $this->selector .= $string{$i};
}
}
- elseif(($string{$i} == '"' || $string{$i} == "'"))
- {
- $this->cur_string = $string{$i};
- $this->status = 'instr';
- $this->str_char = $string{$i};
- $this->from = 'is';
- }
- elseif($this->invalid_at && $string{$i} == ';')
- {
- $this->invalid_at = false;
- $this->status = 'is';
- }
- elseif($string{$i} == '{')
- {
- $this->status = 'ip';
- $this->_add_token(SEL_START, $this->selector);
- $this->added = false;
- }
- elseif($string{$i} == '}')
- {
- $this->_add_token(AT_END, $this->at);
- $this->at = '';
- $this->selector = '';
- $this->sel_separate = array();
- }
- elseif($string{$i} == ',')
- {
- $this->selector = trim($this->selector).',';
- $this->sel_separate[] = strlen($this->selector);
- }
- elseif($string{$i} == '\\')
- {
- $this->selector .= $this->_unicode($string,$i);
- }
- // remove unnecessary universal selector, FS#147
- else if(!($string{$i} == '*' && @in_array($string{$i+1}, array('.', '#', '[', ':')))) {
- $this->selector .= $string{$i};
- }
- }
- else
- {
- $lastpos = strlen($this->selector)-1;
- if($lastpos == -1 || !( (ctype_space($this->selector{$lastpos}) || csstidy::is_token($this->selector,$lastpos) && $this->selector{$lastpos} == ',') && ctype_space($string{$i})))
+ else
{
- $this->selector .= $string{$i};
+ $lastpos = strlen($this->selector)-1;
+ if($lastpos == -1 || !( (ctype_space($this->selector{$lastpos}) || $this->is_token($this->selector,$lastpos) && $this->selector{$lastpos} == ',') && ctype_space($string{$i})))
+ {
+ $this->selector .= $string{$i};
+ }
}
- }
- break;
+ break;
- /* Case in-property */
+ /* Case in-property */
case 'ip':
- if(csstidy::is_token($string,$i))
- {
- if(($string{$i} == ':' || $string{$i} == '=') && $this->property != '')
+ if($this->is_token($string,$i))
{
- $this->status = 'iv';
- if(!$this->get_cfg('discard_invalid_properties') || csstidy::property_is_valid($this->property)) {
- $this->_add_token(PROPERTY, $this->property);
+ if(($string{$i} == ':' || $string{$i} == '=') && $this->property != '')
+ {
+ $this->status = 'iv';
+ if(!$this->get_cfg('discard_invalid_properties') || $this->property_is_valid($this->property)) {
+ $this->_add_token(PROPERTY, $this->property);
+ }
+ }
+ elseif($string{$i} == '/' && @$string{$i+1} == '*' && $this->property == '')
+ {
+ $this->status = 'ic'; ++$i;
+ $this->from = 'ip';
+ }
+ elseif($string{$i} == '}')
+ {
+ $this->explode_selectors();
+ $this->status = 'is';
+ $this->invalid_at = false;
+ $this->_add_token(SEL_END, $this->selector);
+ $this->selector = '';
+ $this->property = '';
+ }
+ elseif($string{$i} == ';')
+ {
+ $this->property = '';
+ }
+ elseif($string{$i} == '\\')
+ {
+ $this->property .= $this->_unicode($string,$i);
}
}
- elseif($string{$i} == '/' && @$string{$i+1} == '*' && $this->property == '')
- {
- $this->status = 'ic'; ++$i;
- $this->from = 'ip';
- }
- elseif($string{$i} == '}')
- {
- $this->explode_selectors();
- $this->status = 'is';
- $this->invalid_at = false;
- $this->_add_token(SEL_END, $this->selector);
- $this->selector = '';
- $this->property = '';
- }
- elseif($string{$i} == ';')
- {
- $this->property = '';
- }
- elseif($string{$i} == '\\')
+ elseif(!ctype_space($string{$i}))
{
- $this->property .= $this->_unicode($string,$i);
+ $this->property .= $string{$i};
}
- }
- elseif(!ctype_space($string{$i}))
- {
- $this->property .= $string{$i};
- }
- break;
+ break;
- /* Case in-value */
+ /* Case in-value */
case 'iv':
- $pn = (($string{$i} == "\n" || $string{$i} == "\r") && $this->property_is_next($string,$i+1) || $i == strlen($string)-1);
- if(csstidy::is_token($string,$i) || $pn)
- {
- if($string{$i} == '/' && @$string{$i+1} == '*')
- {
- $this->status = 'ic'; ++$i;
- $this->from = 'iv';
- }
- elseif(($string{$i} == '"' || $string{$i} == "'" || $string{$i} == '('))
- {
- $this->cur_string = $string{$i};
- $this->str_char = ($string{$i} == '(') ? ')' : $string{$i};
- $this->status = 'instr';
- $this->from = 'iv';
- }
- elseif($string{$i} == ',')
- {
- $this->sub_value = trim($this->sub_value).',';
- }
- elseif($string{$i} == '\\')
+ $pn = (($string{$i} == "\n" || $string{$i} == "\r") && $this->property_is_next($string,$i+1) || $i == strlen($string)-1);
+ if($this->is_token($string,$i) || $pn)
{
- $this->sub_value .= $this->_unicode($string,$i);
- }
- elseif($string{$i} == ';' || $pn)
- {
- if($this->selector{0} == '@' && isset($at_rules[substr($this->selector,1)]) && $at_rules[substr($this->selector,1)] == 'iv')
+ if($string{$i} == '/' && @$string{$i+1} == '*')
{
- $this->sub_value_arr[] = trim($this->sub_value);
+ $this->status = 'ic'; ++$i;
+ $this->from = 'iv';
+ }
+ elseif(($string{$i} == '"' || $string{$i} == "'" || $string{$i} == '('))
+ {
+ $this->cur_string = $string{$i};
+ $this->str_char = ($string{$i} == '(') ? ')' : $string{$i};
+ $this->status = 'instr';
+ $this->from = 'iv';
+ }
+ elseif($string{$i} == ',')
+ {
+ $this->sub_value = trim($this->sub_value).',';
+ }
+ elseif($string{$i} == '\\')
+ {
+ $this->sub_value .= $this->_unicode($string,$i);
+ }
+ elseif($string{$i} == ';' || $pn)
+ {
+ if($this->selector{0} == '@' && isset($at_rules[substr($this->selector,1)]) && $at_rules[substr($this->selector,1)] == 'iv')
+ {
+ $this->sub_value_arr[] = trim($this->sub_value);
- $this->status = 'is';
+ $this->status = 'is';
- switch($this->selector)
- {
+ switch($this->selector)
+ {
case '@charset': $this->charset = $this->sub_value_arr[0]; break;
case '@namespace': $this->namespace = implode(' ',$this->sub_value_arr); break;
case '@import': $this->import[] = implode(' ',$this->sub_value_arr); break;
- }
+ }
- $this->sub_value_arr = array();
- $this->sub_value = '';
- $this->selector = '';
- $this->sel_separate = array();
+ $this->sub_value_arr = array();
+ $this->sub_value = '';
+ $this->selector = '';
+ $this->sel_separate = array();
+ }
+ else
+ {
+ $this->status = 'ip';
+ }
}
- else
+ elseif($string{$i} != '}')
{
- $this->status = 'ip';
+ $this->sub_value .= $string{$i};
}
- }
- elseif($string{$i} != '}')
- {
- $this->sub_value .= $string{$i};
- }
- if(($string{$i} == '}' || $string{$i} == ';' || $pn) && !empty($this->selector))
- {
- if($this->at == '')
+ if(($string{$i} == '}' || $string{$i} == ';' || $pn) && !empty($this->selector))
{
- $this->at = DEFAULT_AT;
- }
+ if($this->at == '')
+ {
+ $this->at = DEFAULT_AT;
+ }
- // case settings
- if($this->get_cfg('lowercase_s'))
- {
- $this->selector = strtolower($this->selector);
- }
- $this->property = strtolower($this->property);
+ // case settings
+ if($this->get_cfg('lowercase_s'))
+ {
+ $this->selector = strtolower($this->selector);
+ }
+ $this->property = strtolower($this->property);
- $this->optimise->subvalue();
- if($this->sub_value != '') {
- $this->sub_value_arr[] = $this->sub_value;
- $this->sub_value = '';
- }
+ $this->optimise->subvalue();
+ if($this->sub_value != '') {
+ $this->sub_value_arr[] = $this->sub_value;
+ $this->sub_value = '';
+ }
- $this->value = implode(' ',$this->sub_value_arr);
+ $this->value = implode(' ',$this->sub_value_arr);
- $this->selector = trim($this->selector);
+ $this->selector = trim($this->selector);
- $this->optimise->value();
+ $this->optimise->value();
- $valid = csstidy::property_is_valid($this->property);
- if((!$this->invalid_at || $this->get_cfg('preserve_css')) && (!$this->get_cfg('discard_invalid_properties') || $valid))
- {
- $this->css_add_property($this->at,$this->selector,$this->property,$this->value);
- $this->_add_token(VALUE, $this->value);
- $this->optimise->shorthands();
- }
- if(!$valid)
- {
- if($this->get_cfg('discard_invalid_properties'))
+ $valid = $this->property_is_valid($this->property);
+ if((!$this->invalid_at || $this->get_cfg('preserve_css')) && (!$this->get_cfg('discard_invalid_properties') || $valid))
{
- $this->log('Removed invalid property: '.$this->property,'Warning');
+ $this->css_add_property($this->at,$this->selector,$this->property,$this->value, $s_id);
+ $this->_add_token(VALUE, $this->value);
+ $this->optimise->shorthands();
}
- else
+ if(!$valid)
{
- $this->log('Invalid property in '.strtoupper($this->get_cfg('css_level')).': '.$this->property,'Warning');
+ if($this->get_cfg('discard_invalid_properties'))
+ {
+ $this->log('Removed invalid property: '.$this->property,'Warning');
+ }
+ else
+ {
+ $this->log('Invalid property in '.strtoupper($this->get_cfg('css_level')).': '.$this->property,'Warning');
+ }
}
- }
- $this->property = '';
- $this->sub_value_arr = array();
- $this->value = '';
+ $this->property = '';
+ $this->sub_value_arr = array();
+ $this->value = '';
+ }
+ if($string{$i} == '}')
+ {
+ $this->explode_selectors();
+ $this->_add_token(SEL_END, $this->selector);
+ $this->status = 'is';
+ $this->invalid_at = false;
+ $this->selector = '';
+ }
}
- if($string{$i} == '}')
+ elseif(!$pn)
{
- $this->explode_selectors();
- $this->_add_token(SEL_END, $this->selector);
- $this->status = 'is';
- $this->invalid_at = false;
- $this->selector = '';
- }
- }
- elseif(!$pn)
- {
- $this->sub_value .= $string{$i};
+ $this->sub_value .= $string{$i};
- if(ctype_space($string{$i}))
- {
- $this->optimise->subvalue();
- if($this->sub_value != '') {
- $this->sub_value_arr[] = $this->sub_value;
- $this->sub_value = '';
+ if(ctype_space($string{$i}))
+ {
+ $this->optimise->subvalue();
+ if($this->sub_value != '') {
+ $this->sub_value_arr[] = $this->sub_value;
+ $this->sub_value = '';
+ }
}
}
- }
- break;
+ break;
- /* Case in string */
+ /* Case in string */
case 'instr':
- if($this->str_char == ')' && ($string{$i} == '"' || $string{$i} == '\'') && !$this->str_in_str && !csstidy::escaped($string,$i))
- {
- $this->str_in_str = true;
- }
- elseif($this->str_char == ')' && ($string{$i} == '"' || $string{$i} == '\'') && $this->str_in_str && !csstidy::escaped($string,$i))
- {
- $this->str_in_str = false;
- }
- $temp_add = $string{$i}; // ...and no not-escaped backslash at the previous position
- if( ($string{$i} == "\n" || $string{$i} == "\r") && !($string{$i-1} == '\\' && !csstidy::escaped($string,$i-1)) )
- {
- $temp_add = "\\A ";
- $this->log('Fixed incorrect newline in string','Warning');
- }
- if (!($this->str_char == ')' && in_array($string{$i}, $GLOBALS['csstidy']['whitespace']) && !$this->str_in_str)) {
- $this->cur_string .= $temp_add;
- }
- if($string{$i} == $this->str_char && !csstidy::escaped($string,$i) && !$this->str_in_str)
- {
- $this->status = $this->from;
- if (!preg_match('|[' . implode('', $GLOBALS['csstidy']['whitespace']) . ']|uis', $this->cur_string) && $this->property != 'content') {
- if ($this->str_char == '"' || $this->str_char == '\'') {
- if ($this->status != 'is') {
- $this->cur_string = substr($this->cur_string, 1, -1);
- }
- } else if (strlen($this->cur_string) > 3 && ($this->cur_string[1] == '"' || $this->cur_string[1] == '\'')) /* () */ {
- $this->cur_string = $this->cur_string[0] . substr($this->cur_string, 2, -2) . substr($this->cur_string, -1);
- }
+ if($this->str_char == ')' && ($string{$i} == '"' || $string{$i} == '\'') && !$this->str_in_str && !$this->escaped($string,$i))
+ {
+ $this->str_in_str = true;
}
- if($this->from == 'iv')
+ elseif($this->str_char == ')' && ($string{$i} == '"' || $string{$i} == '\'') && $this->str_in_str && !$this->escaped($string,$i))
{
- $this->sub_value .= $this->cur_string;
+ $this->str_in_str = false;
}
- elseif($this->from == 'is')
+ $temp_add = $string{$i}; // ...and no not-escaped backslash at the previous position
+ if( ($string{$i} == "\n" || $string{$i} == "\r") && !($string{$i-1} == '\\' && !$this->escaped($string,$i-1)) )
{
- $this->selector .= $this->cur_string;
+ $temp_add = "\\A ";
+ $this->log('Fixed incorrect newline in string','Warning');
}
- }
- break;
+ if (!($this->str_char == ')' && in_array($string{$i}, $GLOBALS['csstidy']['whitespace']) && !$this->str_in_str)) {
+ $this->cur_string .= $temp_add;
+ }
+ if($string{$i} == $this->str_char && !$this->escaped($string,$i) && !$this->str_in_str)
+ {
+ $this->status = $this->from;
+ if (!preg_match('|[' . implode('', $GLOBALS['csstidy']['whitespace']) . ']|uis', $this->cur_string) && $this->property != 'content') {
+ if ($this->str_char == '"' || $this->str_char == '\'') {
+ if ($this->status != 'is') {
+ $this->cur_string = substr($this->cur_string, 1, -1);
+ }
+ } else if (strlen($this->cur_string) > 3 && ($this->cur_string[1] == '"' || $this->cur_string[1] == '\'')) /* () */ {
+ $this->cur_string = $this->cur_string[0] . substr($this->cur_string, 2, -2) . substr($this->cur_string, -1);
+ }
+ }
+ if($this->from == 'iv')
+ {
+ $this->sub_value .= $this->cur_string;
+ }
+ elseif($this->from == 'is')
+ {
+ $this->selector .= $this->cur_string;
+ }
+ }
+ break;
- /* Case in-comment */
+ /* Case in-comment */
case 'ic':
- if($string{$i} == '*' && $string{$i+1} == '/')
- {
- $this->status = $this->from;
- $i++;
- $this->_add_token(COMMENT, $cur_comment);
- $cur_comment = '';
- }
- else
- {
- $cur_comment .= $string{$i};
+ if($string{$i} == '*' && $string{$i+1} == '/')
+ {
+ $this->status = $this->from;
+ $i++;
+ $this->_add_token(COMMENT, $cur_comment);
+ $cur_comment = '';
+ }
+ else
+ {
+ $cur_comment .= $string{$i};
+ }
+ break;
}
- break;
}
- }
- $this->optimise->postparse();
+ $this->optimise->postparse();
- $this->print->_reset();
+ $this->print->_reset();
- return !(empty($this->css) && empty($this->import) && empty($this->charset) && empty($this->tokens) && empty($this->namespace));
-}
+ return !(empty($this->css) && empty($this->import) && empty($this->charset) && empty($this->tokens) && empty($this->namespace));
+ }
-/**
- * Explodes selectors
- * @access private
- * @version 1.0
- */
-function explode_selectors()
-{
- // Explode multiple selectors
- if($this->get_cfg('merge_selectors') == 1)
+ /**
+ * Explodes selectors
+ * @access private
+ */
+ function explode_selectors()
{
- $new_sels = array();
- $lastpos = 0;
- $this->sel_separate[] = strlen($this->selector);
- foreach($this->sel_separate as $num => $pos)
+ // Explode multiple selectors
+ if($this->get_cfg('merge_selectors') == 1)
{
- if($num == count($this->sel_separate)-1) {
- $pos += 1;
- }
+ $new_sels = array();
+ $lastpos = 0;
+ $this->sel_separate[] = strlen($this->selector);
+ foreach($this->sel_separate as $num => $pos)
+ {
+ if($num == count($this->sel_separate)-1) {
+ $pos += 1;
+ }
- $new_sels[] = substr($this->selector,$lastpos,$pos-$lastpos-1);
- $lastpos = $pos;
- }
+ $new_sels[] = substr($this->selector,$lastpos,$pos-$lastpos-1);
+ $lastpos = $pos;
+ }
- if(count($new_sels) > 1)
- {
- foreach($new_sels as $selector)
+ if(count($new_sels) > 1)
{
- $this->merge_css_blocks($this->at,$selector,$this->css[$this->at][$this->selector]);
+ foreach($new_sels as $selector)
+ {
+ $this->merge_css_blocks($this->at,$selector,$this->css[$this->at][$this->selector]);
+ }
+ unset($this->css[$this->at][$this->selector]);
}
- unset($this->css[$this->at][$this->selector]);
}
+ $this->sel_separate = array();
}
- $this->sel_separate = array();
-}
-
-/**
- * Checks if a character is escaped (and returns true if it is)
- * @param string $string
- * @param integer $pos
- * @access public
- * @return bool
- * @version 1.02
- */
-function escaped(&$string,$pos)
-{
- return !(@($string{$pos-1} != '\\') || csstidy::escaped($string,$pos-1));
-}
-/**
- * Adds a property with value to the existing CSS code
- * @param string $media
- * @param string $selector
- * @param string $property
- * @param string $new_val
- * @access private
- * @version 1.2
- */
-function css_add_property($media,$selector,$property,$new_val)
-{
- if($this->get_cfg('preserve_css') || trim($new_val) == '') {
- return;
+ /**
+ * Checks if a character is escaped (and returns true if it is)
+ * @param string $string
+ * @param integer $pos
+ * @access public
+ * @return bool
+ */
+ function escaped(&$string,$pos)
+ {
+ return !(@($string{$pos-1} != '\\') || $this->escaped($string,$pos-1));
}
- $this->added = true;
- if(isset($this->css[$media][$selector][$property]))
+ /**
+ * Adds a property with value to the existing CSS code
+ * @param string $media
+ * @param string $selector
+ * @param string $property
+ * @param string $new_val
+ * @param string $selector_id
+ * @access private
+ */
+ function css_add_property($media,$selector,$property,$new_val,$selector_id = null)
{
- if((csstidy::is_important($this->css[$media][$selector][$property]) && csstidy::is_important($new_val)) || !csstidy::is_important($this->css[$media][$selector][$property]))
- {
- unset($this->css[$media][$selector][$property]);
- $this->css[$media][$selector][$property] = trim($new_val);
+ $new_val = trim($new_val);
+
+ if (!$this->get_cfg('preserve_css') && ($new_val != '')) {
+ $this->added = true;
+
+ if (isset($this->css[$media][$selector][$property])) {
+ $ptr = &$this->css[$media][$selector][$property];
+ if ($this->is_important(end($ptr['p']))) {
+ return;
+ } elseif (!is_null($selector_id) &&
+ ($ptr['id'] == $selector_id)) {
+ $ptr['p'][] = $new_val;
+ return;
+ }
+ }
+
+ $this->css[$media][$selector][$property] = array(
+ 'id' => (is_null($selector_id) ? -1 : $selector_id),
+ 'p' => array($new_val)
+ );
}
}
- else
+
+ /**
+ * Adds CSS to an existing media/selector
+ * @param string $media
+ * @param string $selector
+ * @param array $css_add
+ * @access private
+ */
+ function merge_css_blocks($media, $selector, $css_add)
{
- $this->css[$media][$selector][$property] = trim($new_val);
+ foreach ($css_add as $property => $value) {
+ $this->css_add_property($media, $selector, $property, $value);
+ }
}
-}
-
-/**
- * Adds CSS to an existing media/selector
- * @param string $media
- * @param string $selector
- * @param array $css_add
- * @access private
- * @version 1.1
- */
-function merge_css_blocks($media,$selector,$css_add)
-{
- foreach($css_add as $property => $value)
- {
- $this->css_add_property($media,$selector,$property,$value,false);
- }
-}
-/**
- * Checks if $value is !important.
- * @param string $value
- * @return bool
- * @access public
- * @version 1.0
- */
-function is_important(&$value)
-{
- return (!strcasecmp(substr(str_replace($GLOBALS['csstidy']['whitespace'],'',$value),-10,10),'!important'));
-}
+ /**
+ * Checks if $value is !important.
+ * @param string $value
+ * @return bool
+ * @access public
+ */
+ function is_important($value)
+ {
+ return (!strcasecmp(substr(str_replace($GLOBALS['csstidy']['whitespace'],'',$value),-10,10),'!important'));
+ }
-/**
- * Returns a value without !important
- * @param string $value
- * @return string
- * @access public
- * @version 1.0
- */
-function gvw_important($value)
-{
- if(csstidy::is_important($value))
- {
- $value = trim($value);
- $value = substr($value,0,-9);
- $value = trim($value);
- $value = substr($value,0,-1);
- $value = trim($value);
- return $value;
- }
- return $value;
-}
+ /**
+ * Returns a value without !important
+ * @param string $value
+ * @return string
+ * @access public
+ */
+ function gvw_important($value)
+ {
+ if($this->is_important($value))
+ {
+ $value = trim($value);
+ $value = substr($value,0,-9);
+ $value = trim($value);
+ $value = substr($value,0,-1);
+ $value = trim($value);
+ }
+ return $value;
+ }
-/**
- * Checks if the next word in a string from pos is a CSS property
- * @param string $istring
- * @param integer $pos
- * @return bool
- * @access private
- * @version 1.2
- */
-function property_is_next($istring, $pos)
-{
- $all_properties =& $GLOBALS['csstidy']['all_properties'];
- $istring = substr($istring,$pos,strlen($istring)-$pos);
- $pos = strpos($istring,':');
- if($pos === false)
- {
- return false;
- }
- $istring = strtolower(trim(substr($istring,0,$pos)));
- if(isset($all_properties[$istring]))
- {
- $this->log('Added semicolon to the end of declaration','Warning');
- return true;
- }
- return false;
-}
+ /**
+ * Checks if the next word in a string from pos is a CSS property
+ * @param string $istring
+ * @param integer $pos
+ * @return bool
+ * @access private
+ */
+ function property_is_next($istring, $pos)
+ {
+ $all_properties =& $GLOBALS['csstidy']['all_properties'];
+ $istring = substr($istring,$pos,strlen($istring)-$pos);
+ $pos = strpos($istring,':');
+ if($pos === false)
+ {
+ return false;
+ }
+ $istring = strtolower(trim(substr($istring,0,$pos)));
+ if(isset($all_properties[$istring]))
+ {
+ $this->log('Added semicolon to the end of declaration','Warning');
+ return true;
+ }
+ return false;
+ }
-/**
- * Checks if a property is valid
- * @param string $property
- * @return bool;
- * @access public
- * @version 1.0
- */
-function property_is_valid($property) {
- $all_properties =& $GLOBALS['csstidy']['all_properties'];
- return (isset($all_properties[$property]) && strpos($all_properties[$property],strtoupper($this->get_cfg('css_level'))) !== false );
-}
+ /**
+ * Checks if a property is valid
+ * @param string $property
+ * @return bool;
+ * @access public
+ */
+ function property_is_valid($property) {
+ $all_properties =& $GLOBALS['csstidy']['all_properties'];
+ return (isset($all_properties[$property]) && strpos($all_properties[$property],strtoupper($this->get_cfg('css_level'))) !== false );
+ }
}
-?>
*
* @package csstidy
* @author Florian Schmitz (floele at gmail dot com) 2005-2006
- * @version 1.0
*/
class csstidy_optimise
* Constructor
* @param array $css contains the class csstidy
* @access private
- * @version 1.0
*/
function csstidy_optimise(&$css)
{
$this->parser =& $css;
- $this->css =& $css->css;
$this->sub_value =& $css->sub_value;
$this->at =& $css->at;
$this->selector =& $css->selector;
/**
* Optimises $css after parsing
* @access public
- * @version 1.0
*/
function postparse()
{
return;
}
- if ($this->parser->get_cfg('merge_selectors') == 2)
- {
- foreach ($this->css as $medium => $value)
- {
- $this->merge_selectors($this->css[$medium]);
+ $css = &$this->parser->css;
+
+ if ($this->parser->get_cfg('merge_selectors') == 2) {
+ foreach (array_keys($css) as $medium) {
+ $this->merge_selectors($css[$medium]);
}
}
- if ($this->parser->get_cfg('optimise_shorthands') > 0)
- {
- foreach ($this->css as $medium => $value)
- {
- foreach ($value as $selector => $value1)
- {
- $this->css[$medium][$selector] = csstidy_optimise::merge_4value_shorthands($this->css[$medium][$selector]);
-
- if ($this->parser->get_cfg('optimise_shorthands') < 2) {
- continue;
- }
+ if ($this->parser->get_cfg('optimise_shorthands') > 0) {
+ foreach ($css as $medium => $value) {
+ foreach ($value as $selector => $value1) {
+ $ptr = &$css[$medium][$selector];
+ $ptr = $this->merge_4value_shorthands($ptr);
- $this->css[$medium][$selector] = csstidy_optimise::merge_bg($this->css[$medium][$selector]);
- if (empty($this->css[$medium][$selector])) {
- unset($this->css[$medium][$selector]);
+ if ($this->parser->get_cfg('optimise_shorthands') >= 2) {
+ $ptr = $this->merge_bg($ptr);
+ if (empty($ptr)) {
+ unset($ptr);
+ }
}
}
}
/**
* Optimises values
* @access public
- * @version 1.0
*/
function value()
{
// optimise shorthand properties
if(isset($shorthands[$this->property]))
{
- $temp = csstidy_optimise::shorthand($this->value); // FIXME - move
+ $temp = $this->shorthand($this->value); // FIXME - move
if($temp != $this->value)
{
$this->parser->log('Optimised shorthand notation ('.$this->property.'): Changed "'.$this->value.'" to "'.$temp.'"','Information');
/**
* Optimises shorthands
* @access public
- * @version 1.0
*/
function shorthands()
{
- $shorthands =& $GLOBALS['csstidy']['shorthands'];
-
- if(!$this->parser->get_cfg('optimise_shorthands') || $this->parser->get_cfg('preserve_css')) {
+ if (!$this->parser->get_cfg('optimise_shorthands') ||
+ $this->parser->get_cfg('preserve_css')) {
return;
}
- if($this->property == 'background' && $this->parser->get_cfg('optimise_shorthands') > 1)
- {
- unset($this->css[$this->at][$this->selector]['background']);
- $this->parser->merge_css_blocks($this->at,$this->selector,csstidy_optimise::dissolve_short_bg($this->value));
+ $css = &$this->parser->css;
+ $shorthands =& $GLOBALS['csstidy']['shorthands'];
+
+ if ($this->property == 'background' &&
+ $this->parser->get_cfg('optimise_shorthands') > 1) {
+ unset($css[$this->at][$this->selector]['background']);
+ $this->parser->merge_css_blocks($this->at,$this->selector,$this->dissolve_short_bg($this->value));
}
- if(isset($shorthands[$this->property]))
- {
- $this->parser->merge_css_blocks($this->at,$this->selector,csstidy_optimise::dissolve_4value_shorthands($this->property,$this->value));
- if(is_array($shorthands[$this->property]))
- {
- unset($this->css[$this->at][$this->selector][$this->property]);
+ if(isset($shorthands[$this->property])) {
+ $this->parser->merge_css_blocks($this->at,$this->selector,$this->dissolve_4value_shorthands($this->property,$this->value));
+ if(is_array($shorthands[$this->property])) {
+ unset($css[$this->at][$this->selector][$this->property]);
}
}
}
/**
* Optimises a sub-value
* @access public
- * @version 1.0
*/
function subvalue()
{
}
$important = '';
- if(csstidy::is_important($this->sub_value))
+ if($this->parser->is_important($this->sub_value))
{
$important = '!important';
}
- $this->sub_value = csstidy::gvw_important($this->sub_value);
+ $this->sub_value = $this->parser->gvw_important($this->sub_value);
// Compress font-weight
if($this->property == 'font-weight' && $this->parser->get_cfg('compress_font-weight'))
* @param string $value
* @access public
* @return string
- * @version 1.0
*/
function shorthand($value)
{
$important = '';
- if(csstidy::is_important($value))
+ if($this->parser->is_important($value))
{
- $values = csstidy::gvw_important($value);
+ $values = $this->parser->gvw_important($value);
$important = '!important';
}
else $values = $value;
* @param string $string
* @return string
* @access public
- * @version 1.1
*/
function compress_important(&$string)
{
- if(csstidy::is_important($string))
+ if($this->parser->is_important($string))
{
- $string = csstidy::gvw_important($string) . '!important';
+ $string = $this->parser->gvw_important($string) . '!important';
}
return $string;
}
* Color compression function. Converts all rgb() values to #-values and uses the short-form if possible. Also replaces 4 color names by #-values.
* @param string $color
* @return string
- * @version 1.1
*/
function cut_color($color)
{
* Compresses numbers (ie. 1.0 becomes 1 or 1.100 becomes 1.1 )
* @param string $subvalue
* @return string
- * @version 1.2
*/
function compress_numbers($subvalue)
{
* @param array $array
* @return array
* @access public
- * @version 1.2
*/
function merge_selectors(&$array)
{
* @param string $property
* @param string $value
* @return array
- * @version 1.0
* @see merge_4value_shorthands()
*/
function dissolve_4value_shorthands($property,$value)
}
$important = '';
- if(csstidy::is_important($value))
+ if($this->parser->is_important($value))
{
- $value = csstidy::gvw_important($value);
+ $value = $this->parser->gvw_important($value);
$important = '!important';
}
$values = explode(' ',$value);
* @param string $sep seperator
* @param string $string
* @return array
- * @version 1.0
*/
function explode_ws($sep,$string)
{
switch($status)
{
case 'st':
- if($string{$i} == $sep && !csstidy::escaped($string,$i))
+ if($string{$i} == $sep && !$this->parser->escaped($string,$i))
{
++$num;
}
- elseif($string{$i} == '"' || $string{$i} == '\'' || $string{$i} == '(' && !csstidy::escaped($string,$i))
+ elseif($string{$i} == '"' || $string{$i} == '\'' || $string{$i} == '(' && !$this->parser->escaped($string,$i))
{
$status = 'str';
$to = ($string{$i} == '(') ? ')' : $string{$i};
break;
case 'str':
- if($string{$i} == $to && !csstidy::escaped($string,$i))
+ if($string{$i} == $to && !$this->parser->escaped($string,$i))
{
$status = 'st';
}
* Merges Shorthand properties again, the opposite of dissolve_4value_shorthands()
* @param array $array
* @return array
- * @version 1.2
* @see dissolve_4value_shorthands()
*/
function merge_4value_shorthands($array)
{
$return = $array;
- $shorthands =& $GLOBALS['csstidy']['shorthands'];
+ $shorthands = &$GLOBALS['csstidy']['shorthands'];
- foreach($shorthands as $key => $value)
- {
- if(isset($array[$value[0]]) && isset($array[$value[1]])
- && isset($array[$value[2]]) && isset($array[$value[3]]) && $value !== 0)
- {
- $return[$key] = '';
+ foreach ($shorthands as $key => $value) {
+ if ((count($value) == 4) &&
+ isset($array[$value[0]]) &&
+ isset($array[$value[1]]) &&
+ isset($array[$value[2]]) &&
+ isset($array[$value[3]])) {
- $important = '';
- for($i = 0; $i < 4; $i++)
- {
- $val = $array[$value[$i]];
- if(csstidy::is_important($val))
- {
+ $important = $newval = '';
+
+ for ($i = 0; $i < 4; ++$i) {
+ $val = end($array[$value[$i]]['p']);
+ if ($this->parser->is_important($val)) {
$important = '!important';
- $return[$key] .= csstidy::gvw_important($val).' ';
- }
- else
- {
- $return[$key] .= $val.' ';
+ $newval .= $this->parser->gvw_important($val).' ';
+ } else {
+ $newval .= $val.' ';
}
unset($return[$value[$i]]);
}
- $return[$key] = csstidy_optimise::shorthand(trim($return[$key].$important));
+
+ $return[$key]['p'] = array($this->shorthand(trim($newval . $important)));
}
}
+
return $return;
}
* Dissolve background property
* @param string $str_value
* @return array
- * @version 1.0
* @see merge_bg()
* @todo full CSS 3 compliance
*/
$important = '';
$return = array('background-image' => NULL,'background-size' => NULL,'background-repeat' => NULL,'background-position' => NULL,'background-attachment'=>NULL,'background-clip' => NULL,'background-origin' => NULL,'background-color' => NULL);
- if(csstidy::is_important($str_value))
+ if($this->parser->is_important($str_value))
{
$important = ' !important';
- $str_value = csstidy::gvw_important($str_value);
+ $str_value = $this->parser->gvw_important($str_value);
}
- $str_value = csstidy_optimise::explode_ws(',',$str_value);
+ $str_value = $this->explode_ws(',',$str_value);
for($i = 0; $i < count($str_value); $i++)
{
$have['clip'] = FALSE; $have['pos'] = FALSE;
$have['color'] = FALSE; $have['bg'] = FALSE;
- $str_value[$i] = csstidy_optimise::explode_ws(' ',trim($str_value[$i]));
+ $str_value[$i] = $this->explode_ws(' ',trim($str_value[$i]));
for($j = 0; $j < count($str_value[$i]); $j++)
{
* Merges all background properties
* @param array $input_css
* @return array
- * @version 1.0
* @see dissolve_short_bg()
* @todo full CSS 3 compliance
*/
function merge_bg($input_css)
{
- $background_prop_default =& $GLOBALS['csstidy']['background_prop_default'];
+ $bpd = &$GLOBALS['csstidy']['background_prop_default'];
+
// Max number of background images. CSS3 not yet fully implemented
- $number_of_values = @max(count(csstidy_optimise::explode_ws(',',$input_css['background-image'])),count(csstidy_optimise::explode_ws(',',$input_css['background-color'])),1);
+ $num_vals = @max(count($this->explode_ws(',', end($input_css['background-image']['p']))), count($this->explode_ws(',', end($input_css['background-color']['p']))), 1);
+
// Array with background images to check if BG image exists
- $bg_img_array = @csstidy_optimise::explode_ws(',',csstidy::gvw_important($input_css['background-image']));
- $new_bg_value = '';
- $important = '';
+ $bg_img_array = @$this->explode_ws(',',$this->parser->gvw_important(end($input_css['background-image']['p'])));
+ $important = $new_bg_value = '';
- for($i = 0; $i < $number_of_values; $i++)
- {
- foreach($background_prop_default as $bg_property => $default_value)
- {
+ for ($i = 0; $i < $num_vals; ++$i) {
+ foreach ($bpd as $bg_property => $default_value) {
// Skip if property does not exist
- if(!isset($input_css[$bg_property]))
- {
+ if (!isset($input_css[$bg_property])) {
continue;
}
- $cur_value = $input_css[$bg_property];
+ $cur_value = end($input_css[$bg_property]['p']);
// Skip some properties if there is no background image
if((!isset($bg_img_array[$i]) || $bg_img_array[$i] === 'none')
}
// Remove !important
- if(csstidy::is_important($cur_value))
+ if($this->parser->is_important($cur_value))
{
$important = ' !important';
- $cur_value = csstidy::gvw_important($cur_value);
+ $cur_value = $this->parser->gvw_important($cur_value);
}
// Do not add default values
continue;
}
- $temp = csstidy_optimise::explode_ws(',',$cur_value);
+ $temp = $this->explode_ws(',',$cur_value);
if(isset($temp[$i]))
{
}
$new_bg_value = trim($new_bg_value);
- if($i != $number_of_values-1) $new_bg_value .= ',';
+ if ($i != ($num_vals - 1)) {
+ $new_bg_value .= ',';
+ }
}
// Delete all background-properties
- foreach($background_prop_default as $bg_property => $default_value)
- {
+ foreach ($bpd as $bg_property => $default_value) {
unset($input_css[$bg_property]);
}
// Add new background property
- if($new_bg_value !== '') $input_css['background'] = $new_bg_value.$important;
+ if ($new_bg_value !== '') {
+ $input_css['background'] = array('p' => array($new_bg_value . $important));
+ }
return $input_css;
}