phpjs
Version:
171 lines (162 loc) • 7.54 kB
JavaScript
function dl(library) {
// http://kevin.vanzonneveld.net
// + original by: Brett Zamir (http://brett-zamir.me)
// % note 1: The phpjs.extensions_detect_files custom option requires privileges (and Mozilla at present)
// % note 2: It is generally advised to use the compiler instead of relying on this feature
// - depends on: get_extension_funcs
// - depends on: include
// - depends on: file_get_contents
// * example 1: dl('strings');
// * returns 1: true
var basepath = '', sep = '/', funcs = [], jsext = '.js', ret = false, i = 0, j = 0, subdirs = false, skipErrors = false,
libraries = ['array', 'bc', 'classkit', 'classobj', 'ctype', 'datetime', 'errorfunc', 'exec', 'filesystem', 'funchand',
'i18n', 'inclued', 'info', 'json', 'language', 'math', 'misc', 'net-gopher', 'network', 'objaggregation',
'outcontrol', 'overload', 'pcre', 'runkit', 'session', 'stream', 'strings', 'tokenizer', 'url', 'var', 'xml',
'xmlreader', 'xmlwriter'],
indexOf = function(value) {
for (var i = 0, length = this.length; i < length; i++) {
if (this[i] === value) {
return i;
}
}
return -1;
};
this.php_js = this.php_js || {};
var ini = this.php_js.ini = this.php_js.ini || {};
var that = this;
var _fgc = function(filestr) {
var contents = that.file_get_contents(filestr).replace(/^(function\s+(.*?)\s*\()/gm, 'that.$2 = $1'); // We set the scope to 'this', assuming main functions are at the beginning of lines
ret = !!eval(contents);
return ret;
};
var _ini_get = function(varname) {
if (ini[varname] && ini[varname].local_value !== undefined) {
if (ini[varname].local_value === null) {
return '';
}
return ini[varname].local_value;
}
return '';
};
if (_ini_get('enable_dl') === false || _ini_get('safe_mode')) {
return false;
}
this.php_js.ini['phpjs.loaded_extensions'] = this.php_js.ini['phpjs.loaded_extensions'] || {};
this.php_js.ini['phpjs.loaded_extensions'].local_value = this.php_js.ini['phpjs.loaded_extensions'].local_value || [];
if (!this.php_js.ini['phpjs.loaded_extensions'].local_value.indexOf) {
this.php_js.ini['phpjs.loaded_extensions'].local_value.indexOf = indexOf;
}
if (this.php_js.ini['phpjs.loaded_extensions'].local_value.indexOf(library) === -1) {
this.php_js.ini['phpjs.loaded_extensions'].local_value.push(library);
}
var ext_dir = _ini_get('extension_dir'); // We allow this to be an array of directories as well as a string
ext_dir = (typeof ext_dir === 'string') ? [ext_dir] : ext_dir;
subdirs = _ini_get('phpjs.extension_dir_subdirs');
skipErrors = _ini_get('phpjs.dl_skip_errors');
// This option will load all files available in the extension_dir(s) as individual files; depending on the
// number of directories to check and the functions in the extension (or files in the directory), this could take
// quite a while (e.g., with individual string functions); this option should really just be used for local
// experimentation (e.g., with SVN files) on smaller sets of files
if (_ini_get('phpjs.extensions_individual_files')) {
if (_ini_get('phpjs.extensions_detect_files')) {
// We might not want to depend on get_extension_funcs(), since that is for all possible functions in the
// extension and all must be present
// sep = navigator.platform.indexOf('Win') !== -1 ? '\\' : '/'; // Here it may be in native form // We don't use so can be file URL and used in a local script tag
for (j = 0; j < ext_dir.length; j++) {
basepath = subdirs ? ext_dir[j] + sep + library + sep : ext_dir[j] + sep;
// Mozilla only
/** Use this instead of the following block (and uncomment the sep assignment above) if non-fileURLs are desired (fileURLs are more portable)
var file = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
file.initWithPath(basepath);
//*/
/**/
var ios = Components.classes["@mozilla.org/network/io-service;1"].
getService(Components.interfaces.nsIIOService);
var URL = ios.newURI(basepath, null, null);
var file = URL.QueryInterface(Components.interfaces.nsIFileURL).file;
//*/
try {
var entries = file.directoryEntries;
} catch (e) {
continue;
}
while (entries.hasMoreElements()) {
var entry = entries.getNext();
entry.QueryInterface(Components.interfaces.nsIFile);
// For consistency, we'll get a file URI to still include via script tag
ios = Components.classes['@mozilla.org/network/io-service;1'].getService(Components.interfaces.nsIIOService);
URL = ios.newFileURI(entry);
var filen = URL.spec.slice(URL.spec.slice(0, -1).lastIndexOf('/') + 1);
if (filen.charAt(0) !== '.') {
funcs.push(URL.spec);
}
}
for (i = 0; i < funcs.length; i++) {
//ret = !!this.include(funcs[i]);
try {
ret = _fgc(funcs[i]);
} catch (e) {
}
}
}
return ret;
}
else {
funcs = this.get_extension_funcs(library);
for (i = 0; i < funcs.length; i++) {
ret = false;
for (j = 0; j < ext_dir.length && !ret; j++) {
basepath = subdirs ? ext_dir[j] + sep + library + sep : ext_dir[j] + sep;
//ret = !!this.include(basepath+funcs[i]+jsext);
try {
ret = _fgc(basepath + funcs[i] + jsext);
}
catch (e) {
}
}
if (!ret) {
if (!skipErrors) {break;} // Fail on a single individual file not being found
}
}
return ret;
}
} else {
if (!libraries.indexOf) {
libraries.indexOf = indexOf;
}
if (libraries.indexOf(library) === -1 && !_ini_get('phpjs.dl_allow_individual_funcs')) {
throw 'The library or file is not recognized';
}
// Allow some checking to see if file exists, and if not, check other ext_dir indexes
for (i = 0; i < ext_dir.length && !ret; i++) { // Stop after success
basepath = subdirs && !_ini_get('phpjs.dl_allow_individual_funcs') ? ext_dir[i] + sep + library + sep : ext_dir[i] + sep;
// ret = !!this.include(basepath+library+jsext);
// We use eval() since include() as currently implemented may still be loading the file asynchonously
try {
if (library.slice(-3) === jsext) {
library = library.slice(0, -3);
}
ret = _fgc(basepath + library + jsext);
} catch (e) {
this.get_extension_funcs(); // Doesn't need to exist as we're just setting up the global below
for (var ext in this.php_js.exts) {
if (!this.php_js.exts[ext].indexOf) {
this.php_js.exts[ext].indexOf = indexOf;
}
if (this.php_js.exts[ext].indexOf(library) !== -1) {
try {
ret = _fgc(basepath + ext + sep + library + jsext);
return ret;
}
catch (e) { // Even with skipErrors off, we allow it to get errors in some of the extension directories
}
}
}
}
}
if (!skipErrors) {
return false;
}
return ret;
}
}