WP-SCSS - Version 1.1.0

Version Description

Download this release

Release Info

Developer connectthink
Plugin Icon wp plugin WP-SCSS
Version 1.1.0
Comparing to
See all releases

Code changes from version 1.1.6 to 1.1.0

Files changed (5) hide show
  1. class/class-wp-scss.php +34 -34
  2. options.php +1 -2
  3. readme.txt +11 -29
  4. scssphp/scss.inc.php +98 -167
  5. wp-scss.php +48 -55
class/class-wp-scss.php CHANGED
@@ -1,22 +1,22 @@
1
- <?php
2
 
3
  class Wp_Scss {
4
  /**
5
  * Compiling preferences properites
6
- *
7
  * @var string
8
  * @access public
9
  */
10
  public $scss_dir, $css_dir, $compile_method, $scssc, $compile_errors;
11
-
12
 
13
  /**
14
  * Set values for Wp_Scss::properties
15
- *
16
  * @param string scss_dir - path to source directory for scss files
17
  * @param string css_dir - path to output directory for css files
18
  * @param string method - type of compile (compressed, expanded, etc)
19
- *
20
  * @var object scssc - instantiate the compiling object.
21
  *
22
  * @var array compile_errors - catches errors from compile
@@ -29,35 +29,35 @@ class Wp_Scss {
29
  global $scssc;
30
  $scssc = new scssc();
31
  $scssc->setFormatter($compile_method);
32
- $scssc->setImportPaths($scss_dir);
33
 
34
  $this->compile_errors = array();
35
  }
36
 
37
- /**
38
  * METHOD COMPILE
39
  * Loops through scss directory and compilers files that end
40
  * with .scss and do not have '_' in front.
41
  *
42
- * @function compiler - passes input content through scssphp,
43
  * puts compiled css into cache file
44
  *
45
  * @var array input_files - array of .scss files with no '_' in front
46
  * @var array sdir_arr - an array of all the files in the scss directory
47
- *
48
- * @return nothing - Puts successfully compiled css into apporpriate location
49
  * Puts error in 'compile_errors' property
50
  * @access public
51
  */
52
  public function compile() {
53
  global $scssc, $cache;
54
  $cache = WPSCSS_PLUGIN_DIR . '/cache/';
55
-
56
  //Compiler - Takes scss $in and writes compiled css to $out file
57
  // catches errors and puts them the object's compiled_errors property
58
- function compiler($in, $out, $instance) {
59
- global $scssc, $cache;
60
-
61
  if (is_writable($cache)) {
62
  try {
63
  $css = $scssc->compile(file_get_contents($in));
@@ -78,27 +78,27 @@ class Wp_Scss {
78
  }
79
  }
80
 
81
- $input_files = array();
82
  // Loop through directory and get .scss file that do not start with '_'
83
  foreach(new DirectoryIterator($this->scss_dir) as $file) {
84
  if (substr($file, 0, 1) != "_" && pathinfo($file->getFilename(), PATHINFO_EXTENSION) == 'scss') {
85
  array_push($input_files, $file->getFilename());
86
  }
87
  }
88
-
89
  // For each input file, find matching css file and compile
90
  foreach ($input_files as $scss_file) {
91
  $input = $this->scss_dir.$scss_file;
92
  $outputName = preg_replace("/\.[^$]*/",".css", $scss_file);
93
  $output = $this->css_dir.$outputName;
94
-
95
  compiler($input, $output, $this);
96
  }
97
 
98
  if (count($this->compile_errors) < 1) {
99
  if ( is_writable($this->css_dir) ) {
100
  foreach (new DirectoryIterator($cache) as $cache_file) {
101
- if ( pathinfo($cache_file->getFilename(), PATHINFO_EXTENSION) == 'css') {
102
  file_put_contents($this->css_dir.$cache_file, file_get_contents($cache.$cache_file));
103
  unlink($cache.$cache_file->getFilename()); // Delete file on successful write
104
  }
@@ -111,10 +111,10 @@ class Wp_Scss {
111
  array_push($this->compile_errors, $errors);
112
  }
113
  }
114
- }
115
 
116
 
117
- /**
118
  * METHOD NEEDS_COMPILING
119
  * Gets the most recently modified file in the scss directory
120
  * and compares that do the most recently modified css file.
@@ -126,60 +126,60 @@ class Wp_Scss {
126
  *
127
  * @var array sdir_arr - scss directory files
128
  * @var array cdir_arr - css directory files
129
- *
130
  * @var string latest_scss - file mod time of the most recent file change
131
  * @var string latest_css - file mod time of the most recent file change
132
- *
133
  * @return bool - true if compiling is needed
134
  */
135
  public function needs_compiling() {
136
  $latest_scss = 0;
137
  $latest_css = 0;
138
 
139
- foreach ( new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->scss_dir)) as $sfile ) {
140
  if (pathinfo($sfile->getFilename(), PATHINFO_EXTENSION) == 'scss') {
141
  $file_time = $sfile->getMTime();
142
 
143
  if ( (int) $file_time > $latest_scss) {
144
- $latest_scss = $file_time;
145
  }
146
  }
147
  }
148
 
149
- foreach ( new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->css_dir)) as $cfile ) {
150
  if (pathinfo($cfile->getFilename(), PATHINFO_EXTENSION) == 'css') {
151
  $file_time = $cfile->getMTime();
152
-
153
  if ( (int) $file_time > $latest_css) {
154
- $latest_css = $file_time;
155
  }
156
  }
157
  }
158
-
159
  if ($latest_scss > $latest_css) {
160
  return true;
161
  } else {
162
- return false;
163
  }
164
  }
165
 
166
- /**
167
  * METHOD ENQUEUE STYLES
168
  * Enqueues all styles in the css directory.
169
  *
170
  * @param $css_folder - directory from theme root. We need this passed in separately
171
- * so it can be used in a url, not path
172
  */
173
  public function enqueue_files($css_folder) {
174
-
175
  foreach( new DirectoryIterator($this->css_dir) as $stylesheet ) {
176
  if ( pathinfo($stylesheet->getFilename(), PATHINFO_EXTENSION) == 'css' ) {
177
  $name = $stylesheet->getBasename('.css') . '-style';
178
  $uri = get_stylesheet_directory_uri().$css_folder.$stylesheet->getFilename();
179
  $ver = $stylesheet->getMTime();
180
 
181
-
182
- wp_register_style(
183
  $name,
184
  $uri,
185
  array(),
1
+ <?php
2
 
3
  class Wp_Scss {
4
  /**
5
  * Compiling preferences properites
6
+ *
7
  * @var string
8
  * @access public
9
  */
10
  public $scss_dir, $css_dir, $compile_method, $scssc, $compile_errors;
11
+
12
 
13
  /**
14
  * Set values for Wp_Scss::properties
15
+ *
16
  * @param string scss_dir - path to source directory for scss files
17
  * @param string css_dir - path to output directory for css files
18
  * @param string method - type of compile (compressed, expanded, etc)
19
+ *
20
  * @var object scssc - instantiate the compiling object.
21
  *
22
  * @var array compile_errors - catches errors from compile
29
  global $scssc;
30
  $scssc = new scssc();
31
  $scssc->setFormatter($compile_method);
32
+ $scssc->setImportPaths($scss_dir);
33
 
34
  $this->compile_errors = array();
35
  }
36
 
37
+ /**
38
  * METHOD COMPILE
39
  * Loops through scss directory and compilers files that end
40
  * with .scss and do not have '_' in front.
41
  *
42
+ * @function compiler - passes input content through scssphp,
43
  * puts compiled css into cache file
44
  *
45
  * @var array input_files - array of .scss files with no '_' in front
46
  * @var array sdir_arr - an array of all the files in the scss directory
47
+ *
48
+ * @return nothing - Puts successfully compiled css into apporpriate location
49
  * Puts error in 'compile_errors' property
50
  * @access public
51
  */
52
  public function compile() {
53
  global $scssc, $cache;
54
  $cache = WPSCSS_PLUGIN_DIR . '/cache/';
55
+
56
  //Compiler - Takes scss $in and writes compiled css to $out file
57
  // catches errors and puts them the object's compiled_errors property
58
+ function compiler($in, $out, $instance) {
59
+ global $scssc, $cache;
60
+
61
  if (is_writable($cache)) {
62
  try {
63
  $css = $scssc->compile(file_get_contents($in));
78
  }
79
  }
80
 
81
+ $input_files = array();
82
  // Loop through directory and get .scss file that do not start with '_'
83
  foreach(new DirectoryIterator($this->scss_dir) as $file) {
84
  if (substr($file, 0, 1) != "_" && pathinfo($file->getFilename(), PATHINFO_EXTENSION) == 'scss') {
85
  array_push($input_files, $file->getFilename());
86
  }
87
  }
88
+
89
  // For each input file, find matching css file and compile
90
  foreach ($input_files as $scss_file) {
91
  $input = $this->scss_dir.$scss_file;
92
  $outputName = preg_replace("/\.[^$]*/",".css", $scss_file);
93
  $output = $this->css_dir.$outputName;
94
+
95
  compiler($input, $output, $this);
96
  }
97
 
98
  if (count($this->compile_errors) < 1) {
99
  if ( is_writable($this->css_dir) ) {
100
  foreach (new DirectoryIterator($cache) as $cache_file) {
101
+ if ( pathinfo($cache_file->getFilename(), PATHINFO_EXTENSION) == 'css') {
102
  file_put_contents($this->css_dir.$cache_file, file_get_contents($cache.$cache_file));
103
  unlink($cache.$cache_file->getFilename()); // Delete file on successful write
104
  }
111
  array_push($this->compile_errors, $errors);
112
  }
113
  }
114
+ }
115
 
116
 
117
+ /**
118
  * METHOD NEEDS_COMPILING
119
  * Gets the most recently modified file in the scss directory
120
  * and compares that do the most recently modified css file.
126
  *
127
  * @var array sdir_arr - scss directory files
128
  * @var array cdir_arr - css directory files
129
+ *
130
  * @var string latest_scss - file mod time of the most recent file change
131
  * @var string latest_css - file mod time of the most recent file change
132
+ *
133
  * @return bool - true if compiling is needed
134
  */
135
  public function needs_compiling() {
136
  $latest_scss = 0;
137
  $latest_css = 0;
138
 
139
+ foreach ( new DirectoryIterator($this->scss_dir) as $sfile ) {
140
  if (pathinfo($sfile->getFilename(), PATHINFO_EXTENSION) == 'scss') {
141
  $file_time = $sfile->getMTime();
142
 
143
  if ( (int) $file_time > $latest_scss) {
144
+ $latest_scss = $file_time;
145
  }
146
  }
147
  }
148
 
149
+ foreach ( new DirectoryIterator($this->css_dir) as $cfile ) {
150
  if (pathinfo($cfile->getFilename(), PATHINFO_EXTENSION) == 'css') {
151
  $file_time = $cfile->getMTime();
152
+
153
  if ( (int) $file_time > $latest_css) {
154
+ $latest_css = $file_time;
155
  }
156
  }
157
  }
158
+
159
  if ($latest_scss > $latest_css) {
160
  return true;
161
  } else {
162
+ return false;
163
  }
164
  }
165
 
166
+ /**
167
  * METHOD ENQUEUE STYLES
168
  * Enqueues all styles in the css directory.
169
  *
170
  * @param $css_folder - directory from theme root. We need this passed in separately
171
+ * so it can be used in a url, not path
172
  */
173
  public function enqueue_files($css_folder) {
174
+
175
  foreach( new DirectoryIterator($this->css_dir) as $stylesheet ) {
176
  if ( pathinfo($stylesheet->getFilename(), PATHINFO_EXTENSION) == 'css' ) {
177
  $name = $stylesheet->getBasename('.css') . '-style';
178
  $uri = get_stylesheet_directory_uri().$css_folder.$stylesheet->getFilename();
179
  $ver = $stylesheet->getMTime();
180
 
181
+
182
+ wp_register_style(
183
  $name,
184
  $uri,
185
  array(),
options.php CHANGED
@@ -218,7 +218,6 @@ class Wp_Scss_Settings
218
 
219
  $html = '<select id="errors" name="wpscss_options[errors]">';
220
  $html .= '<option value="show"' . selected( $this->options['errors'], 'show', false) . '>Show in Header</option>';
221
- $html .= '<option value="show-logged-in"' . selected( $this->options['errors'], 'show-logged-in', false) . '>Show to Logged In Users</option>';
222
  $html .= '<option value="log"' . selected( $this->options['errors'], 'hide', false) . '>Print to Log</option>';
223
  $html .= '</select>';
224
 
@@ -231,7 +230,7 @@ class Wp_Scss_Settings
231
  function enqueue_callback() {
232
  $this->options = get_option( 'wpscss_options' );
233
 
234
- $html = '<input type="checkbox" id="enqueue" name="wpscss_options[enqueue]" value="1"' . checked( 1, isset($this->options['enqueue']) ? $this->options['enqueue'] : 0, false ) . '/>';
235
  $html .= '<label for="enqueue"></label>';
236
 
237
  echo $html;
218
 
219
  $html = '<select id="errors" name="wpscss_options[errors]">';
220
  $html .= '<option value="show"' . selected( $this->options['errors'], 'show', false) . '>Show in Header</option>';
 
221
  $html .= '<option value="log"' . selected( $this->options['errors'], 'hide', false) . '>Print to Log</option>';
222
  $html .= '</select>';
223
 
230
  function enqueue_callback() {
231
  $this->options = get_option( 'wpscss_options' );
232
 
233
+ $html = '<input type="checkbox" id="enqueue" name="wpscss_options[enqueue]" value="1"' . checked( 1, $this->options['enqueue'], false ) . '/>';
234
  $html .= '<label for="enqueue"></label>';
235
 
236
  echo $html;
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: sass, scss, css
4
  Plugin URI: https://github.com/ConnectThink/WP-SCSS
5
  Requires at least: 3.0.1
6
  Tested up to: 3.8
7
- Stable tag: 1.1.6
8
  License: GPLv3 or later
9
  License URI: http://www.gnu.org/copyleft/gpl.html
10
 
@@ -14,7 +14,7 @@ Compiles .scss files to .css and enqueues them.
14
 
15
  Compiles .scss files on your wordpress install using [lefo's scssphp](https://github.com/leafo/scssphp). Includes settings page for configuring directories, error reporting, compiling options, and auto enqueuing.
16
 
17
- The plugin only compiles when changes have been made to the scss files. Compiles are made to the matching css file, so disabling this plugin will not take down your stylesheets. In the instance where a matching css file does not exist yet, the plugin will create the appropriate css file in the css directory.
18
 
19
  [Get detailed instructions on github](https://github.com/ConnectThink/WP-SCSS)
20
 
@@ -26,34 +26,30 @@ The plugin only compiles when changes have been made to the scss files. Compiles
26
 
27
  == Frequently Asked Questions ==
28
 
29
- = Can I use a child theme? =
30
-
31
- Yes, absolutely. Make sure you define your directories relative to your child theme and that your child theme is active. Otherwise you'll see an error regarding missing directories.
32
-
33
  = How do I @import subfiles =
34
 
35
  You can import other scss files into parent files and compile them into a single css file. To do this, use @import as normal in your scss file. All imported file names *must* start with an underscore. Otherwise they will be compiled into their own css file.
36
 
37
  When importing in your scss file, you can leave off the underscore.
38
-
39
  > `@import 'subfile';`
 
40
 
41
-
42
- = Does this plugin support Compass? =
43
  Currently there isn't a way to fully support [compass](https://github.com/chriseppstein/compass) with a php compiler. If you want limited support, you can manually import the compass framework. You'll need both the _compass.scss and compass directory.
44
-
45
-
46
  > `compass / frameworks / compass / stylesheets /
47
 
48
  > `@import 'compass';`
49
 
50
 
51
- Alternatively, you can include [Bourbon](https://github.com/thoughtbot/bourbon) in a similar fashion.
52
 
53
  = Can I use .sass syntax with this Plugin? =
54
  This plugin will only work with .scss format.
55
 
56
- = It's not updating my css, what's happening? =
57
  Do you have errors printing to the front end? If not, check your log file in your scss directory. The css will not be updated if there are errors in your sass file(s).
58
 
59
  Make sure your directories are properly defined in the settings. Paths are defined from the root of the theme.
@@ -62,24 +58,10 @@ Make sure your directories are properly defined in the settings. Paths are defin
62
  If you are having issues with the plugin, create an issue on [github](https://github.com/ConnectThink/WP-SCSS), and we'll do our best to help.
63
 
64
  == Changelog ==
65
- = 1.1.6 =
66
- * Upgraded scss.inc.php to version 0.0.10; via pull request from [kirkhoff](https://github.com/kirkhoff)
67
-
68
- = 1.1.5 =
69
- * Added option to only show errors to logged in users; via pull request from [tolnem](https://github.com/tolnem)
70
-
71
- = 1.1.4 =
72
- * Add suport for subfolders in scss directory
73
-
74
- = 1.1.3 =
75
- * Hotfix for a accidental character
76
-
77
- = 1.1.2 =
78
- * Added support for moved wp-content directories
79
 
80
- = 1.1.1 =
81
  * Added error handling for file permissions issues
82
  * Changed error log to .log for auto updating errors
83
 
84
- = 1.0.0 =
85
  * Initial Build
4
  Plugin URI: https://github.com/ConnectThink/WP-SCSS
5
  Requires at least: 3.0.1
6
  Tested up to: 3.8
7
+ Stable tag: 1.1.0
8
  License: GPLv3 or later
9
  License URI: http://www.gnu.org/copyleft/gpl.html
10
 
14
 
15
  Compiles .scss files on your wordpress install using [lefo's scssphp](https://github.com/leafo/scssphp). Includes settings page for configuring directories, error reporting, compiling options, and auto enqueuing.
16
 
17
+ The plugin only compiles when changes have been made to the scss files. Compiles are made to the matching css file, so disabling this plugin will not take down your stylesheets. In the instance where a matching css file does not exist yet, the plugin will create the appropriate css file in the css directory.
18
 
19
  [Get detailed instructions on github](https://github.com/ConnectThink/WP-SCSS)
20
 
26
 
27
  == Frequently Asked Questions ==
28
 
 
 
 
 
29
  = How do I @import subfiles =
30
 
31
  You can import other scss files into parent files and compile them into a single css file. To do this, use @import as normal in your scss file. All imported file names *must* start with an underscore. Otherwise they will be compiled into their own css file.
32
 
33
  When importing in your scss file, you can leave off the underscore.
34
+
35
  > `@import 'subfile';`
36
+
37
 
38
+ = Does this plugin support Compass? =
 
39
  Currently there isn't a way to fully support [compass](https://github.com/chriseppstein/compass) with a php compiler. If you want limited support, you can manually import the compass framework. You'll need both the _compass.scss and compass directory.
40
+
41
+
42
  > `compass / frameworks / compass / stylesheets /
43
 
44
  > `@import 'compass';`
45
 
46
 
47
+ Alternatively, you can include [Bourbon](https://github.com/thoughtbot/bourbon) in a similar fashion.
48
 
49
  = Can I use .sass syntax with this Plugin? =
50
  This plugin will only work with .scss format.
51
 
52
+ = It's not updating my css, what's happening? =
53
  Do you have errors printing to the front end? If not, check your log file in your scss directory. The css will not be updated if there are errors in your sass file(s).
54
 
55
  Make sure your directories are properly defined in the settings. Paths are defined from the root of the theme.
58
  If you are having issues with the plugin, create an issue on [github](https://github.com/ConnectThink/WP-SCSS), and we'll do our best to help.
59
 
60
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
+ = 1.1 =
63
  * Added error handling for file permissions issues
64
  * Changed error log to .log for auto updating errors
65
 
66
+ = 1.0 =
67
  * Initial Build
scssphp/scss.inc.php CHANGED
@@ -43,7 +43,7 @@
43
  * @author Leaf Corcoran <leafot@gmail.com>
44
  */
45
  class scssc {
46
- static public $VERSION = "v0.0.10";
47
 
48
  static protected $operatorNames = array(
49
  '+' => "add",
@@ -67,6 +67,7 @@ class scssc {
67
  "function" => "^",
68
  );
69
 
 
70
  static protected $unitTable = array(
71
  "in" => array(
72
  "in" => 1,
@@ -90,11 +91,9 @@ class scssc {
90
 
91
  protected $userFunctions = array();
92
 
93
- protected $numberPrecision = 5;
94
-
95
  protected $formatter = "scss_formatter_nested";
96
 
97
- public function compile($code, $name=null) {
98
  $this->indentLevel = -1;
99
  $this->commentsSeen = array();
100
  $this->extends = array();
@@ -187,13 +186,6 @@ class scssc {
187
  $rem = array_diff($single, $target);
188
 
189
  foreach ($origin as $j => $new) {
190
- // prevent infinite loop when target extends itself
191
- foreach ($new as $new_selector) {
192
- if (!array_diff($single, $new_selector)) {
193
- continue 2;
194
- }
195
- }
196
-
197
  $origin[$j][count($origin[$j]) - 1] = $this->combineSelectorSingle(end($new), $rem);
198
  }
199
 
@@ -318,40 +310,35 @@ class scssc {
318
 
319
  protected function compileMedia($media) {
320
  $this->pushEnv($media);
 
321
 
322
- $mediaQuery = $this->compileMediaQuery($this->multiplyMedia($this->env));
323
-
324
- if (!empty($mediaQuery)) {
325
-
326
- $this->scope = $this->makeOutputBlock("media", array($mediaQuery));
327
-
328
- $parentScope = $this->mediaParent($this->scope);
329
-
330
- $parentScope->children[] = $this->scope;
331
 
332
- // top level properties in a media cause it to be wrapped
333
- $needsWrap = false;
334
- foreach ($media->children as $child) {
335
- $type = $child[0];
336
- if ($type !== 'block' && $type !== 'media' && $type !== 'directive') {
337
- $needsWrap = true;
338
- break;
339
- }
340
- }
341
 
342
- if ($needsWrap) {
343
- $wrapped = (object)array(
344
- "selectors" => array(),
345
- "children" => $media->children
346
- );
347
- $media->children = array(array("block", $wrapped));
 
348
  }
 
349
 
350
- $this->compileChildren($media->children, $this->scope);
351
-
352
- $this->scope = $this->scope->parent;
 
 
 
353
  }
354
 
 
 
 
355
  $this->popEnv();
356
  }
357
 
@@ -497,7 +484,7 @@ class scssc {
497
  protected function compileChildren($stms, $out) {
498
  foreach ($stms as $stm) {
499
  $ret = $this->compileChild($stm, $out);
500
- if (isset($ret)) return $ret;
501
  }
502
  }
503
 
@@ -505,19 +492,11 @@ class scssc {
505
  $out = "@media";
506
  $first = true;
507
  foreach ($queryList as $query){
508
- $type = null;
509
  $parts = array();
510
  foreach ($query as $q) {
511
  switch ($q[0]) {
512
  case "mediaType":
513
- if ($type) {
514
- $type = $this->mergeMediaTypes($type, array_map(array($this, "compileValue"), array_slice($q, 1)));
515
- if (empty($type)) { // merge failed
516
- return null;
517
- }
518
- } else {
519
- $type = array_map(array($this, "compileValue"), array_slice($q, 1));
520
- }
521
  break;
522
  case "mediaExp":
523
  if (isset($q[2])) {
@@ -528,9 +507,6 @@ class scssc {
528
  break;
529
  }
530
  }
531
- if ($type) {
532
- array_unshift($parts, implode(' ', array_filter($type)));
533
- }
534
  if (!empty($parts)) {
535
  if ($first) {
536
  $first = false;
@@ -544,50 +520,6 @@ class scssc {
544
  return $out;
545
  }
546
 
547
- protected function mergeMediaTypes($type1, $type2) {
548
- if (empty($type1)) {
549
- return $type2;
550
- }
551
- if (empty($type2)) {
552
- return $type1;
553
- }
554
- $m1 = '';
555
- $t1 = '';
556
- if (count($type1) > 1) {
557
- $m1= strtolower($type1[0]);
558
- $t1= strtolower($type1[1]);
559
- } else {
560
- $t1 = strtolower($type1[0]);
561
- }
562
- $m2 = '';
563
- $t2 = '';
564
- if (count($type2) > 1) {
565
- $m2 = strtolower($type2[0]);
566
- $t2 = strtolower($type2[1]);
567
- } else {
568
- $t2 = strtolower($type2[0]);
569
- }
570
- if (($m1 == 'not') ^ ($m2 == 'not')) {
571
- if ($t1 == $t2) {
572
- return null;
573
- }
574
- return array(
575
- $m1 == 'not' ? $m2 : $m1,
576
- $m1 == 'not' ? $t2 : $t1
577
- );
578
- } elseif ($m1 == 'not' && $m2 == 'not') {
579
- # CSS has no way of representing "neither screen nor print"
580
- if ($t1 != $t2) {
581
- return null;
582
- }
583
- return array('not', $t1);
584
- } elseif ($t1 != $t2) {
585
- return null;
586
- } else { // t1 == t2, neither m1 nor m2 are "not"
587
- return array(empty($m1)? $m2 : $m1, $t1);
588
- }
589
- }
590
-
591
  // returns true if the value was something that could be imported
592
  protected function compileImport($rawPath, $out) {
593
  if ($rawPath[0] == "string") {
@@ -778,12 +710,12 @@ class scssc {
778
  $this->env->depth--;
779
  }
780
 
781
- if (isset($content)) {
782
  $content->scope = $callingScope;
783
  $this->setRaw(self::$namespaces["special"] . "content", $content);
784
  }
785
 
786
- if (isset($mixin->args)) {
787
  $this->applyArguments($mixin->args, $argValues);
788
  }
789
 
@@ -796,7 +728,7 @@ class scssc {
796
  break;
797
  case "mixin_content":
798
  $content = $this->get(self::$namespaces["special"] . "content");
799
- if (!isset($content)) {
800
  $this->throwError("Expected @content inside of mixin");
801
  }
802
 
@@ -930,7 +862,7 @@ class scssc {
930
  $out = $this->$fn($left, $right, $shouldEval);
931
  }
932
 
933
- if (isset($out)) {
934
  if ($unitChange && $out[0] == "number") {
935
  $out = $this->coerceUnit($out, $targetUnit);
936
  }
@@ -1006,7 +938,7 @@ class scssc {
1006
  $ret = $this->compileChildren($func->children, $tmp);
1007
  $this->popEnv();
1008
 
1009
- return !isset($ret) ? self::$defaultValue : $ret;
1010
  }
1011
 
1012
  // built in function
@@ -1200,7 +1132,7 @@ class scssc {
1200
  return $this->toBool($left[1] < $right[1]);
1201
  }
1202
 
1203
- public function toBool($thing) {
1204
  return $thing ? self::$true : self::$false;
1205
  }
1206
 
@@ -1248,7 +1180,7 @@ class scssc {
1248
 
1249
  return $h;
1250
  case "number":
1251
- return round($value[1], $this->numberPrecision) . $value[2];
1252
  case "string":
1253
  return $value[1] . $this->compileStringContent($value) . $value[1];
1254
  case "function":
@@ -1383,7 +1315,7 @@ class scssc {
1383
  }
1384
 
1385
  protected function multiplyMedia($env, $childQueries = null) {
1386
- if (!isset($env) ||
1387
  !empty($env->block->type) && $env->block->type != "media")
1388
  {
1389
  return $childQueries;
@@ -1413,11 +1345,11 @@ class scssc {
1413
 
1414
  // convert something to list
1415
  protected function coerceList($item, $delim = ",") {
1416
- if (isset($item) && $item[0] == "list") {
1417
  return $item;
1418
  }
1419
 
1420
- return array("list", $delim, !isset($item) ? array(): array($item));
1421
  }
1422
 
1423
  protected function applyArguments($argDef, $argValues) {
@@ -1519,26 +1451,28 @@ class scssc {
1519
  }
1520
  }
1521
 
 
1522
  protected function setExisting($name, $value, $env = null) {
1523
- if (!isset($env)) $env = $this->getStoreEnv();
1524
 
1525
- if (isset($env->store[$name]) || !isset($env->parent)) {
1526
  $env->store[$name] = $value;
1527
- } else {
1528
  $this->setExisting($name, $value, $env->parent);
 
 
1529
  }
1530
  }
1531
 
1532
  protected function setRaw($name, $value) {
1533
- $env = $this->getStoreEnv();
1534
- $env->store[$name] = $value;
1535
  }
1536
 
1537
- public function get($name, $defaultValue = null, $env = null) {
1538
  $name = $this->normalizeName($name);
1539
 
1540
- if (!isset($env)) $env = $this->getStoreEnv();
1541
- if (!isset($defaultValue)) $defaultValue = self::$defaultValue;
1542
 
1543
  if (isset($env->store[$name])) {
1544
  return $env->store[$name];
@@ -1567,10 +1501,6 @@ class scssc {
1567
  $this->importPaths = (array)$path;
1568
  }
1569
 
1570
- public function setNumberPrecision($numberPrecision) {
1571
- $this->numberPrecision = $numberPrecision;
1572
- }
1573
-
1574
  public function setFormatter($formatterName) {
1575
  $this->formatter = $formatterName;
1576
  }
@@ -1604,7 +1534,7 @@ class scssc {
1604
  }
1605
 
1606
  // results the file path for an import url if it exists
1607
- public function findImport($url) {
1608
  $urls = array();
1609
 
1610
  // for "normal" scss imports (ignore vanilla css and external requests)
@@ -1648,8 +1578,9 @@ class scssc {
1648
  $name = $this->normalizeName($name);
1649
  $libName = "lib_".$name;
1650
  $f = array($this, $libName);
 
 
1651
  if (is_callable($f)) {
1652
- $prototype = isset(self::$$libName) ? self::$$libName : null;
1653
  $sorted = $this->sortArgs($prototype, $args);
1654
  foreach ($sorted as &$val) {
1655
  $val = $this->reduce($val, true);
@@ -1698,7 +1629,7 @@ class scssc {
1698
  }
1699
  }
1700
 
1701
- if (!isset($prototype)) return $posArgs;
1702
 
1703
  $finalArgs = array();
1704
  foreach ($prototype as $i => $names) {
@@ -1738,10 +1669,10 @@ class scssc {
1738
  case "keyword":
1739
  $name = $value[1];
1740
  if (isset(self::$cssColors[$name])) {
1741
- $rgba = explode(',', self::$cssColors[$name]);
1742
- return isset($rgba[3])
1743
- ? array('color', (int) $rgba[0], (int) $rgba[1], (int) $rgba[2], (int) $rgba[3])
1744
- : array('color', (int) $rgba[0], (int) $rgba[1], (int) $rgba[2]);
1745
  }
1746
  return null;
1747
  }
@@ -1759,18 +1690,18 @@ class scssc {
1759
  return null;
1760
  }
1761
 
1762
- public function assertList($value) {
1763
  if ($value[0] != "list")
1764
  $this->throwError("expecting list");
1765
  return $value;
1766
  }
1767
 
1768
- public function assertColor($value) {
1769
  if ($color = $this->coerceColor($value)) return $color;
1770
  $this->throwError("expecting color");
1771
  }
1772
 
1773
- public function assertNumber($value) {
1774
  if ($value[0] != "number")
1775
  $this->throwError("expecting number");
1776
  return $value[1];
@@ -1796,34 +1727,36 @@ class scssc {
1796
  return $c;
1797
  }
1798
 
1799
- public function toHSL($red, $green, $blue) {
1800
- $min = min($red, $green, $blue);
1801
- $max = max($red, $green, $blue);
 
1802
 
1803
- $l = $min + $max;
 
 
 
1804
 
1805
  if ($min == $max) {
1806
  $s = $h = 0;
1807
  } else {
1808
- $d = $max - $min;
1809
-
1810
- if ($l < 255)
1811
- $s = $d / $l;
1812
  else
1813
- $s = $d / (510 - $l);
1814
 
1815
- if ($red == $max)
1816
- $h = 60 * ($green - $blue) / $d;
1817
- elseif ($green == $max)
1818
- $h = 60 * ($blue - $red) / $d + 120;
1819
- elseif ($blue == $max)
1820
- $h = 60 * ($red - $green) / $d + 240;
1821
  }
1822
 
1823
- return array('hsl', fmod($h, 360), $s * 100, $l / 5.1);
1824
  }
1825
 
1826
- public function hueToRGB($m1, $m2, $h) {
1827
  if ($h < 0)
1828
  $h += 1;
1829
  elseif ($h > 1)
@@ -1842,7 +1775,7 @@ class scssc {
1842
  }
1843
 
1844
  // H from 0 to 360, S and L from 0 to 100
1845
- public function toRGB($hue, $saturation, $lightness) {
1846
  if ($hue < 0) {
1847
  $hue += 360;
1848
  }
@@ -1867,7 +1800,7 @@ class scssc {
1867
  protected static $lib_if = array("condition", "if-true", "if-false");
1868
  protected function lib_if($args) {
1869
  list($cond,$t, $f) = $args;
1870
- if (!$this->isTruthy($cond)) return $f;
1871
  return $t;
1872
  }
1873
 
@@ -1896,7 +1829,7 @@ class scssc {
1896
  "green", "blue", "alpha");
1897
  protected function lib_rgba($args) {
1898
  if ($color = $this->coerceColor($args[0])) {
1899
- $num = !isset($args[1]) ? $args[3] : $args[1];
1900
  $alpha = $this->assertNumber($num);
1901
  $color[4] = $alpha;
1902
  return $color;
@@ -1911,7 +1844,7 @@ class scssc {
1911
  $color = $this->assertColor($args[0]);
1912
 
1913
  foreach (array(1,2,3,7) as $i) {
1914
- if (isset($args[$i])) {
1915
  $val = $this->assertNumber($args[$i]);
1916
  $ii = $i == 7 ? 4 : $i; // alpha
1917
  $color[$ii] =
@@ -1919,10 +1852,10 @@ class scssc {
1919
  }
1920
  }
1921
 
1922
- if (isset($args[4]) || isset($args[5]) || isset($args[6])) {
1923
  $hsl = $this->toHSL($color[1], $color[2], $color[3]);
1924
  foreach (array(4,5,6) as $i) {
1925
- if (isset($args[$i])) {
1926
  $val = $this->assertNumber($args[$i]);
1927
  $hsl[$i - 3] = $this->$fn($hsl[$i - 3], $val, $i);
1928
  }
@@ -2040,7 +1973,7 @@ class scssc {
2040
  $first = $this->assertColor($first);
2041
  $second = $this->assertColor($second);
2042
 
2043
- if (!isset($weight)) {
2044
  $weight = 0.5;
2045
  } else {
2046
  $weight = $this->coercePercent($weight);
@@ -2315,7 +2248,7 @@ class scssc {
2315
  }
2316
 
2317
  protected function listSeparatorForJoin($list1, $sep) {
2318
- if (!isset($sep)) return $list1[1];
2319
  switch ($this->compileValue($sep)) {
2320
  case "comma":
2321
  return ",";
@@ -2422,7 +2355,7 @@ class scssc {
2422
  return array('string', '', array('counter(' . implode(',', $list) . ')'));
2423
  }
2424
 
2425
- public function throwError($msg = null) {
2426
  if (func_num_args() > 1) {
2427
  $msg = call_user_func_array("sprintf", func_get_args());
2428
  }
@@ -2627,7 +2560,7 @@ class scss_parser {
2627
  static protected $commentMultiLeft = "/*";
2628
  static protected $commentMultiRight = "*/";
2629
 
2630
- public function __construct($sourceName = null, $rootParser = true) {
2631
  $this->sourceName = $sourceName;
2632
  $this->rootParser = $rootParser;
2633
 
@@ -2647,7 +2580,7 @@ class scss_parser {
2647
  $operators)).')';
2648
  }
2649
 
2650
- public function parse($buffer) {
2651
  $this->count = 0;
2652
  $this->env = null;
2653
  $this->inParens = false;
@@ -2869,7 +2802,7 @@ class scss_parser {
2869
  }
2870
 
2871
  $last = $this->last();
2872
- if (isset($last) && $last[0] == "if") {
2873
  list(, $if) = $last;
2874
  if ($this->literal("@else")) {
2875
  if ($this->literal("{")) {
@@ -3023,7 +2956,7 @@ class scss_parser {
3023
  }
3024
 
3025
  protected function literal($what, $eatWhitespace = null) {
3026
- if (!isset($eatWhitespace)) $eatWhitespace = $this->eatWhiteDefault;
3027
 
3028
  // shortcut on single letter
3029
  if (!isset($what[1]) && isset($this->buffer[$this->count])) {
@@ -3952,7 +3885,7 @@ class scss_parser {
3952
  }
3953
 
3954
  public function throwParseError($msg = "parse error", $count = null) {
3955
- $count = !isset($count) ? $this->count : $count;
3956
 
3957
  $line = $this->getLineNo($count);
3958
 
@@ -3987,7 +3920,7 @@ class scss_parser {
3987
  $token = null;
3988
 
3989
  $end = strpos($this->buffer, "\n", $this->count);
3990
- if ($end === false || $this->buffer[$end - 1] == '\\' || $this->buffer[$end - 2] == '\\' && $this->buffer[$end - 1] == "\r") {
3991
  $end = strlen($this->buffer);
3992
  }
3993
 
@@ -4017,7 +3950,7 @@ class scss_parser {
4017
 
4018
  // try to match something on head of buffer
4019
  protected function match($regex, &$out, $eatWhitespace = null) {
4020
- if (!isset($eatWhitespace)) $eatWhitespace = $this->eatWhiteDefault;
4021
 
4022
  $r = '/'.$regex.'/Ais';
4023
  if (preg_match($r, $this->buffer, $out, null, $this->count)) {
@@ -4045,7 +3978,7 @@ class scss_parser {
4045
  }
4046
 
4047
  protected function peek($regex, &$out, $from=null) {
4048
- if (!isset($from)) $from = $this->count;
4049
 
4050
  $r = '/'.$regex.'/Ais';
4051
  $result = preg_match($r, $this->buffer, $out, null, $from);
@@ -4375,12 +4308,10 @@ class scss_server {
4375
 
4376
  /**
4377
  * Compile requested scss and serve css. Outputs HTTP response.
4378
- *
4379
- * @param string $salt Prefix a string to the filename for creating the cache name hash
4380
  */
4381
- public function serve($salt = '') {
4382
  if ($input = $this->findInput()) {
4383
- $output = $this->cacheName($salt . $input);
4384
  header('Content-type: text/css');
4385
 
4386
  if ($this->needsCompile($input, $output)) {
@@ -4414,14 +4345,14 @@ class scss_server {
4414
  public function __construct($dir, $cacheDir=null, $scss=null) {
4415
  $this->dir = $dir;
4416
 
4417
- if (!isset($cacheDir)) {
4418
  $cacheDir = $this->join($dir, 'scss_cache');
4419
  }
4420
 
4421
  $this->cacheDir = $cacheDir;
4422
  if (!is_dir($this->cacheDir)) mkdir($this->cacheDir, 0755, true);
4423
 
4424
- if (!isset($scss)) {
4425
  $scss = new scssc();
4426
  $scss->setImportPaths($this->dir);
4427
  }
43
  * @author Leaf Corcoran <leafot@gmail.com>
44
  */
45
  class scssc {
46
+ static public $VERSION = "v0.0.8";
47
 
48
  static protected $operatorNames = array(
49
  '+' => "add",
67
  "function" => "^",
68
  );
69
 
70
+ static protected $numberPrecision = 5;
71
  static protected $unitTable = array(
72
  "in" => array(
73
  "in" => 1,
91
 
92
  protected $userFunctions = array();
93
 
 
 
94
  protected $formatter = "scss_formatter_nested";
95
 
96
+ function compile($code, $name=null) {
97
  $this->indentLevel = -1;
98
  $this->commentsSeen = array();
99
  $this->extends = array();
186
  $rem = array_diff($single, $target);
187
 
188
  foreach ($origin as $j => $new) {
 
 
 
 
 
 
 
189
  $origin[$j][count($origin[$j]) - 1] = $this->combineSelectorSingle(end($new), $rem);
190
  }
191
 
310
 
311
  protected function compileMedia($media) {
312
  $this->pushEnv($media);
313
+ $parentScope = $this->mediaParent($this->scope);
314
 
315
+ $this->scope = $this->makeOutputBlock("media", array(
316
+ $this->compileMediaQuery($this->multiplyMedia($this->env)))
317
+ );
 
 
 
 
 
 
318
 
319
+ $parentScope->children[] = $this->scope;
 
 
 
 
 
 
 
 
320
 
321
+ // top level properties in a media cause it to be wrapped
322
+ $needsWrap = false;
323
+ foreach ($media->children as $child) {
324
+ $type = $child[0];
325
+ if ($type !== 'block' && $type !== 'media' && $type !== 'directive') {
326
+ $needsWrap = true;
327
+ break;
328
  }
329
+ }
330
 
331
+ if ($needsWrap) {
332
+ $wrapped = (object)array(
333
+ "selectors" => array(),
334
+ "children" => $media->children
335
+ );
336
+ $media->children = array(array("block", $wrapped));
337
  }
338
 
339
+ $this->compileChildren($media->children, $this->scope);
340
+
341
+ $this->scope = $this->scope->parent;
342
  $this->popEnv();
343
  }
344
 
484
  protected function compileChildren($stms, $out) {
485
  foreach ($stms as $stm) {
486
  $ret = $this->compileChild($stm, $out);
487
+ if (!is_null($ret)) return $ret;
488
  }
489
  }
490
 
492
  $out = "@media";
493
  $first = true;
494
  foreach ($queryList as $query){
 
495
  $parts = array();
496
  foreach ($query as $q) {
497
  switch ($q[0]) {
498
  case "mediaType":
499
+ $parts[] = implode(" ", array_map(array($this, "compileValue"), array_slice($q, 1)));
 
 
 
 
 
 
 
500
  break;
501
  case "mediaExp":
502
  if (isset($q[2])) {
507
  break;
508
  }
509
  }
 
 
 
510
  if (!empty($parts)) {
511
  if ($first) {
512
  $first = false;
520
  return $out;
521
  }
522
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
523
  // returns true if the value was something that could be imported
524
  protected function compileImport($rawPath, $out) {
525
  if ($rawPath[0] == "string") {
710
  $this->env->depth--;
711
  }
712
 
713
+ if (!is_null($content)) {
714
  $content->scope = $callingScope;
715
  $this->setRaw(self::$namespaces["special"] . "content", $content);
716
  }
717
 
718
+ if (!is_null($mixin->args)) {
719
  $this->applyArguments($mixin->args, $argValues);
720
  }
721
 
728
  break;
729
  case "mixin_content":
730
  $content = $this->get(self::$namespaces["special"] . "content");
731
+ if (is_null($content)) {
732
  $this->throwError("Expected @content inside of mixin");
733
  }
734
 
862
  $out = $this->$fn($left, $right, $shouldEval);
863
  }
864
 
865
+ if (!is_null($out)) {
866
  if ($unitChange && $out[0] == "number") {
867
  $out = $this->coerceUnit($out, $targetUnit);
868
  }
938
  $ret = $this->compileChildren($func->children, $tmp);
939
  $this->popEnv();
940
 
941
+ return is_null($ret) ? self::$defaultValue : $ret;
942
  }
943
 
944
  // built in function
1132
  return $this->toBool($left[1] < $right[1]);
1133
  }
1134
 
1135
+ protected function toBool($thing) {
1136
  return $thing ? self::$true : self::$false;
1137
  }
1138
 
1180
 
1181
  return $h;
1182
  case "number":
1183
+ return round($value[1], self::$numberPrecision) . $value[2];
1184
  case "string":
1185
  return $value[1] . $this->compileStringContent($value) . $value[1];
1186
  case "function":
1315
  }
1316
 
1317
  protected function multiplyMedia($env, $childQueries = null) {
1318
+ if (is_null($env) ||
1319
  !empty($env->block->type) && $env->block->type != "media")
1320
  {
1321
  return $childQueries;
1345
 
1346
  // convert something to list
1347
  protected function coerceList($item, $delim = ",") {
1348
+ if (!is_null($item) && $item[0] == "list") {
1349
  return $item;
1350
  }
1351
 
1352
+ return array("list", $delim, is_null($item) ? array(): array($item));
1353
  }
1354
 
1355
  protected function applyArguments($argDef, $argValues) {
1451
  }
1452
  }
1453
 
1454
+ // todo: this is bugged?
1455
  protected function setExisting($name, $value, $env = null) {
1456
+ if (is_null($env)) $env = $this->getStoreEnv();
1457
 
1458
+ if (isset($env->store[$name])) {
1459
  $env->store[$name] = $value;
1460
+ } elseif (!is_null($env->parent)) {
1461
  $this->setExisting($name, $value, $env->parent);
1462
+ } else {
1463
+ $this->env->store[$name] = $value;
1464
  }
1465
  }
1466
 
1467
  protected function setRaw($name, $value) {
1468
+ $this->env->store[$name] = $value;
 
1469
  }
1470
 
1471
+ protected function get($name, $defaultValue = null, $env = null) {
1472
  $name = $this->normalizeName($name);
1473
 
1474
+ if (is_null($env)) $env = $this->getStoreEnv();
1475
+ if (is_null($defaultValue)) $defaultValue = self::$defaultValue;
1476
 
1477
  if (isset($env->store[$name])) {
1478
  return $env->store[$name];
1501
  $this->importPaths = (array)$path;
1502
  }
1503
 
 
 
 
 
1504
  public function setFormatter($formatterName) {
1505
  $this->formatter = $formatterName;
1506
  }
1534
  }
1535
 
1536
  // results the file path for an import url if it exists
1537
+ protected function findImport($url) {
1538
  $urls = array();
1539
 
1540
  // for "normal" scss imports (ignore vanilla css and external requests)
1578
  $name = $this->normalizeName($name);
1579
  $libName = "lib_".$name;
1580
  $f = array($this, $libName);
1581
+ $prototype = isset(self::$$libName) ? self::$$libName : null;
1582
+
1583
  if (is_callable($f)) {
 
1584
  $sorted = $this->sortArgs($prototype, $args);
1585
  foreach ($sorted as &$val) {
1586
  $val = $this->reduce($val, true);
1629
  }
1630
  }
1631
 
1632
+ if (is_null($prototype)) return $posArgs;
1633
 
1634
  $finalArgs = array();
1635
  foreach ($prototype as $i => $names) {
1669
  case "keyword":
1670
  $name = $value[1];
1671
  if (isset(self::$cssColors[$name])) {
1672
+ @list($r, $g, $b, $a) = explode(',', self::$cssColors[$name]);
1673
+ return isset($a)
1674
+ ? array('color', (int) $r, (int) $g, (int) $b, (int) $a)
1675
+ : array('color', (int) $r, (int) $g, (int) $b);
1676
  }
1677
  return null;
1678
  }
1690
  return null;
1691
  }
1692
 
1693
+ protected function assertList($value) {
1694
  if ($value[0] != "list")
1695
  $this->throwError("expecting list");
1696
  return $value;
1697
  }
1698
 
1699
+ protected function assertColor($value) {
1700
  if ($color = $this->coerceColor($value)) return $color;
1701
  $this->throwError("expecting color");
1702
  }
1703
 
1704
+ protected function assertNumber($value) {
1705
  if ($value[0] != "number")
1706
  $this->throwError("expecting number");
1707
  return $value[1];
1727
  return $c;
1728
  }
1729
 
1730
+ function toHSL($red, $green, $blue) {
1731
+ $r = $red / 255;
1732
+ $g = $green / 255;
1733
+ $b = $blue / 255;
1734
 
1735
+ $min = min($r, $g, $b);
1736
+ $max = max($r, $g, $b);
1737
+ $d = $max - $min;
1738
+ $l = ($min + $max) / 2;
1739
 
1740
  if ($min == $max) {
1741
  $s = $h = 0;
1742
  } else {
1743
+ if ($l < 0.5)
1744
+ $s = $d / (2 * $l);
 
 
1745
  else
1746
+ $s = $d / (2 - 2 * $l);
1747
 
1748
+ if ($r == $max)
1749
+ $h = 60 * ($g - $b) / $d;
1750
+ elseif ($g == $max)
1751
+ $h = 60 * ($b - $r) / $d + 120;
1752
+ elseif ($b == $max)
1753
+ $h = 60 * ($r - $g) / $d + 240;
1754
  }
1755
 
1756
+ return array('hsl', fmod($h, 360), $s * 100, $l * 100);
1757
  }
1758
 
1759
+ function hueToRGB($m1, $m2, $h) {
1760
  if ($h < 0)
1761
  $h += 1;
1762
  elseif ($h > 1)
1775
  }
1776
 
1777
  // H from 0 to 360, S and L from 0 to 100
1778
+ function toRGB($hue, $saturation, $lightness) {
1779
  if ($hue < 0) {
1780
  $hue += 360;
1781
  }
1800
  protected static $lib_if = array("condition", "if-true", "if-false");
1801
  protected function lib_if($args) {
1802
  list($cond,$t, $f) = $args;
1803
+ if ($cond == self::$false) return $f;
1804
  return $t;
1805
  }
1806
 
1829
  "green", "blue", "alpha");
1830
  protected function lib_rgba($args) {
1831
  if ($color = $this->coerceColor($args[0])) {
1832
+ $num = is_null($args[1]) ? $args[3] : $args[1];
1833
  $alpha = $this->assertNumber($num);
1834
  $color[4] = $alpha;
1835
  return $color;
1844
  $color = $this->assertColor($args[0]);
1845
 
1846
  foreach (array(1,2,3,7) as $i) {
1847
+ if (!is_null($args[$i])) {
1848
  $val = $this->assertNumber($args[$i]);
1849
  $ii = $i == 7 ? 4 : $i; // alpha
1850
  $color[$ii] =
1852
  }
1853
  }
1854
 
1855
+ if (!is_null($args[4]) || !is_null($args[5]) || !is_null($args[6])) {
1856
  $hsl = $this->toHSL($color[1], $color[2], $color[3]);
1857
  foreach (array(4,5,6) as $i) {
1858
+ if (!is_null($args[$i])) {
1859
  $val = $this->assertNumber($args[$i]);
1860
  $hsl[$i - 3] = $this->$fn($hsl[$i - 3], $val, $i);
1861
  }
1973
  $first = $this->assertColor($first);
1974
  $second = $this->assertColor($second);
1975
 
1976
+ if (is_null($weight)) {
1977
  $weight = 0.5;
1978
  } else {
1979
  $weight = $this->coercePercent($weight);
2248
  }
2249
 
2250
  protected function listSeparatorForJoin($list1, $sep) {
2251
+ if (is_null($sep)) return $list1[1];
2252
  switch ($this->compileValue($sep)) {
2253
  case "comma":
2254
  return ",";
2355
  return array('string', '', array('counter(' . implode(',', $list) . ')'));
2356
  }
2357
 
2358
+ protected function throwError($msg = null) {
2359
  if (func_num_args() > 1) {
2360
  $msg = call_user_func_array("sprintf", func_get_args());
2361
  }
2560
  static protected $commentMultiLeft = "/*";
2561
  static protected $commentMultiRight = "*/";
2562
 
2563
+ function __construct($sourceName = null, $rootParser = true) {
2564
  $this->sourceName = $sourceName;
2565
  $this->rootParser = $rootParser;
2566
 
2580
  $operators)).')';
2581
  }
2582
 
2583
+ function parse($buffer) {
2584
  $this->count = 0;
2585
  $this->env = null;
2586
  $this->inParens = false;
2802
  }
2803
 
2804
  $last = $this->last();
2805
+ if (!is_null($last) && $last[0] == "if") {
2806
  list(, $if) = $last;
2807
  if ($this->literal("@else")) {
2808
  if ($this->literal("{")) {
2956
  }
2957
 
2958
  protected function literal($what, $eatWhitespace = null) {
2959
+ if (is_null($eatWhitespace)) $eatWhitespace = $this->eatWhiteDefault;
2960
 
2961
  // shortcut on single letter
2962
  if (!isset($what[1]) && isset($this->buffer[$this->count])) {
3885
  }
3886
 
3887
  public function throwParseError($msg = "parse error", $count = null) {
3888
+ $count = is_null($count) ? $this->count : $count;
3889
 
3890
  $line = $this->getLineNo($count);
3891
 
3920
  $token = null;
3921
 
3922
  $end = strpos($this->buffer, "\n", $this->count);
3923
+ if ($end === false) {
3924
  $end = strlen($this->buffer);
3925
  }
3926
 
3950
 
3951
  // try to match something on head of buffer
3952
  protected function match($regex, &$out, $eatWhitespace = null) {
3953
+ if (is_null($eatWhitespace)) $eatWhitespace = $this->eatWhiteDefault;
3954
 
3955
  $r = '/'.$regex.'/Ais';
3956
  if (preg_match($r, $this->buffer, $out, null, $this->count)) {
3978
  }
3979
 
3980
  protected function peek($regex, &$out, $from=null) {
3981
+ if (is_null($from)) $from = $this->count;
3982
 
3983
  $r = '/'.$regex.'/Ais';
3984
  $result = preg_match($r, $this->buffer, $out, null, $from);
4308
 
4309
  /**
4310
  * Compile requested scss and serve css. Outputs HTTP response.
 
 
4311
  */
4312
+ public function serve() {
4313
  if ($input = $this->findInput()) {
4314
+ $output = $this->cacheName($input);
4315
  header('Content-type: text/css');
4316
 
4317
  if ($this->needsCompile($input, $output)) {
4345
  public function __construct($dir, $cacheDir=null, $scss=null) {
4346
  $this->dir = $dir;
4347
 
4348
+ if (is_null($cacheDir)) {
4349
  $cacheDir = $this->join($dir, 'scss_cache');
4350
  }
4351
 
4352
  $this->cacheDir = $cacheDir;
4353
  if (!is_dir($this->cacheDir)) mkdir($this->cacheDir, 0755, true);
4354
 
4355
+ if (is_null($scss)) {
4356
  $scss = new scssc();
4357
  $scss->setImportPaths($this->dir);
4358
  }
wp-scss.php CHANGED
@@ -1,9 +1,9 @@
1
- <?php
2
  /**
3
  * Plugin Name: WP-SCSS
4
  * Plugin URI: https://github.com/ConnectThink/WP-SCSS
5
  * Description: Compiles scss files live on wordpress.
6
- * Version: 1.1.6
7
  * Author: Connect Think
8
  * Author URI: http://connectthink.com
9
  * License: GPLv3
@@ -30,7 +30,7 @@
30
 
31
  // Plugin Paths
32
  if (!defined('WPSCSS_THEME_DIR'))
33
- define('WPSCSS_THEME_DIR', get_stylesheet_directory());
34
 
35
  if (!defined('WPSCSS_PLUGIN_NAME'))
36
  define('WPSCSS_PLUGIN_NAME', trim(dirname(plugin_basename(__FILE__)), '/'));
@@ -46,7 +46,7 @@ if (!defined('WPSCSS_VERSION_KEY'))
46
  define('WPSCSS_VERSION_KEY', 'wpscss_version');
47
 
48
  if (!defined('WPSCSS_VERSION_NUM'))
49
- define('WPSCSS_VERSION_NUM', '1.1.6');
50
 
51
  // Add version to options table
52
  add_option(WPSCSS_VERSION_KEY, WPSCSS_VERSION_NUM);
@@ -54,8 +54,8 @@ add_option(WPSCSS_VERSION_KEY, WPSCSS_VERSION_NUM);
54
 
55
  /*
56
  * 2. REQUIRE DEPENDANCIES
57
- *
58
- * scssphp - scss compiler
59
  * class-wp-scss
60
  * options.php - settings for plugin page
61
  */
@@ -67,9 +67,9 @@ include_once WPSCSS_PLUGIN_DIR . '/options.php'; // Options page class
67
 
68
  /**
69
  * 3. REGISTER SETTINGS
70
- *
71
  * Instantiate Options Page
72
- * Create link on plugin page to settings page
73
  */
74
 
75
  if( is_admin() ) {
@@ -93,9 +93,9 @@ function wpscss_plugin_action_links($links, $file) {
93
  }
94
 
95
 
96
- /**
97
  * 4. PLUGIN SETTINGS
98
- *
99
  * Pull settings from options table
100
  * Scrub empty fields or directories that don't exists
101
  * Assign settings via settings array to pass to object
@@ -105,7 +105,7 @@ $wpscss_options = get_option( 'wpscss_options' );
105
  $scss_dir_setting = $wpscss_options['scss_dir'];
106
  $css_dir_setting = $wpscss_options['css_dir'];
107
 
108
- // Checks if directories are empty
109
  if( $scss_dir_setting == false || $css_dir_setting == false ) {
110
  function wpscss_settings_error() {
111
  echo '<div class="error">
@@ -130,9 +130,9 @@ if( $scss_dir_setting == false || $css_dir_setting == false ) {
130
  $wpscss_settings = array(
131
  'scss_dir' => WPSCSS_THEME_DIR . $scss_dir_setting,
132
  'css_dir' => WPSCSS_THEME_DIR . $css_dir_setting,
133
- 'compiling' => $wpscss_options['compiling_options'],
134
  'errors' => $wpscss_options['errors'],
135
- 'enqueue' => isset($wpscss_options['enqueue']) ? $wpscss_options['enqueue'] : 0
136
  );
137
 
138
 
@@ -158,62 +158,55 @@ if ( $wpscss_compiler->needs_compiling() ) {
158
  /**
159
  * 6. HANDLE COMPILING ERRORS
160
  *
161
- * First block handles print errors to front end.
162
  * This adds a small style block the header to help errors get noticed
163
  *
164
- * Second block handles print errors to log file.
165
- * After the file gets over 1MB it does a purge and deletes the first
166
- * half of entries in the file.
167
  */
168
  $log_file = $wpscss_compiler->scss_dir.'error_log.log';
169
 
170
- function wpscss_error_styles() {
171
- echo
172
- '<style>
173
- .scss_errors {
174
- position: fixed;
175
- top: 0px;
176
- z-index: 99999;
177
- width: 100%;
178
- }
179
- .scss_errors pre {
180
- background: #f5f5f5;
181
- border-left: 5px solid #DD3D36;
182
- box-shadow: 0 2px 3px rgba(51,51,51, .4);
183
- color: #666;
184
- font-family: monospace;
185
- font-size: 14px;
186
- margin: 20px 0;
187
- overflow: auto;
188
- padding: 20px;
189
- white-space: pre;
190
- white-space: pre-wrap;
191
- word-wrap: break-word;
192
- }
193
- </style>';
194
- }
195
-
196
- function wpscss_settings_show_errors($errors) {
197
  echo '<div class="scss_errors"><pre>';
198
  echo '<h6 style="margin: 15px 0;">Sass Compiling Error</h6>';
199
-
200
- foreach( $errors as $error) {
201
  echo '<p class="sass_error">';
202
- echo '<strong>'. $error['file'] .'</strong> <br/><em>"'. $error['message'] .'"</em>';
203
  echo '<p class="sass_error">';
204
  }
205
 
206
  echo '</pre></div>';
207
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  add_action('wp_print_styles', 'wpscss_error_styles');
209
- }
210
 
211
- // Show to logged in users: All the methods for checking user login are set up later in the WP flow, so this only checks that there is a cookie
212
- if ( !is_admin() && $wpscss_settings['errors'] === 'show-logged-in' && !empty($_COOKIE[LOGGED_IN_COOKIE]) && count($wpscss_compiler->compile_errors) > 0) {
213
- wpscss_settings_show_errors($wpscss_compiler->compile_errors);
214
- // Show in the header to anyone
215
- } else if ( !is_admin() && $wpscss_settings['errors'] === 'show' && count($wpscss_compiler->compile_errors) > 0) {
216
- wpscss_settings_show_errors($wpscss_compiler->compile_errors);
217
  } else { // Hide errors and print them to a log file.
218
  foreach ($wpscss_compiler->compile_errors as $error) {
219
  $error_string = date('m/d/y g:i:s', time()) .': ';
@@ -242,7 +235,7 @@ if ( file_exists($log_file) ) {
242
  if ( $wpscss_settings['enqueue'] == '1' ) {
243
  function wpscss_enqueue_styles() {
244
  global $wpscss_compiler, $wpscss_options;
245
- $wpscss_compiler->enqueue_files($wpscss_options['css_dir']);
246
  }
247
  add_action('wp_enqueue_scripts', 'wpscss_enqueue_styles', 50);
248
  }
1
+ <?php
2
  /**
3
  * Plugin Name: WP-SCSS
4
  * Plugin URI: https://github.com/ConnectThink/WP-SCSS
5
  * Description: Compiles scss files live on wordpress.
6
+ * Version: 1.0.0
7
  * Author: Connect Think
8
  * Author URI: http://connectthink.com
9
  * License: GPLv3
30
 
31
  // Plugin Paths
32
  if (!defined('WPSCSS_THEME_DIR'))
33
+ define('WPSCSS_THEME_DIR', ABSPATH . 'wp-content/themes/' . get_stylesheet());
34
 
35
  if (!defined('WPSCSS_PLUGIN_NAME'))
36
  define('WPSCSS_PLUGIN_NAME', trim(dirname(plugin_basename(__FILE__)), '/'));
46
  define('WPSCSS_VERSION_KEY', 'wpscss_version');
47
 
48
  if (!defined('WPSCSS_VERSION_NUM'))
49
+ define('WPSCSS_VERSION_NUM', '1.0.0');
50
 
51
  // Add version to options table
52
  add_option(WPSCSS_VERSION_KEY, WPSCSS_VERSION_NUM);
54
 
55
  /*
56
  * 2. REQUIRE DEPENDANCIES
57
+ *
58
+ * scssphp - scss compiler
59
  * class-wp-scss
60
  * options.php - settings for plugin page
61
  */
67
 
68
  /**
69
  * 3. REGISTER SETTINGS
70
+ *
71
  * Instantiate Options Page
72
+ * Create link on plugin page to settings page
73
  */
74
 
75
  if( is_admin() ) {
93
  }
94
 
95
 
96
+ /**
97
  * 4. PLUGIN SETTINGS
98
+ *
99
  * Pull settings from options table
100
  * Scrub empty fields or directories that don't exists
101
  * Assign settings via settings array to pass to object
105
  $scss_dir_setting = $wpscss_options['scss_dir'];
106
  $css_dir_setting = $wpscss_options['css_dir'];
107
 
108
+ // Checks if directories are empty
109
  if( $scss_dir_setting == false || $css_dir_setting == false ) {
110
  function wpscss_settings_error() {
111
  echo '<div class="error">
130
  $wpscss_settings = array(
131
  'scss_dir' => WPSCSS_THEME_DIR . $scss_dir_setting,
132
  'css_dir' => WPSCSS_THEME_DIR . $css_dir_setting,
133
+ 'compiling' => $wpscss_options['compiling_options'],
134
  'errors' => $wpscss_options['errors'],
135
+ 'enqueue' => $wpscss_options['enqueue']
136
  );
137
 
138
 
158
  /**
159
  * 6. HANDLE COMPILING ERRORS
160
  *
161
+ * First block handles print errors to front end.
162
  * This adds a small style block the header to help errors get noticed
163
  *
164
+ * Second block handles print errors to log file.
165
+ * After the file gets over 1MB it does a purge and deletes the first
166
+ * half of entries in the file.
167
  */
168
  $log_file = $wpscss_compiler->scss_dir.'error_log.log';
169
 
170
+ if ( !is_admin() && $wpscss_settings['errors'] === 'show' && count($wpscss_compiler->compile_errors) > 0) {
171
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  echo '<div class="scss_errors"><pre>';
173
  echo '<h6 style="margin: 15px 0;">Sass Compiling Error</h6>';
174
+
175
+ foreach( $wpscss_compiler->compile_errors as $error) {
176
  echo '<p class="sass_error">';
177
+ echo '<strong>'. $error['file'] .'</strong> <br/><em>"'. $error['message'] .'"</em>';
178
  echo '<p class="sass_error">';
179
  }
180
 
181
  echo '</pre></div>';
182
 
183
+ function wpscss_error_styles() {
184
+ echo
185
+ '<style>
186
+ .scss_errors {
187
+ position: fixed;
188
+ top: 0px;
189
+ z-index: 99999;
190
+ width: 100%;
191
+ }
192
+ .scss_errors pre {
193
+ background: #f5f5f5;
194
+ border-left: 5px solid #DD3D36;
195
+ box-shadow: 0 2px 3px rgba(51,51,51, .4);
196
+ color: #666;
197
+ font-family: monospace;
198
+ font-size: 14px;
199
+ margin: 20px 0;
200
+ overflow: auto;
201
+ padding: 20px;
202
+ white-space: pre;
203
+ white-space: pre-wrap;
204
+ word-wrap: break-word;
205
+ }
206
+ </style>';
207
+ }
208
  add_action('wp_print_styles', 'wpscss_error_styles');
 
209
 
 
 
 
 
 
 
210
  } else { // Hide errors and print them to a log file.
211
  foreach ($wpscss_compiler->compile_errors as $error) {
212
  $error_string = date('m/d/y g:i:s', time()) .': ';
235
  if ( $wpscss_settings['enqueue'] == '1' ) {
236
  function wpscss_enqueue_styles() {
237
  global $wpscss_compiler, $wpscss_options;
238
+ $wpscss_compiler->enqueue_files($wpscss_options['css_dir']);
239
  }
240
  add_action('wp_enqueue_scripts', 'wpscss_enqueue_styles', 50);
241
  }