mirror of
https://github.com/apache/cordova-android.git
synced 2026-05-30 00:00:04 +08:00
Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 41ac464aca | |||
| 765a93b3e7 | |||
| 9aa758a1d1 | |||
| bf74f97e7f | |||
| 2bf47422ce | |||
| eaef4d47a2 | |||
| 757a3685f2 | |||
| fd2c3c9857 | |||
| 84477ff212 | |||
| 1d7ccaece6 | |||
| ce2525d4d8 | |||
| 7be9e880c2 | |||
| 7233931681 | |||
| d7e111fb71 | |||
| 2ac191fbb8 | |||
| 088140aca4 | |||
| e08d0671ab | |||
| 7669378c6e | |||
| 1494082a2a | |||
| 233c2bd882 | |||
| 9c4f09a50a | |||
| 89d982a8e4 | |||
| 9d3ee3d56e | |||
| 44421bbc79 | |||
| 320558a782 | |||
| 9ef7ddbf20 | |||
| 603f994f3f | |||
| ada35e0e00 | |||
| fc778006ef | |||
| 11760afddd | |||
| d78ae309f1 | |||
| 73fd9e4dfa | |||
| fb9cf60c41 | |||
| b6a329d479 | |||
| 70bc7b39b7 | |||
| 03777067cd | |||
| f5271431fb | |||
| c30eeee5d8 | |||
| dac02bef8c | |||
| 32edaee3a2 | |||
| ff1c58def4 | |||
| f9372f5578 | |||
| 6afc16c33b | |||
| 74a3d2028f |
@@ -0,0 +1,94 @@
|
||||
* 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
|
||||
+3
-1
@@ -39,5 +39,7 @@ Desktop.ini
|
||||
*.iml
|
||||
.idea
|
||||
npm-debug.log
|
||||
/node_modules
|
||||
/framework/build
|
||||
node_modules/jshint
|
||||
node_modules/promise-matchers
|
||||
node_modules/jasmine-node
|
||||
|
||||
+1
-3
@@ -1,10 +1,8 @@
|
||||
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-23
|
||||
- echo y | android update sdk -u --filter android-22,android-23
|
||||
script:
|
||||
- npm test
|
||||
- npm run test-build
|
||||
|
||||
+29
-1
@@ -19,7 +19,35 @@
|
||||
#
|
||||
-->
|
||||
## Release Notes for Cordova (Android) ##
|
||||
Update these notes using: git log --pretty=format:'* %s' --topo-order --no-merges *remote*/4.1.x...HEAD
|
||||
|
||||
### 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`
|
||||
|
||||
### 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.join(path.resolve(projectPath), 'cordova', 'lib', 'build'));
|
||||
buildModule.prepBuildFiles();
|
||||
var buildModule = require(path.resolve(projectPath, 'cordova/lib/builders/builders'));
|
||||
buildModule.getBuilder('gradle').prepBuildFiles();
|
||||
}
|
||||
|
||||
function copyBuildRules(projectPath) {
|
||||
|
||||
Vendored
+20
-8
@@ -219,6 +219,11 @@ 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;
|
||||
@@ -272,6 +277,11 @@ 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;
|
||||
@@ -431,6 +441,11 @@ 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();
|
||||
};
|
||||
@@ -457,6 +472,10 @@ 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();
|
||||
};
|
||||
@@ -470,20 +489,13 @@ 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';
|
||||
|
||||
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 += JSON.stringify(this._platformJson.root.plugin_metadata, 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.remain;
|
||||
buildOpts.argv = buildOpts.argv.original;
|
||||
|
||||
new Api().build(buildOpts)
|
||||
.catch(function(err) {
|
||||
|
||||
Vendored
+14
-13
@@ -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) {
|
||||
function parseOpts(options, resolvedTarget, projectRoot) {
|
||||
options = options || {};
|
||||
options.argv = nopt({
|
||||
gradle: Boolean,
|
||||
@@ -61,18 +61,18 @@ function parseOpts(options, resolvedTarget) {
|
||||
if (options.nobuild) ret.buildMethod = 'none';
|
||||
|
||||
if (options.argv.versionCode)
|
||||
ret.extraArgs.push('-PcdvVersionCode=' + options.versionCode);
|
||||
ret.extraArgs.push('-PcdvVersionCode=' + options.argv.versionCode);
|
||||
|
||||
if (options.argv.minSdkVersion)
|
||||
ret.extraArgs.push('-PcdvMinSdkVersion=' + options.minSdkVersion);
|
||||
ret.extraArgs.push('-PcdvMinSdkVersion=' + options.argv.minSdkVersion);
|
||||
|
||||
if (options.argv.gradleArg)
|
||||
ret.extraArgs.push(options.gradleArg);
|
||||
ret.extraArgs.push(options.argv.gradleArg);
|
||||
|
||||
var packageArgs = {};
|
||||
|
||||
if (options.argv.keystore)
|
||||
packageArgs.keystore = path.relative(this.root, path.resolve(options.argv.keystore));
|
||||
packageArgs.keystore = path.relative(projectRoot, path.resolve(options.argv.keystore));
|
||||
|
||||
['alias','storePassword','password','keystoreType'].forEach(function (flagName) {
|
||||
if (options.argv[flagName])
|
||||
@@ -88,11 +88,17 @@ function parseOpts(options, resolvedTarget) {
|
||||
throw new Error('Specified build config file does not exist: ' + buildConfig);
|
||||
}
|
||||
events.emit('log', 'Reading build config file: '+ path.resolve(buildConfig));
|
||||
var config = JSON.parse(fs.readFileSync(buildConfig, 'utf8'));
|
||||
var buildjson = fs.readFileSync(buildConfig, 'utf8');
|
||||
//var config = JSON.parse(fs.readFileSync(buildConfig, 'utf8'));
|
||||
var config = JSON.parse(buildjson);
|
||||
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){
|
||||
@@ -120,7 +126,7 @@ function parseOpts(options, resolvedTarget) {
|
||||
* Returns a promise.
|
||||
*/
|
||||
module.exports.runClean = function(options) {
|
||||
var opts = parseOpts(options);
|
||||
var opts = parseOpts(options, null, this.root);
|
||||
var builder = builders.getBuilder(opts.buildMethod);
|
||||
return builder.prepEnv(opts)
|
||||
.then(function() {
|
||||
@@ -141,7 +147,7 @@ module.exports.runClean = function(options) {
|
||||
* information.
|
||||
*/
|
||||
module.exports.run = function(options, optResolvedTarget) {
|
||||
var opts = parseOpts(options, optResolvedTarget);
|
||||
var opts = parseOpts(options, optResolvedTarget, this.root);
|
||||
var builder = builders.getBuilder(opts.buildMethod);
|
||||
var self = this;
|
||||
return builder.prepEnv(opts)
|
||||
@@ -163,11 +169,6 @@ 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()) {
|
||||
if (hasCustomRules(this.root)) {
|
||||
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()) {
|
||||
if (!hasCustomRules(this.root)) {
|
||||
// clean will call check_ant() for us.
|
||||
ret = this.clean(opts);
|
||||
}
|
||||
|
||||
+65
-3
@@ -22,6 +22,7 @@ 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');
|
||||
@@ -55,6 +56,8 @@ 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');
|
||||
@@ -182,9 +185,7 @@ 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 Q().then(function() {
|
||||
return spawn(wrapper, args, {stdio: 'inherit'});
|
||||
});
|
||||
return spawnAndSuppressJavaOptions(wrapper, args);
|
||||
};
|
||||
|
||||
GradleBuilder.prototype.clean = function(opts) {
|
||||
@@ -211,3 +212,64 @@ 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
+18
-5
@@ -89,12 +89,25 @@ module.exports.install = function(target, buildResults) {
|
||||
var pkgName = manifest.getPackageId();
|
||||
var launchName = pkgName + '/.' + manifest.getActivity().getName();
|
||||
events.emit('log', 'Using apk: ' + apk_path);
|
||||
// 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)
|
||||
|
||||
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});
|
||||
});
|
||||
})
|
||||
.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() {
|
||||
|
||||
+67
-31
@@ -23,7 +23,6 @@
|
||||
|
||||
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');
|
||||
@@ -40,6 +39,7 @@ 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,7 +104,8 @@ module.exports.best_image = function() {
|
||||
|
||||
var closest = 9999;
|
||||
var best = images[0];
|
||||
var project_target = check_reqs.get_target().replace('android-', '');
|
||||
// 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-', '');
|
||||
for (var i in images) {
|
||||
var target = images[i].target;
|
||||
if(target) {
|
||||
@@ -146,10 +147,12 @@ 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) {
|
||||
module.exports.start = function(emulator_ID, boot_timeout) {
|
||||
var self = this;
|
||||
|
||||
return Q().then(function() {
|
||||
@@ -162,7 +165,8 @@ module.exports.start = function(emulator_ID) {
|
||||
return best.name;
|
||||
}
|
||||
|
||||
var androidCmd = check_reqs.getAbsoluteAndroidCmd();
|
||||
// Loading check_reqs at run-time to avoid test-time vs run-time directory structure difference issue
|
||||
var androidCmd = require('./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' +
|
||||
@@ -186,14 +190,20 @@ module.exports.start = function(emulator_ID) {
|
||||
|
||||
//wait for emulator to boot up
|
||||
process.stdout.write('Booting up emulator (this may take a while)...');
|
||||
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;
|
||||
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;
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -227,18 +237,25 @@ module.exports.wait_for_emulator = function(uuid) {
|
||||
};
|
||||
|
||||
/*
|
||||
* Waits for the core android process of the emulator to start
|
||||
* 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
|
||||
*/
|
||||
module.exports.wait_for_boot = function(emulator_id) {
|
||||
module.exports.wait_for_boot = function(emulator_id, time_remaining) {
|
||||
var self = this;
|
||||
return Adb.shell(emulator_id, 'ps')
|
||||
.then(function(output) {
|
||||
if (output.match(/android\.process\.acore/)) {
|
||||
return;
|
||||
return true;
|
||||
} else if (time_remaining === 0) {
|
||||
return false;
|
||||
} else {
|
||||
process.stdout.write('.');
|
||||
return Q.delay(3000).then(function() {
|
||||
return self.wait_for_boot(emulator_id);
|
||||
|
||||
// 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);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -321,7 +338,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 Adb.uninstall(target.target, pkgName)
|
||||
return Q.when()
|
||||
.then(function() {
|
||||
|
||||
var apk_path = build.findBestApkForArchitecture(buildResults, target.arch);
|
||||
@@ -334,28 +351,47 @@ module.exports.install = function(givenTarget, buildResults) {
|
||||
events.emit('log', 'Using apk: ' + apk_path);
|
||||
events.emit('verbose', 'Installing app on emulator...');
|
||||
|
||||
function exec(command, opts) {
|
||||
// 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 + '"';
|
||||
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);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var retriedInstall = retry.retryPromise(
|
||||
NUM_INSTALL_RETRIES,
|
||||
exec, 'adb -s ' + target.target + ' install -r "' + apk_path + '"', execOptions
|
||||
);
|
||||
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;
|
||||
|
||||
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));
|
||||
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');
|
||||
});
|
||||
});
|
||||
// unlock screen
|
||||
|
||||
Vendored
+16
-6
@@ -27,6 +27,19 @@ 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
|
||||
@@ -40,10 +53,7 @@ var path = require('path'),
|
||||
module.exports.run = function(runOptions) {
|
||||
|
||||
var self = this;
|
||||
|
||||
var install_target = runOptions.device ? '--device' :
|
||||
runOptions.emulator ? '--emulator' :
|
||||
runOptions.target;
|
||||
var install_target = getInstallTarget(runOptions);
|
||||
|
||||
return Q()
|
||||
.then(function() {
|
||||
@@ -116,8 +126,8 @@ var path = require('path'),
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.help = function(args) {
|
||||
console.log('Usage: ' + path.relative(process.cwd(), args[1]) + ' [options]');
|
||||
module.exports.help = function() {
|
||||
console.log('Usage: ' + path.relative(process.cwd(), process.argv[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.0.0-dev";
|
||||
var VERSION = "5.1.1";
|
||||
|
||||
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.Black.NoTitleBar"
|
||||
android:theme="@android:style/Theme.DeviceDefault.NoActionBar"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale">
|
||||
<intent-filter android:label="@string/launcher_name">
|
||||
|
||||
+227
-36
@@ -1,5 +1,5 @@
|
||||
// Platform: android
|
||||
// a83e94b489774dc8e514671e81c6154eda650af1
|
||||
// c517ca811b4948b630e0b74dbae6c9637939da24
|
||||
/*
|
||||
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 = '4.2.0-dev';
|
||||
var PLATFORM_VERSION_BUILD_LABEL = '5.1.1';
|
||||
// file: src/scripts/require.js
|
||||
|
||||
/*jshint -W079 */
|
||||
@@ -101,7 +101,9 @@ if (typeof module === "object" && typeof require === "function") {
|
||||
// file: src/cordova.js
|
||||
define("cordova", function(require, exports, module) {
|
||||
|
||||
if(window.cordova){
|
||||
// Workaround for Windows 10 in hosted environment case
|
||||
// http://www.w3.org/html/wg/drafts/html/master/browsers.html#named-access-on-the-window-object
|
||||
if (window.cordova && !(window.cordova instanceof HTMLElement)) {
|
||||
throw new Error("cordova already defined");
|
||||
}
|
||||
|
||||
@@ -328,7 +330,7 @@ module.exports = cordova;
|
||||
|
||||
});
|
||||
|
||||
// file: D:/cordova/cordova-android/cordova-js-src/android/nativeapiprovider.js
|
||||
// file: /Users/steveng/repo/cordova/cordova-android/cordova-js-src/android/nativeapiprovider.js
|
||||
define("cordova/android/nativeapiprovider", function(require, exports, module) {
|
||||
|
||||
/**
|
||||
@@ -351,7 +353,7 @@ module.exports = {
|
||||
|
||||
});
|
||||
|
||||
// file: D:/cordova/cordova-android/cordova-js-src/android/promptbasednativeapi.js
|
||||
// file: /Users/steveng/repo/cordova/cordova-android/cordova-js-src/android/promptbasednativeapi.js
|
||||
define("cordova/android/promptbasednativeapi", function(require, exports, module) {
|
||||
|
||||
/**
|
||||
@@ -376,7 +378,6 @@ module.exports = {
|
||||
// file: src/common/argscheck.js
|
||||
define("cordova/argscheck", function(require, exports, module) {
|
||||
|
||||
var exec = require('cordova/exec');
|
||||
var utils = require('cordova/utils');
|
||||
|
||||
var moduleExports = module.exports;
|
||||
@@ -861,7 +862,7 @@ module.exports = channel;
|
||||
|
||||
});
|
||||
|
||||
// file: D:/cordova/cordova-android/cordova-js-src/exec.js
|
||||
// file: /Users/steveng/repo/cordova/cordova-android/cordova-js-src/exec.js
|
||||
define("cordova/exec", function(require, exports, module) {
|
||||
|
||||
/**
|
||||
@@ -1230,6 +1231,7 @@ if (!window.console.warn) {
|
||||
// Register pause, resume and deviceready channels as events on document.
|
||||
channel.onPause = cordova.addDocumentEventHandler('pause');
|
||||
channel.onResume = cordova.addDocumentEventHandler('resume');
|
||||
channel.onActivated = cordova.addDocumentEventHandler('activated');
|
||||
channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
|
||||
|
||||
// Listen for DOMContentLoaded and notify our channel subscribers.
|
||||
@@ -1291,10 +1293,12 @@ define("cordova/init_b", function(require, exports, module) {
|
||||
|
||||
var channel = require('cordova/channel');
|
||||
var cordova = require('cordova');
|
||||
var modulemapper = require('cordova/modulemapper');
|
||||
var platform = require('cordova/platform');
|
||||
var pluginloader = require('cordova/pluginloader');
|
||||
var utils = require('cordova/utils');
|
||||
|
||||
var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady];
|
||||
var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady];
|
||||
|
||||
// setting exec
|
||||
cordova.exec = require('cordova/exec');
|
||||
@@ -1357,6 +1361,7 @@ if (!window.console.warn) {
|
||||
// Register pause, resume and deviceready channels as events on document.
|
||||
channel.onPause = cordova.addDocumentEventHandler('pause');
|
||||
channel.onResume = cordova.addDocumentEventHandler('resume');
|
||||
channel.onActivated = cordova.addDocumentEventHandler('activated');
|
||||
channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
|
||||
|
||||
// Listen for DOMContentLoaded and notify our channel subscribers.
|
||||
@@ -1378,10 +1383,19 @@ if (window._nativeReady) {
|
||||
// Call the platform-specific initialization.
|
||||
platform.bootstrap && platform.bootstrap();
|
||||
|
||||
// Wrap in a setTimeout to support the use-case of having plugin JS appended to cordova.js.
|
||||
// The delay allows the attached modules to be defined before the plugin loader looks for them.
|
||||
setTimeout(function() {
|
||||
pluginloader.load(function() {
|
||||
channel.onPluginsReady.fire();
|
||||
});
|
||||
}, 0);
|
||||
|
||||
/**
|
||||
* Create all cordova objects once native side is ready.
|
||||
*/
|
||||
channel.join(function() {
|
||||
modulemapper.mapModules(window);
|
||||
|
||||
platform.initialize && platform.initialize();
|
||||
|
||||
@@ -1500,9 +1514,109 @@ exports.reset();
|
||||
|
||||
});
|
||||
|
||||
// file: D:/cordova/cordova-android/cordova-js-src/platform.js
|
||||
// file: src/common/modulemapper_b.js
|
||||
define("cordova/modulemapper_b", function(require, exports, module) {
|
||||
|
||||
var builder = require('cordova/builder'),
|
||||
symbolList = [],
|
||||
deprecationMap;
|
||||
|
||||
exports.reset = function() {
|
||||
symbolList = [];
|
||||
deprecationMap = {};
|
||||
};
|
||||
|
||||
function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
|
||||
symbolList.push(strategy, moduleName, symbolPath);
|
||||
if (opt_deprecationMessage) {
|
||||
deprecationMap[symbolPath] = opt_deprecationMessage;
|
||||
}
|
||||
}
|
||||
|
||||
// Note: Android 2.3 does have Function.bind().
|
||||
exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) {
|
||||
addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
|
||||
};
|
||||
|
||||
exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) {
|
||||
addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
|
||||
};
|
||||
|
||||
exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) {
|
||||
addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
|
||||
};
|
||||
|
||||
exports.runs = function(moduleName) {
|
||||
addEntry('r', moduleName, null);
|
||||
};
|
||||
|
||||
function prepareNamespace(symbolPath, context) {
|
||||
if (!symbolPath) {
|
||||
return context;
|
||||
}
|
||||
var parts = symbolPath.split('.');
|
||||
var cur = context;
|
||||
for (var i = 0, part; part = parts[i]; ++i) {
|
||||
cur = cur[part] = cur[part] || {};
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
|
||||
exports.mapModules = function(context) {
|
||||
var origSymbols = {};
|
||||
context.CDV_origSymbols = origSymbols;
|
||||
for (var i = 0, len = symbolList.length; i < len; i += 3) {
|
||||
var strategy = symbolList[i];
|
||||
var moduleName = symbolList[i + 1];
|
||||
var module = require(moduleName);
|
||||
// <runs/>
|
||||
if (strategy == 'r') {
|
||||
continue;
|
||||
}
|
||||
var symbolPath = symbolList[i + 2];
|
||||
var lastDot = symbolPath.lastIndexOf('.');
|
||||
var namespace = symbolPath.substr(0, lastDot);
|
||||
var lastName = symbolPath.substr(lastDot + 1);
|
||||
|
||||
var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null;
|
||||
var parentObj = prepareNamespace(namespace, context);
|
||||
var target = parentObj[lastName];
|
||||
|
||||
if (strategy == 'm' && target) {
|
||||
builder.recursiveMerge(target, module);
|
||||
} else if ((strategy == 'd' && !target) || (strategy != 'd')) {
|
||||
if (!(symbolPath in origSymbols)) {
|
||||
origSymbols[symbolPath] = target;
|
||||
}
|
||||
builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.getOriginalSymbol = function(context, symbolPath) {
|
||||
var origSymbols = context.CDV_origSymbols;
|
||||
if (origSymbols && (symbolPath in origSymbols)) {
|
||||
return origSymbols[symbolPath];
|
||||
}
|
||||
var parts = symbolPath.split('.');
|
||||
var obj = context;
|
||||
for (var i = 0; i < parts.length; ++i) {
|
||||
obj = obj && obj[parts[i]];
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
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() {
|
||||
@@ -1542,6 +1656,19 @@ 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() {
|
||||
@@ -1563,12 +1690,30 @@ 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);
|
||||
}
|
||||
@@ -1576,7 +1721,7 @@ function onMessageFromNative(msg) {
|
||||
|
||||
});
|
||||
|
||||
// file: D:/cordova/cordova-android/cordova-js-src/plugin/android/app.js
|
||||
// file: /Users/steveng/repo/cordova/cordova-android/cordova-js-src/plugin/android/app.js
|
||||
define("cordova/plugin/android/app", function(require, exports, module) {
|
||||
|
||||
var exec = require('cordova/exec');
|
||||
@@ -1779,6 +1924,54 @@ exports.load = function(callback) {
|
||||
};
|
||||
|
||||
|
||||
});
|
||||
|
||||
// file: src/common/pluginloader_b.js
|
||||
define("cordova/pluginloader_b", function(require, exports, module) {
|
||||
|
||||
var modulemapper = require('cordova/modulemapper');
|
||||
|
||||
// Handler for the cordova_plugins.js content.
|
||||
// See plugman's plugin_loader.js for the details of this object.
|
||||
function handlePluginsObject(moduleList) {
|
||||
// if moduleList is not defined or empty, we've nothing to do
|
||||
if (!moduleList || !moduleList.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Loop through all the modules and then through their clobbers and merges.
|
||||
for (var i = 0, module; module = moduleList[i]; i++) {
|
||||
if (module.clobbers && module.clobbers.length) {
|
||||
for (var j = 0; j < module.clobbers.length; j++) {
|
||||
modulemapper.clobbers(module.id, module.clobbers[j]);
|
||||
}
|
||||
}
|
||||
|
||||
if (module.merges && module.merges.length) {
|
||||
for (var k = 0; k < module.merges.length; k++) {
|
||||
modulemapper.merges(module.id, module.merges[k]);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, if runs is truthy we want to simply require() the module.
|
||||
if (module.runs) {
|
||||
modulemapper.runs(module.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Loads all plugins' js-modules. Plugin loading is syncronous in browserified bundle
|
||||
// but the method accepts callback to be compatible with non-browserify flow.
|
||||
// onDeviceReady is blocked on onPluginsReady. onPluginsReady is fired when there are
|
||||
// no plugins to load, or they are all done.
|
||||
exports.load = function(callback) {
|
||||
var moduleList = require("cordova/plugin_list");
|
||||
handlePluginsObject(moduleList);
|
||||
|
||||
callback();
|
||||
};
|
||||
|
||||
|
||||
});
|
||||
|
||||
// file: src/common/urlutil.js
|
||||
@@ -1860,15 +2053,14 @@ utils.typeName = function(val) {
|
||||
/**
|
||||
* Returns an indication of whether the argument is an array or not
|
||||
*/
|
||||
utils.isArray = function(a) {
|
||||
return utils.typeName(a) == 'Array';
|
||||
};
|
||||
utils.isArray = Array.isArray ||
|
||||
function(a) {return utils.typeName(a) == 'Array';};
|
||||
|
||||
/**
|
||||
* Returns an indication of whether the argument is a Date or not
|
||||
*/
|
||||
utils.isDate = function(d) {
|
||||
return utils.typeName(d) == 'Date';
|
||||
return (d instanceof Date);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1902,17 +2094,25 @@ utils.clone = function(obj) {
|
||||
* Returns a wrapped version of the function
|
||||
*/
|
||||
utils.close = function(context, func, params) {
|
||||
if (typeof params == 'undefined') {
|
||||
return function() {
|
||||
return func.apply(context, arguments);
|
||||
};
|
||||
} else {
|
||||
return function() {
|
||||
return func.apply(context, params);
|
||||
};
|
||||
}
|
||||
return function() {
|
||||
var args = params || arguments;
|
||||
return func.apply(context, args);
|
||||
};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
function UUIDcreatePart(length) {
|
||||
var uuidpart = "";
|
||||
for (var i=0; i<length; i++) {
|
||||
var uuidchar = parseInt((Math.random() * 256), 10).toString(16);
|
||||
if (uuidchar.length == 1) {
|
||||
uuidchar = "0" + uuidchar;
|
||||
}
|
||||
uuidpart += uuidchar;
|
||||
}
|
||||
return uuidpart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a UUID
|
||||
*/
|
||||
@@ -1924,6 +2124,7 @@ utils.createUUID = function() {
|
||||
UUIDcreatePart(6);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Extends a child object from a parent object using classical inheritance
|
||||
* pattern.
|
||||
@@ -1933,6 +2134,7 @@ utils.extend = (function() {
|
||||
var F = function() {};
|
||||
// extend Child from Parent
|
||||
return function(Child, Parent) {
|
||||
|
||||
F.prototype = Parent.prototype;
|
||||
Child.prototype = new F();
|
||||
Child.__super__ = Parent.prototype;
|
||||
@@ -1952,18 +2154,7 @@ utils.alert = function(msg) {
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
function UUIDcreatePart(length) {
|
||||
var uuidpart = "";
|
||||
for (var i=0; i<length; i++) {
|
||||
var uuidchar = parseInt((Math.random() * 256), 10).toString(16);
|
||||
if (uuidchar.length == 1) {
|
||||
uuidchar = "0" + uuidchar;
|
||||
}
|
||||
uuidpart += uuidchar;
|
||||
}
|
||||
return uuidpart;
|
||||
}
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
@@ -30,20 +30,10 @@ 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
|
||||
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+'
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:1.5.0'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allow plugins to declare Maven dependencies via build-extras.gradle.
|
||||
repositories {
|
||||
@@ -51,7 +41,7 @@ repositories {
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '2.2.1'
|
||||
gradleVersion = '2.8'
|
||||
}
|
||||
|
||||
// Configuration properties. Set these via environment variables, build-extras.gradle, or gradle.properties.
|
||||
@@ -173,11 +163,17 @@ 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
+35
-1
@@ -19,6 +19,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
// The last resume event that was received that had the result of a plugin call.
|
||||
var lastResumeEvent = null;
|
||||
|
||||
module.exports = {
|
||||
id: 'android',
|
||||
bootstrap: function() {
|
||||
@@ -58,6 +61,19 @@ 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() {
|
||||
@@ -79,12 +95,30 @@ 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.0.0+'
|
||||
classpath 'com.android.tools.build:gradle:1.5.0'
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -128,6 +128,14 @@ 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
|
||||
@@ -179,6 +187,7 @@ 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;
|
||||
private boolean finished;
|
||||
protected boolean finished;
|
||||
private int changingThreads;
|
||||
|
||||
public CallbackContext(String callbackId, CordovaWebView webView) {
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
package org.apache.cordova;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
@@ -28,6 +27,7 @@ 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,6 +46,8 @@ 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());
|
||||
@@ -95,12 +97,31 @@ public class CordovaInterfaceImpl implements CordovaInterface {
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches any pending onActivityResult callbacks.
|
||||
* Dispatches any pending onActivityResult callbacks and sends the resume event if the
|
||||
* Activity was destroyed by the OS.
|
||||
*/
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +136,10 @@ 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;
|
||||
@@ -126,7 +151,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;
|
||||
}
|
||||
|
||||
@@ -147,6 +172,10 @@ public class CordovaInterfaceImpl implements CordovaInterface {
|
||||
String serviceName = activityResultCallback.getServiceName();
|
||||
outState.putString("callbackService", serviceName);
|
||||
}
|
||||
if(pluginManager != null){
|
||||
outState.putBundle("plugin", pluginManager.onSaveInstanceState());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -154,6 +183,8 @@ public class CordovaInterfaceImpl implements CordovaInterface {
|
||||
*/
|
||||
public void restoreInstanceState(Bundle savedInstanceState) {
|
||||
initCallbackService = savedInstanceState.getString("callbackService");
|
||||
savedPluginState = savedInstanceState.getBundle("plugin");
|
||||
activityWasDestroyed = true;
|
||||
}
|
||||
|
||||
private static class ActivityResultHolder {
|
||||
@@ -209,6 +240,4 @@ public class CordovaInterfaceImpl implements CordovaInterface {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ 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;
|
||||
@@ -77,7 +78,7 @@ public class CordovaPlugin {
|
||||
public String getServiceName() {
|
||||
return serviceName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Executes the request.
|
||||
*
|
||||
@@ -174,6 +175,29 @@ 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.
|
||||
*
|
||||
@@ -323,7 +347,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.
|
||||
@@ -332,14 +356,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.0.0-dev";
|
||||
public static final String CORDOVA_VERSION = "5.1.1";
|
||||
|
||||
void init(CordovaInterface cordova, List<PluginEntry> pluginEntries, CordovaPreferences preferences);
|
||||
|
||||
|
||||
@@ -354,6 +354,7 @@ 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);
|
||||
@@ -445,7 +446,10 @@ public class CordovaWebViewImpl implements CordovaWebView {
|
||||
// Resume JavaScript timers. This affects all webviews within the app!
|
||||
engine.setPaused(false);
|
||||
this.pluginManager.onResume(keepRunning);
|
||||
// To be the same as other platforms, fire this event only when resumed after a "pause".
|
||||
|
||||
// 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
|
||||
if (hasPausedEver) {
|
||||
sendJavascriptEvent("resume");
|
||||
}
|
||||
|
||||
@@ -19,10 +19,6 @@
|
||||
|
||||
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;
|
||||
@@ -45,6 +41,8 @@ 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.
|
||||
@@ -112,7 +110,13 @@ class CoreAndroid extends CordovaPlugin {
|
||||
this.exitApp();
|
||||
}
|
||||
else if (action.equals("messageChannel")) {
|
||||
messageChannel = callbackContext;
|
||||
synchronized(messageChannelLock) {
|
||||
messageChannel = callbackContext;
|
||||
if (pendingResume != null) {
|
||||
sendEventMessage(pendingResume);
|
||||
pendingResume = null;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -248,6 +252,9 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -313,10 +320,13 @@ class CoreAndroid extends CordovaPlugin {
|
||||
} catch (JSONException e) {
|
||||
LOG.e(TAG, "Failed to create event message", e);
|
||||
}
|
||||
PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, obj);
|
||||
pluginResult.setKeepCallback(true);
|
||||
sendEventMessage(new PluginResult(PluginResult.Status.OK, obj));
|
||||
}
|
||||
|
||||
private void sendEventMessage(PluginResult payload) {
|
||||
payload.setKeepCallback(true);
|
||||
if (messageChannel != null) {
|
||||
messageChannel.sendPluginResult(pluginResult);
|
||||
messageChannel.sendPluginResult(payload);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,4 +338,23 @@ 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,6 +26,7 @@ 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;
|
||||
|
||||
@@ -511,4 +512,16 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
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
@@ -0,0 +1 @@
|
||||
../nopt/bin/nopt.js
|
||||
+1
@@ -0,0 +1 @@
|
||||
../semver/bin/semver
|
||||
+1
@@ -0,0 +1 @@
|
||||
../shelljs/bin/shjs
|
||||
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
+56
-30
@@ -1,48 +1,74 @@
|
||||
{
|
||||
"name": "abbrev",
|
||||
"version": "1.0.7",
|
||||
"description": "Like ruby's abbrev module, but in js",
|
||||
"_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": {
|
||||
"name": "Isaac Z. Schlueter",
|
||||
"email": "i@izs.me"
|
||||
"email": "i@izs.me",
|
||||
"name": "Isaac Z. Schlueter"
|
||||
},
|
||||
"main": "abbrev.js",
|
||||
"scripts": {
|
||||
"test": "tap test.js --cov"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+ssh://git@github.com/isaacs/abbrev-js.git"
|
||||
},
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"tap": "^1.2.0"
|
||||
},
|
||||
"gitHead": "821d09ce7da33627f91bbd8ed631497ed6f760c2",
|
||||
"bugs": {
|
||||
"url": "https://github.com/isaacs/abbrev-js/issues"
|
||||
},
|
||||
"homepage": "https://github.com/isaacs/abbrev-js#readme",
|
||||
"_id": "abbrev@1.0.7",
|
||||
"_shasum": "5b6035b2ee9d4fb5cf859f08a9be81b208491843",
|
||||
"_from": "abbrev@>=1.0.0 <2.0.0",
|
||||
"_npmVersion": "2.10.1",
|
||||
"_nodeVersion": "2.0.1",
|
||||
"_npmUser": {
|
||||
"name": "isaacs",
|
||||
"email": "isaacs@npmjs.com"
|
||||
"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"
|
||||
}
|
||||
],
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.7.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
"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
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"laxcomma": true,
|
||||
"asi": true
|
||||
}
|
||||
Generated
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
|
||||
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
|
||||
+3
-2
@@ -1,5 +1,6 @@
|
||||
Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
|
||||
All rights reserved.
|
||||
(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
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
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
@@ -0,0 +1,16 @@
|
||||
#!/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
@@ -0,0 +1,15 @@
|
||||
#!/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
@@ -0,0 +1,32 @@
|
||||
#!/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
@@ -0,0 +1,87 @@
|
||||
#!/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
@@ -0,0 +1,405 @@
|
||||
|
||||
/**
|
||||
* 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
@@ -0,0 +1,71 @@
|
||||
|
||||
/**
|
||||
* 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
@@ -0,0 +1,85 @@
|
||||
{
|
||||
"_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"
|
||||
}
|
||||
Generated
Vendored
+12
-9
@@ -1,18 +1,21 @@
|
||||
This software is released under the MIT license:
|
||||
(MIT)
|
||||
|
||||
Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
|
||||
|
||||
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.
|
||||
+9
@@ -47,6 +47,15 @@ If there's no match, `undefined` will be returned.
|
||||
|
||||
If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `['{', 'a', '']`.
|
||||
|
||||
### var r = balanced.range(a, b, str)
|
||||
|
||||
For the first non-nested matching pair of `a` and `b` in `str`, return an
|
||||
array with indexes: `[ <a index>, <b index> ]`.
|
||||
|
||||
If there's no match, `undefined` will be returned.
|
||||
|
||||
If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `[ 1, 3 ]`.
|
||||
|
||||
## Installation
|
||||
|
||||
With [npm](https://npmjs.org) do:
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
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;
|
||||
}
|
||||
+79
-54
@@ -1,73 +1,98 @@
|
||||
{
|
||||
"name": "balanced-match",
|
||||
"description": "Match balanced character pairs, like \"{\" and \"}\"",
|
||||
"version": "0.2.1",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/juliangruber/balanced-match.git"
|
||||
},
|
||||
"homepage": "https://github.com/juliangruber/balanced-match",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "make test"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"tape": "~1.1.1"
|
||||
},
|
||||
"keywords": [
|
||||
"match",
|
||||
"regexp",
|
||||
"test",
|
||||
"balanced",
|
||||
"parse"
|
||||
"_args": [
|
||||
[
|
||||
"balanced-match@^0.3.0",
|
||||
"/Users/steveng/repo/cordova/cordova-android/node_modules/brace-expansion"
|
||||
]
|
||||
],
|
||||
"_from": "balanced-match@>=0.3.0 <0.4.0",
|
||||
"_id": "balanced-match@0.3.0",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/balanced-match",
|
||||
"_nodeVersion": "4.2.1",
|
||||
"_npmUser": {
|
||||
"email": "julian@juliangruber.com",
|
||||
"name": "juliangruber"
|
||||
},
|
||||
"_npmVersion": "2.14.7",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "balanced-match",
|
||||
"raw": "balanced-match@^0.3.0",
|
||||
"rawSpec": "^0.3.0",
|
||||
"scope": null,
|
||||
"spec": ">=0.3.0 <0.4.0",
|
||||
"type": "range"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/brace-expansion"
|
||||
],
|
||||
"_resolved": "http://registry.npmjs.org/balanced-match/-/balanced-match-0.3.0.tgz",
|
||||
"_shasum": "a91cdd1ebef1a86659e70ff4def01625fc2d6756",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "balanced-match@^0.3.0",
|
||||
"_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/brace-expansion",
|
||||
"author": {
|
||||
"name": "Julian Gruber",
|
||||
"email": "mail@juliangruber.com",
|
||||
"name": "Julian Gruber",
|
||||
"url": "http://juliangruber.com"
|
||||
},
|
||||
"license": "MIT",
|
||||
"testling": {
|
||||
"files": "test/*.js",
|
||||
"browsers": [
|
||||
"ie/8..latest",
|
||||
"firefox/20..latest",
|
||||
"firefox/nightly",
|
||||
"chrome/25..latest",
|
||||
"chrome/canary",
|
||||
"opera/12..latest",
|
||||
"opera/next",
|
||||
"safari/5.1..latest",
|
||||
"ipad/6.0..latest",
|
||||
"iphone/6.0..latest",
|
||||
"android-browser/4.2..latest"
|
||||
]
|
||||
},
|
||||
"gitHead": "d743dd31d7376e0fcf99392a4be7227f2e99bf5d",
|
||||
"bugs": {
|
||||
"url": "https://github.com/juliangruber/balanced-match/issues"
|
||||
},
|
||||
"_id": "balanced-match@0.2.1",
|
||||
"_shasum": "7bc658b4bed61eee424ad74f75f5c3e2c4df3cc7",
|
||||
"_from": "balanced-match@>=0.2.0 <0.3.0",
|
||||
"_npmVersion": "2.14.7",
|
||||
"_nodeVersion": "4.2.1",
|
||||
"_npmUser": {
|
||||
"name": "juliangruber",
|
||||
"email": "julian@juliangruber.com"
|
||||
"dependencies": {},
|
||||
"description": "Match balanced character pairs, like \"{\" and \"}\"",
|
||||
"devDependencies": {
|
||||
"tape": "~4.2.2"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "7bc658b4bed61eee424ad74f75f5c3e2c4df3cc7",
|
||||
"tarball": "http://registry.npmjs.org/balanced-match/-/balanced-match-0.2.1.tgz"
|
||||
"shasum": "a91cdd1ebef1a86659e70ff4def01625fc2d6756",
|
||||
"tarball": "http://registry.npmjs.org/balanced-match/-/balanced-match-0.3.0.tgz"
|
||||
},
|
||||
"gitHead": "a7114b0986554787e90b7ac595a043ca75ea77e5",
|
||||
"homepage": "https://github.com/juliangruber/balanced-match",
|
||||
"keywords": [
|
||||
"balanced",
|
||||
"match",
|
||||
"parse",
|
||||
"regexp",
|
||||
"test"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "juliangruber",
|
||||
"email": "julian@juliangruber.com"
|
||||
}
|
||||
],
|
||||
"directories": {},
|
||||
"_resolved": "http://registry.npmjs.org/balanced-match/-/balanced-match-0.2.1.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
"name": "balanced-match",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/juliangruber/balanced-match.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "make test"
|
||||
},
|
||||
"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": "0.3.0"
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
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();
|
||||
});
|
||||
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
+9
-6
@@ -7,18 +7,21 @@ var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||
? Uint8Array
|
||||
: Array
|
||||
|
||||
var ZERO = '0'.charCodeAt(0)
|
||||
var PLUS = '+'.charCodeAt(0)
|
||||
var SLASH = '/'.charCodeAt(0)
|
||||
var NUMBER = '0'.charCodeAt(0)
|
||||
var LOWER = 'a'.charCodeAt(0)
|
||||
var UPPER = 'A'.charCodeAt(0)
|
||||
var PLUS_URL_SAFE = '-'.charCodeAt(0)
|
||||
var SLASH_URL_SAFE = '_'.charCodeAt(0)
|
||||
|
||||
function decode (elt) {
|
||||
var code = elt.charCodeAt(0)
|
||||
if (code === PLUS)
|
||||
if (code === PLUS ||
|
||||
code === PLUS_URL_SAFE)
|
||||
return 62 // '+'
|
||||
if (code === SLASH)
|
||||
if (code === SLASH ||
|
||||
code === SLASH_URL_SAFE)
|
||||
return 63 // '/'
|
||||
if (code < NUMBER)
|
||||
return -1 //no match
|
||||
@@ -116,6 +119,6 @@ var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||
return output
|
||||
}
|
||||
|
||||
module.exports.toByteArray = b64ToByteArray
|
||||
module.exports.fromByteArray = uint8ToBase64
|
||||
}())
|
||||
exports.toByteArray = b64ToByteArray
|
||||
exports.fromByteArray = uint8ToBase64
|
||||
}(typeof exports === 'undefined' ? (this.base64js = {}) : exports))
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
{
|
||||
"_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"
|
||||
}
|
||||
Generated
Vendored
+2
-3
@@ -10,8 +10,7 @@ var test = require('tape'),
|
||||
'sup',
|
||||
'sup?',
|
||||
'sup?!'
|
||||
],
|
||||
res;
|
||||
];
|
||||
|
||||
test('convert to base64 and back', function (t) {
|
||||
t.plan(checks.length);
|
||||
@@ -49,4 +48,4 @@ function map (arr, callback) {
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
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
@@ -0,0 +1,506 @@
|
||||
# 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
@@ -0,0 +1,100 @@
|
||||
{
|
||||
"_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"
|
||||
}
|
||||
Generated
Vendored
Generated
Vendored
Generated
Vendored
+21
-1
@@ -3,6 +3,7 @@
|
||||
// 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
|
||||
@@ -138,9 +139,28 @@ 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 < exports.maxObjectSize) {
|
||||
if (length > 4) {
|
||||
var data = buffer.slice(offset + 1, offset + 1 + length);
|
||||
var str = bufferToHexString(data);
|
||||
return bigInt(str, 16);
|
||||
} 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.");
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
{
|
||||
"_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
@@ -0,0 +1,10 @@
|
||||
<?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
@@ -0,0 +1,159 @@
|
||||
'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.
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
+1
-1
@@ -99,7 +99,7 @@ function expand(str, isTop) {
|
||||
var isOptions = /^(.*,)+(.+)?$/.test(m.body);
|
||||
if (!isSequence && !isOptions) {
|
||||
// {a},b}
|
||||
if (m.post.match(/,.*}/)) {
|
||||
if (m.post.match(/,.*\}/)) {
|
||||
str = m.pre + '{' + m.body + escClose + m.post;
|
||||
return expand(str);
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
{
|
||||
"_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"
|
||||
}
|
||||
Generated
Vendored
Generated
Vendored
Generated
Vendored
+90
-64
@@ -1,83 +1,109 @@
|
||||
{
|
||||
"name": "concat-map",
|
||||
"description": "concatenative mapdashery",
|
||||
"version": "0.0.1",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/substack/node-concat-map.git"
|
||||
},
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
"concat",
|
||||
"concatMap",
|
||||
"map",
|
||||
"functional",
|
||||
"higher-order"
|
||||
"_args": [
|
||||
[
|
||||
"concat-map@0.0.1",
|
||||
"/Users/steveng/repo/cordova/cordova-android/node_modules/brace-expansion"
|
||||
]
|
||||
],
|
||||
"directories": {
|
||||
"example": "example",
|
||||
"test": "test"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape test/*.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tape": "~2.4.0"
|
||||
},
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
"name": "James Halliday",
|
||||
"_from": "concat-map@0.0.1",
|
||||
"_id": "concat-map@0.0.1",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/concat-map",
|
||||
"_npmUser": {
|
||||
"email": "mail@substack.net",
|
||||
"url": "http://substack.net"
|
||||
"name": "substack"
|
||||
},
|
||||
"testling": {
|
||||
"files": "test/*.js",
|
||||
"browsers": {
|
||||
"ie": [
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9
|
||||
],
|
||||
"ff": [
|
||||
3.5,
|
||||
10,
|
||||
15
|
||||
],
|
||||
"chrome": [
|
||||
10,
|
||||
22
|
||||
],
|
||||
"safari": [
|
||||
5.1
|
||||
],
|
||||
"opera": [
|
||||
12
|
||||
]
|
||||
}
|
||||
"_npmVersion": "1.3.21",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "concat-map",
|
||||
"raw": "concat-map@0.0.1",
|
||||
"rawSpec": "0.0.1",
|
||||
"scope": null,
|
||||
"spec": "0.0.1",
|
||||
"type": "version"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/brace-expansion"
|
||||
],
|
||||
"_resolved": "http://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"_shasum": "d8a96bd77fd68df7793a73036a3ba0d5405d477b",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "concat-map@0.0.1",
|
||||
"_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/brace-expansion",
|
||||
"author": {
|
||||
"email": "mail@substack.net",
|
||||
"name": "James Halliday",
|
||||
"url": "http://substack.net"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/substack/node-concat-map/issues"
|
||||
},
|
||||
"homepage": "https://github.com/substack/node-concat-map",
|
||||
"_id": "concat-map@0.0.1",
|
||||
"dependencies": {},
|
||||
"description": "concatenative mapdashery",
|
||||
"devDependencies": {
|
||||
"tape": "~2.4.0"
|
||||
},
|
||||
"directories": {
|
||||
"example": "example",
|
||||
"test": "test"
|
||||
},
|
||||
"dist": {
|
||||
"shasum": "d8a96bd77fd68df7793a73036a3ba0d5405d477b",
|
||||
"tarball": "http://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
|
||||
},
|
||||
"_from": "concat-map@0.0.1",
|
||||
"_npmVersion": "1.3.21",
|
||||
"_npmUser": {
|
||||
"name": "substack",
|
||||
"email": "mail@substack.net"
|
||||
},
|
||||
"homepage": "https://github.com/substack/node-concat-map",
|
||||
"keywords": [
|
||||
"concat",
|
||||
"concatMap",
|
||||
"functional",
|
||||
"higher-order",
|
||||
"map"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "substack",
|
||||
"email": "mail@substack.net"
|
||||
}
|
||||
],
|
||||
"_shasum": "d8a96bd77fd68df7793a73036a3ba0d5405d477b",
|
||||
"_resolved": "http://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
"name": "concat-map",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/substack/node-concat-map.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape test/*.js"
|
||||
},
|
||||
"testling": {
|
||||
"browsers": {
|
||||
"chrome": [
|
||||
10,
|
||||
22
|
||||
],
|
||||
"ff": [
|
||||
10,
|
||||
15,
|
||||
3.5
|
||||
],
|
||||
"ie": [
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9
|
||||
],
|
||||
"opera": [
|
||||
12
|
||||
],
|
||||
"safari": [
|
||||
5.1
|
||||
]
|
||||
},
|
||||
"files": "test/*.js"
|
||||
},
|
||||
"version": "0.0.1"
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
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,6 +107,10 @@ 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,6 +20,14 @@
|
||||
-->
|
||||
# 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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user