]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - vendor/oyejorge/less.php/lessc.inc.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / vendor / oyejorge / less.php / lessc.inc.php
1 <?php
2 /**
3  * This file provides the part of lessphp API (https://github.com/leafo/lessphp)
4  * to be a drop-in replacement for following products:
5  *  - Drupal 7, by the less module v3.0+ (https://drupal.org/project/less)
6  *  - Symfony 2
7  */
8
9 // Register autoloader for non-composer installations
10 if ( !class_exists( 'Less_Parser' ) ) {
11         require_once __DIR__ . '/lib/Less/Autoloader.php';
12         Less_Autoloader::register();
13 }
14
15 class lessc {
16
17         static public $VERSION = Less_Version::less_version;
18
19         public $importDir = '';
20         protected $allParsedFiles = array();
21         protected $libFunctions = array();
22         protected $registeredVars = array();
23         private $formatterName;
24         private $options = array();
25
26         public function __construct( $lessc=null, $sourceName=null ) {}
27
28         public function setImportDir( $dirs ) {
29                 $this->importDir = (array)$dirs;
30         }
31
32         public function addImportDir( $dir ) {
33                 $this->importDir = (array)$this->importDir;
34                 $this->importDir[] = $dir;
35         }
36
37         public function setFormatter( $name ) {
38                 $this->formatterName = $name;
39         }
40
41         public function setPreserveComments( $preserve ) {}
42
43         public function registerFunction( $name, $func ) {
44                 $this->libFunctions[$name] = $func;
45         }
46
47         public function unregisterFunction( $name ) {
48                 unset( $this->libFunctions[$name] );
49         }
50
51         public function setVariables( $variables ){
52                 foreach ( $variables as $name => $value ) {
53                         $this->setVariable( $name, $value );
54                 }
55         }
56
57         public function setVariable( $name, $value ) {
58                 $this->registeredVars[$name] = $value;
59         }
60
61         public function unsetVariable( $name ) {
62                 unset( $this->registeredVars[$name] );
63         }
64
65         public function setOptions( $options ) {
66                 foreach ( $options as $name => $value ) {
67                         $this->setOption( $name, $value);
68                 }
69         }
70         
71         public function setOption( $name, $value ) {
72                 $this->options[$name] = $value;
73         }
74         
75         public function parse( $buffer, $presets = array() ) {
76
77                 $this->setVariables( $presets );
78
79                 $parser = new Less_Parser( $this->getOptions() );
80                 $parser->setImportDirs( $this->getImportDirs() );
81                 foreach ( $this->libFunctions as $name => $func ) {
82                         $parser->registerFunction( $name, $func );
83                 }
84                 $parser->parse($buffer);
85                 if ( count( $this->registeredVars ) ) {
86                         $parser->ModifyVars( $this->registeredVars );
87                 }
88
89                 return $parser->getCss();
90         }
91
92         protected function getOptions() {
93                 $options = array( 'relativeUrls'=>false );
94                 switch( $this->formatterName ) {
95                         case 'compressed':
96                                 $options['compress'] = true;
97                                 break;
98                 }
99                 if (is_array($this->options))
100                 {
101                         $options = array_merge($options, $this->options);
102                 }
103                 return $options;
104         }
105
106         protected function getImportDirs() {
107                 $dirs_ = (array)$this->importDir;
108                 $dirs = array();
109                 foreach ( $dirs_ as $dir ) {
110                         $dirs[$dir] = '';
111                 }
112                 return $dirs;
113         }
114
115         public function compile( $string, $name = null ) {
116
117                 $oldImport = $this->importDir;
118                 $this->importDir = (array)$this->importDir;
119
120                 $this->allParsedFiles = array();
121
122                 $parser = new Less_Parser( $this->getOptions() );
123                 $parser->SetImportDirs( $this->getImportDirs() );
124                 if ( count( $this->registeredVars ) ) {
125                         $parser->ModifyVars( $this->registeredVars );
126                 }
127                 foreach ( $this->libFunctions as $name => $func ) {
128                         $parser->registerFunction( $name, $func );
129                 }
130                 $parser->parse( $string );
131                 $out = $parser->getCss();
132
133                 $parsed = Less_Parser::AllParsedFiles();
134                 foreach ( $parsed as $file ) {
135                         $this->addParsedFile( $file );
136                 }
137
138                 $this->importDir = $oldImport;
139
140                 return $out;
141         }
142
143         public function compileFile( $fname, $outFname = null ) {
144                 if ( !is_readable( $fname ) ) {
145                         throw new Exception( 'load error: failed to find '.$fname );
146                 }
147
148                 $pi = pathinfo( $fname );
149
150                 $oldImport = $this->importDir;
151
152                 $this->importDir = (array)$this->importDir;
153                 $this->importDir[] = Less_Parser::AbsPath( $pi['dirname'] ).'/';
154
155                 $this->allParsedFiles = array();
156                 $this->addParsedFile( $fname );
157
158                 $parser = new Less_Parser( $this->getOptions() );
159                 $parser->SetImportDirs( $this->getImportDirs() );
160                 if ( count( $this->registeredVars ) ) {
161                         $parser->ModifyVars( $this->registeredVars );
162                 }
163                 foreach ( $this->libFunctions as $name => $func ) {
164                         $parser->registerFunction( $name, $func );
165                 }
166                 $parser->parseFile( $fname );
167                 $out = $parser->getCss();
168
169                 $parsed = Less_Parser::AllParsedFiles();
170                 foreach ( $parsed as $file ) {
171                         $this->addParsedFile( $file );
172                 }
173
174                 $this->importDir = $oldImport;
175
176                 if ( $outFname !== null ) {
177                         return file_put_contents( $outFname, $out );
178                 }
179
180                 return $out;
181         }
182
183         public function checkedCompile( $in, $out ) {
184                 if ( !is_file( $out ) || filemtime( $in ) > filemtime( $out ) ) {
185                         $this->compileFile($in, $out);
186                         return true;
187                 }
188                 return false;
189         }
190
191
192         /**
193          * Execute lessphp on a .less file or a lessphp cache structure
194          *
195          * The lessphp cache structure contains information about a specific
196          * less file having been parsed. It can be used as a hint for future
197          * calls to determine whether or not a rebuild is required.
198          *
199          * The cache structure contains two important keys that may be used
200          * externally:
201          *
202          * compiled: The final compiled CSS
203          * updated: The time (in seconds) the CSS was last compiled
204          *
205          * The cache structure is a plain-ol' PHP associative array and can
206          * be serialized and unserialized without a hitch.
207          *
208          * @param mixed $in Input
209          * @param bool $force Force rebuild?
210          * @return array lessphp cache structure
211          */
212         public function cachedCompile( $in, $force = false ) {
213                 // assume no root
214                 $root = null;
215
216                 if ( is_string( $in ) ) {
217                         $root = $in;
218                 } elseif ( is_array( $in ) and isset( $in['root'] ) ) {
219                         if ( $force or ! isset( $in['files'] ) ) {
220                                 // If we are forcing a recompile or if for some reason the
221                                 // structure does not contain any file information we should
222                                 // specify the root to trigger a rebuild.
223                                 $root = $in['root'];
224                         } elseif ( isset( $in['files'] ) and is_array( $in['files'] ) ) {
225                                 foreach ( $in['files'] as $fname => $ftime ) {
226                                         if ( !file_exists( $fname ) or filemtime( $fname ) > $ftime ) {
227                                                 // One of the files we knew about previously has changed
228                                                 // so we should look at our incoming root again.
229                                                 $root = $in['root'];
230                                                 break;
231                                         }
232                                 }
233                         }
234                 } else {
235                         // TODO: Throw an exception? We got neither a string nor something
236                         // that looks like a compatible lessphp cache structure.
237                         return null;
238                 }
239
240                 if ( $root !== null ) {
241                         // If we have a root value which means we should rebuild.
242                         $out = array();
243                         $out['root'] = $root;
244                         $out['compiled'] = $this->compileFile($root);
245                         $out['files'] = $this->allParsedFiles();
246                         $out['updated'] = time();
247                         return $out;
248                 } else {
249                         // No changes, pass back the structure
250                         // we were given initially.
251                         return $in;
252                 }
253         }
254
255         public function ccompile( $in, $out, $less = null ) {
256                 if ( $less === null ) {
257                         $less = new self;
258                 }
259                 return $less->checkedCompile( $in, $out );
260         }
261
262         public static function cexecute( $in, $force = false, $less = null ) {
263                 if ( $less === null ) {
264                         $less = new self;
265                 }
266                 return $less->cachedCompile($in, $force);
267         }
268
269         public function allParsedFiles() {
270                 return $this->allParsedFiles;
271         }
272
273         protected function addParsedFile( $file ) {
274                 $this->allParsedFiles[Less_Parser::AbsPath( $file )] = filemtime( $file );
275         }
276 }