diff options
Diffstat (limited to 'lib/exe')
-rw-r--r-- | lib/exe/ajax.php | 3 | ||||
-rw-r--r-- | lib/exe/css.php | 242 | ||||
-rw-r--r-- | lib/exe/detail.php | 17 | ||||
-rw-r--r-- | lib/exe/fetch.php | 1 | ||||
-rw-r--r-- | lib/exe/indexer.php | 26 | ||||
-rw-r--r-- | lib/exe/js.php | 32 | ||||
-rw-r--r-- | lib/exe/mediamanager.php | 18 | ||||
-rw-r--r-- | lib/exe/opensearch.php | 2 |
8 files changed, 237 insertions, 104 deletions
diff --git a/lib/exe/ajax.php b/lib/exe/ajax.php index 9769503a7..6e2011cd9 100644 --- a/lib/exe/ajax.php +++ b/lib/exe/ajax.php @@ -219,10 +219,11 @@ function ajax_medialist(){ global $INPUT; $NS = cleanID($INPUT->post->str('ns')); + $sort = $INPUT->post->bool('recent') ? 'date' : 'natural'; if ($INPUT->post->str('do') == 'media') { tpl_mediaFileList(); } else { - tpl_mediaContent(true); + tpl_mediaContent(true, $sort); } } diff --git a/lib/exe/css.php b/lib/exe/css.php index 1e662c64a..6dfdf06e8 100644 --- a/lib/exe/css.php +++ b/lib/exe/css.php @@ -40,43 +40,32 @@ function css_out(){ $type = ''; } + // decide from where to get the template $tpl = trim(preg_replace('/[^\w-]+/','',$INPUT->str('t'))); - if($tpl){ - $tplinc = DOKU_INC.'lib/tpl/'.$tpl.'/'; - $tpldir = DOKU_BASE.'lib/tpl/'.$tpl.'/'; - }else{ - $tplinc = tpl_incdir(); - $tpldir = tpl_basedir(); - } - - // used style.ini file - $styleini = css_styleini($tplinc); + if(!$tpl) $tpl = $conf['template']; // The generated script depends on some dynamic options - $cache = new cache('styles'.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'].DOKU_BASE.$tplinc.$type,'.css'); + $cache = new cache('styles'.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'].DOKU_BASE.$tpl.$type,'.css'); - // load template styles - $tplstyles = array(); - if ($styleini) { - foreach($styleini['stylesheets'] as $file => $mode) { - $tplstyles[$mode][$tplinc.$file] = $tpldir; - } - } + // load styl.ini + $styleini = css_styleini($tpl); // if old 'default' userstyle setting exists, make it 'screen' userstyle for backwards compatibility if (isset($config_cascade['userstyle']['default'])) { $config_cascade['userstyle']['screen'] = $config_cascade['userstyle']['default']; } - // Array of needed files and their web locations, the latter ones - // are needed to fix relative paths in the stylesheets - $files = array(); - + // cache influencers + $tplinc = tpl_basedir($tpl); $cache_files = getConfigFiles('main'); $cache_files[] = $tplinc.'style.ini'; - $cache_files[] = $tplinc.'style.local.ini'; + $cache_files[] = $tplinc.'style.local.ini'; // @deprecated + $cache_files[] = DOKU_CONF."tpl/$tpl/style.ini"; $cache_files[] = __FILE__; + // Array of needed files and their web locations, the latter ones + // are needed to fix relative paths in the stylesheets + $files = array(); foreach($mediatypes as $mediatype) { $files[$mediatype] = array(); // load core styles @@ -88,8 +77,8 @@ function css_out(){ // load plugin styles $files[$mediatype] = array_merge($files[$mediatype], css_pluginstyles($mediatype)); // load template styles - if (isset($tplstyles[$mediatype])) { - $files[$mediatype] = array_merge($files[$mediatype], $tplstyles[$mediatype]); + if (isset($styleini['stylesheets'][$mediatype])) { + $files[$mediatype] = array_merge($files[$mediatype], $styleini['stylesheets'][$mediatype]); } // load user styles if(isset($config_cascade['userstyle'][$mediatype])){ @@ -101,7 +90,7 @@ function css_out(){ // please use "[dir=rtl]" in any css file in all, screen or print mode instead if ($mediatype=='screen') { if($lang['direction'] == 'rtl'){ - if (isset($tplstyles['rtl'])) $files[$mediatype] = array_merge($files[$mediatype], $tplstyles['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; } } @@ -131,6 +120,8 @@ function css_out(){ // load files $css_content = ''; foreach($files[$mediatype] as $file => $location){ + $display = str_replace(fullpath(DOKU_INC), '', fullpath($file)); + $css_content .= "\n/* XXXXXXXXX $display XXXXXXXXX */\n"; $css_content .= css_loadfile($file, $location); } switch ($mediatype) { @@ -152,10 +143,10 @@ function css_out(){ ob_end_clean(); // apply style replacements - $css = css_applystyle($css,$tplinc); + $css = css_applystyle($css, $styleini['replacements']); - // place all @import statements at the top of the file - $css = css_moveimports($css); + // parse less + $css = css_parseless($css); // compress whitespace and comments if($conf['compress']){ @@ -172,40 +163,157 @@ function css_out(){ } /** + * Uses phpless to parse LESS in our CSS + * + * most of this function is error handling to show a nice useful error when + * LESS compilation fails + * + * @param $css + * @return string + */ +function css_parseless($css) { + $less = new lessc(); + try { + return $less->compile($css); + } catch(Exception $e) { + // get exception message + $msg = str_replace(array("\n", "\r", "'"), array(), $e->getMessage()); + + // try to use line number to find affected file + if(preg_match('/line: (\d+)$/', $msg, $m)){ + $msg = substr($msg, 0, -1* strlen($m[0])); //remove useless linenumber + $lno = $m[1]; + + // walk upwards to last include + $lines = explode("\n", $css); + for($i=$lno-1; $i>=0; $i--){ + if(preg_match('/\/(\* XXXXXXXXX )(.*?)( XXXXXXXXX \*)\//', $lines[$i], $m)){ + // we found it, add info to message + $msg .= ' in '.$m[2].' at line '.($lno-$i); + break; + } + } + } + + // something went wrong + $error = 'A fatal error occured during compilation of the CSS files. '. + 'If you recently installed a new plugin or template it '. + 'might be broken and you should try disabling it again. ['.$msg.']'; + + echo ".dokuwiki:before { + content: '$error'; + background-color: red; + display: block; + background-color: #fcc; + border-color: #ebb; + color: #000; + padding: 0.5em; + }"; + + exit; + } +} + +/** * Does placeholder replacements in the style according to * the ones defined in a templates style.ini file * + * This also adds the ini defined placeholders as less variables + * (sans the surrounding __ and with a ini_ prefix) + * * @author Andreas Gohr <andi@splitbrain.org> */ -function css_applystyle($css,$tplinc){ - $styleini = css_styleini($tplinc); - - if($styleini){ - $css = strtr($css,$styleini['replacements']); +function css_applystyle($css, $replacements) { + // we convert ini replacements to LESS variable names + // and build a list of variable: value; pairs + $less = ''; + foreach((array) $replacements as $key => $value) { + $lkey = trim($key, '_'); + $lkey = '@ini_'.$lkey; + $less .= "$lkey: $value;\n"; + + $replacements[$key] = $lkey; } + + // we now replace all old ini replacements with LESS variables + $css = strtr($css, $replacements); + + // now prepend the list of LESS variables as the very first thing + $css = $less.$css; return $css; } /** - * Get contents of merged style.ini and style.local.ini as an array. + * Load style ini contents + * + * Loads and merges style.ini files from template and config and prepares + * the stylesheet modes * - * @author Anika Henke <anika@selfthinker.org> + * @author Andreas Gohr <andi@splitbrain.org> + * @param string $tpl the used template + * @return array with keys 'stylesheets' and 'replacements' */ -function css_styleini($tplinc) { - $styleini = array(); +function css_styleini($tpl) { + $stylesheets = array(); // mode, file => base + $replacements = array(); // placeholder => value + + // load template's style.ini + $incbase = tpl_incdir($tpl); + $webbase = tpl_basedir($tpl); + $ini = $incbase.'style.ini'; + if(file_exists($ini)){ + $data = parse_ini_file($ini, true); + + // stylesheets + if(is_array($data['stylesheets'])) foreach($data['stylesheets'] as $file => $mode){ + $stylesheets[$mode][$incbase.$file] = $webbase; + } - foreach (array($tplinc.'style.ini', $tplinc.'style.local.ini') as $ini) { - $tmp = (@file_exists($ini)) ? parse_ini_file($ini, true) : array(); + // replacements + if(is_array($data['replacements'])){ + $replacements = array_merge($replacements, $data['replacements']); + } + } - foreach($tmp as $key => $value) { - if(array_key_exists($key, $styleini) && is_array($value)) { - $styleini[$key] = array_merge($styleini[$key], $tmp[$key]); - } else { - $styleini[$key] = $value; - } + // load template's style.local.ini + // @deprecated 2013-08-03 + $ini = $incbase.'style.local.ini'; + if(file_exists($ini)){ + $data = parse_ini_file($ini, true); + + // stylesheets + if(is_array($data['stylesheets'])) foreach($data['stylesheets'] as $file => $mode){ + $stylesheets[$mode][$incbase.$file] = $webbase; + } + + // replacements + if(is_array($data['replacements'])){ + $replacements = array_merge($replacements, $data['replacements']); + } + } + + // load configs's style.ini + $webbase = DOKU_BASE; + $ini = DOKU_CONF."tpl/$tpl/style.ini"; + $incbase = dirname($ini).'/'; + if(file_exists($ini)){ + $data = parse_ini_file($ini, true); + + // stylesheets + if(is_array($data['stylesheets'])) foreach($data['stylesheets'] as $file => $mode){ + $stylesheets[$mode][$incbase.$file] = $webbase; + } + + // replacements + if(is_array($data['replacements'])){ + $replacements = array_merge($replacements, $data['replacements']); } } - return $styleini; + + return array( + 'stylesheets' => $stylesheets, + 'replacements' => $replacements + ); } /** @@ -314,7 +422,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; } @@ -333,9 +441,11 @@ function css_pluginstyles($mediatype='screen'){ $plugins = plugin_list(); foreach ($plugins as $p){ $list[DOKU_PLUGIN."$p/$mediatype.css"] = DOKU_BASE."lib/plugins/$p/"; + $list[DOKU_PLUGIN."$p/$mediatype.less"] = DOKU_BASE."lib/plugins/$p/"; // alternative for screen.css if ($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 @@ -347,29 +457,6 @@ function css_pluginstyles($mediatype='screen'){ } /** - * Move all @import statements in a combined stylesheet to the top so they - * aren't ignored by the browser. - * - * @author Gabriel Birke <birke@d-scribe.de> - */ -function css_moveimports($css) -{ - if(!preg_match_all('/@import\s+(?:url\([^)]+\)|"[^"]+")\s*[^;]*;\s*/', $css, $matches, PREG_OFFSET_CAPTURE)) { - return $css; - } - $newCss = ""; - $imports = ""; - $offset = 0; - foreach($matches[0] as $match) { - $newCss .= substr($css, $offset, $match[1] - $offset); - $imports .= $match[0]; - $offset = $match[1] + strlen($match[0]); - } - $newCss .= substr($css, $offset); - return $imports.$newCss; -} - -/** * Very simple CSS optimizer * * @author Andreas Gohr <andi@splitbrain.org> @@ -386,8 +473,19 @@ function css_compress($css){ $css = preg_replace('/ ?([;,{}\/]) ?/','\\1',$css); $css = preg_replace('/ ?: /',':',$css); + // number compression + $css = preg_replace('/([: ])0+(\.\d+?)0*((?:pt|pc|in|mm|cm|em|ex|px)\b|%)(?=[^\{]*[;\}])/', '$1$2$3', $css); // "0.1em" to ".1em", "1.10em" to "1.1em" + $css = preg_replace('/([: ])\.(0)+((?:pt|pc|in|mm|cm|em|ex|px)\b|%)(?=[^\{]*[;\}])/', '$1$2', $css); // ".0em" to "0" + $css = preg_replace('/([: ]0)0*(\.0*)?((?:pt|pc|in|mm|cm|em|ex|px)(?=[^\{]*[;\}])\b|%)/', '$1', $css); // "0.0em" to "0" + $css = preg_replace('/([: ]\d+)(\.0*)((?:pt|pc|in|mm|cm|em|ex|px)(?=[^\{]*[;\}])\b|%)/', '$1$3', $css); // "1.0em" to "1em" + $css = preg_replace('/([: ])0+(\d+|\d*\.\d+)((?:pt|pc|in|mm|cm|em|ex|px)(?=[^\{]*[;\}])\b|%)/', '$1$2$3', $css); // "001em" to "1em" + + // shorten attributes (1em 1em 1em 1em -> 1em) + $css = preg_replace('/(?<![\w\-])((?:margin|padding|border|border-(?:width|radius)):)([\w\.]+)( \2)+(?=[;\}]| !)/', '$1$2', $css); // "1em 1em 1em 1em" to "1em" + $css = preg_replace('/(?<![\w\-])((?:margin|padding|border|border-(?:width)):)([\w\.]+) ([\w\.]+) \2 \3(?=[;\}]| !)/', '$1$2 $3', $css); // "1em 2em 1em 2em" to "1em 2em" + // 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); + $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; } diff --git a/lib/exe/detail.php b/lib/exe/detail.php index db635c016..e3c81d877 100644 --- a/lib/exe/detail.php +++ b/lib/exe/detail.php @@ -2,13 +2,20 @@ if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../'); define('DOKU_MEDIADETAIL',1); require_once(DOKU_INC.'inc/init.php'); -trigger_event('DETAIL_STARTED', $tmp=array()); -//close session -session_write_close(); $IMG = getID('media'); $ID = cleanID($INPUT->str('id')); +// this makes some general infos available as well as the info about the +// "parent" page +$INFO = array_merge(pageinfo(),mediainfo()); + +$tmp = array(); +trigger_event('DETAIL_STARTED', $tmp); + +//close session +session_write_close(); + if($conf['allowdebug'] && $INPUT->has('debug')){ print '<pre>'; foreach(explode(' ','basedir userewrite baseurl useslash') as $x){ @@ -39,10 +46,6 @@ if($AUTH >= AUTH_READ){ $ERROR = p_locale_xhtml('denied'); } -// this makes some general infos available as well as the info about the -// "parent" page -$INFO = pageinfo(); - //start output and load template header('Content-Type: text/html; charset=utf-8'); include(template('detail.php')); diff --git a/lib/exe/fetch.php b/lib/exe/fetch.php index 7a2250373..5967494bf 100644 --- a/lib/exe/fetch.php +++ b/lib/exe/fetch.php @@ -60,6 +60,7 @@ if (defined('SIMPLE_TEST')) { if($evt->advise_before()) { // redirects if($data['status'] > 300 && $data['status'] <= 304) { + if (defined('SIMPLE_TEST')) return; //TestResponse doesn't recognize redirects send_redirect($data['statusmessage']); } // send any non 200 status diff --git a/lib/exe/indexer.php b/lib/exe/indexer.php index 57bee8925..3ab117736 100644 --- a/lib/exe/indexer.php +++ b/lib/exe/indexer.php @@ -31,12 +31,12 @@ else header('Content-Type: text/plain'); $tmp = array(); // No event data $evt = new Doku_Event('INDEXER_TASKS_RUN', $tmp); if ($evt->advise_before()) { - runIndexer() or - runSitemapper() or - sendDigest() or - runTrimRecentChanges() or - runTrimRecentChanges(true) or - $evt->advise_after(); + runIndexer() or + runSitemapper() or + sendDigest() or + runTrimRecentChanges() or + runTrimRecentChanges(true) or + $evt->advise_after(); } if(!$output) { @@ -85,13 +85,13 @@ function runTrimRecentChanges($media_changes = false) { $out_lines = array(); for ($i=0; $i<count($lines); $i++) { - $log = parseChangelogLine($lines[$i]); - if ($log === false) continue; // discard junk - if ($log['date'] < $trim_time) { - $old_lines[$log['date'].".$i"] = $lines[$i]; // keep old lines for now (append .$i to prevent key collisions) - } else { - $out_lines[$log['date'].".$i"] = $lines[$i]; // definitely keep these lines - } + $log = parseChangelogLine($lines[$i]); + if ($log === false) continue; // discard junk + if ($log['date'] < $trim_time) { + $old_lines[$log['date'].".$i"] = $lines[$i]; // keep old lines for now (append .$i to prevent key collisions) + } else { + $out_lines[$log['date'].".$i"] = $lines[$i]; // definitely keep these lines + } } if (count($lines)==count($out_lines)) { diff --git a/lib/exe/js.php b/lib/exe/js.php index 4ff48133e..040b8874d 100644 --- a/lib/exe/js.php +++ b/lib/exe/js.php @@ -86,16 +86,25 @@ function js_out(){ // start output buffering and build the script ob_start(); + $json = new JSON(); // add some global variables print "var DOKU_BASE = '".DOKU_BASE."';"; print "var DOKU_TPL = '".tpl_basedir()."';"; + print "var DOKU_COOKIE_PARAM = " . $json->encode( + array( + 'path' => empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'], + 'secure' => $conf['securecookie'] && is_ssl() + )).";"; // FIXME: Move those to JSINFO print "var DOKU_UHN = ".((int) useHeading('navigation')).";"; print "var DOKU_UHC = ".((int) useHeading('content')).";"; // load JS specific translations - $json = new JSON(); $lang['js']['plugins'] = js_pluginstrings(); + $templatestrings = js_templatestrings(); + if(!empty($templatestrings)) { + $lang['js']['template'] = $templatestrings; + } echo 'LANG = '.$json->encode($lang['js']).";\n"; // load toolbar @@ -104,10 +113,13 @@ function js_out(){ // load files foreach($files as $file){ $ismin = (substr($file,-7) == '.min.js'); + $debugjs = ($conf['allowdebug'] && strpos($file, DOKU_INC.'lib/scripts/') !== 0); echo "\n\n/* XXXXXXXXXX begin of ".str_replace(DOKU_INC, '', $file) ." XXXXXXXXXX */\n\n"; if($ismin) echo "\n/* BEGIN NOCOMPRESS */\n"; + if ($debugjs) echo "\ntry {\n"; js_load($file); + if ($debugjs) echo "\n} catch (e) {\n logError(e, '".str_replace(DOKU_INC, '', $file)."');\n}\n"; if($ismin) echo "\n/* END NOCOMPRESS */\n"; echo "\n\n/* XXXXXXXXXX end of " . str_replace(DOKU_INC, '', $file) . " XXXXXXXXXX */\n\n"; } @@ -187,8 +199,7 @@ function js_pluginscripts(){ * * @author Gabriel Birke <birke@d-scribe.de> */ -function js_pluginstrings() -{ +function js_pluginstrings() { global $conf; $pluginstrings = array(); $plugins = plugin_list(); @@ -207,6 +218,21 @@ function js_pluginstrings() return $pluginstrings; } +function js_templatestrings() { + global $conf; + $templatestrings = array(); + if (@file_exists(tpl_incdir()."lang/en/lang.php")) { + include tpl_incdir()."lang/en/lang.php"; + } + if (isset($conf['lang']) && $conf['lang']!='en' && @file_exists(tpl_incdir()."lang/".$conf['lang']."/lang.php")) { + include tpl_incdir()."lang/".$conf['lang']."/lang.php"; + } + if (isset($lang['js'])) { + $templatestrings[$conf['template']] = $lang['js']; + } + return $templatestrings; +} + /** * Escapes a String to be embedded in a JavaScript call, keeps \n * as newline diff --git a/lib/exe/mediamanager.php b/lib/exe/mediamanager.php index 53d438321..d94a24c74 100644 --- a/lib/exe/mediamanager.php +++ b/lib/exe/mediamanager.php @@ -7,15 +7,12 @@ require_once(DOKU_INC.'inc/init.php'); - trigger_event('MEDIAMANAGER_STARTED',$tmp=array()); - session_write_close(); //close session - global $INPUT; // handle passed message if($INPUT->str('msg1')) msg(hsc($INPUT->str('msg1')),1); if($INPUT->str('err')) msg(hsc($INPUT->str('err')),-1); - + global $DEL; // get namespace to display (either direct or from deletion order) if($INPUT->str('delete')){ $DEL = cleanID($INPUT->str('delete')); @@ -29,10 +26,17 @@ $NS = getNS($IMG); }else{ $NS = cleanID($INPUT->str('ns')); + $IMG = null; } - // check auth - $AUTH = auth_quickaclcheck("$NS:*"); + global $INFO, $JSINFO; + $INFO = !empty($INFO) ? array_merge($INFO, mediainfo()) : mediainfo(); + $JSINFO = array('id' => '', 'namespace' => ''); + $AUTH = $INFO['perm']; // shortcut for historical reasons + + $tmp = array(); + trigger_event('MEDIAMANAGER_STARTED', $tmp); + session_write_close(); //close session // do not display the manager if user does not have read access if($AUTH < AUTH_READ && !$fullscreen) { @@ -52,7 +56,7 @@ exit; } - // give info on PHP catched upload errors + // give info on PHP caught upload errors if($_FILES['upload']['error']){ switch($_FILES['upload']['error']){ case 1: diff --git a/lib/exe/opensearch.php b/lib/exe/opensearch.php index 73939c347..98f5f52d5 100644 --- a/lib/exe/opensearch.php +++ b/lib/exe/opensearch.php @@ -21,7 +21,7 @@ if(file_exists(DOKU_INC.'favicon.ico')){ }elseif(file_exists(tpl_incdir().'favicon.ico')){ $ico = DOKU_URL.'lib/tpl/'.$conf['template'].'/favicon.ico'; }else{ - $ico = DOKU_URL.'lib/tpl/default/images/favicon.ico'; + $ico = DOKU_URL.'lib/tpl/dokuwiki/images/favicon.ico'; } // output |