Fast Velocity Minify - Version 2.3.5

Version Description

[2018.08.27] = * added thinkwithgoogle support for the defer for insights option * added HyperCache support, thanks to @erich_k4wp * added suport for wp_add_inline_script, thanks to @yuriipavlov * fixed a bug where some inlined css was missing if not attached to a parent css file * the ignore list now also supports CSS handle names (no JS yet) * updated PHP Minify from master on github * improved performance for gtmetrix tests

Download this release

Release Info

Developer Alignak
Plugin Icon 128x128 Fast Velocity Minify
Version 2.3.5
Comparing to
See all releases

Code changes from version 2.3.4 to 2.3.5

fvm.php CHANGED
@@ -5,7 +5,7 @@ Plugin URI: http://fastvelocity.com
5
  Description: Improve your speed score on GTmetrix, Pingdom Tools and Google PageSpeed Insights by merging and minifying CSS and JavaScript files into groups, compressing HTML and other speed optimizations.
6
  Author: Raul Peixoto
7
  Author URI: http://fastvelocity.com
8
- Version: 2.3.4
9
  License: GPL2
10
 
11
  ------------------------------------------------------------------------
@@ -141,7 +141,7 @@ $exc = array('/html5shiv.js', '/html5shiv-printshiv.min.js', '/excanvas.js', '/a
141
  if(!is_array($blacklist) || strlen(implode($blacklist)) == 0) { update_option('fastvelocity_min_blacklist', implode("\n", $exc)); }
142
 
143
  # default ignore list
144
- $exc = array('/Avada/assets/js/main.min.js', '/woocommerce-product-search/js/product-search.js', '/includes/builder/scripts/frontend-builder-scripts.js', '/assets/js/jquery.themepunch.tools.min.js', '/js/TweenMax.min.js', '/jupiter/assets/js/min/full-scripts');
145
  if(!is_array($ignorelist) || strlen(implode($ignorelist)) == 0) { update_option('fastvelocity_min_ignorelist', implode("\n", $exc)); }
146
 
147
 
@@ -1003,6 +1003,13 @@ for($i=0,$l=count($header);$i<$l;$i++) {
1003
  $code.= $newcode;
1004
  $log.= $newlog;
1005
  }
 
 
 
 
 
 
 
1006
 
1007
  # consider dependencies on handles with an empty src
1008
  } else {
@@ -1139,7 +1146,14 @@ for($i=0,$l=count($footer);$i<$l;$i++) {
1139
  if($newcode !== false) {
1140
  $code.= $newcode;
1141
  $log.= $newlog;
1142
- }
 
 
 
 
 
 
 
1143
 
1144
  # consider dependencies on handles with an empty src
1145
  } else {
@@ -1240,7 +1254,7 @@ if (stripos($tag, "\n") !== false) { return $tag; }
1240
 
1241
  # print code if there are no linebreaks, or return
1242
  if(!empty($tagdefer)) {
1243
- $deferinsights = '<script type="text/javascript">if(navigator.userAgent.match(/speed|Lighthouse|gtmetrix|x11.*firefox\/53|x11.*chrome\/39/i)){document.write('.json_encode($tagdefer).');}else{document.write('.json_encode($tag).');}</script>';
1244
  return preg_replace('#<script(.*?)>(.*?)</script>#is', $deferinsights, $tag);
1245
  }
1246
 
@@ -1888,7 +1902,7 @@ if(substr($handle, 0, 4) != "fvm-" && $defer_for_pagespeed == true && $defer_for
1888
 
1889
  # print code if there are no linebreaks, or return
1890
  if(!empty($tagdefer)) {
1891
- $deferinsights = '<script type="text/javascript">if(!navigator.userAgent.match(/speed|Lighthouse|gtmetrix|x11.*firefox\/53|x11.*chrome\/39/i)){document.write('.json_encode($tag).');}</script>';
1892
  return preg_replace('#<script(.*?)>(.*?)</script>#is', $deferinsights, $tag);
1893
  }
1894
 
5
  Description: Improve your speed score on GTmetrix, Pingdom Tools and Google PageSpeed Insights by merging and minifying CSS and JavaScript files into groups, compressing HTML and other speed optimizations.
6
  Author: Raul Peixoto
7
  Author URI: http://fastvelocity.com
8
+ Version: 2.3.5
9
  License: GPL2
10
 
11
  ------------------------------------------------------------------------
141
  if(!is_array($blacklist) || strlen(implode($blacklist)) == 0) { update_option('fastvelocity_min_blacklist', implode("\n", $exc)); }
142
 
143
  # default ignore list
144
+ $exc = array('/Avada/assets/js/main.min.js', '/woocommerce-product-search/js/product-search.js', '/includes/builder/scripts/frontend-builder-scripts.js', '/assets/js/jquery.themepunch.tools.min.js', '/js/TweenMax.min.js', '/jupiter/assets/js/min/full-scripts', '/wp-content/themes/Divi/core/admin/js/react-dom.production.min.js');
145
  if(!is_array($ignorelist) || strlen(implode($ignorelist)) == 0) { update_option('fastvelocity_min_ignorelist', implode("\n", $exc)); }
146
 
147
 
1003
  $code.= $newcode;
1004
  $log.= $newlog;
1005
  }
1006
+
1007
+ # Add extra data from wp_add_inline_script before
1008
+ if ( ! empty( $wp_scripts->registered[$handle]->extra ) ) {
1009
+ if ( ! empty( $wp_scripts->registered[$handle]->extra['before'] ) ) {
1010
+ $code.= "\n".implode("\n", $wp_scripts->registered[$handle]->extra['before']);
1011
+ }
1012
+ }
1013
 
1014
  # consider dependencies on handles with an empty src
1015
  } else {
1146
  if($newcode !== false) {
1147
  $code.= $newcode;
1148
  $log.= $newlog;
1149
+ }
1150
+
1151
+ # Add extra data from wp_add_inline_script before
1152
+ if ( ! empty( $wp_scripts->registered[$handle]->extra ) ) {
1153
+ if ( ! empty( $wp_scripts->registered[$handle]->extra['before'] ) ) {
1154
+ $code.= "\n".implode("\n", $wp_scripts->registered[$handle]->extra['before']);
1155
+ }
1156
+ }
1157
 
1158
  # consider dependencies on handles with an empty src
1159
  } else {
1254
 
1255
  # print code if there are no linebreaks, or return
1256
  if(!empty($tagdefer)) {
1257
+ $deferinsights = '<script type="text/javascript">if(navigator.userAgent.match(/speed|Lighthouse|gtmetrix|Linux.*Moto\sG|x11.*firefox\/54|x11.*chrome\/39/i)){document.write('.json_encode($tagdefer).');}else{document.write('.json_encode($tag).');}</script>';
1258
  return preg_replace('#<script(.*?)>(.*?)</script>#is', $deferinsights, $tag);
1259
  }
1260
 
1902
 
1903
  # print code if there are no linebreaks, or return
1904
  if(!empty($tagdefer)) {
1905
+ $deferinsights = '<script type="text/javascript">if(!navigator.userAgent.match(/speed|Lighthouse|gtmetrix|Linux.*Moto\sG|x11.*firefox\/54|x11.*chrome\/39/i)){document.write('.json_encode($tag).');}</script>';
1906
  return preg_replace('#<script(.*?)>(.*?)</script>#is', $deferinsights, $tag);
1907
  }
1908
 
inc/functions.php CHANGED
@@ -394,7 +394,7 @@ if (stripos($hurl, $wp_domain) !== false) {
394
  if (file_exists($f)) {
395
  if($type == 'js') { $code = fastvelocity_min_get_js($hurl, file_get_contents($f), $disable_minification); }
396
  else { $code = fastvelocity_min_get_css($hurl, file_get_contents($f).$inline, $disable_minification); }
397
- set_transient($tkey, $code, 7 * DAY_IN_SECONDS );
398
  $log = "$printurl --- Debug: $printhandle File was opened from $f ---\n";
399
  return array('log'=>$log, 'code'=>$code);
400
  }
@@ -406,7 +406,6 @@ if (stripos($hurl, $wp_domain) !== false) {
406
  if (file_exists($f)) {
407
  if($type == 'js') { $code = fastvelocity_min_get_js($hurl, file_get_contents($f), $disable_minification); }
408
  else { $code = fastvelocity_min_get_css($hurl, file_get_contents($f).$inline, $disable_minification); }
409
- set_transient($tkey, $code, 7 * DAY_IN_SECONDS );
410
  $log = "$printurl --- Debug: $printhandle File was opened from $f ---\n";
411
  return array('log'=>$log, 'code'=>$code);
412
  }
@@ -420,7 +419,7 @@ $code = fastvelocity_download($hurl, $tkey, $ttl);
420
  if($code !== false) {
421
  if($type == 'js') { $code = fastvelocity_min_get_js($hurl, $code, $disable_minification); }
422
  else { $code = fastvelocity_min_get_css($hurl, $code.$inline, $disable_minification); }
423
- set_transient($tkey, $code, 7 * DAY_IN_SECONDS );
424
  $log = "$printurl --- Debug: $printhandle Fetched url at $hurl \n";
425
  return array('log'=>$log, 'code'=>$code);
426
  }
@@ -433,7 +432,6 @@ if(stripos($hurl, $wp_domain) !== false && home_url() != site_url()) {
433
  if($code !== false) {
434
  if($type == 'js') { $code = fastvelocity_min_get_js($hurl, $code, $disable_minification); }
435
  else { $code = fastvelocity_min_get_css($hurl, $code.$inline, $disable_minification); }
436
- set_transient($tkey, $code, 7 * DAY_IN_SECONDS );
437
  $log = "$printurl --- Debug: $printhandle Fetched url at $hurl \n";
438
  return array('log'=>$log, 'code'=>$code);
439
  }
@@ -448,7 +446,6 @@ if (stripos($hurl, $wp_domain) !== false) {
448
  if (file_exists($f)) {
449
  if($type == 'js') { $code = fastvelocity_min_get_js($hurl, file_get_contents($f), $disable_minification); }
450
  else { $code = fastvelocity_min_get_css($hurl, file_get_contents($f).$inline, $disable_minification); }
451
- set_transient($tkey, $code, 7 * DAY_IN_SECONDS );
452
  $log = "$printurl --- Debug: $printhandle File was opened from $f ---\n";
453
  return array('log'=>$log, 'code'=>$code);
454
  }
@@ -460,7 +457,6 @@ if (stripos($hurl, $wp_domain) !== false) {
460
  if (file_exists($f)) {
461
  if($type == 'js') { $code = fastvelocity_min_get_js($hurl, file_get_contents($f), $disable_minification); }
462
  else { $code = fastvelocity_min_get_css($hurl, file_get_contents($f).$inline, $disable_minification); }
463
- set_transient($tkey, $code, 7 * DAY_IN_SECONDS );
464
  $log = "$printurl --- Debug: $printhandle File was opened from $f ---\n";
465
  return array('log'=>$log, 'code'=>$code);
466
  }
@@ -951,6 +947,12 @@ sg_cachepress_purge_cache();
951
  return __('<div class="notice notice-info is-dismissible"><p>All caches from <strong>SG Optimizer</strong> have also been purged.</p></div>');
952
  }
953
 
 
 
 
 
 
 
954
  # Purge Godaddy Managed WordPress Hosting (Varnish + APC)
955
  if (class_exists('WPaaS\Plugin')) {
956
  fastvelocity_godaddy_request('BAN');
@@ -964,7 +966,5 @@ if (method_exists('WpeCommon', 'clear_maxcdn_cache')) { WpeCommon::clear_maxcdn_
964
  if (method_exists('WpeCommon', 'purge_varnish_cache')) { WpeCommon::purge_varnish_cache(); }
965
  }
966
 
967
- }
968
-
969
-
970
 
 
394
  if (file_exists($f)) {
395
  if($type == 'js') { $code = fastvelocity_min_get_js($hurl, file_get_contents($f), $disable_minification); }
396
  else { $code = fastvelocity_min_get_css($hurl, file_get_contents($f).$inline, $disable_minification); }
397
+
398
  $log = "$printurl --- Debug: $printhandle File was opened from $f ---\n";
399
  return array('log'=>$log, 'code'=>$code);
400
  }
406
  if (file_exists($f)) {
407
  if($type == 'js') { $code = fastvelocity_min_get_js($hurl, file_get_contents($f), $disable_minification); }
408
  else { $code = fastvelocity_min_get_css($hurl, file_get_contents($f).$inline, $disable_minification); }
 
409
  $log = "$printurl --- Debug: $printhandle File was opened from $f ---\n";
410
  return array('log'=>$log, 'code'=>$code);
411
  }
419
  if($code !== false) {
420
  if($type == 'js') { $code = fastvelocity_min_get_js($hurl, $code, $disable_minification); }
421
  else { $code = fastvelocity_min_get_css($hurl, $code.$inline, $disable_minification); }
422
+ fvm_set_transient($tkey, $code, 604800);
423
  $log = "$printurl --- Debug: $printhandle Fetched url at $hurl \n";
424
  return array('log'=>$log, 'code'=>$code);
425
  }
432
  if($code !== false) {
433
  if($type == 'js') { $code = fastvelocity_min_get_js($hurl, $code, $disable_minification); }
434
  else { $code = fastvelocity_min_get_css($hurl, $code.$inline, $disable_minification); }
 
435
  $log = "$printurl --- Debug: $printhandle Fetched url at $hurl \n";
436
  return array('log'=>$log, 'code'=>$code);
437
  }
446
  if (file_exists($f)) {
447
  if($type == 'js') { $code = fastvelocity_min_get_js($hurl, file_get_contents($f), $disable_minification); }
448
  else { $code = fastvelocity_min_get_css($hurl, file_get_contents($f).$inline, $disable_minification); }
 
449
  $log = "$printurl --- Debug: $printhandle File was opened from $f ---\n";
450
  return array('log'=>$log, 'code'=>$code);
451
  }
457
  if (file_exists($f)) {
458
  if($type == 'js') { $code = fastvelocity_min_get_js($hurl, file_get_contents($f), $disable_minification); }
459
  else { $code = fastvelocity_min_get_css($hurl, file_get_contents($f).$inline, $disable_minification); }
 
460
  $log = "$printurl --- Debug: $printhandle File was opened from $f ---\n";
461
  return array('log'=>$log, 'code'=>$code);
462
  }
947
  return __('<div class="notice notice-info is-dismissible"><p>All caches from <strong>SG Optimizer</strong> have also been purged.</p></div>');
948
  }
949
 
950
+ # Purge Hyper Cache
951
+ if (class_exists( 'HyperCache' )) {
952
+ do_action( 'autoptimize_action_cachepurged' );
953
+ return __( '<div class="notice notice-info is-dismissible"><p>All caches from <strong>HyperCache</strong> have also been purged.</p></div>');
954
+ }
955
+
956
  # Purge Godaddy Managed WordPress Hosting (Varnish + APC)
957
  if (class_exists('WPaaS\Plugin')) {
958
  fastvelocity_godaddy_request('BAN');
966
  if (method_exists('WpeCommon', 'purge_varnish_cache')) { WpeCommon::purge_varnish_cache(); }
967
  }
968
 
 
 
 
969
 
970
+ }
libs/CSSTidy/class.csstidy.php DELETED
@@ -1,1296 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * CSSTidy - CSS Parser and Optimiser
5
- *
6
- * CSS Parser class
7
- *
8
- * Copyright 2005, 2006, 2007 Florian Schmitz
9
- *
10
- * This file is part of CSSTidy.
11
- *
12
- * CSSTidy is free software; you can redistribute it and/or modify
13
- * it under the terms of the GNU Lesser General Public License as published by
14
- * the Free Software Foundation; either version 2.1 of the License, or
15
- * (at your option) any later version.
16
- *
17
- * CSSTidy is distributed in the hope that it will be useful,
18
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
- * GNU Lesser General Public License for more details.
21
- *
22
- * You should have received a copy of the GNU Lesser General Public License
23
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
24
- *
25
- * @license http://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
26
- * @package csstidy
27
- * @author Florian Schmitz (floele at gmail dot com) 2005-2007
28
- * @author Brett Zamir (brettz9 at yahoo dot com) 2007
29
- * @author Nikolay Matsievsky (speed at webo dot name) 2009-2010
30
- * @author Cedric Morin (cedric at yterium dot com) 2010-2012
31
- * @author Christopher Finke (cfinke at gmail.com) 2012
32
- * @author Mark Scherer (remove $GLOBALS once and for all + PHP5.4 comp) 2012
33
- */
34
-
35
- /**
36
- * Defines ctype functions if required.
37
- *
38
- * @TODO: Make these methods of CSSTidy.
39
- * @since 1.0.0
40
- */
41
- if (!function_exists('ctype_space')){
42
- /* ctype_space Check for whitespace character(s) */
43
- function ctype_space($text){
44
- return (1===preg_match("/^[ \r\n\t\f]+$/", $text));
45
- }
46
- }
47
- if (!function_exists('ctype_alpha')){
48
- /* ctype_alpha Check for alphabetic character(s) */
49
- function ctype_alpha($text){
50
- return (1===preg_match('/^[a-zA-Z]+$/', $text));
51
- }
52
- }
53
- if (!function_exists('ctype_xdigit')){
54
- /* ctype_xdigit Check for HEX character(s) */
55
- function ctype_xdigit($text){
56
- return (1===preg_match('/^[a-fA-F0-9]+$/', $text));
57
- }
58
- }
59
-
60
- /**
61
- * Defines constants
62
- * @todo //TODO: make them class constants of csstidy
63
- */
64
- define('AT_START', 1);
65
- define('AT_END', 2);
66
- define('SEL_START', 3);
67
- define('SEL_END', 4);
68
- define('PROPERTY', 5);
69
- define('VALUE', 6);
70
- define('COMMENT', 7);
71
- define('DEFAULT_AT', 41);
72
-
73
- /**
74
- * Contains a class for printing CSS code
75
- *
76
- * @version 1.0
77
- */
78
- require('class.csstidy_print.php');
79
-
80
- /**
81
- * Contains a class for optimising CSS code
82
- *
83
- * @version 1.0
84
- */
85
- require('class.csstidy_optimise.php');
86
-
87
- /**
88
- * CSS Parser class
89
- *
90
- * This class represents a CSS parser which reads CSS code and saves it in an array.
91
- * In opposite to most other CSS parsers, it does not use regular expressions and
92
- * thus has full CSS2 support and a higher reliability.
93
- * Additional to that it applies some optimisations and fixes to the CSS code.
94
- * An online version should be available here: http://cdburnerxp.se/cssparse/css_optimiser.php
95
- * @package csstidy
96
- * @author Florian Schmitz (floele at gmail dot com) 2005-2006
97
- * @version 1.5.6
98
- */
99
- class csstidy {
100
-
101
- /**
102
- * Saves the parsed CSS. This array is empty if preserve_css is on.
103
- * @var array
104
- * @access public
105
- */
106
- public $css = array();
107
- /**
108
- * Saves the parsed CSS (raw)
109
- * @var array
110
- * @access private
111
- */
112
- public $tokens = array();
113
- /**
114
- * Printer class
115
- * @see csstidy_print
116
- * @var object
117
- * @access public
118
- */
119
- public $print;
120
- /**
121
- * Optimiser class
122
- * @see csstidy_optimise
123
- * @var object
124
- * @access private
125
- */
126
- public $optimise;
127
- /**
128
- * Saves the CSS charset (@charset)
129
- * @var string
130
- * @access private
131
- */
132
- public $charset = '';
133
- /**
134
- * Saves all @import URLs
135
- * @var array
136
- * @access private
137
- */
138
- public $import = array();
139
- /**
140
- * Saves the namespace
141
- * @var string
142
- * @access private
143
- */
144
- public $namespace = '';
145
- /**
146
- * Contains the version of csstidy
147
- * @var string
148
- * @access private
149
- */
150
- public $version = '1.5.6';
151
- /**
152
- * Stores the settings
153
- * @var array
154
- * @access private
155
- */
156
- public $settings = array();
157
- /**
158
- * Saves the parser-status.
159
- *
160
- * Possible values:
161
- * - is = in selector
162
- * - ip = in property
163
- * - iv = in value
164
- * - instr = in string (started at " or ' or ( )
165
- * - ic = in comment (ignore everything)
166
- * - at = in @-block
167
- *
168
- * @var string
169
- * @access private
170
- */
171
- public $status = 'is';
172
- /**
173
- * Saves the current at rule (@media)
174
- * @var string
175
- * @access private
176
- */
177
- public $at = '';
178
- /**
179
- * Saves the at rule for next selector (during @font-face or other @)
180
- * @var string
181
- * @access private
182
- */
183
- public $next_selector_at = '';
184
-
185
- /**
186
- * Saves the current selector
187
- * @var string
188
- * @access private
189
- */
190
- public $selector = '';
191
- /**
192
- * Saves the current property
193
- * @var string
194
- * @access private
195
- */
196
- public $property = '';
197
- /**
198
- * Saves the position of , in selectors
199
- * @var array
200
- * @access private
201
- */
202
- public $sel_separate = array();
203
- /**
204
- * Saves the current value
205
- * @var string
206
- * @access private
207
- */
208
- public $value = '';
209
- /**
210
- * Saves the current sub-value
211
- *
212
- * Example for a subvalue:
213
- * background:url(foo.png) red no-repeat;
214
- * "url(foo.png)", "red", and "no-repeat" are subvalues,
215
- * seperated by whitespace
216
- * @var string
217
- * @access private
218
- */
219
- public $sub_value = '';
220
- /**
221
- * Array which saves all subvalues for a property.
222
- * @var array
223
- * @see sub_value
224
- * @access private
225
- */
226
- public $sub_value_arr = array();
227
- /**
228
- * Saves the stack of characters that opened the current strings
229
- * @var array
230
- * @access private
231
- */
232
- public $str_char = array();
233
- public $cur_string = array();
234
- /**
235
- * Status from which the parser switched to ic or instr
236
- * @var array
237
- * @access private
238
- */
239
- public $from = array();
240
- /**
241
- /**
242
- * =true if in invalid at-rule
243
- * @var bool
244
- * @access private
245
- */
246
- public $invalid_at = false;
247
- /**
248
- * =true if something has been added to the current selector
249
- * @var bool
250
- * @access private
251
- */
252
- public $added = false;
253
- /**
254
- * Array which saves the message log
255
- * @var array
256
- * @access private
257
- */
258
- public $log = array();
259
- /**
260
- * Saves the line number
261
- * @var integer
262
- * @access private
263
- */
264
- public $line = 1;
265
- /**
266
- * Marks if we need to leave quotes for a string
267
- * @var array
268
- * @access private
269
- */
270
- public $quoted_string = array();
271
-
272
- /**
273
- * List of tokens
274
- * @var string
275
- */
276
- public $tokens_list = "";
277
-
278
- /**
279
- * Various CSS Data for CSSTidy
280
- * @var array
281
- */
282
- public $data = array();
283
-
284
- /**
285
- * Loads standard template and sets default settings
286
- * @access private
287
- * @version 1.3
288
- */
289
- public function __construct() {
290
- $data = array();
291
- include('data.inc.php');
292
- $this->data = $data;
293
-
294
- $this->settings['remove_bslash'] = true;
295
- $this->settings['compress_colors'] = true;
296
- $this->settings['compress_font-weight'] = true;
297
- $this->settings['lowercase_s'] = false;
298
- /*
299
- 1 common shorthands optimization
300
- 2 + font property optimization
301
- 3 + background property optimization
302
- */
303
- $this->settings['optimise_shorthands'] = 1;
304
- $this->settings['remove_last_;'] = true;
305
- $this->settings['space_before_important'] = false;
306
- /* rewrite all properties with low case, better for later gzip OK, safe*/
307
- $this->settings['case_properties'] = 1;
308
- /* sort properties in alpabetic order, better for later gzip
309
- * but can cause trouble in case of overiding same propertie or using hack
310
- */
311
- $this->settings['sort_properties'] = false;
312
- /*
313
- 1, 3, 5, etc -- enable sorting selectors inside @media: a{}b{}c{}
314
- 2, 5, 8, etc -- enable sorting selectors inside one CSS declaration: a,b,c{}
315
- preserve order by default cause it can break functionnality
316
- */
317
- $this->settings['sort_selectors'] = 0;
318
- /* is dangeroues to be used: CSS is broken sometimes */
319
- $this->settings['merge_selectors'] = 0;
320
- /* preserve or not browser hacks */
321
- $this->settings['discard_invalid_selectors'] = false;
322
- $this->settings['discard_invalid_properties'] = false;
323
- $this->settings['css_level'] = 'CSS3.0';
324
- $this->settings['preserve_css'] = false;
325
- $this->settings['timestamp'] = false;
326
- $this->settings['template'] = ''; // say that propertie exist
327
- $this->set_cfg('template','default'); // call load_template
328
- $this->optimise = new csstidy_optimise($this);
329
-
330
- $this->tokens_list = & $this->data['csstidy']['tokens'];
331
- }
332
-
333
- /**
334
- * Get the value of a setting.
335
- * @param string $setting
336
- * @access public
337
- * @return mixed
338
- * @version 1.0
339
- */
340
- public function get_cfg($setting) {
341
- if (isset($this->settings[$setting])) {
342
- return $this->settings[$setting];
343
- }
344
- return false;
345
- }
346
-
347
- /**
348
- * Load a template
349
- * @param string $template used by set_cfg to load a template via a configuration setting
350
- * @access private
351
- * @version 1.4
352
- */
353
- public function _load_template($template) {
354
- switch ($template) {
355
- case 'default':
356
- $this->load_template('default');
357
- break;
358
-
359
- case 'highest':
360
- $this->load_template('highest_compression');
361
- break;
362
-
363
- case 'high':
364
- $this->load_template('high_compression');
365
- break;
366
-
367
- case 'low':
368
- $this->load_template('low_compression');
369
- break;
370
-
371
- default:
372
- $this->load_template($template);
373
- break;
374
- }
375
- }
376
-
377
- /**
378
- * Set the value of a setting.
379
- * @param string $setting
380
- * @param mixed $value
381
- * @access public
382
- * @return bool
383
- * @version 1.0
384
- */
385
- public function set_cfg($setting, $value=null) {
386
- if (is_array($setting) && $value === null) {
387
- foreach ($setting as $setprop => $setval) {
388
- $this->settings[$setprop] = $setval;
389
- }
390
- if (array_key_exists('template', $setting)) {
391
- $this->_load_template($this->settings['template']);
392
- }
393
- return true;
394
- } elseif (isset($this->settings[$setting]) && $value !== '') {
395
- $this->settings[$setting] = $value;
396
- if ($setting === 'template') {
397
- $this->_load_template($this->settings['template']);
398
- }
399
- return true;
400
- }
401
- return false;
402
- }
403
-
404
- /**
405
- * Adds a token to $this->tokens
406
- * @param mixed $type
407
- * @param string $data
408
- * @param bool $do add a token even if preserve_css is off
409
- * @access private
410
- * @version 1.0
411
- */
412
- public function _add_token($type, $data, $do = false) {
413
- if ($this->get_cfg('preserve_css') || $do) {
414
- $this->tokens[] = array($type, ($type == COMMENT) ? $data : trim($data));
415
- }
416
- }
417
-
418
- /**
419
- * Add a message to the message log
420
- * @param string $message
421
- * @param string $type
422
- * @param integer $line
423
- * @access private
424
- * @version 1.0
425
- */
426
- public function log($message, $type, $line = -1) {
427
- if ($line === -1) {
428
- $line = $this->line;
429
- }
430
- $line = intval($line);
431
- $add = array('m' => $message, 't' => $type);
432
- if (!isset($this->log[$line]) || !in_array($add, $this->log[$line])) {
433
- $this->log[$line][] = $add;
434
- }
435
- }
436
-
437
- /**
438
- * Parse unicode notations and find a replacement character
439
- * @param string $string
440
- * @param integer $i
441
- * @access private
442
- * @return string
443
- * @version 1.2
444
- */
445
- public function _unicode(&$string, &$i) {
446
- ++$i;
447
- $add = '';
448
- $replaced = false;
449
-
450
- while ($i < strlen($string) && (ctype_xdigit($string{$i}) || ctype_space($string{$i})) && strlen($add) < 6) {
451
- $add .= $string{$i};
452
-
453
- if (ctype_space($string{$i})) {
454
- break;
455
- }
456
- $i++;
457
- }
458
-
459
- if (hexdec($add) > 47 && hexdec($add) < 58 || hexdec($add) > 64 && hexdec($add) < 91 || hexdec($add) > 96 && hexdec($add) < 123) {
460
- $this->log('Replaced unicode notation: Changed \\' . $add . ' to ' . chr(hexdec($add)), 'Information');
461
- $add = chr(hexdec($add));
462
- $replaced = true;
463
- } else {
464
- $add = trim('\\' . $add);
465
- }
466
-
467
- if (@ctype_xdigit($string{$i + 1}) && ctype_space($string{$i})
468
- && !$replaced || !ctype_space($string{$i})) {
469
- $i--;
470
- }
471
-
472
- if ($add !== '\\' || !$this->get_cfg('remove_bslash') || strpos($this->tokens_list, $string{$i + 1}) !== false) {
473
- return $add;
474
- }
475
-
476
- if ($add === '\\') {
477
- $this->log('Removed unnecessary backslash', 'Information');
478
- }
479
- return '';
480
- }
481
-
482
- /**
483
- * Write formatted output to a file
484
- * @param string $filename
485
- * @param string $doctype when printing formatted, is a shorthand for the document type
486
- * @param bool $externalcss when printing formatted, indicates whether styles to be attached internally or as an external stylesheet
487
- * @param string $title when printing formatted, is the title to be added in the head of the document
488
- * @param string $lang when printing formatted, gives a two-letter language code to be added to the output
489
- * @access public
490
- * @version 1.4
491
- */
492
- public function write_page($filename, $doctype='xhtml1.1', $externalcss=true, $title='', $lang='en') {
493
- $this->write($filename, true);
494
- }
495
-
496
- /**
497
- * Write plain output to a file
498
- * @param string $filename
499
- * @param bool $formatted whether to print formatted or not
500
- * @param string $doctype when printing formatted, is a shorthand for the document type
501
- * @param bool $externalcss when printing formatted, indicates whether styles to be attached internally or as an external stylesheet
502
- * @param string $title when printing formatted, is the title to be added in the head of the document
503
- * @param string $lang when printing formatted, gives a two-letter language code to be added to the output
504
- * @param bool $pre_code whether to add pre and code tags around the code (for light HTML formatted templates)
505
- * @access public
506
- * @version 1.4
507
- */
508
- public function write($filename, $formatted=false, $doctype='xhtml1.1', $externalcss=true, $title='', $lang='en', $pre_code=true) {
509
- $filename .= ( $formatted) ? '.xhtml' : '.css';
510
-
511
- if (!is_dir('temp')) {
512
- $madedir = mkdir('temp');
513
- if (!$madedir) {
514
- print 'Could not make directory "temp" in ' . dirname(__FILE__);
515
- exit;
516
- }
517
- }
518
- $handle = fopen('temp/' . $filename, 'w');
519
- if ($handle) {
520
- if (!$formatted) {
521
- fwrite($handle, $this->print->plain());
522
- } else {
523
- fwrite($handle, $this->print->formatted_page($doctype, $externalcss, $title, $lang, $pre_code));
524
- }
525
- }
526
- fclose($handle);
527
- }
528
-
529
- /**
530
- * Loads a new template
531
- * @param string $content either filename (if $from_file == true), content of a template file, "high_compression", "highest_compression", "low_compression", or "default"
532
- * @param bool $from_file uses $content as filename if true
533
- * @access public
534
- * @version 1.1
535
- * @see http://csstidy.sourceforge.net/templates.php
536
- */
537
- public function load_template($content, $from_file=true) {
538
- $predefined_templates = & $this->data['csstidy']['predefined_templates'];
539
- if ($content === 'high_compression' || $content === 'default' || $content === 'highest_compression' || $content === 'low_compression') {
540
- $this->template = $predefined_templates[$content];
541
- return;
542
- }
543
-
544
-
545
- if ($from_file) {
546
- $content = strip_tags(file_get_contents($content), '<span>');
547
- }
548
- $content = str_replace("\r\n", "\n", $content); // Unify newlines (because the output also only uses \n)
549
- $template = explode('|', $content);
550
-
551
- for ($i = 0; $i < count($template); $i++) {
552
- $this->template[$i] = $template[$i];
553
- }
554
- }
555
-
556
- /**
557
- * Starts parsing from URL
558
- * @param string $url
559
- * @access public
560
- * @version 1.0
561
- */
562
- public function parse_from_url($url) {
563
- return $this->parse(@file_get_contents($url));
564
- }
565
-
566
- /**
567
- * Checks if there is a token at the current position
568
- * @param string $string
569
- * @param integer $i
570
- * @access public
571
- * @version 1.11
572
- */
573
- public function is_token(&$string, $i) {
574
- return (strpos($this->tokens_list, $string{$i}) !== false && !$this->escaped($string, $i));
575
- }
576
-
577
- /**
578
- * Parses CSS in $string. The code is saved as array in $this->css
579
- * @param string $string the CSS code
580
- * @access public
581
- * @return bool
582
- * @version 1.1
583
- */
584
- public function parse($string) {
585
- // Temporarily set locale to en_US in order to handle floats properly
586
- $old = @setlocale(LC_ALL, 0);
587
- @setlocale(LC_ALL, 'C');
588
-
589
- // PHP bug? Settings need to be refreshed in PHP4
590
- $this->print = new csstidy_print($this);
591
- $this->optimise = new csstidy_optimise($this);
592
-
593
- $all_properties = & $this->data['csstidy']['all_properties'];
594
- $at_rules = & $this->data['csstidy']['at_rules'];
595
- $quoted_string_properties = & $this->data['csstidy']['quoted_string_properties'];
596
-
597
- $this->css = array();
598
- $this->print->input_css = $string;
599
- $string = str_replace("\r\n", "\n", $string) . ' ';
600
- $cur_comment = '';
601
-
602
- for ($i = 0, $size = strlen($string); $i < $size; $i++) {
603
- if ($string{$i} === "\n" || $string{$i} === "\r") {
604
- ++$this->line;
605
- }
606
-
607
- switch ($this->status) {
608
- /* Case in at-block */
609
- case 'at':
610
- if ($this->is_token($string, $i)) {
611
- if ($string{$i} === '/' && @$string{$i + 1} === '*') {
612
- $this->status = 'ic';
613
- ++$i;
614
- $this->from[] = 'at';
615
- } elseif ($string{$i} === '{') {
616
- $this->status = 'is';
617
- $this->at = $this->css_new_media_section($this->at);
618
- $this->_add_token(AT_START, $this->at);
619
- } elseif ($string{$i} === ',') {
620
- $this->at = trim($this->at) . ',';
621
- } elseif ($string{$i} === '\\') {
622
- $this->at .= $this->_unicode($string, $i);
623
- }
624
- // fix for complicated media, i.e @media screen and (-webkit-min-device-pixel-ratio:1.5)
625
- elseif (in_array($string{$i}, array('(', ')', ':', '.', '/'))) {
626
- $this->at .= $string{$i};
627
- }
628
- } else {
629
- $lastpos = strlen($this->at) - 1;
630
- if (!( (ctype_space($this->at{$lastpos}) || $this->is_token($this->at, $lastpos) && $this->at{$lastpos} === ',') && ctype_space($string{$i}))) {
631
- $this->at .= $string{$i};
632
- }
633
- }
634
- break;
635
-
636
- /* Case in-selector */
637
- case 'is':
638
- if ($this->is_token($string, $i)) {
639
- if ($string{$i} === '/' && @$string{$i + 1} === '*' && trim($this->selector) == '') {
640
- $this->status = 'ic';
641
- ++$i;
642
- $this->from[] = 'is';
643
- } elseif ($string{$i} === '@' && trim($this->selector) == '') {
644
- // Check for at-rule
645
- $this->invalid_at = true;
646
- foreach ($at_rules as $name => $type) {
647
- if (!strcasecmp(substr($string, $i + 1, strlen($name)), $name)) {
648
- ($type === 'at') ? $this->at = '@' . $name : $this->selector = '@' . $name;
649
- if ($type === 'atis') {
650
- $this->next_selector_at = ($this->next_selector_at?$this->next_selector_at:($this->at?$this->at:DEFAULT_AT));
651
- $this->at = $this->css_new_media_section(' ');
652
- $type = 'is';
653
- }
654
- $this->status = $type;
655
- $i += strlen($name);
656
- $this->invalid_at = false;
657
- }
658
- }
659
-
660
- if ($this->invalid_at) {
661
- $this->selector = '@';
662
- $invalid_at_name = '';
663
- for ($j = $i + 1; $j < $size; ++$j) {
664
- if (!ctype_alpha($string{$j})) {
665
- break;
666
- }
667
- $invalid_at_name .= $string{$j};
668
- }
669
- $this->log('Invalid @-rule: ' . $invalid_at_name . ' (removed)', 'Warning');
670
- }
671
- } elseif (($string{$i} === '"' || $string{$i} === "'")) {
672
- $this->cur_string[] = $string{$i};
673
- $this->status = 'instr';
674
- $this->str_char[] = $string{$i};
675
- $this->from[] = 'is';
676
- /* fixing CSS3 attribute selectors, i.e. a[href$=".mp3" */
677
- $this->quoted_string[] = ($string{$i - 1} === '=' );
678
- } elseif ($this->invalid_at && $string{$i} === ';') {
679
- $this->invalid_at = false;
680
- $this->status = 'is';
681
- if ($this->next_selector_at) {
682
- $this->at = $this->css_new_media_section($this->next_selector_at);
683
- $this->next_selector_at = '';
684
- }
685
- } elseif ($string{$i} === '{') {
686
- $this->status = 'ip';
687
- if ($this->at == '') {
688
- $this->at = $this->css_new_media_section(DEFAULT_AT);
689
- }
690
- $this->selector = $this->css_new_selector($this->at,$this->selector);
691
- $this->_add_token(SEL_START, $this->selector);
692
- $this->added = false;
693
- } elseif ($string{$i} === '}') {
694
- $this->_add_token(AT_END, $this->at);
695
- $this->at = '';
696
- $this->selector = '';
697
- $this->sel_separate = array();
698
- } elseif ($string{$i} === ',') {
699
- $this->selector = trim($this->selector) . ',';
700
- $this->sel_separate[] = strlen($this->selector);
701
- } elseif ($string{$i} === '\\') {
702
- $this->selector .= $this->_unicode($string, $i);
703
- } elseif ($string{$i} === '*' && @in_array($string{$i + 1}, array('.', '#', '[', ':')) && ($i==0 OR $string{$i - 1}!=='/')) {
704
- // remove unnecessary universal selector, FS#147, but not comment in selector
705
- } else {
706
- $this->selector .= $string{$i};
707
- }
708
- } else {
709
- $lastpos = strlen($this->selector) - 1;
710
- if ($lastpos == -1 || !( (ctype_space($this->selector{$lastpos}) || $this->is_token($this->selector, $lastpos) && $this->selector{$lastpos} === ',') && ctype_space($string{$i}))) {
711
- $this->selector .= $string{$i};
712
- }
713
- }
714
- break;
715
-
716
- /* Case in-property */
717
- case 'ip':
718
- if ($this->is_token($string, $i)) {
719
- if (($string{$i} === ':' || $string{$i} === '=') && $this->property != '') {
720
- $this->status = 'iv';
721
- if (!$this->get_cfg('discard_invalid_properties') || $this->property_is_valid($this->property)) {
722
- $this->property = $this->css_new_property($this->at,$this->selector,$this->property);
723
- $this->_add_token(PROPERTY, $this->property);
724
- }
725
- } elseif ($string{$i} === '/' && @$string{$i + 1} === '*' && $this->property == '') {
726
- $this->status = 'ic';
727
- ++$i;
728
- $this->from[] = 'ip';
729
- } elseif ($string{$i} === '}') {
730
- $this->explode_selectors();
731
- $this->status = 'is';
732
- $this->invalid_at = false;
733
- $this->_add_token(SEL_END, $this->selector);
734
- $this->selector = '';
735
- $this->property = '';
736
- if ($this->next_selector_at) {
737
- $this->at = $this->css_new_media_section($this->next_selector_at);
738
- $this->next_selector_at = '';
739
- }
740
- } elseif ($string{$i} === ';') {
741
- $this->property = '';
742
- } elseif ($string{$i} === '\\') {
743
- $this->property .= $this->_unicode($string, $i);
744
- }
745
- // else this is dumb IE a hack, keep it
746
- // including //
747
- elseif (($this->property === '' && !ctype_space($string{$i}))
748
- || ($this->property === '/' || $string{$i} === '/')) {
749
- $this->property .= $string{$i};
750
- }
751
- } elseif (!ctype_space($string{$i})) {
752
- $this->property .= $string{$i};
753
- }
754
- break;
755
-
756
- /* Case in-value */
757
- case 'iv':
758
- $pn = (($string{$i} === "\n" || $string{$i} === "\r") && $this->property_is_next($string, $i + 1) || $i == strlen($string) - 1);
759
- if ($this->is_token($string, $i) || $pn) {
760
- if ($string{$i} === '/' && @$string{$i + 1} === '*') {
761
- $this->status = 'ic';
762
- ++$i;
763
- $this->from[] = 'iv';
764
- } elseif (($string{$i} === '"' || $string{$i} === "'" || $string{$i} === '(')) {
765
- $this->cur_string[] = $string{$i};
766
- $this->str_char[] = ($string{$i} === '(') ? ')' : $string{$i};
767
- $this->status = 'instr';
768
- $this->from[] = 'iv';
769
- $this->quoted_string[] = in_array(strtolower($this->property), $quoted_string_properties);
770
- } elseif ($string{$i} === ',') {
771
- $this->sub_value = trim($this->sub_value) . ',';
772
- } elseif ($string{$i} === '\\') {
773
- $this->sub_value .= $this->_unicode($string, $i);
774
- } elseif ($string{$i} === ';' || $pn) {
775
- if ($this->selector{0} === '@' && isset($at_rules[substr($this->selector, 1)]) && $at_rules[substr($this->selector, 1)] === 'iv') {
776
- /* Add quotes to charset, import, namespace */
777
- $this->sub_value_arr[] = trim($this->sub_value);
778
-
779
- $this->status = 'is';
780
-
781
- switch ($this->selector) {
782
- case '@charset': $this->charset = '"'.$this->sub_value_arr[0].'"';
783
- break;
784
- case '@namespace': $this->namespace = implode(' ', $this->sub_value_arr);
785
- break;
786
- case '@import': $this->import[] = implode(' ', $this->sub_value_arr);
787
- break;
788
- }
789
-
790
- $this->sub_value_arr = array();
791
- $this->sub_value = '';
792
- $this->selector = '';
793
- $this->sel_separate = array();
794
- } else {
795
- $this->status = 'ip';
796
- }
797
- } elseif ($string{$i} !== '}') {
798
- $this->sub_value .= $string{$i};
799
- }
800
- if (($string{$i} === '}' || $string{$i} === ';' || $pn) && !empty($this->selector)) {
801
- if ($this->at == '') {
802
- $this->at = $this->css_new_media_section(DEFAULT_AT);
803
- }
804
-
805
- // case settings
806
- if ($this->get_cfg('lowercase_s')) {
807
- $this->selector = strtolower($this->selector);
808
- }
809
- $this->property = strtolower($this->property);
810
-
811
- $this->optimise->subvalue();
812
- if ($this->sub_value != '') {
813
- $this->sub_value_arr[] = $this->sub_value;
814
- $this->sub_value = '';
815
- }
816
-
817
- $this->value = '';
818
- while (count($this->sub_value_arr)) {
819
- $sub = array_shift($this->sub_value_arr);
820
- if (strstr($this->selector, 'font-face')) {
821
- $sub = $this->quote_font_format($sub);
822
- }
823
-
824
- if ($sub != '')
825
- $this->value .= ((!strlen($this->value) || substr($this->value,-1,1) === ',')?'':' ').$sub;
826
- }
827
-
828
- $this->optimise->value();
829
-
830
- $valid = $this->property_is_valid($this->property);
831
- if ((!$this->invalid_at || $this->get_cfg('preserve_css')) && (!$this->get_cfg('discard_invalid_properties') || $valid)) {
832
- $this->css_add_property($this->at, $this->selector, $this->property, $this->value);
833
- $this->_add_token(VALUE, $this->value);
834
- $this->optimise->shorthands();
835
- }
836
- if (!$valid) {
837
- if ($this->get_cfg('discard_invalid_properties')) {
838
- $this->log('Removed invalid property: ' . $this->property, 'Warning');
839
- } else {
840
- $this->log('Invalid property in ' . strtoupper($this->get_cfg('css_level')) . ': ' . $this->property, 'Warning');
841
- }
842
- }
843
-
844
- $this->property = '';
845
- $this->sub_value_arr = array();
846
- $this->value = '';
847
- }
848
- if ($string{$i} === '}') {
849
- $this->explode_selectors();
850
- $this->_add_token(SEL_END, $this->selector);
851
- $this->status = 'is';
852
- $this->invalid_at = false;
853
- $this->selector = '';
854
- if ($this->next_selector_at) {
855
- $this->at = $this->css_new_media_section($this->next_selector_at);
856
- $this->next_selector_at = '';
857
- }
858
- }
859
- } elseif (!$pn) {
860
- $this->sub_value .= $string{$i};
861
-
862
- if (ctype_space($string{$i})) {
863
- $this->optimise->subvalue();
864
- if ($this->sub_value != '') {
865
- $this->sub_value_arr[] = $this->sub_value;
866
- $this->sub_value = '';
867
- }
868
- }
869
- }
870
- break;
871
-
872
- /* Case in string */
873
- case 'instr':
874
- $_str_char = $this->str_char[count($this->str_char)-1];
875
- $_cur_string = $this->cur_string[count($this->cur_string)-1];
876
- $_quoted_string = $this->quoted_string[count($this->quoted_string)-1];
877
- $temp_add = $string{$i};
878
-
879
- // Add another string to the stack. Strings can't be nested inside of quotes, only parentheses, but
880
- // parentheticals can be nested more than once.
881
- if ($_str_char === ")" && ($string{$i} === "(" || $string{$i} === '"' || $string{$i} === '\'') && !$this->escaped($string, $i)) {
882
- $this->cur_string[] = $string{$i};
883
- $this->str_char[] = $string{$i} === '(' ? ')' : $string{$i};
884
- $this->from[] = 'instr';
885
- $this->quoted_string[] = ($_str_char === ')' && $string{$i} !== '(' && trim($_cur_string)==='(')?$_quoted_string:!($string{$i} === '(');
886
- continue;
887
- }
888
-
889
- if ($_str_char !== ")" && ($string{$i} === "\n" || $string{$i} === "\r") && !($string{$i - 1} === '\\' && !$this->escaped($string, $i - 1))) {
890
- $temp_add = "\\A";
891
- $this->log('Fixed incorrect newline in string', 'Warning');
892
- }
893
-
894
- $_cur_string .= $temp_add;
895
-
896
- if ($string{$i} === $_str_char && !$this->escaped($string, $i)) {
897
- $this->status = array_pop($this->from);
898
-
899
- if (!preg_match('|[' . implode('', $this->data['csstidy']['whitespace']) . ']|uis', $_cur_string) && $this->property !== 'content') {
900
- if (!$_quoted_string) {
901
- if ($_str_char !== ')') {
902
- // Convert properties like
903
- // font-family: 'Arial';
904
- // to
905
- // font-family: Arial;
906
- // or
907
- // url("abc")
908
- // to
909
- // url(abc)
910
- $_cur_string = substr($_cur_string, 1, -1);
911
- }
912
- } else {
913
- $_quoted_string = false;
914
- }
915
- }
916
-
917
- array_pop($this->cur_string);
918
- array_pop($this->quoted_string);
919
- array_pop($this->str_char);
920
-
921
- if ($_str_char === ')') {
922
- $_cur_string = '(' . trim(substr($_cur_string, 1, -1)) . ')';
923
- }
924
-
925
- if ($this->status === 'iv') {
926
- if (!$_quoted_string) {
927
- if (strpos($_cur_string,',') !== false)
928
- // we can on only remove space next to ','
929
- $_cur_string = implode(',', array_map('trim', explode(',',$_cur_string)));
930
- // and multiple spaces (too expensive)
931
- if (strpos($_cur_string, ' ') !== false)
932
- $_cur_string = preg_replace(",\s+,", ' ', $_cur_string);
933
- }
934
- $this->sub_value .= $_cur_string;
935
- } elseif ($this->status === 'is') {
936
- $this->selector .= $_cur_string;
937
- } elseif ($this->status === 'instr') {
938
- $this->cur_string[count($this->cur_string)-1] .= $_cur_string;
939
- }
940
- } else {
941
- $this->cur_string[count($this->cur_string)-1] = $_cur_string;
942
- }
943
- break;
944
-
945
- /* Case in-comment */
946
- case 'ic':
947
- if ($string{$i} === '*' && $string{$i + 1} === '/') {
948
- $this->status = array_pop($this->from);
949
- $i++;
950
- $this->_add_token(COMMENT, $cur_comment);
951
- $cur_comment = '';
952
- } else {
953
- $cur_comment .= $string{$i};
954
- }
955
- break;
956
- }
957
- }
958
-
959
- $this->optimise->postparse();
960
-
961
- $this->print->_reset();
962
-
963
- @setlocale(LC_ALL, $old); // Set locale back to original setting
964
-
965
- return!(empty($this->css) && empty($this->import) && empty($this->charset) && empty($this->tokens) && empty($this->namespace));
966
- }
967
-
968
-
969
- /**
970
- * format() in font-face needs quoted values for somes browser (FF at least)
971
- *
972
- * @param $value
973
- * @return string
974
- */
975
- public function quote_font_format($value) {
976
- if (strncmp($value,'format',6) == 0) {
977
- $p = strpos($value,')',7);
978
- $end = substr($value,$p);
979
- $format_strings = $this->parse_string_list(substr($value, 7, $p-7));
980
- if (!$format_strings) {
981
- $value = '';
982
- } else {
983
- $value = 'format(';
984
-
985
- foreach ($format_strings as $format_string) {
986
- $value .= '"' . str_replace('"', '\\"', $format_string) . '",';
987
- }
988
-
989
- $value = substr($value, 0, -1) . $end;
990
- }
991
- }
992
- return $value;
993
- }
994
-
995
- /**
996
- * Explodes selectors
997
- * @access private
998
- * @version 1.0
999
- */
1000
- public function explode_selectors() {
1001
- // Explode multiple selectors
1002
- if ($this->get_cfg('merge_selectors') === 1) {
1003
- $new_sels = array();
1004
- $lastpos = 0;
1005
- $this->sel_separate[] = strlen($this->selector);
1006
- foreach ($this->sel_separate as $num => $pos) {
1007
- if ($num == count($this->sel_separate) - 1) {
1008
- $pos += 1;
1009
- }
1010
-
1011
- $new_sels[] = substr($this->selector, $lastpos, $pos - $lastpos - 1);
1012
- $lastpos = $pos;
1013
- }
1014
-
1015
- if (count($new_sels) > 1) {
1016
- foreach ($new_sels as $selector) {
1017
- if (isset($this->css[$this->at][$this->selector])) {
1018
- $this->merge_css_blocks($this->at, $selector, $this->css[$this->at][$this->selector]);
1019
- }
1020
- }
1021
- unset($this->css[$this->at][$this->selector]);
1022
- }
1023
- }
1024
- $this->sel_separate = array();
1025
- }
1026
-
1027
- /**
1028
- * Checks if a character is escaped (and returns true if it is)
1029
- * @param string $string
1030
- * @param integer $pos
1031
- * @access public
1032
- * @return bool
1033
- * @version 1.02
1034
- */
1035
- static function escaped(&$string, $pos) {
1036
- return!(@($string{$pos - 1} !== '\\') || csstidy::escaped($string, $pos - 1));
1037
- }
1038
-
1039
- /**
1040
- * Adds a property with value to the existing CSS code
1041
- * @param string $media
1042
- * @param string $selector
1043
- * @param string $property
1044
- * @param string $new_val
1045
- * @access private
1046
- * @version 1.2
1047
- */
1048
- public function css_add_property($media, $selector, $property, $new_val) {
1049
- if ($this->get_cfg('preserve_css') || trim($new_val) == '') {
1050
- return;
1051
- }
1052
-
1053
- $this->added = true;
1054
- if (isset($this->css[$media][$selector][$property])) {
1055
- if (($this->is_important($this->css[$media][$selector][$property]) && $this->is_important($new_val)) || !$this->is_important($this->css[$media][$selector][$property])) {
1056
- $this->css[$media][$selector][$property] = trim($new_val);
1057
- }
1058
- } else {
1059
- $this->css[$media][$selector][$property] = trim($new_val);
1060
- }
1061
- }
1062
-
1063
- /**
1064
- * Start a new media section.
1065
- * Check if the media is not already known,
1066
- * else rename it with extra spaces
1067
- * to avoid merging
1068
- *
1069
- * @param string $media
1070
- * @return string
1071
- */
1072
- public function css_new_media_section($media) {
1073
- if ($this->get_cfg('preserve_css')) {
1074
- return $media;
1075
- }
1076
-
1077
- // if the last @media is the same as this
1078
- // keep it
1079
- if (!$this->css || !is_array($this->css) || empty($this->css)) {
1080
- return $media;
1081
- }
1082
- end($this->css);
1083
- list($at,) = each($this->css);
1084
- if ($at == $media) {
1085
- return $media;
1086
- }
1087
- while (isset($this->css[$media]))
1088
- if (is_numeric($media))
1089
- $media++;
1090
- else
1091
- $media .= ' ';
1092
- return $media;
1093
- }
1094
-
1095
- /**
1096
- * Start a new selector.
1097
- * If already referenced in this media section,
1098
- * rename it with extra space to avoid merging
1099
- * except if merging is required,
1100
- * or last selector is the same (merge siblings)
1101
- *
1102
- * never merge @font-face
1103
- *
1104
- * @param string $media
1105
- * @param string $selector
1106
- * @return string
1107
- */
1108
- public function css_new_selector($media,$selector) {
1109
- if ($this->get_cfg('preserve_css')) {
1110
- return $selector;
1111
- }
1112
- $selector = trim($selector);
1113
- if (strncmp($selector,'@font-face',10)!=0) {
1114
- if ($this->settings['merge_selectors'] != false)
1115
- return $selector;
1116
-
1117
- if (!$this->css || !isset($this->css[$media]) || !$this->css[$media])
1118
- return $selector;
1119
-
1120
- // if last is the same, keep it
1121
- end($this->css[$media]);
1122
- list($sel,) = each($this->css[$media]);
1123
- if ($sel == $selector) {
1124
- return $selector;
1125
- }
1126
- }
1127
-
1128
- while (isset($this->css[$media][$selector]))
1129
- $selector .= ' ';
1130
- return $selector;
1131
- }
1132
-
1133
- /**
1134
- * Start a new propertie.
1135
- * If already references in this selector,
1136
- * rename it with extra space to avoid override
1137
- *
1138
- * @param string $media
1139
- * @param string $selector
1140
- * @param string $property
1141
- * @return string
1142
- */
1143
- public function css_new_property($media, $selector, $property) {
1144
- if ($this->get_cfg('preserve_css')) {
1145
- return $property;
1146
- }
1147
- if (!$this->css || !isset($this->css[$media][$selector]) || !$this->css[$media][$selector])
1148
- return $property;
1149
-
1150
- while (isset($this->css[$media][$selector][$property]))
1151
- $property .= ' ';
1152
-
1153
- return $property;
1154
- }
1155
-
1156
- /**
1157
- * Adds CSS to an existing media/selector
1158
- * @param string $media
1159
- * @param string $selector
1160
- * @param array $css_add
1161
- * @access private
1162
- * @version 1.1
1163
- */
1164
- public function merge_css_blocks($media, $selector, $css_add) {
1165
- foreach ($css_add as $property => $value) {
1166
- $this->css_add_property($media, $selector, $property, $value, false);
1167
- }
1168
- }
1169
-
1170
- /**
1171
- * Checks if $value is !important.
1172
- * @param string $value
1173
- * @return bool
1174
- * @access public
1175
- * @version 1.0
1176
- */
1177
- public function is_important(&$value) {
1178
- return (
1179
- strpos($value, '!') !== false // quick test
1180
- AND !strcasecmp(substr(str_replace($this->data['csstidy']['whitespace'], '', $value), -10, 10), '!important'));
1181
- }
1182
-
1183
- /**
1184
- * Returns a value without !important
1185
- * @param string $value
1186
- * @return string
1187
- * @access public
1188
- * @version 1.0
1189
- */
1190
- public function gvw_important($value) {
1191
- if ($this->is_important($value)) {
1192
- $value = trim($value);
1193
- $value = substr($value, 0, -9);
1194
- $value = trim($value);
1195
- $value = substr($value, 0, -1);
1196
- $value = trim($value);
1197
- return $value;
1198
- }
1199
- return $value;
1200
- }
1201
-
1202
- /**
1203
- * Checks if the next word in a string from pos is a CSS property
1204
- * @param string $istring
1205
- * @param integer $pos
1206
- * @return bool
1207
- * @access private
1208
- * @version 1.2
1209
- */
1210
- public function property_is_next($istring, $pos) {
1211
- $all_properties = & $this->data['csstidy']['all_properties'];
1212
- $istring = substr($istring, $pos, strlen($istring) - $pos);
1213
- $pos = strpos($istring, ':');
1214
- if ($pos === false) {
1215
- return false;
1216
- }
1217
- $istring = strtolower(trim(substr($istring, 0, $pos)));
1218
- if (isset($all_properties[$istring])) {
1219
- $this->log('Added semicolon to the end of declaration', 'Warning');
1220
- return true;
1221
- }
1222
- return false;
1223
- }
1224
-
1225
- /**
1226
- * Checks if a property is valid
1227
- * @param string $property
1228
- * @return bool;
1229
- * @access public
1230
- * @version 1.0
1231
- */
1232
- public function property_is_valid($property) {
1233
- if (in_array(trim($property), $this->data['csstidy']['multiple_properties'])) $property = trim($property);
1234
- $all_properties = & $this->data['csstidy']['all_properties'];
1235
- return (isset($all_properties[$property]) && strpos($all_properties[$property], strtoupper($this->get_cfg('css_level'))) !== false );
1236
- }
1237
-
1238
- /**
1239
- * Accepts a list of strings (e.g., the argument to format() in a @font-face src property)
1240
- * and returns a list of the strings. Converts things like:
1241
- *
1242
- * format(abc) => format("abc")
1243
- * format(abc def) => format("abc","def")
1244
- * format(abc "def") => format("abc","def")
1245
- * format(abc, def, ghi) => format("abc","def","ghi")
1246
- * format("abc",'def') => format("abc","def")
1247
- * format("abc, def, ghi") => format("abc, def, ghi")
1248
- *
1249
- * @param string
1250
- * @return array
1251
- */
1252
-
1253
- public function parse_string_list($value) {
1254
- $value = trim($value);
1255
-
1256
- // Case: empty
1257
- if (!$value) return array();
1258
-
1259
- $strings = array();
1260
-
1261
- $in_str = false;
1262
- $current_string = '';
1263
-
1264
- for ($i = 0, $_len = strlen($value); $i < $_len; $i++) {
1265
- if (($value{$i} === ',' || $value{$i} === ' ') && $in_str === true) {
1266
- $in_str = false;
1267
- $strings[] = $current_string;
1268
- $current_string = '';
1269
- } elseif ($value{$i} === '"' || $value{$i} === "'") {
1270
- if ($in_str === $value{$i}) {
1271
- $strings[] = $current_string;
1272
- $in_str = false;
1273
- $current_string = '';
1274
- continue;
1275
- } elseif (!$in_str) {
1276
- $in_str = $value{$i};
1277
- }
1278
- } else {
1279
- if ($in_str) {
1280
- $current_string .= $value{$i};
1281
- } else {
1282
- if (!preg_match("/[\s,]/", $value{$i})) {
1283
- $in_str = true;
1284
- $current_string = $value{$i};
1285
- }
1286
- }
1287
- }
1288
- }
1289
-
1290
- if ($current_string) {
1291
- $strings[] = $current_string;
1292
- }
1293
-
1294
- return $strings;
1295
- }
1296
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
libs/CSSTidy/class.csstidy_optimise.php DELETED
@@ -1,963 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * CSSTidy - CSS Parser and Optimiser
5
- *
6
- * CSS Optimising Class
7
- * This class optimises CSS data generated by csstidy.
8
- *
9
- * Copyright 2005, 2006, 2007 Florian Schmitz
10
- *
11
- * This file is part of CSSTidy.
12
- *
13
- * CSSTidy is free software; you can redistribute it and/or modify
14
- * it under the terms of the GNU Lesser General Public License as published by
15
- * the Free Software Foundation; either version 2.1 of the License, or
16
- * (at your option) any later version.
17
- *
18
- * CSSTidy is distributed in the hope that it will be useful,
19
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
- * GNU Lesser General Public License for more details.
22
- *
23
- * You should have received a copy of the GNU Lesser General Public License
24
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
25
- *
26
- * @license http://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
27
- * @package csstidy
28
- * @author Florian Schmitz (floele at gmail dot com) 2005-2007
29
- * @author Brett Zamir (brettz9 at yahoo dot com) 2007
30
- * @author Nikolay Matsievsky (speed at webo dot name) 2009-2010
31
- * @author Cedric Morin (cedric at yterium dot com) 2010-2012
32
- */
33
-
34
- /**
35
- * CSS Optimising Class
36
- *
37
- * This class optimises CSS data generated by csstidy.
38
- *
39
- * @package csstidy
40
- * @author Florian Schmitz (floele at gmail dot com) 2005-2006
41
- * @version 1.0
42
- */
43
- class csstidy_optimise {
44
-
45
- /**
46
- * csstidy object
47
- * @var object
48
- */
49
- public $parser;
50
-
51
- /**
52
- * Constructor
53
- * @param array $css contains the class csstidy
54
- * @access private
55
- * @version 1.0
56
- */
57
- public function __construct($css) {
58
- $this->parser = $css;
59
- $this->css = & $css->css;
60
- $this->sub_value = & $css->sub_value;
61
- $this->at = & $css->at;
62
- $this->selector = & $css->selector;
63
- $this->property = & $css->property;
64
- $this->value = & $css->value;
65
- }
66
-
67
- /**
68
- * Optimises $css after parsing
69
- * @access public
70
- * @version 1.0
71
- */
72
- public function postparse() {
73
- if ($this->parser->get_cfg('preserve_css')) {
74
- return;
75
- }
76
-
77
- if ((int)$this->parser->get_cfg('merge_selectors') === 2) {
78
- foreach ($this->css as $medium => $value) {
79
- $this->merge_selectors($this->css[$medium]);
80
- }
81
- }
82
-
83
- if ($this->parser->get_cfg('discard_invalid_selectors')) {
84
- foreach ($this->css as $medium => $value) {
85
- $this->discard_invalid_selectors($this->css[$medium]);
86
- }
87
- }
88
-
89
- if ($this->parser->get_cfg('optimise_shorthands') > 0) {
90
- foreach ($this->css as $medium => $value) {
91
- foreach ($value as $selector => $value1) {
92
- $this->css[$medium][$selector] = $this->merge_4value_shorthands($this->css[$medium][$selector]);
93
-
94
- if ($this->parser->get_cfg('optimise_shorthands') < 2) {
95
- continue;
96
- }
97
-
98
- $this->css[$medium][$selector] = $this->merge_font($this->css[$medium][$selector]);
99
-
100
- if ($this->parser->get_cfg('optimise_shorthands') < 3) {
101
- continue;
102
- }
103
-
104
- $this->css[$medium][$selector] = $this->merge_bg($this->css[$medium][$selector]);
105
- if (empty($this->css[$medium][$selector])) {
106
- unset($this->css[$medium][$selector]);
107
- }
108
- }
109
- }
110
- }
111
- }
112
-
113
- /**
114
- * Optimises values
115
- * @access public
116
- * @version 1.0
117
- */
118
- public function value() {
119
- $shorthands = & $this->parser->data['csstidy']['shorthands'];
120
-
121
- // optimise shorthand properties
122
- if (isset($shorthands[$this->property])) {
123
- $temp = $this->shorthand($this->value); // FIXME - move
124
- if ($temp != $this->value) {
125
- $this->parser->log('Optimised shorthand notation (' . $this->property . '): Changed "' . $this->value . '" to "' . $temp . '"', 'Information');
126
- }
127
- $this->value = $temp;
128
- }
129
-
130
- // Remove whitespace at ! important
131
- if ($this->value != $this->compress_important($this->value)) {
132
- $this->parser->log('Optimised !important', 'Information');
133
- }
134
- }
135
-
136
- /**
137
- * Optimises shorthands
138
- * @access public
139
- * @version 1.0
140
- */
141
- public function shorthands() {
142
- $shorthands = & $this->parser->data['csstidy']['shorthands'];
143
-
144
- if (!$this->parser->get_cfg('optimise_shorthands') || $this->parser->get_cfg('preserve_css')) {
145
- return;
146
- }
147
-
148
- if ($this->property === 'font' && $this->parser->get_cfg('optimise_shorthands') > 1) {
149
- $this->css[$this->at][$this->selector]['font']='';
150
- $this->parser->merge_css_blocks($this->at, $this->selector, $this->dissolve_short_font($this->value));
151
- }
152
- if ($this->property === 'background' && $this->parser->get_cfg('optimise_shorthands') > 2) {
153
- $this->css[$this->at][$this->selector]['background']='';
154
- $this->parser->merge_css_blocks($this->at, $this->selector, $this->dissolve_short_bg($this->value));
155
- }
156
- if (isset($shorthands[$this->property])) {
157
- $this->parser->merge_css_blocks($this->at, $this->selector, $this->dissolve_4value_shorthands($this->property, $this->value));
158
- if (is_array($shorthands[$this->property])) {
159
- $this->css[$this->at][$this->selector][$this->property] = '';
160
- }
161
- }
162
- }
163
-
164
- /**
165
- * Optimises a sub-value
166
- * @access public
167
- * @version 1.0
168
- */
169
- public function subvalue() {
170
- $replace_colors = & $this->parser->data['csstidy']['replace_colors'];
171
-
172
- $this->sub_value = trim($this->sub_value);
173
- if ($this->sub_value == '') { // caution : '0'
174
- return;
175
- }
176
-
177
- $important = '';
178
- if ($this->parser->is_important($this->sub_value)) {
179
- $important = '!important';
180
- }
181
- $this->sub_value = $this->parser->gvw_important($this->sub_value);
182
-
183
- // Compress font-weight
184
- if ($this->property === 'font-weight' && $this->parser->get_cfg('compress_font-weight')) {
185
- if ($this->sub_value === 'bold') {
186
- $this->sub_value = '700';
187
- $this->parser->log('Optimised font-weight: Changed "bold" to "700"', 'Information');
188
- } elseif ($this->sub_value === 'normal') {
189
- $this->sub_value = '400';
190
- $this->parser->log('Optimised font-weight: Changed "normal" to "400"', 'Information');
191
- }
192
- }
193
-
194
- $temp = $this->compress_numbers($this->sub_value);
195
- if (strcasecmp($temp, $this->sub_value) !== 0) {
196
- if (strlen($temp) > strlen($this->sub_value)) {
197
- $this->parser->log('Fixed invalid number: Changed "' . $this->sub_value . '" to "' . $temp . '"', 'Warning');
198
- } else {
199
- $this->parser->log('Optimised number: Changed "' . $this->sub_value . '" to "' . $temp . '"', 'Information');
200
- }
201
- $this->sub_value = $temp;
202
- }
203
- if ($this->parser->get_cfg('compress_colors')) {
204
- $temp = $this->cut_color($this->sub_value);
205
- if ($temp !== $this->sub_value) {
206
- if (isset($replace_colors[$this->sub_value])) {
207
- $this->parser->log('Fixed invalid color name: Changed "' . $this->sub_value . '" to "' . $temp . '"', 'Warning');
208
- } else {
209
- $this->parser->log('Optimised color: Changed "' . $this->sub_value . '" to "' . $temp . '"', 'Information');
210
- }
211
- $this->sub_value = $temp;
212
- }
213
- }
214
- $this->sub_value .= $important;
215
- }
216
-
217
- /**
218
- * Compresses shorthand values. Example: margin:1px 1px 1px 1px -> margin:1px
219
- * @param string $value
220
- * @access public
221
- * @return string
222
- * @version 1.0
223
- */
224
- public function shorthand($value) {
225
- $important = '';
226
- if ($this->parser->is_important($value)) {
227
- $values = $this->parser->gvw_important($value);
228
- $important = '!important';
229
- }
230
- else
231
- $values = $value;
232
-
233
- $values = explode(' ', $values);
234
- switch (count($values)) {
235
- case 4:
236
- if ($values[0] == $values[1] && $values[0] == $values[2] && $values[0] == $values[3]) {
237
- return $values[0] . $important;
238
- } elseif ($values[1] == $values[3] && $values[0] == $values[2]) {
239
- return $values[0] . ' ' . $values[1] . $important;
240
- } elseif ($values[1] == $values[3]) {
241
- return $values[0] . ' ' . $values[1] . ' ' . $values[2] . $important;
242
- }
243
- break;
244
-
245
- case 3:
246
- if ($values[0] == $values[1] && $values[0] == $values[2]) {
247
- return $values[0] . $important;
248
- } elseif ($values[0] == $values[2]) {
249
- return $values[0] . ' ' . $values[1] . $important;
250
- }
251
- break;
252
-
253
- case 2:
254
- if ($values[0] == $values[1]) {
255
- return $values[0] . $important;
256
- }
257
- break;
258
- }
259
-
260
- return $value;
261
- }
262
-
263
- /**
264
- * Removes unnecessary whitespace in ! important
265
- * @param string $string
266
- * @return string
267
- * @access public
268
- * @version 1.1
269
- */
270
- public function compress_important(&$string) {
271
- if ($this->parser->is_important($string)) {
272
- $important = $this->parser->get_cfg('space_before_important') ? ' !important' : '!important';
273
- $string = $this->parser->gvw_important($string) . $important;
274
- }
275
- return $string;
276
- }
277
-
278
- /**
279
- * Color compression function. Converts all rgb() values to #-values and uses the short-form if possible. Also replaces 4 color names by #-values.
280
- * @param string $color
281
- * @return string
282
- * @version 1.1
283
- */
284
- public function cut_color($color) {
285
- $replace_colors = & $this->parser->data['csstidy']['replace_colors'];
286
-
287
- // if it's a string, don't touch !
288
- if (strncmp($color, "'", 1) == 0 || strncmp($color, '"', 1) == 0)
289
- return $color;
290
-
291
- /* expressions complexes de type gradient */
292
- if (strpos($color, '(') !== false && strncmp($color, 'rgb(' ,4) != 0) {
293
- // on ne touche pas aux couleurs dans les expression ms, c'est trop sensible
294
- if (stripos($color, 'progid:') !== false)
295
- return $color;
296
- preg_match_all(",rgb\([^)]+\),i", $color, $matches, PREG_SET_ORDER);
297
- if (count($matches)) {
298
- foreach ($matches as $m) {
299
- $color = str_replace($m[0], $this->cut_color($m[0]), $color);
300
- }
301
- }
302
- preg_match_all(",#[0-9a-f]{6}(?=[^0-9a-f]),i", $color, $matches, PREG_SET_ORDER);
303
- if (count($matches)) {
304
- foreach ($matches as $m) {
305
- $color = str_replace($m[0],$this->cut_color($m[0]), $color);
306
- }
307
- }
308
- return $color;
309
- }
310
-
311
- // rgb(0,0,0) -> #000000 (or #000 in this case later)
312
- if (strncasecmp($color, 'rgb(', 4)==0) {
313
- $color_tmp = substr($color, 4, strlen($color) - 5);
314
- $color_tmp = explode(',', $color_tmp);
315
- for ($i = 0; $i < count($color_tmp); $i++) {
316
- $color_tmp[$i] = trim($color_tmp[$i]);
317
- if (substr($color_tmp[$i], -1) === '%') {
318
- $color_tmp[$i] = round((255 * $color_tmp[$i]) / 100);
319
- }
320
- if ($color_tmp[$i] > 255)
321
- $color_tmp[$i] = 255;
322
- }
323
- $color = '#';
324
- for ($i = 0; $i < 3; $i++) {
325
- if ($color_tmp[$i] < 16) {
326
- $color .= '0' . dechex($color_tmp[$i]);
327
- } else {
328
- $color .= dechex($color_tmp[$i]);
329
- }
330
- }
331
- }
332
-
333
- // Fix bad color names
334
- if (isset($replace_colors[strtolower($color)])) {
335
- $color = $replace_colors[strtolower($color)];
336
- }
337
-
338
- // #aabbcc -> #abc
339
- if (strlen($color) == 7) {
340
- $color_temp = strtolower($color);
341
- if ($color_temp{0} === '#' && $color_temp{1} == $color_temp{2} && $color_temp{3} == $color_temp{4} && $color_temp{5} == $color_temp{6}) {
342
- $color = '#' . $color{1} . $color{3} . $color{5};
343
- }
344
- }
345
-
346
- switch (strtolower($color)) {
347
- /* color name -> hex code */
348
- case 'black': return '#000';
349
- case 'fuchsia': return '#f0f';
350
- case 'white': return '#fff';
351
- case 'yellow': return '#ff0';
352
-
353
- /* hex code -> color name */
354
- case '#800000': return 'maroon';
355
- case '#ffa500': return 'orange';
356
- case '#808000': return 'olive';
357
- case '#800080': return 'purple';
358
- case '#008000': return 'green';
359
- case '#000080': return 'navy';
360
- case '#008080': return 'teal';
361
- case '#c0c0c0': return 'silver';
362
- case '#808080': return 'gray';
363
- case '#f00': return 'red';
364
- }
365
-
366
- return $color;
367
- }
368
-
369
- /**
370
- * Compresses numbers (ie. 1.0 becomes 1 or 1.100 becomes 1.1 )
371
- * @param string $subvalue
372
- * @return string
373
- * @version 1.2
374
- */
375
- public function compress_numbers($subvalue) {
376
- $unit_values = & $this->parser->data['csstidy']['unit_values'];
377
- $color_values = & $this->parser->data['csstidy']['color_values'];
378
-
379
- // for font:1em/1em sans-serif...;
380
- if ($this->property === 'font') {
381
- $temp = explode('/', $subvalue);
382
- } else {
383
- $temp = array($subvalue);
384
- }
385
-
386
- for ($l = 0; $l < count($temp); $l++) {
387
- // if we are not dealing with a number at this point, do not optimise anything
388
- $number = $this->AnalyseCssNumber($temp[$l]);
389
- if ($number === false) {
390
- return $subvalue;
391
- }
392
-
393
- // Fix bad colors
394
- if (in_array($this->property, $color_values)) {
395
- $temp[$l] = '#' . $temp[$l];
396
- continue;
397
- }
398
-
399
- if (abs($number[0]) > 0) {
400
- if ($number[1] == '' && in_array($this->property, $unit_values, true)) {
401
- $number[1] = 'px';
402
- }
403
- } elseif ($number[1] != 's' && $number[1] != 'ms') {
404
- $number[1] = '';
405
- }
406
-
407
- $temp[$l] = $number[0] . $number[1];
408
- }
409
-
410
- return ((count($temp) > 1) ? $temp[0] . '/' . $temp[1] : $temp[0]);
411
- }
412
-
413
- /**
414
- * Checks if a given string is a CSS valid number. If it is,
415
- * an array containing the value and unit is returned
416
- * @param string $string
417
- * @return array ('unit' if unit is found or '' if no unit exists, number value) or false if no number
418
- */
419
- public function AnalyseCssNumber($string) {
420
- // most simple checks first
421
- if (strlen($string) == 0 || ctype_alpha($string{0})) {
422
- return false;
423
- }
424
-
425
- $units = & $this->parser->data['csstidy']['units'];
426
- $return = array(0, '');
427
-
428
- $return[0] = floatval($string);
429
- if (abs($return[0]) > 0 && abs($return[0]) < 1) {
430
- if ($return[0] < 0) {
431
- $return[0] = '-' . ltrim(substr($return[0], 1), '0');
432
- } else {
433
- $return[0] = ltrim($return[0], '0');
434
- }
435
- }
436
-
437
- // Look for unit and split from value if exists
438
- foreach ($units as $unit) {
439
- $expectUnitAt = strlen($string) - strlen($unit);
440
- if (!($unitInString = stristr($string, $unit))) { // mb_strpos() fails with "false"
441
- continue;
442
- }
443
- $actualPosition = strpos($string, $unitInString);
444
- if ($expectUnitAt === $actualPosition) {
445
- $return[1] = $unit;
446
- $string = substr($string, 0, - strlen($unit));
447
- break;
448
- }
449
- }
450
- if (!is_numeric($string)) {
451
- return false;
452
- }
453
- return $return;
454
- }
455
-
456
- /**
457
- * Merges selectors with same properties. Example: a{color:red} b{color:red} -> a,b{color:red}
458
- * Very basic and has at least one bug. Hopefully there is a replacement soon.
459
- * @param array $array
460
- * @return array
461
- * @access public
462
- * @version 1.2
463
- */
464
- public function merge_selectors(&$array) {
465
- $css = $array;
466
- foreach ($css as $key => $value) {
467
- if (!isset($css[$key])) {
468
- continue;
469
- }
470
- $newsel = '';
471
-
472
- // Check if properties also exist in another selector
473
- $keys = array();
474
- // PHP bug (?) without $css = $array; here
475
- foreach ($css as $selector => $vali) {
476
- if ($selector == $key) {
477
- continue;
478
- }
479
-
480
- if ($css[$key] === $vali) {
481
- $keys[] = $selector;
482
- }
483
- }
484
-
485
- if (!empty($keys)) {
486
- $newsel = $key;
487
- unset($css[$key]);
488
- foreach ($keys as $selector) {
489
- unset($css[$selector]);
490
- $newsel .= ',' . $selector;
491
- }
492
- $css[$newsel] = $value;
493
- }
494
- }
495
- $array = $css;
496
- }
497
-
498
- /**
499
- * Removes invalid selectors and their corresponding rule-sets as
500
- * defined by 4.1.7 in REC-CSS2. This is a very rudimentary check
501
- * and should be replaced by a full-blown parsing algorithm or
502
- * regular expression
503
- * @version 1.4
504
- */
505
- public function discard_invalid_selectors(&$array) {
506
- $invalid = array('+' => true, '~' => true, ',' => true, '>' => true);
507
- foreach ($array as $selector => $decls) {
508
- $ok = true;
509
- $selectors = array_map('trim', explode(',', $selector));
510
- foreach ($selectors as $s) {
511
- $simple_selectors = preg_split('/\s*[+>~\s]\s*/', $s);
512
- foreach ($simple_selectors as $ss) {
513
- if ($ss === '')
514
- $ok = false;
515
- // could also check $ss for internal structure,
516
- // but that probably would be too slow
517
- }
518
- }
519
- if (!$ok)
520
- unset($array[$selector]);
521
- }
522
- }
523
-
524
- /**
525
- * Dissolves properties like padding:10px 10px 10px to padding-top:10px;padding-bottom:10px;...
526
- * @param string $property
527
- * @param string $value
528
- * @return array
529
- * @version 1.0
530
- * @see merge_4value_shorthands()
531
- */
532
- public function dissolve_4value_shorthands($property, $value) {
533
- $shorthands = & $this->parser->data['csstidy']['shorthands'];
534
- if (!is_array($shorthands[$property])) {
535
- $return[$property] = $value;
536
- return $return;
537
- }
538
-
539
- $important = '';
540
- if ($this->parser->is_important($value)) {
541
- $value = $this->parser->gvw_important($value);
542
- $important = '!important';
543
- }
544
- $values = explode(' ', $value);
545
-
546
-
547
- $return = array();
548
- if (count($values) == 4) {
549
- for ($i = 0; $i < 4; $i++) {
550
- $return[$shorthands[$property][$i]] = $values[$i] . $important;
551
- }
552
- } elseif (count($values) == 3) {
553
- $return[$shorthands[$property][0]] = $values[0] . $important;
554
- $return[$shorthands[$property][1]] = $values[1] . $important;
555
- $return[$shorthands[$property][3]] = $values[1] . $important;
556
- $return[$shorthands[$property][2]] = $values[2] . $important;
557
- } elseif (count($values) == 2) {
558
- for ($i = 0; $i < 4; $i++) {
559
- $return[$shorthands[$property][$i]] = (($i % 2 != 0)) ? $values[1] . $important : $values[0] . $important;
560
- }
561
- } else {
562
- for ($i = 0; $i < 4; $i++) {
563
- $return[$shorthands[$property][$i]] = $values[0] . $important;
564
- }
565
- }
566
-
567
- return $return;
568
- }
569
-
570
- /**
571
- * Explodes a string as explode() does, however, not if $sep is escaped or within a string.
572
- * @param string $sep seperator
573
- * @param string $string
574
- * @return array
575
- * @version 1.0
576
- */
577
- public function explode_ws($sep, $string) {
578
- $status = 'st';
579
- $to = '';
580
-
581
- $output = array();
582
- $num = 0;
583
- for ($i = 0, $len = strlen($string); $i < $len; $i++) {
584
- switch ($status) {
585
- case 'st':
586
- if ($string{$i} == $sep && !$this->parser->escaped($string, $i)) {
587
- ++$num;
588
- } elseif ($string{$i} === '"' || $string{$i} === '\'' || $string{$i} === '(' && !$this->parser->escaped($string, $i)) {
589
- $status = 'str';
590
- $to = ($string{$i} === '(') ? ')' : $string{$i};
591
- (isset($output[$num])) ? $output[$num] .= $string{$i} : $output[$num] = $string{$i};
592
- } else {
593
- (isset($output[$num])) ? $output[$num] .= $string{$i} : $output[$num] = $string{$i};
594
- }
595
- break;
596
-
597
- case 'str':
598
- if ($string{$i} == $to && !$this->parser->escaped($string, $i)) {
599
- $status = 'st';
600
- }
601
- (isset($output[$num])) ? $output[$num] .= $string{$i} : $output[$num] = $string{$i};
602
- break;
603
- }
604
- }
605
-
606
- if (isset($output[0])) {
607
- return $output;
608
- } else {
609
- return array($output);
610
- }
611
- }
612
-
613
- /**
614
- * Merges Shorthand properties again, the opposite of dissolve_4value_shorthands()
615
- * @param array $array
616
- * @return array
617
- * @version 1.2
618
- * @see dissolve_4value_shorthands()
619
- */
620
- public function merge_4value_shorthands($array) {
621
- $return = $array;
622
- $shorthands = & $this->parser->data['csstidy']['shorthands'];
623
-
624
- foreach ($shorthands as $key => $value) {
625
- if (isset($array[$value[0]]) && isset($array[$value[1]])
626
- && isset($array[$value[2]]) && isset($array[$value[3]]) && $value !== 0) {
627
- $return[$key] = '';
628
-
629
- $important = '';
630
- for ($i = 0; $i < 4; $i++) {
631
- $val = $array[$value[$i]];
632
- if ($this->parser->is_important($val)) {
633
- $important = '!important';
634
- $return[$key] .= $this->parser->gvw_important($val) . ' ';
635
- } else {
636
- $return[$key] .= $val . ' ';
637
- }
638
- unset($return[$value[$i]]);
639
- }
640
- $return[$key] = $this->shorthand(trim($return[$key] . $important));
641
- }
642
- }
643
- return $return;
644
- }
645
-
646
- /**
647
- * Dissolve background property
648
- * @param string $str_value
649
- * @return array
650
- * @version 1.0
651
- * @see merge_bg()
652
- * @todo full CSS 3 compliance
653
- */
654
- public function dissolve_short_bg($str_value) {
655
- // don't try to explose background gradient !
656
- if (stripos($str_value, 'gradient(')!== false)
657
- return array('background'=>$str_value);
658
-
659
- $background_prop_default = & $this->parser->data['csstidy']['background_prop_default'];
660
- $repeat = array('repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'space');
661
- $attachment = array('scroll', 'fixed', 'local');
662
- $clip = array('border', 'padding');
663
- $origin = array('border', 'padding', 'content');
664
- $pos = array('top', 'center', 'bottom', 'left', 'right');
665
- $important = '';
666
- $return = array('background-image' => null, 'background-size' => null, 'background-repeat' => null, 'background-position' => null, 'background-attachment' => null, 'background-clip' => null, 'background-origin' => null, 'background-color' => null);
667
-
668
- if ($this->parser->is_important($str_value)) {
669
- $important = ' !important';
670
- $str_value = $this->parser->gvw_important($str_value);
671
- }
672
-
673
- $str_value = $this->explode_ws(',', $str_value);
674
- for ($i = 0; $i < count($str_value); $i++) {
675
- $have['clip'] = false;
676
- $have['pos'] = false;
677
- $have['color'] = false;
678
- $have['bg'] = false;
679
-
680
- if (is_array($str_value[$i])) {
681
- $str_value[$i] = $str_value[$i][0];
682
- }
683
- $str_value[$i] = $this->explode_ws(' ', trim($str_value[$i]));
684
-
685
- for ($j = 0; $j < count($str_value[$i]); $j++) {
686
- if ($have['bg'] === false && (substr($str_value[$i][$j], 0, 4) === 'url(' || $str_value[$i][$j] === 'none')) {
687
- $return['background-image'] .= $str_value[$i][$j] . ',';
688
- $have['bg'] = true;
689
- } elseif (in_array($str_value[$i][$j], $repeat, true)) {
690
- $return['background-repeat'] .= $str_value[$i][$j] . ',';
691
- } elseif (in_array($str_value[$i][$j], $attachment, true)) {
692
- $return['background-attachment'] .= $str_value[$i][$j] . ',';
693
- } elseif (in_array($str_value[$i][$j], $clip, true) && !$have['clip']) {
694
- $return['background-clip'] .= $str_value[$i][$j] . ',';
695
- $have['clip'] = true;
696
- } elseif (in_array($str_value[$i][$j], $origin, true)) {
697
- $return['background-origin'] .= $str_value[$i][$j] . ',';
698
- } elseif ($str_value[$i][$j]{0} === '(') {
699
- $return['background-size'] .= substr($str_value[$i][$j], 1, -1) . ',';
700
- } elseif (in_array($str_value[$i][$j], $pos, true) || is_numeric($str_value[$i][$j]{0}) || $str_value[$i][$j]{0} === null || $str_value[$i][$j]{0} === '-' || $str_value[$i][$j]{0} === '.') {
701
- $return['background-position'] .= $str_value[$i][$j];
702
- if (!$have['pos'])
703
- $return['background-position'] .= ' '; else
704
- $return['background-position'].= ',';
705
- $have['pos'] = true;
706
- } elseif (!$have['color']) {
707
- $return['background-color'] .= $str_value[$i][$j] . ',';
708
- $have['color'] = true;
709
- }
710
- }
711
- }
712
-
713
- foreach ($background_prop_default as $bg_prop => $default_value) {
714
- if ($return[$bg_prop] !== null) {
715
- $return[$bg_prop] = substr($return[$bg_prop], 0, -1) . $important;
716
- }
717
- else
718
- $return[$bg_prop] = $default_value . $important;
719
- }
720
- return $return;
721
- }
722
-
723
- /**
724
- * Merges all background properties
725
- * @param array $input_css
726
- * @return array
727
- * @version 1.0
728
- * @see dissolve_short_bg()
729
- * @todo full CSS 3 compliance
730
- */
731
- public function merge_bg($input_css) {
732
- $background_prop_default = & $this->parser->data['csstidy']['background_prop_default'];
733
- // Max number of background images. CSS3 not yet fully implemented
734
- $number_of_values = @max(count($this->explode_ws(',', $input_css['background-image'])), count($this->explode_ws(',', $input_css['background-color'])), 1);
735
- // Array with background images to check if BG image exists
736
- $bg_img_array = @$this->explode_ws(',', $this->parser->gvw_important($input_css['background-image']));
737
- $new_bg_value = '';
738
- $important = '';
739
-
740
- // if background properties is here and not empty, don't try anything
741
- if (isset($input_css['background']) && $input_css['background'])
742
- return $input_css;
743
-
744
- for ($i = 0; $i < $number_of_values; $i++) {
745
- foreach ($background_prop_default as $bg_property => $default_value) {
746
- // Skip if property does not exist
747
- if (!isset($input_css[$bg_property])) {
748
- continue;
749
- }
750
-
751
- $cur_value = $input_css[$bg_property];
752
- // skip all optimisation if gradient() somewhere
753
- if (stripos($cur_value, 'gradient(') !== false)
754
- return $input_css;
755
-
756
- // Skip some properties if there is no background image
757
- if ((!isset($bg_img_array[$i]) || $bg_img_array[$i] === 'none')
758
- && ($bg_property === 'background-size' || $bg_property === 'background-position'
759
- || $bg_property === 'background-attachment' || $bg_property === 'background-repeat')) {
760
- continue;
761
- }
762
-
763
- // Remove !important
764
- if ($this->parser->is_important($cur_value)) {
765
- $important = ' !important';
766
- $cur_value = $this->parser->gvw_important($cur_value);
767
- }
768
-
769
- // Do not add default values
770
- if ($cur_value === $default_value) {
771
- continue;
772
- }
773
-
774
- $temp = $this->explode_ws(',', $cur_value);
775
-
776
- if (isset($temp[$i])) {
777
- if ($bg_property === 'background-size') {
778
- $new_bg_value .= '(' . $temp[$i] . ') ';
779
- } else {
780
- $new_bg_value .= $temp[$i] . ' ';
781
- }
782
- }
783
- }
784
-
785
- $new_bg_value = trim($new_bg_value);
786
- if ($i != $number_of_values - 1)
787
- $new_bg_value .= ',';
788
- }
789
-
790
- // Delete all background-properties
791
- foreach ($background_prop_default as $bg_property => $default_value) {
792
- unset($input_css[$bg_property]);
793
- }
794
-
795
- // Add new background property
796
- if ($new_bg_value !== '')
797
- $input_css['background'] = $new_bg_value . $important;
798
- elseif(isset ($input_css['background']))
799
- $input_css['background'] = 'none';
800
-
801
- return $input_css;
802
- }
803
-
804
- /**
805
- * Dissolve font property
806
- * @param string $str_value
807
- * @return array
808
- * @version 1.3
809
- * @see merge_font()
810
- */
811
- public function dissolve_short_font($str_value) {
812
- $font_prop_default = & $this->parser->data['csstidy']['font_prop_default'];
813
- $font_weight = array('normal', 'bold', 'bolder', 'lighter', 100, 200, 300, 400, 500, 600, 700, 800, 900);
814
- $font_variant = array('normal', 'small-caps');
815
- $font_style = array('normal', 'italic', 'oblique');
816
- $important = '';
817
- $return = array('font-style' => null, 'font-variant' => null, 'font-weight' => null, 'font-size' => null, 'line-height' => null, 'font-family' => null);
818
-
819
- if ($this->parser->is_important($str_value)) {
820
- $important = '!important';
821
- $str_value = $this->parser->gvw_important($str_value);
822
- }
823
-
824
- $have['style'] = false;
825
- $have['variant'] = false;
826
- $have['weight'] = false;
827
- $have['size'] = false;
828
- // Detects if font-family consists of several words w/o quotes
829
- $multiwords = false;
830
-
831
- // Workaround with multiple font-family
832
- $str_value = $this->explode_ws(',', trim($str_value));
833
-
834
- $str_value[0] = $this->explode_ws(' ', trim($str_value[0]));
835
-
836
- for ($j = 0; $j < count($str_value[0]); $j++) {
837
- if ($have['weight'] === false && in_array($str_value[0][$j], $font_weight)) {
838
- $return['font-weight'] = $str_value[0][$j];
839
- $have['weight'] = true;
840
- } elseif ($have['variant'] === false && in_array($str_value[0][$j], $font_variant)) {
841
- $return['font-variant'] = $str_value[0][$j];
842
- $have['variant'] = true;
843
- } elseif ($have['style'] === false && in_array($str_value[0][$j], $font_style)) {
844
- $return['font-style'] = $str_value[0][$j];
845
- $have['style'] = true;
846
- } elseif ($have['size'] === false && (is_numeric($str_value[0][$j]{0}) || $str_value[0][$j]{0} === null || $str_value[0][$j]{0} === '.')) {
847
- $size = $this->explode_ws('/', trim($str_value[0][$j]));
848
- $return['font-size'] = $size[0];
849
- if (isset($size[1])) {
850
- $return['line-height'] = $size[1];
851
- } else {
852
- $return['line-height'] = ''; // don't add 'normal' !
853
- }
854
- $have['size'] = true;
855
- } else {
856
- if (isset($return['font-family'])) {
857
- $return['font-family'] .= ' ' . $str_value[0][$j];
858
- $multiwords = true;
859
- } else {
860
- $return['font-family'] = $str_value[0][$j];
861
- }
862
- }
863
- }
864
- // add quotes if we have several qords in font-family
865
- if ($multiwords !== false) {
866
- $return['font-family'] = '"' . $return['font-family'] . '"';
867
- }
868
- $i = 1;
869
- while (isset($str_value[$i])) {
870
- $return['font-family'] .= ',' . trim($str_value[$i]);
871
- $i++;
872
- }
873
-
874
- // Fix for 100 and more font-size
875
- if ($have['size'] === false && isset($return['font-weight']) &&
876
- is_numeric($return['font-weight']{0})) {
877
- $return['font-size'] = $return['font-weight'];
878
- unset($return['font-weight']);
879
- }
880
-
881
- foreach ($font_prop_default as $font_prop => $default_value) {
882
- if ($return[$font_prop] !== null) {
883
- $return[$font_prop] = $return[$font_prop] . $important;
884
- }
885
- else
886
- $return[$font_prop] = $default_value . $important;
887
- }
888
- return $return;
889
- }
890
-
891
- /**
892
- * Merges all fonts properties
893
- * @param array $input_css
894
- * @return array
895
- * @version 1.3
896
- * @see dissolve_short_font()
897
- */
898
- public function merge_font($input_css) {
899
- $font_prop_default = & $this->parser->data['csstidy']['font_prop_default'];
900
- $new_font_value = '';
901
- $important = '';
902
- // Skip if not font-family and font-size set
903
- if (isset($input_css['font-family']) && isset($input_css['font-size']) && $input_css['font-family'] != 'inherit') {
904
- // fix several words in font-family - add quotes
905
- if (isset($input_css['font-family'])) {
906
- $families = explode(',', $input_css['font-family']);
907
- $result_families = array();
908
- foreach ($families as $family) {
909
- $family = trim($family);
910
- $len = strlen($family);
911
- if (strpos($family, ' ') &&
912
- !(($family{0} === '"' && $family{$len - 1} === '"') ||
913
- ($family{0} === "'" && $family{$len - 1} === "'"))) {
914
- $family = '"' . $family . '"';
915
- }
916
- $result_families[] = $family;
917
- }
918
- $input_css['font-family'] = implode(',', $result_families);
919
- }
920
- foreach ($font_prop_default as $font_property => $default_value) {
921
-
922
- // Skip if property does not exist
923
- if (!isset($input_css[$font_property])) {
924
- continue;
925
- }
926
-
927
- $cur_value = $input_css[$font_property];
928
-
929
- // Skip if default value is used
930
- if ($cur_value === $default_value) {
931
- continue;
932
- }
933
-
934
- // Remove !important
935
- if ($this->parser->is_important($cur_value)) {
936
- $important = '!important';
937
- $cur_value = $this->parser->gvw_important($cur_value);
938
- }
939
-
940
- $new_font_value .= $cur_value;
941
- // Add delimiter
942
- $new_font_value .= ( $font_property === 'font-size' &&
943
- isset($input_css['line-height'])) ? '/' : ' ';
944
- }
945
-
946
- $new_font_value = trim($new_font_value);
947
-
948
- // Delete all font-properties
949
- foreach ($font_prop_default as $font_property => $default_value) {
950
- if ($font_property !== 'font' || !$new_font_value)
951
- unset($input_css[$font_property]);
952
- }
953
-
954
- // Add new font property
955
- if ($new_font_value !== '') {
956
- $input_css['font'] = $new_font_value . $important;
957
- }
958
- }
959
-
960
- return $input_css;
961
- }
962
-
963
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
libs/CSSTidy/class.csstidy_print.php DELETED
@@ -1,446 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * CSSTidy - CSS Parser and Optimiser
5
- *
6
- * CSS Printing class
7
- * This class prints CSS data generated by csstidy.
8
- *
9
- * Copyright 2005, 2006, 2007 Florian Schmitz
10
- *
11
- * This file is part of CSSTidy.
12
- *
13
- * CSSTidy is free software; you can redistribute it and/or modify
14
- * it under the terms of the GNU Lesser General Public License as published by
15
- * the Free Software Foundation; either version 2.1 of the License, or
16
- * (at your option) any later version.
17
- *
18
- * CSSTidy is distributed in the hope that it will be useful,
19
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
- * GNU Lesser General Public License for more details.
22
- *
23
- * You should have received a copy of the GNU Lesser General Public License
24
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
25
- *
26
- * @license http://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
27
- * @package csstidy
28
- * @author Florian Schmitz (floele at gmail dot com) 2005-2007
29
- * @author Brett Zamir (brettz9 at yahoo dot com) 2007
30
- * @author Cedric Morin (cedric at yterium dot com) 2010-2012
31
- */
32
-
33
- /**
34
- * CSS Printing class
35
- *
36
- * This class prints CSS data generated by csstidy.
37
- *
38
- * @package csstidy
39
- * @author Florian Schmitz (floele at gmail dot com) 2005-2006
40
- * @version 1.1.0
41
- */
42
- class csstidy_print {
43
-
44
- /**
45
- * csstidy object
46
- * @var object
47
- */
48
- public $parser;
49
-
50
- /**
51
- * Saves the input CSS string
52
- * @var string
53
- * @access private
54
- */
55
- public $input_css = '';
56
- /**
57
- * Saves the formatted CSS string
58
- * @var string
59
- * @access public
60
- */
61
- public $output_css = '';
62
- /**
63
- * Saves the formatted CSS string (plain text)
64
- * @var string
65
- * @access public
66
- */
67
- public $output_css_plain = '';
68
-
69
- /**
70
- * Constructor
71
- * @param array $css contains the class csstidy
72
- * @access private
73
- * @version 1.0
74
- */
75
- public function __construct($css) {
76
- $this->parser = $css;
77
- $this->css = & $css->css;
78
- $this->template = & $css->template;
79
- $this->tokens = & $css->tokens;
80
- $this->charset = & $css->charset;
81
- $this->import = & $css->import;
82
- $this->namespace = & $css->namespace;
83
- }
84
-
85
- /**
86
- * Resets output_css and output_css_plain (new css code)
87
- * @access private
88
- * @version 1.0
89
- */
90
- public function _reset() {
91
- $this->output_css = '';
92
- $this->output_css_plain = '';
93
- }
94
-
95
- /**
96
- * Returns the CSS code as plain text
97
- * @param string $default_media default @media to add to selectors without any @media
98
- * @return string
99
- * @access public
100
- * @version 1.0
101
- */
102
- public function plain($default_media='') {
103
- $this->_print(true, $default_media);
104
- return $this->output_css_plain;
105
- }
106
-
107
- /**
108
- * Returns the formatted CSS code
109
- * @param string $default_media default @media to add to selectors without any @media
110
- * @return string
111
- * @access public
112
- * @version 1.0
113
- */
114
- public function formatted($default_media='') {
115
- $this->_print(false, $default_media);
116
- return $this->output_css;
117
- }
118
-
119
- /**
120
- * Returns the formatted CSS code to make a complete webpage
121
- * @param string $doctype shorthand for the document type
122
- * @param bool $externalcss indicates whether styles to be attached internally or as an external stylesheet
123
- * @param string $title title to be added in the head of the document
124
- * @param string $lang two-letter language code to be added to the output
125
- * @return string
126
- * @access public
127
- * @version 1.4
128
- */
129
- public function formatted_page($doctype='html5', $externalcss=true, $title='', $lang='en') {
130
- switch ($doctype) {
131
- case 'html5':
132
- $doctype_output = '<!DOCTYPE html>';
133
- break;
134
- case 'xhtml1.0strict':
135
- $doctype_output = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
136
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
137
- break;
138
- case 'xhtml1.1':
139
- default:
140
- $doctype_output = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
141
- "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">';
142
- break;
143
- }
144
-
145
- $output = $cssparsed = '';
146
- $this->output_css_plain = & $output;
147
-
148
- $output .= $doctype_output . "\n" . '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="' . $lang . '"';
149
- $output .= ( $doctype === 'xhtml1.1') ? '>' : ' lang="' . $lang . '">';
150
- $output .= "\n<head>\n <title>$title</title>";
151
-
152
- if ($externalcss) {
153
- $output .= "\n <style type=\"text/css\">\n";
154
- $cssparsed = file_get_contents('cssparsed.css');
155
- $output .= $cssparsed; // Adds an invisible BOM or something, but not in css_optimised.php
156
- $output .= "\n</style>";
157
- } else {
158
- $output .= "\n" . ' <link rel="stylesheet" type="text/css" href="cssparsed.css" />';
159
- }
160
- $output .= "\n</head>\n<body><code id=\"copytext\">";
161
- $output .= $this->formatted();
162
- $output .= '</code>' . "\n" . '</body></html>';
163
- return $this->output_css_plain;
164
- }
165
-
166
- /**
167
- * Returns the formatted CSS Code and saves it into $this->output_css and $this->output_css_plain
168
- * @param bool $plain plain text or not
169
- * @param string $default_media default @media to add to selectors without any @media
170
- * @access private
171
- * @version 2.0
172
- */
173
- public function _print($plain = false, $default_media='') {
174
- if ($this->output_css && $this->output_css_plain) {
175
- return;
176
- }
177
-
178
- $output = '';
179
- if (!$this->parser->get_cfg('preserve_css')) {
180
- $this->_convert_raw_css($default_media);
181
- }
182
-
183
- $template = & $this->template;
184
-
185
- if ($plain) {
186
- $template = array_map('strip_tags', $template);
187
- }
188
-
189
- if ($this->parser->get_cfg('timestamp')) {
190
- array_unshift($this->tokens, array(COMMENT, ' CSSTidy ' . $this->parser->version . ': ' . date('r') . ' '));
191
- }
192
-
193
- if (!empty($this->charset)) {
194
- $output .= $template[0] . '@charset ' . $template[5] . $this->charset . $template[6] . $template[13];
195
- }
196
-
197
- if (!empty($this->import)) {
198
- for ($i = 0, $size = count($this->import); $i < $size; $i++) {
199
- if (substr($this->import[$i], 0, 4) === 'url(' && substr($this->import[$i], -1, 1) === ')') {
200
- $this->import[$i] = '"' . substr($this->import[$i], 4, -1) . '"';
201
- $this->parser->log('Optimised @import : Removed "url("', 'Information');
202
- }
203
- else if (!preg_match('/^".+"$/',$this->import[$i])) {
204
- // fixes a bug for @import ".." instead of the expected @import url("..")
205
- // If it comes in due to @import ".." the "" will be missing and the output will become @import .. (which is an error)
206
- $this->import[$i] = '"' . $this->import[$i] . '"';
207
- }
208
-
209
- $output .= $template[0] . '@import ' . $template[5] . $this->import[$i] . $template[6] . $template[13];
210
- }
211
- }
212
-
213
- if (!empty($this->namespace)) {
214
- if (($p=strpos($this->namespace,"url("))!==false && substr($this->namespace, -1, 1) === ')') {
215
- $this->namespace = substr_replace($this->namespace,'"',$p,4);
216
- $this->namespace = substr($this->namespace, 0, -1) . '"';
217
- $this->parser->log('Optimised @namespace : Removed "url("', 'Information');
218
- }
219
- $output .= $template[0] . '@namespace ' . $template[5] . $this->namespace . $template[6] . $template[13];
220
- }
221
-
222
- $in_at_out = '';
223
- $out = & $output;
224
-
225
- foreach ($this->tokens as $key => $token) {
226
- switch ($token[0]) {
227
- case AT_START:
228
- $out .= $template[0] . $this->_htmlsp($token[1], $plain) . $template[1];
229
- $out = & $in_at_out;
230
- break;
231
-
232
- case SEL_START:
233
- if ($this->parser->get_cfg('lowercase_s'))
234
- $token[1] = strtolower($token[1]);
235
- $out .= ( $token[1]{0} !== '@') ? $template[2] . $this->_htmlsp($token[1], $plain) : $template[0] . $this->_htmlsp($token[1], $plain);
236
- $out .= $template[3];
237
- break;
238
-
239
- case PROPERTY:
240
- if ($this->parser->get_cfg('case_properties') === 2) {
241
- $token[1] = strtoupper($token[1]);
242
- } elseif ($this->parser->get_cfg('case_properties') === 1) {
243
- $token[1] = strtolower($token[1]);
244
- }
245
- $out .= $template[4] . $this->_htmlsp($token[1], $plain) . ':' . $template[5];
246
- break;
247
-
248
- case VALUE:
249
- $out .= $this->_htmlsp($token[1], $plain);
250
- if ($this->_seeknocomment($key, 1) == SEL_END && $this->parser->get_cfg('remove_last_;')) {
251
- $out .= str_replace(';', '', $template[6]);
252
- } else {
253
- $out .= $template[6];
254
- }
255
- break;
256
-
257
- case SEL_END:
258
- $out .= $template[7];
259
- if ($this->_seeknocomment($key, 1) != AT_END)
260
- $out .= $template[8];
261
- break;
262
-
263
- case AT_END:
264
- $out = & $output;
265
- $in_at_out = str_replace("\n\n", "\r\n", $in_at_out); // don't fill empty lines
266
- $in_at_out = str_replace("\n", "\n" . $template[10], $in_at_out);
267
- $in_at_out = str_replace("\r\n", "\n\n", $in_at_out);
268
- $out .= $template[10] . $in_at_out . $template[9];
269
- $in_at_out = '';
270
- break;
271
-
272
- case COMMENT:
273
- $out .= $template[11] . '/*' . $this->_htmlsp($token[1], $plain) . '*/' . $template[12];
274
- break;
275
- }
276
- }
277
-
278
- $output = trim($output);
279
-
280
- if (!$plain) {
281
- $this->output_css = $output;
282
- $this->_print(true);
283
- } else {
284
- // If using spaces in the template, don't want these to appear in the plain output
285
- $this->output_css_plain = str_replace('&#160;', '', $output);
286
- }
287
- }
288
-
289
- /**
290
- * Gets the next token type which is $move away from $key, excluding comments
291
- * @param integer $key current position
292
- * @param integer $move move this far
293
- * @return mixed a token type
294
- * @access private
295
- * @version 1.0
296
- */
297
- public function _seeknocomment($key, $move) {
298
- $go = ($move > 0) ? 1 : -1;
299
- for ($i = $key + 1; abs($key - $i) - 1 < abs($move); $i += $go) {
300
- if (!isset($this->tokens[$i])) {
301
- return;
302
- }
303
- if ($this->tokens[$i][0] == COMMENT) {
304
- $move += 1;
305
- continue;
306
- }
307
- return $this->tokens[$i][0];
308
- }
309
- }
310
-
311
- /**
312
- * Converts $this->css array to a raw array ($this->tokens)
313
- * @param string $default_media default @media to add to selectors without any @media
314
- * @access private
315
- * @version 1.0
316
- */
317
- public function _convert_raw_css($default_media='') {
318
- $this->tokens = array();
319
- $sort_selectors = $this->parser->get_cfg('sort_selectors');
320
- $sort_properties = $this->parser->get_cfg('sort_properties');
321
-
322
- foreach ($this->css as $medium => $val) {
323
- if ($sort_selectors)
324
- ksort($val);
325
- if (intval($medium) < DEFAULT_AT) {
326
- // un medium vide (contenant @font-face ou autre @) ne produit aucun conteneur
327
- if (strlen(trim($medium))) {
328
- $this->parser->_add_token(AT_START, $medium, true);
329
- }
330
- } elseif ($default_media) {
331
- $this->parser->_add_token(AT_START, $default_media, true);
332
- }
333
-
334
- foreach ($val as $selector => $vali) {
335
- if ($sort_properties)
336
- ksort($vali);
337
- $this->parser->_add_token(SEL_START, $selector, true);
338
-
339
- $invalid = array(
340
- '*' => array(), // IE7 hacks first
341
- '_' => array(), // IE6 hacks
342
- '/' => array(), // IE6 hacks
343
- '-' => array() // IE6 hacks
344
- );
345
- foreach ($vali as $property => $valj) {
346
- if (strncmp($property,"//",2)!==0) {
347
- $matches = array();
348
- if ($sort_properties && preg_match('/^(\*|_|\/|-)(?!(ms|moz|o\b|xv|atsc|wap|khtml|webkit|ah|hp|ro|rim|tc)-)/', $property, $matches)) {
349
- $invalid[$matches[1]][$property] = $valj;
350
- } else {
351
- $this->parser->_add_token(PROPERTY, $property, true);
352
- $this->parser->_add_token(VALUE, $valj, true);
353
- }
354
- }
355
- }
356
- foreach ($invalid as $prefix => $props) {
357
- foreach ($props as $property => $valj) {
358
- $this->parser->_add_token(PROPERTY, $property, true);
359
- $this->parser->_add_token(VALUE, $valj, true);
360
- }
361
- }
362
- $this->parser->_add_token(SEL_END, $selector, true);
363
- }
364
-
365
- if (intval($medium) < DEFAULT_AT) {
366
- // un medium vide (contenant @font-face ou autre @) ne produit aucun conteneur
367
- if (strlen(trim($medium))) {
368
- $this->parser->_add_token(AT_END, $medium, true);
369
- }
370
- } elseif ($default_media) {
371
- $this->parser->_add_token(AT_END, $default_media, true);
372
- }
373
- }
374
- }
375
-
376
- /**
377
- * Same as htmlspecialchars, only that chars are not replaced if $plain !== true. This makes print_code() cleaner.
378
- * @param string $string
379
- * @param bool $plain
380
- * @return string
381
- * @see csstidy_print::_print()
382
- * @access private
383
- * @version 1.0
384
- */
385
- public function _htmlsp($string, $plain) {
386
- if (!$plain) {
387
- return htmlspecialchars($string, ENT_QUOTES, 'utf-8');
388
- }
389
- return $string;
390
- }
391
-
392
- /**
393
- * Get compression ratio
394
- * @access public
395
- * @return float
396
- * @version 1.2
397
- */
398
- public function get_ratio() {
399
- if (!$this->output_css_plain) {
400
- $this->formatted();
401
- }
402
- return round((strlen($this->input_css) - strlen($this->output_css_plain)) / strlen($this->input_css), 3) * 100;
403
- }
404
-
405
- /**
406
- * Get difference between the old and new code in bytes and prints the code if necessary.
407
- * @access public
408
- * @return string
409
- * @version 1.1
410
- */
411
- public function get_diff() {
412
- if (!$this->output_css_plain) {
413
- $this->formatted();
414
- }
415
-
416
- $diff = strlen($this->output_css_plain) - strlen($this->input_css);
417
-
418
- if ($diff > 0) {
419
- return '+' . $diff;
420
- } elseif ($diff == 0) {
421
- return '+-' . $diff;
422
- }
423
-
424
- return $diff;
425
- }
426
-
427
- /**
428
- * Get the size of either input or output CSS in KB
429
- * @param string $loc default is "output"
430
- * @access public
431
- * @return integer
432
- * @version 1.0
433
- */
434
- public function size($loc = 'output') {
435
- if ($loc === 'output' && !$this->output_css) {
436
- $this->formatted();
437
- }
438
-
439
- if ($loc === 'input') {
440
- return (strlen($this->input_css) / 1000);
441
- } else {
442
- return (strlen($this->output_css_plain) / 1000);
443
- }
444
- }
445
-
446
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
libs/CSSTidy/data.inc.php DELETED
@@ -1,646 +0,0 @@
1
- <?php
2
- /**
3
- * Various CSS Data for CSSTidy
4
- *
5
- * This file is part of CSSTidy.
6
- *
7
- * CSSTidy is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation; either version 2 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * CSSTidy is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with CSSTidy; if not, write to the Free Software
19
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
- *
21
- * @license http://opensource.org/licenses/gpl-license.php GNU Public License
22
- * @package csstidy
23
- * @author Florian Schmitz (floele at gmail dot com) 2005
24
- * @author Nikolay Matsievsky (speed at webo dot name) 2010
25
- */
26
-
27
- /**
28
- * All whitespace allowed in CSS
29
- *
30
- * @global array $data['csstidy']['whitespace']
31
- * @version 1.0
32
- */
33
- $data['csstidy']['whitespace'] = array(' ',"\n","\t","\r","\x0B");
34
-
35
- /**
36
- * All CSS tokens used by csstidy
37
- *
38
- * @global string $data['csstidy']['tokens']
39
- * @version 1.0
40
- */
41
- $data['csstidy']['tokens'] = '/@}{;:=\'"(,\\!$%&)*+.<>?[]^`|~';
42
-
43
- /**
44
- * All CSS units (CSS 3 units included)
45
- *
46
- * @see compress_numbers()
47
- * @global array $data['csstidy']['units']
48
- * @version 1.0
49
- */
50
- $data['csstidy']['units'] = array('in','cm','mm','pt','pc','px','rem','em','%','ex','gd','vw','vh','vm','deg','grad','rad','turn','ms','s','khz','hz','ch','vmin','vmax','dpi','dpcm','dppx');
51
-
52
- /**
53
- * Available at-rules
54
- *
55
- * @global array $data['csstidy']['at_rules']
56
- * @version 1.1
57
- */
58
- $data['csstidy']['at_rules'] = array('page' => 'is','font-face' => 'atis','charset' => 'iv', 'import' => 'iv','namespace' => 'iv','media' => 'at','keyframes' => 'at','-moz-keyframes' => 'at','-o-keyframes' => 'at','-webkit-keyframes' => 'at','-ms-keyframes' => 'at');
59
-
60
- /**
61
- * Properties that need a value with unit
62
- *
63
- * @todo CSS3 properties
64
- * @see compress_numbers();
65
- * @global array $data['csstidy']['unit_values']
66
- * @version 1.2
67
- */
68
- $data['csstidy']['unit_values'] = array ('background', 'background-position', 'background-size', 'border', 'border-top', 'border-right', 'border-bottom', 'border-left', 'border-width',
69
- 'border-top-width', 'border-right-width', 'border-left-width', 'border-bottom-width', 'bottom', 'border-spacing', 'column-gap', 'column-width',
70
- 'font-size', 'height', 'left', 'margin', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left', 'max-height',
71
- 'max-width', 'min-height', 'min-width', 'outline', 'outline-width', 'padding', 'padding-top', 'padding-right',
72
- 'padding-bottom', 'padding-left', 'perspective', 'right', 'top', 'text-indent', 'letter-spacing', 'word-spacing', 'width');
73
-
74
- /**
75
- * Properties that allow <color> as value
76
- *
77
- * @todo CSS3 properties
78
- * @see compress_numbers();
79
- * @global array $data['csstidy']['color_values']
80
- * @version 1.0
81
- */
82
- $data['csstidy']['color_values'] = array();
83
- $data['csstidy']['color_values'][] = 'background-color';
84
- $data['csstidy']['color_values'][] = 'border-color';
85
- $data['csstidy']['color_values'][] = 'border-top-color';
86
- $data['csstidy']['color_values'][] = 'border-right-color';
87
- $data['csstidy']['color_values'][] = 'border-bottom-color';
88
- $data['csstidy']['color_values'][] = 'border-left-color';
89
- $data['csstidy']['color_values'][] = 'color';
90
- $data['csstidy']['color_values'][] = 'outline-color';
91
- $data['csstidy']['color_values'][] = 'column-rule-color';
92
-
93
- /**
94
- * Default values for the background properties
95
- *
96
- * @todo Possibly property names will change during CSS3 development
97
- * @global array $data['csstidy']['background_prop_default']
98
- * @see dissolve_short_bg()
99
- * @see merge_bg()
100
- * @version 1.0
101
- */
102
- $data['csstidy']['background_prop_default'] = array();
103
- $data['csstidy']['background_prop_default']['background-image'] = 'none';
104
- $data['csstidy']['background_prop_default']['background-size'] = 'auto';
105
- $data['csstidy']['background_prop_default']['background-repeat'] = 'repeat';
106
- $data['csstidy']['background_prop_default']['background-position'] = '0 0';
107
- $data['csstidy']['background_prop_default']['background-attachment'] = 'scroll';
108
- $data['csstidy']['background_prop_default']['background-clip'] = 'border';
109
- $data['csstidy']['background_prop_default']['background-origin'] = 'padding';
110
- $data['csstidy']['background_prop_default']['background-color'] = 'transparent';
111
-
112
- /**
113
- * Default values for the font properties
114
- *
115
- * @global array $data['csstidy']['font_prop_default']
116
- * @see merge_fonts()
117
- * @version 1.3
118
- */
119
- $data['csstidy']['font_prop_default'] = array();
120
- $data['csstidy']['font_prop_default']['font-style'] = 'normal';
121
- $data['csstidy']['font_prop_default']['font-variant'] = 'normal';
122
- $data['csstidy']['font_prop_default']['font-weight'] = 'normal';
123
- $data['csstidy']['font_prop_default']['font-size'] = '';
124
- $data['csstidy']['font_prop_default']['line-height'] = '';
125
- $data['csstidy']['font_prop_default']['font-family'] = '';
126
-
127
- /**
128
- * A list of non-W3C color names which get replaced by their hex-codes
129
- *
130
- * @global array $data['csstidy']['replace_colors']
131
- * @see cut_color()
132
- * @version 1.0
133
- */
134
- $data['csstidy']['replace_colors'] = array();
135
- $data['csstidy']['replace_colors']['aliceblue'] = '#f0f8ff';
136
- $data['csstidy']['replace_colors']['antiquewhite'] = '#faebd7';
137
- $data['csstidy']['replace_colors']['aquamarine'] = '#7fffd4';
138
- $data['csstidy']['replace_colors']['azure'] = '#f0ffff';
139
- $data['csstidy']['replace_colors']['beige'] = '#f5f5dc';
140
- $data['csstidy']['replace_colors']['bisque'] = '#ffe4c4';
141
- $data['csstidy']['replace_colors']['blanchedalmond'] = '#ffebcd';
142
- $data['csstidy']['replace_colors']['blueviolet'] = '#8a2be2';
143
- $data['csstidy']['replace_colors']['brown'] = '#a52a2a';
144
- $data['csstidy']['replace_colors']['burlywood'] = '#deb887';
145
- $data['csstidy']['replace_colors']['cadetblue'] = '#5f9ea0';
146
- $data['csstidy']['replace_colors']['chartreuse'] = '#7fff00';
147
- $data['csstidy']['replace_colors']['chocolate'] = '#d2691e';
148
- $data['csstidy']['replace_colors']['coral'] = '#ff7f50';
149
- $data['csstidy']['replace_colors']['cornflowerblue'] = '#6495ed';
150
- $data['csstidy']['replace_colors']['cornsilk'] = '#fff8dc';
151
- $data['csstidy']['replace_colors']['crimson'] = '#dc143c';
152
- $data['csstidy']['replace_colors']['cyan'] = '#00ffff';
153
- $data['csstidy']['replace_colors']['darkblue'] = '#00008b';
154
- $data['csstidy']['replace_colors']['darkcyan'] = '#008b8b';
155
- $data['csstidy']['replace_colors']['darkgoldenrod'] = '#b8860b';
156
- $data['csstidy']['replace_colors']['darkgray'] = '#a9a9a9';
157
- $data['csstidy']['replace_colors']['darkgreen'] = '#006400';
158
- $data['csstidy']['replace_colors']['darkkhaki'] = '#bdb76b';
159
- $data['csstidy']['replace_colors']['darkmagenta'] = '#8b008b';
160
- $data['csstidy']['replace_colors']['darkolivegreen'] = '#556b2f';
161
- $data['csstidy']['replace_colors']['darkorange'] = '#ff8c00';
162
- $data['csstidy']['replace_colors']['darkorchid'] = '#9932cc';
163
- $data['csstidy']['replace_colors']['darkred'] = '#8b0000';
164
- $data['csstidy']['replace_colors']['darksalmon'] = '#e9967a';
165
- $data['csstidy']['replace_colors']['darkseagreen'] = '#8fbc8f';
166
- $data['csstidy']['replace_colors']['darkslateblue'] = '#483d8b';
167
- $data['csstidy']['replace_colors']['darkslategray'] = '#2f4f4f';
168
- $data['csstidy']['replace_colors']['darkturquoise'] = '#00ced1';
169
- $data['csstidy']['replace_colors']['darkviolet'] = '#9400d3';
170
- $data['csstidy']['replace_colors']['deeppink'] = '#ff1493';
171
- $data['csstidy']['replace_colors']['deepskyblue'] = '#00bfff';
172
- $data['csstidy']['replace_colors']['dimgray'] = '#696969';
173
- $data['csstidy']['replace_colors']['dodgerblue'] = '#1e90ff';
174
- $data['csstidy']['replace_colors']['feldspar'] = '#d19275';
175
- $data['csstidy']['replace_colors']['firebrick'] = '#b22222';
176
- $data['csstidy']['replace_colors']['floralwhite'] = '#fffaf0';
177
- $data['csstidy']['replace_colors']['forestgreen'] = '#228b22';
178
- $data['csstidy']['replace_colors']['gainsboro'] = '#dcdcdc';
179
- $data['csstidy']['replace_colors']['ghostwhite'] = '#f8f8ff';
180
- $data['csstidy']['replace_colors']['gold'] = '#ffd700';
181
- $data['csstidy']['replace_colors']['goldenrod'] = '#daa520';
182
- $data['csstidy']['replace_colors']['greenyellow'] = '#adff2f';
183
- $data['csstidy']['replace_colors']['honeydew'] = '#f0fff0';
184
- $data['csstidy']['replace_colors']['hotpink'] = '#ff69b4';
185
- $data['csstidy']['replace_colors']['indianred'] = '#cd5c5c';
186
- $data['csstidy']['replace_colors']['indigo'] = '#4b0082';
187
- $data['csstidy']['replace_colors']['ivory'] = '#fffff0';
188
- $data['csstidy']['replace_colors']['khaki'] = '#f0e68c';
189
- $data['csstidy']['replace_colors']['lavender'] = '#e6e6fa';
190
- $data['csstidy']['replace_colors']['lavenderblush'] = '#fff0f5';
191
- $data['csstidy']['replace_colors']['lawngreen'] = '#7cfc00';
192
- $data['csstidy']['replace_colors']['lemonchiffon'] = '#fffacd';
193
- $data['csstidy']['replace_colors']['lightblue'] = '#add8e6';
194
- $data['csstidy']['replace_colors']['lightcoral'] = '#f08080';
195
- $data['csstidy']['replace_colors']['lightcyan'] = '#e0ffff';
196
- $data['csstidy']['replace_colors']['lightgoldenrodyellow'] = '#fafad2';
197
- $data['csstidy']['replace_colors']['lightgrey'] = '#d3d3d3';
198
- $data['csstidy']['replace_colors']['lightgreen'] = '#90ee90';
199
- $data['csstidy']['replace_colors']['lightpink'] = '#ffb6c1';
200
- $data['csstidy']['replace_colors']['lightsalmon'] = '#ffa07a';
201
- $data['csstidy']['replace_colors']['lightseagreen'] = '#20b2aa';
202
- $data['csstidy']['replace_colors']['lightskyblue'] = '#87cefa';
203
- $data['csstidy']['replace_colors']['lightslateblue'] = '#8470ff';
204
- $data['csstidy']['replace_colors']['lightslategray'] = '#778899';
205
- $data['csstidy']['replace_colors']['lightsteelblue'] = '#b0c4de';
206
- $data['csstidy']['replace_colors']['lightyellow'] = '#ffffe0';
207
- $data['csstidy']['replace_colors']['limegreen'] = '#32cd32';
208
- $data['csstidy']['replace_colors']['linen'] = '#faf0e6';
209
- $data['csstidy']['replace_colors']['magenta'] = '#ff00ff';
210
- $data['csstidy']['replace_colors']['mediumaquamarine'] = '#66cdaa';
211
- $data['csstidy']['replace_colors']['mediumblue'] = '#0000cd';
212
- $data['csstidy']['replace_colors']['mediumorchid'] = '#ba55d3';
213
- $data['csstidy']['replace_colors']['mediumpurple'] = '#9370d8';
214
- $data['csstidy']['replace_colors']['mediumseagreen'] = '#3cb371';
215
- $data['csstidy']['replace_colors']['mediumslateblue'] = '#7b68ee';
216
- $data['csstidy']['replace_colors']['mediumspringgreen'] = '#00fa9a';
217
- $data['csstidy']['replace_colors']['mediumturquoise'] = '#48d1cc';
218
- $data['csstidy']['replace_colors']['mediumvioletred'] = '#c71585';
219
- $data['csstidy']['replace_colors']['midnightblue'] = '#191970';
220
- $data['csstidy']['replace_colors']['mintcream'] = '#f5fffa';
221
- $data['csstidy']['replace_colors']['mistyrose'] = '#ffe4e1';
222
- $data['csstidy']['replace_colors']['moccasin'] = '#ffe4b5';
223
- $data['csstidy']['replace_colors']['navajowhite'] = '#ffdead';
224
- $data['csstidy']['replace_colors']['oldlace'] = '#fdf5e6';
225
- $data['csstidy']['replace_colors']['olivedrab'] = '#6b8e23';
226
- $data['csstidy']['replace_colors']['orangered'] = '#ff4500';
227
- $data['csstidy']['replace_colors']['orchid'] = '#da70d6';
228
- $data['csstidy']['replace_colors']['palegoldenrod'] = '#eee8aa';
229
- $data['csstidy']['replace_colors']['palegreen'] = '#98fb98';
230
- $data['csstidy']['replace_colors']['paleturquoise'] = '#afeeee';
231
- $data['csstidy']['replace_colors']['palevioletred'] = '#d87093';
232
- $data['csstidy']['replace_colors']['papayawhip'] = '#ffefd5';
233
- $data['csstidy']['replace_colors']['peachpuff'] = '#ffdab9';
234
- $data['csstidy']['replace_colors']['peru'] = '#cd853f';
235
- $data['csstidy']['replace_colors']['pink'] = '#ffc0cb';
236
- $data['csstidy']['replace_colors']['plum'] = '#dda0dd';
237
- $data['csstidy']['replace_colors']['powderblue'] = '#b0e0e6';
238
- $data['csstidy']['replace_colors']['rosybrown'] = '#bc8f8f';
239
- $data['csstidy']['replace_colors']['royalblue'] = '#4169e1';
240
- $data['csstidy']['replace_colors']['saddlebrown'] = '#8b4513';
241
- $data['csstidy']['replace_colors']['salmon'] = '#fa8072';
242
- $data['csstidy']['replace_colors']['sandybrown'] = '#f4a460';
243
- $data['csstidy']['replace_colors']['seagreen'] = '#2e8b57';
244
- $data['csstidy']['replace_colors']['seashell'] = '#fff5ee';
245
- $data['csstidy']['replace_colors']['sienna'] = '#a0522d';
246
- $data['csstidy']['replace_colors']['skyblue'] = '#87ceeb';
247
- $data['csstidy']['replace_colors']['slateblue'] = '#6a5acd';
248
- $data['csstidy']['replace_colors']['slategray'] = '#708090';
249
- $data['csstidy']['replace_colors']['snow'] = '#fffafa';
250
- $data['csstidy']['replace_colors']['springgreen'] = '#00ff7f';
251
- $data['csstidy']['replace_colors']['steelblue'] = '#4682b4';
252
- $data['csstidy']['replace_colors']['tan'] = '#d2b48c';
253
- $data['csstidy']['replace_colors']['thistle'] = '#d8bfd8';
254
- $data['csstidy']['replace_colors']['tomato'] = '#ff6347';
255
- $data['csstidy']['replace_colors']['turquoise'] = '#40e0d0';
256
- $data['csstidy']['replace_colors']['violet'] = '#ee82ee';
257
- $data['csstidy']['replace_colors']['violetred'] = '#d02090';
258
- $data['csstidy']['replace_colors']['wheat'] = '#f5deb3';
259
- $data['csstidy']['replace_colors']['whitesmoke'] = '#f5f5f5';
260
- $data['csstidy']['replace_colors']['yellowgreen'] = '#9acd32';
261
-
262
- /**
263
- * A list of all shorthand properties that are devided into four properties and/or have four subvalues
264
- *
265
- * @global array $data['csstidy']['shorthands']
266
- * @todo Are there new ones in CSS3?
267
- * @see dissolve_4value_shorthands()
268
- * @see merge_4value_shorthands()
269
- * @version 1.0
270
- */
271
- $data['csstidy']['shorthands'] = array();
272
- $data['csstidy']['shorthands']['border-color'] = array('border-top-color','border-right-color','border-bottom-color','border-left-color');
273
- $data['csstidy']['shorthands']['border-style'] = array('border-top-style','border-right-style','border-bottom-style','border-left-style');
274
- $data['csstidy']['shorthands']['border-width'] = array('border-top-width','border-right-width','border-bottom-width','border-left-width');
275
- $data['csstidy']['shorthands']['margin'] = array('margin-top','margin-right','margin-bottom','margin-left');
276
- $data['csstidy']['shorthands']['padding'] = array('padding-top','padding-right','padding-bottom','padding-left');
277
- $data['csstidy']['shorthands']['-moz-border-radius'] = 0;
278
-
279
- /**
280
- * All CSS Properties. Needed for csstidy::property_is_next()
281
- *
282
- * @global array $data['csstidy']['all_properties']
283
- * @version 1.1
284
- * @see csstidy::property_is_next()
285
- */
286
- $data['csstidy']['all_properties']['alignment-adjust'] = 'CSS3.0';
287
- $data['csstidy']['all_properties']['alignment-baseline'] = 'CSS3.0';
288
- $data['csstidy']['all_properties']['animation'] = 'CSS3.0';
289
- $data['csstidy']['all_properties']['animation-delay'] = 'CSS3.0';
290
- $data['csstidy']['all_properties']['animation-direction'] = 'CSS3.0';
291
- $data['csstidy']['all_properties']['animation-duration'] = 'CSS3.0';
292
- $data['csstidy']['all_properties']['animation-iteration-count'] = 'CSS3.0';
293
- $data['csstidy']['all_properties']['animation-name'] = 'CSS3.0';
294
- $data['csstidy']['all_properties']['animation-play-state'] = 'CSS3.0';
295
- $data['csstidy']['all_properties']['animation-timing-function'] = 'CSS3.0';
296
- $data['csstidy']['all_properties']['appearance'] = 'CSS3.0';
297
- $data['csstidy']['all_properties']['azimuth'] = 'CSS2.0,CSS2.1,CSS3.0';
298
- $data['csstidy']['all_properties']['backface-visibility'] = 'CSS3.0';
299
- $data['csstidy']['all_properties']['background'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
300
- $data['csstidy']['all_properties']['background-attachment'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
301
- $data['csstidy']['all_properties']['background-clip'] = 'CSS3.0';
302
- $data['csstidy']['all_properties']['background-color'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
303
- $data['csstidy']['all_properties']['background-image'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
304
- $data['csstidy']['all_properties']['background-origin'] = 'CSS3.0';
305
- $data['csstidy']['all_properties']['background-position'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
306
- $data['csstidy']['all_properties']['background-repeat'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
307
- $data['csstidy']['all_properties']['background-size'] = 'CSS3.0';
308
- $data['csstidy']['all_properties']['baseline-shift'] = 'CSS3.0';
309
- $data['csstidy']['all_properties']['binding'] = 'CSS3.0';
310
- $data['csstidy']['all_properties']['bleed'] = 'CSS3.0';
311
- $data['csstidy']['all_properties']['bookmark-label'] = 'CSS3.0';
312
- $data['csstidy']['all_properties']['bookmark-level'] = 'CSS3.0';
313
- $data['csstidy']['all_properties']['bookmark-state'] = 'CSS3.0';
314
- $data['csstidy']['all_properties']['bookmark-target'] = 'CSS3.0';
315
- $data['csstidy']['all_properties']['border'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
316
- $data['csstidy']['all_properties']['border-bottom'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
317
- $data['csstidy']['all_properties']['border-bottom-color'] = 'CSS2.0,CSS2.1,CSS3.0';
318
- $data['csstidy']['all_properties']['border-bottom-left-radius'] = 'CSS3.0';
319
- $data['csstidy']['all_properties']['border-bottom-right-radius'] = 'CSS3.0';
320
- $data['csstidy']['all_properties']['border-bottom-style'] = 'CSS2.0,CSS2.1,CSS3.0';
321
- $data['csstidy']['all_properties']['border-bottom-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
322
- $data['csstidy']['all_properties']['border-collapse'] = 'CSS2.0,CSS2.1,CSS3.0';
323
- $data['csstidy']['all_properties']['border-color'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
324
- $data['csstidy']['all_properties']['border-image'] = 'CSS3.0';
325
- $data['csstidy']['all_properties']['border-image-outset'] = 'CSS3.0';
326
- $data['csstidy']['all_properties']['border-image-repeat'] = 'CSS3.0';
327
- $data['csstidy']['all_properties']['border-image-slice'] = 'CSS3.0';
328
- $data['csstidy']['all_properties']['border-image-source'] = 'CSS3.0';
329
- $data['csstidy']['all_properties']['border-image-width'] = 'CSS3.0';
330
- $data['csstidy']['all_properties']['border-left'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
331
- $data['csstidy']['all_properties']['border-left-color'] = 'CSS2.0,CSS2.1,CSS3.0';
332
- $data['csstidy']['all_properties']['border-left-style'] = 'CSS2.0,CSS2.1,CSS3.0';
333
- $data['csstidy']['all_properties']['border-left-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
334
- $data['csstidy']['all_properties']['border-radius'] = 'CSS3.0';
335
- $data['csstidy']['all_properties']['border-right'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
336
- $data['csstidy']['all_properties']['border-right-color'] = 'CSS2.0,CSS2.1,CSS3.0';
337
- $data['csstidy']['all_properties']['border-right-style'] = 'CSS2.0,CSS2.1,CSS3.0';
338
- $data['csstidy']['all_properties']['border-right-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
339
- $data['csstidy']['all_properties']['border-spacing'] = 'CSS2.0,CSS2.1,CSS3.0';
340
- $data['csstidy']['all_properties']['border-style'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
341
- $data['csstidy']['all_properties']['border-top'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
342
- $data['csstidy']['all_properties']['border-top-color'] = 'CSS2.0,CSS2.1,CSS3.0';
343
- $data['csstidy']['all_properties']['border-top-left-radius'] = 'CSS3.0';
344
- $data['csstidy']['all_properties']['border-top-right-radius'] = 'CSS3.0';
345
- $data['csstidy']['all_properties']['border-top-style'] = 'CSS2.0,CSS2.1,CSS3.0';
346
- $data['csstidy']['all_properties']['border-top-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
347
- $data['csstidy']['all_properties']['border-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
348
- $data['csstidy']['all_properties']['bottom'] = 'CSS2.0,CSS2.1,CSS3.0';
349
- $data['csstidy']['all_properties']['box-decoration-break'] = 'CSS3.0';
350
- $data['csstidy']['all_properties']['box-shadow'] = 'CSS3.0';
351
- $data['csstidy']['all_properties']['box-sizing'] = 'CSS3.0';
352
- $data['csstidy']['all_properties']['break-after'] = 'CSS3.0';
353
- $data['csstidy']['all_properties']['break-before'] = 'CSS3.0';
354
- $data['csstidy']['all_properties']['break-inside'] = 'CSS3.0';
355
- $data['csstidy']['all_properties']['caption-side'] = 'CSS2.0,CSS2.1,CSS3.0';
356
- $data['csstidy']['all_properties']['clear'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
357
- $data['csstidy']['all_properties']['clip'] = 'CSS2.0,CSS2.1,CSS3.0';
358
- $data['csstidy']['all_properties']['color'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
359
- $data['csstidy']['all_properties']['color-profile'] = 'CSS3.0';
360
- $data['csstidy']['all_properties']['column-count'] = 'CSS3.0';
361
- $data['csstidy']['all_properties']['column-fill'] = 'CSS3.0';
362
- $data['csstidy']['all_properties']['column-gap'] = 'CSS3.0';
363
- $data['csstidy']['all_properties']['column-rule'] = 'CSS3.0';
364
- $data['csstidy']['all_properties']['column-rule-color'] = 'CSS3.0';
365
- $data['csstidy']['all_properties']['column-rule-style'] = 'CSS3.0';
366
- $data['csstidy']['all_properties']['column-rule-width'] = 'CSS3.0';
367
- $data['csstidy']['all_properties']['column-span'] = 'CSS3.0';
368
- $data['csstidy']['all_properties']['column-width'] = 'CSS3.0';
369
- $data['csstidy']['all_properties']['columns'] = 'CSS3.0';
370
- $data['csstidy']['all_properties']['content'] = 'CSS2.0,CSS2.1,CSS3.0';
371
- $data['csstidy']['all_properties']['counter-increment'] = 'CSS2.0,CSS2.1,CSS3.0';
372
- $data['csstidy']['all_properties']['counter-reset'] = 'CSS2.0,CSS2.1,CSS3.0';
373
- $data['csstidy']['all_properties']['crop'] = 'CSS3.0';
374
- $data['csstidy']['all_properties']['cue'] = 'CSS2.0,CSS2.1,CSS3.0';
375
- $data['csstidy']['all_properties']['cue-after'] = 'CSS2.0,CSS2.1,CSS3.0';
376
- $data['csstidy']['all_properties']['cue-before'] = 'CSS2.0,CSS2.1,CSS3.0';
377
- $data['csstidy']['all_properties']['cursor'] = 'CSS2.0,CSS2.1,CSS3.0';
378
- $data['csstidy']['all_properties']['direction'] = 'CSS2.0,CSS2.1,CSS3.0';
379
- $data['csstidy']['all_properties']['display'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
380
- $data['csstidy']['all_properties']['dominant-baseline'] = 'CSS3.0';
381
- $data['csstidy']['all_properties']['drop-initial-after-adjust'] = 'CSS3.0';
382
- $data['csstidy']['all_properties']['drop-initial-after-align'] = 'CSS3.0';
383
- $data['csstidy']['all_properties']['drop-initial-before-adjust'] = 'CSS3.0';
384
- $data['csstidy']['all_properties']['drop-initial-before-align'] = 'CSS3.0';
385
- $data['csstidy']['all_properties']['drop-initial-size'] = 'CSS3.0';
386
- $data['csstidy']['all_properties']['drop-initial-value'] = 'CSS3.0';
387
- $data['csstidy']['all_properties']['elevation'] = 'CSS2.0,CSS2.1,CSS3.0';
388
- $data['csstidy']['all_properties']['empty-cells'] = 'CSS2.0,CSS2.1,CSS3.0';
389
- $data['csstidy']['all_properties']['fit'] = 'CSS3.0';
390
- $data['csstidy']['all_properties']['fit-position'] = 'CSS3.0';
391
- $data['csstidy']['all_properties']['flex-align'] = 'CSS3.0';
392
- $data['csstidy']['all_properties']['flex-flow'] = 'CSS3.0';
393
- $data['csstidy']['all_properties']['flex-line-pack'] = 'CSS3.0';
394
- $data['csstidy']['all_properties']['flex-order'] = 'CSS3.0';
395
- $data['csstidy']['all_properties']['flex-pack'] = 'CSS3.0';
396
- $data['csstidy']['all_properties']['float'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
397
- $data['csstidy']['all_properties']['float-offset'] = 'CSS3.0';
398
- $data['csstidy']['all_properties']['font'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
399
- $data['csstidy']['all_properties']['font-family'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
400
- $data['csstidy']['all_properties']['font-size'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
401
- $data['csstidy']['all_properties']['font-size-adjust'] = 'CSS2.0,CSS3.0';
402
- $data['csstidy']['all_properties']['font-stretch'] = 'CSS2.0,CSS3.0';
403
- $data['csstidy']['all_properties']['font-style'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
404
- $data['csstidy']['all_properties']['font-variant'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
405
- $data['csstidy']['all_properties']['font-weight'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
406
- $data['csstidy']['all_properties']['grid-columns'] = 'CSS3.0';
407
- $data['csstidy']['all_properties']['grid-rows'] = 'CSS3.0';
408
- $data['csstidy']['all_properties']['hanging-punctuation'] = 'CSS3.0';
409
- $data['csstidy']['all_properties']['height'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
410
- $data['csstidy']['all_properties']['hyphenate-after'] = 'CSS3.0';
411
- $data['csstidy']['all_properties']['hyphenate-before'] = 'CSS3.0';
412
- $data['csstidy']['all_properties']['hyphenate-character'] = 'CSS3.0';
413
- $data['csstidy']['all_properties']['hyphenate-lines'] = 'CSS3.0';
414
- $data['csstidy']['all_properties']['hyphenate-resource'] = 'CSS3.0';
415
- $data['csstidy']['all_properties']['hyphens'] = 'CSS3.0';
416
- $data['csstidy']['all_properties']['icon'] = 'CSS3.0';
417
- $data['csstidy']['all_properties']['image-orientation'] = 'CSS3.0';
418
- $data['csstidy']['all_properties']['image-rendering'] = 'CSS3.0';
419
- $data['csstidy']['all_properties']['image-resolution'] = 'CSS3.0';
420
- $data['csstidy']['all_properties']['inline-box-align'] = 'CSS3.0';
421
- $data['csstidy']['all_properties']['left'] = 'CSS2.0,CSS2.1,CSS3.0';
422
- $data['csstidy']['all_properties']['letter-spacing'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
423
- $data['csstidy']['all_properties']['line-break'] = 'CSS3.0';
424
- $data['csstidy']['all_properties']['line-height'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
425
- $data['csstidy']['all_properties']['line-stacking'] = 'CSS3.0';
426
- $data['csstidy']['all_properties']['line-stacking-ruby'] = 'CSS3.0';
427
- $data['csstidy']['all_properties']['line-stacking-shift'] = 'CSS3.0';
428
- $data['csstidy']['all_properties']['line-stacking-strategy'] = 'CSS3.0';
429
- $data['csstidy']['all_properties']['list-style'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
430
- $data['csstidy']['all_properties']['list-style-image'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
431
- $data['csstidy']['all_properties']['list-style-position'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
432
- $data['csstidy']['all_properties']['list-style-type'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
433
- $data['csstidy']['all_properties']['margin'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
434
- $data['csstidy']['all_properties']['margin-bottom'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
435
- $data['csstidy']['all_properties']['margin-left'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
436
- $data['csstidy']['all_properties']['margin-right'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
437
- $data['csstidy']['all_properties']['margin-top'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
438
- $data['csstidy']['all_properties']['marker-offset'] = 'CSS2.0,CSS3.0';
439
- $data['csstidy']['all_properties']['marks'] = 'CSS2.0,CSS3.0';
440
- $data['csstidy']['all_properties']['marquee-direction'] = 'CSS3.0';
441
- $data['csstidy']['all_properties']['marquee-loop'] = 'CSS3.0';
442
- $data['csstidy']['all_properties']['marquee-play-count'] = 'CSS3.0';
443
- $data['csstidy']['all_properties']['marquee-speed'] = 'CSS3.0';
444
- $data['csstidy']['all_properties']['marquee-style'] = 'CSS3.0';
445
- $data['csstidy']['all_properties']['max-height'] = 'CSS2.0,CSS2.1,CSS3.0';
446
- $data['csstidy']['all_properties']['max-width'] = 'CSS2.0,CSS2.1,CSS3.0';
447
- $data['csstidy']['all_properties']['min-height'] = 'CSS2.0,CSS2.1,CSS3.0';
448
- $data['csstidy']['all_properties']['min-width'] = 'CSS2.0,CSS2.1,CSS3.0';
449
- $data['csstidy']['all_properties']['move-to'] = 'CSS3.0';
450
- $data['csstidy']['all_properties']['nav-down'] = 'CSS3.0';
451
- $data['csstidy']['all_properties']['nav-index'] = 'CSS3.0';
452
- $data['csstidy']['all_properties']['nav-left'] = 'CSS3.0';
453
- $data['csstidy']['all_properties']['nav-right'] = 'CSS3.0';
454
- $data['csstidy']['all_properties']['nav-up'] = 'CSS3.0';
455
- $data['csstidy']['all_properties']['opacity'] = 'CSS3.0';
456
- $data['csstidy']['all_properties']['orphans'] = 'CSS2.0,CSS2.1,CSS3.0';
457
- $data['csstidy']['all_properties']['outline'] = 'CSS2.0,CSS2.1,CSS3.0';
458
- $data['csstidy']['all_properties']['outline-color'] = 'CSS2.0,CSS2.1,CSS3.0';
459
- $data['csstidy']['all_properties']['outline-offset'] = 'CSS3.0';
460
- $data['csstidy']['all_properties']['outline-style'] = 'CSS2.0,CSS2.1,CSS3.0';
461
- $data['csstidy']['all_properties']['outline-width'] = 'CSS2.0,CSS2.1,CSS3.0';
462
- $data['csstidy']['all_properties']['overflow'] = 'CSS2.0,CSS2.1,CSS3.0';
463
- $data['csstidy']['all_properties']['overflow-style'] = 'CSS3.0';
464
- $data['csstidy']['all_properties']['overflow-wrap'] = 'CSS3.0';
465
- $data['csstidy']['all_properties']['overflow-x'] = 'CSS3.0';
466
- $data['csstidy']['all_properties']['overflow-y'] = 'CSS3.0';
467
- $data['csstidy']['all_properties']['padding'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
468
- $data['csstidy']['all_properties']['padding-bottom'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
469
- $data['csstidy']['all_properties']['padding-left'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
470
- $data['csstidy']['all_properties']['padding-right'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
471
- $data['csstidy']['all_properties']['padding-top'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
472
- $data['csstidy']['all_properties']['page'] = 'CSS2.0,CSS3.0';
473
- $data['csstidy']['all_properties']['page-break-after'] = 'CSS2.0,CSS2.1,CSS3.0';
474
- $data['csstidy']['all_properties']['page-break-before'] = 'CSS2.0,CSS2.1,CSS3.0';
475
- $data['csstidy']['all_properties']['page-break-inside'] = 'CSS2.0,CSS2.1,CSS3.0';
476
- $data['csstidy']['all_properties']['page-policy'] = 'CSS3.0';
477
- $data['csstidy']['all_properties']['pause'] = 'CSS2.0,CSS2.1,CSS3.0';
478
- $data['csstidy']['all_properties']['pause-after'] = 'CSS2.0,CSS2.1,CSS3.0';
479
- $data['csstidy']['all_properties']['pause-before'] = 'CSS2.0,CSS2.1,CSS3.0';
480
- $data['csstidy']['all_properties']['perspective'] = 'CSS3.0';
481
- $data['csstidy']['all_properties']['perspective-origin'] = 'CSS3.0';
482
- $data['csstidy']['all_properties']['phonemes'] = 'CSS3.0';
483
- $data['csstidy']['all_properties']['pitch'] = 'CSS2.0,CSS2.1,CSS3.0';
484
- $data['csstidy']['all_properties']['pitch-range'] = 'CSS2.0,CSS2.1,CSS3.0';
485
- $data['csstidy']['all_properties']['play-during'] = 'CSS2.0,CSS2.1,CSS3.0';
486
- $data['csstidy']['all_properties']['position'] = 'CSS2.0,CSS2.1,CSS3.0';
487
- $data['csstidy']['all_properties']['presentation-level'] = 'CSS3.0';
488
- $data['csstidy']['all_properties']['punctuation-trim'] = 'CSS3.0';
489
- $data['csstidy']['all_properties']['quotes'] = 'CSS2.0,CSS2.1,CSS3.0';
490
- $data['csstidy']['all_properties']['rendering-intent'] = 'CSS3.0';
491
- $data['csstidy']['all_properties']['resize'] = 'CSS3.0';
492
- $data['csstidy']['all_properties']['rest'] = 'CSS3.0';
493
- $data['csstidy']['all_properties']['rest-after'] = 'CSS3.0';
494
- $data['csstidy']['all_properties']['rest-before'] = 'CSS3.0';
495
- $data['csstidy']['all_properties']['richness'] = 'CSS2.0,CSS2.1,CSS3.0';
496
- $data['csstidy']['all_properties']['right'] = 'CSS2.0,CSS2.1,CSS3.0';
497
- $data['csstidy']['all_properties']['rotation'] = 'CSS3.0';
498
- $data['csstidy']['all_properties']['rotation-point'] = 'CSS3.0';
499
- $data['csstidy']['all_properties']['ruby-align'] = 'CSS3.0';
500
- $data['csstidy']['all_properties']['ruby-overhang'] = 'CSS3.0';
501
- $data['csstidy']['all_properties']['ruby-position'] = 'CSS3.0';
502
- $data['csstidy']['all_properties']['ruby-span'] = 'CSS3.0';
503
- $data['csstidy']['all_properties']['size'] = 'CSS2.0,CSS3.0';
504
- $data['csstidy']['all_properties']['speak'] = 'CSS2.0,CSS2.1,CSS3.0';
505
- $data['csstidy']['all_properties']['speak-header'] = 'CSS2.0,CSS2.1,CSS3.0';
506
- $data['csstidy']['all_properties']['speak-numeral'] = 'CSS2.0,CSS2.1,CSS3.0';
507
- $data['csstidy']['all_properties']['speak-punctuation'] = 'CSS2.0,CSS2.1,CSS3.0';
508
- $data['csstidy']['all_properties']['speech-rate'] = 'CSS2.0,CSS2.1,CSS3.0';
509
- $data['csstidy']['all_properties']['src'] = 'CSS3.0';
510
- $data['csstidy']['all_properties']['stress'] = 'CSS2.0,CSS2.1,CSS3.0';
511
- $data['csstidy']['all_properties']['string-set'] = 'CSS3.0';
512
- $data['csstidy']['all_properties']['tab-size'] = 'CSS3.0';
513
- $data['csstidy']['all_properties']['table-layout'] = 'CSS2.0,CSS2.1,CSS3.0';
514
- $data['csstidy']['all_properties']['target'] = 'CSS3.0';
515
- $data['csstidy']['all_properties']['target-name'] = 'CSS3.0';
516
- $data['csstidy']['all_properties']['target-new'] = 'CSS3.0';
517
- $data['csstidy']['all_properties']['target-position'] = 'CSS3.0';
518
- $data['csstidy']['all_properties']['text-align'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
519
- $data['csstidy']['all_properties']['text-align-last'] = 'CSS3.0';
520
- $data['csstidy']['all_properties']['text-decoration'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
521
- $data['csstidy']['all_properties']['text-decoration-color'] = 'CSS3.0';
522
- $data['csstidy']['all_properties']['text-decoration-line'] = 'CSS3.0';
523
- $data['csstidy']['all_properties']['text-decoration-skip'] = 'CSS3.0';
524
- $data['csstidy']['all_properties']['text-decoration-style'] = 'CSS3.0';
525
- $data['csstidy']['all_properties']['text-emphasis'] = 'CSS3.0';
526
- $data['csstidy']['all_properties']['text-emphasis-color'] = 'CSS3.0';
527
- $data['csstidy']['all_properties']['text-emphasis-position'] = 'CSS3.0';
528
- $data['csstidy']['all_properties']['text-emphasis-style'] = 'CSS3.0';
529
- $data['csstidy']['all_properties']['text-height'] = 'CSS3.0';
530
- $data['csstidy']['all_properties']['text-indent'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
531
- $data['csstidy']['all_properties']['text-justify'] = 'CSS3.0';
532
- $data['csstidy']['all_properties']['text-outline'] = 'CSS3.0';
533
- $data['csstidy']['all_properties']['text-shadow'] = 'CSS2.0,CSS3.0';
534
- $data['csstidy']['all_properties']['text-space-collapse'] = 'CSS3.0';
535
- $data['csstidy']['all_properties']['text-transform'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
536
- $data['csstidy']['all_properties']['text-underline-position'] = 'CSS3.0';
537
- $data['csstidy']['all_properties']['text-wrap'] = 'CSS3.0';
538
- $data['csstidy']['all_properties']['top'] = 'CSS2.0,CSS2.1,CSS3.0';
539
- $data['csstidy']['all_properties']['transform'] = 'CSS3.0';
540
- $data['csstidy']['all_properties']['transform-origin'] = 'CSS3.0';
541
- $data['csstidy']['all_properties']['transform-style'] = 'CSS3.0';
542
- $data['csstidy']['all_properties']['transition'] = 'CSS3.0';
543
- $data['csstidy']['all_properties']['transition-delay'] = 'CSS3.0';
544
- $data['csstidy']['all_properties']['transition-duration'] = 'CSS3.0';
545
- $data['csstidy']['all_properties']['transition-property'] = 'CSS3.0';
546
- $data['csstidy']['all_properties']['transition-timing-function'] = 'CSS3.0';
547
- $data['csstidy']['all_properties']['unicode-bidi'] = 'CSS2.0,CSS2.1,CSS3.0';
548
- $data['csstidy']['all_properties']['vertical-align'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
549
- $data['csstidy']['all_properties']['visibility'] = 'CSS2.0,CSS2.1,CSS3.0';
550
- $data['csstidy']['all_properties']['voice-balance'] = 'CSS3.0';
551
- $data['csstidy']['all_properties']['voice-duration'] = 'CSS3.0';
552
- $data['csstidy']['all_properties']['voice-family'] = 'CSS2.0,CSS2.1,CSS3.0';
553
- $data['csstidy']['all_properties']['voice-pitch'] = 'CSS3.0';
554
- $data['csstidy']['all_properties']['voice-pitch-range'] = 'CSS3.0';
555
- $data['csstidy']['all_properties']['voice-rate'] = 'CSS3.0';
556
- $data['csstidy']['all_properties']['voice-stress'] = 'CSS3.0';
557
- $data['csstidy']['all_properties']['voice-volume'] = 'CSS3.0';
558
- $data['csstidy']['all_properties']['volume'] = 'CSS2.0,CSS2.1,CSS3.0';
559
- $data['csstidy']['all_properties']['white-space'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
560
- $data['csstidy']['all_properties']['widows'] = 'CSS2.0,CSS2.1,CSS3.0';
561
- $data['csstidy']['all_properties']['width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
562
- $data['csstidy']['all_properties']['word-break'] = 'CSS3.0';
563
- $data['csstidy']['all_properties']['word-spacing'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
564
- $data['csstidy']['all_properties']['word-wrap'] = 'CSS3.0';
565
- $data['csstidy']['all_properties']['z-index'] = 'CSS2.0,CSS2.1,CSS3.0';
566
-
567
- /**
568
- * An array containing all properties that can accept a quoted string as a value.
569
- *
570
- * @global array $data['csstidy']['quoted_string_properties']
571
- */
572
- $data['csstidy']['quoted_string_properties'] = array('content', 'font-family', 'quotes');
573
-
574
- /**
575
- * An array containing all properties that can be defined multiple times without being overwritten.
576
- *
577
- * @global array $data['csstidy']['quoted_string_properties']
578
- */
579
- $data['csstidy']['multiple_properties'] = array('background', 'background-image');
580
-
581
- /**
582
- * An array containing all predefined templates.
583
- *
584
- * @global array $data['csstidy']['predefined_templates']
585
- * @version 1.0
586
- * @see csstidy::load_template()
587
- */
588
- $data['csstidy']['predefined_templates']['default'][] = '<span class="at">'; //string before @rule
589
- $data['csstidy']['predefined_templates']['default'][] = '</span> <span class="format">{</span>'."\n"; //bracket after @-rule
590
- $data['csstidy']['predefined_templates']['default'][] = '<span class="selector">'; //string before selector
591
- $data['csstidy']['predefined_templates']['default'][] = '</span> <span class="format">{</span>'."\n"; //bracket after selector
592
- $data['csstidy']['predefined_templates']['default'][] = '<span class="property">'; //string before property
593
- $data['csstidy']['predefined_templates']['default'][] = '</span><span class="value">'; //string after property+before value
594
- $data['csstidy']['predefined_templates']['default'][] = '</span><span class="format">;</span>'."\n"; //string after value
595
- $data['csstidy']['predefined_templates']['default'][] = '<span class="format">}</span>'; //closing bracket - selector
596
- $data['csstidy']['predefined_templates']['default'][] = "\n\n"; //space between blocks {...}
597
- $data['csstidy']['predefined_templates']['default'][] = "\n".'<span class="format">}</span>'. "\n\n"; //closing bracket @-rule
598
- $data['csstidy']['predefined_templates']['default'][] = ''; //indent in @-rule
599
- $data['csstidy']['predefined_templates']['default'][] = '<span class="comment">'; // before comment
600
- $data['csstidy']['predefined_templates']['default'][] = '</span>'."\n"; // after comment
601
- $data['csstidy']['predefined_templates']['default'][] = "\n"; // after each line @-rule
602
-
603
- $data['csstidy']['predefined_templates']['high_compression'][] = '<span class="at">';
604
- $data['csstidy']['predefined_templates']['high_compression'][] = '</span> <span class="format">{</span>'."\n";
605
- $data['csstidy']['predefined_templates']['high_compression'][] = '<span class="selector">';
606
- $data['csstidy']['predefined_templates']['high_compression'][] = '</span><span class="format">{</span>';
607
- $data['csstidy']['predefined_templates']['high_compression'][] = '<span class="property">';
608
- $data['csstidy']['predefined_templates']['high_compression'][] = '</span><span class="value">';
609
- $data['csstidy']['predefined_templates']['high_compression'][] = '</span><span class="format">;</span>';
610
- $data['csstidy']['predefined_templates']['high_compression'][] = '<span class="format">}</span>';
611
- $data['csstidy']['predefined_templates']['high_compression'][] = "\n";
612
- $data['csstidy']['predefined_templates']['high_compression'][] = "\n". '<span class="format">}'."\n".'</span>';
613
- $data['csstidy']['predefined_templates']['high_compression'][] = '';
614
- $data['csstidy']['predefined_templates']['high_compression'][] = '<span class="comment">'; // before comment
615
- $data['csstidy']['predefined_templates']['high_compression'][] = '</span>'; // after comment
616
- $data['csstidy']['predefined_templates']['high_compression'][] = "\n";
617
-
618
- $data['csstidy']['predefined_templates']['highest_compression'][] = '<span class="at">';
619
- $data['csstidy']['predefined_templates']['highest_compression'][] = '</span><span class="format">{</span>';
620
- $data['csstidy']['predefined_templates']['highest_compression'][] = '<span class="selector">';
621
- $data['csstidy']['predefined_templates']['highest_compression'][] = '</span><span class="format">{</span>';
622
- $data['csstidy']['predefined_templates']['highest_compression'][] = '<span class="property">';
623
- $data['csstidy']['predefined_templates']['highest_compression'][] = '</span><span class="value">';
624
- $data['csstidy']['predefined_templates']['highest_compression'][] = '</span><span class="format">;</span>';
625
- $data['csstidy']['predefined_templates']['highest_compression'][] = '<span class="format">}</span>';
626
- $data['csstidy']['predefined_templates']['highest_compression'][] = '';
627
- $data['csstidy']['predefined_templates']['highest_compression'][] = '<span class="format">}</span>';
628
- $data['csstidy']['predefined_templates']['highest_compression'][] = '';
629
- $data['csstidy']['predefined_templates']['highest_compression'][] = '<span class="comment">'; // before comment
630
- $data['csstidy']['predefined_templates']['highest_compression'][] = '</span>'; // after comment
631
- $data['csstidy']['predefined_templates']['highest_compression'][] = '';
632
-
633
- $data['csstidy']['predefined_templates']['low_compression'][] = '<span class="at">';
634
- $data['csstidy']['predefined_templates']['low_compression'][] = '</span> <span class="format">{</span>'."\n";
635
- $data['csstidy']['predefined_templates']['low_compression'][] = '<span class="selector">';
636
- $data['csstidy']['predefined_templates']['low_compression'][] = '</span>'."\n".'<span class="format">{</span>'."\n";
637
- $data['csstidy']['predefined_templates']['low_compression'][] = ' <span class="property">';
638
- $data['csstidy']['predefined_templates']['low_compression'][] = '</span><span class="value">';
639
- $data['csstidy']['predefined_templates']['low_compression'][] = '</span><span class="format">;</span>'."\n";
640
- $data['csstidy']['predefined_templates']['low_compression'][] = '<span class="format">}</span>';
641
- $data['csstidy']['predefined_templates']['low_compression'][] = "\n\n";
642
- $data['csstidy']['predefined_templates']['low_compression'][] = "\n".'<span class="format">}</span>'."\n\n";
643
- $data['csstidy']['predefined_templates']['low_compression'][] = ' ';
644
- $data['csstidy']['predefined_templates']['low_compression'][] = '<span class="comment">'; // before comment
645
- $data['csstidy']['predefined_templates']['low_compression'][] = '</span>'."\n"; // after comment
646
- $data['csstidy']['predefined_templates']['low_compression'][] = "\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
libs/CSSTidy/lang.inc.php DELETED
@@ -1,309 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Localization of CSS Optimiser Interface of CSSTidy
5
- *
6
- * Copyright 2005, 2006, 2007 Florian Schmitz
7
- *
8
- * This file is part of CSSTidy.
9
- *
10
- * CSSTidy is free software; you can redistribute it and/or modify
11
- * it under the terms of the GNU Lesser General Public License as published by
12
- * the Free Software Foundation; either version 2.1 of the License, or
13
- * (at your option) any later version.
14
- *
15
- * CSSTidy is distributed in the hope that it will be useful,
16
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
- * GNU Lesser General Public License for more details.
19
- *
20
- * You should have received a copy of the GNU Lesser General Public License
21
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
22
- *
23
- * @license http://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
24
- * @package csstidy
25
- * @author Florian Schmitz (floele at gmail dot com) 2005-2007
26
- * @author Brett Zamir (brettz9 at yahoo dot com) 2007
27
- */
28
-
29
-
30
- if (isset($_GET['lang'])) {
31
- $l = $_GET['lang'];
32
- } elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
33
- $l = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
34
- $l = strtolower(substr($l, 0, 2));
35
- } else {
36
- $l = '';
37
- }
38
-
39
- $l = (in_array($l, array('de', 'fr', 'zh'))) ? $l : 'en';
40
-
41
- // note 5 in all but French, and 40 in all are orphaned
42
-
43
- $lang = array();
44
- $lang['en'][0] = 'CSS Formatter and Optimiser/Optimizer (based on CSSTidy ';
45
- $lang['en'][1] = 'CSS Formatter and Optimiser';
46
- $lang['en'][2] = '(based on';
47
- $lang['en'][3] = '(plaintext)';
48
- $lang['en'][4] = 'Important Note:';
49
- $lang['en'][6] = 'Your code should be well-formed. This is <strong>not a validator</strong> which points out errors in your CSS code. To make sure that your code is valid, use the <a href="http://jigsaw.w3.org/css-validator/">W3C Validator</a>.';
50
- $lang['en'][7] = 'all comments are removed';
51
- $lang['en'][8] = 'CSS Input:';
52
- $lang['en'][9] = 'CSS-Code:';
53
- $lang['en'][10] = 'CSS from URL:';
54
- $lang['en'][11] = 'Code Layout:';
55
- $lang['en'][12] = 'Compression&#160;(code&#160;layout):';
56
- $lang['en'][13] = 'Highest (no readability, smallest size)';
57
- $lang['en'][14] = 'High (moderate readability, smaller size)';
58
- $lang['en'][15] = 'Standard (balance between readability and size)';
59
- $lang['en'][16] = 'Low (higher readability)';
60
- $lang['en'][17] = 'Custom (enter below)';
61
- $lang['en'][18] = 'Custom <a href="http://csstidy.sourceforge.net/templates.php">template</a>';
62
- $lang['en'][19] = 'Options';
63
- $lang['en'][20] = 'Sort Selectors (caution)';
64
- $lang['en'][21] = 'Sort Properties';
65
- $lang['en'][22] = 'Regroup selectors';
66
- $lang['en'][23] = 'Optimise shorthands';
67
- $lang['en'][24] = 'Compress colors';
68
- $lang['en'][25] = 'Lowercase selectors';
69
- $lang['en'][26] = 'Case for properties:';
70
- $lang['en'][27] = 'Lowercase';
71
- $lang['en'][28] = 'No or invalid CSS input or wrong URL!';
72
- $lang['en'][29] = 'Uppercase';
73
- $lang['en'][30] = 'lowercase elementnames needed for XHTML';
74
- $lang['en'][31] = 'Remove unnecessary backslashes';
75
- $lang['en'][32] = 'convert !important-hack';
76
- $lang['en'][33] = 'Output as file';
77
- $lang['en'][34] = 'Bigger compression because of smaller newlines (copy &#38; paste doesn\'t work)';
78
- $lang['en'][35] = 'Process CSS';
79
- $lang['en'][36] = 'Compression Ratio';
80
- $lang['en'][37] = 'Input';
81
- $lang['en'][38] = 'Output';
82
- $lang['en'][39] = 'Language';
83
- $lang['en'][41] = 'Attention: This may change the behaviour of your CSS Code!';
84
- $lang['en'][42] = 'Remove last ;';
85
- $lang['en'][43] = 'Discard invalid properties';
86
- $lang['en'][44] = 'Only safe optimisations';
87
- $lang['en'][45] = 'Compress font-weight';
88
- $lang['en'][46] = 'Save comments';
89
- $lang['en'][47] = 'Do not change anything';
90
- $lang['en'][48] = 'Only seperate selectors (split at ,)';
91
- $lang['en'][49] = 'Merge selectors with the same properties (fast)';
92
- $lang['en'][50] = 'Merge selectors intelligently (slow)';
93
- $lang['en'][51] = 'Preserve CSS';
94
- $lang['en'][52] = 'Save comments, hacks, etc. Most optimisations can *not* be applied if this is enabled.';
95
- $lang['en'][53] = 'None';
96
- $lang['en'][54] = 'Don\'t optimise';
97
- $lang['en'][55] = 'Safe optimisations';
98
- $lang['en'][56] = 'All optimisations';
99
- $lang['en'][57] = 'Add timestamp';
100
- $lang['en'][58] = 'Copy to clipboard';
101
- $lang['en'][59] = 'Back to top';
102
- $lang['en'][60] = 'Your browser doesn\'t support copy to clipboard.';
103
- $lang['en'][61] = 'For bugs and suggestions feel free to';
104
- $lang['en'][62] = 'contact me';
105
- $lang['en'][63] = 'Output CSS code as complete HTML document';
106
- $lang['en'][64] = 'Code';
107
- $lang['en'][65] = 'CSS to style CSS output';
108
- $lang['en'][66] = 'You need to go to about:config in your URL bar, select \'signed.applets.codebase_principal_support\' in the filter field, and set its value to true in order to use this feature; however, be aware that doing so increases security risks.';
109
-
110
-
111
- $lang['de'][0] = 'CSS Formatierer und Optimierer (basierend auf CSSTidy ';
112
- $lang['de'][1] = 'CSS Formatierer und Optimierer';
113
- $lang['de'][2] = '(basierend auf';
114
- $lang['de'][3] = '(Textversion)';
115
- $lang['de'][4] = 'Wichtiger Hinweis:';
116
- $lang['de'][6] = 'Der CSS Code sollte wohlgeformt sein. Der CSS Code wird <strong>nicht auf Gültigkeit überprüft</strong>. Um sicherzugehen dass dein Code valide ist, benutze den <a href="http://jigsaw.w3.org/css-validator/">W3C Validierungsservice</a>.';
117
- $lang['de'][7] = 'alle Kommentare werden entfernt';
118
- $lang['de'][8] = 'CSS Eingabe:';
119
- $lang['de'][9] = 'CSS-Code:';
120
- $lang['de'][10] = 'CSS von URL:';
121
- $lang['de'][11] = 'Code Layout:';
122
- $lang['de'][12] = 'Komprimierung&#160;(Code&#160;Layout):';
123
- $lang['de'][13] = 'Höchste (keine Lesbarkeit, niedrigste Größe)';
124
- $lang['de'][14] = 'Hoch (mittelmäßige Lesbarkeit, geringe Größe)';
125
- $lang['de'][15] = 'Standard (Kompromiss zwischen Lesbarkeit und Größe)';
126
- $lang['de'][16] = 'Niedrig (höhere Lesbarkeit)';
127
- $lang['de'][17] = 'Benutzerdefiniert (unten eingeben)';
128
- $lang['de'][18] = 'Benutzerdefinierte <a href="http://csstidy.sourceforge.net/templates.php">Vorlage</a>';
129
- $lang['de'][19] = 'Optionen';
130
- $lang['de'][20] = 'Selektoren sortieren (Vorsicht)';
131
- $lang['de'][21] = 'Eigenschaften sortieren';
132
- $lang['de'][22] = 'Selektoren umgruppieren';
133
- $lang['de'][23] = 'Shorthands optimieren';
134
- $lang['de'][24] = 'Farben komprimieren';
135
- $lang['de'][25] = 'Selektoren in Kleinbuchstaben';
136
- $lang['de'][26] = 'Groß-/Kleinschreibung für Eigenschaften';
137
- $lang['de'][27] = 'Kleinbuchstaben';
138
- $lang['de'][28] = 'Keine oder ungültige CSS Eingabe oder falsche URL!';
139
- $lang['de'][29] = 'Großbuchstaben';
140
- $lang['de'][30] = 'kleingeschriebene Elementnamen benötigt für XHTML';
141
- $lang['de'][31] = 'Unnötige Backslashes entfernen';
142
- $lang['de'][32] = '!important-Hack konvertieren';
143
- $lang['de'][33] = 'Als Datei ausgeben';
144
- $lang['de'][34] = 'Größere Komprimierung augrund von kleineren Neuezeile-Zeichen';
145
- $lang['de'][35] = 'CSS verarbeiten';
146
- $lang['de'][36] = 'Komprimierungsrate';
147
- $lang['de'][37] = 'Eingabe';
148
- $lang['de'][38] = 'Ausgabe';
149
- $lang['de'][39] = 'Sprache';
150
- $lang['de'][41] = 'Achtung: Dies könnte das Verhalten ihres CSS-Codes verändern!';
151
- $lang['de'][42] = 'Letztes ; entfernen';
152
- $lang['de'][43] = 'Ungültige Eigenschaften entfernen';
153
- $lang['de'][44] = 'Nur sichere Optimierungen';
154
- $lang['de'][45] = 'font-weight komprimieren';
155
- $lang['de'][46] = 'Kommentare beibehalten';
156
- $lang['de'][47] = 'Nichts ändern';
157
- $lang['de'][48] = 'Selektoren nur trennen (am Komma)';
158
- $lang['de'][49] = 'Selektoren mit gleichen Eigenschaften zusammenfassen (schnell)';
159
- $lang['de'][50] = 'Selektoren intelligent zusammenfassen (langsam!)';
160
- $lang['de'][51] = 'CSS erhalten';
161
- $lang['de'][52] = 'Kommentare, Hacks, etc. speichern. Viele Optimierungen sind dann aber nicht mehr möglich.';
162
- $lang['de'][53] = 'Keine';
163
- $lang['de'][54] = 'Nicht optimieren';
164
- $lang['de'][55] = 'Sichere Optimierungen';
165
- $lang['de'][56] = 'Alle Optimierungen';
166
- $lang['de'][57] = 'Zeitstempel hinzufügen';
167
- $lang['de'][58] = 'Copy to clipboard';
168
- $lang['de'][59] = 'Back to top';
169
- $lang['de'][60] = 'Your browser doesn\'t support copy to clipboard.';
170
- $lang['de'][61] = 'For bugs and suggestions feel free to';
171
- $lang['de'][62] = 'contact me';
172
- $lang['de'][63] = 'Output CSS code as complete HTML document';
173
- $lang['de'][64] = 'Code';
174
- $lang['de'][65] = 'CSS to style CSS output';
175
- $lang['de'][66] = 'You need to go to about:config in your URL bar, select \'signed.applets.codebase_principal_support\' in the filter field, and set its value to true in order to use this feature; however, be aware that doing so increases security risks.';
176
-
177
-
178
- $lang['fr'][0] = 'CSS Formateur et Optimiseur (basé sur CSSTidy ';
179
- $lang['fr'][1] = 'CSS Formateur et Optimiseur';
180
- $lang['fr'][2] = '(basé sur ';
181
- $lang['fr'][3] = '(Version texte)';
182
- $lang['fr'][4] = 'Note Importante&#160;:';
183
- $lang['fr'][6] = 'Votre code doit être valide. Ce n’est <strong>pas un validateur</strong> qui signale les erreurs dans votre code CSS. Pour être sûr que votre code est correct, utilisez le validateur&#160;: <a href="http://jigsaw.w3.org/css-validator/">W3C Validator</a>.';
184
- $lang['fr'][7] = 'tous les commentaires sont enlevés';
185
- $lang['fr'][8] = 'Champ CSS&#160;:';
186
- $lang['fr'][9] = 'Code CSS&#160;:';
187
- $lang['fr'][10] = 'CSS en provenance d’une URL&#160;:<br />';
188
- $lang['fr'][11] = 'Mise en page du code&#160;:';
189
- $lang['fr'][12] = 'Compression (mise en page du code)&#160;:';
190
- $lang['fr'][13] = 'La plus élevée (aucune lisibilité, taille minimale)';
191
- $lang['fr'][14] = 'Élevée (lisibilité modérée, petite taille)';
192
- $lang['fr'][15] = 'Normale (équilibre entre lisibilité et taille)';
193
- $lang['fr'][16] = 'Faible (lisibilité élevée)';
194
- $lang['fr'][17] = 'Sur mesure (entrer ci-dessous)';
195
- $lang['fr'][18] = '<a href="http://csstidy.sourceforge.net/templates.php">Gabarit</a> sur mesure';
196
- $lang['fr'][19] = 'Options';
197
- $lang['fr'][20] = 'Trier les sélecteurs (attention)';
198
- $lang['fr'][21] = 'Trier les propriétés';
199
- $lang['fr'][22] = 'Regrouper les sélecteurs';
200
- $lang['fr'][23] = 'Propriétés raccourcies';
201
- $lang['fr'][24] = 'Compresser les couleurs';
202
- $lang['fr'][25] = 'Sélecteurs en minuscules';
203
- $lang['fr'][26] = 'Case pour les propriétés&#160;:';
204
- $lang['fr'][27] = 'Minuscule';
205
- $lang['fr'][28] = 'CSS non valide ou URL incorrecte&#160;!';
206
- $lang['fr'][29] = 'Majuscule';
207
- $lang['fr'][30] = 'les noms des éléments en minuscules (indispensables pour XHTML)';
208
- $lang['fr'][31] = 'enlever les antislashs inutiles';
209
- $lang['fr'][32] = 'convertir !important-hack';
210
- $lang['fr'][33] = 'Sauver en tant que fichier';
211
- $lang['fr'][34] = 'Meilleure compression grâce aux caractères de saut de ligne plus petits (copier &#38; coller ne marche pas)';
212
- $lang['fr'][35] = 'Compresser la CSS';
213
- $lang['fr'][36] = 'Facteur de Compression';
214
- $lang['fr'][37] = 'Entrée';
215
- $lang['fr'][38] = 'Sortie';
216
- $lang['fr'][39] = 'Langue';
217
- $lang['fr'][41] = 'Attention&#160;: ceci peut changer le comportement de votre code CSS&#160;!';
218
- $lang['fr'][42] = 'Enlever le dernier ;';
219
- $lang['fr'][43] = 'Supprimer les propriétés non valide';
220
- $lang['fr'][44] = 'Seulement les optimisations sûres';
221
- $lang['fr'][45] = 'Compresser font-weight';
222
- $lang['fr'][46] = 'Sauvegarder les commentaires ';
223
- $lang['fr'][47] = 'Ne rien changer';
224
- $lang['fr'][48] = 'Sépare les sélecteurs (sépare au niveau de ,)';
225
- $lang['fr'][49] = 'Fusionne les sélecteurs avec les mêmes propriétés (rapide)';
226
- $lang['fr'][50] = 'Fusionne les sélecteurs intelligemment (lent)';
227
- $lang['fr'][51] = 'Préserver la CSS';
228
- $lang['fr'][52] = 'Sauvegarder les commentaires, hacks, etc. La plupart des optimisations ne peuvent *pas* être appliquées si cela est activé.';
229
- $lang['fr'][53] = 'Aucun';
230
- $lang['fr'][54] = 'Ne pas optimiser';
231
- $lang['fr'][55] = 'Optimisations sûres';
232
- $lang['fr'][56] = 'Toutes les optimisations';
233
- $lang['fr'][57] = 'Ajouter un timestamp';
234
- $lang['fr'][58] = 'Copier dans le presse-papiers';
235
- $lang['fr'][59] = 'Retour en haut';
236
- $lang['fr'][60] = 'Votre navigateur ne supporte pas la copie vers le presse-papiers.';
237
- $lang['fr'][61] = 'Pour signaler des bugs ou pour des suggestions,';
238
- $lang['fr'][62] = 'contactez-moi';
239
- $lang['fr'][63] = 'Sauver le code CSS comme document complet HTML';
240
- $lang['fr'][64] = 'Code';
241
- $lang['fr'][65] = 'CSS pour colorier la sortie CSS';
242
- $lang['fr'][66] = 'Vous devez aller dans about:config dans votre barre d’adresse, sélectionner \'signed.applets.codebase_principal_support\' dans le champ Filtre et attribuez-lui la valeur \'true\' pour utiliser cette fonctionnalité; toutefois, soyez conscient que cela augmente les risques de sécurité.';
243
-
244
-
245
- $lang['zh'][0] = 'CSS整形與最佳化工具(使用 CSSTidy ';
246
- $lang['zh'][1] = 'CSS整形與最佳化工具';
247
- $lang['zh'][2] = '(使用';
248
- $lang['zh'][3] = '(純文字)';
249
- $lang['zh'][4] = '重要事項:';
250
- $lang['zh'][6] = '你的原始碼必須是良構的(well-formed). 這個工具<strong>沒有內建驗證器(validator)</strong>. 驗證器能夠指出你CSS原始碼裡的錯誤. 請使用 <a href="http://jigsaw.w3.org/css-validator/">W3C 驗證器</a>, 確保你的原始碼合乎規範.';
251
- $lang['zh'][7] = '所有註解都移除了';
252
- $lang['zh'][8] = 'CSS 輸入:';
253
- $lang['zh'][9] = 'CSS 原始碼:';
254
- $lang['zh'][10] = 'CSS 檔案網址(URL):';
255
- $lang['zh'][11] = '原始碼規劃:';
256
- $lang['zh'][12] = '壓縮程度(原始碼規劃):';
257
- $lang['zh'][13] = '最高 (沒有辦法讀, 檔案最小)';
258
- $lang['zh'][14] = '高 (適度的可讀性, 檔案小)';
259
- $lang['zh'][15] = '標準 (兼顧可讀性與檔案大小)';
260
- $lang['zh'][16] = '低 (注重可讀性)';
261
- $lang['zh'][17] = '自訂 (在下方設定)';
262
- $lang['zh'][18] = '自訂<a href="http://csstidy.sourceforge.net/templates.php">樣板</a>';
263
- $lang['zh'][19] = '選項';
264
- $lang['zh'][20] = '整理選擇符(請謹慎使用)';
265
- $lang['zh'][21] = '整理屬性';
266
- $lang['zh'][22] = '重組選擇符';
267
- $lang['zh'][23] = '速記法(shorthand)最佳化';
268
- $lang['zh'][24] = '壓縮色彩語法';
269
- $lang['zh'][25] = '改用小寫選擇符';
270
- $lang['zh'][26] = '屬性的字形:';
271
- $lang['zh'][27] = '小寫';
272
- $lang['zh'][28] = '沒有輸入CSS, 語法不符合規定, 或是網址錯誤!';
273
- $lang['zh'][29] = '大寫';
274
- $lang['zh'][30] = 'XHTML必須使用小寫的元素名稱';
275
- $lang['zh'][31] = '移除不必要的反斜線';
276
- $lang['zh'][32] = '轉換 !important-hack';
277
- $lang['zh'][33] = '輸出成檔案形式';
278
- $lang['zh'][34] = '由於比較少換行字元, 會有更大的壓縮比率(複製&#38;貼上沒有用)';
279
- $lang['zh'][35] = '執行';
280
- $lang['zh'][36] = '壓縮比率';
281
- $lang['zh'][37] = '輸入';
282
- $lang['zh'][38] = '輸出';
283
- $lang['zh'][39] = '語言';
284
- $lang['zh'][41] = '注意: 這或許會變更你CSS原始碼的行為!';
285
- $lang['zh'][42] = '除去最後一個分號';
286
- $lang['zh'][43] = '拋棄不符合規定的屬性';
287
- $lang['zh'][44] = '只安全地最佳化';
288
- $lang['zh'][45] = '壓縮 font-weight';
289
- $lang['zh'][46] = '保留註解';
290
- $lang['zh'][47] = '什麼都不要改';
291
- $lang['zh'][48] = '只分開原本用逗號分隔的選擇符';
292
- $lang['zh'][49] = '合併有相同屬性的選擇符(快速)';
293
- $lang['zh'][50] = '聰明地合併選擇符(慢速)';
294
- $lang['zh'][51] = '保護CSS';
295
- $lang['zh'][52] = '保留註解與 hack 等等. 如果啟用這個選項, 大多數的最佳化程序都不會執行.';
296
- $lang['zh'][53] = '不改變';
297
- $lang['zh'][54] = '不做最佳化';
298
- $lang['zh'][55] = '安全地最佳化';
299
- $lang['zh'][56] = '全部最佳化';
300
- $lang['zh'][57] = '加上時間戳記';
301
- $lang['zh'][58] = '复制到剪贴板';
302
- $lang['zh'][59] = '回到页面上方';
303
- $lang['zh'][60] = '你的浏览器不支持复制到剪贴板。';
304
- $lang['zh'][61] = '如果程序有错误或你有建议,欢迎';
305
- $lang['zh'][62] = '和我联系';
306
- $lang['zh'][63] = 'Output CSS code as complete HTML document';
307
- $lang['zh'][64] = '代码';
308
- $lang['zh'][65] = 'CSS to style CSS output';
309
- $lang['zh'][66] = 'You need to go to about:config in your URL bar, select \'signed.applets.codebase_principal_support\' in the filter field, and set its value to true in order to use this feature; however, be aware that doing so increases security risks.';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
libs/JSMin/jsmin.php DELETED
@@ -1,386 +0,0 @@
1
- <?php
2
- /**
3
- * jsmin.php - PHP implementation of Douglas Crockford's JSMin.
4
- *
5
- * This is pretty much a direct port of jsmin.c to PHP with just a few
6
- * PHP-specific performance tweaks. Also, whereas jsmin.c reads from stdin and
7
- * outputs to stdout, this library accepts a string as input and returns another
8
- * string as output.
9
- *
10
- * PHP 5 or higher is required.
11
- *
12
- * Permission is hereby granted to use this version of the library under the
13
- * same terms as jsmin.c, which has the following license:
14
- *
15
- * --
16
- * Copyright (c) 2002 Douglas Crockford (www.crockford.com)
17
- *
18
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
19
- * this software and associated documentation files (the "Software"), to deal in
20
- * the Software without restriction, including without limitation the rights to
21
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
22
- * of the Software, and to permit persons to whom the Software is furnished to do
23
- * so, subject to the following conditions:
24
- *
25
- * The above copyright notice and this permission notice shall be included in all
26
- * copies or substantial portions of the Software.
27
- *
28
- * The Software shall be used for Good, not Evil.
29
- *
30
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
33
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
35
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36
- * SOFTWARE.
37
- * --
38
- *
39
- * @package JSMin
40
- * @author Ryan Grove <ryan@wonko.com>
41
- * @copyright 2002 Douglas Crockford <douglas@crockford.com> (jsmin.c)
42
- * @copyright 2008 Ryan Grove <ryan@wonko.com> (PHP port)
43
- * @copyright 2012 Adam Goforth <aag@adamgoforth.com> (Updates)
44
- * @license http://opensource.org/licenses/mit-license.php MIT License
45
- * @version 1.1.2 (2012-05-01)
46
- * @link https://github.com/rgrove/jsmin-php
47
- */
48
-
49
- class JSMin {
50
- const ORD_LF = 10;
51
- const ORD_SPACE = 32;
52
- const ACTION_KEEP_A = 1;
53
- const ACTION_DELETE_A = 2;
54
- const ACTION_DELETE_A_B = 3;
55
-
56
- protected $a = '';
57
- protected $b = '';
58
- protected $input = '';
59
- protected $inputIndex = 0;
60
- protected $inputLength = 0;
61
- protected $lookAhead = null;
62
- protected $output = '';
63
-
64
- // -- Public Static Methods --------------------------------------------------
65
-
66
- /**
67
- * Minify Javascript
68
- *
69
- * @uses __construct()
70
- * @uses min()
71
- * @param string $js Javascript to be minified
72
- * @return string
73
- */
74
- public static function minify($js) {
75
- $jsmin = new JSMin($js);
76
- return $jsmin->min();
77
- }
78
-
79
- // -- Public Instance Methods ------------------------------------------------
80
-
81
- /**
82
- * Constructor
83
- *
84
- * @param string $input Javascript to be minified
85
- */
86
- public function __construct($input) {
87
- $this->input = str_replace("\r\n", "\n", $input);
88
- $this->inputLength = strlen($this->input);
89
- }
90
-
91
- // -- Protected Instance Methods ---------------------------------------------
92
-
93
- /**
94
- * Action -- do something! What to do is determined by the $command argument.
95
- *
96
- * action treats a string as a single character. Wow!
97
- * action recognizes a regular expression if it is preceded by ( or , or =.
98
- *
99
- * @uses next()
100
- * @uses get()
101
- * @throws JSMinException If parser errors are found:
102
- * - Unterminated string literal
103
- * - Unterminated regular expression set in regex literal
104
- * - Unterminated regular expression literal
105
- * @param int $command One of class constants:
106
- * ACTION_KEEP_A Output A. Copy B to A. Get the next B.
107
- * ACTION_DELETE_A Copy B to A. Get the next B. (Delete A).
108
- * ACTION_DELETE_A_B Get the next B. (Delete B).
109
- */
110
- protected function action($command) {
111
- switch($command) {
112
- case self::ACTION_KEEP_A:
113
- $this->output .= $this->a;
114
-
115
- case self::ACTION_DELETE_A:
116
- $this->a = $this->b;
117
-
118
- if ($this->a === "'" || $this->a === '"') {
119
- for (;;) {
120
- $this->output .= $this->a;
121
- $this->a = $this->get();
122
-
123
- if ($this->a === $this->b) {
124
- break;
125
- }
126
-
127
- if (ord($this->a) <= self::ORD_LF) {
128
- throw new JSMinException('Unterminated string literal.');
129
- }
130
-
131
- if ($this->a === '\\') {
132
- $this->output .= $this->a;
133
- $this->a = $this->get();
134
- }
135
- }
136
- }
137
-
138
- case self::ACTION_DELETE_A_B:
139
- $this->b = $this->next();
140
-
141
- if ($this->b === '/' && (
142
- $this->a === '(' || $this->a === ',' || $this->a === '=' ||
143
- $this->a === ':' || $this->a === '[' || $this->a === '!' ||
144
- $this->a === '&' || $this->a === '|' || $this->a === '?' ||
145
- $this->a === '{' || $this->a === '}' || $this->a === ';' ||
146
- $this->a === "\n" )) {
147
-
148
- $this->output .= $this->a . $this->b;
149
-
150
- for (;;) {
151
- $this->a = $this->get();
152
-
153
- if ($this->a === '[') {
154
- /*
155
- inside a regex [...] set, which MAY contain a '/' itself. Example: mootools Form.Validator near line 460:
156
- return Form.Validator.getValidator('IsEmpty').test(element) || (/^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]\.?){0,63}[a-z0-9!#$%&'*+/=?^_`{|}~-]@(?:(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\])$/i).test(element.get('value'));
157
- */
158
- for (;;) {
159
- $this->output .= $this->a;
160
- $this->a = $this->get();
161
-
162
- if ($this->a === ']') {
163
- break;
164
- } elseif ($this->a === '\\') {
165
- $this->output .= $this->a;
166
- $this->a = $this->get();
167
- } elseif (ord($this->a) <= self::ORD_LF) {
168
- throw new JSMinException('Unterminated regular expression set in regex literal.');
169
- }
170
- }
171
- } elseif ($this->a === '/') {
172
- break;
173
- } elseif ($this->a === '\\') {
174
- $this->output .= $this->a;
175
- $this->a = $this->get();
176
- } elseif (ord($this->a) <= self::ORD_LF) {
177
- throw new JSMinException('Unterminated regular expression literal.');
178
- }
179
-
180
- $this->output .= $this->a;
181
- }
182
-
183
- $this->b = $this->next();
184
- }
185
- }
186
- }
187
-
188
- /**
189
- * Get next char. Convert ctrl char to space.
190
- *
191
- * @return string|null
192
- */
193
- protected function get() {
194
- $c = $this->lookAhead;
195
- $this->lookAhead = null;
196
-
197
- if ($c === null) {
198
- if ($this->inputIndex < $this->inputLength) {
199
- $c = substr($this->input, $this->inputIndex, 1);
200
- $this->inputIndex += 1;
201
- } else {
202
- $c = null;
203
- }
204
- }
205
-
206
- if ($c === "\r") {
207
- return "\n";
208
- }
209
-
210
- if ($c === null || $c === "\n" || ord($c) >= self::ORD_SPACE) {
211
- return $c;
212
- }
213
-
214
- return ' ';
215
- }
216
-
217
- /**
218
- * Is $c a letter, digit, underscore, dollar sign, or non-ASCII character.
219
- *
220
- * @return bool
221
- */
222
- protected function isAlphaNum($c) {
223
- return ord($c) > 126 || $c === '\\' || preg_match('/^[\w\$]$/', $c) === 1;
224
- }
225
-
226
- /**
227
- * Perform minification, return result
228
- *
229
- * @uses action()
230
- * @uses isAlphaNum()
231
- * @uses get()
232
- * @uses peek()
233
- * @return string
234
- */
235
- protected function min() {
236
- if (0 == strncmp($this->peek(), "\xef", 1)) {
237
- $this->get();
238
- $this->get();
239
- $this->get();
240
- }
241
-
242
- $this->a = "\n";
243
- $this->action(self::ACTION_DELETE_A_B);
244
-
245
- while ($this->a !== null) {
246
- switch ($this->a) {
247
- case ' ':
248
- if ($this->isAlphaNum($this->b)) {
249
- $this->action(self::ACTION_KEEP_A);
250
- } else {
251
- $this->action(self::ACTION_DELETE_A);
252
- }
253
- break;
254
-
255
- case "\n":
256
- switch ($this->b) {
257
- case '{':
258
- case '[':
259
- case '(':
260
- case '+':
261
- case '-':
262
- case '!':
263
- case '~':
264
- $this->action(self::ACTION_KEEP_A);
265
- break;
266
-
267
- case ' ':
268
- $this->action(self::ACTION_DELETE_A_B);
269
- break;
270
-
271
- default:
272
- if ($this->isAlphaNum($this->b)) {
273
- $this->action(self::ACTION_KEEP_A);
274
- }
275
- else {
276
- $this->action(self::ACTION_DELETE_A);
277
- }
278
- }
279
- break;
280
-
281
- default:
282
- switch ($this->b) {
283
- case ' ':
284
- if ($this->isAlphaNum($this->a)) {
285
- $this->action(self::ACTION_KEEP_A);
286
- break;
287
- }
288
-
289
- $this->action(self::ACTION_DELETE_A_B);
290
- break;
291
-
292
- case "\n":
293
- switch ($this->a) {
294
- case '}':
295
- case ']':
296
- case ')':
297
- case '+':
298
- case '-':
299
- case '"':
300
- case "'":
301
- $this->action(self::ACTION_KEEP_A);
302
- break;
303
-
304
- default:
305
- if ($this->isAlphaNum($this->a)) {
306
- $this->action(self::ACTION_KEEP_A);
307
- }
308
- else {
309
- $this->action(self::ACTION_DELETE_A_B);
310
- }
311
- }
312
- break;
313
-
314
- default:
315
- $this->action(self::ACTION_KEEP_A);
316
- break;
317
- }
318
- }
319
- }
320
-
321
- return $this->output;
322
- }
323
-
324
- /**
325
- * Get the next character, skipping over comments. peek() is used to see
326
- * if a '/' is followed by a '/' or '*'.
327
- *
328
- * @uses get()
329
- * @uses peek()
330
- * @throws JSMinException On unterminated comment.
331
- * @return string
332
- */
333
- protected function next() {
334
- $c = $this->get();
335
-
336
- if ($c === '/') {
337
- switch($this->peek()) {
338
- case '/':
339
- for (;;) {
340
- $c = $this->get();
341
-
342
- if (ord($c) <= self::ORD_LF) {
343
- return $c;
344
- }
345
- }
346
-
347
- case '*':
348
- $this->get();
349
-
350
- for (;;) {
351
- switch($this->get()) {
352
- case '*':
353
- if ($this->peek() === '/') {
354
- $this->get();
355
- return ' ';
356
- }
357
- break;
358
-
359
- case null:
360
- throw new JSMinException('Unterminated comment.');
361
- }
362
- }
363
-
364
- default:
365
- return $c;
366
- }
367
- }
368
-
369
- return $c;
370
- }
371
-
372
- /**
373
- * Get next char. If is ctrl character, translate to a space or newline.
374
- *
375
- * @uses get()
376
- * @return string|null
377
- */
378
- protected function peek() {
379
- $this->lookAhead = $this->get();
380
- return $this->lookAhead;
381
- }
382
- }
383
-
384
- // -- Exceptions ---------------------------------------------------------------
385
- class JSMinException extends Exception {}
386
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
libs/matthiasmullie/minify/src/CSS.php CHANGED
@@ -86,7 +86,7 @@ class CSS extends Minify
86
  */
87
  protected function moveImportsToTop($content)
88
  {
89
- if (preg_match_all('/(;?)(@import (?<url>url\()?(?P<quotes>["\']?).+?(?P=quotes)(?(url)\)))/', $content, $matches)) {
90
  // remove from content
91
  foreach ($matches[0] as $import) {
92
  $content = str_replace($import, '', $content);
@@ -217,6 +217,8 @@ class CSS extends Minify
217
  // grab referenced file & minify it (which may include importing
218
  // yet other @import statements recursively)
219
  $minifier = new static($importPath);
 
 
220
  $importContent = $minifier->execute($source, $parents);
221
 
222
  // check if this is only valid for certain media
@@ -591,10 +593,11 @@ class CSS extends Minify
591
  // strip negative zeroes (-0 -> 0) & truncate zeroes (00 -> 0)
592
  $content = preg_replace('/'.$before.'-?0+'.$units.'?'.$after.'/', '0\\1', $content);
593
 
594
- // IE doesn't seem to understand a unitless flex-basis value, so let's
595
- // add it in again (make it `%`, which is only 1 char: 0%, 0px, 0
596
- // anything, it's all just the same)
597
- $content = preg_replace('/flex:([^ ]+ [^ ]+ )0([;\}])/', 'flex:${1}0%${2}', $content);
 
598
  $content = preg_replace('/flex-basis:0([;\}])/', 'flex-basis:0%${1}', $content);
599
 
600
  // restore `calc()` expressions
86
  */
87
  protected function moveImportsToTop($content)
88
  {
89
+ if (preg_match_all('/(;?)(@import (?<url>url\()?(?P<quotes>["\']?).+?(?P=quotes)(?(url)\)));?/', $content, $matches)) {
90
  // remove from content
91
  foreach ($matches[0] as $import) {
92
  $content = str_replace($import, '', $content);
217
  // grab referenced file & minify it (which may include importing
218
  // yet other @import statements recursively)
219
  $minifier = new static($importPath);
220
+ $minifier->setMaxImportSize($this->maxImportSize);
221
+ $minifier->setImportExtensions($this->importExtensions);
222
  $importContent = $minifier->execute($source, $parents);
223
 
224
  // check if this is only valid for certain media
593
  // strip negative zeroes (-0 -> 0) & truncate zeroes (00 -> 0)
594
  $content = preg_replace('/'.$before.'-?0+'.$units.'?'.$after.'/', '0\\1', $content);
595
 
596
+ // IE doesn't seem to understand a unitless flex-basis value (correct -
597
+ // it goes against the spec), so let's add it in again (make it `%`,
598
+ // which is only 1 char: 0%, 0px, 0 anything, it's all just the same)
599
+ // @see https://developer.mozilla.org/nl/docs/Web/CSS/flex
600
+ $content = preg_replace('/flex:([0-9]+\s[0-9]+\s)0([;\}])/', 'flex:${1}0%${2}', $content);
601
  $content = preg_replace('/flex-basis:0([;\}])/', 'flex-basis:0%${1}', $content);
602
 
603
  // restore `calc()` expressions
libs/matthiasmullie/minify/src/JS.php CHANGED
@@ -179,7 +179,7 @@ class JS extends Minify
179
 
180
  // clean up leftover `;`s from the combination of multiple scripts
181
  $content = ltrim($content, ';');
182
- $content = substr($content, 0, -1);
183
 
184
  /*
185
  * Earlier, we extracted strings & regular expressions and replaced them
@@ -236,13 +236,15 @@ class JS extends Minify
236
  // one being escaped)
237
  // this should allow all chars, except for an unescaped `/` (= the one
238
  // closing the regex)
239
- $pattern = '\\/([^\\/\\\\]*+|(\\\\.)*+)+\\/[gimy]*';
 
 
240
 
241
  // a regular expression can only be followed by a few operators or some
242
  // of the RegExp methods (a `\` followed by a variable or value is
243
  // likely part of a division, not a regex)
244
  $keywords = array('do', 'in', 'new', 'else', 'throw', 'yield', 'delete', 'return', 'typeof');
245
- $before = '([=:,;\}\(\{\[&\|!\)]|^|'.implode('|', $keywords).')\s*';
246
  $propertiesAndMethods = array(
247
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#Properties_2
248
  'constructor',
@@ -262,7 +264,22 @@ class JS extends Minify
262
  );
263
  $delimiters = array_fill(0, count($propertiesAndMethods), '/');
264
  $propertiesAndMethods = array_map('preg_quote', $propertiesAndMethods, $delimiters);
265
- $after = '(?=\s*[\.,;\)\}&\|+]|\/\/|$|\.('.implode('|', $propertiesAndMethods).'))';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
266
  $this->registerPattern('/'.$before.'\K'.$pattern.$after.'/', $callback);
267
 
268
  // 1 more edge case: a regex can be followed by a lot more operators or
@@ -347,8 +364,12 @@ class JS extends Minify
347
  /*
348
  * Whitespace after `return` can be omitted in a few occasions
349
  * (such as when followed by a string or regex)
 
 
350
  */
351
  $content = preg_replace('/\breturn\s+(["\'\/\+\-])/', 'return$1', $content);
 
 
352
 
353
  /*
354
  * Get rid of double semicolons, except where they can be used like:
179
 
180
  // clean up leftover `;`s from the combination of multiple scripts
181
  $content = ltrim($content, ';');
182
+ $content = (string) substr($content, 0, -1);
183
 
184
  /*
185
  * Earlier, we extracted strings & regular expressions and replaced them
236
  // one being escaped)
237
  // this should allow all chars, except for an unescaped `/` (= the one
238
  // closing the regex)
239
+ // then also ignore bare `/` inside `[]`, where they don't need to be
240
+ // escaped: anything inside `[]` can be ignored safely
241
+ $pattern = '\\/(?:[^\\[\\/\\\\\n\r]+|(?:\\\\.)+|(?:\\[(?:[^\\]\\\\\n\r]+|(?:\\\\.)+)+\\])+)++\\/[gimuy]*';
242
 
243
  // a regular expression can only be followed by a few operators or some
244
  // of the RegExp methods (a `\` followed by a variable or value is
245
  // likely part of a division, not a regex)
246
  $keywords = array('do', 'in', 'new', 'else', 'throw', 'yield', 'delete', 'return', 'typeof');
247
+ $before = '([=:,;\+\-\*\/\}\(\{\[&\|!]|^|'.implode('|', $keywords).')\s*';
248
  $propertiesAndMethods = array(
249
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#Properties_2
250
  'constructor',
264
  );
265
  $delimiters = array_fill(0, count($propertiesAndMethods), '/');
266
  $propertiesAndMethods = array_map('preg_quote', $propertiesAndMethods, $delimiters);
267
+ $after = '(?=\s*([\.,;\)\}&\|+]|\/\/|$|\.('.implode('|', $propertiesAndMethods).')))';
268
+ $this->registerPattern('/'.$before.'\K'.$pattern.$after.'/', $callback);
269
+
270
+ // regular expressions following a `)` are rather annoying to detect...
271
+ // quite often, `/` after `)` is a division operator & if it happens to
272
+ // be followed by another one (or a comment), it is likely to be
273
+ // confused for a regular expression
274
+ // however, it's perfectly possible for a regex to follow a `)`: after
275
+ // a single-line `if()`, `while()`, ... statement, for example
276
+ // since, when they occur like that, they're always the start of a
277
+ // statement, there's only a limited amount of ways they can be useful:
278
+ // by calling the regex methods directly
279
+ // if a regex following `)` is not followed by `.<property or method>`,
280
+ // it's quite likely not a regex
281
+ $before = '\)\s*';
282
+ $after = '(?=\s*\.('.implode('|', $propertiesAndMethods).'))';
283
  $this->registerPattern('/'.$before.'\K'.$pattern.$after.'/', $callback);
284
 
285
  // 1 more edge case: a regex can be followed by a lot more operators or
364
  /*
365
  * Whitespace after `return` can be omitted in a few occasions
366
  * (such as when followed by a string or regex)
367
+ * Same for whitespace in between `)` and `{`, or between `{` and some
368
+ * keywords.
369
  */
370
  $content = preg_replace('/\breturn\s+(["\'\/\+\-])/', 'return$1', $content);
371
+ $content = preg_replace('/\)\s+\{/', '){', $content);
372
+ $content = preg_replace('/}\n(else|catch|finally)\b/', '}$1', $content);
373
 
374
  /*
375
  * Get rid of double semicolons, except where they can be used like:
libs/matthiasmullie/minify/src/Minify.php CHANGED
@@ -239,6 +239,12 @@ abstract class Minify
239
  foreach ($this->patterns as $i => $pattern) {
240
  list($pattern, $replacement) = $pattern;
241
 
 
 
 
 
 
 
242
  // no need to re-run matches that are still in the part of the
243
  // content that hasn't been processed
244
  if ($positions[$i] >= 0) {
@@ -246,19 +252,18 @@ abstract class Minify
246
  }
247
 
248
  $match = null;
249
- if (preg_match($pattern, $content, $match)) {
250
  $matches[$i] = $match;
251
 
252
  // we'll store the match position as well; that way, we
253
  // don't have to redo all preg_matches after changing only
254
  // the first (we'll still know where those others are)
255
- $positions[$i] = strpos($content, $match[0]);
256
  } else {
257
  // if the pattern couldn't be matched, there's no point in
258
  // executing it again in later runs on this same content;
259
  // ignore this one until we reach end of content
260
- unset($matches[$i]);
261
- $positions[$i] = strlen($content);
262
  }
263
  }
264
 
@@ -273,7 +278,7 @@ abstract class Minify
273
  // other found was not inside what the first found)
274
  $discardLength = min($positions);
275
  $firstPattern = array_search($discardLength, $positions);
276
- $match = $matches[$firstPattern][0];
277
 
278
  // execute the pattern that matches earliest in the content string
279
  list($pattern, $replacement) = $this->patterns[$firstPattern];
@@ -281,7 +286,7 @@ abstract class Minify
281
 
282
  // figure out which part of the string was unmatched; that's the
283
  // part we'll execute the patterns on again next
284
- $content = substr($content, $discardLength);
285
  $unmatched = (string) substr($content, strpos($content, $match) + strlen($match));
286
 
287
  // move the replaced part to $processed and prepare $content to
@@ -405,6 +410,16 @@ abstract class Minify
405
  */
406
  protected function canImportFile($path)
407
  {
 
 
 
 
 
 
 
 
 
 
408
  return strlen($path) < PHP_MAXPATHLEN && @is_file($path) && is_readable($path);
409
  }
410
 
239
  foreach ($this->patterns as $i => $pattern) {
240
  list($pattern, $replacement) = $pattern;
241
 
242
+ // we can safely ignore patterns for positions we've unset earlier,
243
+ // because we know these won't show up anymore
244
+ if (!isset($positions[$i])) {
245
+ continue;
246
+ }
247
+
248
  // no need to re-run matches that are still in the part of the
249
  // content that hasn't been processed
250
  if ($positions[$i] >= 0) {
252
  }
253
 
254
  $match = null;
255
+ if (preg_match($pattern, $content, $match, PREG_OFFSET_CAPTURE)) {
256
  $matches[$i] = $match;
257
 
258
  // we'll store the match position as well; that way, we
259
  // don't have to redo all preg_matches after changing only
260
  // the first (we'll still know where those others are)
261
+ $positions[$i] = $match[0][1];
262
  } else {
263
  // if the pattern couldn't be matched, there's no point in
264
  // executing it again in later runs on this same content;
265
  // ignore this one until we reach end of content
266
+ unset($matches[$i], $positions[$i]);
 
267
  }
268
  }
269
 
278
  // other found was not inside what the first found)
279
  $discardLength = min($positions);
280
  $firstPattern = array_search($discardLength, $positions);
281
+ $match = $matches[$firstPattern][0][0];
282
 
283
  // execute the pattern that matches earliest in the content string
284
  list($pattern, $replacement) = $this->patterns[$firstPattern];
286
 
287
  // figure out which part of the string was unmatched; that's the
288
  // part we'll execute the patterns on again next
289
+ $content = (string) substr($content, $discardLength);
290
  $unmatched = (string) substr($content, strpos($content, $match) + strlen($match));
291
 
292
  // move the replaced part to $processed and prepare $content to
410
  */
411
  protected function canImportFile($path)
412
  {
413
+ $parsed = parse_url($path);
414
+ if (
415
+ // file is elsewhere
416
+ isset($parsed['host']) ||
417
+ // file responds to queries (may change, or need to bypass cache)
418
+ isset($parsed['query'])
419
+ ) {
420
+ return false;
421
+ }
422
+
423
  return strlen($path) < PHP_MAXPATHLEN && @is_file($path) && is_readable($path);
424
  }
425
 
libs/matthiasmullie/path-converter/src/Converter.php CHANGED
@@ -44,8 +44,8 @@ class Converter implements ConverterInterface
44
 
45
  // or traveling the tree via `..`
46
  // attempt to resolve path, or assume it's fine if it doesn't exist
47
- $from = realpath($from) ?: $from;
48
- $to = realpath($to) ?: $to;
49
  }
50
 
51
  $from = $this->dirname($from);
@@ -169,11 +169,11 @@ class Converter implements ConverterInterface
169
  */
170
  protected function dirname($path)
171
  {
172
- if (is_file($path)) {
173
  return dirname($path);
174
  }
175
 
176
- if (is_dir($path)) {
177
  return rtrim($path, '/');
178
  }
179
 
44
 
45
  // or traveling the tree via `..`
46
  // attempt to resolve path, or assume it's fine if it doesn't exist
47
+ $from = @realpath($from) ?: $from;
48
+ $to = @realpath($to) ?: $to;
49
  }
50
 
51
  $from = $this->dirname($from);
169
  */
170
  protected function dirname($path)
171
  {
172
+ if (@is_file($path)) {
173
  return dirname($path);
174
  }
175
 
176
+ if (@is_dir($path)) {
177
  return rtrim($path, '/');
178
  }
179
 
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: Alignak
3
  Tags: PHP Minify, YUI Compressor, GTmetrix, Pingdom, Pagespeed, CSS Merging, JS Merging, CSS Minification, JS Minification, Speed Optimization, HTML Minification, Performance
4
  Requires at least: 4.5
5
- Stable tag: 2.3.4
6
- Tested up to: 4.9.6
7
  License: GPLv3 or later
8
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
9
 
@@ -43,7 +43,7 @@ I can offer you aditional `custom made` optimization on top of this plugin. If y
43
  * Support for multisite installations
44
  * Support for gzip_static on Nginx
45
  * Support for the CDN Enabler plugin
46
- * Auto purging of cache files on W3 Total Cache, WP Supercache, WP Rocket, Wp Fastest Cache, Cachify, Comet Cache, Zen Cache, LiteSpeed Cache, Nginx Cache (by Till Krüss ), SG Optimizer, Godaddy Managed WordPress Hosting and WP Engine (read the FAQs)
47
  * WP CLI support
48
  * Support for preconnect and preload headers
49
  * and some more...
@@ -74,8 +74,9 @@ I can offer you aditional `custom made` optimization on top of this plugin. If y
74
 
75
  == Screenshots ==
76
 
77
- 1. You can view the logs and purge the cache files.
78
  2. The settings page.
 
79
 
80
 
81
  == Frequently Asked Questions ==
@@ -264,6 +265,15 @@ If you would like to donate any amount to the plugin author (thank you in advanc
264
 
265
  == Changelog ==
266
 
 
 
 
 
 
 
 
 
 
267
  = 2.3.4 [2018.06.30] =
268
  * bug fix
269
 
2
  Contributors: Alignak
3
  Tags: PHP Minify, YUI Compressor, GTmetrix, Pingdom, Pagespeed, CSS Merging, JS Merging, CSS Minification, JS Minification, Speed Optimization, HTML Minification, Performance
4
  Requires at least: 4.5
5
+ Stable tag: 2.3.5
6
+ Tested up to: 4.9.8
7
  License: GPLv3 or later
8
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
9
 
43
  * Support for multisite installations
44
  * Support for gzip_static on Nginx
45
  * Support for the CDN Enabler plugin
46
+ * Auto purging of cache files on W3 Total Cache, WP Supercache, WP Rocket, Wp Fastest Cache, Cachify, Comet Cache, Zen Cache, LiteSpeed Cache, Nginx Cache (by Till Krüss ), SG Optimizer, HyperCache, Godaddy Managed WordPress Hosting and WP Engine (read the FAQs)
47
  * WP CLI support
48
  * Support for preconnect and preload headers
49
  * and some more...
74
 
75
  == Screenshots ==
76
 
77
+ 1. The status and logs page.
78
  2. The settings page.
79
+ 3. The Advanced settings.
80
 
81
 
82
  == Frequently Asked Questions ==
265
 
266
  == Changelog ==
267
 
268
+ = 2.3.5 [2018.08.27] =
269
+ * added thinkwithgoogle support for the defer for insights option
270
+ * added HyperCache support, thanks to @erich_k4wp
271
+ * added suport for wp_add_inline_script, thanks to @yuriipavlov
272
+ * fixed a bug where some inlined css was missing if not attached to a parent css file
273
+ * the ignore list now also supports CSS handle names (no JS yet)
274
+ * updated PHP Minify from master on github
275
+ * improved performance for gtmetrix tests
276
+
277
  = 2.3.4 [2018.06.30] =
278
  * bug fix
279