cordova-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ste...@apache.org
Subject [12/27] webos commit: Updated with refactorization
Date Thu, 18 Jun 2015 06:40:50 GMT
http://git-wip-us.apache.org/repos/asf/cordova-webos/blob/242b6c27/bin/templates/project/cordova/lib/ares-spawn.js
----------------------------------------------------------------------
diff --git a/bin/templates/project/cordova/lib/ares-spawn.js b/bin/templates/project/cordova/lib/ares-spawn.js
new file mode 100755
index 0000000..47f6fb6
--- /dev/null
+++ b/bin/templates/project/cordova/lib/ares-spawn.js
@@ -0,0 +1,52 @@
+#!/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.
+*/
+
+var child_process = require('child_process'),
+        Q  = require('q');
+var isWindows = process.platform.slice(0, 3) == 'win';
+
+// Takes an ares command and optional current working directory.
+module.exports = function(cmd, args, stdio, opt_cwd) {
+    var d = Q.defer();
+    stdio = stdio || "inherit";
+    try {
+        // Work around spawn not being able to find .cmd files.
+        if (isWindows) {
+            args.unshift('/s', '/c', cmd);
+            cmd = 'cmd';
+        } else {
+            cmd += ".sh";
+        }
+        var child = child_process.spawn(cmd, args, {cwd: opt_cwd, stdio: stdio});
+        child.on('exit', function(code) {
+            if(code===0) {
+                d.resolve();
+            } else {
+                d.reject('Error code ' + code + ' for command: ' + cmd + ' with args: ' + args);
+            }
+        });
+    } catch(e) {
+        console.error('error caught: ' + e);
+        d.reject(e);
+    }
+    return d.promise;
+}
+

http://git-wip-us.apache.org/repos/asf/cordova-webos/blob/242b6c27/bin/templates/project/cordova/lib/build.js
----------------------------------------------------------------------
diff --git a/bin/templates/project/cordova/lib/build.js b/bin/templates/project/cordova/lib/build.js
new file mode 100755
index 0000000..21b78bb
--- /dev/null
+++ b/bin/templates/project/cordova/lib/build.js
@@ -0,0 +1,82 @@
+#!/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.
+*/
+
+var shell = require("shelljs"),
+    spawn = require("./ares-spawn"),
+    Q = require("q"),
+    path = require("path"),
+    fs = require("fs"),
+    ROOT = path.join(__dirname, "..", "..");
+
+
+/*
+ * Builds the project with ares-package.
+ * Returns a promise.
+ */
+module.exports.run = function(build_type) {
+    build_type = typeof build_type !== "undefined" ? build_type : "";
+    var binDir = path.join(ROOT, "bin");
+    if(!fs.existsSync(binDir)) {
+        shell.mkdir("-p", binDir);
+    }
+    var args = ["-o", path.join(ROOT, "bin")];
+    if(build_type==="--debug" || build_type==="--no-minify"
+            || build_type==="--enyo-debug") {
+        args.push("-n");
+    }
+    args.push(path.join(ROOT, "www"));
+    return spawn("ares-package", args);
+}
+
+/*
+ * Gets the path to the ipk file, if not such file exists then
+ * the script will error out.
+ */
+module.exports.get_ipk = function() {
+    var binDir = path.join(ROOT, "bin");
+    if (fs.existsSync(binDir)) {
+        var candidates = fs.readdirSync(binDir).filter(function(p) {
+            // Need to find most recent .ipk.
+            return path.extname(p) == ".ipk";
+        }).map(function(p) {
+            p = path.join(binDir, p);
+            return { p: p, t: fs.statSync(p).mtime };
+        }).sort(function(a,b) {
+            return a.t > b.t ? -1 :
+                   a.t < b.t ? 1 : 0;
+        });
+        if (candidates.length === 0) {
+            console.error("ERROR : No .ipk found in " + binDir + " directory");
+            process.exit(2);
+        }
+        console.log("Using ipk: " + candidates[0].p);
+        return candidates[0].p;
+    } else {
+        console.error("ERROR : unable to find project " + binDir + " directory, could not locate .ipk");
+        process.exit(2);
+    }
+}
+
+module.exports.help = function() {
+    console.log("Usage: " + path.relative(process.cwd(), path.join(ROOT, 'cordova', 'build')) + " [options]");
+    console.log("    '--debug|--no-minify': Will build the project without minification phase");
+    process.exit(0);
+}

