You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by br...@apache.org on 2013/12/11 22:54:23 UTC

[04/15] refactoring to small modules

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/ubuntu/platform.js
----------------------------------------------------------------------
diff --git a/src/ubuntu/platform.js b/src/ubuntu/platform.js
new file mode 100644
index 0000000..3871545
--- /dev/null
+++ b/src/ubuntu/platform.js
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ *
+*/
+module.exports = {
+    id: "ubuntu",
+    bootstrap: function() {
+        var channel = require("cordova/channel"),
+            cordova = require('cordova'),
+            exec = require('cordova/exec'),
+            modulemapper = require('cordova/modulemapper');
+
+        modulemapper.clobbers('cordova/exec/proxy', 'cordova.commandProxy');
+        require('cordova/channel').onNativeReady.fire();
+    }
+};

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/windows8/exec.js
----------------------------------------------------------------------
diff --git a/src/windows8/exec.js b/src/windows8/exec.js
new file mode 100644
index 0000000..6720572
--- /dev/null
+++ b/src/windows8/exec.js
@@ -0,0 +1,80 @@
+/*
+ *
+ * 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.
+ *
+*/
+
+/*jslint sloppy:true, plusplus:true*/
+/*global require, module, console */
+
+var cordova = require('cordova');
+var execProxy = require('cordova/exec/proxy');
+
+/**
+ * Execute a cordova command.  It is up to the native side whether this action
+ * is synchronous or asynchronous.  The native side can return:
+ *      Synchronous: PluginResult object as a JSON string
+ *      Asynchronous: Empty string ""
+ * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
+ * depending upon the result of the action.
+ *
+ * @param {Function} success    The success callback
+ * @param {Function} fail       The fail callback
+ * @param {String} service      The name of the service to use
+ * @param {String} action       Action to be run in cordova
+ * @param {String[]} [args]     Zero or more arguments to pass to the method
+ */
+module.exports = function (success, fail, service, action, args) {
+
+    var proxy = execProxy.get(service, action),
+        callbackId,
+        onSuccess,
+        onError;
+
+    if (proxy) {
+        callbackId = service + cordova.callbackId++;
+        // console.log("EXEC:" + service + " : " + action);
+        if (typeof success === "function" || typeof fail === "function") {
+            cordova.callbacks[callbackId] = {success: success, fail: fail};
+        }
+        try {
+            onSuccess = function (result) {
+                cordova.callbackSuccess(callbackId,
+                        {
+                        status: cordova.callbackStatus.OK,
+                        message: result
+                    });
+            };
+            onError = function (err) {
+                cordova.callbackError(callbackId,
+                        {
+                        status: cordova.callbackStatus.ERROR,
+                        message: err
+                    });
+            };
+            proxy(onSuccess, onError, args);
+
+        } catch (e) {
+            console.log("Exception calling native with command :: " + service + " :: " + action  + " ::exception=" + e);
+        }
+    } else {
+        if (typeof fail === "function") {
+            fail("Missing Command Error");
+        }
+    }
+};

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/windows8/platform.js
----------------------------------------------------------------------
diff --git a/src/windows8/platform.js b/src/windows8/platform.js
new file mode 100755
index 0000000..67a564c
--- /dev/null
+++ b/src/windows8/platform.js
@@ -0,0 +1,62 @@
+/*
+ *
+ * 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.
+ *
+*/
+
+module.exports = {
+    id: 'windows8',
+    bootstrap:function() {
+        var cordova = require('cordova'),
+            exec = require('cordova/exec'),
+            channel = cordova.require('cordova/channel'),
+            modulemapper = require('cordova/modulemapper');
+
+        modulemapper.clobbers('cordova/exec/proxy', 'cordova.commandProxy');
+        channel.onNativeReady.fire();
+
+        var onWinJSReady = function () {
+            var app = WinJS.Application;
+            var checkpointHandler = function checkpointHandler() {
+                cordova.fireDocumentEvent('pause');
+            };
+
+            var resumingHandler = function resumingHandler() {
+                cordova.fireDocumentEvent('resume');
+            };
+
+            app.addEventListener("checkpoint", checkpointHandler);
+            Windows.UI.WebUI.WebUIApplication.addEventListener("resuming", resumingHandler, false);
+            app.start();
+
+        };
+
+        if (!window.WinJS) {
+            // <script src="//Microsoft.WinJS.1.0/js/base.js"></script>
+            var scriptElem = document.createElement("script");
+            scriptElem.src = "//Microsoft.WinJS.1.0/js/base.js";
+            scriptElem.addEventListener("load", onWinJSReady);
+            document.head.appendChild(scriptElem);
+
+            console.log("added WinJS ... ");
+        }
+        else {
+            onWinJSReady();
+        }
+    }
+};

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/windows8/windows8/commandProxy.js
----------------------------------------------------------------------
diff --git a/src/windows8/windows8/commandProxy.js b/src/windows8/windows8/commandProxy.js
new file mode 100644
index 0000000..cbdf720
--- /dev/null
+++ b/src/windows8/windows8/commandProxy.js
@@ -0,0 +1,23 @@
+/*
+ *
+ * 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.
+ *
+*/
+
+console.log('WARNING: please require cordova/exec/proxy instead');
+module.exports = require('cordova/exec/proxy');

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/windowsphone/exec.js
----------------------------------------------------------------------
diff --git a/src/windowsphone/exec.js b/src/windowsphone/exec.js
new file mode 100644
index 0000000..96eb306
--- /dev/null
+++ b/src/windowsphone/exec.js
@@ -0,0 +1,68 @@
+/*
+ *
+ * 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 cordova = require('cordova');
+
+/**
+ * Execute a cordova command.  It is up to the native side whether this action
+ * is synchronous or asynchronous.  The native side can return:
+ *      Synchronous: PluginResult object as a JSON string
+ *      Asynchronous: Empty string ""
+ * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
+ * depending upon the result of the action.
+ *
+ * @param {Function} success    The success callback
+ * @param {Function} fail       The fail callback
+ * @param {String} service      The name of the service to use
+ * @param {String} action       Action to be run in cordova
+ * @param {String[]} [args]     Zero or more arguments to pass to the method
+
+ */
+
+module.exports = function(success, fail, service, action, args) {
+
+    var callbackId = service + cordova.callbackId++;
+    if (typeof success == "function" || typeof fail == "function") {
+        cordova.callbacks[callbackId] = {success:success, fail:fail};
+    }
+    // generate a new command string, ex. DebugConsole/log/DebugConsole23/["wtf dude?"]
+    for(var n = 0; n < args.length; n++)
+    {
+        if(typeof args[n] !== "string")
+        {
+            args[n] = JSON.stringify(args[n]);
+        }
+    }
+    var command = service + "/" + action + "/" + callbackId + "/" + JSON.stringify(args);
+    // pass it on to Notify
+    try {
+        if(window.external) {
+            window.external.Notify(command);
+        }
+        else {
+            console.log("window.external not available :: command=" + command);
+        }
+    }
+    catch(e) {
+        console.log("Exception calling native with command :: " + command + " :: exception=" + e);
+    }
+};
+

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/windowsphone/platform.js
----------------------------------------------------------------------
diff --git a/src/windowsphone/platform.js b/src/windowsphone/platform.js
new file mode 100644
index 0000000..237d4f5
--- /dev/null
+++ b/src/windowsphone/platform.js
@@ -0,0 +1,34 @@
+/*
+ *
+ * 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.
+ *
+*/
+
+module.exports = {
+    id: 'windowsphone',
+    bootstrap: function() {
+        var cordova = require('cordova'),
+               exec = require('cordova/exec');
+
+        // Inject a listener for the backbutton, and tell native to override the flag (true/false) when we have 1 or more, or 0, listeners
+        var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
+        backButtonChannel.onHasSubscribersChange = function() {
+            exec(null, null, "CoreEvents", "overridebackbutton", [this.numHandlers == 1]);
+        };
+    }
+};

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/compile.js
----------------------------------------------------------------------
diff --git a/tasks/compile.js b/tasks/compile.js
new file mode 100644
index 0000000..a30fb7a
--- /dev/null
+++ b/tasks/compile.js
@@ -0,0 +1,30 @@
+/*
+ * 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 packager = require('./lib/packager');
+
+module.exports = function(grunt) {
+    grunt.registerMultiTask('compile', 'Packages cordova.js', function() {
+
+        var done = this.async();
+        var platformName = this.target;
+        var useWindowsLineEndings = this.data.useWindowsLineEndings;
+
+        packager.generate(platformName, useWindowsLineEndings, done);
+    });
+}

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/lib/LICENSE-for-js-file.txt
----------------------------------------------------------------------
diff --git a/tasks/lib/LICENSE-for-js-file.txt b/tasks/lib/LICENSE-for-js-file.txt
new file mode 100644
index 0000000..20f533b
--- /dev/null
+++ b/tasks/lib/LICENSE-for-js-file.txt
@@ -0,0 +1,16 @@
+ 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.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/lib/collect-file.js
----------------------------------------------------------------------
diff --git a/tasks/lib/collect-file.js b/tasks/lib/collect-file.js
new file mode 100644
index 0000000..6f62885
--- /dev/null
+++ b/tasks/lib/collect-file.js
@@ -0,0 +1,15 @@
+
+module.exports = function collectFile(dir, id, entry) {
+    if (!id) id = ''
+    var moduleId = path.join(id,  entry)
+    var fileName = path.join(dir, entry)
+    
+    var stat = fs.statSync(fileName)
+
+    var result = {};
+
+    moduleId         = getModuleId(moduleId)
+    result[moduleId] = fileName
+
+    return copyProps({}, result)
+}

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/lib/collect-files.js
----------------------------------------------------------------------
diff --git a/tasks/lib/collect-files.js b/tasks/lib/collect-files.js
new file mode 100644
index 0000000..13bee5b
--- /dev/null
+++ b/tasks/lib/collect-files.js
@@ -0,0 +1,28 @@
+module.exports = function collectFiles(dir, id) {
+    if (!id) id = ''
+
+    var result = {}    
+    var entries = fs.readdirSync(dir)
+
+    entries = entries.filter(function(entry) {
+        if (entry.match(/\.js$/)) return true
+        
+        var stat = fs.statSync(path.join(dir, entry))
+        if (stat.isDirectory())  return true
+    })
+
+    entries.forEach(function(entry) {
+        var moduleId = path.join(id, entry)
+        var fileName = path.join(dir, entry)
+        
+        var stat = fs.statSync(fileName)
+        if (stat.isDirectory()) {
+            copyProps(result, collectFiles(fileName, moduleId))
+        }
+        else {
+            moduleId         = getModuleId(moduleId)
+            result[moduleId] = fileName
+        }
+    })
+    return copyProps({}, result)
+}

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/lib/copy-props.js
----------------------------------------------------------------------
diff --git a/tasks/lib/copy-props.js b/tasks/lib/copy-props.js
new file mode 100644
index 0000000..8335bc8
--- /dev/null
+++ b/tasks/lib/copy-props.js
@@ -0,0 +1,10 @@
+
+module.exports = function copyProps(target, source) {
+
+    for (var key in source) {
+        if (!source.hasOwnProperty(key)) continue    
+        target[key] = source[key]
+    }
+    
+    return target
+}

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/lib/get-module-id.js
----------------------------------------------------------------------
diff --git a/tasks/lib/get-module-id.js b/tasks/lib/get-module-id.js
new file mode 100644
index 0000000..4d3cf75
--- /dev/null
+++ b/tasks/lib/get-module-id.js
@@ -0,0 +1,4 @@
+
+module.exports = function getModuleId(fileName) {
+    return fileName.match(/(.*)\.js$/)[1]
+}

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/lib/gv-requires.js
----------------------------------------------------------------------
diff --git a/tasks/lib/gv-requires.js b/tasks/lib/gv-requires.js
new file mode 100755
index 0000000..fb7684d
--- /dev/null
+++ b/tasks/lib/gv-requires.js
@@ -0,0 +1,133 @@
+#!/usr/bin/env node
+
+/*
+ * 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.
+ */
+
+fs   = require('fs')
+path = require('path')
+
+//------------------------------------------------------------------------------
+process.chdir(path.join(__dirname, ".."))
+
+var platforms = getPlatforms()
+
+console.log("//-------------------------------------------------------")
+console.log("// graphviz .dot file for Cordova requires by platform")
+console.log("// http://www.graphviz.org/")
+console.log("// ")
+console.log("//   - ./build/gv-requires.js > ~/tmp/requires.dot")
+console.log("//   - [edit dot file to leave just one digraph]")
+console.log("//   - dot -Tsvg ~/tmp/requires.dot > ~/tmp/requires.svg")
+console.log("//   - [open svg file in a browser]")
+console.log("//-------------------------------------------------------")
+console.log("")
+
+for (var i=0; i<platforms.length; i++) {
+    var platform = platforms[i]
+    
+    generateGraph(platform)
+}
+
+//------------------------------------------------------------------------------
+function getPlatforms() {
+    var entries = fs.readdirSync("pkg")
+    
+    var platforms = []
+    
+    for (var i=0; i<entries.length; i++) {
+        var entry = entries[i]
+        
+        var match = entry.match(/^cordova\.(.*)\.js$/)
+        if (match)
+            platforms.push(match[1])
+    }
+    
+    return platforms
+}
+
+//------------------------------------------------------------------------------
+function generateGraph(platform) {
+    var modules = {}
+    
+    var jsFile = path.join("pkg", "cordova." + platform + ".js")
+    
+    contents = fs.readFileSync(jsFile, 'utf-8')
+    contents = contents.replace(/\n/g, ' ')
+    
+    modulesSource = contents.split(/define\(/)
+    
+    console.log("//--------------------------------------------------")
+    console.log("// graphviz .dot file for " + platform)
+    console.log("//--------------------------------------------------")
+    console.log("digraph G {")
+    
+    for (var i=0; i< modulesSource.length; i++) {
+        var moduleSource = modulesSource[i];
+        
+        var match = moduleSource.match(/'(.*?)'(.*)/)
+        if (!match) continue
+        
+        var moduleName = match[1]
+        moduleSource   = match[2]
+        
+        if (moduleName.match(/\s/)) continue
+        if (moduleName   == "")     continue
+        if (moduleSource == "")     continue
+
+        modules[moduleName] = modules[moduleName] || []
+        // console.log("   found module " + moduleName)
+        
+        var requires = getRequires(moduleSource, modules[moduleName])
+        
+        for (var j=0; j < requires.length; j++) {
+            var gvModule  =  moduleName.replace(/\//g, '\\n')
+            var gvRequire = requires[j].replace(/\//g, '\\n')
+            
+            console.log('   "' + gvModule + '" -> "' + gvRequire + '";')
+        }
+        
+    }
+
+    console.log("}")
+    console.log("")
+}
+
+//------------------------------------------------------------------------------
+function getRequires(moduleSource, requires) {
+    var pattern = /.*?require\((.*?)\)(.*)/
+
+    var result = []
+//    console.log(moduleSource)
+    
+    var match = moduleSource.match(pattern)
+    
+    while (match) {
+        var require  = match[1]
+        moduleSource = match[2]
+        
+        require = require.replace(/'|"/g, '')
+        result.push(require)
+        
+        match = moduleSource.match(pattern)
+    }
+    
+    return result
+}
+
+    

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/lib/packager.js
----------------------------------------------------------------------
diff --git a/tasks/lib/packager.js b/tasks/lib/packager.js
new file mode 100644
index 0000000..7b0da47
--- /dev/null
+++ b/tasks/lib/packager.js
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF
+ * or more contributor license agreements.  See th
+ * distributed with this work for additional infor
+ * regarding copyright ownership.  The ASF license
+ * to you under the Apache License, Version 2.0 (t
+ * "License"); you may not use this file except in
+ * with the License.  You may obtain a copy of the
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to 
+ * software distributed under the License is distr
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * KIND, either express or implied.  See the Licen
+ * specific language governing permissions and lim
+ * under the License.
+ */
+
+var childProcess  = require('child_process');
+var fs            = require('fs');
+var util          = require('util');
+var path          = require('path');
+var stripHeader   = require('./strip-header');
+var copyProps     = require('./copy-props');
+var getModuleId   = require('./get-module-id');
+var writeContents = require('./write-contents');
+var writeModule   = require('./write-module');
+var writeScript   = require('./write-script');
+var collectFiles  = require('./collect-files');
+var collectFile   = require('./collect-file');
+
+
+
+
+
+var packager = module.exports
+var cachedGitVersion = null;
+
+packager.computeCommitId = function(callback) {
+
+    if (cachedGitVersion) {
+        callback(cachedGitVersion);
+        return;
+    }
+
+    var versionFileId = fs.readFileSync('VERSION', { encoding: 'utf8' }).trim();
+    
+    if (/-dev$/.test(versionFileId) && fs.existsSync('.git')) {
+        var gitPath = 'git';
+        var args = 'rev-list HEAD --max-count=1 --abbrev-commit';
+        childProcess.exec(gitPath + ' ' + args, function(err, stdout, stderr) {
+            var isWindows = process.platform.slice(0, 3) == 'win';
+            if (err && isWindows) {
+                gitPath = '"' + path.join(process.env['ProgramFiles'], 'Git', 'bin', 'git.exe') + '"';
+                childProcess.exec(gitPath + ' ' + args, function(err, stdout, stderr) {
+                    if (err) {
+                        error(err);
+                    } else {
+                        done(versionFileId + '-' + stdout);
+                    }
+                });
+            } else if (err) {
+                error(err);
+            } else {
+                done(versionFileId + '-' + stdout);
+            }
+        });
+    } else {
+        done(fs.readFileSync('VERSION', { encoding: 'utf8' }));
+    }
+
+    function error(err) {
+        throw new Error(err);
+    }
+
+    function done(stdout) {
+        var version = stdout.trim();
+        cachedGitVersion = version;
+        callback(version);
+    };
+}
+
+//------------------------------------------------------------------------------
+packager.generate = function(platform, useWindowsLineEndings, callback) {
+    packager.computeCommitId(function(commitId) {
+        var outFile;
+        var time = new Date().valueOf();
+
+        var libraryRelease = packager.bundle(platform, false, commitId);
+        // if we are using windows line endings, we will also add the BOM
+        if(useWindowsLineEndings) {
+            libraryRelease = "\ufeff" + libraryRelease.split(/\r?\n/).join("\r\n");
+        }
+        var libraryDebug   = packager.bundle(platform, true, commitId);
+        
+        time = new Date().valueOf() - time;
+        if (!fs.existsSync('pkg')) {
+            fs.mkdirSync('pkg');
+        }
+        if(!fs.existsSync('pkg/debug')) {
+            fs.mkdirSync('pkg/debug');
+        }
+
+        outFile = path.join('pkg', 'cordova.' + platform + '.js');
+        fs.writeFileSync(outFile, libraryRelease, 'utf8');
+        
+        outFile = path.join('pkg', 'debug', 'cordova.' + platform + '-debug.js');
+        fs.writeFileSync(outFile, libraryDebug, 'utf8');
+        
+        console.log('generated cordova.' + platform + '.js @ ' + commitId + ' in ' + time + 'ms');
+        callback();
+    });
+}
+
+//------------------------------------------------------------------------------
+packager.bundle = function(platform, debug, commitId) {
+    var modules = collectFiles('lib/common')
+    var scripts = collectFiles('lib/scripts')
+    
+    modules[''] = 'lib/cordova.js'
+    copyProps(modules, collectFiles(path.join('lib', platform)));
+
+    if (platform === 'test') {
+        copyProps(modules, collectFiles(path.join('lib', 'android', 'android'), 'android/'));
+    }
+
+    var output = [];
+	
+    output.push("// Platform: " + platform);
+    output.push("// "  + commitId);
+
+    // write header
+    output.push('/*', fs.readFileSync('LICENSE-for-js-file.txt', 'utf8'), '*/')
+    output.push(';(function() {')
+    output.push("var CORDOVA_JS_BUILD_LABEL = '"  + commitId + "';");
+
+    // write initial scripts
+    if (!scripts['require']) {
+        throw new Error("didn't find a script for 'require'")
+    }
+    
+    writeScript(output, scripts['require'], debug)
+
+    // write modules
+    var moduleIds = Object.keys(modules)
+    moduleIds.sort()
+    
+    for (var i=0; i<moduleIds.length; i++) {
+        var moduleId = moduleIds[i]
+        
+        writeModule(output, modules[moduleId], moduleId, debug)
+    }
+
+    output.push("window.cordova = require('cordova');")
+
+    // write final scripts
+    if (!scripts['bootstrap']) {
+        throw new Error("didn't find a script for 'bootstrap'")
+    }
+    
+    writeScript(output, scripts['bootstrap'], debug)
+    
+    var bootstrapPlatform = 'bootstrap-' + platform
+    if (scripts[bootstrapPlatform]) {
+        writeScript(output, scripts[bootstrapPlatform], debug)
+    }
+
+    // write trailer
+    output.push('})();')
+
+    return output.join('\n')
+}
+
+//------------------------------------------------------------------------------
+
+
+
+
+

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/lib/process-white-space.js
----------------------------------------------------------------------
diff --git a/tasks/lib/process-white-space.js b/tasks/lib/process-white-space.js
new file mode 100644
index 0000000..f071800
--- /dev/null
+++ b/tasks/lib/process-white-space.js
@@ -0,0 +1,66 @@
+var fs = require('fs');
+var path = require('path');
+
+// Iterates over a directory
+function forEachFile(root, cbFile, cbDone) {
+    var count = 0;
+
+    function scan(name) {
+        ++count;
+
+        fs.stat(name, function (err, stats) {
+            if (err) cbFile(err);
+
+            if (stats.isDirectory()) {
+                fs.readdir(name, function (err, files) {
+                    if (err) cbFile(err);
+
+                    files.forEach(function (file) {
+                        scan(path.join(name, file));
+                    });
+                    done();
+                });
+            } else if (stats.isFile()) {
+                cbFile(null, name, stats, done);
+            } else {
+                done();
+            }
+        });
+    }
+
+    function done() {
+        --count;
+        if (count === 0 && cbDone) cbDone();
+    }
+
+    scan(root);
+}
+
+module.exports = function processWhiteSpace(processor, callback) {
+
+    var rexp_minified = new RegExp("\\.min\\.js$");
+    var rexp_src = new RegExp('\\.js$');
+    
+    forEachFile('src', function(err, file, stats, cbDone) {
+        //if (err) throw err;
+        if (rexp_minified.test(file) || !rexp_src.test(file)) {
+            cbDone();
+        } else {
+            var origsrc = src = fs.readFileSync(file, 'utf8');
+
+            // tabs -> four spaces
+            if (src.indexOf('\t') >= 0) {
+                src = src.split('\t').join('    ');
+            }
+
+            // eliminate trailing white space
+            src = src.replace(/ +\n/g, '\n');
+
+            if (origsrc !== src) {
+                // write it out yo
+                processor(file, src);
+            }
+            cbDone();
+        }
+    }, callback);
+}

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/lib/strip-header.js
----------------------------------------------------------------------
diff --git a/tasks/lib/strip-header.js b/tasks/lib/strip-header.js
new file mode 100644
index 0000000..de6b25e
--- /dev/null
+++ b/tasks/lib/strip-header.js
@@ -0,0 +1,19 @@
+
+// Strips the license header. Basically only the first multi-line comment up to to the closing */
+module.exports = function stripHeader(contents, fileName) {
+    var ls = contents.split(/\r?\n/);
+    while (ls[0]) {
+        if (ls[0].match(/^\s*\/\*/) || ls[0].match(/^\s*\*/)) {
+            ls.shift();
+        }
+        else if (ls[0].match(/^\s*\*\//)) {
+            ls.shift();
+            break;
+        }
+        else {
+        	console.log("WARNING: file name " + fileName + " is missing the license header");
+        	break;
+    	}
+    }
+    return ls.join('\n');
+}

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/lib/write-contents.js
----------------------------------------------------------------------
diff --git a/tasks/lib/write-contents.js b/tasks/lib/write-contents.js
new file mode 100644
index 0000000..083245a
--- /dev/null
+++ b/tasks/lib/write-contents.js
@@ -0,0 +1,22 @@
+
+module.exports = function writeContents(oFile, fileName, contents, debug) {
+    
+    if (debug) {
+        contents += '\n//@ sourceURL=' + fileName
+        
+        contents = 'eval(' + JSON.stringify(contents) + ')'
+        
+        // this bit makes it easier to identify modules
+        // with syntax errors in them
+        var handler = 'console.log("exception: in ' + fileName + ': " + e);'
+        handler += 'console.log(e.stack);'
+        
+        contents = 'try {' + contents + '} catch(e) {' + handler + '}'
+    }
+    
+    else {
+        contents = '// file: ' + fileName.split("\\").join("/") + '\n' + contents;
+    }
+
+    oFile.push(contents)
+}

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/lib/write-module.js
----------------------------------------------------------------------
diff --git a/tasks/lib/write-module.js b/tasks/lib/write-module.js
new file mode 100644
index 0000000..6d8efde
--- /dev/null
+++ b/tasks/lib/write-module.js
@@ -0,0 +1,16 @@
+
+module.exports = function writeModule(oFile, fileName, moduleId, debug) {
+    var contents = fs.readFileSync(fileName, 'utf8')
+
+    contents = '\n' + stripHeader(contents, fileName) + '\n'
+
+	// Windows fix, '\' is an escape, but defining requires '/' -jm
+    moduleId = path.join('cordova', moduleId).split("\\").join("/");
+    
+    var signature = 'function(require, exports, module)';
+    
+    contents = 'define("' + moduleId + '", ' + signature + ' {' + contents + '});\n'
+
+    writeContents(oFile, fileName, contents, debug)    
+}
+

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/lib/write-script.js
----------------------------------------------------------------------
diff --git a/tasks/lib/write-script.js b/tasks/lib/write-script.js
new file mode 100644
index 0000000..a666bd5
--- /dev/null
+++ b/tasks/lib/write-script.js
@@ -0,0 +1,8 @@
+var fs = require('fs');
+
+module.exports = function writeScript(oFile, fileName, debug) {
+    var contents = fs.readFileSync(fileName, 'utf8')
+
+    contents = stripHeader(contents, fileName);
+    writeContents(oFile, fileName, contents, debug);
+}

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/test.js
----------------------------------------------------------------------
diff --git a/tasks/test.js b/tasks/test.js
new file mode 100644
index 0000000..c0bb274
--- /dev/null
+++ b/tasks/test.js
@@ -0,0 +1,29 @@
+/*
+ * 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.
+*/
+module.exports = function(grunt) {
+    grunt.registerTask('_test', 'Runs test in node', function() {
+        var done = this.async();
+        require('./../test/runner').node(done);
+    });
+
+    grunt.registerTask('_btest', 'Runs tests in the browser', function() {
+        require('./../test/runner').browser();
+        this.async(); // never finish.
+    });
+}

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/README.txt
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/README.txt b/tasks/vendor/commonjs-tests/README.txt
new file mode 100644
index 0000000..21ce798
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/README.txt
@@ -0,0 +1,9 @@
+The test cases contained in this directory were obtained from the
+commonjs project at GitHub:
+
+   https://github.com/commonjs/commonjs
+
+Specifically, the directories in the 'tests' subdirectory.
+
+See the file test/commonjs/README.txt off the root directory of this
+project for more information.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/absolute/b.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/absolute/b.js b/tasks/vendor/commonjs-tests/modules/1.0/absolute/b.js
new file mode 100644
index 0000000..da5bf4f
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/absolute/b.js
@@ -0,0 +1 @@
+exports.foo = function() {};

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/absolute/program.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/absolute/program.js b/tasks/vendor/commonjs-tests/modules/1.0/absolute/program.js
new file mode 100644
index 0000000..7980ecf
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/absolute/program.js
@@ -0,0 +1,5 @@
+var test = require('test');
+var a = require('submodule/a');
+var b = require('b');
+test.assert(a.foo().foo === b.foo, 'require works with absolute identifiers');
+test.print('DONE', 'info');

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/absolute/submodule/a.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/absolute/submodule/a.js b/tasks/vendor/commonjs-tests/modules/1.0/absolute/submodule/a.js
new file mode 100644
index 0000000..bc138b8
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/absolute/submodule/a.js
@@ -0,0 +1,3 @@
+exports.foo = function () {
+    return require('b');
+};

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/absolute/test.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/absolute/test.js b/tasks/vendor/commonjs-tests/modules/1.0/absolute/test.js
new file mode 100644
index 0000000..5d0984e
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/absolute/test.js
@@ -0,0 +1,15 @@
+
+exports.print = typeof print !== "undefined" ? print : function () {
+    var system = require("system");
+    var stdio = system.stdio;
+    stdio.print.apply(stdio, arguments);
+};
+
+exports.assert = function (guard, message) {
+    if (guard) {
+        exports.print('PASS ' + message, 'pass');
+    } else {
+        exports.print('FAIL ' + message, 'fail');
+    }
+};
+

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/cyclic/a.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/cyclic/a.js b/tasks/vendor/commonjs-tests/modules/1.0/cyclic/a.js
new file mode 100644
index 0000000..e0188fa
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/cyclic/a.js
@@ -0,0 +1,4 @@
+exports.a = function () {
+    return b;
+};
+var b = require('b');

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/cyclic/b.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/cyclic/b.js b/tasks/vendor/commonjs-tests/modules/1.0/cyclic/b.js
new file mode 100644
index 0000000..873a305
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/cyclic/b.js
@@ -0,0 +1,4 @@
+var a = require('a');
+exports.b = function () {
+    return a;
+};

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/cyclic/program.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/cyclic/program.js b/tasks/vendor/commonjs-tests/modules/1.0/cyclic/program.js
new file mode 100644
index 0000000..2ee4758
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/cyclic/program.js
@@ -0,0 +1,10 @@
+var test = require('test');
+var a = require('a');
+var b = require('b');
+
+test.assert(a.a, 'a exists');
+test.assert(b.b, 'b exists')
+test.assert(a.a().b === b.b, 'a gets b');
+test.assert(b.b().a === a.a, 'b gets a');
+
+test.print('DONE', 'info');

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/cyclic/test.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/cyclic/test.js b/tasks/vendor/commonjs-tests/modules/1.0/cyclic/test.js
new file mode 100644
index 0000000..5d0984e
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/cyclic/test.js
@@ -0,0 +1,15 @@
+
+exports.print = typeof print !== "undefined" ? print : function () {
+    var system = require("system");
+    var stdio = system.stdio;
+    stdio.print.apply(stdio, arguments);
+};
+
+exports.assert = function (guard, message) {
+    if (guard) {
+        exports.print('PASS ' + message, 'pass');
+    } else {
+        exports.print('FAIL ' + message, 'fail');
+    }
+};
+

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/determinism/program.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/determinism/program.js b/tasks/vendor/commonjs-tests/modules/1.0/determinism/program.js
new file mode 100644
index 0000000..7c0e50b
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/determinism/program.js
@@ -0,0 +1,3 @@
+var test = require('test');
+require('submodule/a');
+test.print('DONE', 'info');

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/determinism/submodule/a.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/determinism/submodule/a.js b/tasks/vendor/commonjs-tests/modules/1.0/determinism/submodule/a.js
new file mode 100644
index 0000000..215ea1d
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/determinism/submodule/a.js
@@ -0,0 +1,9 @@
+var test = require('test');
+var pass = false;
+var test = require('test');
+try {
+    require('a');
+} catch (exception) {
+    pass = true;
+}
+test.assert(pass, 'require does not fall back to relative modules when absolutes are not available.')

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/determinism/submodule/b.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/determinism/submodule/b.js b/tasks/vendor/commonjs-tests/modules/1.0/determinism/submodule/b.js
new file mode 100644
index 0000000..139597f
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/determinism/submodule/b.js
@@ -0,0 +1,2 @@
+
+

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/determinism/test.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/determinism/test.js b/tasks/vendor/commonjs-tests/modules/1.0/determinism/test.js
new file mode 100644
index 0000000..5d0984e
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/determinism/test.js
@@ -0,0 +1,15 @@
+
+exports.print = typeof print !== "undefined" ? print : function () {
+    var system = require("system");
+    var stdio = system.stdio;
+    stdio.print.apply(stdio, arguments);
+};
+
+exports.assert = function (guard, message) {
+    if (guard) {
+        exports.print('PASS ' + message, 'pass');
+    } else {
+        exports.print('FAIL ' + message, 'fail');
+    }
+};
+

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/exactExports/a.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/exactExports/a.js b/tasks/vendor/commonjs-tests/modules/1.0/exactExports/a.js
new file mode 100644
index 0000000..99c929e
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/exactExports/a.js
@@ -0,0 +1,3 @@
+exports.program = function () {
+    return require('program');
+};

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/exactExports/program.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/exactExports/program.js b/tasks/vendor/commonjs-tests/modules/1.0/exactExports/program.js
new file mode 100644
index 0000000..e82bd6d
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/exactExports/program.js
@@ -0,0 +1,4 @@
+var test = require('test');
+var a = require('a');
+test.assert(a.program() === exports, 'exact exports');
+test.print('DONE', 'info');

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/exactExports/test.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/exactExports/test.js b/tasks/vendor/commonjs-tests/modules/1.0/exactExports/test.js
new file mode 100644
index 0000000..5d0984e
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/exactExports/test.js
@@ -0,0 +1,15 @@
+
+exports.print = typeof print !== "undefined" ? print : function () {
+    var system = require("system");
+    var stdio = system.stdio;
+    stdio.print.apply(stdio, arguments);
+};
+
+exports.assert = function (guard, message) {
+    if (guard) {
+        exports.print('PASS ' + message, 'pass');
+    } else {
+        exports.print('FAIL ' + message, 'fail');
+    }
+};
+

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/hasOwnProperty/hasOwnProperty.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/hasOwnProperty/hasOwnProperty.js b/tasks/vendor/commonjs-tests/modules/1.0/hasOwnProperty/hasOwnProperty.js
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/hasOwnProperty/program.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/hasOwnProperty/program.js b/tasks/vendor/commonjs-tests/modules/1.0/hasOwnProperty/program.js
new file mode 100644
index 0000000..1653f1b
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/hasOwnProperty/program.js
@@ -0,0 +1,4 @@
+var hasOwnProperty = require('hasOwnProperty');
+var toString = require('toString');
+var test = require('test');
+test.print('DONE', 'info');

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/hasOwnProperty/test.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/hasOwnProperty/test.js b/tasks/vendor/commonjs-tests/modules/1.0/hasOwnProperty/test.js
new file mode 100644
index 0000000..5d0984e
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/hasOwnProperty/test.js
@@ -0,0 +1,15 @@
+
+exports.print = typeof print !== "undefined" ? print : function () {
+    var system = require("system");
+    var stdio = system.stdio;
+    stdio.print.apply(stdio, arguments);
+};
+
+exports.assert = function (guard, message) {
+    if (guard) {
+        exports.print('PASS ' + message, 'pass');
+    } else {
+        exports.print('FAIL ' + message, 'fail');
+    }
+};
+

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/hasOwnProperty/toString.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/hasOwnProperty/toString.js b/tasks/vendor/commonjs-tests/modules/1.0/hasOwnProperty/toString.js
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/method/a.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/method/a.js b/tasks/vendor/commonjs-tests/modules/1.0/method/a.js
new file mode 100644
index 0000000..69c48af
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/method/a.js
@@ -0,0 +1,12 @@
+exports.foo = function () {
+    return this;
+};
+exports.set = function (x) {
+    this.x = x;
+};
+exports.get = function () {
+    return this.x;
+};
+exports.getClosed = function () {
+    return exports.x;
+};

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/method/program.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/method/program.js b/tasks/vendor/commonjs-tests/modules/1.0/method/program.js
new file mode 100644
index 0000000..192811c
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/method/program.js
@@ -0,0 +1,8 @@
+var test = require('test');
+var a = require('a');
+var foo = a.foo;
+test.assert(a.foo() == a, 'calling a module member');
+test.assert(foo() == (function (){return this})(), 'members not implicitly bound');
+a.set(10);
+test.assert(a.get() == 10, 'get and set')
+test.print('DONE', 'info');

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/method/test.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/method/test.js b/tasks/vendor/commonjs-tests/modules/1.0/method/test.js
new file mode 100644
index 0000000..5d0984e
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/method/test.js
@@ -0,0 +1,15 @@
+
+exports.print = typeof print !== "undefined" ? print : function () {
+    var system = require("system");
+    var stdio = system.stdio;
+    stdio.print.apply(stdio, arguments);
+};
+
+exports.assert = function (guard, message) {
+    if (guard) {
+        exports.print('PASS ' + message, 'pass');
+    } else {
+        exports.print('FAIL ' + message, 'fail');
+    }
+};
+

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/missing/program.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/missing/program.js b/tasks/vendor/commonjs-tests/modules/1.0/missing/program.js
new file mode 100644
index 0000000..c6b03aa
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/missing/program.js
@@ -0,0 +1,8 @@
+var test = require('test');
+try {
+    require('bogus');
+    test.print('FAIL require throws error when module missing', 'fail');
+} catch (exception) {
+    test.print('PASS require throws error when module missing', 'pass');
+}
+test.print('DONE', 'info');

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/missing/test.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/missing/test.js b/tasks/vendor/commonjs-tests/modules/1.0/missing/test.js
new file mode 100644
index 0000000..5d0984e
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/missing/test.js
@@ -0,0 +1,15 @@
+
+exports.print = typeof print !== "undefined" ? print : function () {
+    var system = require("system");
+    var stdio = system.stdio;
+    stdio.print.apply(stdio, arguments);
+};
+
+exports.assert = function (guard, message) {
+    if (guard) {
+        exports.print('PASS ' + message, 'pass');
+    } else {
+        exports.print('FAIL ' + message, 'fail');
+    }
+};
+

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/monkeys/a.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/monkeys/a.js b/tasks/vendor/commonjs-tests/modules/1.0/monkeys/a.js
new file mode 100644
index 0000000..a949e1d
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/monkeys/a.js
@@ -0,0 +1 @@
+require('program').monkey = 10;

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/monkeys/program.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/monkeys/program.js b/tasks/vendor/commonjs-tests/modules/1.0/monkeys/program.js
new file mode 100644
index 0000000..42d6711
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/monkeys/program.js
@@ -0,0 +1,4 @@
+var a = require('a');
+var test = require('test');
+test.assert(exports.monkey == 10, 'monkeys permitted');
+test.print('DONE', 'info');

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/monkeys/test.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/monkeys/test.js b/tasks/vendor/commonjs-tests/modules/1.0/monkeys/test.js
new file mode 100644
index 0000000..5d0984e
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/monkeys/test.js
@@ -0,0 +1,15 @@
+
+exports.print = typeof print !== "undefined" ? print : function () {
+    var system = require("system");
+    var stdio = system.stdio;
+    stdio.print.apply(stdio, arguments);
+};
+
+exports.assert = function (guard, message) {
+    if (guard) {
+        exports.print('PASS ' + message, 'pass');
+    } else {
+        exports.print('FAIL ' + message, 'fail');
+    }
+};
+

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/nested/a/b/c/d.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/nested/a/b/c/d.js b/tasks/vendor/commonjs-tests/modules/1.0/nested/a/b/c/d.js
new file mode 100644
index 0000000..69fd282
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/nested/a/b/c/d.js
@@ -0,0 +1,3 @@
+exports.foo = function () {
+    return 1;
+};

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/nested/program.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/nested/program.js b/tasks/vendor/commonjs-tests/modules/1.0/nested/program.js
new file mode 100644
index 0000000..c014b57
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/nested/program.js
@@ -0,0 +1,3 @@
+var test = require('test');
+test.assert(require('a/b/c/d').foo() == 1, 'nested module identifier');
+test.print('DONE', 'info');

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/nested/test.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/nested/test.js b/tasks/vendor/commonjs-tests/modules/1.0/nested/test.js
new file mode 100644
index 0000000..5d0984e
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/nested/test.js
@@ -0,0 +1,15 @@
+
+exports.print = typeof print !== "undefined" ? print : function () {
+    var system = require("system");
+    var stdio = system.stdio;
+    stdio.print.apply(stdio, arguments);
+};
+
+exports.assert = function (guard, message) {
+    if (guard) {
+        exports.print('PASS ' + message, 'pass');
+    } else {
+        exports.print('FAIL ' + message, 'fail');
+    }
+};
+

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/relative/program.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/relative/program.js b/tasks/vendor/commonjs-tests/modules/1.0/relative/program.js
new file mode 100644
index 0000000..b3e4b6e
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/relative/program.js
@@ -0,0 +1,5 @@
+var test = require('test');
+var a = require('submodule/a');
+var b = require('submodule/b');
+test.assert(a.foo == b.foo, 'a and b share foo through a relative require');
+test.print('DONE', 'info');

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/relative/submodule/a.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/relative/submodule/a.js b/tasks/vendor/commonjs-tests/modules/1.0/relative/submodule/a.js
new file mode 100644
index 0000000..42e4ca0
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/relative/submodule/a.js
@@ -0,0 +1 @@
+exports.foo = require('./b').foo;

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/relative/submodule/b.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/relative/submodule/b.js b/tasks/vendor/commonjs-tests/modules/1.0/relative/submodule/b.js
new file mode 100644
index 0000000..9042c16
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/relative/submodule/b.js
@@ -0,0 +1,2 @@
+exports.foo = function () {
+};

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/relative/test.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/relative/test.js b/tasks/vendor/commonjs-tests/modules/1.0/relative/test.js
new file mode 100644
index 0000000..5d0984e
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/relative/test.js
@@ -0,0 +1,15 @@
+
+exports.print = typeof print !== "undefined" ? print : function () {
+    var system = require("system");
+    var stdio = system.stdio;
+    stdio.print.apply(stdio, arguments);
+};
+
+exports.assert = function (guard, message) {
+    if (guard) {
+        exports.print('PASS ' + message, 'pass');
+    } else {
+        exports.print('FAIL ' + message, 'fail');
+    }
+};
+

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/transitive/a.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/transitive/a.js b/tasks/vendor/commonjs-tests/modules/1.0/transitive/a.js
new file mode 100644
index 0000000..4df7bb8
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/transitive/a.js
@@ -0,0 +1 @@
+exports.foo = require('b').foo;

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/transitive/b.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/transitive/b.js b/tasks/vendor/commonjs-tests/modules/1.0/transitive/b.js
new file mode 100644
index 0000000..30ea70d
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/transitive/b.js
@@ -0,0 +1 @@
+exports.foo = require('c').foo;

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/transitive/c.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/transitive/c.js b/tasks/vendor/commonjs-tests/modules/1.0/transitive/c.js
new file mode 100644
index 0000000..69fd282
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/transitive/c.js
@@ -0,0 +1,3 @@
+exports.foo = function () {
+    return 1;
+};

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/transitive/program.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/transitive/program.js b/tasks/vendor/commonjs-tests/modules/1.0/transitive/program.js
new file mode 100644
index 0000000..98bb996
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/transitive/program.js
@@ -0,0 +1,3 @@
+var test = require('test');
+test.assert(require('a').foo() == 1, 'transitive');
+test.print('DONE', 'info');

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/commonjs-tests/modules/1.0/transitive/test.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/commonjs-tests/modules/1.0/transitive/test.js b/tasks/vendor/commonjs-tests/modules/1.0/transitive/test.js
new file mode 100644
index 0000000..5d0984e
--- /dev/null
+++ b/tasks/vendor/commonjs-tests/modules/1.0/transitive/test.js
@@ -0,0 +1,15 @@
+
+exports.print = typeof print !== "undefined" ? print : function () {
+    var system = require("system");
+    var stdio = system.stdio;
+    stdio.print.apply(stdio, arguments);
+};
+
+exports.assert = function (guard, message) {
+    if (guard) {
+        exports.print('PASS ' + message, 'pass');
+    } else {
+        exports.print('FAIL ' + message, 'fail');
+    }
+};
+

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/jasmine/MIT.LICENSE
----------------------------------------------------------------------
diff --git a/tasks/vendor/jasmine/MIT.LICENSE b/tasks/vendor/jasmine/MIT.LICENSE
new file mode 100644
index 0000000..7c435ba
--- /dev/null
+++ b/tasks/vendor/jasmine/MIT.LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2008-2011 Pivotal Labs
+
+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-js/blob/d9a3dced/tasks/vendor/jasmine/jasmine-html.js
----------------------------------------------------------------------
diff --git a/tasks/vendor/jasmine/jasmine-html.js b/tasks/vendor/jasmine/jasmine-html.js
new file mode 100644
index 0000000..423d3ea
--- /dev/null
+++ b/tasks/vendor/jasmine/jasmine-html.js
@@ -0,0 +1,190 @@
+jasmine.TrivialReporter = function(doc) {
+  this.document = doc || document;
+  this.suiteDivs = {};
+  this.logRunningSpecs = false;
+};
+
+jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
+  var el = document.createElement(type);
+
+  for (var i = 2; i < arguments.length; i++) {
+    var child = arguments[i];
+
+    if (typeof child === 'string') {
+      el.appendChild(document.createTextNode(child));
+    } else {
+      if (child) { el.appendChild(child); }
+    }
+  }
+
+  for (var attr in attrs) {
+    if (attr == "className") {
+      el[attr] = attrs[attr];
+    } else {
+      el.setAttribute(attr, attrs[attr]);
+    }
+  }
+
+  return el;
+};
+
+jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
+  var showPassed, showSkipped;
+
+  this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' },
+      this.createDom('div', { className: 'banner' },
+        this.createDom('div', { className: 'logo' },
+            this.createDom('span', { className: 'title' }, "Jasmine"),
+            this.createDom('span', { className: 'version' }, runner.env.versionString())),
+        this.createDom('div', { className: 'options' },
+            "Show ",
+            showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
+            this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
+            showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
+            this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
+            )
+          ),
+
+      this.runnerDiv = this.createDom('div', { className: 'runner running' },
+          this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
+          this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
+          this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
+      );
+
+  this.document.body.appendChild(this.outerDiv);
+
+  var suites = runner.suites();
+  for (var i = 0; i < suites.length; i++) {
+    var suite = suites[i];
+    var suiteDiv = this.createDom('div', { className: 'suite' },
+        this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
+        this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
+    this.suiteDivs[suite.id] = suiteDiv;
+    var parentDiv = this.outerDiv;
+    if (suite.parentSuite) {
+      parentDiv = this.suiteDivs[suite.parentSuite.id];
+    }
+    parentDiv.appendChild(suiteDiv);
+  }
+
+  this.startedAt = new Date();
+
+  var self = this;
+  showPassed.onclick = function(evt) {
+    if (showPassed.checked) {
+      self.outerDiv.className += ' show-passed';
+    } else {
+      self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
+    }
+  };
+
+  showSkipped.onclick = function(evt) {
+    if (showSkipped.checked) {
+      self.outerDiv.className += ' show-skipped';
+    } else {
+      self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
+    }
+  };
+};
+
+jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
+  var results = runner.results();
+  var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
+  this.runnerDiv.setAttribute("class", className);
+  //do it twice for IE
+  this.runnerDiv.setAttribute("className", className);
+  var specs = runner.specs();
+  var specCount = 0;
+  for (var i = 0; i < specs.length; i++) {
+    if (this.specFilter(specs[i])) {
+      specCount++;
+    }
+  }
+  var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
+  message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
+  this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
+
+  this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
+};
+
+jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
+  var results = suite.results();
+  var status = results.passed() ? 'passed' : 'failed';
+  if (results.totalCount === 0) { // todo: change this to check results.skipped
+    status = 'skipped';
+  }
+  this.suiteDivs[suite.id].className += " " + status;
+};
+
+jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
+  if (this.logRunningSpecs) {
+    this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
+  }
+};
+
+jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
+  var results = spec.results();
+  var status = results.passed() ? 'passed' : 'failed';
+  if (results.skipped) {
+    status = 'skipped';
+  }
+  var specDiv = this.createDom('div', { className: 'spec '  + status },
+      this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
+      this.createDom('a', {
+        className: 'description',
+        href: '?spec=' + encodeURIComponent(spec.getFullName()),
+        title: spec.getFullName()
+      }, spec.description));
+
+
+  var resultItems = results.getItems();
+  var messagesDiv = this.createDom('div', { className: 'messages' });
+  for (var i = 0; i < resultItems.length; i++) {
+    var result = resultItems[i];
+
+    if (result.type == 'log') {
+      messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
+    } else if (result.type == 'expect' && result.passed && !result.passed()) {
+      messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
+
+      if (result.trace.stack) {
+        messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
+      }
+    }
+  }
+
+  if (messagesDiv.childNodes.length > 0) {
+    specDiv.appendChild(messagesDiv);
+  }
+
+  this.suiteDivs[spec.suite.id].appendChild(specDiv);
+};
+
+jasmine.TrivialReporter.prototype.log = function() {
+  var console = jasmine.getGlobal().console;
+  if (console && console.log) {
+    if (console.log.apply) {
+      console.log.apply(console, arguments);
+    } else {
+      console.log(arguments); // IE fix: console.log.apply doesn't exist in IE
+    }
+  }
+};
+
+jasmine.TrivialReporter.prototype.getLocation = function() {
+  return this.document.location;
+};
+
+jasmine.TrivialReporter.prototype.specFilter = function(spec) {
+  var paramMap = {};
+  var params = this.getLocation().search.substring(1).split('&');
+  for (var i = 0; i < params.length; i++) {
+    var p = params[i].split('=');
+    paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
+  }
+
+  if (!paramMap.spec) {
+    return true;
+  }
+  return spec.getFullName().indexOf(paramMap.spec) === 0;
+};

