4 * CSSTidy - CSS Optimiser Interface
5 * This file produces an XHTML interface for optimising CSS code
7 * Copyright 2005, 2006, 2007 Florian Schmitz
9 * This file is part of CSSTidy.
11 * CSSTidy is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation; either version 2.1 of the License, or
14 * (at your option) any later version.
16 * CSSTidy is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 * @license http://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
26 * @author Florian Schmitz (floele at gmail dot com) 2005-2007
27 * @author Brett Zamir (brettz9 at yahoo dot com) 2007
30 require('class.csstidy.php');
31 require('lang.inc.php');
34 if (get_magic_quotes_gpc()) {
35 if (isset($_REQUEST['css_text'])) {
36 $_REQUEST['css_text'] = stripslashes($_REQUEST['css_text']);
38 if (isset($_REQUEST['custom'])) {
39 $_REQUEST['custom'] = stripslashes($_REQUEST['custom']);
41 if (isset($_COOKIE['custom_template'])) {
42 $_COOKIE['custom_template'] = stripslashes($_COOKIE['custom_template']);
46 function rmdirr($dirname,$oc=0)
49 if (!file_exists($dirname)) {
52 // Simple delete for a file
53 if (is_file($dirname) && (time()-fileatime($dirname))>3600) {
54 return unlink($dirname);
56 // Loop through the folder
60 while (false !== $entry = $dir->read()) {
62 if ($entry === '.' ||
$entry === '..') {
66 rmdirr($dirname.'/'.$entry,$oc);
73 return rmdir($dirname);
77 function options($options, $selected = null, $labelIsValue = false)
81 settype($selected, 'array');
82 settype($options, 'array');
84 foreach ($options as $value=>$label)
86 if (is_array($label)) {
90 $label = htmlspecialchars($label, ENT_QUOTES
, 'utf-8');
91 $value = $labelIsValue ?
$label
92 : htmlspecialchars($value, ENT_QUOTES
, 'utf-8');
94 $html .= '<option value="'.$value.'"';
95 if (in_array($value, $selected)) {
96 $html .= ' selected="selected"';
98 $html .= '>'.$label.'</option>';
101 $html .= '<option value="0">---</option>';
107 $css = new csstidy();
108 $is_custom = isset($_REQUEST['custom']) && !empty($_REQUEST['custom']) && isset($_REQUEST['template']) && ($_REQUEST['template'] === '4');
111 setcookie ('custom_template', $_REQUEST['custom'], time()+
360000);
116 if(isset($_REQUEST['case_properties'])) $css->set_cfg('case_properties',$_REQUEST['case_properties']);
117 if(isset($_REQUEST['lowercase'])) $css->set_cfg('lowercase_s',true);
118 if(!isset($_REQUEST['compress_c']) && isset($_REQUEST['post'])) $css->set_cfg('compress_colors',false);
119 if(!isset($_REQUEST['compress_fw']) && isset($_REQUEST['post'])) $css->set_cfg('compress_font-weight',false);
120 if(isset($_REQUEST['merge_selectors'])) $css->set_cfg('merge_selectors', $_REQUEST['merge_selectors']);
121 if(isset($_REQUEST['optimise_shorthands'])) $css->set_cfg('optimise_shorthands',$_REQUEST['optimise_shorthands']);
122 if(!isset($_REQUEST['rbs']) && isset($_REQUEST['post'])) $css->set_cfg('remove_bslash',false);
123 if(isset($_REQUEST['preserve_css'])) $css->set_cfg('preserve_css',true);
124 if(isset($_REQUEST['sort_sel'])) $css->set_cfg('sort_selectors',true);
125 if(isset($_REQUEST['sort_de'])) $css->set_cfg('sort_properties',true);
126 if(isset($_REQUEST['remove_last_sem'])) $css->set_cfg('remove_last_;',true);
127 if(isset($_REQUEST['discard'])) $css->set_cfg('discard_invalid_properties',true);
128 if(isset($_REQUEST['css_level'])) $css->set_cfg('css_level',$_REQUEST['css_level']);
129 if(isset($_REQUEST['timestamp'])) $css->set_cfg('timestamp',true);
132 // This by itself is enough since our scripts don't use DOM to create elements (in which case the namespace aware ones
133 // should be used when serving as application/xhtml+xml but not when served as text/html ;
134 // also, case will be different when retrieving element names, as HTML DOM returns in upper case,
135 // genuine XHTML DOM (when XHTML served as such) as lower
136 if (stristr($_SERVER['HTTP_ACCEPT'], 'application/xhtml+xml')) {
137 $http_accept = 'application/xhtml+xml';
139 elseif (stristr($_SERVER['HTTP_ACCEPT'], 'application/xml')) {
140 $http_accept = 'application/xml';
142 elseif (stristr($_SERVER['HTTP_ACCEPT'], 'text/xml')) {
143 $http_accept = 'text/xml';
145 elseif (stristr($_SERVER['HTTP_USER_AGENT'], 'Opera ') ||
stristr($_SERVER['HTTP_USER_AGENT'], 'Opera/')) {
146 preg_match('@Opera/(\d)@', $_SERVER['HTTP_USER_AGENT'], $matches);
147 if (isset($matches[1]) && $matches[1] >= 7) {
148 $http_accept = 'application/xhtml+xml';
151 $http_accept = 'text/html';
155 $http_accept = 'text/html';
158 header('Content-Type: '.$http_accept.'; charset=utf-8');
160 if ($http_accept === 'text/html') {
162 <!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
163 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
168 <!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
172 <html xmlns
="http://www.w3.org/1999/xhtml" xml
:lang
="<?php echo $l; ?>">
174 <meta http
-equiv
="Content-Type" content
="application/xhtml+xml; charset=utf-8" />
176 <?php
echo $lang[$l][0]; echo $css->version
; ?
>)
178 <link rel
="stylesheet" href
="cssparse.css" type
="text/css" />
179 <script type
="text/javascript"><!--/*--><![CDATA[/*><!--*/
180 function enable_disable_preserve()
182 var inputs
= new Array('sort_sel', 'sort_de', 'optimise_shorthands', 'merge_selectors', 'none');
183 var inputs_v
= new Array( true, true, true, true, false);
184 for(var i
= 0; i
< inputs
.length
; i++
)
186 if(document
.getElementById('preserve_css').checked
) {
187 document
.getElementById(inputs
[i
]).disabled
= inputs_v
[i
];
189 document
.getElementById(inputs
[i
]).disabled
= !inputs_v
[i
];
195 if (window
.clipboardData
) { // Feature testing
196 window
.clipboardData
.setData('Text',document
.getElementById("copytext").innerText
);
198 else if (navigator
.userAgent
.indexOf('Gecko') != -1
199 && navigator
.userAgent
.indexOf('Apple') == -1
202 netscape
.security
.PrivilegeManager
.enablePrivilege('UniversalXPConnect');
203 const gClipboardHelper
= Components
.classes
["@mozilla.org/widget/clipboardhelper;1"].
204 getService(Components
.interfaces
.nsIClipboardHelper
);
205 gClipboardHelper
.copyString(document
.getElementById("copytext").innerHTML
);
208 alert(e+
"\n\n"+
"<?php echo $lang[$l][66] ?>");
212 alert("<?php echo $lang[$l][60]; ?>");
218 <body onload
="enable_disable_preserve()">
219 <div
><h1 style
="display:inline">
220 <?php
echo $lang[$l][1]; ?
>
222 <?php
echo $lang[$l][2]; ?
> <a
223 href
="http://csstidy.sourceforge.net/">csstidy
</a
> <?php
echo $css->version
; ?
>)
225 <?php
echo $lang[$l][39]; ?
>: <a hreflang
="en" href
="?lang=en">English
</a
> <a hreflang
="de" href
="?lang=de">Deutsch
</a
> <a hreflang
="fr" href
="?lang=fr">French
</a
> <a hreflang
="zh" href
="?lang=zh">Chinese
</a
></p
>
226 <p
><?php
echo $lang[$l][4]; ?
>
227 <?php
echo $lang[$l][6]; ?
>
230 <form method
="post" action
="">
232 <fieldset id
="field_input">
233 <legend
><?php
echo $lang[$l][8]; ?
></legend
> <label
for="css_text"
234 class="block"><?php
echo $lang[$l][9]; ?
></label
><textarea id
="css_text" name
="css_text" rows
="20" cols
="35"><?php
if(isset($_REQUEST['css_text'])) echo htmlspecialchars($_REQUEST['css_text'], ENT_QUOTES
, "utf-8"); ?
></textarea
>
235 <label
for="url"><?php
echo $lang[$l][10]; ?
></label
> <input type
="text"
236 name
="url" id
="url" <?php
if(isset($_REQUEST['url']) &&
237 !empty($_REQUEST['url'])) echo 'value="',htmlspecialchars($_REQUEST['url'], ENT_QUOTES
, 'utf-8'),'"'; ?
>
239 <input type
="submit" value
="<?php echo $lang[$l][35]; ?>" id
="submit" />
242 <fieldset id
="code_layout">
243 <legend
><?php
echo $lang[$l][11]; ?
></legend
> <label
for="template"
244 class="block"><?php
echo $lang[$l][12]; ?
></label
> <select
245 id
="template" name
="template" style
="margin-bottom:1em;">
247 $num = (isset($_REQUEST['template'])) ?
intval($_REQUEST['template']) : 1;
248 echo options(array(3 => $lang[$l][13], 2 => $lang[$l][14], 1 => $lang[$l][15], 0 => $lang[$l][16], 4 => $lang[$l][17]), $num);
251 <label
for="custom" class="block">
252 <?php
echo $lang[$l][18]; ?
> </label
> <textarea id
="custom"
253 name
="custom" cols
="33" rows
="4"><?php
255 htmlspecialchars($_REQUEST['custom'], ENT_QUOTES
, 'utf-8');
256 elseif(isset($_COOKIE['custom_template']) &&
257 !empty($_COOKIE['custom_template'])) echo
258 htmlspecialchars($_COOKIE['custom_template'], ENT_QUOTES
, 'utf-8');
261 <fieldset id
="options">
262 <legend
><?php
echo $lang[$l][19]; ?
></legend
>
264 <input onchange
="enable_disable_preserve()" type
="checkbox" name
="preserve_css" id
="preserve_css"
265 <?php
if($css->get_cfg('preserve_css')) echo 'checked="checked"'; ?
> />
266 <label
for="preserve_css" title
="<?php echo $lang[$l][52]; ?>" class="help"><?php
echo $lang[$l][51]; ?
></label
><br
/>
269 <input type
="checkbox" name
="sort_sel" id
="sort_sel"
270 <?php
if($css->get_cfg('sort_selectors')) echo 'checked="checked"'; ?
> />
271 <label
for="sort_sel" title
="<?php echo $lang[$l][41]; ?>" class="help"><?php
echo $lang[$l][20]; ?
></label
><br
/>
274 <input type
="checkbox" name
="sort_de" id
="sort_de"
275 <?php
if($css->get_cfg('sort_properties')) echo 'checked="checked"'; ?
> />
276 <label
for="sort_de"><?php
echo $lang[$l][21]; ?
></label
><br
/>
279 <label
for="merge_selectors"><?php
echo $lang[$l][22]; ?
></label
>
280 <select style
="width:15em;" name
="merge_selectors" id
="merge_selectors">
281 <?php
echo options(array('0' => $lang[$l][47], '1' => $lang[$l][48], '2' => $lang[$l][49]), $css->get_cfg('merge_selectors')); ?
>
284 <label
for="optimise_shorthands"><?php
echo $lang[$l][23]; ?
></label
>
285 <select name
="optimise_shorthands" id
="optimise_shorthands">
286 <?php
echo options(array($lang[$l][54], $lang[$l][55], $lang[$l][56]), $css->get_cfg('optimise_shorthands')); ?
>
290 <input type
="checkbox" name
="compress_c" id
="compress_c"
291 <?php
if($css->get_cfg('compress_colors')) echo 'checked="checked"';?
> />
292 <label
for="compress_c"><?php
echo $lang[$l][24]; ?
></label
><br
/>
295 <input type
="checkbox" name
="compress_fw" id
="compress_fw"
296 <?php
if($css->get_cfg('compress_font-weight')) echo 'checked="checked"';?
> />
297 <label
for="compress_fw"><?php
echo $lang[$l][45]; ?
></label
><br
/>
300 <input type
="checkbox" name
="lowercase" id
="lowercase" value
="lowercase"
301 <?php
if($css->get_cfg('lowercase_s')) echo 'checked="checked"'; ?
> />
302 <label title
="<?php echo $lang[$l][30]; ?>" class="help" for="lowercase"><?php
echo $lang[$l][25]; ?
></label
><br
/>
305 <?php
echo $lang[$l][26]; ?
><br
/>
306 <input type
="radio" name
="case_properties" id
="none" value
="0"
307 <?php
if($css->get_cfg('case_properties') === 0) echo 'checked="checked"'; ?
> />
308 <label
for="none"><?php
echo $lang[$l][53]; ?
></label
>
309 <input type
="radio" name
="case_properties" id
="lower_yes" value
="1"
310 <?php
if($css->get_cfg('case_properties') === 1) echo 'checked="checked"'; ?
> />
311 <label
for="lower_yes"><?php
echo $lang[$l][27]; ?
></label
>
312 <input type
="radio" name
="case_properties" id
="upper_yes" value
="2"
313 <?php
if($css->get_cfg('case_properties') === 2) echo 'checked="checked"'; ?
> />
314 <label
for="upper_yes"><?php
echo $lang[$l][29]; ?
></label
><br
/>
316 <input type
="checkbox" name
="rbs" id
="rbs"
317 <?php
if($css->get_cfg('remove_bslash')) echo 'checked="checked"'; ?
> />
318 <label
for="rbs"><?php
echo $lang[$l][31]; ?
></label
><br
/>
321 <input type
="checkbox" id
="remove_last_sem" name
="remove_last_sem"
322 <?php
if($css->get_cfg('remove_last_;')) echo 'checked="checked"'; ?
> />
323 <label
for="remove_last_sem"><?php
echo $lang[$l][42]; ?
></label
><br
/>
326 <input type
="checkbox" id
="discard" name
="discard"
327 <?php
if($css->get_cfg('discard_invalid_properties')) echo 'checked="checked"'; ?
> />
328 <label
for="discard"><?php
echo $lang[$l][43]; ?
></label
>
329 <select name
="css_level"><?php
echo options(array('CSS2.1','CSS2.0','CSS1.0'),$css->get_cfg('css_level'), true); ?
></select
><br
/>
332 <input type
="checkbox" id
="timestamp" name
="timestamp"
333 <?php
if($css->get_cfg('timestamp')) echo 'checked="checked"'; ?
> />
334 <label
for="timestamp"><?php
echo $lang[$l][57]; ?
></label
><br
/>
336 <input type
="checkbox" id
="whole_file" name
="whole_file"
337 <?php
if(isset($_REQUEST['whole_file'])) echo 'checked="checked"'; ?
> />
338 <label
for="whole_file"><?php
echo $lang[$l][63]; ?
></label
><br
/>
341 <input type
="checkbox" name
="file_output" id
="file_output" value
="file_output"
342 <?php
if(isset($_REQUEST['file_output'])) echo 'checked="checked"'; ?
> />
343 <label
class="help" title
="<?php echo $lang[$l][34]; ?>" for="file_output">
344 <strong
><?php
echo $lang[$l][33]; ?
></strong
>
348 <input type
="hidden" name
="post" />
357 $url = (isset($_REQUEST['url']) && !empty($_REQUEST['url'])) ?
$_REQUEST['url'] : false;
359 if(isset($_REQUEST['template']))
361 switch($_REQUEST['template'])
366 $css->load_template($_REQUEST['custom'],false);
371 $css->load_template('highest_compression');
375 $css->load_template('high_compression');
379 $css->load_template('low_compression');
386 if(substr($_REQUEST['url'],0,7) !== 'http://')
388 $_REQUEST['url'] = 'http://'.$_REQUEST['url'];
390 $result = $css->parse_from_url($_REQUEST['url'],0);
392 elseif(isset($_REQUEST['css_text']) && strlen($_REQUEST['css_text'])>5)
394 $result = $css->parse($_REQUEST['css_text']);
399 $ratio = $css->print->get_ratio();
400 $diff = $css->print->get_diff();
401 if(isset($_REQUEST['file_output']))
403 $filename = md5(mt_rand().time().mt_rand());
404 if (!is_dir('temp')) {
405 $madedir = mkdir('temp');
407 print 'Could not make directory "temp" in '.dirname(__FILE__
);
411 $handle = fopen('temp/'.$filename.'.css','w');
413 if(fwrite($handle,$css->print->plain()))
420 if($ratio>0) $ratio = '<span style="color:green;">'.$ratio.'%</span>
421 ('.$diff.' Bytes)'; else $ratio = '<span
422 style="color:red;">'.$ratio.'%</span> ('.$diff.' Bytes)';
423 if(count($css->log
) > 0): ?
>
424 <fieldset id
="messages"><legend
>Messages
</legend
>
426 foreach($css->log
as $line => $array)
428 echo '<dt>',$line,'</dt>';
429 $array_size = count($array);
430 for($i = 0; $i < $array_size; ++
$i)
432 echo '<dd class="',$array[$i]['t'],'">',$array[$i]['m'],'</dd>';
438 echo '<fieldset><legend>',$lang[$l][37],': ',$css->print->size('input'),'KB, ',$lang[$l][38],':',$css->print->size('output'),'KB, ',$lang[$l][36],': ',$ratio;
441 echo ' - <a href="temp/',$filename,'.css">Download</a>';
443 echo ' - <a href="javascript:ClipBoard()">',$lang[$l][58],'</a>';
445 echo '<code id="copytext">';
446 echo $css->print->formatted();
447 echo '</code></fieldset><div><br /></div>';
449 echo '<fieldset class="code_output"><legend>',$lang[$l][64],'</legend>';
450 echo '<textarea rows="10" cols="80">';
452 if(isset($_REQUEST['whole_file'])) {
453 echo htmlspecialchars($css->print->formatted_page('xhtml1.1', false, '', 'en'), ENT_QUOTES
, 'utf-8');
456 echo htmlspecialchars('<code id="copytext">', ENT_QUOTES
, 'utf-8'),"\n";
457 echo htmlspecialchars($css->print->formatted()."\n".'</code>', ENT_QUOTES
, 'utf-8');
459 echo '</textarea></fieldset>';
460 echo '<fieldset class="code_output"><legend>',$lang[$l][65],'</legend>';
461 echo '<textarea rows="10" cols="30">';
463 echo file_get_contents('cssparsed.css');
466 echo '</fieldset><p><a href="javascript:scrollTo(0,0)">↑ ',$lang[$l][59],'</a></p>';
469 elseif(isset($_REQUEST['css_text']) ||
isset($_REQUEST['url'])) {
470 echo '<p class="important">',$lang[$l][28],'</p>';
473 <p style
="text-align:center;font-size:.8em;clear:both;">
474 <?php
echo $lang[$l][61] ?
> <a
475 href
="http://csstidy.sourceforge.net/contact.php"><?php
echo $lang[$l][62] ?
></a
>.