Javascript Porter Ver 2.0 Source Code


*         //#include_once 
*     filename is the name of the Javascript to be
*     included, without extension ".js".
*     When using "#include_once", the file will only
*     be included when that file has not yet been
*     included before.
*         If loading file A, B and C, while A and B
*         both need to include D, when processing
*         the "#include_once" command in file B, D
*         will not be included again.
*     The inclusion command is find recuisively; if
*     the file being included needs to include other
*     files, those file will be loaded first.
*     If any file that is need by one file fails to
*     be loaded, either not existing or unreadable,
*     the whole file is considered failing to be loaded.
* Change the header to console commands.
* Added a switch to disable header.
*
* ver 1.1 change log
* Fixed the issue when removing in-line comments. Now only
* single-line comments will be removed, pending in-line
* comments will remain.
*
* ver 1.0 change log
* This program gathers and sends multiple Javascript files
* on demand which benefits webpage loading speed in the
* way of avoiding unnecessary requests and reduces the
* amount of Script tags on pages.
*
* Instruction:
* This program search under the preset folder (JSFILEFOLDER)
* for requested files and send them in order
* This program accepts 4 arguments: l(link list), duplicate
* , noheader and compress
* Arguments:
*     link list
*         A list of names of Javascript files needed to be gathered
*         Do not include file extension (.js), separate with commas
*     duplicate
*         Allow duplication or not (i.e. when the request is "A,B,A", if duplication is not allowed, the last duplicated A will be ignored)
*         Acceptable Value: true | yes | false | no
*         Default: no
*     noheader
*         disable header
*         Acceptable Value: true | yes | false | no
*         Default: no
*     compress
*         Level of compression
*         Add 1 to remove comment blocks
*         Add 2 to remove comment lines
*         Add 4 to remove indents
*         Add 8 to remove line breakers
*         i.e. if need to remove all comments, use value 3 (Add 1 and 2)
*         Default: 0 (no compression)
* Request Sample: js.php?l=jquery-latest,yui-latest&duplicate=true&compress=15&noheader=true
* jquery-latest.js and yui-latest.js are requested, allowing duplication, at compression level of 15 and disable header
*/
define('APPNAME', 'Javascript Porter ver 2.0');
define('JSFILEFOLDER', './js');
// output buffer start
ob_start();
// set output header
header('Content-Type: application/javascript');
header('Content-Disposition: inline; filename="container.js"');
header('Cache-Control: no-cache');
header('Pragma: no-cache');
// print title
printf("console.group('%s');n", APPNAME);
// fetch raw request
// if no js file list request detected, halt
if (!array_key_exists('l', $_GET))
die("console.warn('no request');");
$rawRequestString = $_GET['l'];
$noHeader  = array_key_exists('noheader', $_GET)
? (($_GET['noheader'] == 'yes' || $_GET['noheader'] == 'true')
? true
: false)
: false;
$allowDuplicate  = array_key_exists('duplicate', $_GET)
? (($_GET['duplicate'] == 'yes' || $_GET['duplicate'] == 'true')
? true
: false)
: false;
$compression      = array_key_exists('compress', $_GET)
? intval($_GET['compress'])
: 0;
// force direct to directory containing this file
chdir(dirname(__FILE__));
// javascript file folder check
if (!file_exists(JSFILEFOLDER) || !is_dir(JSFILEFOLDER))
die("console.error('js directory not found');");
// force direct to directory containing javascript files
chdir(JSFILEFOLDER);
function jsCompress($jsContent, $compressLevel)
{
// 1 remove comment blocks
// 2 remove comment lines
// 3 remove all comments
// 4 remove indents
// 5 remove comment blocks and indents
// 6 remove comment lines and indents
// 7 remove all comments and indents
// 8 remove line breakers *
// 9 remove comment blocks and line breakers *
// 10 remove comment lines and line breakers
// 11 remove all comments and line breakers
// 12 remove indents and line breakers *
// 13 remove comment blocks, indents and line breakers *
// 14 remove comment lines, indents and line breakers
// 15 remove all comments and line breakers
// * not suggested using without removing comment lines
// if invalid comression level, return raw content
if ($compressLevel > 15)
return $jsContent;
// remove comment blocks
if ($compressLevel % 2 >= 1)
$jsContent = preg_replace('//*.**//uUs', '', $jsContent);
// remove comment lines
if ($compressLevel % 4 >= 2)
$jsContent = preg_replace('/^s*//.*$/uUm', '', $jsContent);
// remove indents
if ($compressLevel % 8 >= 4)
$jsContent = preg_replace('/^s+/um', '', $jsContent);
// remove line breakers
if ($compressLevel % 16 >= 8)
$jsContent = preg_replace('/(n|r)/um', ' ', $jsContent);
return $jsContent;
}
function parseItems($itemString)
{
$rawItems = explode(',', $itemString);
$resultItems = array();
for ($i = 0; $i < count($rawItems); ++$i) {
$temp = trimKey($rawItems[$i]);
if ($temp !== '') array_push($resultItems, $temp);
unset($temp);
}
unset($rawItems);
return $resultItems;
}
function trimKey($filename)
{
return urlencode(trim(basename($filename)));
}
// a dummy function for getContent()
function getContentOnlyIfNotInBank($key, &$contentBank)
{
return getContent($key, &$contentBank, true);
}
function getContent($key, &$contentBank, $onlyIfNotInBank = false)
{
$key = trimKey($key);
if (array_key_exists($key, $contentBank)) {
return (!$onlyIfNotInBank) ? $contentBank[$key] : '';
} else {
$returnValue = false;
$filename = "{$key}.js";
printf("console.group('getting content of %s');n", $filename);
if (!file_exists($filename) || !is_file($filename) || !is_readable($filename)) {
print("console.warn('file not found or not readable');n");
} else {
$rawFileContent = file_get_contents($filename);
if ($rawFileContent === false) {
print("console.warn('file not readable');n");
} else {
$fileComplete = true;
// deal with include_once commands
while ($fileComplete && preg_match('/^(//#include_once <(.{1,})>)$/um', $rawFileContent, $matches) > 0) {
$includingCommand = $matches[1];
$includingKey = trimKey($matches[2]);
printf("console.log('including %s');n", $includingKey);
$includingContent = getContentOnlyIfNotInBank($includingKey, $contentBank);
if ($includingContent === false) {
print("console.warn('including failed, file incomplete');n");
$fileComplete = false; // break;
} else {
$rawFileContent = str_replace($includingCommand, $includingContent, $rawFileContent);
print("console.log('including done');n");
}
unset($includingCommand, $includingKey, $includingContent);
}
// deal with include commands
while ($fileComplete && preg_match('/^(//#include <(.{1,})>)$/um', $rawFileContent, $matches) > 0) {
$includingCommand = $matches[1];
$includingKey = trimKey($matches[2]);
printf("console.log('including %s');n", $includingKey);
$includingContent = getContent($includingKey, $contentBank);
if ($includingContent === false) {
print("console.warn('including failed, file incomplete');n");
$fileComplete = false; // break;
} else {
$rawFileContent = str_replace($includingCommand, $includingContent, $rawFileContent);
print("console.log('including done');n");
}
unset($includingCommand, $includingKey, $includingContent);
}
$returnValue = ($fileComplete) ? $rawFileContent : false;
unset($fileComplete);
}
unset($rawFileContent);
}
print("console.groupEnd();n");
$contentBank[$key] = $returnValue;
return $returnValue;
}
}
printf("console.info('raw request: %s');n", $rawRequestString);
printf("console.info('allow duplicates: %s');n", $allowDuplicate ? 'true' : 'false');
// turn requested file list (seperated by ',') into an array
$requestList = parseItems($rawRequestString);
// traversal all requested items and setup a hash table for files to be loaded
// printList is an array of js filenames in which order js file contents should be printed
$printList = array();
while (count($requestList) > 0) {
$requestItem = array_shift($requestList);
if ($allowDuplicate || !in_array($requestItem, $printList, true)) array_push($printList, $requestItem);
}
print("console.group('requested js files...');n");
// $contents is an array of js file contents with their filename as keys
$contents = array();
for ($i = 0; $i < count($printList); ++$i) {
$key = $printList[$i];
$printList[$i] = jsCompress(getContent($key, $contents), $compression);
printf("console.log('%s %s');n", $key, (!$printList[$i]) ? 'false' : md5($printList[$i]));
}
print("console.groupEnd();n");
// clean header if requested
if ($noHeader) ob_clean();
for ($i = 0; $i < count($printList); ++$i) {
$content = (!$printList[$i]) ? '' : "n{$printList[$i]}n";
print($content);
}
ob_end_flush();
?>

