Version Description
[2018.06.03] = * added some compatibility fixes when merging and minifying JS files * added an option to enable an "FVM Purge" button on the admin bar * moved all large transients (cached css or js code) to temporary disk files to reduce the database load
Download this release
Release Info
Developer | Alignak |
Plugin | Fast Velocity Minify |
Version | 2.3.2 |
Comparing to | |
See all releases |
Code changes from version 2.3.1 to 2.3.2
- fvm.php +56 -18
- inc/functions-admin.php +0 -75
- inc/functions.php +97 -48
- libs/CSSTidy/class.csstidy.php +1296 -0
- libs/CSSTidy/class.csstidy_optimise.php +963 -0
- libs/CSSTidy/class.csstidy_print.php +446 -0
- libs/CSSTidy/data.inc.php +646 -0
- libs/CSSTidy/lang.inc.php +309 -0
- libs/JSMin/jsmin.php +386 -0
- readme.txt +6 -1
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.
|
9 |
License: GPL2
|
10 |
|
11 |
------------------------------------------------------------------------
|
@@ -102,6 +102,7 @@ $ignore = array_map('trim', explode("\n", get_option('fastvelocity_min_ignore',
|
|
102 |
$blacklist = array_map('trim', explode("\n", get_option('fastvelocity_min_blacklist', '')));
|
103 |
$ignorelist = array_map('trim', explode("\n", get_option('fastvelocity_min_ignorelist', '')));
|
104 |
$merge_allowed_urls = array_map('trim', explode("\n", get_option('fastvelocity_min_merge_allowed_urls', '')));
|
|
|
105 |
$default_protocol = get_option('fastvelocity_min_default_protocol', 'dynamic');
|
106 |
$disable_js_merge = get_option('fastvelocity_min_disable_js_merge');
|
107 |
$disable_css_merge = get_option('fastvelocity_min_disable_css_merge');
|
@@ -132,6 +133,7 @@ $fvm_remove_css = get_option('fastvelocity_min_fvm_removecss');
|
|
132 |
$critical_path_css = get_option('fastvelocity_min_critical_path_css');
|
133 |
$fvm_cdn_url = get_option('fastvelocity_min_fvm_cdn_url');
|
134 |
|
|
|
135 |
# default options
|
136 |
$used_css_files = array();
|
137 |
|
@@ -140,7 +142,7 @@ $exc = array('/html5shiv.js', '/html5shiv-printshiv.min.js', '/excanvas.js', '/a
|
|
140 |
if(!is_array($blacklist) || strlen(implode($blacklist)) == 0) { update_option('fastvelocity_min_blacklist', implode("\n", $exc)); }
|
141 |
|
142 |
# default ignore list
|
143 |
-
$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');
|
144 |
if(!is_array($ignorelist) || strlen(implode($ignorelist)) == 0) { update_option('fastvelocity_min_ignorelist', implode("\n", $exc)); }
|
145 |
|
146 |
|
@@ -221,6 +223,27 @@ add_options_page('Fast Velocity Minify Settings', 'Fast Velocity Minify', 'manag
|
|
221 |
}
|
222 |
|
223 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
224 |
# function to list all cache files
|
225 |
function fastvelocity_min_files_callback() {
|
226 |
global $cachedir;
|
@@ -271,6 +294,7 @@ function fastvelocity_min_load_admin_jscss($hook) {
|
|
271 |
# register plugin settings
|
272 |
function fastvelocity_min_register_settings() {
|
273 |
register_setting('fvm-group', 'fastvelocity_min_ignore');
|
|
|
274 |
register_setting('fvm-group', 'fastvelocity_min_default_protocol');
|
275 |
register_setting('fvm-group', 'fastvelocity_min_disable_js_merge');
|
276 |
register_setting('fvm-group', 'fastvelocity_min_disable_css_merge');
|
@@ -314,10 +338,10 @@ function fastvelocity_min_register_settings() {
|
|
314 |
|
315 |
# add settings link on plugin page
|
316 |
function fastvelocity_min_settings_link($links) {
|
317 |
-
if (is_plugin_active(plugin_basename( __FILE__ ))) {
|
318 |
-
$settings_link = '<a href="options-general.php?page=fastvelocity-min&tab=settings">Settings</a>';
|
319 |
-
array_unshift($links, $settings_link);
|
320 |
-
}
|
321 |
return $links;
|
322 |
}
|
323 |
add_filter("plugin_action_links_".plugin_basename(__FILE__), 'fastvelocity_min_settings_link' );
|
@@ -341,11 +365,14 @@ $active_tab = isset($_GET['tab']) ? $_GET['tab'] : 'status';
|
|
341 |
<?php
|
342 |
|
343 |
# purge all caches
|
344 |
-
if(isset($
|
345 |
-
|
346 |
-
|
347 |
-
echo
|
|
|
|
|
348 |
}
|
|
|
349 |
?>
|
350 |
|
351 |
<h2 class="nav-tab-wrapper wp-clearfix">
|
@@ -412,6 +439,17 @@ echo fastvelocity_purge_others(); # purge third party caches
|
|
412 |
<table class="form-table fvm-settings">
|
413 |
<tbody>
|
414 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
415 |
<tr>
|
416 |
<th scope="row">Troubleshooting</th>
|
417 |
<td>
|
@@ -796,7 +834,7 @@ Async CSS with LoadCSS<span class="note-info">[ Only works if "Inline all header
|
|
796 |
|
797 |
<div style="height: 20px;"></div>
|
798 |
<h2 class="title">Cache Location</h2>
|
799 |
-
<p class="fvm-bold-green">
|
800 |
<table class="form-table fvm-settings">
|
801 |
<tbody>
|
802 |
<tr>
|
@@ -813,7 +851,7 @@ Async CSS with LoadCSS<span class="note-info">[ Only works if "Inline all header
|
|
813 |
<td><fieldset>
|
814 |
<label for="fastvelocity_min_change_cache_base_url">
|
815 |
<p><input type="text" name="fastvelocity_min_change_cache_base_url" id="fastvelocity_min_change_cache_base_url" value="<?php echo get_option('fastvelocity_min_change_cache_base_url', ''); ?>" size="80" /></p>
|
816 |
-
<p class="description">[ Default cache base url is: <?php echo
|
817 |
</label>
|
818 |
</fieldset></td>
|
819 |
</tr>
|
@@ -946,7 +984,7 @@ for($i=0,$l=count($header);$i<$l;$i++) {
|
|
946 |
|
947 |
# get css from hurl, if available and valid
|
948 |
$tkey = 'fvm-cache-'.$ctime.hash('adler32', $hurl);
|
949 |
-
$newcode = false; $newcode =
|
950 |
if ( $newcode === false) {
|
951 |
$res = fvm_download_and_cache($hurl, $tkey, null, $disable_js_minification, 'js', $handle);
|
952 |
if(is_array($res)) {
|
@@ -1079,7 +1117,7 @@ for($i=0,$l=count($footer);$i<$l;$i++) {
|
|
1079 |
|
1080 |
# get css from hurl, if available and valid
|
1081 |
$tkey = 'fvm-cache-'.$ctime.hash('adler32', $hurl);
|
1082 |
-
$newcode = false; $newcode =
|
1083 |
if ( $newcode === false) {
|
1084 |
$res = fvm_download_and_cache($hurl, $tkey, null, $disable_js_minification, 'js', $handle);
|
1085 |
if(is_array($res)) {
|
@@ -1284,7 +1322,7 @@ if(!$skip_google_fonts && count($google_fonts) > 0) {
|
|
1284 |
|
1285 |
# google fonts download and inlining, ignore logs
|
1286 |
$tkey = 'fvm-cache-'.$ctime.hash('adler32', $concat_google_fonts);
|
1287 |
-
$newcode = false; $newcode =
|
1288 |
if ( $newcode === false) {
|
1289 |
$res = fvm_download_and_cache($concat_google_fonts, $tkey, null, $disable_css_minification, 'css');
|
1290 |
if(is_array($res)) { $newcode = $res['code']; }
|
@@ -1412,7 +1450,7 @@ for($i=0,$l=count($header);$i<$l;$i++) {
|
|
1412 |
|
1413 |
# get css from hurl, if available and valid
|
1414 |
$tkey = 'fvm-cache-'.$ctime.hash('adler32', $hurl);
|
1415 |
-
$newcode = false; $newcode =
|
1416 |
if ( $newcode === false) {
|
1417 |
$res = fvm_download_and_cache($hurl, $tkey, null, $disable_css_minification, 'css', $handle);
|
1418 |
if(is_array($res)) {
|
@@ -1548,7 +1586,7 @@ if(!$skip_google_fonts && count($google_fonts) > 0) {
|
|
1548 |
|
1549 |
# google fonts download and inlining, ignore logs
|
1550 |
$tkey = 'fvm-cache-'.$ctime.hash('adler32', $concat_google_fonts);
|
1551 |
-
$newcode = false; $newcode =
|
1552 |
if ( $newcode === false) {
|
1553 |
$res = fvm_download_and_cache($concat_google_fonts, $tkey, null, $disable_css_minification, 'css');
|
1554 |
if(is_array($res)) { $newcode = $res['code']; }
|
@@ -1673,7 +1711,7 @@ for($i=0,$l=count($footer);$i<$l;$i++) {
|
|
1673 |
|
1674 |
# get css from hurl, if available and valid
|
1675 |
$tkey = 'fvm-cache-'.$ctime.hash('adler32', $hurl);
|
1676 |
-
$newcode = false; $newcode =
|
1677 |
if ( $newcode === false) {
|
1678 |
$res = fvm_download_and_cache($hurl, $tkey, null, $disable_css_minification, 'css', $handle);
|
1679 |
if(is_array($res)) {
|
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.2
|
9 |
License: GPL2
|
10 |
|
11 |
------------------------------------------------------------------------
|
102 |
$blacklist = array_map('trim', explode("\n", get_option('fastvelocity_min_blacklist', '')));
|
103 |
$ignorelist = array_map('trim', explode("\n", get_option('fastvelocity_min_ignorelist', '')));
|
104 |
$merge_allowed_urls = array_map('trim', explode("\n", get_option('fastvelocity_min_merge_allowed_urls', '')));
|
105 |
+
$fvm_enable_purgemenu = get_option('fastvelocity_min_enable_purgemenu');
|
106 |
$default_protocol = get_option('fastvelocity_min_default_protocol', 'dynamic');
|
107 |
$disable_js_merge = get_option('fastvelocity_min_disable_js_merge');
|
108 |
$disable_css_merge = get_option('fastvelocity_min_disable_css_merge');
|
133 |
$critical_path_css = get_option('fastvelocity_min_critical_path_css');
|
134 |
$fvm_cdn_url = get_option('fastvelocity_min_fvm_cdn_url');
|
135 |
|
136 |
+
|
137 |
# default options
|
138 |
$used_css_files = array();
|
139 |
|
142 |
if(!is_array($blacklist) || strlen(implode($blacklist)) == 0) { update_option('fastvelocity_min_blacklist', implode("\n", $exc)); }
|
143 |
|
144 |
# default ignore list
|
145 |
+
$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');
|
146 |
if(!is_array($ignorelist) || strlen(implode($ignorelist)) == 0) { update_option('fastvelocity_min_ignorelist', implode("\n", $exc)); }
|
147 |
|
148 |
|
223 |
}
|
224 |
|
225 |
|
226 |
+
# add admin toolbar
|
227 |
+
if($fvm_enable_purgemenu == true) {
|
228 |
+
add_action( 'admin_bar_menu', 'fastvelocity_admintoolbar', 100 );
|
229 |
+
}
|
230 |
+
|
231 |
+
# admin toolbar processing
|
232 |
+
function fastvelocity_admintoolbar() {
|
233 |
+
if(current_user_can('manage_options')) {
|
234 |
+
global $wp_admin_bar;
|
235 |
+
|
236 |
+
# Create or add new items into the Admin Toolbar.
|
237 |
+
$wp_admin_bar->add_node(array(
|
238 |
+
'id' => 'fvm',
|
239 |
+
'title' => '<span class="ab-icon"></span><span class="ab-label">' . __("FVM Purge",'fvm') . '</span>',
|
240 |
+
'href' => admin_url( '/options-general.php?page=fastvelocity-min&fvm_flush=1' )
|
241 |
+
));
|
242 |
+
|
243 |
+
}
|
244 |
+
}
|
245 |
+
|
246 |
+
|
247 |
# function to list all cache files
|
248 |
function fastvelocity_min_files_callback() {
|
249 |
global $cachedir;
|
294 |
# register plugin settings
|
295 |
function fastvelocity_min_register_settings() {
|
296 |
register_setting('fvm-group', 'fastvelocity_min_ignore');
|
297 |
+
register_setting('fvm-group', 'fastvelocity_min_enable_purgemenu');
|
298 |
register_setting('fvm-group', 'fastvelocity_min_default_protocol');
|
299 |
register_setting('fvm-group', 'fastvelocity_min_disable_js_merge');
|
300 |
register_setting('fvm-group', 'fastvelocity_min_disable_css_merge');
|
338 |
|
339 |
# add settings link on plugin page
|
340 |
function fastvelocity_min_settings_link($links) {
|
341 |
+
if (is_plugin_active(plugin_basename( __FILE__ ))) {
|
342 |
+
$settings_link = '<a href="options-general.php?page=fastvelocity-min&tab=settings">Settings</a>';
|
343 |
+
array_unshift($links, $settings_link);
|
344 |
+
}
|
345 |
return $links;
|
346 |
}
|
347 |
add_filter("plugin_action_links_".plugin_basename(__FILE__), 'fastvelocity_min_settings_link' );
|
365 |
<?php
|
366 |
|
367 |
# purge all caches
|
368 |
+
if(isset($_GET['page']) && $_GET['page'] == 'fastvelocity-min') {
|
369 |
+
if((isset($_POST['purgeall']) && $_POST['purgeall'] == 1) || isset($_GET['fvm_flush']) && $_GET['fvm_flush'] == 1) {
|
370 |
+
fvm_purge_all(); # purge all
|
371 |
+
echo __('<div class="notice notice-success is-dismissible"><p>All caches from <strong>FVM</strong> have been purged!</p></div>');
|
372 |
+
echo fastvelocity_purge_others(); # purge third party caches
|
373 |
+
}
|
374 |
}
|
375 |
+
|
376 |
?>
|
377 |
|
378 |
<h2 class="nav-tab-wrapper wp-clearfix">
|
439 |
<table class="form-table fvm-settings">
|
440 |
<tbody>
|
441 |
|
442 |
+
<tr>
|
443 |
+
<th scope="row">Admin Toolbar</th>
|
444 |
+
<td>
|
445 |
+
<p class="fvm-bold-green fvm-rowintro">Enable the "FVM purge" button on the admin bar.</p>
|
446 |
+
<fieldset>
|
447 |
+
<label for="fastvelocity_min_enable_purgemenu">
|
448 |
+
<input name="fastvelocity_min_enable_purgemenu" type="checkbox" id="fastvelocity_min_enable_purgemenu" value="1" <?php echo checked(1 == get_option('fastvelocity_min_enable_purgemenu'), true, false); ?>>
|
449 |
+
Admin Bar Purge <span class="note-info">[ If selected, a new option to purge FVM cache from the admin bar will show up. ]</span></label>
|
450 |
+
</fieldset></td>
|
451 |
+
</tr>
|
452 |
+
|
453 |
<tr>
|
454 |
<th scope="row">Troubleshooting</th>
|
455 |
<td>
|
834 |
|
835 |
<div style="height: 20px;"></div>
|
836 |
<h2 class="title">Cache Location</h2>
|
837 |
+
<p class="fvm-bold-green">If your server blocks JavaScript on the uploads directory, you can change "wp-content/uploads" with "wp-content/cache" or other allowed public directory.</p>
|
838 |
<table class="form-table fvm-settings">
|
839 |
<tbody>
|
840 |
<tr>
|
851 |
<td><fieldset>
|
852 |
<label for="fastvelocity_min_change_cache_base_url">
|
853 |
<p><input type="text" name="fastvelocity_min_change_cache_base_url" id="fastvelocity_min_change_cache_base_url" value="<?php echo get_option('fastvelocity_min_change_cache_base_url', ''); ?>" size="80" /></p>
|
854 |
+
<p class="description">[ Default cache base url is: <?php echo rtrim(fvm_get_protocol(wp_upload_dir()['baseurl']), '/'); ?> ]</p>
|
855 |
</label>
|
856 |
</fieldset></td>
|
857 |
</tr>
|
984 |
|
985 |
# get css from hurl, if available and valid
|
986 |
$tkey = 'fvm-cache-'.$ctime.hash('adler32', $hurl);
|
987 |
+
$newcode = false; $newcode = fvm_get_transient($tkey);
|
988 |
if ( $newcode === false) {
|
989 |
$res = fvm_download_and_cache($hurl, $tkey, null, $disable_js_minification, 'js', $handle);
|
990 |
if(is_array($res)) {
|
1117 |
|
1118 |
# get css from hurl, if available and valid
|
1119 |
$tkey = 'fvm-cache-'.$ctime.hash('adler32', $hurl);
|
1120 |
+
$newcode = false; $newcode = fvm_get_transient($tkey);
|
1121 |
if ( $newcode === false) {
|
1122 |
$res = fvm_download_and_cache($hurl, $tkey, null, $disable_js_minification, 'js', $handle);
|
1123 |
if(is_array($res)) {
|
1322 |
|
1323 |
# google fonts download and inlining, ignore logs
|
1324 |
$tkey = 'fvm-cache-'.$ctime.hash('adler32', $concat_google_fonts);
|
1325 |
+
$newcode = false; $newcode = fvm_get_transient($tkey);
|
1326 |
if ( $newcode === false) {
|
1327 |
$res = fvm_download_and_cache($concat_google_fonts, $tkey, null, $disable_css_minification, 'css');
|
1328 |
if(is_array($res)) { $newcode = $res['code']; }
|
1450 |
|
1451 |
# get css from hurl, if available and valid
|
1452 |
$tkey = 'fvm-cache-'.$ctime.hash('adler32', $hurl);
|
1453 |
+
$newcode = false; $newcode = fvm_get_transient($tkey);
|
1454 |
if ( $newcode === false) {
|
1455 |
$res = fvm_download_and_cache($hurl, $tkey, null, $disable_css_minification, 'css', $handle);
|
1456 |
if(is_array($res)) {
|
1586 |
|
1587 |
# google fonts download and inlining, ignore logs
|
1588 |
$tkey = 'fvm-cache-'.$ctime.hash('adler32', $concat_google_fonts);
|
1589 |
+
$newcode = false; $newcode = fvm_get_transient($tkey);
|
1590 |
if ( $newcode === false) {
|
1591 |
$res = fvm_download_and_cache($concat_google_fonts, $tkey, null, $disable_css_minification, 'css');
|
1592 |
if(is_array($res)) { $newcode = $res['code']; }
|
1711 |
|
1712 |
# get css from hurl, if available and valid
|
1713 |
$tkey = 'fvm-cache-'.$ctime.hash('adler32', $hurl);
|
1714 |
+
$newcode = false; $newcode = fvm_get_transient($tkey);
|
1715 |
if ( $newcode === false) {
|
1716 |
$res = fvm_download_and_cache($hurl, $tkey, null, $disable_css_minification, 'css', $handle);
|
1717 |
if(is_array($res)) {
|
inc/functions-admin.php
DELETED
@@ -1,75 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/*
|
4 |
-
in development...
|
5 |
-
*/
|
6 |
-
|
7 |
-
# add admin toolbar
|
8 |
-
add_action( 'admin_bar_menu', 'fastvelocity_add_toolbar', 100 );
|
9 |
-
|
10 |
-
|
11 |
-
# admin toolbar processing
|
12 |
-
function fastvelocity_add_toolbar() {
|
13 |
-
if(current_user_can('manage_options')) {
|
14 |
-
global $wp_admin_bar;
|
15 |
-
|
16 |
-
# get cache size
|
17 |
-
$stats = fastvelocity_get_cachestats();
|
18 |
-
$count = $stats['count'];
|
19 |
-
$size = $stats['size'];
|
20 |
-
|
21 |
-
# Create or add new items into the Admin Toolbar.
|
22 |
-
$wp_admin_bar->add_node( array(
|
23 |
-
'id' => 'fvm',
|
24 |
-
'title' => '<span class="ab-icon"></span><span class="ab-label">' . __("Fast Velocity",'fvm') . '</span>',
|
25 |
-
'href' => admin_url( 'options-general.php?page=fastvelocity-min' ),
|
26 |
-
'meta' => array( 'class' => 'bullet-green')
|
27 |
-
));
|
28 |
-
|
29 |
-
# Cache Info node
|
30 |
-
$wp_admin_bar->add_node( array(
|
31 |
-
'id' => 'fvm-cache-info',
|
32 |
-
'title' => '<p class="bold">' . __( "Cache Info", 'fvm' ) . '</p>' .
|
33 |
-
'<table>' .
|
34 |
-
'<tr><td>' . __( "Size", 'fvm' ) . ':</td><td class="size green">' . $size . '</td></tr>' .
|
35 |
-
'<tr><td>' . __( "Files", 'fvm' ) . ':</td><td class="files white">' . $count . '</td></tr>' .
|
36 |
-
'</table>',
|
37 |
-
'parent'=> 'fvm'
|
38 |
-
));
|
39 |
-
|
40 |
-
# Delete Cache node
|
41 |
-
$wp_admin_bar->add_node( array(
|
42 |
-
'id' => 'fvm-delete-cache',
|
43 |
-
'title' => __("Purge Cache",'fvm'),
|
44 |
-
'parent'=> 'fvm'
|
45 |
-
));
|
46 |
-
|
47 |
-
}
|
48 |
-
}
|
49 |
-
|
50 |
-
|
51 |
-
/*
|
52 |
-
# get cache size and count
|
53 |
-
function fastvelocity_get_cachestats() {
|
54 |
-
|
55 |
-
# info
|
56 |
-
$cachepath = fvm_cachepath();
|
57 |
-
$tmpdir = $cachepath['tmpdir'];
|
58 |
-
$cachedir = $cachepath['cachedir'];
|
59 |
-
$search = array($tmpdir, $cachedir);
|
60 |
-
$size = 0;
|
61 |
-
$count = 0;
|
62 |
-
|
63 |
-
foreach ($search as $dir) {
|
64 |
-
if(is_dir(rtrim($dir, '/'))) {
|
65 |
-
if ($handle = opendir($dir.'/')) {
|
66 |
-
while (false !== ($file = readdir($handle))) { $f = $dir.'/'.$file; $size = $size + filesize($f); $count++; }
|
67 |
-
closedir($handle);
|
68 |
-
}
|
69 |
-
}
|
70 |
-
}
|
71 |
-
|
72 |
-
return array('size'=>fastvelocity_format_filesize($size), 'count'=>$count);
|
73 |
-
}
|
74 |
-
*(
|
75 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inc/functions.php
CHANGED
@@ -190,7 +190,7 @@ function fvm_server_is_windows() {
|
|
190 |
function fastvelocity_min_get_js($url, $js, $disable_js_minification) {
|
191 |
|
192 |
# exclude minification on already minified files + jquery (because minification might break those)
|
193 |
-
$excl = array('jquery.js', '.min.js', '-min.js', '/uploads/fusion-scripts/');
|
194 |
foreach($excl as $e) { if (stripos(basename($url), $e) !== false) { $disable_js_minification = true; break; } }
|
195 |
|
196 |
# remove BOM
|
@@ -271,14 +271,18 @@ return $html;
|
|
271 |
|
272 |
|
273 |
# remove all cache files
|
274 |
-
function fastvelocity_rrmdir($
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
|
|
|
|
|
|
|
|
282 |
}
|
283 |
|
284 |
|
@@ -294,10 +298,13 @@ function fastvelocity_format_filesize($bytes, $decimals = 2) {
|
|
294 |
|
295 |
# get cache size and count
|
296 |
function fastvelocity_get_cachestats() {
|
297 |
-
clearstatcache();
|
298 |
-
$dir = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(fvm_cachepath()['cachebase'], FilesystemIterator::SKIP_DOTS));
|
299 |
-
$size = 0;
|
300 |
-
|
|
|
|
|
|
|
301 |
}
|
302 |
|
303 |
|
@@ -376,7 +383,6 @@ if (stripos($hurl, $wp_domain) !== false) {
|
|
376 |
if($type == 'js') { $code = fastvelocity_min_get_js($hurl, file_get_contents($f), $disable_minification); }
|
377 |
else { $code = fastvelocity_min_get_css($hurl, file_get_contents($f).$inline, $disable_minification); }
|
378 |
set_transient($tkey, $code, 7 * DAY_IN_SECONDS );
|
379 |
-
fvm_update_transient_keys($tkey); # keep track
|
380 |
$log = "$printurl --- Debug: $printhandle File was opened from $f ---\n";
|
381 |
return array('log'=>$log, 'code'=>$code);
|
382 |
}
|
@@ -389,7 +395,6 @@ if (stripos($hurl, $wp_domain) !== false) {
|
|
389 |
if($type == 'js') { $code = fastvelocity_min_get_js($hurl, file_get_contents($f), $disable_minification); }
|
390 |
else { $code = fastvelocity_min_get_css($hurl, file_get_contents($f).$inline, $disable_minification); }
|
391 |
set_transient($tkey, $code, 7 * DAY_IN_SECONDS );
|
392 |
-
fvm_update_transient_keys($tkey); # keep track
|
393 |
$log = "$printurl --- Debug: $printhandle File was opened from $f ---\n";
|
394 |
return array('log'=>$log, 'code'=>$code);
|
395 |
}
|
@@ -404,7 +409,6 @@ if($code !== false) {
|
|
404 |
if($type == 'js') { $code = fastvelocity_min_get_js($hurl, $code, $disable_minification); }
|
405 |
else { $code = fastvelocity_min_get_css($hurl, $code.$inline, $disable_minification); }
|
406 |
set_transient($tkey, $code, 7 * DAY_IN_SECONDS );
|
407 |
-
fvm_update_transient_keys($tkey); # keep track
|
408 |
$log = "$printurl --- Debug: $printhandle Fetched url at $hurl \n";
|
409 |
return array('log'=>$log, 'code'=>$code);
|
410 |
}
|
@@ -418,7 +422,6 @@ if(stripos($hurl, $wp_domain) !== false && home_url() != site_url()) {
|
|
418 |
if($type == 'js') { $code = fastvelocity_min_get_js($hurl, $code, $disable_minification); }
|
419 |
else { $code = fastvelocity_min_get_css($hurl, $code.$inline, $disable_minification); }
|
420 |
set_transient($tkey, $code, 7 * DAY_IN_SECONDS );
|
421 |
-
fvm_update_transient_keys($tkey); # keep track
|
422 |
$log = "$printurl --- Debug: $printhandle Fetched url at $hurl \n";
|
423 |
return array('log'=>$log, 'code'=>$code);
|
424 |
}
|
@@ -434,7 +437,6 @@ if (stripos($hurl, $wp_domain) !== false) {
|
|
434 |
if($type == 'js') { $code = fastvelocity_min_get_js($hurl, file_get_contents($f), $disable_minification); }
|
435 |
else { $code = fastvelocity_min_get_css($hurl, file_get_contents($f).$inline, $disable_minification); }
|
436 |
set_transient($tkey, $code, 7 * DAY_IN_SECONDS );
|
437 |
-
fvm_update_transient_keys($tkey); # keep track
|
438 |
$log = "$printurl --- Debug: $printhandle File was opened from $f ---\n";
|
439 |
return array('log'=>$log, 'code'=>$code);
|
440 |
}
|
@@ -447,7 +449,6 @@ if (stripos($hurl, $wp_domain) !== false) {
|
|
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 |
set_transient($tkey, $code, 7 * DAY_IN_SECONDS );
|
450 |
-
fvm_update_transient_keys($tkey); # keep track
|
451 |
$log = "$printurl --- Debug: $printhandle File was opened from $f ---\n";
|
452 |
return array('log'=>$log, 'code'=>$code);
|
453 |
}
|
@@ -660,39 +661,88 @@ function fvm_get_protocol($url) {
|
|
660 |
return $url;
|
661 |
}
|
662 |
|
663 |
-
# keep track of transients, whenever we save a transient.
|
664 |
-
function fvm_update_transient_keys($new_transient_key) {
|
665 |
-
$transient_keys = get_option('fvm_transient_keys'); # get
|
666 |
-
$transient_keys[]= $new_transient_key; # append
|
667 |
-
update_option( 'fvm_transient_keys', $transient_keys); # save
|
668 |
-
}
|
669 |
|
670 |
# keep track of transients, dump our plugin transients as needed
|
671 |
function fvm_transients_purge() {
|
672 |
-
|
673 |
-
|
674 |
-
update_option(
|
675 |
-
|
676 |
-
|
677 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
678 |
|
679 |
# purge all caches
|
680 |
function fvm_purge_all() {
|
681 |
|
682 |
-
# get cache directories and urls
|
683 |
-
$cachepath = fvm_cachepath();
|
684 |
-
$
|
685 |
-
|
686 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
687 |
|
688 |
-
# delete minification files and transients
|
689 |
-
if(!is_dir($cachedir)) { return false; }
|
690 |
-
fastvelocity_rrmdir($cachedir);
|
691 |
-
fvm_transients_purge();
|
692 |
|
693 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
694 |
}
|
695 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
696 |
|
697 |
|
698 |
# exclude processing from some pages / posts / contents
|
@@ -765,12 +815,12 @@ function fastvelocity_ie_blacklist($url) {
|
|
765 |
function fastvelocity_download($url, $tkey, $ttl) {
|
766 |
|
767 |
# rate limit requests, prevent slowdowns
|
768 |
-
$rtlim = false; $rtlim =
|
769 |
if ( $rtlim !== false) { return false; }
|
770 |
|
771 |
# info (needed for google fonts woff files + hinted fonts)
|
772 |
$uagent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586';
|
773 |
-
$data = false; $data =
|
774 |
if ( $data === false) {
|
775 |
|
776 |
# get updated list from our api and cache it for 24 hours
|
@@ -779,8 +829,7 @@ function fastvelocity_download($url, $tkey, $ttl) {
|
|
779 |
if($res_code == '200') {
|
780 |
$data = wp_remote_retrieve_body($response);
|
781 |
if(strlen($data) > 1 && $ttl > 0) {
|
782 |
-
|
783 |
-
fvm_update_transient_keys($tkey); # keep track
|
784 |
return $data;
|
785 |
}
|
786 |
}
|
@@ -789,14 +838,13 @@ function fastvelocity_download($url, $tkey, $ttl) {
|
|
789 |
if(function_exists('curl_version')) {
|
790 |
$curl = fvm_file_get_contents_curl($url, $uagent);
|
791 |
if(!empty($curl) && strlen($curl) > 1 && $ttl > 0) {
|
792 |
-
|
793 |
-
fvm_update_transient_keys($tkey); # keep track
|
794 |
return $data;
|
795 |
}
|
796 |
}
|
797 |
|
798 |
# error
|
799 |
-
|
800 |
return false;
|
801 |
}
|
802 |
|
@@ -894,3 +942,4 @@ if (method_exists('WpeCommon', 'purge_varnish_cache')) { WpeCommon::purge_varnis
|
|
894 |
}
|
895 |
|
896 |
|
|
190 |
function fastvelocity_min_get_js($url, $js, $disable_js_minification) {
|
191 |
|
192 |
# exclude minification on already minified files + jquery (because minification might break those)
|
193 |
+
$excl = array('jquery.js', '.min.js', '-min.js', '/uploads/fusion-scripts/', '/min/');
|
194 |
foreach($excl as $e) { if (stripos(basename($url), $e) !== false) { $disable_js_minification = true; break; } }
|
195 |
|
196 |
# remove BOM
|
271 |
|
272 |
|
273 |
# remove all cache files
|
274 |
+
function fastvelocity_rrmdir($path) {
|
275 |
+
clearstatcache();
|
276 |
+
if(is_dir($path)) {
|
277 |
+
$i = new DirectoryIterator($path);
|
278 |
+
foreach($i as $f){
|
279 |
+
if($f->isFile()){ unlink($f->getRealPath());
|
280 |
+
} else if(!$f->isDot() && $f->isDir()){
|
281 |
+
fastvelocity_rrmdir($f->getRealPath());
|
282 |
+
rmdir($f->getRealPath());
|
283 |
+
}
|
284 |
+
}
|
285 |
+
}
|
286 |
}
|
287 |
|
288 |
|
298 |
|
299 |
# get cache size and count
|
300 |
function fastvelocity_get_cachestats() {
|
301 |
+
clearstatcache();
|
302 |
+
$dir = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(fvm_cachepath()['cachebase'], FilesystemIterator::SKIP_DOTS));
|
303 |
+
$size = 0;
|
304 |
+
foreach ($dir as $file) {
|
305 |
+
$size += $file->getSize();
|
306 |
+
}
|
307 |
+
return fastvelocity_format_filesize($size);
|
308 |
}
|
309 |
|
310 |
|
383 |
if($type == 'js') { $code = fastvelocity_min_get_js($hurl, file_get_contents($f), $disable_minification); }
|
384 |
else { $code = fastvelocity_min_get_css($hurl, file_get_contents($f).$inline, $disable_minification); }
|
385 |
set_transient($tkey, $code, 7 * DAY_IN_SECONDS );
|
|
|
386 |
$log = "$printurl --- Debug: $printhandle File was opened from $f ---\n";
|
387 |
return array('log'=>$log, 'code'=>$code);
|
388 |
}
|
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 |
}
|
409 |
if($type == 'js') { $code = fastvelocity_min_get_js($hurl, $code, $disable_minification); }
|
410 |
else { $code = fastvelocity_min_get_css($hurl, $code.$inline, $disable_minification); }
|
411 |
set_transient($tkey, $code, 7 * DAY_IN_SECONDS );
|
|
|
412 |
$log = "$printurl --- Debug: $printhandle Fetched url at $hurl \n";
|
413 |
return array('log'=>$log, 'code'=>$code);
|
414 |
}
|
422 |
if($type == 'js') { $code = fastvelocity_min_get_js($hurl, $code, $disable_minification); }
|
423 |
else { $code = fastvelocity_min_get_css($hurl, $code.$inline, $disable_minification); }
|
424 |
set_transient($tkey, $code, 7 * DAY_IN_SECONDS );
|
|
|
425 |
$log = "$printurl --- Debug: $printhandle Fetched url at $hurl \n";
|
426 |
return array('log'=>$log, 'code'=>$code);
|
427 |
}
|
437 |
if($type == 'js') { $code = fastvelocity_min_get_js($hurl, file_get_contents($f), $disable_minification); }
|
438 |
else { $code = fastvelocity_min_get_css($hurl, file_get_contents($f).$inline, $disable_minification); }
|
439 |
set_transient($tkey, $code, 7 * DAY_IN_SECONDS );
|
|
|
440 |
$log = "$printurl --- Debug: $printhandle File was opened from $f ---\n";
|
441 |
return array('log'=>$log, 'code'=>$code);
|
442 |
}
|
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 |
}
|
661 |
return $url;
|
662 |
}
|
663 |
|
|
|
|
|
|
|
|
|
|
|
|
|
664 |
|
665 |
# keep track of transients, dump our plugin transients as needed
|
666 |
function fvm_transients_purge() {
|
667 |
+
|
668 |
+
# last cache update to now
|
669 |
+
update_option('fvm-last-cache-update', time());
|
670 |
+
|
671 |
+
# delete legacy transients
|
672 |
+
$tk = get_option( 'fvm_transient_keys' );
|
673 |
+
if($tk !== false) {
|
674 |
+
delete_option('fvm_transient_keys');
|
675 |
+
if(is_array($tk)) {
|
676 |
+
foreach( $tk as $t ) {
|
677 |
+
delete_transient($t);
|
678 |
+
}
|
679 |
+
}
|
680 |
+
}
|
681 |
+
}
|
682 |
|
683 |
# purge all caches
|
684 |
function fvm_purge_all() {
|
685 |
|
686 |
+
# get cache directories and urls
|
687 |
+
$cachepath = fvm_cachepath();
|
688 |
+
$cachebase = $cachepath['cachebase'];
|
689 |
+
|
690 |
+
# delete minification files and transients
|
691 |
+
if(!is_dir($cachebase)) {
|
692 |
+
return false;
|
693 |
+
}
|
694 |
+
|
695 |
+
# remove cache files, set last update and clean legacy transients
|
696 |
+
fastvelocity_rrmdir($cachebase);
|
697 |
+
fvm_transients_purge();
|
698 |
+
return true;
|
699 |
+
}
|
700 |
|
|
|
|
|
|
|
|
|
701 |
|
702 |
+
# get transients on the disk
|
703 |
+
function fvm_get_transient($key) {
|
704 |
+
$cachepath = fvm_cachepath();
|
705 |
+
$tmpdir = $cachepath['tmpdir'];
|
706 |
+
$f = $tmpdir.'/'.$key.'.transient';
|
707 |
+
clearstatcache();
|
708 |
+
if(file_exists($tmpdir.'/'.$key)) {
|
709 |
+
return file_get_contents($f);
|
710 |
+
} else {
|
711 |
+
return false;
|
712 |
+
}
|
713 |
}
|
714 |
|
715 |
+
# set transients on the disk
|
716 |
+
function fvm_set_transient($key, $code, $ttl) {
|
717 |
+
if(is_null($code) || empty($code)) { return false; }
|
718 |
+
$cachepath = fvm_cachepath();
|
719 |
+
$tmpdir = $cachepath['tmpdir'];
|
720 |
+
$f = $tmpdir.'/'.$key.'.transient';
|
721 |
+
$e = $tmpdir.'/'.$key.'.exp';
|
722 |
+
clearstatcache();
|
723 |
+
|
724 |
+
# update or not?
|
725 |
+
if(!file_exists($f)) {
|
726 |
+
$write = 1;
|
727 |
+
} else {
|
728 |
+
if(file_exists($e)) {
|
729 |
+
$t = file_get_contents($e);
|
730 |
+
if(is_numeric($t) && $t < time()) {
|
731 |
+
$write = 1;
|
732 |
+
}
|
733 |
+
}
|
734 |
+
}
|
735 |
+
|
736 |
+
# proceed
|
737 |
+
if(isset($write) && $write == 1) {
|
738 |
+
file_put_contents($f, $code);
|
739 |
+
file_put_contents($e, time()+$ttl);
|
740 |
+
return true;
|
741 |
+
}
|
742 |
+
|
743 |
+
# fallback
|
744 |
+
return false;
|
745 |
+
}
|
746 |
|
747 |
|
748 |
# exclude processing from some pages / posts / contents
|
815 |
function fastvelocity_download($url, $tkey, $ttl) {
|
816 |
|
817 |
# rate limit requests, prevent slowdowns
|
818 |
+
$rtlim = false; $rtlim = fvm_get_transient($tkey.'_access');
|
819 |
if ( $rtlim !== false) { return false; }
|
820 |
|
821 |
# info (needed for google fonts woff files + hinted fonts)
|
822 |
$uagent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586';
|
823 |
+
$data = false; $data = fvm_get_transient($tkey);
|
824 |
if ( $data === false) {
|
825 |
|
826 |
# get updated list from our api and cache it for 24 hours
|
829 |
if($res_code == '200') {
|
830 |
$data = wp_remote_retrieve_body($response);
|
831 |
if(strlen($data) > 1 && $ttl > 0) {
|
832 |
+
fvm_set_transient($tkey, $data, $ttl);
|
|
|
833 |
return $data;
|
834 |
}
|
835 |
}
|
838 |
if(function_exists('curl_version')) {
|
839 |
$curl = fvm_file_get_contents_curl($url, $uagent);
|
840 |
if(!empty($curl) && strlen($curl) > 1 && $ttl > 0) {
|
841 |
+
fvm_set_transient($tkey, $data, $ttl);
|
|
|
842 |
return $data;
|
843 |
}
|
844 |
}
|
845 |
|
846 |
# error
|
847 |
+
fvm_set_transient($tkey.'_access', "Failed to fetch: $url on ".current_time('timestamp'), $ttl);
|
848 |
return false;
|
849 |
}
|
850 |
|
942 |
}
|
943 |
|
944 |
|
945 |
+
|
libs/CSSTidy/class.csstidy.php
ADDED
@@ -0,0 +1,1296 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
ADDED
@@ -0,0 +1,963 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
ADDED
@@ -0,0 +1,446 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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(' ', '', $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
ADDED
@@ -0,0 +1,646 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
ADDED
@@ -0,0 +1,309 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 (code 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 & 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 (Code 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 :';
|
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 : <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 :';
|
186 |
+
$lang['fr'][9] = 'Code CSS :';
|
187 |
+
$lang['fr'][10] = 'CSS en provenance d’une URL :<br />';
|
188 |
+
$lang['fr'][11] = 'Mise en page du code :';
|
189 |
+
$lang['fr'][12] = 'Compression (mise en page du code) :';
|
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 :';
|
204 |
+
$lang['fr'][27] = 'Minuscule';
|
205 |
+
$lang['fr'][28] = 'CSS non valide ou URL incorrecte !';
|
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 & 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 : ceci peut changer le comportement de votre code CSS !';
|
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] = '由於比較少換行字元, 會有更大的壓縮比率(複製&貼上沒有用)';
|
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
ADDED
@@ -0,0 +1,386 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
+
?>
|
readme.txt
CHANGED
@@ -2,7 +2,7 @@
|
|
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.
|
6 |
Tested up to: 4.9.6
|
7 |
License: GPLv3 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
@@ -271,6 +271,11 @@ Note: Kindly re-save all options and purge all caches (the plugin cache as well
|
|
271 |
|
272 |
== Changelog ==
|
273 |
|
|
|
|
|
|
|
|
|
|
|
274 |
= 2.3.1 [2018.06.01] =
|
275 |
* bug fixes and performance tweaks for the "fix page editors" option
|
276 |
|
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.2
|
6 |
Tested up to: 4.9.6
|
7 |
License: GPLv3 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
271 |
|
272 |
== Changelog ==
|
273 |
|
274 |
+
= 2.3.2 [2018.06.03] =
|
275 |
+
* added some compatibility fixes when merging and minifying JS files
|
276 |
+
* added an option to enable an "FVM Purge" button on the admin bar
|
277 |
+
* moved all large transients (cached css or js code) to temporary disk files to reduce the database load
|
278 |
+
|
279 |
= 2.3.1 [2018.06.01] =
|
280 |
* bug fixes and performance tweaks for the "fix page editors" option
|
281 |
|