[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/lib/exe/ -> js.php (source)

   1  <?php
   2  /**
   3   * DokuWiki JavaScript creator
   4   *
   5   * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
   6   * @author     Andreas Gohr <andi@splitbrain.org>
   7   */
   8  
   9  if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
  10  if(!defined('NOSESSION')) define('NOSESSION',true); // we do not use a session or authentication here (better caching)
  11  if(!defined('NL')) define('NL',"\n");
  12  require_once (DOKU_INC.'inc/init.php');
  13  require_once (DOKU_INC.'inc/pageutils.php');
  14  require_once (DOKU_INC.'inc/io.php');
  15  require_once (DOKU_INC.'inc/JSON.php');
  16  
  17  // Main (don't run when UNIT test)
  18  if(!defined('SIMPLE_TEST')){
  19      header('Content-Type: text/javascript; charset=utf-8');
  20      js_out();
  21  }
  22  
  23  
  24  // ---------------------- functions ------------------------------
  25  
  26  /**
  27   * Output all needed JavaScript
  28   *
  29   * @author Andreas Gohr <andi@splitbrain.org>
  30   */
  31  function js_out(){
  32      global $conf;
  33      global $lang;
  34      $edit  = (bool) $_REQUEST['edit'];   // edit or preview mode?
  35      $write = (bool) $_REQUEST['write'];  // writable?
  36  
  37      // The generated script depends on some dynamic options
  38      $cache = getCacheName('scripts'.$edit.'x'.$write,'.js');
  39  
  40      // Array of needed files
  41      $files = array(
  42                  DOKU_INC.'lib/scripts/helpers.js',
  43                  DOKU_INC.'lib/scripts/events.js',
  44                  DOKU_INC.'lib/scripts/cookie.js',
  45                  DOKU_INC.'lib/scripts/script.js',
  46                  DOKU_INC.'lib/scripts/tw-sack.js',
  47                  DOKU_INC.'lib/scripts/ajax.js',
  48                  DOKU_INC.'lib/scripts/index.js',
  49               );
  50      if($edit){
  51          if($write){
  52              $files[] = DOKU_INC.'lib/scripts/edit.js';
  53          }
  54          $files[] = DOKU_INC.'lib/scripts/media.js';
  55      }
  56      $files[] = DOKU_TPLINC.'script.js';
  57  
  58      // get possible plugin scripts
  59      $plugins = js_pluginscripts();
  60  
  61      // check cache age & handle conditional request
  62      header('Cache-Control: public, max-age=3600');
  63      header('Pragma: public');
  64      if(js_cacheok($cache,array_merge($files,$plugins))){
  65          http_conditionalRequest(filemtime($cache));
  66          if($conf['allowdebug']) header("X-CacheUsed: $cache");
  67          readfile($cache);
  68          return;
  69      } else {
  70          http_conditionalRequest(time());
  71      }
  72  
  73      // start output buffering and build the script
  74      ob_start();
  75  
  76      // add some global variables
  77      print "var DOKU_BASE   = '".DOKU_BASE."';";
  78      print "var DOKU_TPL    = '".DOKU_TPL."';";
  79  
  80      //FIXME: move thes into LANG
  81      print "var alertText   = '".js_escape($lang['qb_alert'])."';";
  82      print "var notSavedYet = '".js_escape($lang['notsavedyet'])."';";
  83      print "var reallyDel   = '".js_escape($lang['del_confirm'])."';";
  84  
  85      // load JS strings form plugins
  86      $lang['js']['plugins'] = js_pluginstrings();
  87      
  88      // load JS specific translations
  89      $json = new JSON();
  90      echo 'LANG = '.$json->encode($lang['js']).";\n";
  91  
  92      // load files
  93      foreach($files as $file){
  94          echo "\n\n/* XXXXXXXXXX begin of $file XXXXXXXXXX */\n\n";
  95          js_load($file);
  96          echo "\n\n/* XXXXXXXXXX end of $file XXXXXXXXXX */\n\n";
  97      }
  98  
  99      // init stuff
 100      js_runonstart("ajax_qsearch.init('qsearch__in','qsearch__out')");
 101      js_runonstart("addEvent(document,'click',closePopups)");
 102      js_runonstart('addTocToggle()');
 103  
 104      if($edit){
 105          // size controls
 106          js_runonstart("initSizeCtl('size__ctl','wiki__text')");
 107  
 108          if($write){
 109              require_once (DOKU_INC.'inc/toolbar.php');
 110              toolbar_JSdefines('toolbar');
 111              js_runonstart("initToolbar('tool__bar','wiki__text',toolbar)");
 112  
 113              // add pageleave check
 114              js_runonstart("initChangeCheck('".js_escape($lang['notsavedyet'])."')");
 115  
 116              // add lock timer
 117              js_runonstart("locktimer.init(".($conf['locktime'] - 60).",'".js_escape($lang['willexpire'])."',".$conf['usedraft'].")");
 118          }
 119      }
 120  
 121      // load plugin scripts (suppress warnings for missing ones)
 122      foreach($plugins as $plugin){
 123          if (@file_exists($plugin)) {
 124            echo "\n\n/* XXXXXXXXXX begin of $plugin XXXXXXXXXX */\n\n";
 125            js_load($plugin);
 126            echo "\n\n/* XXXXXXXXXX end of $plugin XXXXXXXXXX */\n\n";
 127          }
 128      }
 129  
 130      // load user script
 131      @readfile(DOKU_CONF.'userscript.js');
 132  
 133      // add scroll event and tooltip rewriting
 134      js_runonstart('updateAccessKeyTooltip()');
 135      js_runonstart('scrollToMarker()');
 136      js_runonstart('focusMarker()');
 137  
 138      // end output buffering and get contents
 139      $js = ob_get_contents();
 140      ob_end_clean();
 141  
 142      // compress whitespace and comments
 143      if($conf['compress']){
 144          $js = js_compress($js);
 145      }
 146  
 147      $js .= "\n"; // https://bugzilla.mozilla.org/show_bug.cgi?id=316033
 148  
 149      // save cache file
 150      io_saveFile($cache,$js);
 151  
 152      // finally send output
 153      print $js;
 154  }
 155  
 156  /**
 157   * Load the given file, handle include calls and print it
 158   *
 159   * @author Andreas Gohr <andi@splitbrain.org>
 160   */
 161  function js_load($file){
 162      if(!@file_exists($file)) return;
 163      static $loaded = array();
 164  
 165      $data = io_readFile($file);
 166      while(preg_match('#/\*\s*DOKUWIKI:include(_once)?\s+([\w\./]+)\s*\*/#',$data,$match)){
 167          $ifile = $match[2];
 168  
 169          // is it a include_once?
 170          if($match[1]){
 171              $base = basename($ifile);
 172              if($loaded[$base]) continue;
 173              $loaded[$base] = true;
 174          }
 175  
 176          if($ifile{0} != '/') $ifile = dirname($file).'/'.$ifile;
 177  
 178          if(@file_exists($ifile)){
 179              $idata = io_readFile($ifile);
 180          }else{
 181              $idata = '';
 182          }
 183          $data  = str_replace($match[0],$idata,$data);
 184      }
 185      echo $data;
 186  }
 187  
 188  /**
 189   * Checks if a JavaScript Cache file still is valid
 190   *
 191   * @author Andreas Gohr <andi@splitbrain.org>
 192   */
 193  function js_cacheok($cache,$files){
 194      if($_REQUEST['purge']) return false; //support purge request
 195  
 196      $ctime = @filemtime($cache);
 197      if(!$ctime) return false; //There is no cache
 198  
 199      // some additional files to check
 200      $files[] = DOKU_CONF.'dokuwiki.php';
 201      $files[] = DOKU_CONF.'local.php';
 202      $files[] = DOKU_CONF.'userscript.js';
 203      $files[] = __FILE__;
 204  
 205      // now walk the files
 206      foreach($files as $file){
 207          if(@filemtime($file) > $ctime){
 208              return false;
 209          }
 210      }
 211      return true;
 212  }
 213  
 214  /**
 215   * Returns a list of possible Plugin Scripts (no existance check here)
 216   *
 217   * @author Andreas Gohr <andi@splitbrain.org>
 218   */
 219  function js_pluginscripts(){
 220      $list = array();
 221      $plugins = plugin_list();
 222      foreach ($plugins as $p){
 223          $list[] = DOKU_PLUGIN."$p/script.js";
 224      }
 225      return $list;
 226  }
 227  
 228  /**
 229   * Return an two-dimensional array with strings from the language file of each plugin.
 230   *
 231   * - $lang['js'] must be an array. 
 232   * - Nothing is returned for plugins without an entry for $lang['js']
 233   *
 234   * @author Gabriel Birke <birke@d-scribe.de>
 235   */
 236  function js_pluginstrings()
 237  {
 238      global $conf;
 239      $pluginstrings = array();
 240      $plugins = plugin_list();
 241      foreach ($plugins as $p){
 242          if (isset($lang)) unset($lang);
 243          if (@file_exists(DOKU_PLUGIN."$p/lang/en/lang.php")) {
 244              include DOKU_PLUGIN."$p/lang/en/lang.php";
 245          }
 246          if (isset($conf['lang']) && $conf['lang']!='en' && @file_exists(DOKU_PLUGIN."$p/lang/".$conf['lang']."/lang.php")) {
 247              include DOKU_PLUGIN."$p/lang/".$conf['lang']."/lang.php";
 248          }
 249          if (isset($lang['js'])) {
 250              $pluginstrings[$p] = $lang['js'];
 251          }
 252      }
 253      return $pluginstrings;
 254  }
 255  
 256  /**
 257   * Escapes a String to be embedded in a JavaScript call, keeps \n
 258   * as newline
 259   *
 260   * @author Andreas Gohr <andi@splitbrain.org>
 261   */
 262  function js_escape($string){
 263      return str_replace('\\\\n','\\n',addslashes($string));
 264  }
 265  
 266  /**
 267   * Adds the given JavaScript code to the window.onload() event
 268   *
 269   * @author Andreas Gohr <andi@splitbrain.org>
 270   */
 271  function js_runonstart($func){
 272      echo "addInitEvent(function(){ $func; });".NL;
 273  }
 274  
 275  /**
 276   * Strip comments and whitespaces from given JavaScript Code
 277   *
 278   * This is a port of Nick Galbreath's python tool jsstrip.py which is
 279   * released under BSD license. See link for original code.
 280   *
 281   * @author Nick Galbreath <nickg@modp.com>
 282   * @author Andreas Gohr <andi@splitbrain.org>
 283   * @link   http://code.google.com/p/jsstrip/
 284   */
 285  function js_compress($s){
 286      $s = ltrim($s);     // strip all initial whitespace
 287      $s .= "\n";
 288      $i = 0;             // char index for input string
 289      $j = 0;             // char forward index for input string
 290      $line = 0;          // line number of file (close to it anyways)
 291      $slen = strlen($s); // size of input string
 292      $lch  = '';         // last char added
 293      $result = '';       // we store the final result here
 294  
 295      // items that don't need spaces next to them
 296      $chars = "^&|!+\-*\/%=\?:;,{}()<>% \t\n\r'\"[]";
 297  
 298      while($i < $slen){
 299          // skip all "boring" characters.  This is either
 300          // reserved word (e.g. "for", "else", "if") or a
 301          // variable/object/method (e.g. "foo.color")
 302          while ($i < $slen && (strpos($chars,$s[$i]) === false) ){
 303              $result .= $s{$i};
 304              $i = $i + 1;
 305          }
 306  
 307          $ch = $s{$i};
 308          // multiline comments (keeping IE conditionals)
 309          if($ch == '/' && $s{$i+1} == '*' && $s{$i+2} != '@'){
 310              $endC = strpos($s,'*/',$i+2);
 311              if($endC === false) trigger_error('Found invalid /*..*/ comment', E_USER_ERROR);
 312              $i = $endC + 2;
 313              continue;
 314          }
 315  
 316          // singleline
 317          if($ch == '/' && $s{$i+1} == '/'){
 318              $endC = strpos($s,"\n",$i+2);
 319              if($endC === false) trigger_error('Invalid comment', E_USER_ERROR);
 320              $i = $endC;
 321              continue;
 322          }
 323  
 324          // tricky.  might be an RE
 325          if($ch == '/'){
 326              // rewind, skip white space
 327              $j = 1;
 328              while($s{$i-$j} == ' '){
 329                  $j = $j + 1;
 330              }
 331              if( ($s{$i-$j} == '=') || ($s{$i-$j} == '(') ){
 332                  // yes, this is an re
 333                  // now move forward and find the end of it
 334                  $j = 1;
 335                  while($s{$i+$j} != '/'){
 336                      while( ($s{$i+$j} != '\\') && ($s{$i+$j} != '/')){
 337                          $j = $j + 1;
 338                      }
 339                      if($s{$i+$j} == '\\') $j = $j + 2;
 340                  }
 341                  $result .= substr($s,$i,$j+1);
 342                  $i = $i + $j + 1;
 343                  continue;
 344              }
 345          }
 346  
 347          // double quote strings
 348          if($ch == '"'){
 349              $j = 1;
 350              while( $s{$i+$j} != '"' && ($i+$j < $slen)){
 351                  if( $s{$i+$j} == '\\' && ($s{$i+$j+1} == '"' || $s{$i+$j+1} == '\\') ){
 352                      $j += 2;
 353                  }else{
 354                      $j += 1;
 355                  }
 356              }
 357              $result .= substr($s,$i,$j+1);
 358              $i = $i + $j + 1;
 359              continue;
 360          }
 361  
 362          // single quote strings
 363          if($ch == "'"){
 364              $j = 1;
 365              while( $s{$i+$j} != "'" && ($i+$j < $slen)){
 366                  if( $s{$i+$j} == '\\' && ($s{$i+$j+1} == "'" || $s{$i+$j+1} == '\\') ){
 367                      $j += 2;
 368                  }else{
 369                      $j += 1;
 370                  }
 371              }
 372              $result .= substr($s,$i,$j+1);
 373              $i = $i + $j + 1;
 374              continue;
 375          }
 376  
 377          // whitespaces
 378          if( $ch == ' ' || $ch == "\r" || $ch == "\n" || $ch == "\t" ){
 379              // leading spaces
 380              if($i+1 < $slen && (strpos($chars,$s[$i+1]) !== false)){
 381                  $i = $i + 1;
 382                  continue;
 383              }
 384              // trailing spaces
 385              //  if this ch is space AND the last char processed
 386              //  is special, then skip the space
 387              $lch = substr($result,-1);
 388              if($lch && (strpos($chars,$lch) !== false)){
 389                  $i = $i + 1;
 390                  continue;
 391              }
 392              // else after all of this convert the "whitespace" to
 393              // a single space.  It will get appended below
 394              $ch = ' ';
 395          }
 396  
 397          // other chars
 398          $result .= $ch;
 399          $i = $i + 1;
 400      }
 401  
 402      return trim($result);
 403  }
 404  
 405  //Setup VIM: ex: et ts=4 enc=utf-8 :
 406  ?>


Generated: Sat Sep 6 01:30:01 2008 Cross-referenced by PHPXref 0.7