tikiwiki/packages/tiki-pkg-casperjs/jerome-breton/casperjs/bin/bootstrap.js
2023-11-20 20:52:04 +00:00

460 lines
17 KiB
JavaScript
Executable File

/*!
* Casper is a navigation utility for PhantomJS.
*
* Documentation: http://casperjs.org/
* Repository: http://github.com/casperjs/casperjs
*
* Copyright (c) 2011-2012 Nicolas Perriault
*
* Part of source code is Copyright Joyent, Inc. and other Node contributors.
*
* 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 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.
*
*/
/*eslint max-statements:0, complexity:0*/
// node check
if ('process' in this && this.process.title === "node") {
console.error('CasperJS cannot be executed within a nodejs environment');
this.process.exit(1);
}
// phantom check
if (!('phantom' in this)) {
console.error('CasperJS needs to be executed in a PhantomJS environment http://phantomjs.org/');
}
// Common polyfills
void function() {
// cujos bind shim instead of MDN shim, see #1396
var isFunction = function(o) {
return 'function' === typeof o;
};
var bind;
var slice = [].slice;
var proto = Function.prototype;
var featureMap = {
'function-bind': 'bind'
};
function has(feature) {
var prop = featureMap[feature];
return isFunction(proto[prop]);
}
// check for missing features
if (!has('function-bind')) {
// adapted from Mozilla Developer Network example at
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
bind = function bind(obj) {
var args = slice.call(arguments, 1),
self = this,
nop = function() {
},
bound = function() {
return self.apply(this instanceof nop ? this : (obj || {}), args.concat(slice.call(arguments)));
};
nop.prototype = this.prototype || {}; // Firefox cries sometimes if prototype is undefined
bound.prototype = new nop();
return bound;
};
proto.bind = bind;
}
}();
// Custom base error
var CasperError = function CasperError(msg) {
"use strict";
Error.call(this);
this.message = msg;
this.name = 'CasperError';
};
CasperError.prototype = Object.getPrototypeOf(new Error());
// casperjs env initialization
(function(global, phantom, system){
"use strict";
// phantom args
var phantomArgs = system.args.slice(1);
if ("slimer" in global) {
phantom.casperEngine = "slimerjs";
} else {
phantom.casperEngine = "phantomjs";
}
if (phantom.casperLoaded) {
return;
}
function __exit(statusCode){
setTimeout(function() { phantom.exit(statusCode); }, 0);
}
function __die(message) {
if (message) {
console.error(message);
}
__exit(1);
}
function __terminate(message) {
if (message) {
console.log(message);
}
__exit();
}
(function (version) {
// required version check
if (phantom.casperEngine === 'phantomjs') {
if (version.major === 1) {
if (version.minor < 9) {
return __die('CasperJS needs at least PhantomJS v1.9 or later.');
}
if (version.minor === 9 && version.patch < 1) {
return __die('CasperJS needs at least PhantomJS v1.9.1 or later.');
}
} else if (version.major === 2) {
// No requirements yet known
} else {
return __die('CasperJS needs PhantomJS v1.9.x or v2.x');
}
}
})(phantom.version);
// Hooks in default phantomjs error handler
phantom.onError = function onPhantomError(msg, trace) {
phantom.defaultErrorHandler.apply(phantom, arguments);
// print a hint when a possible casperjs command misuse is detected
if (msg.indexOf("ReferenceError: Can't find variable: casper") === 0) {
console.error('Hint: you may want to use the `casperjs test` command.');
}
// exits on syntax error
if (msg.indexOf('SyntaxError: ') === 0) {
__die();
}
};
// Patching fs
var fs = (function patchFs(fs) {
if (!fs.hasOwnProperty('basename')) {
fs.basename = function basename(path) {
return path.replace(/.*\//, '');
};
}
if (!fs.hasOwnProperty('dirname')) {
fs.dirname = function dirname(path) {
if (!path) return undefined;
return path.toString().replace(/\\/g, '/').replace(/\/[^\/]*$/, '');
};
}
if (!fs.hasOwnProperty('isWindows')) {
fs.isWindows = function isWindows() {
var testPath = arguments[0] || this.workingDirectory;
return (/^[a-z]{1,2}:/i).test(testPath) || testPath.indexOf("\\\\") === 0;
};
}
if (fs.hasOwnProperty('joinPath')) {
fs.pathJoin = fs.joinPath;
} else if (!fs.hasOwnProperty('pathJoin')) {
fs.pathJoin = function pathJoin() {
return Array.prototype.filter.call(arguments,function(elm){
return typeof elm !== "undefined" && elm !== null;
}).join('/');
};
}
if (phantom.casperEngine === 'slimerjs' && slimer.version.major === 0 && slimer.version.minor <= 9){
fs.size = function (filename){
var t = fs.read(filename, "rt");
return t.length;
};
}
return fs;
})(require('fs'));
// CasperJS root path
if (!phantom.casperPath) {
try {
phantom.casperPath = phantomArgs.map(function _map(arg) {
var match = arg.match(/^--casper-path=(.*)/);
if (match) {
return fs.absolute(match[1]);
}
}).filter(function _filter(path) {
return fs.isDirectory(path);
}).pop();
} catch (e) {
return __die("Couldn't find nor compute phantom.casperPath, exiting.");
}
}
/**
* Prints CasperJS help.
*/
function printHelp() {
/* global slimer */
var engine = phantom.casperEngine === 'slimerjs' ? slimer : phantom;
var version = [engine.version.major, engine.version.minor, engine.version.patch].join('.');
return __terminate([
'CasperJS version ' + phantom.casperVersion.toString() +
' at ' + phantom.casperPath + ', using ' + phantom.casperEngine + ' version ' + version,
fs.read(fs.pathJoin(phantom.casperPath, 'bin', 'usage.txt'))
].join('\n'));
}
/**
* Patched require to allow loading of native casperjs modules.
* Every casperjs module have to first call this function in order to
* load a native casperjs module:
*
* var require = patchRequire(require);
* var utils = require('utils');
*
* Useless for SlimerJS
*/
function patchRequire(require) {
if (require.patched) {
return require;
}
function fromPackageJson(module, dir) {
var pkgPath, pkgContents, pkg;
pkgPath = fs.pathJoin(dir, module, 'package.json');
if (!fs.exists(pkgPath)) {
return;
}
pkgContents = fs.read(pkgPath);
if (!pkgContents) {
return;
}
try {
pkg = JSON.parse(pkgContents);
} catch (e) {
return;
}
if (typeof pkg === "object" && pkg.main) {
return fs.absolute(fs.pathJoin(dir, module, pkg.main));
}
}
function resolveFile(path, dir) {
var extensions = ['js', 'coffee', 'json'];
var basenames = [path, path + '/index'];
var paths = [];
var nodejsScript = fromPackageJson(path, dir);
if (nodejsScript) {
return nodejsScript;
}
basenames.forEach(function(basename) {
paths.push(fs.absolute(fs.pathJoin(dir, basename)));
extensions.forEach(function(extension) {
paths.push(fs.absolute(fs.pathJoin(dir, [basename, extension].join('.'))));
});
});
for (var i = 0; i < paths.length; i++) {
if (fs.isFile(paths[i])) {
return paths[i];
}
}
return null;
}
function getCurrentScriptRoot() {
if ((phantom.casperScriptBaseDir || "").indexOf(fs.workingDirectory) === 0) {
return phantom.casperScriptBaseDir;
}
return fs.absolute(fs.pathJoin(fs.workingDirectory, phantom.casperScriptBaseDir));
}
function casperBuiltinPath(path) {
return resolveFile(path, fs.pathJoin(phantom.casperPath, 'modules'));
}
function nodeModulePath(path) {
var resolved, prevBaseDir;
var baseDir = getCurrentScriptRoot();
do {
resolved = resolveFile(path, fs.pathJoin(baseDir, 'node_modules'));
prevBaseDir = baseDir;
baseDir = fs.absolute(fs.pathJoin(prevBaseDir, '..'));
} while (!resolved && baseDir !== '/' && prevBaseDir !== '/' && baseDir !== prevBaseDir);
return resolved;
}
function localModulePath(path) {
return resolveFile(path, phantom.casperScriptBaseDir || fs.workingDirectory);
}
var patchedRequire = function patchedRequire(path) {
try {
return require(casperBuiltinPath(path) ||
nodeModulePath(path) ||
localModulePath(path) ||
path);
} catch (e) {
throw new CasperError("Can't find module " + path);
}
};
patchedRequire.cache = require.cache;
patchedRequire.extensions = require.extensions;
patchedRequire.stubs = require.stubs;
patchedRequire.patched = true;
return patchedRequire;
}
/**
* Initializes the CasperJS Command Line Interface.
*/
function initCasperCli(casperArgs) {
/*eslint complexity:0*/
var baseTestsPath = fs.pathJoin(phantom.casperPath, 'tests');
function setScriptBaseDir(scriptName) {
var dir = fs.dirname(scriptName);
if (dir === scriptName) {
dir = '.';
}
phantom.casperScriptBaseDir = dir;
}
if (!!casperArgs.options.version) {
return __terminate(phantom.casperVersion.toString());
} else if (casperArgs.get(0) === "test") {
phantom.casperScript = fs.absolute(fs.pathJoin(baseTestsPath, 'run.js'));
phantom.casperTest = true;
casperArgs.drop("test");
setScriptBaseDir(casperArgs.get(0));
} else if (casperArgs.get(0) === "selftest") {
phantom.casperScript = fs.absolute(fs.pathJoin(baseTestsPath, 'run.js'));
phantom.casperSelfTest = phantom.casperTest = true;
casperArgs.options.includes = fs.pathJoin(baseTestsPath, 'selftest.js');
if (casperArgs.args.length <= 1) {
casperArgs.args.push(fs.pathJoin(baseTestsPath, 'suites'));
}
casperArgs.drop("selftest");
phantom.casperScriptBaseDir = fs.dirname(casperArgs.get(1) || fs.dirname(phantom.casperScript));
} else if (casperArgs.args.length === 0 || !!casperArgs.options.help) {
return printHelp();
}
if (!phantom.casperScript) {
phantom.casperScript = casperArgs.get(0);
}
if (phantom.casperScript !== "/dev/stdin" && !fs.isFile(phantom.casperScript)) {
return __die('Unable to open file: ' + phantom.casperScript);
}
if (!phantom.casperScriptBaseDir) {
setScriptBaseDir(phantom.casperScript);
}
// filter out the called script name from casper args
casperArgs.drop(phantom.casperScript);
}
// CasperJS version, extracted from package.json - see http://semver.org/
phantom.casperVersion = (function getCasperVersion(path) {
var parts, patchPart, pkg, pkgFile;
pkgFile = fs.absolute(fs.pathJoin(path, 'package.json'));
if (!fs.exists(pkgFile)) {
throw new CasperError('Cannot find package.json at ' + pkgFile);
}
try {
pkg = JSON.parse(require('fs').read(pkgFile));
} catch (e) {
throw new CasperError('Cannot read package file contents: ' + e);
}
parts = pkg.version.trim().split(".");
if (parts.length < 3) {
throw new CasperError("Invalid version number");
}
patchPart = parts[2].split('-');
return {
major: ~~parts[0] || 0,
minor: ~~parts[1] || 0,
patch: ~~patchPart[0] || 0,
ident: patchPart[1] || "",
toString: function toString() {
var version = [this.major, this.minor, this.patch].join('.');
if (this.ident) {
version = [version, this.ident].join('-');
}
return version;
}
};
})(phantom.casperPath);
// phantomjs2 has paths in require, but needs patchRequire anyway
if (!("paths" in global.require) ||
('phantomjs' === phantom.casperEngine && 1 < phantom.version.major)
) {
global.__require = require;
global.patchRequire = patchRequire; // must be called in every casperjs module as of 1.1
global.require = patchRequire(global.require);
} else {
// declare a dummy patchRequire function
global.patchRequire = function(req) {return req;};
require.paths.push(fs.pathJoin(phantom.casperPath, 'modules'));
require.paths.push(fs.workingDirectory);
}
if (phantom.casperEngine === 'slimerjs') {
require.globals.patchRequire = global.patchRequire;
require.globals.CasperError = CasperError;
}
// casper cli args
phantom.casperArgs = require('cli').parse(phantomArgs);
if (true === phantom.casperArgs.get('cli')) {
initCasperCli(phantom.casperArgs);
}
if ("paths" in global.require) {
if ((phantom.casperScriptBaseDir || "").indexOf(fs.workingDirectory) === 0) {
require.paths.push(phantom.casperScriptBaseDir);
} else {
require.paths.push(fs.pathJoin(fs.workingDirectory, phantom.casperScriptBaseDir));
}
(function nodeModulePath(path) {
var resolved = false, prevBaseDir;
var baseDir = path;
do {
path = fs.pathJoin(baseDir, 'node_modules');
resolved = fs.exists(path) && fs.isDirectory(path);
prevBaseDir = baseDir;
baseDir = fs.absolute(fs.pathJoin(prevBaseDir, '..'));
} while (!resolved && baseDir !== '/' && prevBaseDir !== '/' && baseDir !== prevBaseDir);
if (!resolved) return;
require.paths.push(fs.pathJoin(prevBaseDir, 'node_modules'));
})(fs.pathJoin(fs.workingDirectory, phantom.casperScriptBaseDir));
}
// casper loading status flag
phantom.casperLoaded = true;
if (phantom.version.major === 2
&& phantom.casperScript
&& phantom.casperScript.split('.').pop() === 'coffee'
) {
return __terminate('CoffeeScript is not supported by PhantomJS > 2.');
}
// passed casperjs script execution
if (phantom.casperScript && !phantom.injectJs(phantom.casperScript)) {
return __die('Unable to load script ' + phantom.casperScript + '; check file syntax');
}
})(this, phantom, require('system'));