mirror of
https://github.com/apache/cordova-android.git
synced 2026-05-11 00:00:05 +08:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 59a0189719 | |||
| 43dc7c68a6 | |||
| 49870d2d63 | |||
| 278197ae7c |
@@ -1,94 +0,0 @@
|
||||
* text eol=lf
|
||||
|
||||
# source code
|
||||
*.php text
|
||||
*.css text
|
||||
*.sass text
|
||||
*.scss text
|
||||
*.less text
|
||||
*.styl text
|
||||
*.js text
|
||||
*.coffee text
|
||||
*.json text
|
||||
*.htm text
|
||||
*.html text
|
||||
*.xml text
|
||||
*.svg text
|
||||
*.txt text
|
||||
*.ini text
|
||||
*.inc text
|
||||
*.pl text
|
||||
*.rb text
|
||||
*.py text
|
||||
*.scm text
|
||||
*.sql text
|
||||
*.sh text
|
||||
*.bat text
|
||||
|
||||
# templates
|
||||
*.ejs text
|
||||
*.hbt text
|
||||
*.jade text
|
||||
*.haml text
|
||||
*.hbs text
|
||||
*.dot text
|
||||
*.tmpl text
|
||||
*.phtml text
|
||||
|
||||
# server config
|
||||
.htaccess text
|
||||
|
||||
# git config
|
||||
.gitattributes text
|
||||
.gitignore text
|
||||
.gitconfig text
|
||||
|
||||
# code analysis config
|
||||
.jshintrc text
|
||||
.jscsrc text
|
||||
.jshintignore text
|
||||
.csslintrc text
|
||||
|
||||
# misc config
|
||||
*.yaml text
|
||||
*.yml text
|
||||
.editorconfig text
|
||||
|
||||
# build config
|
||||
*.npmignore text
|
||||
*.bowerrc text
|
||||
|
||||
# Heroku
|
||||
Procfile text
|
||||
.slugignore text
|
||||
|
||||
# Documentation
|
||||
*.md text
|
||||
LICENSE text
|
||||
AUTHORS text
|
||||
|
||||
|
||||
#
|
||||
## These files are binary and should be left untouched
|
||||
#
|
||||
|
||||
# (binary is a macro for -text -diff)
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
*.jpeg binary
|
||||
*.gif binary
|
||||
*.ico binary
|
||||
*.mov binary
|
||||
*.mp4 binary
|
||||
*.mp3 binary
|
||||
*.flv binary
|
||||
*.fla binary
|
||||
*.swf binary
|
||||
*.gz binary
|
||||
*.zip binary
|
||||
*.7z binary
|
||||
*.ttf binary
|
||||
*.eot binary
|
||||
*.woff binary
|
||||
*.pyc binary
|
||||
*.pdf binary
|
||||
+1
-3
@@ -40,6 +40,4 @@ Desktop.ini
|
||||
.idea
|
||||
npm-debug.log
|
||||
/framework/build
|
||||
node_modules/jshint
|
||||
node_modules/promise-matchers
|
||||
node_modules/jasmine-node
|
||||
node_modules/
|
||||
|
||||
+3
-1
@@ -1,8 +1,10 @@
|
||||
language: android
|
||||
sudo: false
|
||||
install:
|
||||
- "(pushd .. && git clone https://github.com/apache/cordova-lib.git && popd)"
|
||||
- npm link ../cordova-lib/cordova-common
|
||||
- npm install
|
||||
- echo y | android update sdk -u --filter android-22,android-23
|
||||
- echo y | android update sdk -u --filter android-23
|
||||
script:
|
||||
- npm test
|
||||
- npm run test-build
|
||||
|
||||
+1
-29
@@ -19,35 +19,7 @@
|
||||
#
|
||||
-->
|
||||
## Release Notes for Cordova (Android) ##
|
||||
|
||||
### 5.1.1 (Feb 24, 2016)
|
||||
* updated `cordova-common` dependnecy to `1.1.0`
|
||||
* CB-10628 Fix `emulate android --target`
|
||||
* CB-10618 Handle gradle frameworks on plugin installation/uninstallation
|
||||
* CB-10510: Add an optional timeout to `emu` start script
|
||||
* CB-10498: Resume event should be sticky if it has a plugin result
|
||||
* fix `HtmlNotFoundTest` so that it passes when file not found is handled correctly
|
||||
* CB-10472 `NullPointerException`: `org.apache.cordova.PluginManager.onSaveInstanceState` check if `pluginManager` is `null` before using it
|
||||
* CB-10138 Adds missing plugin metadata to `plugin_list` module.
|
||||
* CB-10443 Pass original options instead of remaining
|
||||
* CB-10443 Fix `this.root` null reference
|
||||
* CB-10421 Fixes exception when calling run script with `--help` option
|
||||
* updated `.gitignore`
|
||||
* CB-10406 Fixes an exception, thrown when building using Ant.
|
||||
* CB-10157 Uninstall app from device/emulator only when signed apk is already installed
|
||||
|
||||
### 5.1.0 (Jan 19, 2016)
|
||||
* CB-10386 Add `android.useDeprecatedNdk=true` to support `NDK` in `gradle`
|
||||
* CB-8864: Fixing this to mitigate CB-8685 and CB-10104
|
||||
* CB-10105: Spot fix for tilde errors on paths.
|
||||
* Update theme to `Theme.DeviceDefault.NoActionBar`
|
||||
* CB-10014: Set gradle `applicationId` to `package name`.
|
||||
* CB-9949: Fixing menu button event not fired in **Android**
|
||||
* CB-9479: Fixing the conditionals again, we should
|
||||
* CB-8917: New Plugin API for passing results on resume after Activity destruction
|
||||
* CB-9971 Suppress `gradlew _JAVA_OPTIONS` output during build
|
||||
* CB-9836 Add `.gitattributes` to prevent `CRLF` line endings in repos
|
||||
* added node_modules back into `.gitignore`
|
||||
Update these notes using: git log --pretty=format:'* %s' --topo-order --no-merges *remote*/4.1.x...HEAD
|
||||
|
||||
### 5.0.0 (Nov 01, 2015)
|
||||
* Update CordovaWebViewEngine.java
|
||||
|
||||
+2
-2
@@ -126,8 +126,8 @@ function writeProjectProperties(projectPath, target_api) {
|
||||
}
|
||||
|
||||
function prepBuildFiles(projectPath) {
|
||||
var buildModule = require(path.resolve(projectPath, 'cordova/lib/builders/builders'));
|
||||
buildModule.getBuilder('gradle').prepBuildFiles();
|
||||
var buildModule = require(path.join(path.resolve(projectPath), 'cordova', 'lib', 'build'));
|
||||
buildModule.prepBuildFiles();
|
||||
}
|
||||
|
||||
function copyBuildRules(projectPath) {
|
||||
|
||||
Vendored
+8
-20
@@ -219,11 +219,6 @@ Api.prototype.addPlugin = function (plugin, installOptions) {
|
||||
.add_plugin_changes(plugin, installOptions.variables, /*is_top_level=*/true, /*should_increment=*/true)
|
||||
.save_all();
|
||||
|
||||
if (plugin.getFrameworks(self.platform).length > 0) {
|
||||
self.events.emit('verbose', 'Updating build files since android plugin contained <framework>');
|
||||
require('./lib/builders/builders').getBuilder('gradle').prepBuildFiles();
|
||||
}
|
||||
|
||||
var targetDir = installOptions.usePlatformWww ?
|
||||
self.locations.platformWww :
|
||||
self.locations.www;
|
||||
@@ -277,11 +272,6 @@ Api.prototype.removePlugin = function (plugin, uninstallOptions) {
|
||||
.remove_plugin_changes(plugin, /*is_top_level=*/true)
|
||||
.save_all();
|
||||
|
||||
if (plugin.getFrameworks(self.platform).length > 0) {
|
||||
self.events.emit('verbose', 'Updating build files since android plugin contained <framework>');
|
||||
require('./lib/builders/builders').getBuilder('gradle').prepBuildFiles();
|
||||
}
|
||||
|
||||
var targetDir = uninstallOptions.usePlatformWww ?
|
||||
self.locations.platformWww :
|
||||
self.locations.www;
|
||||
@@ -441,11 +431,6 @@ Api.prototype._addModulesInfo = function(plugin, targetDir) {
|
||||
});
|
||||
|
||||
this._platformJson.root.modules = installedModules.concat(modulesToInstall);
|
||||
if (!this._platformJson.root.plugin_metadata) {
|
||||
this._platformJson.root.plugin_metadata = {};
|
||||
}
|
||||
this._platformJson.root.plugin_metadata[plugin.id] = plugin.version;
|
||||
|
||||
this._writePluginModules(targetDir);
|
||||
this._platformJson.save();
|
||||
};
|
||||
@@ -472,10 +457,6 @@ Api.prototype._removeModulesInfo = function(plugin, targetDir) {
|
||||
});
|
||||
|
||||
this._platformJson.root.modules = updatedModules;
|
||||
if (this._platformJson.root.plugin_metadata) {
|
||||
delete this._platformJson.root.plugin_metadata[plugin.id];
|
||||
}
|
||||
|
||||
this._writePluginModules(targetDir);
|
||||
this._platformJson.save();
|
||||
};
|
||||
@@ -489,13 +470,20 @@ Api.prototype._removeModulesInfo = function(plugin, targetDir) {
|
||||
* directories.
|
||||
*/
|
||||
Api.prototype._writePluginModules = function (targetDir) {
|
||||
var self = this;
|
||||
// Write out moduleObjects as JSON wrapped in a cordova module to cordova_plugins.js
|
||||
var final_contents = 'cordova.define(\'cordova/plugin_list\', function(require, exports, module) {\n';
|
||||
final_contents += 'module.exports = ' + JSON.stringify(this._platformJson.root.modules, null, ' ') + ';\n';
|
||||
final_contents += 'module.exports.metadata = \n';
|
||||
final_contents += '// TOP OF METADATA\n';
|
||||
|
||||
final_contents += JSON.stringify(this._platformJson.root.plugin_metadata, null, 4) + ';\n';
|
||||
var pluginMetadata = Object.keys(this._platformJson.root.installed_plugins)
|
||||
.reduce(function (metadata, plugin) {
|
||||
metadata[plugin] = self._platformJson.root.installed_plugins[plugin].version;
|
||||
return metadata;
|
||||
}, {});
|
||||
|
||||
final_contents += JSON.stringify(pluginMetadata, null, 4) + '\n';
|
||||
final_contents += '// BOTTOM OF METADATA\n';
|
||||
final_contents += '});'; // Close cordova.define.
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ var buildOpts = nopt({
|
||||
}, { 'd' : '--verbose' });
|
||||
|
||||
// Make buildOptions compatible with PlatformApi build method spec
|
||||
buildOpts.argv = buildOpts.argv.original;
|
||||
buildOpts.argv = buildOpts.argv.remain;
|
||||
|
||||
new Api().build(buildOpts)
|
||||
.catch(function(err) {
|
||||
|
||||
Vendored
+13
-14
@@ -31,7 +31,7 @@ var events = require('cordova-common').events;
|
||||
var spawn = require('cordova-common').superspawn.spawn;
|
||||
var CordovaError = require('cordova-common').CordovaError;
|
||||
|
||||
function parseOpts(options, resolvedTarget, projectRoot) {
|
||||
function parseOpts(options, resolvedTarget) {
|
||||
options = options || {};
|
||||
options.argv = nopt({
|
||||
gradle: Boolean,
|
||||
@@ -61,18 +61,18 @@ function parseOpts(options, resolvedTarget, projectRoot) {
|
||||
if (options.nobuild) ret.buildMethod = 'none';
|
||||
|
||||
if (options.argv.versionCode)
|
||||
ret.extraArgs.push('-PcdvVersionCode=' + options.argv.versionCode);
|
||||
ret.extraArgs.push('-PcdvVersionCode=' + options.versionCode);
|
||||
|
||||
if (options.argv.minSdkVersion)
|
||||
ret.extraArgs.push('-PcdvMinSdkVersion=' + options.argv.minSdkVersion);
|
||||
ret.extraArgs.push('-PcdvMinSdkVersion=' + options.minSdkVersion);
|
||||
|
||||
if (options.argv.gradleArg)
|
||||
ret.extraArgs.push(options.argv.gradleArg);
|
||||
ret.extraArgs.push(options.gradleArg);
|
||||
|
||||
var packageArgs = {};
|
||||
|
||||
if (options.argv.keystore)
|
||||
packageArgs.keystore = path.relative(projectRoot, path.resolve(options.argv.keystore));
|
||||
packageArgs.keystore = path.relative(this.root, path.resolve(options.argv.keystore));
|
||||
|
||||
['alias','storePassword','password','keystoreType'].forEach(function (flagName) {
|
||||
if (options.argv[flagName])
|
||||
@@ -88,17 +88,11 @@ function parseOpts(options, resolvedTarget, projectRoot) {
|
||||
throw new Error('Specified build config file does not exist: ' + buildConfig);
|
||||
}
|
||||
events.emit('log', 'Reading build config file: '+ path.resolve(buildConfig));
|
||||
var buildjson = fs.readFileSync(buildConfig, 'utf8');
|
||||
//var config = JSON.parse(fs.readFileSync(buildConfig, 'utf8'));
|
||||
var config = JSON.parse(buildjson);
|
||||
var config = JSON.parse(fs.readFileSync(buildConfig, 'utf8'));
|
||||
if (config.android && config.android[ret.buildType]) {
|
||||
var androidInfo = config.android[ret.buildType];
|
||||
if(androidInfo.keystore && !packageArgs.keystore) {
|
||||
if(androidInfo.keystore.substr(0,1) === '~') {
|
||||
androidInfo.keystore = process.env.HOME + androidInfo.keystore.substr(1);
|
||||
}
|
||||
packageArgs.keystore = path.resolve(path.dirname(buildConfig), androidInfo.keystore);
|
||||
events.emit('log', 'Reading the keystore from: ' + packageArgs.keystore);
|
||||
}
|
||||
|
||||
['alias', 'storePassword', 'password','keystoreType'].forEach(function (key){
|
||||
@@ -126,7 +120,7 @@ function parseOpts(options, resolvedTarget, projectRoot) {
|
||||
* Returns a promise.
|
||||
*/
|
||||
module.exports.runClean = function(options) {
|
||||
var opts = parseOpts(options, null, this.root);
|
||||
var opts = parseOpts(options);
|
||||
var builder = builders.getBuilder(opts.buildMethod);
|
||||
return builder.prepEnv(opts)
|
||||
.then(function() {
|
||||
@@ -147,7 +141,7 @@ module.exports.runClean = function(options) {
|
||||
* information.
|
||||
*/
|
||||
module.exports.run = function(options, optResolvedTarget) {
|
||||
var opts = parseOpts(options, optResolvedTarget, this.root);
|
||||
var opts = parseOpts(options, optResolvedTarget);
|
||||
var builder = builders.getBuilder(opts.buildMethod);
|
||||
var self = this;
|
||||
return builder.prepEnv(opts)
|
||||
@@ -169,6 +163,11 @@ module.exports.run = function(options, optResolvedTarget) {
|
||||
});
|
||||
};
|
||||
|
||||
// Called by plugman after installing plugins, and by create script after creating project.
|
||||
module.exports.prepBuildFiles = function() {
|
||||
return builders.getBuilder('gradle').prepBuildFiles();
|
||||
};
|
||||
|
||||
/*
|
||||
* Detects the architecture of a device/emulator
|
||||
* Returns "arm" or "x86".
|
||||
|
||||
+2
-2
@@ -45,7 +45,7 @@ util.inherits(AntBuilder, GenericBuilder);
|
||||
AntBuilder.prototype.getArgs = function(cmd, opts) {
|
||||
var args = [cmd, '-f', path.join(this.root, 'build.xml')];
|
||||
// custom_rules.xml is required for incremental builds.
|
||||
if (hasCustomRules(this.root)) {
|
||||
if (hasCustomRules()) {
|
||||
args.push('-Dout.dir=ant-build', '-Dgen.absolute.dir=ant-gen');
|
||||
}
|
||||
if(opts.packageInfo) {
|
||||
@@ -99,7 +99,7 @@ AntBuilder.prototype.prepEnv = function(opts) {
|
||||
AntBuilder.prototype.build = function(opts) {
|
||||
// Without our custom_rules.xml, we need to clean before building.
|
||||
var ret = Q();
|
||||
if (!hasCustomRules(this.root)) {
|
||||
if (!hasCustomRules()) {
|
||||
// clean will call check_ant() for us.
|
||||
ret = this.clean(opts);
|
||||
}
|
||||
|
||||
+3
-65
@@ -22,7 +22,6 @@ var fs = require('fs');
|
||||
var util = require('util');
|
||||
var path = require('path');
|
||||
var shell = require('shelljs');
|
||||
var child_process = require('child_process');
|
||||
var spawn = require('cordova-common').superspawn.spawn;
|
||||
var CordovaError = require('cordova-common').CordovaError;
|
||||
var check_reqs = require('../check_reqs');
|
||||
@@ -56,8 +55,6 @@ GradleBuilder.prototype.getArgs = function(cmd, opts) {
|
||||
|
||||
// 10 seconds -> 6 seconds
|
||||
args.push('-Dorg.gradle.daemon=true');
|
||||
// allow NDK to be used - required by Gradle 1.5 plugin
|
||||
args.push('-Pandroid.useDeprecatedNdk=true');
|
||||
args.push.apply(args, opts.extraArgs);
|
||||
// Shaves another 100ms, but produces a "try at own risk" warning. Not worth it (yet):
|
||||
// args.push('-Dorg.gradle.parallel=true');
|
||||
@@ -185,7 +182,9 @@ GradleBuilder.prototype.prepEnv = function(opts) {
|
||||
GradleBuilder.prototype.build = function(opts) {
|
||||
var wrapper = path.join(this.root, 'gradlew');
|
||||
var args = this.getArgs(opts.buildType == 'debug' ? 'debug' : 'release', opts);
|
||||
return spawnAndSuppressJavaOptions(wrapper, args);
|
||||
return Q().then(function() {
|
||||
return spawn(wrapper, args, {stdio: 'inherit'});
|
||||
});
|
||||
};
|
||||
|
||||
GradleBuilder.prototype.clean = function(opts) {
|
||||
@@ -212,64 +211,3 @@ module.exports = GradleBuilder;
|
||||
function isAutoGenerated(file) {
|
||||
return fs.existsSync(file) && fs.readFileSync(file, 'utf8').indexOf(MARKER) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* A special superspawn-like implementation, required to workaround the issue
|
||||
* with Java printing some unwanted information to stderr instead of stdout.
|
||||
* This function suppresses 'Picked up _JAVA_OPTIONS' message from being
|
||||
* printed to stderr. See https://issues.apache.org/jira/browse/CB-9971 for
|
||||
* explanation.
|
||||
*
|
||||
* This function needed because superspawn does not provide a way to get and
|
||||
* manage spawned process output streams. There is a CB-10052 which describes
|
||||
* an improvements for superspawn, needed to get rid of this.
|
||||
* TODO: Once this improvement added to cordova-common, we could remove this functionality.
|
||||
*
|
||||
* @param {String} cmd A command to spawn
|
||||
* @param {String[]} args Command arguments. Note that on Windows arguments
|
||||
* will be concatenated into string and passed to 'cmd.exe' along with '/s'
|
||||
* and '/c' switches for proper space-in-path handling
|
||||
*
|
||||
* @return {Promise} A promise, rejected with error message if
|
||||
* underlying command exits with nonzero exit code, fulfilled otherwise
|
||||
*/
|
||||
function spawnAndSuppressJavaOptions(cmd, args) {
|
||||
var opts = { stdio: 'pipe' };
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
// Work around spawn not being able to find .bat files.
|
||||
var joinedArgs = [cmd]
|
||||
.concat(args)
|
||||
.map(function(a){
|
||||
// Add quotes to arguments which contains whitespaces
|
||||
if (/^[^"].* .*[^"]/.test(a)) return '"' + a + '"';
|
||||
return a;
|
||||
}).join(' ');
|
||||
|
||||
args = ['/s', '/c'].concat('"' + joinedArgs + '"');
|
||||
cmd = 'cmd';
|
||||
opts.windowsVerbatimArguments = true;
|
||||
}
|
||||
|
||||
return Q.Promise(function (resolve, reject) {
|
||||
var proc = child_process.spawn(cmd, args, opts);
|
||||
|
||||
proc.stdout.on('data', process.stdout.write.bind(process.stdout));
|
||||
proc.stderr.on('data', function (data) {
|
||||
var suppressThisLine = /^Picked up _JAVA_OPTIONS: /i.test(data.toString());
|
||||
if (suppressThisLine) {
|
||||
return;
|
||||
}
|
||||
|
||||
process.stderr.write(data);
|
||||
});
|
||||
|
||||
proc.on('exit', function(code) {
|
||||
if (code) {
|
||||
reject('Error code ' + code + ' for command: ' + cmd + ' with args: ' + args);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Vendored
+5
-18
@@ -89,25 +89,12 @@ module.exports.install = function(target, buildResults) {
|
||||
var pkgName = manifest.getPackageId();
|
||||
var launchName = pkgName + '/.' + manifest.getActivity().getName();
|
||||
events.emit('log', 'Using apk: ' + apk_path);
|
||||
|
||||
return Adb.install(resolvedTarget.target, apk_path, {replace: true})
|
||||
.catch(function (error) {
|
||||
// CB-9557 CB-10157 only uninstall and reinstall app if the one that
|
||||
// is already installed on device was signed w/different certificate
|
||||
if (!/INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES/.test(error.toString()))
|
||||
throw error;
|
||||
|
||||
events.emit('warn', 'Uninstalling app from device and reinstalling it again because the ' +
|
||||
'installed app already signed with different key');
|
||||
|
||||
// This promise is always resolved, even if 'adb uninstall' fails to uninstall app
|
||||
// or the app doesn't installed at all, so no error catching needed.
|
||||
return Adb.uninstall(resolvedTarget.target, pkgName)
|
||||
.then(function() {
|
||||
return Adb.install(resolvedTarget.target, apk_path, {replace: true});
|
||||
});
|
||||
})
|
||||
// This promise is always resolved, even if 'adb uninstall' fails to uninstall app
|
||||
// or the app doesn't installed at all, so no error catching needed.
|
||||
return Adb.uninstall(resolvedTarget.target, pkgName)
|
||||
.then(function() {
|
||||
return Adb.install(resolvedTarget.target, apk_path, {replace: true});
|
||||
}).then(function() {
|
||||
//unlock screen
|
||||
return Adb.shell(resolvedTarget.target, 'input keyevent 82');
|
||||
}).then(function() {
|
||||
|
||||
+31
-67
@@ -23,6 +23,7 @@
|
||||
|
||||
var retry = require('./retry');
|
||||
var build = require('./build');
|
||||
var check_reqs = require('./check_reqs');
|
||||
var path = require('path');
|
||||
var Adb = require('./Adb');
|
||||
var AndroidManifest = require('./AndroidManifest');
|
||||
@@ -39,7 +40,6 @@ var ONE_SECOND = 1000; // in milliseconds
|
||||
var ONE_MINUTE = 60 * ONE_SECOND; // in milliseconds
|
||||
var INSTALL_COMMAND_TIMEOUT = 5 * ONE_MINUTE; // in milliseconds
|
||||
var NUM_INSTALL_RETRIES = 3;
|
||||
var CHECK_BOOTED_INTERVAL = 3 * ONE_SECOND; // in milliseconds
|
||||
var EXEC_KILL_SIGNAL = 'SIGKILL';
|
||||
|
||||
/**
|
||||
@@ -104,8 +104,7 @@ module.exports.best_image = function() {
|
||||
|
||||
var closest = 9999;
|
||||
var best = images[0];
|
||||
// Loading check_reqs at run-time to avoid test-time vs run-time directory structure difference issue
|
||||
var project_target = require('./check_reqs').get_target().replace('android-', '');
|
||||
var project_target = check_reqs.get_target().replace('android-', '');
|
||||
for (var i in images) {
|
||||
var target = images[i].target;
|
||||
if(target) {
|
||||
@@ -147,12 +146,10 @@ module.exports.list_targets = function() {
|
||||
* and returns the started ID of that emulator.
|
||||
* If no ID is given it will use the first image available,
|
||||
* if no image is available it will error out (maybe create one?).
|
||||
* If no boot timeout is given or the value is negative it will wait forever for
|
||||
* the emulator to boot
|
||||
*
|
||||
* Returns a promise.
|
||||
*/
|
||||
module.exports.start = function(emulator_ID, boot_timeout) {
|
||||
module.exports.start = function(emulator_ID) {
|
||||
var self = this;
|
||||
|
||||
return Q().then(function() {
|
||||
@@ -165,8 +162,7 @@ module.exports.start = function(emulator_ID, boot_timeout) {
|
||||
return best.name;
|
||||
}
|
||||
|
||||
// Loading check_reqs at run-time to avoid test-time vs run-time directory structure difference issue
|
||||
var androidCmd = require('./check_reqs').getAbsoluteAndroidCmd();
|
||||
var androidCmd = check_reqs.getAbsoluteAndroidCmd();
|
||||
return Q.reject(new CordovaError('No emulator images (avds) found.\n' +
|
||||
'1. Download desired System Image by running: ' + androidCmd + ' sdk\n' +
|
||||
'2. Create an AVD by running: ' + androidCmd + ' avd\n' +
|
||||
@@ -190,20 +186,14 @@ module.exports.start = function(emulator_ID, boot_timeout) {
|
||||
|
||||
//wait for emulator to boot up
|
||||
process.stdout.write('Booting up emulator (this may take a while)...');
|
||||
return self.wait_for_boot(emulatorId, boot_timeout)
|
||||
.then(function(success) {
|
||||
if (success) {
|
||||
events.emit('log','BOOT COMPLETE');
|
||||
//unlock screen
|
||||
return Adb.shell(emulatorId, 'input keyevent 82')
|
||||
.then(function() {
|
||||
//return the new emulator id for the started emulators
|
||||
return emulatorId;
|
||||
});
|
||||
} else {
|
||||
// We timed out waiting for the boot to happen
|
||||
return null;
|
||||
}
|
||||
return self.wait_for_boot(emulatorId)
|
||||
.then(function() {
|
||||
events.emit('log','BOOT COMPLETE');
|
||||
//unlock screen
|
||||
return Adb.shell(emulatorId, 'input keyevent 82');
|
||||
}).then(function() {
|
||||
//return the new emulator id for the started emulators
|
||||
return emulatorId;
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -237,25 +227,18 @@ module.exports.wait_for_emulator = function(uuid) {
|
||||
};
|
||||
|
||||
/*
|
||||
* Waits for the core android process of the emulator to start. Returns a
|
||||
* promise that resolves to a boolean indicating success. Not specifying a
|
||||
* time_remaining or passing a negative value will cause it to wait forever
|
||||
* Waits for the core android process of the emulator to start
|
||||
*/
|
||||
module.exports.wait_for_boot = function(emulator_id, time_remaining) {
|
||||
module.exports.wait_for_boot = function(emulator_id) {
|
||||
var self = this;
|
||||
return Adb.shell(emulator_id, 'ps')
|
||||
.then(function(output) {
|
||||
if (output.match(/android\.process\.acore/)) {
|
||||
return true;
|
||||
} else if (time_remaining === 0) {
|
||||
return false;
|
||||
return;
|
||||
} else {
|
||||
process.stdout.write('.');
|
||||
|
||||
// Check at regular intervals
|
||||
return Q.delay(time_remaining < CHECK_BOOTED_INTERVAL ? time_remaining : CHECK_BOOTED_INTERVAL).then(function() {
|
||||
var updated_time = time_remaining >= 0 ? Math.max(time_remaining - CHECK_BOOTED_INTERVAL, 0) : time_remaining;
|
||||
return self.wait_for_boot(emulator_id, updated_time);
|
||||
return Q.delay(3000).then(function() {
|
||||
return self.wait_for_boot(emulator_id);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -338,7 +321,7 @@ module.exports.install = function(givenTarget, buildResults) {
|
||||
}).then(function () {
|
||||
// This promise is always resolved, even if 'adb uninstall' fails to uninstall app
|
||||
// or the app doesn't installed at all, so no error catching needed.
|
||||
return Q.when()
|
||||
return Adb.uninstall(target.target, pkgName)
|
||||
.then(function() {
|
||||
|
||||
var apk_path = build.findBestApkForArchitecture(buildResults, target.arch);
|
||||
@@ -351,47 +334,28 @@ module.exports.install = function(givenTarget, buildResults) {
|
||||
events.emit('log', 'Using apk: ' + apk_path);
|
||||
events.emit('verbose', 'Installing app on emulator...');
|
||||
|
||||
// A special function to call adb install in specific environment w/ specific options.
|
||||
// Introduced as a part of fix for http://issues.apache.org/jira/browse/CB-9119
|
||||
// to workaround sporadic emulator hangs
|
||||
function adbInstallWithOptions(target, apk, opts) {
|
||||
events.emit('verbose', 'Installing apk ' + apk + ' on ' + target + '...');
|
||||
|
||||
var command = 'adb -s ' + target + ' install -r "' + apk + '"';
|
||||
function exec(command, opts) {
|
||||
return Q.promise(function (resolve, reject) {
|
||||
child_process.exec(command, opts, function(err, stdout, stderr) {
|
||||
if (err) reject(new CordovaError('Error executing "' + command + '": ' + stderr));
|
||||
// adb does not return an error code even if installation fails. Instead it puts a specific
|
||||
// message to stdout, so we have to use RegExp matching to detect installation failure.
|
||||
else if (/Failure/.test(stdout)) reject(new CordovaError('Failed to install apk to emulator: ' + stdout));
|
||||
else resolve(stdout);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function installPromise () {
|
||||
return adbInstallWithOptions(target.target, apk_path, execOptions)
|
||||
.catch(function (error) {
|
||||
// CB-9557 CB-10157 only uninstall and reinstall app if the one that
|
||||
// is already installed on device was signed w/different certificate
|
||||
if (!/INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES/.test(error.toString()))
|
||||
throw error;
|
||||
var retriedInstall = retry.retryPromise(
|
||||
NUM_INSTALL_RETRIES,
|
||||
exec, 'adb -s ' + target.target + ' install -r "' + apk_path + '"', execOptions
|
||||
);
|
||||
|
||||
events.emit('warn', 'Uninstalling app from device and reinstalling it again because the ' +
|
||||
'installed app already signed with different key');
|
||||
|
||||
// This promise is always resolved, even if 'adb uninstall' fails to uninstall app
|
||||
// or the app doesn't installed at all, so no error catching needed.
|
||||
return Adb.uninstall(target.target, pkgName)
|
||||
.then(function() {
|
||||
return adbInstallWithOptions(target.target, apk_path, execOptions);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return retry.retryPromise(NUM_INSTALL_RETRIES, installPromise)
|
||||
.then(function (output) {
|
||||
events.emit('log', 'INSTALL SUCCESS');
|
||||
return retriedInstall.then(function (output) {
|
||||
if (output.match(/Failure/)) {
|
||||
return Q.reject(new CordovaError('Failed to install apk to emulator: ' + output));
|
||||
} else {
|
||||
events.emit('log', 'INSTALL SUCCESS');
|
||||
}
|
||||
}, function (err) {
|
||||
return Q.reject(new CordovaError('Failed to install apk to emulator: ' + err));
|
||||
});
|
||||
});
|
||||
// unlock screen
|
||||
|
||||
Vendored
+6
-16
@@ -27,19 +27,6 @@ var path = require('path'),
|
||||
device = require('./device'),
|
||||
Q = require('q');
|
||||
|
||||
function getInstallTarget(runOptions) {
|
||||
var install_target;
|
||||
if (runOptions.target) {
|
||||
install_target = runOptions.target;
|
||||
} else if (runOptions.device) {
|
||||
install_target = '--device';
|
||||
} else if (runOptions.emulator) {
|
||||
install_target = '--emulator';
|
||||
}
|
||||
|
||||
return install_target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the application on a device if available. If no device is found, it will
|
||||
* use a started emulator. If no started emulators are found it will attempt
|
||||
@@ -53,7 +40,10 @@ function getInstallTarget(runOptions) {
|
||||
module.exports.run = function(runOptions) {
|
||||
|
||||
var self = this;
|
||||
var install_target = getInstallTarget(runOptions);
|
||||
|
||||
var install_target = runOptions.device ? '--device' :
|
||||
runOptions.emulator ? '--emulator' :
|
||||
runOptions.target;
|
||||
|
||||
return Q()
|
||||
.then(function() {
|
||||
@@ -126,8 +116,8 @@ function getInstallTarget(runOptions) {
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.help = function() {
|
||||
console.log('Usage: ' + path.relative(process.cwd(), process.argv[1]) + ' [options]');
|
||||
module.exports.help = function(args) {
|
||||
console.log('Usage: ' + path.relative(process.cwd(), args[1]) + ' [options]');
|
||||
console.log('Build options :');
|
||||
console.log(' --debug : Builds project in debug mode');
|
||||
console.log(' --release : Builds project in release mode');
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
// Coho updates this line:
|
||||
var VERSION = "5.1.1";
|
||||
var VERSION = "5.0.0";
|
||||
|
||||
module.exports.version = VERSION;
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<activity android:name="__ACTIVITY__"
|
||||
android:label="@string/activity_name"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@android:style/Theme.DeviceDefault.NoActionBar"
|
||||
android:theme="@android:style/Theme.Black.NoTitleBar"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale">
|
||||
<intent-filter android:label="@string/launcher_name">
|
||||
|
||||
+3
-37
@@ -1,5 +1,5 @@
|
||||
// Platform: android
|
||||
// c517ca811b4948b630e0b74dbae6c9637939da24
|
||||
// 6b83950ffdd6b84977dfae49d8147ef640b8097f
|
||||
/*
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
@@ -19,7 +19,7 @@
|
||||
under the License.
|
||||
*/
|
||||
;(function() {
|
||||
var PLATFORM_VERSION_BUILD_LABEL = '5.1.1';
|
||||
var PLATFORM_VERSION_BUILD_LABEL = '5.0.0';
|
||||
// file: src/scripts/require.js
|
||||
|
||||
/*jshint -W079 */
|
||||
@@ -1614,9 +1614,6 @@ exports.reset();
|
||||
// file: /Users/steveng/repo/cordova/cordova-android/cordova-js-src/platform.js
|
||||
define("cordova/platform", function(require, exports, module) {
|
||||
|
||||
// The last resume event that was received that had the result of a plugin call.
|
||||
var lastResumeEvent = null;
|
||||
|
||||
module.exports = {
|
||||
id: 'android',
|
||||
bootstrap: function() {
|
||||
@@ -1656,19 +1653,6 @@ module.exports = {
|
||||
bindButtonChannel('volumeup');
|
||||
bindButtonChannel('volumedown');
|
||||
|
||||
// The resume event is not "sticky", but it is possible that the event
|
||||
// will contain the result of a plugin call. We need to ensure that the
|
||||
// plugin result is delivered even after the event is fired (CB-10498)
|
||||
var cordovaAddEventListener = document.addEventListener;
|
||||
|
||||
document.addEventListener = function(evt, handler, capture) {
|
||||
cordovaAddEventListener(evt, handler, capture);
|
||||
|
||||
if (evt === 'resume' && lastResumeEvent) {
|
||||
handler(lastResumeEvent);
|
||||
}
|
||||
};
|
||||
|
||||
// Let native code know we are all done on the JS side.
|
||||
// Native code will then un-hide the WebView.
|
||||
channel.onCordovaReady.subscribe(function() {
|
||||
@@ -1690,30 +1674,12 @@ function onMessageFromNative(msg) {
|
||||
case 'searchbutton':
|
||||
// App life cycle events
|
||||
case 'pause':
|
||||
case 'resume':
|
||||
// Volume events
|
||||
case 'volumedownbutton':
|
||||
case 'volumeupbutton':
|
||||
cordova.fireDocumentEvent(action);
|
||||
break;
|
||||
case 'resume':
|
||||
if(arguments.length > 1 && msg.pendingResult) {
|
||||
if(arguments.length === 2) {
|
||||
msg.pendingResult.result = arguments[1];
|
||||
} else {
|
||||
// The plugin returned a multipart message
|
||||
var res = [];
|
||||
for(var i = 1; i < arguments.length; i++) {
|
||||
res.push(arguments[i]);
|
||||
}
|
||||
msg.pendingResult.result = res;
|
||||
}
|
||||
|
||||
// Save the plugin result so that it can be delivered to the js
|
||||
// even if they miss the initial firing of the event
|
||||
lastResumeEvent = msg;
|
||||
}
|
||||
cordova.fireDocumentEvent(action, msg);
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unknown event action ' + action);
|
||||
}
|
||||
|
||||
@@ -30,10 +30,20 @@ buildscript {
|
||||
// installed version of Gradle. This dependency is documented at
|
||||
// http://tools.android.com/tech-docs/new-build-system/version-compatibility
|
||||
// and https://issues.apache.org/jira/browse/CB-8143
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:1.5.0'
|
||||
if (gradle.gradleVersion >= "2.2") {
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:1.0.0+'
|
||||
}
|
||||
} else if (gradle.gradleVersion >= "2.1") {
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:0.14.0+'
|
||||
}
|
||||
} else {
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:0.12.0+'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allow plugins to declare Maven dependencies via build-extras.gradle.
|
||||
repositories {
|
||||
@@ -41,7 +51,7 @@ repositories {
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '2.8'
|
||||
gradleVersion = '2.2.1'
|
||||
}
|
||||
|
||||
// Configuration properties. Set these via environment variables, build-extras.gradle, or gradle.properties.
|
||||
@@ -163,17 +173,11 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
versionCode cdvVersionCode ?: Integer.parseInt("" + privateHelpers.extractIntFromManifest("versionCode") + "0")
|
||||
applicationId privateHelpers.extractStringFromManifest("package")
|
||||
|
||||
if (cdvMinSdkVersion != null) {
|
||||
minSdkVersion cdvMinSdkVersion
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError false;
|
||||
}
|
||||
|
||||
compileSdkVersion cdvCompileSdkVersion
|
||||
buildToolsVersion cdvBuildToolsVersion
|
||||
|
||||
|
||||
Vendored
+1
-35
@@ -19,9 +19,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
// The last resume event that was received that had the result of a plugin call.
|
||||
var lastResumeEvent = null;
|
||||
|
||||
module.exports = {
|
||||
id: 'android',
|
||||
bootstrap: function() {
|
||||
@@ -61,19 +58,6 @@ module.exports = {
|
||||
bindButtonChannel('volumeup');
|
||||
bindButtonChannel('volumedown');
|
||||
|
||||
// The resume event is not "sticky", but it is possible that the event
|
||||
// will contain the result of a plugin call. We need to ensure that the
|
||||
// plugin result is delivered even after the event is fired (CB-10498)
|
||||
var cordovaAddEventListener = document.addEventListener;
|
||||
|
||||
document.addEventListener = function(evt, handler, capture) {
|
||||
cordovaAddEventListener(evt, handler, capture);
|
||||
|
||||
if (evt === 'resume' && lastResumeEvent) {
|
||||
handler(lastResumeEvent);
|
||||
}
|
||||
};
|
||||
|
||||
// Let native code know we are all done on the JS side.
|
||||
// Native code will then un-hide the WebView.
|
||||
channel.onCordovaReady.subscribe(function() {
|
||||
@@ -95,30 +79,12 @@ function onMessageFromNative(msg) {
|
||||
case 'searchbutton':
|
||||
// App life cycle events
|
||||
case 'pause':
|
||||
case 'resume':
|
||||
// Volume events
|
||||
case 'volumedownbutton':
|
||||
case 'volumeupbutton':
|
||||
cordova.fireDocumentEvent(action);
|
||||
break;
|
||||
case 'resume':
|
||||
if(arguments.length > 1 && msg.pendingResult) {
|
||||
if(arguments.length === 2) {
|
||||
msg.pendingResult.result = arguments[1];
|
||||
} else {
|
||||
// The plugin returned a multipart message
|
||||
var res = [];
|
||||
for(var i = 1; i < arguments.length; i++) {
|
||||
res.push(arguments[i]);
|
||||
}
|
||||
msg.pendingResult.result = res;
|
||||
}
|
||||
|
||||
// Save the plugin result so that it can be delivered to the js
|
||||
// even if they miss the initial firing of the event
|
||||
lastResumeEvent = msg;
|
||||
}
|
||||
cordova.fireDocumentEvent(action, msg);
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unknown event action ' + action);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:1.5.0'
|
||||
classpath 'com.android.tools.build:gradle:1.0.0+'
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -128,14 +128,6 @@ def doExtractIntFromManifest(name) {
|
||||
return Integer.parseInt(matcher.group(1))
|
||||
}
|
||||
|
||||
def doExtractStringFromManifest(name) {
|
||||
def manifestFile = file(android.sourceSets.main.manifest.srcFile)
|
||||
def pattern = Pattern.compile(name + "=\"(\\S+)\"")
|
||||
def matcher = pattern.matcher(manifestFile.getText())
|
||||
matcher.find()
|
||||
return matcher.group(1)
|
||||
}
|
||||
|
||||
def doPromptForPassword(msg) {
|
||||
if (System.console() == null) {
|
||||
def ret = null
|
||||
@@ -187,7 +179,6 @@ ext {
|
||||
privateHelpers.getProjectTarget = { doGetProjectTarget() }
|
||||
privateHelpers.findLatestInstalledBuildTools = { doFindLatestInstalledBuildTools('19.1.0') }
|
||||
privateHelpers.extractIntFromManifest = { name -> doExtractIntFromManifest(name) }
|
||||
privateHelpers.extractStringFromManifest = { name -> doExtractStringFromManifest(name) }
|
||||
privateHelpers.promptForPassword = { msg -> doPromptForPassword(msg) }
|
||||
privateHelpers.ensureValueExists = { filePath, props, key -> doEnsureValueExists(filePath, props, key) }
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ public class CallbackContext {
|
||||
|
||||
private String callbackId;
|
||||
private CordovaWebView webView;
|
||||
protected boolean finished;
|
||||
private boolean finished;
|
||||
private int changingThreads;
|
||||
|
||||
public CallbackContext(String callbackId, CordovaWebView webView) {
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
package org.apache.cordova;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
@@ -27,7 +28,6 @@ import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
@@ -46,8 +46,6 @@ public class CordovaInterfaceImpl implements CordovaInterface {
|
||||
protected CordovaPlugin permissionResultCallback;
|
||||
protected String initCallbackService;
|
||||
protected int activityResultRequestCode;
|
||||
protected boolean activityWasDestroyed = false;
|
||||
protected Bundle savedPluginState;
|
||||
|
||||
public CordovaInterfaceImpl(Activity activity) {
|
||||
this(activity, Executors.newCachedThreadPool());
|
||||
@@ -97,31 +95,12 @@ public class CordovaInterfaceImpl implements CordovaInterface {
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches any pending onActivityResult callbacks and sends the resume event if the
|
||||
* Activity was destroyed by the OS.
|
||||
* Dispatches any pending onActivityResult callbacks.
|
||||
*/
|
||||
public void onCordovaInit(PluginManager pluginManager) {
|
||||
this.pluginManager = pluginManager;
|
||||
if (savedResult != null) {
|
||||
onActivityResult(savedResult.requestCode, savedResult.resultCode, savedResult.intent);
|
||||
} else if(activityWasDestroyed) {
|
||||
// If there was no Activity result, we still need to send out the resume event if the
|
||||
// Activity was destroyed by the OS
|
||||
activityWasDestroyed = false;
|
||||
if(pluginManager != null)
|
||||
{
|
||||
CoreAndroid appPlugin = (CoreAndroid) pluginManager.getPlugin(CoreAndroid.PLUGIN_NAME);
|
||||
if(appPlugin != null) {
|
||||
JSONObject obj = new JSONObject();
|
||||
try {
|
||||
obj.put("action", "resume");
|
||||
} catch (JSONException e) {
|
||||
LOG.e(TAG, "Failed to create event message", e);
|
||||
}
|
||||
appPlugin.sendResumeEvent(new PluginResult(PluginResult.Status.OK, obj));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,10 +115,6 @@ public class CordovaInterfaceImpl implements CordovaInterface {
|
||||
savedResult = new ActivityResultHolder(requestCode, resultCode, intent);
|
||||
if (pluginManager != null) {
|
||||
callback = pluginManager.getPlugin(initCallbackService);
|
||||
if(callback != null) {
|
||||
callback.onRestoreStateForActivityResult(savedPluginState.getBundle(callback.getServiceName()),
|
||||
new ResumeCallback(callback.getServiceName(), pluginManager));
|
||||
}
|
||||
}
|
||||
}
|
||||
activityResultCallback = null;
|
||||
@@ -151,7 +126,7 @@ public class CordovaInterfaceImpl implements CordovaInterface {
|
||||
callback.onActivityResult(requestCode, resultCode, intent);
|
||||
return true;
|
||||
}
|
||||
Log.w(TAG, "Got an activity result, but no plugin was registered to receive it" + (savedResult != null ? " yet!" : "."));
|
||||
Log.w(TAG, "Got an activity result, but no plugin was registered to receive it" + (savedResult != null ? " yet!": "."));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -172,10 +147,6 @@ public class CordovaInterfaceImpl implements CordovaInterface {
|
||||
String serviceName = activityResultCallback.getServiceName();
|
||||
outState.putString("callbackService", serviceName);
|
||||
}
|
||||
if(pluginManager != null){
|
||||
outState.putBundle("plugin", pluginManager.onSaveInstanceState());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -183,8 +154,6 @@ public class CordovaInterfaceImpl implements CordovaInterface {
|
||||
*/
|
||||
public void restoreInstanceState(Bundle savedInstanceState) {
|
||||
initCallbackService = savedInstanceState.getString("callbackService");
|
||||
savedPluginState = savedInstanceState.getBundle("plugin");
|
||||
activityWasDestroyed = true;
|
||||
}
|
||||
|
||||
private static class ActivityResultHolder {
|
||||
@@ -240,4 +209,6 @@ public class CordovaInterfaceImpl implements CordovaInterface {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
@@ -78,7 +77,7 @@ public class CordovaPlugin {
|
||||
public String getServiceName() {
|
||||
return serviceName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Executes the request.
|
||||
*
|
||||
@@ -175,29 +174,6 @@ public class CordovaPlugin {
|
||||
public void onDestroy() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the Activity is being destroyed (e.g. if a plugin calls out to an external
|
||||
* Activity and the OS kills the CordovaActivity in the background). The plugin should save its
|
||||
* state in this method only if it is awaiting the result of an external Activity and needs
|
||||
* to preserve some information so as to handle that result; onRestoreStateForActivityResult()
|
||||
* will only be called if the plugin is the recipient of an Activity result
|
||||
*
|
||||
* @return Bundle containing the state of the plugin or null if state does not need to be saved
|
||||
*/
|
||||
public Bundle onSaveInstanceState() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a plugin is the recipient of an Activity result after the CordovaActivity has
|
||||
* been destroyed. The Bundle will be the same as the one the plugin returned in
|
||||
* onSaveInstanceState()
|
||||
*
|
||||
* @param state Bundle containing the state of the plugin
|
||||
* @param callbackContext Replacement Context to return the plugin result to
|
||||
*/
|
||||
public void onRestoreStateForActivityResult(Bundle state, CallbackContext callbackContext) {}
|
||||
|
||||
/**
|
||||
* Called when a message is sent to plugin.
|
||||
*
|
||||
@@ -347,7 +323,7 @@ public class CordovaPlugin {
|
||||
*/
|
||||
public void onReset() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called when the system received an HTTP authentication request. Plugin can use
|
||||
* the supplied HttpAuthHandler to process this auth challenge.
|
||||
@@ -356,14 +332,14 @@ public class CordovaPlugin {
|
||||
* @param handler The HttpAuthHandler used to set the WebView's response
|
||||
* @param host The host requiring authentication
|
||||
* @param realm The realm for which authentication is required
|
||||
*
|
||||
*
|
||||
* @return Returns True if plugin will resolve this auth challenge, otherwise False
|
||||
*
|
||||
*
|
||||
*/
|
||||
public boolean onReceivedHttpAuthRequest(CordovaWebView view, ICordovaHttpAuthHandler handler, String host, String realm) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called when he system received an SSL client certificate request. Plugin can use
|
||||
* the supplied ClientCertRequest to process this certificate challenge.
|
||||
|
||||
@@ -31,7 +31,7 @@ import android.webkit.WebChromeClient.CustomViewCallback;
|
||||
* are not expected to implement it.
|
||||
*/
|
||||
public interface CordovaWebView {
|
||||
public static final String CORDOVA_VERSION = "5.1.1";
|
||||
public static final String CORDOVA_VERSION = "5.0.0";
|
||||
|
||||
void init(CordovaInterface cordova, List<PluginEntry> pluginEntries, CordovaPreferences preferences);
|
||||
|
||||
|
||||
@@ -354,7 +354,6 @@ public class CordovaWebViewImpl implements CordovaWebView {
|
||||
case KeyEvent.KEYCODE_VOLUME_DOWN:
|
||||
case KeyEvent.KEYCODE_VOLUME_UP:
|
||||
case KeyEvent.KEYCODE_BACK:
|
||||
case KeyEvent.KEYCODE_MENU:
|
||||
// TODO: Why are search and menu buttons handled separately?
|
||||
if (override) {
|
||||
boundKeyCodes.add(keyCode);
|
||||
@@ -446,10 +445,7 @@ public class CordovaWebViewImpl implements CordovaWebView {
|
||||
// Resume JavaScript timers. This affects all webviews within the app!
|
||||
engine.setPaused(false);
|
||||
this.pluginManager.onResume(keepRunning);
|
||||
|
||||
// In order to match the behavior of the other platforms, we only send onResume after an
|
||||
// onPause has occurred. The resume event might still be sent if the Activity was killed
|
||||
// while waiting for the result of an external Activity once the result is obtained
|
||||
// To be the same as other platforms, fire this event only when resumed after a "pause".
|
||||
if (hasPausedEver) {
|
||||
sendJavascriptEvent("resume");
|
||||
}
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
|
||||
package org.apache.cordova;
|
||||
|
||||
import org.apache.cordova.CallbackContext;
|
||||
import org.apache.cordova.CordovaPlugin;
|
||||
import org.apache.cordova.LOG;
|
||||
import org.apache.cordova.PluginResult;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
@@ -41,8 +45,6 @@ class CoreAndroid extends CordovaPlugin {
|
||||
protected static final String TAG = "CordovaApp";
|
||||
private BroadcastReceiver telephonyReceiver;
|
||||
private CallbackContext messageChannel;
|
||||
private PluginResult pendingResume;
|
||||
private final Object messageChannelLock = new Object();
|
||||
|
||||
/**
|
||||
* Send an event to be fired on the Javascript side.
|
||||
@@ -110,13 +112,7 @@ class CoreAndroid extends CordovaPlugin {
|
||||
this.exitApp();
|
||||
}
|
||||
else if (action.equals("messageChannel")) {
|
||||
synchronized(messageChannelLock) {
|
||||
messageChannel = callbackContext;
|
||||
if (pendingResume != null) {
|
||||
sendEventMessage(pendingResume);
|
||||
pendingResume = null;
|
||||
}
|
||||
}
|
||||
messageChannel = callbackContext;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -252,9 +248,6 @@ class CoreAndroid extends CordovaPlugin {
|
||||
else if (button.equals("volumedown")) {
|
||||
webView.setButtonPlumbedToJs(KeyEvent.KEYCODE_VOLUME_DOWN, override);
|
||||
}
|
||||
else if (button.equals("menubutton")) {
|
||||
webView.setButtonPlumbedToJs(KeyEvent.KEYCODE_MENU, override);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -320,13 +313,10 @@ class CoreAndroid extends CordovaPlugin {
|
||||
} catch (JSONException e) {
|
||||
LOG.e(TAG, "Failed to create event message", e);
|
||||
}
|
||||
sendEventMessage(new PluginResult(PluginResult.Status.OK, obj));
|
||||
}
|
||||
|
||||
private void sendEventMessage(PluginResult payload) {
|
||||
payload.setKeepCallback(true);
|
||||
PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, obj);
|
||||
pluginResult.setKeepCallback(true);
|
||||
if (messageChannel != null) {
|
||||
messageChannel.sendPluginResult(payload);
|
||||
messageChannel.sendPluginResult(pluginResult);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,23 +328,4 @@ class CoreAndroid extends CordovaPlugin {
|
||||
{
|
||||
webView.getContext().unregisterReceiver(this.telephonyReceiver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to send the resume event in the case that the Activity is destroyed by the OS
|
||||
*
|
||||
* @param resumeEvent PluginResult containing the payload for the resume event to be fired
|
||||
*/
|
||||
public void sendResumeEvent(PluginResult resumeEvent) {
|
||||
// This operation must be synchronized because plugin results that trigger resume
|
||||
// events can be processed asynchronously
|
||||
synchronized(messageChannelLock) {
|
||||
if (messageChannel != null) {
|
||||
sendEventMessage(resumeEvent);
|
||||
} else {
|
||||
// Might get called before the page loads, so we need to store it until the
|
||||
// messageChannel gets created
|
||||
this.pendingResume = resumeEvent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ import org.json.JSONException;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Debug;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -512,16 +511,4 @@ public class PluginManager {
|
||||
}
|
||||
}
|
||||
|
||||
public Bundle onSaveInstanceState() {
|
||||
Bundle state = new Bundle();
|
||||
for (CordovaPlugin plugin : this.pluginMap.values()) {
|
||||
if (plugin != null) {
|
||||
Bundle pluginState = plugin.onSaveInstanceState();
|
||||
if(pluginState != null) {
|
||||
state.putBundle(plugin.getServiceName(), pluginState);
|
||||
}
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
package org.apache.cordova;
|
||||
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ResumeCallback extends CallbackContext {
|
||||
private final String TAG = "CordovaResumeCallback";
|
||||
private String serviceName;
|
||||
private PluginManager pluginManager;
|
||||
|
||||
public ResumeCallback(String serviceName, PluginManager pluginManager) {
|
||||
super("resumecallback", null);
|
||||
this.serviceName = serviceName;
|
||||
this.pluginManager = pluginManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPluginResult(PluginResult pluginResult) {
|
||||
synchronized (this) {
|
||||
if (finished) {
|
||||
LOG.w(TAG, serviceName + " attempted to send a second callback to ResumeCallback\nResult was: " + pluginResult.getMessage());
|
||||
return;
|
||||
} else {
|
||||
finished = true;
|
||||
}
|
||||
}
|
||||
|
||||
JSONObject event = new JSONObject();
|
||||
JSONObject pluginResultObject = new JSONObject();
|
||||
|
||||
try {
|
||||
pluginResultObject.put("pluginServiceName", this.serviceName);
|
||||
pluginResultObject.put("pluginStatus", PluginResult.StatusMessages[pluginResult.getStatus()]);
|
||||
|
||||
event.put("action", "resume");
|
||||
event.put("pendingResult", pluginResultObject);
|
||||
} catch (JSONException e) {
|
||||
LOG.e(TAG, "Unable to create resume object for Activity Result");
|
||||
}
|
||||
|
||||
PluginResult eventResult = new PluginResult(PluginResult.Status.OK, event);
|
||||
|
||||
// We send a list of results to the js so that we don't have to decode
|
||||
// the PluginResult passed to this CallbackContext into JSON twice.
|
||||
// The results are combined into an event payload before the event is
|
||||
// fired on the js side of things (see platform.js)
|
||||
List<PluginResult> result = new ArrayList<PluginResult>();
|
||||
result.add(eventResult);
|
||||
result.add(pluginResult);
|
||||
|
||||
CoreAndroid appPlugin = (CoreAndroid) pluginManager.getPlugin(CoreAndroid.PLUGIN_NAME);
|
||||
appPlugin.sendResumeEvent(new PluginResult(PluginResult.Status.OK, result));
|
||||
}
|
||||
}
|
||||
-1
@@ -1 +0,0 @@
|
||||
../nopt/bin/nopt.js
|
||||
-1
@@ -1 +0,0 @@
|
||||
../semver/bin/semver
|
||||
-1
@@ -1 +0,0 @@
|
||||
../shelljs/bin/shjs
|
||||
-74
@@ -1,74 +0,0 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"abbrev@1",
|
||||
"/Users/steveng/repo/cordova/cordova-android/node_modules/nopt"
|
||||
]
|
||||
],
|
||||
"_from": "abbrev@>=1.0.0 <2.0.0",
|
||||
"_id": "abbrev@1.0.7",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/abbrev",
|
||||
"_nodeVersion": "2.0.1",
|
||||
"_npmUser": {
|
||||
"email": "isaacs@npmjs.com",
|
||||
"name": "isaacs"
|
||||
},
|
||||
"_npmVersion": "2.10.1",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "abbrev",
|
||||
"raw": "abbrev@1",
|
||||
"rawSpec": "1",
|
||||
"scope": null,
|
||||
"spec": ">=1.0.0 <2.0.0",
|
||||
"type": "range"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/nopt"
|
||||
],
|
||||
"_resolved": "http://registry.npmjs.org/abbrev/-/abbrev-1.0.7.tgz",
|
||||
"_shasum": "5b6035b2ee9d4fb5cf859f08a9be81b208491843",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "abbrev@1",
|
||||
"_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/nopt",
|
||||
"author": {
|
||||
"email": "i@izs.me",
|
||||
"name": "Isaac Z. Schlueter"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/isaacs/abbrev-js/issues"
|
||||
},
|
||||
"dependencies": {},
|
||||
"description": "Like ruby's abbrev module, but in js",
|
||||
"devDependencies": {
|
||||
"tap": "^1.2.0"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "5b6035b2ee9d4fb5cf859f08a9be81b208491843",
|
||||
"tarball": "http://registry.npmjs.org/abbrev/-/abbrev-1.0.7.tgz"
|
||||
},
|
||||
"gitHead": "821d09ce7da33627f91bbd8ed631497ed6f760c2",
|
||||
"homepage": "https://github.com/isaacs/abbrev-js#readme",
|
||||
"license": "ISC",
|
||||
"main": "abbrev.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "isaacs",
|
||||
"email": "i@izs.me"
|
||||
}
|
||||
],
|
||||
"name": "abbrev",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+ssh://git@github.com/isaacs/abbrev-js.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tap test.js --cov"
|
||||
},
|
||||
"version": "1.0.7"
|
||||
}
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"laxcomma": true,
|
||||
"asi": true
|
||||
}
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
|
||||
0.3.1 / 2016-01-14
|
||||
==================
|
||||
|
||||
* add MIT LICENSE file (#23, @kasicka)
|
||||
* preserve chaining after redundant style-method calls (#19, @drewblaisdell)
|
||||
* package: add "license" field (#16, @BenjaminTsai)
|
||||
|
||||
0.3.0 / 2014-05-09
|
||||
==================
|
||||
|
||||
* package: remove "test" script and "devDependencies"
|
||||
* package: remove "engines" section
|
||||
* pacakge: remove "bin" section
|
||||
* package: beautify
|
||||
* examples: remove `starwars` example (#15)
|
||||
* Documented goto, horizontalAbsolute, and eraseLine methods in README.md (#12, @Jammerwoch)
|
||||
* add `.jshintrc` file
|
||||
|
||||
< 0.3.0
|
||||
=======
|
||||
|
||||
* Prehistoric
|
||||
-98
@@ -1,98 +0,0 @@
|
||||
ansi.js
|
||||
=========
|
||||
### Advanced ANSI formatting tool for Node.js
|
||||
|
||||
`ansi.js` is a module for Node.js that provides an easy-to-use API for
|
||||
writing ANSI escape codes to `Stream` instances. ANSI escape codes are used to do
|
||||
fancy things in a terminal window, like render text in colors, delete characters,
|
||||
lines, the entire window, or hide and show the cursor, and lots more!
|
||||
|
||||
#### Features:
|
||||
|
||||
* 256 color support for the terminal!
|
||||
* Make a beep sound from your terminal!
|
||||
* Works with *any* writable `Stream` instance.
|
||||
* Allows you to move the cursor anywhere on the terminal window.
|
||||
* Allows you to delete existing contents from the terminal window.
|
||||
* Allows you to hide and show the cursor.
|
||||
* Converts CSS color codes and RGB values into ANSI escape codes.
|
||||
* Low-level; you are in control of when escape codes are used, it's not abstracted.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Install with `npm`:
|
||||
|
||||
``` bash
|
||||
$ npm install ansi
|
||||
```
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
``` js
|
||||
var ansi = require('ansi')
|
||||
, cursor = ansi(process.stdout)
|
||||
|
||||
// You can chain your calls forever:
|
||||
cursor
|
||||
.red() // Set font color to red
|
||||
.bg.grey() // Set background color to grey
|
||||
.write('Hello World!') // Write 'Hello World!' to stdout
|
||||
.bg.reset() // Reset the bgcolor before writing the trailing \n,
|
||||
// to avoid Terminal glitches
|
||||
.write('\n') // And a final \n to wrap things up
|
||||
|
||||
// Rendering modes are persistent:
|
||||
cursor.hex('#660000').bold().underline()
|
||||
|
||||
// You can use the regular logging functions, text will be green:
|
||||
console.log('This is blood red, bold text')
|
||||
|
||||
// To reset just the foreground color:
|
||||
cursor.fg.reset()
|
||||
|
||||
console.log('This will still be bold')
|
||||
|
||||
// to go to a location (x,y) on the console
|
||||
// note: 1-indexed, not 0-indexed:
|
||||
cursor.goto(10, 5).write('Five down, ten over')
|
||||
|
||||
// to clear the current line:
|
||||
cursor.horizontalAbsolute(0).eraseLine().write('Starting again')
|
||||
|
||||
// to go to a different column on the current line:
|
||||
cursor.horizontalAbsolute(5).write('column five')
|
||||
|
||||
// Clean up after yourself!
|
||||
cursor.reset()
|
||||
```
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2012 Nathan Rajlich <nathan@tootallnate.net>
|
||||
|
||||
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.
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Invokes the terminal "beep" sound once per second on every exact second.
|
||||
*/
|
||||
|
||||
process.title = 'beep'
|
||||
|
||||
var cursor = require('../../')(process.stdout)
|
||||
|
||||
function beep () {
|
||||
cursor.beep()
|
||||
setTimeout(beep, 1000 - (new Date()).getMilliseconds())
|
||||
}
|
||||
|
||||
setTimeout(beep, 1000 - (new Date()).getMilliseconds())
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Like GNU ncurses "clear" command.
|
||||
* https://github.com/mscdex/node-ncurses/blob/master/deps/ncurses/progs/clear.c
|
||||
*/
|
||||
|
||||
process.title = 'clear'
|
||||
|
||||
function lf () { return '\n' }
|
||||
|
||||
require('../../')(process.stdout)
|
||||
.write(Array.apply(null, Array(process.stdout.getWindowSize()[1])).map(lf).join(''))
|
||||
.eraseData(2)
|
||||
.goto(1, 1)
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var tty = require('tty')
|
||||
var cursor = require('../')(process.stdout)
|
||||
|
||||
// listen for the queryPosition report on stdin
|
||||
process.stdin.resume()
|
||||
raw(true)
|
||||
|
||||
process.stdin.once('data', function (b) {
|
||||
var match = /\[(\d+)\;(\d+)R$/.exec(b.toString())
|
||||
if (match) {
|
||||
var xy = match.slice(1, 3).reverse().map(Number)
|
||||
console.error(xy)
|
||||
}
|
||||
|
||||
// cleanup and close stdin
|
||||
raw(false)
|
||||
process.stdin.pause()
|
||||
})
|
||||
|
||||
|
||||
// send the query position request code to stdout
|
||||
cursor.queryPosition()
|
||||
|
||||
function raw (mode) {
|
||||
if (process.stdin.setRawMode) {
|
||||
process.stdin.setRawMode(mode)
|
||||
} else {
|
||||
tty.setRawMode(mode)
|
||||
}
|
||||
}
|
||||
-87
@@ -1,87 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var assert = require('assert')
|
||||
, ansi = require('../../')
|
||||
|
||||
function Progress (stream, width) {
|
||||
this.cursor = ansi(stream)
|
||||
this.delta = this.cursor.newlines
|
||||
this.width = width | 0 || 10
|
||||
this.open = '['
|
||||
this.close = ']'
|
||||
this.complete = '█'
|
||||
this.incomplete = '_'
|
||||
|
||||
// initial render
|
||||
this.progress = 0
|
||||
}
|
||||
|
||||
Object.defineProperty(Progress.prototype, 'progress', {
|
||||
get: get
|
||||
, set: set
|
||||
, configurable: true
|
||||
, enumerable: true
|
||||
})
|
||||
|
||||
function get () {
|
||||
return this._progress
|
||||
}
|
||||
|
||||
function set (v) {
|
||||
this._progress = Math.max(0, Math.min(v, 100))
|
||||
|
||||
var w = this.width - this.complete.length - this.incomplete.length
|
||||
, n = w * (this._progress / 100) | 0
|
||||
, i = w - n
|
||||
, com = c(this.complete, n)
|
||||
, inc = c(this.incomplete, i)
|
||||
, delta = this.cursor.newlines - this.delta
|
||||
|
||||
assert.equal(com.length + inc.length, w)
|
||||
|
||||
if (delta > 0) {
|
||||
this.cursor.up(delta)
|
||||
this.delta = this.cursor.newlines
|
||||
}
|
||||
|
||||
this.cursor
|
||||
.horizontalAbsolute(0)
|
||||
.eraseLine(2)
|
||||
.fg.white()
|
||||
.write(this.open)
|
||||
.fg.grey()
|
||||
.bold()
|
||||
.write(com)
|
||||
.resetBold()
|
||||
.write(inc)
|
||||
.fg.white()
|
||||
.write(this.close)
|
||||
.fg.reset()
|
||||
.write('\n')
|
||||
}
|
||||
|
||||
function c (char, length) {
|
||||
return Array.apply(null, Array(length)).map(function () {
|
||||
return char
|
||||
}).join('')
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Usage
|
||||
var width = parseInt(process.argv[2], 10) || process.stdout.getWindowSize()[0] / 2
|
||||
, p = new Progress(process.stdout, width)
|
||||
|
||||
;(function tick () {
|
||||
p.progress += Math.random() * 5
|
||||
p.cursor
|
||||
.eraseLine(2)
|
||||
.write('Progress: ')
|
||||
.bold().write(p.progress.toFixed(2))
|
||||
.write('%')
|
||||
.resetBold()
|
||||
.write('\n')
|
||||
if (p.progress < 100)
|
||||
setTimeout(tick, 100)
|
||||
})()
|
||||
-405
@@ -1,405 +0,0 @@
|
||||
|
||||
/**
|
||||
* References:
|
||||
*
|
||||
* - http://en.wikipedia.org/wiki/ANSI_escape_code
|
||||
* - http://www.termsys.demon.co.uk/vtansi.htm
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var emitNewlineEvents = require('./newlines')
|
||||
, prefix = '\x1b[' // For all escape codes
|
||||
, suffix = 'm' // Only for color codes
|
||||
|
||||
/**
|
||||
* The ANSI escape sequences.
|
||||
*/
|
||||
|
||||
var codes = {
|
||||
up: 'A'
|
||||
, down: 'B'
|
||||
, forward: 'C'
|
||||
, back: 'D'
|
||||
, nextLine: 'E'
|
||||
, previousLine: 'F'
|
||||
, horizontalAbsolute: 'G'
|
||||
, eraseData: 'J'
|
||||
, eraseLine: 'K'
|
||||
, scrollUp: 'S'
|
||||
, scrollDown: 'T'
|
||||
, savePosition: 's'
|
||||
, restorePosition: 'u'
|
||||
, queryPosition: '6n'
|
||||
, hide: '?25l'
|
||||
, show: '?25h'
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendering ANSI codes.
|
||||
*/
|
||||
|
||||
var styles = {
|
||||
bold: 1
|
||||
, italic: 3
|
||||
, underline: 4
|
||||
, inverse: 7
|
||||
}
|
||||
|
||||
/**
|
||||
* The negating ANSI code for the rendering modes.
|
||||
*/
|
||||
|
||||
var reset = {
|
||||
bold: 22
|
||||
, italic: 23
|
||||
, underline: 24
|
||||
, inverse: 27
|
||||
}
|
||||
|
||||
/**
|
||||
* The standard, styleable ANSI colors.
|
||||
*/
|
||||
|
||||
var colors = {
|
||||
white: 37
|
||||
, black: 30
|
||||
, blue: 34
|
||||
, cyan: 36
|
||||
, green: 32
|
||||
, magenta: 35
|
||||
, red: 31
|
||||
, yellow: 33
|
||||
, grey: 90
|
||||
, brightBlack: 90
|
||||
, brightRed: 91
|
||||
, brightGreen: 92
|
||||
, brightYellow: 93
|
||||
, brightBlue: 94
|
||||
, brightMagenta: 95
|
||||
, brightCyan: 96
|
||||
, brightWhite: 97
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a Cursor instance based off the given `writable stream` instance.
|
||||
*/
|
||||
|
||||
function ansi (stream, options) {
|
||||
if (stream._ansicursor) {
|
||||
return stream._ansicursor
|
||||
} else {
|
||||
return stream._ansicursor = new Cursor(stream, options)
|
||||
}
|
||||
}
|
||||
module.exports = exports = ansi
|
||||
|
||||
/**
|
||||
* The `Cursor` class.
|
||||
*/
|
||||
|
||||
function Cursor (stream, options) {
|
||||
if (!(this instanceof Cursor)) {
|
||||
return new Cursor(stream, options)
|
||||
}
|
||||
if (typeof stream != 'object' || typeof stream.write != 'function') {
|
||||
throw new Error('a valid Stream instance must be passed in')
|
||||
}
|
||||
|
||||
// the stream to use
|
||||
this.stream = stream
|
||||
|
||||
// when 'enabled' is false then all the functions are no-ops except for write()
|
||||
this.enabled = options && options.enabled
|
||||
if (typeof this.enabled === 'undefined') {
|
||||
this.enabled = stream.isTTY
|
||||
}
|
||||
this.enabled = !!this.enabled
|
||||
|
||||
// then `buffering` is true, then `write()` calls are buffered in
|
||||
// memory until `flush()` is invoked
|
||||
this.buffering = !!(options && options.buffering)
|
||||
this._buffer = []
|
||||
|
||||
// controls the foreground and background colors
|
||||
this.fg = this.foreground = new Colorer(this, 0)
|
||||
this.bg = this.background = new Colorer(this, 10)
|
||||
|
||||
// defaults
|
||||
this.Bold = false
|
||||
this.Italic = false
|
||||
this.Underline = false
|
||||
this.Inverse = false
|
||||
|
||||
// keep track of the number of "newlines" that get encountered
|
||||
this.newlines = 0
|
||||
emitNewlineEvents(stream)
|
||||
stream.on('newline', function () {
|
||||
this.newlines++
|
||||
}.bind(this))
|
||||
}
|
||||
exports.Cursor = Cursor
|
||||
|
||||
/**
|
||||
* Helper function that calls `write()` on the underlying Stream.
|
||||
* Returns `this` instead of the write() return value to keep
|
||||
* the chaining going.
|
||||
*/
|
||||
|
||||
Cursor.prototype.write = function (data) {
|
||||
if (this.buffering) {
|
||||
this._buffer.push(arguments)
|
||||
} else {
|
||||
this.stream.write.apply(this.stream, arguments)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Buffer `write()` calls into memory.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Cursor.prototype.buffer = function () {
|
||||
this.buffering = true
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Write out the in-memory buffer.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Cursor.prototype.flush = function () {
|
||||
this.buffering = false
|
||||
var str = this._buffer.map(function (args) {
|
||||
if (args.length != 1) throw new Error('unexpected args length! ' + args.length);
|
||||
return args[0];
|
||||
}).join('');
|
||||
this._buffer.splice(0); // empty
|
||||
this.write(str);
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The `Colorer` class manages both the background and foreground colors.
|
||||
*/
|
||||
|
||||
function Colorer (cursor, base) {
|
||||
this.current = null
|
||||
this.cursor = cursor
|
||||
this.base = base
|
||||
}
|
||||
exports.Colorer = Colorer
|
||||
|
||||
/**
|
||||
* Write an ANSI color code, ensuring that the same code doesn't get rewritten.
|
||||
*/
|
||||
|
||||
Colorer.prototype._setColorCode = function setColorCode (code) {
|
||||
var c = String(code)
|
||||
if (this.current === c) return
|
||||
this.cursor.enabled && this.cursor.write(prefix + c + suffix)
|
||||
this.current = c
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set up the positional ANSI codes.
|
||||
*/
|
||||
|
||||
Object.keys(codes).forEach(function (name) {
|
||||
var code = String(codes[name])
|
||||
Cursor.prototype[name] = function () {
|
||||
var c = code
|
||||
if (arguments.length > 0) {
|
||||
c = toArray(arguments).map(Math.round).join(';') + code
|
||||
}
|
||||
this.enabled && this.write(prefix + c)
|
||||
return this
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Set up the functions for the rendering ANSI codes.
|
||||
*/
|
||||
|
||||
Object.keys(styles).forEach(function (style) {
|
||||
var name = style[0].toUpperCase() + style.substring(1)
|
||||
, c = styles[style]
|
||||
, r = reset[style]
|
||||
|
||||
Cursor.prototype[style] = function () {
|
||||
if (this[name]) return this
|
||||
this.enabled && this.write(prefix + c + suffix)
|
||||
this[name] = true
|
||||
return this
|
||||
}
|
||||
|
||||
Cursor.prototype['reset' + name] = function () {
|
||||
if (!this[name]) return this
|
||||
this.enabled && this.write(prefix + r + suffix)
|
||||
this[name] = false
|
||||
return this
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Setup the functions for the standard colors.
|
||||
*/
|
||||
|
||||
Object.keys(colors).forEach(function (color) {
|
||||
var code = colors[color]
|
||||
|
||||
Colorer.prototype[color] = function () {
|
||||
this._setColorCode(this.base + code)
|
||||
return this.cursor
|
||||
}
|
||||
|
||||
Cursor.prototype[color] = function () {
|
||||
return this.foreground[color]()
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Makes a beep sound!
|
||||
*/
|
||||
|
||||
Cursor.prototype.beep = function () {
|
||||
this.enabled && this.write('\x07')
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves cursor to specific position
|
||||
*/
|
||||
|
||||
Cursor.prototype.goto = function (x, y) {
|
||||
x = x | 0
|
||||
y = y | 0
|
||||
this.enabled && this.write(prefix + y + ';' + x + 'H')
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the color.
|
||||
*/
|
||||
|
||||
Colorer.prototype.reset = function () {
|
||||
this._setColorCode(this.base + 39)
|
||||
return this.cursor
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all ANSI formatting on the stream.
|
||||
*/
|
||||
|
||||
Cursor.prototype.reset = function () {
|
||||
this.enabled && this.write(prefix + '0' + suffix)
|
||||
this.Bold = false
|
||||
this.Italic = false
|
||||
this.Underline = false
|
||||
this.Inverse = false
|
||||
this.foreground.current = null
|
||||
this.background.current = null
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the foreground color with the given RGB values.
|
||||
* The closest match out of the 216 colors is picked.
|
||||
*/
|
||||
|
||||
Colorer.prototype.rgb = function (r, g, b) {
|
||||
var base = this.base + 38
|
||||
, code = rgb(r, g, b)
|
||||
this._setColorCode(base + ';5;' + code)
|
||||
return this.cursor
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as `cursor.fg.rgb(r, g, b)`.
|
||||
*/
|
||||
|
||||
Cursor.prototype.rgb = function (r, g, b) {
|
||||
return this.foreground.rgb(r, g, b)
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts CSS color codes for use with ANSI escape codes.
|
||||
* For example: `#FF000` would be bright red.
|
||||
*/
|
||||
|
||||
Colorer.prototype.hex = function (color) {
|
||||
return this.rgb.apply(this, hex(color))
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as `cursor.fg.hex(color)`.
|
||||
*/
|
||||
|
||||
Cursor.prototype.hex = function (color) {
|
||||
return this.foreground.hex(color)
|
||||
}
|
||||
|
||||
|
||||
// UTIL FUNCTIONS //
|
||||
|
||||
/**
|
||||
* Translates a 255 RGB value to a 0-5 ANSI RGV value,
|
||||
* then returns the single ANSI color code to use.
|
||||
*/
|
||||
|
||||
function rgb (r, g, b) {
|
||||
var red = r / 255 * 5
|
||||
, green = g / 255 * 5
|
||||
, blue = b / 255 * 5
|
||||
return rgb5(red, green, blue)
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns rgb 0-5 values into a single ANSI color code to use.
|
||||
*/
|
||||
|
||||
function rgb5 (r, g, b) {
|
||||
var red = Math.round(r)
|
||||
, green = Math.round(g)
|
||||
, blue = Math.round(b)
|
||||
return 16 + (red*36) + (green*6) + blue
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts a hex CSS color code string (# is optional) and
|
||||
* translates it into an Array of 3 RGB 0-255 values, which
|
||||
* can then be used with rgb().
|
||||
*/
|
||||
|
||||
function hex (color) {
|
||||
var c = color[0] === '#' ? color.substring(1) : color
|
||||
, r = c.substring(0, 2)
|
||||
, g = c.substring(2, 4)
|
||||
, b = c.substring(4, 6)
|
||||
return [parseInt(r, 16), parseInt(g, 16), parseInt(b, 16)]
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns an array-like object into a real array.
|
||||
*/
|
||||
|
||||
function toArray (a) {
|
||||
var i = 0
|
||||
, l = a.length
|
||||
, rtn = []
|
||||
for (; i<l; i++) {
|
||||
rtn.push(a[i])
|
||||
}
|
||||
return rtn
|
||||
}
|
||||
-71
@@ -1,71 +0,0 @@
|
||||
|
||||
/**
|
||||
* Accepts any node Stream instance and hijacks its "write()" function,
|
||||
* so that it can count any newlines that get written to the output.
|
||||
*
|
||||
* When a '\n' byte is encountered, then a "newline" event will be emitted
|
||||
* on the stream, with no arguments. It is up to the listeners to determine
|
||||
* any necessary deltas required for their use-case.
|
||||
*
|
||||
* Ex:
|
||||
*
|
||||
* var cursor = ansi(process.stdout)
|
||||
* , ln = 0
|
||||
* process.stdout.on('newline', function () {
|
||||
* ln++
|
||||
* })
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var assert = require('assert')
|
||||
var NEWLINE = '\n'.charCodeAt(0)
|
||||
|
||||
function emitNewlineEvents (stream) {
|
||||
if (stream._emittingNewlines) {
|
||||
// already emitting newline events
|
||||
return
|
||||
}
|
||||
|
||||
var write = stream.write
|
||||
|
||||
stream.write = function (data) {
|
||||
// first write the data
|
||||
var rtn = write.apply(stream, arguments)
|
||||
|
||||
if (stream.listeners('newline').length > 0) {
|
||||
var len = data.length
|
||||
, i = 0
|
||||
// now try to calculate any deltas
|
||||
if (typeof data == 'string') {
|
||||
for (; i<len; i++) {
|
||||
processByte(stream, data.charCodeAt(i))
|
||||
}
|
||||
} else {
|
||||
// buffer
|
||||
for (; i<len; i++) {
|
||||
processByte(stream, data[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rtn
|
||||
}
|
||||
|
||||
stream._emittingNewlines = true
|
||||
}
|
||||
module.exports = emitNewlineEvents
|
||||
|
||||
|
||||
/**
|
||||
* Processes an individual byte being written to a stream
|
||||
*/
|
||||
|
||||
function processByte (stream, b) {
|
||||
assert.equal(typeof b, 'number')
|
||||
if (b === NEWLINE) {
|
||||
stream.emit('newline')
|
||||
}
|
||||
}
|
||||
-85
@@ -1,85 +0,0 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"ansi@^0.3.1",
|
||||
"/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common"
|
||||
]
|
||||
],
|
||||
"_from": "ansi@>=0.3.1 <0.4.0",
|
||||
"_id": "ansi@0.3.1",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/ansi",
|
||||
"_nodeVersion": "5.3.0",
|
||||
"_npmUser": {
|
||||
"email": "nathan@tootallnate.net",
|
||||
"name": "tootallnate"
|
||||
},
|
||||
"_npmVersion": "3.3.12",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "ansi",
|
||||
"raw": "ansi@^0.3.1",
|
||||
"rawSpec": "^0.3.1",
|
||||
"scope": null,
|
||||
"spec": ">=0.3.1 <0.4.0",
|
||||
"type": "range"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/cordova-common"
|
||||
],
|
||||
"_resolved": "http://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz",
|
||||
"_shasum": "0c42d4fb17160d5a9af1e484bace1c66922c1b21",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "ansi@^0.3.1",
|
||||
"_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common",
|
||||
"author": {
|
||||
"email": "nathan@tootallnate.net",
|
||||
"name": "Nathan Rajlich",
|
||||
"url": "http://tootallnate.net"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/TooTallNate/ansi.js/issues"
|
||||
},
|
||||
"dependencies": {},
|
||||
"description": "Advanced ANSI formatting tool for Node.js",
|
||||
"devDependencies": {},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "0c42d4fb17160d5a9af1e484bace1c66922c1b21",
|
||||
"tarball": "http://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz"
|
||||
},
|
||||
"gitHead": "4d0d4af94e0bdaa648bd7262acd3bde4b98d5246",
|
||||
"homepage": "https://github.com/TooTallNate/ansi.js#readme",
|
||||
"keywords": [
|
||||
"256",
|
||||
"ansi",
|
||||
"color",
|
||||
"cursor",
|
||||
"formatting",
|
||||
"rgb",
|
||||
"stream",
|
||||
"terminal"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "./lib/ansi.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "TooTallNate",
|
||||
"email": "nathan@tootallnate.net"
|
||||
},
|
||||
{
|
||||
"name": "tootallnate",
|
||||
"email": "nathan@tootallnate.net"
|
||||
}
|
||||
],
|
||||
"name": "ansi",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/TooTallNate/ansi.js.git"
|
||||
},
|
||||
"scripts": {},
|
||||
"version": "0.3.1"
|
||||
}
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
module.exports = balanced;
|
||||
function balanced(a, b, str) {
|
||||
var r = range(a, b, str);
|
||||
|
||||
return r && {
|
||||
start: r[0],
|
||||
end: r[1],
|
||||
pre: str.slice(0, r[0]),
|
||||
body: str.slice(r[0] + a.length, r[1]),
|
||||
post: str.slice(r[1] + b.length)
|
||||
};
|
||||
}
|
||||
|
||||
balanced.range = range;
|
||||
function range(a, b, str) {
|
||||
var begs, beg, left, right, result;
|
||||
var ai = str.indexOf(a);
|
||||
var bi = str.indexOf(b, ai + 1);
|
||||
var i = ai;
|
||||
|
||||
if (ai >= 0 && bi > 0) {
|
||||
begs = [];
|
||||
left = str.length;
|
||||
|
||||
while (i < str.length && i >= 0 && ! result) {
|
||||
if (i == ai) {
|
||||
begs.push(i);
|
||||
ai = str.indexOf(a, i + 1);
|
||||
} else if (begs.length == 1) {
|
||||
result = [ begs.pop(), bi ];
|
||||
} else {
|
||||
beg = begs.pop();
|
||||
if (beg < left) {
|
||||
left = beg;
|
||||
right = bi;
|
||||
}
|
||||
|
||||
bi = str.indexOf(b, i + 1);
|
||||
}
|
||||
|
||||
i = ai < bi && ai >= 0 ? ai : bi;
|
||||
}
|
||||
|
||||
if (begs.length) {
|
||||
result = [ left, right ];
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
-84
@@ -1,84 +0,0 @@
|
||||
var test = require('tape');
|
||||
var balanced = require('..');
|
||||
|
||||
test('balanced', function(t) {
|
||||
t.deepEqual(balanced('{', '}', 'pre{in{nest}}post'), {
|
||||
start: 3,
|
||||
end: 12,
|
||||
pre: 'pre',
|
||||
body: 'in{nest}',
|
||||
post: 'post'
|
||||
});
|
||||
t.deepEqual(balanced('{', '}', '{{{{{{{{{in}post'), {
|
||||
start: 8,
|
||||
end: 11,
|
||||
pre: '{{{{{{{{',
|
||||
body: 'in',
|
||||
post: 'post'
|
||||
});
|
||||
t.deepEqual(balanced('{', '}', 'pre{body{in}post'), {
|
||||
start: 8,
|
||||
end: 11,
|
||||
pre: 'pre{body',
|
||||
body: 'in',
|
||||
post: 'post'
|
||||
});
|
||||
t.deepEqual(balanced('{', '}', 'pre}{in{nest}}post'), {
|
||||
start: 4,
|
||||
end: 13,
|
||||
pre: 'pre}',
|
||||
body: 'in{nest}',
|
||||
post: 'post'
|
||||
});
|
||||
t.deepEqual(balanced('{', '}', 'pre{body}between{body2}post'), {
|
||||
start: 3,
|
||||
end: 8,
|
||||
pre: 'pre',
|
||||
body: 'body',
|
||||
post: 'between{body2}post'
|
||||
});
|
||||
t.notOk(balanced('{', '}', 'nope'), 'should be notOk');
|
||||
t.deepEqual(balanced('<b>', '</b>', 'pre<b>in<b>nest</b></b>post'), {
|
||||
start: 3,
|
||||
end: 19,
|
||||
pre: 'pre',
|
||||
body: 'in<b>nest</b>',
|
||||
post: 'post'
|
||||
});
|
||||
t.deepEqual(balanced('<b>', '</b>', 'pre</b><b>in<b>nest</b></b>post'), {
|
||||
start: 7,
|
||||
end: 23,
|
||||
pre: 'pre</b>',
|
||||
body: 'in<b>nest</b>',
|
||||
post: 'post'
|
||||
});
|
||||
t.deepEqual(balanced('{{', '}}', 'pre{{{in}}}post'), {
|
||||
start: 3,
|
||||
end: 9,
|
||||
pre: 'pre',
|
||||
body: '{in}',
|
||||
post: 'post'
|
||||
});
|
||||
t.deepEqual(balanced('{{{', '}}', 'pre{{{in}}}post'), {
|
||||
start: 3,
|
||||
end: 8,
|
||||
pre: 'pre',
|
||||
body: 'in',
|
||||
post: '}post'
|
||||
});
|
||||
t.deepEqual(balanced('{', '}', 'pre{{first}in{second}post'), {
|
||||
start: 4,
|
||||
end: 10,
|
||||
pre: 'pre{',
|
||||
body: 'first',
|
||||
post: 'in{second}post'
|
||||
});
|
||||
t.deepEqual(balanced('<?', '?>', 'pre<?>post'), {
|
||||
start: 3,
|
||||
end: 4,
|
||||
pre: 'pre',
|
||||
body: '',
|
||||
post: 'post'
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
-93
@@ -1,93 +0,0 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"base64-js@0.0.8",
|
||||
"/Users/steveng/repo/cordova/cordova-android/node_modules/plist"
|
||||
]
|
||||
],
|
||||
"_from": "base64-js@0.0.8",
|
||||
"_id": "base64-js@0.0.8",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/base64-js",
|
||||
"_nodeVersion": "0.10.35",
|
||||
"_npmUser": {
|
||||
"email": "feross@feross.org",
|
||||
"name": "feross"
|
||||
},
|
||||
"_npmVersion": "2.1.16",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "base64-js",
|
||||
"raw": "base64-js@0.0.8",
|
||||
"rawSpec": "0.0.8",
|
||||
"scope": null,
|
||||
"spec": "0.0.8",
|
||||
"type": "version"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/plist"
|
||||
],
|
||||
"_resolved": "http://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz",
|
||||
"_shasum": "1101e9544f4a76b1bc3b26d452ca96d7a35e7978",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "base64-js@0.0.8",
|
||||
"_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/plist",
|
||||
"author": {
|
||||
"email": "t.jameson.little@gmail.com",
|
||||
"name": "T. Jameson Little"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/beatgammit/base64-js/issues"
|
||||
},
|
||||
"dependencies": {},
|
||||
"description": "Base64 encoding/decoding in pure JS",
|
||||
"devDependencies": {
|
||||
"tape": "~2.3.2"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "1101e9544f4a76b1bc3b26d452ca96d7a35e7978",
|
||||
"tarball": "http://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"gitHead": "b4a8a5fa9b0caeddb5ad94dd1108253d8f2a315f",
|
||||
"homepage": "https://github.com/beatgammit/base64-js",
|
||||
"license": "MIT",
|
||||
"main": "lib/b64.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "beatgammit",
|
||||
"email": "t.jameson.little@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "feross",
|
||||
"email": "feross@feross.org"
|
||||
}
|
||||
],
|
||||
"name": "base64-js",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/beatgammit/base64-js.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape test/*.js"
|
||||
},
|
||||
"testling": {
|
||||
"browsers": [
|
||||
"chrome/4..latest",
|
||||
"firefox/3..latest",
|
||||
"ie/6..latest",
|
||||
"ipad/6",
|
||||
"iphone/6",
|
||||
"opera/11.0..latest",
|
||||
"safari/5.1..latest"
|
||||
],
|
||||
"files": "test/*.js"
|
||||
},
|
||||
"version": "0.0.8"
|
||||
}
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
var test = require('tape'),
|
||||
b64 = require('../lib/b64');
|
||||
|
||||
test('decode url-safe style base64 strings', function (t) {
|
||||
var expected = [0xff, 0xff, 0xbe, 0xff, 0xef, 0xbf, 0xfb, 0xef, 0xff];
|
||||
|
||||
var actual = b64.toByteArray('//++/++/++//');
|
||||
for (var i = 0; i < actual.length; i++) {
|
||||
t.equal(actual[i], expected[i])
|
||||
}
|
||||
|
||||
actual = b64.toByteArray('__--_--_--__');
|
||||
for (var i = 0; i < actual.length; i++) {
|
||||
t.equal(actual[i], expected[i])
|
||||
}
|
||||
|
||||
t.end();
|
||||
});
|
||||
-1189
File diff suppressed because it is too large
Load Diff
-1
File diff suppressed because one or more lines are too long
-506
@@ -1,506 +0,0 @@
|
||||
# BigInteger.js [![Build Status][travis-img]][travis-url] [![Coverage Status][coveralls-img]][coveralls-url] [![Monthly Downloads][downloads-img]][downloads-url]
|
||||
|
||||
[travis-url]: https://travis-ci.org/peterolson/BigInteger.js
|
||||
[travis-img]: https://travis-ci.org/peterolson/BigInteger.js.svg?branch=master
|
||||
[coveralls-url]: https://coveralls.io/github/peterolson/BigInteger.js?branch=master
|
||||
[coveralls-img]: https://coveralls.io/repos/peterolson/BigInteger.js/badge.svg?branch=master&service=github
|
||||
[downloads-url]: https://www.npmjs.com/package/big-integer
|
||||
[downloads-img]: https://img.shields.io/npm/dm/big-integer.svg
|
||||
|
||||
**BigInteger.js** is an arbitrary-length integer library for Javascript, allowing arithmetic operations on integers of unlimited size, notwithstanding memory and time limitations.
|
||||
|
||||
## Installation
|
||||
|
||||
If you are using a browser, you can download [BigInteger.js from GitHub](http://peterolson.github.com/BigInteger.js/BigInteger.min.js) or just hotlink to it:
|
||||
|
||||
<script src="http://peterolson.github.com/BigInteger.js/BigInteger.min.js"></script>
|
||||
|
||||
If you are using node, you can install BigInteger with [npm](https://npmjs.org/).
|
||||
|
||||
npm install big-integer
|
||||
|
||||
Then you can include it in your code:
|
||||
|
||||
var bigInt = require("big-integer");
|
||||
|
||||
|
||||
## Usage
|
||||
### `bigInt(number, [base])`
|
||||
|
||||
You can create a bigInt by calling the `bigInt` function. You can pass in
|
||||
|
||||
- a string, which it will parse as an bigInt and throw an `"Invalid integer"` error if the parsing fails.
|
||||
- a Javascript number, which it will parse as an bigInt and throw an `"Invalid integer"` error if the parsing fails.
|
||||
- another bigInt.
|
||||
- nothing, and it will return `bigInt.zero`.
|
||||
|
||||
If you provide a second parameter, then it will parse `number` as a number in base `base`. Note that `base` can be any bigInt (even negative or zero). The letters "a-z" and "A-Z" will be interpreted as the numbers 10 to 35. Higher digits can be specified in angle brackets (`<` and `>`).
|
||||
|
||||
Examples:
|
||||
|
||||
var zero = bigInt();
|
||||
var ninetyThree = bigInt(93);
|
||||
var largeNumber = bigInt("75643564363473453456342378564387956906736546456235345");
|
||||
var googol = bigInt("1e100");
|
||||
var bigNumber = bigInt(largeNumber);
|
||||
|
||||
var maximumByte = bigInt("FF", 16);
|
||||
var fiftyFiveGoogol = bigInt("<55>0", googol);
|
||||
|
||||
Note that Javascript numbers larger than `9007199254740992` and smaller than `-9007199254740992` are not precisely represented numbers and will not produce exact results. If you are dealing with numbers outside that range, it is better to pass in strings.
|
||||
|
||||
### Method Chaining
|
||||
|
||||
Note that bigInt operations return bigInts, which allows you to chain methods, for example:
|
||||
|
||||
var salary = bigInt(dollarsPerHour).times(hoursWorked).plus(randomBonuses)
|
||||
|
||||
### Constants
|
||||
|
||||
There are three named constants already stored that you do not have to construct with the `bigInt` function yourself:
|
||||
|
||||
- `bigInt.one`, equivalent to `bigInt(1)`
|
||||
- `bigInt.zero`, equivalent to `bigInt(0)`
|
||||
- `bigInt.minusOne`, equivalent to `bigInt(-1)`
|
||||
|
||||
The numbers from -999 to 999 are also already prestored and can be accessed using `bigInt[index]`, for example:
|
||||
|
||||
- `bigInt[-999]`, equivalent to `bigInt(-999)`
|
||||
- `bigInt[256]`, equivalent to `bigInt(256)`
|
||||
|
||||
### Methods
|
||||
|
||||
#### `abs()`
|
||||
|
||||
Returns the absolute value of a bigInt.
|
||||
|
||||
- `bigInt(-45).abs()` => `45`
|
||||
- `bigInt(45).abs()` => `45`
|
||||
|
||||
#### `add(number)`
|
||||
|
||||
Performs addition.
|
||||
|
||||
- `bigInt(5).add(7)` => `12`
|
||||
|
||||
[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Addition)
|
||||
|
||||
#### `and(number)`
|
||||
|
||||
Performs the bitwise AND operation. The operands are treated as if they were represented using [two's complement representation](http://en.wikipedia.org/wiki/Two%27s_complement).
|
||||
|
||||
- `bigInt(6).and(3)` => `2`
|
||||
- `bigInt(6).and(-3)` => `4`
|
||||
|
||||
#### `compare(number)`
|
||||
|
||||
Performs a comparison between two numbers. If the numbers are equal, it returns `0`. If the first number is greater, it returns `1`. If the first number is lesser, it returns `-1`.
|
||||
|
||||
- `bigInt(5).compare(5)` => `0`
|
||||
- `bigInt(5).compare(4)` => `1`
|
||||
- `bigInt(4).compare(5)` => `-1`
|
||||
|
||||
#### `compareAbs(number)`
|
||||
|
||||
Performs a comparison between the absolute value of two numbers.
|
||||
|
||||
- `bigInt(5).compareAbs(-5)` => `0`
|
||||
- `bigInt(5).compareAbs(4)` => `1`
|
||||
- `bigInt(4).compareAbs(-5)` => `-1`
|
||||
|
||||
#### `compareTo(number)`
|
||||
|
||||
Alias for the `compare` method.
|
||||
|
||||
#### `divide(number)`
|
||||
|
||||
Performs integer division, disregarding the remainder.
|
||||
|
||||
- `bigInt(59).divide(5)` => `11`
|
||||
|
||||
[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Division)
|
||||
|
||||
#### `divmod(number)`
|
||||
|
||||
Performs division and returns an object with two properties: `quotient` and `remainder`. The sign of the remainder will match the sign of the dividend.
|
||||
|
||||
- `bigInt(59).divmod(5)` => `{quotient: bigInt(11), remainder: bigInt(4) }`
|
||||
- `bigInt(-5).divmod(2)` => `{quotient: bigInt(-2), remainder: bigInt(-1) }`
|
||||
|
||||
[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Division)
|
||||
|
||||
#### `eq(number)`
|
||||
|
||||
Alias for the `equals` method.
|
||||
|
||||
#### `equals(number)`
|
||||
|
||||
Checks if two numbers are equal.
|
||||
|
||||
- `bigInt(5).equals(5)` => `true`
|
||||
- `bigInt(4).equals(7)` => `false`
|
||||
|
||||
#### `geq(number)`
|
||||
|
||||
Alias for the `greaterOrEquals` method.
|
||||
|
||||
|
||||
#### `greater(number)`
|
||||
|
||||
Checks if the first number is greater than the second.
|
||||
|
||||
- `bigInt(5).greater(6)` => `false`
|
||||
- `bigInt(5).greater(5)` => `false`
|
||||
- `bigInt(5).greater(4)` => `true`
|
||||
|
||||
#### `greaterOrEquals(number)`
|
||||
|
||||
Checks if the first number is greater than or equal to the second.
|
||||
|
||||
- `bigInt(5).greaterOrEquals(6)` => `false`
|
||||
- `bigInt(5).greaterOrEquals(5)` => `true`
|
||||
- `bigInt(5).greaterOrEquals(4)` => `true`
|
||||
|
||||
#### `gt(number)`
|
||||
|
||||
Alias for the `greater` method.
|
||||
|
||||
#### `isDivisibleBy(number)`
|
||||
|
||||
Returns `true` if the first number is divisible by the second number, `false` otherwise.
|
||||
|
||||
- `bigInt(999).isDivisibleBy(333)` => `true`
|
||||
- `bigInt(99).isDivisibleBy(5)` => `false`
|
||||
|
||||
#### `isEven()`
|
||||
|
||||
Returns `true` if the number is even, `false` otherwise.
|
||||
|
||||
- `bigInt(6).isEven()` => `true`
|
||||
- `bigInt(3).isEven()` => `false`
|
||||
|
||||
#### `isNegative()`
|
||||
|
||||
Returns `true` if the number is negative, `false` otherwise.
|
||||
Returns `false` for `0` and `-0`.
|
||||
|
||||
- `bigInt(-23).isNegative()` => `true`
|
||||
- `bigInt(50).isNegative()` => `false`
|
||||
|
||||
#### `isOdd()`
|
||||
|
||||
Returns `true` if the number is odd, `false` otherwise.
|
||||
|
||||
- `bigInt(13).isOdd()` => `true`
|
||||
- `bigInt(40).isOdd()` => `false`
|
||||
|
||||
#### `isPositive()`
|
||||
|
||||
Return `true` if the number is positive, `false` otherwise.
|
||||
Returns `false` for `0` and `-0`.
|
||||
|
||||
- `bigInt(54).isPositive()` => `true`
|
||||
- `bigInt(-1).isPositive()` => `false`
|
||||
|
||||
#### `isPrime()`
|
||||
|
||||
Returns `true` if the number is prime, `false` otherwise.
|
||||
|
||||
- `bigInt(5).isPrime()` => `true`
|
||||
- `bigInt(6).isPrime()` => `false`
|
||||
|
||||
#### `isProbablePrime([iterations])`
|
||||
|
||||
Returns `true` if the number is very likely to be positive, `false` otherwise.
|
||||
Argument is optional and determines the amount of iterations of the test (default: `5`). The more iterations, the lower chance of getting a false positive.
|
||||
This uses the [Fermat primality test](https://en.wikipedia.org/wiki/Fermat_primality_test).
|
||||
|
||||
- `bigInt(5).isProbablePrime()` => `true`
|
||||
- `bigInt(49).isProbablePrime()` => `false`
|
||||
- `bigInt(1729).isProbablePrime(50)` => `false`
|
||||
|
||||
Note that this function is not deterministic, since it relies on random sampling of factors, so the result for some numbers is not always the same. [Carmichael numbers](https://en.wikipedia.org/wiki/Carmichael_number) are particularly prone to give unreliable results.
|
||||
|
||||
For example, `bigInt(1729).isProbablePrime()` returns `false` about 76% of the time and `true` about 24% of the time. The correct result is `false`.
|
||||
|
||||
#### `isUnit()`
|
||||
|
||||
Returns `true` if the number is `1` or `-1`, `false` otherwise.
|
||||
|
||||
- `bigInt.one.isUnit()` => `true`
|
||||
- `bigInt.minusOne.isUnit()` => `true`
|
||||
- `bigInt(5).isUnit()` => `false`
|
||||
|
||||
#### `isZero()`
|
||||
|
||||
Return `true` if the number is `0` or `-0`, `false` otherwise.
|
||||
|
||||
- `bigInt.zero.isZero()` => `true`
|
||||
- `bigInt("-0").isZero()` => `true`
|
||||
- `bigInt(50).isZero()` => `false`
|
||||
|
||||
#### `leq(number)`
|
||||
|
||||
Alias for the `lesserOrEquals` method.
|
||||
|
||||
#### `lesser(number)`
|
||||
|
||||
Checks if the first number is lesser than the second.
|
||||
|
||||
- `bigInt(5).lesser(6)` => `true`
|
||||
- `bigInt(5).lesser(5)` => `false`
|
||||
- `bigInt(5).lesser(4)` => `false`
|
||||
|
||||
#### `lesserOrEquals(number)`
|
||||
|
||||
Checks if the first number is less than or equal to the second.
|
||||
|
||||
- `bigInt(5).lesserOrEquals(6)` => `true`
|
||||
- `bigInt(5).lesserOrEquals(5)` => `true`
|
||||
- `bigInt(5).lesserOrEquals(4)` => `false`
|
||||
|
||||
#### `lt(number)`
|
||||
|
||||
Alias for the `lesser` method.
|
||||
|
||||
#### `minus(number)`
|
||||
|
||||
Alias for the `subtract` method.
|
||||
|
||||
- `bigInt(3).minus(5)` => `-2`
|
||||
|
||||
[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Subtraction)
|
||||
|
||||
#### `mod(number)`
|
||||
|
||||
Performs division and returns the remainder, disregarding the quotient. The sign of the remainder will match the sign of the dividend.
|
||||
|
||||
- `bigInt(59).mod(5)` => `4`
|
||||
- `bigInt(-5).mod(2)` => `-1`
|
||||
|
||||
[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Division)
|
||||
|
||||
#### `modPow(exp, mod)`
|
||||
|
||||
Takes the number to the power `exp` modulo `mod`.
|
||||
|
||||
- `bigInt(10).modPow(3, 30)` => `10`
|
||||
|
||||
#### `multiply(number)`
|
||||
|
||||
Performs multiplication.
|
||||
|
||||
- `bigInt(111).multiply(111)` => `12321`
|
||||
|
||||
[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Multiplication)
|
||||
|
||||
#### `neq(number)`
|
||||
|
||||
Alias for the `notEquals` method.
|
||||
|
||||
#### `next()`
|
||||
|
||||
Adds one to the number.
|
||||
|
||||
- `bigInt(6).next()` => `7`
|
||||
|
||||
#### `not()`
|
||||
|
||||
Performs the bitwise NOT operation. The operands are treated as if they were represented using [two's complement representation](http://en.wikipedia.org/wiki/Two%27s_complement).
|
||||
|
||||
- `bigInt(10).not()` => `-11`
|
||||
- `bigInt(0).not()` => `-1`
|
||||
|
||||
#### `notEquals(number)`
|
||||
|
||||
Checks if two numbers are not equal.
|
||||
|
||||
- `bigInt(5).notEquals(5)` => `false`
|
||||
- `bigInt(4).notEquals(7)` => `true`
|
||||
|
||||
#### `or(number)`
|
||||
|
||||
Performs the bitwise OR operation. The operands are treated as if they were represented using [two's complement representation](http://en.wikipedia.org/wiki/Two%27s_complement).
|
||||
|
||||
- `bigInt(13).or(10)` => `15`
|
||||
- `bigInt(13).or(-8)` => `-3`
|
||||
|
||||
#### `over(number)`
|
||||
|
||||
Alias for the `divide` method.
|
||||
|
||||
- `bigInt(59).over(5)` => `11`
|
||||
|
||||
[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Division)
|
||||
|
||||
#### `plus(number)`
|
||||
|
||||
Alias for the `add` method.
|
||||
|
||||
- `bigInt(5).plus(7)` => `12`
|
||||
|
||||
[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Addition)
|
||||
|
||||
#### `pow(number)`
|
||||
|
||||
Performs exponentiation. If the exponent is less than `0`, `pow` returns `0`. `bigInt.zero.pow(0)` returns `1`.
|
||||
|
||||
- `bigInt(16).pow(16)` => `18446744073709551616`
|
||||
|
||||
[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Exponentiation)
|
||||
|
||||
#### `prev(number)`
|
||||
|
||||
Subtracts one from the number.
|
||||
|
||||
- `bigInt(6).prev()` => `5`
|
||||
|
||||
#### `remainder(number)`
|
||||
|
||||
Alias for the `mod` method.
|
||||
|
||||
[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Division)
|
||||
|
||||
#### `shiftLeft(n)`
|
||||
|
||||
Shifts the number left by `n` places in its binary representation. If a negative number is provided, it will shift right. Throws an error if `n` is outside of the range `[-9007199254740992, 9007199254740992]`.
|
||||
|
||||
- `bigInt(8).shiftLeft(2)` => `32`
|
||||
- `bigInt(8).shiftLeft(-2)` => `2`
|
||||
|
||||
#### `shiftRight(n)`
|
||||
|
||||
Shifts the number right by `n` places in its binary representation. If a negative number is provided, it will shift left. Throws an error if `n` is outside of the range `[-9007199254740992, 9007199254740992]`.
|
||||
|
||||
- `bigInt(8).shiftRight(2)` => `2`
|
||||
- `bigInt(8).shiftRight(-2)` => `32`
|
||||
|
||||
#### `square()`
|
||||
|
||||
Squares the number
|
||||
|
||||
- `bigInt(3).square()` => `9`
|
||||
|
||||
[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Squaring)
|
||||
|
||||
#### `subtract(number)`
|
||||
|
||||
Performs subtraction.
|
||||
|
||||
- `bigInt(3).subtract(5)` => `-2`
|
||||
|
||||
[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Subtraction)
|
||||
|
||||
#### `times(number)`
|
||||
|
||||
Alias for the `multiply` method.
|
||||
|
||||
- `bigInt(111).times(111)` => `12321`
|
||||
|
||||
[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Multiplication)
|
||||
|
||||
#### `toJSNumber()`
|
||||
|
||||
Converts a bigInt into a native Javascript number. Loses precision for numbers outside the range `[-9007199254740992, 9007199254740992]`.
|
||||
|
||||
- `bigInt("18446744073709551616").toJSNumber()` => `18446744073709552000`
|
||||
|
||||
#### `xor(number)`
|
||||
|
||||
Performs the bitwise XOR operation. The operands are treated as if they were represented using [two's complement representation](http://en.wikipedia.org/wiki/Two%27s_complement).
|
||||
|
||||
- `bigInt(12).xor(5)` => `9`
|
||||
- `bigInt(12).xor(-5)` => `-9`
|
||||
|
||||
### Static Methods
|
||||
|
||||
#### `gcd(a, b)`
|
||||
|
||||
Finds the greatest common denominator of `a` and `b`.
|
||||
|
||||
- `bigInt.gcd(42,56)` => `14`
|
||||
|
||||
#### `isInstance(x)`
|
||||
|
||||
Returns `true` if `x` is a BigInteger, `false` otherwise.
|
||||
|
||||
- `bigInt.isInstance(bigInt(14))` => `true`
|
||||
- `bigInt.isInstance(14)` => `false`
|
||||
|
||||
#### `lcm(a,b)`
|
||||
|
||||
Finds the least common multiple of `a` and `b`.
|
||||
|
||||
- `bigInt.lcm(21, 6)` => `42`
|
||||
|
||||
#### `max(a,b)`
|
||||
|
||||
Returns the largest of `a` and `b`.
|
||||
|
||||
- `bigInt.max(77, 432)` => `432`
|
||||
|
||||
#### `min(a,b)`
|
||||
|
||||
Returns the smallest of `a` and `b`.
|
||||
|
||||
- `bigInt.min(77, 432)` => `77`
|
||||
|
||||
#### `randBetween(min, max)`
|
||||
|
||||
Returns a random number between `min` and `max`.
|
||||
|
||||
- `bigInt.randBetween("-1e100", "1e100")` => (for example) `8494907165436643479673097939554427056789510374838494147955756275846226209006506706784609314471378745`
|
||||
|
||||
|
||||
### Override Methods
|
||||
|
||||
#### `toString(radix = 10)`
|
||||
|
||||
Converts a bigInt to a string. There is an optional radix parameter (which defaults to 10) that converts the number to the given radix. Digits in the range `10-35` will use the letters `a-z`.
|
||||
|
||||
- `bigInt("1e9").toString()` => `"1000000000"`
|
||||
- `bigInt("1e9").toString(16)` => `"3b9aca00"`
|
||||
|
||||
**Note that arithmetical operators will trigger the `valueOf` function rather than the `toString` function.** When converting a bigInteger to a string, you should use the `toString` method or the `String` function instead of adding the empty string.
|
||||
|
||||
- `bigInt("999999999999999999").toString()` => `"999999999999999999"`
|
||||
- `String(bigInt("999999999999999999"))` => `"999999999999999999"`
|
||||
- `bigInt("999999999999999999") + ""` => `1000000000000000000`
|
||||
|
||||
Bases larger than 36 are supported. If a digit is greater than or equal to 36, it will be enclosed in angle brackets.
|
||||
|
||||
- `bigInt(567890).toString(100)` => `"<56><78><90>"`
|
||||
|
||||
Negative bases are also supported.
|
||||
|
||||
- `bigInt(12345).toString(-10)` => `"28465"`
|
||||
|
||||
Base 1 and base -1 are also supported.
|
||||
|
||||
- `bigInt(-15).toString(1)` => `"-111111111111111"`
|
||||
- `bigInt(-15).toString(-1)` => `"101010101010101010101010101010"`
|
||||
|
||||
Base 0 is only allowed for the number zero.
|
||||
|
||||
- `bigInt(0).toString(0)` => `0`
|
||||
- `bigInt(1).toString(0)` => `Error: Cannot convert nonzero numbers to base 0.`
|
||||
|
||||
[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#toString)
|
||||
|
||||
#### `valueOf()`
|
||||
|
||||
Converts a bigInt to a native Javascript number. This override allows you to use native arithmetic operators without explicit conversion:
|
||||
|
||||
- `bigInt("100") + bigInt("200") === 300; //true`
|
||||
|
||||
## Contributors
|
||||
|
||||
To contribute, just fork the project, make some changes, and submit a pull request. Please verify that the unit tests pass before submitting.
|
||||
|
||||
The unit tests are contained in the `spec/spec.js` file. You can run them locally by opening the `spec/SpecRunner.html` or file or running `npm test`. You can also [run the tests online from GitHub](http://peterolson.github.io/BigInteger.js/spec/SpecRunner.html).
|
||||
|
||||
There are performance benchmarks that can be viewed from the `benchmarks/index.html` page. You can [run them online from GitHub](http://peterolson.github.io/BigInteger.js/benchmark/).
|
||||
|
||||
## License
|
||||
|
||||
This project is public domain. For more details, read about the [Unlicense](http://unlicense.org/).
|
||||
-100
@@ -1,100 +0,0 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"big-integer@^1.6.7",
|
||||
"/Users/steveng/repo/cordova/cordova-android/node_modules/bplist-parser"
|
||||
]
|
||||
],
|
||||
"_from": "big-integer@>=1.6.7 <2.0.0",
|
||||
"_id": "big-integer@1.6.12",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/big-integer",
|
||||
"_nodeVersion": "0.12.3",
|
||||
"_npmOperationalInternal": {
|
||||
"host": "packages-6-west.internal.npmjs.com",
|
||||
"tmp": "tmp/big-integer-1.6.12.tgz_1455702804335_0.11810904298909009"
|
||||
},
|
||||
"_npmUser": {
|
||||
"email": "peter.e.c.olson+npm@gmail.com",
|
||||
"name": "peterolson"
|
||||
},
|
||||
"_npmVersion": "2.9.1",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "big-integer",
|
||||
"raw": "big-integer@^1.6.7",
|
||||
"rawSpec": "^1.6.7",
|
||||
"scope": null,
|
||||
"spec": ">=1.6.7 <2.0.0",
|
||||
"type": "range"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/bplist-parser"
|
||||
],
|
||||
"_resolved": "http://registry.npmjs.org/big-integer/-/big-integer-1.6.12.tgz",
|
||||
"_shasum": "39afcddafcd5c4480864efb757337d508938bb26",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "big-integer@^1.6.7",
|
||||
"_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/bplist-parser",
|
||||
"author": {
|
||||
"email": "peter.e.c.olson+npm@gmail.com",
|
||||
"name": "Peter Olson"
|
||||
},
|
||||
"bin": {},
|
||||
"bugs": {
|
||||
"url": "https://github.com/peterolson/BigInteger.js/issues"
|
||||
},
|
||||
"contributors": [],
|
||||
"dependencies": {},
|
||||
"description": "An arbitrary length integer library for Javascript",
|
||||
"devDependencies": {
|
||||
"coveralls": "^2.11.4",
|
||||
"jasmine": "2.1.x",
|
||||
"jasmine-core": "^2.3.4",
|
||||
"karma": "^0.13.3",
|
||||
"karma-coverage": "^0.4.2",
|
||||
"karma-jasmine": "^0.3.6",
|
||||
"karma-phantomjs-launcher": "~0.1"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "39afcddafcd5c4480864efb757337d508938bb26",
|
||||
"tarball": "http://registry.npmjs.org/big-integer/-/big-integer-1.6.12.tgz"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
},
|
||||
"gitHead": "56f449108e31542f939e701f1fe562a46e6c1fab",
|
||||
"homepage": "https://github.com/peterolson/BigInteger.js#readme",
|
||||
"keywords": [
|
||||
"arbitrary",
|
||||
"arithmetic",
|
||||
"big",
|
||||
"bigint",
|
||||
"biginteger",
|
||||
"bignum",
|
||||
"integer",
|
||||
"math",
|
||||
"precision"
|
||||
],
|
||||
"license": "Unlicense",
|
||||
"main": "./BigInteger",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "peterolson",
|
||||
"email": "peter.e.c.olson+npm@gmail.com"
|
||||
}
|
||||
],
|
||||
"name": "big-integer",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+ssh://git@github.com/peterolson/BigInteger.js.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "karma start my.conf.js"
|
||||
},
|
||||
"version": "1.6.12"
|
||||
}
|
||||
-81
@@ -1,81 +0,0 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"bplist-parser@^0.1.0",
|
||||
"/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common"
|
||||
]
|
||||
],
|
||||
"_from": "bplist-parser@>=0.1.0 <0.2.0",
|
||||
"_id": "bplist-parser@0.1.1",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/bplist-parser",
|
||||
"_nodeVersion": "5.1.0",
|
||||
"_npmUser": {
|
||||
"email": "joe@fernsroth.com",
|
||||
"name": "joeferner"
|
||||
},
|
||||
"_npmVersion": "3.4.0",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "bplist-parser",
|
||||
"raw": "bplist-parser@^0.1.0",
|
||||
"rawSpec": "^0.1.0",
|
||||
"scope": null,
|
||||
"spec": ">=0.1.0 <0.2.0",
|
||||
"type": "range"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/cordova-common"
|
||||
],
|
||||
"_resolved": "http://registry.npmjs.org/bplist-parser/-/bplist-parser-0.1.1.tgz",
|
||||
"_shasum": "d60d5dcc20cba6dc7e1f299b35d3e1f95dafbae6",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "bplist-parser@^0.1.0",
|
||||
"_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common",
|
||||
"author": {
|
||||
"email": "joe.ferner@nearinfinity.com",
|
||||
"name": "Joe Ferner"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/nearinfinity/node-bplist-parser/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"big-integer": "^1.6.7"
|
||||
},
|
||||
"description": "Binary plist parser.",
|
||||
"devDependencies": {
|
||||
"nodeunit": "~0.9.1"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "d60d5dcc20cba6dc7e1f299b35d3e1f95dafbae6",
|
||||
"tarball": "http://registry.npmjs.org/bplist-parser/-/bplist-parser-0.1.1.tgz"
|
||||
},
|
||||
"gitHead": "c4f22650de2cc95edd21a6e609ff0654a2b951bd",
|
||||
"homepage": "https://github.com/nearinfinity/node-bplist-parser#readme",
|
||||
"keywords": [
|
||||
"bplist",
|
||||
"parser",
|
||||
"plist"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "bplistParser.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "joeferner",
|
||||
"email": "joe@fernsroth.com"
|
||||
}
|
||||
],
|
||||
"name": "bplist-parser",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/nearinfinity/node-bplist-parser.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "./node_modules/nodeunit/bin/nodeunit test"
|
||||
},
|
||||
"version": "0.1.1"
|
||||
}
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
-10
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>zero</key>
|
||||
<integer>0</integer>
|
||||
<key>int64item</key>
|
||||
<integer>12345678901234567890</integer>
|
||||
</dict>
|
||||
</plist>
|
||||
-159
@@ -1,159 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
// tests are adapted from https://github.com/TooTallNate/node-plist
|
||||
|
||||
var path = require('path');
|
||||
var nodeunit = require('nodeunit');
|
||||
var bplist = require('../');
|
||||
|
||||
module.exports = {
|
||||
'iTunes Small': function (test) {
|
||||
var file = path.join(__dirname, "iTunes-small.bplist");
|
||||
var startTime1 = new Date();
|
||||
|
||||
bplist.parseFile(file, function (err, dicts) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
var endTime = new Date();
|
||||
console.log('Parsed "' + file + '" in ' + (endTime - startTime1) + 'ms');
|
||||
var dict = dicts[0];
|
||||
test.equal(dict['Application Version'], "9.0.3");
|
||||
test.equal(dict['Library Persistent ID'], "6F81D37F95101437");
|
||||
test.done();
|
||||
});
|
||||
},
|
||||
|
||||
'sample1': function (test) {
|
||||
var file = path.join(__dirname, "sample1.bplist");
|
||||
var startTime = new Date();
|
||||
|
||||
bplist.parseFile(file, function (err, dicts) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
var endTime = new Date();
|
||||
console.log('Parsed "' + file + '" in ' + (endTime - startTime) + 'ms');
|
||||
var dict = dicts[0];
|
||||
test.equal(dict['CFBundleIdentifier'], 'com.apple.dictionary.MySample');
|
||||
test.done();
|
||||
});
|
||||
},
|
||||
|
||||
'sample2': function (test) {
|
||||
var file = path.join(__dirname, "sample2.bplist");
|
||||
var startTime = new Date();
|
||||
|
||||
bplist.parseFile(file, function (err, dicts) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
var endTime = new Date();
|
||||
console.log('Parsed "' + file + '" in ' + (endTime - startTime) + 'ms');
|
||||
var dict = dicts[0];
|
||||
test.equal(dict['PopupMenu'][2]['Key'], "\n #import <Cocoa/Cocoa.h>\n\n#import <MacRuby/MacRuby.h>\n\nint main(int argc, char *argv[])\n{\n return macruby_main(\"rb_main.rb\", argc, argv);\n}\n");
|
||||
test.done();
|
||||
});
|
||||
},
|
||||
|
||||
'airplay': function (test) {
|
||||
var file = path.join(__dirname, "airplay.bplist");
|
||||
var startTime = new Date();
|
||||
|
||||
bplist.parseFile(file, function (err, dicts) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
var endTime = new Date();
|
||||
console.log('Parsed "' + file + '" in ' + (endTime - startTime) + 'ms');
|
||||
|
||||
var dict = dicts[0];
|
||||
test.equal(dict['duration'], 5555.0495000000001);
|
||||
test.equal(dict['position'], 4.6269989039999997);
|
||||
test.done();
|
||||
});
|
||||
},
|
||||
|
||||
'utf16': function (test) {
|
||||
var file = path.join(__dirname, "utf16.bplist");
|
||||
var startTime = new Date();
|
||||
|
||||
bplist.parseFile(file, function (err, dicts) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
var endTime = new Date();
|
||||
console.log('Parsed "' + file + '" in ' + (endTime - startTime) + 'ms');
|
||||
|
||||
var dict = dicts[0];
|
||||
test.equal(dict['CFBundleName'], 'sellStuff');
|
||||
test.equal(dict['CFBundleShortVersionString'], '2.6.1');
|
||||
test.equal(dict['NSHumanReadableCopyright'], '©2008-2012, sellStuff, Inc.');
|
||||
test.done();
|
||||
});
|
||||
},
|
||||
|
||||
'utf16chinese': function (test) {
|
||||
var file = path.join(__dirname, "utf16_chinese.plist");
|
||||
var startTime = new Date();
|
||||
|
||||
bplist.parseFile(file, function (err, dicts) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
var endTime = new Date();
|
||||
console.log('Parsed "' + file + '" in ' + (endTime - startTime) + 'ms');
|
||||
|
||||
var dict = dicts[0];
|
||||
test.equal(dict['CFBundleName'], '天翼阅读');
|
||||
test.equal(dict['CFBundleDisplayName'], '天翼阅读');
|
||||
test.done();
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
|
||||
'uid': function (test) {
|
||||
var file = path.join(__dirname, "uid.bplist");
|
||||
var startTime = new Date();
|
||||
|
||||
bplist.parseFile(file, function (err, dicts) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
var endTime = new Date();
|
||||
console.log('Parsed "' + file + '" in ' + (endTime - startTime) + 'ms');
|
||||
|
||||
var dict = dicts[0];
|
||||
test.deepEqual(dict['$objects'][1]['NS.keys'], [{UID:2}, {UID:3}, {UID:4}]);
|
||||
test.deepEqual(dict['$objects'][1]['NS.objects'], [{UID: 5}, {UID:6}, {UID:7}]);
|
||||
test.deepEqual(dict['$top']['root'], {UID:1});
|
||||
test.done();
|
||||
});
|
||||
},
|
||||
|
||||
'int64': function (test) {
|
||||
var file = path.join(__dirname, "int64.bplist");
|
||||
var startTime = new Date();
|
||||
|
||||
bplist.parseFile(file, function (err, dicts) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
var endTime = new Date();
|
||||
console.log('Parsed "' + file + '" in ' + (endTime - startTime) + 'ms');
|
||||
var dict = dicts[0];
|
||||
test.equal(dict['zero'], '0');
|
||||
test.equal(dict['int64item'], '12345678901234567890');
|
||||
test.done();
|
||||
});
|
||||
}
|
||||
};
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
-104
@@ -1,104 +0,0 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"brace-expansion@^1.0.0",
|
||||
"/Users/steveng/repo/cordova/cordova-android/node_modules/minimatch"
|
||||
]
|
||||
],
|
||||
"_from": "brace-expansion@>=1.0.0 <2.0.0",
|
||||
"_id": "brace-expansion@1.1.3",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/brace-expansion",
|
||||
"_nodeVersion": "5.5.0",
|
||||
"_npmOperationalInternal": {
|
||||
"host": "packages-6-west.internal.npmjs.com",
|
||||
"tmp": "tmp/brace-expansion-1.1.3.tgz_1455216688668_0.948847763473168"
|
||||
},
|
||||
"_npmUser": {
|
||||
"email": "julian@juliangruber.com",
|
||||
"name": "juliangruber"
|
||||
},
|
||||
"_npmVersion": "3.3.12",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "brace-expansion",
|
||||
"raw": "brace-expansion@^1.0.0",
|
||||
"rawSpec": "^1.0.0",
|
||||
"scope": null,
|
||||
"spec": ">=1.0.0 <2.0.0",
|
||||
"type": "range"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/minimatch"
|
||||
],
|
||||
"_resolved": "http://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.3.tgz",
|
||||
"_shasum": "46bff50115d47fc9ab89854abb87d98078a10991",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "brace-expansion@^1.0.0",
|
||||
"_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/minimatch",
|
||||
"author": {
|
||||
"email": "mail@juliangruber.com",
|
||||
"name": "Julian Gruber",
|
||||
"url": "http://juliangruber.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/juliangruber/brace-expansion/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"balanced-match": "^0.3.0",
|
||||
"concat-map": "0.0.1"
|
||||
},
|
||||
"description": "Brace expansion as known from sh/bash",
|
||||
"devDependencies": {
|
||||
"tape": "4.4.0"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "46bff50115d47fc9ab89854abb87d98078a10991",
|
||||
"tarball": "http://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.3.tgz"
|
||||
},
|
||||
"gitHead": "f0da1bb668e655f67b6b2d660c6e1c19e2a6f231",
|
||||
"homepage": "https://github.com/juliangruber/brace-expansion",
|
||||
"keywords": [],
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "juliangruber",
|
||||
"email": "julian@juliangruber.com"
|
||||
},
|
||||
{
|
||||
"name": "isaacs",
|
||||
"email": "isaacs@npmjs.com"
|
||||
}
|
||||
],
|
||||
"name": "brace-expansion",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/juliangruber/brace-expansion.git"
|
||||
},
|
||||
"scripts": {
|
||||
"gentest": "bash test/generate.sh",
|
||||
"test": "tape test/*.js"
|
||||
},
|
||||
"testling": {
|
||||
"browsers": [
|
||||
"android-browser/4.2..latest",
|
||||
"chrome/25..latest",
|
||||
"chrome/canary",
|
||||
"firefox/20..latest",
|
||||
"firefox/nightly",
|
||||
"ie/8..latest",
|
||||
"ipad/6.0..latest",
|
||||
"iphone/6.0..latest",
|
||||
"opera/12..latest",
|
||||
"opera/next",
|
||||
"safari/5.1..latest"
|
||||
],
|
||||
"files": "test/*.js"
|
||||
},
|
||||
"version": "1.1.3"
|
||||
}
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
var concatMap = require('../');
|
||||
var test = require('tape');
|
||||
|
||||
test('empty or not', function (t) {
|
||||
var xs = [ 1, 2, 3, 4, 5, 6 ];
|
||||
var ixes = [];
|
||||
var ys = concatMap(xs, function (x, ix) {
|
||||
ixes.push(ix);
|
||||
return x % 2 ? [ x - 0.1, x, x + 0.1 ] : [];
|
||||
});
|
||||
t.same(ys, [ 0.9, 1, 1.1, 2.9, 3, 3.1, 4.9, 5, 5.1 ]);
|
||||
t.same(ixes, [ 0, 1, 2, 3, 4, 5 ]);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('always something', function (t) {
|
||||
var xs = [ 'a', 'b', 'c', 'd' ];
|
||||
var ys = concatMap(xs, function (x) {
|
||||
return x === 'b' ? [ 'B', 'B', 'B' ] : [ x ];
|
||||
});
|
||||
t.same(ys, [ 'a', 'B', 'B', 'B', 'c', 'd' ]);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('scalars', function (t) {
|
||||
var xs = [ 'a', 'b', 'c', 'd' ];
|
||||
var ys = concatMap(xs, function (x) {
|
||||
return x === 'b' ? [ 'B', 'B', 'B' ] : x;
|
||||
});
|
||||
t.same(ys, [ 'a', 'B', 'B', 'B', 'c', 'd' ]);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('undefs', function (t) {
|
||||
var xs = [ 'a', 'b', 'c', 'd' ];
|
||||
var ys = concatMap(xs, function () {});
|
||||
t.same(ys, [ undefined, undefined, undefined, undefined ]);
|
||||
t.end();
|
||||
});
|
||||
-4
@@ -107,10 +107,6 @@ Usage:
|
||||
```
|
||||
var superspawn = require('cordova-common').superspawn;
|
||||
superspawn.spawn('adb', ['devices'])
|
||||
.progress(function(data){
|
||||
if (data.stderr)
|
||||
console.error('"adb devices" raised an error: ' + data.stderr);
|
||||
})
|
||||
.then(function(devices){
|
||||
// Do something...
|
||||
})
|
||||
|
||||
-8
@@ -20,14 +20,6 @@
|
||||
-->
|
||||
# Cordova-common Release Notes
|
||||
|
||||
### 1.1.0 (Feb 16, 2016)
|
||||
* CB-10482 Remove references to windows8 from cordova-lib/cli
|
||||
* CB-10430 Adds forwardEvents method to easily connect two EventEmitters
|
||||
* CB-10176 Adds CordovaLogger class, based on logger module from cordova-cli
|
||||
* CB-10052 Expose child process' io streams via promise progress notification
|
||||
* CB-10497 Prefer .bat over .cmd on windows platform
|
||||
* CB-9984 Bumps plist version and fixes failing cordova-common test
|
||||
|
||||
### 1.0.0 (Oct 29, 2015)
|
||||
|
||||
* CB-9890 Documents cordova-common
|
||||
|
||||
-1
@@ -26,7 +26,6 @@ exports = module.exports = {
|
||||
|
||||
ActionStack: require('./src/ActionStack'),
|
||||
CordovaError: require('./src/CordovaError/CordovaError'),
|
||||
CordovaLogger: require('./src/CordovaLogger'),
|
||||
CordovaExternalToolErrorContext: require('./src/CordovaError/CordovaExternalToolErrorContext'),
|
||||
PlatformJson: require('./src/PlatformJson'),
|
||||
ConfigParser: require('./src/ConfigParser/ConfigParser.js'),
|
||||
|
||||
Generated
Vendored
Generated
Vendored
Generated
Vendored
+1
-21
@@ -3,7 +3,6 @@
|
||||
// adapted from http://code.google.com/p/plist/source/browse/trunk/src/com/dd/plist/BinaryPropertyListParser.java
|
||||
|
||||
var fs = require('fs');
|
||||
var bigInt = require("big-integer");
|
||||
var debug = false;
|
||||
|
||||
exports.maxObjectSize = 100 * 1000 * 1000; // 100Meg
|
||||
@@ -139,28 +138,9 @@ var parseBuffer = exports.parseBuffer = function (buffer) {
|
||||
}
|
||||
}
|
||||
|
||||
function bufferToHexString(buffer) {
|
||||
var str = '';
|
||||
var i;
|
||||
for (i = 0; i < buffer.length; i++) {
|
||||
if (buffer[i] != 0x00) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (; i < buffer.length; i++) {
|
||||
var part = '00' + buffer[i].toString(16);
|
||||
str += part.substr(part.length - 2);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
function parseInteger() {
|
||||
var length = Math.pow(2, objInfo);
|
||||
if (length > 4) {
|
||||
var data = buffer.slice(offset + 1, offset + 1 + length);
|
||||
var str = bufferToHexString(data);
|
||||
return bigInt(str, 16);
|
||||
} if (length < exports.maxObjectSize) {
|
||||
if (length < exports.maxObjectSize) {
|
||||
return readUInt(buffer.slice(offset + 1, offset + 1 + length));
|
||||
} else {
|
||||
throw new Error("To little heap space available! Wanted to read " + length + " bytes, but only " + exports.maxObjectSize + " are available.");
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "bplist-parser",
|
||||
"version": "0.1.0",
|
||||
"description": "Binary plist parser.",
|
||||
"main": "bplistParser.js",
|
||||
"scripts": {
|
||||
"test": "./node_modules/nodeunit/bin/nodeunit test"
|
||||
},
|
||||
"keywords": [
|
||||
"bplist",
|
||||
"plist",
|
||||
"parser"
|
||||
],
|
||||
"author": {
|
||||
"name": "Joe Ferner",
|
||||
"email": "joe.ferner@nearinfinity.com"
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"nodeunit": "~0.9.1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/nearinfinity/node-bplist-parser.git"
|
||||
},
|
||||
"readme": "bplist-parser\n=============\n\nBinary Mac OS X Plist (property list) parser.\n\n## Installation\n\n```bash\n$ npm install bplist-parser\n```\n\n## Quick Examples\n\n```javascript\nvar bplist = require('bplist-parser');\n\nbplist.parseFile('myPlist.bplist', function(err, obj) {\n if (err) throw err;\n\n console.log(JSON.stringify(obj));\n});\n```\n\n## License\n\n(The MIT License)\n\nCopyright (c) 2012 Near Infinity Corporation\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n",
|
||||
"readmeFilename": "README.md",
|
||||
"bugs": {
|
||||
"url": "https://github.com/nearinfinity/node-bplist-parser/issues"
|
||||
},
|
||||
"homepage": "https://github.com/nearinfinity/node-bplist-parser#readme",
|
||||
"_id": "bplist-parser@0.1.0",
|
||||
"_shasum": "630823f2056437d4dbefc20e84017f8bac48e008",
|
||||
"_resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.1.0.tgz",
|
||||
"_from": "bplist-parser@>=0.1.0 <0.2.0"
|
||||
}
|
||||
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
+5
-10
@@ -159,7 +159,7 @@ var map = {
|
||||
'de.fastr.phonegap.plugins.downloader' : 'cordova-plugin-fastrde-downloader',
|
||||
'de.fastr.phonegap.plugins.injectView' : 'cordova-plugin-fastrde-injectview',
|
||||
'de.fastr.phonegap.plugins.CheckGPS' : 'cordova-plugin-fastrde-checkgps',
|
||||
'de.fastr.phonegap.plugins.md5chksum' : 'cordova-plugin-fastrde-md5',
|
||||
'de.fastr.phonegap.plugins.md5chksum' : ' cordova-plugin-fastrde-md5',
|
||||
'io.repro.cordova' : 'cordova-plugin-repro',
|
||||
're.notifica.cordova': 'cordova-plugin-notificare-push',
|
||||
'com.megster.cordova.ble': 'cordova-plugin-ble-central',
|
||||
@@ -182,23 +182,18 @@ var map = {
|
||||
'com.ios.libgoogleadmobads': 'cordova-libgoogleadmobads',
|
||||
'com.google.play.services': 'cordova-google-play-services',
|
||||
'android.support.v13': 'cordova-android-support-v13',
|
||||
'android.support.v4': 'cordova-android-support-v4', // Duplicated key ;)
|
||||
'android.support.v4': 'cordova-android-support-v4',
|
||||
'com.analytics.google': 'cordova-plugin-analytics',
|
||||
'com.analytics.adid.google': 'cordova-plugin-analytics-adid',
|
||||
'com.chariotsolutions.nfc.plugin': 'phonegap-nfc',
|
||||
'com.samz.mixpanel': 'cordova-plugin-mixpanel',
|
||||
'de.appplant.cordova.common.RegisterUserNotificationSettings': 'cordova-plugin-registerusernotificationsettings',
|
||||
'plugin.google.maps': 'cordova-plugin-googlemaps',
|
||||
'xu.li.cordova.wechat': 'cordova-plugin-wechat',
|
||||
'es.keensoft.fullscreenimage': 'cordova-plugin-fullscreenimage',
|
||||
'com.arcoirislabs.plugin.mqtt' : 'cordova-plugin-mqtt'
|
||||
};
|
||||
'com.samz.mixpanel': 'cordova-plugin-mixpanel'
|
||||
}
|
||||
|
||||
module.exports.oldToNew = map;
|
||||
|
||||
var reverseMap = {};
|
||||
Object.keys(map).forEach(function(elem){
|
||||
reverseMap[map[elem]] = elem;
|
||||
});
|
||||
})
|
||||
|
||||
module.exports.newToOld = reverseMap;
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
/node_modules
|
||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.8"
|
||||
- "0.10"
|
||||
Generated
Vendored
Generated
Vendored
+140
@@ -0,0 +1,140 @@
|
||||
var defined = require('defined');
|
||||
var createDefaultStream = require('./lib/default_stream');
|
||||
var Test = require('./lib/test');
|
||||
var createResult = require('./lib/results');
|
||||
var through = require('through');
|
||||
|
||||
var canEmitExit = typeof process !== 'undefined' && process
|
||||
&& typeof process.on === 'function' && process.browser !== true
|
||||
;
|
||||
var canExit = typeof process !== 'undefined' && process
|
||||
&& typeof process.exit === 'function'
|
||||
;
|
||||
|
||||
var nextTick = typeof setImmediate !== 'undefined'
|
||||
? setImmediate
|
||||
: process.nextTick
|
||||
;
|
||||
|
||||
exports = module.exports = (function () {
|
||||
var harness;
|
||||
var lazyLoad = function () {
|
||||
return getHarness().apply(this, arguments);
|
||||
};
|
||||
|
||||
lazyLoad.only = function () {
|
||||
return getHarness().only.apply(this, arguments);
|
||||
};
|
||||
|
||||
lazyLoad.createStream = function (opts) {
|
||||
if (!opts) opts = {};
|
||||
if (!harness) {
|
||||
var output = through();
|
||||
getHarness({ stream: output, objectMode: opts.objectMode });
|
||||
return output;
|
||||
}
|
||||
return harness.createStream(opts);
|
||||
};
|
||||
|
||||
return lazyLoad
|
||||
|
||||
function getHarness (opts) {
|
||||
if (!opts) opts = {};
|
||||
opts.autoclose = !canEmitExit;
|
||||
if (!harness) harness = createExitHarness(opts);
|
||||
return harness;
|
||||
}
|
||||
})();
|
||||
|
||||
function createExitHarness (conf) {
|
||||
if (!conf) conf = {};
|
||||
var harness = createHarness({
|
||||
autoclose: defined(conf.autoclose, false)
|
||||
});
|
||||
|
||||
var stream = harness.createStream({ objectMode: conf.objectMode });
|
||||
var es = stream.pipe(conf.stream || createDefaultStream());
|
||||
if (canEmitExit) {
|
||||
es.on('error', function (err) { harness._exitCode = 1 });
|
||||
}
|
||||
|
||||
var ended = false;
|
||||
stream.on('end', function () { ended = true });
|
||||
|
||||
if (conf.exit === false) return harness;
|
||||
if (!canEmitExit || !canExit) return harness;
|
||||
|
||||
var inErrorState = false;
|
||||
|
||||
process.on('exit', function (code) {
|
||||
// let the process exit cleanly.
|
||||
if (code !== 0) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!ended) {
|
||||
var only = harness._results._only;
|
||||
for (var i = 0; i < harness._tests.length; i++) {
|
||||
var t = harness._tests[i];
|
||||
if (only && t.name !== only) continue;
|
||||
t._exit();
|
||||
}
|
||||
}
|
||||
harness.close();
|
||||
process.exit(code || harness._exitCode);
|
||||
});
|
||||
|
||||
return harness;
|
||||
}
|
||||
|
||||
exports.createHarness = createHarness;
|
||||
exports.Test = Test;
|
||||
exports.test = exports; // tap compat
|
||||
exports.test.skip = Test.skip;
|
||||
|
||||
var exitInterval;
|
||||
|
||||
function createHarness (conf_) {
|
||||
if (!conf_) conf_ = {};
|
||||
var results = createResult();
|
||||
if (conf_.autoclose !== false) {
|
||||
results.once('done', function () { results.close() });
|
||||
}
|
||||
|
||||
var test = function (name, conf, cb) {
|
||||
var t = new Test(name, conf, cb);
|
||||
test._tests.push(t);
|
||||
|
||||
(function inspectCode (st) {
|
||||
st.on('test', function sub (st_) {
|
||||
inspectCode(st_);
|
||||
});
|
||||
st.on('result', function (r) {
|
||||
if (!r.ok) test._exitCode = 1
|
||||
});
|
||||
})(t);
|
||||
|
||||
results.push(t);
|
||||
return t;
|
||||
};
|
||||
test._results = results;
|
||||
|
||||
test._tests = [];
|
||||
|
||||
test.createStream = function (opts) {
|
||||
return results.createStream(opts);
|
||||
};
|
||||
|
||||
var only = false;
|
||||
test.only = function (name) {
|
||||
if (only) throw new Error('there can only be one only test');
|
||||
results.only(name);
|
||||
only = true;
|
||||
return test.apply(null, arguments);
|
||||
};
|
||||
test._exitCode = 0;
|
||||
|
||||
test.close = function () { results.close() };
|
||||
|
||||
return test;
|
||||
}
|
||||
Generated
Vendored
+31
@@ -0,0 +1,31 @@
|
||||
var through = require('through');
|
||||
var fs = require('fs');
|
||||
|
||||
module.exports = function () {
|
||||
var line = '';
|
||||
var stream = through(write, flush);
|
||||
return stream;
|
||||
|
||||
function write (buf) {
|
||||
for (var i = 0; i < buf.length; i++) {
|
||||
var c = typeof buf === 'string'
|
||||
? buf.charAt(i)
|
||||
: String.fromCharCode(buf[i])
|
||||
;
|
||||
if (c === '\n') flush();
|
||||
else line += c;
|
||||
}
|
||||
}
|
||||
|
||||
function flush () {
|
||||
if (fs.writeSync && /^win/.test(process.platform)) {
|
||||
try { fs.writeSync(1, line + '\n'); }
|
||||
catch (e) { stream.emit('error', e) }
|
||||
}
|
||||
else {
|
||||
try { console.log(line) }
|
||||
catch (e) { stream.emit('error', e) }
|
||||
}
|
||||
line = '';
|
||||
}
|
||||
};
|
||||
Generated
Vendored
+189
@@ -0,0 +1,189 @@
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var inherits = require('inherits');
|
||||
var through = require('through');
|
||||
var resumer = require('resumer');
|
||||
var inspect = require('object-inspect');
|
||||
var nextTick = typeof setImmediate !== 'undefined'
|
||||
? setImmediate
|
||||
: process.nextTick
|
||||
;
|
||||
|
||||
module.exports = Results;
|
||||
inherits(Results, EventEmitter);
|
||||
|
||||
function Results () {
|
||||
if (!(this instanceof Results)) return new Results;
|
||||
this.count = 0;
|
||||
this.fail = 0;
|
||||
this.pass = 0;
|
||||
this._stream = through();
|
||||
this.tests = [];
|
||||
}
|
||||
|
||||
Results.prototype.createStream = function (opts) {
|
||||
if (!opts) opts = {};
|
||||
var self = this;
|
||||
var output, testId = 0;
|
||||
if (opts.objectMode) {
|
||||
output = through();
|
||||
self.on('_push', function ontest (t, extra) {
|
||||
if (!extra) extra = {};
|
||||
var id = testId++;
|
||||
t.once('prerun', function () {
|
||||
var row = {
|
||||
type: 'test',
|
||||
name: t.name,
|
||||
id: id
|
||||
};
|
||||
if (has(extra, 'parent')) {
|
||||
row.parent = extra.parent;
|
||||
}
|
||||
output.queue(row);
|
||||
});
|
||||
t.on('test', function (st) {
|
||||
ontest(st, { parent: id });
|
||||
});
|
||||
t.on('result', function (res) {
|
||||
res.test = id;
|
||||
res.type = 'assert';
|
||||
output.queue(res);
|
||||
});
|
||||
t.on('end', function () {
|
||||
output.queue({ type: 'end', test: id });
|
||||
});
|
||||
});
|
||||
self.on('done', function () { output.queue(null) });
|
||||
}
|
||||
else {
|
||||
output = resumer();
|
||||
output.queue('TAP version 13\n');
|
||||
self._stream.pipe(output);
|
||||
}
|
||||
|
||||
nextTick(function next() {
|
||||
var t;
|
||||
while (t = getNextTest(self)) {
|
||||
t.run();
|
||||
if (!t.ended) return t.once('end', function(){ nextTick(next); });
|
||||
}
|
||||
self.emit('done');
|
||||
});
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
Results.prototype.push = function (t) {
|
||||
var self = this;
|
||||
self.tests.push(t);
|
||||
self._watch(t);
|
||||
self.emit('_push', t);
|
||||
};
|
||||
|
||||
Results.prototype.only = function (name) {
|
||||
if (this._only) {
|
||||
self.count ++;
|
||||
self.fail ++;
|
||||
write('not ok ' + self.count + ' already called .only()\n');
|
||||
}
|
||||
this._only = name;
|
||||
};
|
||||
|
||||
Results.prototype._watch = function (t) {
|
||||
var self = this;
|
||||
var write = function (s) { self._stream.queue(s) };
|
||||
t.once('prerun', function () {
|
||||
write('# ' + t.name + '\n');
|
||||
});
|
||||
|
||||
t.on('result', function (res) {
|
||||
if (typeof res === 'string') {
|
||||
write('# ' + res + '\n');
|
||||
return;
|
||||
}
|
||||
write(encodeResult(res, self.count + 1));
|
||||
self.count ++;
|
||||
|
||||
if (res.ok) self.pass ++
|
||||
else self.fail ++
|
||||
});
|
||||
|
||||
t.on('test', function (st) { self._watch(st) });
|
||||
};
|
||||
|
||||
Results.prototype.close = function () {
|
||||
var self = this;
|
||||
if (self.closed) self._stream.emit('error', new Error('ALREADY CLOSED'));
|
||||
self.closed = true;
|
||||
var write = function (s) { self._stream.queue(s) };
|
||||
|
||||
write('\n1..' + self.count + '\n');
|
||||
write('# tests ' + self.count + '\n');
|
||||
write('# pass ' + self.pass + '\n');
|
||||
if (self.fail) write('# fail ' + self.fail + '\n')
|
||||
else write('\n# ok\n')
|
||||
|
||||
self._stream.queue(null);
|
||||
};
|
||||
|
||||
function encodeResult (res, count) {
|
||||
var output = '';
|
||||
output += (res.ok ? 'ok ' : 'not ok ') + count;
|
||||
output += res.name ? ' ' + res.name.toString().replace(/\s+/g, ' ') : '';
|
||||
|
||||
if (res.skip) output += ' # SKIP';
|
||||
else if (res.todo) output += ' # TODO';
|
||||
|
||||
output += '\n';
|
||||
if (res.ok) return output;
|
||||
|
||||
var outer = ' ';
|
||||
var inner = outer + ' ';
|
||||
output += outer + '---\n';
|
||||
output += inner + 'operator: ' + res.operator + '\n';
|
||||
|
||||
if (has(res, 'expected') || has(res, 'actual')) {
|
||||
var ex = inspect(res.expected);
|
||||
var ac = inspect(res.actual);
|
||||
|
||||
if (Math.max(ex.length, ac.length) > 65) {
|
||||
output += inner + 'expected:\n' + inner + ' ' + ex + '\n';
|
||||
output += inner + 'actual:\n' + inner + ' ' + ac + '\n';
|
||||
}
|
||||
else {
|
||||
output += inner + 'expected: ' + ex + '\n';
|
||||
output += inner + 'actual: ' + ac + '\n';
|
||||
}
|
||||
}
|
||||
if (res.at) {
|
||||
output += inner + 'at: ' + res.at + '\n';
|
||||
}
|
||||
if (res.operator === 'error' && res.actual && res.actual.stack) {
|
||||
var lines = String(res.actual.stack).split('\n');
|
||||
output += inner + 'stack:\n';
|
||||
output += inner + ' ' + lines[0] + '\n';
|
||||
for (var i = 1; i < lines.length; i++) {
|
||||
output += inner + lines[i] + '\n';
|
||||
}
|
||||
}
|
||||
|
||||
output += outer + '...\n';
|
||||
return output;
|
||||
}
|
||||
|
||||
function getNextTest (results) {
|
||||
if (!results._only) {
|
||||
return results.tests.shift();
|
||||
}
|
||||
|
||||
do {
|
||||
var t = results.tests.shift();
|
||||
if (!t) continue;
|
||||
if (results._only === t.name) {
|
||||
return t;
|
||||
}
|
||||
} while (results.tests.length !== 0)
|
||||
}
|
||||
|
||||
function has (obj, prop) {
|
||||
return Object.prototype.hasOwnProperty.call(obj, prop);
|
||||
}
|
||||
Generated
Vendored
+496
@@ -0,0 +1,496 @@
|
||||
var deepEqual = require('deep-equal');
|
||||
var defined = require('defined');
|
||||
var path = require('path');
|
||||
var inherits = require('inherits');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
|
||||
module.exports = Test;
|
||||
|
||||
var nextTick = typeof setImmediate !== 'undefined'
|
||||
? setImmediate
|
||||
: process.nextTick
|
||||
;
|
||||
|
||||
inherits(Test, EventEmitter);
|
||||
|
||||
var getTestArgs = function (name_, opts_, cb_) {
|
||||
var name = '(anonymous)';
|
||||
var opts = {};
|
||||
var cb;
|
||||
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
var arg = arguments[i];
|
||||
var t = typeof arg;
|
||||
if (t === 'string') {
|
||||
name = arg;
|
||||
}
|
||||
else if (t === 'object') {
|
||||
opts = arg || opts;
|
||||
}
|
||||
else if (t === 'function') {
|
||||
cb = arg;
|
||||
}
|
||||
}
|
||||
return { name: name, opts: opts, cb: cb };
|
||||
};
|
||||
|
||||
function Test (name_, opts_, cb_) {
|
||||
if (! (this instanceof Test)) {
|
||||
return new Test(name_, opts_, cb_);
|
||||
}
|
||||
|
||||
var args = getTestArgs(name_, opts_, cb_);
|
||||
|
||||
this.readable = true;
|
||||
this.name = args.name || '(anonymous)';
|
||||
this.assertCount = 0;
|
||||
this.pendingCount = 0;
|
||||
this._skip = args.opts.skip || false;
|
||||
this._plan = undefined;
|
||||
this._cb = args.cb;
|
||||
this._progeny = [];
|
||||
this._ok = true;
|
||||
|
||||
if (args.opts.timeout !== undefined) {
|
||||
this.timeoutAfter(args.opts.timeout);
|
||||
}
|
||||
|
||||
for (var prop in this) {
|
||||
this[prop] = (function bind(self, val) {
|
||||
if (typeof val === 'function') {
|
||||
return function bound() {
|
||||
return val.apply(self, arguments);
|
||||
};
|
||||
}
|
||||
else return val;
|
||||
})(this, this[prop]);
|
||||
}
|
||||
}
|
||||
|
||||
Test.prototype.run = function () {
|
||||
if (!this._cb || this._skip) {
|
||||
return this._end();
|
||||
}
|
||||
this.emit('prerun');
|
||||
this._cb(this);
|
||||
this.emit('run');
|
||||
};
|
||||
|
||||
Test.prototype.test = function (name, opts, cb) {
|
||||
var self = this;
|
||||
var t = new Test(name, opts, cb);
|
||||
this._progeny.push(t);
|
||||
this.pendingCount++;
|
||||
this.emit('test', t);
|
||||
t.on('prerun', function () {
|
||||
self.assertCount++;
|
||||
})
|
||||
|
||||
if (!self._pendingAsserts()) {
|
||||
nextTick(function () {
|
||||
self._end();
|
||||
});
|
||||
}
|
||||
|
||||
nextTick(function() {
|
||||
if (!self._plan && self.pendingCount == self._progeny.length) {
|
||||
self._end();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Test.prototype.comment = function (msg) {
|
||||
this.emit('result', msg.trim().replace(/^#\s*/, ''));
|
||||
};
|
||||
|
||||
Test.prototype.plan = function (n) {
|
||||
this._plan = n;
|
||||
this.emit('plan', n);
|
||||
};
|
||||
|
||||
Test.prototype.timeoutAfter = function(ms) {
|
||||
if (!ms) throw new Error('timeoutAfter requires a timespan');
|
||||
var self = this;
|
||||
var timeout = setTimeout(function() {
|
||||
self.fail('test timed out after ' + ms + 'ms');
|
||||
self.end();
|
||||
}, ms);
|
||||
this.once('end', function() {
|
||||
clearTimeout(timeout);
|
||||
});
|
||||
}
|
||||
|
||||
Test.prototype.end = function (err) {
|
||||
var self = this;
|
||||
if (arguments.length >= 1) {
|
||||
this.ifError(err);
|
||||
}
|
||||
|
||||
if (this.calledEnd) {
|
||||
this.fail('.end() called twice');
|
||||
}
|
||||
this.calledEnd = true;
|
||||
this._end();
|
||||
};
|
||||
|
||||
Test.prototype._end = function (err) {
|
||||
var self = this;
|
||||
if (this._progeny.length) {
|
||||
var t = this._progeny.shift();
|
||||
t.on('end', function () { self._end() });
|
||||
t.run();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.ended) this.emit('end');
|
||||
var pendingAsserts = this._pendingAsserts();
|
||||
if (!this._planError && this._plan !== undefined && pendingAsserts) {
|
||||
this._planError = true;
|
||||
this.fail('plan != count', {
|
||||
expected : this._plan,
|
||||
actual : this.assertCount
|
||||
});
|
||||
}
|
||||
this.ended = true;
|
||||
};
|
||||
|
||||
Test.prototype._exit = function () {
|
||||
if (this._plan !== undefined &&
|
||||
!this._planError && this.assertCount !== this._plan) {
|
||||
this._planError = true;
|
||||
this.fail('plan != count', {
|
||||
expected : this._plan,
|
||||
actual : this.assertCount,
|
||||
exiting : true
|
||||
});
|
||||
}
|
||||
else if (!this.ended) {
|
||||
this.fail('test exited without ending', {
|
||||
exiting: true
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Test.prototype._pendingAsserts = function () {
|
||||
if (this._plan === undefined) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return this._plan - (this._progeny.length + this.assertCount);
|
||||
}
|
||||
};
|
||||
|
||||
Test.prototype._assert = function assert (ok, opts) {
|
||||
var self = this;
|
||||
var extra = opts.extra || {};
|
||||
|
||||
var res = {
|
||||
id : self.assertCount ++,
|
||||
ok : Boolean(ok),
|
||||
skip : defined(extra.skip, opts.skip),
|
||||
name : defined(extra.message, opts.message, '(unnamed assert)'),
|
||||
operator : defined(extra.operator, opts.operator)
|
||||
};
|
||||
if (has(opts, 'actual') || has(extra, 'actual')) {
|
||||
res.actual = defined(extra.actual, opts.actual);
|
||||
}
|
||||
if (has(opts, 'expected') || has(extra, 'expected')) {
|
||||
res.expected = defined(extra.expected, opts.expected);
|
||||
}
|
||||
this._ok = Boolean(this._ok && ok);
|
||||
|
||||
if (!ok) {
|
||||
res.error = defined(extra.error, opts.error, new Error(res.name));
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
var e = new Error('exception');
|
||||
var err = (e.stack || '').split('\n');
|
||||
var dir = path.dirname(__dirname) + '/';
|
||||
|
||||
for (var i = 0; i < err.length; i++) {
|
||||
var m = /^[^\s]*\s*\bat\s+(.+)/.exec(err[i]);
|
||||
if (!m) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var s = m[1].split(/\s+/);
|
||||
var filem = /(\/[^:\s]+:(\d+)(?::(\d+))?)/.exec(s[1]);
|
||||
if (!filem) {
|
||||
filem = /(\/[^:\s]+:(\d+)(?::(\d+))?)/.exec(s[2]);
|
||||
|
||||
if (!filem) {
|
||||
filem = /(\/[^:\s]+:(\d+)(?::(\d+))?)/.exec(s[3]);
|
||||
|
||||
if (!filem) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (filem[1].slice(0, dir.length) === dir) {
|
||||
continue;
|
||||
}
|
||||
|
||||
res.functionName = s[0];
|
||||
res.file = filem[1];
|
||||
res.line = Number(filem[2]);
|
||||
if (filem[3]) res.column = filem[3];
|
||||
|
||||
res.at = m[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
self.emit('result', res);
|
||||
|
||||
var pendingAsserts = self._pendingAsserts();
|
||||
if (!pendingAsserts) {
|
||||
if (extra.exiting) {
|
||||
self._end();
|
||||
} else {
|
||||
nextTick(function () {
|
||||
self._end();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!self._planError && pendingAsserts < 0) {
|
||||
self._planError = true;
|
||||
self.fail('plan != count', {
|
||||
expected : self._plan,
|
||||
actual : self._plan - pendingAsserts
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Test.prototype.fail = function (msg, extra) {
|
||||
this._assert(false, {
|
||||
message : msg,
|
||||
operator : 'fail',
|
||||
extra : extra
|
||||
});
|
||||
};
|
||||
|
||||
Test.prototype.pass = function (msg, extra) {
|
||||
this._assert(true, {
|
||||
message : msg,
|
||||
operator : 'pass',
|
||||
extra : extra
|
||||
});
|
||||
};
|
||||
|
||||
Test.prototype.skip = function (msg, extra) {
|
||||
this._assert(true, {
|
||||
message : msg,
|
||||
operator : 'skip',
|
||||
skip : true,
|
||||
extra : extra
|
||||
});
|
||||
};
|
||||
|
||||
Test.prototype.ok
|
||||
= Test.prototype['true']
|
||||
= Test.prototype.assert
|
||||
= function (value, msg, extra) {
|
||||
this._assert(value, {
|
||||
message : msg,
|
||||
operator : 'ok',
|
||||
expected : true,
|
||||
actual : value,
|
||||
extra : extra
|
||||
});
|
||||
};
|
||||
|
||||
Test.prototype.notOk
|
||||
= Test.prototype['false']
|
||||
= Test.prototype.notok
|
||||
= function (value, msg, extra) {
|
||||
this._assert(!value, {
|
||||
message : msg,
|
||||
operator : 'notOk',
|
||||
expected : false,
|
||||
actual : value,
|
||||
extra : extra
|
||||
});
|
||||
};
|
||||
|
||||
Test.prototype.error
|
||||
= Test.prototype.ifError
|
||||
= Test.prototype.ifErr
|
||||
= Test.prototype.iferror
|
||||
= function (err, msg, extra) {
|
||||
this._assert(!err, {
|
||||
message : defined(msg, String(err)),
|
||||
operator : 'error',
|
||||
actual : err,
|
||||
extra : extra
|
||||
});
|
||||
};
|
||||
|
||||
Test.prototype.equal
|
||||
= Test.prototype.equals
|
||||
= Test.prototype.isEqual
|
||||
= Test.prototype.is
|
||||
= Test.prototype.strictEqual
|
||||
= Test.prototype.strictEquals
|
||||
= function (a, b, msg, extra) {
|
||||
this._assert(a === b, {
|
||||
message : defined(msg, 'should be equal'),
|
||||
operator : 'equal',
|
||||
actual : a,
|
||||
expected : b,
|
||||
extra : extra
|
||||
});
|
||||
};
|
||||
|
||||
Test.prototype.notEqual
|
||||
= Test.prototype.notEquals
|
||||
= Test.prototype.notStrictEqual
|
||||
= Test.prototype.notStrictEquals
|
||||
= Test.prototype.isNotEqual
|
||||
= Test.prototype.isNot
|
||||
= Test.prototype.not
|
||||
= Test.prototype.doesNotEqual
|
||||
= Test.prototype.isInequal
|
||||
= function (a, b, msg, extra) {
|
||||
this._assert(a !== b, {
|
||||
message : defined(msg, 'should not be equal'),
|
||||
operator : 'notEqual',
|
||||
actual : a,
|
||||
notExpected : b,
|
||||
extra : extra
|
||||
});
|
||||
};
|
||||
|
||||
Test.prototype.deepEqual
|
||||
= Test.prototype.deepEquals
|
||||
= Test.prototype.isEquivalent
|
||||
= Test.prototype.same
|
||||
= function (a, b, msg, extra) {
|
||||
this._assert(deepEqual(a, b, { strict: true }), {
|
||||
message : defined(msg, 'should be equivalent'),
|
||||
operator : 'deepEqual',
|
||||
actual : a,
|
||||
expected : b,
|
||||
extra : extra
|
||||
});
|
||||
};
|
||||
|
||||
Test.prototype.deepLooseEqual
|
||||
= Test.prototype.looseEqual
|
||||
= Test.prototype.looseEquals
|
||||
= function (a, b, msg, extra) {
|
||||
this._assert(deepEqual(a, b), {
|
||||
message : defined(msg, 'should be equivalent'),
|
||||
operator : 'deepLooseEqual',
|
||||
actual : a,
|
||||
expected : b,
|
||||
extra : extra
|
||||
});
|
||||
};
|
||||
|
||||
Test.prototype.notDeepEqual
|
||||
= Test.prototype.notEquivalent
|
||||
= Test.prototype.notDeeply
|
||||
= Test.prototype.notSame
|
||||
= Test.prototype.isNotDeepEqual
|
||||
= Test.prototype.isNotDeeply
|
||||
= Test.prototype.isNotEquivalent
|
||||
= Test.prototype.isInequivalent
|
||||
= function (a, b, msg, extra) {
|
||||
this._assert(!deepEqual(a, b, { strict: true }), {
|
||||
message : defined(msg, 'should not be equivalent'),
|
||||
operator : 'notDeepEqual',
|
||||
actual : a,
|
||||
notExpected : b,
|
||||
extra : extra
|
||||
});
|
||||
};
|
||||
|
||||
Test.prototype.notDeepLooseEqual
|
||||
= Test.prototype.notLooseEqual
|
||||
= Test.prototype.notLooseEquals
|
||||
= function (a, b, msg, extra) {
|
||||
this._assert(!deepEqual(a, b), {
|
||||
message : defined(msg, 'should be equivalent'),
|
||||
operator : 'notDeepLooseEqual',
|
||||
actual : a,
|
||||
expected : b,
|
||||
extra : extra
|
||||
});
|
||||
};
|
||||
|
||||
Test.prototype['throws'] = function (fn, expected, msg, extra) {
|
||||
if (typeof expected === 'string') {
|
||||
msg = expected;
|
||||
expected = undefined;
|
||||
}
|
||||
|
||||
var caught = undefined;
|
||||
|
||||
try {
|
||||
fn();
|
||||
} catch (err) {
|
||||
caught = { error : err };
|
||||
var message = err.message;
|
||||
delete err.message;
|
||||
err.message = message;
|
||||
}
|
||||
|
||||
var passed = caught;
|
||||
|
||||
if (expected instanceof RegExp) {
|
||||
passed = expected.test(caught && caught.error);
|
||||
expected = String(expected);
|
||||
}
|
||||
|
||||
if (typeof expected === 'function') {
|
||||
passed = caught.error instanceof expected;
|
||||
caught.error = caught.error.constructor;
|
||||
}
|
||||
|
||||
this._assert(passed, {
|
||||
message : defined(msg, 'should throw'),
|
||||
operator : 'throws',
|
||||
actual : caught && caught.error,
|
||||
expected : expected,
|
||||
error: !passed && caught && caught.error,
|
||||
extra : extra
|
||||
});
|
||||
};
|
||||
|
||||
Test.prototype.doesNotThrow = function (fn, expected, msg, extra) {
|
||||
if (typeof expected === 'string') {
|
||||
msg = expected;
|
||||
expected = undefined;
|
||||
}
|
||||
var caught = undefined;
|
||||
try {
|
||||
fn();
|
||||
}
|
||||
catch (err) {
|
||||
caught = { error : err };
|
||||
}
|
||||
this._assert(!caught, {
|
||||
message : defined(msg, 'should not throw'),
|
||||
operator : 'throws',
|
||||
actual : caught && caught.error,
|
||||
expected : expected,
|
||||
error : caught && caught.error,
|
||||
extra : extra
|
||||
});
|
||||
};
|
||||
|
||||
function has (obj, prop) {
|
||||
return Object.prototype.hasOwnProperty.call(obj, prop);
|
||||
}
|
||||
|
||||
Test.skip = function (name_, _opts, _cb) {
|
||||
var args = getTestArgs.apply(null, arguments);
|
||||
args.opts.skip = true;
|
||||
return Test(args.name, args.opts, args.cb);
|
||||
};
|
||||
|
||||
// vim: set softtabstop=4 shiftwidth=4:
|
||||
|
||||
Generated
Vendored
Generated
Vendored
+9
-12
@@ -1,21 +1,18 @@
|
||||
(MIT)
|
||||
|
||||
Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
|
||||
This software is released under the MIT license:
|
||||
|
||||
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:
|
||||
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.
|
||||
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.
|
||||
Generated
Vendored
+94
@@ -0,0 +1,94 @@
|
||||
var pSlice = Array.prototype.slice;
|
||||
var objectKeys = require('./lib/keys.js');
|
||||
var isArguments = require('./lib/is_arguments.js');
|
||||
|
||||
var deepEqual = module.exports = function (actual, expected, opts) {
|
||||
if (!opts) opts = {};
|
||||
// 7.1. All identical values are equivalent, as determined by ===.
|
||||
if (actual === expected) {
|
||||
return true;
|
||||
|
||||
} else if (actual instanceof Date && expected instanceof Date) {
|
||||
return actual.getTime() === expected.getTime();
|
||||
|
||||
// 7.3. Other pairs that do not both pass typeof value == 'object',
|
||||
// equivalence is determined by ==.
|
||||
} else if (typeof actual != 'object' && typeof expected != 'object') {
|
||||
return opts.strict ? actual === expected : actual == expected;
|
||||
|
||||
// 7.4. For all other Object pairs, including Array objects, equivalence is
|
||||
// determined by having the same number of owned properties (as verified
|
||||
// with Object.prototype.hasOwnProperty.call), the same set of keys
|
||||
// (although not necessarily the same order), equivalent values for every
|
||||
// corresponding key, and an identical 'prototype' property. Note: this
|
||||
// accounts for both named and indexed properties on Arrays.
|
||||
} else {
|
||||
return objEquiv(actual, expected, opts);
|
||||
}
|
||||
}
|
||||
|
||||
function isUndefinedOrNull(value) {
|
||||
return value === null || value === undefined;
|
||||
}
|
||||
|
||||
function isBuffer (x) {
|
||||
if (!x || typeof x !== 'object' || typeof x.length !== 'number') return false;
|
||||
if (typeof x.copy !== 'function' || typeof x.slice !== 'function') {
|
||||
return false;
|
||||
}
|
||||
if (x.length > 0 && typeof x[0] !== 'number') return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function objEquiv(a, b, opts) {
|
||||
var i, key;
|
||||
if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
|
||||
return false;
|
||||
// an identical 'prototype' property.
|
||||
if (a.prototype !== b.prototype) return false;
|
||||
//~~~I've managed to break Object.keys through screwy arguments passing.
|
||||
// Converting to array solves the problem.
|
||||
if (isArguments(a)) {
|
||||
if (!isArguments(b)) {
|
||||
return false;
|
||||
}
|
||||
a = pSlice.call(a);
|
||||
b = pSlice.call(b);
|
||||
return deepEqual(a, b, opts);
|
||||
}
|
||||
if (isBuffer(a)) {
|
||||
if (!isBuffer(b)) {
|
||||
return false;
|
||||
}
|
||||
if (a.length !== b.length) return false;
|
||||
for (i = 0; i < a.length; i++) {
|
||||
if (a[i] !== b[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
var ka = objectKeys(a),
|
||||
kb = objectKeys(b);
|
||||
} catch (e) {//happens when one is a string literal and the other isn't
|
||||
return false;
|
||||
}
|
||||
// having the same number of owned properties (keys incorporates
|
||||
// hasOwnProperty)
|
||||
if (ka.length != kb.length)
|
||||
return false;
|
||||
//the same set of keys (although not necessarily the same order),
|
||||
ka.sort();
|
||||
kb.sort();
|
||||
//~~~cheap key test
|
||||
for (i = ka.length - 1; i >= 0; i--) {
|
||||
if (ka[i] != kb[i])
|
||||
return false;
|
||||
}
|
||||
//equivalent values for every corresponding key, and
|
||||
//~~~possibly expensive deep test
|
||||
for (i = ka.length - 1; i >= 0; i--) {
|
||||
key = ka[i];
|
||||
if (!deepEqual(a[key], b[key], opts)) return false;
|
||||
}
|
||||
return typeof a === typeof b;
|
||||
}
|
||||
Generated
Vendored
+20
@@ -0,0 +1,20 @@
|
||||
var supportsArgumentsClass = (function(){
|
||||
return Object.prototype.toString.call(arguments)
|
||||
})() == '[object Arguments]';
|
||||
|
||||
exports = module.exports = supportsArgumentsClass ? supported : unsupported;
|
||||
|
||||
exports.supported = supported;
|
||||
function supported(object) {
|
||||
return Object.prototype.toString.call(object) == '[object Arguments]';
|
||||
};
|
||||
|
||||
exports.unsupported = unsupported;
|
||||
function unsupported(object){
|
||||
return object &&
|
||||
typeof object == 'object' &&
|
||||
typeof object.length == 'number' &&
|
||||
Object.prototype.hasOwnProperty.call(object, 'callee') &&
|
||||
!Object.prototype.propertyIsEnumerable.call(object, 'callee') ||
|
||||
false;
|
||||
};
|
||||
Generated
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
exports = module.exports = typeof Object.keys === 'function'
|
||||
? Object.keys : shim;
|
||||
|
||||
exports.shim = shim;
|
||||
function shim (obj) {
|
||||
var keys = [];
|
||||
for (var key in obj) keys.push(key);
|
||||
return keys;
|
||||
}
|
||||
Generated
Vendored
+84
@@ -0,0 +1,84 @@
|
||||
{
|
||||
"name": "deep-equal",
|
||||
"version": "0.2.2",
|
||||
"description": "node's assert.deepEqual algorithm",
|
||||
"main": "index.js",
|
||||
"directories": {
|
||||
"lib": ".",
|
||||
"example": "example",
|
||||
"test": "test"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape test/*.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tape": "^3.5.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+ssh://git@github.com/substack/node-deep-equal.git"
|
||||
},
|
||||
"keywords": [
|
||||
"equality",
|
||||
"equal",
|
||||
"compare"
|
||||
],
|
||||
"author": {
|
||||
"name": "James Halliday",
|
||||
"email": "mail@substack.net",
|
||||
"url": "http://substack.net"
|
||||
},
|
||||
"license": "MIT",
|
||||
"testling": {
|
||||
"files": "test/*.js",
|
||||
"browsers": {
|
||||
"ie": [
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9
|
||||
],
|
||||
"ff": [
|
||||
3.5,
|
||||
10,
|
||||
15
|
||||
],
|
||||
"chrome": [
|
||||
10,
|
||||
22
|
||||
],
|
||||
"safari": [
|
||||
5.1
|
||||
],
|
||||
"opera": [
|
||||
12
|
||||
]
|
||||
}
|
||||
},
|
||||
"gitHead": "05cd26a25f0d7babf0c2758827b4dafec9d0582e",
|
||||
"bugs": {
|
||||
"url": "https://github.com/substack/node-deep-equal/issues"
|
||||
},
|
||||
"homepage": "https://github.com/substack/node-deep-equal",
|
||||
"_id": "deep-equal@0.2.2",
|
||||
"_shasum": "84b745896f34c684e98f2ce0e42abaf43bba017d",
|
||||
"_from": "deep-equal@>=0.2.0 <0.3.0",
|
||||
"_npmVersion": "2.3.0",
|
||||
"_nodeVersion": "0.10.35",
|
||||
"_npmUser": {
|
||||
"name": "substack",
|
||||
"email": "mail@substack.net"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "substack",
|
||||
"email": "mail@substack.net"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "84b745896f34c684e98f2ce0e42abaf43bba017d",
|
||||
"tarball": "http://registry.npmjs.org/deep-equal/-/deep-equal-0.2.2.tgz"
|
||||
},
|
||||
"_resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-0.2.2.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
}
|
||||
Generated
Vendored
+61
@@ -0,0 +1,61 @@
|
||||
# deep-equal
|
||||
|
||||
Node's `assert.deepEqual() algorithm` as a standalone module.
|
||||
|
||||
This module is around [5 times faster](https://gist.github.com/2790507)
|
||||
than wrapping `assert.deepEqual()` in a `try/catch`.
|
||||
|
||||
[](https://ci.testling.com/substack/node-deep-equal)
|
||||
|
||||
[](https://travis-ci.org/substack/node-deep-equal)
|
||||
|
||||
# example
|
||||
|
||||
``` js
|
||||
var equal = require('deep-equal');
|
||||
console.dir([
|
||||
equal(
|
||||
{ a : [ 2, 3 ], b : [ 4 ] },
|
||||
{ a : [ 2, 3 ], b : [ 4 ] }
|
||||
),
|
||||
equal(
|
||||
{ x : 5, y : [6] },
|
||||
{ x : 5, y : 6 }
|
||||
)
|
||||
]);
|
||||
```
|
||||
|
||||
# methods
|
||||
|
||||
``` js
|
||||
var deepEqual = require('deep-equal')
|
||||
```
|
||||
|
||||
## deepEqual(a, b, opts)
|
||||
|
||||
Compare objects `a` and `b`, returning whether they are equal according to a
|
||||
recursive equality algorithm.
|
||||
|
||||
If `opts.strict` is `true`, use strict equality (`===`) to compare leaf nodes.
|
||||
The default is to use coercive equality (`==`) because that's how
|
||||
`assert.deepEqual()` works by default.
|
||||
|
||||
# install
|
||||
|
||||
With [npm](http://npmjs.org) do:
|
||||
|
||||
```
|
||||
npm install deep-equal
|
||||
```
|
||||
|
||||
# test
|
||||
|
||||
With [npm](http://npmjs.org) do:
|
||||
|
||||
```
|
||||
npm test
|
||||
```
|
||||
|
||||
# license
|
||||
|
||||
MIT. Derived largely from node's assert module.
|
||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.6
|
||||
- 0.8
|
||||
Generated
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
This software is released under the MIT license:
|
||||
|
||||
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.
|
||||
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
module.exports = function () {
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
if (arguments[i] !== undefined) return arguments[i];
|
||||
}
|
||||
};
|
||||
Generated
Vendored
+60
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"name": "defined",
|
||||
"version": "0.0.0",
|
||||
"description": "return the first argument that is `!== undefined`",
|
||||
"main": "index.js",
|
||||
"directories": {
|
||||
"example": "example",
|
||||
"test": "test"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"tap": "~0.3.0",
|
||||
"tape": "~0.0.2"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tap test/*.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/substack/defined.git"
|
||||
},
|
||||
"homepage": "https://github.com/substack/defined",
|
||||
"keywords": [
|
||||
"undefined",
|
||||
"short-circuit",
|
||||
"||",
|
||||
"or",
|
||||
"//",
|
||||
"defined-or"
|
||||
],
|
||||
"author": {
|
||||
"name": "James Halliday",
|
||||
"email": "mail@substack.net",
|
||||
"url": "http://substack.net"
|
||||
},
|
||||
"license": "MIT",
|
||||
"_id": "defined@0.0.0",
|
||||
"dist": {
|
||||
"shasum": "f35eea7d705e933baf13b2f03b3f83d921403b3e",
|
||||
"tarball": "http://registry.npmjs.org/defined/-/defined-0.0.0.tgz"
|
||||
},
|
||||
"_npmVersion": "1.1.59",
|
||||
"_npmUser": {
|
||||
"name": "substack",
|
||||
"email": "mail@substack.net"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "substack",
|
||||
"email": "mail@substack.net"
|
||||
}
|
||||
],
|
||||
"_shasum": "f35eea7d705e933baf13b2f03b3f83d921403b3e",
|
||||
"_resolved": "https://registry.npmjs.org/defined/-/defined-0.0.0.tgz",
|
||||
"_from": "defined@>=0.0.0 <0.1.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/substack/defined/issues"
|
||||
},
|
||||
"readme": "ERROR: No README data found!"
|
||||
}
|
||||
Generated
Vendored
+51
@@ -0,0 +1,51 @@
|
||||
# defined
|
||||
|
||||
return the first argument that is `!== undefined`
|
||||
|
||||
[](http://travis-ci.org/substack/defined)
|
||||
|
||||
Most of the time when I chain together `||`s, I actually just want the first
|
||||
item that is not `undefined`, not the first non-falsy item.
|
||||
|
||||
This module is like the defined-or (`//`) operator in perl 5.10+.
|
||||
|
||||
# example
|
||||
|
||||
``` js
|
||||
var defined = require('defined');
|
||||
var opts = { y : false, w : 4 };
|
||||
var x = defined(opts.x, opts.y, opts.w, 100);
|
||||
console.log(x);
|
||||
```
|
||||
|
||||
```
|
||||
$ node example/defined.js
|
||||
false
|
||||
```
|
||||
|
||||
The return value is `false` because `false` is the first item that is
|
||||
`!== undefined`.
|
||||
|
||||
# methods
|
||||
|
||||
``` js
|
||||
var defined = require('defined')
|
||||
```
|
||||
|
||||
## var x = defined(a, b, c...)
|
||||
|
||||
Return the first item in the argument list `a, b, c...` that is `!== undefined`.
|
||||
|
||||
If all the items are `=== undefined`, return undefined.
|
||||
|
||||
# install
|
||||
|
||||
With [npm](https://npmjs.org) do:
|
||||
|
||||
```
|
||||
npm install defined
|
||||
```
|
||||
|
||||
# license
|
||||
|
||||
MIT
|
||||
Generated
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
.*.swp
|
||||
test/a/
|
||||
Generated
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.8
|
||||
Generated
Vendored
+27
@@ -0,0 +1,27 @@
|
||||
Copyright (c) Isaac Z. Schlueter ("Author")
|
||||
All rights reserved.
|
||||
|
||||
The BSD License
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
Generated
Vendored
+250
@@ -0,0 +1,250 @@
|
||||
# Glob
|
||||
|
||||
Match files using the patterns the shell uses, like stars and stuff.
|
||||
|
||||
This is a glob implementation in JavaScript. It uses the `minimatch`
|
||||
library to do its matching.
|
||||
|
||||
## Attention: node-glob users!
|
||||
|
||||
The API has changed dramatically between 2.x and 3.x. This library is
|
||||
now 100% JavaScript, and the integer flags have been replaced with an
|
||||
options object.
|
||||
|
||||
Also, there's an event emitter class, proper tests, and all the other
|
||||
things you've come to expect from node modules.
|
||||
|
||||
And best of all, no compilation!
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
var glob = require("glob")
|
||||
|
||||
// options is optional
|
||||
glob("**/*.js", options, function (er, files) {
|
||||
// files is an array of filenames.
|
||||
// If the `nonull` option is set, and nothing
|
||||
// was found, then files is ["**/*.js"]
|
||||
// er is an error object or null.
|
||||
})
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
Please see the [minimatch
|
||||
documentation](https://github.com/isaacs/minimatch) for more details.
|
||||
|
||||
Supports these glob features:
|
||||
|
||||
* Brace Expansion
|
||||
* Extended glob matching
|
||||
* "Globstar" `**` matching
|
||||
|
||||
See:
|
||||
|
||||
* `man sh`
|
||||
* `man bash`
|
||||
* `man 3 fnmatch`
|
||||
* `man 5 gitignore`
|
||||
* [minimatch documentation](https://github.com/isaacs/minimatch)
|
||||
|
||||
## glob(pattern, [options], cb)
|
||||
|
||||
* `pattern` {String} Pattern to be matched
|
||||
* `options` {Object}
|
||||
* `cb` {Function}
|
||||
* `err` {Error | null}
|
||||
* `matches` {Array<String>} filenames found matching the pattern
|
||||
|
||||
Perform an asynchronous glob search.
|
||||
|
||||
## glob.sync(pattern, [options])
|
||||
|
||||
* `pattern` {String} Pattern to be matched
|
||||
* `options` {Object}
|
||||
* return: {Array<String>} filenames found matching the pattern
|
||||
|
||||
Perform a synchronous glob search.
|
||||
|
||||
## Class: glob.Glob
|
||||
|
||||
Create a Glob object by instanting the `glob.Glob` class.
|
||||
|
||||
```javascript
|
||||
var Glob = require("glob").Glob
|
||||
var mg = new Glob(pattern, options, cb)
|
||||
```
|
||||
|
||||
It's an EventEmitter, and starts walking the filesystem to find matches
|
||||
immediately.
|
||||
|
||||
### new glob.Glob(pattern, [options], [cb])
|
||||
|
||||
* `pattern` {String} pattern to search for
|
||||
* `options` {Object}
|
||||
* `cb` {Function} Called when an error occurs, or matches are found
|
||||
* `err` {Error | null}
|
||||
* `matches` {Array<String>} filenames found matching the pattern
|
||||
|
||||
Note that if the `sync` flag is set in the options, then matches will
|
||||
be immediately available on the `g.found` member.
|
||||
|
||||
### Properties
|
||||
|
||||
* `minimatch` The minimatch object that the glob uses.
|
||||
* `options` The options object passed in.
|
||||
* `error` The error encountered. When an error is encountered, the
|
||||
glob object is in an undefined state, and should be discarded.
|
||||
* `aborted` Boolean which is set to true when calling `abort()`. There
|
||||
is no way at this time to continue a glob search after aborting, but
|
||||
you can re-use the statCache to avoid having to duplicate syscalls.
|
||||
* `statCache` Collection of all the stat results the glob search
|
||||
performed.
|
||||
* `cache` Convenience object. Each field has the following possible
|
||||
values:
|
||||
* `false` - Path does not exist
|
||||
* `true` - Path exists
|
||||
* `1` - Path exists, and is not a directory
|
||||
* `2` - Path exists, and is a directory
|
||||
* `[file, entries, ...]` - Path exists, is a directory, and the
|
||||
array value is the results of `fs.readdir`
|
||||
|
||||
### Events
|
||||
|
||||
* `end` When the matching is finished, this is emitted with all the
|
||||
matches found. If the `nonull` option is set, and no match was found,
|
||||
then the `matches` list contains the original pattern. The matches
|
||||
are sorted, unless the `nosort` flag is set.
|
||||
* `match` Every time a match is found, this is emitted with the matched.
|
||||
* `error` Emitted when an unexpected error is encountered, or whenever
|
||||
any fs error occurs if `options.strict` is set.
|
||||
* `abort` When `abort()` is called, this event is raised.
|
||||
|
||||
### Methods
|
||||
|
||||
* `abort` Stop the search.
|
||||
|
||||
### Options
|
||||
|
||||
All the options that can be passed to Minimatch can also be passed to
|
||||
Glob to change pattern matching behavior. Also, some have been added,
|
||||
or have glob-specific ramifications.
|
||||
|
||||
All options are false by default, unless otherwise noted.
|
||||
|
||||
All options are added to the glob object, as well.
|
||||
|
||||
* `cwd` The current working directory in which to search. Defaults
|
||||
to `process.cwd()`.
|
||||
* `root` The place where patterns starting with `/` will be mounted
|
||||
onto. Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix
|
||||
systems, and `C:\` or some such on Windows.)
|
||||
* `dot` Include `.dot` files in normal matches and `globstar` matches.
|
||||
Note that an explicit dot in a portion of the pattern will always
|
||||
match dot files.
|
||||
* `nomount` By default, a pattern starting with a forward-slash will be
|
||||
"mounted" onto the root setting, so that a valid filesystem path is
|
||||
returned. Set this flag to disable that behavior.
|
||||
* `mark` Add a `/` character to directory matches. Note that this
|
||||
requires additional stat calls.
|
||||
* `nosort` Don't sort the results.
|
||||
* `stat` Set to true to stat *all* results. This reduces performance
|
||||
somewhat, and is completely unnecessary, unless `readdir` is presumed
|
||||
to be an untrustworthy indicator of file existence. It will cause
|
||||
ELOOP to be triggered one level sooner in the case of cyclical
|
||||
symbolic links.
|
||||
* `silent` When an unusual error is encountered
|
||||
when attempting to read a directory, a warning will be printed to
|
||||
stderr. Set the `silent` option to true to suppress these warnings.
|
||||
* `strict` When an unusual error is encountered
|
||||
when attempting to read a directory, the process will just continue on
|
||||
in search of other matches. Set the `strict` option to raise an error
|
||||
in these cases.
|
||||
* `cache` See `cache` property above. Pass in a previously generated
|
||||
cache object to save some fs calls.
|
||||
* `statCache` A cache of results of filesystem information, to prevent
|
||||
unnecessary stat calls. While it should not normally be necessary to
|
||||
set this, you may pass the statCache from one glob() call to the
|
||||
options object of another, if you know that the filesystem will not
|
||||
change between calls. (See "Race Conditions" below.)
|
||||
* `sync` Perform a synchronous glob search.
|
||||
* `nounique` In some cases, brace-expanded patterns can result in the
|
||||
same file showing up multiple times in the result set. By default,
|
||||
this implementation prevents duplicates in the result set.
|
||||
Set this flag to disable that behavior.
|
||||
* `nonull` Set to never return an empty set, instead returning a set
|
||||
containing the pattern itself. This is the default in glob(3).
|
||||
* `nocase` Perform a case-insensitive match. Note that case-insensitive
|
||||
filesystems will sometimes result in glob returning results that are
|
||||
case-insensitively matched anyway, since readdir and stat will not
|
||||
raise an error.
|
||||
* `debug` Set to enable debug logging in minimatch and glob.
|
||||
* `globDebug` Set to enable debug logging in glob, but not minimatch.
|
||||
|
||||
## Comparisons to other fnmatch/glob implementations
|
||||
|
||||
While strict compliance with the existing standards is a worthwhile
|
||||
goal, some discrepancies exist between node-glob and other
|
||||
implementations, and are intentional.
|
||||
|
||||
If the pattern starts with a `!` character, then it is negated. Set the
|
||||
`nonegate` flag to suppress this behavior, and treat leading `!`
|
||||
characters normally. This is perhaps relevant if you wish to start the
|
||||
pattern with a negative extglob pattern like `!(a|B)`. Multiple `!`
|
||||
characters at the start of a pattern will negate the pattern multiple
|
||||
times.
|
||||
|
||||
If a pattern starts with `#`, then it is treated as a comment, and
|
||||
will not match anything. Use `\#` to match a literal `#` at the
|
||||
start of a line, or set the `nocomment` flag to suppress this behavior.
|
||||
|
||||
The double-star character `**` is supported by default, unless the
|
||||
`noglobstar` flag is set. This is supported in the manner of bsdglob
|
||||
and bash 4.1, where `**` only has special significance if it is the only
|
||||
thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but
|
||||
`a/**b` will not.
|
||||
|
||||
If an escaped pattern has no matches, and the `nonull` flag is set,
|
||||
then glob returns the pattern as-provided, rather than
|
||||
interpreting the character escapes. For example,
|
||||
`glob.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
|
||||
`"*a?"`. This is akin to setting the `nullglob` option in bash, except
|
||||
that it does not resolve escaped pattern characters.
|
||||
|
||||
If brace expansion is not disabled, then it is performed before any
|
||||
other interpretation of the glob pattern. Thus, a pattern like
|
||||
`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
|
||||
**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
|
||||
checked for validity. Since those two are valid, matching proceeds.
|
||||
|
||||
## Windows
|
||||
|
||||
**Please only use forward-slashes in glob expressions.**
|
||||
|
||||
Though windows uses either `/` or `\` as its path separator, only `/`
|
||||
characters are used by this glob implementation. You must use
|
||||
forward-slashes **only** in glob expressions. Back-slashes will always
|
||||
be interpreted as escape characters, not path separators.
|
||||
|
||||
Results from absolute patterns such as `/foo/*` are mounted onto the
|
||||
root setting using `path.join`. On windows, this will by default result
|
||||
in `/foo/*` matching `C:\foo\bar.txt`.
|
||||
|
||||
## Race Conditions
|
||||
|
||||
Glob searching, by its very nature, is susceptible to race conditions,
|
||||
since it relies on directory walking and such.
|
||||
|
||||
As a result, it is possible that a file that exists when glob looks for
|
||||
it may have been deleted or modified by the time it returns the result.
|
||||
|
||||
As part of its internal implementation, this program caches all stat
|
||||
and readdir calls that it makes, in order to cut down on system
|
||||
overhead. However, this also makes it even more susceptible to races,
|
||||
especially if the cache or statCache objects are reused between glob
|
||||
calls.
|
||||
|
||||
Users are thus advised not to use a glob result as a guarantee of
|
||||
filesystem state in the face of rapid changes. For the vast majority
|
||||
of operations, this is never a problem.
|
||||
Generated
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
var Glob = require("../").Glob
|
||||
|
||||
var pattern = "test/a/**/[cg]/../[cg]"
|
||||
console.log(pattern)
|
||||
|
||||
var mg = new Glob(pattern, {mark: true, sync:true}, function (er, matches) {
|
||||
console.log("matches", matches)
|
||||
})
|
||||
console.log("after")
|
||||
Generated
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
var Glob = require("../").Glob
|
||||
|
||||
var pattern = "{./*/*,/*,/usr/local/*}"
|
||||
console.log(pattern)
|
||||
|
||||
var mg = new Glob(pattern, {mark: true}, function (er, matches) {
|
||||
console.log("matches", matches)
|
||||
})
|
||||
console.log("after")
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user