http://git-wip-us.apache.org/repos/asf/cordova-webos/blob/242b6c27/bin/templates/project/cordova/lib/emulator.js
----------------------------------------------------------------------
diff --git a/bin/templates/project/cordova/lib/emulator.js b/bin/templates/project/cordova/lib/emulator.js
new file mode 100755
index 0000000..b8d4142
--- /dev/null
+++ b/bin/templates/project/cordova/lib/emulator.js
@@ -0,0 +1,126 @@
+var virtualbox = require('./virtualbox.js');
+var exec = require('child_process').exec;
+
+var timeout = {id:undefined};
+
+module.exports = {
+	is_running: function(callback) {
+		module.exports.active_emulator(function(vm) {
+			callback(vm!==undefined);
+		});
+	},
+	active_emulator: function(callback) {
+		virtualbox.list(function(allVMs) {
+			var runningVMs = [];
+			// look for active webOS VMs
+			for(var x in allVMs) {
+				if(allVMs[x].running && allVMs[x].name) {
+					var name = allVMs[x].name.toLowerCase();
+					allVMs[x].id = x;
+					if(name.indexOf("webos")>-1) {
+						callback(allVMs[x]);
+						return;
+					} else {
+						runningVMs.push(allVMs[x]);
+					}
+				}
+			}
+			// check for legacy emulator VMs
+			var checkVM = function(status) {
+				if(status || runningVMs.length===0) {
+					callback(status);
+				} else {
+					var curr = runningVMs.pop();
+					virtualbox.info(curr.id, function(info) {
+						if(info["Forwarding(0)"] && info["Forwarding(0)"].indexOf("palm")>-1) {
+							checkVM(curr);
+						} else {
+							checkVM();
+						}
+					});
+				}
+			};
+			checkVM();
+		});
+	},
+	wait_for_emulator: function(callback) {
+		var count = 0;
+		var TIMECAP = 20000;
+
+		var nextTimeout = function(funct) {
+			if(count>=TIMECAP) {
+				callback(new Error("Emulator connection timeout"));
+			} else {
+				count+= 2000;
+				setTimeout(funct, 2000);
+			}
+		};
+		var wait = function() {
+			module.exports.active_emulator(function(vm) {
+				if(vm) {
+					callback();
+				} else {
+					nextTimeout(wait);
+				}
+			});
+		}
+		setTimeout(wait, 5000);
+	},
+	webos_images: function(callback) {
+		virtualbox.list(function(availableVMs) {
+			var webOS_VMs = {};
+			for(var x in availableVMs) {
+				if(availableVMs[x] && availableVMs[x].name) {
+					var name = availableVMs[x].name.toLowerCase();
+					if(name.indexOf("webos")>-1) {
+						webOS_VMs[x] = availableVMs[x];
+					}
+				}
+			}
+			callback(webOS_VMs);
+		});
+	},
+	legacy_emulator: function(callback) {
+		exec("palm-emulator", function (err, stdout, stderr) {
+			callback(err);
+		});
+	},
+	start_emulator: function(callback) {
+		module.exports.webos_images(function(webOS_VMs) {
+			var vm;
+			for(var x in webOS_VMs) {
+				vm = x;
+				if(webOS_VMs[x].name==="LG webOS TV Emulator") {
+					// ideal default VM name for SmartTV SDK-installed VM
+					break;
+				}
+			}
+			var emu_started = function(err) {
+				if(err) {
+					console.error("Unable to start emulator");
+				};
+				callback(err);
+			}
+			if(vm) {
+				virtualbox.start(vm, true, emu_started);
+			} else {
+				module.exports.legacy_emulator(emu_started);
+			}
+		});
+		
+	},
+	stop_emulator: function(callback) {
+		module.exports.active_emulator(function(active) {
+			if(active) {
+				virtualbox.poweroff(active.id, function(err) {
+					if(err) {
+						console.error("Unable to poweroff emulator");
+					};
+					callback(err);
+				});
+			} else {
+				callback();
+			}
+		})
+	}
+};

http://git-wip-us.apache.org/repos/asf/cordova-webos/blob/242b6c27/bin/templates/project/cordova/lib/run.js
----------------------------------------------------------------------
diff --git a/bin/templates/project/cordova/lib/run.js b/bin/templates/project/cordova/lib/run.js
new file mode 100755
index 0000000..80c9961
--- /dev/null
+++ b/bin/templates/project/cordova/lib/run.js
@@ -0,0 +1,112 @@
+#!/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.
+*/
+
+var path  = require("path"),
+    fs = require("fs"),
+    build = require("./build"),
+    spawn = require("./ares-spawn"),
+    emu = require("./emulator"),
+    Q = require("q"),
+    ROOT = path.join(__dirname, "..", "..");
+
+
+
+/*
+ * Runs the application
+ * Returns a promise.
+ */
+module.exports.run = function(args) {
+  var build_type;
+  var install_target;
+
+  for (var i=2; i<args.length; i++) {
+      if (args[i] == "--debug" || args[i] == "--no-minify" || args[i] == "--enyo-debug") {
+          build_type = "--debug";
+      } else if (args[i] == "--emulator") {
+          install_target = "emulator";
+      } else if (args[i].substring(0, 9) == "--target=") {
+          install_target = args[i].substring(9, args[i].length);
+      }
+  }
+
+  var launchEmulatorIfNeeded = function() {
+    var d = Q.defer();
+    if(install_target==="emulator") {
+      emu.start_emulator(function(err1) {
+        if(err1) {
+          d.reject(err1);
+        } else {
+          emu.wait_for_emulator(function(err2) {
+            if(err2) {
+              d.reject(err2);
+            } else {
+              d.resolve();
+            }
+          });
+        }
+      });
+    } else {
+      d.resolve();
+    }
+    return d.promise;
+  }
+
+  return build.run(build_type).then(launchEmulatorIfNeeded).then(function() {
+      var installArgs = [];
+      if(install_target) {
+          installArgs.push("-d", install_target);
+      }
+      installArgs.push(build.get_ipk());
+      return spawn("ares-install", installArgs).then(function() {
+          var appinfoPath = path.join(ROOT, "www", "appinfo.json");
+          if(fs.existsSync(appinfoPath)) {
+              try {
+                  var appinfo = JSON.parse(fs.readFileSync(appinfoPath));
+                  return module.exports.launch(appinfo.id);
+              } catch(e) {
+                  console.error("ERROR : Unable to read \"appinfo.json\"; cannot determine appID to launch.");
+                  process.exit(2);
+              }
+            }
+      });
+  });
+};
+
+/*
+ * Runs the application
+ * Returns a promise.
+ */
+module.exports.launch = function(appID) {
+  var doLaunch = function() {
+      return spawn("ares-launch", [appID]);
+  };
+  // close application if it's open, then launch
+  return spawn("ares-launch", ["-c", appID], "ignore").then(doLaunch, doLaunch);
+};
+
+module.exports.help = function() {
+    console.log("Usage: " + path.relative(process.cwd(), path.join(ROOT, 'cordova', 'run')) + " [options]");
+    console.log("Build options :");
+    console.log("    --debug|--no-minify : Builds project without minification");
+    console.log("    --emulator : Will deploy the built project to an emulator if one exists");
+    console.log("    --target=<target_id> : Installs to the target with the specified id.");
+    process.exit(0);
+};

