diff options
Diffstat (limited to 'lib/exe/css.php')
-rw-r--r-- | lib/exe/css.php | 136 |
1 files changed, 110 insertions, 26 deletions
diff --git a/lib/exe/css.php b/lib/exe/css.php index 6dfdf06e8..c96dedd37 100644 --- a/lib/exe/css.php +++ b/lib/exe/css.php @@ -84,16 +84,6 @@ function css_out(){ if(isset($config_cascade['userstyle'][$mediatype])){ $files[$mediatype][$config_cascade['userstyle'][$mediatype]] = DOKU_BASE; } - // load rtl styles - // note: this adds the rtl styles only to the 'screen' media type - // @deprecated 2012-04-09: rtl will cease to be a mode of its own, - // please use "[dir=rtl]" in any css file in all, screen or print mode instead - if ($mediatype=='screen') { - if($lang['direction'] == 'rtl'){ - if (isset($styleini['stylesheets']['rtl'])) $files[$mediatype] = array_merge($files[$mediatype], $styleini['stylesheets']['rtl']); - if (isset($config_cascade['userstyle']['rtl'])) $files[$mediatype][$config_cascade['userstyle']['rtl']] = DOKU_BASE; - } - } $cache_files = array_merge($cache_files, array_keys($files[$mediatype])); } @@ -173,6 +163,12 @@ function css_out(){ */ function css_parseless($css) { $less = new lessc(); + $less->importDir[] = DOKU_INC; + + if (defined('DOKU_UNITTEST')){ + $less->importDir[] = TMP_DIR; + } + try { return $less->compile($css); } catch(Exception $e) { @@ -271,7 +267,7 @@ function css_styleini($tpl) { // replacements if(is_array($data['replacements'])){ - $replacements = array_merge($replacements, $data['replacements']); + $replacements = array_merge($replacements, css_fixreplacementurls($data['replacements'],$webbase)); } } @@ -288,7 +284,7 @@ function css_styleini($tpl) { // replacements if(is_array($data['replacements'])){ - $replacements = array_merge($replacements, $data['replacements']); + $replacements = array_merge($replacements, css_fixreplacementurls($data['replacements'],$webbase)); } } @@ -306,7 +302,7 @@ function css_styleini($tpl) { // replacements if(is_array($data['replacements'])){ - $replacements = array_merge($replacements, $data['replacements']); + $replacements = array_merge($replacements, css_fixreplacementurls($data['replacements'],$webbase)); } } @@ -317,6 +313,18 @@ function css_styleini($tpl) { } /** + * Amend paths used in replacement relative urls, refer FS#2879 + * + * @author Chris Smith <chris@jalakai.co.uk> + */ +function css_fixreplacementurls($replacements, $location) { + foreach($replacements as $key => $value) { + $replacements[$key] = preg_replace('#(url\([ \'"]*)(?!/|data:|http://|https://| |\'|")#','\\1'.$location,$value); + } + return $replacements; +} + +/** * Prints classes for interwikilinks * * Interwiki links have two classes: 'interwiki' and 'iw_$name>' where @@ -393,18 +401,99 @@ function css_filetypes(){ * given location prefix */ function css_loadfile($file,$location=''){ - if(!@file_exists($file)) return ''; - $css = io_readFile($file); - if(!$location) return $css; + $css_file = new DokuCssFile($file); + return $css_file->load($location); +} + +/** + * Helper class to abstract loading of css/less files + * + * @author Chris Smith <chris@jalakai.co.uk> + */ +class DokuCssFile { - $css = preg_replace('#(url\([ \'"]*)(?!/|data:|http://|https://| |\'|")#','\\1'.$location,$css); - $css = preg_replace('#(@import\s+[\'"])(?!/|data:|http://|https://)#', '\\1'.$location, $css); + protected $filepath; // file system path to the CSS/Less file + protected $location; // base url location of the CSS/Less file + private $relative_path = null; - return $css; + public function __construct($file) { + $this->filepath = $file; + } + + /** + * Load the contents of the css/less file and adjust any relative paths/urls (relative to this file) to be + * relative to the dokuwiki root: the web root (DOKU_BASE) for most files; the file system root (DOKU_INC) + * for less files. + * + * @param string $location base url for this file + * @return string the CSS/Less contents of the file + */ + public function load($location='') { + if (!@file_exists($this->filepath)) return ''; + + $css = io_readFile($this->filepath); + if (!$location) return $css; + + $this->location = $location; + + $css = preg_replace_callback('#(url\( *)([\'"]?)(.*?)(\2)( *\))#',array($this,'replacements'),$css); + $css = preg_replace_callback('#(@import\s+)([\'"])(.*?)(\2)#',array($this,'replacements'),$css); + + return $css; + } + + /** + * Get the relative file system path of this file, relative to dokuwiki's root folder, DOKU_INC + * + * @return string relative file system path + */ + private function getRelativePath(){ + + if (is_null($this->relative_path)) { + $basedir = array(DOKU_INC); + + // during testing, files may be found relative to a second base dir, TMP_DIR + if (defined('DOKU_UNITTEST')) { + $basedir[] = realpath(TMP_DIR); + } + $regex = '#^('.join('|',$basedir).')#'; + + $this->relative_path = preg_replace($regex, '', dirname($this->filepath)); + } + + return $this->relative_path; + } + + /** + * preg_replace callback to adjust relative urls from relative to this file to relative + * to the appropriate dokuwiki root location as described in the code + * + * @param array see http://php.net/preg_replace_callback + * @return string see http://php.net/preg_replace_callback + */ + public function replacements($match) { + + // not a relative url? - no adjustment required + if (preg_match('#^(/|data:|https?://)#',$match[3])) { + return $match[0]; + } + // a less file import? - requires a file system location + else if (substr($match[3],-5) == '.less') { + if ($match[3]{0} != '/') { + $match[3] = $this->getRelativePath() . '/' . $match[3]; + } + } + // everything else requires a url adjustment + else { + $match[3] = $this->location . $match[3]; + } + + return join('',array_slice($match,1)); + } } /** - * Converte local image URLs to data URLs if the filesize is small + * Convert local image URLs to data URLs if the filesize is small * * Callback for preg_replace_callback */ @@ -422,7 +511,7 @@ function css_datauri($match){ $data = base64_encode(file_get_contents($local)); } if($data){ - $url = '\'data:image/'.$ext.';base64,'.$data.'\''; + $url = 'data:image/'.$ext.';base64,'.$data; }else{ $url = $base.$url; } @@ -447,11 +536,6 @@ function css_pluginstyles($mediatype='screen'){ $list[DOKU_PLUGIN."$p/style.css"] = DOKU_BASE."lib/plugins/$p/"; $list[DOKU_PLUGIN."$p/style.less"] = DOKU_BASE."lib/plugins/$p/"; } - // @deprecated 2012-04-09: rtl will cease to be a mode of its own, - // please use "[dir=rtl]" in any css file in all, screen or print mode instead - if($lang['direction'] == 'rtl'){ - $list[DOKU_PLUGIN."$p/rtl.css"] = DOKU_BASE."lib/plugins/$p/"; - } } return $list; } |