Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Implemented autoloader for loading all classes (moving towards PSR-0 …

…compliance).

Moved all classes into seperate files with no 'side-effects' for PSR compliance.
Updated casing of all classname references for the autoloader; all
classnaming needs to be StudlyCaps now.
Added options class (with getters and setters) to abstract out some of the fiddly options.
Added new options to the command line utility and a little refactoring.
Added flexbox aliases for to cover all common implementations.
Added formatters option and some default formatters.
Added newlines option to provide consistent output when required.
Selector aliases now accept arguments.
`disable` and `enable` options have been flipped in order of priority so you
can easily disable all then enable just what you need.
  • Loading branch information...
commit 3fd598c6992440114b82038893c0f555508d5790 1 parent 0d92ba3
@peteboere authored
Showing with 2,512 additions and 1,736 deletions.
  1. +116 −48 Aliases.ini
  2. +13 −5 CHANGELOG.txt
  3. +26 −15 CssCrush.php
  4. +81 −63 cli.php
  5. +96 −0 lib/ArgList.php
  6. +68 −0 lib/BalancedMatch.php
  7. +48 −38 lib/Color.php
  8. +137 −55 lib/Core.php
  9. +104 −0 lib/Declaration.php
  10. +32 −0 lib/ExtendArg.php
  11. +36 −0 lib/Fragment.php
  12. +51 −46 lib/Function.php
  13. +8 −7 lib/Hook.php
  14. +59 −57 lib/IO.php
  15. +42 −43 lib/Importer.php
  16. +23 −157 lib/Mixin.php
  17. +91 −0 lib/Options.php
  18. +13 −13 lib/Plugin.php
  19. +116 −0 lib/PostAliasFix.php
  20. +272 −212 lib/Process.php
  21. +19 −19 lib/Regex.php
  22. +186 −470 lib/Rule.php
  23. +64 −0 lib/Selector.php
  24. +120 −0 lib/Stream.php
  25. +129 −0 lib/Url.php
  26. +24 −398 lib/Util.php
  27. +71 −0 lib/Version.php
  28. +5 −5 plugins/hocus-pocus.php
  29. +6 −6 plugins/hsl-to-hex.php
  30. +7 −7 plugins/ie-clip.php
  31. +8 −8 plugins/ie-filter.php
  32. +16 −15 plugins/ie-inline-block.php
  33. +6 −6 plugins/ie-min-height.php
  34. +8 −8 plugins/ie-opacity.php
  35. +11 −11 plugins/initial.php
  36. +376 −0 plugins/legacy-flexbox.php
  37. +6 −6 plugins/property-sorter.php
  38. +6 −6 plugins/rgba-fallback.php
  39. +3 −3 plugins/spiffing.php
  40. +9 −9 plugins/svg-gradients.php