http://git-wip-us.apache.org/repos/asf/cordova-webos/blob/242b6c27/bin/templates/project/cordova/lib/virtualbox.js
----------------------------------------------------------------------
diff --git a/bin/templates/project/cordova/lib/virtualbox.js b/bin/templates/project/cordova/lib/virtualbox.js
new file mode 100755
index 0000000..a398060
--- /dev/null
+++ b/bin/templates/project/cordova/lib/virtualbox.js
@@ -0,0 +1,362 @@
+/*
+	Copyright © 2012-2014 Azer Koculu. All Rights Reserved. 
+	https://github.com/azer/node-virtualbox
+	
+	Additional contributions by Michael Sanford, Steffen Roegner, Jakub Lekstan, 
+	Christopher Najewicz, Cédric Belin, and Jason Robitaille.
+
+	Redistribution and use in source and binary forms, with or without modification, 
+	are permitted provided that the following conditions are met:
+
+	1. Redistributions of source code must retain the above copyright notice, 
+	this list of conditions and the following disclaimer.
+
+	2. Redistributions in binary form must reproduce the above copyright notice, 
+	this list of conditions and the following disclaimer in the documentation and/or 
+	other materials provided with the distribution.
+
+	3. The name of the author may not be used to endorse or promote products derived 
+	from this software without specific prior written permission.
+
+	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
+	EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
+	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+	SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 
+	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
+	GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
+	CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
+	EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+"use strict";
+
+var exec = require('child_process').exec,
+	host_platform = process.platform,
+	vBoxManageBinary,
+	known_OS_types = {
+		WINDOWS: 'windows',
+		MAC: 'mac',
+		LINUX: 'linux'
+	};
+
+
+// Host operating system
+if (/^win/.test(host_platform)) {
+
+	// Path may not contain VBoxManage.exe but it provides this environment variable
+	var vBoxInstallPath = process.env.VBOX_INSTALL_PATH || process.env.VBOX_MSI_INSTALL_PATH;
+	vBoxManageBinary = '"' + vBoxInstallPath + '\\VBoxManage.exe' + '" ';
+
+} else if (/^darwin/.test(host_platform) || /^linux/.test(host_platform)) {
+
+	// Mac OS X and most Linux use the same binary name, in the path
+	vBoxManageBinary = 'vboxmanage ';
+
+} else {
+
+	// Otherwise (e.g., SunOS) hope it's in the path
+	vBoxManageBinary = 'vboxmanage ';
+
+}
+
+function command(cmd, callback) {
+	exec(cmd, function(err, stdout, stderr) {
+
+		if (!err && stderr && cmd.indexOf("pause") !== -1 && cmd.indexOf("savestate") !== -1) {
+			err = new Error(stderr);
+		}
+
+		callback(err, stdout);
+	});
+}
+
+function vboxcontrol(cmd, callback) {
+	command('VBoxControl ' + cmd, callback);
+}
+
+function vboxmanage(cmd, callback) {
+	command(vBoxManageBinary + cmd, callback);
+}
+
+function pause(vmname, callback) {
+	vboxmanage('controlvm "' + vmname + '" pause', function(error, stdout) {
+		callback(error);
+	});
+}
+
+function list(callback) {
+	vboxmanage('list "runningvms"', function(error, stdout) {
+		var _list = {};
+		var _runningvms = parse_listdata(stdout);
+		vboxmanage('list "vms"', function(error, full_stdout) {
+			var _all = parse_listdata(full_stdout);
+			var _keys = Object.keys(_all);
+			for (var _i = 0; _i < _keys.length; _i += 1) {
+				var _key = _keys[_i];
+				if (_runningvms[_key]) {
+					_all[_key].running = true;
+				} else {
+					_all[_key].running = false;
+				}
+			}
+			callback(_all, error);
+		});
+	});
+}
+
+function parse_listdata(raw_data) {
+	var _raw = raw_data.split(/\r?\n/g);
+	var _data = {};
+	if (_raw.length > 0) {
+		for (var _i = 0; _i < _raw.length; _i += 1) {
+			var _line = _raw[_i];
+			if (_line === '') {
+				continue;
+			}
+			// "centos6" {64ec13bb-5889-4352-aee9-0f1c2a17923d}
+			var rePattern = /^"(.+)" \{(.+)\}$/;
+			var arrMatches = _line.match(rePattern);
+			// {'64ec13bb-5889-4352-aee9-0f1c2a17923d': 'centos6'}
+			if (arrMatches && arrMatches.length === 3) {
+				_data[arrMatches[2].toString()] = {
+					name: arrMatches[1].toString()
+				};
+			}
+		}
+	}
+	return _data;
+}
+
+function info(vmname, callback) {
+	vboxmanage('showvminfo "' + vmname + '" --machinereadable', function(error, stdout) {
+		var info = {};
+		var data = stdout.split(/\r?\n/g);
+		for(var i=0; i<data.length; i++) {
+			if(data[i].length>0) {
+				var index = data[i].indexOf("=");
+				if(index>0) {
+					var key = parse_infoentry(data[i].substring(0, index));
+					var value = parse_infoentry(data[i].substring(index+1));
+					info[key] = value;
+				}
+			}
+		}
+		callback(info);
+	});
+}
+
+function parse_infoentry(entry) {
+	if(entry.length>1 && entry.charAt(0)=="\"") {
+		entry = entry.substring(1);
+	}
+	if(entry.length>1 && entry.charAt(entry.length-1)=="\"") {
+		entry = entry.substring(0, entry.length-1);
+	}
+	return entry;
+}
+
+function reset(vmname, callback) {
+	vboxmanage('controlvm "' + vmname + '" reset', function(error, stdout) {
+		callback(error);
+	});
+}
+
+function resume(vmname, callback) {
+	vboxmanage('controlvm "' + vmname + '" resume', function(error, stdout) {
+		callback(error);
+	});
+}
+
+function start(vmname, use_gui, callback) {
+	var start_opts = ' --type ';
+	if ((typeof use_gui) === 'function') {
+		callback = use_gui;
+		use_gui = false;
+	}
+	start_opts += (use_gui ? 'gui' : 'headless');
+
+	vboxmanage('-nologo startvm "' + vmname + '"' + start_opts, function(error, stdout) {
+		if (error && /VBOX_E_INVALID_OBJECT_STATE/.test(error.message)) {
+			error = undefined;
+		}
+		callback(error);
+	});
+}
+
+function stop(vmname, callback) {
+	vboxmanage('controlvm "' + vmname + '" savestate', function(error, stdout) {
+		callback(error);
+	});
+}
+
+function savestate(vmname, callback) {
+	stop(vmname, callback);
+}
+
+function poweroff(vmname, callback) {
+	vboxmanage('controlvm "' + vmname + '" poweroff', function(error, stdout) {
+		callback(error);
+	});
+}
+
+function acpipowerbutton(vmname, callback) {
+	vboxmanage('controlvm "' + vmname + '" acpipowerbutton', function(error, stdout) {
+		callback(error);
+	});
+}
+
+function acpisleepbutton(vmname, callback) {
+	vboxmanage('controlvm "' + vmname + '" acpisleepbutton', function(error, stdout) {
+		callback(error);
+	});
+}
+
+function vmExec(options, callback) {
+	var vm = options.vm || options.name || options.vmname || options.title,
+		username = options.user || options.username || 'Guest',
+		password = options.pass || options.passwd || options.password,
+		path = options.path || options.cmd || options.command || options.exec || options.execute || options.run,
+		cmd,
+		params = options.params || options.parameters || options.args;
+
+	if (Array.isArray(params)) {
+		params = params.join(" ");
+	}
+
+	if (params === undefined) {
+		params = "";
+	}
+
+	guestproperty.os(vm, getOSTypeCb);
+
+	function getOSTypeCb(os_type) {
+		var cmd = 'guestcontrol "' + vm + '"';
+
+		switch (os_type) {
+			case known_OS_types.WINDOWS:
+				path = path.replace(/\\/g, '\\\\');
+				cmd += ' execute	--image "cmd.exe" --username ' + username + (password ? ' --password ' + password : '') + ' -- "/c" "' + path + '" "' + params + '"';
+				break;
+			case known_OS_types.MAC:
+				cmd += ' execute	--image "/usr/bin/open -a" --username ' + username + (password ? ' --password ' + password : '') + ' -- "/c" "' + path + '" "' + params + '"';
+				break;
+			case known_OS_types.LINUX:
+				cmd += ' execute	--image "/bin/sh" --username ' + username + (password ? ' --password ' + password : '') + ' -- "/c" "' + path + '" "' + params + '"';
+				break;
+			default:
+				break;
+		}
+
+		vboxmanage(cmd, function(error, stdout) {
+			callback(error);
+		});
+	}
+
+}
+
+function vmKill(options, callback) {
+	options = options || {};
+	var vm = options.vm || options.name || options.vmname || options.title,
+		path = options.path || options.cmd || options.command || options.exec || options.execute || options.run,
+		image_name = options.image_name || path,
+		cmd = 'guestcontrol "' + vm + '" process kill';
+
+	guestproperty.os(vm, function(os_type) {
+		switch (os_type) {
+			case known_OS_types.WINDOWS:
+				vmExec({
+					vm: vm,
+					user: options.user,
+					password: options.password,
+					path: 'C:\\Windows\\System32\\taskkill.exe /im ',
+					params: image_name
+				}, callback);
+				break;
+			case known_OS_types.MAC:
+			case known_OS_types.LINUX:
+				vmExec({
+					vm: vm,
+					user: options.user,
+					password: options.password,
+					path: 'sudo killall ',
+					params: image_name
+				}, callback);
+				break;
+		}
+	});
+
+}
+
+var guestproperty = {
+	get: function(options, callback) {
+		var vm = options.vm || options.name || options.vmname || options.title,
+			key = options.key,
+			value = options.defaultValue || options.value;
+
+		guestproperty.os(vm, getOSTypeCallback);
+
+		function getOSTypeCallback(os_type) {
+			var cmd = 'guestproperty get "' + vm + '" ' + key;
+			vboxmanage(cmd, function(error, stdout) {
+				if (error) {
+					throw error;
+				}
+				var value = stdout.substr(stdout.indexOf(':') + 1).trim();
+				if (value === 'No value set!') {
+					value = undefined;
+				}
+				callback(value);
+			});
+		}
+
+	},
+
+	os_type: null, // cached
+
+	os: function(vmname, callback) {
+		function getOSTypeCallback(error, stdout, stderr) {
+			if (error) {
+				throw error;
+			}
+
+			// The ostype is matched against the ID attribute of 'vboxmanage list ostypes'
+			if (stdout.indexOf('ostype="Windows') !== -1) {
+				guestproperty.os_type = known_OS_types.WINDOWS;
+			} else if (stdout.indexOf('ostype="MacOS') !== -1) {
+				guestproperty.os_type = known_OS_types.MAC;
+			} else {
+				guestproperty.os_type = known_OS_types.LINUX;
+			}
+			callback(guestproperty.os_type);
+		}
+
+		if (guestproperty.os_type) {
+			return callback(guestproperty.os_type);
+		}
+
+		try {
+			exec(vBoxManageBinary + 'showvminfo -machinereadable "' + vmname + '"', getOSTypeCallback);
+		} catch (e) {
+			console.error('Could not showvminfo for ' + vmname);
+		}
+	}
+
+};
+
+module.exports = {
+	'exec': vmExec,
+	'kill': vmKill,
+	'list': list,
+	'info': info,
+	'pause': pause,
+	'reset': reset,
+	'resume': resume,
+	'start': start,
+	'stop': stop,
+	'savestate': savestate,
+	'poweroff': poweroff,
+	'acpisleepbutton': acpisleepbutton,
+	'acpipowerbutton': acpipowerbutton,
+	'guestproperty': guestproperty
+};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-webos/blob/242b6c27/bin/templates/project/www/appinfo.json
----------------------------------------------------------------------
diff --git a/bin/templates/project/www/appinfo.json b/bin/templates/project/www/appinfo.json
new file mode 100755
index 0000000..f0fc03c
--- /dev/null
+++ b/bin/templates/project/www/appinfo.json
@@ -0,0 +1,10 @@
+{
+	"id": "org.apache.cordova.example",
+	"version": "0.0.1",
+	"vendor": "Apache Cordova Team",
+	"type": "web",
+	"main": "index.html",
+	"title": "CordovaExample",
+	"icon": "img/logo.png",
+	"uiRevision":2
+}

http://git-wip-us.apache.org/repos/asf/cordova-webos/blob/242b6c27/bin/templates/project/www/css/index.css
----------------------------------------------------------------------
diff --git a/bin/templates/project/www/css/index.css b/bin/templates/project/www/css/index.css
new file mode 100755
index 0000000..be178b7
--- /dev/null
+++ b/bin/templates/project/www/css/index.css
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+* {
+    -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
+}
+
+body {
+    -webkit-touch-callout: none;                /* prevent callout to copy image, etc when tap to hold */
+    -webkit-text-size-adjust: none;             /* prevent webkit from resizing text to fit */
+    -webkit-user-select: none;                  /* prevent copy paste, to allow, change 'none' to 'text' */
+    background-color:#E4E4E4;
+    background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+    background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+    background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+    background-image:-webkit-gradient(
+        linear,
+        left top,
+        left bottom,
+        color-stop(0, #A7A7A7),
+        color-stop(0.51, #E4E4E4)
+    );
+    background-attachment:fixed;
+    font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
+    font-size:12px;
+    height:100%;
+    margin:0px;
+    padding:0px;
+    text-transform:uppercase;
+    width:100%;
+}
+
+/* Portrait layout (default) */
+.app {
+    background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
+    position:absolute;             /* position in the center of the screen */
+    left:50%;
+    top:50%;
+    height:50px;                   /* text area height */
+    width:225px;                   /* text area width */
+    text-align:center;
+    padding:180px 0px 0px 0px;     /* image height is 200px (bottom 20px are overlapped with text) */
+    margin:-115px 0px 0px -112px;  /* offset vertical: half of image height and text area height */
+                                   /* offset horizontal: half of text area width */
+}
+
+/* Landscape layout (with min-width) */
+@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
+    .app {
+        background-position:left center;
+        padding:75px 0px 75px 170px;  /* padding-top + padding-bottom + text area = image height */
+        margin:-90px 0px 0px -198px;  /* offset vertical: half of image height */
+                                      /* offset horizontal: half of image width and text area width */
+    }
+}
+
+h1 {
+    font-size:24px;
+    font-weight:normal;
+    margin:0px;
+    overflow:visible;
+    padding:0px;
+    text-align:center;
+}
+
+.event {
+    border-radius:4px;
+    -webkit-border-radius:4px;
+    color:#FFFFFF;
+    font-size:12px;
+    margin:0px 30px;
+    padding:2px 0px;
+}
+
+.event.listening {
+    background-color:#333333;
+    display:block;
+}
+
+.event.received {
+    background-color:#4B946A;
+    display:none;
+}
+
+@keyframes fade {
+    from { opacity: 1.0; }
+    50% { opacity: 0.4; }
+    to { opacity: 1.0; }
+}
+ 
+@-webkit-keyframes fade {
+    from { opacity: 1.0; }
+    50% { opacity: 0.4; }
+    to { opacity: 1.0; }
+}
+ 
+.blink {
+    animation:fade 3000ms infinite;
+    -webkit-animation:fade 3000ms infinite;
+}

