1<?php 2/** 3 * DokuWiki StyleSheet creator 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Andreas Gohr <andi@splitbrain.org> 7 */ 8 9if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 10define('NOSESSION',true); // we do not use a session or authentication here (better caching) 11require_once(DOKU_INC.'inc/init.php'); 12require_once(DOKU_INC.'inc/pageutils.php'); 13require_once(DOKU_INC.'inc/io.php'); 14 15// Main (don't run when UNIT test) 16if(!defined('SIMPLE_TEST')){ 17 header('Content-Type: text/css; charset=utf-8'); 18 css_out(); 19} 20 21 22// ---------------------- functions ------------------------------ 23 24/** 25 * Output all needed Styles 26 * 27 * @author Andreas Gohr <andi@splitbrain.org> 28 */ 29function css_out(){ 30 global $conf; 31 global $lang; 32 $print = (bool) $_REQUEST['print']; //print mode? 33 34 // The generated script depends on some dynamic options 35 $cache = getCacheName('styles'.$print,'.css'); 36 37 // Array of needed files and their web locations, the latter ones 38 // are needed to fix relative paths in the stylesheets 39 $files = array(); 40 if($print){ 41 $files[DOKU_TPLINC.'print.css'] = DOKU_TPL; 42 // load plugin styles 43 $files = array_merge($files, css_pluginstyles('print')); 44 $files[DOKU_CONF.'userprint.css'] = ''; 45 }else{ 46 $files[DOKU_INC.'lib/styles/style.css'] = DOKU_BASE.'lib/styles/'; 47 //fixme spellchecker style 48 $files[DOKU_TPLINC.'layout.css'] = DOKU_TPL; 49 $files[DOKU_TPLINC.'design.css'] = DOKU_TPL; 50 if($lang['direction'] == 'rtl'){ 51 $files[DOKU_TPLINC.'rtl.css'] = DOKU_TPL; 52 } 53 // load plugin styles 54 $files = array_merge($files, css_pluginstyles('screen')); 55 $files[DOKU_CONF.'userstyle.css'] = ''; 56 } 57 58 // check cache age 59 if(css_cacheok($cache,array_keys($files))){ 60 readfile($cache); 61 return; 62 } 63 64 // start output buffering and build the stylesheet 65 ob_start(); 66 67 // load files 68 foreach($files as $file => $location){ 69 print css_loadfile($file, $location); 70 } 71 72 // end output buffering and get contents 73 $css = ob_get_contents(); 74 ob_end_clean(); 75 76 // compress whitespace and comments 77 if($conf['compress']){ 78 $css = css_compress($css); 79 } 80 81 // save cache file 82 io_saveFile($cache,$css); 83 84 // finally send output 85 print $css; 86} 87 88/** 89 * Checks if a CSS Cache file still is valid 90 * 91 * @author Andreas Gohr <andi@splitbrain.org> 92 */ 93function css_cacheok($cache,$files){ 94 $ctime = @filemtime($cache); 95 if(!$ctime) return false; //There is no cache 96 97 // some additional files to check 98 $files[] = DOKU_CONF.'dokuwiki.conf'; 99 $files[] = DOKU_CONF.'local.conf'; 100 $files[] = __FILE__; 101 102 // now walk the files 103 foreach($files as $file){ 104 if(@filemtime($file) > $ctime){ 105 return false; 106 } 107 } 108 return true; 109} 110 111/** 112 * Loads a given file and fixes relative URLs with the 113 * given location prefix 114 */ 115function css_loadfile($file,$location=''){ 116 if(!@file_exists($file)) return ''; 117 $css = io_readFile($file); 118 if(!$location) return $css; 119 120 $css = preg_replace('!(url\( *)([^/])!','\\1'.$location.'\\2',$css); 121 return $css; 122} 123 124/** 125 * Returns a list of possible Plugin Styles (no existance check here) 126 * 127 * @author Andreas Gohr <andi@splitbrain.org> 128 */ 129function css_pluginstyles($mode='screen'){ 130 $list = array(); 131 $plugins = plugin_list(); 132 foreach ($plugins as $p){ 133 if($mode == 'print'){ 134 $list[DOKU_PLUGIN."$p/print.css"] = DOKU_BASE."lib/plugins/$p/"; 135 }else{ 136 $list[DOKU_PLUGIN."$p/style.css"] = DOKU_BASE."lib/plugins/$p/"; 137 $list[DOKU_PLUGIN."$p/screen.css"] = DOKU_BASE."lib/plugins/$p/"; 138 } 139 } 140 return $list; 141} 142 143/** 144 * Very simple CSS optimizer 145 * 146 * @author Andreas Gohr <andi@splitbrain.org> 147 */ 148function css_compress($css){ 149 // strip whitespaces 150 $css = preg_replace('![\r\n\t ]+!',' ',$css); 151 $css = preg_replace('/ ?([:;,{}]) ?/','\\1',$css); 152 153 // strip comments (ungreedy) 154 // We keep very small comments to maintain typical browser hacks 155 $css = preg_replace('!(/\*)(.{4,})(\*/)!U','',$css); 156 157 // shorten colors 158 $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); 159 160 return $css; 161} 162 163 164//Setup VIM: ex: et ts=4 enc=utf-8 : 165?> 166