Version Description
Download this release
Release Info
Developer | oncletom |
Plugin | WP-LESS |
Version | 1.3 |
Comparing to | |
See all releases |
Code changes from version 1.2 to 1.3
- bootstrap-for-theme.php +1 -1
- bootstrap.php +2 -2
- lib/Compiler.class.php +37 -5
- lib/Configuration.class.php +1 -1
- lib/Plugin.class.php +28 -16
- lib/Stylesheet.class.php +15 -34
- lib/vendor/lessphp/{README → README.md} +0 -0
- lib/vendor/lessphp/docs/docs.html +6 -7
- lib/vendor/lessphp/lessc.inc.php +278 -61
- lib/vendor/lessphp/plessc +26 -12
- lib/vendor/lessphp/tests/README +21 -0
- lib/vendor/lessphp/tests/inputs/accessors.less +36 -0
- lib/vendor/lessphp/tests/inputs/attributes.less +41 -0
- lib/vendor/lessphp/tests/inputs/font_family.less +28 -0
- lib/vendor/lessphp/tests/inputs/keyframes.less +48 -0
- lib/vendor/lessphp/tests/inputs/media.less +21 -0
- lib/vendor/lessphp/tests/inputs/misc.less +15 -0
- lib/vendor/lessphp/tests/inputs/mixin_functions.less +39 -0
- lib/vendor/lessphp/tests/inputs/mixins.less +51 -0
- lib/vendor/lessphp/tests/inputs/nested.less +21 -0
- lib/vendor/lessphp/tests/inputs/variables.less +64 -0
- lib/vendor/lessphp/tests/outputs/accessors.css +12 -0
- lib/vendor/lessphp/tests/outputs/attributes.css +35 -0
- lib/vendor/lessphp/tests/outputs/font_family.css +17 -0
- lib/vendor/lessphp/tests/outputs/keyframes.css +34 -0
- lib/vendor/lessphp/tests/outputs/media.css +18 -0
- lib/vendor/lessphp/tests/outputs/misc.css +4 -0
- lib/vendor/lessphp/tests/outputs/mixin_functions.css +15 -0
- lib/vendor/lessphp/tests/outputs/mixins.css +33 -0
- lib/vendor/lessphp/tests/outputs/nested.css +6 -0
- lib/vendor/lessphp/tests/outputs/nesting.css +6 -0
- lib/vendor/lessphp/tests/outputs/variables.css +25 -0
- lib/vendor/lessphp/tests/test.php +121 -0
- lib/vendor/plugin-toolkit/BaseConfiguration.class.php +94 -30
- lib/vendor/plugin-toolkit/BasePlugin.class.php +28 -12
- readme.txt +16 -1
bootstrap-for-theme.php
CHANGED
@@ -17,7 +17,7 @@
|
|
17 |
* And to apply automatic building on page display:
|
18 |
* `add_action('wp_print_styles', array($WPLessPlugin, 'processStylesheets'));`
|
19 |
* Or apply all hooks with:
|
20 |
-
* `$WPLessPlugin->
|
21 |
*
|
22 |
* You can rebuild all stylesheets at any time with:
|
23 |
* `$WPLessPlugin->processStylesheets();`
|
17 |
* And to apply automatic building on page display:
|
18 |
* `add_action('wp_print_styles', array($WPLessPlugin, 'processStylesheets'));`
|
19 |
* Or apply all hooks with:
|
20 |
+
* `$WPLessPlugin->dispatch();`
|
21 |
*
|
22 |
* You can rebuild all stylesheets at any time with:
|
23 |
* `$WPLessPlugin->processStylesheets();`
|
bootstrap.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: WP LESS
|
4 |
Description: LESS extends CSS with variables, mixins, operations and nested rules. This plugin magically parse all your <code>*.less</code> files queued with <code>wp_enqueue_style</code> in WordPress.
|
5 |
Author: Oncle Tom
|
6 |
-
Version: 1.
|
7 |
Author URI: http://case.oncle-tom.net/
|
8 |
Plugin URI: http://wordpress.org/extend/plugins/wp-less/
|
9 |
|
@@ -14,4 +14,4 @@ Plugin URI: http://wordpress.org/extend/plugins/wp-less/
|
|
14 |
require dirname(__FILE__).'/lib/Plugin.class.php';
|
15 |
$WPLessPlugin = WPPluginToolkitPlugin::create('WPLess', __FILE__);
|
16 |
|
17 |
-
$WPLessPlugin->
|
3 |
Plugin Name: WP LESS
|
4 |
Description: LESS extends CSS with variables, mixins, operations and nested rules. This plugin magically parse all your <code>*.less</code> files queued with <code>wp_enqueue_style</code> in WordPress.
|
5 |
Author: Oncle Tom
|
6 |
+
Version: 1.3
|
7 |
Author URI: http://case.oncle-tom.net/
|
8 |
Plugin URI: http://wordpress.org/extend/plugins/wp-less/
|
9 |
|
14 |
require dirname(__FILE__).'/lib/Plugin.class.php';
|
15 |
$WPLessPlugin = WPPluginToolkitPlugin::create('WPLess', __FILE__);
|
16 |
|
17 |
+
$WPLessPlugin->dispatch();
|
lib/Compiler.class.php
CHANGED
@@ -7,24 +7,56 @@
|
|
7 |
* @package wp-less
|
8 |
* @subpackage lib
|
9 |
* @since 1.2
|
10 |
-
* @version 1.
|
11 |
*/
|
12 |
class WPLessCompiler extends lessc
|
13 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
/**
|
15 |
* Parse a LESS file
|
16 |
*
|
17 |
* @see lessc::parse
|
18 |
-
* @author oncletom
|
19 |
* @throws Exception
|
20 |
* @param string $text [optional] Custom CSS to parse
|
21 |
* @return string CSS output
|
22 |
*/
|
23 |
public function parse($text = null)
|
24 |
{
|
25 |
-
|
26 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
}
|
30 |
}
|
7 |
* @package wp-less
|
8 |
* @subpackage lib
|
9 |
* @since 1.2
|
10 |
+
* @version 1.1
|
11 |
*/
|
12 |
class WPLessCompiler extends lessc
|
13 |
{
|
14 |
+
/**
|
15 |
+
* Instantiate a compiler
|
16 |
+
*
|
17 |
+
* @see lessc::__construct
|
18 |
+
* @param $file string [optional] Additional file to parse
|
19 |
+
*/
|
20 |
+
public function __construct($file = null)
|
21 |
+
{
|
22 |
+
do_action('wp-less_compiler_construct', $this, $file);
|
23 |
+
parent::__construct(apply_filters('wp-less_compiler_construct', $file));
|
24 |
+
}
|
25 |
+
|
26 |
/**
|
27 |
* Parse a LESS file
|
28 |
*
|
29 |
* @see lessc::parse
|
|
|
30 |
* @throws Exception
|
31 |
* @param string $text [optional] Custom CSS to parse
|
32 |
* @return string CSS output
|
33 |
*/
|
34 |
public function parse($text = null)
|
35 |
{
|
36 |
+
do_action('wp-less_compiler_parse', $this);
|
37 |
+
return apply_filters('wp-less_compiler_parse', parent::parse($text));
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Returns the LESS buffer
|
42 |
+
*
|
43 |
+
* @since 1.1
|
44 |
+
* @return string current buffer
|
45 |
+
*/
|
46 |
+
public function getBuffer()
|
47 |
+
{
|
48 |
+
return $this->buffer;
|
49 |
+
}
|
50 |
|
51 |
+
/**
|
52 |
+
* Enables to overload the current LESS buffer
|
53 |
+
* Use at your own risks.
|
54 |
+
*
|
55 |
+
* @since 1.1
|
56 |
+
* @param $css string CSS you'd like to see in the buffer, before being parse
|
57 |
+
*/
|
58 |
+
public function setBuffer($css)
|
59 |
+
{
|
60 |
+
$this->buffer = $css;
|
61 |
}
|
62 |
}
|
lib/Configuration.class.php
CHANGED
@@ -10,7 +10,7 @@ class WPLessConfiguration extends WPPluginToolkitConfiguration
|
|
10 |
/**
|
11 |
* Refers to the version of the plugin
|
12 |
*/
|
13 |
-
const VERSION = '1.
|
14 |
|
15 |
|
16 |
protected function configure()
|
10 |
/**
|
11 |
* Refers to the version of the plugin
|
12 |
*/
|
13 |
+
const VERSION = '1.3';
|
14 |
|
15 |
|
16 |
protected function configure()
|
lib/Plugin.class.php
CHANGED
@@ -1,12 +1,12 @@
|
|
1 |
<?php
|
2 |
-
if (!class_exists('
|
3 |
{
|
4 |
require dirname(__FILE__).'/vendor/plugin-toolkit/BasePlugin.class.php';
|
5 |
}
|
6 |
|
7 |
/**
|
8 |
* WP LESS Plugin class
|
9 |
-
*
|
10 |
* @author oncletom
|
11 |
* @package wp-less
|
12 |
* @subpackage lib
|
@@ -22,11 +22,22 @@ class WPLessPlugin extends WPPluginToolkitPlugin
|
|
22 |
*/
|
23 |
public static $match_pattern = '/\.less$/U';
|
24 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
/**
|
26 |
* Correct Stylesheet URI
|
27 |
-
*
|
28 |
* It enables the cache without loosing reference to URI
|
29 |
-
*
|
30 |
* @author oncletom
|
31 |
* @since 1.2
|
32 |
* @version 1.0
|
@@ -45,7 +56,7 @@ class WPLessPlugin extends WPPluginToolkitPlugin
|
|
45 |
|
46 |
/**
|
47 |
* Find any style to process
|
48 |
-
*
|
49 |
* @author oncletom
|
50 |
* @since 1.0
|
51 |
* @version 1.0
|
@@ -56,7 +67,7 @@ class WPLessPlugin extends WPPluginToolkitPlugin
|
|
56 |
$wp_styles = $this->getStyles();
|
57 |
$to_process = array();
|
58 |
|
59 |
-
foreach ($wp_styles->queue as $style_id)
|
60 |
{
|
61 |
if (preg_match(self::$match_pattern, $wp_styles->registered[$style_id]->src))
|
62 |
{
|
@@ -69,7 +80,7 @@ class WPLessPlugin extends WPPluginToolkitPlugin
|
|
69 |
|
70 |
/**
|
71 |
* Returns WordPress Styles manager
|
72 |
-
*
|
73 |
* @author oncletom
|
74 |
* @uses WP_Styles
|
75 |
* @since 1.0
|
@@ -84,7 +95,7 @@ class WPLessPlugin extends WPPluginToolkitPlugin
|
|
84 |
|
85 |
/**
|
86 |
* Process a single stylesheet
|
87 |
-
*
|
88 |
* @author oncletom
|
89 |
* @since 1.1
|
90 |
* @version 1.1
|
@@ -97,7 +108,7 @@ class WPLessPlugin extends WPPluginToolkitPlugin
|
|
97 |
$wp_styles = $this->getStyles();
|
98 |
$stylesheet = new WPLessStylesheet($wp_styles->registered[$handle]);
|
99 |
|
100 |
-
if ($force || $stylesheet->hasToCompile())
|
101 |
{
|
102 |
$stylesheet->save();
|
103 |
}
|
@@ -109,7 +120,7 @@ class WPLessPlugin extends WPPluginToolkitPlugin
|
|
109 |
|
110 |
/**
|
111 |
* Process all stylesheets to compile just in time
|
112 |
-
*
|
113 |
* @author oncletom
|
114 |
* @since 1.0
|
115 |
* @version 1.1
|
@@ -119,7 +130,8 @@ class WPLessPlugin extends WPPluginToolkitPlugin
|
|
119 |
{
|
120 |
$styles = $this->getQueuedStylesToProcess();
|
121 |
$wp_styles = $this->getStyles();
|
122 |
-
|
|
|
123 |
WPLessStylesheet::$upload_dir = $this->configuration->getUploadDir();
|
124 |
WPLessStylesheet::$upload_uri = $this->configuration->getUploadUrl();
|
125 |
|
@@ -133,7 +145,6 @@ class WPLessPlugin extends WPPluginToolkitPlugin
|
|
133 |
throw new WPLessException(sprintf('The upload dir folder (`%s`) is not writable from %s.', WPLessStylesheet::$upload_dir, get_class($this)));
|
134 |
}
|
135 |
|
136 |
-
|
137 |
foreach ($styles as $style_id)
|
138 |
{
|
139 |
$this->processStylesheet($style_id, $force);
|
@@ -144,12 +155,13 @@ class WPLessPlugin extends WPPluginToolkitPlugin
|
|
144 |
|
145 |
/**
|
146 |
* Method to register hooks (and do it only once)
|
147 |
-
*
|
|
|
148 |
* @author oncletom
|
149 |
* @since 1.1
|
150 |
* @version 1.1
|
151 |
*/
|
152 |
-
|
153 |
{
|
154 |
if ($this->is_hooks_registered)
|
155 |
{
|
@@ -159,8 +171,8 @@ class WPLessPlugin extends WPPluginToolkitPlugin
|
|
159 |
if (!is_admin())
|
160 |
{
|
161 |
do_action('wp-less_init', $this);
|
162 |
-
add_action('
|
163 |
-
add_filter('wp-
|
164 |
}
|
165 |
else
|
166 |
{
|
1 |
<?php
|
2 |
+
if (!class_exists('WPPluginToolkitPlugin'))
|
3 |
{
|
4 |
require dirname(__FILE__).'/vendor/plugin-toolkit/BasePlugin.class.php';
|
5 |
}
|
6 |
|
7 |
/**
|
8 |
* WP LESS Plugin class
|
9 |
+
*
|
10 |
* @author oncletom
|
11 |
* @package wp-less
|
12 |
* @subpackage lib
|
22 |
*/
|
23 |
public static $match_pattern = '/\.less$/U';
|
24 |
|
25 |
+
/**
|
26 |
+
* Dispatches all events of the plugin
|
27 |
+
*
|
28 |
+
* @author oncletom
|
29 |
+
* @since 1.3
|
30 |
+
*/
|
31 |
+
public function dispatch()
|
32 |
+
{
|
33 |
+
$this->registerHooks();
|
34 |
+
}
|
35 |
+
|
36 |
/**
|
37 |
* Correct Stylesheet URI
|
38 |
+
*
|
39 |
* It enables the cache without loosing reference to URI
|
40 |
+
*
|
41 |
* @author oncletom
|
42 |
* @since 1.2
|
43 |
* @version 1.0
|
56 |
|
57 |
/**
|
58 |
* Find any style to process
|
59 |
+
*
|
60 |
* @author oncletom
|
61 |
* @since 1.0
|
62 |
* @version 1.0
|
67 |
$wp_styles = $this->getStyles();
|
68 |
$to_process = array();
|
69 |
|
70 |
+
foreach ((array)$wp_styles->queue as $style_id)
|
71 |
{
|
72 |
if (preg_match(self::$match_pattern, $wp_styles->registered[$style_id]->src))
|
73 |
{
|
80 |
|
81 |
/**
|
82 |
* Returns WordPress Styles manager
|
83 |
+
*
|
84 |
* @author oncletom
|
85 |
* @uses WP_Styles
|
86 |
* @since 1.0
|
95 |
|
96 |
/**
|
97 |
* Process a single stylesheet
|
98 |
+
*
|
99 |
* @author oncletom
|
100 |
* @since 1.1
|
101 |
* @version 1.1
|
108 |
$wp_styles = $this->getStyles();
|
109 |
$stylesheet = new WPLessStylesheet($wp_styles->registered[$handle]);
|
110 |
|
111 |
+
if ((is_bool($force) && $force) || $stylesheet->hasToCompile())
|
112 |
{
|
113 |
$stylesheet->save();
|
114 |
}
|
120 |
|
121 |
/**
|
122 |
* Process all stylesheets to compile just in time
|
123 |
+
*
|
124 |
* @author oncletom
|
125 |
* @since 1.0
|
126 |
* @version 1.1
|
130 |
{
|
131 |
$styles = $this->getQueuedStylesToProcess();
|
132 |
$wp_styles = $this->getStyles();
|
133 |
+
$force = is_bool($force) && $force ? !!$force : false;
|
134 |
+
|
135 |
WPLessStylesheet::$upload_dir = $this->configuration->getUploadDir();
|
136 |
WPLessStylesheet::$upload_uri = $this->configuration->getUploadUrl();
|
137 |
|
145 |
throw new WPLessException(sprintf('The upload dir folder (`%s`) is not writable from %s.', WPLessStylesheet::$upload_dir, get_class($this)));
|
146 |
}
|
147 |
|
|
|
148 |
foreach ($styles as $style_id)
|
149 |
{
|
150 |
$this->processStylesheet($style_id, $force);
|
155 |
|
156 |
/**
|
157 |
* Method to register hooks (and do it only once)
|
158 |
+
*
|
159 |
+
* @protected
|
160 |
* @author oncletom
|
161 |
* @since 1.1
|
162 |
* @version 1.1
|
163 |
*/
|
164 |
+
protected function registerHooks()
|
165 |
{
|
166 |
if ($this->is_hooks_registered)
|
167 |
{
|
171 |
if (!is_admin())
|
172 |
{
|
173 |
do_action('wp-less_init', $this);
|
174 |
+
add_action('wp', array($this, 'processStylesheets'), 999, 0);
|
175 |
+
add_filter('wp-less_stylesheet_save', array($this, 'filterStylesheetUri'), 10, 2);
|
176 |
}
|
177 |
else
|
178 |
{
|
lib/Stylesheet.class.php
CHANGED
@@ -3,7 +3,7 @@ require dirname(__FILE__).'/vendor/lessphp/lessc.inc.php';
|
|
3 |
|
4 |
/**
|
5 |
* Stylesheet management
|
6 |
-
*
|
7 |
* @author oncletom
|
8 |
* @package wp-less
|
9 |
* @subpackage lib
|
@@ -25,7 +25,7 @@ class WPLessStylesheet
|
|
25 |
|
26 |
/**
|
27 |
* Constructs the object, paths and all
|
28 |
-
*
|
29 |
* @author oncletom
|
30 |
* @since 1.0
|
31 |
* @version 1.0
|
@@ -49,7 +49,7 @@ class WPLessStylesheet
|
|
49 |
|
50 |
/**
|
51 |
* Returns the computed path for a given dependency
|
52 |
-
*
|
53 |
* @author oncletom
|
54 |
* @since 1.0
|
55 |
* @version 1.0
|
@@ -68,7 +68,7 @@ class WPLessStylesheet
|
|
68 |
/**
|
69 |
* Configure paths for the stylesheet
|
70 |
* Since this moment, everything is configured to be usable
|
71 |
-
*
|
72 |
* @protected
|
73 |
* @author oncletom
|
74 |
* @since 1.0
|
@@ -86,10 +86,10 @@ class WPLessStylesheet
|
|
86 |
|
87 |
/**
|
88 |
* Configures version and timestamp
|
89 |
-
*
|
90 |
* It can be run only after paths have been configured. Otherwise (or if the calculation went wrong),
|
91 |
* an exception will be thrown.
|
92 |
-
*
|
93 |
* @author oncletom
|
94 |
* @since 1.2
|
95 |
* @version 1.0
|
@@ -118,7 +118,7 @@ class WPLessStylesheet
|
|
118 |
|
119 |
/**
|
120 |
* Returns source content (CSS to parse)
|
121 |
-
*
|
122 |
* @author oncletom
|
123 |
* @since 1.0
|
124 |
* @version 1.0
|
@@ -131,7 +131,7 @@ class WPLessStylesheet
|
|
131 |
|
132 |
/**
|
133 |
* Returns source path
|
134 |
-
*
|
135 |
* @author oncletom
|
136 |
* @since 1.0
|
137 |
* @version 1.0
|
@@ -144,7 +144,7 @@ class WPLessStylesheet
|
|
144 |
|
145 |
/**
|
146 |
* Returns source URI
|
147 |
-
*
|
148 |
* @author oncletom
|
149 |
* @since 1.0
|
150 |
* @version 1.0
|
@@ -155,27 +155,9 @@ class WPLessStylesheet
|
|
155 |
return $this->source_uri;
|
156 |
}
|
157 |
|
158 |
-
/**
|
159 |
-
* Returns parsed CSS
|
160 |
-
*
|
161 |
-
* @author oncletom
|
162 |
-
* @since 1.0
|
163 |
-
* @version 1.0
|
164 |
-
* @return string
|
165 |
-
*/
|
166 |
-
public function getTargetContent()
|
167 |
-
{
|
168 |
-
if (!$this->compiler)
|
169 |
-
{
|
170 |
-
$this->compiler = new lessc($this->getSourcePath());
|
171 |
-
}
|
172 |
-
|
173 |
-
return apply_filters('wp-less_stylesheet_target_content', $this->compiler->parse());
|
174 |
-
}
|
175 |
-
|
176 |
/**
|
177 |
* Returns target path
|
178 |
-
*
|
179 |
* @author oncletom
|
180 |
* @since 1.0
|
181 |
* @version 1.0
|
@@ -188,7 +170,7 @@ class WPLessStylesheet
|
|
188 |
|
189 |
/**
|
190 |
* Returns target URI
|
191 |
-
*
|
192 |
* @author oncletom
|
193 |
* @since 1.0
|
194 |
* @version 1.1
|
@@ -203,7 +185,7 @@ class WPLessStylesheet
|
|
203 |
|
204 |
/**
|
205 |
* Tells if compilation is needed
|
206 |
-
*
|
207 |
* @author oncletom
|
208 |
* @since 1.0
|
209 |
* @version 1.0
|
@@ -216,10 +198,10 @@ class WPLessStylesheet
|
|
216 |
|
217 |
/**
|
218 |
* Save the current stylesheet as a parsed css file
|
219 |
-
*
|
220 |
* @author oncletom
|
221 |
* @since 1.0
|
222 |
-
* @version 1.
|
223 |
* @throws Exception in case of parsing went bad
|
224 |
*/
|
225 |
public function save()
|
@@ -231,8 +213,7 @@ class WPLessStylesheet
|
|
231 |
do_action('wp-less_stylesheet_save_pre', $this);
|
232 |
$compiler = new WPLessCompiler($this->getSourcePath());
|
233 |
|
234 |
-
$
|
235 |
-
file_put_contents($this->getTargetPath(), $output);
|
236 |
chmod($this->getTargetPath(), 0666);
|
237 |
|
238 |
$this->is_new = false;
|
3 |
|
4 |
/**
|
5 |
* Stylesheet management
|
6 |
+
*
|
7 |
* @author oncletom
|
8 |
* @package wp-less
|
9 |
* @subpackage lib
|
25 |
|
26 |
/**
|
27 |
* Constructs the object, paths and all
|
28 |
+
*
|
29 |
* @author oncletom
|
30 |
* @since 1.0
|
31 |
* @version 1.0
|
49 |
|
50 |
/**
|
51 |
* Returns the computed path for a given dependency
|
52 |
+
*
|
53 |
* @author oncletom
|
54 |
* @since 1.0
|
55 |
* @version 1.0
|
68 |
/**
|
69 |
* Configure paths for the stylesheet
|
70 |
* Since this moment, everything is configured to be usable
|
71 |
+
*
|
72 |
* @protected
|
73 |
* @author oncletom
|
74 |
* @since 1.0
|
86 |
|
87 |
/**
|
88 |
* Configures version and timestamp
|
89 |
+
*
|
90 |
* It can be run only after paths have been configured. Otherwise (or if the calculation went wrong),
|
91 |
* an exception will be thrown.
|
92 |
+
*
|
93 |
* @author oncletom
|
94 |
* @since 1.2
|
95 |
* @version 1.0
|
118 |
|
119 |
/**
|
120 |
* Returns source content (CSS to parse)
|
121 |
+
*
|
122 |
* @author oncletom
|
123 |
* @since 1.0
|
124 |
* @version 1.0
|
131 |
|
132 |
/**
|
133 |
* Returns source path
|
134 |
+
*
|
135 |
* @author oncletom
|
136 |
* @since 1.0
|
137 |
* @version 1.0
|
144 |
|
145 |
/**
|
146 |
* Returns source URI
|
147 |
+
*
|
148 |
* @author oncletom
|
149 |
* @since 1.0
|
150 |
* @version 1.0
|
155 |
return $this->source_uri;
|
156 |
}
|
157 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
158 |
/**
|
159 |
* Returns target path
|
160 |
+
*
|
161 |
* @author oncletom
|
162 |
* @since 1.0
|
163 |
* @version 1.0
|
170 |
|
171 |
/**
|
172 |
* Returns target URI
|
173 |
+
*
|
174 |
* @author oncletom
|
175 |
* @since 1.0
|
176 |
* @version 1.1
|
185 |
|
186 |
/**
|
187 |
* Tells if compilation is needed
|
188 |
+
*
|
189 |
* @author oncletom
|
190 |
* @since 1.0
|
191 |
* @version 1.0
|
198 |
|
199 |
/**
|
200 |
* Save the current stylesheet as a parsed css file
|
201 |
+
*
|
202 |
* @author oncletom
|
203 |
* @since 1.0
|
204 |
+
* @version 1.2
|
205 |
* @throws Exception in case of parsing went bad
|
206 |
*/
|
207 |
public function save()
|
213 |
do_action('wp-less_stylesheet_save_pre', $this);
|
214 |
$compiler = new WPLessCompiler($this->getSourcePath());
|
215 |
|
216 |
+
file_put_contents($this->getTargetPath(), apply_filters('wp-less_stylesheet_save', $compiler->parse(), $this));
|
|
|
217 |
chmod($this->getTargetPath(), 0666);
|
218 |
|
219 |
$this->is_new = false;
|
lib/vendor/lessphp/{README → README.md}
RENAMED
File without changes
|
lib/vendor/lessphp/docs/docs.html
CHANGED
@@ -182,27 +182,26 @@ div {
|
|
182 |
}</pre>
|
183 |
|
184 |
<p>It is possible to give an abstract block the same name as an abstract property; their names will not collide.
|
185 |
-
Block names and property names exist in different spaces
|
186 |
|
|
|
|
|
187 |
|
188 |
<a name="args"></a>
|
189 |
<h2>Mixin Arguments</h2>
|
190 |
<p>All blocks have the option of taking argument lists, and the arguments can have default values.</p>
|
191 |
|
192 |
-
<pre class="code"
|
193 |
border-radius: @radius;
|
194 |
width: @width
|
195 |
}
|
196 |
|
197 |
-
@color(@color:red) { color: @color; } // this is valid
|
198 |
-
|
199 |
.first {
|
200 |
-
|
201 |
-
@color(blue):
|
202 |
}
|
203 |
|
204 |
.second {
|
205 |
-
|
206 |
}</pre>
|
207 |
|
208 |
<a name="import"></a>
|
182 |
}</pre>
|
183 |
|
184 |
<p>It is possible to give an abstract block the same name as an abstract property; their names will not collide.
|
185 |
+
Block names and property names exist in different spaces. For example:</p>
|
186 |
|
187 |
+
<pre class="code">@color(@color:red) { color: @color; } // this is valid
|
188 |
+
</pre>
|
189 |
|
190 |
<a name="args"></a>
|
191 |
<h2>Mixin Arguments</h2>
|
192 |
<p>All blocks have the option of taking argument lists, and the arguments can have default values.</p>
|
193 |
|
194 |
+
<pre class="code">@some_mixin(@width: 200px;@radius) {
|
195 |
border-radius: @radius;
|
196 |
width: @width
|
197 |
}
|
198 |
|
|
|
|
|
199 |
.first {
|
200 |
+
@some_mixin(300px; 2em);
|
|
|
201 |
}
|
202 |
|
203 |
.second {
|
204 |
+
@some_mixin(;4px); // blank argument takes default value
|
205 |
}</pre>
|
206 |
|
207 |
<a name="import"></a>
|
lib/vendor/lessphp/lessc.inc.php
CHANGED
@@ -11,7 +11,6 @@
|
|
11 |
*/
|
12 |
|
13 |
//
|
14 |
-
// investigate trouble with ^M
|
15 |
// fix the alpha value with color when using a percent
|
16 |
//
|
17 |
|
@@ -20,9 +19,15 @@ class lessc {
|
|
20 |
private $count;
|
21 |
private $line;
|
22 |
private $expandStack;
|
|
|
|
|
|
|
|
|
23 |
|
24 |
private $env = array();
|
25 |
|
|
|
|
|
26 |
public $vPrefix = '@';
|
27 |
public $mPrefix = '$';
|
28 |
public $imPrefix = '!';
|
@@ -39,7 +44,7 @@ class lessc {
|
|
39 |
|
40 |
static private $dtypes = array('expression', 'variable', 'function', 'negative'); // types with delayed computation
|
41 |
static private $units = array(
|
42 |
-
'px', '%', 'in', 'cm', 'mm', 'em', 'ex', 'pt', 'pc', 'ms', 's', 'deg');
|
43 |
|
44 |
public $importDisabled = false;
|
45 |
public $importDir = '';
|
@@ -84,10 +89,45 @@ class lessc {
|
|
84 |
|
85 |
// charset
|
86 |
if ($this->literal('@charset') && $this->propertyValue($value) && $this->end()) {
|
87 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
} else {
|
89 |
$this->seek($s);
|
90 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
}
|
92 |
|
93 |
// opening abstract block
|
@@ -122,6 +162,18 @@ class lessc {
|
|
122 |
|
123 |
// closing block
|
124 |
if ($this->literal('}')) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
$tags = $this->multiplyTags();
|
126 |
$env = end($this->env);
|
127 |
$ctags = $env['__tags'];
|
@@ -139,7 +191,12 @@ class lessc {
|
|
139 |
if (!empty($tags))
|
140 |
$out = $this->compileBlock($tags, $env);
|
141 |
|
142 |
-
|
|
|
|
|
|
|
|
|
|
|
143 |
|
144 |
// make the block(s) available in the new current scope
|
145 |
if (!isset($env['__dontsave'])) {
|
@@ -161,21 +218,14 @@ class lessc {
|
|
161 |
if ($this->importDisabled) return "/* import is disabled */\n";
|
162 |
|
163 |
$full = $this->importDir.$url;
|
164 |
-
if (
|
165 |
-
$
|
|
|
166 |
$this->buffer = substr($this->buffer, 0, $this->count).$loaded.substr($this->buffer, $this->count);
|
167 |
return true;
|
168 |
}
|
169 |
|
170 |
-
return '@import url("'.$url.'")'.($media ? ' '.$media : '').
|
171 |
-
}
|
172 |
-
|
173 |
-
// setting variable
|
174 |
-
if ($this->variable($name) && $this->assign() && $this->propertyValue($value) && $this->end()) {
|
175 |
-
$this->append($this->vPrefix.$name, $value);
|
176 |
-
return true;
|
177 |
-
} else {
|
178 |
-
$this->seek($s);
|
179 |
}
|
180 |
|
181 |
// mixin/function expand
|
@@ -204,9 +254,10 @@ class lessc {
|
|
204 |
}
|
205 |
}
|
206 |
|
207 |
-
//
|
208 |
ob_start();
|
209 |
$blocks = array();
|
|
|
210 |
foreach ($env as $name => $value) {
|
211 |
// skip the metatdata
|
212 |
if (preg_match('/^__/', $name)) continue;
|
@@ -215,6 +266,8 @@ class lessc {
|
|
215 |
// is mixed in
|
216 |
if (!isset($value[0]))
|
217 |
$blocks[] = array($name, $value);
|
|
|
|
|
218 |
|
219 |
// copy the data
|
220 |
// don't overwrite previous value, look in current env for name
|
@@ -225,6 +278,35 @@ class lessc {
|
|
225 |
$this->set($name, $value);
|
226 |
}
|
227 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
228 |
// render sub blocks
|
229 |
foreach ($blocks as $b) {
|
230 |
$rtags = $this->multiplyTags(array($b[0]));
|
@@ -242,6 +324,11 @@ class lessc {
|
|
242 |
return false; // couldn't match anything, throw error
|
243 |
}
|
244 |
|
|
|
|
|
|
|
|
|
|
|
245 |
// recursively find the cartesian product of all tags in stack
|
246 |
function multiplyTags($tags = array(' '), $d = null) {
|
247 |
if ($d === null) $d = count($this->env) - 1;
|
@@ -429,6 +516,23 @@ class lessc {
|
|
429 |
return $this->to(';', $media, false, true);
|
430 |
}
|
431 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
432 |
// a scoped value accessor
|
433 |
// .hello > @scope1 > @scope2['value'];
|
434 |
function accessor(&$var) {
|
@@ -540,10 +644,14 @@ class lessc {
|
|
540 |
if (!$this->literal('(')) return false;
|
541 |
|
542 |
$values = array();
|
543 |
-
while (
|
544 |
-
$values[] = $value;
|
545 |
if (!$this->literal($delim)) break;
|
546 |
-
|
|
|
|
|
|
|
|
|
547 |
|
548 |
if (!$this->literal(')')) {
|
549 |
$this->seek($s);
|
@@ -593,6 +701,20 @@ class lessc {
|
|
593 |
return true;
|
594 |
}
|
595 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
596 |
// a single tag
|
597 |
function tag(&$tag, $simple = false) {
|
598 |
if ($simple)
|
@@ -601,17 +723,12 @@ class lessc {
|
|
601 |
$chars = '^,;{}[';
|
602 |
|
603 |
$tag = '';
|
|
|
604 |
while ($this->match('(['.$chars.'0-9]['.$chars.']*)', $m)) {
|
605 |
-
$tag.= $m[1];
|
606 |
if ($simple) break;
|
607 |
|
608 |
-
|
609 |
-
if ($this->literal('[') && $this->to(']', $c, true) && $this->literal(']')) {
|
610 |
-
$tag .= '['.$c.'] ';
|
611 |
-
} else {
|
612 |
-
$this->seek($s);
|
613 |
-
break;
|
614 |
-
}
|
615 |
}
|
616 |
$tag = trim($tag);
|
617 |
if ($tag == '') return false;
|
@@ -662,6 +779,7 @@ class lessc {
|
|
662 |
if ($this->literal($this->vPrefix, false) && $this->keyword($name)) {
|
663 |
return true;
|
664 |
}
|
|
|
665 |
return false;
|
666 |
}
|
667 |
|
@@ -715,21 +833,30 @@ class lessc {
|
|
715 |
// but.. don't render special properties (blocks, vars, metadata)
|
716 |
if (isset($value[0]) && $name{0} != $this->vPrefix && $name != '__args') {
|
717 |
echo $this->compileProperty($name, $value, 1)."\n";
|
718 |
-
$props
|
719 |
}
|
720 |
}
|
721 |
$list = ob_get_clean();
|
722 |
-
|
723 |
if ($props == 0) return '';
|
724 |
|
725 |
-
|
726 |
-
if ($props
|
727 |
-
|
728 |
-
|
|
|
|
|
|
|
|
|
|
|
729 |
|
|
|
|
|
|
|
|
|
730 |
}
|
731 |
|
732 |
function compileProperty($name, $value, $level = 0) {
|
|
|
733 |
// output all repeated properties
|
734 |
foreach ($value as $v)
|
735 |
$props[] = str_repeat(' ', $level).
|
@@ -759,7 +886,7 @@ class lessc {
|
|
759 |
|
760 |
// search for inline variables to replace
|
761 |
$replace = array();
|
762 |
-
if (preg_match_all('/{(
|
763 |
foreach($m[1] as $name) {
|
764 |
if (!isset($replace[$name]))
|
765 |
$replace[$name] = $this->compileValue(array('variable', $name));
|
@@ -773,6 +900,7 @@ class lessc {
|
|
773 |
$value[1] = str_replace('{'.$var.'}', $val, $value[1]);
|
774 |
}
|
775 |
|
|
|
776 |
return $value[1];
|
777 |
case 'color':
|
778 |
// [1] - red component (either number for a %)
|
@@ -1200,8 +1328,11 @@ class lessc {
|
|
1200 |
|
1201 |
$this->env = array();
|
1202 |
$this->expandStack = array();
|
|
|
|
|
1203 |
$this->count = 0;
|
1204 |
$this->line = 1;
|
|
|
1205 |
|
1206 |
$this->buffer = $this->removeComments($this->buffer);
|
1207 |
$this->push(); // set up global scope
|
@@ -1229,7 +1360,7 @@ class lessc {
|
|
1229 |
|
1230 |
function throwParseError($msg = 'parse error') {
|
1231 |
$line = $this->line + substr_count(substr($this->buffer, 0, $this->count), "\n");
|
1232 |
-
if ($this->peek("(.*?)\n", $m))
|
1233 |
throw new exception($msg.': failed at `'.$m[1].'` line: '.$line);
|
1234 |
}
|
1235 |
|
@@ -1248,48 +1379,70 @@ class lessc {
|
|
1248 |
$this->fileName = $fname;
|
1249 |
$this->importDir = $pi['dirname'].'/';
|
1250 |
$this->buffer = file_get_contents($fname);
|
|
|
|
|
1251 |
}
|
1252 |
}
|
1253 |
|
1254 |
// remove comments from $text
|
1255 |
// todo: make it work for all functions, not just url
|
1256 |
-
// todo: make it not mess up line counter with block comments
|
1257 |
function removeComments($text) {
|
1258 |
-
$
|
|
|
|
|
1259 |
|
1260 |
-
|
1261 |
-
|
1262 |
-
|
1263 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1264 |
|
1265 |
-
$
|
1266 |
-
$text = substr($text, strlen($m[0]));
|
1267 |
|
1268 |
-
|
|
|
|
|
|
|
1269 |
case 'url(':
|
1270 |
-
preg_match('
|
1271 |
-
|
1272 |
-
$out .= $m[2].$inner[1].$inner[2];
|
1273 |
-
break;
|
1274 |
-
case '//':
|
1275 |
-
preg_match("/^(.*?)(\n|$)/is", $text, $inner);
|
1276 |
-
// give back the newline
|
1277 |
-
$text = substr($text, strlen($inner[0]) - 1);
|
1278 |
-
break;
|
1279 |
-
case '/*';
|
1280 |
-
preg_match("/^(.*?)(\*\/|$)/is", $text, $inner);
|
1281 |
-
$text = substr($text, strlen($inner[0]));
|
1282 |
break;
|
1283 |
case '"':
|
1284 |
case "'":
|
1285 |
-
preg_match(
|
1286 |
-
|
1287 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1288 |
break;
|
1289 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1290 |
}
|
1291 |
|
1292 |
-
return $out;
|
|
|
|
|
|
|
|
|
|
|
1293 |
}
|
1294 |
|
1295 |
|
@@ -1305,8 +1458,72 @@ class lessc {
|
|
1305 |
return false;
|
1306 |
}
|
1307 |
|
1308 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1309 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1310 |
|
|
|
|
|
|
|
1311 |
|
1312 |
?>
|
11 |
*/
|
12 |
|
13 |
//
|
|
|
14 |
// fix the alpha value with color when using a percent
|
15 |
//
|
16 |
|
19 |
private $count;
|
20 |
private $line;
|
21 |
private $expandStack;
|
22 |
+
private $media;
|
23 |
+
private $indentLevel;
|
24 |
+
private $level;
|
25 |
+
private $inAnimations;
|
26 |
|
27 |
private $env = array();
|
28 |
|
29 |
+
private $allParsedFiles = array();
|
30 |
+
|
31 |
public $vPrefix = '@';
|
32 |
public $mPrefix = '$';
|
33 |
public $imPrefix = '!';
|
44 |
|
45 |
static private $dtypes = array('expression', 'variable', 'function', 'negative'); // types with delayed computation
|
46 |
static private $units = array(
|
47 |
+
'px', '%', 'in', 'cm', 'mm', 'em', 'ex', 'pt', 'pc', 'ms', 's', 'deg', 'gr');
|
48 |
|
49 |
public $importDisabled = false;
|
50 |
public $importDir = '';
|
89 |
|
90 |
// charset
|
91 |
if ($this->literal('@charset') && $this->propertyValue($value) && $this->end()) {
|
92 |
+
return $this->indent('@charset '.$this->compileValue($value).';');
|
93 |
+
} else {
|
94 |
+
$this->seek($s);
|
95 |
+
}
|
96 |
+
|
97 |
+
// media
|
98 |
+
if ($this->literal('@media') && $this->mediaTypes($types, $rest) && $this->literal('{')) {
|
99 |
+
$this->media = $types;
|
100 |
+
$this->indentLevel++;
|
101 |
+
return "@media ".join(', ', $types).(!empty($rest) ? " $rest" : '' )." {\n";
|
102 |
} else {
|
103 |
$this->seek($s);
|
104 |
}
|
105 |
+
|
106 |
+
// css animations
|
107 |
+
if ($this->match('(@(-[a-z]+-)?keyframes)', $m) && $this->propertyValue($value) && $this->literal('{')) {
|
108 |
+
$this->indentLevel++;
|
109 |
+
$this->inAnimations = true;
|
110 |
+
return $m[0].$this->compileValue($value)." {\n";
|
111 |
+
} else {
|
112 |
+
$this->seek($s);
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
// see if we're in animations and handle pseudo classes
|
117 |
+
if($this->inAnimations && $this->match("(to|from|[0-9]+%)", $m) && $this->literal('{')) {
|
118 |
+
$this->push();
|
119 |
+
$this->set('__tags', array($m[1]));
|
120 |
+
return true;
|
121 |
+
} else {
|
122 |
+
$this->seek($s);
|
123 |
+
}
|
124 |
+
|
125 |
+
// setting variable
|
126 |
+
if ($this->variable($name) && $this->assign() && $this->propertyValue($value) && $this->end()) {
|
127 |
+
$this->append($this->vPrefix.$name, $value);
|
128 |
+
return true;
|
129 |
+
} else {
|
130 |
+
$this->seek($s);
|
131 |
}
|
132 |
|
133 |
// opening abstract block
|
162 |
|
163 |
// closing block
|
164 |
if ($this->literal('}')) {
|
165 |
+
if ($this->level == 1 && !is_null($this->media)) {
|
166 |
+
$this->indentLevel--;
|
167 |
+
$this->media = null;
|
168 |
+
return "}\n";
|
169 |
+
}
|
170 |
+
|
171 |
+
if ($this->level == 1 && $this->inAnimations === true) {
|
172 |
+
$this->indentLevel--;
|
173 |
+
$this->inAnimations = false;
|
174 |
+
return "}\n";
|
175 |
+
}
|
176 |
+
|
177 |
$tags = $this->multiplyTags();
|
178 |
$env = end($this->env);
|
179 |
$ctags = $env['__tags'];
|
191 |
if (!empty($tags))
|
192 |
$out = $this->compileBlock($tags, $env);
|
193 |
|
194 |
+
try {
|
195 |
+
$this->pop();
|
196 |
+
} catch (exception $e) {
|
197 |
+
$this->seek($s);
|
198 |
+
$this->throwParseError($e->getMessage());
|
199 |
+
}
|
200 |
|
201 |
// make the block(s) available in the new current scope
|
202 |
if (!isset($env['__dontsave'])) {
|
218 |
if ($this->importDisabled) return "/* import is disabled */\n";
|
219 |
|
220 |
$full = $this->importDir.$url;
|
221 |
+
if ($this->fileExists($file = $full) || $this->fileExists($file = $full.'.less')) {
|
222 |
+
$this->addParsedFile($file);
|
223 |
+
$loaded = ltrim($this->removeComments(file_get_contents($file).";"));
|
224 |
$this->buffer = substr($this->buffer, 0, $this->count).$loaded.substr($this->buffer, $this->count);
|
225 |
return true;
|
226 |
}
|
227 |
|
228 |
+
return $this->indent('@import url("'.$url.'")'.($media ? ' '.$media : '').';');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
229 |
}
|
230 |
|
231 |
// mixin/function expand
|
254 |
}
|
255 |
}
|
256 |
|
257 |
+
// copy all properties from tmp env to current block
|
258 |
ob_start();
|
259 |
$blocks = array();
|
260 |
+
$toReduce = array();
|
261 |
foreach ($env as $name => $value) {
|
262 |
// skip the metatdata
|
263 |
if (preg_match('/^__/', $name)) continue;
|
266 |
// is mixed in
|
267 |
if (!isset($value[0]))
|
268 |
$blocks[] = array($name, $value);
|
269 |
+
else if ($name{0} != $this->vPrefix)
|
270 |
+
$toReduce[] = $name;
|
271 |
|
272 |
// copy the data
|
273 |
// don't overwrite previous value, look in current env for name
|
278 |
$this->set($name, $value);
|
279 |
}
|
280 |
|
281 |
+
// extract the args as a temp environment, put them before top
|
282 |
+
if (isset($env['__args'])) {
|
283 |
+
$tmp = array();
|
284 |
+
foreach ($env['__args'] as $arg) {
|
285 |
+
if (isset($arg[1])) // if there is a value
|
286 |
+
$tmp[$this->vPrefix.$arg[0]] = array($arg[1]);
|
287 |
+
}
|
288 |
+
|
289 |
+
$top = array_pop($this->env);
|
290 |
+
array_push($this->env, $tmp, $top);
|
291 |
+
}
|
292 |
+
|
293 |
+
|
294 |
+
// reduce all values that came out of this mixin
|
295 |
+
foreach ($toReduce as $name) {
|
296 |
+
$reduced = array();
|
297 |
+
foreach ($this->get($name) as $value) {
|
298 |
+
$reduced[] = $this->reduce($value);
|
299 |
+
}
|
300 |
+
$this->set($name, $reduced);
|
301 |
+
}
|
302 |
+
|
303 |
+
if (isset($env['__args'])) {
|
304 |
+
// get rid of tmp
|
305 |
+
$top = array_pop($this->env);
|
306 |
+
array_pop($this->env);
|
307 |
+
array_push($this->env, $top);
|
308 |
+
}
|
309 |
+
|
310 |
// render sub blocks
|
311 |
foreach ($blocks as $b) {
|
312 |
$rtags = $this->multiplyTags(array($b[0]));
|
324 |
return false; // couldn't match anything, throw error
|
325 |
}
|
326 |
|
327 |
+
function fileExists($name) {
|
328 |
+
// sym link workaround
|
329 |
+
return file_exists($name) || file_exists(realpath(preg_replace('/\w+\/\.\.\//', '', $name)));
|
330 |
+
}
|
331 |
+
|
332 |
// recursively find the cartesian product of all tags in stack
|
333 |
function multiplyTags($tags = array(' '), $d = null) {
|
334 |
if ($d === null) $d = count($this->env) - 1;
|
516 |
return $this->to(';', $media, false, true);
|
517 |
}
|
518 |
|
519 |
+
// a list of media types, very lenient
|
520 |
+
function mediaTypes(&$types, &$rest) {
|
521 |
+
$s = $this->seek();
|
522 |
+
$types = array();
|
523 |
+
while ($this->match('([^,{\s]+)', $m)) {
|
524 |
+
$types[] = $m[1];
|
525 |
+
if (!$this->literal(',')) break;
|
526 |
+
}
|
527 |
+
|
528 |
+
// get everything else
|
529 |
+
if ($this->to('{', $rest, true, true)) {
|
530 |
+
$rest = trim($rest);
|
531 |
+
}
|
532 |
+
|
533 |
+
return count($types) > 0;
|
534 |
+
}
|
535 |
+
|
536 |
// a scoped value accessor
|
537 |
// .hello > @scope1 > @scope2['value'];
|
538 |
function accessor(&$var) {
|
644 |
if (!$this->literal('(')) return false;
|
645 |
|
646 |
$values = array();
|
647 |
+
while (true) {
|
648 |
+
if ($this->propertyValue($value)) $values[] = $value;
|
649 |
if (!$this->literal($delim)) break;
|
650 |
+
else {
|
651 |
+
if ($value == null) $values[] = null;
|
652 |
+
$value = null;
|
653 |
+
}
|
654 |
+
}
|
655 |
|
656 |
if (!$this->literal(')')) {
|
657 |
$this->seek($s);
|
701 |
return true;
|
702 |
}
|
703 |
|
704 |
+
// a bracketed value (contained within in a tag definition)
|
705 |
+
function tagBracket(&$value) {
|
706 |
+
$s = $this->seek();
|
707 |
+
if ($this->literal('[') && $this->to(']', $c, true) && $this->literal(']', false)) {
|
708 |
+
$value = '['.$c.']';
|
709 |
+
// whitespace?
|
710 |
+
if ($this->match('', $_)) $value .= $_[0];
|
711 |
+
return true;
|
712 |
+
}
|
713 |
+
|
714 |
+
$this->seek($s);
|
715 |
+
return false;
|
716 |
+
}
|
717 |
+
|
718 |
// a single tag
|
719 |
function tag(&$tag, $simple = false) {
|
720 |
if ($simple)
|
723 |
$chars = '^,;{}[';
|
724 |
|
725 |
$tag = '';
|
726 |
+
while ($this->tagBracket($first)) $tag .= $first;
|
727 |
while ($this->match('(['.$chars.'0-9]['.$chars.']*)', $m)) {
|
728 |
+
$tag .= $m[1];
|
729 |
if ($simple) break;
|
730 |
|
731 |
+
while ($this->tagBracket($brack)) $tag .= $brack;
|
|
|
|
|
|
|
|
|
|
|
|
|
732 |
}
|
733 |
$tag = trim($tag);
|
734 |
if ($tag == '') return false;
|
779 |
if ($this->literal($this->vPrefix, false) && $this->keyword($name)) {
|
780 |
return true;
|
781 |
}
|
782 |
+
|
783 |
return false;
|
784 |
}
|
785 |
|
833 |
// but.. don't render special properties (blocks, vars, metadata)
|
834 |
if (isset($value[0]) && $name{0} != $this->vPrefix && $name != '__args') {
|
835 |
echo $this->compileProperty($name, $value, 1)."\n";
|
836 |
+
$props += count($value);
|
837 |
}
|
838 |
}
|
839 |
$list = ob_get_clean();
|
|
|
840 |
if ($props == 0) return '';
|
841 |
|
842 |
+
$blockDecl = implode(", ", $rtags).' {';
|
843 |
+
if ($props > 1)
|
844 |
+
return $this->indent($blockDecl).$list.$this->indent('}');
|
845 |
+
else {
|
846 |
+
$list = ' '.trim($list).' ';
|
847 |
+
return $this->indent($blockDecl.$list.'}');
|
848 |
+
}
|
849 |
+
|
850 |
+
}
|
851 |
|
852 |
+
// write a line a the proper indent
|
853 |
+
function indent($str, $level = null) {
|
854 |
+
if (is_null($level)) $level = $this->indentLevel;
|
855 |
+
return str_repeat(' ', $level).$str."\n";
|
856 |
}
|
857 |
|
858 |
function compileProperty($name, $value, $level = 0) {
|
859 |
+
$level = $this->indentLevel + $level;
|
860 |
// output all repeated properties
|
861 |
foreach ($value as $v)
|
862 |
$props[] = str_repeat(' ', $level).
|
886 |
|
887 |
// search for inline variables to replace
|
888 |
$replace = array();
|
889 |
+
if (preg_match_all('/{('.$this->preg_quote($this->vPrefix).'[\w-_][0-9\w-_]*?)}/', $value[1], $m)) {
|
890 |
foreach($m[1] as $name) {
|
891 |
if (!isset($replace[$name]))
|
892 |
$replace[$name] = $this->compileValue(array('variable', $name));
|
900 |
$value[1] = str_replace('{'.$var.'}', $val, $value[1]);
|
901 |
}
|
902 |
|
903 |
+
|
904 |
return $value[1];
|
905 |
case 'color':
|
906 |
// [1] - red component (either number for a %)
|
1328 |
|
1329 |
$this->env = array();
|
1330 |
$this->expandStack = array();
|
1331 |
+
$this->indentLevel = 0;
|
1332 |
+
$this->media = null;
|
1333 |
$this->count = 0;
|
1334 |
$this->line = 1;
|
1335 |
+
$this->level = 0;
|
1336 |
|
1337 |
$this->buffer = $this->removeComments($this->buffer);
|
1338 |
$this->push(); // set up global scope
|
1360 |
|
1361 |
function throwParseError($msg = 'parse error') {
|
1362 |
$line = $this->line + substr_count(substr($this->buffer, 0, $this->count), "\n");
|
1363 |
+
if ($this->peek("(.*?)(\n|$)", $m))
|
1364 |
throw new exception($msg.': failed at `'.$m[1].'` line: '.$line);
|
1365 |
}
|
1366 |
|
1379 |
$this->fileName = $fname;
|
1380 |
$this->importDir = $pi['dirname'].'/';
|
1381 |
$this->buffer = file_get_contents($fname);
|
1382 |
+
|
1383 |
+
$this->addParsedFile($fname);
|
1384 |
}
|
1385 |
}
|
1386 |
|
1387 |
// remove comments from $text
|
1388 |
// todo: make it work for all functions, not just url
|
|
|
1389 |
function removeComments($text) {
|
1390 |
+
$look = array(
|
1391 |
+
'url(', '//', '/*', '"', "'"
|
1392 |
+
);
|
1393 |
|
1394 |
+
$out = '';
|
1395 |
+
$min = null;
|
1396 |
+
$done = false;
|
1397 |
+
while (true) {
|
1398 |
+
// find the next item
|
1399 |
+
foreach($look as $token) {
|
1400 |
+
$pos = strpos($text, $token);
|
1401 |
+
if ($pos !== false) {
|
1402 |
+
if (!isset($min) || $pos < $min[1]) $min = array($token, $pos);
|
1403 |
+
}
|
1404 |
+
}
|
1405 |
|
1406 |
+
if (is_null($min)) break;
|
|
|
1407 |
|
1408 |
+
$count = $min[1];
|
1409 |
+
$skip = 0;
|
1410 |
+
$newlines = 0;
|
1411 |
+
switch($min[0]) {
|
1412 |
case 'url(':
|
1413 |
+
if (preg_match('/url\(.*?\)/', $text, $m, 0, $count))
|
1414 |
+
$count += strlen($m[0]) - strlen($min[0]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1415 |
break;
|
1416 |
case '"':
|
1417 |
case "'":
|
1418 |
+
if (preg_match('/'.$min[0].'.*?'.$min[0].'/', $text, $m, 0, $count))
|
1419 |
+
$count += strlen($m[0]) - 1;
|
1420 |
+
break;
|
1421 |
+
case '//':
|
1422 |
+
$skip = strpos($text, "\n", $count) - $count;
|
1423 |
+
break;
|
1424 |
+
case '/*':
|
1425 |
+
if (preg_match('/\/\*.*?\*\//s', $text, $m, 0, $count)) {
|
1426 |
+
$skip = strlen($m[0]);
|
1427 |
+
$newlines = substr_count($m[0], "\n");
|
1428 |
+
}
|
1429 |
break;
|
1430 |
}
|
1431 |
+
|
1432 |
+
if ($skip == 0) $count += strlen($min[0]);
|
1433 |
+
|
1434 |
+
$out .= substr($text, 0, $count).str_repeat("\n", $newlines);
|
1435 |
+
$text = substr($text, $count + $skip);
|
1436 |
+
|
1437 |
+
$min = null;
|
1438 |
}
|
1439 |
|
1440 |
+
return $out.$text;
|
1441 |
+
}
|
1442 |
+
|
1443 |
+
public function allParsedFiles() { return $this->allParsedFiles; }
|
1444 |
+
protected function addParsedFile($file) {
|
1445 |
+
$this->allParsedFiles[realpath($file)] = filemtime($file);
|
1446 |
}
|
1447 |
|
1448 |
|
1458 |
return false;
|
1459 |
}
|
1460 |
|
1461 |
+
/**
|
1462 |
+
* Execute lessphp on a .less file or a lessphp cache structure
|
1463 |
+
*
|
1464 |
+
* The lessphp cache structure contains information about a specific
|
1465 |
+
* less file having been parsed. It can be used as a hint for future
|
1466 |
+
* calls to determine whether or not a rebuild is required.
|
1467 |
+
*
|
1468 |
+
* The cache structure contains two important keys that may be used
|
1469 |
+
* externally:
|
1470 |
+
*
|
1471 |
+
* compiled: The final compiled CSS
|
1472 |
+
* updated: The time (in seconds) the CSS was last compiled
|
1473 |
+
*
|
1474 |
+
* The cache structure is a plain-ol' PHP associative array and can
|
1475 |
+
* be serialized and unserialized without a hitch.
|
1476 |
+
*
|
1477 |
+
* @param mixed $in Input
|
1478 |
+
* @param bool $force Force rebuild?
|
1479 |
+
* @return array lessphp cache structure
|
1480 |
+
*/
|
1481 |
+
public static function cexecute($in, $force = false) {
|
1482 |
+
|
1483 |
+
// assume no root
|
1484 |
+
$root = null;
|
1485 |
+
|
1486 |
+
if ( is_string($in) ) {
|
1487 |
+
$root = $in;
|
1488 |
+
} elseif ( is_array($in) and isset($in['root']) ) {
|
1489 |
+
if ( $force or ! isset($in['files']) ) {
|
1490 |
+
// If we are forcing a recompile or if for some reason the
|
1491 |
+
// structure does not contain any file information we should
|
1492 |
+
// specify the root to trigger a rebuild.
|
1493 |
+
$root = $in['root'];
|
1494 |
+
} elseif ( isset($in['files']) and is_array($in['files']) ) {
|
1495 |
+
foreach ( $in['files'] as $fname => $ftime ) {
|
1496 |
+
if ( ! file_exists($fname) or filemtime($fname) > $ftime ) {
|
1497 |
+
// One of the files we knew about previously has changed
|
1498 |
+
// so we should look at our incoming root again.
|
1499 |
+
$root = $in['root'];
|
1500 |
+
break;
|
1501 |
+
}
|
1502 |
+
}
|
1503 |
+
}
|
1504 |
+
} else {
|
1505 |
+
// TODO: Throw an exception? We got neither a string nor something
|
1506 |
+
// that looks like a compatible lessphp cache structure.
|
1507 |
+
return null;
|
1508 |
+
}
|
1509 |
|
1510 |
+
if ( $root !== null ) {
|
1511 |
+
// If we have a root value which means we should rebuild.
|
1512 |
+
$less = new lessc($root);
|
1513 |
+
$out = array();
|
1514 |
+
$out['root'] = $root;
|
1515 |
+
$out['compiled'] = $less->parse();
|
1516 |
+
$out['files'] = $less->allParsedFiles();
|
1517 |
+
$out['updated'] = time();
|
1518 |
+
return $out;
|
1519 |
+
} else {
|
1520 |
+
// No changes, pass back the structure
|
1521 |
+
// we were given initially.
|
1522 |
+
return $in;
|
1523 |
+
}
|
1524 |
|
1525 |
+
}
|
1526 |
+
|
1527 |
+
}
|
1528 |
|
1529 |
?>
|
lib/vendor/lessphp/plessc
CHANGED
@@ -91,24 +91,38 @@ if (has("w")) {
|
|
91 |
", press Ctrl + c to exit.\n";
|
92 |
|
93 |
$fail_time = 0;
|
|
|
|
|
|
|
94 |
while (1) {
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
echo "Writing updated file: ".$out."\n";
|
101 |
-
if (!file_put_contents($out, $
|
102 |
err($fa."Could not write to file ".$out);
|
103 |
exit(1);
|
104 |
}
|
105 |
-
}
|
106 |
-
|
107 |
-
|
|
|
108 |
|
109 |
-
|
110 |
-
|
111 |
-
}
|
112 |
}
|
113 |
}
|
114 |
|
91 |
", press Ctrl + c to exit.\n";
|
92 |
|
93 |
$fail_time = 0;
|
94 |
+
// $l = new lessc($in);
|
95 |
+
$cache = $in;
|
96 |
+
$last_build = 0;
|
97 |
while (1) {
|
98 |
+
// check if anything has changed since last fail
|
99 |
+
$updated = false;
|
100 |
+
if (is_array($cache)) {
|
101 |
+
foreach ($cache['files'] as $fname=>$_) {
|
102 |
+
if (filemtime($fname) > $fail_time) {
|
103 |
+
$updated = true;
|
104 |
+
break;
|
105 |
+
}
|
106 |
+
}
|
107 |
+
} else $updated = true;
|
108 |
+
|
109 |
+
// try to compile it
|
110 |
+
if ($updated) try {
|
111 |
+
$cache = lessc::cexecute($cache);
|
112 |
+
if ($cache['updated'] > $last_build) {
|
113 |
+
$last_build = $cache['updated'];
|
114 |
echo "Writing updated file: ".$out."\n";
|
115 |
+
if (!file_put_contents($out, $cache['compiled'])) {
|
116 |
err($fa."Could not write to file ".$out);
|
117 |
exit(1);
|
118 |
}
|
119 |
+
}
|
120 |
+
} catch (exception $ex) {
|
121 |
+
echo "\nFatal Error:\n".str_repeat('=', 20)."\n".$ex->getMessage()."\n\n";
|
122 |
+
$fail_time = time();
|
123 |
|
124 |
+
if (has("n")) {
|
125 |
+
`notify-send -u critical "compile failed" "{$ex->getMessage()}"`;
|
|
|
126 |
}
|
127 |
}
|
128 |
|
lib/vendor/lessphp/tests/README
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
test.php
|
2 |
+
========================================
|
3 |
+
|
4 |
+
to run:
|
5 |
+
php test.php
|
6 |
+
|
7 |
+
|
8 |
+
Runs through all files in `inputs`, compiles them, then
|
9 |
+
compares to respective file in `outputs`. If there are
|
10 |
+
any differences then the test will fail.
|
11 |
+
|
12 |
+
Add the -d flag to show the differences of failed tests
|
13 |
+
in your diff tool (currently assigned in code, $difftool)
|
14 |
+
Defaults to diff, but I like using meld.
|
15 |
+
|
16 |
+
Pass the -C flag to save the output of the inputs to
|
17 |
+
the appropriate file. This will overwrite any existing
|
18 |
+
outputs. Use this when you want to save verified test
|
19 |
+
results.
|
20 |
+
|
21 |
+
|
lib/vendor/lessphp/tests/inputs/accessors.less
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* accessors */
|
2 |
+
|
3 |
+
#defaults {
|
4 |
+
@width: 960px;
|
5 |
+
@color: black;
|
6 |
+
.something {
|
7 |
+
@space: 10px;
|
8 |
+
@hello {
|
9 |
+
color: green;
|
10 |
+
}
|
11 |
+
}
|
12 |
+
}
|
13 |
+
|
14 |
+
.article { color: #294366; }
|
15 |
+
|
16 |
+
.comment {
|
17 |
+
width: #defaults[@width];
|
18 |
+
color: .article['color'];
|
19 |
+
padding: #defaults > .something[@space];
|
20 |
+
}
|
21 |
+
|
22 |
+
.wow {
|
23 |
+
height: .comment['width'];
|
24 |
+
background-color: .comment['color'];
|
25 |
+
color: #defaults > .something > @hello['color'];
|
26 |
+
|
27 |
+
padding: #defaults > non-existant['padding'];
|
28 |
+
margin: #defaults > .something['non-existant'];
|
29 |
+
}
|
30 |
+
|
31 |
+
.mix {
|
32 |
+
#defaults;
|
33 |
+
font-size: .something[@space];
|
34 |
+
}
|
35 |
+
|
36 |
+
|
lib/vendor/lessphp/tests/inputs/attributes.less
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
* { color: blue; }
|
2 |
+
E { color: blue; }
|
3 |
+
E[foo] { color: blue; }
|
4 |
+
[foo] { color: blue; }
|
5 |
+
[foo] .helloWorld { color: blue; }
|
6 |
+
[foo].helloWorld { color: blue; }
|
7 |
+
E[foo="barbar"] { color: blue; }
|
8 |
+
E[foo~="hello#$@%@$#^"] { color: blue; }
|
9 |
+
E[foo^="color: green;"] { color: blue; }
|
10 |
+
E[foo$="239023"] { color: blue; }
|
11 |
+
E[foo*="29302"] { color: blue; }
|
12 |
+
E[foo|="239032"] { color: blue; }
|
13 |
+
E:root { color: blue; }
|
14 |
+
|
15 |
+
E:nth-child(odd) { color: blue; }
|
16 |
+
E:nth-child(2n+1) { color: blue; }
|
17 |
+
E:nth-child(5) { color: blue; }
|
18 |
+
E:nth-last-child(-n+2) { color: blue; }
|
19 |
+
E:nth-of-type(2n) { color: blue; }
|
20 |
+
E:nth-last-of-type(n) { color: blue; }
|
21 |
+
|
22 |
+
E:first-child { color: blue; }
|
23 |
+
E:last-child { color: blue; }
|
24 |
+
E:first-of-type { color: blue; }
|
25 |
+
E:last-of-type { color: blue; }
|
26 |
+
E:only-child { color: blue; }
|
27 |
+
E:only-of-type { color: blue; }
|
28 |
+
E:empty { color: blue; }
|
29 |
+
|
30 |
+
E:lang(en) { color: blue; }
|
31 |
+
E::first-line { color: blue; }
|
32 |
+
E::before { color: blue; }
|
33 |
+
|
34 |
+
E#id { color: blue; }
|
35 |
+
E:not(:link) { color: blue; }
|
36 |
+
|
37 |
+
E F { color: blue; }
|
38 |
+
E > F { color: blue; }
|
39 |
+
E + F { color: blue; }
|
40 |
+
E ~ F { color: blue; }
|
41 |
+
|
lib/vendor/lessphp/tests/inputs/font_family.less
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
@font-directory: 'fonts/';
|
3 |
+
@some-family: Gentium;
|
4 |
+
|
5 |
+
@font-face: maroon; // won't collide with @font-face { }
|
6 |
+
|
7 |
+
@font-face {
|
8 |
+
font-family: Graublau Sans Web;
|
9 |
+
src: url({@font-directory}GraublauWeb.otf) format("opentype");
|
10 |
+
}
|
11 |
+
|
12 |
+
@font-face {
|
13 |
+
font-family: @some-family;
|
14 |
+
src: url('{@font-directory}Gentium.ttf');
|
15 |
+
}
|
16 |
+
|
17 |
+
@font-face {
|
18 |
+
font-family: @some-family;
|
19 |
+
src: url("{@font-directory}GentiumItalic.ttf");
|
20 |
+
font-style: italic;
|
21 |
+
}
|
22 |
+
|
23 |
+
h2 {
|
24 |
+
font-family: @some-family;
|
25 |
+
crazy: @font-face;
|
26 |
+
}
|
27 |
+
|
28 |
+
|
lib/vendor/lessphp/tests/inputs/keyframes.less
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@keyframes 'bounce' {
|
2 |
+
from {
|
3 |
+
top: 100px;
|
4 |
+
animation-timing-function: ease-out;
|
5 |
+
}
|
6 |
+
|
7 |
+
25% {
|
8 |
+
top: 50px;
|
9 |
+
animation-timing-function: ease-in;
|
10 |
+
}
|
11 |
+
|
12 |
+
50% {
|
13 |
+
top: 100px;
|
14 |
+
animation-timing-function: ease-out;
|
15 |
+
}
|
16 |
+
|
17 |
+
75% {
|
18 |
+
top: 75px;
|
19 |
+
animation-timing-function: ease-in;
|
20 |
+
}
|
21 |
+
|
22 |
+
to {
|
23 |
+
top: 100px;
|
24 |
+
}
|
25 |
+
}
|
26 |
+
|
27 |
+
|
28 |
+
|
29 |
+
div {
|
30 |
+
animation-name: 'diagonal-slide';
|
31 |
+
animation-duration: 5s;
|
32 |
+
animation-iteration-count: 10;
|
33 |
+
}
|
34 |
+
|
35 |
+
@keyframes 'diagonal-slide' {
|
36 |
+
|
37 |
+
from {
|
38 |
+
left: 0;
|
39 |
+
top: 0;
|
40 |
+
}
|
41 |
+
|
42 |
+
to {
|
43 |
+
left: 100px;
|
44 |
+
top: 100px;
|
45 |
+
}
|
46 |
+
|
47 |
+
}
|
48 |
+
|
lib/vendor/lessphp/tests/inputs/media.less
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@media screen, 3D {
|
2 |
+
P { color: green; }
|
3 |
+
}
|
4 |
+
@media print {
|
5 |
+
body { font-size: 10pt }
|
6 |
+
}
|
7 |
+
@media screen {
|
8 |
+
body { font-size: 13px }
|
9 |
+
}
|
10 |
+
@media screen, print {
|
11 |
+
body { line-height: 1.2 }
|
12 |
+
}
|
13 |
+
|
14 |
+
@media all and (min-width: 0px) {
|
15 |
+
body { line-height: 1.2 }
|
16 |
+
}
|
17 |
+
|
18 |
+
@media all and (min-width: 0) {
|
19 |
+
body { line-height: 1.2 }
|
20 |
+
}
|
21 |
+
|
lib/vendor/lessphp/tests/inputs/misc.less
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
@hello: "utf-8";
|
3 |
+
@charset @hello;
|
4 |
+
|
5 |
+
@color: #fff;
|
6 |
+
@images: "/assets/images/";
|
7 |
+
@images: @images + "test/";
|
8 |
+
.topbar { background: url({@images}topbar.png); }
|
9 |
+
.hello { test: empty-function(@images, 40%, to(@color)); }
|
10 |
+
|
11 |
+
.css3 {
|
12 |
+
background-image: -webkit-gradient(linear, 0% 0%, 0% 90%,
|
13 |
+
from(#E9A000), to(#A37000));
|
14 |
+
}
|
15 |
+
|
lib/vendor/lessphp/tests/inputs/mixin_functions.less
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
@outer: 10px;
|
3 |
+
@class(@var:22px; @car: 400px + @outer) {
|
4 |
+
margin: @var;
|
5 |
+
height: @car;
|
6 |
+
}
|
7 |
+
|
8 |
+
@group {
|
9 |
+
@f(@color) {
|
10 |
+
color: @color;
|
11 |
+
}
|
12 |
+
.cool {
|
13 |
+
border-bottom: 1px solid green;
|
14 |
+
}
|
15 |
+
}
|
16 |
+
|
17 |
+
.class(@width:200px) {
|
18 |
+
padding: @width;
|
19 |
+
}
|
20 |
+
|
21 |
+
body {
|
22 |
+
.class(2.0em);
|
23 |
+
@group > @f(red);
|
24 |
+
@class(10px; 10px + 2);
|
25 |
+
@group > .cool;
|
26 |
+
}
|
27 |
+
|
28 |
+
|
29 |
+
@lots(@a: 10px; @b: 20px; @c: 30px; @d: 40px; @e: 4px; @f:3px; @g:2px; @h: 1px) {
|
30 |
+
padding: @a @b @c @d;
|
31 |
+
margin: @e @f @g @h;
|
32 |
+
}
|
33 |
+
|
34 |
+
.skip_args {
|
35 |
+
@class(;12px);
|
36 |
+
@lots(;;;88px;;12px);
|
37 |
+
@group > @f(red;;;;);
|
38 |
+
}
|
39 |
+
|
lib/vendor/lessphp/tests/inputs/mixins.less
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
@rounded-corners {
|
3 |
+
border-radius: 10px;
|
4 |
+
}
|
5 |
+
|
6 |
+
.bold {
|
7 |
+
@font-size: 20px;
|
8 |
+
font-size: @font-size;
|
9 |
+
font-weight: bold;
|
10 |
+
}
|
11 |
+
|
12 |
+
body #window {
|
13 |
+
@rounded-corners;
|
14 |
+
.bold;
|
15 |
+
line-height: @font-size * 1.5;
|
16 |
+
}
|
17 |
+
|
18 |
+
#bundle {
|
19 |
+
.button {
|
20 |
+
display: block;
|
21 |
+
border: 1px solid black;
|
22 |
+
background-color: grey;
|
23 |
+
:hover { background-color: white }
|
24 |
+
}
|
25 |
+
}
|
26 |
+
#header a {
|
27 |
+
color: orange;
|
28 |
+
#bundle > .button; // mixin the button class
|
29 |
+
}
|
30 |
+
|
31 |
+
div {
|
32 |
+
@abstract {
|
33 |
+
hello: world;
|
34 |
+
b {
|
35 |
+
color: blue;
|
36 |
+
}
|
37 |
+
}
|
38 |
+
|
39 |
+
@abstract > b;
|
40 |
+
@abstract;
|
41 |
+
}
|
42 |
+
|
43 |
+
@poop {
|
44 |
+
big: baby;
|
45 |
+
}
|
46 |
+
|
47 |
+
body {
|
48 |
+
div;
|
49 |
+
}
|
50 |
+
|
51 |
+
|
lib/vendor/lessphp/tests/inputs/nested.less
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#header {
|
2 |
+
color: black;
|
3 |
+
|
4 |
+
.navigation {
|
5 |
+
font-size: 12px;
|
6 |
+
.border {
|
7 |
+
.outside {
|
8 |
+
color: blue;
|
9 |
+
}
|
10 |
+
}
|
11 |
+
}
|
12 |
+
.logo {
|
13 |
+
width: 300px;
|
14 |
+
:hover { text-decoration: none }
|
15 |
+
}
|
16 |
+
}
|
17 |
+
|
18 |
+
a { b { ul { li { color: green; } } } }
|
19 |
+
|
20 |
+
this { will { not { show { } } } }
|
21 |
+
|
lib/vendor/lessphp/tests/inputs/variables.less
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@a: 2;
|
2 |
+
@x: @a * @a;
|
3 |
+
@y: @x + 1;
|
4 |
+
@z: @y + @x * 2;
|
5 |
+
@m: @z % @y;
|
6 |
+
|
7 |
+
@nice-blue: #5B83AD;
|
8 |
+
@light-blue: @nice-blue + #111;
|
9 |
+
|
10 |
+
@rgb-color: rgb(20%, 15%, 80%);
|
11 |
+
@rgba-color: rgba(23,68,149,0.5);
|
12 |
+
|
13 |
+
@b: @a * 10px;
|
14 |
+
@c: #888;
|
15 |
+
@fonts: "Trebuchet MS", Verdana, sans-serif;
|
16 |
+
|
17 |
+
.variables {
|
18 |
+
width: @z + 1cm; // 14cm
|
19 |
+
height: @b + @x + 0px; // 24px
|
20 |
+
margin-top: -@b; // -20px
|
21 |
+
margin-bottom: 10 - -@b; // 30px
|
22 |
+
@c: @c + #001;
|
23 |
+
color: @c;
|
24 |
+
background: @light-blue;
|
25 |
+
font-family: @fonts;
|
26 |
+
margin: @m + 0px; // 3px
|
27 |
+
font-size: 10px/12px;
|
28 |
+
font-size: 120%/120%;
|
29 |
+
}
|
30 |
+
|
31 |
+
.external {
|
32 |
+
color: @c;
|
33 |
+
border: 1px solid @rgb-color;
|
34 |
+
background: @rgba-color;
|
35 |
+
padding: @nonexistant + 4px;
|
36 |
+
}
|
37 |
+
|
38 |
+
// some math tests & considerations
|
39 |
+
division: 10px / 2;
|
40 |
+
division: 10px/ 2;
|
41 |
+
//division: 10px /2; // doesn't work, probably should support this
|
42 |
+
|
43 |
+
// consideratins for subtraction:
|
44 |
+
// something-something is a single keyword
|
45 |
+
// @something-@something should be subtraction? eg.
|
46 |
+
@test-: 10;
|
47 |
+
@west: "hello";
|
48 |
+
subtract: @test-@west; // this will compile but the output will be: 10 "hello"
|
49 |
+
|
50 |
+
subtract: 2-2; // this will give you: 2 -2, similar to above
|
51 |
+
|
52 |
+
// addition: 5+5; // doesn't work
|
53 |
+
// addition: 5 +5; // doesn't work, similar to broken division above
|
54 |
+
addition: 5+ 5;
|
55 |
+
addition: 5 + 5;
|
56 |
+
|
57 |
+
|
58 |
+
// conclusion:
|
59 |
+
// probably best to enforce space around both sides of every operator
|
60 |
+
// (except when touching a paren)
|
61 |
+
math: (5 + 5)*(2 / 1); // this already works
|
62 |
+
|
63 |
+
|
64 |
+
|
lib/vendor/lessphp/tests/outputs/accessors.css
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.article { color:#294366; }
|
2 |
+
.comment {
|
3 |
+
width:960px;
|
4 |
+
color:#294366;
|
5 |
+
padding:10px;
|
6 |
+
}
|
7 |
+
.wow {
|
8 |
+
height:960px;
|
9 |
+
background-color:#294366;
|
10 |
+
color:green;
|
11 |
+
}
|
12 |
+
.mix { font-size:10px; }
|
lib/vendor/lessphp/tests/outputs/attributes.css
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
* { color:blue; }
|
2 |
+
E { color:blue; }
|
3 |
+
E[foo] { color:blue; }
|
4 |
+
[foo] { color:blue; }
|
5 |
+
[foo] .helloWorld { color:blue; }
|
6 |
+
[foo].helloWorld { color:blue; }
|
7 |
+
E[foo="barbar"] { color:blue; }
|
8 |
+
E[foo~="hello#$@%@$#^"] { color:blue; }
|
9 |
+
E[foo^="color: green;"] { color:blue; }
|
10 |
+
E[foo$="239023"] { color:blue; }
|
11 |
+
E[foo*="29302"] { color:blue; }
|
12 |
+
E[foo|="239032"] { color:blue; }
|
13 |
+
E:root { color:blue; }
|
14 |
+
E:nth-child(odd) { color:blue; }
|
15 |
+
E:nth-child(2n+1) { color:blue; }
|
16 |
+
E:nth-child(5) { color:blue; }
|
17 |
+
E:nth-last-child(-n+2) { color:blue; }
|
18 |
+
E:nth-of-type(2n) { color:blue; }
|
19 |
+
E:nth-last-of-type(n) { color:blue; }
|
20 |
+
E:first-child { color:blue; }
|
21 |
+
E:last-child { color:blue; }
|
22 |
+
E:first-of-type { color:blue; }
|
23 |
+
E:last-of-type { color:blue; }
|
24 |
+
E:only-child { color:blue; }
|
25 |
+
E:only-of-type { color:blue; }
|
26 |
+
E:empty { color:blue; }
|
27 |
+
E:lang(en) { color:blue; }
|
28 |
+
E::first-line { color:blue; }
|
29 |
+
E::before { color:blue; }
|
30 |
+
E#id { color:blue; }
|
31 |
+
E:not(:link) { color:blue; }
|
32 |
+
E F { color:blue; }
|
33 |
+
E > F { color:blue; }
|
34 |
+
E + F { color:blue; }
|
35 |
+
E ~ F { color:blue; }
|
lib/vendor/lessphp/tests/outputs/font_family.css
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@font-face {
|
2 |
+
font-family:Graublau Sans Web;
|
3 |
+
src:url(fonts/GraublauWeb.otf) format("opentype");
|
4 |
+
}
|
5 |
+
@font-face {
|
6 |
+
font-family:Gentium;
|
7 |
+
src:url('fonts/Gentium.ttf');
|
8 |
+
}
|
9 |
+
@font-face {
|
10 |
+
font-family:Gentium;
|
11 |
+
src:url("fonts/GentiumItalic.ttf");
|
12 |
+
font-style:italic;
|
13 |
+
}
|
14 |
+
h2 {
|
15 |
+
font-family:Gentium;
|
16 |
+
crazy:maroon;
|
17 |
+
}
|
lib/vendor/lessphp/tests/outputs/keyframes.css
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@keyframes 'bounce' {
|
2 |
+
from {
|
3 |
+
top:100px;
|
4 |
+
animation-timing-function:ease-out;
|
5 |
+
}
|
6 |
+
25% {
|
7 |
+
top:50px;
|
8 |
+
animation-timing-function:ease-in;
|
9 |
+
}
|
10 |
+
50% {
|
11 |
+
top:100px;
|
12 |
+
animation-timing-function:ease-out;
|
13 |
+
}
|
14 |
+
75% {
|
15 |
+
top:75px;
|
16 |
+
animation-timing-function:ease-in;
|
17 |
+
}
|
18 |
+
to { top:100px; }
|
19 |
+
}
|
20 |
+
div {
|
21 |
+
animation-name:'diagonal-slide';
|
22 |
+
animation-duration:5s;
|
23 |
+
animation-iteration-count:10;
|
24 |
+
}
|
25 |
+
@keyframes 'diagonal-slide' {
|
26 |
+
from {
|
27 |
+
left:0;
|
28 |
+
top:0;
|
29 |
+
}
|
30 |
+
to {
|
31 |
+
left:100px;
|
32 |
+
top:100px;
|
33 |
+
}
|
34 |
+
}
|
lib/vendor/lessphp/tests/outputs/media.css
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@media screen, 3D {
|
2 |
+
P { color:green; }
|
3 |
+
}
|
4 |
+
@media print {
|
5 |
+
body { font-size:10pt; }
|
6 |
+
}
|
7 |
+
@media screen {
|
8 |
+
body { font-size:13px; }
|
9 |
+
}
|
10 |
+
@media screen, print {
|
11 |
+
body { line-height:1.2; }
|
12 |
+
}
|
13 |
+
@media all and (min-width: 0px) {
|
14 |
+
body { line-height:1.2; }
|
15 |
+
}
|
16 |
+
@media all and (min-width: 0) {
|
17 |
+
body { line-height:1.2; }
|
18 |
+
}
|
lib/vendor/lessphp/tests/outputs/misc.css
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
1 |
+
@charset "utf-8";
|
2 |
+
.topbar { background:url(/assets/images/test/topbar.png); }
|
3 |
+
.hello { test:empty-function("/assets/images/test/",40%,to(#ffffff)); }
|
4 |
+
.css3 { background-image:-webkit-gradient(linear,0% 0%,0% 90%,from(#e9a000),to(#a37000)); }
|
lib/vendor/lessphp/tests/outputs/mixin_functions.css
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.class { padding:200px; }
|
2 |
+
body {
|
3 |
+
padding:2.0em;
|
4 |
+
color:red;
|
5 |
+
margin:10px;
|
6 |
+
height:12px;
|
7 |
+
border-bottom:1px solid green;
|
8 |
+
}
|
9 |
+
.skip_args {
|
10 |
+
margin:22px;
|
11 |
+
margin:4px 12px 2px 1px;
|
12 |
+
height:12px;
|
13 |
+
padding:10px 20px 30px 88px;
|
14 |
+
color:red;
|
15 |
+
}
|
lib/vendor/lessphp/tests/outputs/mixins.css
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.bold {
|
2 |
+
font-size:20px;
|
3 |
+
font-weight:bold;
|
4 |
+
}
|
5 |
+
body #window {
|
6 |
+
border-radius:10px;
|
7 |
+
font-size:20px;
|
8 |
+
font-weight:bold;
|
9 |
+
line-height:30px;
|
10 |
+
}
|
11 |
+
#bundle .button:hover { background-color:white; }
|
12 |
+
#bundle .button {
|
13 |
+
display:block;
|
14 |
+
border:1px solid black;
|
15 |
+
background-color:grey;
|
16 |
+
}
|
17 |
+
#header a:hover { background-color:white; }
|
18 |
+
#header a {
|
19 |
+
color:orange;
|
20 |
+
display:block;
|
21 |
+
border:1px solid black;
|
22 |
+
background-color:grey;
|
23 |
+
}
|
24 |
+
div b { color:blue; }
|
25 |
+
div {
|
26 |
+
color:blue;
|
27 |
+
hello:world;
|
28 |
+
}
|
29 |
+
body b { color:blue; }
|
30 |
+
body {
|
31 |
+
color:blue;
|
32 |
+
hello:world;
|
33 |
+
}
|
lib/vendor/lessphp/tests/outputs/nested.css
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#header .navigation .border .outside { color:blue; }
|
2 |
+
#header .navigation { font-size:12px; }
|
3 |
+
#header .logo:hover { text-decoration:none; }
|
4 |
+
#header .logo { width:300px; }
|
5 |
+
#header { color:black; }
|
6 |
+
a b ul li { color:green; }
|
lib/vendor/lessphp/tests/outputs/nesting.css
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#header .navigation .border .outside { color:blue; }
|
2 |
+
#header .navigation { font-size:12px; }
|
3 |
+
#header .logo:hover { text-decoration:none; }
|
4 |
+
#header .logo { width:300px; }
|
5 |
+
#header { color:black; }
|
6 |
+
a b ul li { color:green; }
|
lib/vendor/lessphp/tests/outputs/variables.css
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.variables {
|
2 |
+
width:14cm;
|
3 |
+
height:24px;
|
4 |
+
margin-top:-20px;
|
5 |
+
margin-bottom:30px;
|
6 |
+
color:#888899;
|
7 |
+
background:#6c94be;
|
8 |
+
font-family:"Trebuchet MS", Verdana, sans-serif;
|
9 |
+
margin:3px;
|
10 |
+
font-size:10px/12px;
|
11 |
+
font-size:120%/120%;
|
12 |
+
}
|
13 |
+
.external {
|
14 |
+
color:#888888;
|
15 |
+
border:1px solid rgb(20%,15%,80%);
|
16 |
+
background:rgba(23,68,149,0.5);
|
17 |
+
padding:4px;
|
18 |
+
}
|
19 |
+
division:5px;
|
20 |
+
division:5px;
|
21 |
+
subtract:10 "hello";
|
22 |
+
subtract:2 -2;
|
23 |
+
addition:10;
|
24 |
+
addition:10;
|
25 |
+
math:20;
|
lib/vendor/lessphp/tests/test.php
ADDED
@@ -0,0 +1,121 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
error_reporting(E_ALL);
|
3 |
+
|
4 |
+
/**
|
5 |
+
* Go through all files matching pattern in input directory
|
6 |
+
* and compile them, then compare them to paired file in
|
7 |
+
* output directory.
|
8 |
+
*/
|
9 |
+
$difftool = 'diff';
|
10 |
+
$input = array(
|
11 |
+
'dir' => 'inputs',
|
12 |
+
'match' => '(.*?)\.less',
|
13 |
+
);
|
14 |
+
|
15 |
+
$output = array(
|
16 |
+
'dir' => 'outputs',
|
17 |
+
'filename' => '%s.css',
|
18 |
+
);
|
19 |
+
|
20 |
+
require realpath(dirname(__FILE__)).'/../lessc.inc.php';
|
21 |
+
$compiler = new lessc();
|
22 |
+
|
23 |
+
$fa = 'Fatal Error: ';
|
24 |
+
if (php_sapi_name() != 'cli') {
|
25 |
+
exit($fa.$argv[0].' must be run in the command line.');
|
26 |
+
}
|
27 |
+
|
28 |
+
$exe = array_shift($argv); // remove filename
|
29 |
+
function flag($f) {
|
30 |
+
if (func_num_args() > 1) {
|
31 |
+
foreach (func_get_args() as $f) if (flag($f)) return true;
|
32 |
+
return false;
|
33 |
+
}
|
34 |
+
global $argv;
|
35 |
+
$pre = strlen($f) > 1 ? '--' : '-';
|
36 |
+
foreach ($argv as $a) {
|
37 |
+
if (preg_match('/^'.$pre.$f.'($|\s)/', $a)) return true;
|
38 |
+
}
|
39 |
+
return false;
|
40 |
+
}
|
41 |
+
|
42 |
+
if (flag('h', 'help')) {
|
43 |
+
exit('help me');
|
44 |
+
}
|
45 |
+
|
46 |
+
if (!is_dir($input['dir']) || !is_dir($output['dir']))
|
47 |
+
exit($fa." both input and output directories must exist\n");
|
48 |
+
|
49 |
+
$tests = array();
|
50 |
+
// todo: use glob so user can select tests by name
|
51 |
+
foreach (scandir($input['dir']) as $fname) {
|
52 |
+
if (preg_match('/^'.$input['match'].'$/', $fname, $match)) {
|
53 |
+
$tests[] = array(
|
54 |
+
'in' => $input['dir'].'/'.$fname,
|
55 |
+
'out' => $output['dir'].'/'.sprintf($output['filename'], $match[1]),
|
56 |
+
);
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
$count = count($tests);
|
61 |
+
$compiling = flag('C');
|
62 |
+
$showDiff = flag('d', 'diff');
|
63 |
+
echo ($compiling ? "Compiling" : "Running")." $count test".($count == 1 ? '' : 's').":\n";
|
64 |
+
|
65 |
+
function dump($msgs, $depth = 1) {
|
66 |
+
if (!is_array($msgs)) $msgs = array($msgs);
|
67 |
+
foreach ($msgs as $m) {
|
68 |
+
echo str_repeat("\t", $depth).' - '.$m."\n";
|
69 |
+
}
|
70 |
+
}
|
71 |
+
|
72 |
+
$i = 1;
|
73 |
+
foreach ($tests as $test) {
|
74 |
+
printf("\t[Test %04d/%04d] %s -> %s\n", $i, $count, basename($test['in']), basename($test['out']));
|
75 |
+
|
76 |
+
try {
|
77 |
+
ob_start();
|
78 |
+
$parsed = trim($compiler->parse(file_get_contents($test['in'])));
|
79 |
+
ob_end_clean();
|
80 |
+
} catch (exception $e) {
|
81 |
+
dump(array(
|
82 |
+
"Failed to compile input, reason:",
|
83 |
+
$e->getMessage(),
|
84 |
+
"Aborting"
|
85 |
+
));
|
86 |
+
break;
|
87 |
+
}
|
88 |
+
|
89 |
+
if ($compiling) {
|
90 |
+
file_put_contents($test['out'], $parsed);
|
91 |
+
} else {
|
92 |
+
if (!is_file($test['out'])) {
|
93 |
+
dump(array(
|
94 |
+
"Failed to find output file: $test[out]",
|
95 |
+
"Maybe you forgot to compile tests?",
|
96 |
+
"Aborting"
|
97 |
+
));
|
98 |
+
break;
|
99 |
+
}
|
100 |
+
$expected = trim(file_get_contents($test['out']));
|
101 |
+
|
102 |
+
if ($expected != $parsed) {
|
103 |
+
if ($showDiff) {
|
104 |
+
dump("Failed:");
|
105 |
+
$tmp = $test['out'].".tmp";
|
106 |
+
file_put_contents($tmp, $parsed);
|
107 |
+
system($difftool.' '.$test['out'].' '.$tmp);
|
108 |
+
unlink($tmp);
|
109 |
+
|
110 |
+
dump("Aborting");
|
111 |
+
break;
|
112 |
+
} else dump("Failed, run with -d flag to view diff");
|
113 |
+
} else {
|
114 |
+
dump("Passed");
|
115 |
+
}
|
116 |
+
}
|
117 |
+
|
118 |
+
$i++;
|
119 |
+
}
|
120 |
+
|
121 |
+
?>
|
lib/vendor/plugin-toolkit/BaseConfiguration.class.php
CHANGED
@@ -1,12 +1,17 @@
|
|
1 |
<?php
|
2 |
-
|
|
|
|
|
|
|
|
|
|
|
3 |
abstract class WPPluginToolkitConfiguration
|
4 |
{
|
5 |
const UNIX_NAME = null;
|
6 |
const I18N_DIR = 'i18n';
|
7 |
|
8 |
-
protected
|
9 |
-
|
10 |
|
11 |
protected $base_class_name,
|
12 |
$base_dirname,
|
@@ -17,12 +22,13 @@ abstract class WPPluginToolkitConfiguration
|
|
17 |
$i18n_path_from_plugins,
|
18 |
$options,
|
19 |
$plugin_path,
|
|
|
20 |
$unix_name;
|
21 |
|
22 |
/**
|
23 |
* Launch the configure process
|
24 |
* It is generally totally specific to each plugin.
|
25 |
-
*
|
26 |
* @author oncletom
|
27 |
* @protected
|
28 |
*/
|
@@ -34,7 +40,7 @@ abstract class WPPluginToolkitConfiguration
|
|
34 |
|
35 |
/**
|
36 |
* Let the plugin configure its own options
|
37 |
-
*
|
38 |
* @author oncletom
|
39 |
* @abstract
|
40 |
* @protected
|
@@ -43,7 +49,7 @@ abstract class WPPluginToolkitConfiguration
|
|
43 |
|
44 |
/**
|
45 |
* Base constructor for a plugin configuration
|
46 |
-
*
|
47 |
* @author oncletom
|
48 |
* @since 1.0
|
49 |
* @version 1.0
|
@@ -61,7 +67,7 @@ abstract class WPPluginToolkitConfiguration
|
|
61 |
}
|
62 |
|
63 |
$this->base_class_name = $baseClassName;
|
64 |
-
$this->setupPath($baseFileName,
|
65 |
$this->setupPathGlobal();
|
66 |
//$this->options = new $baseClassName.'OptionCollection';
|
67 |
|
@@ -71,7 +77,7 @@ abstract class WPPluginToolkitConfiguration
|
|
71 |
|
72 |
/**
|
73 |
* Returns resolved plugin full path location
|
74 |
-
*
|
75 |
* @author oncletom
|
76 |
* @since 1.0
|
77 |
* @version 1.0
|
@@ -84,7 +90,7 @@ abstract class WPPluginToolkitConfiguration
|
|
84 |
|
85 |
/**
|
86 |
* Returns resolved plugin full path filename
|
87 |
-
*
|
88 |
* @author oncletom
|
89 |
* @since 1.0
|
90 |
* @version 1.0
|
@@ -95,9 +101,35 @@ abstract class WPPluginToolkitConfiguration
|
|
95 |
return $this->filename;
|
96 |
}
|
97 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
/**
|
99 |
* Returns plugin prefix for classes
|
100 |
-
*
|
101 |
* @author oncletom
|
102 |
* @since 1.0
|
103 |
* @version 1.0
|
@@ -110,10 +142,10 @@ abstract class WPPluginToolkitConfiguration
|
|
110 |
|
111 |
/**
|
112 |
* Returns resolved plugin path location, from plugin path
|
113 |
-
*
|
114 |
* In theory, it's the same as Unix path but in fact, if the plugin is renamed it can helps
|
115 |
* Not very used yet, though.
|
116 |
-
*
|
117 |
* @author oncletom
|
118 |
* @since 1.0
|
119 |
* @version 1.0
|
@@ -122,11 +154,16 @@ abstract class WPPluginToolkitConfiguration
|
|
122 |
public function getPluginPath()
|
123 |
{
|
124 |
return $this->plugin_path;
|
125 |
-
}
|
|
|
|
|
|
|
|
|
|
|
126 |
|
127 |
/**
|
128 |
* Returns unix name of the plugin
|
129 |
-
*
|
130 |
* @author oncletom
|
131 |
* @since 1.0
|
132 |
* @version 1.0
|
@@ -139,7 +176,7 @@ abstract class WPPluginToolkitConfiguration
|
|
139 |
|
140 |
/**
|
141 |
* Returns the upload dir for this configuration class (common to all instances)
|
142 |
-
*
|
143 |
* @author oncletom
|
144 |
* @since 1.0
|
145 |
* @version 1.0
|
@@ -147,12 +184,12 @@ abstract class WPPluginToolkitConfiguration
|
|
147 |
*/
|
148 |
public function getUploadDir()
|
149 |
{
|
150 |
-
return
|
151 |
}
|
152 |
|
153 |
/**
|
154 |
* Returns the upload URL for this configuration class (common to all instances)
|
155 |
-
*
|
156 |
* @author oncletom
|
157 |
* @since 1.0
|
158 |
* @version 1.0
|
@@ -160,12 +197,12 @@ abstract class WPPluginToolkitConfiguration
|
|
160 |
*/
|
161 |
public function getUploadUrl()
|
162 |
{
|
163 |
-
return
|
164 |
}
|
165 |
|
166 |
/**
|
167 |
* Build paths for various access
|
168 |
-
*
|
169 |
* @author oncletom
|
170 |
* @protected
|
171 |
* @since 1.0
|
@@ -196,29 +233,43 @@ abstract class WPPluginToolkitConfiguration
|
|
196 |
|
197 |
$this->dirname = dirname($this->filename);
|
198 |
$this->plugin_path = preg_replace('#(.+)([^/]+/[^/]+)$#sU', "$2", $this->filename);
|
|
|
199 |
do_action($this->unix_name.'_configuration_setup_path', $this);
|
200 |
}
|
201 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
202 |
/**
|
203 |
* Resolves global upload path as WP does not provide any clean and independant solution for that
|
204 |
-
*
|
205 |
* It's barely based on the logic of `wp_upload_dir` function.
|
206 |
-
*
|
207 |
* @author oncletom
|
208 |
* @since 1.0
|
209 |
-
* @version 1.
|
210 |
* @return boolean
|
211 |
*/
|
212 |
protected function setupPathGlobal()
|
213 |
{
|
214 |
-
if (isset(
|
215 |
{
|
216 |
return false;
|
217 |
}
|
218 |
|
219 |
$siteurl = get_option('siteurl');
|
220 |
$upload_path = trim(get_option('upload_path'));
|
221 |
-
$subdir =
|
222 |
|
223 |
if (defined('UPLOADS'))
|
224 |
{
|
@@ -237,19 +288,32 @@ abstract class WPPluginToolkitConfiguration
|
|
237 |
: trailingslashit($siteurl).$upload_path;
|
238 |
}
|
239 |
}
|
240 |
-
|
241 |
$uploads = apply_filters('upload_dir', array(
|
242 |
'path' => $dir,
|
243 |
'url' => $url,
|
244 |
-
'subdir' =>
|
245 |
-
'basedir' => $dir.$subdir,
|
246 |
-
'baseurl' => $url.$subdir,
|
247 |
'error' => false,
|
248 |
));
|
249 |
|
250 |
-
|
251 |
-
|
252 |
|
253 |
return $uploads['error'] ? false : true;
|
254 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
255 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Base class for plugin configuration
|
4 |
+
*
|
5 |
+
* @author oncletom
|
6 |
+
* @version 1.1
|
7 |
+
*/
|
8 |
abstract class WPPluginToolkitConfiguration
|
9 |
{
|
10 |
const UNIX_NAME = null;
|
11 |
const I18N_DIR = 'i18n';
|
12 |
|
13 |
+
protected $upload_dir,
|
14 |
+
$upload_url;
|
15 |
|
16 |
protected $base_class_name,
|
17 |
$base_dirname,
|
22 |
$i18n_path_from_plugins,
|
23 |
$options,
|
24 |
$plugin_path,
|
25 |
+
$plugin_uri,
|
26 |
$unix_name;
|
27 |
|
28 |
/**
|
29 |
* Launch the configure process
|
30 |
* It is generally totally specific to each plugin.
|
31 |
+
*
|
32 |
* @author oncletom
|
33 |
* @protected
|
34 |
*/
|
40 |
|
41 |
/**
|
42 |
* Let the plugin configure its own options
|
43 |
+
*
|
44 |
* @author oncletom
|
45 |
* @abstract
|
46 |
* @protected
|
49 |
|
50 |
/**
|
51 |
* Base constructor for a plugin configuration
|
52 |
+
*
|
53 |
* @author oncletom
|
54 |
* @since 1.0
|
55 |
* @version 1.0
|
67 |
}
|
68 |
|
69 |
$this->base_class_name = $baseClassName;
|
70 |
+
$this->setupPath($baseFileName, $this->unix_name);
|
71 |
$this->setupPathGlobal();
|
72 |
//$this->options = new $baseClassName.'OptionCollection';
|
73 |
|
77 |
|
78 |
/**
|
79 |
* Returns resolved plugin full path location
|
80 |
+
*
|
81 |
* @author oncletom
|
82 |
* @since 1.0
|
83 |
* @version 1.0
|
90 |
|
91 |
/**
|
92 |
* Returns resolved plugin full path filename
|
93 |
+
*
|
94 |
* @author oncletom
|
95 |
* @since 1.0
|
96 |
* @version 1.0
|
101 |
return $this->filename;
|
102 |
}
|
103 |
|
104 |
+
/**
|
105 |
+
* Returns i18n path from WordPress root directory
|
106 |
+
*
|
107 |
+
* @author oncletom
|
108 |
+
* @since 1.0
|
109 |
+
* @version 1.0
|
110 |
+
* @return String
|
111 |
+
*/
|
112 |
+
public function getI18nPath()
|
113 |
+
{
|
114 |
+
return $this->i18n_path;
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Returns i18n path from plugin directory
|
119 |
+
*
|
120 |
+
* @author oncletom
|
121 |
+
* @since 1.0
|
122 |
+
* @version 1.0
|
123 |
+
* @return String
|
124 |
+
*/
|
125 |
+
public function getI18nFromPluginPath()
|
126 |
+
{
|
127 |
+
return $this->i18n_path_from_plugins;
|
128 |
+
}
|
129 |
+
|
130 |
/**
|
131 |
* Returns plugin prefix for classes
|
132 |
+
*
|
133 |
* @author oncletom
|
134 |
* @since 1.0
|
135 |
* @version 1.0
|
142 |
|
143 |
/**
|
144 |
* Returns resolved plugin path location, from plugin path
|
145 |
+
*
|
146 |
* In theory, it's the same as Unix path but in fact, if the plugin is renamed it can helps
|
147 |
* Not very used yet, though.
|
148 |
+
*
|
149 |
* @author oncletom
|
150 |
* @since 1.0
|
151 |
* @version 1.0
|
154 |
public function getPluginPath()
|
155 |
{
|
156 |
return $this->plugin_path;
|
157 |
+
}
|
158 |
+
|
159 |
+
public function getPluginUri()
|
160 |
+
{
|
161 |
+
return $this->plugin_uri;
|
162 |
+
}
|
163 |
|
164 |
/**
|
165 |
* Returns unix name of the plugin
|
166 |
+
*
|
167 |
* @author oncletom
|
168 |
* @since 1.0
|
169 |
* @version 1.0
|
176 |
|
177 |
/**
|
178 |
* Returns the upload dir for this configuration class (common to all instances)
|
179 |
+
*
|
180 |
* @author oncletom
|
181 |
* @since 1.0
|
182 |
* @version 1.0
|
184 |
*/
|
185 |
public function getUploadDir()
|
186 |
{
|
187 |
+
return $this->upload_dir;
|
188 |
}
|
189 |
|
190 |
/**
|
191 |
* Returns the upload URL for this configuration class (common to all instances)
|
192 |
+
*
|
193 |
* @author oncletom
|
194 |
* @since 1.0
|
195 |
* @version 1.0
|
197 |
*/
|
198 |
public function getUploadUrl()
|
199 |
{
|
200 |
+
return $this->upload_url;
|
201 |
}
|
202 |
|
203 |
/**
|
204 |
* Build paths for various access
|
205 |
+
*
|
206 |
* @author oncletom
|
207 |
* @protected
|
208 |
* @since 1.0
|
233 |
|
234 |
$this->dirname = dirname($this->filename);
|
235 |
$this->plugin_path = preg_replace('#(.+)([^/]+/[^/]+)$#sU', "$2", $this->filename);
|
236 |
+
$this->plugin_uri = WP_PLUGIN_URL.'/'.dirname($this->plugin_path);
|
237 |
do_action($this->unix_name.'_configuration_setup_path', $this);
|
238 |
}
|
239 |
|
240 |
+
/**
|
241 |
+
* Defines an upload directory
|
242 |
+
*
|
243 |
+
* @author oncletom
|
244 |
+
* @version 1.1
|
245 |
+
* @since 1.1
|
246 |
+
* @param String $upload_uri
|
247 |
+
*/
|
248 |
+
public function setUploadDir($upload_dir)
|
249 |
+
{
|
250 |
+
return $this->upload_dir = $upload_dir;
|
251 |
+
}
|
252 |
+
|
253 |
/**
|
254 |
* Resolves global upload path as WP does not provide any clean and independant solution for that
|
255 |
+
*
|
256 |
* It's barely based on the logic of `wp_upload_dir` function.
|
257 |
+
*
|
258 |
* @author oncletom
|
259 |
* @since 1.0
|
260 |
+
* @version 1.2
|
261 |
* @return boolean
|
262 |
*/
|
263 |
protected function setupPathGlobal()
|
264 |
{
|
265 |
+
if (isset($this->upload_url))
|
266 |
{
|
267 |
return false;
|
268 |
}
|
269 |
|
270 |
$siteurl = get_option('siteurl');
|
271 |
$upload_path = trim(get_option('upload_path'));
|
272 |
+
$subdir = $this->unix_name;
|
273 |
|
274 |
if (defined('UPLOADS'))
|
275 |
{
|
288 |
: trailingslashit($siteurl).$upload_path;
|
289 |
}
|
290 |
}
|
291 |
+
|
292 |
$uploads = apply_filters('upload_dir', array(
|
293 |
'path' => $dir,
|
294 |
'url' => $url,
|
295 |
+
'subdir' => '/'.$subdir,
|
296 |
+
'basedir' => trailingslashit($dir).$subdir,
|
297 |
+
'baseurl' => trailingslashit($url).$subdir,
|
298 |
'error' => false,
|
299 |
));
|
300 |
|
301 |
+
$this->setUploadDir($uploads['basedir']);
|
302 |
+
$this->setUploadUrl($uploads['baseurl']);
|
303 |
|
304 |
return $uploads['error'] ? false : true;
|
305 |
}
|
306 |
+
|
307 |
+
/**
|
308 |
+
* Defines an upload URL
|
309 |
+
*
|
310 |
+
* @author oncletom
|
311 |
+
* @version 1.1
|
312 |
+
* @since 1.1
|
313 |
+
* @param String $upload_url
|
314 |
+
*/
|
315 |
+
public function setUploadUrl($upload_url)
|
316 |
+
{
|
317 |
+
return $this->upload_url = $upload_url;
|
318 |
+
}
|
319 |
}
|
lib/vendor/plugin-toolkit/BasePlugin.class.php
CHANGED
@@ -1,9 +1,9 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
* Base plugin class to extend
|
4 |
-
*
|
5 |
-
* @version 1.
|
6 |
-
* @author
|
7 |
* @package plugin-toolkit
|
8 |
*/
|
9 |
abstract class WPPluginToolkitPlugin
|
@@ -13,9 +13,20 @@ abstract class WPPluginToolkitPlugin
|
|
13 |
|
14 |
protected static $instances = array();
|
15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
/**
|
17 |
* Plugin constructor
|
18 |
-
*
|
19 |
* @author oncletom
|
20 |
* @since 1.0
|
21 |
* @version 1.0
|
@@ -30,12 +41,13 @@ abstract class WPPluginToolkitPlugin
|
|
30 |
spl_autoload_register(array($this, 'configureAutoload'));
|
31 |
}
|
32 |
|
33 |
-
|
|
|
34 |
}
|
35 |
|
36 |
/**
|
37 |
* Autoloads classes for this plugin
|
38 |
-
*
|
39 |
* @author oncletom
|
40 |
* @return boolean
|
41 |
* @param string $className
|
@@ -64,12 +76,12 @@ abstract class WPPluginToolkitPlugin
|
|
64 |
|
65 |
/**
|
66 |
* WordPress plugin builder
|
67 |
-
*
|
68 |
* @author oncletom
|
69 |
* @static
|
70 |
* @final
|
71 |
* @since 1.0
|
72 |
-
* @version 1.
|
73 |
* @param string $baseClassName
|
74 |
* @param string $baseFileName
|
75 |
* @param string $singleton_identifier[optional]
|
@@ -77,7 +89,11 @@ abstract class WPPluginToolkitPlugin
|
|
77 |
*/
|
78 |
public final static function create($baseClassName, $baseFileName, $singleton_identifier = null)
|
79 |
{
|
80 |
-
|
|
|
|
|
|
|
|
|
81 |
require_once dirname($baseFileName).'/lib/Configuration.class.php';
|
82 |
|
83 |
$class = $baseClassName.'Plugin';
|
@@ -99,7 +115,7 @@ abstract class WPPluginToolkitPlugin
|
|
99 |
|
100 |
/**
|
101 |
* Returns the current configuration
|
102 |
-
*
|
103 |
* @author oncletom
|
104 |
* @since 1.0
|
105 |
* @version 1.0
|
@@ -113,7 +129,7 @@ abstract class WPPluginToolkitPlugin
|
|
113 |
/**
|
114 |
* Retrieves the instance of an object
|
115 |
* If no identifier is given, the first created instance is returned
|
116 |
-
*
|
117 |
* @author oncletom
|
118 |
* @since 1.1
|
119 |
* @version 1.0
|
@@ -134,7 +150,7 @@ abstract class WPPluginToolkitPlugin
|
|
134 |
/**
|
135 |
* Stores an instance of a created object
|
136 |
* Self storage is so good :)
|
137 |
-
*
|
138 |
* @author oncletom
|
139 |
* @since 1.1
|
140 |
* @version 1.0
|
1 |
<?php
|
2 |
/**
|
3 |
* Base plugin class to extend
|
4 |
+
*
|
5 |
+
* @version 1.2
|
6 |
+
* @author oncletom
|
7 |
* @package plugin-toolkit
|
8 |
*/
|
9 |
abstract class WPPluginToolkitPlugin
|
13 |
|
14 |
protected static $instances = array();
|
15 |
|
16 |
+
/**
|
17 |
+
* Dispatches the plugin hooks, filters etc.
|
18 |
+
*
|
19 |
+
* This is basically the first thing done when the class is created.
|
20 |
+
*
|
21 |
+
* @author oncletom
|
22 |
+
* @since 1.0
|
23 |
+
* @abstract
|
24 |
+
*/
|
25 |
+
abstract public function dispatch();
|
26 |
+
|
27 |
/**
|
28 |
* Plugin constructor
|
29 |
+
*
|
30 |
* @author oncletom
|
31 |
* @since 1.0
|
32 |
* @version 1.0
|
41 |
spl_autoload_register(array($this, 'configureAutoload'));
|
42 |
}
|
43 |
|
44 |
+
load_plugin_textdomain($configuration->getUnixName(), $configuration->getI18nPath(), $configuration->getI18nFromPluginPath());
|
45 |
+
do_action($configuration->getUnixName().'_plugin_construct', $this);
|
46 |
}
|
47 |
|
48 |
/**
|
49 |
* Autoloads classes for this plugin
|
50 |
+
*
|
51 |
* @author oncletom
|
52 |
* @return boolean
|
53 |
* @param string $className
|
76 |
|
77 |
/**
|
78 |
* WordPress plugin builder
|
79 |
+
*
|
80 |
* @author oncletom
|
81 |
* @static
|
82 |
* @final
|
83 |
* @since 1.0
|
84 |
+
* @version 1.1
|
85 |
* @param string $baseClassName
|
86 |
* @param string $baseFileName
|
87 |
* @param string $singleton_identifier[optional]
|
89 |
*/
|
90 |
public final static function create($baseClassName, $baseFileName, $singleton_identifier = null)
|
91 |
{
|
92 |
+
if (!class_exists('WPPluginToolkitConfiguration'))
|
93 |
+
{
|
94 |
+
require_once dirname(__FILE__).'/BaseConfiguration.class.php';
|
95 |
+
}
|
96 |
+
|
97 |
require_once dirname($baseFileName).'/lib/Configuration.class.php';
|
98 |
|
99 |
$class = $baseClassName.'Plugin';
|
115 |
|
116 |
/**
|
117 |
* Returns the current configuration
|
118 |
+
*
|
119 |
* @author oncletom
|
120 |
* @since 1.0
|
121 |
* @version 1.0
|
129 |
/**
|
130 |
* Retrieves the instance of an object
|
131 |
* If no identifier is given, the first created instance is returned
|
132 |
+
*
|
133 |
* @author oncletom
|
134 |
* @since 1.1
|
135 |
* @version 1.0
|
150 |
/**
|
151 |
* Stores an instance of a created object
|
152 |
* Self storage is so good :)
|
153 |
+
*
|
154 |
* @author oncletom
|
155 |
* @since 1.1
|
156 |
* @version 1.0
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_i
|
|
4 |
Tags: dev, theme, themes, toolkit, plugin-toolkit, less, lesscss, lessc, lessphp, productivity, style, stylesheet, api
|
5 |
Requires at least: 2.8
|
6 |
Tested up to: 2.8.x
|
7 |
-
Stable tag: 1.
|
8 |
|
9 |
Implementation of LESS (Leaner CSS) in order to make themes development easier.
|
10 |
|
@@ -47,6 +47,21 @@ The sole requirement is to use WordPress API and LESS convention: the `.less` ex
|
|
47 |
1. Activate it through your WordPress plugins administration page
|
48 |
|
49 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
= Version 1.2 =
|
51 |
|
52 |
* added 2 new filters working on freshly transformed CSS
|
4 |
Tags: dev, theme, themes, toolkit, plugin-toolkit, less, lesscss, lessc, lessphp, productivity, style, stylesheet, api
|
5 |
Requires at least: 2.8
|
6 |
Tested up to: 2.8.x
|
7 |
+
Stable tag: 1.3
|
8 |
|
9 |
Implementation of LESS (Leaner CSS) in order to make themes development easier.
|
10 |
|
47 |
1. Activate it through your WordPress plugins administration page
|
48 |
|
49 |
== Changelog ==
|
50 |
+
= Version 1.3 =
|
51 |
+
|
52 |
+
* moved stylesheet processing from `wp_print_styles` to `wp` action
|
53 |
+
* added new compiler actions and filters (same name each): `wp-less_compiler_construct` and `wp-less_compiler_parse`
|
54 |
+
* added `WPLessCompiler::getBuffer()` and `WPLessCompiler::setBuffer()` method, to enables hooking on LESS content, before being compiled into CSS
|
55 |
+
* removed `WPLessStyleseet::getTargetContent` method
|
56 |
+
* upgraded `plugin-toolkit`
|
57 |
+
* usage of `$WPLessPlugin->dispatch` instead of `$WPLessPlugin->registerHooks` to match the new `plugin-toolkit` signature
|
58 |
+
* no more configuration collision if usage of multiple plugins using `plugin-toolkit`
|
59 |
+
* lessphp: updated to [eac64a9d5a3bc3186a11c7130968388819f4c403](https://github.com/leafo/lessphp/commit/eac64a9d5a3bc3186a11c7130968388819f4c403) commit
|
60 |
+
|
61 |
+
= Version 1.2.1 =
|
62 |
+
|
63 |
+
* fixed the case where no stylesheet is queued (no warning anymore)
|
64 |
+
|
65 |
= Version 1.2 =
|
66 |
|
67 |
* added 2 new filters working on freshly transformed CSS
|