Version Description
- Added filter to set variables via PHP @ohlle
- Added option to minify CSS output @mndewitt
Download this release
Release Info
Developer | connectthink |
Plugin | WP-SCSS |
Version | 1.1.9 |
Comparing to | |
See all releases |
Code changes from version 1.1.0 to 1.1.9
- class/class-wp-scss.php +45 -36
- options.php +4 -2
- readme.txt +40 -12
- scssphp/scss.inc.php +367 -138
- wp-scss.php +96 -66
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));
|
@@ -71,34 +71,34 @@ class Wp_Scss {
|
|
71 |
}
|
72 |
} else {
|
73 |
$errors = array (
|
74 |
-
'file' =>
|
75 |
'message' => "File Permission Error, permission denied. Please make the cache directory writable."
|
76 |
);
|
77 |
array_push($instance->compile_errors, $errors);
|
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,64 @@ 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
|
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
|
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(),
|
@@ -191,4 +195,9 @@ class Wp_Scss {
|
|
191 |
}
|
192 |
}
|
193 |
|
194 |
-
|
|
|
|
|
|
|
|
|
|
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));
|
71 |
}
|
72 |
} else {
|
73 |
$errors = array (
|
74 |
+
'file' => $cache,
|
75 |
'message' => "File Permission Error, permission denied. Please make the cache directory writable."
|
76 |
);
|
77 |
array_push($instance->compile_errors, $errors);
|
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 |
+
if (defined('WP_SCSS_ALWAYS_RECOMPILE') && WP_SCSS_ALWAYS_RECOMPILE) {
|
137 |
+
return true;
|
138 |
+
}
|
139 |
+
|
140 |
$latest_scss = 0;
|
141 |
$latest_css = 0;
|
142 |
|
143 |
+
foreach ( new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->scss_dir)) as $sfile ) {
|
144 |
if (pathinfo($sfile->getFilename(), PATHINFO_EXTENSION) == 'scss') {
|
145 |
$file_time = $sfile->getMTime();
|
146 |
|
147 |
if ( (int) $file_time > $latest_scss) {
|
148 |
+
$latest_scss = $file_time;
|
149 |
}
|
150 |
}
|
151 |
}
|
152 |
|
153 |
+
foreach ( new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->css_dir)) as $cfile ) {
|
154 |
if (pathinfo($cfile->getFilename(), PATHINFO_EXTENSION) == 'css') {
|
155 |
$file_time = $cfile->getMTime();
|
156 |
+
|
157 |
if ( (int) $file_time > $latest_css) {
|
158 |
+
$latest_css = $file_time;
|
159 |
}
|
160 |
}
|
161 |
}
|
162 |
+
|
163 |
if ($latest_scss > $latest_css) {
|
164 |
return true;
|
165 |
} else {
|
166 |
+
return false;
|
167 |
}
|
168 |
}
|
169 |
|
170 |
+
/**
|
171 |
* METHOD ENQUEUE STYLES
|
172 |
* Enqueues all styles in the css directory.
|
173 |
*
|
174 |
* @param $css_folder - directory from theme root. We need this passed in separately
|
175 |
+
* so it can be used in a url, not path
|
176 |
*/
|
177 |
public function enqueue_files($css_folder) {
|
178 |
+
|
179 |
foreach( new DirectoryIterator($this->css_dir) as $stylesheet ) {
|
180 |
if ( pathinfo($stylesheet->getFilename(), PATHINFO_EXTENSION) == 'css' ) {
|
181 |
$name = $stylesheet->getBasename('.css') . '-style';
|
182 |
$uri = get_stylesheet_directory_uri().$css_folder.$stylesheet->getFilename();
|
183 |
$ver = $stylesheet->getMTime();
|
184 |
|
185 |
+
|
186 |
+
wp_register_style(
|
187 |
$name,
|
188 |
$uri,
|
189 |
array(),
|
195 |
}
|
196 |
}
|
197 |
|
198 |
+
public function set_variables(array $variables) {
|
199 |
+
global $scssc;
|
200 |
+
$scssc->setVariables($variables);
|
201 |
+
}
|
202 |
+
|
203 |
+
} // End Wp_Scss Class
|
options.php
CHANGED
@@ -208,7 +208,8 @@ class Wp_Scss_Settings
|
|
208 |
$html = '<select id="compiling_options" name="wpscss_options[compiling_options]">';
|
209 |
$html .= '<option value="scss_formatter"' . selected( $this->options['compiling_options'], 'scss_formatter', false) . '>Expanded</option>';
|
210 |
$html .= '<option value="scss_formatter_nested"' . selected( $this->options['compiling_options'], 'scss_formatter_nested', false) . '>Nested</option>';
|
211 |
-
$html .= '<option value="scss_formatter_compressed"' . selected( $this->options['compiling_options'], 'scss_formatter_compressed', false) . '>Compressed</option>';
|
|
|
212 |
$html .= '</select>';
|
213 |
|
214 |
echo $html;
|
@@ -218,6 +219,7 @@ 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="log"' . selected( $this->options['errors'], 'hide', false) . '>Print to Log</option>';
|
222 |
$html .= '</select>';
|
223 |
|
@@ -230,7 +232,7 @@ class Wp_Scss_Settings
|
|
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;
|
208 |
$html = '<select id="compiling_options" name="wpscss_options[compiling_options]">';
|
209 |
$html .= '<option value="scss_formatter"' . selected( $this->options['compiling_options'], 'scss_formatter', false) . '>Expanded</option>';
|
210 |
$html .= '<option value="scss_formatter_nested"' . selected( $this->options['compiling_options'], 'scss_formatter_nested', false) . '>Nested</option>';
|
211 |
+
$html .= '<option value="scss_formatter_compressed"' . selected( $this->options['compiling_options'], 'scss_formatter_compressed', false) . '>Compressed</option>';
|
212 |
+
$html .= '<option value="scss_formatter_minified"' . selected( $this->options['compiling_options'], 'scss_formatter_minified', false) . '>Minified</option>';
|
213 |
$html .= '</select>';
|
214 |
|
215 |
echo $html;
|
219 |
|
220 |
$html = '<select id="errors" name="wpscss_options[errors]">';
|
221 |
$html .= '<option value="show"' . selected( $this->options['errors'], 'show', false) . '>Show in Header</option>';
|
222 |
+
$html .= '<option value="show-logged-in"' . selected( $this->options['errors'], 'show-logged-in', false) . '>Show to Logged In Users</option>';
|
223 |
$html .= '<option value="log"' . selected( $this->options['errors'], 'hide', false) . '>Print to Log</option>';
|
224 |
$html .= '</select>';
|
225 |
|
232 |
function enqueue_callback() {
|
233 |
$this->options = get_option( 'wpscss_options' );
|
234 |
|
235 |
+
$html = '<input type="checkbox" id="enqueue" name="wpscss_options[enqueue]" value="1"' . checked( 1, isset($this->options['enqueue']) ? $this->options['enqueue'] : 0, false ) . '/>';
|
236 |
$html .= '<label for="enqueue"></label>';
|
237 |
|
238 |
echo $html;
|
readme.txt
CHANGED
@@ -3,8 +3,8 @@ Contributors: connectthink
|
|
3 |
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
|
7 |
-
Stable tag: 1.1.
|
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,30 +26,34 @@ The plugin only compiles when changes have been made to the scss files. Compiles
|
|
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 |
-
|
|
|
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,10 +62,34 @@ Make sure your directories are properly defined in the settings. Paths are defin
|
|
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
|
3 |
Tags: sass, scss, css
|
4 |
Plugin URI: https://github.com/ConnectThink/WP-SCSS
|
5 |
Requires at least: 3.0.1
|
6 |
+
Tested up to: 4.3
|
7 |
+
Stable tag: 1.1.9
|
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 |
+
= 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 |
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.9 =
|
66 |
+
* Added filter to set variables via PHP [@ohlle](https://github.com/ohlle)
|
67 |
+
* Added option to minify CSS output [@mndewitt](https://github.com/mndewitt)
|
68 |
+
|
69 |
+
= 1.1.8 =
|
70 |
+
Various improvements from pull requests by [@jbrains](https://github.com/jbrains) and [@brainfork](https://github.com/brainfork)
|
71 |
+
|
72 |
+
= 1.1.7 =
|
73 |
+
* Update scssphp to 0.0.12 - pull from #16 [@GabrielGil](https://github.com/GabrielGil)
|
74 |
+
|
75 |
+
= 1.1.6 =
|
76 |
+
* Upgraded scss.inc.php to version 0.0.10; via pull request from [kirkhoff](https://github.com/kirkhoff)
|
77 |
+
|
78 |
+
= 1.1.5 =
|
79 |
+
* Added option to only show errors to logged in users; via pull request from [tolnem](https://github.com/tolnem)
|
80 |
+
|
81 |
+
= 1.1.4 =
|
82 |
+
* Add suport for subfolders in scss directory
|
83 |
+
|
84 |
+
= 1.1.3 =
|
85 |
+
* Hotfix for a accidental character
|
86 |
+
|
87 |
+
= 1.1.2 =
|
88 |
+
* Added support for moved wp-content directories
|
89 |
|
90 |
+
= 1.1.1 =
|
91 |
* Added error handling for file permissions issues
|
92 |
* Changed error log to .log for auto updating errors
|
93 |
|
94 |
+
= 1.0.0 =
|
95 |
* Initial Build
|
scssphp/scss.inc.php
CHANGED
@@ -14,9 +14,9 @@
|
|
14 |
* The scss compiler and parser.
|
15 |
*
|
16 |
* Converting SCSS to CSS is a three stage process. The incoming file is parsed
|
17 |
-
* by `
|
18 |
* representing the CSS structure by `scssc`. The CSS tree is fed into a
|
19 |
-
* formatter, like `
|
20 |
*
|
21 |
* During the first compile, all values are *reduced*, which means that their
|
22 |
* types are brought to the lowest form before being dump as strings. This
|
@@ -31,9 +31,9 @@
|
|
31 |
* evaluation context, such as all available mixins and variables at any given
|
32 |
* time.
|
33 |
*
|
34 |
-
* The `
|
35 |
*
|
36 |
-
* The `
|
37 |
* handling things like indentation.
|
38 |
*/
|
39 |
|
@@ -43,7 +43,7 @@
|
|
43 |
* @author Leaf Corcoran <leafot@gmail.com>
|
44 |
*/
|
45 |
class scssc {
|
46 |
-
static public $VERSION =
|
47 |
|
48 |
static protected $operatorNames = array(
|
49 |
'+' => "add",
|
@@ -67,7 +67,6 @@ class scssc {
|
|
67 |
"function" => "^",
|
68 |
);
|
69 |
|
70 |
-
static protected $numberPrecision = 5;
|
71 |
static protected $unitTable = array(
|
72 |
"in" => array(
|
73 |
"in" => 1,
|
@@ -90,32 +89,48 @@ class scssc {
|
|
90 |
protected $importCache = array();
|
91 |
|
92 |
protected $userFunctions = array();
|
|
|
|
|
|
|
93 |
|
94 |
protected $formatter = "scss_formatter_nested";
|
95 |
|
96 |
-
|
97 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
$this->commentsSeen = array();
|
99 |
-
$this->extends
|
100 |
-
$this->extendsMap
|
|
|
|
|
|
|
101 |
|
102 |
$locale = setlocale(LC_NUMERIC, 0);
|
103 |
setlocale(LC_NUMERIC, "C");
|
104 |
|
105 |
-
$this->parsedFiles = array();
|
106 |
$this->parser = new scss_parser($name);
|
|
|
107 |
$tree = $this->parser->parse($code);
|
108 |
|
109 |
$this->formatter = new $this->formatter();
|
110 |
|
111 |
-
$this->
|
112 |
-
$this->
|
113 |
-
|
114 |
$this->compileRoot($tree);
|
|
|
115 |
|
116 |
$out = $this->formatter->format($this->scope);
|
117 |
|
118 |
setlocale(LC_NUMERIC, $locale);
|
|
|
119 |
return $out;
|
120 |
}
|
121 |
|
@@ -186,6 +201,13 @@ class scssc {
|
|
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 |
|
@@ -298,47 +320,50 @@ class scssc {
|
|
298 |
}
|
299 |
}
|
300 |
|
301 |
-
protected function compileRoot($rootBlock)
|
302 |
-
|
303 |
-
$this->scope = $this->makeOutputBlock(
|
304 |
|
305 |
$this->compileChildren($rootBlock->children, $this->scope);
|
306 |
$this->flattenSelectors($this->scope);
|
307 |
-
|
308 |
-
$this->popEnv();
|
309 |
}
|
310 |
|
311 |
protected function compileMedia($media) {
|
312 |
$this->pushEnv($media);
|
313 |
-
$parentScope = $this->mediaParent($this->scope);
|
314 |
|
315 |
-
$
|
316 |
-
$this->compileMediaQuery($this->multiplyMedia($this->env)))
|
317 |
-
);
|
318 |
|
319 |
-
$
|
320 |
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
328 |
}
|
329 |
-
}
|
330 |
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
|
339 |
-
|
|
|
|
|
|
|
340 |
|
341 |
-
$this->scope = $this->scope->parent;
|
342 |
$this->popEnv();
|
343 |
}
|
344 |
|
@@ -484,7 +509,7 @@ class scssc {
|
|
484 |
protected function compileChildren($stms, $out) {
|
485 |
foreach ($stms as $stm) {
|
486 |
$ret = $this->compileChild($stm, $out);
|
487 |
-
if (
|
488 |
}
|
489 |
}
|
490 |
|
@@ -492,11 +517,19 @@ class scssc {
|
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
500 |
break;
|
501 |
case "mediaExp":
|
502 |
if (isset($q[2])) {
|
@@ -507,6 +540,9 @@ class scssc {
|
|
507 |
break;
|
508 |
}
|
509 |
}
|
|
|
|
|
|
|
510 |
if (!empty($parts)) {
|
511 |
if ($first) {
|
512 |
$first = false;
|
@@ -520,6 +556,50 @@ class scssc {
|
|
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,12 +790,12 @@ class scssc {
|
|
710 |
$this->env->depth--;
|
711 |
}
|
712 |
|
713 |
-
if (
|
714 |
$content->scope = $callingScope;
|
715 |
$this->setRaw(self::$namespaces["special"] . "content", $content);
|
716 |
}
|
717 |
|
718 |
-
if (
|
719 |
$this->applyArguments($mixin->args, $argValues);
|
720 |
}
|
721 |
|
@@ -728,7 +808,7 @@ class scssc {
|
|
728 |
break;
|
729 |
case "mixin_content":
|
730 |
$content = $this->get(self::$namespaces["special"] . "content");
|
731 |
-
if (
|
732 |
$this->throwError("Expected @content inside of mixin");
|
733 |
}
|
734 |
|
@@ -862,7 +942,7 @@ class scssc {
|
|
862 |
$out = $this->$fn($left, $right, $shouldEval);
|
863 |
}
|
864 |
|
865 |
-
if (
|
866 |
if ($unitChange && $out[0] == "number") {
|
867 |
$out = $this->coerceUnit($out, $targetUnit);
|
868 |
}
|
@@ -938,7 +1018,7 @@ class scssc {
|
|
938 |
$ret = $this->compileChildren($func->children, $tmp);
|
939 |
$this->popEnv();
|
940 |
|
941 |
-
return
|
942 |
}
|
943 |
|
944 |
// built in function
|
@@ -1132,7 +1212,7 @@ class scssc {
|
|
1132 |
return $this->toBool($left[1] < $right[1]);
|
1133 |
}
|
1134 |
|
1135 |
-
|
1136 |
return $thing ? self::$true : self::$false;
|
1137 |
}
|
1138 |
|
@@ -1180,7 +1260,7 @@ class scssc {
|
|
1180 |
|
1181 |
return $h;
|
1182 |
case "number":
|
1183 |
-
return round($value[1],
|
1184 |
case "string":
|
1185 |
return $value[1] . $this->compileStringContent($value) . $value[1];
|
1186 |
case "function":
|
@@ -1315,7 +1395,7 @@ class scssc {
|
|
1315 |
}
|
1316 |
|
1317 |
protected function multiplyMedia($env, $childQueries = null) {
|
1318 |
-
if (
|
1319 |
!empty($env->block->type) && $env->block->type != "media")
|
1320 |
{
|
1321 |
return $childQueries;
|
@@ -1345,11 +1425,11 @@ class scssc {
|
|
1345 |
|
1346 |
// convert something to list
|
1347 |
protected function coerceList($item, $delim = ",") {
|
1348 |
-
if (
|
1349 |
return $item;
|
1350 |
}
|
1351 |
|
1352 |
-
return array("list", $delim,
|
1353 |
}
|
1354 |
|
1355 |
protected function applyArguments($argDef, $argValues) {
|
@@ -1451,28 +1531,26 @@ class scssc {
|
|
1451 |
}
|
1452 |
}
|
1453 |
|
1454 |
-
// todo: this is bugged?
|
1455 |
protected function setExisting($name, $value, $env = null) {
|
1456 |
-
if (
|
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->
|
1464 |
}
|
1465 |
}
|
1466 |
|
1467 |
protected function setRaw($name, $value) {
|
1468 |
-
$
|
|
|
1469 |
}
|
1470 |
|
1471 |
-
|
1472 |
$name = $this->normalizeName($name);
|
1473 |
|
1474 |
-
if (
|
1475 |
-
if (
|
1476 |
|
1477 |
if (isset($env->store[$name])) {
|
1478 |
return $env->store[$name];
|
@@ -1483,6 +1561,54 @@ class scssc {
|
|
1483 |
return $defaultValue; // found nothing
|
1484 |
}
|
1485 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1486 |
protected function popEnv() {
|
1487 |
$env = $this->env;
|
1488 |
$this->env = $this->env->parent;
|
@@ -1501,6 +1627,10 @@ class scssc {
|
|
1501 |
$this->importPaths = (array)$path;
|
1502 |
}
|
1503 |
|
|
|
|
|
|
|
|
|
1504 |
public function setFormatter($formatterName) {
|
1505 |
$this->formatter = $formatterName;
|
1506 |
}
|
@@ -1534,7 +1664,7 @@ class scssc {
|
|
1534 |
}
|
1535 |
|
1536 |
// results the file path for an import url if it exists
|
1537 |
-
|
1538 |
$urls = array();
|
1539 |
|
1540 |
// for "normal" scss imports (ignore vanilla css and external requests)
|
@@ -1578,9 +1708,8 @@ class scssc {
|
|
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,7 +1758,7 @@ class scssc {
|
|
1629 |
}
|
1630 |
}
|
1631 |
|
1632 |
-
if (
|
1633 |
|
1634 |
$finalArgs = array();
|
1635 |
foreach ($prototype as $i => $names) {
|
@@ -1669,10 +1798,10 @@ class scssc {
|
|
1669 |
case "keyword":
|
1670 |
$name = $value[1];
|
1671 |
if (isset(self::$cssColors[$name])) {
|
1672 |
-
|
1673 |
-
return isset($
|
1674 |
-
? array('color', (int) $
|
1675 |
-
: array('color', (int) $
|
1676 |
}
|
1677 |
return null;
|
1678 |
}
|
@@ -1690,18 +1819,18 @@ class scssc {
|
|
1690 |
return null;
|
1691 |
}
|
1692 |
|
1693 |
-
|
1694 |
if ($value[0] != "list")
|
1695 |
$this->throwError("expecting list");
|
1696 |
return $value;
|
1697 |
}
|
1698 |
|
1699 |
-
|
1700 |
if ($color = $this->coerceColor($value)) return $color;
|
1701 |
$this->throwError("expecting color");
|
1702 |
}
|
1703 |
|
1704 |
-
|
1705 |
if ($value[0] != "number")
|
1706 |
$this->throwError("expecting number");
|
1707 |
return $value[1];
|
@@ -1727,36 +1856,34 @@ class scssc {
|
|
1727 |
return $c;
|
1728 |
}
|
1729 |
|
1730 |
-
function toHSL($red, $green, $blue) {
|
1731 |
-
$
|
1732 |
-
$
|
1733 |
-
$b = $blue / 255;
|
1734 |
|
1735 |
-
$
|
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 |
-
|
1744 |
-
|
|
|
|
|
1745 |
else
|
1746 |
-
$s = $d / (
|
1747 |
|
1748 |
-
if ($
|
1749 |
-
$h = 60 * ($
|
1750 |
-
elseif ($
|
1751 |
-
$h = 60 * ($
|
1752 |
-
elseif ($
|
1753 |
-
$h = 60 * ($
|
1754 |
}
|
1755 |
|
1756 |
-
return array('hsl', fmod($h, 360), $s * 100, $l
|
1757 |
}
|
1758 |
|
1759 |
-
function hueToRGB($m1, $m2, $h) {
|
1760 |
if ($h < 0)
|
1761 |
$h += 1;
|
1762 |
elseif ($h > 1)
|
@@ -1775,7 +1902,7 @@ class scssc {
|
|
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,7 +1927,7 @@ class scssc {
|
|
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
|
1804 |
return $t;
|
1805 |
}
|
1806 |
|
@@ -1829,7 +1956,7 @@ class scssc {
|
|
1829 |
"green", "blue", "alpha");
|
1830 |
protected function lib_rgba($args) {
|
1831 |
if ($color = $this->coerceColor($args[0])) {
|
1832 |
-
$num =
|
1833 |
$alpha = $this->assertNumber($num);
|
1834 |
$color[4] = $alpha;
|
1835 |
return $color;
|
@@ -1844,7 +1971,7 @@ class scssc {
|
|
1844 |
$color = $this->assertColor($args[0]);
|
1845 |
|
1846 |
foreach (array(1,2,3,7) as $i) {
|
1847 |
-
if (
|
1848 |
$val = $this->assertNumber($args[$i]);
|
1849 |
$ii = $i == 7 ? 4 : $i; // alpha
|
1850 |
$color[$ii] =
|
@@ -1852,10 +1979,10 @@ class scssc {
|
|
1852 |
}
|
1853 |
}
|
1854 |
|
1855 |
-
if (
|
1856 |
$hsl = $this->toHSL($color[1], $color[2], $color[3]);
|
1857 |
foreach (array(4,5,6) as $i) {
|
1858 |
-
if (
|
1859 |
$val = $this->assertNumber($args[$i]);
|
1860 |
$hsl[$i - 3] = $this->$fn($hsl[$i - 3], $val, $i);
|
1861 |
}
|
@@ -1973,7 +2100,7 @@ class scssc {
|
|
1973 |
$first = $this->assertColor($first);
|
1974 |
$second = $this->assertColor($second);
|
1975 |
|
1976 |
-
if (
|
1977 |
$weight = 0.5;
|
1978 |
} else {
|
1979 |
$weight = $this->coercePercent($weight);
|
@@ -2248,7 +2375,7 @@ class scssc {
|
|
2248 |
}
|
2249 |
|
2250 |
protected function listSeparatorForJoin($list1, $sep) {
|
2251 |
-
if (
|
2252 |
switch ($this->compileValue($sep)) {
|
2253 |
case "comma":
|
2254 |
return ",";
|
@@ -2355,7 +2482,7 @@ class scssc {
|
|
2355 |
return array('string', '', array('counter(' . implode(',', $list) . ')'));
|
2356 |
}
|
2357 |
|
2358 |
-
|
2359 |
if (func_num_args() > 1) {
|
2360 |
$msg = call_user_func_array("sprintf", func_get_args());
|
2361 |
}
|
@@ -2560,7 +2687,13 @@ class scss_parser {
|
|
2560 |
static protected $commentMultiLeft = "/*";
|
2561 |
static protected $commentMultiRight = "*/";
|
2562 |
|
2563 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
2564 |
$this->sourceName = $sourceName;
|
2565 |
$this->rootParser = $rootParser;
|
2566 |
|
@@ -2580,27 +2713,38 @@ class scss_parser {
|
|
2580 |
$operators)).')';
|
2581 |
}
|
2582 |
|
2583 |
-
|
2584 |
-
|
2585 |
-
|
2586 |
-
|
2587 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2588 |
$this->eatWhiteDefault = true;
|
2589 |
-
$this->insertComments
|
2590 |
-
|
2591 |
-
$this->buffer = $buffer;
|
2592 |
|
|
|
2593 |
$this->whitespace();
|
2594 |
-
while (false !== $this->parseChunk());
|
2595 |
|
2596 |
-
|
|
|
|
|
|
|
2597 |
$this->throwParseError();
|
|
|
2598 |
|
2599 |
if (!empty($this->env->parent)) {
|
2600 |
$this->throwParseError("unclosed block");
|
2601 |
}
|
2602 |
|
2603 |
-
$this->env->isRoot
|
|
|
2604 |
return $this->env;
|
2605 |
}
|
2606 |
|
@@ -2802,7 +2946,7 @@ class scss_parser {
|
|
2802 |
}
|
2803 |
|
2804 |
$last = $this->last();
|
2805 |
-
if (
|
2806 |
list(, $if) = $last;
|
2807 |
if ($this->literal("@else")) {
|
2808 |
if ($this->literal("{")) {
|
@@ -2956,7 +3100,7 @@ class scss_parser {
|
|
2956 |
}
|
2957 |
|
2958 |
protected function literal($what, $eatWhitespace = null) {
|
2959 |
-
if (
|
2960 |
|
2961 |
// shortcut on single letter
|
2962 |
if (!isset($what[1]) && isset($this->buffer[$this->count])) {
|
@@ -3104,13 +3248,21 @@ class scss_parser {
|
|
3104 |
return false;
|
3105 |
}
|
3106 |
|
3107 |
-
|
3108 |
-
|
3109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3110 |
}
|
3111 |
|
3112 |
-
protected function spaceList(&$out)
|
3113 |
-
|
|
|
3114 |
}
|
3115 |
|
3116 |
protected function genericList(&$out, $parseItem, $delim="", $flatten=true) {
|
@@ -3885,7 +4037,7 @@ class scss_parser {
|
|
3885 |
}
|
3886 |
|
3887 |
public function throwParseError($msg = "parse error", $count = null) {
|
3888 |
-
$count =
|
3889 |
|
3890 |
$line = $this->getLineNo($count);
|
3891 |
|
@@ -3920,7 +4072,7 @@ class scss_parser {
|
|
3920 |
$token = null;
|
3921 |
|
3922 |
$end = strpos($this->buffer, "\n", $this->count);
|
3923 |
-
if ($end === false) {
|
3924 |
$end = strlen($this->buffer);
|
3925 |
}
|
3926 |
|
@@ -3950,7 +4102,7 @@ class scss_parser {
|
|
3950 |
|
3951 |
// try to match something on head of buffer
|
3952 |
protected function match($regex, &$out, $eatWhitespace = null) {
|
3953 |
-
if (
|
3954 |
|
3955 |
$r = '/'.$regex.'/Ais';
|
3956 |
if (preg_match($r, $this->buffer, $out, null, $this->count)) {
|
@@ -3978,7 +4130,7 @@ class scss_parser {
|
|
3978 |
}
|
3979 |
|
3980 |
protected function peek($regex, &$out, $from=null) {
|
3981 |
-
if (
|
3982 |
|
3983 |
$r = '/'.$regex.'/Ais';
|
3984 |
$result = preg_match($r, $this->buffer, $out, null, $from);
|
@@ -4186,6 +4338,32 @@ class scss_formatter_compressed extends scss_formatter {
|
|
4186 |
}
|
4187 |
}
|
4188 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4189 |
/**
|
4190 |
* SCSS server
|
4191 |
*
|
@@ -4283,6 +4461,26 @@ class scss_server {
|
|
4283 |
return false;
|
4284 |
}
|
4285 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4286 |
/**
|
4287 |
* Compile .scss file
|
4288 |
*
|
@@ -4297,7 +4495,7 @@ class scss_server {
|
|
4297 |
$elapsed = round((microtime(true) - $start), 4);
|
4298 |
|
4299 |
$v = scssc::$VERSION;
|
4300 |
-
$t = date('r');
|
4301 |
$css = "/* compiled by scssphp $v on $t (${elapsed}s) */\n\n" . $css;
|
4302 |
|
4303 |
file_put_contents($out, $css);
|
@@ -4308,29 +4506,60 @@ class scss_server {
|
|
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)) {
|
4318 |
try {
|
4319 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4320 |
} catch (Exception $e) {
|
4321 |
-
header(
|
|
|
|
|
4322 |
echo 'Parse error: ' . $e->getMessage() . "\n";
|
4323 |
}
|
4324 |
-
} else {
|
4325 |
-
header('X-SCSS-Cache: true');
|
4326 |
-
echo file_get_contents($output);
|
4327 |
}
|
4328 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4329 |
return;
|
4330 |
}
|
4331 |
|
4332 |
-
header(
|
4333 |
-
header('Content-type: text');
|
|
|
4334 |
$v = scssc::$VERSION;
|
4335 |
echo "/* INPUT NOT FOUND scss $v */\n";
|
4336 |
}
|
@@ -4345,14 +4574,14 @@ class scss_server {
|
|
4345 |
public function __construct($dir, $cacheDir=null, $scss=null) {
|
4346 |
$this->dir = $dir;
|
4347 |
|
4348 |
-
if (
|
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 (
|
4356 |
$scss = new scssc();
|
4357 |
$scss->setImportPaths($this->dir);
|
4358 |
}
|
14 |
* The scss compiler and parser.
|
15 |
*
|
16 |
* Converting SCSS to CSS is a three stage process. The incoming file is parsed
|
17 |
+
* by `scss_parser` into a syntax tree, then it is compiled into another tree
|
18 |
* representing the CSS structure by `scssc`. The CSS tree is fed into a
|
19 |
+
* formatter, like `scss_formatter` which then outputs CSS as a string.
|
20 |
*
|
21 |
* During the first compile, all values are *reduced*, which means that their
|
22 |
* types are brought to the lowest form before being dump as strings. This
|
31 |
* evaluation context, such as all available mixins and variables at any given
|
32 |
* time.
|
33 |
*
|
34 |
+
* The `scss_parser` class is only concerned with parsing its input.
|
35 |
*
|
36 |
+
* The `scss_formatter` takes a CSS tree, and dumps it to a formatted string,
|
37 |
* handling things like indentation.
|
38 |
*/
|
39 |
|
43 |
* @author Leaf Corcoran <leafot@gmail.com>
|
44 |
*/
|
45 |
class scssc {
|
46 |
+
static public $VERSION = 'v0.0.12';
|
47 |
|
48 |
static protected $operatorNames = array(
|
49 |
'+' => "add",
|
67 |
"function" => "^",
|
68 |
);
|
69 |
|
|
|
70 |
static protected $unitTable = array(
|
71 |
"in" => array(
|
72 |
"in" => 1,
|
89 |
protected $importCache = array();
|
90 |
|
91 |
protected $userFunctions = array();
|
92 |
+
protected $registeredVars = array();
|
93 |
+
|
94 |
+
protected $numberPrecision = 5;
|
95 |
|
96 |
protected $formatter = "scss_formatter_nested";
|
97 |
|
98 |
+
/**
|
99 |
+
* Compile scss
|
100 |
+
*
|
101 |
+
* @param string $code
|
102 |
+
* @param string $name
|
103 |
+
*
|
104 |
+
* @return string
|
105 |
+
*/
|
106 |
+
public function compile($code, $name = null)
|
107 |
+
{
|
108 |
+
$this->indentLevel = -1;
|
109 |
$this->commentsSeen = array();
|
110 |
+
$this->extends = array();
|
111 |
+
$this->extendsMap = array();
|
112 |
+
$this->parsedFiles = array();
|
113 |
+
$this->env = null;
|
114 |
+
$this->scope = null;
|
115 |
|
116 |
$locale = setlocale(LC_NUMERIC, 0);
|
117 |
setlocale(LC_NUMERIC, "C");
|
118 |
|
|
|
119 |
$this->parser = new scss_parser($name);
|
120 |
+
|
121 |
$tree = $this->parser->parse($code);
|
122 |
|
123 |
$this->formatter = new $this->formatter();
|
124 |
|
125 |
+
$this->pushEnv($tree);
|
126 |
+
$this->injectVariables($this->registeredVars);
|
|
|
127 |
$this->compileRoot($tree);
|
128 |
+
$this->popEnv();
|
129 |
|
130 |
$out = $this->formatter->format($this->scope);
|
131 |
|
132 |
setlocale(LC_NUMERIC, $locale);
|
133 |
+
|
134 |
return $out;
|
135 |
}
|
136 |
|
201 |
$rem = array_diff($single, $target);
|
202 |
|
203 |
foreach ($origin as $j => $new) {
|
204 |
+
// prevent infinite loop when target extends itself
|
205 |
+
foreach ($new as $new_selector) {
|
206 |
+
if (!array_diff($single, $new_selector)) {
|
207 |
+
continue 2;
|
208 |
+
}
|
209 |
+
}
|
210 |
+
|
211 |
$origin[$j][count($origin[$j]) - 1] = $this->combineSelectorSingle(end($new), $rem);
|
212 |
}
|
213 |
|
320 |
}
|
321 |
}
|
322 |
|
323 |
+
protected function compileRoot($rootBlock)
|
324 |
+
{
|
325 |
+
$this->scope = $this->makeOutputBlock('root');
|
326 |
|
327 |
$this->compileChildren($rootBlock->children, $this->scope);
|
328 |
$this->flattenSelectors($this->scope);
|
|
|
|
|
329 |
}
|
330 |
|
331 |
protected function compileMedia($media) {
|
332 |
$this->pushEnv($media);
|
|
|
333 |
|
334 |
+
$mediaQuery = $this->compileMediaQuery($this->multiplyMedia($this->env));
|
|
|
|
|
335 |
|
336 |
+
if (!empty($mediaQuery)) {
|
337 |
|
338 |
+
$this->scope = $this->makeOutputBlock("media", array($mediaQuery));
|
339 |
+
|
340 |
+
$parentScope = $this->mediaParent($this->scope);
|
341 |
+
|
342 |
+
$parentScope->children[] = $this->scope;
|
343 |
+
|
344 |
+
// top level properties in a media cause it to be wrapped
|
345 |
+
$needsWrap = false;
|
346 |
+
foreach ($media->children as $child) {
|
347 |
+
$type = $child[0];
|
348 |
+
if ($type !== 'block' && $type !== 'media' && $type !== 'directive') {
|
349 |
+
$needsWrap = true;
|
350 |
+
break;
|
351 |
+
}
|
352 |
}
|
|
|
353 |
|
354 |
+
if ($needsWrap) {
|
355 |
+
$wrapped = (object)array(
|
356 |
+
"selectors" => array(),
|
357 |
+
"children" => $media->children
|
358 |
+
);
|
359 |
+
$media->children = array(array("block", $wrapped));
|
360 |
+
}
|
361 |
|
362 |
+
$this->compileChildren($media->children, $this->scope);
|
363 |
+
|
364 |
+
$this->scope = $this->scope->parent;
|
365 |
+
}
|
366 |
|
|
|
367 |
$this->popEnv();
|
368 |
}
|
369 |
|
509 |
protected function compileChildren($stms, $out) {
|
510 |
foreach ($stms as $stm) {
|
511 |
$ret = $this->compileChild($stm, $out);
|
512 |
+
if (isset($ret)) return $ret;
|
513 |
}
|
514 |
}
|
515 |
|
517 |
$out = "@media";
|
518 |
$first = true;
|
519 |
foreach ($queryList as $query){
|
520 |
+
$type = null;
|
521 |
$parts = array();
|
522 |
foreach ($query as $q) {
|
523 |
switch ($q[0]) {
|
524 |
case "mediaType":
|
525 |
+
if ($type) {
|
526 |
+
$type = $this->mergeMediaTypes($type, array_map(array($this, "compileValue"), array_slice($q, 1)));
|
527 |
+
if (empty($type)) { // merge failed
|
528 |
+
return null;
|
529 |
+
}
|
530 |
+
} else {
|
531 |
+
$type = array_map(array($this, "compileValue"), array_slice($q, 1));
|
532 |
+
}
|
533 |
break;
|
534 |
case "mediaExp":
|
535 |
if (isset($q[2])) {
|
540 |
break;
|
541 |
}
|
542 |
}
|
543 |
+
if ($type) {
|
544 |
+
array_unshift($parts, implode(' ', array_filter($type)));
|
545 |
+
}
|
546 |
if (!empty($parts)) {
|
547 |
if ($first) {
|
548 |
$first = false;
|
556 |
return $out;
|
557 |
}
|
558 |
|
559 |
+
protected function mergeMediaTypes($type1, $type2) {
|
560 |
+
if (empty($type1)) {
|
561 |
+
return $type2;
|
562 |
+
}
|
563 |
+
if (empty($type2)) {
|
564 |
+
return $type1;
|
565 |
+
}
|
566 |
+
$m1 = '';
|
567 |
+
$t1 = '';
|
568 |
+
if (count($type1) > 1) {
|
569 |
+
$m1= strtolower($type1[0]);
|
570 |
+
$t1= strtolower($type1[1]);
|
571 |
+
} else {
|
572 |
+
$t1 = strtolower($type1[0]);
|
573 |
+
}
|
574 |
+
$m2 = '';
|
575 |
+
$t2 = '';
|
576 |
+
if (count($type2) > 1) {
|
577 |
+
$m2 = strtolower($type2[0]);
|
578 |
+
$t2 = strtolower($type2[1]);
|
579 |
+
} else {
|
580 |
+
$t2 = strtolower($type2[0]);
|
581 |
+
}
|
582 |
+
if (($m1 == 'not') ^ ($m2 == 'not')) {
|
583 |
+
if ($t1 == $t2) {
|
584 |
+
return null;
|
585 |
+
}
|
586 |
+
return array(
|
587 |
+
$m1 == 'not' ? $m2 : $m1,
|
588 |
+
$m1 == 'not' ? $t2 : $t1
|
589 |
+
);
|
590 |
+
} elseif ($m1 == 'not' && $m2 == 'not') {
|
591 |
+
# CSS has no way of representing "neither screen nor print"
|
592 |
+
if ($t1 != $t2) {
|
593 |
+
return null;
|
594 |
+
}
|
595 |
+
return array('not', $t1);
|
596 |
+
} elseif ($t1 != $t2) {
|
597 |
+
return null;
|
598 |
+
} else { // t1 == t2, neither m1 nor m2 are "not"
|
599 |
+
return array(empty($m1)? $m2 : $m1, $t1);
|
600 |
+
}
|
601 |
+
}
|
602 |
+
|
603 |
// returns true if the value was something that could be imported
|
604 |
protected function compileImport($rawPath, $out) {
|
605 |
if ($rawPath[0] == "string") {
|
790 |
$this->env->depth--;
|
791 |
}
|
792 |
|
793 |
+
if (isset($content)) {
|
794 |
$content->scope = $callingScope;
|
795 |
$this->setRaw(self::$namespaces["special"] . "content", $content);
|
796 |
}
|
797 |
|
798 |
+
if (isset($mixin->args)) {
|
799 |
$this->applyArguments($mixin->args, $argValues);
|
800 |
}
|
801 |
|
808 |
break;
|
809 |
case "mixin_content":
|
810 |
$content = $this->get(self::$namespaces["special"] . "content");
|
811 |
+
if (!isset($content)) {
|
812 |
$this->throwError("Expected @content inside of mixin");
|
813 |
}
|
814 |
|
942 |
$out = $this->$fn($left, $right, $shouldEval);
|
943 |
}
|
944 |
|
945 |
+
if (isset($out)) {
|
946 |
if ($unitChange && $out[0] == "number") {
|
947 |
$out = $this->coerceUnit($out, $targetUnit);
|
948 |
}
|
1018 |
$ret = $this->compileChildren($func->children, $tmp);
|
1019 |
$this->popEnv();
|
1020 |
|
1021 |
+
return !isset($ret) ? self::$defaultValue : $ret;
|
1022 |
}
|
1023 |
|
1024 |
// built in function
|
1212 |
return $this->toBool($left[1] < $right[1]);
|
1213 |
}
|
1214 |
|
1215 |
+
public function toBool($thing) {
|
1216 |
return $thing ? self::$true : self::$false;
|
1217 |
}
|
1218 |
|
1260 |
|
1261 |
return $h;
|
1262 |
case "number":
|
1263 |
+
return round($value[1], $this->numberPrecision) . $value[2];
|
1264 |
case "string":
|
1265 |
return $value[1] . $this->compileStringContent($value) . $value[1];
|
1266 |
case "function":
|
1395 |
}
|
1396 |
|
1397 |
protected function multiplyMedia($env, $childQueries = null) {
|
1398 |
+
if (!isset($env) ||
|
1399 |
!empty($env->block->type) && $env->block->type != "media")
|
1400 |
{
|
1401 |
return $childQueries;
|
1425 |
|
1426 |
// convert something to list
|
1427 |
protected function coerceList($item, $delim = ",") {
|
1428 |
+
if (isset($item) && $item[0] == "list") {
|
1429 |
return $item;
|
1430 |
}
|
1431 |
|
1432 |
+
return array("list", $delim, !isset($item) ? array(): array($item));
|
1433 |
}
|
1434 |
|
1435 |
protected function applyArguments($argDef, $argValues) {
|
1531 |
}
|
1532 |
}
|
1533 |
|
|
|
1534 |
protected function setExisting($name, $value, $env = null) {
|
1535 |
+
if (!isset($env)) $env = $this->getStoreEnv();
|
1536 |
|
1537 |
+
if (isset($env->store[$name]) || !isset($env->parent)) {
|
1538 |
$env->store[$name] = $value;
|
|
|
|
|
1539 |
} else {
|
1540 |
+
$this->setExisting($name, $value, $env->parent);
|
1541 |
}
|
1542 |
}
|
1543 |
|
1544 |
protected function setRaw($name, $value) {
|
1545 |
+
$env = $this->getStoreEnv();
|
1546 |
+
$env->store[$name] = $value;
|
1547 |
}
|
1548 |
|
1549 |
+
public function get($name, $defaultValue = null, $env = null) {
|
1550 |
$name = $this->normalizeName($name);
|
1551 |
|
1552 |
+
if (!isset($env)) $env = $this->getStoreEnv();
|
1553 |
+
if (!isset($defaultValue)) $defaultValue = self::$defaultValue;
|
1554 |
|
1555 |
if (isset($env->store[$name])) {
|
1556 |
return $env->store[$name];
|
1561 |
return $defaultValue; // found nothing
|
1562 |
}
|
1563 |
|
1564 |
+
protected function injectVariables(array $args)
|
1565 |
+
{
|
1566 |
+
if (empty($args)) {
|
1567 |
+
return;
|
1568 |
+
}
|
1569 |
+
|
1570 |
+
$parser = new scss_parser(__METHOD__, false);
|
1571 |
+
|
1572 |
+
foreach ($args as $name => $strValue) {
|
1573 |
+
if ($name[0] === '$') {
|
1574 |
+
$name = substr($name, 1);
|
1575 |
+
}
|
1576 |
+
|
1577 |
+
$parser->env = null;
|
1578 |
+
$parser->count = 0;
|
1579 |
+
$parser->buffer = (string) $strValue;
|
1580 |
+
$parser->inParens = false;
|
1581 |
+
$parser->eatWhiteDefault = true;
|
1582 |
+
$parser->insertComments = true;
|
1583 |
+
|
1584 |
+
if ( ! $parser->valueList($value)) {
|
1585 |
+
throw new Exception("failed to parse passed in variable $name: $strValue");
|
1586 |
+
}
|
1587 |
+
|
1588 |
+
$this->set($name, $value);
|
1589 |
+
}
|
1590 |
+
}
|
1591 |
+
|
1592 |
+
/**
|
1593 |
+
* Set variables
|
1594 |
+
*
|
1595 |
+
* @param array $variables
|
1596 |
+
*/
|
1597 |
+
public function setVariables(array $variables)
|
1598 |
+
{
|
1599 |
+
$this->registeredVars = array_merge($this->registeredVars, $variables);
|
1600 |
+
}
|
1601 |
+
|
1602 |
+
/**
|
1603 |
+
* Unset variable
|
1604 |
+
*
|
1605 |
+
* @param string $name
|
1606 |
+
*/
|
1607 |
+
public function unsetVariable($name)
|
1608 |
+
{
|
1609 |
+
unset($this->registeredVars[$name]);
|
1610 |
+
}
|
1611 |
+
|
1612 |
protected function popEnv() {
|
1613 |
$env = $this->env;
|
1614 |
$this->env = $this->env->parent;
|
1627 |
$this->importPaths = (array)$path;
|
1628 |
}
|
1629 |
|
1630 |
+
public function setNumberPrecision($numberPrecision) {
|
1631 |
+
$this->numberPrecision = $numberPrecision;
|
1632 |
+
}
|
1633 |
+
|
1634 |
public function setFormatter($formatterName) {
|
1635 |
$this->formatter = $formatterName;
|
1636 |
}
|
1664 |
}
|
1665 |
|
1666 |
// results the file path for an import url if it exists
|
1667 |
+
public function findImport($url) {
|
1668 |
$urls = array();
|
1669 |
|
1670 |
// for "normal" scss imports (ignore vanilla css and external requests)
|
1708 |
$name = $this->normalizeName($name);
|
1709 |
$libName = "lib_".$name;
|
1710 |
$f = array($this, $libName);
|
|
|
|
|
1711 |
if (is_callable($f)) {
|
1712 |
+
$prototype = isset(self::$$libName) ? self::$$libName : null;
|
1713 |
$sorted = $this->sortArgs($prototype, $args);
|
1714 |
foreach ($sorted as &$val) {
|
1715 |
$val = $this->reduce($val, true);
|
1758 |
}
|
1759 |
}
|
1760 |
|
1761 |
+
if (!isset($prototype)) return $posArgs;
|
1762 |
|
1763 |
$finalArgs = array();
|
1764 |
foreach ($prototype as $i => $names) {
|
1798 |
case "keyword":
|
1799 |
$name = $value[1];
|
1800 |
if (isset(self::$cssColors[$name])) {
|
1801 |
+
$rgba = explode(',', self::$cssColors[$name]);
|
1802 |
+
return isset($rgba[3])
|
1803 |
+
? array('color', (int) $rgba[0], (int) $rgba[1], (int) $rgba[2], (int) $rgba[3])
|
1804 |
+
: array('color', (int) $rgba[0], (int) $rgba[1], (int) $rgba[2]);
|
1805 |
}
|
1806 |
return null;
|
1807 |
}
|
1819 |
return null;
|
1820 |
}
|
1821 |
|
1822 |
+
public function assertList($value) {
|
1823 |
if ($value[0] != "list")
|
1824 |
$this->throwError("expecting list");
|
1825 |
return $value;
|
1826 |
}
|
1827 |
|
1828 |
+
public function assertColor($value) {
|
1829 |
if ($color = $this->coerceColor($value)) return $color;
|
1830 |
$this->throwError("expecting color");
|
1831 |
}
|
1832 |
|
1833 |
+
public function assertNumber($value) {
|
1834 |
if ($value[0] != "number")
|
1835 |
$this->throwError("expecting number");
|
1836 |
return $value[1];
|
1856 |
return $c;
|
1857 |
}
|
1858 |
|
1859 |
+
public function toHSL($red, $green, $blue) {
|
1860 |
+
$min = min($red, $green, $blue);
|
1861 |
+
$max = max($red, $green, $blue);
|
|
|
1862 |
|
1863 |
+
$l = $min + $max;
|
|
|
|
|
|
|
1864 |
|
1865 |
if ($min == $max) {
|
1866 |
$s = $h = 0;
|
1867 |
} else {
|
1868 |
+
$d = $max - $min;
|
1869 |
+
|
1870 |
+
if ($l < 255)
|
1871 |
+
$s = $d / $l;
|
1872 |
else
|
1873 |
+
$s = $d / (510 - $l);
|
1874 |
|
1875 |
+
if ($red == $max)
|
1876 |
+
$h = 60 * ($green - $blue) / $d;
|
1877 |
+
elseif ($green == $max)
|
1878 |
+
$h = 60 * ($blue - $red) / $d + 120;
|
1879 |
+
elseif ($blue == $max)
|
1880 |
+
$h = 60 * ($red - $green) / $d + 240;
|
1881 |
}
|
1882 |
|
1883 |
+
return array('hsl', fmod($h, 360), $s * 100, $l / 5.1);
|
1884 |
}
|
1885 |
|
1886 |
+
public function hueToRGB($m1, $m2, $h) {
|
1887 |
if ($h < 0)
|
1888 |
$h += 1;
|
1889 |
elseif ($h > 1)
|
1902 |
}
|
1903 |
|
1904 |
// H from 0 to 360, S and L from 0 to 100
|
1905 |
+
public function toRGB($hue, $saturation, $lightness) {
|
1906 |
if ($hue < 0) {
|
1907 |
$hue += 360;
|
1908 |
}
|
1927 |
protected static $lib_if = array("condition", "if-true", "if-false");
|
1928 |
protected function lib_if($args) {
|
1929 |
list($cond,$t, $f) = $args;
|
1930 |
+
if (!$this->isTruthy($cond)) return $f;
|
1931 |
return $t;
|
1932 |
}
|
1933 |
|
1956 |
"green", "blue", "alpha");
|
1957 |
protected function lib_rgba($args) {
|
1958 |
if ($color = $this->coerceColor($args[0])) {
|
1959 |
+
$num = !isset($args[1]) ? $args[3] : $args[1];
|
1960 |
$alpha = $this->assertNumber($num);
|
1961 |
$color[4] = $alpha;
|
1962 |
return $color;
|
1971 |
$color = $this->assertColor($args[0]);
|
1972 |
|
1973 |
foreach (array(1,2,3,7) as $i) {
|
1974 |
+
if (isset($args[$i])) {
|
1975 |
$val = $this->assertNumber($args[$i]);
|
1976 |
$ii = $i == 7 ? 4 : $i; // alpha
|
1977 |
$color[$ii] =
|
1979 |
}
|
1980 |
}
|
1981 |
|
1982 |
+
if (isset($args[4]) || isset($args[5]) || isset($args[6])) {
|
1983 |
$hsl = $this->toHSL($color[1], $color[2], $color[3]);
|
1984 |
foreach (array(4,5,6) as $i) {
|
1985 |
+
if (isset($args[$i])) {
|
1986 |
$val = $this->assertNumber($args[$i]);
|
1987 |
$hsl[$i - 3] = $this->$fn($hsl[$i - 3], $val, $i);
|
1988 |
}
|
2100 |
$first = $this->assertColor($first);
|
2101 |
$second = $this->assertColor($second);
|
2102 |
|
2103 |
+
if (!isset($weight)) {
|
2104 |
$weight = 0.5;
|
2105 |
} else {
|
2106 |
$weight = $this->coercePercent($weight);
|
2375 |
}
|
2376 |
|
2377 |
protected function listSeparatorForJoin($list1, $sep) {
|
2378 |
+
if (!isset($sep)) return $list1[1];
|
2379 |
switch ($this->compileValue($sep)) {
|
2380 |
case "comma":
|
2381 |
return ",";
|
2482 |
return array('string', '', array('counter(' . implode(',', $list) . ')'));
|
2483 |
}
|
2484 |
|
2485 |
+
public function throwError($msg = null) {
|
2486 |
if (func_num_args() > 1) {
|
2487 |
$msg = call_user_func_array("sprintf", func_get_args());
|
2488 |
}
|
2687 |
static protected $commentMultiLeft = "/*";
|
2688 |
static protected $commentMultiRight = "*/";
|
2689 |
|
2690 |
+
/**
|
2691 |
+
* Constructor
|
2692 |
+
*
|
2693 |
+
* @param string $sourceName
|
2694 |
+
* @param boolean $rootParser
|
2695 |
+
*/
|
2696 |
+
public function __construct($sourceName = null, $rootParser = true) {
|
2697 |
$this->sourceName = $sourceName;
|
2698 |
$this->rootParser = $rootParser;
|
2699 |
|
2713 |
$operators)).')';
|
2714 |
}
|
2715 |
|
2716 |
+
/**
|
2717 |
+
* Parser buffer
|
2718 |
+
*
|
2719 |
+
* @param string $buffer;
|
2720 |
+
*
|
2721 |
+
* @return \StdClass
|
2722 |
+
*/
|
2723 |
+
public function parse($buffer)
|
2724 |
+
{
|
2725 |
+
$this->count = 0;
|
2726 |
+
$this->env = null;
|
2727 |
+
$this->inParens = false;
|
2728 |
$this->eatWhiteDefault = true;
|
2729 |
+
$this->insertComments = true;
|
2730 |
+
$this->buffer = $buffer;
|
|
|
2731 |
|
2732 |
+
$this->pushBlock(null); // root block
|
2733 |
$this->whitespace();
|
|
|
2734 |
|
2735 |
+
while (false !== $this->parseChunk())
|
2736 |
+
;
|
2737 |
+
|
2738 |
+
if ($this->count != strlen($this->buffer)) {
|
2739 |
$this->throwParseError();
|
2740 |
+
}
|
2741 |
|
2742 |
if (!empty($this->env->parent)) {
|
2743 |
$this->throwParseError("unclosed block");
|
2744 |
}
|
2745 |
|
2746 |
+
$this->env->isRoot = true;
|
2747 |
+
|
2748 |
return $this->env;
|
2749 |
}
|
2750 |
|
2946 |
}
|
2947 |
|
2948 |
$last = $this->last();
|
2949 |
+
if (isset($last) && $last[0] == "if") {
|
2950 |
list(, $if) = $last;
|
2951 |
if ($this->literal("@else")) {
|
2952 |
if ($this->literal("{")) {
|
3100 |
}
|
3101 |
|
3102 |
protected function literal($what, $eatWhitespace = null) {
|
3103 |
+
if (!isset($eatWhitespace)) $eatWhitespace = $this->eatWhiteDefault;
|
3104 |
|
3105 |
// shortcut on single letter
|
3106 |
if (!isset($what[1]) && isset($this->buffer[$this->count])) {
|
3248 |
return false;
|
3249 |
}
|
3250 |
|
3251 |
+
/**
|
3252 |
+
* Parse list
|
3253 |
+
*
|
3254 |
+
* @param string $out
|
3255 |
+
*
|
3256 |
+
* @return boolean
|
3257 |
+
*/
|
3258 |
+
public function valueList(&$out)
|
3259 |
+
{
|
3260 |
+
return $this->genericList($out, 'spaceList', ',');
|
3261 |
}
|
3262 |
|
3263 |
+
protected function spaceList(&$out)
|
3264 |
+
{
|
3265 |
+
return $this->genericList($out, 'expression');
|
3266 |
}
|
3267 |
|
3268 |
protected function genericList(&$out, $parseItem, $delim="", $flatten=true) {
|
4037 |
}
|
4038 |
|
4039 |
public function throwParseError($msg = "parse error", $count = null) {
|
4040 |
+
$count = !isset($count) ? $this->count : $count;
|
4041 |
|
4042 |
$line = $this->getLineNo($count);
|
4043 |
|
4072 |
$token = null;
|
4073 |
|
4074 |
$end = strpos($this->buffer, "\n", $this->count);
|
4075 |
+
if ($end === false || $this->buffer[$end - 1] == '\\' || $this->buffer[$end - 2] == '\\' && $this->buffer[$end - 1] == "\r") {
|
4076 |
$end = strlen($this->buffer);
|
4077 |
}
|
4078 |
|
4102 |
|
4103 |
// try to match something on head of buffer
|
4104 |
protected function match($regex, &$out, $eatWhitespace = null) {
|
4105 |
+
if (!isset($eatWhitespace)) $eatWhitespace = $this->eatWhiteDefault;
|
4106 |
|
4107 |
$r = '/'.$regex.'/Ais';
|
4108 |
if (preg_match($r, $this->buffer, $out, null, $this->count)) {
|
4130 |
}
|
4131 |
|
4132 |
protected function peek($regex, &$out, $from=null) {
|
4133 |
+
if (!isset($from)) $from = $this->count;
|
4134 |
|
4135 |
$r = '/'.$regex.'/Ais';
|
4136 |
$result = preg_match($r, $this->buffer, $out, null, $from);
|
4338 |
}
|
4339 |
}
|
4340 |
|
4341 |
+
/**
|
4342 |
+
* SCSS minified formatter
|
4343 |
+
*
|
4344 |
+
* @author Mike DeWitt
|
4345 |
+
*/
|
4346 |
+
class scss_formatter_minified extends scss_formatter {
|
4347 |
+
public $open = "{";
|
4348 |
+
public $tagSeparator = ",";
|
4349 |
+
public $assignSeparator = ":";
|
4350 |
+
public $break = "";
|
4351 |
+
|
4352 |
+
public function indentStr($n = 0) {
|
4353 |
+
return "";
|
4354 |
+
}
|
4355 |
+
|
4356 |
+
public function format($block) {
|
4357 |
+
ob_start();
|
4358 |
+
$this->block($block);
|
4359 |
+
$out = ob_get_clean();
|
4360 |
+
|
4361 |
+
$out = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $out);
|
4362 |
+
|
4363 |
+
return $out;
|
4364 |
+
}
|
4365 |
+
}
|
4366 |
+
|
4367 |
/**
|
4368 |
* SCSS server
|
4369 |
*
|
4461 |
return false;
|
4462 |
}
|
4463 |
|
4464 |
+
/**
|
4465 |
+
* Get If-Modified-Since header from client request
|
4466 |
+
*
|
4467 |
+
* @return string
|
4468 |
+
*/
|
4469 |
+
protected function getModifiedSinceHeader()
|
4470 |
+
{
|
4471 |
+
$modifiedSince = '';
|
4472 |
+
|
4473 |
+
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
|
4474 |
+
$modifiedSince = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
|
4475 |
+
|
4476 |
+
if (false !== ($semicolonPos = strpos($modifiedSince, ';'))) {
|
4477 |
+
$modifiedSince = substr($modifiedSince, 0, $semicolonPos);
|
4478 |
+
}
|
4479 |
+
}
|
4480 |
+
|
4481 |
+
return $modifiedSince;
|
4482 |
+
}
|
4483 |
+
|
4484 |
/**
|
4485 |
* Compile .scss file
|
4486 |
*
|
4495 |
$elapsed = round((microtime(true) - $start), 4);
|
4496 |
|
4497 |
$v = scssc::$VERSION;
|
4498 |
+
$t = @date('r');
|
4499 |
$css = "/* compiled by scssphp $v on $t (${elapsed}s) */\n\n" . $css;
|
4500 |
|
4501 |
file_put_contents($out, $css);
|
4506 |
|
4507 |
/**
|
4508 |
* Compile requested scss and serve css. Outputs HTTP response.
|
4509 |
+
*
|
4510 |
+
* @param string $salt Prefix a string to the filename for creating the cache name hash
|
4511 |
*/
|
4512 |
+
public function serve($salt = '') {
|
4513 |
+
$protocol = isset($_SERVER['SERVER_PROTOCOL'])
|
4514 |
+
? $_SERVER['SERVER_PROTOCOL']
|
4515 |
+
: 'HTTP/1.0';
|
4516 |
+
|
4517 |
if ($input = $this->findInput()) {
|
4518 |
+
$output = $this->cacheName($salt . $input);
|
|
|
4519 |
|
4520 |
if ($this->needsCompile($input, $output)) {
|
4521 |
try {
|
4522 |
+
$css = $this->compile($input, $output);
|
4523 |
+
|
4524 |
+
$lastModified = gmdate('D, d M Y H:i:s', filemtime($output)) . ' GMT';
|
4525 |
+
|
4526 |
+
header('Last-Modified: ' . $lastModified);
|
4527 |
+
header('Content-type: text/css');
|
4528 |
+
|
4529 |
+
echo $css;
|
4530 |
+
|
4531 |
+
return;
|
4532 |
} catch (Exception $e) {
|
4533 |
+
header($protocol . ' 500 Internal Server Error');
|
4534 |
+
header('Content-type: text/plain');
|
4535 |
+
|
4536 |
echo 'Parse error: ' . $e->getMessage() . "\n";
|
4537 |
}
|
|
|
|
|
|
|
4538 |
}
|
4539 |
|
4540 |
+
header('X-SCSS-Cache: true');
|
4541 |
+
header('Content-type: text/css');
|
4542 |
+
|
4543 |
+
$modifiedSince = $this->getModifiedSinceHeader();
|
4544 |
+
$mtime = filemtime($output);
|
4545 |
+
|
4546 |
+
if (@strtotime($modifiedSince) === $mtime) {
|
4547 |
+
header($protocol . ' 304 Not Modified');
|
4548 |
+
|
4549 |
+
return;
|
4550 |
+
}
|
4551 |
+
|
4552 |
+
$lastModified = gmdate('D, d M Y H:i:s', $mtime) . ' GMT';
|
4553 |
+
header('Last-Modified: ' . $lastModified);
|
4554 |
+
|
4555 |
+
echo file_get_contents($output);
|
4556 |
+
|
4557 |
return;
|
4558 |
}
|
4559 |
|
4560 |
+
header($protocol . ' 404 Not Found');
|
4561 |
+
header('Content-type: text/plain');
|
4562 |
+
|
4563 |
$v = scssc::$VERSION;
|
4564 |
echo "/* INPUT NOT FOUND scss $v */\n";
|
4565 |
}
|
4574 |
public function __construct($dir, $cacheDir=null, $scss=null) {
|
4575 |
$this->dir = $dir;
|
4576 |
|
4577 |
+
if (!isset($cacheDir)) {
|
4578 |
$cacheDir = $this->join($dir, 'scss_cache');
|
4579 |
}
|
4580 |
|
4581 |
$this->cacheDir = $cacheDir;
|
4582 |
if (!is_dir($this->cacheDir)) mkdir($this->cacheDir, 0755, true);
|
4583 |
|
4584 |
+
if (!isset($scss)) {
|
4585 |
$scss = new scssc();
|
4586 |
$scss->setImportPaths($this->dir);
|
4587 |
}
|
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.
|
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',
|
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.
|
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' => $wpscss_options['enqueue']
|
136 |
);
|
137 |
|
138 |
|
@@ -149,82 +149,112 @@ $wpscss_compiler = new Wp_Scss(
|
|
149 |
$wpscss_settings['compiling']
|
150 |
);
|
151 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
152 |
|
153 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
$wpscss_compiler->compile();
|
155 |
}
|
156 |
|
157 |
-
|
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 |
-
|
171 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
echo '<div class="scss_errors"><pre>';
|
173 |
echo '<h6 style="margin: 15px 0;">Sass Compiling Error</h6>';
|
174 |
-
|
175 |
-
foreach( $
|
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()) .': ';
|
213 |
-
$error_string .= $error['file'] .' - '. $error['message'] . PHP_EOL;
|
214 |
-
file_put_contents($log_file, $error_string, FILE_APPEND);
|
215 |
-
$error_string = "";
|
216 |
-
}
|
217 |
}
|
218 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
219 |
// Clean out log file if it get's too large
|
220 |
-
if ( file_exists($log_file) ) {
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
|
|
|
|
228 |
}
|
229 |
|
230 |
|
@@ -235,7 +265,7 @@ if ( file_exists($log_file) ) {
|
|
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 |
}
|
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.9
|
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', get_stylesheet_directory());
|
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.1.9');
|
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' => isset($wpscss_options['enqueue']) ? $wpscss_options['enqueue'] : 0
|
136 |
);
|
137 |
|
138 |
|
149 |
$wpscss_settings['compiling']
|
150 |
);
|
151 |
|
152 |
+
//wp_scss_needs_compiling() needs to be run as wp_head-action to make it possible
|
153 |
+
//for themes to set variables and decide if the style needs compiling
|
154 |
+
function wp_scss_needs_compiling() {
|
155 |
+
global $wpscss_compiler;
|
156 |
+
$needs_compiling = apply_filters('wp_scss_needs_compiling', $wpscss_compiler->needs_compiling());
|
157 |
+
if ( $needs_compiling ) {
|
158 |
+
wp_scss_compile();
|
159 |
+
wpscss_handle_errors();
|
160 |
+
}
|
161 |
+
}
|
162 |
+
|
163 |
+
add_action('wp_head', 'wp_scss_needs_compiling');
|
164 |
|
165 |
+
function wp_scss_compile() {
|
166 |
+
global $wpscss_compiler;
|
167 |
+
$variables = apply_filters('wp_scss_variables', array());
|
168 |
+
foreach ($variables as $variable_key => $variable_value) {
|
169 |
+
if (strlen(trim($variable_value)) == 0) {
|
170 |
+
unset($variables[$variable_key]);
|
171 |
+
}
|
172 |
+
}
|
173 |
+
$wpscss_compiler->set_variables($variables);
|
174 |
$wpscss_compiler->compile();
|
175 |
}
|
176 |
|
|
|
177 |
/**
|
178 |
* 6. HANDLE COMPILING ERRORS
|
179 |
*
|
180 |
+
* First block handles print errors to front end.
|
181 |
* This adds a small style block the header to help errors get noticed
|
182 |
*
|
183 |
+
* Second block handles print errors to log file.
|
184 |
+
* After the file gets over 1MB it does a purge and deletes the first
|
185 |
+
* half of entries in the file.
|
186 |
*/
|
187 |
$log_file = $wpscss_compiler->scss_dir.'error_log.log';
|
188 |
|
189 |
+
function wpscss_error_styles() {
|
190 |
+
echo
|
191 |
+
'<style>
|
192 |
+
.scss_errors {
|
193 |
+
position: fixed;
|
194 |
+
top: 0px;
|
195 |
+
z-index: 99999;
|
196 |
+
width: 100%;
|
197 |
+
}
|
198 |
+
.scss_errors pre {
|
199 |
+
background: #f5f5f5;
|
200 |
+
border-left: 5px solid #DD3D36;
|
201 |
+
box-shadow: 0 2px 3px rgba(51,51,51, .4);
|
202 |
+
color: #666;
|
203 |
+
font-family: monospace;
|
204 |
+
font-size: 14px;
|
205 |
+
margin: 20px 0;
|
206 |
+
overflow: auto;
|
207 |
+
padding: 20px;
|
208 |
+
white-space: pre;
|
209 |
+
white-space: pre-wrap;
|
210 |
+
word-wrap: break-word;
|
211 |
+
}
|
212 |
+
</style>';
|
213 |
+
}
|
214 |
+
|
215 |
+
function wpscss_settings_show_errors($errors) {
|
216 |
echo '<div class="scss_errors"><pre>';
|
217 |
echo '<h6 style="margin: 15px 0;">Sass Compiling Error</h6>';
|
218 |
+
|
219 |
+
foreach( $errors as $error) {
|
220 |
echo '<p class="sass_error">';
|
221 |
+
echo '<strong>'. $error['file'] .'</strong> <br/><em>"'. $error['message'] .'"</em>';
|
222 |
echo '<p class="sass_error">';
|
223 |
}
|
224 |
|
225 |
echo '</pre></div>';
|
226 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
227 |
add_action('wp_print_styles', 'wpscss_error_styles');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
228 |
}
|
229 |
|
230 |
+
function wpscss_handle_errors() {
|
231 |
+
global $wpscss_settings, $log_file, $wpscss_compiler;
|
232 |
+
// 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
|
233 |
+
if ( !is_admin() && $wpscss_settings['errors'] === 'show-logged-in' && !empty($_COOKIE[LOGGED_IN_COOKIE]) && count($wpscss_compiler->compile_errors) > 0) {
|
234 |
+
wpscss_settings_show_errors($wpscss_compiler->compile_errors);
|
235 |
+
// Show in the header to anyone
|
236 |
+
} else if ( !is_admin() && $wpscss_settings['errors'] === 'show' && count($wpscss_compiler->compile_errors) > 0) {
|
237 |
+
wpscss_settings_show_errors($wpscss_compiler->compile_errors);
|
238 |
+
} else { // Hide errors and print them to a log file.
|
239 |
+
foreach ($wpscss_compiler->compile_errors as $error) {
|
240 |
+
$error_string = date('m/d/y g:i:s', time()) .': ';
|
241 |
+
$error_string .= $error['file'] .' - '. $error['message'] . PHP_EOL;
|
242 |
+
file_put_contents($log_file, $error_string, FILE_APPEND);
|
243 |
+
$error_string = "";
|
244 |
+
}
|
245 |
+
}
|
246 |
+
|
247 |
// Clean out log file if it get's too large
|
248 |
+
if ( file_exists($log_file) ) {
|
249 |
+
if ( filesize($log_file) > 1000000) {
|
250 |
+
$log_contents = file_get_contents($log_file);
|
251 |
+
$log_arr = explode("\n", $log_contents);
|
252 |
+
$new_contents_arr = array_slice($log_arr, count($log_arr)/2);
|
253 |
+
$new_contents = implode(PHP_EOL, $new_contents_arr) . 'LOG FILE CLEANED ' . date('n/j/y g:i:s', time());
|
254 |
+
file_put_contents($log_file, $new_contents);
|
255 |
+
}
|
256 |
+
}
|
257 |
+
|
258 |
}
|
259 |
|
260 |
|
265 |
if ( $wpscss_settings['enqueue'] == '1' ) {
|
266 |
function wpscss_enqueue_styles() {
|
267 |
global $wpscss_compiler, $wpscss_options;
|
268 |
+
$wpscss_compiler->enqueue_files($wpscss_options['css_dir']);
|
269 |
}
|
270 |
add_action('wp_enqueue_scripts', 'wpscss_enqueue_styles', 50);
|
271 |
}
|