http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/tasks/vendor/jasmine/jasmine.css
----------------------------------------------------------------------
diff --git a/tasks/vendor/jasmine/jasmine.css b/tasks/vendor/jasmine/jasmine.css
new file mode 100644
index 0000000..6583fe7
--- /dev/null
+++ b/tasks/vendor/jasmine/jasmine.css
@@ -0,0 +1,166 @@
+body {
+  font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif;
+}
+
+
+.jasmine_reporter a:visited, .jasmine_reporter a {
+  color: #303; 
+}
+
+.jasmine_reporter a:hover, .jasmine_reporter a:active {
+  color: blue; 
+}
+
+.run_spec {
+  float:right;
+  padding-right: 5px;
+  font-size: .8em;
+  text-decoration: none;
+}
+
+.jasmine_reporter {
+  margin: 0 5px;
+}
+
+.banner {
+  color: #303;
+  background-color: #fef;
+  padding: 5px;
+}
+
+.logo {
+  float: left;
+  font-size: 1.1em;
+  padding-left: 5px;
+}
+
+.logo .version {
+  font-size: .6em;
+  padding-left: 1em;
+}
+
+.runner.running {
+  background-color: yellow;
+}
+
+
+.options {
+  text-align: right;
+  font-size: .8em;
+}
+
+
+
+
+.suite {
+  border: 1px outset gray;
+  margin: 5px 0;
+  padding-left: 1em;
+}
+
+.suite .suite {
+  margin: 5px; 
+}
+
+.suite.passed {
+  background-color: #dfd;
+}
+
+.suite.failed {
+  background-color: #fdd;
+}
+
+.spec {
+  margin: 5px;
+  padding-left: 1em;
+  clear: both;
+}
+
+.spec.failed, .spec.passed, .spec.skipped {
+  padding-bottom: 5px;
+  border: 1px solid gray;
+}
+
+.spec.failed {
+  background-color: #fbb;
+  border-color: red;
+}
+
+.spec.passed {
+  background-color: #bfb;
+  border-color: green;
+}
+
+.spec.skipped {
+  background-color: #bbb;
+}
+
+.messages {
+  border-left: 1px dashed gray;
+  padding-left: 1em;
+  padding-right: 1em;
+}
+
+.passed {
+  background-color: #cfc;
+  display: none;
+}
+
+.failed {
+  background-color: #fbb;
+}
+
+.skipped {
+  color: #777;
+  background-color: #eee;
+  display: none;
+}
+
+
+/*.resultMessage {*/
+  /*white-space: pre;*/
+/*}*/
+
+.resultMessage span.result {
+  display: block;
+  line-height: 2em;
+  color: black;
+}
+
+.resultMessage .mismatch {
+  color: black;
+}
+
+.stackTrace {
+  white-space: pre;
+  font-size: .8em;
+  margin-left: 10px;
+  max-height: 5em;
+  overflow: auto;
+  border: 1px inset red;
+  padding: 1em;
+  background: #eef;
+}
+
+.finished-at {
+  padding-left: 1em;
+  font-size: .6em;
+}
+
+.show-passed .passed,
+.show-skipped .skipped {
+  display: block;
+}
+
+
+#jasmine_content {
+  position:fixed;
+  right: 100%;
+}
+
+.runner {
+  border: 1px solid gray;
+  display: block;
+  margin: 5px 0;
+  padding: 2px 0 2px 10px;
+}