/** * Imports css via @import statements * * @author Anthony Short * @param $css */ public static function server_import($css, $previous = "") { # If they want to override the CSS syntax if (CSScaffold::config('core.override_import') === true) { $import = 'import'; } else { $import = 'include'; } if (preg_match_all('/\\@' . $import . '\\s+(?:\'|\\")([^\'\\"]+)(?:\'|\\")\\;/', $css, $matches)) { $unique = array_unique($matches[1]); $include = str_replace("\\", "/", unquote($unique[0])); # If they're getting an absolute file if ($include[0] == "/") { $include = DOCROOT . ltrim($include, "/"); } # Make sure recursion isn't happening if ($include == $previous) { throw new Scaffold_Exception("Recursion occurring with CSS @includes in {$include}"); } # If they haven't supplied an extension, we'll assume its a css file if (pathinfo($include, PATHINFO_EXTENSION) == "") { $include .= '.css'; } # Make sure it's a CSS file if (!is_css($include)) { throw new Scaffold_Exception("Included file isn't a CSS file ({$include})"); } # If the url starts with ~, we'll assume it's from the root of the css directory if ($include[0] == "~") { $include = ltrim($include, '~/'); $include = CSScaffold::config('core.path.css') . $include; } if (file_exists($include)) { # Make sure it hasn't already been included if (!in_array($include, self::$loaded)) { self::$loaded[] = $include; $css = str_replace($matches[0][0], file_get_contents($include), $css); } else { $css = str_replace($matches[0][0], '', $css); } # Compress it which removes any commented out @imports CSS::compress($css); # Check the file again for more imports $css = self::server_import($css, $include); } else { throw new Scaffold_Exception("Included CSS file doesn't exist ({$include})"); } } return $css; }
/** * Parse the CSS * * @return string - The processes css file as a string * @author Anthony Short **/ public static function parse_css() { # If the cache is stale or doesn't exist if (self::config('core.cache.mod_time') <= self::config('core.request.mod_time')) { # Start the timer Benchmark::start("parse_css"); # Compress it before parsing CSS::compress(CSS::$css); # Import CSS files Import::parse(); if (self::config('core.auto_include_mixins') === true) { # Import the mixins in the plugin/module folders Mixins::import_mixins('framework/mixins'); } # Parse our css through the plugins foreach (self::$plugins as $plugin) { call_user_func(array($plugin, 'import_process')); } # Compress it before parsing CSS::compress(CSS::$css); # Parse the constants Constants::parse(); foreach (self::$plugins as $plugin) { call_user_func(array($plugin, 'pre_process')); } # Parse the @grid Layout::parse_grid(); # Replace the constants Constants::replace(); # Parse @for loops Iteration::parse(); foreach (self::$plugins as $plugin) { call_user_func(array($plugin, 'process')); } # Compress it before parsing CSS::compress(CSS::$css); # Parse the mixins Mixins::parse(); # Find missing constants Constants::replace(); # Compress it before parsing CSS::compress(CSS::$css); foreach (self::$plugins as $plugin) { call_user_func(array($plugin, 'post_process')); } # Parse the expressions Expression::parse(); # Parse the nested selectors NestedSelectors::parse(); # Convert all url()'s to absolute paths if required if (self::config('core.absolute_urls') === true) { CSS::convert_to_absolute_urls(); } # Replaces url()'s that start with ~ to lead to the CSS directory CSS::replace_css_urls(); # Add the extra string we've been storing CSS::$css .= CSS::$append; # If they want to minify it if (self::config('core.minify_css') === true) { Minify::compress(); } else { CSS::pretty(); } # Formatting hook foreach (self::$plugins as $plugin) { call_user_func(array($plugin, 'formatting_process')); } # Validate the CSS if (self::config('core.validate') === true) { Validate::check(); } # Stop the timer... Benchmark::stop("parse_css"); if (self::config('core.show_header') === TRUE) { CSS::$css = "/* Processed by CSScaffold on " . gmdate('r') . " in " . Benchmark::get("parse_css", "time") . " seconds */\n\n" . CSS::$css; } # Write the css file to the cache self::cache_write(CSS::$css); # Output process hook for plugins to display views. # Doesn't run in production mode. if (!IN_PRODUCTION) { foreach (array_merge(self::$plugins, self::$modules) as $plugin) { call_user_func(array($plugin, 'output')); } } } }