<?php
/*
js.php, WAJAF, the WebAbility(r) Javascript Application Framework
Contains the wrapper to load, minimize and cache javascripts of WAJAF
(c) 2008-2009 Philippe Thomassigny
This file is part of WAJAF
WAJAF is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
WAJAF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with WAJAF. If not, see <http://www.gnu.org/licenses/>.
*/
class js
{
function notFound()
{
if (substr(php_sapi_name(), 0, 3) == 'cgi')
header('Status: 404 Not Found', TRUE);
else
header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
return null;
}
function getJS($BASEDIR, $REPOSITORYDIR)
{
if (isset($_GET["JS"]) && $_GET["JS"])
{
if (strpos($_GET["JS"], "/") !== false || strpos($_GET["JS"], "\\") || strpos($_GET["JS"], "%2F") || strpos($_GET["JS"], "%5C")) // No / \ or rawurlencoded allowed
return $this->notFound();
$dirs = array('/system/', '/managers/', '/containers/', '/elements/');
$xF = explode(',', $_GET["JS"]);
if (!$xF)
return null;
$code = '';
$usedF = array();
$finalF = array();
foreach ($xF as $k => $js)
{
if ($js == 'wajaf.js')
{
unset($xF[$k]);
$usedF['core.js'] = $finalF[] = 'core.js';
$usedF['eventManager.js'] = $finalF[] = 'eventManager.js';
$usedF['ddManager.js'] = $finalF[] = 'ddManager.js';
$usedF['soundManager.js'] = $finalF[] = 'soundManager.js';
$usedF['animManager.js'] = $finalF[] = 'animManager.js';
$usedF['helpManager.js'] = $finalF[] = 'helpManager.js';
$usedF['ajaxManager.js'] = $finalF[] = 'ajaxManager.js';
$usedF['ondemandManager.js'] = $finalF[] = 'ondemandManager.js';
$usedF['messageManager.js'] = $finalF[] = 'messageManager.js';
$usedF['wa4glManager.js'] = $finalF[] = 'wa4glManager.js';
}
}
foreach ($xF as $k => $js)
{
if (!isset($usedF[$js]))
$usedF[$js] = $finalF[] = $js;
}
foreach ($finalF as $k => $js)
{
$filename = null;
foreach ($dirs as $d)
{
$fn = $BASEDIR.$d.$js;
if (file_exists($fn))
{
$filename = $fn;
break;
}
}
if ($filename)
{
$code .= $this->minimizeJS($REPOSITORYDIR, $filename);
}
}
header("Content-Type: text/javascript");
header("Content-Length: " . strlen($code));
print $code;
return null;
}
elseif (isset($_GET["TEMP"]))
{
if (strpos("/", $_GET["TEMP"]) !== false || strpos("\\", $_GET["TEMP"]) || strpos("%2F", $_GET["TEMP"]) || strpos("%5C", $_GET["TEMP"])) // No / \ or rawurlencoded allowed
return $this->notFound();
$filename = $BASEDIR."/components/js/templates/".$_GET["TEMP"];
if (file_exists($filename))
{
header("Content-Type: text/html");
header("Content-Length: " . filesize($filename));
readfile($filename);
return;
}
else
{
return $this->notFound();
}
}
return $this->notFound();
}
function minimizeJS($REPOSITORYDIR, $filename)
{
$cfilename = $REPOSITORYDIR.'jsmin/'.md5($filename);
if (is_file($cfilename))
{
// check dates cache vs original to know if we use or invalidate the file
if (filemtime($cfilename) > filemtime($filename))
return file_get_contents($cfilename);
unlink($cfilename);
}
$code = file_get_contents($filename);
if (strpos($code, 'NO_MIN') !== false)
return $code;
$code = JSMin::minify($code);
file_put_contents($cfilename, $code);
return $code;
}
}
$j = new js();
echo $j->getJS('../../','../../../temporal/');
// ==================================================================================================
// The class below is not part of WAJAF v1 and is (c) to its specific authors.
// ==================================================================================================
/**
* jsmin.php - PHP implementation of Douglas Crockford's JSMin.
*
* This is pretty much a direct port of jsmin.c to PHP with just a few
* PHP-specific performance tweaks. Also, whereas jsmin.c reads from stdin and
* outputs to stdout, this library accepts a string as input and returns another
* string as output.
*
* PHP 5 or higher is required.
*
* Permission is hereby granted to use this version of the library under the
* same terms as jsmin.c, which has the following license:
*
* --
* Copyright (c) 2002 Douglas Crockford (www.crockford.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* The Software shall be used for Good, not Evil.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* --
*
* @package JSMin
* @author Ryan Grove <ryan@wonko.com>
* @copyright 2002 Douglas Crockford <douglas@crockford.com> (jsmin.c)
* @copyright 2008 Ryan Grove <ryan@wonko.com> (PHP port)
* @license http://opensource.org/licenses/mit-license.php MIT License
* @version 1.1.1 (2008-03-02)
* @link http://code.google.com/p/jsmin-php/
*/
class JSMin
{
const ORD_LF = 10;
const ORD_SPACE = 32;
protected $a = '';
protected $b = '';
protected $input = '';
protected $inputIndex = 0;
protected $inputLength = 0;
protected $lookAhead = null;
protected $output = '';
// -- Public Static Methods --------------------------------------------------
public static function minify($js)
{
$jsmin = new JSMin($js);
return $jsmin->min();
}
// -- Public Instance Methods ------------------------------------------------
public function __construct($input)
{
$this->input = str_replace("\r\n", "\n", $input);
$this->inputLength = strlen($this->input);
}
// -- Protected Instance Methods ---------------------------------------------
protected function action($d)
{
switch($d)
{
case 1:
$this->output .= $this->a;
case 2:
$this->a = $this->b;
if ($this->a === "'" || $this->a === '"')
{
for (;;)
{
$this->output .= $this->a;
$this->a = $this->get();
if ($this->a === $this->b)
{
break;
}
if (ord($this->a) <= self::ORD_LF)
{
throw new JSMinException('Unterminated string literal.');
}
if ($this->a === '\\')
{
$this->output .= $this->a;
$this->a = $this->get();
}
}
}
case 3:
$this->b = $this->next();
if ($this->b === '/' && (
$this->a === '(' || $this->a === ',' || $this->a === '=' ||
$this->a === ':' || $this->a === '[' || $this->a === '!' ||
$this->a === '&' || $this->a === '|' || $this->a === '?'))
{
$this->output .= $this->a . $this->b;
for (;;)
{
$this->a = $this->get();
if ($this->a === '/')
{
break;
}
elseif ($this->a === '\\')
{
$this->output .= $this->a;
$this->a = $this->get();
}
elseif (ord($this->a) <= self::ORD_LF)
{
throw new JSMinException('Unterminated regular expression '.
'literal.');
}
$this->output .= $this->a;
}
$this->b = $this->next();
}
}
}
protected function get()
{
$c = $this->lookAhead;
$this->lookAhead = null;
if ($c === null)
{
if ($this->inputIndex < $this->inputLength)
{
$c = $this->input[$this->inputIndex];
$this->inputIndex += 1;
}
else
{
$c = null;
}
}
if ($c === "\r")
{
return "\n";
}
if ($c === null || $c === "\n" || ord($c) >= self::ORD_SPACE)
{
return $c;
}
return ' ';
}
protected function isAlphaNum($c)
{
return ord($c) > 126 || $c === '\\' || preg_match('/^[\w\$]$/', $c) === 1;
}
protected function min()
{
$this->a = "\n";
$this->action(3);
while ($this->a !== null)
{
switch ($this->a)
{
case ' ':
if ($this->isAlphaNum($this->b))
{
$this->action(1);
}
else
{
$this->action(2);
}
break;
case "\n":
switch ($this->b)
{
case '{':
case '[':
case '(':
case '+':
case '-':
$this->action(1);
break;
case ' ':
$this->action(3);
break;
default:
if ($this->isAlphaNum($this->b))
{
$this->action(1);
}
else
{
$this->action(2);
}
}
break;
default:
switch ($this->b)
{
case ' ':
if ($this->isAlphaNum($this->a))
{
$this->action(1);
break;
}
$this->action(3);
break;
case "\n":
switch ($this->a)
{
case '}':
case ']':
case ')':
case '+':
case '-':
case '"':
case "'":
$this->action(1);
break;
default:
if ($this->isAlphaNum($this->a))
{
$this->action(1);
}
else
{
$this->action(3);
}
}
break;
default:
$this->action(1);
break;
}
}
}
return $this->output;
}
protected function next()
{
$c = $this->get();
if ($c === '/')
{
switch($this->peek())
{
case '/':
for (;;)
{
$c = $this->get();
if (ord($c) <= self::ORD_LF)
{
return $c;
}
}
case '*':
$this->get();
for (;;) {
switch($this->get())
{
case '*':
if ($this->peek() === '/')
{
$this->get();
return ' ';
}
break;
case null:
throw new JSMinException('Unterminated comment.');
}
}
default:
return $c;
}
}
return $c;
}
protected function peek()
{
$this->lookAhead = $this->get();
return $this->lookAhead;
}
}
// -- Exceptions ---------------------------------------------------------------
class JSMinException extends Exception {}
?>
|