Merge pull request #122 from roccivic/js-file-loader

Js file loader
This commit is contained in:
Michal Čihař 2012-12-19 05:22:16 -08:00
commit fe8999cdb3
3 changed files with 103 additions and 64 deletions

View File

@ -255,7 +255,7 @@ var AJAX = {
$('#selflink > a').attr('href', data._selflink);
}
if (data._scripts) {
AJAX.scriptHandler.load(data._scripts, 1);
AJAX.scriptHandler.load(data._scripts);
}
if (data._selflink && data._scripts && data._menuHash && data._params) {
AJAX.cache.add(
@ -329,46 +329,46 @@ var AJAX = {
return this;
},
/**
* Queues up an array of files to be downloaded
* Download a list of js files in one request
*
* @param array files An array of filenames and flags
*
* @return void
*/
load: function (files, reset) {
if (reset) {
this._scriptsToBeLoaded = [];
this._scriptsToBeFired = [];
}
load: function (files) {
var self = this;
self._scriptsToBeLoaded = [];
self._scriptsToBeFired = [];
for (var i in files) {
this._scriptsToBeLoaded.push(files[i].name);
self._scriptsToBeLoaded.push(files[i].name);
if (files[i].fire) {
this._scriptsToBeFired.push(files[i].name);
self._scriptsToBeFired.push(files[i].name);
}
}
this.callback();
},
/**
* Called whenever a file is loaded.
* Will queue up another file, or call done();
*
* @return void
*/
callback: function () {
var scripts = this._scriptsToBeLoaded;
if (scripts.length > 0) {
var script = scripts.shift();
if ($.inArray(script, this._scripts) == -1) {
// Generate a request string
var request = [];
var needRequest = false;
for (var index in self._scriptsToBeLoaded) {
var script = self._scriptsToBeLoaded[index];
// Only for scripts that we don't already have
if ($.inArray(script, self._scripts) == -1) {
needRequest = true;
this.add(script);
var self = this;
$.getScript('js/' + script, function () {
self.callback();
});
} else {
this.callback();
request.push("scripts[]=" + script);
}
}
// Download the composite js file, if necessary
if (needRequest) {
$.ajax({
url: "js/get_scripts.js.php?" + request.join("&"),
cache: true,
success: function () {
self.done();
},
dataType: "script"
});
} else {
this.done();
self.done();
}
},
/**
@ -386,7 +386,6 @@ var AJAX = {
* Fires all the teardown event handlers for the current page
* and rebinds all forms and links to the request handler
*
* @param object ctx Context for the callback
* @param function callback The callback to call after resetting
*
* @return void

38
js/get_scripts.js.php Normal file
View File

@ -0,0 +1,38 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Concatenates reveral js files to reduce the number of
* http requests sent to the server
*
* @package PhpMyAdmin
*/
chdir('..');
// Send correct type
header('Content-Type: text/javascript; charset=UTF-8');
// Enable browser cache for 1 hour
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
if (! empty($_GET['scripts']) && is_array($_GET['scripts'])) {
foreach ($_GET['scripts'] as $script) {
// Sanitise filename
$script_name = 'js';
$path = explode("/", $script);
foreach ($path as $index => $filename) {
if (! preg_match("@^\.+$@", $filename)
&& preg_match("@^[\w\.-]+$@", $filename)
) {
// Disallow "." and ".." alone
// Allow alphanumeric, "." and "-" chars only
$script_name .= DIRECTORY_SEPARATOR . $filename;
}
}
// Output file contents
if (preg_match("@\.js$@", $script_name) && is_readable($script_name)) {
readfile($script_name);
echo ";\n\n";
}
}
}
?>

View File

@ -44,32 +44,38 @@ class PMA_Scripts
/**
* Returns HTML code to include javascript file.
*
* @param string $url Location of javascript, relative to js/ folder.
* @param int $timestamp The date when the file was last modified
* @param string $ie_conditional true - wrap with IE conditional comment
* 'lt 9' etc. - wrap for specific IE version
* @param array $files The list of js file to include
*
* @return string HTML code for javascript inclusion.
*/
private function _includeFile($url, $timestamp = null, $ie_conditional = false)
private function _includeFiles($files)
{
$include = '';
if ($ie_conditional !== false) {
if ($ie_conditional === true) {
$include .= '<!--[if IE]>' . "\n ";
$dynamic_scripts = "";
$params = array();
foreach ($files as $key => $value) {
if (strpos($value['filename'], "?") === false) {
$include = true;
if ($value['conditional_ie'] !== false && PMA_USR_BROWSER_AGENT === 'IE') {
if ($value['conditional_ie'] === true) {
$include = true;
} else if ($value['conditional_ie'] == PMA_USR_BROWSER_VER) {
$include = true;
} else {
$include = false;
}
}
if ($include) {
$params[] = "scripts[]=" . $value['filename'];
}
} else {
$include .= '<!--[if IE ' . $ie_conditional . ']>' . "\n ";
$dynamic_scripts .= "<script type='text/javascript' src='js/" . $value['filename'] . "'></script>";
}
}
$include .= '<script src="' . $url;
if (! empty($timestamp)) {
$include .= '?ts=' . filemtime($url);
}
$include .= '" type="text/javascript"></script>' . "\n";
if ($ie_conditional !== false) {
$include .= '<![endif]-->' . "\n";
}
return $include;
$static_scripts = sprintf(
"<script type='text/javascript' src='js/get_scripts.js.php?%s'></script>",
implode("&", $params)
);
return $static_scripts . $dynamic_scripts;
}
/**
@ -99,14 +105,9 @@ class PMA_Scripts
$hash = md5($filename);
if (empty($this->_files[$hash])) {
$has_onload = $this->_eventBlacklist($filename);
$timestamp = null;
if (strpos($filename, '?') === false) {
$timestamp = filemtime('js/' . $filename);
}
$this->_files[$hash] = array(
'has_onload' => $has_onload,
'filename' => $filename,
'timestamp' => $timestamp,
'conditional_ie' => $conditional_ie
);
}
@ -175,11 +176,13 @@ class PMA_Scripts
{
$retval = array();
foreach ($this->_files as $file) {
if (! $file['conditional_ie'] || PMA_USR_BROWSER_AGENT == 'IE') {
$retval[] = array(
'name' => $file['filename'],
'fire' => $file['has_onload']
);
if (strpos($file['filename'], "?") === false) {
if (! $file['conditional_ie'] || PMA_USR_BROWSER_AGENT == 'IE') {
$retval[] = array(
'name' => $file['filename'],
'fire' => $file['has_onload']
);
}
}
}
return $retval;
@ -194,13 +197,12 @@ class PMA_Scripts
{
$retval = '';
foreach ($this->_files as $file) {
$retval .= $this->_includeFile(
'js/' . $file['filename'],
$file['timestamp'],
$file['conditional_ie']
if (count($this->_files) > 0) {
$retval .= $this->_includeFiles(
$this->_files
);
}
$code = 'AJAX.scriptHandler';
foreach ($this->_files as $file) {
$code .= sprintf(