View
164 Aliases.ini
@@ -9,11 +9,11 @@
;
;----------------------------------------------------------------
-; Property aliases
+; Property aliases.
[properties]
- ; Animations
+ ; Animations.
animation[] = -webkit-animation
animation[] = -moz-animation
animation[] = -o-animation
@@ -42,60 +42,43 @@
animation-timing-function[] = -moz-animation-timing-function
animation-timing-function[] = -o-animation-timing-function
- ; Backface visibility
+ ; Backface visibility.
backface-visibility[] = -webkit-backface-visibility
backface-visibility[] = -moz-backface-visibility
backface-visibility[] = -ms-backface-visibility
- ; Background clip
+ ; Background clip.
background-clip[] = -webkit-background-clip
background-clip[] = -moz-background-clip
- ; Background origin
+ ; Background origin.
background-origin[] = -webkit-background-origin
background-origin[] = -moz-background-origin
- ; Background size
+ ; Background size.
background-size[] = -webkit-background-size
background-size[] = -moz-background-size
- ; Border radius
+ ; Border radius.
border-radius[] = -webkit-border-radius
border-top-left-radius[] = -webkit-border-top-left-radius
border-top-right-radius[] = -webkit-border-top-right-radius
border-bottom-left-radius[] = -webkit-border-bottom-left-radius
border-bottom-right-radius[] = -webkit-border-bottom-right-radius
- ; Border-image
+ ; Border-image.
border-image[] = -webkit-border-image
border-image[] = -moz-border-image
border-image[] = -o-border-image
- ; Flexbox (old, but supported implementation)
- box-align[] = -webkit-box-align
- box-align[] = -moz-box-align
- box-align[] = -ms-box-align
- box-direction[] = -webkit-box-direction
- box-direction[] = -moz-box-direction
- box-direction[] = -ms-box-direction
- box-flex[] = -webkit-box-flex
- box-flex[] = -moz-box-flex
- box-flex[] = -ms-box-flex
- box-orient[] = -webkit-box-orient
- box-orient[] = -moz-box-orient
- box-orient[] = -ms-box-orient
- box-pack[] = -webkit-box-pack
- box-pack[] = -moz-box-pack
- box-pack[] = -ms-box-pack
-
- ; Box shadow
+ ; Box shadow.
box-shadow[] = -webkit-box-shadow
- ; Box sizing
+ ; Box sizing.
box-sizing[] = -webkit-box-sizing
box-sizing[] = -moz-box-sizing
- ; Columns
+ ; Columns.
columns[] = -webkit-columns
columns[] = -moz-columns
column-count[] = -webkit-column-count
@@ -119,19 +102,69 @@
column-width[] = -webkit-column-width
column-width[] = -moz-column-width
- ; Hyphens
+ ; Flexbox (2012).
+ ;
+ ; Merges two similar versions of the flexbox spec:
+ ; - September 2012 (for non IE): http://www.w3.org/TR/2012/CR-css3-flexbox-20120918
+ ; - March 2012 (for IE10): http://www.w3.org/TR/2012/WD-css3-flexbox-20120322
+ ;
+ ; The early 2012 spec mostly differs only in syntax to the later one, with the notable
+ ; exception of not supporting seperate properties for <flex-grow>, <flex-shrink>
+ ; and <flex-basis>. These properties are available in both 2012 implementations via
+ ; <flex> shorthand.
+ ;
+ ; Support for the early 2012 syntax implemented in IE10 is achieved here in part with
+ ; property aliases, and in part with property/value aliases later in this file.
+ ;
+ align-content[] = -webkit-align-content
+ align-items[] = -webkit-align-items
+ align-self[] = -webkit-align-self
+ flex[] = -webkit-flex
+ flex[] = -ms-flex
+ flex-basis[] = -webkit-flex-basis
+ flex-direction[] = -webkit-flex-direction
+ flex-direction[] = -ms-flex-direction
+ flex-flow[] = -webkit-flex-flow
+ flex-flow[] = -ms-flex-flow
+ flex-grow[] = -webkit-flex-grow
+ flex-shrink[] = -webkit-flex-shrink
+ flex-wrap[] = -webkit-flex-wrap
+ flex-wrap[] = -ms-flex-wrap
+ justify-content[] = -webkit-justify-content
+ order[] = -webkit-order
+ order[] = -ms-flex-order
+
+ ; Flexbox (2009).
+ box-align[] = -webkit-box-align
+ box-align[] = -moz-box-align
+ box-direction[] = -webkit-box-direction
+ box-direction[] = -moz-box-direction
+ box-flex[] = -webkit-box-flex
+ box-flex[] = -moz-box-flex
+ box-flex-group[] = -webkit-box-flex-group
+ box-flex-group[] = -moz-box-flex-group
+ box-lines[] = -webkit-box-lines
+ box-lines[] = -moz-box-lines
+ box-ordinal-group[] = -webkit-box-ordinal-group
+ box-ordinal-group[] = -moz-box-ordinal-group
+ box-orient[] = -webkit-box-orient
+ box-orient[] = -moz-box-orient
+ box-pack[] = -webkit-box-pack
+ box-pack[] = -moz-box-pack
+
+ ; Hyphens.
hyphens[] = -webkit-hyphens
hyphens[] = -moz-hyphens
hyphens[] = -ms-hyphens
- ; Outline radius
+ ; Outline radius.
outline-radius[] = -moz-outline-radius
outline-top-left-radius[] = -moz-outline-radius-topleft
outline-top-right-radius[] = -moz-outline-radius-topright
outline-bottom-left-radius[] = -moz-outline-radius-bottomleft
outline-bottom-right-radius[] = -moz-outline-radius-bottomright
- ; Perspective
+ ; Perspective.
perspective[] = -webkit-perspective
perspective[] = -moz-perspective
perspective[] = -ms-perspective
@@ -139,23 +172,23 @@
perspective-origin[] = -moz-perspective-origin
perspective-origin[] = -ms-perspective-origin
- ; Tab size
+ ; Tab size.
tab-size[] = -moz-tab-size
tab-size[] = -o-tab-size
- ; Text align last
+ ; Text align last.
text-align-last[] = -webkit-text-align-last
text-align-last[] = -moz-text-align-last
- ; Text decoration
+ ; Text decoration.
text-decoration-color[] = -moz-text-decoration-color
text-decoration-line[] = -moz-text-decoration-line
text-decoration-style[] = -moz-text-decoration-style
- ; Text overflow (Opera mini support)
+ ; Text overflow (Opera mini support).
text-overflow[] = -o-text-overflow
- ; Transforms
+ ; Transforms.
transform[] = -webkit-transform
transform[] = -moz-transform
transform[] = -ms-transform
@@ -168,7 +201,7 @@
transform-style[] = -moz-transform-style
transform-style[] = -ms-transform-style
- ; Transitions
+ ; Transitions.
transition[] = -webkit-transition
transition[] = -moz-transition
transition[] = -o-transition
@@ -185,7 +218,7 @@
transition-timing-function[] = -moz-transition-timing-function
transition-timing-function[] = -o-transition-timing-function
- ; User select (non standard)
+ ; User select (non standard).
user-select[] = -webkit-user-select
user-select[] = -moz-user-select
user-select[] = -ms-user-select
@@ -194,26 +227,61 @@
;----------------------------------------------------------------
-; Property:value aliases
+; Property:value aliases.
[values]
- ; Flexbox TBC.
+ ; Flexbox (2012).
+ display:flex[] = display:-webkit-flex
+ display:flex[] = display:-ms-flexbox
+ display:inline-flex[] = display:-webkit-inline-flex
+ display:inline-flex[] = display:-ms-inline-flexbox
+
+ ; Flexbox (early 2012).
+ align-content:flex-start[] = -ms-flex-line-pack:start
+ align-content:flex-end[] = -ms-flex-line-pack:end
+ align-content:center[] = -ms-flex-line-pack:center
+ align-content:space-between[] = -ms-flex-line-pack:justify
+ align-content:space-around[] = -ms-flex-line-pack:distribute
+ align-content:stretch[] = -ms-flex-line-pack:stretch
+
+ align-items:flex-start[] = -ms-flex-align:start
+ align-items:flex-end[] = -ms-flex-align:end
+ align-items:center[] = -ms-flex-align:center
+ align-items:baseline[] = -ms-flex-align:baseline
+ align-items:stretch[] = -ms-flex-align:stretch
+
+ align-self:auto[] = -ms-flex-item-align:auto
+ align-self:flex-start[] = -ms-flex-item-align:start
+ align-self:flex-end[] = -ms-flex-item-align:end
+ align-self:center[] = -ms-flex-item-align:center
+ align-self:baseline[] = -ms-flex-item-align:baseline
+ align-self:stretch[] = -ms-flex-item-align:stretch
+
+ justify-content:flex-start[] = -ms-flex-pack:start
+ justify-content:flex-end[] = -ms-flex-pack:end
+ justify-content:center[] = -ms-flex-pack:center
+ justify-content:space-between[] = -ms-flex-pack:justify
+ justify-content:space-around[] = -ms-flex-pack:distribute
+
+ ; Flexbox (2009).
+ display:box[] = display:-webkit-box
+ display:box[] = display:-moz-box
;----------------------------------------------------------------
-; Function aliases
+; Function aliases.
[functions]
- ; Calc
+ ; Calc.
calc[] = -webkit-calc
calc[] = -moz-calc
- ; Element
+ ; Element.
element[] = -moz-element
- ; Gradients
+ ; Gradients.
linear-gradient[] = -webkit-linear-gradient
linear-gradient[] = -moz-linear-gradient
linear-gradient[] = -ms-linear-gradient
@@ -223,7 +291,7 @@
radial-gradient[] = -ms-radial-gradient
radial-gradient[] = -o-radial-gradient
- ; Repeating gradients
+ ; Repeating gradients.
repeating-linear-gradient[] = -webkit-repeating-linear-gradient
repeating-linear-gradient[] = -moz-repeating-linear-gradient
repeating-linear-gradient[] = -ms-repeating-linear-gradient
@@ -235,16 +303,16 @@
;----------------------------------------------------------------
-; @rule aliases
+; @rule aliases.
[at-rules]
- ; Keyframes
+ ; Keyframes.
keyframes[] = -webkit-keyframes
keyframes[] = -moz-keyframes
keyframes[] = -o-keyframes
- ; Viewport
+ ; Viewport.
viewport[] = -webkit-viewport
viewport[] = -moz-viewport
viewport[] = -ms-viewport
View
18 CHANGELOG.txt
@@ -1,9 +1,17 @@
1.9
---
-Added functions API for defining custom functions inside plugins.
+Added flexbox aliases for both 2009 and 2012 edition specs.
+Added a legacy-flexbox plugin for auto-generating the flexbox 2009 spec equivilant properties.
+Updated selector aliases to take arguments at runtime.
Updated plugin API to use distinct 'enable' and 'disable' handlers.
+The disable option is now resolved before the enable option so you can easily disable all plugins
+and then specify the plugins you want to apply.
+Added functions API for defining custom functions inside plugins.
Improved gradient function aliasing to handle new angle keywords ('to left', 'at center' etc.).
Added svg-gradients plugin for simulating CSS3 gradients with data-uris.
+Added formatting option so custom formatters can be defined for un-minified output (see wiki for options).
+Added newlines option to force the style of newlines in output (see wiki for options).
+Updated command line utility to employ the new options.
1.8
@@ -16,7 +24,7 @@ Debug option renamed to 'minify'; debug option will still work as before but is
New minify option optionally takes an array of advanced minification parameters.
Expanded trace option to take an optional array of log parameters;
log params available are stubs, selector_count, errors and compile_time.
-Added csscrush::stat method to retrieve logged parameters.
+Added CssCrush::stat method to retrieve logged parameters.
Improved cross OS support.
Improved minification.
Major refactoring.
@@ -31,7 +39,7 @@ Added options for enabling and disabling plugins at runtime.
Added property sorter plugin.
Added support for SASS-like @include/@extend syntax for invoking mixins and extends.
Boilerplate option now accepts a filename string as a boilerplate template.
-csscrush::string method now uses document_root as a default context for finding linked resources.
+CssCrush::string method now uses document_root as a default context for finding linked resources.
Updated command line appication.
Updated aliases and initial value files.
Fixed parsing issue introduced in 1.6.1.
@@ -65,7 +73,7 @@ Fixed some test cases.
1.5.2
-----
Resolved issue #32.
-csscrush::inline method now defaults to not printing a boilerplate.
+CssCrush::inline method now defaults to not printing a boilerplate.
Updated aliases file.
@@ -108,7 +116,7 @@ Added Prepend.css - Optionally prepend css to every input.
Fix for issue #21.
Reorganized aliases file with some additions.
Initial-values updated.
-Updated csscrush::string method to correctly handle import statements.
+Updated CssCrush::string method to correctly handle import statements.
1.4
View
41 CssCrush.php
@@ -2,25 +2,36 @@
/**
*
* CSS Crush
- * Extensible CSS preprocessor
+ * Extensible CSS preprocessor.
*
* @version 1.9
* @link https://github.com/peteboere/css-crush
* @license http://www.opensource.org/licenses/mit-license.php (MIT)
- * @copyright (c) 2010-2012 Pete Boere
+ * @copyright (c) 2010-2013 Pete Boere
*/
-require_once 'lib/Util.php';
-require_once 'lib/IO.php';
-require_once 'lib/Core.php';
-require_once 'lib/Process.php';
-require_once 'lib/Rule.php';
-require_once 'lib/Mixin.php';
-require_once 'lib/Function.php';
-require_once 'lib/Importer.php';
-require_once 'lib/Color.php';
-require_once 'lib/Regex.php';
-require_once 'lib/Hook.php';
-require_once 'lib/Plugin.php';
+function csscrush_autoload ( $class ) {
-csscrush::init( __FILE__ );
+ // Only autoload classes with the library prefix.
+ if ( stripos( $class, 'csscrush' ) !== 0 ) {
+ return;
+ }
+ $class = ltrim( substr( $class, 8 ), '_' );
+
+ if ( empty( $class ) ) {
+ $subpath = 'Core';
+ }
+ // Tolerate some cases of lowercasing from external use.
+ elseif ( strpos( $class, '_' ) !== false ) {
+ $subpath = implode( '/', array_map( 'ucfirst', explode( '_', $class ) ) );
+ }
+ else {
+ $subpath = ucfirst( $class );
+ }
+
+ require dirname( __FILE__ ) . "/lib/$subpath.php";
+}
+
+spl_autoload_register( 'csscrush_autoload' );
+
+CssCrush::init( __FILE__ );
View
144 cli.php
@@ -2,23 +2,18 @@
<?php
/**
*
- * Command line application
+ * Command line utility.
*
*/
require_once 'CssCrush.php';
-// Exit status constants
+// Exit status constants.
define( 'STATUS_OK', 0 );
define( 'STATUS_ERROR', 1 );
-// Open stream handles
-$stdin = fopen( 'php://stdin', 'r' );
-$stdout = fopen( 'php://stdout', 'w' );
-$stderr = fopen( 'php://stderr', 'w' );
-
-// Get stdin contents
+// Get stdin content.
+$stdin = fopen( 'php://stdin', 'r' );
if ( ! stream_set_blocking( $stdin, false ) ) {
-
stderr( 'Failed to disable stdin blocking' );
exit( STATUS_ERROR );
}
@@ -27,25 +22,21 @@
##################################################################
-## Helpers
+## Helpers.
function stderr ( $lines, $closing_newline = true ) {
- global $stderr;
- fwrite( $stderr,
- implode( PHP_EOL, (array) $lines ) . ( $closing_newline ? PHP_EOL : '' )
- );
+ $out = implode( PHP_EOL, (array) $lines ) . ( $closing_newline ? PHP_EOL : '' );
+ fwrite( STDERR, $out );
}
function stdout ( $lines, $closing_newline = true ) {
- global $stdout;
- fwrite( $stdout,
- implode( PHP_EOL, (array) $lines ) . ( $closing_newline ? PHP_EOL : '' )
- );
+ $out = implode( PHP_EOL, (array) $lines ) . ( $closing_newline ? PHP_EOL : '' );
+ fwrite( STDOUT, $out );
}
##################################################################
-## Version detection
+## Version detection.
$version = PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION;
$required_version = 5.3;
@@ -64,26 +55,28 @@ function stdout ( $lines, $closing_newline = true ) {
## Options
$short_opts = array(
- "f:", // Input file. Defaults to sdtin
- "o:", // Output file. Defaults to stdout
- "p", // Pretty formatting
- 'b', // Output boilerplate
- 'h', // Display help
+ "f:", // Input file. Defaults to sdtin.
+ "o:", // Output file. Defaults to stdout.
+ "p", // Pretty formatting.
+ 'b', // Output boilerplate.
+ 'h', // Display help.
);
$long_opts = array(
- 'file:', // Input file. Defaults to sdtin
- 'output:', // Output file. Defaults to stdout
- 'pretty', // Pretty formatting
- 'boilerplate', // Output boilerplate
- 'help', // Display help
- 'version', // Display version
- 'trace', // Output sass tracing stubs
- 'vendor-target:', // Vendor target
- 'variables:', // Map of variable names in an http query string format
- 'enable:', // List of plugins to enable
- 'disable:', // List of plugins to disable
- 'context:', // Context for resolving URLs
+ 'file:', // Input file. Defaults to sdtin.
+ 'output:', // Output file. Defaults to stdout.
+ 'pretty', // Pretty formatting.
+ 'boilerplate', // Output boilerplate.
+ 'help', // Display help.
+ 'version', // Display version.
+ 'trace', // Output sass tracing stubs.
+ 'formatter:', // Formatter name for formatted output.
+ 'vendor-target:', // Vendor target.
+ 'variables:', // Map of variable names in an http query string format.
+ 'enable:', // List of plugins to enable.
+ 'disable:', // List of plugins to disable.
+ 'context:', // Context for resolving URLs.
+ 'newlines:', // Newline style.
);
$opts = getopt( implode( $short_opts ), $long_opts );
@@ -95,15 +88,17 @@ function stdout ( $lines, $closing_newline = true ) {
$help_flag = @( isset( $opts['h'] ) ?: isset( $opts['help'] ) );
$version_flag = @isset( $opts['version'] );
$trace_flag = @isset( $opts['trace'] );
+$formatter = @$opts['formatter'];
$vendor_target = @$opts['vendor-target'];
$variables = @$opts['variables'];
+$newlines = @$opts['newlines'];
$enable_plugins = isset( $opts['enable'] ) ? (array) $opts['enable'] : null;
$disable_plugins = isset( $opts['disable'] ) ? (array) $opts['disable'] : null;
$context = isset( $opts['context'] ) ? (array) $opts['context'] : null;
##################################################################
-## Help page
+## Help page.
$command = 'csscrush';
@@ -111,46 +106,62 @@ function stdout ( $lines, $closing_newline = true ) {
Usage:
csscrush [-f|--file] [-o|--output-file] [-p|--pretty] [-b|--boilerplate]
- [-h|--help] [--variables] [--vendor-target] [--version]
+ [-h|--help] [--formatter] [--variables] [--vendor-target]
+ [--version] [--newlines]
Options:
-f, --file:
- The input file, if omitted takes input from stdin
+ The input file, if omitted takes input from stdin.
-o, --output:
- The output file, if omitted prints to stdout
+ The output file, if omitted prints to stdout.
-p, --pretty:
- Formatted, unminified output
+ Formatted, unminified output.
-b, --boilerplate:
- Whether or not to output a boilerplate
+ Whether or not to output a boilerplate.
-h, --help:
- Display this help mesasge
+ Display this help mesasge.
- --enable:
- List of plugins to enable
+ --context:
+ Filepath context for resolving URLs.
--disable:
- List of plugins to disable
+ List of plugins to disable. Pass 'all' to disable all.
- --context:
- Filepath context for resolving URLs
+ --enable:
+ List of plugins to enable. Overrides --disable.
+
+ --formatter:
+ Formatter to use for formatted (--pretty) output.
+ Available formatters:
+
+ 'block' (default) -
+ Rules are block formatted.
+ 'single-line' -
+ Rules are printed in single lines.
+ 'padded' -
+ Rules are printed in single lines with right padded selectors.
+
+ --newlines:
+ Force newline style on output css. Defaults to the current platform
+ newline. Possible values: 'windows' (or 'win'), 'unix', 'use-platform'.
--trace:
- Output debug-info stubs compatible with sass development tools
+ Output debug-info stubs compatible with client-side sass debuggers.
--variables:
- Map of variable names in an http query string format
+ Map of variable names in an http query string format.
--vendor-target:
- Set to 'all' for all vendor prefixes (default)
- Set to 'none' for no vendor prefixes
- Set to a specific vendor prefix
+ Set to 'all' for all vendor prefixes (default).
+ Set to 'none' for no vendor prefixes.
+ Set to a specific vendor prefix.
--version:
- Version number
+ Print version number.
Examples:
$command -f styles.css --pretty --vendor-target webkit
@@ -167,7 +178,7 @@ function stdout ( $lines, $closing_newline = true ) {
if ( $version_flag ) {
- stdout( 'CSS Crush ' . csscrush::$config->version );
+ stdout( 'CSS Crush ' . CssCrush::$config->version );
exit( STATUS_OK );
}
@@ -179,7 +190,7 @@ function stdout ( $lines, $closing_newline = true ) {
##################################################################
-## Input
+## Input.
$input = null;
@@ -197,21 +208,27 @@ function stdout ( $lines, $closing_newline = true ) {
}
else {
- // No input, just output help screen
+ // No input, just output help screen.
stdout( $help );
exit( STATUS_OK );
}
##################################################################
-## Processing
+## Processing.
$process_opts = array();
$process_opts[ 'boilerplate' ] = $boilerplate ? true : false;
$process_opts[ 'minify' ] = $pretty ? false : true;
+$process_opts[ 'formatter' ] = $formatter ?: null;
$process_opts[ 'rewrite_import_urls' ] = true;
-// Enable plugin args
+// Newlines.
+if ( isset( $newlines ) ) {
+ $process_opts[ 'newlines' ] = $newlines;
+}
+
+// Enable plugin args.
if ( $enable_plugins ) {
foreach ( $enable_plugins as $arg ) {
foreach ( preg_split( '!\s*,\s*!', $arg ) as $plugin ) {
@@ -255,11 +272,12 @@ function stdout ( $lines, $closing_newline = true ) {
$process_opts[ 'doc_root' ] = $context;
$process_opts[ 'context' ] = $context;
}
-$output = csscrush::string( $input, $process_opts );
+
+$output = CssCrush::string( $input, $process_opts );
##################################################################
-## Output
+## Output.
if ( $output_file ) {
@@ -277,8 +295,8 @@ function stdout ( $lines, $closing_newline = true ) {
}
else {
- if ( csscrush::$process->errors ) {
- stderr( csscrush::$process->errors );
+ if ( CssCrush::$process->errors ) {
+ stderr( CssCrush::$process->errors );
}
stdout( $output );
View
96 lib/ArgList.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ *
+ * Argument list management for mixins and fragments.
+ *
+ */
+class CssCrush_ArgList implements Countable
+{
+ // Positional argument default values.
+ public $defaults = array();
+
+ // The number of expected arguments.
+ public $argCount = 0;
+
+ // The string passed in with arg calls replaced by tokens.
+ public $string;
+
+ public function __construct ( $str )
+ {
+ // Parse all arg function calls in the passed string, callback creates default values
+ CssCrush_Function::executeCustomFunctions( $str,
+ CssCrush_Regex::$patt->argFunction, array(
+ 'arg' => array( $this, 'store' )
+ ));
+ $this->string = $str;
+ }
+
+ public function store ( $raw_argument )
+ {
+ $args = CssCrush_Function::parseArgsSimple( $raw_argument );
+
+ // Match the argument index integer
+ if ( ! ctype_digit( $args[0] ) ) {
+
+ // On failure to match an integer, return an empty string
+ return '';
+ }
+
+ // Get the match from the array
+ $position_match = $args[0];
+
+ // Store the default value
+ $default_value = isset( $args[1] ) ? $args[1] : null;
+
+ if ( ! is_null( $default_value ) ) {
+ $this->defaults[ $position_match ] = trim( $default_value );
+ }
+
+ // Update the mixin argument count
+ $argNumber = ( (int) $position_match ) + 1;
+ $this->argCount = max( $this->argCount, $argNumber );
+
+ // Return the argument token
+ return "?arg$position_match?";
+ }
+
+ public function getArgValue ( $index, &$args )
+ {
+ // First lookup a passed value
+ if ( isset( $args[ $index ] ) && $args[ $index ] !== 'default' ) {
+ return $args[ $index ];
+ }
+
+ // Get a default value
+ $default = isset( $this->defaults[ $index ] ) ? $this->defaults[ $index ] : '';
+
+ // Recurse for nested arg() calls
+ if ( preg_match( CssCrush_Regex::$patt->aToken, $default, $m ) ) {
+
+ $default = $this->getArgValue( (int) $m[1], $args );
+ }
+ return $default;
+ }
+
+ public function getSubstitutions ( $args )
+ {
+ $argIndexes = range( 0, $this->argCount-1 );
+
+ // Create table of substitutions
+ $find = array();
+ $replace = array();
+
+ foreach ( $argIndexes as $index ) {
+
+ $find[] = "?arg$index?";
+ $replace[] = $this->getArgValue( $index, $args );
+ }
+
+ return array( $find, $replace );
+ }
+
+ public function count ()
+ {
+ return $this->argCount;
+ }
+}
View
68 lib/BalancedMatch.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ *
+ * Balanced bracket matching on the main stream.
+ *
+ */
+class CssCrush_BalancedMatch
+{
+ public function __construct ( CssCrush_Stream $stream, $offset, $brackets = '{}' )
+ {
+ $this->stream = $stream;
+ $this->offset = $offset;
+ $this->match = null;
+ $this->length = 0;
+
+ list( $opener, $closer ) = str_split( $brackets, 1 );
+
+ if ( strpos( $stream->raw, $opener, $this->offset ) === false ) {
+ return;
+ }
+
+ if ( substr_count( $stream->raw, $opener ) !== substr_count( $stream->raw, $closer ) ) {
+ $sample = substr( $stream->raw, $this->offset, 25 );
+ trigger_error( __METHOD__ . ": Unmatched token near '$sample'.\n", E_USER_WARNING );
+ return;
+ }
+
+ $patt = $opener === '{' ?
+ CssCrush_Regex::$patt->balancedCurlies : CssCrush_Regex::$patt->balancedParens;
+
+ if ( preg_match( $patt, $stream->raw, $m, PREG_OFFSET_CAPTURE, $this->offset ) ) {
+
+ $this->match = $m;
+ $this->matchLength = strlen( $m[0][0] );
+ $this->matchStart = $m[0][1];
+ $this->matchEnd = $this->matchStart + $this->matchLength;
+ $this->length = $this->matchEnd - $this->offset;
+ }
+ else {
+ trigger_error( __METHOD__ . ": Could not match '$opener'. Exiting.\n", E_USER_WARNING );
+ }
+ }
+
+ public function inside ()
+ {
+ return $this->match[1][0];
+ }
+
+ public function whole ()
+ {
+ return substr( $this->stream->raw, $this->offset, $this->length );
+ }
+
+ public function replace ( $replacement )
+ {
+ $this->stream->splice( $replacement, $this->offset, $this->length );
+ }
+
+ public function unWrap ()
+ {
+ $this->stream->splice( $this->inside(), $this->offset, $this->length );
+ }
+
+ public function nextIndexOf ( $needle )
+ {
+ return strpos( $this->stream->raw, $needle, $this->offset );
+ }
+}
View
86 lib/Color.php
@@ -4,18 +4,18 @@
* Colour parsing and conversion.
*
*/
-class csscrush_color {
-
+class CssCrush_Color
+{
// Cached color keyword tables.
static public $keywords;
static public $minifyableKeywords;
- static public function &loadKeywords () {
-
+ static public function &loadKeywords ()
+ {
if ( is_null( self::$keywords ) ) {
$table = array();
- $path = csscrush::$config->location . '/misc/color-keywords.ini';
+ $path = CssCrush::$config->location . '/misc/color-keywords.ini';
if ( $keywords = parse_ini_file( $path ) ) {
foreach ( $keywords as $word => $rgb ) {
$rgb = array_map( 'intval', explode( ',', $rgb ) );
@@ -26,14 +26,14 @@ static public function &loadKeywords () {
return self::$keywords;
}
- static public function &loadMinifyableKeywords () {
-
+ static public function &loadMinifyableKeywords ()
+ {
if ( is_null( self::$minifyableKeywords ) ) {
// If color name is longer than 4 and less than 8 test to see if its hex
// representation could be shortened.
$table = array();
- $keywords =& csscrush_color::loadKeywords();
+ $keywords =& CssCrush_Color::loadKeywords();
foreach ( $keywords as $name => &$rgb ) {
$name_len = strlen( $name );
@@ -47,7 +47,7 @@ static public function &loadMinifyableKeywords () {
self::$minifyableKeywords[ $name ] = $hex;
}
else {
- if ( preg_match( csscrush_regex::$patt->cruftyHex, $hex ) ) {
+ if ( preg_match( CssCrush_Regex::$patt->cruftyHex, $hex ) ) {
self::$minifyableKeywords[ $name ] = $hex;
}
}
@@ -56,8 +56,8 @@ static public function &loadMinifyableKeywords () {
return self::$minifyableKeywords;
}
- static public function parse ( $color ) {
-
+ static public function parse ( $color )
+ {
$rgba = null;
$color = strtolower( $color );
@@ -73,7 +73,7 @@ static public function parse ( $color ) {
switch ( $m[1] ) {
case '#':
- $rgba = csscrush_color::hexToRgb( $color );
+ $rgba = CssCrush_Color::hexToRgb( $color );
break;
case 'rgb':
@@ -89,10 +89,10 @@ static public function parse ( $color ) {
$vals[3] = isset( $vals[3] ) ? floatval( $vals[3] ) : 1;
if ( strpos( $function, 'rgb' ) === 0 ) {
- $rgba = csscrush_color::normalizeCssRgb( $vals );
+ $rgba = CssCrush_Color::normalizeCssRgb( $vals );
}
else {
- $rgba = csscrush_color::cssHslToRgb( $vals );
+ $rgba = CssCrush_Color::cssHslToRgb( $vals );
}
break;
}
@@ -121,8 +121,8 @@ static public function parse ( $color ) {
* Assumes r, g, and b are contained in the set [0, 255] and
* returns h, s, and l in the set [0, 1].
*/
- static public function rgbToHsl ( array $rgba ) {
-
+ static public function rgbToHsl ( array $rgba )
+ {
list( $r, $g, $b, $a ) = $rgba;
$r /= 255;
$g /= 255;
@@ -165,7 +165,8 @@ static public function rgbToHsl ( array $rgba ) {
* Assumes h, s, and l are contained in the set [0, 1] and
* returns r, g, and b in the set [0, 255].
*/
- static public function hslToRgb ( array $hsla ) {
+ static public function hslToRgb ( array $hsla )
+ {
// Populate unspecified alpha value.
if ( ! isset( $hsla[3] ) ) {
@@ -190,7 +191,8 @@ static public function hslToRgb ( array $hsla ) {
}
// Convert percentages to points (0-255).
- static public function normalizeCssRgb ( array $rgba ) {
+ static public function normalizeCssRgb ( array $rgba )
+ {
foreach ( $rgba as &$val ) {
if ( strpos( $val, '%' ) !== false ) {
$val = str_replace( '%', '', $val );
@@ -200,8 +202,8 @@ static public function normalizeCssRgb ( array $rgba ) {
return $rgba;
}
- static public function cssHslToRgb ( array $hsla ) {
-
+ static public function cssHslToRgb ( array $hsla )
+ {
// Populate unspecified alpha value.
if ( ! isset( $hsla[3] ) ) {
$hsla[3] = 1;
@@ -228,8 +230,8 @@ static public function cssHslToRgb ( array $hsla ) {
return self::hslToRgb( array( $h, $s, $l, $a ) );
}
- static public function hueToRgb ( $p, $q, $t ) {
-
+ static public function hueToRgb ( $p, $q, $t )
+ {
if ( $t < 0 ) $t += 1;
if ( $t > 1 ) $t -= 1;
if ( $t < 1/6 ) return $p + ( $q - $p ) * 6 * $t;
@@ -238,8 +240,8 @@ static public function hueToRgb ( $p, $q, $t ) {
return $p;
}
- static public function rgbToHex ( array $rgba ) {
-
+ static public function rgbToHex ( array $rgba )
+ {
// Drop alpha component.
array_pop( $rgba );
@@ -250,8 +252,8 @@ static public function rgbToHex ( array $rgba ) {
return $hex_out;
}
- static public function hexToRgb ( $hex ) {
-
+ static public function hexToRgb ( $hex )
+ {
$hex = substr( $hex, 1 );
// Handle shortened format.
@@ -280,7 +282,8 @@ static public function hexToRgb ( $hex ) {
protected $hslColorSpace;
public $isValid;
- public function __construct ( $color, $use_hsl_color_space = false ) {
+ public function __construct ( $color, $use_hsl_color_space = false )
+ {
$this->value = is_array( $color ) ? $color : self::parse( $color );
$this->isValid = isset( $this->value );
if ( $use_hsl_color_space && $this->isValid ) {
@@ -288,7 +291,8 @@ public function __construct ( $color, $use_hsl_color_space = false ) {
}
}
- public function __toString () {
+ public function __toString ()
+ {
if ( $this->value[3] !== 1 ) {
return 'rgba(' . implode( ',', $this->hslColorSpace ? $this->getRgb() : $this->value ) . ')';
}
@@ -297,7 +301,8 @@ public function __toString () {
}
}
- public function toRgb () {
+ public function toRgb ()
+ {
if ( $this->hslColorSpace ) {
$this->hslColorSpace = false;
$this->value = self::hslToRgb( $this->value );
@@ -305,7 +310,8 @@ public function toRgb () {
return $this;
}
- public function toHsl () {
+ public function toHsl ()
+ {
if ( ! $this->hslColorSpace ) {
$this->hslColorSpace = true;
$this->value = self::rgbToHsl( $this->value );
@@ -313,32 +319,36 @@ public function toHsl () {
return $this;
}
- public function getHex () {
+ public function getHex ()
+ {
return self::rgbToHex( $this->getRgb() );
}
- public function getHsl () {
+ public function getHsl ()
+ {
return ! $this->hslColorSpace ? self::rgbToHsl( $this->value ) : $this->value;
}
- public function getRgb () {
+ public function getRgb ()
+ {
return $this->hslColorSpace ? self::hslToRgb( $this->value ) : $this->value;
}
- public function getComponent ( $index ) {
+ public function getComponent ( $index )
+ {
return $this->value[ $index ];
}
- public function setComponent ( $index, $new_component_value ) {
+ public function setComponent ( $index, $new_component_value )
+ {
$this->value[ $index ] = $new_component_value;
}
- public function adjust ( array $adjustments ) {
-
+ public function adjust ( array $adjustments )
+ {
$was_hsl_color_space = $this->hslColorSpace;
$this->toHsl();
-
// Normalize percentage adjustment parameters to floating point numbers.
foreach ( $adjustments as $index => $val ) {
View
192 lib/Core.php
@@ -4,8 +4,8 @@
* Main script. Includes core public API.
*
*/
-class csscrush {
-
+class CssCrush
+{
// Global settings.
static public $config;
@@ -13,8 +13,8 @@ class csscrush {
static public $process;
// Init called once manually post class definition.
- static public function init ( $seed_file ) {
-
+ static public function init ( $seed_file )
+ {
self::$config = new stdclass();
// Path to this installation.
@@ -22,27 +22,30 @@ static public function init ( $seed_file ) {
// Get version ID from seed file.
$seed_file_contents = file_get_contents( $seed_file );
- $match_count = preg_match( '!@version\s+([\d\.\w-]+)!', $seed_file_contents, $version_match );
- self::$config->version = $match_count ? new csscrush_version( $version_match[1] ) : null;
+ $match_count = preg_match( '~@version\s+([\d\.\w-]+)~', $seed_file_contents, $version_match );
+ self::$config->version = $match_count ? new CssCrush_Version( $version_match[1] ) : null;
// Set the docRoot reference.
self::setDocRoot();
// Set the default IO handler.
- self::$config->io = 'csscrush_io';
+ self::$config->io = 'CssCrush_IO';
- // Global storage.
+ // Shared resources.
self::$config->vars = array();
self::$config->aliases = array();
self::$config->selectorAliases = array();
self::$config->plugins = array();
// Default options.
- self::$config->options = (object) array(
+ self::$config->options = new CssCrush_Options( array(
// Minify. Set false for formatting and comments.
'minify' => true,
+ // Alternative formatter to use for un-minified output.
+ 'formatter' => null,
+
// Append 'checksum' to output file name.
'versioning' => true,
@@ -79,14 +82,27 @@ static public function init ( $seed_file ) {
// Debugging options.
// Set true to output sass debug-info stubs that work with development tools like FireSass.
'trace' => array(),
+
+ // Force newline type on output files. Defaults to the current platform newline.
+ // Options: 'windows' (or 'win'), 'unix', 'use-platform'
+ 'newlines' => 'use-platform',
+ ));
+
+ // Register default formatters.
+ self::$config->formatters = array(
+ 'single-line' => 'csscrush__fmtr_single',
+ 'padded' => 'csscrush__fmtr_padded',
+ 'nested' => 'csscrush__fmtr_nested',
);
// Initialise other classes.
- csscrush_regex::init();
+ CssCrush_Regex::init();
+ CssCrush_Function::init();
+ CssCrush_PostAliasFix::init();
}
- static protected function setDocRoot ( $doc_root = null ) {
-
+ static protected function setDocRoot ( $doc_root = null )
+ {
// Get document_root reference
// $_SERVER['DOCUMENT_ROOT'] is unreliable in certain CGI/Apache/IIS setups
@@ -120,17 +136,17 @@ static protected function setDocRoot ( $doc_root = null ) {
// If doc_root is still falsy, log an error
$error = "Could not get a document_root reference.";
- csscrush::logError( $error );
+ CssCrush::logError( $error );
trigger_error( __METHOD__ . ": $error\n", E_USER_NOTICE );
}
}
- self::$config->docRoot = csscrush_util::normalizePath( $doc_root );
+ self::$config->docRoot = CssCrush_Util::normalizePath( $doc_root );
}
// Aliases and macros loader.
- static public function loadAssets () {
-
+ static public function loadAssets ()
+ {
static $called;
if ( $called ) {
return;
@@ -138,7 +154,7 @@ static public function loadAssets () {
// Find an aliases file in the root directory
// a local file overrides the default
- $aliases_file = csscrush_util::find( 'Aliases-local.ini', 'Aliases.ini' );
+ $aliases_file = CssCrush_Util::find( 'Aliases-local.ini', 'Aliases.ini' );
// Load aliases file if it exists
if ( $aliases_file ) {
@@ -147,23 +163,27 @@ static public function loadAssets () {
self::$config->aliases = $result;
- // Value aliases require a little preprocessing
+ // Value aliases require a little preprocessing.
if ( isset( self::$config->aliases[ 'values' ] ) ) {
$store = array();
foreach ( self::$config->aliases[ 'values' ] as $prop_val => $aliases ) {
list( $prop, $value ) = array_map( 'trim', explode( ':', $prop_val ) );
+ foreach ( $aliases as &$alias ) {
+ $alias = explode( ':', $alias );
+ }
$store[ $prop ][ $value ] = $aliases;
}
self::$config->aliases[ 'values' ] = $store;
}
// Ensure all alias groups are at least set (issue #34)
- self::$config->aliases += array(
+ self::$config->bareAliasGroups = array(
'properties' => array(),
'functions' => array(),
'values' => array(),
'at-rules' => array(),
);
+ self::$config->aliases += self::$config->bareAliasGroups;
}
else {
trigger_error( __METHOD__ . ": Aliases file could not be parsed.\n", E_USER_NOTICE );
@@ -175,7 +195,7 @@ static public function loadAssets () {
// Find a plugins file in the root directory,
// a local file overrides the default
- $plugins_file = csscrush_util::find( 'Plugins-local.ini', 'Plugins.ini' );
+ $plugins_file = CssCrush_Util::find( 'Plugins-local.ini', 'Plugins.ini' );
// Load plugins
if ( $plugins_file ) {
@@ -183,7 +203,7 @@ static public function loadAssets () {
foreach ( $result[ 'plugins' ] as $plugin_name ) {
// Backwards compat.
$plugin_name = basename( $plugin_name, '.php' );
- if ( csscrush_plugin::load( $plugin_name ) ) {
+ if ( CssCrush_Plugin::load( $plugin_name ) ) {
self::$config->plugins[ $plugin_name ] = true;
}
}
@@ -207,9 +227,9 @@ static public function loadAssets () {
* @param mixed $options An array of options or null.
* @return string The public path to the compiled file or an empty string.
*/
- static public function file ( $file, $options = null ) {
-
- self::$process = new csscrush_process( $options );
+ static public function file ( $file, $options = null )
+ {
+ self::$process = new CssCrush_Process( $options );
$config = self::$config;
$process = self::$process;
@@ -240,7 +260,7 @@ static public function file ( $file, $options = null ) {
}
// Validate file input.
- if ( ! csscrush_io::registerInputFile( $file ) ) {
+ if ( ! CssCrush_IO::registerInputFile( $file ) ) {
return '';
}
@@ -283,8 +303,8 @@ static public function file ( $file, $options = null ) {
* @param array $attributes An array of HTML attributes.
* @return string HTML link tag or error message inside HTML comment.
*/
- static public function tag ( $file, $options = null, $attributes = array() ) {
-
+ static public function tag ( $file, $options = null, $attributes = array() )
+ {
$file = self::file( $file, $options );
if ( ! empty( $file ) ) {
@@ -297,7 +317,7 @@ static public function tag ( $file, $options = null, $attributes = array() ) {
if ( ! isset( $attributes[ 'media' ] ) ) {
$attributes[ 'media' ] = 'all';
}
- $attr_string = csscrush_util::htmlAttributes( $attributes );
+ $attr_string = CssCrush_Util::htmlAttributes( $attributes );
return "<link$attr_string />\n";
}
else {
@@ -317,8 +337,8 @@ static public function tag ( $file, $options = null, $attributes = array() ) {
* @param array $attributes An array of HTML attributes, set false to return CSS text without tag.
* @return string HTML link tag or error message inside HTML comment.
*/
- static public function inline ( $file, $options = null, $attributes = array() ) {
-
+ static public function inline ( $file, $options = null, $attributes = array() )
+ {
// For inline output set boilerplate to not display by default
if ( ! is_array( $options ) ) {
$options = array();
@@ -338,7 +358,7 @@ static public function inline ( $file, $options = null, $attributes = array() )
$tag_close = '';
if ( is_array( $attributes ) ) {
- $attr_string = csscrush_util::htmlAttributes( $attributes );
+ $attr_string = CssCrush_Util::htmlAttributes( $attributes );
$tag_open = "<style$attr_string>";
$tag_close = '</style>';
}
@@ -360,14 +380,14 @@ static public function inline ( $file, $options = null, $attributes = array() )
* @param mixed $options An array of options or null.
* @return string CSS text.
*/
- static public function string ( $string, $options = null ) {
-
+ static public function string ( $string, $options = null )
+ {
// For strings set boilerplate to not display by default
if ( ! isset( $options[ 'boilerplate' ] ) ) {
$options[ 'boilerplate' ] = false;
}
- self::$process = new csscrush_process( $options );
+ self::$process = new CssCrush_Process( $options );
$config = self::$config;
$process = self::$process;
@@ -385,7 +405,7 @@ static public function string ( $string, $options = null ) {
// Set the string on the input object.
$process->input->string = $string;
- // Import files may be ignored
+ // Import files may be ignored.
if ( isset( $options->no_import ) ) {
$process->input->importIgnore = true;
}
@@ -399,8 +419,8 @@ static public function string ( $string, $options = null ) {
*
* @param mixed $var Assoc array of variable names and values, a php ini filename or null.
*/
- static public function globalVars ( $vars ) {
-
+ static public function globalVars ( $vars )
+ {
$config = self::$config;
// Merge into the stack, overrides existing variables of the same name
@@ -424,7 +444,8 @@ static public function globalVars ( $vars ) {
*
* @param string $dir System path to the directory.
*/
- static public function clearCache ( $dir = '' ) {
+ static public function clearCache ( $dir = '' )
+ {
return $process->ioCall( 'clearCache', $dir );
}
@@ -434,9 +455,9 @@ static public function clearCache ( $dir = '' ) {
*
* @param string $name Name of stat to retrieve. Leave blank to retrieve all.
*/
- static public function stat ( $name = null ) {
-
- $process = csscrush::$process;
+ static public function stat ( $name = null )
+ {
+ $process = CssCrush::$process;
$stat = $process->stat;
// Get logged errors as late as possible.
@@ -460,8 +481,8 @@ static public function stat ( $name = null ) {
static public $logging = false;
- static public function log ( $arg = null, $label = '' ) {
-
+ static public function log ( $arg = null, $label = '' )
+ {
if ( ! self::$logging ) {
return;
}
@@ -490,16 +511,18 @@ static public function log ( $arg = null, $label = '' ) {
}
}
- static public function logError ( $msg ) {
+ static public function logError ( $msg )
+ {
self::$process->errors[] = $msg;
self::log( $msg );
}
- static public function runStat ( $name ) {
-
- $process = csscrush::$process;
+ static public function runStat ( $name )
+ {
+ $process = CssCrush::$process;
+ $trace = $process->options->trace;
- if ( ! $process->options->trace || ! in_array( $name, $process->options->trace ) ) {
+ if ( ! $trace || ! in_array( $name, $trace ) ) {
return;
}
@@ -508,7 +531,7 @@ static public function runStat ( $name ) {
case 'selector_count':
$process->stat[ 'selector_count' ] = 0;
foreach ( $process->tokens->r as $rule ) {
- $process->stat[ 'selector_count' ] += count( $rule->selectorList );
+ $process->stat[ 'selector_count' ] += count( $rule->selectors );
}
break;
@@ -526,23 +549,82 @@ static public function runStat ( $name ) {
#############################
+# Default formatters.
+
+function csscrush__fmtr_single ( $rule ) {
+
+ $EOL = CssCrush::$process->newline;
+ if ( $stub = $rule->tracingStub ) {
+ $stub .= $EOL;
+ }
+
+ $comments = implode( '', $rule->comments );
+ if ( $comments ) {
+ $comments = "$EOL$comments";
+ }
+ $selectors = implode( ", ", $rule->selectors );
+ $block = implode( "; ", $rule->declarations );
+ return "$comments$stub$selectors { $block; }$EOL";
+}
+
+function csscrush__fmtr_padded ( $rule ) {
+
+ $EOL = CssCrush::$process->newline;
+ if ( $stub = $rule->tracingStub ) {
+ $stub .= $EOL;
+ }
+
+ $comments = implode( '', $rule->comments );
+ if ( $comments ) {
+ $comments = "$EOL$comments";
+ }
+
+ $cutoff = 40;
+ $selectors = implode( ", ", $rule->selectors );
+ $block = implode( "; ", $rule->declarations );
+
+ if ( strlen( $selectors ) > $cutoff ) {
+ $padding = str_repeat( ' ', $cutoff );
+ return "$comments$stub$selectors$EOL$padding { $block; }$EOL";
+ }
+ else {
+ $selectors = str_pad( $selectors, $cutoff );
+ return "$comments$stub$selectors { $block; }$EOL";
+ }
+}
+
+function csscrush__fmtr_block ( $rule, $indent = ' ' ) {
+
+ $EOL = CssCrush::$process->newline;
+ if ( $stub = $rule->tracingStub ) {
+ $stub .= $EOL;
+ }
+
+ $comments = implode( '', $rule->comments );
+ $selectors = implode( ",$EOL", $rule->selectors );
+ $block = implode( ";$EOL$indent", $rule->declarations );
+ return "$comments$stub$selectors {{$EOL}$indent$block;$EOL$indent}$EOL$EOL";
+}
+
+
+#############################
# Procedural style external API.
function csscrush_file ( $file, $options = null ) {
- return csscrush::file( $file, $options );
+ return CssCrush::file( $file, $options );
}
function csscrush_tag ( $file, $options = null, $attributes = array() ) {
- return csscrush::tag( $file, $options, $attributes );
+ return CssCrush::tag( $file, $options, $attributes );
}
function csscrush_inline ( $file, $options = null, $attributes = array() ) {
- return csscrush::inline( $file, $options, $attributes );
+ return CssCrush::inline( $file, $options, $attributes );
}
function csscrush_string ( $string, $options = null ) {
- return csscrush::string( $string, $options );
+ return CssCrush::string( $string, $options );
}
function csscrush_globalvars ( $vars ) {
- return csscrush::globalVars( $vars );
+ return CssCrush::globalVars( $vars );
}
function csscrush_clearcache ( $dir = '' ) {
- return csscrush::clearcache( $dir );
+ return CssCrush::clearcache( $dir );
}
View
104 lib/Declaration.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ *
+ * Declaration objects.
+ *
+ */
+class CssCrush_Declaration
+{
+ public $property;
+ public $canonicalProperty;
+ public $vendor;
+ public $functions;
+ public $value;
+ public $index;
+ public $skip;
+ public $important;
+ public $isValid = true;
+
+ public function __construct ( $prop, $value, $contextIndex = 0 )
+ {
+ $regex = CssCrush_Regex::$patt;
+
+ // Normalize input. Lowercase the property name.
+ $prop = strtolower( trim( $prop ) );
+ $value = trim( $value );
+
+ // Check the input.
+ if ( $prop === '' || $value === '' || $value === null ) {
+ $this->isValid = false;
+ return;
+ }
+
+ // Test for escape tilde.
+ if ( $skip = strpos( $prop, '~' ) === 0 ) {
+ $prop = substr( $prop, 1 );
+ }
+
+ // Store the canonical property name.
+ // Store the vendor mark if one is present.
+ if ( preg_match( $regex->vendorPrefix, $prop, $vendor ) ) {
+ $canonical_property = $vendor[2];
+ $vendor = $vendor[1];
+ }
+ else {
+ $vendor = null;
+ $canonical_property = $prop;
+ }
+
+ // Check for !important.
+ if ( ( $important = stripos( $value, '!important' ) ) !== false ) {
+ $value = rtrim( substr( $value, 0, $important ) );
+ $important = true;
+ }
+
+ // Ignore declarations with null css values.
+ if ( $value === false || $value === '' ) {
+ $this->isValid = false;
+ return;
+ }
+
+ // Apply custom functions.
+ if ( ! $skip ) {
+ CssCrush_Function::executeCustomFunctions( $value );
+ }
+
+ // Capture all remaining paren pairs.
+ CssCrush::$process->captureParens( $value );
+
+ // Create an index of all regular functions in the value.
+ $functions = array();
+ if ( preg_match_all( $regex->function, $value, $m ) ) {
+ foreach ( $m[2] as $index => $fn_name ) {
+ $functions[ strtolower( $fn_name ) ] = true;
+ }
+ }
+
+ $this->property = $prop;
+ $this->canonicalProperty = $canonical_property;
+ $this->vendor = $vendor;
+ $this->functions = $functions;
+ $this->index = $contextIndex;
+ $this->value = $value;
+ $this->skip = $skip;
+ $this->important = $important;
+ }
+
+ public function __toString ()
+ {
+ if ( CssCrush::$process->minifyOutput ) {
+ $whitespace = '';
+ }
+ else {
+ $whitespace = ' ';
+ }
+ $important = $this->important ? "$whitespace!important" : '';
+
+ return "$this->property:$whitespace$this->value$important";
+ }
+
+ public function getFullValue ()
+ {
+ return CssCrush::$process->restoreTokens( $this->value, 'p' );
+ }
+}
View
32 lib/ExtendArg.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ *
+ * Extend argument objects.
+ *
+ */
+class CssCrush_ExtendArg
+{
+ public $pointer;
+ public $name;
+ public $pseudo;
+
+ public function __construct ( $name )
+ {
+ $this->name = $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 );
+
+ // If applying the pseudo on output store
+ if ( substr( $this->name, -1 ) === '!' ) {
+
+ $this->name = rtrim( $this->name, ' !' );
+ if ( preg_match( '!\:\:?[\w-]+$!', $this->name, $m ) ) {
+ $this->pseudo = $m[0];
+ }
+ }
+ }
+ }
+}
View
36 lib/Fragment.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ *
+ * Fragment objects.
+ *
+ */
+class CssCrush_Fragment
+{
+ public $template = array();
+
+ public $arguments;
+
+ public function __construct ( $block )
+ {
+ // Prepare the arguments object
+ $this->arguments = new CssCrush_ArgList( $block );
+
+ // Re-assign with the parsed arguments string
+ $this->template = $this->arguments->string;
+ }
+
+ public function call ( array $args )
+ {
+ // Copy the template
+ $template = $this->template;
+
+ if ( count( $this->arguments ) ) {
+
+ list( $find, $replace ) = $this->arguments->getSubstitutions( $args );
+ $template = str_replace( $find, $replace, $template );
+ }
+
+ // Return fragment css
+ return $template;
+ }
+}
View
97 lib/Function.php
@@ -4,7 +4,20 @@
* Custom CSS functions
*
*/
-class csscrush_function {
+class CssCrush_Function
+{
+ static function init ()
+ {
+ CssCrush_Function::register( 'math', 'csscrush_fn__math' );
+ CssCrush_Function::register( 'percent', 'csscrush_fn__percent' );
+ CssCrush_Function::register( 'pc', 'csscrush_fn__percent' );
+ CssCrush_Function::register( 'hsla-adjust', 'csscrush_fn__hsla_adjust' );
+ CssCrush_Function::register( 'hsl-adjust', 'csscrush_fn__hsl_adjust' );
+ CssCrush_Function::register( 'h-adjust', 'csscrush_fn__h_adjust' );
+ CssCrush_Function::register( 's-adjust', 'csscrush_fn__s_adjust' );
+ CssCrush_Function::register( 'l-adjust', 'csscrush_fn__l_adjust' );
+ CssCrush_Function::register( 'a-adjust', 'csscrush_fn__a_adjust' );
+ }
// Regex pattern for finding custom functions.
static public $functionPatt;
@@ -12,13 +25,13 @@ class csscrush_function {
// Stack for function names.
static protected $customFunctions;
- static public function setMatchPatt () {
-
- self::$functionPatt = csscrush_regex::createFunctionMatchPatt( array_keys( self::$customFunctions ), true );
+ static public function setMatchPatt ()
+ {
+ self::$functionPatt = CssCrush_Regex::createFunctionMatchPatt( array_keys( self::$customFunctions ), true );
}
- static public function executeCustomFunctions ( &$str, $patt = null, $process_callback = null, $property = null ) {
-
+ static public function executeCustomFunctions ( &$str, $patt = null, $process_callback = null, $property = null )
+ {
// No bracketed expressions, early return.
if ( false === strpos( $str, '(' ) ) {
return;
@@ -26,7 +39,7 @@ static public function executeCustomFunctions ( &$str, $patt = null, $process_ca
// Set default pattern if not set.
if ( is_null( $patt ) ) {
- $patt = csscrush_function::$functionPatt;
+ $patt = CssCrush_Function::$functionPatt;
}
// No custom functions, early return.
@@ -35,14 +48,14 @@ static public function executeCustomFunctions ( &$str, $patt = null, $process_ca
}
// Find custom function matches.
- $matches = csscrush_regex::matchAll( $patt, $str );
+ $matches = CssCrush_Regex::matchAll( $patt, $str );
// Step through the matches from last to first.
while ( $match = array_pop( $matches ) ) {
$offset = $match[0][1];
- if ( ! preg_match( csscrush_regex::$patt->balancedParens,
+ if ( ! preg_match( CssCrush_Regex::$patt->balancedParens,
$str, $parens, PREG_OFFSET_CAPTURE, $offset ) ) {
continue;
}
@@ -87,28 +100,32 @@ static public function executeCustomFunctions ( &$str, $patt = null, $process_ca
#############################
# API and helpers.
- static public function register ( $name, $callback ) {
- csscrush_function::$customFunctions[ $name ] = $callback;
+ static public function register ( $name, $callback )
+ {
+ CssCrush_Function::$customFunctions[ $name ] = $callback;
}
- static public function deRegister ( $name ) {
- unset( csscrush_function::$customFunctions[ $name ] );
+ static public function deRegister ( $name )
+ {
+ unset( CssCrush_Function::$customFunctions[ $name ] );
}
- static public function parseArgs ( $input, $allowSpaceDelim = false ) {
- return csscrush_util::splitDelimList(
+ static public function parseArgs ( $input, $allowSpaceDelim = false )
+ {
+ return CssCrush_Util::splitDelimList(
$input, ( $allowSpaceDelim ? '\s*[,\s]\s*' : ',' ) );
}
// Intended as a quick arg-list parse for function that take up-to 2 arguments
// with the proviso the first argument is an ident.
- static public function parseArgsSimple ( $input ) {
- return preg_split( csscrush_regex::$patt->argListSplit, $input, 2 );
+ static public function parseArgsSimple ( $input )
+ {
+ return preg_split( CssCrush_Regex::$patt->argListSplit, $input, 2 );
}
- static public function colorAdjust ( $raw_color, array $adjustments ) {
-
- $hsla = new csscrush_color( $raw_color, true );
+ static public function colorAdjust ( $raw_color, array $adjustments )
+ {
+ $hsla = new CssCrush_Color( $raw_color, true );
// On failure to parse return input.
return $hsla->isValid ? $hsla->adjust( $adjustments )->__toString() : $raw_color;
@@ -116,14 +133,13 @@ static public function colorAdjust ( $raw_color, array $adjustments ) {
}
-
#############################
# Stock custom CSS functions.
function csscrush_fn__math ( $input ) {
// Strip blacklisted characters
- $input = preg_replace( csscrush_regex::$patt->mathBlacklist, '', $input );
+ $input = preg_replace( CssCrush_Regex::$patt->mathBlacklist, '', $input );
$result = @eval( "return $input;" );
@@ -135,7 +151,7 @@ function csscrush_fn__percent ( $input ) {
// Strip non-numeric and non delimiter characters
$input = preg_replace( '![^\d\.\s,]!S', '', $input );
- $args = preg_split( csscrush_regex::$patt->argListSplit, $input, -1, PREG_SPLIT_NO_EMPTY );
+ $args = preg_split( CssCrush_Regex::$patt->argListSplit, $input, -1, PREG_SPLIT_NO_EMPTY );
// Use precision argument if it exists, use default otherwise
$precision = isset( $args[2] ) ? $args[2] : 5;
@@ -173,42 +189,31 @@ function csscrush_fn__percent ( $input ) {
}
function csscrush_fn__hsla_adjust ( $input ) {
- list( $color, $h, $s, $l, $a ) = array_pad( csscrush_function::parseArgs( $input, true ), 5, 0 );
- return csscrush_function::colorAdjust( $color, array( $h, $s, $l, $a ) );
+ list( $color, $h, $s, $l, $a ) = array_pad( CssCrush_Function::parseArgs( $input, true ), 5, 0 );
+ return CssCrush_Function::colorAdjust( $color, array( $h, $s, $l, $a ) );
}
function csscrush_fn__hsl_adjust ( $input ) {
- list( $color, $h, $s, $l ) = array_pad( csscrush_function::parseArgs( $input, true ), 4, 0 );
- return csscrush_function::colorAdjust( $color, array( $h, $s, $l, 0 ) );
+ list( $color, $h, $s, $l ) = array_pad( CssCrush_Function::parseArgs( $input, true ), 4, 0 );
+ return CssCrush_Function::colorAdjust( $color, array( $h, $s, $l, 0 ) );
}
function csscrush_fn__h_adjust ( $input ) {
- list( $color, $h ) = array_pad( csscrush_function::parseArgs( $input, true ), 2, 0 );
- return csscrush_function::colorAdjust( $color, array( $h, 0, 0, 0 ) );
+ list( $color, $h ) = array_pad( CssCrush_Function::parseArgs( $input, true ), 2, 0 );
+ return CssCrush_Function::colorAdjust( $color, array( $h, 0, 0, 0 ) );
}
function csscrush_fn__s_adjust ( $input ) {
- list( $color, $s ) = array_pad( csscrush_function::parseArgs( $input, true ), 2, 0 );
- return csscrush_function::colorAdjust( $color, array( 0, $s, 0, 0 ) );
+ list( $color, $s ) = array_pad( CssCrush_Function::parseArgs( $input, true ), 2, 0 );
+ return CssCrush_Function::colorAdjust( $color, array( 0, $s, 0, 0 ) );
}
function csscrush_fn__l_adjust ( $input ) {
- list( $color, $l ) = array_pad( csscrush_function::parseArgs( $input, true ), 2, 0 );
- return csscrush_function::colorAdjust( $color, array( 0, 0, $l, 0 ) );
+ list( $color, $l ) = array_pad( CssCrush_Function::parseArgs( $input, true ), 2, 0 );
+ return CssCrush_Function::colorAdjust( $color, array( 0, 0, $l, 0 ) );
}
function csscrush_fn__a_adjust ( $input ) {
- list( $color, $a ) = array_pad( csscrush_function::parseArgs( $input, true ), 2, 0 );
- return csscrush_function::colorAdjust( $color, array( 0, 0, 0, $a ) );
+ list( $color, $a ) = array_pad( CssCrush_Function::parseArgs( $input, true ), 2, 0 );
+ return CssCrush_Function::colorAdjust( $color, array( 0, 0, 0, $a ) );
}
-
-csscrush_function::register( 'math', 'csscrush_fn__math' );
-csscrush_function::register( 'percent', 'csscrush_fn__percent' );
-csscrush_function::register( 'pc', 'csscrush_fn__percent' );
-csscrush_function::register( 'hsla-adjust', 'csscrush_fn__hsla_adjust' );
-csscrush_function::register( 'hsl-adjust', 'csscrush_fn__hsl_adjust' );
-csscrush_function::register( 'h-adjust', 'csscrush_fn__h_adjust' );
-csscrush_function::register( 's-adjust', 'csscrush_fn__s_adjust' );
-csscrush_function::register( 'l-adjust', 'csscrush_fn__l_adjust' );
-csscrush_function::register( 'a-adjust', 'csscrush_fn__a_adjust' );
-
View
15 lib/Hook.php
@@ -4,13 +4,13 @@
* Access to the execution flow.
*
*/
-class csscrush_hook {
-
+class CssCrush_Hook
+{
// Table of hooks and the functions attached to them.
static public $register = array();
- static public function add ( $hook, $fn_name ) {
-
+ static public function add ( $hook, $fn_name )
+ {
// Bail early is the named hook and callback combination is already loaded.
if ( isset( self::$register[ $hook ][ $fn_name ] ) ) {
return;
@@ -24,12 +24,13 @@ static public function add ( $hook, $fn_name ) {
}
}
- static public function remove ( $hook, $fn_name ) {
+ static public function remove ( $hook, $fn_name )
+ {
unset( self::$register[ $hook ][ $fn_name ] );
}
- static public function run ( $hook, $arg_obj = null ) {
-
+ static public function run ( $hook, $arg_obj = null )
+ {
// Run all callbacks attached to the hook.
if ( ! isset( self::$register[ $hook ] ) ) {
return;
View
116 lib/IO.php
@@ -4,24 +4,25 @@
* Interface for writing files, retrieving files and checking caches
*
*/
-class csscrush_io {
-
+class CssCrush_IO
+{
// Any setup that needs to be done
- static public function init () {
-
- $process = csscrush::$process;
+ static public function init ()
+ {
+ $process = CssCrush::$process;
$process->cacheFile = "{$process->output->dir}/.csscrush";
}
- static public function getOutputDir () {<