Javascript Porter Ver 1.1 Source Code

/**
* Javascript Porter ver 1.1
* Fixed the issue when removing in-line comments. Now only single-line
* comments will be removed, pending in-line comments will remain.
*
* This program gathers and sends multiple Javascript files on demand
* which benefits webpage loading speed in the way of avoiding
* unnecessary requests and reduces the amount of Script tags on pages
*
* Instruction:
* This program search under the preset folder (JSFILEFOLDER) for requested files and send them in order
* This program accepts 3 arguments: l(link list), duplicate and compress
* Arguments:
*     link list
*         A list of names of Javascript files needed to be gathered
*         Do not include file extension (.js), separate with commas
*     duplicate
*         Allow duplication or not (i.e. when the request is "A,B,A", if duplication is not allowed, the last duplicated A will be ignored)
*         Acceptable Value: true | yes | false | no
*         Default: no
*     compress
*         Level of compression
*         Add 1 to remove comment blocks
*         Add 2 to remove comment lines
*         Add 4 to remove indents
*         Add 8 to remove line breakers
*         i.e. if need to remove all comments, use value 3 (Add 1 and 2)
*         Default: 0 (no compression)
* Request Sample: js.php?l=jquery-latest,yui-latest&duplicate=true&compress=15
* jquery-latest.js and yui-latest.js are requested, allowing duplication, at compression level of 15
*/
define('APPNAME', 'Javascript Porter ver 1.0');
define('JSFILEFOLDER', './js');
// Enable output buffer
ob_start();
// Configure output header (Type: Javascript, Filename: container.js, disable cache)
header('Content-Type: application/javascript');
header('Content-Disposition: inline; filename="container.js"');
header('Cache-Control: no-cache');
header('Pragma: no-cache');
// Print program name
printf("/* %s */n", APPNAME);
// Fetch raw request
// If link list is not found, halt the program
if (!array_key_exists('l', $_GET))
die('// no request');
$rawRequestString = $_GET['l'];
$allowDuplicate  = array_key_exists('duplicate', $_GET) 
? (($_GET['duplicate'] == 'yes' || $_GET['duplicate'] == 'true')
? true 
: false) 
: false;
$compression      = array_key_exists('compress', $_GET) 
? intval($_GET['compress']) 
: 0;
// change to program directory
chdir(dirname(__FILE__));
// check if Javascript file directory exists
if (!file_exists(JSFILEFOLDER) || !is_dir(JSFILEFOLDER))
die('// js directory not found');
// change to Javascript file directory
chdir(JSFILEFOLDER);
// Compression Function
function jsCompress($jsContent, $compressLevel)
{
/**
* 1 Remove comment blocks
* 2 Remove comment lines
* 3 Remove all comments
* 4 Remove indents
* 5 Remove comment blocks + indents
* 6 Remove comment lines + indents
* 7 Remove all comments + indents
* 8 Remove line breakers *
* 9 Remove comment blocks + line breakers *
* 10 Remove comment lines + line breakers
* 11 Remove all comments + line breakers
* 12 Remove indents + line breakers *
* 13 Remove comment blocks + indents + line breakers *
* 14 Remove comment lines + indents + line breakers
* 15 Remove all comments + indents + line breakers
* * Not recommended before removing comment lines
*/
// return raw data if compression level is invalid
if ($compressLevel > 15)
return $jsContent;
// remove comment blocks
if ($compressLevel % 2 >= 1)
$jsContent = preg_replace('//*.**//uUs', '', $jsContent);
// remove comment lines
if ($compressLevel % 4 >= 2)
$jsContent = preg_replace('/^s*//.*$/uUm', '', $jsContent);
// remove indents
if ($compressLevel % 8 >= 4)
$jsContent = preg_replace('/^s+/um', '', $jsContent);
// remove line breakers
if ($compressLevel % 16 >= 8)
$jsContent = preg_replace('/(n|r)/um', '', $jsContent);
return $jsContent;
}
// Print organized request info
printf("// raw request: %sn", $rawRequestString);
printf("// allow duplicates: %sn", $allowDuplicate ? 'true' : 'false');
// Turn request list into an array
$requestList = explode(',', $rawRequestString);
// Traverse the requested items and generate a list of files to be loaded
// jsFiles this array has keys as Javascript filenames (without extension) and contents as Javascript file contents
$jsFiles = Array();
// printList this array contains printing order
$printList = Array();
print("// requested js files: n");
foreach ($requestList as $value) {
$requestItem = trim(basename($value));
if ($requestItem == '') continue;
printf("// 	%s,n", $requestItem);
if ($allowDuplicate || !array_key_exists($requestItem, $jsFiles))
$printList[] = $requestItem;
$jsFiles[$requestItem] = false;
}
print("// loading requested files:n");
foreach ($jsFiles as $key => $value) {
$filename = "{$key}.js";
printf("// 	./%s ", $filename);
if (file_exists($filename) && is_file($filename)) {
$jsFiles[$key] = jsCompress(file_get_contents($filename), $compression);
printf("(md5: %s)n", md5($jsFiles[$key]));
} else {
printf("%sn", 'not found');
}
}
// Print Javascript contents
for ($i = 0; $i < count($printList); ++$i) {
$key = $printList[$i];
$content = $jsFiles[$key];
printf("n// %sn%sn", $key, $content);
}
// Program ends
die();