http://git-wip-us.apache.org/repos/asf/cordova-webos/blob/242b6c27/bin/templates/project/www/img/logo.png
----------------------------------------------------------------------
diff --git a/bin/templates/project/www/img/logo.png b/bin/templates/project/www/img/logo.png
new file mode 100755
index 0000000..9519e7d
Binary files /dev/null and b/bin/templates/project/www/img/logo.png differ

http://git-wip-us.apache.org/repos/asf/cordova-webos/blob/242b6c27/bin/templates/project/www/index.html
----------------------------------------------------------------------
diff --git a/bin/templates/project/www/index.html b/bin/templates/project/www/index.html
new file mode 100755
index 0000000..3bd1b6d
--- /dev/null
+++ b/bin/templates/project/www/index.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!--
+    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.
+-->
+<html>
+    <head>
+        <meta charset="utf-8" />
+        <meta name="format-detection" content="telephone=no" />
+        <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
+        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
+        <link rel="stylesheet" type="text/css" href="css/index.css" />
+        <title>Hello World</title>
+    </head>
+    <body>
+        <div class="app">
+            <h1>Apache Cordova</h1>
+            <div id="deviceready" class="blink">
+                <p class="event listening">Connecting to Device</p>
+                <p class="event received">Device is Ready</p>
+            </div>
+        </div>
+        <script type="text/javascript" src="cordova.js"></script>
+        <script type="text/javascript" src="js/index.js"></script>
+        <script type="text/javascript">
+            app.initialize();
+        </script>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-webos/blob/242b6c27/bin/templates/project/www/js/index.js
----------------------------------------------------------------------
diff --git a/bin/templates/project/www/js/index.js b/bin/templates/project/www/js/index.js
new file mode 100755
index 0000000..5bba3a9
--- /dev/null
+++ b/bin/templates/project/www/js/index.js
@@ -0,0 +1,49 @@
+/*
+ * 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 app = {
+    // Application Constructor
+    initialize: function() {
+        this.bindEvents();
+    },
+    // Bind Event Listeners
+    //
+    // Bind any events that are required on startup. Common events are:
+    // 'load', 'deviceready', 'offline', and 'online'.
+    bindEvents: function() {
+        document.addEventListener('deviceready', this.onDeviceReady, false);
+    },
+    // deviceready Event Handler
+    //
+    // The scope of 'this' is the event. In order to call the 'receivedEvent'
+    // function, we must explicity call 'app.receivedEvent(...);'
+    onDeviceReady: function() {
+        app.receivedEvent('deviceready');
+    },
+    // Update DOM on a Received Event
+    receivedEvent: function(id) {
+        var parentElement = document.getElementById(id);
+        var listeningElement = parentElement.querySelector('.listening');
+        var receivedElement = parentElement.querySelector('.received');
+
+        listeningElement.setAttribute('style', 'display:none;');
+        receivedElement.setAttribute('style', 'display:block;');
+
+        console.log('Received Event: ' + id);
+    }
+};

http://git-wip-us.apache.org/repos/asf/cordova-webos/blob/242b6c27/bin/templates/project/www/spec.html
----------------------------------------------------------------------
diff --git a/bin/templates/project/www/spec.html b/bin/templates/project/www/spec.html
new file mode 100755
index 0000000..6f4f6db
--- /dev/null
+++ b/bin/templates/project/www/spec.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<!--
+    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.
+-->
+<html>
+    <head>
+        <title>Jasmine Spec Runner</title>
+
+        <!-- jasmine source -->
+        <link rel="shortcut icon" type="image/png" href="spec/lib/jasmine-1.2.0/jasmine_favicon.png">
+        <link rel="stylesheet" type="text/css" href="spec/lib/jasmine-1.2.0/jasmine.css">
+        <script type="text/javascript" src="spec/lib/jasmine-1.2.0/jasmine.js"></script>
+        <script type="text/javascript" src="spec/lib/jasmine-1.2.0/jasmine-html.js"></script>
+
+        <!-- include source files here... -->
+        <script type="text/javascript" src="js/index.js"></script>
+
+        <!-- include spec files here... -->
+        <script type="text/javascript" src="spec/helper.js"></script>
+        <script type="text/javascript" src="spec/index.js"></script>
+
+        <script type="text/javascript">
+            (function() {
+                var jasmineEnv = jasmine.getEnv();
+                jasmineEnv.updateInterval = 1000;
+
+                var htmlReporter = new jasmine.HtmlReporter();
+
+                jasmineEnv.addReporter(htmlReporter);
+
+                jasmineEnv.specFilter = function(spec) {
+                    return htmlReporter.specFilter(spec);
+                };
+
+                var currentWindowOnload = window.onload;
+
+                window.onload = function() {
+                    if (currentWindowOnload) {
+                        currentWindowOnload();
+                    }
+                    execJasmine();
+                };
+
+                function execJasmine() {
+                    jasmineEnv.execute();
+                }
+            })();
+        </script>
+    </head>
+    <body>
+        <div id="stage" style="display:none;"></div>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-webos/blob/242b6c27/bin/templates/project/www/spec/helper.js
----------------------------------------------------------------------
diff --git a/bin/templates/project/www/spec/helper.js b/bin/templates/project/www/spec/helper.js
new file mode 100755
index 0000000..98e84d8
--- /dev/null
+++ b/bin/templates/project/www/spec/helper.js
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+afterEach(function() {
+    document.getElementById('stage').innerHTML = '';
+});
+
+var helper = {
+    trigger: function(obj, name) {
+        var e = document.createEvent('Event');
+        e.initEvent(name, true, true);
+        obj.dispatchEvent(e);
+    },
+    getComputedStyle: function(querySelector, property) {
+        var element = document.querySelector(querySelector);
+        return window.getComputedStyle(element).getPropertyValue(property);
+    }
+};

http://git-wip-us.apache.org/repos/asf/cordova-webos/blob/242b6c27/bin/templates/project/www/spec/index.js
----------------------------------------------------------------------
diff --git a/bin/templates/project/www/spec/index.js b/bin/templates/project/www/spec/index.js
new file mode 100755
index 0000000..f9f729a
--- /dev/null
+++ b/bin/templates/project/www/spec/index.js
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+describe('app', function() {
+    describe('initialize', function() {
+        it('should bind deviceready', function() {
+            runs(function() {
+                spyOn(app, 'onDeviceReady');
+                app.initialize();
+                helper.trigger(window.document, 'deviceready');
+            });
+
+            waitsFor(function() {
+                return (app.onDeviceReady.calls.length > 0);
+            }, 'onDeviceReady should be called once', 500);
+
+            runs(function() {
+                expect(app.onDeviceReady).toHaveBeenCalled();
+            });
+        });
+    });
+
+    describe('onDeviceReady', function() {
+        it('should report that it fired', function() {
+            spyOn(app, 'receivedEvent');
+            app.onDeviceReady();
+            expect(app.receivedEvent).toHaveBeenCalledWith('deviceready');
+        });
+    });
+
+    describe('receivedEvent', function() {
+        beforeEach(function() {
+            var el = document.getElementById('stage');
+            el.innerHTML = ['<div id="deviceready">',
+                            '    <p class="event listening">Listening</p>',
+                            '    <p class="event received">Received</p>',
+                            '</div>'].join('\n');
+        });
+
+        it('should hide the listening element', function() {
+            app.receivedEvent('deviceready');
+            var displayStyle = helper.getComputedStyle('#deviceready .listening', 'display');
+            expect(displayStyle).toEqual('none');
+        });
+
+        it('should show the received element', function() {
+            app.receivedEvent('deviceready');
+            var displayStyle = helper.getComputedStyle('#deviceready .received', 'display');
+            expect(displayStyle).toEqual('block');
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-webos/blob/242b6c27/bin/templates/project/www/spec/lib/jasmine-1.2.0/MIT.LICENSE
----------------------------------------------------------------------
diff --git a/bin/templates/project/www/spec/lib/jasmine-1.2.0/MIT.LICENSE b/bin/templates/project/www/spec/lib/jasmine-1.2.0/MIT.LICENSE
new file mode 100755
index 0000000..d6cfd3f
--- /dev/null
+++ b/bin/templates/project/www/spec/lib/jasmine-1.2.0/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-webos/blob/242b6c27/bin/templates/project/www/spec/lib/jasmine-1.2.0/jasmine-html.js
----------------------------------------------------------------------
diff --git a/bin/templates/project/www/spec/lib/jasmine-1.2.0/jasmine-html.js b/bin/templates/project/www/spec/lib/jasmine-1.2.0/jasmine-html.js
new file mode 100755
index 0000000..108750b
--- /dev/null
+++ b/bin/templates/project/www/spec/lib/jasmine-1.2.0/jasmine-html.js
@@ -0,0 +1,616 @@
+jasmine.HtmlReporterHelpers = {};
+
+jasmine.HtmlReporterHelpers.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.HtmlReporterHelpers.getSpecStatus = function(child) {
+  var results = child.results();
+  var status = results.passed() ? 'passed' : 'failed';
+  if (results.skipped) {
+    status = 'skipped';
+  }
+
+  return status;
+};
+
+jasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) {
+  var parentDiv = this.dom.summary;
+  var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite';
+  var parent = child[parentSuite];
+
+  if (parent) {
+    if (typeof this.views.suites[parent.id] == 'undefined') {
+      this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views);
+    }
+    parentDiv = this.views.suites[parent.id].element;
+  }
+
+  parentDiv.appendChild(childElement);
+};
+
+
+jasmine.HtmlReporterHelpers.addHelpers = function(ctor) {
+  for(var fn in jasmine.HtmlReporterHelpers) {
+    ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn];
+  }
+};
+
+jasmine.HtmlReporter = function(_doc) {
+  var self = this;
+  var doc = _doc || window.document;
+
+  var reporterView;
+
+  var dom = {};
+
+  // Jasmine Reporter Public Interface
+  self.logRunningSpecs = false;
+
+  self.reportRunnerStarting = function(runner) {
+    var specs = runner.specs() || [];
+
+    if (specs.length == 0) {
+      return;
+    }
+
+    createReporterDom(runner.env.versionString());
+    doc.body.appendChild(dom.reporter);
+
+    reporterView = new jasmine.HtmlReporter.ReporterView(dom);
+    reporterView.addSpecs(specs, self.specFilter);
+  };
+
+  self.reportRunnerResults = function(runner) {
+    reporterView && reporterView.complete();
+  };
+
+  self.reportSuiteResults = function(suite) {
+    reporterView.suiteComplete(suite);
+  };
+
+  self.reportSpecStarting = function(spec) {
+    if (self.logRunningSpecs) {
+      self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
+    }
+  };
+
+  self.reportSpecResults = function(spec) {
+    reporterView.specComplete(spec);
+  };
+
+  self.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 on ie
+      }
+    }
+  };
+
+  self.specFilter = function(spec) {
+    if (!focusedSpecName()) {
+      return true;
+    }
+
+    return spec.getFullName().indexOf(focusedSpecName()) === 0;
+  };
+
+  return self;
+
+  function focusedSpecName() {
+    var specName;
+
+    (function memoizeFocusedSpec() {
+      if (specName) {
+        return;
+      }
+
+      var paramMap = [];
+      var params = doc.location.search.substring(1).split('&');
+
+      for (var i = 0; i < params.length; i++) {
+        var p = params[i].split('=');
+        paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
+      }
+
+      specName = paramMap.spec;
+    })();
+
+    return specName;
+  }
+
+  function createReporterDom(version) {
+    dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' },
+      dom.banner = self.createDom('div', { className: 'banner' },
+        self.createDom('span', { className: 'title' }, "Jasmine "),
+        self.createDom('span', { className: 'version' }, version)),
+
+      dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),
+      dom.alert = self.createDom('div', {className: 'alert'}),
+      dom.results = self.createDom('div', {className: 'results'},
+        dom.summary = self.createDom('div', { className: 'summary' }),
+        dom.details = self.createDom('div', { id: 'details' }))
+    );
+  }
+};
+jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);jasmine.HtmlReporter.ReporterView = function(dom) {
+  this.startedAt = new Date();
+  this.runningSpecCount = 0;
+  this.completeSpecCount = 0;
+  this.passedCount = 0;
+  this.failedCount = 0;
+  this.skippedCount = 0;
+
+  this.createResultsMenu = function() {
+    this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'},
+      this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: "#"}, '0 specs'),
+      ' | ',
+      this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: "#"}, '0 failing'));
+
+    this.summaryMenuItem.onclick = function() {
+      dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, '');
+    };
+
+    this.detailsMenuItem.onclick = function() {
+      showDetails();
+    };
+  };
+
+  this.addSpecs = function(specs, specFilter) {
+    this.totalSpecCount = specs.length;
+
+    this.views = {
+      specs: {},
+      suites: {}
+    };
+
+    for (var i = 0; i < specs.length; i++) {
+      var spec = specs[i];
+      this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views);
+      if (specFilter(spec)) {
+        this.runningSpecCount++;
+      }
+    }
+  };
+
+  this.specComplete = function(spec) {
+    this.completeSpecCount++;
+
+    if (isUndefined(this.views.specs[spec.id])) {
+      this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom);
+    }
+
+    var specView = this.views.specs[spec.id];
+
+    switch (specView.status()) {
+      case 'passed':
+        this.passedCount++;
+        break;
+
+      case 'failed':
+        this.failedCount++;
+        break;
+
+      case 'skipped':
+        this.skippedCount++;
+        break;
+    }
+
+    specView.refresh();
+    this.refresh();
+  };
+
+  this.suiteComplete = function(suite) {
+    var suiteView = this.views.suites[suite.id];
+    if (isUndefined(suiteView)) {
+      return;
+    }
+    suiteView.refresh();
+  };
+
+  this.refresh = function() {
+
+    if (isUndefined(this.resultsMenu)) {
+      this.createResultsMenu();
+    }
+
+    // currently running UI
+    if (isUndefined(this.runningAlert)) {
+      this.runningAlert = this.createDom('a', {href: "?", className: "runningAlert bar"});
+      dom.alert.appendChild(this.runningAlert);
+    }
+    this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount);
+
+    // skipped specs UI
+    if (isUndefined(this.skippedAlert)) {
+      this.skippedAlert = this.createDom('a', {href: "?", className: "skippedAlert bar"});
+    }
+
+    this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
+
+    if (this.skippedCount === 1 && isDefined(dom.alert)) {
+      dom.alert.appendChild(this.skippedAlert);
+    }
+
+    // passing specs UI
+    if (isUndefined(this.passedAlert)) {
+      this.passedAlert = this.createDom('span', {href: "?", className: "passingAlert bar"});
+    }
+    this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount);
+
+    // failing specs UI
+    if (isUndefined(this.failedAlert)) {
+      this.failedAlert = this.createDom('span', {href: "?", className: "failingAlert bar"});
+    }
+    this.failedAlert.innerHTML = "Failing " + specPluralizedFor(this.failedCount);
+
+    if (this.failedCount === 1 && isDefined(dom.alert)) {
+      dom.alert.appendChild(this.failedAlert);
+      dom.alert.appendChild(this.resultsMenu);
+    }
+
+    // summary info
+    this.summaryMenuItem.innerHTML = "" + specPluralizedFor(this.runningSpecCount);
+    this.detailsMenuItem.innerHTML = "" + this.failedCount + " failing";
+  };
+
+  this.complete = function() {
+    dom.alert.removeChild(this.runningAlert);
+
+    this.skippedAlert.innerHTML = "Ran " + this.runningSpecCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
+
+    if (this.failedCount === 0) {
+      dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, "Passing " + specPluralizedFor(this.passedCount)));
+    } else {
+      showDetails();
+    }
+
+    dom.banner.appendChild(this.createDom('span', {className: 'duration'}, "finished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"));
+  };
+
+  return this;
+
+  function showDetails() {
+    if (dom.reporter.className.search(/showDetails/) === -1) {
+      dom.reporter.className += " showDetails";
+    }
+  }
+
+  function isUndefined(obj) {
+    return typeof obj === 'undefined';
+  }
+
+  function isDefined(obj) {
+    return !isUndefined(obj);
+  }
+
+  function specPluralizedFor(count) {
+    var str = count + " spec";
+    if (count > 1) {
+      str += "s"
+    }
+    return str;
+  }
+
+};
+
+jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView);
+
+
+jasmine.HtmlReporter.SpecView = function(spec, dom, views) {
+  this.spec = spec;
+  this.dom = dom;
+  this.views = views;
+
+  this.symbol = this.createDom('li', { className: 'pending' });
+  this.dom.symbolSummary.appendChild(this.symbol);
+
+  this.summary = this.createDom('div', { className: 'specSummary' },
+      this.createDom('a', {
+        className: 'description',
+        href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
+        title: this.spec.getFullName()
+      }, this.spec.description)
+  );
+
+  this.detail = this.createDom('div', { className: 'specDetail' },
+      this.createDom('a', {
+        className: 'description',
+        href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
+        title: this.spec.getFullName()
+      }, this.spec.getFullName())
+  );
+};
+
+jasmine.HtmlReporter.SpecView.prototype.status = function() {
+  return this.getSpecStatus(this.spec);
+};
+
+jasmine.HtmlReporter.SpecView.prototype.refresh = function() {
+  this.symbol.className = this.status();
+
+  switch (this.status()) {
+    case 'skipped':
+      break;
+
+    case 'passed':
+      this.appendSummaryToSuiteDiv();
+      break;
+
+    case 'failed':
+      this.appendSummaryToSuiteDiv();
+      this.appendFailureDetail();
+      break;
+  }
+};
+
+jasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() {
+  this.summary.className += ' ' + this.status();
+  this.appendToSummary(this.spec, this.summary);
+};
+
+jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {
+  this.detail.className += ' ' + this.status();
+
+  var resultItems = this.spec.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) {
+    this.detail.appendChild(messagesDiv);
+    this.dom.details.appendChild(this.detail);
+  }
+};
+
+jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);jasmine.HtmlReporter.SuiteView = function(suite, dom, views) {
+  this.suite = suite;
+  this.dom = dom;
+  this.views = views;
+
+  this.element = this.createDom('div', { className: 'suite' },
+      this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(this.suite.getFullName()) }, this.suite.description)
+  );
+
+  this.appendToSummary(this.suite, this.element);
+};
+
+jasmine.HtmlReporter.SuiteView.prototype.status = function() {
+  return this.getSpecStatus(this.suite);
+};
+
+jasmine.HtmlReporter.SuiteView.prototype.refresh = function() {
+  this.element.className += " " + this.status();
+};
+
+jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView);
+
+/* @deprecated Use jasmine.HtmlReporter instead
+ */
+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', { id: 'TrivialReporter', 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 on 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-webos/blob/242b6c27/bin/templates/project/www/spec/lib/jasmine-1.2.0/jasmine.css
----------------------------------------------------------------------
diff --git a/bin/templates/project/www/spec/lib/jasmine-1.2.0/jasmine.css b/bin/templates/project/www/spec/lib/jasmine-1.2.0/jasmine.css
new file mode 100755
index 0000000..9b0375e
--- /dev/null
+++ b/bin/templates/project/www/spec/lib/jasmine-1.2.0/jasmine.css
@@ -0,0 +1,81 @@
+body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
+
+#HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
+#HTMLReporter a { text-decoration: none; }
+#HTMLReporter a:hover { text-decoration: underline; }
+#HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; }
+#HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; }
+#HTMLReporter #jasmine_content { position: fixed; right: 100%; }
+#HTMLReporter .version { color: #aaaaaa; }
+#HTMLReporter .banner { margin-top: 14px; }
+#HTMLReporter .duration { color: #aaaaaa; float: right; }
+#HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; }
+#HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
+#HTMLReporter .symbolSummary li.passed { font-size: 14px; }
+#HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; }
+#HTMLReporter .symbolSummary li.failed { line-height: 9px; }
+#HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
+#HTMLReporter .symbolSummary li.skipped { font-size: 14px; }
+#HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; }
+#HTMLReporter .symbolSummary li.pending { line-height: 11px; }
+#HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; }
+#HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
+#HTMLReporter .runningAlert { background-color: #666666; }
+#HTMLReporter .skippedAlert { background-color: #aaaaaa; }
+#HTMLReporter .skippedAlert:first-child { background-color: #333333; }
+#HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; }
+#HTMLReporter .passingAlert { background-color: #a6b779; }
+#HTMLReporter .passingAlert:first-child { background-color: #5e7d00; }
+#HTMLReporter .failingAlert { background-color: #cf867e; }
+#HTMLReporter .failingAlert:first-child { background-color: #b03911; }
+#HTMLReporter .results { margin-top: 14px; }
+#HTMLReporter #details { display: none; }
+#HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; }
+#HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
+#HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
+#HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
+#HTMLReporter.showDetails .summary { display: none; }
+#HTMLReporter.showDetails #details { display: block; }
+#HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
+#HTMLReporter .summary { margin-top: 14px; }
+#HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; }
+#HTMLReporter .summary .specSummary.passed a { color: #5e7d00; }
+#HTMLReporter .summary .specSummary.failed a { color: #b03911; }
+#HTMLReporter .description + .suite { margin-top: 0; }
+#HTMLReporter .suite { margin-top: 14px; }
+#HTMLReporter .suite a { color: #333333; }
+#HTMLReporter #details .specDetail { margin-bottom: 28px; }
+#HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; }
+#HTMLReporter .resultMessage { padding-top: 14px; color: #333333; }
+#HTMLReporter .resultMessage span.result { display: block; }
+#HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }
+
+#TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ }
+#TrivialReporter a:visited, #TrivialReporter a { color: #303; }
+#TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }
+#TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }
+#TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }
+#TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }
+#TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }
+#TrivialReporter .runner.running { background-color: yellow; }
+#TrivialReporter .options { text-align: right; font-size: .8em; }
+#TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }
+#TrivialReporter .suite .suite { margin: 5px; }
+#TrivialReporter .suite.passed { background-color: #dfd; }
+#TrivialReporter .suite.failed { background-color: #fdd; }
+#TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }
+#TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }
+#TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }
+#TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }
+#TrivialReporter .spec.skipped { background-color: #bbb; }
+#TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }
+#TrivialReporter .passed { background-color: #cfc; display: none; }
+#TrivialReporter .failed { background-color: #fbb; }
+#TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }
+#TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }
+#TrivialReporter .resultMessage .mismatch { color: black; }
+#TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }
+#TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }
+#TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }
+#TrivialReporter #jasmine_content { position: fixed; right: 100%; }
+#TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org


Mime
View raw message