Viewing file: css.php (9.33 KB) -rw-rw-r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php /** * DokuWiki StyleSheet creator * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Andreas Gohr <andi@splitbrain.org> */
if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../'); if(!defined('NOSESSION')) define('NOSESSION',true); // we do not use a session or authentication here (better caching) require_once(DOKU_INC.'inc/init.php'); require_once(DOKU_INC.'inc/pageutils.php'); require_once(DOKU_INC.'inc/io.php'); require_once(DOKU_INC.'inc/confutils.php');
// Main (don't run when UNIT test) if(!defined('SIMPLE_TEST')){ header('Content-Type: text/css; charset=utf-8'); css_out(); }
// ---------------------- functions ------------------------------
/** * Output all needed Styles * * @author Andreas Gohr <andi@splitbrain.org> */ function css_out(){ global $conf; global $lang; switch ($_REQUEST['s']) { case 'all': case 'print': case 'feed': $style = $_REQUEST['s']; break; default: $style = ''; break; }
$tpl = trim(preg_replace('/[^\w-]+/','',$_REQUEST['t'])); if($tpl){ $tplinc = DOKU_INC.'lib/tpl/'.$tpl.'/'; $tpldir = DOKU_BASE.'lib/tpl/'.$tpl.'/'; }else{ $tplinc = DOKU_TPLINC; $tpldir = DOKU_TPL; }
// The generated script depends on some dynamic options $cache = getCacheName('styles'.DOKU_BASE.$tplinc.$style,'.css');
// load template styles $tplstyles = array(); if(@file_exists($tplinc.'style.ini')){ $ini = parse_ini_file($tplinc.'style.ini',true); foreach($ini['stylesheets'] as $file => $mode){ $tplstyles[$mode][$tplinc.$file] = $tpldir; } }
// Array of needed files and their web locations, the latter ones // are needed to fix relative paths in the stylesheets $files = array(); //if (isset($tplstyles['all'])) $files = array_merge($files, $tplstyles['all']); if(!empty($style)){ $files[DOKU_INC.'lib/styles/'.$style.'.css'] = DOKU_BASE.'lib/styles/'; // load plugin, template, user styles $files = array_merge($files, css_pluginstyles($style)); if (isset($tplstyles[$style])) $files = array_merge($files, $tplstyles[$style]); $files[DOKU_CONF.'user'.$style.'.css'] = ''; }else{ $files[DOKU_INC.'lib/styles/style.css'] = DOKU_BASE.'lib/styles/'; if($conf['spellchecker']){ $files[DOKU_INC.'lib/styles/spellcheck.css'] = DOKU_BASE.'lib/styles/'; } // load plugin, template, user styles $files = array_merge($files, css_pluginstyles('screen')); if (isset($tplstyles['screen'])) $files = array_merge($files, $tplstyles['screen']); if($lang['direction'] == 'rtl'){ if (isset($tplstyles['rtl'])) $files = array_merge($files, $tplstyles['rtl']); } $files[DOKU_CONF.'userstyle.css'] = ''; }
// check cache age & handle conditional request header('Cache-Control: public, max-age=3600'); header('Pragma: public'); if(css_cacheok($cache,array_keys($files),$tplinc)){ http_conditionalRequest(filemtime($cache)); if($conf['allowdebug']) header("X-CacheUsed: $cache"); readfile($cache); return; } else { http_conditionalRequest(time()); }
// start output buffering and build the stylesheet ob_start();
// print the default classes for interwiki links and file downloads css_interwiki(); css_filetypes();
// load files foreach($files as $file => $location){ print css_loadfile($file, $location); }
// end output buffering and get contents $css = ob_get_contents(); ob_end_clean();
// apply style replacements $css = css_applystyle($css,$tplinc);
// compress whitespace and comments if($conf['compress']){ $css = css_compress($css); }
// save cache file io_saveFile($cache,$css);
// finally send output print $css; }
/** * Checks if a CSS Cache file still is valid * * @author Andreas Gohr <andi@splitbrain.org> */ function css_cacheok($cache,$files,$tplinc){ if($_REQUEST['purge']) return false; //support purge request
$ctime = @filemtime($cache); if(!$ctime) return false; //There is no cache
// some additional files to check $files[] = DOKU_CONF.'dokuwiki.php'; $files[] = DOKU_CONF.'local.php'; $files[] = $tplinc.'style.ini'; $files[] = __FILE__;
// now walk the files foreach($files as $file){ if(@filemtime($file) > $ctime){ return false; } } return true; }
/** * Does placeholder replacements in the style according to * the ones defined in a templates style.ini file * * @author Andreas Gohr <andi@splitbrain.org> */ function css_applystyle($css,$tplinc){ if(@file_exists($tplinc.'style.ini')){ $ini = parse_ini_file($tplinc.'style.ini',true); $css = strtr($css,$ini['replacements']); } return $css; }
/** * Prints classes for interwikilinks * * Interwiki links have two classes: 'interwiki' and 'iw_$name>' where * $name is the identifier given in the config. All Interwiki links get * an default style with a default icon. If a special icon is available * for an interwiki URL it is set in it's own class. Both classes can be * overwritten in the template or userstyles. * * @author Andreas Gohr <andi@splitbrain.org> */ function css_interwiki(){
// default style echo 'a.interwiki {'; echo ' background: transparent url('.DOKU_BASE.'lib/images/interwiki.png) 0px 1px no-repeat;'; echo ' padding-left: 16px;'; echo '}';
// additional styles when icon available $iwlinks = getInterwiki(); foreach(array_keys($iwlinks) as $iw){ $class = preg_replace('/[^_\-a-z0-9]+/i','_',$iw); if(@file_exists(DOKU_INC.'lib/images/interwiki/'.$iw.'.png')){ echo "a.iw_$class {"; echo ' background-image: url('.DOKU_BASE.'lib/images/interwiki/'.$iw.'.png)'; echo '}'; }elseif(@file_exists(DOKU_INC.'lib/images/interwiki/'.$iw.'.gif')){ echo "a.iw_$class {"; echo ' background-image: url('.DOKU_BASE.'lib/images/interwiki/'.$iw.'.gif)'; echo '}'; } } }
/** * Prints classes for file download links * * @author Andreas Gohr <andi@splitbrain.org> */ function css_filetypes(){
// default style echo 'a.mediafile {'; echo ' background: transparent url('.DOKU_BASE.'lib/images/fileicons/file.png) 0px 1px no-repeat;'; echo ' padding-left: 18px;'; echo ' padding-bottom: 1px;'; echo '}';
// additional styles when icon available $mimes = getMimeTypes(); foreach(array_keys($mimes) as $mime){ $class = preg_replace('/[^_\-a-z0-9]+/i','_',$mime); if(@file_exists(DOKU_INC.'lib/images/fileicons/'.$mime.'.png')){ echo "a.mf_$class {"; echo ' background-image: url('.DOKU_BASE.'lib/images/fileicons/'.$mime.'.png)'; echo '}'; }elseif(@file_exists(DOKU_INC.'lib/images/fileicons/'.$mime.'.gif')){ echo "a.mf_$class {"; echo ' background-image: url('.DOKU_BASE.'lib/images/fileicons/'.$mime.'.gif)'; echo '}'; } } }
/** * Loads a given file and fixes relative URLs with the * given location prefix */ function css_loadfile($file,$location=''){ if(!@file_exists($file)) return ''; $css = io_readFile($file); if(!$location) return $css;
$css = preg_replace('#(url\([ \'"]*)((?!/|http://|https://| |\'|"))#','\\1'.$location.'\\3',$css); return $css; }
/** * Returns a list of possible Plugin Styles (no existance check here) * * @author Andreas Gohr <andi@splitbrain.org> */ function css_pluginstyles($mode='screen'){ global $lang; $list = array(); $plugins = plugin_list(); foreach ($plugins as $p){ if($mode == 'all'){ $list[DOKU_PLUGIN."$p/all.css"] = DOKU_BASE."lib/plugins/$p/"; }elseif($mode == 'print'){ $list[DOKU_PLUGIN."$p/print.css"] = DOKU_BASE."lib/plugins/$p/"; }elseif($mode == 'feed'){ $list[DOKU_PLUGIN."$p/feed.css"] = DOKU_BASE."lib/plugins/$p/"; }else{ $list[DOKU_PLUGIN."$p/style.css"] = DOKU_BASE."lib/plugins/$p/"; $list[DOKU_PLUGIN."$p/screen.css"] = DOKU_BASE."lib/plugins/$p/"; } if($lang['direction'] == 'rtl'){ $list[DOKU_PLUGIN."$p/rtl.css"] = DOKU_BASE."lib/plugins/$p/"; } } return $list; }
/** * Very simple CSS optimizer * * @author Andreas Gohr <andi@splitbrain.org> */ function css_compress($css){ //strip comments through a callback $css = preg_replace_callback('#(/\*)(.*?)(\*/)#s','css_comment_cb',$css);
//strip (incorrect but common) one line comments $css = preg_replace('/(?<!:)\/\/.*$/m','',$css);
// strip whitespaces $css = preg_replace('![\r\n\t ]+!',' ',$css); $css = preg_replace('/ ?([:;,{}\/]) ?/','\\1',$css);
// shorten colors $css = preg_replace("/#([0-9a-fA-F]{1})\\1([0-9a-fA-F]{1})\\2([0-9a-fA-F]{1})\\3/", "#\\1\\2\\3",$css);
return $css; }
/** * Callback for css_compress() * * Keeps short comments (< 5 chars) to maintain typical browser hacks * * @author Andreas Gohr <andi@splitbrain.org> */ function css_comment_cb($matches){ if(strlen($matches[2]) > 4) return ''; return $matches[0]; }
//Setup VIM: ex: et ts=4 enc=utf-8 : ?>
|