Javascript Porter Ver 1.0 Source Code

/**
* Javascript Porter ver 1.0
* This program gathers and sends multiple Javascript files on demand
* which benefits webpage loading speed in the way of avoiding
* unnecessary requests and reduces the amount of Script tags on pages
*
* Instruction:
* This program search under the preset folder (JSFILEFOLDER) for requested files and send them in order
* This program accepts 3 arguments: l(link list), duplicate and compress
* Arguments:
*     link list
*         A list of names of Javascript files needed to be gathered
*         Do not include file extension (.js), separate with commas
*     duplicate
*         Allow duplication or not (i.e. when the request is "A,B,A", if duplication is not allowed, the last duplicated A will be ignored)
*         Acceptable Value: true | yes | false | no
*         Default: no
*     compress
*         Level of compression
*         Add 1 to remove comment blocks
*         Add 2 to remove comment lines
*         Add 4 to remove indents
*         Add 8 to remove line breakers
*         i.e. if need to remove all comments, use value 3 (Add 1 and 2)
*         Default: 0 (no compression)
* Request Sample: js.php?l=jquery-latest,yui-latest&duplicate=true&compress=15
* jquery-latest.js and yui-latest.js are requested, allowing duplication, at compression level of 15
*/
define('APPNAME', 'Javascript Porter ver 1.0');
define('JSFILEFOLDER', './js');
// Enable output buffer
ob_start();
// Configure output header (Type: Javascript, Filename: container.js, disable cache)
header('Content-Type: application/javascript');
header('Content-Disposition: inline; filename="container.js"');
header('Cache-Control: no-cache');
header('Pragma: no-cache');
// Print program name
printf("/* %s */n", APPNAME);
// Fetch raw request
// If link list is not found, halt the program
if (!array_key_exists('l', $_GET))
die('// no request');
$rawRequestString = $_GET['l'];
$allowDuplicate  = array_key_exists('duplicate', $_GET) 
? (($_GET['duplicate'] == 'yes' || $_GET['duplicate'] == 'true')
? true 
: false) 
: false;
$compression      = array_key_exists('compress', $_GET) 
? intval($_GET['compress']) 
: 0;
// change to program directory
chdir(dirname(__FILE__));
// check if Javascript file directory exists
if (!file_exists(JSFILEFOLDER) || !is_dir(JSFILEFOLDER))
die('// js directory not found');
// change to Javascript file directory
chdir(JSFILEFOLDER);
// Compression Function
function jsCompress($jsContent, $compressLevel)
{
/**
* 1 Remove comment blocks
* 2 Remove comment lines
* 3 Remove all comments
* 4 Remove indents
* 5 Remove comment blocks + indents
* 6 Remove comment lines + indents
* 7 Remove all comments + indents
* 8 Remove line breakers *
* 9 Remove comment blocks + line breakers *
* 10 Remove comment lines + line breakers
* 11 Remove all comments + line breakers
* 12 Remove indents + line breakers *
* 13 Remove comment blocks + indents + line breakers *
* 14 Remove comment lines + indents + line breakers
* 15 Remove all comments + indents + line breakers
* * Not recommended before removing comment lines
*/
// return raw data if compression level is invalid
if ($compressLevel > 15)
return $jsContent;
// remove comment blocks
if ($compressLevel % 2 >= 1)
$jsContent = preg_replace('//*.**//uUs', '', $jsContent);
// remove comment lines
if ($compressLevel % 4 >= 2)
$jsContent = preg_replace('///.*$/uUm', '', $jsContent);
// remove indents
if ($compressLevel % 8 >= 4)
$jsContent = preg_replace('/^s+/um', '', $jsContent);
// remove line breakers
if ($compressLevel % 16 >= 8)
$jsContent = preg_replace('/(n|r)/um', '', $jsContent);
return $jsContent;
}
// Print organized request info
printf("// raw request: %sn", $rawRequestString);
printf("// allow duplicates: %sn", $allowDuplicate ? 'true' : 'false');
// Turn request list into an array
$requestList = explode(',', $rawRequestString);
// Traverse the requested items and generate a list of files to be loaded
// jsFiles this array has keys as Javascript filenames (without extension) and contents as Javascript file contents
$jsFiles = Array();
// printList this array contains printing order
$printList = Array();
print("// requested js files: n");
foreach ($requestList as $value) {
$requestItem = trim(basename($value));
if ($requestItem == '') continue;
printf("// 	%s,n", $requestItem);
if ($allowDuplicate || !array_key_exists($requestItem, $jsFiles))
$printList[] = $requestItem;
$jsFiles[$requestItem] = false;
}
print("// loading requested files:n");
foreach ($jsFiles as $key => $value) {
$filename = "{$key}.js";
printf("// 	./%s ", $filename);
if (file_exists($filename) && is_file($filename)) {
$jsFiles[$key] = jsCompress(file_get_contents($filename), $compression);
printf("(md5: %s)n", md5($jsFiles[$key]));
} else {
printf("%sn", 'not found');
}
}
// Print Javascript contents
for ($i = 0; $i < count($printList); ++$i) {
$key = $printList[$i];
$content = $jsFiles[$key];
printf("n// %sn%sn", $key, $content);
}
// Program ends
die();