diff options
author | Christopher Smith <chris@jalakai.co.uk> | 2014-03-12 18:39:11 +0000 |
---|---|---|
committer | Christopher Smith <chris@jalakai.co.uk> | 2014-03-12 18:39:11 +0000 |
commit | 4e60057c8ccbee18b94a64208311f9bbb338eec6 (patch) | |
tree | 08d79159aa78693c27f54ecebc3105034dfc5933 /lib/exe/css.php | |
parent | 57a6f99d09d3662a8a2ad72e312aa6f53bcc2d01 (diff) | |
parent | 069942acdaa5ba825bc3f92c7093b5071789f1ca (diff) | |
download | rpg-4e60057c8ccbee18b94a64208311f9bbb338eec6.tar.gz rpg-4e60057c8ccbee18b94a64208311f9bbb338eec6.tar.bz2 |
Merge branch 'master' into tablethead
Diffstat (limited to 'lib/exe/css.php')
-rw-r--r-- | lib/exe/css.php | 138 |
1 files changed, 112 insertions, 26 deletions
diff --git a/lib/exe/css.php b/lib/exe/css.php index 6dfdf06e8..cab7384b2 100644 --- a/lib/exe/css.php +++ b/lib/exe/css.php @@ -70,6 +70,7 @@ function css_out(){ $files[$mediatype] = array(); // load core styles $files[$mediatype][DOKU_INC.'lib/styles/'.$mediatype.'.css'] = DOKU_BASE.'lib/styles/'; + // load jQuery-UI theme if ($mediatype == 'screen') { $files[$mediatype][DOKU_INC.'lib/scripts/jquery/jquery-ui-theme/smoothness.css'] = DOKU_BASE.'lib/scripts/jquery/jquery-ui-theme/'; @@ -84,16 +85,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 +164,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 +268,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 +285,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 +303,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 +314,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 +402,100 @@ 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); + } + + $basedir = array_map('preg_quote_cb', $basedir); + $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 +513,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 +538,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; } |