Skip to content
Browse files

Added @ifdefine directive for dynamically including or excluding chun…

…ks of CSS based on existence of variables.
  • Loading branch information...
1 parent 041b1e5 commit 0c96aa87f8a6cbc4bd60ca675ed90af132cf3955 @peteboere committed
Showing with 70 additions and 35 deletions.
  1. +1 −0 CHANGELOG.txt
  2. +58 −24 lib/Core.php
  3. +9 −9 lib/Regex.php
  4. +2 −2 lib/Rule.php
View
1 CHANGELOG.txt
@@ -1,6 +1,7 @@
1.7
---
Added trace option to output SASS compatible debug-info stubs for use with tools like FireSass.
+Added @ifdefine directive for dynamically including/excluding parts of a CSS file based on the existence of variables.
Updated plugin API.
Added options for enabling and disabling plugins at runtime.
Added property sorter plugin.
View
82 lib/Core.php
@@ -563,7 +563,6 @@ public static function addTracingStubs ( &$stream ) {
}
// Get the currently processed file path, and escape it.
- // if ( $current_file = csscrush::$process->currentFile ) {
$current_file = str_replace( ' ', '%20', csscrush::$process->currentFile );
$current_file = preg_replace( '![^\w-]!', '\\\\$0', $current_file );
@@ -854,7 +853,7 @@ protected static function compile ( $stream ) {
$process = self::$process;
$options = $process->options;
- // Load in aliases and macros
+ // Load in aliases and plugins.
if ( ! self::$assetsLoaded ) {
self::loadAssets();
self::$assetsLoaded = true;
@@ -887,28 +886,31 @@ protected static function compile ( $stream ) {
csscrush_plugin::enable( $plugin_name );
}
- // Set aliases
+ // Set aliases.
self::$config->aliases = self::$config->aliasesRaw;
- // Prune if a vendor target is set
+ // Prune if a vendor target is set.
self::pruneAliases();
- // Parse variables
+ // Parse variables.
self::extractVariables( $stream );
- // Calculate the variable stack
+ // Calculate the variable stack.
self::calculateVariables();
- // Place the variables
+ // Apply variables.
self::placeVariables( $stream );
- // Pull out the mixin declarations
+ // Resolve @ifdefine blocks.
+ self::resolveIfDefines( $stream );
+
+ // Pull out @mixin definitions.
self::extractMixins( $stream );
- // Process fragments
+ // Pull out @fragment blocks, and invoke.
self::resolveFragments( $stream );
- // Adjust the stream so we can extract the rules cleanly
+ // Adjust the stream so we can extract the rules cleanly.
$map = array(
'@' => "\n@",
'}' => "}\n",
@@ -917,34 +919,32 @@ protected static function compile ( $stream ) {
);
$stream = "\n" . str_replace( array_keys( $map ), array_values( $map ), $stream );
- // Rules
+ // Parse rules.
self::extractRules( $stream );
- // Process any @-in blocks
+ // Process @in blocks.
self::prefixSelectors( $stream );
- // Main processing on the rule objects
+ // Main processing on the rule objects.
self::processRules();
- // csscrush::log( array_keys( self::$process->selectorRelationships ) );
-
- // Alias any @-rules
+ // Alias any @-rules.
self::aliasAtRules( $stream );
- // Print it all back
+ // Print it all back.
self::display( $stream );
- // Add in boilerplate
+ // Add in boilerplate.
if ( $options->boilerplate ) {
$stream = self::getBoilerplate() . "\n$stream";
}
- // Add @charset at top if set
+ // Add @charset at top if set.
if ( $process->charset ) {
$stream = "@charset $process->charset;\n" . $stream;
}
- // Release memory
+ // Release memory.
self::$storage = null;
$process->mixins = null;
$process->abstracts = null;
@@ -1452,7 +1452,7 @@ public static function extractMixins ( &$stream ) {
public static function resolveFragments ( &$stream ) {
- $matches = csscrush_regex::matchAll( '@fragment\s+(<name>)\s*{', $stream, true );
+ $matches = csscrush_regex::matchAll( '@fragment\s+(<ident>)\s*{', $stream, true );
$fragments = array();
// Move through the matches last to first
@@ -1483,7 +1483,7 @@ public static function resolveFragments ( &$stream ) {
}
// Now find all the fragment calls
- $matches = csscrush_regex::matchAll( '@fragment\s+(<name>)\s*(\(|;)', $stream, true );
+ $matches = csscrush_regex::matchAll( '@fragment\s+(<ident>)\s*(\(|;)', $stream, true );
// Move through the matches last to first
while ( $match = array_pop( $matches ) ) {
@@ -1501,7 +1501,6 @@ public static function resolveFragments ( &$stream ) {
// Fragment may be called without any argument list
$with_arguments = $match[2][0] === '(';
-
if ( $with_arguments ) {
$paren_match = csscrush_util::matchBrackets(
$stream, $brackets = array( '(', ')' ), $match_start_pos, true );
@@ -1523,7 +1522,6 @@ public static function resolveFragments ( &$stream ) {
if ( $with_arguments ) {
// Get the argument array to pass to the fragment
$args = csscrush_util::splitDelimList( $paren_match->inside, ',', true, true );
- // $args = array_map( 'trim', $args->list );
$args = $args->list;
}
@@ -1535,6 +1533,42 @@ public static function resolveFragments ( &$stream ) {
}
}
}
+
+ public static function resolveIfDefines ( &$stream ) {
+
+ $matches = csscrush_regex::matchAll( '@ifdefine\s+(not\s+)?(<ident>)\s*\{', $stream, true );
+
+ // Move through the matches last to first.
+ while ( $match = array_pop( $matches ) ) {
+
+ $full_match = $match[0][0];
+ $full_match_start = $match[0][1];
+ $before = substr( $stream, 0, $full_match_start );
+
+ $negate = $match[1][1] != -1;
+ $name = $match[2][0];
+ $name_defined = isset( self::$storage->variables[ $name ] );
+
+ $curly_match = csscrush_util::matchBrackets(
+ $stream, $brackets = array( '{', '}' ), $full_match_start, true );
+
+ if ( ! $curly_match ) {
+ // Couldn't match the block.
+ $stream = $before . substr( $stream, $full_match_start + strlen( $full_match ) );
+ continue;
+ }
+
+ if ( ! $negate && $name_defined || $negate && ! $name_defined ) {
+ // Test resolved true so include the innards.
+ $stream = $before . $curly_match->inside . $curly_match->after;
+ }
+ else {
+ // Recontruct the stream without the innards.
+ $stream = $before . $curly_match->after;
+ }
+ }
+ }
+
}
View
18 lib/Regex.php
@@ -17,13 +17,13 @@ public static function init () {
self::$patt = $patt = (object) array();
self::$class = $class = (object) array();
- // Character classes
- $class->name = '[a-zA-Z0-9_-]+';
- $class->notName = '[^a-zA-Z0-9_-]+';
+ // Character classes.
+ $class->ident = '[a-zA-Z0-9_-]+';
+ $class->notIdent = '[^a-zA-Z0-9_-]+';
- // Patterns
- $patt->name = '!^' . $class->name . '$!';
- $patt->notName = '!^' . $class->notName . '$!';
+ // Patterns.
+ $patt->ident = '!^' . $class->ident . '$!';
+ $patt->notIdent = '!^' . $class->notIdent . '$!';
$patt->import = '!
@import\s+ # import at-rule
@@ -37,7 +37,7 @@ public static function init () {
$patt->variables = '!@(?:variables|define)\s*([^\{]*)\{\s*(.*?)\s*\};?!s';
$patt->mixin = '!@mixin\s*([^\{]*)\{\s*(.*?)\s*\};?!s';
- $patt->abstract = csscrush_regex::create( '^@abstract\s+(<name>)', 'i' );
+ $patt->abstract = csscrush_regex::create( '^@abstract\s+(<ident>)', 'i' );
$patt->commentAndString = '!
(\'|")(?:\\\\\1|[^\1])*?(?:\1|$) # quoted string (to EOF if unmatched)
|
@@ -86,8 +86,8 @@ public static function create ( $pattern_template, $flags = '' ) {
// Sugar
$pattern = str_replace(
- array( '<name>', '<!name>' ),
- array( self::$class->name, self::$class->notName ),
+ array( '<ident>', '<!ident>' ),
+ array( self::$class->ident, self::$class->notIdent ),
$pattern_template );
return '!' . $pattern . "!$flags";
}
View
4 lib/Rule.php
@@ -263,7 +263,7 @@ public function cssQueryFunction ( $input, $fn_name, $call_property ) {
$default = isset( $args[0] ) ? $args[0] : null;
// Try to match a abstract rule first
- if ( preg_match( csscrush_regex::$patt->name, $name ) ) {
+ if ( preg_match( csscrush_regex::$patt->ident, $name ) ) {
// Search order: abstracts, mixins, rules
if ( isset( $abstracts[ $name ]->data[ $property ] ) ) {
@@ -882,7 +882,7 @@ public function __construct ( $name ) {
$this->name = $name;
- if ( ! preg_match( csscrush_regex::$patt->name, $this->name ) ) {
+ if ( ! preg_match( csscrush_regex::$patt->ident, $this->name ) ) {
// Not a regular name: Some kind of selector so normalize it for later comparison
$this->name = csscrush_selector::makeReadableSelector( $this->name );

0 comments on commit 0c96aa8

Please sign in to comment.
Something went wrong with that request. Please try again.