You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by st...@apache.org on 2017/05/01 21:17:20 UTC
[38/63] [abbrv] cordova-lib git commit: CB-11242: updated tests and
fixtures
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07bed560/cordova-lib/spec-plugman/projects/android/cordova/node_modules/brace-expansion/package.json
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android/cordova/node_modules/brace-expansion/package.json b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/brace-expansion/package.json
new file mode 100644
index 0000000..26ddb66
--- /dev/null
+++ b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/brace-expansion/package.json
@@ -0,0 +1,112 @@
+{
+ "_args": [
+ [
+ {
+ "raw": "brace-expansion@^1.0.0",
+ "scope": null,
+ "escapedName": "brace-expansion",
+ "name": "brace-expansion",
+ "rawSpec": "^1.0.0",
+ "spec": ">=1.0.0 <2.0.0",
+ "type": "range"
+ },
+ "/Users/steveng/repo/cordova/cordova-android/node_modules/minimatch"
+ ]
+ ],
+ "_from": "brace-expansion@>=1.0.0 <2.0.0",
+ "_id": "brace-expansion@1.1.6",
+ "_inCache": true,
+ "_location": "/cordova-android/brace-expansion",
+ "_nodeVersion": "4.4.7",
+ "_npmOperationalInternal": {
+ "host": "packages-16-east.internal.npmjs.com",
+ "tmp": "tmp/brace-expansion-1.1.6.tgz_1469047715600_0.9362958471756428"
+ },
+ "_npmUser": {
+ "name": "juliangruber",
+ "email": "julian@juliangruber.com"
+ },
+ "_npmVersion": "2.15.8",
+ "_phantomChildren": {},
+ "_requested": {
+ "raw": "brace-expansion@^1.0.0",
+ "scope": null,
+ "escapedName": "brace-expansion",
+ "name": "brace-expansion",
+ "rawSpec": "^1.0.0",
+ "spec": ">=1.0.0 <2.0.0",
+ "type": "range"
+ },
+ "_requiredBy": [
+ "/cordova-android/minimatch"
+ ],
+ "_resolved": "http://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz",
+ "_shasum": "7197d7eaa9b87e648390ea61fc66c84427420df9",
+ "_shrinkwrap": null,
+ "_spec": "brace-expansion@^1.0.0",
+ "_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/minimatch",
+ "author": {
+ "name": "Julian Gruber",
+ "email": "mail@juliangruber.com",
+ "url": "http://juliangruber.com"
+ },
+ "bugs": {
+ "url": "https://github.com/juliangruber/brace-expansion/issues"
+ },
+ "dependencies": {
+ "balanced-match": "^0.4.1",
+ "concat-map": "0.0.1"
+ },
+ "description": "Brace expansion as known from sh/bash",
+ "devDependencies": {
+ "tape": "^4.6.0"
+ },
+ "directories": {},
+ "dist": {
+ "shasum": "7197d7eaa9b87e648390ea61fc66c84427420df9",
+ "tarball": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz"
+ },
+ "gitHead": "791262fa06625e9c5594cde529a21d82086af5f2",
+ "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": {
+ "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"
+ ]
+ },
+ "version": "1.1.6"
+}
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07bed560/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/.travis.yml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/.travis.yml b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/.travis.yml
new file mode 100644
index 0000000..f1d0f13
--- /dev/null
+++ b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/.travis.yml
@@ -0,0 +1,4 @@
+language: node_js
+node_js:
+ - 0.4
+ - 0.6
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07bed560/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/LICENSE
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/LICENSE b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/LICENSE
new file mode 100644
index 0000000..ee27ba4
--- /dev/null
+++ b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/LICENSE
@@ -0,0 +1,18 @@
+This software is released under the MIT license:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07bed560/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/README.markdown
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/README.markdown b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/README.markdown
new file mode 100644
index 0000000..408f70a
--- /dev/null
+++ b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/README.markdown
@@ -0,0 +1,62 @@
+concat-map
+==========
+
+Concatenative mapdashery.
+
+[![browser support](http://ci.testling.com/substack/node-concat-map.png)](http://ci.testling.com/substack/node-concat-map)
+
+[![build status](https://secure.travis-ci.org/substack/node-concat-map.png)](http://travis-ci.org/substack/node-concat-map)
+
+example
+=======
+
+``` js
+var concatMap = require('concat-map');
+var xs = [ 1, 2, 3, 4, 5, 6 ];
+var ys = concatMap(xs, function (x) {
+ return x % 2 ? [ x - 0.1, x, x + 0.1 ] : [];
+});
+console.dir(ys);
+```
+
+***
+
+```
+[ 0.9, 1, 1.1, 2.9, 3, 3.1, 4.9, 5, 5.1 ]
+```
+
+methods
+=======
+
+``` js
+var concatMap = require('concat-map')
+```
+
+concatMap(xs, fn)
+-----------------
+
+Return an array of concatenated elements by calling `fn(x, i)` for each element
+`x` and each index `i` in the array `xs`.
+
+When `fn(x, i)` returns an array, its result will be concatenated with the
+result array. If `fn(x, i)` returns anything else, that value will be pushed
+onto the end of the result array.
+
+install
+=======
+
+With [npm](http://npmjs.org) do:
+
+```
+npm install concat-map
+```
+
+license
+=======
+
+MIT
+
+notes
+=====
+
+This module was written while sitting high above the ground in a tree.
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07bed560/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/example/map.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/example/map.js b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/example/map.js
new file mode 100644
index 0000000..3365621
--- /dev/null
+++ b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/example/map.js
@@ -0,0 +1,6 @@
+var concatMap = require('../');
+var xs = [ 1, 2, 3, 4, 5, 6 ];
+var ys = concatMap(xs, function (x) {
+ return x % 2 ? [ x - 0.1, x, x + 0.1 ] : [];
+});
+console.dir(ys);
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07bed560/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/index.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/index.js b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/index.js
new file mode 100644
index 0000000..b29a781
--- /dev/null
+++ b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/index.js
@@ -0,0 +1,13 @@
+module.exports = function (xs, fn) {
+ var res = [];
+ for (var i = 0; i < xs.length; i++) {
+ var x = fn(xs[i], i);
+ if (isArray(x)) res.push.apply(res, x);
+ else res.push(x);
+ }
+ return res;
+};
+
+var isArray = Array.isArray || function (xs) {
+ return Object.prototype.toString.call(xs) === '[object Array]';
+};
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07bed560/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/package.json
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/package.json b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/package.json
new file mode 100644
index 0000000..c42a6ef
--- /dev/null
+++ b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/package.json
@@ -0,0 +1,117 @@
+{
+ "_args": [
+ [
+ {
+ "raw": "concat-map@0.0.1",
+ "scope": null,
+ "escapedName": "concat-map",
+ "name": "concat-map",
+ "rawSpec": "0.0.1",
+ "spec": "0.0.1",
+ "type": "version"
+ },
+ "/Users/steveng/repo/cordova/cordova-android/node_modules/brace-expansion"
+ ]
+ ],
+ "_from": "concat-map@0.0.1",
+ "_id": "concat-map@0.0.1",
+ "_inCache": true,
+ "_location": "/cordova-android/concat-map",
+ "_npmUser": {
+ "name": "substack",
+ "email": "mail@substack.net"
+ },
+ "_npmVersion": "1.3.21",
+ "_phantomChildren": {},
+ "_requested": {
+ "raw": "concat-map@0.0.1",
+ "scope": null,
+ "escapedName": "concat-map",
+ "name": "concat-map",
+ "rawSpec": "0.0.1",
+ "spec": "0.0.1",
+ "type": "version"
+ },
+ "_requiredBy": [
+ "/cordova-android/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": {
+ "name": "James Halliday",
+ "email": "mail@substack.net",
+ "url": "http://substack.net"
+ },
+ "bugs": {
+ "url": "https://github.com/substack/node-concat-map/issues"
+ },
+ "dependencies": {},
+ "description": "concatenative mapdashery",
+ "devDependencies": {
+ "tape": "~2.4.0"
+ },
+ "directories": {
+ "example": "example",
+ "test": "test"
+ },
+ "dist": {
+ "shasum": "d8a96bd77fd68df7793a73036a3ba0d5405d477b",
+ "tarball": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
+ },
+ "homepage": "https://github.com/substack/node-concat-map",
+ "keywords": [
+ "concat",
+ "concatMap",
+ "map",
+ "functional",
+ "higher-order"
+ ],
+ "license": "MIT",
+ "main": "index.js",
+ "maintainers": [
+ {
+ "name": "substack",
+ "email": "mail@substack.net"
+ }
+ ],
+ "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": {
+ "files": "test/*.js",
+ "browsers": {
+ "ie": [
+ 6,
+ 7,
+ 8,
+ 9
+ ],
+ "ff": [
+ 3.5,
+ 10,
+ 15
+ ],
+ "chrome": [
+ 10,
+ 22
+ ],
+ "safari": [
+ 5.1
+ ],
+ "opera": [
+ 12
+ ]
+ }
+ },
+ "version": "0.0.1"
+}
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07bed560/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/test/map.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/test/map.js b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/test/map.js
new file mode 100644
index 0000000..fdbd702
--- /dev/null
+++ b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/concat-map/test/map.js
@@ -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();
+});
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07bed560/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/.jscs.json
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/.jscs.json b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/.jscs.json
new file mode 100644
index 0000000..5cc7e26
--- /dev/null
+++ b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/.jscs.json
@@ -0,0 +1,24 @@
+{
+ "disallowMixedSpacesAndTabs": true,
+ "disallowTrailingWhitespace": true,
+ "validateLineBreaks": "LF",
+ "validateIndentation": 4,
+ "requireLineFeedAtFileEnd": true,
+
+ "disallowSpaceAfterPrefixUnaryOperators": true,
+ "disallowSpaceBeforePostfixUnaryOperators": true,
+ "requireSpaceAfterLineComment": true,
+ "requireCapitalizedConstructors": true,
+
+ "disallowSpacesInNamedFunctionExpression": {
+ "beforeOpeningRoundBrace": true
+ },
+
+ "requireSpaceAfterKeywords": [
+ "if",
+ "else",
+ "for",
+ "while",
+ "do"
+ ]
+}
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07bed560/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/.jshintignore
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/.jshintignore b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/.jshintignore
new file mode 100644
index 0000000..d606f61
--- /dev/null
+++ b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/.jshintignore
@@ -0,0 +1 @@
+spec/fixtures/*
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07bed560/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/.npmignore
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/.npmignore b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/.npmignore
new file mode 100644
index 0000000..5d14118
--- /dev/null
+++ b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/.npmignore
@@ -0,0 +1,2 @@
+spec
+coverage
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07bed560/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/.ratignore
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/.ratignore b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/.ratignore
new file mode 100644
index 0000000..d9f5e52
--- /dev/null
+++ b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/.ratignore
@@ -0,0 +1,3 @@
+fixtures
+coverage
+jasmine.json
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07bed560/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/README.md
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/README.md b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/README.md
new file mode 100644
index 0000000..c5dcfd5
--- /dev/null
+++ b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/README.md
@@ -0,0 +1,153 @@
+<!--
+#
+# 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.
+#
+-->
+
+# cordova-common
+Expoeses shared functionality used by [cordova-lib](https://github.com/apache/cordova-lib/) and Cordova platforms.
+## Exposed APIs
+
+### `events`
+
+Represents special instance of NodeJS EventEmitter which is intended to be used to post events to cordova-lib and cordova-cli
+
+Usage:
+```js
+var events = require('cordova-common').events;
+events.emit('warn', 'Some warning message')
+```
+
+There are the following events supported by cordova-cli: `verbose`, `log`, `info`, `warn`, `error`.
+
+### `CordovaError`
+
+An error class used by Cordova to throw cordova-specific errors. The CordovaError class is inherited from Error, so CordovaError instances is also valid Error instances (`instanceof` check succeeds).
+
+Usage:
+
+```js
+var CordovaError = require('cordova-common').CordovaError;
+throw new CordovaError('Some error message', SOME_ERR_CODE);
+```
+
+See [CordovaError](src/CordovaError/CordovaError.js) for supported error codes.
+
+### `ConfigParser`
+
+Exposes functionality to deal with cordova project `config.xml` files. For ConfigParser API reference check [ConfigParser Readme](src/ConfigParser/README.md).
+
+Usage:
+```js
+var ConfigParser = require('cordova-common').ConfigParser;
+var appConfig = new ConfigParser('path/to/cordova-app/config.xml');
+console.log(appconfig.name() + ':' + appConfig.version());
+```
+
+### `PluginInfoProvider` and `PluginInfo`
+
+`PluginInfo` is a wrapper for cordova plugins' `plugin.xml` files. This class may be instantiated directly or via `PluginInfoProvider`. The difference is that `PluginInfoProvider` caches `PluginInfo` instances based on plugin source directory.
+
+Usage:
+```js
+var PluginInfo: require('cordova-common').PluginInfo;
+var PluginInfoProvider: require('cordova-common').PluginInfoProvider;
+
+// The following instances are equal
+var plugin1 = new PluginInfo('path/to/plugin_directory');
+var plugin2 = new PluginInfoProvider().get('path/to/plugin_directory');
+
+console.log('The plugin ' + plugin1.id + ' has version ' + plugin1.version)
+```
+
+### `ActionStack`
+
+Utility module for dealing with sequential tasks. Provides a set of tasks that are needed to be done and reverts all tasks that are already completed if one of those tasks fail to complete. Used internally by cordova-lib and platform's plugin installation routines.
+
+Usage:
+```js
+var ActionStack = require('cordova-common').ActionStack;
+var stack = new ActionStack()
+
+var action1 = stack.createAction(task1, [<task parameters>], task1_reverter, [<reverter_parameters>]);
+var action2 = stack.createAction(task2, [<task parameters>], task2_reverter, [<reverter_parameters>]);
+
+stack.push(action1);
+stack.push(action2);
+
+stack.process()
+.then(function() {
+ // all actions succeded
+})
+.catch(function(error){
+ // One of actions failed with error
+})
+```
+
+### `superspawn`
+
+Module for spawning child processes with some advanced logic.
+
+Usage:
+```js
+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...
+})
+```
+
+### `xmlHelpers`
+
+A set of utility methods for dealing with xml files.
+
+Usage:
+```js
+var xml = require('cordova-common').xmlHelpers;
+
+var xmlDoc1 = xml.parseElementtreeSync('some/xml/file');
+var xmlDoc2 = xml.parseElementtreeSync('another/xml/file');
+
+xml.mergeXml(doc1, doc2); // doc2 now contains all the nodes from doc1
+```
+
+### Other APIs
+
+The APIs listed below are also exposed but are intended to be only used internally by cordova plugin installation routines.
+
+```
+PlatformJson
+ConfigChanges
+ConfigKeeper
+ConfigFile
+mungeUtil
+```
+
+## Setup
+* Clone this repository onto your local machine
+ `git clone https://git-wip-us.apache.org/repos/asf/cordova-lib.git`
+* In terminal, navigate to the inner cordova-common directory
+ `cd cordova-lib/cordova-common`
+* Install dependencies and npm-link
+ `npm install && npm link`
+* Navigate to cordova-lib directory and link cordova-common
+ `cd ../cordova-lib && npm link cordova-common && npm install`
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07bed560/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/RELEASENOTES.md
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/RELEASENOTES.md b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/RELEASENOTES.md
new file mode 100644
index 0000000..83777f5
--- /dev/null
+++ b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/RELEASENOTES.md
@@ -0,0 +1,97 @@
+<!--
+#
+# 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.
+#
+-->
+# Cordova-common Release Notes
+
+### 2.0.1 (Mar 09, 2017)
+* [CB-12557](https://issues.apache.org/jira/browse/CB-12557) add both stdout and stderr properties to the error object passed to superspawn reject handler.
+
+### 2.0.0 (Jan 17, 2017)
+* [CB-8978](https://issues.apache.org/jira/browse/CB-8978) Add `resource-file` parsing to `config.xml`
+* [CB-12018](https://issues.apache.org/jira/browse/CB-12018): updated `jshint` and updated tests to work with `jasmine@2` instead of `jasmine-node`
+* [CB-12163](https://issues.apache.org/jira/browse/CB-12163) Add reference attrib to `resource-file` for **Windows**
+* Move windows-specific logic to `cordova-windows`
+* [CB-12189](https://issues.apache.org/jira/browse/CB-12189) Add implementation attribute to framework
+
+### 1.5.1 (Oct 12, 2016)
+* [CB-12002](https://issues.apache.org/jira/browse/CB-12002) Add `getAllowIntents()` to `ConfigParser`
+* [CB-11998](https://issues.apache.org/jira/browse/CB-11998) `cordova platform add` error with `cordova-common@1.5.0`
+
+### 1.5.0 (Oct 06, 2016)
+* [CB-11776](https://issues.apache.org/jira/browse/CB-11776) Add test case for different `edit-config` targets
+* [CB-11908](https://issues.apache.org/jira/browse/CB-11908) Add `edit-config` to `config.xml`
+* [CB-11936](https://issues.apache.org/jira/browse/CB-11936) Support four new **App Transport Security (ATS)** keys
+* update `config.xml` location if it is a **Android Studio** project.
+* use `array` methods and `object.keys` for iterating. avoiding `for-in` loops
+* [CB-11517](https://issues.apache.org/jira/browse/CB-11517) Allow `.folder` matches
+* [CB-11776](https://issues.apache.org/jira/browse/CB-11776) check `edit-config` target exists
+
+### 1.4.1 (Aug 09, 2016)
+* Add general purpose `ConfigParser.getAttribute` API
+* [CB-11653](https://issues.apache.org/jira/browse/CB-11653) moved `findProjectRoot` from `cordova-lib` to `cordova-common`
+* [CB-11636](https://issues.apache.org/jira/browse/CB-11636) Handle attributes with quotes correctly
+* [CB-11645](https://issues.apache.org/jira/browse/CB-11645) added check to see if `getEditConfig` exists before trying to use it
+* [CB-9825](https://issues.apache.org/jira/browse/CB-9825) framework tag spec parsing
+
+### 1.4.0 (Jul 12, 2016)
+* [CB-11023](https://issues.apache.org/jira/browse/CB-11023) Add edit-config functionality
+
+### 1.3.0 (May 12, 2016)
+* [CB-11259](https://issues.apache.org/jira/browse/CB-11259): Improving prepare and build logging
+* [CB-11194](https://issues.apache.org/jira/browse/CB-11194) Improve cordova load time
+* [CB-1117](https://issues.apache.org/jira/browse/CB-1117) Add `FileUpdater` module to `cordova-common`.
+* [CB-11131](https://issues.apache.org/jira/browse/CB-11131) Fix `TypeError: message.toUpperCase` is not a function in `CordovaLogger`
+
+### 1.2.0 (Apr 18, 2016)
+* [CB-11022](https://issues.apache.org/jira/browse/CB-11022) Save modulesMetadata to both www and platform_www when necessary
+* [CB-10833](https://issues.apache.org/jira/browse/CB-10833) Deduplicate common logic for plugin installation/uninstallation
+* [CB-10822](https://issues.apache.org/jira/browse/CB-10822) Manage plugins/modules metadata using PlatformJson
+* [CB-10940](https://issues.apache.org/jira/browse/CB-10940) Can't add Android platform from path
+* [CB-10965](https://issues.apache.org/jira/browse/CB-10965) xml helper allows multiple instances to be merge in config.xml
+
+### 1.1.1 (Mar 18, 2016)
+* [CB-10694](https://issues.apache.org/jira/browse/CB-10694) Update test to reflect merging of [CB-9264](https://issues.apache.org/jira/browse/CB-9264) fix
+* [CB-10694](https://issues.apache.org/jira/browse/CB-10694) Platform-specific configuration preferences don't override global settings
+* [CB-9264](https://issues.apache.org/jira/browse/CB-9264) Duplicate entries in `config.xml`
+* [CB-10791](https://issues.apache.org/jira/browse/CB-10791) Add `adjustLoggerLevel` to `cordova-common.CordovaLogger`
+* [CB-10662](https://issues.apache.org/jira/browse/CB-10662) Add tests for `ConfigParser.getStaticResources`
+* [CB-10622](https://issues.apache.org/jira/browse/CB-10622) fix target attribute being ignored for images in `config.xml`.
+* [CB-10583](https://issues.apache.org/jira/browse/CB-10583) Protect plugin preferences from adding extra Array properties.
+
+### 1.1.0 (Feb 16, 2016)
+* [CB-10482](https://issues.apache.org/jira/browse/CB-10482) Remove references to windows8 from cordova-lib/cli
+* [CB-10430](https://issues.apache.org/jira/browse/CB-10430) Adds forwardEvents method to easily connect two EventEmitters
+* [CB-10176](https://issues.apache.org/jira/browse/CB-10176) Adds CordovaLogger class, based on logger module from cordova-cli
+* [CB-10052](https://issues.apache.org/jira/browse/CB-10052) Expose child process' io streams via promise progress notification
+* [CB-10497](https://issues.apache.org/jira/browse/CB-10497) Prefer .bat over .cmd on windows platform
+* [CB-9984](https://issues.apache.org/jira/browse/CB-9984) Bumps plist version and fixes failing cordova-common test
+
+### 1.0.0 (Oct 29, 2015)
+
+* [CB-9890](https://issues.apache.org/jira/browse/CB-9890) Documents cordova-common
+* [CB-9598](https://issues.apache.org/jira/browse/CB-9598) Correct cordova-lib -> cordova-common in README
+* Pick ConfigParser changes from apache@0c3614e
+* [CB-9743](https://issues.apache.org/jira/browse/CB-9743) Removes system frameworks handling from ConfigChanges
+* [CB-9598](https://issues.apache.org/jira/browse/CB-9598) Cleans out code which has been moved to `cordova-common`
+* Pick ConfigParser changes from apache@ddb027b
+* Picking CordovaError changes from apache@a3b1fca
+* [CB-9598](https://issues.apache.org/jira/browse/CB-9598) Adds tests and fixtures based on existing cordova-lib ones
+* [CB-9598](https://issues.apache.org/jira/browse/CB-9598) Initial implementation for cordova-common
+
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07bed560/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/cordova-common.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/cordova-common.js b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/cordova-common.js
new file mode 100644
index 0000000..801d510
--- /dev/null
+++ b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/cordova-common.js
@@ -0,0 +1,47 @@
+/**
+ 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.
+*/
+
+var addProperty = require('./src/util/addProperty');
+
+module.exports = { };
+
+addProperty(module, 'events', './src/events');
+addProperty(module, 'superspawn', './src/superspawn');
+
+addProperty(module, 'ActionStack', './src/ActionStack');
+addProperty(module, 'CordovaError', './src/CordovaError/CordovaError');
+addProperty(module, 'CordovaLogger', './src/CordovaLogger');
+addProperty(module, 'CordovaCheck', './src/CordovaCheck');
+addProperty(module, 'CordovaExternalToolErrorContext', './src/CordovaError/CordovaExternalToolErrorContext');
+addProperty(module, 'PlatformJson', './src/PlatformJson');
+addProperty(module, 'ConfigParser', './src/ConfigParser/ConfigParser');
+addProperty(module, 'FileUpdater', './src/FileUpdater');
+
+addProperty(module, 'PluginInfo', './src/PluginInfo/PluginInfo');
+addProperty(module, 'PluginInfoProvider', './src/PluginInfo/PluginInfoProvider');
+
+addProperty(module, 'PluginManager', './src/PluginManager');
+
+addProperty(module, 'ConfigChanges', './src/ConfigChanges/ConfigChanges');
+addProperty(module, 'ConfigKeeper', './src/ConfigChanges/ConfigKeeper');
+addProperty(module, 'ConfigFile', './src/ConfigChanges/ConfigFile');
+addProperty(module, 'mungeUtil', './src/ConfigChanges/munge-util');
+
+addProperty(module, 'xmlHelpers', './src/util/xml-helpers');
+
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07bed560/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/package.json
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/package.json b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/package.json
new file mode 100644
index 0000000..eb493d8
--- /dev/null
+++ b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/package.json
@@ -0,0 +1,133 @@
+{
+ "_args": [
+ [
+ {
+ "raw": "cordova-common@^2.0.1",
+ "scope": null,
+ "escapedName": "cordova-common",
+ "name": "cordova-common",
+ "rawSpec": "^2.0.1",
+ "spec": ">=2.0.1 <3.0.0",
+ "type": "range"
+ },
+ "/Users/steveng/repo/cordova/cordova-android"
+ ]
+ ],
+ "_from": "cordova-common@>=2.0.1 <3.0.0",
+ "_id": "cordova-common@2.0.1",
+ "_inCache": true,
+ "_location": "/cordova-android/cordova-common",
+ "_nodeVersion": "6.9.4",
+ "_npmOperationalInternal": {
+ "host": "packages-18-east.internal.npmjs.com",
+ "tmp": "tmp/cordova-common-2.0.1.tgz_1489432932737_0.5238456283695996"
+ },
+ "_npmUser": {
+ "name": "filmaj",
+ "email": "maj.fil@gmail.com"
+ },
+ "_npmVersion": "3.10.10",
+ "_phantomChildren": {},
+ "_requested": {
+ "raw": "cordova-common@^2.0.1",
+ "scope": null,
+ "escapedName": "cordova-common",
+ "name": "cordova-common",
+ "rawSpec": "^2.0.1",
+ "spec": ">=2.0.1 <3.0.0",
+ "type": "range"
+ },
+ "_requiredBy": [
+ "/cordova-android"
+ ],
+ "_resolved": "http://registry.npmjs.org/cordova-common/-/cordova-common-2.0.1.tgz",
+ "_shasum": "99af318d7cb8988047cfe37bb9f25ea881d52815",
+ "_shrinkwrap": null,
+ "_spec": "cordova-common@^2.0.1",
+ "_where": "/Users/steveng/repo/cordova/cordova-android",
+ "author": {
+ "name": "Apache Software Foundation"
+ },
+ "bugs": {
+ "url": "https://issues.apache.org/jira/browse/CB",
+ "email": "dev@cordova.apache.org"
+ },
+ "contributors": [],
+ "dependencies": {
+ "ansi": "^0.3.1",
+ "bplist-parser": "^0.1.0",
+ "cordova-registry-mapper": "^1.1.8",
+ "elementtree": "^0.1.6",
+ "glob": "^5.0.13",
+ "minimatch": "^3.0.0",
+ "osenv": "^0.1.3",
+ "plist": "^1.2.0",
+ "q": "^1.4.1",
+ "semver": "^5.0.1",
+ "shelljs": "^0.5.3",
+ "underscore": "^1.8.3",
+ "unorm": "^1.3.3"
+ },
+ "description": "Apache Cordova tools and platforms shared routines",
+ "devDependencies": {
+ "istanbul": "^0.4.5",
+ "jasmine": "^2.5.2",
+ "jshint": "^2.8.0",
+ "promise-matchers": "^0.9.6",
+ "rewire": "^2.5.1"
+ },
+ "directories": {},
+ "dist": {
+ "shasum": "99af318d7cb8988047cfe37bb9f25ea881d52815",
+ "tarball": "https://registry.npmjs.org/cordova-common/-/cordova-common-2.0.1.tgz"
+ },
+ "engines": {
+ "node": ">=0.9.9"
+ },
+ "license": "Apache-2.0",
+ "main": "cordova-common.js",
+ "maintainers": [
+ {
+ "name": "bowserj",
+ "email": "bowserj@apache.org"
+ },
+ {
+ "name": "filmaj",
+ "email": "maj.fil@gmail.com"
+ },
+ {
+ "name": "kotikov.vladimir",
+ "email": "kotikov.vladimir@gmail.com"
+ },
+ {
+ "name": "purplecabbage",
+ "email": "purplecabbage@gmail.com"
+ },
+ {
+ "name": "shazron",
+ "email": "shazron@gmail.com"
+ },
+ {
+ "name": "stevegill",
+ "email": "stevengill97@gmail.com"
+ },
+ {
+ "name": "timbarham",
+ "email": "npmjs@barhams.info"
+ }
+ ],
+ "name": "cordova-common",
+ "optionalDependencies": {},
+ "readme": "ERROR: No README data found!",
+ "repository": {
+ "type": "git",
+ "url": "git://git-wip-us.apache.org/repos/asf/cordova-common.git"
+ },
+ "scripts": {
+ "cover": "istanbul cover --root src --print detail jasmine",
+ "jasmine": "jasmine --captureExceptions --color",
+ "jshint": "jshint src && jshint spec",
+ "test": "npm run jshint && npm run jasmine"
+ },
+ "version": "2.0.1"
+}
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07bed560/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/.jshintrc
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/.jshintrc b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/.jshintrc
new file mode 100644
index 0000000..89a121c
--- /dev/null
+++ b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/.jshintrc
@@ -0,0 +1,10 @@
+{
+ "node": true
+ , "bitwise": true
+ , "undef": true
+ , "trailing": true
+ , "quotmark": true
+ , "indent": 4
+ , "unused": "vars"
+ , "latedef": "nofunc"
+}
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07bed560/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/ActionStack.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/ActionStack.js b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/ActionStack.js
new file mode 100644
index 0000000..5ef6f84
--- /dev/null
+++ b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/ActionStack.js
@@ -0,0 +1,85 @@
+/**
+ 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.
+*/
+
+/* jshint quotmark:false */
+
+var events = require('./events'),
+ Q = require('q');
+
+function ActionStack() {
+ this.stack = [];
+ this.completed = [];
+}
+
+ActionStack.prototype = {
+ createAction:function(handler, action_params, reverter, revert_params) {
+ return {
+ handler:{
+ run:handler,
+ params:action_params
+ },
+ reverter:{
+ run:reverter,
+ params:revert_params
+ }
+ };
+ },
+ push:function(tx) {
+ this.stack.push(tx);
+ },
+ // Returns a promise.
+ process:function(platform) {
+ events.emit('verbose', 'Beginning processing of action stack for ' + platform + ' project...');
+
+ while (this.stack.length) {
+ var action = this.stack.shift();
+ var handler = action.handler.run;
+ var action_params = action.handler.params;
+
+ try {
+ handler.apply(null, action_params);
+ } catch(e) {
+ events.emit('warn', 'Error during processing of action! Attempting to revert...');
+ this.stack.unshift(action);
+ var issue = 'Uh oh!\n';
+ // revert completed tasks
+ while(this.completed.length) {
+ var undo = this.completed.shift();
+ var revert = undo.reverter.run;
+ var revert_params = undo.reverter.params;
+
+ try {
+ revert.apply(null, revert_params);
+ } catch(err) {
+ events.emit('warn', 'Error during reversion of action! We probably really messed up your project now, sorry! D:');
+ issue += 'A reversion action failed: ' + err.message + '\n';
+ }
+ }
+ e.message = issue + e.message;
+ return Q.reject(e);
+ }
+ this.completed.push(action);
+ }
+ events.emit('verbose', 'Action stack processing complete.');
+
+ return Q();
+ }
+};
+
+module.exports = ActionStack;
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07bed560/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/ConfigChanges/ConfigChanges.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/ConfigChanges/ConfigChanges.js b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/ConfigChanges/ConfigChanges.js
new file mode 100644
index 0000000..4a58132
--- /dev/null
+++ b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/ConfigChanges/ConfigChanges.js
@@ -0,0 +1,431 @@
+/**
+ 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.
+*/
+
+/*
+ * This module deals with shared configuration / dependency "stuff". That is:
+ * - XML configuration files such as config.xml, AndroidManifest.xml or WMAppManifest.xml.
+ * - plist files in iOS
+ * Essentially, any type of shared resources that we need to handle with awareness
+ * of how potentially multiple plugins depend on a single shared resource, should be
+ * handled in this module.
+ *
+ * The implementation uses an object as a hash table, with "leaves" of the table tracking
+ * reference counts.
+ */
+
+/* jshint sub:true */
+
+var path = require('path'),
+ et = require('elementtree'),
+ ConfigKeeper = require('./ConfigKeeper'),
+ CordovaLogger = require('../CordovaLogger');
+
+var mungeutil = require('./munge-util');
+var xml_helpers = require('../util/xml-helpers');
+
+exports.PlatformMunger = PlatformMunger;
+
+exports.process = function(plugins_dir, project_dir, platform, platformJson, pluginInfoProvider) {
+ var munger = new PlatformMunger(platform, project_dir, platformJson, pluginInfoProvider);
+ munger.process(plugins_dir);
+ munger.save_all();
+};
+
+/******************************************************************************
+* PlatformMunger class
+*
+* Can deal with config file of a single project.
+* Parsed config files are cached in a ConfigKeeper object.
+******************************************************************************/
+function PlatformMunger(platform, project_dir, platformJson, pluginInfoProvider) {
+ this.platform = platform;
+ this.project_dir = project_dir;
+ this.config_keeper = new ConfigKeeper(project_dir);
+ this.platformJson = platformJson;
+ this.pluginInfoProvider = pluginInfoProvider;
+}
+
+// Write out all unsaved files.
+PlatformMunger.prototype.save_all = PlatformMunger_save_all;
+function PlatformMunger_save_all() {
+ this.config_keeper.save_all();
+ this.platformJson.save();
+}
+
+// Apply a munge object to a single config file.
+// The remove parameter tells whether to add the change or remove it.
+PlatformMunger.prototype.apply_file_munge = PlatformMunger_apply_file_munge;
+function PlatformMunger_apply_file_munge(file, munge, remove) {
+ var self = this;
+
+ for (var selector in munge.parents) {
+ for (var xml_child in munge.parents[selector]) {
+ // this xml child is new, graft it (only if config file exists)
+ var config_file = self.config_keeper.get(self.project_dir, self.platform, file);
+ if (config_file.exists) {
+ if (remove) config_file.prune_child(selector, munge.parents[selector][xml_child]);
+ else config_file.graft_child(selector, munge.parents[selector][xml_child]);
+ }
+ }
+ }
+}
+
+
+PlatformMunger.prototype.remove_plugin_changes = remove_plugin_changes;
+function remove_plugin_changes(pluginInfo, is_top_level) {
+ var self = this;
+ var platform_config = self.platformJson.root;
+ var plugin_vars = is_top_level ?
+ platform_config.installed_plugins[pluginInfo.id] :
+ platform_config.dependent_plugins[pluginInfo.id];
+ var edit_config_changes = null;
+ if(pluginInfo.getEditConfigs) {
+ edit_config_changes = pluginInfo.getEditConfigs(self.platform);
+ }
+
+ // get config munge, aka how did this plugin change various config files
+ var config_munge = self.generate_plugin_config_munge(pluginInfo, plugin_vars, edit_config_changes);
+ // global munge looks at all plugins' changes to config files
+ var global_munge = platform_config.config_munge;
+ var munge = mungeutil.decrement_munge(global_munge, config_munge);
+
+ for (var file in munge.files) {
+ self.apply_file_munge(file, munge.files[file], /* remove = */ true);
+ }
+
+ // Remove from installed_plugins
+ self.platformJson.removePlugin(pluginInfo.id, is_top_level);
+ return self;
+}
+
+
+PlatformMunger.prototype.add_plugin_changes = add_plugin_changes;
+function add_plugin_changes(pluginInfo, plugin_vars, is_top_level, should_increment, plugin_force) {
+ var self = this;
+ var platform_config = self.platformJson.root;
+
+ var edit_config_changes = null;
+ if(pluginInfo.getEditConfigs) {
+ edit_config_changes = pluginInfo.getEditConfigs(self.platform);
+ }
+
+ var config_munge;
+
+ if (!edit_config_changes || edit_config_changes.length === 0) {
+ // get config munge, aka how should this plugin change various config files
+ config_munge = self.generate_plugin_config_munge(pluginInfo, plugin_vars);
+ }
+ else {
+ var isConflictingInfo = is_conflicting(edit_config_changes, platform_config.config_munge, self, plugin_force);
+
+ if (isConflictingInfo.conflictWithConfigxml) {
+ throw new Error(pluginInfo.id +
+ ' cannot be added. <edit-config> changes in this plugin conflicts with <edit-config> changes in config.xml. Conflicts must be resolved before plugin can be added.');
+ }
+ if (plugin_force) {
+ CordovaLogger.get().log(CordovaLogger.WARN, '--force is used. edit-config will overwrite conflicts if any. Conflicting plugins may not work as expected.');
+
+ // remove conflicting munges
+ var conflict_munge = mungeutil.decrement_munge(platform_config.config_munge, isConflictingInfo.conflictingMunge);
+ for (var conflict_file in conflict_munge.files) {
+ self.apply_file_munge(conflict_file, conflict_munge.files[conflict_file], /* remove = */ true);
+ }
+
+ // force add new munges
+ config_munge = self.generate_plugin_config_munge(pluginInfo, plugin_vars, edit_config_changes);
+ }
+ else if(isConflictingInfo.conflictFound) {
+ throw new Error('There was a conflict trying to modify attributes with <edit-config> in plugin ' + pluginInfo.id +
+ '. The conflicting plugin, ' + isConflictingInfo.conflictingPlugin + ', already modified the same attributes. The conflict must be resolved before ' +
+ pluginInfo.id + ' can be added. You may use --force to add the plugin and overwrite the conflicting attributes.');
+ }
+ else {
+ // no conflicts, will handle edit-config
+ config_munge = self.generate_plugin_config_munge(pluginInfo, plugin_vars, edit_config_changes);
+ }
+ }
+
+ self = munge_helper(should_increment, self, platform_config, config_munge);
+
+ // Move to installed/dependent_plugins
+ self.platformJson.addPlugin(pluginInfo.id, plugin_vars || {}, is_top_level);
+ return self;
+}
+
+
+// Handle edit-config changes from config.xml
+PlatformMunger.prototype.add_config_changes = add_config_changes;
+function add_config_changes(config, should_increment) {
+ var self = this;
+ var platform_config = self.platformJson.root;
+
+ var config_munge;
+ var edit_config_changes = null;
+ if(config.getEditConfigs) {
+ edit_config_changes = config.getEditConfigs(self.platform);
+ }
+
+ if (!edit_config_changes || edit_config_changes.length === 0) {
+ // There are no edit-config changes to add, return here
+ return self;
+ }
+ else {
+ var isConflictingInfo = is_conflicting(edit_config_changes, platform_config.config_munge, self, true /*always force overwrite other edit-config*/);
+
+ if(isConflictingInfo.conflictFound) {
+ var conflict_munge;
+ var conflict_file;
+
+ if (Object.keys(isConflictingInfo.configxmlMunge.files).length !== 0) {
+ // silently remove conflicting config.xml munges so new munges can be added
+ conflict_munge = mungeutil.decrement_munge(platform_config.config_munge, isConflictingInfo.configxmlMunge);
+ for (conflict_file in conflict_munge.files) {
+ self.apply_file_munge(conflict_file, conflict_munge.files[conflict_file], /* remove = */ true);
+ }
+ }
+ if (Object.keys(isConflictingInfo.conflictingMunge.files).length !== 0) {
+ CordovaLogger.get().log(CordovaLogger.WARN, 'Conflict found, edit-config changes from config.xml will overwrite plugin.xml changes');
+
+ // remove conflicting plugin.xml munges
+ conflict_munge = mungeutil.decrement_munge(platform_config.config_munge, isConflictingInfo.conflictingMunge);
+ for (conflict_file in conflict_munge.files) {
+ self.apply_file_munge(conflict_file, conflict_munge.files[conflict_file], /* remove = */ true);
+ }
+ }
+ }
+ // Add config.xml edit-config munges
+ config_munge = self.generate_config_xml_munge(config, edit_config_changes, 'config.xml');
+ }
+
+ self = munge_helper(should_increment, self, platform_config, config_munge);
+
+ // Move to installed/dependent_plugins
+ return self;
+}
+
+function munge_helper(should_increment, self, platform_config, config_munge) {
+ // global munge looks at all changes to config files
+
+ // TODO: The should_increment param is only used by cordova-cli and is going away soon.
+ // If should_increment is set to false, avoid modifying the global_munge (use clone)
+ // and apply the entire config_munge because it's already a proper subset of the global_munge.
+ var munge, global_munge;
+ if (should_increment) {
+ global_munge = platform_config.config_munge;
+ munge = mungeutil.increment_munge(global_munge, config_munge);
+ } else {
+ global_munge = mungeutil.clone_munge(platform_config.config_munge);
+ munge = config_munge;
+ }
+
+ for (var file in munge.files) {
+ self.apply_file_munge(file, munge.files[file]);
+ }
+
+ return self;
+}
+
+
+// Load the global munge from platform json and apply all of it.
+// Used by cordova prepare to re-generate some config file from platform
+// defaults and the global munge.
+PlatformMunger.prototype.reapply_global_munge = reapply_global_munge ;
+function reapply_global_munge () {
+ var self = this;
+
+ var platform_config = self.platformJson.root;
+ var global_munge = platform_config.config_munge;
+ for (var file in global_munge.files) {
+ self.apply_file_munge(file, global_munge.files[file]);
+ }
+
+ return self;
+}
+
+// generate_plugin_config_munge
+// Generate the munge object from config.xml
+PlatformMunger.prototype.generate_config_xml_munge = generate_config_xml_munge;
+function generate_config_xml_munge(config, edit_config_changes, type) {
+
+ var munge = { files: {} };
+ var changes = edit_config_changes;
+ var id;
+
+ if(!changes) {
+ return munge;
+ }
+
+ if (type === 'config.xml') {
+ id = type;
+ }
+ else {
+ id = config.id;
+ }
+
+ changes.forEach(function(change) {
+ change.xmls.forEach(function(xml) {
+ // 1. stringify each xml
+ var stringified = (new et.ElementTree(xml)).write({xml_declaration:false});
+ // 2. add into munge
+ if (change.mode) {
+ mungeutil.deep_add(munge, change.file, change.target, { xml: stringified, count: 1, mode: change.mode, id: id });
+ }
+ });
+ });
+ return munge;
+}
+
+
+// generate_plugin_config_munge
+// Generate the munge object from plugin.xml + vars
+PlatformMunger.prototype.generate_plugin_config_munge = generate_plugin_config_munge;
+function generate_plugin_config_munge(pluginInfo, vars, edit_config_changes) {
+ var self = this;
+
+ vars = vars || {};
+ var munge = { files: {} };
+ var changes = pluginInfo.getConfigFiles(self.platform);
+
+ if(edit_config_changes) {
+ Array.prototype.push.apply(changes, edit_config_changes);
+ }
+
+ changes.forEach(function(change) {
+ change.xmls.forEach(function(xml) {
+ // 1. stringify each xml
+ var stringified = (new et.ElementTree(xml)).write({xml_declaration:false});
+ // interp vars
+ if (vars) {
+ Object.keys(vars).forEach(function(key) {
+ var regExp = new RegExp('\\$' + key, 'g');
+ stringified = stringified.replace(regExp, vars[key]);
+ });
+ }
+ // 2. add into munge
+ if (change.mode) {
+ if (change.mode !== 'remove') {
+ mungeutil.deep_add(munge, change.file, change.target, { xml: stringified, count: 1, mode: change.mode, plugin: pluginInfo.id });
+ }
+ }
+ else {
+ mungeutil.deep_add(munge, change.target, change.parent, { xml: stringified, count: 1, after: change.after });
+ }
+ });
+ });
+ return munge;
+}
+
+function is_conflicting(editchanges, config_munge, self, force) {
+ var files = config_munge.files;
+ var conflictFound = false;
+ var conflictWithConfigxml = false;
+ var conflictingMunge = { files: {} };
+ var configxmlMunge = { files: {} };
+ var conflictingParent;
+ var conflictingPlugin;
+
+ editchanges.forEach(function(editchange) {
+ if (files[editchange.file]) {
+ var parents = files[editchange.file].parents;
+ var target = parents[editchange.target];
+
+ // Check if the edit target will resolve to an existing target
+ if (!target || target.length === 0) {
+ var file_xml = self.config_keeper.get(self.project_dir, self.platform, editchange.file).data;
+ var resolveEditTarget = xml_helpers.resolveParent(file_xml, editchange.target);
+ var resolveTarget;
+
+ if (resolveEditTarget) {
+ for (var parent in parents) {
+ resolveTarget = xml_helpers.resolveParent(file_xml, parent);
+ if (resolveEditTarget === resolveTarget) {
+ conflictingParent = parent;
+ target = parents[parent];
+ break;
+ }
+ }
+ }
+ }
+ else {
+ conflictingParent = editchange.target;
+ }
+
+ if (target && target.length !== 0) {
+ // conflict has been found
+ conflictFound = true;
+
+ if (editchange.id === 'config.xml') {
+ if (target[0].id === 'config.xml') {
+ // Keep track of config.xml/config.xml edit-config conflicts
+ mungeutil.deep_add(configxmlMunge, editchange.file, conflictingParent, target[0]);
+ }
+ else {
+ // Keep track of config.xml x plugin.xml edit-config conflicts
+ mungeutil.deep_add(conflictingMunge, editchange.file, conflictingParent, target[0]);
+ }
+ }
+ else {
+ if (target[0].id === 'config.xml') {
+ // plugin.xml cannot overwrite config.xml changes even if --force is used
+ conflictWithConfigxml = true;
+ return;
+ }
+
+ if (force) {
+ // Need to find all conflicts when --force is used, track conflicting munges
+ mungeutil.deep_add(conflictingMunge, editchange.file, conflictingParent, target[0]);
+ }
+ else {
+ // plugin cannot overwrite other plugin changes without --force
+ conflictingPlugin = target[0].plugin;
+ return;
+ }
+ }
+ }
+ }
+ });
+
+ return {conflictFound: conflictFound, conflictingPlugin: conflictingPlugin, conflictingMunge: conflictingMunge,
+ configxmlMunge: configxmlMunge, conflictWithConfigxml:conflictWithConfigxml};
+}
+
+// Go over the prepare queue and apply the config munges for each plugin
+// that has been (un)installed.
+PlatformMunger.prototype.process = PlatformMunger_process;
+function PlatformMunger_process(plugins_dir) {
+ var self = this;
+ var platform_config = self.platformJson.root;
+
+ // Uninstallation first
+ platform_config.prepare_queue.uninstalled.forEach(function(u) {
+ var pluginInfo = self.pluginInfoProvider.get(path.join(plugins_dir, u.plugin));
+ self.remove_plugin_changes(pluginInfo, u.topLevel);
+ });
+
+ // Now handle installation
+ platform_config.prepare_queue.installed.forEach(function(u) {
+ var pluginInfo = self.pluginInfoProvider.get(path.join(plugins_dir, u.plugin));
+ self.add_plugin_changes(pluginInfo, u.vars, u.topLevel, true, u.force);
+ });
+
+ // Empty out installed/ uninstalled queues.
+ platform_config.prepare_queue.uninstalled = [];
+ platform_config.prepare_queue.installed = [];
+}
+/**** END of PlatformMunger ****/
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07bed560/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/ConfigChanges/ConfigFile.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/ConfigChanges/ConfigFile.js b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/ConfigChanges/ConfigFile.js
new file mode 100644
index 0000000..4a58008
--- /dev/null
+++ b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/ConfigChanges/ConfigFile.js
@@ -0,0 +1,240 @@
+/*
+ * Licensed 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.
+ *
+*/
+
+var fs = require('fs');
+var path = require('path');
+
+var modules = {};
+var addProperty = require('../util/addProperty');
+
+// Use delay loading to ensure plist and other node modules to not get loaded
+// on Android, Windows platforms
+addProperty(module, 'bplist', 'bplist-parser', modules);
+addProperty(module, 'et', 'elementtree', modules);
+addProperty(module, 'glob', 'glob', modules);
+addProperty(module, 'plist', 'plist', modules);
+addProperty(module, 'plist_helpers', '../util/plist-helpers', modules);
+addProperty(module, 'xml_helpers', '../util/xml-helpers', modules);
+
+/******************************************************************************
+* ConfigFile class
+*
+* Can load and keep various types of config files. Provides some functionality
+* specific to some file types such as grafting XML children. In most cases it
+* should be instantiated by ConfigKeeper.
+*
+* For plugin.xml files use as:
+* plugin_config = self.config_keeper.get(plugin_dir, '', 'plugin.xml');
+*
+* TODO: Consider moving it out to a separate file and maybe partially with
+* overrides in platform handlers.
+******************************************************************************/
+function ConfigFile(project_dir, platform, file_tag) {
+ this.project_dir = project_dir;
+ this.platform = platform;
+ this.file_tag = file_tag;
+ this.is_changed = false;
+
+ this.load();
+}
+
+// ConfigFile.load()
+ConfigFile.prototype.load = ConfigFile_load;
+function ConfigFile_load() {
+ var self = this;
+
+ // config file may be in a place not exactly specified in the target
+ var filepath = self.filepath = resolveConfigFilePath(self.project_dir, self.platform, self.file_tag);
+
+ if ( !filepath || !fs.existsSync(filepath) ) {
+ self.exists = false;
+ return;
+ }
+ self.exists = true;
+ self.mtime = fs.statSync(self.filepath).mtime;
+
+ var ext = path.extname(filepath);
+ // Windows8 uses an appxmanifest, and wp8 will likely use
+ // the same in a future release
+ if (ext == '.xml' || ext == '.appxmanifest') {
+ self.type = 'xml';
+ self.data = modules.xml_helpers.parseElementtreeSync(filepath);
+ } else {
+ // plist file
+ self.type = 'plist';
+ // TODO: isBinaryPlist() reads the file and then parse re-reads it again.
+ // We always write out text plist, not binary.
+ // Do we still need to support binary plist?
+ // If yes, use plist.parseStringSync() and read the file once.
+ self.data = isBinaryPlist(filepath) ?
+ modules.bplist.parseBuffer(fs.readFileSync(filepath)) :
+ modules.plist.parse(fs.readFileSync(filepath, 'utf8'));
+ }
+}
+
+ConfigFile.prototype.save = function ConfigFile_save() {
+ var self = this;
+ if (self.type === 'xml') {
+ fs.writeFileSync(self.filepath, self.data.write({indent: 4}), 'utf-8');
+ } else {
+ // plist
+ var regExp = new RegExp('<string>[ \t\r\n]+?</string>', 'g');
+ fs.writeFileSync(self.filepath, modules.plist.build(self.data).replace(regExp, '<string></string>'));
+ }
+ self.is_changed = false;
+};
+
+ConfigFile.prototype.graft_child = function ConfigFile_graft_child(selector, xml_child) {
+ var self = this;
+ var filepath = self.filepath;
+ var result;
+ if (self.type === 'xml') {
+ var xml_to_graft = [modules.et.XML(xml_child.xml)];
+ switch (xml_child.mode) {
+ case 'merge':
+ result = modules.xml_helpers.graftXMLMerge(self.data, xml_to_graft, selector, xml_child);
+ break;
+ case 'overwrite':
+ result = modules.xml_helpers.graftXMLOverwrite(self.data, xml_to_graft, selector, xml_child);
+ break;
+ case 'remove':
+ result= true;
+ break;
+ default:
+ result = modules.xml_helpers.graftXML(self.data, xml_to_graft, selector, xml_child.after);
+ }
+ if ( !result) {
+ throw new Error('Unable to graft xml at selector "' + selector + '" from "' + filepath + '" during config install');
+ }
+ } else {
+ // plist file
+ result = modules.plist_helpers.graftPLIST(self.data, xml_child.xml, selector);
+ if ( !result ) {
+ throw new Error('Unable to graft plist "' + filepath + '" during config install');
+ }
+ }
+ self.is_changed = true;
+};
+
+ConfigFile.prototype.prune_child = function ConfigFile_prune_child(selector, xml_child) {
+ var self = this;
+ var filepath = self.filepath;
+ var result;
+ if (self.type === 'xml') {
+ var xml_to_graft = [modules.et.XML(xml_child.xml)];
+ switch (xml_child.mode) {
+ case 'merge':
+ case 'overwrite':
+ result = modules.xml_helpers.pruneXMLRestore(self.data, selector, xml_child);
+ break;
+ case 'remove':
+ result = modules.xml_helpers.prunXMLRemove(self.data, selector, xml_to_graft);
+ break;
+ default:
+ result = modules.xml_helpers.pruneXML(self.data, xml_to_graft, selector);
+ }
+ } else {
+ // plist file
+ result = modules.plist_helpers.prunePLIST(self.data, xml_child.xml, selector);
+ }
+ if (!result) {
+ var err_msg = 'Pruning at selector "' + selector + '" from "' + filepath + '" went bad.';
+ throw new Error(err_msg);
+ }
+ self.is_changed = true;
+};
+
+// Some config-file target attributes are not qualified with a full leading directory, or contain wildcards.
+// Resolve to a real path in this function.
+// TODO: getIOSProjectname is slow because of glob, try to avoid calling it several times per project.
+function resolveConfigFilePath(project_dir, platform, file) {
+ var filepath = path.join(project_dir, file);
+ var matches;
+
+ if (file.indexOf('*') > -1) {
+ // handle wildcards in targets using glob.
+ matches = modules.glob.sync(path.join(project_dir, '**', file));
+ if (matches.length) filepath = matches[0];
+
+ // [CB-5989] multiple Info.plist files may exist. default to $PROJECT_NAME-Info.plist
+ if(matches.length > 1 && file.indexOf('-Info.plist')>-1){
+ var plistName = getIOSProjectname(project_dir)+'-Info.plist';
+ for (var i=0; i < matches.length; i++) {
+ if(matches[i].indexOf(plistName) > -1){
+ filepath = matches[i];
+ break;
+ }
+ }
+ }
+ return filepath;
+ }
+
+ // special-case config.xml target that is just "config.xml". This should be resolved to the real location of the file.
+ // TODO: move the logic that contains the locations of config.xml from cordova CLI into plugman.
+ if (file == 'config.xml') {
+ if (platform == 'ubuntu') {
+ filepath = path.join(project_dir, 'config.xml');
+ } else if (platform == 'ios') {
+ var iospath = getIOSProjectname(project_dir);
+ filepath = path.join(project_dir,iospath, 'config.xml');
+ } else if (platform == 'android') {
+ filepath = path.join(project_dir, 'res', 'xml', 'config.xml');
+ } else {
+ matches = modules.glob.sync(path.join(project_dir, '**', 'config.xml'));
+ if (matches.length) filepath = matches[0];
+ }
+ return filepath;
+ }
+
+ // XXX this checks for android studio projects
+ // only if none of the options above are satisfied does this get called
+ if(platform === 'android' && !fs.existsSync(filepath)) {
+ filepath = path.join(project_dir, 'app', 'src', 'main', 'res', 'xml', 'config.xml');
+ }
+
+ // None of the special cases matched, returning project_dir/file.
+ return filepath;
+}
+
+// Find out the real name of an iOS project
+// TODO: glob is slow, need a better way or caching, or avoid using more than once.
+function getIOSProjectname(project_dir) {
+ var matches = modules.glob.sync(path.join(project_dir, '*.xcodeproj'));
+ var iospath;
+ if (matches.length === 1) {
+ iospath = path.basename(matches[0],'.xcodeproj');
+ } else {
+ var msg;
+ if (matches.length === 0) {
+ msg = 'Does not appear to be an xcode project, no xcode project file in ' + project_dir;
+ } else {
+ msg = 'There are multiple *.xcodeproj dirs in ' + project_dir;
+ }
+ throw new Error(msg);
+ }
+ return iospath;
+}
+
+// determine if a plist file is binary
+function isBinaryPlist(filename) {
+ // I wish there was a synchronous way to read only the first 6 bytes of a
+ // file. This is wasteful :/
+ var buf = '' + fs.readFileSync(filename, 'utf8');
+ // binary plists start with a magic header, "bplist"
+ return buf.substring(0, 6) === 'bplist';
+}
+
+module.exports = ConfigFile;
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07bed560/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/ConfigChanges/ConfigKeeper.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/ConfigChanges/ConfigKeeper.js b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/ConfigChanges/ConfigKeeper.js
new file mode 100644
index 0000000..894e922
--- /dev/null
+++ b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/ConfigChanges/ConfigKeeper.js
@@ -0,0 +1,65 @@
+/*
+ * Licensed 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.
+ *
+*/
+/* jshint sub:true */
+
+var path = require('path');
+var ConfigFile = require('./ConfigFile');
+
+/******************************************************************************
+* ConfigKeeper class
+*
+* Used to load and store config files to avoid re-parsing and writing them out
+* multiple times.
+*
+* The config files are referred to by a fake path constructed as
+* project_dir/platform/file
+* where file is the name used for the file in config munges.
+******************************************************************************/
+function ConfigKeeper(project_dir, plugins_dir) {
+ this.project_dir = project_dir;
+ this.plugins_dir = plugins_dir;
+ this._cached = {};
+}
+
+ConfigKeeper.prototype.get = function ConfigKeeper_get(project_dir, platform, file) {
+ var self = this;
+
+ // This fixes a bug with older plugins - when specifying config xml instead of res/xml/config.xml
+ // https://issues.apache.org/jira/browse/CB-6414
+ if(file == 'config.xml' && platform == 'android'){
+ file = 'res/xml/config.xml';
+ }
+ var fake_path = path.join(project_dir, platform, file);
+
+ if (self._cached[fake_path]) {
+ return self._cached[fake_path];
+ }
+ // File was not cached, need to load.
+ var config_file = new ConfigFile(project_dir, platform, file);
+ self._cached[fake_path] = config_file;
+ return config_file;
+};
+
+
+ConfigKeeper.prototype.save_all = function ConfigKeeper_save_all() {
+ var self = this;
+ Object.keys(self._cached).forEach(function (fake_path) {
+ var config_file = self._cached[fake_path];
+ if (config_file.is_changed) config_file.save();
+ });
+};
+
+module.exports = ConfigKeeper;
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07bed560/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/ConfigChanges/munge-util.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/ConfigChanges/munge-util.js b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/ConfigChanges/munge-util.js
new file mode 100644
index 0000000..0149bab
--- /dev/null
+++ b/cordova-lib/spec-plugman/projects/android/cordova/node_modules/cordova-common/src/ConfigChanges/munge-util.js
@@ -0,0 +1,163 @@
+/*
+ * Licensed 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.
+ *
+*/
+/* jshint sub:true */
+
+var _ = require('underscore');
+
+// add the count of [key1][key2]...[keyN] to obj
+// return true if it didn't exist before
+exports.deep_add = function deep_add(obj, keys /* or key1, key2 .... */ ) {
+ if ( !Array.isArray(keys) ) {
+ keys = Array.prototype.slice.call(arguments, 1);
+ }
+
+ return exports.process_munge(obj, true/*createParents*/, function (parentArray, k) {
+ var found = _.find(parentArray, function(element) {
+ return element.xml == k.xml;
+ });
+ if (found) {
+ found.after = found.after || k.after;
+ found.count += k.count;
+ } else {
+ parentArray.push(k);
+ }
+ return !found;
+ }, keys);
+};
+
+// decrement the count of [key1][key2]...[keyN] from obj and remove if it reaches 0
+// return true if it was removed or not found
+exports.deep_remove = function deep_remove(obj, keys /* or key1, key2 .... */ ) {
+ if ( !Array.isArray(keys) ) {
+ keys = Array.prototype.slice.call(arguments, 1);
+ }
+
+ var result = exports.process_munge(obj, false/*createParents*/, function (parentArray, k) {
+ var index = -1;
+ var found = _.find(parentArray, function (element) {
+ index++;
+ return element.xml == k.xml;
+ });
+ if (found) {
+ if (parentArray[index].oldAttrib) {
+ k.oldAttrib = _.extend({}, parentArray[index].oldAttrib);
+ }
+ found.count -= k.count;
+ if (found.count > 0) {
+ return false;
+ }
+ else {
+ parentArray.splice(index, 1);
+ }
+ }
+ return undefined;
+ }, keys);
+
+ return typeof result === 'undefined' ? true : result;
+};
+
+// search for [key1][key2]...[keyN]
+// return the object or undefined if not found
+exports.deep_find = function deep_find(obj, keys /* or key1, key2 .... */ ) {
+ if ( !Array.isArray(keys) ) {
+ keys = Array.prototype.slice.call(arguments, 1);
+ }
+
+ return exports.process_munge(obj, false/*createParents?*/, function (parentArray, k) {
+ return _.find(parentArray, function (element) {
+ return element.xml == (k.xml || k);
+ });
+ }, keys);
+};
+
+// Execute func passing it the parent array and the xmlChild key.
+// When createParents is true, add the file and parent items they are missing
+// When createParents is false, stop and return undefined if the file and/or parent items are missing
+
+exports.process_munge = function process_munge(obj, createParents, func, keys /* or key1, key2 .... */ ) {
+ if ( !Array.isArray(keys) ) {
+ keys = Array.prototype.slice.call(arguments, 1);
+ }
+ var k = keys[0];
+ if (keys.length == 1) {
+ return func(obj, k);
+ } else if (keys.length == 2) {
+ if (!obj.parents[k] && !createParents) {
+ return undefined;
+ }
+ obj.parents[k] = obj.parents[k] || [];
+ return exports.process_munge(obj.parents[k], createParents, func, keys.slice(1));
+ } else if (keys.length == 3){
+ if (!obj.files[k] && !createParents) {
+ return undefined;
+ }
+ obj.files[k] = obj.files[k] || { parents: {} };
+ return exports.process_munge(obj.files[k], createParents, func, keys.slice(1));
+ } else {
+ throw new Error('Invalid key format. Must contain at most 3 elements (file, parent, xmlChild).');
+ }
+};
+
+// All values from munge are added to base as
+// base[file][selector][child] += munge[file][selector][child]
+// Returns a munge object containing values that exist in munge
+// but not in base.
+exports.increment_munge = function increment_munge(base, munge) {
+ var diff = { files: {} };
+
+ for (var file in munge.files) {
+ for (var selector in munge.files[file].parents) {
+ for (var xml_child in munge.files[file].parents[selector]) {
+ var val = munge.files[file].parents[selector][xml_child];
+ // if node not in base, add it to diff and base
+ // else increment it's value in base without adding to diff
+ var newlyAdded = exports.deep_add(base, [file, selector, val]);
+ if (newlyAdded) {
+ exports.deep_add(diff, file, selector, val);
+ }
+ }
+ }
+ }
+ return diff;
+};
+
+// Update the base munge object as
+// base[file][selector][child] -= munge[file][selector][child]
+// nodes that reached zero value are removed from base and added to the returned munge
+// object.
+exports.decrement_munge = function decrement_munge(base, munge) {
+ var zeroed = { files: {} };
+
+ for (var file in munge.files) {
+ for (var selector in munge.files[file].parents) {
+ for (var xml_child in munge.files[file].parents[selector]) {
+ var val = munge.files[file].parents[selector][xml_child];
+ // if node not in base, add it to diff and base
+ // else increment it's value in base without adding to diff
+ var removed = exports.deep_remove(base, [file, selector, val]);
+ if (removed) {
+ exports.deep_add(zeroed, file, selector, val);
+ }
+ }
+ }
+ }
+ return zeroed;
+};
+
+// For better readability where used
+exports.clone_munge = function clone_munge(munge) {
+ return exports.increment_munge({}, munge);
+};
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org